Better handling of document versions

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-08-08 15:12:06 +02:00
parent 81e7cd3574
commit a43328560a
12 changed files with 621 additions and 83 deletions

View File

@@ -3,6 +3,7 @@ import { graphql } from "relay-runtime";
import { useMutationWithToasts } from "../useMutationWithToasts"; import { useMutationWithToasts } from "../useMutationWithToasts";
import type { DocumentGraphDeleteMutation } from "./__generated__/DocumentGraphDeleteMutation.graphql"; import type { DocumentGraphDeleteMutation } from "./__generated__/DocumentGraphDeleteMutation.graphql";
import type { DocumentGraphSendSigningNotificationsMutation } from "./__generated__/DocumentGraphSendSigningNotificationsMutation.graphql"; import type { DocumentGraphSendSigningNotificationsMutation } from "./__generated__/DocumentGraphSendSigningNotificationsMutation.graphql";
import type { DocumentGraphDeleteDraftMutation } from "./__generated__/DocumentGraphDeleteDraftMutation.graphql";
export const documentsQuery = graphql` export const documentsQuery = graphql`
query DocumentGraphListQuery($organizationId: ID!) { query DocumentGraphListQuery($organizationId: ID!) {
@@ -13,15 +14,14 @@ export const documentsQuery = graphql`
} }
`; `;
export const DocumentsConnectionKey = "DocumentsPageFragment_documents"; export const DocumentsConnectionKey = "DocumentsListQuery_documents";
const deleteDocumentMutation = graphql` const deleteDocumentMutation = graphql`
mutation DocumentGraphDeleteMutation( mutation DocumentGraphDeleteMutation(
$input: DeleteDocumentInput! $input: DeleteDocumentInput!
$connections: [ID!]!
) { ) {
deleteDocument(input: $input) { deleteDocument(input: $input) {
deletedDocumentId @deleteEdge(connections: $connections) deletedDocumentId @deleteRecord
} }
} }
`; `;
@@ -38,6 +38,29 @@ export function useDeleteDocumentMutation() {
); );
} }
const deleteDraftDocumentVersionMutation = graphql`
mutation DocumentGraphDeleteDraftMutation(
$input: DeleteDraftDocumentVersionInput!
$connections: [ID!]!
) {
deleteDraftDocumentVersion(input: $input) {
deletedDocumentVersionId @deleteEdge(connections: $connections)
}
}
`;
export function useDeleteDraftDocumentVersionMutation() {
const { __ } = useTranslate();
return useMutationWithToasts<DocumentGraphDeleteDraftMutation>(
deleteDraftDocumentVersionMutation,
{
successMessage: __("Draft deleted successfully."),
errorMessage: __("Failed to delete draft. Please try again."),
}
);
}
const sendSigningNotificationsMutation = graphql` const sendSigningNotificationsMutation = graphql`
mutation DocumentGraphSendSigningNotificationsMutation( mutation DocumentGraphSendSigningNotificationsMutation(
$input: SendSigningNotificationsInput! $input: SendSigningNotificationsInput!

View File

@@ -0,0 +1,132 @@
/**
* @generated SignedSource<<f114dd31b601c0097380450ab5029b01>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type DeleteDraftDocumentVersionInput = {
documentVersionId: string;
};
export type DocumentGraphDeleteDraftMutation$variables = {
connections: ReadonlyArray<string>;
input: DeleteDraftDocumentVersionInput;
};
export type DocumentGraphDeleteDraftMutation$data = {
readonly deleteDraftDocumentVersion: {
readonly deletedDocumentVersionId: string;
};
};
export type DocumentGraphDeleteDraftMutation = {
response: DocumentGraphDeleteDraftMutation$data;
variables: DocumentGraphDeleteDraftMutation$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": "deletedDocumentVersionId",
"storageKey": null
};
return {
"fragment": {
"argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/)
],
"kind": "Fragment",
"metadata": null,
"name": "DocumentGraphDeleteDraftMutation",
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "DeleteDraftDocumentVersionPayload",
"kind": "LinkedField",
"name": "deleteDraftDocumentVersion",
"plural": false,
"selections": [
(v3/*: any*/)
],
"storageKey": null
}
],
"type": "Mutation",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": [
(v1/*: any*/),
(v0/*: any*/)
],
"kind": "Operation",
"name": "DocumentGraphDeleteDraftMutation",
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "DeleteDraftDocumentVersionPayload",
"kind": "LinkedField",
"name": "deleteDraftDocumentVersion",
"plural": false,
"selections": [
(v3/*: any*/),
{
"alias": null,
"args": null,
"filters": null,
"handle": "deleteEdge",
"key": "",
"kind": "ScalarHandle",
"name": "deletedDocumentVersionId",
"handleArgs": [
{
"kind": "Variable",
"name": "connections",
"variableName": "connections"
}
]
}
],
"storageKey": null
}
]
},
"params": {
"cacheID": "cd7e8253362e1d7e719e4ae2c206756e",
"id": null,
"metadata": {},
"name": "DocumentGraphDeleteDraftMutation",
"operationKind": "mutation",
"text": "mutation DocumentGraphDeleteDraftMutation(\n $input: DeleteDraftDocumentVersionInput!\n) {\n deleteDraftDocumentVersion(input: $input) {\n deletedDocumentVersionId\n }\n}\n"
}
};
})();
(node as any).hash = "d43940b41e3838fd03c3341c13b4c5c5";
export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<64c2c92a2a0806f34243f8fc9904167c>> * @generated SignedSource<<6b7916e6ff46a629bf97a7b072db2d8b>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -13,7 +13,6 @@ export type DeleteDocumentInput = {
documentId: string; documentId: string;
}; };
export type DocumentGraphDeleteMutation$variables = { export type DocumentGraphDeleteMutation$variables = {
connections: ReadonlyArray<string>;
input: DeleteDocumentInput; input: DeleteDocumentInput;
}; };
export type DocumentGraphDeleteMutation$data = { export type DocumentGraphDeleteMutation$data = {
@@ -27,24 +26,21 @@ export type DocumentGraphDeleteMutation = {
}; };
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
var v0 = { var v0 = [
"defaultValue": null, {
"kind": "LocalArgument", "defaultValue": null,
"name": "connections" "kind": "LocalArgument",
}, "name": "input"
v1 = { }
"defaultValue": null, ],
"kind": "LocalArgument", v1 = [
"name": "input"
},
v2 = [
{ {
"kind": "Variable", "kind": "Variable",
"name": "input", "name": "input",
"variableName": "input" "variableName": "input"
} }
], ],
v3 = { v2 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
@@ -53,23 +49,20 @@ v3 = {
}; };
return { return {
"fragment": { "fragment": {
"argumentDefinitions": [ "argumentDefinitions": (v0/*: any*/),
(v0/*: any*/),
(v1/*: any*/)
],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "DocumentGraphDeleteMutation", "name": "DocumentGraphDeleteMutation",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": (v2/*: any*/), "args": (v1/*: any*/),
"concreteType": "DeleteDocumentPayload", "concreteType": "DeleteDocumentPayload",
"kind": "LinkedField", "kind": "LinkedField",
"name": "deleteDocument", "name": "deleteDocument",
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/) (v2/*: any*/)
], ],
"storageKey": null "storageKey": null
} }
@@ -79,37 +72,27 @@ return {
}, },
"kind": "Request", "kind": "Request",
"operation": { "operation": {
"argumentDefinitions": [ "argumentDefinitions": (v0/*: any*/),
(v1/*: any*/),
(v0/*: any*/)
],
"kind": "Operation", "kind": "Operation",
"name": "DocumentGraphDeleteMutation", "name": "DocumentGraphDeleteMutation",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": (v2/*: any*/), "args": (v1/*: any*/),
"concreteType": "DeleteDocumentPayload", "concreteType": "DeleteDocumentPayload",
"kind": "LinkedField", "kind": "LinkedField",
"name": "deleteDocument", "name": "deleteDocument",
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/), (v2/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"filters": null, "filters": null,
"handle": "deleteEdge", "handle": "deleteRecord",
"key": "", "key": "",
"kind": "ScalarHandle", "kind": "ScalarHandle",
"name": "deletedDocumentId", "name": "deletedDocumentId"
"handleArgs": [
{
"kind": "Variable",
"name": "connections",
"variableName": "connections"
}
]
} }
], ],
"storageKey": null "storageKey": null
@@ -127,6 +110,6 @@ return {
}; };
})(); })();
(node as any).hash = "355f3a70caecabb2146075657665633e"; (node as any).hash = "471020248ed9d398ab80655e04cb823d";
export default node; export default node;

View File

@@ -1,6 +1,5 @@
import type { PreloadedQuery } from "react-relay"; import type { PreloadedQuery } from "react-relay";
import { import {
ConnectionHandler,
graphql, graphql,
loadQuery, loadQuery,
useFragment, useFragment,
@@ -9,8 +8,8 @@ import {
import type { DocumentGraphNodeQuery } from "/hooks/graph/__generated__/DocumentGraphNodeQuery.graphql"; import type { DocumentGraphNodeQuery } from "/hooks/graph/__generated__/DocumentGraphNodeQuery.graphql";
import { import {
documentNodeQuery, documentNodeQuery,
DocumentsConnectionKey,
useDeleteDocumentMutation, useDeleteDocumentMutation,
useDeleteDraftDocumentVersionMutation,
} from "/hooks/graph/DocumentGraph"; } from "/hooks/graph/DocumentGraph";
import { usePageTitle } from "@probo/hooks"; import { usePageTitle } from "@probo/hooks";
import type { import type {
@@ -187,6 +186,7 @@ export default function DocumentDetailPage(props: Props) {
} }
); );
const [deleteDocument, isDeleting] = useDeleteDocumentMutation(); const [deleteDocument, isDeleting] = useDeleteDocumentMutation();
const [deleteDraftDocumentVersion, isDeletingDraft] = useDeleteDraftDocumentVersionMutation();
const [exportDocumentVersionPDF, isExporting] = const [exportDocumentVersionPDF, isExporting] =
useMutationWithToasts<DocumentDetailPageExportPDFMutation>( useMutationWithToasts<DocumentDetailPageExportPDFMutation>(
exportDocumentVersionPDFMutation, exportDocumentVersionPDFMutation,
@@ -285,17 +285,13 @@ export default function DocumentDetailPage(props: Props) {
confirm( confirm(
() => () =>
new Promise<void>((resolve) => { new Promise<void>((resolve) => {
const connectionId = ConnectionHandler.getConnectionID(
organizationId,
DocumentsConnectionKey
);
deleteDocument({ deleteDocument({
variables: { variables: {
input: { documentId: document.id }, input: { documentId: document.id },
connections: [connectionId],
}, },
onSuccess() { onSuccess() {
navigate(`/organizations/${organizationId}/documents`); navigate(`/organizations/${organizationId}/documents`);
resolve();
}, },
onError: () => resolve(), onError: () => resolve(),
}); });
@@ -311,6 +307,40 @@ export default function DocumentDetailPage(props: Props) {
); );
}; };
const handleDeleteDraft = () => {
confirm(
() =>
new Promise<void>((resolve) => {
deleteDraftDocumentVersion({
variables: {
input: { documentVersionId: currentVersion.id },
connections: [versionConnectionId],
},
onSuccess() {
loadQuery(
props.queryRef.environment,
documentNodeQuery,
props.queryRef.variables,
{ fetchPolicy: "network-only" }
);
resolve();
},
onError: () => resolve(),
});
}),
{
message: sprintf(
__(
'This will permanently delete the draft version %s of "%s". This action cannot be undone.'
),
currentVersion.version,
document.title
),
}
);
};
const handleDownloadPdf = () => { const handleDownloadPdf = () => {
exportDocumentVersionPDF({ exportDocumentVersionPDF({
variables: { variables: {
@@ -392,6 +422,15 @@ export default function DocumentDetailPage(props: Props) {
> >
{isDraft ? __("Edit draft document") : __("Create new draft")} {isDraft ? __("Edit draft document") : __("Create new draft")}
</DropdownItem> </DropdownItem>
{isDraft && versions.length > 1 && (
<DropdownItem
onClick={handleDeleteDraft}
icon={IconTrashCan}
disabled={isDeletingDraft}
>
{__("Delete draft document")}
</DropdownItem>
)}
<DropdownItem <DropdownItem
onClick={handleDownloadPdf} onClick={handleDownloadPdf}
icon={IconArrowDown} icon={IconArrowDown}
@@ -405,7 +444,7 @@ export default function DocumentDetailPage(props: Props) {
disabled={isDeleting} disabled={isDeleting}
onClick={handleDelete} onClick={handleDelete}
> >
{__("Delete")} {__("Delete document")}
</DropdownItem> </DropdownItem>
</ActionDropdown> </ActionDropdown>
</div> </div>

View File

@@ -227,7 +227,6 @@ const rowFragment = graphql`
function DocumentRow({ function DocumentRow({
document: documentKey, document: documentKey,
organizationId, organizationId,
connectionId,
checked, checked,
onCheck, onCheck,
}: { }: {
@@ -257,7 +256,6 @@ function DocumentRow({
deleteDocument({ deleteDocument({
variables: { variables: {
input: { documentId: document.id }, input: { documentId: document.id },
connections: [connectionId],
}, },
}), }),
{ {

View File

@@ -101,28 +101,6 @@ export default function UpdateVersionDialog({
ref.current = { ref.current = {
open: () => { open: () => {
dialogRef.current?.open(); dialogRef.current?.open();
if (!isDraft) {
createDraftDocumentVersion({
variables: {
input: {
documentID: document.id,
},
connections: [connectionId],
},
onCompleted: (_, errors) => {
if (errors) {
toast({
variant: "error",
title: __("Error creating draft"),
description:
errors[0]?.message || __("An unknown error occurred"),
});
dialogRef.current?.close();
return;
}
},
});
}
}, },
}; };
@@ -131,25 +109,65 @@ export default function UpdateVersionDialog({
} }
const onSubmit = handleSubmit((data) => { const onSubmit = handleSubmit((data) => {
updateDocumentVersion({ if (isDraft) {
variables: { updateDocumentVersion({
input: { variables: {
documentVersionId: version.id, input: {
content: data.content, documentVersionId: version.id,
content: data.content,
},
}, },
}, onSuccess: () => {
onSuccess: () => { dialogRef.current?.close();
dialogRef.current?.close(); },
}, });
}); } else {
createDraftDocumentVersion({
variables: {
input: {
documentID: document.id,
},
connections: [connectionId],
},
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) {
updateDocumentVersion({
variables: {
input: {
documentVersionId: newVersionId,
content: data.content,
},
},
onSuccess: () => {
dialogRef.current?.close();
},
});
} else {
dialogRef.current?.close();
}
},
});
}
}); });
const isLoading = isCreatingDraft || isUpdating;
return ( return (
<Dialog <Dialog
ref={dialogRef} ref={dialogRef}
title={<Breadcrumb items={[__("Documents"), __("Edit document")]} />} title={<Breadcrumb items={[__("Documents"), __("Edit document")]} />}
> >
{isCreatingDraft && <Spinner centered />}
<form onSubmit={onSubmit}> <form onSubmit={onSubmit}>
<DialogContent> <DialogContent>
<Textarea <Textarea
@@ -164,7 +182,8 @@ export default function UpdateVersionDialog({
/> />
</DialogContent> </DialogContent>
<DialogFooter> <DialogFooter>
<Button disabled={isUpdating} type="submit"> <Button disabled={isLoading} type="submit">
{isLoading && <Spinner />}
{__("Update document")} {__("Update document")}
</Button> </Button>
</DialogFooter> </DialogFooter>

View File

@@ -415,3 +415,29 @@ WHERE %s
return nil return nil
} }
func (p DocumentVersion) Delete(
ctx context.Context,
conn pg.Conn,
scope Scoper,
) error {
q := `
DELETE FROM document_versions
WHERE %s
AND id = @document_version_id
`
q = fmt.Sprintf(q, scope.SQLFragment())
args := pgx.NamedArgs{
"document_version_id": p.ID,
}
maps.Copy(args, scope.SQLArguments())
_, err := conn.Exec(ctx, q, args)
if err != nil {
return fmt.Errorf("cannot delete document version: %w", err)
}
return nil
}

View File

@@ -770,6 +770,36 @@ func (s *DocumentService) CreateDraft(
return draftVersion, nil return draftVersion, nil
} }
func (s *DocumentService) DeleteDraft(
ctx context.Context,
documentVersionID gid.GID,
) error {
documentVersion := &coredata.DocumentVersion{}
return s.svc.pg.WithTx(
ctx,
func(conn pg.Conn) error {
if err := documentVersion.LoadByID(ctx, conn, s.svc.scope, documentVersionID); err != nil {
return fmt.Errorf("cannot load document version: %w", err)
}
if documentVersion.Status != coredata.DocumentStatusDraft {
return fmt.Errorf("cannot delete published document version")
}
if documentVersion.VersionNumber == 1 {
return fmt.Errorf("cannot delete the first version of a document")
}
if err := documentVersion.Delete(ctx, conn, s.svc.scope); err != nil {
return fmt.Errorf("cannot delete document version: %w", err)
}
return nil
},
)
}
func (s *DocumentService) Delete( func (s *DocumentService) Delete(
ctx context.Context, ctx context.Context,
documentID gid.GID, documentID gid.GID,

View File

@@ -1604,6 +1604,9 @@ type Mutation {
createDraftDocumentVersion( createDraftDocumentVersion(
input: CreateDraftDocumentVersionInput! input: CreateDraftDocumentVersionInput!
): CreateDraftDocumentVersionPayload! ): CreateDraftDocumentVersionPayload!
deleteDraftDocumentVersion(
input: DeleteDraftDocumentVersionInput!
): DeleteDraftDocumentVersionPayload!
updateDocumentVersion( updateDocumentVersion(
input: UpdateDocumentVersionInput! input: UpdateDocumentVersionInput!
): UpdateDocumentVersionPayload! ): UpdateDocumentVersionPayload!
@@ -2427,10 +2430,18 @@ type CreateDraftDocumentVersionPayload {
documentVersionEdge: DocumentVersionEdge! documentVersionEdge: DocumentVersionEdge!
} }
type DeleteDraftDocumentVersionPayload {
deletedDocumentVersionId: ID!
}
input CreateDraftDocumentVersionInput { input CreateDraftDocumentVersionInput {
documentID: ID! documentID: ID!
} }
input DeleteDraftDocumentVersionInput {
documentVersionId: ID!
}
input UpdateDocumentVersionInput { input UpdateDocumentVersionInput {
documentVersionId: ID! documentVersionId: ID!
content: String! content: String!

View File

@@ -343,6 +343,10 @@ type ComplexityRoot struct {
DeletedDocumentID func(childComplexity int) int DeletedDocumentID func(childComplexity int) int
} }
DeleteDraftDocumentVersionPayload struct {
DeletedDocumentVersionID func(childComplexity int) int
}
DeleteEvidencePayload struct { DeleteEvidencePayload struct {
DeletedEvidenceID func(childComplexity int) int DeletedEvidenceID func(childComplexity int) int
} }
@@ -602,6 +606,7 @@ type ComplexityRoot struct {
DeleteControlMeasureMapping func(childComplexity int, input types.DeleteControlMeasureMappingInput) int DeleteControlMeasureMapping func(childComplexity int, input types.DeleteControlMeasureMappingInput) int
DeleteDatum func(childComplexity int, input types.DeleteDatumInput) int DeleteDatum func(childComplexity int, input types.DeleteDatumInput) int
DeleteDocument func(childComplexity int, input types.DeleteDocumentInput) int DeleteDocument func(childComplexity int, input types.DeleteDocumentInput) int
DeleteDraftDocumentVersion func(childComplexity int, input types.DeleteDraftDocumentVersionInput) int
DeleteEvidence func(childComplexity int, input types.DeleteEvidenceInput) int DeleteEvidence func(childComplexity int, input types.DeleteEvidenceInput) int
DeleteFramework func(childComplexity int, input types.DeleteFrameworkInput) int DeleteFramework func(childComplexity int, input types.DeleteFrameworkInput) int
DeleteMeasure func(childComplexity int, input types.DeleteMeasureInput) int DeleteMeasure func(childComplexity int, input types.DeleteMeasureInput) int
@@ -1179,6 +1184,7 @@ type MutationResolver interface {
BulkPublishDocumentVersions(ctx context.Context, input types.BulkPublishDocumentVersionsInput) (*types.BulkPublishDocumentVersionsPayload, error) BulkPublishDocumentVersions(ctx context.Context, input types.BulkPublishDocumentVersionsInput) (*types.BulkPublishDocumentVersionsPayload, error)
GenerateDocumentChangelog(ctx context.Context, input types.GenerateDocumentChangelogInput) (*types.GenerateDocumentChangelogPayload, error) GenerateDocumentChangelog(ctx context.Context, input types.GenerateDocumentChangelogInput) (*types.GenerateDocumentChangelogPayload, error)
CreateDraftDocumentVersion(ctx context.Context, input types.CreateDraftDocumentVersionInput) (*types.CreateDraftDocumentVersionPayload, error) CreateDraftDocumentVersion(ctx context.Context, input types.CreateDraftDocumentVersionInput) (*types.CreateDraftDocumentVersionPayload, error)
DeleteDraftDocumentVersion(ctx context.Context, input types.DeleteDraftDocumentVersionInput) (*types.DeleteDraftDocumentVersionPayload, error)
UpdateDocumentVersion(ctx context.Context, input types.UpdateDocumentVersionInput) (*types.UpdateDocumentVersionPayload, error) UpdateDocumentVersion(ctx context.Context, input types.UpdateDocumentVersionInput) (*types.UpdateDocumentVersionPayload, error)
RequestSignature(ctx context.Context, input types.RequestSignatureInput) (*types.RequestSignaturePayload, error) RequestSignature(ctx context.Context, input types.RequestSignatureInput) (*types.RequestSignaturePayload, error)
BulkRequestSignatures(ctx context.Context, input types.BulkRequestSignaturesInput) (*types.BulkRequestSignaturesPayload, error) BulkRequestSignatures(ctx context.Context, input types.BulkRequestSignaturesInput) (*types.BulkRequestSignaturesPayload, error)
@@ -2100,6 +2106,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.DeleteDocumentPayload.DeletedDocumentID(childComplexity), true return e.complexity.DeleteDocumentPayload.DeletedDocumentID(childComplexity), true
case "DeleteDraftDocumentVersionPayload.deletedDocumentVersionId":
if e.complexity.DeleteDraftDocumentVersionPayload.DeletedDocumentVersionID == nil {
break
}
return e.complexity.DeleteDraftDocumentVersionPayload.DeletedDocumentVersionID(childComplexity), true
case "DeleteEvidencePayload.deletedEvidenceId": case "DeleteEvidencePayload.deletedEvidenceId":
if e.complexity.DeleteEvidencePayload.DeletedEvidenceID == nil { if e.complexity.DeleteEvidencePayload.DeletedEvidenceID == nil {
break break
@@ -3334,6 +3347,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.Mutation.DeleteDocument(childComplexity, args["input"].(types.DeleteDocumentInput)), true return e.complexity.Mutation.DeleteDocument(childComplexity, args["input"].(types.DeleteDocumentInput)), true
case "Mutation.deleteDraftDocumentVersion":
if e.complexity.Mutation.DeleteDraftDocumentVersion == nil {
break
}
args, err := ec.field_Mutation_deleteDraftDocumentVersion_args(ctx, rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.DeleteDraftDocumentVersion(childComplexity, args["input"].(types.DeleteDraftDocumentVersionInput)), true
case "Mutation.deleteEvidence": case "Mutation.deleteEvidence":
if e.complexity.Mutation.DeleteEvidence == nil { if e.complexity.Mutation.DeleteEvidence == nil {
break break
@@ -5495,6 +5520,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
ec.unmarshalInputDeleteControlMeasureMappingInput, ec.unmarshalInputDeleteControlMeasureMappingInput,
ec.unmarshalInputDeleteDatumInput, ec.unmarshalInputDeleteDatumInput,
ec.unmarshalInputDeleteDocumentInput, ec.unmarshalInputDeleteDocumentInput,
ec.unmarshalInputDeleteDraftDocumentVersionInput,
ec.unmarshalInputDeleteEvidenceInput, ec.unmarshalInputDeleteEvidenceInput,
ec.unmarshalInputDeleteFrameworkInput, ec.unmarshalInputDeleteFrameworkInput,
ec.unmarshalInputDeleteMeasureInput, ec.unmarshalInputDeleteMeasureInput,
@@ -7262,6 +7288,9 @@ type Mutation {
createDraftDocumentVersion( createDraftDocumentVersion(
input: CreateDraftDocumentVersionInput! input: CreateDraftDocumentVersionInput!
): CreateDraftDocumentVersionPayload! ): CreateDraftDocumentVersionPayload!
deleteDraftDocumentVersion(
input: DeleteDraftDocumentVersionInput!
): DeleteDraftDocumentVersionPayload!
updateDocumentVersion( updateDocumentVersion(
input: UpdateDocumentVersionInput! input: UpdateDocumentVersionInput!
): UpdateDocumentVersionPayload! ): UpdateDocumentVersionPayload!
@@ -8085,10 +8114,18 @@ type CreateDraftDocumentVersionPayload {
documentVersionEdge: DocumentVersionEdge! documentVersionEdge: DocumentVersionEdge!
} }
type DeleteDraftDocumentVersionPayload {
deletedDocumentVersionId: ID!
}
input CreateDraftDocumentVersionInput { input CreateDraftDocumentVersionInput {
documentID: ID! documentID: ID!
} }
input DeleteDraftDocumentVersionInput {
documentVersionId: ID!
}
input UpdateDocumentVersionInput { input UpdateDocumentVersionInput {
documentVersionId: ID! documentVersionId: ID!
content: String! content: String!
@@ -10338,6 +10375,29 @@ func (ec *executionContext) field_Mutation_deleteDocument_argsInput(
return zeroVal, nil return zeroVal, nil
} }
func (ec *executionContext) field_Mutation_deleteDraftDocumentVersion_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
args := map[string]any{}
arg0, err := ec.field_Mutation_deleteDraftDocumentVersion_argsInput(ctx, rawArgs)
if err != nil {
return nil, err
}
args["input"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_deleteDraftDocumentVersion_argsInput(
ctx context.Context,
rawArgs map[string]any,
) (types.DeleteDraftDocumentVersionInput, error) {
ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input"))
if tmp, ok := rawArgs["input"]; ok {
return ec.unmarshalNDeleteDraftDocumentVersionInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteDraftDocumentVersionInput(ctx, tmp)
}
var zeroVal types.DeleteDraftDocumentVersionInput
return zeroVal, nil
}
func (ec *executionContext) field_Mutation_deleteEvidence_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { func (ec *executionContext) field_Mutation_deleteEvidence_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error var err error
args := map[string]any{} args := map[string]any{}
@@ -19385,6 +19445,50 @@ func (ec *executionContext) fieldContext_DeleteDocumentPayload_deletedDocumentId
return fc, nil return fc, nil
} }
func (ec *executionContext) _DeleteDraftDocumentVersionPayload_deletedDocumentVersionId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteDraftDocumentVersionPayload) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_DeleteDraftDocumentVersionPayload_deletedDocumentVersionId(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DeletedDocumentVersionID, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(gid.GID)
fc.Result = res
return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_DeleteDraftDocumentVersionPayload_deletedDocumentVersionId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "DeleteDraftDocumentVersionPayload",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type ID does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _DeleteEvidencePayload_deletedEvidenceId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteEvidencePayload) (ret graphql.Marshaler) { func (ec *executionContext) _DeleteEvidencePayload_deletedEvidenceId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteEvidencePayload) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_DeleteEvidencePayload_deletedEvidenceId(ctx, field) fc, err := ec.fieldContext_DeleteEvidencePayload_deletedEvidenceId(ctx, field)
if err != nil { if err != nil {
@@ -28463,6 +28567,65 @@ func (ec *executionContext) fieldContext_Mutation_createDraftDocumentVersion(ctx
return fc, nil return fc, nil
} }
func (ec *executionContext) _Mutation_deleteDraftDocumentVersion(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Mutation_deleteDraftDocumentVersion(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().DeleteDraftDocumentVersion(rctx, fc.Args["input"].(types.DeleteDraftDocumentVersionInput))
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*types.DeleteDraftDocumentVersionPayload)
fc.Result = res
return ec.marshalNDeleteDraftDocumentVersionPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteDraftDocumentVersionPayload(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_deleteDraftDocumentVersion(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Mutation",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "deletedDocumentVersionId":
return ec.fieldContext_DeleteDraftDocumentVersionPayload_deletedDocumentVersionId(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type DeleteDraftDocumentVersionPayload", field.Name)
},
}
defer func() {
if r := recover(); r != nil {
err = ec.Recover(ctx, r)
ec.Error(ctx, err)
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
if fc.Args, err = ec.field_Mutation_deleteDraftDocumentVersion_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return fc, err
}
return fc, nil
}
func (ec *executionContext) _Mutation_updateDocumentVersion(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { func (ec *executionContext) _Mutation_updateDocumentVersion(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Mutation_updateDocumentVersion(ctx, field) fc, err := ec.fieldContext_Mutation_updateDocumentVersion(ctx, field)
if err != nil { if err != nil {
@@ -44442,6 +44605,33 @@ func (ec *executionContext) unmarshalInputDeleteDocumentInput(ctx context.Contex
return it, nil return it, nil
} }
func (ec *executionContext) unmarshalInputDeleteDraftDocumentVersionInput(ctx context.Context, obj any) (types.DeleteDraftDocumentVersionInput, error) {
var it types.DeleteDraftDocumentVersionInput
asMap := map[string]any{}
for k, v := range obj.(map[string]any) {
asMap[k] = v
}
fieldsInOrder := [...]string{"documentVersionId"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
continue
}
switch k {
case "documentVersionId":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("documentVersionId"))
data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
if err != nil {
return it, err
}
it.DocumentVersionID = data
}
}
return it, nil
}
func (ec *executionContext) unmarshalInputDeleteEvidenceInput(ctx context.Context, obj any) (types.DeleteEvidenceInput, error) { func (ec *executionContext) unmarshalInputDeleteEvidenceInput(ctx context.Context, obj any) (types.DeleteEvidenceInput, error) {
var it types.DeleteEvidenceInput var it types.DeleteEvidenceInput
asMap := map[string]any{} asMap := map[string]any{}
@@ -49915,6 +50105,45 @@ func (ec *executionContext) _DeleteDocumentPayload(ctx context.Context, sel ast.
return out return out
} }
var deleteDraftDocumentVersionPayloadImplementors = []string{"DeleteDraftDocumentVersionPayload"}
func (ec *executionContext) _DeleteDraftDocumentVersionPayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteDraftDocumentVersionPayload) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, deleteDraftDocumentVersionPayloadImplementors)
out := graphql.NewFieldSet(fields)
deferred := make(map[string]*graphql.FieldSet)
for i, field := range fields {
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("DeleteDraftDocumentVersionPayload")
case "deletedDocumentVersionId":
out.Values[i] = ec._DeleteDraftDocumentVersionPayload_deletedDocumentVersionId(ctx, field, obj)
if out.Values[i] == graphql.Null {
out.Invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch(ctx)
if out.Invalids > 0 {
return graphql.Null
}
atomic.AddInt32(&ec.deferred, int32(len(deferred)))
for label, dfs := range deferred {
ec.processDeferredGroup(graphql.DeferredGroup{
Label: label,
Path: graphql.GetPath(ctx),
FieldSet: dfs,
Context: ctx,
})
}
return out
}
var deleteEvidencePayloadImplementors = []string{"DeleteEvidencePayload"} var deleteEvidencePayloadImplementors = []string{"DeleteEvidencePayload"}
func (ec *executionContext) _DeleteEvidencePayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteEvidencePayload) graphql.Marshaler { func (ec *executionContext) _DeleteEvidencePayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteEvidencePayload) graphql.Marshaler {
@@ -52884,6 +53113,13 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
out.Invalids++ out.Invalids++
} }
case "deleteDraftDocumentVersion":
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
return ec._Mutation_deleteDraftDocumentVersion(ctx, field)
})
if out.Values[i] == graphql.Null {
out.Invalids++
}
case "updateDocumentVersion": case "updateDocumentVersion":
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
return ec._Mutation_updateDocumentVersion(ctx, field) return ec._Mutation_updateDocumentVersion(ctx, field)
@@ -59143,6 +59379,25 @@ func (ec *executionContext) marshalNDeleteDocumentPayload2ᚖgithubᚗcomᚋgetp
return ec._DeleteDocumentPayload(ctx, sel, v) return ec._DeleteDocumentPayload(ctx, sel, v)
} }
func (ec *executionContext) unmarshalNDeleteDraftDocumentVersionInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteDraftDocumentVersionInput(ctx context.Context, v any) (types.DeleteDraftDocumentVersionInput, error) {
res, err := ec.unmarshalInputDeleteDraftDocumentVersionInput(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNDeleteDraftDocumentVersionPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteDraftDocumentVersionPayload(ctx context.Context, sel ast.SelectionSet, v types.DeleteDraftDocumentVersionPayload) graphql.Marshaler {
return ec._DeleteDraftDocumentVersionPayload(ctx, sel, &v)
}
func (ec *executionContext) marshalNDeleteDraftDocumentVersionPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteDraftDocumentVersionPayload(ctx context.Context, sel ast.SelectionSet, v *types.DeleteDraftDocumentVersionPayload) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
}
return graphql.Null
}
return ec._DeleteDraftDocumentVersionPayload(ctx, sel, v)
}
func (ec *executionContext) unmarshalNDeleteEvidenceInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteEvidenceInput(ctx context.Context, v any) (types.DeleteEvidenceInput, error) { func (ec *executionContext) unmarshalNDeleteEvidenceInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteEvidenceInput(ctx context.Context, v any) (types.DeleteEvidenceInput, error) {
res, err := ec.unmarshalInputDeleteEvidenceInput(ctx, v) res, err := ec.unmarshalInputDeleteEvidenceInput(ctx, v)
return res, graphql.ErrorOnPath(ctx, err) return res, graphql.ErrorOnPath(ctx, err)

View File

@@ -503,6 +503,14 @@ type DeleteDocumentPayload struct {
DeletedDocumentID gid.GID `json:"deletedDocumentId"` DeletedDocumentID gid.GID `json:"deletedDocumentId"`
} }
type DeleteDraftDocumentVersionInput struct {
DocumentVersionID gid.GID `json:"documentVersionId"`
}
type DeleteDraftDocumentVersionPayload struct {
DeletedDocumentVersionID gid.GID `json:"deletedDocumentVersionId"`
}
type DeleteEvidenceInput struct { type DeleteEvidenceInput struct {
EvidenceID gid.GID `json:"evidenceId"` EvidenceID gid.GID `json:"evidenceId"`
} }

View File

@@ -2063,6 +2063,20 @@ func (r *mutationResolver) CreateDraftDocumentVersion(ctx context.Context, input
}, nil }, nil
} }
// DeleteDraftDocumentVersion is the resolver for the deleteDraftDocumentVersion field.
func (r *mutationResolver) DeleteDraftDocumentVersion(ctx context.Context, input types.DeleteDraftDocumentVersionInput) (*types.DeleteDraftDocumentVersionPayload, error) {
prb := r.ProboService(ctx, input.DocumentVersionID.TenantID())
err := prb.Documents.DeleteDraft(ctx, input.DocumentVersionID)
if err != nil {
panic(fmt.Errorf("cannot delete draft document version: %w", err))
}
return &types.DeleteDraftDocumentVersionPayload{
DeletedDocumentVersionID: input.DocumentVersionID,
}, nil
}
// UpdateDocumentVersion is the resolver for the updateDocumentVersion field. // UpdateDocumentVersion is the resolver for the updateDocumentVersion field.
func (r *mutationResolver) UpdateDocumentVersion(ctx context.Context, input types.UpdateDocumentVersionInput) (*types.UpdateDocumentVersionPayload, error) { func (r *mutationResolver) UpdateDocumentVersion(ctx context.Context, input types.UpdateDocumentVersionInput) (*types.UpdateDocumentVersionPayload, error) {
prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) prb := r.ProboService(ctx, input.DocumentVersionID.TenantID())