From 069b47d24054aa46fc97bd757c2d3b895d0972cb Mon Sep 17 00:00:00 2001 From: Bryan Frimin Date: Fri, 20 Feb 2026 12:12:04 +0100 Subject: [PATCH] Add NDA view on console Signed-off-by: Bryan Frimin --- ...iancePageAccessListItemFragment.graphql.ts | 24 +++- .../CompliancePageAccessListQuery.graphql.ts | 22 +++- .../CompliancePageAccessPageQuery.graphql.ts | 22 +++- ...ctronicSignatureSectionFragment.graphql.ts | 105 ++++++++++++++++++ ...pliancePageAccessDialogMutation.graphql.ts | 22 +++- ...sGraphLoadDocumentAccessesQuery.graphql.ts | 88 ++++++++++++++- .../src/hooks/graph/TrustCenterAccessGraph.ts | 3 + .../CompliancePageAccessListItem.tsx | 18 ++- .../ElectronicSignatureSection.tsx | 94 ++++++++++++++++ .../access/_components/EventTypeLabel.tsx | 28 +++++ .../access/_components/NdaSignatureBadge.tsx | 20 ++++ .../TrustCenterAccessEditDialog.tsx | 5 + 12 files changed, 422 insertions(+), 29 deletions(-) create mode 100644 apps/console/src/__generated__/core/ElectronicSignatureSectionFragment.graphql.ts create mode 100644 apps/console/src/pages/organizations/compliance-page/access/_components/ElectronicSignatureSection.tsx create mode 100644 apps/console/src/pages/organizations/compliance-page/access/_components/EventTypeLabel.tsx create mode 100644 apps/console/src/pages/organizations/compliance-page/access/_components/NdaSignatureBadge.tsx diff --git a/apps/console/src/__generated__/core/CompliancePageAccessListItemFragment.graphql.ts b/apps/console/src/__generated__/core/CompliancePageAccessListItemFragment.graphql.ts index 825331f4e..ecdaad488 100644 --- a/apps/console/src/__generated__/core/CompliancePageAccessListItemFragment.graphql.ts +++ b/apps/console/src/__generated__/core/CompliancePageAccessListItemFragment.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<97bc9b075b82bb1543c80843430ced5d>> * @lightSyntaxTransform * @nogrep */ @@ -9,6 +9,7 @@ // @ts-nocheck import { ReaderFragment } from 'relay-runtime'; +export type ElectronicSignatureStatus = "ACCEPTED" | "COMPLETED" | "FAILED" | "PENDING" | "PROCESSING"; export type TrustCenterAccessState = "ACTIVE" | "INACTIVE"; import { FragmentRefs } from "relay-runtime"; export type CompliancePageAccessListItemFragment$data = { @@ -16,9 +17,11 @@ export type CompliancePageAccessListItemFragment$data = { readonly canUpdate: boolean; readonly createdAt: string; readonly email: string; - readonly hasAcceptedNonDisclosureAgreement: boolean; readonly id: string; readonly name: string; + readonly ndaSignature: { + readonly status: ElectronicSignatureStatus; + } | null | undefined; readonly pendingRequestCount: number; readonly state: TrustCenterAccessState; readonly " $fragmentType": "CompliancePageAccessListItemFragment"; @@ -86,8 +89,19 @@ const node: ReaderFragment = { { "alias": null, "args": null, - "kind": "ScalarField", - "name": "hasAcceptedNonDisclosureAgreement", + "concreteType": "ElectronicSignature", + "kind": "LinkedField", + "name": "ndaSignature", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "status", + "storageKey": null + } + ], "storageKey": null }, { @@ -108,6 +122,6 @@ const node: ReaderFragment = { "abstractKey": null }; -(node as any).hash = "2492ed4967d57febe8f1153f75280410"; +(node as any).hash = "9047d3d3f232d43c6f951c74b0395b58"; export default node; diff --git a/apps/console/src/__generated__/core/CompliancePageAccessListQuery.graphql.ts b/apps/console/src/__generated__/core/CompliancePageAccessListQuery.graphql.ts index 1cb02c665..9ab8355d5 100644 --- a/apps/console/src/__generated__/core/CompliancePageAccessListQuery.graphql.ts +++ b/apps/console/src/__generated__/core/CompliancePageAccessListQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<431a10def7d71c15412c347717ca5e18>> + * @generated SignedSource<<42b8a91e3553bb30392c749d440cc0c0>> * @lightSyntaxTransform * @nogrep */ @@ -276,8 +276,20 @@ return { { "alias": null, "args": null, - "kind": "ScalarField", - "name": "hasAcceptedNonDisclosureAgreement", + "concreteType": "ElectronicSignature", + "kind": "LinkedField", + "name": "ndaSignature", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "status", + "storageKey": null + }, + (v8/*: any*/) + ], "storageKey": null }, { @@ -336,12 +348,12 @@ return { ] }, "params": { - "cacheID": "22c44994c224b90e58e0cdf12cc39c46", + "cacheID": "e4ac357eef4246850b334e1f8f1faab2", "id": null, "metadata": {}, "name": "CompliancePageAccessListQuery", "operationKind": "query", - "text": "query CompliancePageAccessListQuery(\n $after: CursorKey = null\n $first: Int = 10\n $order: TrustCenterAccessOrder = {field: CREATED_AT, direction: DESC}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...CompliancePageAccessListFragment_gOVF5\n id\n }\n}\n\nfragment CompliancePageAccessListFragment_gOVF5 on TrustCenter {\n accesses(first: $first, after: $after, orderBy: $order) {\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n cursor\n node {\n id\n ...CompliancePageAccessListItemFragment\n __typename\n }\n }\n }\n id\n}\n\nfragment CompliancePageAccessListItemFragment on TrustCenterAccess {\n id\n name\n email\n createdAt\n state\n activeCount\n pendingRequestCount\n hasAcceptedNonDisclosureAgreement\n canUpdate: permission(action: \"core:trust-center-access:update\")\n}\n" + "text": "query CompliancePageAccessListQuery(\n $after: CursorKey = null\n $first: Int = 10\n $order: TrustCenterAccessOrder = {field: CREATED_AT, direction: DESC}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...CompliancePageAccessListFragment_gOVF5\n id\n }\n}\n\nfragment CompliancePageAccessListFragment_gOVF5 on TrustCenter {\n accesses(first: $first, after: $after, orderBy: $order) {\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n cursor\n node {\n id\n ...CompliancePageAccessListItemFragment\n __typename\n }\n }\n }\n id\n}\n\nfragment CompliancePageAccessListItemFragment on TrustCenterAccess {\n id\n name\n email\n createdAt\n state\n activeCount\n pendingRequestCount\n ndaSignature {\n status\n id\n }\n canUpdate: permission(action: \"core:trust-center-access:update\")\n}\n" } }; })(); diff --git a/apps/console/src/__generated__/core/CompliancePageAccessPageQuery.graphql.ts b/apps/console/src/__generated__/core/CompliancePageAccessPageQuery.graphql.ts index c8df94a70..4f9e0dab4 100644 --- a/apps/console/src/__generated__/core/CompliancePageAccessPageQuery.graphql.ts +++ b/apps/console/src/__generated__/core/CompliancePageAccessPageQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<780d27bc715545a78041c8202835912d>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -285,8 +285,20 @@ return { { "alias": null, "args": null, - "kind": "ScalarField", - "name": "hasAcceptedNonDisclosureAgreement", + "concreteType": "ElectronicSignature", + "kind": "LinkedField", + "name": "ndaSignature", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "status", + "storageKey": null + }, + (v3/*: any*/) + ], "storageKey": null }, { @@ -349,12 +361,12 @@ return { ] }, "params": { - "cacheID": "e8e8a8bf8523698493434cd320860613", + "cacheID": "ad9508484592b38254e9cc66941b926e", "id": null, "metadata": {}, "name": "CompliancePageAccessPageQuery", "operationKind": "query", - "text": "query CompliancePageAccessPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n compliancePage: trustCenter {\n id\n canCreateAccess: permission(action: \"core:trust-center-access:create\")\n ...CompliancePageAccessListFragment\n }\n }\n id\n }\n}\n\nfragment CompliancePageAccessListFragment on TrustCenter {\n accesses(first: 10, orderBy: {field: CREATED_AT, direction: DESC}) {\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n cursor\n node {\n id\n ...CompliancePageAccessListItemFragment\n __typename\n }\n }\n }\n id\n}\n\nfragment CompliancePageAccessListItemFragment on TrustCenterAccess {\n id\n name\n email\n createdAt\n state\n activeCount\n pendingRequestCount\n hasAcceptedNonDisclosureAgreement\n canUpdate: permission(action: \"core:trust-center-access:update\")\n}\n" + "text": "query CompliancePageAccessPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n compliancePage: trustCenter {\n id\n canCreateAccess: permission(action: \"core:trust-center-access:create\")\n ...CompliancePageAccessListFragment\n }\n }\n id\n }\n}\n\nfragment CompliancePageAccessListFragment on TrustCenter {\n accesses(first: 10, orderBy: {field: CREATED_AT, direction: DESC}) {\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n cursor\n node {\n id\n ...CompliancePageAccessListItemFragment\n __typename\n }\n }\n }\n id\n}\n\nfragment CompliancePageAccessListItemFragment on TrustCenterAccess {\n id\n name\n email\n createdAt\n state\n activeCount\n pendingRequestCount\n ndaSignature {\n status\n id\n }\n canUpdate: permission(action: \"core:trust-center-access:update\")\n}\n" } }; })(); diff --git a/apps/console/src/__generated__/core/ElectronicSignatureSectionFragment.graphql.ts b/apps/console/src/__generated__/core/ElectronicSignatureSectionFragment.graphql.ts new file mode 100644 index 000000000..ca282c8af --- /dev/null +++ b/apps/console/src/__generated__/core/ElectronicSignatureSectionFragment.graphql.ts @@ -0,0 +1,105 @@ +/** + * @generated SignedSource<<8ef79d0009e7493acec0b0dd749911a2>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ReaderFragment } from 'relay-runtime'; +export type ElectronicSignatureEventType = "CERTIFICATE_GENERATED" | "CONSENT_GIVEN" | "DOCUMENT_VIEWED" | "FULL_NAME_TYPED" | "PROCESSING_ERROR" | "SEAL_COMPUTED" | "SIGNATURE_ACCEPTED" | "SIGNATURE_COMPLETED" | "TIMESTAMP_REQUESTED"; +export type ElectronicSignatureStatus = "ACCEPTED" | "COMPLETED" | "FAILED" | "PENDING" | "PROCESSING"; +import { FragmentRefs } from "relay-runtime"; +export type ElectronicSignatureSectionFragment$data = { + readonly certificateFileUrl: string | null | undefined; + readonly events: ReadonlyArray<{ + readonly actorEmail: string; + readonly eventType: ElectronicSignatureEventType; + readonly id: string; + readonly occurredAt: string; + }>; + readonly signedAt: string | null | undefined; + readonly status: ElectronicSignatureStatus; + readonly " $fragmentType": "ElectronicSignatureSectionFragment"; +}; +export type ElectronicSignatureSectionFragment$key = { + readonly " $data"?: ElectronicSignatureSectionFragment$data; + readonly " $fragmentSpreads": FragmentRefs<"ElectronicSignatureSectionFragment">; +}; + +const node: ReaderFragment = { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "ElectronicSignatureSectionFragment", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "status", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "signedAt", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "certificateFileUrl", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "ElectronicSignatureEvent", + "kind": "LinkedField", + "name": "events", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "eventType", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "actorEmail", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "occurredAt", + "storageKey": null + } + ], + "storageKey": null + } + ], + "type": "ElectronicSignature", + "abstractKey": null +}; + +(node as any).hash = "70f3c5dd8a387d419c5ebdf752908162"; + +export default node; diff --git a/apps/console/src/__generated__/core/NewCompliancePageAccessDialogMutation.graphql.ts b/apps/console/src/__generated__/core/NewCompliancePageAccessDialogMutation.graphql.ts index 3583aa698..700c8db7c 100644 --- a/apps/console/src/__generated__/core/NewCompliancePageAccessDialogMutation.graphql.ts +++ b/apps/console/src/__generated__/core/NewCompliancePageAccessDialogMutation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<6bb56648c233a0887b8579cb6fa2e9ab>> + * @generated SignedSource<<9b82b09c2b56467a1dfa0fcdf809bc34>> * @lightSyntaxTransform * @nogrep */ @@ -201,8 +201,20 @@ return { { "alias": null, "args": null, - "kind": "ScalarField", - "name": "hasAcceptedNonDisclosureAgreement", + "concreteType": "ElectronicSignature", + "kind": "LinkedField", + "name": "ndaSignature", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "status", + "storageKey": null + }, + (v4/*: any*/) + ], "storageKey": null }, { @@ -246,12 +258,12 @@ return { ] }, "params": { - "cacheID": "22a7b4c8022edd73d37f5a8ebb5fe57a", + "cacheID": "685bbdb5f629501f61631592530f46a7", "id": null, "metadata": {}, "name": "NewCompliancePageAccessDialogMutation", "operationKind": "mutation", - "text": "mutation NewCompliancePageAccessDialogMutation(\n $input: CreateTrustCenterAccessInput!\n) {\n createTrustCenterAccess(input: $input) {\n trustCenterAccessEdge {\n cursor\n node {\n id\n ...CompliancePageAccessListItemFragment\n }\n }\n }\n}\n\nfragment CompliancePageAccessListItemFragment on TrustCenterAccess {\n id\n name\n email\n createdAt\n state\n activeCount\n pendingRequestCount\n hasAcceptedNonDisclosureAgreement\n canUpdate: permission(action: \"core:trust-center-access:update\")\n}\n" + "text": "mutation NewCompliancePageAccessDialogMutation(\n $input: CreateTrustCenterAccessInput!\n) {\n createTrustCenterAccess(input: $input) {\n trustCenterAccessEdge {\n cursor\n node {\n id\n ...CompliancePageAccessListItemFragment\n }\n }\n }\n}\n\nfragment CompliancePageAccessListItemFragment on TrustCenterAccess {\n id\n name\n email\n createdAt\n state\n activeCount\n pendingRequestCount\n ndaSignature {\n status\n id\n }\n canUpdate: permission(action: \"core:trust-center-access:update\")\n}\n" } }; })(); diff --git a/apps/console/src/__generated__/core/TrustCenterAccessGraphLoadDocumentAccessesQuery.graphql.ts b/apps/console/src/__generated__/core/TrustCenterAccessGraphLoadDocumentAccessesQuery.graphql.ts index 9c727f8a9..98a5b0812 100644 --- a/apps/console/src/__generated__/core/TrustCenterAccessGraphLoadDocumentAccessesQuery.graphql.ts +++ b/apps/console/src/__generated__/core/TrustCenterAccessGraphLoadDocumentAccessesQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<72bab693664bbf68879e863c85f980b5>> + * @generated SignedSource<<88767d7e81f9900c5bd01a14ffb14bfa>> * @lightSyntaxTransform * @nogrep */ @@ -9,6 +9,7 @@ // @ts-nocheck import { ConcreteRequest } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; export type DocumentType = "ISMS" | "OTHER" | "POLICY" | "PROCEDURE"; export type TrustCenterDocumentAccessStatus = "GRANTED" | "REJECTED" | "REQUESTED" | "REVOKED"; export type TrustCenterAccessGraphLoadDocumentAccessesQuery$variables = { @@ -45,6 +46,9 @@ export type TrustCenterAccessGraphLoadDocumentAccessesQuery$data = { }>; }; readonly id?: string; + readonly ndaSignature?: { + readonly " $fragmentSpreads": FragmentRefs<"ElectronicSignatureSectionFragment">; + } | null | undefined; }; }; export type TrustCenterAccessGraphLoadDocumentAccessesQuery = { @@ -175,6 +179,22 @@ return { "kind": "InlineFragment", "selections": [ (v2/*: any*/), + { + "alias": null, + "args": null, + "concreteType": "ElectronicSignature", + "kind": "LinkedField", + "name": "ndaSignature", + "plural": false, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "ElectronicSignatureSectionFragment" + } + ], + "storageKey": null + }, { "alias": null, "args": (v3/*: any*/), @@ -285,6 +305,66 @@ return { { "kind": "InlineFragment", "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ElectronicSignature", + "kind": "LinkedField", + "name": "ndaSignature", + "plural": false, + "selections": [ + (v4/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "signedAt", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "certificateFileUrl", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "ElectronicSignatureEvent", + "kind": "LinkedField", + "name": "events", + "plural": true, + "selections": [ + (v2/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "eventType", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "actorEmail", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "occurredAt", + "storageKey": null + } + ], + "storageKey": null + }, + (v2/*: any*/) + ], + "storageKey": null + }, { "alias": null, "args": (v3/*: any*/), @@ -370,16 +450,16 @@ return { ] }, "params": { - "cacheID": "a3c6d83c3fae9bd8ab3e474706423115", + "cacheID": "175c4de41f02ea26f9a4ebc2124d6a51", "id": null, "metadata": {}, "name": "TrustCenterAccessGraphLoadDocumentAccessesQuery", "operationKind": "query", - "text": "query TrustCenterAccessGraphLoadDocumentAccessesQuery(\n $accessId: ID!\n) {\n node(id: $accessId) {\n __typename\n ... on TrustCenterAccess {\n id\n availableDocumentAccesses(first: 100, orderBy: {field: CREATED_AT, direction: DESC}) {\n edges {\n node {\n id\n status\n document {\n id\n title\n documentType\n }\n report {\n id\n filename\n audit {\n id\n framework {\n name\n id\n }\n }\n }\n trustCenterFile {\n id\n name\n category\n }\n }\n }\n }\n }\n id\n }\n}\n" + "text": "query TrustCenterAccessGraphLoadDocumentAccessesQuery(\n $accessId: ID!\n) {\n node(id: $accessId) {\n __typename\n ... on TrustCenterAccess {\n id\n ndaSignature {\n ...ElectronicSignatureSectionFragment\n id\n }\n availableDocumentAccesses(first: 100, orderBy: {field: CREATED_AT, direction: DESC}) {\n edges {\n node {\n id\n status\n document {\n id\n title\n documentType\n }\n report {\n id\n filename\n audit {\n id\n framework {\n name\n id\n }\n }\n }\n trustCenterFile {\n id\n name\n category\n }\n }\n }\n }\n }\n id\n }\n}\n\nfragment ElectronicSignatureSectionFragment on ElectronicSignature {\n status\n signedAt\n certificateFileUrl\n events {\n id\n eventType\n actorEmail\n occurredAt\n }\n}\n" } }; })(); -(node as any).hash = "f2fad3a04a700d1a9b045d1fa09e470c"; +(node as any).hash = "d104626a4915648265550778f1ce6606"; export default node; diff --git a/apps/console/src/hooks/graph/TrustCenterAccessGraph.ts b/apps/console/src/hooks/graph/TrustCenterAccessGraph.ts index f4e4f804f..b3e787c62 100644 --- a/apps/console/src/hooks/graph/TrustCenterAccessGraph.ts +++ b/apps/console/src/hooks/graph/TrustCenterAccessGraph.ts @@ -25,6 +25,9 @@ export const loadTrustCenterAccessDocumentAccessesQuery = graphql` node(id: $accessId) { ... on TrustCenterAccess { id + ndaSignature { + ...ElectronicSignatureSectionFragment + } availableDocumentAccesses( first: 100 orderBy: { field: CREATED_AT, direction: DESC } diff --git a/apps/console/src/pages/organizations/compliance-page/access/_components/CompliancePageAccessListItem.tsx b/apps/console/src/pages/organizations/compliance-page/access/_components/CompliancePageAccessListItem.tsx index ec75d08a2..a4e28990c 100644 --- a/apps/console/src/pages/organizations/compliance-page/access/_components/CompliancePageAccessListItem.tsx +++ b/apps/console/src/pages/organizations/compliance-page/access/_components/CompliancePageAccessListItem.tsx @@ -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: {
- {access.hasAcceptedNonDisclosureAgreement && ( - - )} + {access.ndaSignature + ? ( + + ) + : ( + - + )}
diff --git a/apps/console/src/pages/organizations/compliance-page/access/_components/ElectronicSignatureSection.tsx b/apps/console/src/pages/organizations/compliance-page/access/_components/ElectronicSignatureSection.tsx new file mode 100644 index 000000000..b050cc153 --- /dev/null +++ b/apps/console/src/pages/organizations/compliance-page/access/_components/ElectronicSignatureSection.tsx @@ -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 ( +
+

+ {__("Electronic Signature")} +

+
+
+ {__("Status")} + +
+ {signature.signedAt && ( +
+ {__("Signed at")} + + {formatDatetime(signature.signedAt)} + +
+ )} + {signature.certificateFileUrl && ( +
+ {__("Certificate")} + + {__("Download")} + +
+ )} + {signature.events.length > 0 && ( +
+ + {__("Activity")} + +
+ {signature.events.map(event => ( +
+
+ + + + + {event.actorEmail} + +
+ + {formatDatetime(event.occurredAt)} + +
+ ))} +
+
+ )} +
+
+ ); +} diff --git a/apps/console/src/pages/organizations/compliance-page/access/_components/EventTypeLabel.tsx b/apps/console/src/pages/organizations/compliance-page/access/_components/EventTypeLabel.tsx new file mode 100644 index 000000000..fc7d4caac --- /dev/null +++ b/apps/console/src/pages/organizations/compliance-page/access/_components/EventTypeLabel.tsx @@ -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; + } +} diff --git a/apps/console/src/pages/organizations/compliance-page/access/_components/NdaSignatureBadge.tsx b/apps/console/src/pages/organizations/compliance-page/access/_components/NdaSignatureBadge.tsx new file mode 100644 index 000000000..f44b535a6 --- /dev/null +++ b/apps/console/src/pages/organizations/compliance-page/access/_components/NdaSignatureBadge.tsx @@ -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 {__("Signed")}; + case "ACCEPTED": + case "PROCESSING": + return {__("Processing")}; + case "PENDING": + return {__("Pending")}; + case "FAILED": + return {__("Failed")}; + } +} diff --git a/apps/console/src/pages/organizations/trustCenter/TrustCenterAccessTab/TrustCenterAccessEditDialog.tsx b/apps/console/src/pages/organizations/trustCenter/TrustCenterAccessTab/TrustCenterAccessEditDialog.tsx index 1c2f85766..611647d0a 100644 --- a/apps/console/src/pages/organizations/trustCenter/TrustCenterAccessTab/TrustCenterAccessEditDialog.tsx +++ b/apps/console/src/pages/organizations/trustCenter/TrustCenterAccessTab/TrustCenterAccessEditDialog.tsx @@ -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( + {data.node.ndaSignature && ( + + )} +