mirror of
https://github.com/documenso/documenso.git
synced 2025-11-10 04:22:32 +10:00
feat: add document version history UI
This commit is contained in:
@ -1,5 +1,14 @@
|
||||
import type { DocumentAuditLog, DocumentMeta, Field, Recipient } from '@documenso/prisma/client';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import type {
|
||||
DocumentAuditLog,
|
||||
DocumentMeta,
|
||||
Field,
|
||||
Recipient,
|
||||
RecipientRole,
|
||||
} from '@documenso/prisma/client';
|
||||
|
||||
import { RECIPIENT_ROLES_DESCRIPTION } from '../constants/recipient-roles';
|
||||
import type {
|
||||
TDocumentAuditLog,
|
||||
TDocumentAuditLogDocumentMetaDiffSchema,
|
||||
@ -7,6 +16,7 @@ import type {
|
||||
TDocumentAuditLogRecipientDiffSchema,
|
||||
} from '../types/document-audit-logs';
|
||||
import {
|
||||
DOCUMENT_AUDIT_LOG_TYPE,
|
||||
DOCUMENT_META_DIFF_TYPE,
|
||||
FIELD_DIFF_TYPE,
|
||||
RECIPIENT_DIFF_TYPE,
|
||||
@ -58,6 +68,7 @@ export const parseDocumentAuditLogData = (auditLog: DocumentAuditLog): TDocument
|
||||
|
||||
// Handle any required migrations here.
|
||||
if (!data.success) {
|
||||
console.error(data.error);
|
||||
throw new Error('Migration required');
|
||||
}
|
||||
|
||||
@ -203,3 +214,114 @@ export const diffDocumentMetaChanges = (
|
||||
|
||||
return diffs;
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats the audit log into a description of the action.
|
||||
*
|
||||
* Provide a userId to prefix the action with the user, example 'X did Y'.
|
||||
*/
|
||||
export const formatDocumentAuditLogActionString = (
|
||||
auditLog: TDocumentAuditLog,
|
||||
userId?: number,
|
||||
) => {
|
||||
const { prefix, description } = formatDocumentAuditLogAction(auditLog, userId);
|
||||
|
||||
return prefix ? `${prefix} ${description}` : description;
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats the audit log into a description of the action.
|
||||
*
|
||||
* Provide a userId to prefix the action with the user, example 'X did Y'.
|
||||
*/
|
||||
export const formatDocumentAuditLogAction = (auditLog: TDocumentAuditLog, userId?: number) => {
|
||||
let prefix = userId === auditLog.userId ? 'You' : auditLog.name || auditLog.email || '';
|
||||
|
||||
const description = match(auditLog)
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_CREATED }, () => ({
|
||||
anonymous: 'A field was added',
|
||||
identified: 'added a field',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_DELETED }, () => ({
|
||||
anonymous: 'A field was removed',
|
||||
identified: 'removed a field',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_UPDATED }, () => ({
|
||||
anonymous: 'A field was updated',
|
||||
identified: 'updated a field',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_CREATED }, () => ({
|
||||
anonymous: 'A recipient was added',
|
||||
identified: 'added a recipient',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_DELETED }, () => ({
|
||||
anonymous: 'A recipient was removed',
|
||||
identified: 'removed a recipient',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_UPDATED }, () => ({
|
||||
anonymous: 'A recipient was updated',
|
||||
identified: 'updated a recipient',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_CREATED }, () => ({
|
||||
anonymous: 'Document created',
|
||||
identified: 'created the document',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED }, () => ({
|
||||
anonymous: 'Document deleted',
|
||||
identified: 'deleted the document',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_INSERTED }, () => ({
|
||||
anonymous: 'Field signed',
|
||||
identified: 'signed a field',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_UNINSERTED }, () => ({
|
||||
anonymous: 'Field unsigned',
|
||||
identified: 'unsigned a field',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_META_UPDATED }, () => ({
|
||||
anonymous: 'Document updated',
|
||||
identified: 'updated the document',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED }, () => ({
|
||||
anonymous: 'Document opened',
|
||||
identified: 'opened the document',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_TITLE_UPDATED }, () => ({
|
||||
anonymous: 'Document title updated',
|
||||
identified: 'updated the document title',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_SENT }, () => ({
|
||||
anonymous: 'Document sent',
|
||||
identified: 'sent the document',
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED }, ({ data }) => {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const action = RECIPIENT_ROLES_DESCRIPTION[data.recipientRole as RecipientRole]?.actioned;
|
||||
|
||||
const value = action ? `${action.toLowerCase()} the document` : 'completed their task';
|
||||
|
||||
return {
|
||||
anonymous: `Recipient ${value}`,
|
||||
identified: value,
|
||||
};
|
||||
})
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT }, ({ data }) => ({
|
||||
anonymous: `Email ${data.isResending ? 'resent' : 'sent'}`,
|
||||
identified: `${data.isResending ? 'resent' : 'sent'} an email`,
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED }, () => {
|
||||
// Clear the prefix since this should be considered an 'anonymous' event.
|
||||
prefix = '';
|
||||
|
||||
return {
|
||||
anonymous: 'Document completed',
|
||||
identified: 'Document completed',
|
||||
};
|
||||
})
|
||||
.exhaustive();
|
||||
|
||||
return {
|
||||
prefix,
|
||||
description: prefix ? description.identified : description.anonymous,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user