@@ -2,9 +2,9 @@ import { z } from "zod";
|
||||
import { useFormWithSchema } from "../useFormWithSchema";
|
||||
|
||||
export const documentSchema = z.object({
|
||||
title: z.string(),
|
||||
content: z.string(),
|
||||
ownerId: z.string(),
|
||||
title: z.string().min(1, "Title is required"),
|
||||
content: z.string().min(1, "Content is required"),
|
||||
ownerId: z.string().min(1, "Owner is required"),
|
||||
documentType: z.enum(["OTHER", "ISMS", "POLICY", "PROCEDURE"]),
|
||||
classification: z.enum(["PUBLIC", "INTERNAL", "CONFIDENTIAL", "SECRET"]),
|
||||
});
|
||||
|
||||
@@ -32,10 +32,10 @@ export type RiskKey = useRiskFormFragment$key & { id: string };
|
||||
|
||||
// Export the schema so it can be used elsewhere
|
||||
export const riskSchema = z.object({
|
||||
category: z.string(),
|
||||
name: z.string(),
|
||||
description: z.string(),
|
||||
ownerId: z.string(),
|
||||
category: z.string().min(1, "Category is required"),
|
||||
name: z.string().min(1, "Name is required"),
|
||||
description: z.string().min(1, "Description is required"),
|
||||
ownerId: z.string().min(1, "Owner is required"),
|
||||
treatment: z.enum(["AVOIDED", "MITIGATED", "TRANSFERRED", "ACCEPTED"]),
|
||||
inherentLikelihood: z.number({ coerce: true }).min(1).max(5),
|
||||
inherentImpact: z.number({ coerce: true }).min(1).max(5),
|
||||
|
||||
@@ -8,21 +8,21 @@ import { useTranslate } from "@probo/i18n";
|
||||
import { useEffect, useMemo } from "react";
|
||||
|
||||
const schema = z.object({
|
||||
name: z.string(),
|
||||
description: z.string(),
|
||||
name: z.string().min(1, "Name is required"),
|
||||
description: z.string().min(1, "Description is required"),
|
||||
category: z.string().nullish(),
|
||||
statusPageUrl: z.string(),
|
||||
termsOfServiceUrl: z.string(),
|
||||
privacyPolicyUrl: z.string(),
|
||||
serviceLevelAgreementUrl: z.string(),
|
||||
dataProcessingAgreementUrl: z.string(),
|
||||
websiteUrl: z.string(),
|
||||
legalName: z.string(),
|
||||
headquarterAddress: z.string(),
|
||||
statusPageUrl: z.string().optional(),
|
||||
termsOfServiceUrl: z.string().optional(),
|
||||
privacyPolicyUrl: z.string().optional(),
|
||||
serviceLevelAgreementUrl: z.string().optional(),
|
||||
dataProcessingAgreementUrl: z.string().optional(),
|
||||
websiteUrl: z.string().optional(),
|
||||
legalName: z.string().optional(),
|
||||
headquarterAddress: z.string().optional(),
|
||||
certifications: z.array(z.string()),
|
||||
countries: z.array(z.string()),
|
||||
securityPageUrl: z.string(),
|
||||
trustPageUrl: z.string(),
|
||||
securityPageUrl: z.string().optional(),
|
||||
trustPageUrl: z.string().optional(),
|
||||
businessOwnerId: z.string().nullish(),
|
||||
securityOwnerId: z.string().nullish(),
|
||||
});
|
||||
@@ -70,7 +70,7 @@ export function useVendorForm(vendorKey: useVendorFormFragment$key) {
|
||||
|
||||
const [mutate] = useMutationWithToasts(vendorUpdateQuery, {
|
||||
successMessage: __("Vendor updated successfully."),
|
||||
errorMessage: __("Failed to update vendor. Please try again."),
|
||||
errorMessage: __("Failed to update vendor"),
|
||||
});
|
||||
|
||||
const defaultValues = useMemo(
|
||||
|
||||
@@ -34,7 +34,7 @@ export function useDeleteDocumentMutation() {
|
||||
deleteDocumentMutation,
|
||||
{
|
||||
successMessage: __("Document deleted successfully."),
|
||||
errorMessage: __("Failed to delete document. Please try again."),
|
||||
errorMessage: __("Failed to delete document"),
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -57,7 +57,7 @@ export function useDeleteDraftDocumentVersionMutation() {
|
||||
deleteDraftDocumentVersionMutation,
|
||||
{
|
||||
successMessage: __("Draft deleted successfully."),
|
||||
errorMessage: __("Failed to delete draft. Please try again."),
|
||||
errorMessage: __("Failed to delete draft"),
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -79,7 +79,7 @@ export function useBulkDeleteDocumentsMutation() {
|
||||
bulkDeleteDocumentsMutation,
|
||||
{
|
||||
successMessage: __("Documents deleted successfully."),
|
||||
errorMessage: __("Failed to delete documents. Please try again."),
|
||||
errorMessage: __("Failed to delete documents"),
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -101,7 +101,7 @@ export function useSendSigningNotificationsMutation() {
|
||||
sendSigningNotificationsMutation,
|
||||
{
|
||||
successMessage: __("Signing notifications sent successfully."),
|
||||
errorMessage: __("Failed to send signing notifications. Please try again."),
|
||||
errorMessage: __("Failed to send signing notifications"),
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -123,7 +123,7 @@ export function useBulkExportDocumentsMutation() {
|
||||
bulkExportDocumentsMutation,
|
||||
{
|
||||
successMessage: __("Document export started successfully. You will receive an email when the export is ready."),
|
||||
errorMessage: __("Failed to start document export. Please try again."),
|
||||
errorMessage: __("Failed to start document export"),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ export function useDeleteMeasureMutation() {
|
||||
deleteMeasureMutation,
|
||||
{
|
||||
successMessage: __("Measure deleted successfully."),
|
||||
errorMessage: __("Failed to delete measure. Please try again."),
|
||||
errorMessage: __("Failed to delete measure"),
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -83,6 +83,6 @@ export const useUpdateMeasure = () => {
|
||||
|
||||
return useMutationWithToasts(measureUpdateMutation, {
|
||||
successMessage: __("Measure updated successfully."),
|
||||
errorMessage: __("Failed to update measure. Please try again."),
|
||||
errorMessage: __("Failed to update measure"),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@ export function useDeleteOrganizationMutation() {
|
||||
deleteOrganizationMutation,
|
||||
{
|
||||
successMessage: __("Organization deleted successfully."),
|
||||
errorMessage: __("Failed to delete organization. Please try again."),
|
||||
errorMessage: __("Failed to delete organization"),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import {
|
||||
import { useMemo } from "react";
|
||||
import type { PeopleGraphPaginatedQuery } from "./__generated__/PeopleGraphPaginatedQuery.graphql";
|
||||
import type { PeopleGraphPaginatedFragment$key } from "./__generated__/PeopleGraphPaginatedFragment.graphql";
|
||||
import { useConfirm } from "@probo/ui";
|
||||
import { useConfirm, useToast } from "@probo/ui";
|
||||
import type { PeopleGraphDeleteMutation } from "./__generated__/PeopleGraphDeleteMutation.graphql";
|
||||
import { promisifyMutation, sprintf } from "@probo/helpers";
|
||||
import { promisifyMutation, sprintf, formatError, type GraphQLError } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
|
||||
const peopleQuery = graphql`
|
||||
@@ -132,6 +132,7 @@ export const useDeletePeople = (
|
||||
) => {
|
||||
const [mutate] = useMutation<PeopleGraphDeleteMutation>(deletePeopleMutation);
|
||||
const confirm = useConfirm();
|
||||
const { toast } = useToast();
|
||||
const { __ } = useTranslate();
|
||||
|
||||
return () => {
|
||||
@@ -147,6 +148,12 @@ export const useDeletePeople = (
|
||||
},
|
||||
connections: [connectionId],
|
||||
},
|
||||
}).catch((error) => {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: formatError(__("Failed to delete people"), error as GraphQLError),
|
||||
variant: "error",
|
||||
});
|
||||
}),
|
||||
{
|
||||
message: sprintf(
|
||||
|
||||
@@ -26,7 +26,7 @@ export function useDeleteRiskMutation() {
|
||||
|
||||
return useMutationWithToasts<RiskGraphDeleteMutation>(deleteRiskMutation, {
|
||||
successMessage: __("Risk deleted successfully."),
|
||||
errorMessage: __("Failed to delete risk. Please try again."),
|
||||
errorMessage: __("Failed to delete risk"),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ export function useCreateSAMLConfigurationMutation() {
|
||||
createSAMLConfigurationMutation,
|
||||
{
|
||||
successMessage: "SAML configuration created successfully.",
|
||||
errorMessage: "Failed to create SAML configuration. Please try again.",
|
||||
errorMessage: "Failed to create SAML configuration",
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export function useTrustCenterAuditUpdate() {
|
||||
trustCenterAuditUpdateMutation,
|
||||
{
|
||||
successMessage: __("Audit visibility updated successfully."),
|
||||
errorMessage: __("Failed to update audit visibility. Please try again."),
|
||||
errorMessage: __("Failed to update audit visibility"),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ export function useUpdateDocumentVisibilityMutation() {
|
||||
updateDocumentVisibilityMutation,
|
||||
{
|
||||
successMessage: __("Document visibility updated successfully."),
|
||||
errorMessage: __("Failed to update document visibility. Please try again."),
|
||||
errorMessage: __("Failed to update document visibility"),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export function useTrustCenterVendorUpdate() {
|
||||
trustCenterVendorUpdateMutation,
|
||||
{
|
||||
successMessage: __("Vendor visibility updated successfully."),
|
||||
errorMessage: __("Failed to update vendor visibility. Please try again."),
|
||||
errorMessage: __("Failed to update vendor visibility"),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ export function useCreateVendorMutation() {
|
||||
createVendorMutation,
|
||||
{
|
||||
successMessage: __("Vendor created successfully."),
|
||||
errorMessage: __("Failed to create vendor. Please try again."),
|
||||
errorMessage: __("Failed to create vendor"),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@ import {
|
||||
type GraphQLTaggedNode,
|
||||
type MutationParameters,
|
||||
} from "relay-runtime";
|
||||
import { useToast } from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { formatError, type GraphQLError } from "@probo/helpers";
|
||||
|
||||
const defaultOptions = {
|
||||
field: "totalCount",
|
||||
@@ -26,17 +29,27 @@ export function useMutationWithIncrement<T extends MutationParameters>(
|
||||
node: string;
|
||||
field?: string;
|
||||
value?: 1 | -1;
|
||||
errorMessage?: string;
|
||||
},
|
||||
) {
|
||||
const [mutate, isLoading] = useMutation<T>(query);
|
||||
const relayEnv = useRelayEnvironment();
|
||||
const { toast } = useToast();
|
||||
const { __ } = useTranslate();
|
||||
const options = { ...defaultOptions, ...baseOptions };
|
||||
const mutateAndIncrement = useCallback(
|
||||
(queryOptions: UseMutationConfig<T>) => {
|
||||
return mutate({
|
||||
...queryOptions,
|
||||
onCompleted: (response, error) => {
|
||||
if (!error) {
|
||||
if (error) {
|
||||
const errorTitle = options.errorMessage ?? __("Failed to commit this operation");
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: formatError(errorTitle, error as GraphQLError[]),
|
||||
variant: "error",
|
||||
});
|
||||
} else {
|
||||
updateStoreCounter(
|
||||
relayEnv,
|
||||
options.id,
|
||||
@@ -47,9 +60,18 @@ export function useMutationWithIncrement<T extends MutationParameters>(
|
||||
}
|
||||
queryOptions.onCompleted?.(response, error);
|
||||
},
|
||||
onError: (error) => {
|
||||
const errorTitle = options.errorMessage ?? __("Failed to commit this operation");
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: formatError(errorTitle, error as GraphQLError),
|
||||
variant: "error",
|
||||
});
|
||||
queryOptions.onError?.(error);
|
||||
},
|
||||
});
|
||||
},
|
||||
[mutate, options.id, options.node, options.field, options.value, relayEnv],
|
||||
[mutate, options.id, options.node, options.field, options.value, options.errorMessage, relayEnv, toast, __],
|
||||
);
|
||||
|
||||
return [mutateAndIncrement, isLoading] as const;
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useMutation, type UseMutationConfig } from "react-relay";
|
||||
import { useToast } from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import type { MutationParameters, GraphQLTaggedNode } from "relay-runtime";
|
||||
import { formatError, type GraphQLError } from "@probo/helpers";
|
||||
|
||||
/**
|
||||
* A decorated useMutation hook that emits toast notifications on success or error.
|
||||
@@ -32,11 +33,10 @@ export function useMutationWithToasts<T extends MutationParameters>(
|
||||
onCompleted: (response, error) => {
|
||||
options.onCompleted?.(response, error);
|
||||
if (error) {
|
||||
const errorTitle = options.errorMessage ?? __("Failed to commit this operation");
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description:
|
||||
options.errorMessage ??
|
||||
__("Failed to commit this operation."),
|
||||
description: formatError(errorTitle, error as GraphQLError[]),
|
||||
variant: "error",
|
||||
});
|
||||
reject(error);
|
||||
@@ -57,10 +57,10 @@ export function useMutationWithToasts<T extends MutationParameters>(
|
||||
resolve();
|
||||
},
|
||||
onError: (error) => {
|
||||
const errorTitle = options.errorMessage ?? __("Failed to commit this operation");
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description:
|
||||
options.errorMessage ?? __("Failed to commit this operation."),
|
||||
description: formatError(errorTitle, error as GraphQLError),
|
||||
variant: "error",
|
||||
});
|
||||
reject(error);
|
||||
|
||||
Reference in New Issue
Block a user