Add cancel signature action

Fix #169

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Jonathan
2025-07-08 09:47:04 +02:00
committed by Sacha Al Himdani
parent 8a77271308
commit 0a5524ce5d
2 changed files with 179 additions and 10 deletions

View File

@@ -35,7 +35,7 @@ export function DocumentSignaturesDialog(props: Props) {
const { __ } = useTranslate(); const { __ } = useTranslate();
const versions = props.document.versions.edges.map((edge) => edge.node); const versions = props.document.versions.edges.map((edge) => edge.node);
const [selectedVersionId, setSelectedVersionId] = useState<string>( const [selectedVersionId, setSelectedVersionId] = useState<string>(
versions[0].id versions[0].id,
); );
const selectedVersion = versions.find((v) => v.id === selectedVersionId); const selectedVersion = versions.find((v) => v.id === selectedVersionId);
@@ -65,7 +65,7 @@ export function DocumentSignaturesDialog(props: Props) {
</DialogTitle> </DialogTitle>
<p className="text-sm text-txt-secondary mb-4"> <p className="text-sm text-txt-secondary mb-4">
{__( {__(
"Click request to ask for a signature from people in your organization." "Click request to ask for a signature from people in your organization.",
)} )}
</p> </p>
<Suspense fallback={<Spinner centered />}> <Suspense fallback={<Spinner centered />}>
@@ -95,14 +95,14 @@ function VersionItem(props: {
const { dateTimeFormat, __ } = useTranslate(); const { dateTimeFormat, __ } = useTranslate();
const version = useFragment<DocumentSignaturesDialog_version$key>( const version = useFragment<DocumentSignaturesDialog_version$key>(
versionFragment, versionFragment,
props.version props.version,
); );
return ( return (
<button <button
onClick={() => props.onSelect(props.version.id)} onClick={() => props.onSelect(props.version.id)}
className={clsx( className={clsx(
"text-start space-y-1 w-full overflow-hidden py-2 px-3 w-full hover:bg-tertiary-hover cursor-pointer rounded", "text-start space-y-1 w-full overflow-hidden py-2 px-3 w-full hover:bg-tertiary-hover cursor-pointer rounded",
props.active && "bg-tertiary-pressed" props.active && "bg-tertiary-pressed",
)} )}
> >
<div className="flex gap-1 text-sm text-txt-primary"> <div className="flex gap-1 text-sm text-txt-primary">
@@ -188,6 +188,16 @@ const requestSignatureMutation = graphql`
} }
} }
`; `;
const cancelSignatureMutation = graphql`
mutation DocumentSignaturesDialog_cancelSignatureMutation(
$input: CancelSignatureRequestInput!
$connections: [ID!]!
) {
cancelSignatureRequest(input: $input) {
deletedDocumentVersionSignatureId @deleteEdge(connections: $connections)
}
}
`;
function SignatureItem(props: { function SignatureItem(props: {
versionId: string; versionId: string;
@@ -203,7 +213,14 @@ function SignatureItem(props: {
{ {
successMessage: __("Signature request sent successfully"), successMessage: __("Signature request sent successfully"),
errorMessage: __("Failed to send signature request"), errorMessage: __("Failed to send signature request"),
} },
);
const [cancelSignature, isCancellingSignature] = useMutationWithToasts(
cancelSignatureMutation,
{
successMessage: __("Request cancelled successfully"),
errorMessage: __("Failed to cancel signature request"),
},
); );
// No signature request for this user // No signature request for this user
@@ -263,15 +280,35 @@ function SignatureItem(props: {
{sprintf( {sprintf(
label, label,
dateTimeFormat( dateTimeFormat(
isSigned ? signature.signedAt : signature.requestedAt isSigned ? signature.signedAt : signature.requestedAt,
) ),
)} )}
</span> </span>
</div> </div>
</div> </div>
<Badge variant={isSigned ? "success" : "warning"} className="ml-auto"> {isSigned ? (
{isSigned ? __("Signed") : __("Pending")} <Badge variant="success" className="ml-auto">
{__("Signed")}
</Badge> </Badge>
) : (
<Button
variant="danger"
className="ml-auto"
disabled={isCancellingSignature}
onClick={() => {
cancelSignature({
variables: {
input: {
documentVersionSignatureId: signature.id,
},
connections: [props.connectionId],
},
});
}}
>
{__("Cancel request")}
</Button>
)}
</div> </div>
); );
} }

View File

@@ -0,0 +1,132 @@
/**
* @generated SignedSource<<9f55e528d2b6366114a1852c9beaf1b0>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type CancelSignatureRequestInput = {
documentVersionSignatureId: string;
};
export type DocumentSignaturesDialog_cancelSignatureMutation$variables = {
connections: ReadonlyArray<string>;
input: CancelSignatureRequestInput;
};
export type DocumentSignaturesDialog_cancelSignatureMutation$data = {
readonly cancelSignatureRequest: {
readonly deletedDocumentVersionSignatureId: string;
};
};
export type DocumentSignaturesDialog_cancelSignatureMutation = {
response: DocumentSignaturesDialog_cancelSignatureMutation$data;
variables: DocumentSignaturesDialog_cancelSignatureMutation$variables;
};
const node: ConcreteRequest = (function(){
var v0 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "connections"
},
v1 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "input"
},
v2 = [
{
"kind": "Variable",
"name": "input",
"variableName": "input"
}
],
v3 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "deletedDocumentVersionSignatureId",
"storageKey": null
};
return {
"fragment": {
"argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/)
],
"kind": "Fragment",
"metadata": null,
"name": "DocumentSignaturesDialog_cancelSignatureMutation",
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "CancelSignatureRequestPayload",
"kind": "LinkedField",
"name": "cancelSignatureRequest",
"plural": false,
"selections": [
(v3/*: any*/)
],
"storageKey": null
}
],
"type": "Mutation",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": [
(v1/*: any*/),
(v0/*: any*/)
],
"kind": "Operation",
"name": "DocumentSignaturesDialog_cancelSignatureMutation",
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "CancelSignatureRequestPayload",
"kind": "LinkedField",
"name": "cancelSignatureRequest",
"plural": false,
"selections": [
(v3/*: any*/),
{
"alias": null,
"args": null,
"filters": null,
"handle": "deleteEdge",
"key": "",
"kind": "ScalarHandle",
"name": "deletedDocumentVersionSignatureId",
"handleArgs": [
{
"kind": "Variable",
"name": "connections",
"variableName": "connections"
}
]
}
],
"storageKey": null
}
]
},
"params": {
"cacheID": "81d10822e563ceb7ebcd4fdb5d19e8f5",
"id": null,
"metadata": {},
"name": "DocumentSignaturesDialog_cancelSignatureMutation",
"operationKind": "mutation",
"text": "mutation DocumentSignaturesDialog_cancelSignatureMutation(\n $input: CancelSignatureRequestInput!\n) {\n cancelSignatureRequest(input: $input) {\n deletedDocumentVersionSignatureId\n }\n}\n"
}
};
})();
(node as any).hash = "0cbec91e7ba7cc09d2bbf7169e98f30c";
export default node;