@@ -170,6 +170,7 @@ export const useCreateAudit = (connectionId: string) => {
|
||||
validUntil?: string;
|
||||
reportKey?: string;
|
||||
state?: string;
|
||||
file?: File | null;
|
||||
}) => {
|
||||
if (!input.organizationId) {
|
||||
return alert(__("Failed to create audit: organization is required"));
|
||||
@@ -188,9 +189,11 @@ export const useCreateAudit = (connectionId: string) => {
|
||||
validUntil: input.validUntil,
|
||||
reportKey: input.reportKey,
|
||||
state: input.state || "NOT_STARTED",
|
||||
file: input.file ? null : undefined,
|
||||
},
|
||||
connections: [connectionId],
|
||||
},
|
||||
...(input.file ? { uploadables: { "input.file": input.file } } : {}),
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
@@ -23,35 +23,15 @@ import {
|
||||
} from "@probo/ui";
|
||||
import { Suspense } from "react";
|
||||
import { type Control, Controller } from "react-hook-form";
|
||||
import { useLazyLoadQuery, useMutation } from "react-relay";
|
||||
import { useLazyLoadQuery } from "react-relay";
|
||||
import { graphql } from "relay-runtime";
|
||||
import { z } from "zod";
|
||||
|
||||
import type { CreateAuditDialogFrameworksQuery } from "#/__generated__/core/CreateAuditDialogFrameworksQuery.graphql";
|
||||
import type { CreateAuditDialogUploadReportMutation } from "#/__generated__/core/CreateAuditDialogUploadReportMutation.graphql";
|
||||
import { ControlledField } from "#/components/form/ControlledField";
|
||||
import { useCreateAudit } from "#/hooks/graph/AuditGraph";
|
||||
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
|
||||
|
||||
const uploadAuditReportMutation = graphql`
|
||||
mutation CreateAuditDialogUploadReportMutation(
|
||||
$input: UploadAuditReportInput!
|
||||
) {
|
||||
uploadAuditReport(input: $input) {
|
||||
audit {
|
||||
id
|
||||
report {
|
||||
id
|
||||
filename
|
||||
downloadUrl
|
||||
createdAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const frameworksQuery = graphql`
|
||||
query CreateAuditDialogFrameworksQuery($organizationId: ID!) {
|
||||
organization: node(id: $organizationId) {
|
||||
@@ -115,68 +95,29 @@ export function CreateAuditDialog({
|
||||
const internalRef = useDialogRef();
|
||||
const ref = externalRef ?? internalRef;
|
||||
const createAudit = useCreateAudit(connection);
|
||||
const [uploadMutate] = useMutation<CreateAuditDialogUploadReportMutation>(uploadAuditReportMutation);
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof schema>) => {
|
||||
try {
|
||||
const response = await createAudit({
|
||||
await createAudit({
|
||||
organizationId,
|
||||
frameworkId: data.frameworkId,
|
||||
name: data.name || null,
|
||||
validFrom: formatDatetime(data.validFrom),
|
||||
validUntil: formatDatetime(data.validUntil),
|
||||
state: data.state,
|
||||
file: file ?? null,
|
||||
});
|
||||
|
||||
const auditId = (response as { createAudit: { auditEdge: { node: { id: string } } } })
|
||||
.createAudit.auditEdge.node.id;
|
||||
|
||||
if (file && auditId) {
|
||||
try {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
uploadMutate({
|
||||
variables: {
|
||||
input: {
|
||||
auditId,
|
||||
file: null,
|
||||
},
|
||||
},
|
||||
uploadables: {
|
||||
"input.file": file,
|
||||
},
|
||||
onCompleted: (_response, errors) => {
|
||||
if (errors) {
|
||||
reject(errors);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
onError: error => reject(error),
|
||||
});
|
||||
});
|
||||
toast({
|
||||
title: __("Success"),
|
||||
description: __("Audit created and report uploaded successfully"),
|
||||
variant: "success",
|
||||
});
|
||||
} catch {
|
||||
toast({
|
||||
title: __("Warning"),
|
||||
description: __("Audit created but report upload failed. You can upload the report from the audit detail page."),
|
||||
variant: "warning",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
toast({
|
||||
title: __("Success"),
|
||||
description: __("Audit created successfully"),
|
||||
variant: "success",
|
||||
});
|
||||
}
|
||||
|
||||
ref.current?.close();
|
||||
reset();
|
||||
onClose?.();
|
||||
toast({
|
||||
title: __("Success"),
|
||||
description: file
|
||||
? __("Audit created and report uploaded successfully")
|
||||
: __("Audit created successfully"),
|
||||
variant: "success",
|
||||
});
|
||||
} catch (error) {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
|
||||
@@ -4459,6 +4459,7 @@ input CreateAuditInput {
|
||||
validUntil: Datetime
|
||||
state: AuditState
|
||||
trustCenterVisibility: TrustCenterVisibility
|
||||
file: Upload
|
||||
}
|
||||
|
||||
input UpdateAuditInput {
|
||||
|
||||
@@ -5338,6 +5338,27 @@ func (r *mutationResolver) CreateAudit(ctx context.Context, input types.CreateAu
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
if input.File != nil {
|
||||
uploadReq := probo.UploadAuditReportRequest{
|
||||
AuditID: audit.ID,
|
||||
File: probo.File{
|
||||
Content: input.File.File,
|
||||
Filename: input.File.Filename,
|
||||
Size: input.File.Size,
|
||||
ContentType: input.File.ContentType,
|
||||
},
|
||||
}
|
||||
|
||||
audit, err = prb.Audits.UploadReport(ctx, uploadReq)
|
||||
if err != nil {
|
||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot upload audit report", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
return &types.CreateAuditPayload{
|
||||
AuditEdge: types.NewAuditEdge(audit, coredata.AuditOrderFieldCreatedAt),
|
||||
}, nil
|
||||
|
||||
Reference in New Issue
Block a user