Refactor compliange page access code

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2026-02-20 12:24:28 +01:00
parent 069b47d240
commit 79084bca23
7 changed files with 318 additions and 131 deletions

View File

@@ -18,39 +18,96 @@ import {
usePreloadedQuery,
useQueryLoader,
} from "react-relay";
import { graphql } from "relay-runtime";
import { z } from "zod";
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 type { TrustCenterAccessGraphLoadDocumentAccessesQuery } from "#/__generated__/core/TrustCenterAccessGraphLoadDocumentAccessesQuery.graphql";
import {
loadTrustCenterAccessDocumentAccessesQuery,
updateTrustCenterAccessMutation,
} from "#/hooks/graph/TrustCenterAccessGraph";
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
import { CompliancePageDocumentAccessList } from "#/pages/organizations/compliance-page/access/_components/CompliancePageDocumentAccessList";
import { ElectronicSignatureSection } from "#/pages/organizations/compliance-page/access/_components/ElectronicSignatureSection";
import { TrustCenterDocumentAccessList } from "./TrustCenterDocumentAccessList";
interface TrustCenterAccessEditDialogProps {
const compliancePageAccessEditDialogQuery = graphql`
query CompliancePageAccessEditDialogQuery($accessId: ID!) {
node(id: $accessId) {
... on TrustCenterAccess {
id
ndaSignature {
...ElectronicSignatureSectionFragment
}
availableDocumentAccesses(
first: 100
orderBy: { field: CREATED_AT, direction: DESC }
) {
edges {
node {
id
status
document {
id
title
documentType
}
report {
id
filename
audit {
id
framework {
name
}
}
}
trustCenterFile {
id
name
category
}
}
}
}
}
}
}
`;
const updateAccessMutation = graphql`
mutation CompliancePageAccessEditDialogUpdateMutation(
$input: UpdateTrustCenterAccessInput!
) {
updateTrustCenterAccess(input: $input) {
trustCenterAccess {
id
email
name
state
hasAcceptedNonDisclosureAgreement
createdAt
updatedAt
pendingRequestCount
activeCount
}
}
}
`;
export function CompliancePageAccessEditDialog(props: {
access: CompliancePageAccessListItemFragment$data;
onClose: () => void;
}
export function TrustCenterAccessEditDialog(
props: TrustCenterAccessEditDialogProps,
) {
}) {
const { access, onClose } = props;
const { __ } = useTranslate();
const [queryRef, loadDocumentAccessesQuery]
= useQueryLoader<TrustCenterAccessGraphLoadDocumentAccessesQuery>(
loadTrustCenterAccessDocumentAccessesQuery,
const [queryRef, loadQuery]
= useQueryLoader<CompliancePageAccessEditDialogQueryType>(
compliancePageAccessEditDialogQuery,
);
useEffect(() => {
loadDocumentAccessesQuery(
loadQuery(
{
accessId: access.id,
},
@@ -58,13 +115,13 @@ export function TrustCenterAccessEditDialog(
fetchPolicy: "network-only",
},
);
}, [access.id, loadDocumentAccessesQuery]);
}, [access.id, loadQuery]);
return (
<Dialog defaultOpen={true} title={__("Edit Access")} onClose={onClose}>
{queryRef && (
<Suspense>
<TrustCenterAccessEditForm
<CompliancePageAccessEditForm
access={access}
queryRef={queryRef}
onSubmit={onClose}
@@ -75,21 +132,17 @@ export function TrustCenterAccessEditDialog(
);
}
interface TrustCenterAccessEditFormProps {
function CompliancePageAccessEditForm(props: {
access: CompliancePageAccessListItemFragment$data;
onSubmit: () => void;
queryRef: PreloadedQuery<TrustCenterAccessGraphLoadDocumentAccessesQuery>;
}
export function TrustCenterAccessEditForm(
props: TrustCenterAccessEditFormProps,
) {
queryRef: PreloadedQuery<CompliancePageAccessEditDialogQueryType>;
}) {
const { access, onSubmit, queryRef } = props;
const { __ } = useTranslate();
const data
= usePreloadedQuery<TrustCenterAccessGraphLoadDocumentAccessesQuery>(
loadTrustCenterAccessDocumentAccessesQuery,
= usePreloadedQuery<CompliancePageAccessEditDialogQueryType>(
compliancePageAccessEditDialogQuery,
queryRef,
);
@@ -154,8 +207,8 @@ export function TrustCenterAccessEditForm(
defaultValues: { name: access.name, active: access.state === "ACTIVE" },
});
const [updateTrustCenterAccess, isUpdating] = useMutationWithToasts(
updateTrustCenterAccessMutation,
const [updateTrustCenterAccess, isUpdating] = useMutationWithToasts<CompliancePageAccessEditDialogUpdateMutation>(
updateAccessMutation,
{
successMessage: __("Access updated successfully"),
errorMessage: __("Failed to update access"),
@@ -228,7 +281,7 @@ export function TrustCenterAccessEditForm(
<ElectronicSignatureSection fragmentRef={data.node.ndaSignature} />
)}
<TrustCenterDocumentAccessList
<CompliancePageDocumentAccessList
documentAccesses={documentAccesses}
initialStatusByID={initialStatusByID}
onGrantAll={handleGrantAllDocumentAccess}

View File

@@ -6,11 +6,10 @@ import { useFragment } from "react-relay";
import { graphql } from "relay-runtime";
import type { CompliancePageAccessListItemFragment$key } from "#/__generated__/core/CompliancePageAccessListItemFragment.graphql";
import type { TrustCenterAccessGraphUpdateMutation } from "#/__generated__/core/TrustCenterAccessGraphUpdateMutation.graphql";
import { updateTrustCenterAccessMutation } from "#/hooks/graph/TrustCenterAccessGraph";
import type { CompliancePageAccessListItemUpdateMutation } from "#/__generated__/core/CompliancePageAccessListItemUpdateMutation.graphql";
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
import { TrustCenterAccessEditDialog } from "#/pages/organizations/trustCenter/TrustCenterAccessTab/TrustCenterAccessEditDialog";
import { CompliancePageAccessEditDialog } from "./CompliancePageAccessEditDialog";
import { NdaSignatureBadge } from "./NdaSignatureBadge";
const fragment = graphql`
@@ -29,6 +28,26 @@ const fragment = graphql`
}
`;
const toggleAccessStateMutation = graphql`
mutation CompliancePageAccessListItemUpdateMutation(
$input: UpdateTrustCenterAccessInput!
) {
updateTrustCenterAccess(input: $input) {
trustCenterAccess {
id
email
name
state
hasAcceptedNonDisclosureAgreement
createdAt
updatedAt
pendingRequestCount
activeCount
}
}
}
`;
export function CompliancePageAccessListItem(props: {
fragmentRef: CompliancePageAccessListItemFragment$key;
dialogOpen: boolean;
@@ -42,8 +61,8 @@ export function CompliancePageAccessListItem(props: {
const isActive = access.state === "ACTIVE";
const [updateAccess, isUpdating] = useMutationWithToasts<TrustCenterAccessGraphUpdateMutation>(
updateTrustCenterAccessMutation,
const [toggleAccessState, isToggling] = useMutationWithToasts<CompliancePageAccessListItemUpdateMutation>(
toggleAccessStateMutation,
{
successMessage: isActive
? __("Access deactivated successfully")
@@ -55,7 +74,7 @@ export function CompliancePageAccessListItem(props: {
);
const handleToggleState = useCallback(() => {
void updateAccess({
void toggleAccessState({
variables: {
input: {
id: access.id,
@@ -64,7 +83,7 @@ export function CompliancePageAccessListItem(props: {
},
},
});
}, [updateAccess, access.id, access.name, isActive]);
}, [toggleAccessState, access.id, access.name, isActive]);
return (
<>
@@ -109,7 +128,7 @@ export function CompliancePageAccessListItem(props: {
<DropdownItem
icon={isActive ? IconArchive : IconRotateCw}
onClick={handleToggleState}
disabled={isUpdating}
disabled={isToggling}
variant={isActive ? "danger" : "primary"}
>
{isActive ? __("Deactivate") : __("Activate")}
@@ -121,7 +140,7 @@ export function CompliancePageAccessListItem(props: {
</Tr>
{access.canUpdate && isActive && dialogOpen && (
<TrustCenterAccessEditDialog
<CompliancePageAccessEditDialog
access={access}
onClose={() => setDialogOpen(false)}
/>

View File

@@ -3,7 +3,7 @@ import { getTrustCenterDocumentAccessStatusBadgeVariant, getTrustCenterDocumentA
import { useTranslate } from "@probo/i18n";
import { Badge, Button, Table, Tbody, Td, Th, Thead, Tr } from "@probo/ui";
interface TrustCenterDocumentAccessListProps {
interface CompliancePageDocumentAccessListProps {
documentAccesses: TrustCenterDocumentAccessInfo[];
initialStatusByID: Record<string, TrustCenterDocumentAccessStatus>;
onGrantAll: () => void;
@@ -11,7 +11,7 @@ interface TrustCenterDocumentAccessListProps {
onUpdateStatus: (docAccess: TrustCenterDocumentAccessInfo, status: TrustCenterDocumentAccessStatus) => void;
}
export function TrustCenterDocumentAccessList(props: TrustCenterDocumentAccessListProps) {
export function CompliancePageDocumentAccessList(props: CompliancePageDocumentAccessListProps) {
const { documentAccesses, initialStatusByID, onGrantAll, onRejectOrRevokeAll, onUpdateStatus } = props;
const { __ } = useTranslate();