Add console useMutation and rename compliance graphs
Introduce the app-bound useMutation primitive and rename the trust center graph and reference hooks to compliance page, moving the shared reference dialogs alongside them. Sweep the compliance page subpages onto the new mutation hook and the compliance-portal permission strings, and strip the profile fields from the organization settings form. Signed-off-by: Bryan Frimin <bryan@probo.com>
This commit is contained in:
@@ -36,9 +36,9 @@ import { z } from "zod";
|
||||
|
||||
import type { CompliancePageReferenceListItemFragment$data } from "#/__generated__/core/CompliancePageReferenceListItemFragment.graphql";
|
||||
import {
|
||||
useCreateTrustCenterReferenceMutation,
|
||||
useUpdateTrustCenterReferenceMutation,
|
||||
} from "#/hooks/graph/TrustCenterReferenceGraph";
|
||||
useCreateCompliancePageReferenceMutation,
|
||||
useUpdateCompliancePageReferenceMutation,
|
||||
} from "#/hooks/graph/CompliancePageReferenceGraph";
|
||||
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
|
||||
|
||||
const referenceSchema = z.object({
|
||||
@@ -50,23 +50,23 @@ const referenceSchema = z.object({
|
||||
|
||||
type ReferenceFormData = z.infer<typeof referenceSchema>;
|
||||
|
||||
export type TrustCenterReferenceDialogRef = {
|
||||
openCreate: (trustCenterId: string, connectionId: string) => void;
|
||||
export type CompliancePageReferenceDialogRef = {
|
||||
openCreate: (compliancePageId: string, connectionId: string) => void;
|
||||
openEdit: (reference: CompliancePageReferenceListItemFragment$data, rank: number) => void;
|
||||
};
|
||||
|
||||
export const TrustCenterReferenceDialog = forwardRef<TrustCenterReferenceDialogRef, { children?: ReactNode }>(
|
||||
function TrustCenterReferenceDialog({ children }, ref) {
|
||||
export const CompliancePageReferenceDialog = forwardRef<CompliancePageReferenceDialogRef, { children?: ReactNode }>(
|
||||
function CompliancePageReferenceDialog({ children }, ref) {
|
||||
const { __ } = useTranslate();
|
||||
const dialogRef = useDialogRef();
|
||||
const [mode, setMode] = useState<"create" | "edit">("create");
|
||||
const [trustCenterId, setTrustCenterId] = useState<string>("");
|
||||
const [compliancePageId, setCompliancePageId] = useState<string>("");
|
||||
const [connectionId, setConnectionId] = useState<string>("");
|
||||
const [editReference, setEditReference] = useState<CompliancePageReferenceListItemFragment$data | null>(null);
|
||||
const [uploadedFile, setUploadedFile] = useState<File | null>(null);
|
||||
|
||||
const [createReference, isCreating] = useCreateTrustCenterReferenceMutation();
|
||||
const [updateReference, isUpdating] = useUpdateTrustCenterReferenceMutation();
|
||||
const [createReference, isCreating] = useCreateCompliancePageReferenceMutation();
|
||||
const [updateReference, isUpdating] = useUpdateCompliancePageReferenceMutation();
|
||||
|
||||
const { register, handleSubmit, formState: { errors }, reset } = useFormWithSchema(
|
||||
referenceSchema,
|
||||
@@ -80,9 +80,9 @@ export const TrustCenterReferenceDialog = forwardRef<TrustCenterReferenceDialogR
|
||||
);
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
openCreate: (tId: string, cId: string) => {
|
||||
openCreate: (pageId: string, cId: string) => {
|
||||
setMode("create");
|
||||
setTrustCenterId(tId);
|
||||
setCompliancePageId(pageId);
|
||||
setConnectionId(cId);
|
||||
setEditReference(null);
|
||||
setUploadedFile(null);
|
||||
@@ -123,7 +123,7 @@ export const TrustCenterReferenceDialog = forwardRef<TrustCenterReferenceDialogR
|
||||
await createReference({
|
||||
variables: {
|
||||
input: {
|
||||
trustCenterId,
|
||||
trustCenterId: compliancePageId,
|
||||
name: data.name,
|
||||
description: data.description || null,
|
||||
websiteUrl: data.websiteUrl,
|
||||
@@ -134,12 +134,11 @@ export const TrustCenterReferenceDialog = forwardRef<TrustCenterReferenceDialogR
|
||||
uploadables: {
|
||||
"input.logoFile": uploadedFile,
|
||||
},
|
||||
onSuccess: () => {
|
||||
reset();
|
||||
setUploadedFile(null);
|
||||
dialogRef.current?.close();
|
||||
},
|
||||
});
|
||||
|
||||
reset();
|
||||
setUploadedFile(null);
|
||||
dialogRef.current?.close();
|
||||
} else if (editReference) {
|
||||
const input: {
|
||||
id: string;
|
||||
@@ -169,12 +168,11 @@ export const TrustCenterReferenceDialog = forwardRef<TrustCenterReferenceDialogR
|
||||
await updateReference({
|
||||
variables: { input },
|
||||
uploadables: Object.keys(uploadables).length > 0 ? uploadables : undefined,
|
||||
onSuccess: () => {
|
||||
reset();
|
||||
setUploadedFile(null);
|
||||
dialogRef.current?.close();
|
||||
},
|
||||
});
|
||||
|
||||
reset();
|
||||
setUploadedFile(null);
|
||||
dialogRef.current?.close();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -30,8 +30,9 @@ import {
|
||||
useDialogRef,
|
||||
} from "@probo/ui";
|
||||
|
||||
import { deleteTrustCenterReferenceMutation } from "#/hooks/graph/TrustCenterReferenceGraph";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import type { CompliancePageReferenceGraphDeleteMutation } from "#/__generated__/core/CompliancePageReferenceGraphDeleteMutation.graphql";
|
||||
import { deleteCompliancePageReferenceMutation } from "#/hooks/graph/CompliancePageReferenceGraph";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
@@ -41,7 +42,7 @@ type Props = {
|
||||
onSuccess?: () => void;
|
||||
};
|
||||
|
||||
export function DeleteTrustCenterReferenceDialog({
|
||||
export function DeleteCompliancePageReferenceDialog({
|
||||
children,
|
||||
referenceId,
|
||||
referenceName,
|
||||
@@ -51,10 +52,13 @@ export function DeleteTrustCenterReferenceDialog({
|
||||
const { __ } = useTranslate();
|
||||
const ref = useDialogRef();
|
||||
|
||||
const [mutate, isDeleting] = useMutationWithToasts(deleteTrustCenterReferenceMutation, {
|
||||
successMessage: __("Reference deleted successfully"),
|
||||
errorMessage: __("Failed to delete reference"),
|
||||
});
|
||||
const [mutate, isDeleting] = useMutation<CompliancePageReferenceGraphDeleteMutation>(
|
||||
deleteCompliancePageReferenceMutation,
|
||||
{
|
||||
successMessage: __("Reference deleted successfully"),
|
||||
errorToast: __("Failed to delete reference"),
|
||||
},
|
||||
);
|
||||
|
||||
const handleDelete = async () => {
|
||||
await mutate({
|
||||
@@ -20,34 +20,40 @@
|
||||
|
||||
import { graphql } from "relay-runtime";
|
||||
|
||||
import type { TrustCenterGraphUpdateMutation } from "#/__generated__/core/TrustCenterGraphUpdateMutation.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import type { CompliancePageGraphDeleteNDAMutation } from "#/__generated__/core/CompliancePageGraphDeleteNDAMutation.graphql";
|
||||
import type { CompliancePageGraphUpdateMutation } from "#/__generated__/core/CompliancePageGraphUpdateMutation.graphql";
|
||||
import type { CompliancePageGraphUploadNDAMutation } from "#/__generated__/core/CompliancePageGraphUploadNDAMutation.graphql";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
const updateTrustCenterMutation = graphql`
|
||||
mutation TrustCenterGraphUpdateMutation($input: UpdateTrustCenterInput!) {
|
||||
const updateCompliancePageMutation = graphql`
|
||||
mutation CompliancePageGraphUpdateMutation($input: UpdateTrustCenterInput!) {
|
||||
updateTrustCenter(input: $input) {
|
||||
trustCenter {
|
||||
id
|
||||
active
|
||||
searchEngineIndexing
|
||||
description
|
||||
websiteUrl
|
||||
email
|
||||
headquarterAddress
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function useUpdateTrustCenterMutation() {
|
||||
return useMutationWithToasts<TrustCenterGraphUpdateMutation>(
|
||||
updateTrustCenterMutation,
|
||||
export function useUpdateCompliancePageMutation() {
|
||||
return useMutation<CompliancePageGraphUpdateMutation>(
|
||||
updateCompliancePageMutation,
|
||||
{
|
||||
successMessage: "Compliance Page updated successfully",
|
||||
errorMessage: "Failed to update compliance page",
|
||||
errorToast: "Failed to update compliance page",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
const uploadTrustCenterNDAMutation = graphql`
|
||||
mutation TrustCenterGraphUploadNDAMutation(
|
||||
const uploadCompliancePageNDAMutation = graphql`
|
||||
mutation CompliancePageGraphUploadNDAMutation(
|
||||
$input: UploadTrustCenterNDAInput!
|
||||
) {
|
||||
uploadTrustCenterNDA(input: $input) {
|
||||
@@ -63,15 +69,15 @@ const uploadTrustCenterNDAMutation = graphql`
|
||||
}
|
||||
`;
|
||||
|
||||
export function useUploadTrustCenterNDAMutation() {
|
||||
return useMutationWithToasts(uploadTrustCenterNDAMutation, {
|
||||
export function useUploadCompliancePageNDAMutation() {
|
||||
return useMutation<CompliancePageGraphUploadNDAMutation>(uploadCompliancePageNDAMutation, {
|
||||
successMessage: "NDA uploaded successfully",
|
||||
errorMessage: "Failed to upload NDA",
|
||||
errorToast: "Failed to upload NDA",
|
||||
});
|
||||
}
|
||||
|
||||
const deleteTrustCenterNDAMutation = graphql`
|
||||
mutation TrustCenterGraphDeleteNDAMutation(
|
||||
const deleteCompliancePageNDAMutation = graphql`
|
||||
mutation CompliancePageGraphDeleteNDAMutation(
|
||||
$input: DeleteTrustCenterNDAInput!
|
||||
) {
|
||||
deleteTrustCenterNDA(input: $input) {
|
||||
@@ -87,9 +93,9 @@ const deleteTrustCenterNDAMutation = graphql`
|
||||
}
|
||||
`;
|
||||
|
||||
export function useDeleteTrustCenterNDAMutation() {
|
||||
return useMutationWithToasts(deleteTrustCenterNDAMutation, {
|
||||
export function useDeleteCompliancePageNDAMutation() {
|
||||
return useMutation<CompliancePageGraphDeleteNDAMutation>(deleteCompliancePageNDAMutation, {
|
||||
successMessage: "NDA deleted successfully",
|
||||
errorMessage: "Failed to delete NDA",
|
||||
errorToast: "Failed to delete NDA",
|
||||
});
|
||||
}
|
||||
135
apps/console/src/hooks/graph/CompliancePageReferenceGraph.ts
Normal file
135
apps/console/src/hooks/graph/CompliancePageReferenceGraph.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
// Copyright (c) 2025-2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import type { CompliancePageReferenceGraphCreateMutation } from "#/__generated__/core/CompliancePageReferenceGraphCreateMutation.graphql";
|
||||
import type { CompliancePageReferenceGraphDeleteMutation } from "#/__generated__/core/CompliancePageReferenceGraphDeleteMutation.graphql";
|
||||
import type { CompliancePageReferenceGraphUpdateMutation } from "#/__generated__/core/CompliancePageReferenceGraphUpdateMutation.graphql";
|
||||
import type { CompliancePageReferenceGraphUpdateRankMutation } from "#/__generated__/core/CompliancePageReferenceGraphUpdateRankMutation.graphql";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
export const createCompliancePageReferenceMutation = graphql`
|
||||
mutation CompliancePageReferenceGraphCreateMutation(
|
||||
$input: CreateTrustCenterReferenceInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
createTrustCenterReference(input: $input) {
|
||||
trustCenterReferenceEdge @appendEdge(connections: $connections) {
|
||||
cursor
|
||||
node {
|
||||
id
|
||||
name
|
||||
description
|
||||
websiteUrl
|
||||
logo {
|
||||
downloadUrl
|
||||
}
|
||||
rank
|
||||
createdAt
|
||||
updatedAt
|
||||
canUpdate: permission(action: "compliance-portal:portal-reference:update")
|
||||
canDelete: permission(action: "compliance-portal:portal-reference:delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const updateCompliancePageReferenceMutation = graphql`
|
||||
mutation CompliancePageReferenceGraphUpdateMutation(
|
||||
$input: UpdateTrustCenterReferenceInput!
|
||||
) {
|
||||
updateTrustCenterReference(input: $input) {
|
||||
trustCenterReference {
|
||||
id
|
||||
name
|
||||
description
|
||||
websiteUrl
|
||||
logo {
|
||||
downloadUrl
|
||||
}
|
||||
rank
|
||||
createdAt
|
||||
updatedAt
|
||||
canUpdate: permission(action: "compliance-portal:portal-reference:update")
|
||||
canDelete: permission(action: "compliance-portal:portal-reference:delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const deleteCompliancePageReferenceMutation = graphql`
|
||||
mutation CompliancePageReferenceGraphDeleteMutation(
|
||||
$input: DeleteTrustCenterReferenceInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deleteTrustCenterReference(input: $input) {
|
||||
deletedTrustCenterReferenceId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function useCreateCompliancePageReferenceMutation() {
|
||||
return useMutation<CompliancePageReferenceGraphCreateMutation>(
|
||||
createCompliancePageReferenceMutation,
|
||||
{
|
||||
successMessage: "Reference created successfully",
|
||||
errorToast: "Failed to create reference",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function useUpdateCompliancePageReferenceMutation() {
|
||||
return useMutation<CompliancePageReferenceGraphUpdateMutation>(
|
||||
updateCompliancePageReferenceMutation,
|
||||
{
|
||||
successMessage: "Reference updated successfully",
|
||||
errorToast: "Failed to update reference",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export const updateCompliancePageReferenceRankMutation = graphql`
|
||||
mutation CompliancePageReferenceGraphUpdateRankMutation(
|
||||
$input: UpdateTrustCenterReferenceInput!
|
||||
) {
|
||||
updateTrustCenterReference(input: $input) {
|
||||
trustCenterReference {
|
||||
id
|
||||
rank
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function useUpdateCompliancePageReferenceRankMutation() {
|
||||
return useMutation<CompliancePageReferenceGraphUpdateRankMutation>(
|
||||
updateCompliancePageReferenceRankMutation,
|
||||
{
|
||||
successMessage: "Order updated successfully",
|
||||
errorToast: "Failed to update order",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function useDeleteCompliancePageReferenceMutation() {
|
||||
return useMutation<CompliancePageReferenceGraphDeleteMutation>(
|
||||
deleteCompliancePageReferenceMutation,
|
||||
{
|
||||
successMessage: "Reference deleted successfully",
|
||||
errorToast: "Failed to delete reference",
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
// Copyright (c) 2025-2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import type { TrustCenterReferenceGraphCreateMutation } from "#/__generated__/core/TrustCenterReferenceGraphCreateMutation.graphql";
|
||||
import type { TrustCenterReferenceGraphDeleteMutation } from "#/__generated__/core/TrustCenterReferenceGraphDeleteMutation.graphql";
|
||||
import type { TrustCenterReferenceGraphUpdateMutation } from "#/__generated__/core/TrustCenterReferenceGraphUpdateMutation.graphql";
|
||||
import type { TrustCenterReferenceGraphUpdateRankMutation } from "#/__generated__/core/TrustCenterReferenceGraphUpdateRankMutation.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
|
||||
export const createTrustCenterReferenceMutation = graphql`
|
||||
mutation TrustCenterReferenceGraphCreateMutation(
|
||||
$input: CreateTrustCenterReferenceInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
createTrustCenterReference(input: $input) {
|
||||
trustCenterReferenceEdge @appendEdge(connections: $connections) {
|
||||
cursor
|
||||
node {
|
||||
id
|
||||
name
|
||||
description
|
||||
websiteUrl
|
||||
logo {
|
||||
downloadUrl
|
||||
}
|
||||
rank
|
||||
createdAt
|
||||
updatedAt
|
||||
canUpdate: permission(action: "core:trust-center-reference:update")
|
||||
canDelete: permission(action: "core:trust-center-reference:delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const updateTrustCenterReferenceMutation = graphql`
|
||||
mutation TrustCenterReferenceGraphUpdateMutation(
|
||||
$input: UpdateTrustCenterReferenceInput!
|
||||
) {
|
||||
updateTrustCenterReference(input: $input) {
|
||||
trustCenterReference {
|
||||
id
|
||||
name
|
||||
description
|
||||
websiteUrl
|
||||
logo {
|
||||
downloadUrl
|
||||
}
|
||||
rank
|
||||
createdAt
|
||||
updatedAt
|
||||
canUpdate: permission(action: "core:trust-center-reference:update")
|
||||
canDelete: permission(action: "core:trust-center-reference:delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const deleteTrustCenterReferenceMutation = graphql`
|
||||
mutation TrustCenterReferenceGraphDeleteMutation(
|
||||
$input: DeleteTrustCenterReferenceInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deleteTrustCenterReference(input: $input) {
|
||||
deletedTrustCenterReferenceId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function useCreateTrustCenterReferenceMutation() {
|
||||
return useMutationWithToasts<TrustCenterReferenceGraphCreateMutation>(
|
||||
createTrustCenterReferenceMutation,
|
||||
{
|
||||
successMessage: "Reference created successfully",
|
||||
errorMessage: "Failed to create reference",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function useUpdateTrustCenterReferenceMutation() {
|
||||
return useMutationWithToasts<TrustCenterReferenceGraphUpdateMutation>(
|
||||
updateTrustCenterReferenceMutation,
|
||||
{
|
||||
successMessage: "Reference updated successfully",
|
||||
errorMessage: "Failed to update reference",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export const updateTrustCenterReferenceRankMutation = graphql`
|
||||
mutation TrustCenterReferenceGraphUpdateRankMutation(
|
||||
$input: UpdateTrustCenterReferenceInput!
|
||||
) {
|
||||
updateTrustCenterReference(input: $input) {
|
||||
trustCenterReference {
|
||||
id
|
||||
rank
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function useUpdateTrustCenterReferenceRankMutation() {
|
||||
return useMutationWithToasts<TrustCenterReferenceGraphUpdateRankMutation>(
|
||||
updateTrustCenterReferenceRankMutation,
|
||||
{
|
||||
successMessage: "Order updated successfully",
|
||||
errorMessage: "Failed to update order",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function useDeleteTrustCenterReferenceMutation() {
|
||||
return useMutationWithToasts<TrustCenterReferenceGraphDeleteMutation>(
|
||||
deleteTrustCenterReferenceMutation,
|
||||
{
|
||||
successMessage: "Reference deleted successfully",
|
||||
errorMessage: "Failed to delete reference",
|
||||
},
|
||||
);
|
||||
}
|
||||
53
apps/console/src/lib/relay/useMutation.ts
Normal file
53
apps/console/src/lib/relay/useMutation.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
import { formatError } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { createUseMutation, type MutationNotifier } from "@probo/relay";
|
||||
import { useToast } from "@probo/ui";
|
||||
import { useMemo } from "react";
|
||||
|
||||
/**
|
||||
* Binds the shared awaitable useMutation (`@probo/relay`) to this app's
|
||||
* feedback stack: `@probo/ui` toasts, i18n titles, and `formatError`
|
||||
* descriptions. This is the only place those opinions are wired.
|
||||
*
|
||||
* Always import useMutation from `#/lib/relay/useMutation` — never useMutation
|
||||
* from react-relay.
|
||||
*/
|
||||
function useMutationNotifier(): MutationNotifier {
|
||||
const { toast } = useToast();
|
||||
const { __ } = useTranslate();
|
||||
|
||||
return useMemo<MutationNotifier>(
|
||||
() => ({
|
||||
notifySuccess: (title) => {
|
||||
toast({ title, description: "", variant: "success" });
|
||||
},
|
||||
notifyError: (error, title) => {
|
||||
const finalTitle = title ?? __("Error");
|
||||
toast({
|
||||
title: finalTitle,
|
||||
description: formatError(finalTitle, error),
|
||||
variant: "error",
|
||||
});
|
||||
},
|
||||
}),
|
||||
[toast, __],
|
||||
);
|
||||
}
|
||||
|
||||
export type { MutationFeedback } from "@probo/relay";
|
||||
|
||||
export const useMutation = createUseMutation(useMutationNotifier);
|
||||
@@ -68,7 +68,7 @@ const fragment = graphql`
|
||||
action: "core:processing-activity:list"
|
||||
)
|
||||
canListRightsRequests: permission(action: "core:rights-request:list")
|
||||
canGetTrustCenter: permission(action: "core:trust-center:get")
|
||||
canGetCompliancePage: permission(action: "compliance-portal:portal:get")
|
||||
canListCookieBanners: permission(action: "core:cookie-banner:list")
|
||||
canUpdateOrganization: permission(action: "iam:organization:update")
|
||||
canListStatementsOfApplicability: permission(
|
||||
@@ -212,7 +212,7 @@ export function Sidebar(props: { fKey: SidebarFragment$key }) {
|
||||
to={`${prefix}/access-reviews`}
|
||||
/>
|
||||
)}
|
||||
{organization.canGetTrustCenter && (
|
||||
{organization.canGetCompliancePage && (
|
||||
<SidebarItem
|
||||
label={__("Compliance Page")}
|
||||
icon={IconShield}
|
||||
|
||||
@@ -31,7 +31,6 @@ import {
|
||||
IconTrashCan,
|
||||
Label,
|
||||
Spinner,
|
||||
Textarea,
|
||||
useDialogRef,
|
||||
} from "@probo/ui";
|
||||
import { type ChangeEventHandler, useState } from "react";
|
||||
@@ -53,10 +52,6 @@ const fragment = graphql`
|
||||
horizontalLogo {
|
||||
downloadUrl
|
||||
}
|
||||
description
|
||||
websiteUrl
|
||||
email
|
||||
headquarterAddress
|
||||
canUpdate: permission(action: "iam:organization:update")
|
||||
}
|
||||
`;
|
||||
@@ -73,10 +68,6 @@ const updateOrganizationMutation = graphql`
|
||||
horizontalLogo {
|
||||
downloadUrl
|
||||
}
|
||||
description
|
||||
websiteUrl
|
||||
email
|
||||
headquarterAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,10 +90,6 @@ const deleteHorizontalLogoMutation = graphql`
|
||||
|
||||
const organizationSchema = z.object({
|
||||
name: z.string().min(1, "Organization name is required"),
|
||||
description: z.string().optional(),
|
||||
websiteUrl: z.string().optional(),
|
||||
email: z.string().optional(),
|
||||
headquarterAddress: z.string().optional(),
|
||||
});
|
||||
|
||||
type OrganizationFormData = z.infer<typeof organizationSchema>;
|
||||
@@ -140,10 +127,6 @@ export function OrganizationForm(props: {
|
||||
{
|
||||
defaultValues: {
|
||||
name: organization.name,
|
||||
description: organization.description || "",
|
||||
websiteUrl: organization.websiteUrl || "",
|
||||
email: organization.email || "",
|
||||
headquarterAddress: organization.headquarterAddress || "",
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -221,10 +204,6 @@ export function OrganizationForm(props: {
|
||||
input: {
|
||||
organizationId: organization.id,
|
||||
name: data.name,
|
||||
description: data.description || null,
|
||||
websiteUrl: data.websiteUrl || null,
|
||||
email: data.email || null,
|
||||
headquarterAddress: data.headquarterAddress || null,
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -344,43 +323,6 @@ export function OrganizationForm(props: {
|
||||
label={__("Organization name")}
|
||||
placeholder={__("Organization name")}
|
||||
/>
|
||||
<div>
|
||||
<Label>{__("Description")}</Label>
|
||||
<Textarea
|
||||
{...register("description")}
|
||||
readOnly={formState.isSubmitting || !canUpdate}
|
||||
name="description"
|
||||
placeholder={__("Brief description of your organization")}
|
||||
rows={3}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<Field
|
||||
{...register("websiteUrl")}
|
||||
readOnly={formState.isSubmitting || !canUpdate}
|
||||
name="websiteUrl"
|
||||
type="url"
|
||||
label={__("Website URL")}
|
||||
placeholder={__("https://example.com")}
|
||||
/>
|
||||
<Field
|
||||
{...register("email")}
|
||||
readOnly={formState.isSubmitting || !canUpdate}
|
||||
name="email"
|
||||
type="email"
|
||||
label={__("Email")}
|
||||
placeholder={__("contact@example.com")}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>{__("Headquarter Address")}</Label>
|
||||
<Textarea
|
||||
{...register("headquarterAddress")}
|
||||
readOnly={formState.isSubmitting || !canUpdate}
|
||||
name="headquarterAddress"
|
||||
placeholder={__("123 Main St, City, Country")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{formState.isDirty && canUpdate && (
|
||||
<div className="flex justify-end pt-6">
|
||||
|
||||
@@ -23,7 +23,9 @@ import { Field } from "@probo/ui";
|
||||
import { useCallback, useState } from "react";
|
||||
import { graphql } from "relay-runtime";
|
||||
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import type { CompliancePageAliasField_removeResourceAliasMutation } from "#/__generated__/core/CompliancePageAliasField_removeResourceAliasMutation.graphql";
|
||||
import type { CompliancePageAliasField_setResourceAliasMutation } from "#/__generated__/core/CompliancePageAliasField_setResourceAliasMutation.graphql";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
const setResourceAliasMutation = graphql`
|
||||
mutation CompliancePageAliasField_setResourceAliasMutation(
|
||||
@@ -65,18 +67,18 @@ export function CompliancePageAliasField(props: {
|
||||
setValue(alias ?? "");
|
||||
}
|
||||
|
||||
const [setResourceAlias, isSettingAlias] = useMutationWithToasts(
|
||||
const [setResourceAlias, isSettingAlias] = useMutation<CompliancePageAliasField_setResourceAliasMutation>(
|
||||
setResourceAliasMutation,
|
||||
{
|
||||
successMessage: __("Alias updated successfully."),
|
||||
errorMessage: __("Failed to update alias"),
|
||||
errorToast: __("Failed to update alias"),
|
||||
},
|
||||
);
|
||||
const [removeResourceAlias, isRemovingAlias] = useMutationWithToasts(
|
||||
const [removeResourceAlias, isRemovingAlias] = useMutation<CompliancePageAliasField_removeResourceAliasMutation>(
|
||||
removeResourceAliasMutation,
|
||||
{
|
||||
successMessage: __("Alias removed successfully."),
|
||||
errorMessage: __("Failed to remove alias"),
|
||||
errorToast: __("Failed to remove alias"),
|
||||
},
|
||||
);
|
||||
|
||||
@@ -117,7 +119,7 @@ export function CompliancePageAliasField(props: {
|
||||
},
|
||||
});
|
||||
} catch {
|
||||
// useMutationWithToasts already shows an error toast.
|
||||
// useMutation already shows an error toast.
|
||||
}
|
||||
}, [alias, canRemoveAlias, canSetAlias, removeResourceAlias, resourceId, setResourceAlias, value]);
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
// SOFTWARE.
|
||||
|
||||
import type { TrustCenterDocumentAccessStatus } from "@probo/coredata";
|
||||
import type { TrustCenterDocumentAccessInfo } from "@probo/helpers";
|
||||
import type { CompliancePageDocumentAccessInfo } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import {
|
||||
Button,
|
||||
@@ -40,7 +40,7 @@ import type { CompliancePageAccessEditDialogDocumentAccessFragment$data, Complia
|
||||
import type { CompliancePageAccessEditDialogQuery as CompliancePageAccessEditDialogQueryType } from "#/__generated__/core/CompliancePageAccessEditDialogQuery.graphql";
|
||||
import type { CompliancePageAccessEditDialogUpdateMutation } from "#/__generated__/core/CompliancePageAccessEditDialogUpdateMutation.graphql";
|
||||
import type { CompliancePageAccessListItemFragment$data } from "#/__generated__/core/CompliancePageAccessListItemFragment.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
import { CompliancePageDocumentAccessList } from "#/pages/organizations/compliance-page/access/_components/CompliancePageDocumentAccessList";
|
||||
import { ElectronicSignatureSection } from "#/pages/organizations/compliance-page/access/_components/ElectronicSignatureSection";
|
||||
|
||||
@@ -76,10 +76,10 @@ const documentAccessFragment = graphql`
|
||||
}
|
||||
`;
|
||||
|
||||
function getTrustCenterDocumentAccessInfo(
|
||||
function getCompliancePageDocumentAccessInfo(
|
||||
fragmentRef: CompliancePageAccessEditDialogDocumentAccessFragment$key,
|
||||
__: (key: string) => string,
|
||||
): TrustCenterDocumentAccessInfo {
|
||||
): CompliancePageDocumentAccessInfo {
|
||||
const node = readInlineData(documentAccessFragment, fragmentRef);
|
||||
return toDocumentAccessInfo(node, __);
|
||||
}
|
||||
@@ -87,7 +87,7 @@ function getTrustCenterDocumentAccessInfo(
|
||||
function toDocumentAccessInfo(
|
||||
node: CompliancePageAccessEditDialogDocumentAccessFragment$data,
|
||||
__: (key: string) => string,
|
||||
): TrustCenterDocumentAccessInfo {
|
||||
): CompliancePageDocumentAccessInfo {
|
||||
if (node.document) {
|
||||
return {
|
||||
persisted: node.id !== node.document.id,
|
||||
@@ -124,7 +124,7 @@ function toDocumentAccessInfo(
|
||||
status: node.status,
|
||||
};
|
||||
}
|
||||
throw new Error("Unknown trust center access document type");
|
||||
throw new Error("Unknown compliance page access document type");
|
||||
}
|
||||
|
||||
const compliancePageAccessEditDialogQuery = graphql`
|
||||
@@ -221,7 +221,7 @@ function CompliancePageAccessEditForm(props: {
|
||||
|
||||
const initialDocumentAccesses
|
||||
= data.node.availableDocumentAccesses?.edges.map(edge =>
|
||||
getTrustCenterDocumentAccessInfo(edge.node, __),
|
||||
getCompliancePageDocumentAccessInfo(edge.node, __),
|
||||
) ?? [];
|
||||
const initialStatusByID = initialDocumentAccesses.reduce<
|
||||
Record<string, TrustCenterDocumentAccessStatus>
|
||||
@@ -230,12 +230,12 @@ function CompliancePageAccessEditForm(props: {
|
||||
return acc;
|
||||
}, {});
|
||||
const [documentAccesses, setDocumentAccesses] = useState<
|
||||
TrustCenterDocumentAccessInfo[]
|
||||
CompliancePageDocumentAccessInfo[]
|
||||
>(initialDocumentAccesses);
|
||||
|
||||
const handleUpdateDocumentAccessStatus = useCallback(
|
||||
(
|
||||
documentAccess: TrustCenterDocumentAccessInfo,
|
||||
documentAccess: CompliancePageDocumentAccessInfo,
|
||||
status: TrustCenterDocumentAccessStatus,
|
||||
) => {
|
||||
setDocumentAccesses((prev) => {
|
||||
@@ -269,11 +269,11 @@ function CompliancePageAccessEditForm(props: {
|
||||
);
|
||||
}, [initialStatusByID]);
|
||||
|
||||
const [updateTrustCenterAccess, isUpdating] = useMutationWithToasts<CompliancePageAccessEditDialogUpdateMutation>(
|
||||
const [updateCompliancePageAccess, isUpdating] = useMutation<CompliancePageAccessEditDialogUpdateMutation>(
|
||||
updateAccessMutation,
|
||||
{
|
||||
successMessage: __("Access updated successfully"),
|
||||
errorMessage: __("Failed to update access"),
|
||||
errorToast: __("Failed to update access"),
|
||||
},
|
||||
);
|
||||
|
||||
@@ -282,7 +282,7 @@ function CompliancePageAccessEditForm(props: {
|
||||
= [];
|
||||
const reports: { id: string; status: TrustCenterDocumentAccessStatus }[]
|
||||
= [];
|
||||
const trustCenterFiles: {
|
||||
const compliancePageFiles: {
|
||||
id: string;
|
||||
status: TrustCenterDocumentAccessStatus;
|
||||
}[] = [];
|
||||
@@ -297,7 +297,7 @@ function CompliancePageAccessEditForm(props: {
|
||||
reports.push({ id: docAccess.id, status: docAccess.status });
|
||||
break;
|
||||
case "file":
|
||||
trustCenterFiles.push({
|
||||
compliancePageFiles.push({
|
||||
id: docAccess.id,
|
||||
status: docAccess.status,
|
||||
});
|
||||
@@ -306,17 +306,18 @@ function CompliancePageAccessEditForm(props: {
|
||||
}
|
||||
}
|
||||
|
||||
await updateTrustCenterAccess({
|
||||
await updateCompliancePageAccess({
|
||||
variables: {
|
||||
input: {
|
||||
id: access.id,
|
||||
documents,
|
||||
reports,
|
||||
trustCenterFiles,
|
||||
trustCenterFiles: compliancePageFiles,
|
||||
},
|
||||
},
|
||||
onSuccess: onSubmit,
|
||||
});
|
||||
|
||||
onSubmit();
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -44,7 +44,7 @@ const fragment = graphql`
|
||||
ndaSignature {
|
||||
status
|
||||
}
|
||||
canUpdate: permission(action: "core:trust-center-access:update")
|
||||
canUpdate: permission(action: "compliance-portal:portal-access:update")
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -19,16 +19,17 @@
|
||||
// SOFTWARE.
|
||||
|
||||
import type { TrustCenterDocumentAccessStatus } from "@probo/coredata";
|
||||
import { getTrustCenterDocumentAccessStatusBadgeVariant, getTrustCenterDocumentAccessStatusLabel, type TrustCenterDocumentAccessInfo } from "@probo/helpers";
|
||||
import type { CompliancePageDocumentAccessInfo } from "@probo/helpers";
|
||||
import { getCompliancePageDocumentAccessStatusBadgeVariant, getCompliancePageDocumentAccessStatusLabel } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { Badge, Button, Table, Tbody, Td, Th, Thead, Tr } from "@probo/ui";
|
||||
|
||||
interface CompliancePageDocumentAccessListProps {
|
||||
documentAccesses: TrustCenterDocumentAccessInfo[];
|
||||
documentAccesses: CompliancePageDocumentAccessInfo[];
|
||||
initialStatusByID: Record<string, TrustCenterDocumentAccessStatus>;
|
||||
onGrantAll: () => void;
|
||||
onRejectOrRevokeAll: () => void;
|
||||
onUpdateStatus: (docAccess: TrustCenterDocumentAccessInfo, status: TrustCenterDocumentAccessStatus) => void;
|
||||
onUpdateStatus: (docAccess: CompliancePageDocumentAccessInfo, status: TrustCenterDocumentAccessStatus) => void;
|
||||
}
|
||||
|
||||
export function CompliancePageDocumentAccessList(props: CompliancePageDocumentAccessListProps) {
|
||||
@@ -108,8 +109,8 @@ export function CompliancePageDocumentAccessList(props: CompliancePageDocumentAc
|
||||
<Td>
|
||||
{(docAccess.persisted || docAccess.status !== "REQUESTED")
|
||||
&& (
|
||||
<Badge variant={getTrustCenterDocumentAccessStatusBadgeVariant(docAccess.status)}>
|
||||
{getTrustCenterDocumentAccessStatusLabel(docAccess.status, __)}
|
||||
<Badge variant={getCompliancePageDocumentAccessStatusBadgeVariant(docAccess.status)}>
|
||||
{getCompliancePageDocumentAccessStatusLabel(docAccess.status, __)}
|
||||
</Badge>
|
||||
)}
|
||||
</Td>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
import { formatDate, getAuditStateLabel, getAuditStateVariant, getTrustCenterVisibilityOptions } from "@probo/helpers";
|
||||
import { formatDate, getAuditStateLabel, getAuditStateVariant, getCompliancePageVisibilityOptions } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { Badge, Field, Option, Td, Tr } from "@probo/ui";
|
||||
import { useCallback } from "react";
|
||||
@@ -28,12 +28,12 @@ import { graphql } from "relay-runtime";
|
||||
import type { CompliancePageAuditListItem_auditFragment$key } from "#/__generated__/core/CompliancePageAuditListItem_auditFragment.graphql";
|
||||
import type { CompliancePageAuditListItem_compliancePageFragment$key } from "#/__generated__/core/CompliancePageAuditListItem_compliancePageFragment.graphql";
|
||||
import type { CompliancePageAuditListItem_updateAuditVisibilityMutation } from "#/__generated__/core/CompliancePageAuditListItem_updateAuditVisibilityMutation.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useOrganizationId } from "#/hooks/useOrganizationId";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
const compliancePageFragment = graphql`
|
||||
fragment CompliancePageAuditListItem_compliancePageFragment on TrustCenter {
|
||||
canUpdate: permission(action: "core:trust-center:update")
|
||||
canUpdate: permission(action: "compliance-portal:portal:update")
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -46,7 +46,7 @@ const auditFragment = graphql`
|
||||
}
|
||||
validUntil
|
||||
state
|
||||
trustCenterVisibility
|
||||
compliancePageVisibility: trustCenterVisibility
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -75,13 +75,13 @@ export function CompliancePageAuditListItem(props: {
|
||||
);
|
||||
const audit = useFragment<CompliancePageAuditListItem_auditFragment$key>(auditFragment, auditFragmentRef);
|
||||
|
||||
const [updateAuditVisibility, isUpdatingAuditVisibility] = useMutationWithToasts<
|
||||
const [updateAuditVisibility, isUpdatingAuditVisibility] = useMutation<
|
||||
CompliancePageAuditListItem_updateAuditVisibilityMutation
|
||||
>(
|
||||
updateAuditVisibilityMutation,
|
||||
{
|
||||
successMessage: __("Audit visibility updated successfully."),
|
||||
errorMessage: __("Failed to update audit visibility"),
|
||||
errorToast: __("Failed to update audit visibility"),
|
||||
},
|
||||
);
|
||||
const handleVisibilityChange = useCallback(
|
||||
@@ -100,7 +100,7 @@ export function CompliancePageAuditListItem(props: {
|
||||
[audit.id, updateAuditVisibility],
|
||||
);
|
||||
|
||||
const visibilityOptions = getTrustCenterVisibilityOptions(__);
|
||||
const visibilityOptions = getCompliancePageVisibilityOptions(__);
|
||||
const validUntilFormatted = audit.validUntil
|
||||
? formatDate(audit.validUntil)
|
||||
: __("No expiry");
|
||||
@@ -120,7 +120,7 @@ export function CompliancePageAuditListItem(props: {
|
||||
<Td noLink width={130} className="pr-0">
|
||||
<Field
|
||||
type="select"
|
||||
value={audit.trustCenterVisibility}
|
||||
value={audit.compliancePageVisibility}
|
||||
onValueChange={value => void handleVisibilityChange(value)}
|
||||
disabled={isUpdatingAuditVisibility || !compliancePage.canUpdate}
|
||||
className="w-[105px]"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
import { getTrustCenterVisibilityOptions } from "@probo/helpers";
|
||||
import { getCompliancePageVisibilityOptions } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { Badge, DocumentTypeBadge, Field, Option, Td, Tr } from "@probo/ui";
|
||||
import { useCallback } from "react";
|
||||
@@ -27,14 +27,15 @@ import { graphql } from "relay-runtime";
|
||||
|
||||
import type { CompliancePageDocumentListItem_compliancePageFragment$key } from "#/__generated__/core/CompliancePageDocumentListItem_compliancePageFragment.graphql";
|
||||
import type { CompliancePageDocumentListItem_documentFragment$key } from "#/__generated__/core/CompliancePageDocumentListItem_documentFragment.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import type { CompliancePageDocumentListItem_updateVisibilityMutation } from "#/__generated__/core/CompliancePageDocumentListItem_updateVisibilityMutation.graphql";
|
||||
import { useOrganizationId } from "#/hooks/useOrganizationId";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
import { CompliancePageAliasField } from "../../_components/CompliancePageAliasField";
|
||||
|
||||
const compliancePageFragment = graphql`
|
||||
fragment CompliancePageDocumentListItem_compliancePageFragment on TrustCenter {
|
||||
canUpdate: permission(action: "core:trust-center:update")
|
||||
canUpdate: permission(action: "compliance-portal:portal:update")
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -44,7 +45,7 @@ const documentFragment = graphql`
|
||||
alias
|
||||
canSetAlias: permission(action: "resourcealias:alias:set")
|
||||
canRemoveAlias: permission(action: "resourcealias:alias:remove")
|
||||
trustCenterVisibility
|
||||
compliancePageVisibility: trustCenterVisibility
|
||||
latestPublishedVersion: versions(
|
||||
first: 1
|
||||
orderBy: { field: CREATED_AT, direction: DESC }
|
||||
@@ -80,7 +81,7 @@ export function CompliancePageDocumentListItem(props: {
|
||||
|
||||
const organizationId = useOrganizationId();
|
||||
const { __ } = useTranslate();
|
||||
const visibilityOptions = getTrustCenterVisibilityOptions(__);
|
||||
const visibilityOptions = getCompliancePageVisibilityOptions(__);
|
||||
|
||||
const compliancePage = useFragment<CompliancePageDocumentListItem_compliancePageFragment$key>(
|
||||
compliancePageFragment,
|
||||
@@ -90,13 +91,14 @@ export function CompliancePageDocumentListItem(props: {
|
||||
documentFragment,
|
||||
documentFragmentRef,
|
||||
);
|
||||
const [updateDocumentVisibility, isUpdatingDocumentVisibility] = useMutationWithToasts(
|
||||
updateDocumentVisibilityMutation,
|
||||
{
|
||||
successMessage: __("Document visibility updated successfully."),
|
||||
errorMessage: __("Failed to update document visibility"),
|
||||
},
|
||||
);
|
||||
const [updateDocumentVisibility, isUpdatingDocumentVisibility]
|
||||
= useMutation<CompliancePageDocumentListItem_updateVisibilityMutation>(
|
||||
updateDocumentVisibilityMutation,
|
||||
{
|
||||
successMessage: __("Document visibility updated successfully."),
|
||||
errorToast: __("Failed to update document visibility"),
|
||||
},
|
||||
);
|
||||
const handleVsibilityChange = useCallback(
|
||||
async (value: string) => {
|
||||
const stringValue = typeof value === "string" ? value : "";
|
||||
@@ -135,7 +137,7 @@ export function CompliancePageDocumentListItem(props: {
|
||||
<Td noLink width={130} className="pr-0">
|
||||
<Field
|
||||
type="select"
|
||||
value={document.trustCenterVisibility}
|
||||
value={document.compliancePageVisibility}
|
||||
onValueChange={value => void handleVsibilityChange(value)}
|
||||
disabled={isUpdatingDocumentVisibility || !compliancePage.canUpdate}
|
||||
className="w-[105px]"
|
||||
|
||||
@@ -32,7 +32,7 @@ export const compliancePageFilesPageQuery = graphql`
|
||||
query CompliancePageFilesPageQuery($organizationId: ID!) {
|
||||
organization: node(id: $organizationId) {
|
||||
... on Organization {
|
||||
canCreateTrustCenterFile: permission(action: "core:trust-center-file:create")
|
||||
canCreateCompliancePageFile: permission(action: "compliance-portal:portal-file:create")
|
||||
}
|
||||
...CompliancePageFileListFragment
|
||||
}
|
||||
@@ -52,7 +52,7 @@ export function CompliancePageFilesPage(props: {
|
||||
|
||||
const filesConnectionId = ConnectionHandler.getConnectionID(
|
||||
organizationId,
|
||||
"CompliancePageFileList_trustCenterFiles",
|
||||
"CompliancePageFileList_compliancePageFiles",
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -64,7 +64,7 @@ export function CompliancePageFilesPage(props: {
|
||||
{__("Upload and manage files for your compliance page")}
|
||||
</p>
|
||||
</div>
|
||||
{organization.canCreateTrustCenterFile && (
|
||||
{organization.canCreateCompliancePageFile && (
|
||||
<Button
|
||||
icon={IconPlusLarge}
|
||||
onClick={() => createDialogRef.current?.open()}
|
||||
|
||||
@@ -36,8 +36,8 @@ const fragment = graphql`
|
||||
compliancePage: trustCenter @required(action: THROW) {
|
||||
...CompliancePageFileListItem_compliancePageFragment
|
||||
}
|
||||
trustCenterFiles(first: 100)
|
||||
@connection(key: "CompliancePageFileList_trustCenterFiles") {
|
||||
compliancePageFiles: trustCenterFiles(first: 100)
|
||||
@connection(key: "CompliancePageFileList_compliancePageFiles") {
|
||||
__id
|
||||
edges {
|
||||
node {
|
||||
@@ -57,7 +57,7 @@ export function CompliancePageFileList(props: { fragmentRef: CompliancePageFileL
|
||||
|
||||
const {
|
||||
compliancePage,
|
||||
trustCenterFiles: files,
|
||||
compliancePageFiles: files,
|
||||
} = useFragment<CompliancePageFileListFragment$key>(fragment, fragmentRef);
|
||||
|
||||
const [editingFile, setEditingFile] = useState<
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
import { formatDate, getTrustCenterVisibilityOptions } from "@probo/helpers";
|
||||
import { formatDate, getCompliancePageVisibilityOptions } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { Badge, Button, Field, IconArrowLink, IconPencil, IconTrashCan, Option, Td, Tr } from "@probo/ui";
|
||||
import { useCallback } from "react";
|
||||
@@ -28,13 +28,13 @@ import { graphql } from "relay-runtime";
|
||||
import type { CompliancePageFileListItem_compliancePageFragment$key } from "#/__generated__/core/CompliancePageFileListItem_compliancePageFragment.graphql";
|
||||
import type { CompliancePageFileListItem_fileFragment$data, CompliancePageFileListItem_fileFragment$key } from "#/__generated__/core/CompliancePageFileListItem_fileFragment.graphql";
|
||||
import type { CompliancePageFileListItemMutation } from "#/__generated__/core/CompliancePageFileListItemMutation.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
import { CompliancePageAliasField } from "../../_components/CompliancePageAliasField";
|
||||
|
||||
const compliancePageFragment = graphql`
|
||||
fragment CompliancePageFileListItem_compliancePageFragment on TrustCenter {
|
||||
canUpdate: permission(action: "core:trust-center:update")
|
||||
canUpdate: permission(action: "compliance-portal:portal:update")
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -49,10 +49,10 @@ const fileFragment = graphql`
|
||||
file {
|
||||
downloadUrl
|
||||
}
|
||||
trustCenterVisibility
|
||||
compliancePageVisibility: trustCenterVisibility
|
||||
createdAt
|
||||
canUpdate: permission(action: "core:trust-center-file:update")
|
||||
canDelete: permission(action: "core:trust-center-file:delete")
|
||||
canUpdate: permission(action: "compliance-portal:portal-file:update")
|
||||
canDelete: permission(action: "compliance-portal:portal-file:delete")
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -75,7 +75,7 @@ export function CompliancePageFileListItem(props: {
|
||||
const { compliancePageFragmentRef, fileFragmentRef, onEdit, onDelete } = props;
|
||||
|
||||
const { __ } = useTranslate();
|
||||
const visibilityOptions = getTrustCenterVisibilityOptions(__);
|
||||
const visibilityOptions = getCompliancePageVisibilityOptions(__);
|
||||
|
||||
const compliancePage = useFragment<CompliancePageFileListItem_compliancePageFragment$key>(
|
||||
compliancePageFragment,
|
||||
@@ -83,11 +83,11 @@ export function CompliancePageFileListItem(props: {
|
||||
);
|
||||
const file = useFragment<CompliancePageFileListItem_fileFragment$key>(fileFragment, fileFragmentRef);
|
||||
|
||||
const [updateFile, isUpdating] = useMutationWithToasts<CompliancePageFileListItemMutation>(
|
||||
const [updateFile, isUpdating] = useMutation<CompliancePageFileListItemMutation>(
|
||||
updateCompliancePageFileMutation,
|
||||
{
|
||||
successMessage: "File updated successfully",
|
||||
errorMessage: "Failed to update file",
|
||||
errorToast: "Failed to update file",
|
||||
},
|
||||
);
|
||||
|
||||
@@ -125,7 +125,7 @@ export function CompliancePageFileListItem(props: {
|
||||
<Td noLink width={130} className="pr-0">
|
||||
<Field
|
||||
type="select"
|
||||
value={file.trustCenterVisibility}
|
||||
value={file.compliancePageVisibility}
|
||||
onValueChange={value => void handleValueChange(value)}
|
||||
disabled={isUpdating || !compliancePage.canUpdate}
|
||||
className="w-[105px]"
|
||||
|
||||
@@ -24,7 +24,7 @@ import { useCallback } from "react";
|
||||
import { type DataID, graphql } from "relay-runtime";
|
||||
|
||||
import type { DeleteCompliancePageFileDialogMutation } from "#/__generated__/core/DeleteCompliancePageFileDialogMutation.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
const deleteCompliancePageFileMutation = graphql`
|
||||
mutation DeleteCompliancePageFileDialogMutation(
|
||||
@@ -47,11 +47,11 @@ export function DeleteCompliancePageFileDialog(props: {
|
||||
|
||||
const { __ } = useTranslate();
|
||||
|
||||
const [deleteFile, isDeleting] = useMutationWithToasts<DeleteCompliancePageFileDialogMutation>(
|
||||
const [deleteFile, isDeleting] = useMutation<DeleteCompliancePageFileDialogMutation>(
|
||||
deleteCompliancePageFileMutation,
|
||||
{
|
||||
successMessage: "File deleted successfully",
|
||||
errorMessage: "Failed to delete file",
|
||||
errorToast: "Failed to delete file",
|
||||
},
|
||||
);
|
||||
|
||||
@@ -65,11 +65,10 @@ export function DeleteCompliancePageFileDialog(props: {
|
||||
input: { id: fileId },
|
||||
connections: connectionId ? [connectionId] : [],
|
||||
},
|
||||
onSuccess: () => {
|
||||
ref.current?.close();
|
||||
onDelete();
|
||||
},
|
||||
});
|
||||
|
||||
ref.current?.close();
|
||||
onDelete();
|
||||
}, [fileId, deleteFile, ref, connectionId, onDelete]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -26,7 +26,7 @@ import { z } from "zod";
|
||||
import type { CompliancePageFileListItem_fileFragment$data } from "#/__generated__/core/CompliancePageFileListItem_fileFragment.graphql";
|
||||
import type { EditCompliancePageFileDialogMutation } from "#/__generated__/core/EditCompliancePageFileDialogMutation.graphql";
|
||||
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
const updateCompliancePageFileMutation = graphql`
|
||||
mutation EditCompliancePageFileDialogMutation($input: UpdateTrustCenterFileInput!) {
|
||||
@@ -54,11 +54,11 @@ export function EditCompliancePageFileDialog(props: {
|
||||
defaultValues: { name: file.name, category: file.category },
|
||||
});
|
||||
|
||||
const [updateFile, isUpdating] = useMutationWithToasts<EditCompliancePageFileDialogMutation>(
|
||||
const [updateFile, isUpdating] = useMutation<EditCompliancePageFileDialogMutation>(
|
||||
updateCompliancePageFileMutation,
|
||||
{
|
||||
successMessage: "File updated successfully",
|
||||
errorMessage: "Failed to update file",
|
||||
errorToast: "Failed to update file",
|
||||
},
|
||||
);
|
||||
|
||||
@@ -71,10 +71,9 @@ export function EditCompliancePageFileDialog(props: {
|
||||
category: data.category,
|
||||
},
|
||||
},
|
||||
onSuccess: () => {
|
||||
onClose();
|
||||
},
|
||||
});
|
||||
|
||||
onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
acceptPresentation,
|
||||
acceptSpreadsheet,
|
||||
acceptText,
|
||||
getTrustCenterVisibilityOptions,
|
||||
getCompliancePageVisibilityOptions,
|
||||
} from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { Badge, Button, Dialog, DialogContent, DialogFooter, type DialogRef, Dropzone, Field, Option, Spinner } from "@probo/ui";
|
||||
@@ -35,8 +35,8 @@ import { z } from "zod";
|
||||
|
||||
import type { NewCompliancePageFileDialog_createMutation } from "#/__generated__/core/NewCompliancePageFileDialog_createMutation.graphql";
|
||||
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useOrganizationId } from "#/hooks/useOrganizationId";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
const acceptedFileTypes = {
|
||||
...acceptDocument,
|
||||
@@ -76,10 +76,10 @@ export function NewCompliancePageFileDialog(props: {
|
||||
const createSchema = z.object({
|
||||
name: z.string().min(1, __("Name is required")),
|
||||
category: z.string().min(1, __("Category is required")),
|
||||
trustCenterVisibility: z.enum(["NONE", "PRIVATE", "PUBLIC"]),
|
||||
compliancePageVisibility: z.enum(["NONE", "PRIVATE", "PUBLIC"]),
|
||||
});
|
||||
const createForm = useFormWithSchema(createSchema, {
|
||||
defaultValues: { name: "", category: "", trustCenterVisibility: "NONE" },
|
||||
defaultValues: { name: "", category: "", compliancePageVisibility: "NONE" },
|
||||
});
|
||||
|
||||
const handleFileUpload = useCallback(
|
||||
@@ -105,10 +105,10 @@ export function NewCompliancePageFileDialog(props: {
|
||||
[createForm, __],
|
||||
);
|
||||
|
||||
const [createFile, isCreating] = useMutationWithToasts<NewCompliancePageFileDialog_createMutation>(
|
||||
const [createFile, isCreating] = useMutation<NewCompliancePageFileDialog_createMutation>(
|
||||
createCompliancePageFileMutation, {
|
||||
successMessage: "File uploaded successfully",
|
||||
errorMessage: "Failed to upload file",
|
||||
errorToast: "Failed to upload file",
|
||||
},
|
||||
);
|
||||
const handleCreate = async (data: z.infer<typeof createSchema>) => {
|
||||
@@ -122,7 +122,7 @@ export function NewCompliancePageFileDialog(props: {
|
||||
organizationId,
|
||||
name: data.name,
|
||||
category: data.category,
|
||||
trustCenterVisibility: data.trustCenterVisibility,
|
||||
trustCenterVisibility: data.compliancePageVisibility,
|
||||
file: null,
|
||||
},
|
||||
connections: connectionId ? [connectionId] : [],
|
||||
@@ -130,12 +130,11 @@ export function NewCompliancePageFileDialog(props: {
|
||||
uploadables: {
|
||||
"input.file": uploadedFile,
|
||||
},
|
||||
onSuccess: () => {
|
||||
ref.current?.close();
|
||||
createForm.reset();
|
||||
setUploadedFile(null);
|
||||
},
|
||||
});
|
||||
|
||||
ref.current?.close();
|
||||
createForm.reset();
|
||||
setUploadedFile(null);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -176,15 +175,15 @@ export function NewCompliancePageFileDialog(props: {
|
||||
<Field
|
||||
label={__("Visibility")}
|
||||
type="select"
|
||||
value={createForm.watch("trustCenterVisibility")}
|
||||
value={createForm.watch("compliancePageVisibility")}
|
||||
onValueChange={value =>
|
||||
createForm.setValue(
|
||||
"trustCenterVisibility",
|
||||
"compliancePageVisibility",
|
||||
value as "NONE" | "PRIVATE" | "PUBLIC",
|
||||
)}
|
||||
error={createForm.formState.errors.trustCenterVisibility?.message}
|
||||
error={createForm.formState.errors.compliancePageVisibility?.message}
|
||||
>
|
||||
{getTrustCenterVisibilityOptions(__).map(option => (
|
||||
{getCompliancePageVisibilityOptions(__).map(option => (
|
||||
<Option key={option.value} value={option.value}>
|
||||
<div className="flex items-center justify-between w-full">
|
||||
<Badge variant={option.variant}>{option.label}</Badge>
|
||||
|
||||
@@ -26,7 +26,7 @@ import { ConnectionHandler, graphql } from "relay-runtime";
|
||||
|
||||
import type { CompliancePageMailingListPage_updateMailingListMutation } from "#/__generated__/core/CompliancePageMailingListPage_updateMailingListMutation.graphql";
|
||||
import type { CompliancePageMailingListPageQuery } from "#/__generated__/core/CompliancePageMailingListPageQuery.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
import { CompliancePageMailingList } from "./_components/CompliancePageMailingList";
|
||||
import { CompliancePageUpdatesList, type UpdateNode } from "./_components/CompliancePageUpdatesList";
|
||||
@@ -101,11 +101,11 @@ export function CompliancePageMailingListPage(props: {
|
||||
const [replyTo, setReplyTo] = useState(mailingList?.replyTo ?? "");
|
||||
|
||||
const [updateMailingList, isUpdating]
|
||||
= useMutationWithToasts<CompliancePageMailingListPage_updateMailingListMutation>(
|
||||
= useMutation<CompliancePageMailingListPage_updateMailingListMutation>(
|
||||
updateMailingListMutation,
|
||||
{
|
||||
successMessage: __("Mailing list updated successfully"),
|
||||
errorMessage: __("Failed to update mailing list"),
|
||||
errorToast: __("Failed to update mailing list"),
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import { graphql } from "relay-runtime";
|
||||
import type { CompliancePageMailingListDeleteMutation } from "#/__generated__/core/CompliancePageMailingListDeleteMutation.graphql";
|
||||
import type { CompliancePageMailingListFragment$key } from "#/__generated__/core/CompliancePageMailingListFragment.graphql";
|
||||
import type { CompliancePageMailingListQuery } from "#/__generated__/core/CompliancePageMailingListQuery.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
const deleteMutation = graphql`
|
||||
mutation CompliancePageMailingListDeleteMutation(
|
||||
@@ -89,11 +89,11 @@ export function CompliancePageMailingList(props: {
|
||||
|
||||
const subscribers = data.mailingList?.subscribers;
|
||||
|
||||
const [deleteSubscriber, isDeleting] = useMutationWithToasts<CompliancePageMailingListDeleteMutation>(
|
||||
const [deleteSubscriber, isDeleting] = useMutation<CompliancePageMailingListDeleteMutation>(
|
||||
deleteMutation,
|
||||
{
|
||||
successMessage: __("Subscriber removed successfully"),
|
||||
errorMessage: __("Failed to delete subscriber"),
|
||||
errorToast: __("Failed to delete subscriber"),
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import { graphql } from "relay-runtime";
|
||||
import type { CompliancePageUpdatesListDeleteMutation } from "#/__generated__/core/CompliancePageUpdatesListDeleteMutation.graphql";
|
||||
import type { CompliancePageUpdatesListFragment$data, CompliancePageUpdatesListFragment$key } from "#/__generated__/core/CompliancePageUpdatesListFragment.graphql";
|
||||
import type { CompliancePageUpdatesListQuery } from "#/__generated__/core/CompliancePageUpdatesListQuery.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
import { SendUpdateDialog } from "./SendUpdateDialog";
|
||||
|
||||
@@ -92,9 +92,9 @@ export function CompliancePageUpdatesList(props: {
|
||||
const connection = data.updates;
|
||||
|
||||
const [deleteUpdate, isDeleting]
|
||||
= useMutationWithToasts<CompliancePageUpdatesListDeleteMutation>(deleteMutation, {
|
||||
= useMutation<CompliancePageUpdatesListDeleteMutation>(deleteMutation, {
|
||||
successMessage: __("Update deleted successfully"),
|
||||
errorMessage: __("Failed to delete update"),
|
||||
errorToast: __("Failed to delete update"),
|
||||
});
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
|
||||
@@ -27,7 +27,7 @@ import { z } from "zod";
|
||||
import type { ComplianceUpdateFormDialogCreateMutation } from "#/__generated__/core/ComplianceUpdateFormDialogCreateMutation.graphql";
|
||||
import type { ComplianceUpdateFormDialogUpdateMutation } from "#/__generated__/core/ComplianceUpdateFormDialogUpdateMutation.graphql";
|
||||
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
import type { UpdateNode } from "./CompliancePageUpdatesList";
|
||||
|
||||
@@ -104,19 +104,19 @@ export function ComplianceUpdateFormDialog(props: Props) {
|
||||
}
|
||||
}, [update, form]);
|
||||
|
||||
const [createUpdate, isCreating] = useMutationWithToasts<ComplianceUpdateFormDialogCreateMutation>(
|
||||
const [createUpdate, isCreating] = useMutation<ComplianceUpdateFormDialogCreateMutation>(
|
||||
createMutation,
|
||||
{
|
||||
successMessage: __("Update created successfully"),
|
||||
errorMessage: __("Failed to create update"),
|
||||
errorToast: __("Failed to create update"),
|
||||
},
|
||||
);
|
||||
|
||||
const [saveUpdate, isSaving] = useMutationWithToasts<ComplianceUpdateFormDialogUpdateMutation>(
|
||||
const [saveUpdate, isSaving] = useMutation<ComplianceUpdateFormDialogUpdateMutation>(
|
||||
updateMutation,
|
||||
{
|
||||
successMessage: __("Update saved successfully"),
|
||||
errorMessage: __("Failed to save update"),
|
||||
errorToast: __("Failed to save update"),
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import { z } from "zod";
|
||||
|
||||
import type { NewCompliancePageSubscriberDialogMutation } from "#/__generated__/core/NewCompliancePageSubscriberDialogMutation.graphql";
|
||||
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
const createSubscriberMutation = graphql`
|
||||
mutation NewCompliancePageSubscriberDialogMutation(
|
||||
@@ -69,11 +69,11 @@ export function NewCompliancePageSubscriberDialog(props: {
|
||||
defaultValues: { fullName: "", email: "", confirmed: false },
|
||||
});
|
||||
|
||||
const [createSubscriber, isCreating] = useMutationWithToasts<NewCompliancePageSubscriberDialogMutation>(
|
||||
const [createSubscriber, isCreating] = useMutation<NewCompliancePageSubscriberDialogMutation>(
|
||||
createSubscriberMutation,
|
||||
{
|
||||
successMessage: __("Subscriber added successfully"),
|
||||
errorMessage: __("Failed to add subscriber"),
|
||||
errorToast: __("Failed to add subscriber"),
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import { Button, Dialog, DialogContent, DialogFooter, type DialogRef, IconSend,
|
||||
import { graphql } from "relay-runtime";
|
||||
|
||||
import type { SendUpdateDialogMutation } from "#/__generated__/core/SendUpdateDialogMutation.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
import type { UpdateNode } from "./CompliancePageUpdatesList";
|
||||
|
||||
@@ -50,9 +50,9 @@ type Props = {
|
||||
export function SendUpdateDialog({ ref, update, onSent }: Props) {
|
||||
const { __ } = useTranslate();
|
||||
|
||||
const [sendUpdate, isSending] = useMutationWithToasts<SendUpdateDialogMutation>(sendMutation, {
|
||||
const [sendUpdate, isSending] = useMutation<SendUpdateDialogMutation>(sendMutation, {
|
||||
successMessage: __("Update enqueued for delivery"),
|
||||
errorMessage: __("Failed to enqueue update for delivery"),
|
||||
errorToast: __("Failed to enqueue update for delivery"),
|
||||
});
|
||||
|
||||
const handleSend = async () => {
|
||||
|
||||
@@ -25,7 +25,7 @@ import { ConnectionHandler, graphql, type PreloadedQuery, usePreloadedQuery } fr
|
||||
|
||||
import type { CompliancePageReferenceListItemFragment$data } from "#/__generated__/core/CompliancePageReferenceListItemFragment.graphql";
|
||||
import type { CompliancePageReferencesPageQuery } from "#/__generated__/core/CompliancePageReferencesPageQuery.graphql";
|
||||
import { TrustCenterReferenceDialog, type TrustCenterReferenceDialogRef } from "#/components/trustCenter/TrustCenterReferenceDialog";
|
||||
import { CompliancePageReferenceDialog, type CompliancePageReferenceDialogRef } from "#/components/compliancePage/CompliancePageReferenceDialog";
|
||||
|
||||
import { CompliancePageReferenceList } from "./_components/CompliancePageReferenceList";
|
||||
|
||||
@@ -36,7 +36,7 @@ export const compliancePageReferencesPageQuery = graphql`
|
||||
... on Organization {
|
||||
compliancePage: trustCenter @required(action: THROW) {
|
||||
id
|
||||
canCreateReference: permission(action: "core:trust-center-reference:create")
|
||||
canCreateReference: permission(action: "compliance-portal:portal-reference:create")
|
||||
...CompliancePageReferenceListFragment
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ export function CompliancePageReferencesPage(props: { queryRef: PreloadedQuery<C
|
||||
const { queryRef } = props;
|
||||
|
||||
const { __ } = useTranslate();
|
||||
const dialogRef = useRef<TrustCenterReferenceDialogRef>(null);
|
||||
const dialogRef = useRef<CompliancePageReferenceDialogRef>(null);
|
||||
|
||||
const { organization } = usePreloadedQuery<CompliancePageReferencesPageQuery>(
|
||||
compliancePageReferencesPageQuery,
|
||||
@@ -94,7 +94,7 @@ export function CompliancePageReferencesPage(props: { queryRef: PreloadedQuery<C
|
||||
|
||||
<CompliancePageReferenceList fragmentRef={organization.compliancePage} onEdit={handleEdit} />
|
||||
|
||||
<TrustCenterReferenceDialog ref={dialogRef} />
|
||||
<CompliancePageReferenceDialog ref={dialogRef} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -27,7 +27,7 @@ import { graphql } from "relay-runtime";
|
||||
import type { CompliancePageReferenceListFragment$key } from "#/__generated__/core/CompliancePageReferenceListFragment.graphql";
|
||||
import type { CompliancePageReferenceListItemFragment$data } from "#/__generated__/core/CompliancePageReferenceListItemFragment.graphql";
|
||||
import type { CompliancePageReferenceListQuery } from "#/__generated__/core/CompliancePageReferenceListQuery.graphql";
|
||||
import { useUpdateTrustCenterReferenceRankMutation } from "#/hooks/graph/TrustCenterReferenceGraph";
|
||||
import { useUpdateCompliancePageReferenceRankMutation } from "#/hooks/graph/CompliancePageReferenceGraph";
|
||||
|
||||
import { CompliancePageReferenceListItem } from "./CompliancePageReferenceListItem";
|
||||
|
||||
@@ -65,7 +65,7 @@ export function CompliancePageReferenceList(props: {
|
||||
CompliancePageReferenceListQuery,
|
||||
CompliancePageReferenceListFragment$key
|
||||
>(fragment, fragmentRef);
|
||||
const [updateRank] = useUpdateTrustCenterReferenceRankMutation();
|
||||
const [updateRank] = useUpdateCompliancePageReferenceRankMutation();
|
||||
|
||||
const [draggedIndex, setDraggedIndex] = useState<number | null>(null);
|
||||
const [dragOverIndex, setDragOverIndex] = useState<number | null>(null);
|
||||
|
||||
@@ -25,7 +25,7 @@ import { useFragment } from "react-relay";
|
||||
import { type DataID, graphql } from "relay-runtime";
|
||||
|
||||
import type { CompliancePageReferenceListItemFragment$data, CompliancePageReferenceListItemFragment$key } from "#/__generated__/core/CompliancePageReferenceListItemFragment.graphql";
|
||||
import { DeleteTrustCenterReferenceDialog } from "#/components/trustCenter/DeleteTrustCenterReferenceDialog";
|
||||
import { DeleteCompliancePageReferenceDialog } from "#/components/compliancePage/DeleteCompliancePageReferenceDialog";
|
||||
|
||||
const fragment = graphql`
|
||||
fragment CompliancePageReferenceListItemFragment on TrustCenterReference {
|
||||
@@ -36,8 +36,8 @@ const fragment = graphql`
|
||||
name
|
||||
description
|
||||
websiteUrl
|
||||
canUpdate: permission(action: "core:trust-center-reference:update")
|
||||
canDelete: permission(action: "core:trust-center-reference:delete")
|
||||
canUpdate: permission(action: "compliance-portal:portal-reference:update")
|
||||
canDelete: permission(action: "compliance-portal:portal-reference:delete")
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -109,13 +109,13 @@ export function CompliancePageReferenceListItem(props: {
|
||||
<Button variant="secondary" icon={IconPencil} onClick={() => onEdit(reference)} />
|
||||
)}
|
||||
{reference.canDelete && (
|
||||
<DeleteTrustCenterReferenceDialog
|
||||
<DeleteCompliancePageReferenceDialog
|
||||
referenceId={reference.id}
|
||||
referenceName={reference.name}
|
||||
connectionId={connectionId}
|
||||
>
|
||||
<Button variant="danger" icon={IconTrashCan} />
|
||||
</DeleteTrustCenterReferenceDialog>
|
||||
</DeleteCompliancePageReferenceDialog>
|
||||
)}
|
||||
</div>
|
||||
</Td>
|
||||
|
||||
@@ -25,15 +25,15 @@ import { graphql } from "relay-runtime";
|
||||
|
||||
import type { CompliancePageThirdPartyListItem_thirdPartyFragment$key } from "#/__generated__/core/CompliancePageThirdPartyListItem_thirdPartyFragment.graphql";
|
||||
import type { CompliancePageThirdPartyListItemMutation } from "#/__generated__/core/CompliancePageThirdPartyListItemMutation.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
import { useOrganizationId } from "#/hooks/useOrganizationId";
|
||||
import { useMutation } from "#/lib/relay/useMutation";
|
||||
|
||||
const thirdPartyFragment = graphql`
|
||||
fragment CompliancePageThirdPartyListItem_thirdPartyFragment on ThirdParty {
|
||||
id
|
||||
category
|
||||
name
|
||||
showOnTrustCenter
|
||||
showOnCompliancePage: showOnTrustCenter
|
||||
canUpdate: permission(action: "core:thirdParty:update")
|
||||
}
|
||||
`;
|
||||
@@ -62,13 +62,13 @@ export function CompliancePageThirdPartyListItem(props: {
|
||||
thirdPartyFragment,
|
||||
thirdPartyFragmentRef,
|
||||
);
|
||||
const [updateThirdPartyVisibility, isUpadtingThirdPartyVisibility] = useMutationWithToasts<
|
||||
const [updateThirdPartyVisibility, isUpadtingThirdPartyVisibility] = useMutation<
|
||||
CompliancePageThirdPartyListItemMutation
|
||||
>(
|
||||
updateThirdPartyVisibilityMutation,
|
||||
{
|
||||
successMessage: __("Subprocessor visibility updated successfully."),
|
||||
errorMessage: __("Failed to update subprocessor visibility"),
|
||||
errorToast: __("Failed to update subprocessor visibility"),
|
||||
},
|
||||
);
|
||||
|
||||
@@ -81,8 +81,8 @@ export function CompliancePageThirdPartyListItem(props: {
|
||||
<Badge variant="neutral">{thirdParty.category}</Badge>
|
||||
</Td>
|
||||
<Td>
|
||||
<Badge variant={thirdParty.showOnTrustCenter ? "success" : "danger"}>
|
||||
{thirdParty.showOnTrustCenter ? __("Visible") : __("None")}
|
||||
<Badge variant={thirdParty.showOnCompliancePage ? "success" : "danger"}>
|
||||
{thirdParty.showOnCompliancePage ? __("Visible") : __("None")}
|
||||
</Badge>
|
||||
</Td>
|
||||
<Td noLink width={100} className="text-end">
|
||||
@@ -94,14 +94,14 @@ export function CompliancePageThirdPartyListItem(props: {
|
||||
variables: {
|
||||
input: {
|
||||
id: thirdParty.id,
|
||||
showOnTrustCenter: !thirdParty.showOnTrustCenter,
|
||||
showOnTrustCenter: !thirdParty.showOnCompliancePage,
|
||||
},
|
||||
},
|
||||
})}
|
||||
icon={thirdParty.showOnTrustCenter ? IconCrossLargeX : IconCheckmark1}
|
||||
icon={thirdParty.showOnCompliancePage ? IconCrossLargeX : IconCheckmark1}
|
||||
disabled={isUpadtingThirdPartyVisibility}
|
||||
>
|
||||
{thirdParty.showOnTrustCenter ? __("Hide") : __("Show")}
|
||||
{thirdParty.showOnCompliancePage ? __("Hide") : __("Show")}
|
||||
</Button>
|
||||
)}
|
||||
</Td>
|
||||
|
||||
@@ -86,8 +86,13 @@ export {
|
||||
getTrustCenterVisibilityVariant,
|
||||
getTrustCenterVisibilityLabel,
|
||||
getTrustCenterVisibilityOptions,
|
||||
getTrustCenterVisibilityVariant as getCompliancePageVisibilityVariant,
|
||||
getTrustCenterVisibilityLabel as getCompliancePageVisibilityLabel,
|
||||
getTrustCenterVisibilityOptions as getCompliancePageVisibilityOptions,
|
||||
trustCenterVisibilities,
|
||||
trustCenterVisibilities as compliancePageVisibilities,
|
||||
type TrustCenterVisibility,
|
||||
type TrustCenterVisibility as CompliancePageVisibility,
|
||||
} from "./trustCenterVisibility";
|
||||
export { promisifyMutation } from "./relay";
|
||||
export { fileType, fileSize } from "./file";
|
||||
@@ -123,7 +128,10 @@ export { Role, roles, getAssignableRoles } from "./roles";
|
||||
export {
|
||||
getTrustCenterDocumentAccessStatusBadgeVariant,
|
||||
getTrustCenterDocumentAccessStatusLabel,
|
||||
getTrustCenterDocumentAccessStatusBadgeVariant as getCompliancePageDocumentAccessStatusBadgeVariant,
|
||||
getTrustCenterDocumentAccessStatusLabel as getCompliancePageDocumentAccessStatusLabel,
|
||||
type TrustCenterDocumentAccessInfo,
|
||||
type TrustCenterDocumentAccessInfo as CompliancePageDocumentAccessInfo,
|
||||
} from "./trustCenterDocumentAccess";
|
||||
export {
|
||||
getRightsRequestTypeLabel,
|
||||
|
||||
Reference in New Issue
Block a user