diff --git a/apps/console/src/pages/organizations/documents/_components/DocumentActionsDropdown.tsx b/apps/console/src/pages/organizations/documents/_components/DocumentActionsDropdown.tsx index 0047355cf..a67235297 100644 --- a/apps/console/src/pages/organizations/documents/_components/DocumentActionsDropdown.tsx +++ b/apps/console/src/pages/organizations/documents/_components/DocumentActionsDropdown.tsx @@ -21,6 +21,7 @@ import { useNavigate, useParams } from "react-router"; import { ConnectionHandler, graphql } from "relay-runtime"; import type { DocumentActionsDropdown_archiveMutation } from "#/__generated__/core/DocumentActionsDropdown_archiveMutation.graphql"; +import type { DocumentActionsDropdown_createDraftMutation } from "#/__generated__/core/DocumentActionsDropdown_createDraftMutation.graphql"; import type { DocumentActionsDropdown_documentFragment$key } from "#/__generated__/core/DocumentActionsDropdown_documentFragment.graphql"; import type { DocumentActionsDropdown_unarchiveMutation } from "#/__generated__/core/DocumentActionsDropdown_unarchiveMutation.graphql"; import type { DocumentActionsDropdown_versionFragment$key } from "#/__generated__/core/DocumentActionsDropdown_versionFragment.graphql"; @@ -31,8 +32,6 @@ import { useMutationWithToasts } from "#/hooks/useMutationWithToasts"; import { useOrganizationId } from "#/hooks/useOrganizationId"; import { CurrentUser } from "#/providers/CurrentUser"; -import UpdateVersionDialog from "./UpdateVersionDialog"; - const documentFragment = graphql` fragment DocumentActionsDropdown_documentFragment on Document { id @@ -43,10 +42,37 @@ const documentFragment = graphql` canUnarchive: permission(action: "core:document:unarchive") canDelete: permission(action: "core:document:delete") versions(first: 20) { - __id totalCount } - ...UpdateVersionDialogFragment + } +`; + +const createDraftDocumentVersionMutation = graphql` + mutation DocumentActionsDropdown_createDraftMutation( + $input: CreateDraftDocumentVersionInput! + $connections: [ID!]! + ) { + createDraftDocumentVersion(input: $input) { + documentVersionEdge @prependEdge(connections: $connections) { + node { + id + content + status + publishedAt + major + minor + updatedAt + signatures(first: 100) { + edges { + node { + id + state + } + } + } + } + } + } } `; @@ -118,7 +144,6 @@ export function DocumentActionsDropdownn(props: { const { versionId } = useParams(); const { __ } = useTranslate(); const { email: defaultEmail } = use(CurrentUser); - const updateDialogRef = useRef<{ open: () => void }>(null); const pdfDownloadDialogRef = useRef(null); const confirm = useConfirm(); const { toast } = useToast(); @@ -128,6 +153,8 @@ export function DocumentActionsDropdownn(props: { const isDraft = version.status === "DRAFT"; + const [createDraftDocumentVersion, isCreatingDraft] + = useMutation(createDraftDocumentVersionMutation); const [deleteDocument, isDeleting] = useDeleteDocumentMutation(); const [archiveDocument, isArchiving] = useMutation(archiveDocumentMutation); @@ -144,6 +171,38 @@ export function DocumentActionsDropdownn(props: { }, ); + const handleCreateDraft = () => { + const connectionId = ConnectionHandler.getConnectionID(document.id, "DocumentversionsDropdownMenu_versions"); + createDraftDocumentVersion({ + variables: { + input: { + documentID: document.id, + }, + connections: [connectionId], + }, + onCompleted: (response, errors) => { + if (errors) { + toast({ + variant: "error", + title: __("Error creating draft"), + description: + errors[0]?.message || __("An unknown error occurred"), + }); + return; + } + + const newVersionId + = response.createDraftDocumentVersion.documentVersionEdge.node.id; + + void navigate(`/organizations/${organizationId}/documents/${document.id}/versions/${newVersionId}`); + }, + onError(error) { + console.log(error); + toast({ title: __("Error"), description: error.message, variant: "error" }); + }, + }); + }; + const handleArchive = () => { confirm( () => @@ -220,16 +279,13 @@ export function DocumentActionsDropdownn(props: { }; const handleDeleteDraft = () => { - const versionsConnectionId = ConnectionHandler.getConnectionID( - document.id, - "DocumentLayout_versions", - ); + const connectionId = ConnectionHandler.getConnectionID(document.id, "DocumentversionsDropdownMenu_versions"); confirm( () => deleteDraftDocumentVersion({ variables: { input: { documentVersionId: version.id }, - connections: [document.versions.__id, versionsConnectionId], + connections: [connectionId], }, onSuccess() { if (versionId) { @@ -285,10 +341,6 @@ export function DocumentActionsDropdownn(props: { return ( <> - void handleExportDocumentVersion(options)} @@ -296,12 +348,13 @@ export function DocumentActionsDropdownn(props: { defaultEmail={defaultEmail} /> - {document.canUpdate && ( + {document.canUpdate && !isDraft && ( updateDialogRef.current?.open()} + onClick={handleCreateDraft} icon={IconPencil} + disabled={isCreatingDraft} > - {isDraft ? __("Edit draft document") : __("Create new draft")} + {__("Create new draft")} )} {isDraft diff --git a/apps/console/src/pages/organizations/documents/_components/DocumentVersionsDropdownMenu.tsx b/apps/console/src/pages/organizations/documents/_components/DocumentVersionsDropdownMenu.tsx index b80fd8c6d..7fca61e16 100644 --- a/apps/console/src/pages/organizations/documents/_components/DocumentVersionsDropdownMenu.tsx +++ b/apps/console/src/pages/organizations/documents/_components/DocumentVersionsDropdownMenu.tsx @@ -24,7 +24,7 @@ export const documentVersionsDropdownMenuQuery = graphql` document: node(id: $documentId) { __typename ... on Document { - versions(first: 20) { + versions(first: 20) @connection(key: "DocumentversionsDropdownMenu_versions") { edges { node { id diff --git a/apps/console/src/pages/organizations/documents/_components/UpdateVersionDialog.tsx b/apps/console/src/pages/organizations/documents/_components/UpdateVersionDialog.tsx deleted file mode 100644 index e16429ada..000000000 --- a/apps/console/src/pages/organizations/documents/_components/UpdateVersionDialog.tsx +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright (c) 2026 Probo Inc . -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -// PERFORMANCE OF THIS SOFTWARE. - -import { useTranslate } from "@probo/i18n"; -import { - Breadcrumb, - Button, - Dialog, - DialogContent, - DialogFooter, - Spinner, - Textarea, - useDialogRef, - useToast, -} from "@probo/ui"; -import { type RefObject, useEffect } from "react"; -import { useFragment, useMutation } from "react-relay"; -import { useNavigate } from "react-router"; -import { graphql } from "relay-runtime"; -import { z } from "zod"; - -import type { UpdateVersionDialogCreateMutation } from "#/__generated__/core/UpdateVersionDialogCreateMutation.graphql"; -import type { UpdateVersionDialogFragment$key } from "#/__generated__/core/UpdateVersionDialogFragment.graphql"; -import type { UpdateVersionDialogUpdateMutation } from "#/__generated__/core/UpdateVersionDialogUpdateMutation.graphql"; -import { useFormWithSchema } from "#/hooks/useFormWithSchema"; -import { useMutationWithToasts } from "#/hooks/useMutationWithToasts"; -import { useOrganizationId } from "#/hooks/useOrganizationId"; - -const fragment = graphql` - fragment UpdateVersionDialogFragment on Document { - id - versions(first: 20) @connection(key: "DocumentLayout_versions") { - __id - edges { - node { - id - status - content - } - } - } - } -`; - -const createDraftDocument = graphql` - mutation UpdateVersionDialogCreateMutation( - $input: CreateDraftDocumentVersionInput! - $connections: [ID!]! - ) { - createDraftDocumentVersion(input: $input) { - documentVersionEdge @prependEdge(connections: $connections) { - node { - id - content - status - publishedAt - major - minor - updatedAt - signatures(first: 100) { - edges { - node { - id - state - } - } - } - } - } - } - } -`; - -const updateDocumentMutation = graphql` - mutation UpdateVersionDialogUpdateMutation( - $input: UpdateDocumentVersionInput! - ) { - updateDocumentVersion(input: $input) { - documentVersion { - id - content - } - } - } -`; - -type UpdateVersionDialogProps = { - fKey: UpdateVersionDialogFragment$key; - ref: RefObject<{ open: () => void } | null>; -}; - -const versionSchema = z.object({ - content: z.string(), -}); - -export default function UpdateVersionDialog(props: UpdateVersionDialogProps) { - const { fKey, ref } = props; - - const organizationId = useOrganizationId(); - const navigate = useNavigate(); - const { __ } = useTranslate(); - const { toast } = useToast(); - const dialogRef = useDialogRef(); - - const document = useFragment(fragment, fKey); - const version = document.versions.edges[0].node; - const isDraft = version.status === "DRAFT"; - const [createDraftDocumentVersion, isCreatingDraft] - = useMutation(createDraftDocument); - const [updateDocumentVersion, isUpdating] - = useMutationWithToasts( - updateDocumentMutation, - { - successMessage: __("Document updated successfully."), - errorMessage: __("Failed to update document"), - }, - ); - const { handleSubmit, register } = useFormWithSchema(versionSchema, { - defaultValues: { - content: version.content, - }, - }); - - useEffect(() => { - if (!ref.current) { - ref.current = { - open: () => { - dialogRef.current?.open(); - }, - }; - } - }); - - if (!version) { - return; - } - - const onSubmit = async (data: z.infer) => { - if (isDraft) { - await updateDocumentVersion({ - variables: { - input: { - documentVersionId: version.id, - content: data.content, - }, - }, - onSuccess: () => { - dialogRef.current?.close(); - }, - }); - } else { - createDraftDocumentVersion({ - variables: { - input: { - documentID: document.id, - }, - connections: [document.versions.__id], - }, - onCompleted: (createResponse, errors) => { - if (errors) { - toast({ - variant: "error", - title: __("Error creating draft"), - description: - errors[0]?.message || __("An unknown error occurred"), - }); - return; - } - - const newVersionId - = createResponse?.createDraftDocumentVersion?.documentVersionEdge - ?.node?.id; - if (newVersionId && data.content !== version.content) { - void updateDocumentVersion({ - variables: { - input: { - documentVersionId: newVersionId, - content: data.content, - }, - }, - onSuccess: () => { - dialogRef.current?.close(); - void navigate(`/organizations/${organizationId}/documents/${document.id}/versions/${newVersionId}`); - }, - }); - } else { - dialogRef.current?.close(); - void navigate(`/organizations/${organizationId}/documents/${document.id}/versions/${newVersionId}`); - } - }, - }); - } - }; - - const isLoading = isCreatingDraft || isUpdating; - - return ( - } - > -
void handleSubmit(onSubmit)(e)}> - -