Fix bulk update document front counts

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-07-15 17:17:30 +02:00
parent be6c668aa6
commit 578289f053
3 changed files with 53 additions and 29 deletions

View File

@@ -10,7 +10,7 @@ import type { MutationParameters, GraphQLTaggedNode } from "relay-runtime";
export function useMutationWithToasts<T extends MutationParameters>( export function useMutationWithToasts<T extends MutationParameters>(
query: GraphQLTaggedNode, query: GraphQLTaggedNode,
baseOptions?: { baseOptions?: {
successMessage?: string; successMessage?: string | ((response: T["response"]) => string);
errorMessage?: string; errorMessage?: string;
} }
) { ) {
@@ -21,7 +21,7 @@ export function useMutationWithToasts<T extends MutationParameters>(
( (
queryOptions: UseMutationConfig<T> & { queryOptions: UseMutationConfig<T> & {
onSuccess?: () => void; onSuccess?: () => void;
successMessage?: string; successMessage?: string | ((response: T["response"]) => string);
errorMessage?: string; errorMessage?: string;
} }
) => { ) => {
@@ -42,10 +42,14 @@ export function useMutationWithToasts<T extends MutationParameters>(
reject(error); reject(error);
return; return;
} }
const successMessage = typeof options.successMessage === "function"
? options.successMessage(response)
: options.successMessage;
toast({ toast({
title: __("Success"), title: __("Success"),
description: description:
options.successMessage ?? successMessage ??
__("Operation completed successfully"), __("Operation completed successfully"),
variant: "success", variant: "success",
}); });

View File

@@ -14,6 +14,7 @@ import { useFormWithSchema } from "/hooks/useFormWithSchema.ts";
import { graphql } from "relay-runtime"; import { graphql } from "relay-runtime";
import { sprintf } from "@probo/helpers"; import { sprintf } from "@probo/helpers";
import { useMutationWithToasts } from "/hooks/useMutationWithToasts.ts"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts.ts";
import type { PublishDocumentsDialogMutation } from "./__generated__/PublishDocumentsDialogMutation.graphql.ts";
type Props = { type Props = {
documentIds: string[]; documentIds: string[];
@@ -36,10 +37,6 @@ const documentsPublishMutation = graphql`
} }
`; `;
const schema = z.object({
changelog: z.string().min(1, "Changelog is required"),
});
export function PublishDocumentsDialog({ export function PublishDocumentsDialog({
documentIds, documentIds,
children, children,
@@ -47,6 +44,22 @@ export function PublishDocumentsDialog({
}: Props) { }: Props) {
const { __ } = useTranslate(); const { __ } = useTranslate();
const dialogRef = useDialogRef(); const dialogRef = useDialogRef();
const schema = z.object({
changelog: z.string().min(1, __("Changelog is required")),
});
const [publishMutation] = useMutationWithToasts<PublishDocumentsDialogMutation>(documentsPublishMutation, {
successMessage: (response) => {
const actualPublishedCount = response.bulkPublishDocumentVersions.documentEdges.length;
return sprintf(__("%s documents published"), actualPublishedCount);
},
errorMessage: sprintf(
__("Failed to publish %s documents"),
documentIds.length
),
});
const { const {
handleSubmit, handleSubmit,
register, register,
@@ -56,6 +69,7 @@ export function PublishDocumentsDialog({
changelog: "", changelog: "",
}, },
}); });
const onSubmit = handleSubmit(async (data) => { const onSubmit = handleSubmit(async (data) => {
await publishMutation({ await publishMutation({
variables: { variables: {
@@ -64,17 +78,11 @@ export function PublishDocumentsDialog({
changelog: data.changelog, changelog: data.changelog,
}, },
}, },
onSuccess: () => {
dialogRef.current?.close();
onSave();
},
}); });
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 ( return (

View File

@@ -14,12 +14,15 @@ import {
Table, Table,
IconChevronDown, IconChevronDown,
} from "@probo/ui"; } from "@probo/ui";
import { Suspense, type FormEventHandler, type ReactNode } from "react"; import { Suspense, type ReactNode } from "react";
import { useTranslate } from "@probo/i18n"; import { useTranslate } from "@probo/i18n";
import { graphql } from "relay-runtime"; import { graphql } from "relay-runtime";
import { sprintf } from "@probo/helpers"; import { sprintf } from "@probo/helpers";
import { useMutationWithToasts } from "/hooks/useMutationWithToasts.ts"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts.ts";
import { useOrganizationId } from "/hooks/useOrganizationId.ts"; import { useOrganizationId } from "/hooks/useOrganizationId.ts";
import type { SignatureDocumentsDialogMutation } from "./__generated__/SignatureDocumentsDialogMutation.graphql.ts";
import { useFormWithSchema } from "/hooks/useFormWithSchema.ts";
import z from "zod";
import { import {
paginatedPeopleFragment, paginatedPeopleFragment,
paginatedPeopleQuery, paginatedPeopleQuery,
@@ -58,16 +61,23 @@ export function SignatureDocumentsDialog({
const { __ } = useTranslate(); const { __ } = useTranslate();
const dialogRef = useDialogRef(); const dialogRef = useDialogRef();
const { list: selectedPeople, toggle } = useList<string>([]); const { list: selectedPeople, toggle } = useList<string>([]);
const [publishMutation] = useMutationWithToasts(documentsSignatureMutation, {
successMessage: sprintf( const schema = z.object({});
__("%s signature requests sent"),
documentIds.length const [publishMutation] = useMutationWithToasts<SignatureDocumentsDialogMutation>(documentsSignatureMutation, {
), successMessage: (response) => {
const actualRequestsCount = response.bulkRequestSignatures.documentVersionSignatureEdges.length;
return sprintf(__("%s signature requests sent"), actualRequestsCount);
},
errorMessage: __("Failed to send signature requests"), errorMessage: __("Failed to send signature requests"),
}); });
const onSubmit: FormEventHandler<HTMLFormElement> = async (e) => { const {
e.preventDefault(); handleSubmit,
formState: { isSubmitting },
} = useFormWithSchema(schema, {});
const onSubmit = handleSubmit(async () => {
await publishMutation({ await publishMutation({
variables: { variables: {
input: { input: {
@@ -75,10 +85,12 @@ export function SignatureDocumentsDialog({
signatoryIds: selectedPeople, signatoryIds: selectedPeople,
}, },
}, },
onSuccess: () => {
dialogRef.current?.close();
onSave();
},
}); });
dialogRef.current?.close(); });
onSave();
};
return ( return (
<Dialog <Dialog
@@ -94,7 +106,7 @@ export function SignatureDocumentsDialog({
</Suspense> </Suspense>
</DialogContent> </DialogContent>
<DialogFooter> <DialogFooter>
<Button type="submit" disabled={selectedPeople.length === 0}> <Button type="submit" disabled={selectedPeople.length === 0 || isSubmitting}>
{__("Send signature requests")} {__("Send signature requests")}
</Button> </Button>
</DialogFooter> </DialogFooter>