mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 08:13:56 +10:00
feat: add certificate translations (#1440)
Add translations for audit logs and certificates.
This commit is contained in:
@ -143,17 +143,11 @@ export const DocumentPageViewRecentActivity = ({
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Todo: Translations. */}
|
|
||||||
<p
|
<p
|
||||||
className="text-muted-foreground dark:text-muted-foreground/70 flex-auto truncate py-0.5 text-xs leading-5"
|
className="text-muted-foreground dark:text-muted-foreground/70 flex-auto truncate py-0.5 text-xs leading-5"
|
||||||
title={`${formatDocumentAuditLogAction(auditLog, userId).prefix} ${
|
title={formatDocumentAuditLogAction(_, auditLog, userId).description}
|
||||||
formatDocumentAuditLogAction(auditLog, userId).description
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<span className="text-foreground font-medium">
|
{formatDocumentAuditLogAction(_, auditLog, userId).description}
|
||||||
{formatDocumentAuditLogAction(auditLog, userId).prefix}
|
|
||||||
</span>{' '}
|
|
||||||
{formatDocumentAuditLogAction(auditLog, userId).description}
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<time className="text-muted-foreground dark:text-muted-foreground/70 flex-none py-0.5 text-xs leading-5">
|
<time className="text-muted-foreground dark:text-muted-foreground/70 flex-none py-0.5 text-xs leading-5">
|
||||||
|
|||||||
@ -58,10 +58,6 @@ export const DocumentLogsDataTable = ({ documentId }: DocumentLogsDataTableProps
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const uppercaseFistLetter = (text: string) => {
|
|
||||||
return text.charAt(0).toUpperCase() + text.slice(1);
|
|
||||||
};
|
|
||||||
|
|
||||||
const results = data ?? {
|
const results = data ?? {
|
||||||
data: [],
|
data: [],
|
||||||
perPage: 10,
|
perPage: 10,
|
||||||
@ -103,9 +99,7 @@ export const DocumentLogsDataTable = ({ documentId }: DocumentLogsDataTableProps
|
|||||||
{
|
{
|
||||||
header: _(msg`Action`),
|
header: _(msg`Action`),
|
||||||
accessorKey: 'type',
|
accessorKey: 'type',
|
||||||
cell: ({ row }) => (
|
cell: ({ row }) => <span>{formatDocumentAuditLogAction(_, row.original).description}</span>,
|
||||||
<span>{uppercaseFistLetter(formatDocumentAuditLogAction(row.original).description)}</span>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: 'IP Address',
|
header: 'IP Address',
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
'use client';
|
import { msg } from '@lingui/macro';
|
||||||
|
import { useLingui } from '@lingui/react';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import type { DateTimeFormatOptions } from 'luxon';
|
import type { DateTimeFormatOptions } from 'luxon';
|
||||||
import { UAParser } from 'ua-parser-js';
|
import { UAParser } from 'ua-parser-js';
|
||||||
@ -25,7 +25,12 @@ const dateFormat: DateTimeFormatOptions = {
|
|||||||
hourCycle: 'h12',
|
hourCycle: 'h12',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DO NOT USE TRANS. YOU MUST USE _ FOR THIS FILE AND ALL CHILDREN COMPONENTS.
|
||||||
|
*/
|
||||||
export const AuditLogDataTable = ({ logs }: AuditLogDataTableProps) => {
|
export const AuditLogDataTable = ({ logs }: AuditLogDataTableProps) => {
|
||||||
|
const { _ } = useLingui();
|
||||||
|
|
||||||
const parser = new UAParser();
|
const parser = new UAParser();
|
||||||
|
|
||||||
const uppercaseFistLetter = (text: string) => {
|
const uppercaseFistLetter = (text: string) => {
|
||||||
@ -36,11 +41,11 @@ export const AuditLogDataTable = ({ logs }: AuditLogDataTableProps) => {
|
|||||||
<Table overflowHidden>
|
<Table overflowHidden>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead>Time</TableHead>
|
<TableHead>{_(msg`Time`)}</TableHead>
|
||||||
<TableHead>User</TableHead>
|
<TableHead>{_(msg`User`)}</TableHead>
|
||||||
<TableHead>Action</TableHead>
|
<TableHead>{_(msg`Action`)}</TableHead>
|
||||||
<TableHead>IP Address</TableHead>
|
<TableHead>{_(msg`IP Address`)}</TableHead>
|
||||||
<TableHead>Browser</TableHead>
|
<TableHead>{_(msg`Browser`)}</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
|
|
||||||
@ -74,7 +79,7 @@ export const AuditLogDataTable = ({ logs }: AuditLogDataTableProps) => {
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<TableCell>
|
<TableCell>
|
||||||
{uppercaseFistLetter(formatDocumentAuditLogAction(log).description)}
|
{uppercaseFistLetter(formatDocumentAuditLogAction(_, log).description)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<TableCell>{log.ipAddress}</TableCell>
|
<TableCell>{log.ipAddress}</TableCell>
|
||||||
|
|||||||
@ -2,13 +2,18 @@ import React from 'react';
|
|||||||
|
|
||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
|
import { msg } from '@lingui/macro';
|
||||||
|
import { useLingui } from '@lingui/react';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
|
|
||||||
import { APP_I18N_OPTIONS } from '@documenso/lib/constants/i18n';
|
import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server';
|
||||||
import { RECIPIENT_ROLES_DESCRIPTION_ENG } from '@documenso/lib/constants/recipient-roles';
|
import { DOCUMENT_STATUS } from '@documenso/lib/constants/document';
|
||||||
|
import { APP_I18N_OPTIONS, ZSupportedLanguageCodeSchema } from '@documenso/lib/constants/i18n';
|
||||||
|
import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient-roles';
|
||||||
import { getEntireDocument } from '@documenso/lib/server-only/admin/get-entire-document';
|
import { getEntireDocument } from '@documenso/lib/server-only/admin/get-entire-document';
|
||||||
import { decryptSecondaryData } from '@documenso/lib/server-only/crypto/decrypt';
|
import { decryptSecondaryData } from '@documenso/lib/server-only/crypto/decrypt';
|
||||||
import { findDocumentAuditLogs } from '@documenso/lib/server-only/document/find-document-audit-logs';
|
import { findDocumentAuditLogs } from '@documenso/lib/server-only/document/find-document-audit-logs';
|
||||||
|
import { dynamicActivate } from '@documenso/lib/utils/i18n';
|
||||||
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||||
|
|
||||||
import { Logo } from '~/components/branding/logo';
|
import { Logo } from '~/components/branding/logo';
|
||||||
@ -21,7 +26,17 @@ type AuditLogProps = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DO NOT USE TRANS. YOU MUST USE _ FOR THIS FILE AND ALL CHILDREN COMPONENTS.
|
||||||
|
*
|
||||||
|
* Cannot use dynamicActivate by itself to translate this specific page and all
|
||||||
|
* children components because `not-found.tsx` page runs and overrides the i18n.
|
||||||
|
*/
|
||||||
export default async function AuditLog({ searchParams }: AuditLogProps) {
|
export default async function AuditLog({ searchParams }: AuditLogProps) {
|
||||||
|
const { i18n } = await setupI18nSSR();
|
||||||
|
|
||||||
|
const { _ } = useLingui();
|
||||||
|
|
||||||
const { d } = searchParams;
|
const { d } = searchParams;
|
||||||
|
|
||||||
if (typeof d !== 'string' || !d) {
|
if (typeof d !== 'string' || !d) {
|
||||||
@ -44,6 +59,10 @@ export default async function AuditLog({ searchParams }: AuditLogProps) {
|
|||||||
return redirect('/');
|
return redirect('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const documentLanguage = ZSupportedLanguageCodeSchema.parse(document.documentMeta?.language);
|
||||||
|
|
||||||
|
await dynamicActivate(i18n, documentLanguage);
|
||||||
|
|
||||||
const { data: auditLogs } = await findDocumentAuditLogs({
|
const { data: auditLogs } = await findDocumentAuditLogs({
|
||||||
documentId: documentId,
|
documentId: documentId,
|
||||||
userId: document.userId,
|
userId: document.userId,
|
||||||
@ -53,31 +72,35 @@ export default async function AuditLog({ searchParams }: AuditLogProps) {
|
|||||||
return (
|
return (
|
||||||
<div className="print-provider pointer-events-none mx-auto max-w-screen-md">
|
<div className="print-provider pointer-events-none mx-auto max-w-screen-md">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<h1 className="my-8 text-2xl font-bold">Version History</h1>
|
<h1 className="my-8 text-2xl font-bold">{_(msg`Version History`)}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Card>
|
<Card>
|
||||||
<CardContent className="grid grid-cols-2 gap-4 p-6 text-sm print:text-xs">
|
<CardContent className="grid grid-cols-2 gap-4 p-6 text-sm print:text-xs">
|
||||||
<p>
|
<p>
|
||||||
<span className="font-medium">Document ID</span>
|
<span className="font-medium">{_(msg`Document ID`)}</span>
|
||||||
|
|
||||||
<span className="mt-1 block break-words">{document.id}</span>
|
<span className="mt-1 block break-words">{document.id}</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span className="font-medium">Enclosed Document</span>
|
<span className="font-medium">{_(msg`Enclosed Document`)}</span>
|
||||||
|
|
||||||
<span className="mt-1 block break-words">{document.title}</span>
|
<span className="mt-1 block break-words">{document.title}</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span className="font-medium">Status</span>
|
<span className="font-medium">{_(msg`Status`)}</span>
|
||||||
|
|
||||||
<span className="mt-1 block">{document.deletedAt ? 'DELETED' : document.status}</span>
|
<span className="mt-1 block">
|
||||||
|
{_(
|
||||||
|
document.deletedAt ? msg`Deleted` : DOCUMENT_STATUS[document.status].description,
|
||||||
|
).toUpperCase()}
|
||||||
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span className="font-medium">Owner</span>
|
<span className="font-medium">{_(msg`Owner`)}</span>
|
||||||
|
|
||||||
<span className="mt-1 block break-words">
|
<span className="mt-1 block break-words">
|
||||||
{document.User.name} ({document.User.email})
|
{document.User.name} ({document.User.email})
|
||||||
@ -85,7 +108,7 @@ export default async function AuditLog({ searchParams }: AuditLogProps) {
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span className="font-medium">Created At</span>
|
<span className="font-medium">{_(msg`Created At`)}</span>
|
||||||
|
|
||||||
<span className="mt-1 block">
|
<span className="mt-1 block">
|
||||||
{DateTime.fromJSDate(document.createdAt)
|
{DateTime.fromJSDate(document.createdAt)
|
||||||
@ -95,7 +118,7 @@ export default async function AuditLog({ searchParams }: AuditLogProps) {
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span className="font-medium">Last Updated</span>
|
<span className="font-medium">{_(msg`Last Updated`)}</span>
|
||||||
|
|
||||||
<span className="mt-1 block">
|
<span className="mt-1 block">
|
||||||
{DateTime.fromJSDate(document.updatedAt)
|
{DateTime.fromJSDate(document.updatedAt)
|
||||||
@ -105,7 +128,7 @@ export default async function AuditLog({ searchParams }: AuditLogProps) {
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span className="font-medium">Time Zone</span>
|
<span className="font-medium">{_(msg`Time Zone`)}</span>
|
||||||
|
|
||||||
<span className="mt-1 block break-words">
|
<span className="mt-1 block break-words">
|
||||||
{document.documentMeta?.timezone ?? 'N/A'}
|
{document.documentMeta?.timezone ?? 'N/A'}
|
||||||
@ -113,13 +136,13 @@ export default async function AuditLog({ searchParams }: AuditLogProps) {
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p className="font-medium">Recipients</p>
|
<p className="font-medium">{_(msg`Recipients`)}</p>
|
||||||
|
|
||||||
<ul className="mt-1 list-inside list-disc">
|
<ul className="mt-1 list-inside list-disc">
|
||||||
{document.Recipient.map((recipient) => (
|
{document.Recipient.map((recipient) => (
|
||||||
<li key={recipient.id}>
|
<li key={recipient.id}>
|
||||||
<span className="text-muted-foreground">
|
<span className="text-muted-foreground">
|
||||||
[{RECIPIENT_ROLES_DESCRIPTION_ENG[recipient.role].roleName}]
|
[{_(RECIPIENT_ROLES_DESCRIPTION[recipient.role].roleName)}]
|
||||||
</span>{' '}
|
</span>{' '}
|
||||||
{recipient.name} ({recipient.email})
|
{recipient.name} ({recipient.email})
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@ -2,20 +2,24 @@ import React from 'react';
|
|||||||
|
|
||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
|
import { msg } from '@lingui/macro';
|
||||||
|
import { useLingui } from '@lingui/react';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { match } from 'ts-pattern';
|
import { match } from 'ts-pattern';
|
||||||
import { UAParser } from 'ua-parser-js';
|
import { UAParser } from 'ua-parser-js';
|
||||||
|
|
||||||
import { APP_I18N_OPTIONS } from '@documenso/lib/constants/i18n';
|
import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server';
|
||||||
|
import { APP_I18N_OPTIONS, ZSupportedLanguageCodeSchema } from '@documenso/lib/constants/i18n';
|
||||||
import {
|
import {
|
||||||
RECIPIENT_ROLES_DESCRIPTION_ENG,
|
RECIPIENT_ROLES_DESCRIPTION,
|
||||||
RECIPIENT_ROLE_SIGNING_REASONS_ENG,
|
RECIPIENT_ROLE_SIGNING_REASONS,
|
||||||
} from '@documenso/lib/constants/recipient-roles';
|
} from '@documenso/lib/constants/recipient-roles';
|
||||||
import { getEntireDocument } from '@documenso/lib/server-only/admin/get-entire-document';
|
import { getEntireDocument } from '@documenso/lib/server-only/admin/get-entire-document';
|
||||||
import { decryptSecondaryData } from '@documenso/lib/server-only/crypto/decrypt';
|
import { decryptSecondaryData } from '@documenso/lib/server-only/crypto/decrypt';
|
||||||
import { getDocumentCertificateAuditLogs } from '@documenso/lib/server-only/document/get-document-certificate-audit-logs';
|
import { getDocumentCertificateAuditLogs } from '@documenso/lib/server-only/document/get-document-certificate-audit-logs';
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||||
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
|
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
|
||||||
|
import { dynamicActivate } from '@documenso/lib/utils/i18n';
|
||||||
import { FieldType } from '@documenso/prisma/client';
|
import { FieldType } from '@documenso/prisma/client';
|
||||||
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||||
import {
|
import {
|
||||||
@ -36,11 +40,21 @@ type SigningCertificateProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const FRIENDLY_SIGNING_REASONS = {
|
const FRIENDLY_SIGNING_REASONS = {
|
||||||
['__OWNER__']: `I am the owner of this document`,
|
['__OWNER__']: msg`I am the owner of this document`,
|
||||||
...RECIPIENT_ROLE_SIGNING_REASONS_ENG,
|
...RECIPIENT_ROLE_SIGNING_REASONS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DO NOT USE TRANS. YOU MUST USE _ FOR THIS FILE AND ALL CHILDREN COMPONENTS.
|
||||||
|
*
|
||||||
|
* Cannot use dynamicActivate by itself to translate this specific page and all
|
||||||
|
* children components because `not-found.tsx` page runs and overrides the i18n.
|
||||||
|
*/
|
||||||
export default async function SigningCertificate({ searchParams }: SigningCertificateProps) {
|
export default async function SigningCertificate({ searchParams }: SigningCertificateProps) {
|
||||||
|
const { i18n } = await setupI18nSSR();
|
||||||
|
|
||||||
|
const { _ } = useLingui();
|
||||||
|
|
||||||
const { d } = searchParams;
|
const { d } = searchParams;
|
||||||
|
|
||||||
if (typeof d !== 'string' || !d) {
|
if (typeof d !== 'string' || !d) {
|
||||||
@ -63,6 +77,10 @@ export default async function SigningCertificate({ searchParams }: SigningCertif
|
|||||||
return redirect('/');
|
return redirect('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const documentLanguage = ZSupportedLanguageCodeSchema.parse(document.documentMeta?.language);
|
||||||
|
|
||||||
|
await dynamicActivate(i18n, documentLanguage);
|
||||||
|
|
||||||
const auditLogs = await getDocumentCertificateAuditLogs({
|
const auditLogs = await getDocumentCertificateAuditLogs({
|
||||||
id: documentId,
|
id: documentId,
|
||||||
});
|
});
|
||||||
@ -98,17 +116,17 @@ export default async function SigningCertificate({ searchParams }: SigningCertif
|
|||||||
});
|
});
|
||||||
|
|
||||||
let authLevel = match(extractedAuthMethods.derivedRecipientActionAuth)
|
let authLevel = match(extractedAuthMethods.derivedRecipientActionAuth)
|
||||||
.with('ACCOUNT', () => 'Account Re-Authentication')
|
.with('ACCOUNT', () => _(msg`Account Re-Authentication`))
|
||||||
.with('TWO_FACTOR_AUTH', () => 'Two-Factor Re-Authentication')
|
.with('TWO_FACTOR_AUTH', () => _(msg`Two-Factor Re-Authentication`))
|
||||||
.with('PASSKEY', () => 'Passkey Re-Authentication')
|
.with('PASSKEY', () => _(msg`Passkey Re-Authentication`))
|
||||||
.with('EXPLICIT_NONE', () => 'Email')
|
.with('EXPLICIT_NONE', () => _(msg`Email`))
|
||||||
.with(null, () => null)
|
.with(null, () => null)
|
||||||
.exhaustive();
|
.exhaustive();
|
||||||
|
|
||||||
if (!authLevel) {
|
if (!authLevel) {
|
||||||
authLevel = match(extractedAuthMethods.derivedRecipientAccessAuth)
|
authLevel = match(extractedAuthMethods.derivedRecipientAccessAuth)
|
||||||
.with('ACCOUNT', () => 'Account Authentication')
|
.with('ACCOUNT', () => _(msg`Account Authentication`))
|
||||||
.with(null, () => 'Email')
|
.with(null, () => _(msg`Email`))
|
||||||
.exhaustive();
|
.exhaustive();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +165,7 @@ export default async function SigningCertificate({ searchParams }: SigningCertif
|
|||||||
return (
|
return (
|
||||||
<div className="print-provider pointer-events-none mx-auto max-w-screen-md">
|
<div className="print-provider pointer-events-none mx-auto max-w-screen-md">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<h1 className="my-8 text-2xl font-bold">Signing Certificate</h1>
|
<h1 className="my-8 text-2xl font-bold">{_(msg`Signing Certificate`)}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Card>
|
<Card>
|
||||||
@ -155,9 +173,9 @@ export default async function SigningCertificate({ searchParams }: SigningCertif
|
|||||||
<Table overflowHidden>
|
<Table overflowHidden>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead>Signer Events</TableHead>
|
<TableHead>{_(msg`Signer Events`)}</TableHead>
|
||||||
<TableHead>Signature</TableHead>
|
<TableHead>{_(msg`Signature`)}</TableHead>
|
||||||
<TableHead>Details</TableHead>
|
<TableHead>{_(msg`Details`)}</TableHead>
|
||||||
{/* <TableHead>Security</TableHead> */}
|
{/* <TableHead>Security</TableHead> */}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
@ -173,11 +191,11 @@ export default async function SigningCertificate({ searchParams }: SigningCertif
|
|||||||
<div className="hyphens-auto break-words font-medium">{recipient.name}</div>
|
<div className="hyphens-auto break-words font-medium">{recipient.name}</div>
|
||||||
<div className="break-all">{recipient.email}</div>
|
<div className="break-all">{recipient.email}</div>
|
||||||
<p className="text-muted-foreground mt-2 text-sm print:text-xs">
|
<p className="text-muted-foreground mt-2 text-sm print:text-xs">
|
||||||
{RECIPIENT_ROLES_DESCRIPTION_ENG[recipient.role].roleName}
|
{_(RECIPIENT_ROLES_DESCRIPTION[recipient.role].roleName)}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="text-muted-foreground mt-2 text-sm print:text-xs">
|
<p className="text-muted-foreground mt-2 text-sm print:text-xs">
|
||||||
<span className="font-medium">Authentication Level:</span>{' '}
|
<span className="font-medium">{_(msg`Authentication Level`)}:</span>{' '}
|
||||||
<span className="block">{getAuthenticationLevel(recipient.id)}</span>
|
<span className="block">{getAuthenticationLevel(recipient.id)}</span>
|
||||||
</p>
|
</p>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@ -199,21 +217,21 @@ export default async function SigningCertificate({ searchParams }: SigningCertif
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="text-muted-foreground mt-2 text-sm print:text-xs">
|
<p className="text-muted-foreground mt-2 text-sm print:text-xs">
|
||||||
<span className="font-medium">Signature ID:</span>{' '}
|
<span className="font-medium">{_(msg`Signature ID`)}:</span>{' '}
|
||||||
<span className="block font-mono uppercase">
|
<span className="block font-mono uppercase">
|
||||||
{signature.secondaryId}
|
{signature.secondaryId}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="text-muted-foreground mt-2 text-sm print:text-xs">
|
<p className="text-muted-foreground mt-2 text-sm print:text-xs">
|
||||||
<span className="font-medium">IP Address:</span>{' '}
|
<span className="font-medium">{_(msg`IP Address`)}:</span>{' '}
|
||||||
<span className="inline-block">
|
<span className="inline-block">
|
||||||
{logs.DOCUMENT_RECIPIENT_COMPLETED[0]?.ipAddress ?? 'Unknown'}
|
{logs.DOCUMENT_RECIPIENT_COMPLETED[0]?.ipAddress ?? _(msg`Unknown`)}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="text-muted-foreground mt-1 text-sm print:text-xs">
|
<p className="text-muted-foreground mt-1 text-sm print:text-xs">
|
||||||
<span className="font-medium">Device:</span>{' '}
|
<span className="font-medium">{_(msg`Device`)}:</span>{' '}
|
||||||
<span className="inline-block">
|
<span className="inline-block">
|
||||||
{getDevice(logs.DOCUMENT_RECIPIENT_COMPLETED[0]?.userAgent)}
|
{getDevice(logs.DOCUMENT_RECIPIENT_COMPLETED[0]?.userAgent)}
|
||||||
</span>
|
</span>
|
||||||
@ -227,44 +245,46 @@ export default async function SigningCertificate({ searchParams }: SigningCertif
|
|||||||
<TableCell truncate={false} className="w-[min-content] align-top">
|
<TableCell truncate={false} className="w-[min-content] align-top">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<p className="text-muted-foreground text-sm print:text-xs">
|
<p className="text-muted-foreground text-sm print:text-xs">
|
||||||
<span className="font-medium">Sent:</span>{' '}
|
<span className="font-medium">{_(msg`Sent`)}:</span>{' '}
|
||||||
<span className="inline-block">
|
<span className="inline-block">
|
||||||
{logs.EMAIL_SENT[0]
|
{logs.EMAIL_SENT[0]
|
||||||
? DateTime.fromJSDate(logs.EMAIL_SENT[0].createdAt)
|
? DateTime.fromJSDate(logs.EMAIL_SENT[0].createdAt)
|
||||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||||
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)')
|
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)')
|
||||||
: 'Unknown'}
|
: _(msg`Unknown`)}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="text-muted-foreground text-sm print:text-xs">
|
<p className="text-muted-foreground text-sm print:text-xs">
|
||||||
<span className="font-medium">Viewed:</span>{' '}
|
<span className="font-medium">{_(msg`Viewed`)}:</span>{' '}
|
||||||
<span className="inline-block">
|
<span className="inline-block">
|
||||||
{logs.DOCUMENT_OPENED[0]
|
{logs.DOCUMENT_OPENED[0]
|
||||||
? DateTime.fromJSDate(logs.DOCUMENT_OPENED[0].createdAt)
|
? DateTime.fromJSDate(logs.DOCUMENT_OPENED[0].createdAt)
|
||||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||||
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)')
|
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)')
|
||||||
: 'Unknown'}
|
: _(msg`Unknown`)}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="text-muted-foreground text-sm print:text-xs">
|
<p className="text-muted-foreground text-sm print:text-xs">
|
||||||
<span className="font-medium">Signed:</span>{' '}
|
<span className="font-medium">{_(msg`Signed`)}:</span>{' '}
|
||||||
<span className="inline-block">
|
<span className="inline-block">
|
||||||
{logs.DOCUMENT_RECIPIENT_COMPLETED[0]
|
{logs.DOCUMENT_RECIPIENT_COMPLETED[0]
|
||||||
? DateTime.fromJSDate(logs.DOCUMENT_RECIPIENT_COMPLETED[0].createdAt)
|
? DateTime.fromJSDate(logs.DOCUMENT_RECIPIENT_COMPLETED[0].createdAt)
|
||||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||||
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)')
|
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)')
|
||||||
: 'Unknown'}
|
: _(msg`Unknown`)}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="text-muted-foreground text-sm print:text-xs">
|
<p className="text-muted-foreground text-sm print:text-xs">
|
||||||
<span className="font-medium">Reason:</span>{' '}
|
<span className="font-medium">{_(msg`Reason`)}:</span>{' '}
|
||||||
<span className="inline-block">
|
<span className="inline-block">
|
||||||
{isOwner(recipient.email)
|
{_(
|
||||||
? FRIENDLY_SIGNING_REASONS['__OWNER__']
|
isOwner(recipient.email)
|
||||||
: FRIENDLY_SIGNING_REASONS[recipient.role]}
|
? FRIENDLY_SIGNING_REASONS['__OWNER__']
|
||||||
|
: FRIENDLY_SIGNING_REASONS[recipient.role],
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -280,7 +300,7 @@ export default async function SigningCertificate({ searchParams }: SigningCertif
|
|||||||
<div className="my-8 flex-row-reverse">
|
<div className="my-8 flex-row-reverse">
|
||||||
<div className="flex items-end justify-end gap-x-4">
|
<div className="flex items-end justify-end gap-x-4">
|
||||||
<p className="flex-shrink-0 text-sm font-medium print:text-xs">
|
<p className="flex-shrink-0 text-sm font-medium print:text-xs">
|
||||||
Signing certificate provided by:
|
{_(msg`Signing certificate provided by`)}:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<Logo className="max-h-6 print:max-h-4" />
|
<Logo className="max-h-6 print:max-h-4" />
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import { UAParser } from 'ua-parser-js';
|
|||||||
import { DOCUMENT_AUDIT_LOG_EMAIL_FORMAT } from '@documenso/lib/constants/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_EMAIL_FORMAT } from '@documenso/lib/constants/document-audit-logs';
|
||||||
import { DOCUMENT_AUTH_TYPES } from '@documenso/lib/constants/document-auth';
|
import { DOCUMENT_AUTH_TYPES } from '@documenso/lib/constants/document-auth';
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||||
import { formatDocumentAuditLogActionString } from '@documenso/lib/utils/document-audit-logs';
|
import { formatDocumentAuditLogAction } from '@documenso/lib/utils/document-audit-logs';
|
||||||
import { trpc } from '@documenso/trpc/react';
|
import { trpc } from '@documenso/trpc/react';
|
||||||
import { cn } from '@documenso/ui/lib/utils';
|
import { cn } from '@documenso/ui/lib/utils';
|
||||||
import { Avatar, AvatarFallback } from '@documenso/ui/primitives/avatar';
|
import { Avatar, AvatarFallback } from '@documenso/ui/primitives/avatar';
|
||||||
@ -37,7 +37,7 @@ export const DocumentHistorySheet = ({
|
|||||||
onMenuOpenChange,
|
onMenuOpenChange,
|
||||||
children,
|
children,
|
||||||
}: DocumentHistorySheetProps) => {
|
}: DocumentHistorySheetProps) => {
|
||||||
const { i18n } = useLingui();
|
const { _, i18n } = useLingui();
|
||||||
|
|
||||||
const [isUserDetailsVisible, setIsUserDetailsVisible] = useState(false);
|
const [isUserDetailsVisible, setIsUserDetailsVisible] = useState(false);
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ export const DocumentHistorySheet = ({
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p className="text-foreground text-xs font-bold">
|
<p className="text-foreground text-xs font-bold">
|
||||||
{formatDocumentAuditLogActionString(auditLog, userId)}
|
{formatDocumentAuditLogAction(_, auditLog, userId).description}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-foreground/50 text-xs">
|
<p className="text-foreground/50 text-xs">
|
||||||
{DateTime.fromJSDate(auditLog.createdAt)
|
{DateTime.fromJSDate(auditLog.createdAt)
|
||||||
|
|||||||
18
packages/lib/constants/document.ts
Normal file
18
packages/lib/constants/document.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import type { MessageDescriptor } from '@lingui/core';
|
||||||
|
import { msg } from '@lingui/macro';
|
||||||
|
|
||||||
|
import { DocumentStatus } from '@documenso/prisma/client';
|
||||||
|
|
||||||
|
export const DOCUMENT_STATUS: {
|
||||||
|
[status in DocumentStatus]: { description: MessageDescriptor };
|
||||||
|
} = {
|
||||||
|
[DocumentStatus.COMPLETED]: {
|
||||||
|
description: msg`Completed`,
|
||||||
|
},
|
||||||
|
[DocumentStatus.DRAFT]: {
|
||||||
|
description: msg`Draft`,
|
||||||
|
},
|
||||||
|
[DocumentStatus.PENDING]: {
|
||||||
|
description: msg`Pending`,
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -78,13 +78,3 @@ export const RECIPIENT_ROLE_SIGNING_REASONS = {
|
|||||||
[RecipientRole.CC]: msg`I am required to receive a copy of this document`,
|
[RecipientRole.CC]: msg`I am required to receive a copy of this document`,
|
||||||
[RecipientRole.VIEWER]: msg`I am a viewer of this document`,
|
[RecipientRole.VIEWER]: msg`I am a viewer of this document`,
|
||||||
} satisfies Record<keyof typeof RecipientRole, MessageDescriptor>;
|
} satisfies Record<keyof typeof RecipientRole, MessageDescriptor>;
|
||||||
|
|
||||||
/**
|
|
||||||
* Raw english descriptions for certificates.
|
|
||||||
*/
|
|
||||||
export const RECIPIENT_ROLE_SIGNING_REASONS_ENG = {
|
|
||||||
[RecipientRole.SIGNER]: `I am a signer of this document`,
|
|
||||||
[RecipientRole.APPROVER]: `I am an approver of this document`,
|
|
||||||
[RecipientRole.CC]: `I am required to receive a copy of this document`,
|
|
||||||
[RecipientRole.VIEWER]: `I am a viewer of this document`,
|
|
||||||
} satisfies Record<keyof typeof RecipientRole, string>;
|
|
||||||
|
|||||||
@ -1,14 +1,10 @@
|
|||||||
|
import type { I18n } from '@lingui/core';
|
||||||
|
import { msg } from '@lingui/macro';
|
||||||
import { match } from 'ts-pattern';
|
import { match } from 'ts-pattern';
|
||||||
|
|
||||||
import type {
|
import type { DocumentAuditLog, DocumentMeta, Field, Recipient } from '@documenso/prisma/client';
|
||||||
DocumentAuditLog,
|
import { RecipientRole } from '@documenso/prisma/client';
|
||||||
DocumentMeta,
|
|
||||||
Field,
|
|
||||||
Recipient,
|
|
||||||
RecipientRole,
|
|
||||||
} from '@documenso/prisma/client';
|
|
||||||
|
|
||||||
import { RECIPIENT_ROLES_DESCRIPTION_ENG } from '../constants/recipient-roles';
|
|
||||||
import type {
|
import type {
|
||||||
TDocumentAuditLog,
|
TDocumentAuditLog,
|
||||||
TDocumentAuditLogDocumentMetaDiffSchema,
|
TDocumentAuditLogDocumentMetaDiffSchema,
|
||||||
@ -254,129 +250,119 @@ export const diffDocumentMetaChanges = (
|
|||||||
*
|
*
|
||||||
* Provide a userId to prefix the action with the user, example 'X did Y'.
|
* Provide a userId to prefix the action with the user, example 'X did Y'.
|
||||||
*/
|
*/
|
||||||
export const formatDocumentAuditLogActionString = (
|
export const formatDocumentAuditLogAction = (
|
||||||
|
_: I18n['_'],
|
||||||
auditLog: TDocumentAuditLog,
|
auditLog: TDocumentAuditLog,
|
||||||
userId?: number,
|
userId?: number,
|
||||||
) => {
|
) => {
|
||||||
const { prefix, description } = formatDocumentAuditLogAction(auditLog, userId);
|
const prefix = userId === auditLog.userId ? _(msg`You`) : auditLog.name || auditLog.email || '';
|
||||||
|
|
||||||
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'.
|
|
||||||
*/
|
|
||||||
// Todo: Translations.
|
|
||||||
export const formatDocumentAuditLogAction = (auditLog: TDocumentAuditLog, userId?: number) => {
|
|
||||||
let prefix = userId === auditLog.userId ? 'You' : auditLog.name || auditLog.email || '';
|
|
||||||
|
|
||||||
const description = match(auditLog)
|
const description = match(auditLog)
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_CREATED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_CREATED }, () => ({
|
||||||
anonymous: 'A field was added',
|
anonymous: msg`A field was added`,
|
||||||
identified: 'added a field',
|
identified: msg`${prefix} added a field`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_DELETED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_DELETED }, () => ({
|
||||||
anonymous: 'A field was removed',
|
anonymous: msg`A field was removed`,
|
||||||
identified: 'removed a field',
|
identified: msg`${prefix} removed a field`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_UPDATED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_UPDATED }, () => ({
|
||||||
anonymous: 'A field was updated',
|
anonymous: msg`A field was updated`,
|
||||||
identified: 'updated a field',
|
identified: msg`${prefix} updated a field`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_CREATED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_CREATED }, () => ({
|
||||||
anonymous: 'A recipient was added',
|
anonymous: msg`A recipient was added`,
|
||||||
identified: 'added a recipient',
|
identified: msg`${prefix} added a recipient`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_DELETED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_DELETED }, () => ({
|
||||||
anonymous: 'A recipient was removed',
|
anonymous: msg`A recipient was removed`,
|
||||||
identified: 'removed a recipient',
|
identified: msg`${prefix} removed a recipient`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_UPDATED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_UPDATED }, () => ({
|
||||||
anonymous: 'A recipient was updated',
|
anonymous: msg`A recipient was updated`,
|
||||||
identified: 'updated a recipient',
|
identified: msg`${prefix} updated a recipient`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_CREATED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_CREATED }, () => ({
|
||||||
anonymous: 'Document created',
|
anonymous: msg`Document created`,
|
||||||
identified: 'created the document',
|
identified: msg`${prefix} created the document`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED }, () => ({
|
||||||
anonymous: 'Document deleted',
|
anonymous: msg`Document deleted`,
|
||||||
identified: 'deleted the document',
|
identified: msg`${prefix} deleted the document`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_INSERTED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_INSERTED }, () => ({
|
||||||
anonymous: 'Field signed',
|
anonymous: msg`Field signed`,
|
||||||
identified: 'signed a field',
|
identified: msg`${prefix} signed a field`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_UNINSERTED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_UNINSERTED }, () => ({
|
||||||
anonymous: 'Field unsigned',
|
anonymous: msg`Field unsigned`,
|
||||||
identified: 'unsigned a field',
|
identified: msg`${prefix} unsigned a field`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_VISIBILITY_UPDATED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_VISIBILITY_UPDATED }, () => ({
|
||||||
anonymous: 'Document visibility updated',
|
anonymous: msg`Document visibility updated`,
|
||||||
identified: 'updated the document visibility',
|
identified: msg`${prefix} updated the document visibility`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_GLOBAL_AUTH_ACCESS_UPDATED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_GLOBAL_AUTH_ACCESS_UPDATED }, () => ({
|
||||||
anonymous: 'Document access auth updated',
|
anonymous: msg`Document access auth updated`,
|
||||||
identified: 'updated the document access auth requirements',
|
identified: msg`${prefix} updated the document access auth requirements`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_GLOBAL_AUTH_ACTION_UPDATED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_GLOBAL_AUTH_ACTION_UPDATED }, () => ({
|
||||||
anonymous: 'Document signing auth updated',
|
anonymous: msg`Document signing auth updated`,
|
||||||
identified: 'updated the document signing auth requirements',
|
identified: msg`${prefix} updated the document signing auth requirements`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_META_UPDATED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_META_UPDATED }, () => ({
|
||||||
anonymous: 'Document updated',
|
anonymous: msg`Document updated`,
|
||||||
identified: 'updated the document',
|
identified: msg`${prefix} updated the document`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED }, () => ({
|
||||||
anonymous: 'Document opened',
|
anonymous: msg`Document opened`,
|
||||||
identified: 'opened the document',
|
identified: msg`${prefix} opened the document`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_TITLE_UPDATED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_TITLE_UPDATED }, () => ({
|
||||||
anonymous: 'Document title updated',
|
anonymous: msg`Document title updated`,
|
||||||
identified: 'updated the document title',
|
identified: msg`${prefix} updated the document title`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_EXTERNAL_ID_UPDATED }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_EXTERNAL_ID_UPDATED }, () => ({
|
||||||
anonymous: 'Document external ID updated',
|
anonymous: msg`Document external ID updated`,
|
||||||
identified: 'updated the document external ID',
|
identified: msg`${prefix} updated the document external ID`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_SENT }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_SENT }, () => ({
|
||||||
anonymous: 'Document sent',
|
anonymous: msg`Document sent`,
|
||||||
identified: 'sent the document',
|
identified: msg`${prefix} sent the document`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_MOVED_TO_TEAM }, () => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_MOVED_TO_TEAM }, () => ({
|
||||||
anonymous: 'Document moved to team',
|
anonymous: msg`Document moved to team`,
|
||||||
identified: 'moved the document to team',
|
identified: msg`${prefix} moved the document to team`,
|
||||||
}))
|
}))
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED }, ({ data }) => {
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED }, ({ data }) => {
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
const userName = prefix || _(msg`Recipient`);
|
||||||
const action = RECIPIENT_ROLES_DESCRIPTION_ENG[data.recipientRole as RecipientRole]?.actioned;
|
|
||||||
|
|
||||||
const value = action ? `${action.toLowerCase()} the document` : 'completed their task';
|
const result = match(data.recipientRole)
|
||||||
|
.with(RecipientRole.SIGNER, () => msg`${userName} signed the document`)
|
||||||
|
.with(RecipientRole.VIEWER, () => msg`${userName} viewed the document`)
|
||||||
|
.with(RecipientRole.APPROVER, () => msg`${userName} approved the document`)
|
||||||
|
.with(RecipientRole.CC, () => msg`${userName} CC'd the document`)
|
||||||
|
.otherwise(() => msg`${userName} completed their task`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
anonymous: `Recipient ${value}`,
|
anonymous: result,
|
||||||
identified: value,
|
identified: result,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT }, ({ data }) => ({
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT }, ({ data }) => ({
|
||||||
anonymous: `Email ${data.isResending ? 'resent' : 'sent'}`,
|
anonymous: data.isResending ? msg`Email resent` : msg`Email sent`,
|
||||||
identified: `${data.isResending ? 'resent' : 'sent'} an email to ${data.recipientEmail}`,
|
identified: data.isResending
|
||||||
|
? msg`${prefix} resent an email to ${data.recipientEmail}`
|
||||||
|
: msg`${prefix} sent an email to ${data.recipientEmail}`,
|
||||||
|
}))
|
||||||
|
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED }, () => ({
|
||||||
|
anonymous: msg`Document completed`,
|
||||||
|
identified: msg`Document completed`,
|
||||||
}))
|
}))
|
||||||
.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();
|
.exhaustive();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
prefix,
|
prefix,
|
||||||
description: prefix ? description.identified : description.anonymous,
|
description: _(prefix ? description.identified : description.anonymous),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user