From 8fd8319ad4997988d960b3f08882231da6f3f414 Mon Sep 17 00:00:00 2001 From: Grafikart Date: Fri, 11 Jul 2025 15:05:00 +0200 Subject: [PATCH] Add changelog dialog when bulk publishing Signed-off-by: Sacha Al Himdani --- .../organizations/documents/DocumentsPage.tsx | 86 ++++++-------- .../dialogs/PublishDocumentsDialog.tsx | 107 ++++++++++++++++++ ...PublishDocumentsDialogMutation.graphql.ts} | 24 ++-- 3 files changed, 152 insertions(+), 65 deletions(-) create mode 100644 apps/console/src/pages/organizations/documents/dialogs/PublishDocumentsDialog.tsx rename apps/console/src/pages/organizations/documents/{__generated__/DocumentsPagePublishMutation.graphql.ts => dialogs/__generated__/PublishDocumentsDialogMutation.graphql.ts} (88%) diff --git a/apps/console/src/pages/organizations/documents/DocumentsPage.tsx b/apps/console/src/pages/organizations/documents/DocumentsPage.tsx index 263fc1253..1f64b1eef 100644 --- a/apps/console/src/pages/organizations/documents/DocumentsPage.tsx +++ b/apps/console/src/pages/organizations/documents/DocumentsPage.tsx @@ -41,6 +41,7 @@ import type { DocumentsPageRowFragment$key } from "./__generated__/DocumentsPage import { SortableTable, SortableTh } from "/components/SortableTable"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts.ts"; import { usePeople } from "/hooks/graph/PeopleGraph.ts"; +import { PublishDocumentsDialog } from "./dialogs/PublishDocumentsDialog.tsx"; const documentsFragment = graphql` fragment DocumentsPageListFragment on Organization @@ -73,25 +74,8 @@ const documentsFragment = graphql` } `; -const documentsPublishMutation = graphql` - mutation DocumentsPagePublishMutation( - $input: BulkPublishDocumentVersionsInput! - ) { - bulkPublishDocumentVersions(input: $input) { - documentEdges { - node { - id - ...DocumentsPageRowFragment - } - } - } - } -`; - const documentsSignatureMutation = graphql` - mutation DocumentsPageSignatureMutation( - $input: BulkRequestSignaturesInput! - ) { + mutation DocumentsPageSignatureMutation($input: BulkRequestSignaturesInput!) { bulkRequestSignatures(input: $input) { documentVersionSignatureEdges { node { @@ -112,11 +96,11 @@ export default function DocumentsPage(props: Props) { const organization = usePreloadedQuery( documentsQuery, - props.queryRef, + props.queryRef ).organization; const pagination = usePaginationFragment( documentsFragment, - organization as DocumentsPageListFragment$key, + organization as DocumentsPageListFragment$key ); const documents = pagination.data.documents.edges.map((edge) => edge.node); @@ -124,15 +108,13 @@ export default function DocumentsPage(props: Props) { const [sendSigningNotifications] = useSendSigningNotificationsMutation(); const { list: selection, toggle, clear, reset } = useList([]); - const [publishMutation, isPublishing] = useMutationWithToasts(documentsPublishMutation, { - successMessage: sprintf(__("%s documents published"), selection.length), - errorMessage: sprintf(__("Failed to publish %s documents"), selection.length), - }) - - const [signatureMutation, isSigning] = useMutationWithToasts(documentsSignatureMutation, { - successMessage: __("Signature request send successfully"), - errorMessage: __("Failed to send signature requests"), - }) + const [signatureMutation, isSigning] = useMutationWithToasts( + documentsSignatureMutation, + { + successMessage: __("Signature request send successfully"), + errorMessage: __("Failed to send signature requests"), + } + ); const people = usePeople(organization.id); usePageTitle(__("Documents")); @@ -144,29 +126,17 @@ export default function DocumentsPage(props: Props) { }); }; - const publish = async () => { - await publishMutation({ - variables: { - input: { - documentIds: selection, - changelog: '', - } - } - }) - clear(); - } - const requestSignatures = async () => { await signatureMutation({ variables: { input: { documentIds: selection, - signatoryIds: people.map(p => p.id), - } - } - }) + signatoryIds: people.map((p) => p.id), + }, + }, + }); clear(); - } + }; return (
@@ -221,8 +191,18 @@ export default function DocumentsPage(props: Props) {
- - + +
@@ -293,14 +273,14 @@ function DocumentRow({ }) { const document = useFragment( rowFragment, - documentKey, + documentKey ); const lastVersion = document.versions.edges[0].node; const isDraft = lastVersion.status === "DRAFT"; const { __, dateFormat } = useTranslate(); const signatures = lastVersion.signatures.edges.map((edge) => edge.node); const signedCount = signatures.filter( - (signature) => signature.state === "SIGNED", + (signature) => signature.state === "SIGNED" ).length; const [deleteDocument] = useDeleteDocumentMutation(); const confirm = useConfirm(); @@ -317,11 +297,11 @@ function DocumentRow({ { 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 ), - }, + } ); }; diff --git a/apps/console/src/pages/organizations/documents/dialogs/PublishDocumentsDialog.tsx b/apps/console/src/pages/organizations/documents/dialogs/PublishDocumentsDialog.tsx new file mode 100644 index 000000000..32f7553be --- /dev/null +++ b/apps/console/src/pages/organizations/documents/dialogs/PublishDocumentsDialog.tsx @@ -0,0 +1,107 @@ +import { + Button, + Dialog, + DialogContent, + DialogFooter, + Field, + useDialogRef, + Breadcrumb, +} from "@probo/ui"; +import { type ReactNode } from "react"; +import { useTranslate } from "@probo/i18n"; +import z from "zod"; +import { useFormWithSchema } from "/hooks/useFormWithSchema.ts"; +import { graphql } from "relay-runtime"; +import { sprintf } from "@probo/helpers"; +import { useMutationWithToasts } from "/hooks/useMutationWithToasts.ts"; + +type Props = { + documentIds: string[]; + children: ReactNode; + onSave: () => void; +}; + +const documentsPublishMutation = graphql` + mutation PublishDocumentsDialogMutation( + $input: BulkPublishDocumentVersionsInput! + ) { + bulkPublishDocumentVersions(input: $input) { + documentEdges { + node { + id + ...DocumentsPageRowFragment + } + } + } + } +`; + +const schema = z.object({ + changelog: z.string().min(1, "Changelog is required"), +}); + +export function PublishDocumentsDialog({ + documentIds, + children, + onSave, +}: Props) { + const { __ } = useTranslate(); + const dialogRef = useDialogRef(); + const { + handleSubmit, + register, + formState: { isSubmitting, errors }, + } = useFormWithSchema(schema, { + defaultValues: { + changelog: "", + }, + }); + const onSubmit = handleSubmit(async (data) => { + await publishMutation({ + variables: { + input: { + documentIds, + changelog: data.changelog, + }, + }, + }); + dialogRef.current?.close(); + onSave(); + }); + + const [publishMutation] = useMutationWithToasts(documentsPublishMutation, { + successMessage: sprintf(__("%s documents published"), documentIds.length), + errorMessage: sprintf( + __("Failed to publish %s documents"), + documentIds.length + ), + }); + + return ( + } + > +
+ + + + + + +
+
+ ); +} diff --git a/apps/console/src/pages/organizations/documents/__generated__/DocumentsPagePublishMutation.graphql.ts b/apps/console/src/pages/organizations/documents/dialogs/__generated__/PublishDocumentsDialogMutation.graphql.ts similarity index 88% rename from apps/console/src/pages/organizations/documents/__generated__/DocumentsPagePublishMutation.graphql.ts rename to apps/console/src/pages/organizations/documents/dialogs/__generated__/PublishDocumentsDialogMutation.graphql.ts index 4663558d6..f99faedaf 100644 --- a/apps/console/src/pages/organizations/documents/__generated__/DocumentsPagePublishMutation.graphql.ts +++ b/apps/console/src/pages/organizations/documents/dialogs/__generated__/PublishDocumentsDialogMutation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<2961ff4f50f912f350acab5b0a341042>> * @lightSyntaxTransform * @nogrep */ @@ -14,10 +14,10 @@ export type BulkPublishDocumentVersionsInput = { changelog: string; documentIds: ReadonlyArray; }; -export type DocumentsPagePublishMutation$variables = { +export type PublishDocumentsDialogMutation$variables = { input: BulkPublishDocumentVersionsInput; }; -export type DocumentsPagePublishMutation$data = { +export type PublishDocumentsDialogMutation$data = { readonly bulkPublishDocumentVersions: { readonly documentEdges: ReadonlyArray<{ readonly node: { @@ -27,9 +27,9 @@ export type DocumentsPagePublishMutation$data = { }>; }; }; -export type DocumentsPagePublishMutation = { - response: DocumentsPagePublishMutation$data; - variables: DocumentsPagePublishMutation$variables; +export type PublishDocumentsDialogMutation = { + response: PublishDocumentsDialogMutation$data; + variables: PublishDocumentsDialogMutation$variables; }; const node: ConcreteRequest = (function(){ @@ -59,7 +59,7 @@ return { "argumentDefinitions": (v0/*: any*/), "kind": "Fragment", "metadata": null, - "name": "DocumentsPagePublishMutation", + "name": "PublishDocumentsDialogMutation", "selections": [ { "alias": null, @@ -108,7 +108,7 @@ return { "operation": { "argumentDefinitions": (v0/*: any*/), "kind": "Operation", - "name": "DocumentsPagePublishMutation", + "name": "PublishDocumentsDialogMutation", "selections": [ { "alias": null, @@ -288,16 +288,16 @@ return { ] }, "params": { - "cacheID": "7cd29425535c6d30017201fee219447b", + "cacheID": "bcc8589071b241670107f00c127f70d0", "id": null, "metadata": {}, - "name": "DocumentsPagePublishMutation", + "name": "PublishDocumentsDialogMutation", "operationKind": "mutation", - "text": "mutation DocumentsPagePublishMutation(\n $input: BulkPublishDocumentVersionsInput!\n) {\n bulkPublishDocumentVersions(input: $input) {\n documentEdges {\n node {\n id\n ...DocumentsPageRowFragment\n }\n }\n }\n}\n\nfragment DocumentsPageRowFragment on Document {\n id\n title\n description\n documentType\n updatedAt\n owner {\n id\n fullName\n }\n versions(first: 1) {\n edges {\n node {\n id\n status\n signatures(first: 100) {\n edges {\n node {\n id\n state\n }\n }\n }\n }\n }\n }\n}\n" + "text": "mutation PublishDocumentsDialogMutation(\n $input: BulkPublishDocumentVersionsInput!\n) {\n bulkPublishDocumentVersions(input: $input) {\n documentEdges {\n node {\n id\n ...DocumentsPageRowFragment\n }\n }\n }\n}\n\nfragment DocumentsPageRowFragment on Document {\n id\n title\n description\n documentType\n updatedAt\n owner {\n id\n fullName\n }\n versions(first: 1) {\n edges {\n node {\n id\n status\n signatures(first: 100) {\n edges {\n node {\n id\n state\n }\n }\n }\n }\n }\n }\n}\n" } }; })(); -(node as any).hash = "baea3e7dce61a42bf5bf2caefda998ea"; +(node as any).hash = "c9d699258bb8638d5474ab5e6b5e4585"; export default node;