From f114f3bc4ae592fe051862a12500de8dd3cf2ddd Mon Sep 17 00:00:00 2001 From: Jonathan Date: Tue, 8 Jul 2025 14:59:26 +0200 Subject: [PATCH] Add version selector on document Fix #166 Signed-off-by: Sacha Al Himdani --- .../DocumentGraphNodeQuery.graphql.ts | 39 +-- .../documents/DocumentDetailPage.tsx | 316 ++++++++++++++---- ...umentDetailPageDocumentFragment.graphql.ts | 71 ++-- .../dialogs/DocumentVersionHistoryDialog.tsx | 167 --------- ...ocumentSignaturesDialog_version.graphql.ts | 67 ---- ...nHistoryDialogExportPDFMutation.graphql.ts | 95 ------ ...entVersionHistoryDialogFragment.graphql.ts | 112 ------- .../documents/tabs/DocumentDescriptionTab.tsx | 6 +- .../DocumentSignaturesTab.tsx} | 113 +------ ...resTab_cancelSignatureMutation.graphql.ts} | 24 +- ...esTab_requestSignatureMutation.graphql.ts} | 28 +- ...ocumentSignaturesTab_signature.graphql.ts} | 16 +- apps/console/src/routes/documentsRoutes.ts | 74 ++-- packages/ui/src/Atoms/Dropdown/Dropdown.tsx | 6 +- 14 files changed, 412 insertions(+), 722 deletions(-) delete mode 100644 apps/console/src/pages/organizations/documents/dialogs/DocumentVersionHistoryDialog.tsx delete mode 100644 apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_version.graphql.ts delete mode 100644 apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentVersionHistoryDialogExportPDFMutation.graphql.ts delete mode 100644 apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentVersionHistoryDialogFragment.graphql.ts rename apps/console/src/pages/organizations/documents/{dialogs/DocumentSignaturesDialog.tsx => tabs/DocumentSignaturesTab.tsx} (63%) rename apps/console/src/pages/organizations/documents/{dialogs/__generated__/DocumentSignaturesDialog_cancelSignatureMutation.graphql.ts => tabs/__generated__/DocumentSignaturesTab_cancelSignatureMutation.graphql.ts} (72%) rename apps/console/src/pages/organizations/documents/{dialogs/__generated__/DocumentSignaturesDialog_requestSignatureMutation.graphql.ts => tabs/__generated__/DocumentSignaturesTab_requestSignatureMutation.graphql.ts} (82%) rename apps/console/src/pages/organizations/documents/{dialogs/__generated__/DocumentSignaturesDialog_signature.graphql.ts => tabs/__generated__/DocumentSignaturesTab_signature.graphql.ts} (81%) diff --git a/apps/console/src/hooks/graph/__generated__/DocumentGraphNodeQuery.graphql.ts b/apps/console/src/hooks/graph/__generated__/DocumentGraphNodeQuery.graphql.ts index 7818ed557..2b0265199 100644 --- a/apps/console/src/hooks/graph/__generated__/DocumentGraphNodeQuery.graphql.ts +++ b/apps/console/src/hooks/graph/__generated__/DocumentGraphNodeQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<5c3e7dba407e37cfc0203138d5db8318>> + * @generated SignedSource<<85c6bcb5e086b05009ccfaf8ac21a23e>> * @lightSyntaxTransform * @nogrep */ @@ -387,6 +387,19 @@ return { "name": "updatedAt", "storageKey": null }, + { + "alias": null, + "args": null, + "concreteType": "People", + "kind": "LinkedField", + "name": "publishedBy", + "plural": false, + "selections": [ + (v4/*: any*/), + (v3/*: any*/) + ], + "storageKey": null + }, { "alias": null, "args": (v11/*: any*/), @@ -475,26 +488,6 @@ return { "kind": "LinkedHandle", "name": "signatures" }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "changelog", - "storageKey": null - }, - { - "alias": null, - "args": null, - "concreteType": "People", - "kind": "LinkedField", - "name": "publishedBy", - "plural": false, - "selections": [ - (v4/*: any*/), - (v3/*: any*/) - ], - "storageKey": null - }, (v2/*: any*/) ], "storageKey": null @@ -527,12 +520,12 @@ return { ] }, "params": { - "cacheID": "ad8c2b55a545807ab1fe72c21ed8f9c1", + "cacheID": "fbfe2cc393b8fc5349a92f3443f12e0e", "id": null, "metadata": {}, "name": "DocumentGraphNodeQuery", "operationKind": "query", - "text": "query DocumentGraphNodeQuery(\n $documentId: ID!\n) {\n node(id: $documentId) {\n __typename\n ... on Document {\n ...DocumentDetailPageDocumentFragment\n }\n id\n }\n}\n\nfragment DocumentControlsTabFragment on Document {\n id\n controls(first: 20) {\n edges {\n node {\n id\n ...LinkedControlsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment DocumentDetailPageDocumentFragment on Document {\n id\n title\n documentType\n owner {\n id\n fullName\n }\n ...DocumentControlsTabFragment\n controlsInfo: controls(first: 0) {\n totalCount\n }\n versions(first: 20) {\n edges {\n node {\n id\n content\n status\n publishedAt\n version\n updatedAt\n signatures(first: 100) {\n edges {\n node {\n id\n state\n signedBy {\n id\n }\n ...DocumentSignaturesDialog_signature\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n ...DocumentVersionHistoryDialogFragment\n ...DocumentSignaturesDialog_version\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment DocumentSignaturesDialog_signature on DocumentVersionSignature {\n id\n state\n signedAt\n requestedAt\n signedBy {\n fullName\n primaryEmailAddress\n id\n }\n}\n\nfragment DocumentSignaturesDialog_version on DocumentVersion {\n version\n status\n publishedAt\n updatedAt\n}\n\nfragment DocumentVersionHistoryDialogFragment on DocumentVersion {\n id\n version\n status\n content\n changelog\n publishedAt\n updatedAt\n publishedBy {\n fullName\n id\n }\n}\n\nfragment LinkedControlsCardFragment on Control {\n id\n name\n sectionTitle\n framework {\n id\n name\n }\n}\n" + "text": "query DocumentGraphNodeQuery(\n $documentId: ID!\n) {\n node(id: $documentId) {\n __typename\n ... on Document {\n ...DocumentDetailPageDocumentFragment\n }\n id\n }\n}\n\nfragment DocumentControlsTabFragment on Document {\n id\n controls(first: 20) {\n edges {\n node {\n id\n ...LinkedControlsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment DocumentDetailPageDocumentFragment on Document {\n id\n title\n documentType\n owner {\n id\n fullName\n }\n ...DocumentControlsTabFragment\n controlsInfo: controls(first: 0) {\n totalCount\n }\n versions(first: 20) {\n edges {\n node {\n id\n content\n status\n publishedAt\n version\n updatedAt\n publishedBy {\n fullName\n id\n }\n signatures(first: 100) {\n edges {\n node {\n id\n state\n signedBy {\n id\n }\n ...DocumentSignaturesTab_signature\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment DocumentSignaturesTab_signature on DocumentVersionSignature {\n id\n state\n signedAt\n requestedAt\n signedBy {\n fullName\n primaryEmailAddress\n id\n }\n}\n\nfragment LinkedControlsCardFragment on Control {\n id\n name\n sectionTitle\n framework {\n id\n name\n }\n}\n" } }; })(); diff --git a/apps/console/src/pages/organizations/documents/DocumentDetailPage.tsx b/apps/console/src/pages/organizations/documents/DocumentDetailPage.tsx index bf794e70b..6eee938ce 100644 --- a/apps/console/src/pages/organizations/documents/DocumentDetailPage.tsx +++ b/apps/console/src/pages/organizations/documents/DocumentDetailPage.tsx @@ -1,5 +1,4 @@ import type { PreloadedQuery } from "react-relay"; -import type { DocumentGraphNodeQuery } from "/hooks/graph/__generated__/DocumentGraphNodeQuery.graphql"; import { ConnectionHandler, graphql, @@ -7,42 +6,53 @@ import { useFragment, usePreloadedQuery, } from "react-relay"; +import type { DocumentGraphNodeQuery } from "/hooks/graph/__generated__/DocumentGraphNodeQuery.graphql"; import { - DocumentsConnectionKey, documentNodeQuery, + DocumentsConnectionKey, useDeleteDocumentMutation, } from "/hooks/graph/DocumentGraph"; import { usePageTitle } from "@probo/hooks"; -import type { DocumentDetailPageDocumentFragment$key } from "./__generated__/DocumentDetailPageDocumentFragment.graphql"; +import type { + DocumentDetailPageDocumentFragment$data, + DocumentDetailPageDocumentFragment$key, +} from "./__generated__/DocumentDetailPageDocumentFragment.graphql"; import { useTranslate } from "@probo/i18n"; import { - PageHeader, - Breadcrumb, - IconCheckmark1, - PropertyRow, - Drawer, - Badge, - Avatar, - DropdownItem, ActionDropdown, - IconTrashCan, - IconPencil, + Avatar, + Badge, + Breadcrumb, + Button, + Drawer, + Dropdown, + DropdownItem, + IconCheckmark1, + IconChevronDown, IconClock, - IconSignature, - useConfirm, - Tabs, - TabLink, + IconPencil, + IconTrashCan, + PageHeader, + PropertyRow, TabBadge, + TabLink, + Tabs, + useConfirm, } from "@probo/ui"; import { useOrganizationId } from "/hooks/useOrganizationId"; -import { Button } from "@probo/ui"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; -import { sprintf, getDocumentTypeLabel } from "@probo/helpers"; -import { Outlet, useNavigate } from "react-router"; +import { getDocumentTypeLabel, sprintf } from "@probo/helpers"; +import { + Link, + Outlet, + useLocation, + useNavigate, + useParams, +} from "react-router"; import UpdateVersionDialog from "./dialogs/UpdateVersionDialog"; import { useRef } from "react"; -import { DocumentVersionHistoryDialog } from "./dialogs/DocumentVersionHistoryDialog"; -import { DocumentSignaturesDialog } from "./dialogs/DocumentSignaturesDialog"; +import type { NodeOf } from "/types.ts"; +import clsx from "clsx"; type Props = { queryRef: PreloadedQuery; @@ -71,6 +81,9 @@ const documentFragment = graphql` publishedAt version updatedAt + publishedBy { + fullName + } signatures(first: 100) @connection(key: "DocumentDetailPage_signatures") { __id @@ -81,12 +94,10 @@ const documentFragment = graphql` signedBy { id } - ...DocumentSignaturesDialog_signature + ...DocumentSignaturesTab_signature } } } - ...DocumentVersionHistoryDialogFragment - ...DocumentSignaturesDialog_version } } } @@ -106,22 +117,28 @@ const publishDocumentVersionMutation = graphql` `; export default function DocumentDetailPage(props: Props) { + const { versionId } = useParams<{ versionId?: string }>(); const node = usePreloadedQuery(documentNodeQuery, props.queryRef).node; const document = useFragment( documentFragment, - node as DocumentDetailPageDocumentFragment$key + node as DocumentDetailPageDocumentFragment$key, ); const { __, dateFormat } = useTranslate(); const organizationId = useOrganizationId(); const navigate = useNavigate(); - const lastVersion = document.versions.edges[0].node; - const isDraft = lastVersion.status === "DRAFT"; + const versions = document.versions.edges.map((edge) => edge.node); + const currentVersion = + document.versions.edges.find((v) => v.node.id === versionId)?.node ?? + document.versions.edges[0].node; + const signatures = currentVersion.signatures.edges.map((s) => s.node); + const signedSignatures = signatures.filter((s) => s.state === "SIGNED"); + const isDraft = currentVersion.status === "DRAFT"; const [publishDocumentVersion, isPublishing] = useMutationWithToasts( publishDocumentVersionMutation, { successMessage: __("Document published successfully."), errorMessage: __("Failed to publish document. Please try again."), - } + }, ); const [deleteDocument, isDeleting] = useDeleteDocumentMutation(); const versionConnectionId = document.versions.__id; @@ -139,7 +156,7 @@ export default function DocumentDetailPage(props: Props) { props.queryRef.environment, documentNodeQuery, props.queryRef.variables, - { fetchPolicy: "network-only" } + { fetchPolicy: "network-only" }, ); }, }); @@ -153,7 +170,7 @@ export default function DocumentDetailPage(props: Props) { new Promise((resolve) => { const connectionId = ConnectionHandler.getConnectionID( organizationId, - DocumentsConnectionKey + DocumentsConnectionKey, ); deleteDocument({ variables: { @@ -169,16 +186,19 @@ export default function DocumentDetailPage(props: Props) { { message: sprintf( __( - 'This will permanently delete the document "%s". This action cannot be undone.' + 'This will permanently delete the document "%s". This action cannot be undone.', ), - document.title + document.title, ), - } + }, ); }; const updateDialogRef = useRef<{ open: () => void }>(null); const controlsCount = document.controlsInfo.totalCount; + const urlPrefix = versionId + ? `/organizations/${organizationId}/documents/${document.id}/versions/${versionId}` + : `/organizations/${organizationId}/documents/${document.id}`; return ( <> @@ -210,16 +230,155 @@ export default function DocumentDetailPage(props: Props) { {__("Publish")} )} - - - - - - + + {__("Version history")} + + + } + > + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + {versions.map((version) => ( + + {}} + /> + + ))} + - - {__("Description")} - - + {__("Description")} + {__("Controls")} {controlsCount} + + {__("Signatures")} + + {signedSignatures.length}/{signatures.length} + + - +
@@ -283,18 +442,18 @@ export default function DocumentDetailPage(props: Props) {
- {lastVersion.version} + {currentVersion.version}
- {dateFormat(lastVersion.updatedAt)} + {dateFormat(currentVersion.updatedAt)}
- {lastVersion.publishedAt && ( + {currentVersion.publishedAt && (
- {dateFormat(lastVersion.publishedAt)} + {dateFormat(currentVersion.publishedAt)}
)} @@ -302,3 +461,46 @@ export default function DocumentDetailPage(props: Props) { ); } + +type Version = NodeOf; + +function VersionItem({ + document, + version, + active, + onSelect, + ...props +}: { + document: DocumentDetailPageDocumentFragment$data; + version: Version; + active?: boolean; + onSelect: (v: Version) => void; +}) { + const { dateTimeFormat } = useTranslate(); + const organizationId = useOrganizationId(); + const suffix = useLocation().pathname.split("/").at(-1); + return ( + onSelect(version)} + className={clsx( + "flex items-center gap-2 py-2 px-[10px] w-full hover:bg-tertiary-hover cursor-pointer rounded", + active && "bg-tertiary-pressed", + )} + {...props} + > + +
+
+ {version.publishedBy?.fullName ?? document.owner.fullName} +
+
+ {dateTimeFormat(version.publishedAt ?? version.updatedAt)} +
+
+ + ); +} diff --git a/apps/console/src/pages/organizations/documents/__generated__/DocumentDetailPageDocumentFragment.graphql.ts b/apps/console/src/pages/organizations/documents/__generated__/DocumentDetailPageDocumentFragment.graphql.ts index d617e1267..09d65e9e5 100644 --- a/apps/console/src/pages/organizations/documents/__generated__/DocumentDetailPageDocumentFragment.graphql.ts +++ b/apps/console/src/pages/organizations/documents/__generated__/DocumentDetailPageDocumentFragment.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<4318aaecefe001fe6f42e6db26c421b4>> + * @generated SignedSource<<8db0c7dcd7ff31c01ec5facd5a3b598a>> * @lightSyntaxTransform * @nogrep */ @@ -31,6 +31,9 @@ export type DocumentDetailPageDocumentFragment$data = { readonly content: string; readonly id: string; readonly publishedAt: any | null | undefined; + readonly publishedBy: { + readonly fullName: string; + } | null | undefined; readonly signatures: { readonly __id: string; readonly edges: ReadonlyArray<{ @@ -40,14 +43,13 @@ export type DocumentDetailPageDocumentFragment$data = { readonly id: string; }; readonly state: DocumentVersionSignatureState; - readonly " $fragmentSpreads": FragmentRefs<"DocumentSignaturesDialog_signature">; + readonly " $fragmentSpreads": FragmentRefs<"DocumentSignaturesTab_signature">; }; }>; }; readonly status: DocumentStatus; readonly updatedAt: any; readonly version: number; - readonly " $fragmentSpreads": FragmentRefs<"DocumentSignaturesDialog_version" | "DocumentVersionHistoryDialogFragment">; }; }>; }; @@ -71,17 +73,24 @@ v1 = { "alias": null, "args": null, "kind": "ScalarField", - "name": "__typename", + "name": "fullName", "storageKey": null }, v2 = { "alias": null, "args": null, "kind": "ScalarField", - "name": "cursor", + "name": "__typename", "storageKey": null }, v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "cursor", + "storageKey": null +}, +v4 = { "alias": null, "args": null, "concreteType": "PageInfo", @@ -106,7 +115,7 @@ v3 = { ], "storageKey": null }, -v4 = { +v5 = { "kind": "ClientExtension", "selections": [ { @@ -165,13 +174,7 @@ return { "plural": false, "selections": [ (v0/*: any*/), - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "fullName", - "storageKey": null - } + (v1/*: any*/) ], "storageKey": null }, @@ -264,6 +267,18 @@ return { "name": "updatedAt", "storageKey": null }, + { + "alias": null, + "args": null, + "concreteType": "People", + "kind": "LinkedField", + "name": "publishedBy", + "plural": false, + "selections": [ + (v1/*: any*/) + ], + "storageKey": null + }, { "alias": "signatures", "args": null, @@ -311,41 +326,31 @@ return { { "args": null, "kind": "FragmentSpread", - "name": "DocumentSignaturesDialog_signature" + "name": "DocumentSignaturesTab_signature" }, - (v1/*: any*/) + (v2/*: any*/) ], "storageKey": null }, - (v2/*: any*/) + (v3/*: any*/) ], "storageKey": null }, - (v3/*: any*/), - (v4/*: any*/) + (v4/*: any*/), + (v5/*: any*/) ], "storageKey": null }, - { - "args": null, - "kind": "FragmentSpread", - "name": "DocumentVersionHistoryDialogFragment" - }, - { - "args": null, - "kind": "FragmentSpread", - "name": "DocumentSignaturesDialog_version" - }, - (v1/*: any*/) + (v2/*: any*/) ], "storageKey": null }, - (v2/*: any*/) + (v3/*: any*/) ], "storageKey": null }, - (v3/*: any*/), - (v4/*: any*/) + (v4/*: any*/), + (v5/*: any*/) ], "storageKey": null } @@ -355,6 +360,6 @@ return { }; })(); -(node as any).hash = "da1a4055d701fa9c3e0e0e50df24860f"; +(node as any).hash = "1523ddad229ae2d6bf94d30de5579ae6"; export default node; diff --git a/apps/console/src/pages/organizations/documents/dialogs/DocumentVersionHistoryDialog.tsx b/apps/console/src/pages/organizations/documents/dialogs/DocumentVersionHistoryDialog.tsx deleted file mode 100644 index 29fc7bdcf..000000000 --- a/apps/console/src/pages/organizations/documents/dialogs/DocumentVersionHistoryDialog.tsx +++ /dev/null @@ -1,167 +0,0 @@ -import { - Avatar, - Button, - Dialog, - DialogContent, - DialogFooter, - DialogTitle, - IconArrowInbox, - Markdown, -} from "@probo/ui"; -import { graphql } from "relay-runtime"; -import { useTranslate } from "@probo/i18n"; -import { useState, type ReactNode } from "react"; -import { useFragment } from "react-relay"; -import type { DocumentVersionHistoryDialogFragment$key } from "./__generated__/DocumentVersionHistoryDialogFragment.graphql"; -import type { DocumentVersionHistoryDialogExportPDFMutation } from "./__generated__/DocumentVersionHistoryDialogExportPDFMutation.graphql"; -import clsx from "clsx"; -import type { NodeOf } from "/types"; -import type { DocumentDetailPageDocumentFragment$data } from "../__generated__/DocumentDetailPageDocumentFragment.graphql"; -import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; - -const historyFragment = graphql` - fragment DocumentVersionHistoryDialogFragment on DocumentVersion { - id - version - status - content - changelog - publishedAt - updatedAt - publishedBy { - fullName - } - } -`; - -const exportPDFMutation = graphql` - mutation DocumentVersionHistoryDialogExportPDFMutation( - $documentVersionId: ID! - ) { - exportDocumentVersionPDF(input: { documentVersionId: $documentVersionId }) { - data - } - } -`; - -type Props = { - document: DocumentDetailPageDocumentFragment$data; - children?: ReactNode; -}; - -type Version = NodeOf; - -export function DocumentVersionHistoryDialog(props: Props) { - const { __ } = useTranslate(); - const versions = props.document.versions.edges.map((edge) => edge.node); - const [selectedVersion, setSelectedVersion] = useState(versions[0]); - const [exportPDF, isExporting] = - useMutationWithToasts( - exportPDFMutation, - { - errorMessage: __("Failed to export PDF"), - successMessage: __("PDF exported successfully"), - } - ); - - const handleDownloadPDF = () => { - exportPDF({ - variables: { documentVersionId: selectedVersion.id }, - onCompleted: (data) => { - if (data.exportDocumentVersionPDF.data) { - // Handle data URI format (data:application/pdf;base64,...) - const dataUri = data.exportDocumentVersionPDF.data; - - // Extract base64 part from data URI - const base64Data = dataUri.split(",")[1]; - - // Convert base64 to blob and download - const binaryString = atob(base64Data); - const bytes = new Uint8Array(binaryString.length); - for (let i = 0; i < binaryString.length; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - const blob = new Blob([bytes], { type: "application/pdf" }); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = `${props.document.title}-v${selectedVersion.version}.pdf`; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - URL.revokeObjectURL(url); - } - }, - }); - }; - - return ( - - - -
-
- -
- -
-
- -
- ); -} - -function VersionItem(props: { - document: DocumentDetailPageDocumentFragment$data; - version: Version; - active?: boolean; - onSelect: (v: Version) => void; -}) { - const version = useFragment( - historyFragment, - props.version - ); - const { dateTimeFormat } = useTranslate(); - return ( - - ); -} diff --git a/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_version.graphql.ts b/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_version.graphql.ts deleted file mode 100644 index cec587e99..000000000 --- a/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_version.graphql.ts +++ /dev/null @@ -1,67 +0,0 @@ -/** - * @generated SignedSource<> - * @lightSyntaxTransform - * @nogrep - */ - -/* tslint:disable */ -/* eslint-disable */ -// @ts-nocheck - -import { ReaderFragment } from 'relay-runtime'; -export type DocumentStatus = "DRAFT" | "PUBLISHED"; -import { FragmentRefs } from "relay-runtime"; -export type DocumentSignaturesDialog_version$data = { - readonly publishedAt: any | null | undefined; - readonly status: DocumentStatus; - readonly updatedAt: any; - readonly version: number; - readonly " $fragmentType": "DocumentSignaturesDialog_version"; -}; -export type DocumentSignaturesDialog_version$key = { - readonly " $data"?: DocumentSignaturesDialog_version$data; - readonly " $fragmentSpreads": FragmentRefs<"DocumentSignaturesDialog_version">; -}; - -const node: ReaderFragment = { - "argumentDefinitions": [], - "kind": "Fragment", - "metadata": null, - "name": "DocumentSignaturesDialog_version", - "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "version", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "status", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "publishedAt", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "updatedAt", - "storageKey": null - } - ], - "type": "DocumentVersion", - "abstractKey": null -}; - -(node as any).hash = "564746ce584a834e25a5a341155d6b2c"; - -export default node; diff --git a/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentVersionHistoryDialogExportPDFMutation.graphql.ts b/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentVersionHistoryDialogExportPDFMutation.graphql.ts deleted file mode 100644 index 7e25eb1b2..000000000 --- a/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentVersionHistoryDialogExportPDFMutation.graphql.ts +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @generated SignedSource<<06126b60bc37d8fbbb9a475af6d5d29d>> - * @lightSyntaxTransform - * @nogrep - */ - -/* tslint:disable */ -/* eslint-disable */ -// @ts-nocheck - -import { ConcreteRequest } from 'relay-runtime'; -export type DocumentVersionHistoryDialogExportPDFMutation$variables = { - documentVersionId: string; -}; -export type DocumentVersionHistoryDialogExportPDFMutation$data = { - readonly exportDocumentVersionPDF: { - readonly data: string; - }; -}; -export type DocumentVersionHistoryDialogExportPDFMutation = { - response: DocumentVersionHistoryDialogExportPDFMutation$data; - variables: DocumentVersionHistoryDialogExportPDFMutation$variables; -}; - -const node: ConcreteRequest = (function(){ -var v0 = [ - { - "defaultValue": null, - "kind": "LocalArgument", - "name": "documentVersionId" - } -], -v1 = [ - { - "alias": null, - "args": [ - { - "fields": [ - { - "kind": "Variable", - "name": "documentVersionId", - "variableName": "documentVersionId" - } - ], - "kind": "ObjectValue", - "name": "input" - } - ], - "concreteType": "ExportDocumentVersionPDFPayload", - "kind": "LinkedField", - "name": "exportDocumentVersionPDF", - "plural": false, - "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "data", - "storageKey": null - } - ], - "storageKey": null - } -]; -return { - "fragment": { - "argumentDefinitions": (v0/*: any*/), - "kind": "Fragment", - "metadata": null, - "name": "DocumentVersionHistoryDialogExportPDFMutation", - "selections": (v1/*: any*/), - "type": "Mutation", - "abstractKey": null - }, - "kind": "Request", - "operation": { - "argumentDefinitions": (v0/*: any*/), - "kind": "Operation", - "name": "DocumentVersionHistoryDialogExportPDFMutation", - "selections": (v1/*: any*/) - }, - "params": { - "cacheID": "45204e42c1018e00dcceaae84eb9a5f7", - "id": null, - "metadata": {}, - "name": "DocumentVersionHistoryDialogExportPDFMutation", - "operationKind": "mutation", - "text": "mutation DocumentVersionHistoryDialogExportPDFMutation(\n $documentVersionId: ID!\n) {\n exportDocumentVersionPDF(input: {documentVersionId: $documentVersionId}) {\n data\n }\n}\n" - } -}; -})(); - -(node as any).hash = "587bcc8bb6cf72e64a5eca18769ac432"; - -export default node; diff --git a/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentVersionHistoryDialogFragment.graphql.ts b/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentVersionHistoryDialogFragment.graphql.ts deleted file mode 100644 index ed58fcce4..000000000 --- a/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentVersionHistoryDialogFragment.graphql.ts +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @generated SignedSource<> - * @lightSyntaxTransform - * @nogrep - */ - -/* tslint:disable */ -/* eslint-disable */ -// @ts-nocheck - -import { ReaderFragment } from 'relay-runtime'; -export type DocumentStatus = "DRAFT" | "PUBLISHED"; -import { FragmentRefs } from "relay-runtime"; -export type DocumentVersionHistoryDialogFragment$data = { - readonly changelog: string; - readonly content: string; - readonly id: string; - readonly publishedAt: any | null | undefined; - readonly publishedBy: { - readonly fullName: string; - } | null | undefined; - readonly status: DocumentStatus; - readonly updatedAt: any; - readonly version: number; - readonly " $fragmentType": "DocumentVersionHistoryDialogFragment"; -}; -export type DocumentVersionHistoryDialogFragment$key = { - readonly " $data"?: DocumentVersionHistoryDialogFragment$data; - readonly " $fragmentSpreads": FragmentRefs<"DocumentVersionHistoryDialogFragment">; -}; - -const node: ReaderFragment = { - "argumentDefinitions": [], - "kind": "Fragment", - "metadata": null, - "name": "DocumentVersionHistoryDialogFragment", - "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "id", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "version", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "status", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "content", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "changelog", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "publishedAt", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "updatedAt", - "storageKey": null - }, - { - "alias": null, - "args": null, - "concreteType": "People", - "kind": "LinkedField", - "name": "publishedBy", - "plural": false, - "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "fullName", - "storageKey": null - } - ], - "storageKey": null - } - ], - "type": "DocumentVersion", - "abstractKey": null -}; - -(node as any).hash = "947253287039236aa413ee33879a6e4b"; - -export default node; diff --git a/apps/console/src/pages/organizations/documents/tabs/DocumentDescriptionTab.tsx b/apps/console/src/pages/organizations/documents/tabs/DocumentDescriptionTab.tsx index bfd5e0341..c94b993cd 100644 --- a/apps/console/src/pages/organizations/documents/tabs/DocumentDescriptionTab.tsx +++ b/apps/console/src/pages/organizations/documents/tabs/DocumentDescriptionTab.tsx @@ -4,12 +4,12 @@ import type { NodeOf } from "/types"; import { Markdown } from "@probo/ui"; export default function DocumentDescriptionTab() { - const { lastVersion } = useOutletContext<{ - lastVersion: NodeOf; + const { version } = useOutletContext<{ + version: NodeOf; }>(); return (
- +
); } diff --git a/apps/console/src/pages/organizations/documents/dialogs/DocumentSignaturesDialog.tsx b/apps/console/src/pages/organizations/documents/tabs/DocumentSignaturesTab.tsx similarity index 63% rename from apps/console/src/pages/organizations/documents/dialogs/DocumentSignaturesDialog.tsx rename to apps/console/src/pages/organizations/documents/tabs/DocumentSignaturesTab.tsx index 56c36fee3..ce859269e 100644 --- a/apps/console/src/pages/organizations/documents/dialogs/DocumentSignaturesDialog.tsx +++ b/apps/console/src/pages/organizations/documents/tabs/DocumentSignaturesTab.tsx @@ -2,119 +2,34 @@ import { Avatar, Badge, Button, - Dialog, - DialogContent, - DialogFooter, - DialogTitle, IconCircleCheck, IconClock, - DocumentVersionBadge, Spinner, } from "@probo/ui"; import { useTranslate } from "@probo/i18n"; -import { useState, type ReactNode, Suspense } from "react"; -import clsx from "clsx"; +import { Suspense } from "react"; import type { ItemOf, NodeOf } from "/types"; import { graphql, useFragment } from "react-relay"; -import type { DocumentSignaturesDialog_version$key } from "./__generated__/DocumentSignaturesDialog_version.graphql"; -import type { DocumentSignaturesDialog_signature$key } from "./__generated__/DocumentSignaturesDialog_signature.graphql"; import { usePeople } from "/hooks/graph/PeopleGraph.ts"; import { useOrganizationId } from "/hooks/useOrganizationId.ts"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts.ts"; import { sprintf } from "@probo/helpers"; import type { DocumentDetailPageDocumentFragment$data } from "../__generated__/DocumentDetailPageDocumentFragment.graphql"; - -type Props = { - document: DocumentDetailPageDocumentFragment$data; - children?: ReactNode; -}; +import { useOutletContext } from "react-router"; +import type { DocumentSignaturesTab_signature$key } from "/pages/organizations/documents/tabs/__generated__/DocumentSignaturesTab_signature.graphql.ts"; type Version = NodeOf; -export function DocumentSignaturesDialog(props: Props) { - const { __ } = useTranslate(); - const versions = props.document.versions.edges.map((edge) => edge.node); - const [selectedVersionId, setSelectedVersionId] = useState( - versions[0].id, - ); - const selectedVersion = versions.find((v) => v.id === selectedVersionId); - - if (!selectedVersion) { +export default function DocumentSignaturesTab() { + const { version } = useOutletContext<{ version: Version }>(); + if (!version) { return null; } return ( - - - -
- - {__("Signatures")} - -

- {__( - "Click request to ask for a signature from people in your organization.", - )} -

- }> - - -
-
- -
- ); -} - -const versionFragment = graphql` - fragment DocumentSignaturesDialog_version on DocumentVersion { - version - status - publishedAt - updatedAt - } -`; - -function VersionItem(props: { - version: Version; - active?: boolean; - onSelect: (v: string) => void; -}) { - const { dateTimeFormat, __ } = useTranslate(); - const version = useFragment( - versionFragment, - props.version, - ); - return ( - + }> + + ); } @@ -154,7 +69,7 @@ function SignatureList(props: { version: Version }) { * Fragments */ const signatureFragment = graphql` - fragment DocumentSignaturesDialog_signature on DocumentVersionSignature { + fragment DocumentSignaturesTab_signature on DocumentVersionSignature { id state signedAt @@ -170,7 +85,7 @@ const signatureFragment = graphql` * Mutations */ const requestSignatureMutation = graphql` - mutation DocumentSignaturesDialog_requestSignatureMutation( + mutation DocumentSignaturesTab_requestSignatureMutation( $input: RequestSignatureInput! $connections: [ID!]! ) { @@ -182,14 +97,14 @@ const requestSignatureMutation = graphql` signedBy { id } - ...DocumentSignaturesDialog_signature + ...DocumentSignaturesTab_signature } } } } `; const cancelSignatureMutation = graphql` - mutation DocumentSignaturesDialog_cancelSignatureMutation( + mutation DocumentSignaturesTab_cancelSignatureMutation( $input: CancelSignatureRequestInput! $connections: [ID!]! ) { @@ -201,7 +116,7 @@ const cancelSignatureMutation = graphql` function SignatureItem(props: { versionId: string; - signature?: DocumentSignaturesDialog_signature$key; + signature?: DocumentSignaturesTab_signature$key; people: ItemOf>; connectionId: string; signable: boolean; diff --git a/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_cancelSignatureMutation.graphql.ts b/apps/console/src/pages/organizations/documents/tabs/__generated__/DocumentSignaturesTab_cancelSignatureMutation.graphql.ts similarity index 72% rename from apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_cancelSignatureMutation.graphql.ts rename to apps/console/src/pages/organizations/documents/tabs/__generated__/DocumentSignaturesTab_cancelSignatureMutation.graphql.ts index 9a6aa9c27..d2767601c 100644 --- a/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_cancelSignatureMutation.graphql.ts +++ b/apps/console/src/pages/organizations/documents/tabs/__generated__/DocumentSignaturesTab_cancelSignatureMutation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<9f55e528d2b6366114a1852c9beaf1b0>> + * @generated SignedSource<<0a17c03011fe74b75a90dbeae02ab2ef>> * @lightSyntaxTransform * @nogrep */ @@ -12,18 +12,18 @@ import { ConcreteRequest } from 'relay-runtime'; export type CancelSignatureRequestInput = { documentVersionSignatureId: string; }; -export type DocumentSignaturesDialog_cancelSignatureMutation$variables = { +export type DocumentSignaturesTab_cancelSignatureMutation$variables = { connections: ReadonlyArray; input: CancelSignatureRequestInput; }; -export type DocumentSignaturesDialog_cancelSignatureMutation$data = { +export type DocumentSignaturesTab_cancelSignatureMutation$data = { readonly cancelSignatureRequest: { readonly deletedDocumentVersionSignatureId: string; }; }; -export type DocumentSignaturesDialog_cancelSignatureMutation = { - response: DocumentSignaturesDialog_cancelSignatureMutation$data; - variables: DocumentSignaturesDialog_cancelSignatureMutation$variables; +export type DocumentSignaturesTab_cancelSignatureMutation = { + response: DocumentSignaturesTab_cancelSignatureMutation$data; + variables: DocumentSignaturesTab_cancelSignatureMutation$variables; }; const node: ConcreteRequest = (function(){ @@ -59,7 +59,7 @@ return { ], "kind": "Fragment", "metadata": null, - "name": "DocumentSignaturesDialog_cancelSignatureMutation", + "name": "DocumentSignaturesTab_cancelSignatureMutation", "selections": [ { "alias": null, @@ -84,7 +84,7 @@ return { (v0/*: any*/) ], "kind": "Operation", - "name": "DocumentSignaturesDialog_cancelSignatureMutation", + "name": "DocumentSignaturesTab_cancelSignatureMutation", "selections": [ { "alias": null, @@ -117,16 +117,16 @@ return { ] }, "params": { - "cacheID": "81d10822e563ceb7ebcd4fdb5d19e8f5", + "cacheID": "c57722e2b57faca64eea4950864e034d", "id": null, "metadata": {}, - "name": "DocumentSignaturesDialog_cancelSignatureMutation", + "name": "DocumentSignaturesTab_cancelSignatureMutation", "operationKind": "mutation", - "text": "mutation DocumentSignaturesDialog_cancelSignatureMutation(\n $input: CancelSignatureRequestInput!\n) {\n cancelSignatureRequest(input: $input) {\n deletedDocumentVersionSignatureId\n }\n}\n" + "text": "mutation DocumentSignaturesTab_cancelSignatureMutation(\n $input: CancelSignatureRequestInput!\n) {\n cancelSignatureRequest(input: $input) {\n deletedDocumentVersionSignatureId\n }\n}\n" } }; })(); -(node as any).hash = "0cbec91e7ba7cc09d2bbf7169e98f30c"; +(node as any).hash = "9f5d3ff869ec6f91285140285248e824"; export default node; diff --git a/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_requestSignatureMutation.graphql.ts b/apps/console/src/pages/organizations/documents/tabs/__generated__/DocumentSignaturesTab_requestSignatureMutation.graphql.ts similarity index 82% rename from apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_requestSignatureMutation.graphql.ts rename to apps/console/src/pages/organizations/documents/tabs/__generated__/DocumentSignaturesTab_requestSignatureMutation.graphql.ts index 4f2f0085a..94256da88 100644 --- a/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_requestSignatureMutation.graphql.ts +++ b/apps/console/src/pages/organizations/documents/tabs/__generated__/DocumentSignaturesTab_requestSignatureMutation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -15,11 +15,11 @@ export type RequestSignatureInput = { documentVersionId: string; signatoryId: string; }; -export type DocumentSignaturesDialog_requestSignatureMutation$variables = { +export type DocumentSignaturesTab_requestSignatureMutation$variables = { connections: ReadonlyArray; input: RequestSignatureInput; }; -export type DocumentSignaturesDialog_requestSignatureMutation$data = { +export type DocumentSignaturesTab_requestSignatureMutation$data = { readonly requestSignature: { readonly documentVersionSignatureEdge: { readonly node: { @@ -28,14 +28,14 @@ export type DocumentSignaturesDialog_requestSignatureMutation$data = { readonly id: string; }; readonly state: DocumentVersionSignatureState; - readonly " $fragmentSpreads": FragmentRefs<"DocumentSignaturesDialog_signature">; + readonly " $fragmentSpreads": FragmentRefs<"DocumentSignaturesTab_signature">; }; }; }; }; -export type DocumentSignaturesDialog_requestSignatureMutation = { - response: DocumentSignaturesDialog_requestSignatureMutation$data; - variables: DocumentSignaturesDialog_requestSignatureMutation$variables; +export type DocumentSignaturesTab_requestSignatureMutation = { + response: DocumentSignaturesTab_requestSignatureMutation$data; + variables: DocumentSignaturesTab_requestSignatureMutation$variables; }; const node: ConcreteRequest = (function(){ @@ -78,7 +78,7 @@ return { ], "kind": "Fragment", "metadata": null, - "name": "DocumentSignaturesDialog_requestSignatureMutation", + "name": "DocumentSignaturesTab_requestSignatureMutation", "selections": [ { "alias": null, @@ -121,7 +121,7 @@ return { { "args": null, "kind": "FragmentSpread", - "name": "DocumentSignaturesDialog_signature" + "name": "DocumentSignaturesTab_signature" } ], "storageKey": null @@ -143,7 +143,7 @@ return { (v0/*: any*/) ], "kind": "Operation", - "name": "DocumentSignaturesDialog_requestSignatureMutation", + "name": "DocumentSignaturesTab_requestSignatureMutation", "selections": [ { "alias": null, @@ -239,16 +239,16 @@ return { ] }, "params": { - "cacheID": "6a5413db69a07e0eef99245e949cf4b2", + "cacheID": "e582b90bdad831d64741b45de17f45b5", "id": null, "metadata": {}, - "name": "DocumentSignaturesDialog_requestSignatureMutation", + "name": "DocumentSignaturesTab_requestSignatureMutation", "operationKind": "mutation", - "text": "mutation DocumentSignaturesDialog_requestSignatureMutation(\n $input: RequestSignatureInput!\n) {\n requestSignature(input: $input) {\n documentVersionSignatureEdge {\n node {\n id\n state\n signedBy {\n id\n }\n ...DocumentSignaturesDialog_signature\n }\n }\n }\n}\n\nfragment DocumentSignaturesDialog_signature on DocumentVersionSignature {\n id\n state\n signedAt\n requestedAt\n signedBy {\n fullName\n primaryEmailAddress\n id\n }\n}\n" + "text": "mutation DocumentSignaturesTab_requestSignatureMutation(\n $input: RequestSignatureInput!\n) {\n requestSignature(input: $input) {\n documentVersionSignatureEdge {\n node {\n id\n state\n signedBy {\n id\n }\n ...DocumentSignaturesTab_signature\n }\n }\n }\n}\n\nfragment DocumentSignaturesTab_signature on DocumentVersionSignature {\n id\n state\n signedAt\n requestedAt\n signedBy {\n fullName\n primaryEmailAddress\n id\n }\n}\n" } }; })(); -(node as any).hash = "6c51f681411cd3de162c78a3db20ec30"; +(node as any).hash = "f0b9fc6ff9db455e9079bf7e45fcd603"; export default node; diff --git a/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_signature.graphql.ts b/apps/console/src/pages/organizations/documents/tabs/__generated__/DocumentSignaturesTab_signature.graphql.ts similarity index 81% rename from apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_signature.graphql.ts rename to apps/console/src/pages/organizations/documents/tabs/__generated__/DocumentSignaturesTab_signature.graphql.ts index 0460943ef..a1bb8a857 100644 --- a/apps/console/src/pages/organizations/documents/dialogs/__generated__/DocumentSignaturesDialog_signature.graphql.ts +++ b/apps/console/src/pages/organizations/documents/tabs/__generated__/DocumentSignaturesTab_signature.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<71e44f5802c3eaba88dde399af20ed89>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -11,7 +11,7 @@ import { ReaderFragment } from 'relay-runtime'; export type DocumentVersionSignatureState = "REQUESTED" | "SIGNED"; import { FragmentRefs } from "relay-runtime"; -export type DocumentSignaturesDialog_signature$data = { +export type DocumentSignaturesTab_signature$data = { readonly id: string; readonly requestedAt: any; readonly signedAt: any | null | undefined; @@ -20,18 +20,18 @@ export type DocumentSignaturesDialog_signature$data = { readonly primaryEmailAddress: string; }; readonly state: DocumentVersionSignatureState; - readonly " $fragmentType": "DocumentSignaturesDialog_signature"; + readonly " $fragmentType": "DocumentSignaturesTab_signature"; }; -export type DocumentSignaturesDialog_signature$key = { - readonly " $data"?: DocumentSignaturesDialog_signature$data; - readonly " $fragmentSpreads": FragmentRefs<"DocumentSignaturesDialog_signature">; +export type DocumentSignaturesTab_signature$key = { + readonly " $data"?: DocumentSignaturesTab_signature$data; + readonly " $fragmentSpreads": FragmentRefs<"DocumentSignaturesTab_signature">; }; const node: ReaderFragment = { "argumentDefinitions": [], "kind": "Fragment", "metadata": null, - "name": "DocumentSignaturesDialog_signature", + "name": "DocumentSignaturesTab_signature", "selections": [ { "alias": null, @@ -91,6 +91,6 @@ const node: ReaderFragment = { "abstractKey": null }; -(node as any).hash = "0db843d4ebd21f44a3d126e85da8cf26"; +(node as any).hash = "b07437b34548744fef4ed78d4f1f0a62"; export default node; diff --git a/apps/console/src/routes/documentsRoutes.ts b/apps/console/src/routes/documentsRoutes.ts index 1c404398d..56931f21a 100644 --- a/apps/console/src/routes/documentsRoutes.ts +++ b/apps/console/src/routes/documentsRoutes.ts @@ -9,6 +9,46 @@ import { redirect } from "react-router"; import { lazy } from "@probo/react-lazy"; import { LinkCardSkeleton } from "/components/skeletons/LinkCardSkeleton"; +const documentTabs = (prefix: string) => { + return [ + { + path: `${prefix}`, + queryLoader: ({ organizationId, documentId }) => { + throw redirect( + `/organizations/${organizationId}/documents/${documentId}/description`, + ); + }, + Component: Fragment, + }, + { + path: `${prefix}description`, + fallback: LinkCardSkeleton, + Component: lazy( + () => + import( + "../pages/organizations/documents/tabs/DocumentDescriptionTab" + ), + ), + }, + { + path: `${prefix}controls`, + fallback: LinkCardSkeleton, + Component: lazy( + () => + import("../pages/organizations/documents/tabs/DocumentControlsTab"), + ), + }, + { + path: `${prefix}signatures`, + fallback: LinkCardSkeleton, + Component: lazy( + () => + import("../pages/organizations/documents/tabs/DocumentSignaturesTab"), + ), + }, + ] satisfies AppRoute[]; +}; + export const documentsRoutes = [ { path: "documents", @@ -16,7 +56,7 @@ export const documentsRoutes = [ queryLoader: ({ organizationId }) => loadQuery(relayEnvironment, documentsQuery, { organizationId }), Component: lazy( - () => import("/pages/organizations/documents/DocumentsPage") + () => import("/pages/organizations/documents/DocumentsPage"), ), }, { @@ -25,36 +65,8 @@ export const documentsRoutes = [ queryLoader: ({ documentId }) => loadQuery(relayEnvironment, documentNodeQuery, { documentId }), Component: lazy( - () => import("../pages/organizations/documents/DocumentDetailPage") + () => import("../pages/organizations/documents/DocumentDetailPage"), ), - children: [ - { - path: "", - queryLoader: ({ organizationId, documentId }) => { - throw redirect( - `/organizations/${organizationId}/documents/${documentId}/description` - ); - }, - Component: Fragment, - }, - { - path: "description", - fallback: LinkCardSkeleton, - Component: lazy( - () => - import( - "../pages/organizations/documents/tabs/DocumentDescriptionTab" - ) - ), - }, - { - path: "controls", - fallback: LinkCardSkeleton, - Component: lazy( - () => - import("../pages/organizations/documents/tabs/DocumentControlsTab") - ), - }, - ], + children: [...documentTabs(""), ...documentTabs("versions/:versionId/")], }, ] satisfies AppRoute[]; diff --git a/packages/ui/src/Atoms/Dropdown/Dropdown.tsx b/packages/ui/src/Atoms/Dropdown/Dropdown.tsx index b21566891..4ac450589 100644 --- a/packages/ui/src/Atoms/Dropdown/Dropdown.tsx +++ b/packages/ui/src/Atoms/Dropdown/Dropdown.tsx @@ -3,7 +3,7 @@ import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; import { clsx } from "clsx"; import type { IconProps } from "../Icons/type.ts"; import { tv } from "tailwind-variants"; -import { IconDotGrid1x3Horizontal } from "../Icons/IconDotGrid1x3Horizontal.tsx"; +import { IconDotGrid1x3Horizontal } from "../Icons"; import { Button } from "../Button/Button.tsx"; type Props = PropsWithChildren<{ @@ -24,6 +24,10 @@ export function Dropdown({ children, toggle, className, open }: Props) { )}