Add NDA view on console
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { formatDate } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { ActionDropdown, DropdownItem, IconArchive, IconCheckmark1, IconPencil, IconRotateCw, Td, Tr } from "@probo/ui";
|
||||
import { ActionDropdown, DropdownItem, IconArchive, IconPencil, IconRotateCw, Td, Tr } from "@probo/ui";
|
||||
import { useCallback, useState } from "react";
|
||||
import { useFragment } from "react-relay";
|
||||
import { graphql } from "relay-runtime";
|
||||
@@ -11,6 +11,8 @@ import { updateTrustCenterAccessMutation } from "#/hooks/graph/TrustCenterAccess
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { TrustCenterAccessEditDialog } from "#/pages/organizations/trustCenter/TrustCenterAccessTab/TrustCenterAccessEditDialog";
|
||||
|
||||
import { NdaSignatureBadge } from "./NdaSignatureBadge";
|
||||
|
||||
const fragment = graphql`
|
||||
fragment CompliancePageAccessListItemFragment on TrustCenterAccess {
|
||||
id
|
||||
@@ -20,7 +22,9 @@ const fragment = graphql`
|
||||
state
|
||||
activeCount
|
||||
pendingRequestCount
|
||||
hasAcceptedNonDisclosureAgreement
|
||||
ndaSignature {
|
||||
status
|
||||
}
|
||||
canUpdate: permission(action: "core:trust-center-access:update")
|
||||
}
|
||||
`;
|
||||
@@ -78,9 +82,13 @@ export function CompliancePageAccessListItem(props: {
|
||||
</Td>
|
||||
<Td>
|
||||
<div className="flex justify-center">
|
||||
{access.hasAcceptedNonDisclosureAgreement && (
|
||||
<IconCheckmark1 size={16} className="text-txt-success" />
|
||||
)}
|
||||
{access.ndaSignature
|
||||
? (
|
||||
<NdaSignatureBadge status={access.ndaSignature.status} />
|
||||
)
|
||||
: (
|
||||
<span className="text-txt-tertiary">-</span>
|
||||
)}
|
||||
</div>
|
||||
</Td>
|
||||
<Td noLink width={160} className="text-end">
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import { formatDatetime } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { useFragment } from "react-relay";
|
||||
import { graphql } from "relay-runtime";
|
||||
|
||||
import type { ElectronicSignatureSectionFragment$key } from "#/__generated__/core/ElectronicSignatureSectionFragment.graphql";
|
||||
|
||||
import { EventTypeLabel } from "./EventTypeLabel";
|
||||
import { NdaSignatureBadge } from "./NdaSignatureBadge";
|
||||
|
||||
const fragment = graphql`
|
||||
fragment ElectronicSignatureSectionFragment on ElectronicSignature {
|
||||
status
|
||||
signedAt
|
||||
certificateFileUrl
|
||||
events {
|
||||
id
|
||||
eventType
|
||||
actorEmail
|
||||
occurredAt
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function ElectronicSignatureSection({
|
||||
fragmentRef,
|
||||
}: {
|
||||
fragmentRef: ElectronicSignatureSectionFragment$key;
|
||||
}) {
|
||||
const { __ } = useTranslate();
|
||||
const signature = useFragment(fragment, fragmentRef);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3 className="text-sm font-medium text-txt-primary mb-3">
|
||||
{__("Electronic Signature")}
|
||||
</h3>
|
||||
<div className="rounded-lg border border-border-solid bg-bg-secondary p-4 space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-txt-secondary">{__("Status")}</span>
|
||||
<NdaSignatureBadge status={signature.status} />
|
||||
</div>
|
||||
{signature.signedAt && (
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-txt-secondary">{__("Signed at")}</span>
|
||||
<span className="text-sm text-txt-primary">
|
||||
{formatDatetime(signature.signedAt)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{signature.certificateFileUrl && (
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-txt-secondary">{__("Certificate")}</span>
|
||||
<a
|
||||
href={signature.certificateFileUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-txt-accent hover:underline"
|
||||
>
|
||||
{__("Download")}
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
{signature.events.length > 0 && (
|
||||
<div className="pt-2 border-t border-border-solid">
|
||||
<span className="text-xs font-medium text-txt-secondary uppercase tracking-wider">
|
||||
{__("Activity")}
|
||||
</span>
|
||||
<div className="mt-2 space-y-2">
|
||||
{signature.events.map(event => (
|
||||
<div
|
||||
key={event.id}
|
||||
className="flex items-start justify-between text-xs"
|
||||
>
|
||||
<div>
|
||||
<span className="text-txt-primary">
|
||||
<EventTypeLabel eventType={event.eventType} />
|
||||
</span>
|
||||
<span className="text-txt-tertiary ml-1">
|
||||
{event.actorEmail}
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-txt-tertiary shrink-0 ml-2">
|
||||
{formatDatetime(event.occurredAt)}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
|
||||
export function EventTypeLabel({ eventType }: { eventType: string }) {
|
||||
const { __ } = useTranslate();
|
||||
|
||||
switch (eventType) {
|
||||
case "DOCUMENT_VIEWED":
|
||||
return __("Document viewed");
|
||||
case "CONSENT_GIVEN":
|
||||
return __("Consent given");
|
||||
case "FULL_NAME_TYPED":
|
||||
return __("Full name typed");
|
||||
case "SIGNATURE_ACCEPTED":
|
||||
return __("Signature accepted");
|
||||
case "SIGNATURE_COMPLETED":
|
||||
return __("Signature completed");
|
||||
case "SEAL_COMPUTED":
|
||||
return __("Seal computed");
|
||||
case "TIMESTAMP_REQUESTED":
|
||||
return __("Timestamp requested");
|
||||
case "CERTIFICATE_GENERATED":
|
||||
return __("Certificate generated");
|
||||
case "PROCESSING_ERROR":
|
||||
return __("Processing error");
|
||||
default:
|
||||
return eventType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { Badge } from "@probo/ui";
|
||||
|
||||
type ElectronicSignatureStatus = "PENDING" | "ACCEPTED" | "PROCESSING" | "COMPLETED" | "FAILED";
|
||||
|
||||
export function NdaSignatureBadge({ status }: { status: ElectronicSignatureStatus }) {
|
||||
const { __ } = useTranslate();
|
||||
|
||||
switch (status) {
|
||||
case "COMPLETED":
|
||||
return <Badge variant="success">{__("Signed")}</Badge>;
|
||||
case "ACCEPTED":
|
||||
case "PROCESSING":
|
||||
return <Badge variant="info">{__("Processing")}</Badge>;
|
||||
case "PENDING":
|
||||
return <Badge variant="warning">{__("Pending")}</Badge>;
|
||||
case "FAILED":
|
||||
return <Badge variant="danger">{__("Failed")}</Badge>;
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
|
||||
import { ElectronicSignatureSection } from "#/pages/organizations/compliance-page/access/_components/ElectronicSignatureSection";
|
||||
import { TrustCenterDocumentAccessList } from "./TrustCenterDocumentAccessList";
|
||||
|
||||
interface TrustCenterAccessEditDialogProps {
|
||||
@@ -223,6 +224,10 @@ export function TrustCenterAccessEditForm(
|
||||
|
||||
</div>
|
||||
|
||||
{data.node.ndaSignature && (
|
||||
<ElectronicSignatureSection fragmentRef={data.node.ndaSignature} />
|
||||
)}
|
||||
|
||||
<TrustCenterDocumentAccessList
|
||||
documentAccesses={documentAccesses}
|
||||
initialStatusByID={initialStatusByID}
|
||||
|
||||
Reference in New Issue
Block a user