Simplify UX of compliance access management

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2026-02-10 11:32:20 +01:00
parent 09b6934c04
commit 5f7d4689aa
23 changed files with 323 additions and 190 deletions

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<c3f94c9533e0031a201dd75921757748>> * @generated SignedSource<<e5a5b11ba24baf03ee3f94fa65cf3591>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,9 +9,9 @@
// @ts-nocheck // @ts-nocheck
import { ReaderFragment } from 'relay-runtime'; import { ReaderFragment } from 'relay-runtime';
export type TrustCenterAccessState = "ACTIVE" | "INACTIVE";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type CompliancePageAccessListItemFragment$data = { export type CompliancePageAccessListItemFragment$data = {
readonly active: boolean;
readonly activeCount: number; readonly activeCount: number;
readonly canDelete: boolean; readonly canDelete: boolean;
readonly canUpdate: boolean; readonly canUpdate: boolean;
@@ -21,6 +21,7 @@ export type CompliancePageAccessListItemFragment$data = {
readonly id: string; readonly id: string;
readonly name: string; readonly name: string;
readonly pendingRequestCount: number; readonly pendingRequestCount: number;
readonly state: TrustCenterAccessState;
readonly " $fragmentType": "CompliancePageAccessListItemFragment"; readonly " $fragmentType": "CompliancePageAccessListItemFragment";
}; };
export type CompliancePageAccessListItemFragment$key = { export type CompliancePageAccessListItemFragment$key = {
@@ -66,7 +67,7 @@ const node: ReaderFragment = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "active", "name": "state",
"storageKey": null "storageKey": null
}, },
{ {
@@ -121,6 +122,6 @@ const node: ReaderFragment = {
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = "e7120d76d08974b672e2ed1e66bf6cd7"; (node as any).hash = "4e78486a2c8edc2b5f73fb64dbeb4006";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<3c657b1368adbcba6300b5b94eff92f2>> * @generated SignedSource<<19cd995fe2d7406ddfadd5df6f2b2412>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -256,7 +256,7 @@ return {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "active", "name": "state",
"storageKey": null "storageKey": null
}, },
{ {
@@ -349,12 +349,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "75c843f8501c2e5bd2c1422f7cf35b5f", "cacheID": "27720ebe7c7eee3a27c486be063d9f18",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "CompliancePageAccessListQuery", "name": "CompliancePageAccessListQuery",
"operationKind": "query", "operationKind": "query",
"text": "query CompliancePageAccessListQuery(\n $after: CursorKey = null\n $first: Int = 10\n $order: TrustCenterAccessOrder = {field: CREATED_AT, direction: DESC}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...CompliancePageAccessListFragment_gOVF5\n id\n }\n}\n\nfragment CompliancePageAccessListFragment_gOVF5 on TrustCenter {\n accesses(first: $first, after: $after, orderBy: $order) {\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n cursor\n node {\n id\n ...CompliancePageAccessListItemFragment\n __typename\n }\n }\n }\n id\n}\n\nfragment CompliancePageAccessListItemFragment on TrustCenterAccess {\n id\n name\n email\n createdAt\n active\n activeCount\n pendingRequestCount\n hasAcceptedNonDisclosureAgreement\n canUpdate: permission(action: \"core:trust-center-access:update\")\n canDelete: permission(action: \"core:trust-center-access:delete\")\n}\n" "text": "query CompliancePageAccessListQuery(\n $after: CursorKey = null\n $first: Int = 10\n $order: TrustCenterAccessOrder = {field: CREATED_AT, direction: DESC}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...CompliancePageAccessListFragment_gOVF5\n id\n }\n}\n\nfragment CompliancePageAccessListFragment_gOVF5 on TrustCenter {\n accesses(first: $first, after: $after, orderBy: $order) {\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n cursor\n node {\n id\n ...CompliancePageAccessListItemFragment\n __typename\n }\n }\n }\n id\n}\n\nfragment CompliancePageAccessListItemFragment on TrustCenterAccess {\n id\n name\n email\n createdAt\n state\n activeCount\n pendingRequestCount\n hasAcceptedNonDisclosureAgreement\n canUpdate: permission(action: \"core:trust-center-access:update\")\n canDelete: permission(action: \"core:trust-center-access:delete\")\n}\n"
} }
}; };
})(); })();

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<e5353f41022bedfa45f3607edac692d7>> * @generated SignedSource<<2ba5d01d3d1dbb4956627eae14df34ab>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -265,7 +265,7 @@ return {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "active", "name": "state",
"storageKey": null "storageKey": null
}, },
{ {
@@ -362,12 +362,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "651e7d8df512ab49f09e5b086a488266", "cacheID": "6e4d46f7b3fdff2e4650ea27d96b8c5b",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "CompliancePageAccessPageQuery", "name": "CompliancePageAccessPageQuery",
"operationKind": "query", "operationKind": "query",
"text": "query CompliancePageAccessPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n compliancePage: trustCenter {\n id\n canCreateAccess: permission(action: \"core:trust-center-access:create\")\n ...CompliancePageAccessListFragment\n }\n }\n id\n }\n}\n\nfragment CompliancePageAccessListFragment on TrustCenter {\n accesses(first: 10, orderBy: {field: CREATED_AT, direction: DESC}) {\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n cursor\n node {\n id\n ...CompliancePageAccessListItemFragment\n __typename\n }\n }\n }\n id\n}\n\nfragment CompliancePageAccessListItemFragment on TrustCenterAccess {\n id\n name\n email\n createdAt\n active\n activeCount\n pendingRequestCount\n hasAcceptedNonDisclosureAgreement\n canUpdate: permission(action: \"core:trust-center-access:update\")\n canDelete: permission(action: \"core:trust-center-access:delete\")\n}\n" "text": "query CompliancePageAccessPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n compliancePage: trustCenter {\n id\n canCreateAccess: permission(action: \"core:trust-center-access:create\")\n ...CompliancePageAccessListFragment\n }\n }\n id\n }\n}\n\nfragment CompliancePageAccessListFragment on TrustCenter {\n accesses(first: 10, orderBy: {field: CREATED_AT, direction: DESC}) {\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n cursor\n node {\n id\n ...CompliancePageAccessListItemFragment\n __typename\n }\n }\n }\n id\n}\n\nfragment CompliancePageAccessListItemFragment on TrustCenterAccess {\n id\n name\n email\n createdAt\n state\n activeCount\n pendingRequestCount\n hasAcceptedNonDisclosureAgreement\n canUpdate: permission(action: \"core:trust-center-access:update\")\n canDelete: permission(action: \"core:trust-center-access:delete\")\n}\n"
} }
}; };
})(); })();

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<953f0fbe58d5428b76797adcd479aa06>> * @generated SignedSource<<8d43c1f38ab045ccce31f220486fcb88>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -11,7 +11,6 @@
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type CreateTrustCenterAccessInput = { export type CreateTrustCenterAccessInput = {
active: boolean;
email: string; email: string;
name: string; name: string;
trustCenterId: string; trustCenterId: string;
@@ -182,7 +181,7 @@ return {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "active", "name": "state",
"storageKey": null "storageKey": null
}, },
{ {
@@ -260,12 +259,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "35604e9722512d1d60d70b6bce7d866b", "cacheID": "ed150f3e2ca1f480ae7d18be081dfec1",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "NewCompliancePageAccessDialogMutation", "name": "NewCompliancePageAccessDialogMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation NewCompliancePageAccessDialogMutation(\n $input: CreateTrustCenterAccessInput!\n) {\n createTrustCenterAccess(input: $input) {\n trustCenterAccessEdge {\n cursor\n node {\n id\n ...CompliancePageAccessListItemFragment\n }\n }\n }\n}\n\nfragment CompliancePageAccessListItemFragment on TrustCenterAccess {\n id\n name\n email\n createdAt\n active\n activeCount\n pendingRequestCount\n hasAcceptedNonDisclosureAgreement\n canUpdate: permission(action: \"core:trust-center-access:update\")\n canDelete: permission(action: \"core:trust-center-access:delete\")\n}\n" "text": "mutation NewCompliancePageAccessDialogMutation(\n $input: CreateTrustCenterAccessInput!\n) {\n createTrustCenterAccess(input: $input) {\n trustCenterAccessEdge {\n cursor\n node {\n id\n ...CompliancePageAccessListItemFragment\n }\n }\n }\n}\n\nfragment CompliancePageAccessListItemFragment on TrustCenterAccess {\n id\n name\n email\n createdAt\n state\n activeCount\n pendingRequestCount\n hasAcceptedNonDisclosureAgreement\n canUpdate: permission(action: \"core:trust-center-access:update\")\n canDelete: permission(action: \"core:trust-center-access:delete\")\n}\n"
} }
}; };
})(); })();

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<d0efc00be7fc303cb2c45ae11fe587c7>> * @generated SignedSource<<8060916e92063b503b064a3ce7675e1a>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,13 +9,14 @@
// @ts-nocheck // @ts-nocheck
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
export type TrustCenterAccessState = "ACTIVE" | "INACTIVE";
export type TrustCenterDocumentAccessStatus = "GRANTED" | "REJECTED" | "REQUESTED" | "REVOKED"; export type TrustCenterDocumentAccessStatus = "GRANTED" | "REJECTED" | "REQUESTED" | "REVOKED";
export type UpdateTrustCenterAccessInput = { export type UpdateTrustCenterAccessInput = {
active?: boolean | null | undefined;
documents?: ReadonlyArray<TrustCenterDocumentAccessInput> | null | undefined; documents?: ReadonlyArray<TrustCenterDocumentAccessInput> | null | undefined;
id: string; id: string;
name?: string | null | undefined; name?: string | null | undefined;
reports?: ReadonlyArray<TrustCenterDocumentAccessInput> | null | undefined; reports?: ReadonlyArray<TrustCenterDocumentAccessInput> | null | undefined;
state?: TrustCenterAccessState | null | undefined;
trustCenterFiles?: ReadonlyArray<TrustCenterDocumentAccessInput> | null | undefined; trustCenterFiles?: ReadonlyArray<TrustCenterDocumentAccessInput> | null | undefined;
}; };
export type TrustCenterDocumentAccessInput = { export type TrustCenterDocumentAccessInput = {
@@ -28,7 +29,6 @@ export type TrustCenterAccessGraphUpdateMutation$variables = {
export type TrustCenterAccessGraphUpdateMutation$data = { export type TrustCenterAccessGraphUpdateMutation$data = {
readonly updateTrustCenterAccess: { readonly updateTrustCenterAccess: {
readonly trustCenterAccess: { readonly trustCenterAccess: {
readonly active: boolean;
readonly activeCount: number; readonly activeCount: number;
readonly createdAt: string; readonly createdAt: string;
readonly email: string; readonly email: string;
@@ -36,6 +36,7 @@ export type TrustCenterAccessGraphUpdateMutation$data = {
readonly id: string; readonly id: string;
readonly name: string; readonly name: string;
readonly pendingRequestCount: number; readonly pendingRequestCount: number;
readonly state: TrustCenterAccessState;
readonly updatedAt: string; readonly updatedAt: string;
}; };
}; };
@@ -101,7 +102,7 @@ v1 = [
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "active", "name": "state",
"storageKey": null "storageKey": null
}, },
{ {
@@ -164,16 +165,16 @@ return {
"selections": (v1/*: any*/) "selections": (v1/*: any*/)
}, },
"params": { "params": {
"cacheID": "1367c160aa881878e5eed860509e7610", "cacheID": "bfc1209ce4d692ddb3692305aff7a33d",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "TrustCenterAccessGraphUpdateMutation", "name": "TrustCenterAccessGraphUpdateMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation TrustCenterAccessGraphUpdateMutation(\n $input: UpdateTrustCenterAccessInput!\n) {\n updateTrustCenterAccess(input: $input) {\n trustCenterAccess {\n id\n email\n name\n active\n hasAcceptedNonDisclosureAgreement\n createdAt\n updatedAt\n pendingRequestCount\n activeCount\n }\n }\n}\n" "text": "mutation TrustCenterAccessGraphUpdateMutation(\n $input: UpdateTrustCenterAccessInput!\n) {\n updateTrustCenterAccess(input: $input) {\n trustCenterAccess {\n id\n email\n name\n state\n hasAcceptedNonDisclosureAgreement\n createdAt\n updatedAt\n pendingRequestCount\n activeCount\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "7e5d2ce261f3e877ef54e5acfbd00bde"; (node as any).hash = "750e100701bf905c8fff08f3f5155b5b";
export default node; export default node;

View File

@@ -9,7 +9,7 @@ export const updateTrustCenterAccessMutation = graphql`
id id
email email
name name
active state
hasAcceptedNonDisclosureAgreement hasAcceptedNonDisclosureAgreement
createdAt createdAt
updatedAt updatedAt

View File

@@ -77,7 +77,6 @@ export function CompliancePageAccessList(props: {
<Th>{__("Name")}</Th> <Th>{__("Name")}</Th>
<Th>{__("Email")}</Th> <Th>{__("Email")}</Th>
<Th>{__("Date")}</Th> <Th>{__("Date")}</Th>
<Th className="text-center">{__("Active")}</Th>
<Th className="text-center">{__("Access")}</Th> <Th className="text-center">{__("Access")}</Th>
<Th className="text-center">{__("Requests")}</Th> <Th className="text-center">{__("Requests")}</Th>
<Th className="text-center">{__("NDA")}</Th> <Th className="text-center">{__("NDA")}</Th>
@@ -89,7 +88,6 @@ export function CompliancePageAccessList(props: {
<CompliancePageAccessListItem <CompliancePageAccessListItem
key={`${access.id}-${editingAccessId === access.id}`} key={`${access.id}-${editingAccessId === access.id}`}
fragmentRef={access} fragmentRef={access}
connectionId={accesses.__id}
dialogOpen={editingAccessId === access.id} dialogOpen={editingAccessId === access.id}
/> />
))} ))}

View File

@@ -1,12 +1,13 @@
import { formatDate } from "@probo/helpers"; import { formatDate } from "@probo/helpers";
import { useTranslate } from "@probo/i18n"; import { useTranslate } from "@probo/i18n";
import { Button, IconCheckmark1, IconCrossLargeX, IconPencil, IconTrashCan, Td, Tr } from "@probo/ui"; import { ActionDropdown, DropdownItem, IconArchive, IconCheckmark1, IconPencil, IconRotateCw, Td, Tr } from "@probo/ui";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { useFragment } from "react-relay"; import { useFragment } from "react-relay";
import { type DataID, graphql } from "relay-runtime"; import { graphql } from "relay-runtime";
import type { CompliancePageAccessListItem_deleteMutation } from "#/__generated__/core/CompliancePageAccessListItem_deleteMutation.graphql";
import type { CompliancePageAccessListItemFragment$key } from "#/__generated__/core/CompliancePageAccessListItemFragment.graphql"; import type { CompliancePageAccessListItemFragment$key } from "#/__generated__/core/CompliancePageAccessListItemFragment.graphql";
import type { TrustCenterAccessGraphUpdateMutation } from "#/__generated__/core/TrustCenterAccessGraphUpdateMutation.graphql";
import { updateTrustCenterAccessMutation } from "#/hooks/graph/TrustCenterAccessGraph";
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts"; import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
import { TrustCenterAccessEditDialog } from "#/pages/organizations/trustCenter/TrustCenterAccessTab/TrustCenterAccessEditDialog"; import { TrustCenterAccessEditDialog } from "#/pages/organizations/trustCenter/TrustCenterAccessTab/TrustCenterAccessEditDialog";
@@ -16,79 +17,61 @@ const fragment = graphql`
name name
email email
createdAt createdAt
active state
activeCount activeCount
pendingRequestCount pendingRequestCount
hasAcceptedNonDisclosureAgreement hasAcceptedNonDisclosureAgreement
canUpdate: permission(action: "core:trust-center-access:update") canUpdate: permission(action: "core:trust-center-access:update")
canDelete: permission(action: "core:trust-center-access:delete")
}
`;
const deleteCompliancePageAccessMutation = graphql`
mutation CompliancePageAccessListItem_deleteMutation(
$input: DeleteTrustCenterAccessInput!
$connections: [ID!]!
) {
deleteTrustCenterAccess(input: $input) {
deletedTrustCenterAccessId @deleteEdge(connections: $connections)
}
} }
`; `;
export function CompliancePageAccessListItem(props: { export function CompliancePageAccessListItem(props: {
connectionId: DataID;
fragmentRef: CompliancePageAccessListItemFragment$key; fragmentRef: CompliancePageAccessListItemFragment$key;
dialogOpen: boolean; dialogOpen: boolean;
}) { }) {
const { connectionId, fragmentRef, dialogOpen: initialDialogOpen } = props; const { fragmentRef, dialogOpen: initialDialogOpen } = props;
const { __ } = useTranslate(); const { __ } = useTranslate();
const [dialogOpen, setDialogOpen] = useState<boolean>(initialDialogOpen); const [dialogOpen, setDialogOpen] = useState<boolean>(initialDialogOpen);
const access = useFragment<CompliancePageAccessListItemFragment$key>(fragment, fragmentRef); const access = useFragment<CompliancePageAccessListItemFragment$key>(fragment, fragmentRef);
const [deleteInvitation, isDeleting] = useMutationWithToasts<CompliancePageAccessListItem_deleteMutation>( const isActive = access.state === "ACTIVE";
deleteCompliancePageAccessMutation,
const [updateAccess, isUpdating] = useMutationWithToasts<TrustCenterAccessGraphUpdateMutation>(
updateTrustCenterAccessMutation,
{ {
successMessage: __("Access deleted successfully"), successMessage: isActive
errorMessage: __("Failed to delete access"), ? __("Access deactivated successfully")
: __("Access activated successfully"),
errorMessage: isActive
? __("Failed to deactivate access")
: __("Failed to activate access"),
}, },
); );
const handleDelete = useCallback( const handleToggleState = useCallback(() => {
async (id: string) => { updateAccess({
await deleteInvitation({ variables: {
variables: { input: {
input: { id }, id: access.id,
connections: [connectionId], name: access.name,
state: isActive ? "INACTIVE" : "ACTIVE",
}, },
}); },
}, });
[deleteInvitation, connectionId], }, [updateAccess, access.id, access.name, isActive]);
);
return ( return (
<> <>
<Tr <Tr
key={access.id} key={access.id}
onClick={() => access.canUpdate && setDialogOpen(true)} onClick={() => access.canUpdate && isActive && setDialogOpen(true)}
className="cursor-pointer hover:bg-bg-secondary transition-colors" className={`cursor-pointer hover:bg-bg-secondary transition-colors${!isActive ? " opacity-50" : ""}`}
> >
<Td className="font-medium">{access.name}</Td> <Td className="font-medium">{access.name}</Td>
<Td>{access.email}</Td> <Td>{access.email}</Td>
<Td>{formatDate(access.createdAt)}</Td> <Td>{formatDate(access.createdAt)}</Td>
<Td>
<div className="flex justify-center">
{access.active
? (
<IconCheckmark1 size={16} className="text-txt-success" />
)
: (
<IconCrossLargeX size={16} className="text-txt-danger" />
)}
</div>
</Td>
<Td className="text-center">{access.activeCount}</Td> <Td className="text-center">{access.activeCount}</Td>
<Td className="text-center"> <Td className="text-center">
{access.pendingRequestCount > 0 ? access.pendingRequestCount : ""} {access.pendingRequestCount > 0 ? access.pendingRequestCount : ""}
@@ -106,25 +89,30 @@ export function CompliancePageAccessListItem(props: {
onClick={e => e.stopPropagation()} onClick={e => e.stopPropagation()}
> >
{access.canUpdate && ( {access.canUpdate && (
<Button <ActionDropdown>
variant="secondary" {isActive && (
onClick={() => setDialogOpen(true)} <DropdownItem
icon={IconPencil} icon={IconPencil}
/> onClick={() => setDialogOpen(true)}
)} >
{access.canDelete && ( {__("Edit")}
<Button </DropdownItem>
variant="danger" )}
onClick={() => void handleDelete(access.id)} <DropdownItem
disabled={isDeleting} icon={isActive ? IconArchive : IconRotateCw}
icon={IconTrashCan} onClick={handleToggleState}
/> disabled={isUpdating}
variant={isActive ? "danger" : "primary"}
>
{isActive ? __("Deactivate") : __("Activate")}
</DropdownItem>
</ActionDropdown>
)} )}
</div> </div>
</Td> </Td>
</Tr> </Tr>
{access.canUpdate && dialogOpen && ( {access.canUpdate && isActive && dialogOpen && (
<TrustCenterAccessEditDialog <TrustCenterAccessEditDialog
access={access} access={access}
onClose={() => setDialogOpen(false)} onClose={() => setDialogOpen(false)}

View File

@@ -64,7 +64,6 @@ export function NewCompliancePageAccessDialog(props: {
trustCenterId: compliancePageId, trustCenterId: compliancePageId,
email: email, email: email,
name: data.name.trim(), name: data.name.trim(),
active: false,
}, },
connections: connectionId ? [connectionId] : [], connections: connectionId ? [connectionId] : [],
}, },

View File

@@ -6,7 +6,6 @@ import {
import { useTranslate } from "@probo/i18n"; import { useTranslate } from "@probo/i18n";
import { import {
Button, Button,
Checkbox,
Dialog, Dialog,
DialogContent, DialogContent,
DialogFooter, DialogFooter,
@@ -151,7 +150,7 @@ export function TrustCenterAccessEditForm(
active: z.boolean(), active: z.boolean(),
}); });
const editForm = useFormWithSchema(editSchema, { const editForm = useFormWithSchema(editSchema, {
defaultValues: { name: access.name, active: access.active }, defaultValues: { name: access.name, active: access.state === "ACTIVE" },
}); });
const [updateTrustCenterAccess, isUpdating] = useMutationWithToasts( const [updateTrustCenterAccess, isUpdating] = useMutationWithToasts(
@@ -196,7 +195,7 @@ export function TrustCenterAccessEditForm(
input: { input: {
id: access.id, id: access.id,
name: data.name.trim(), name: data.name.trim(),
active: data.active, state: data.active ? "ACTIVE" : "INACTIVE",
documents, documents,
reports, reports,
trustCenterFiles, trustCenterFiles,
@@ -222,20 +221,6 @@ export function TrustCenterAccessEditForm(
placeholder={__("John Doe")} placeholder={__("John Doe")}
/> />
<div className="flex items-center justify-between mt-6">
<div>
<label className="font-medium text-txt-primary">
{__("Active Status")}
</label>
<p className="text-sm text-txt-secondary">
{__("Enable or disable access for this user")}
</p>
</div>
<Checkbox
checked={editForm.watch("active")}
onChange={checked => editForm.setValue("active", checked)}
/>
</div>
</div> </div>
<TrustCenterDocumentAccessList <TrustCenterDocumentAccessList

View File

@@ -0,0 +1,13 @@
import type { IconProps } from "./type";
// Source: Lucide Icons "archive" - https://lucide.dev/icons/archive
// Licensed under ISC License
export function IconArchive({ size = 24, className }: IconProps) {
return (
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className} xmlns="http://www.w3.org/2000/svg">
<rect width="20" height="5" x="2" y="3" rx="1" />
<path d="M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8" />
<path d="M10 12h4" />
</svg>
);
}

View File

@@ -1,3 +1,4 @@
export { IconArchive } from "./IconArchive";
export { IconArrowUp } from "./IconArrowUp"; export { IconArrowUp } from "./IconArrowUp";
export { IconBox } from "./IconBox"; export { IconBox } from "./IconBox";
export { IconBell2 } from "./IconBell2"; export { IconBell2 } from "./IconBell2";

View File

@@ -0,0 +1,14 @@
CREATE TYPE trust_center_access_state AS ENUM ('ACTIVE', 'INACTIVE');
ALTER TABLE trust_center_accesses
ADD COLUMN state trust_center_access_state NOT NULL DEFAULT 'INACTIVE';
UPDATE trust_center_accesses
SET state = 'ACTIVE'
WHERE active = true;
ALTER TABLE trust_center_accesses
DROP COLUMN active;
ALTER TABLE trust_center_accesses
ALTER COLUMN state DROP DEFAULT;

View File

@@ -32,18 +32,18 @@ import (
type ( type (
TrustCenterAccess struct { TrustCenterAccess struct {
ID gid.GID `db:"id"` ID gid.GID `db:"id"`
OrganizationID gid.GID `db:"organization_id"` OrganizationID gid.GID `db:"organization_id"`
TenantID gid.TenantID `db:"tenant_id"` TenantID gid.TenantID `db:"tenant_id"`
TrustCenterID gid.GID `db:"trust_center_id"` TrustCenterID gid.GID `db:"trust_center_id"`
Email mail.Addr `db:"email"` Email mail.Addr `db:"email"`
Name string `db:"name"` Name string `db:"name"`
Active bool `db:"active"` State TrustCenterAccessState `db:"state"`
HasAcceptedNonDisclosureAgreement bool `db:"has_accepted_non_disclosure_agreement"` HasAcceptedNonDisclosureAgreement bool `db:"has_accepted_non_disclosure_agreement"`
HasAcceptedNonDisclosureAgreementMetadata json.RawMessage `db:"has_accepted_non_disclosure_agreement_metadata"` HasAcceptedNonDisclosureAgreementMetadata json.RawMessage `db:"has_accepted_non_disclosure_agreement_metadata"`
NDAFileID *gid.GID `db:"nda_file_id"` NDAFileID *gid.GID `db:"nda_file_id"`
CreatedAt time.Time `db:"created_at"` CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"` UpdatedAt time.Time `db:"updated_at"`
} }
TrustCenterAccesses []*TrustCenterAccess TrustCenterAccesses []*TrustCenterAccess
@@ -86,7 +86,7 @@ SELECT
trust_center_id, trust_center_id,
email, email,
name, name,
active, state,
has_accepted_non_disclosure_agreement, has_accepted_non_disclosure_agreement,
has_accepted_non_disclosure_agreement_metadata, has_accepted_non_disclosure_agreement_metadata,
nda_file_id, nda_file_id,
@@ -139,7 +139,7 @@ SELECT
trust_center_id, trust_center_id,
email, email,
name, name,
active, state,
has_accepted_non_disclosure_agreement, has_accepted_non_disclosure_agreement,
has_accepted_non_disclosure_agreement_metadata, has_accepted_non_disclosure_agreement_metadata,
nda_file_id, nda_file_id,
@@ -194,7 +194,7 @@ INSERT INTO trust_center_accesses (
trust_center_id, trust_center_id,
email, email,
name, name,
active, state,
has_accepted_non_disclosure_agreement, has_accepted_non_disclosure_agreement,
created_at, created_at,
updated_at updated_at
@@ -205,7 +205,7 @@ INSERT INTO trust_center_accesses (
@trust_center_id, @trust_center_id,
@email, @email,
@name, @name,
@active, @state,
@has_accepted_non_disclosure_agreement, @has_accepted_non_disclosure_agreement,
@created_at, @created_at,
@updated_at @updated_at
@@ -219,7 +219,7 @@ INSERT INTO trust_center_accesses (
"trust_center_id": tca.TrustCenterID, "trust_center_id": tca.TrustCenterID,
"email": tca.Email, "email": tca.Email,
"name": tca.Name, "name": tca.Name,
"active": tca.Active, "state": tca.State,
"has_accepted_non_disclosure_agreement": tca.HasAcceptedNonDisclosureAgreement, "has_accepted_non_disclosure_agreement": tca.HasAcceptedNonDisclosureAgreement,
"created_at": tca.CreatedAt, "created_at": tca.CreatedAt,
"updated_at": tca.UpdatedAt, "updated_at": tca.UpdatedAt,
@@ -247,7 +247,7 @@ func (tca *TrustCenterAccess) Update(
q := ` q := `
UPDATE trust_center_accesses SET UPDATE trust_center_accesses SET
name = @name, name = @name,
active = @active, state = @state,
updated_at = @updated_at, updated_at = @updated_at,
has_accepted_non_disclosure_agreement = @has_accepted_non_disclosure_agreement, has_accepted_non_disclosure_agreement = @has_accepted_non_disclosure_agreement,
has_accepted_non_disclosure_agreement_metadata = @has_accepted_non_disclosure_agreement_metadata, has_accepted_non_disclosure_agreement_metadata = @has_accepted_non_disclosure_agreement_metadata,
@@ -262,7 +262,7 @@ WHERE
args := pgx.StrictNamedArgs{ args := pgx.StrictNamedArgs{
"id": tca.ID, "id": tca.ID,
"name": tca.Name, "name": tca.Name,
"active": tca.Active, "state": tca.State,
"updated_at": tca.UpdatedAt, "updated_at": tca.UpdatedAt,
"has_accepted_non_disclosure_agreement": tca.HasAcceptedNonDisclosureAgreement, "has_accepted_non_disclosure_agreement": tca.HasAcceptedNonDisclosureAgreement,
"has_accepted_non_disclosure_agreement_metadata": tca.HasAcceptedNonDisclosureAgreementMetadata, "has_accepted_non_disclosure_agreement_metadata": tca.HasAcceptedNonDisclosureAgreementMetadata,
@@ -320,7 +320,7 @@ SELECT
trust_center_id, trust_center_id,
email, email,
name, name,
active, state,
has_accepted_non_disclosure_agreement, has_accepted_non_disclosure_agreement,
has_accepted_non_disclosure_agreement_metadata, has_accepted_non_disclosure_agreement_metadata,
nda_file_id, nda_file_id,

View File

@@ -0,0 +1,57 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.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.
package coredata
import (
"database/sql/driver"
"fmt"
)
type TrustCenterAccessState string
const (
TrustCenterAccessStateActive TrustCenterAccessState = "ACTIVE"
TrustCenterAccessStateInactive TrustCenterAccessState = "INACTIVE"
)
func (s TrustCenterAccessState) String() string {
return string(s)
}
func (s *TrustCenterAccessState) Scan(value any) error {
var str string
switch v := value.(type) {
case string:
str = v
case []byte:
str = string(v)
default:
return fmt.Errorf("unsupported type for TrustCenterAccessState: %T", value)
}
switch str {
case "ACTIVE":
*s = TrustCenterAccessStateActive
case "INACTIVE":
*s = TrustCenterAccessStateInactive
default:
return fmt.Errorf("invalid TrustCenterAccessState value: %q", str)
}
return nil
}
func (s TrustCenterAccessState) Value() (driver.Value, error) {
return s.String(), nil
}

View File

@@ -49,7 +49,7 @@ type (
UpdateTrustCenterAccessRequest struct { UpdateTrustCenterAccessRequest struct {
ID gid.GID ID gid.GID
Name *string Name *string
Active *bool State *coredata.TrustCenterAccessState
DocumentAccesses []UpdateTrustCenterDocumentAccessRequest DocumentAccesses []UpdateTrustCenterDocumentAccessRequest
ReportAccesses []UpdateTrustCenterDocumentAccessRequest ReportAccesses []UpdateTrustCenterDocumentAccessRequest
TrustCenterFileAccesses []UpdateTrustCenterDocumentAccessRequest TrustCenterFileAccesses []UpdateTrustCenterDocumentAccessRequest
@@ -243,7 +243,7 @@ func (s TrustCenterAccessService) Create(
TrustCenterID: req.TrustCenterID, TrustCenterID: req.TrustCenterID,
Email: req.Email, Email: req.Email,
Name: req.FullName, Name: req.FullName,
Active: false, State: coredata.TrustCenterAccessStateActive,
HasAcceptedNonDisclosureAgreement: false, HasAcceptedNonDisclosureAgreement: false,
CreatedAt: now, CreatedAt: now,
UpdatedAt: now, UpdatedAt: now,
@@ -286,12 +286,12 @@ func (s TrustCenterAccessService) Update(
return fmt.Errorf("cannot load trust center access: %w", err) return fmt.Errorf("cannot load trust center access: %w", err)
} }
trustCenterAcessActivated = req.Active != nil && *req.Active && !access.Active trustCenterAcessActivated = req.State != nil && *req.State == coredata.TrustCenterAccessStateActive && access.State != coredata.TrustCenterAccessStateActive
if req.Name != nil { if req.Name != nil {
access.Name = *req.Name access.Name = *req.Name
} }
if req.Active != nil { if req.State != nil {
access.Active = *req.Active access.State = *req.State
} }
access.UpdatedAt = now access.UpdatedAt = now

View File

@@ -23,6 +23,7 @@ import (
"github.com/vektah/gqlparser/v2/gqlerror" "github.com/vektah/gqlparser/v2/gqlerror"
"go.gearno.de/kit/httpserver" "go.gearno.de/kit/httpserver"
"go.gearno.de/kit/log" "go.gearno.de/kit/log"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/server/api/authn" "go.probo.inc/probo/pkg/server/api/authn"
"go.probo.inc/probo/pkg/server/gqlutils" "go.probo.inc/probo/pkg/server/gqlutils"
"go.probo.inc/probo/pkg/trust" "go.probo.inc/probo/pkg/trust"
@@ -61,7 +62,7 @@ func NewMembershipMiddleware(trustSvc *trust.Service, logger *log.Logger) func(n
return return
} }
if membership.Active { if membership.State == coredata.TrustCenterAccessStateActive {
ctx = context.WithValue(ctx, complianceMembershipKey, membership) ctx = context.WithValue(ctx, complianceMembershipKey, membership)
next.ServeHTTP(w, r.WithContext(ctx)) next.ServeHTTP(w, r.WithContext(ctx))
return return

View File

@@ -1175,6 +1175,20 @@ enum TrustCenterAccessOrderField
) )
} }
enum TrustCenterAccessState
@goModel(
model: "go.probo.inc/probo/pkg/coredata.TrustCenterAccessState"
) {
ACTIVE
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.TrustCenterAccessStateActive"
)
INACTIVE
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.TrustCenterAccessStateInactive"
)
}
enum TrustCenterDocumentAccessOrderField enum TrustCenterDocumentAccessOrderField
@goModel( @goModel(
model: "go.probo.inc/probo/pkg/coredata.TrustCenterDocumentAccessOrderField" model: "go.probo.inc/probo/pkg/coredata.TrustCenterDocumentAccessOrderField"
@@ -2572,7 +2586,7 @@ type TrustCenterAccess implements Node {
id: ID! id: ID!
email: EmailAddr! email: EmailAddr!
name: String! name: String!
active: Boolean! state: TrustCenterAccessState!
hasAcceptedNonDisclosureAgreement: Boolean! hasAcceptedNonDisclosureAgreement: Boolean!
createdAt: Datetime! createdAt: Datetime!
updatedAt: Datetime! updatedAt: Datetime!
@@ -3458,7 +3472,6 @@ input CreateTrustCenterAccessInput {
trustCenterId: ID! trustCenterId: ID!
email: EmailAddr! email: EmailAddr!
name: String! name: String!
active: Boolean!
} }
input TrustCenterDocumentAccessInput { input TrustCenterDocumentAccessInput {
@@ -3469,7 +3482,7 @@ input TrustCenterDocumentAccessInput {
input UpdateTrustCenterAccessInput { input UpdateTrustCenterAccessInput {
id: ID! id: ID!
name: String name: String
active: Boolean state: TrustCenterAccessState
documents: [TrustCenterDocumentAccessInput!] documents: [TrustCenterDocumentAccessInput!]
reports: [TrustCenterDocumentAccessInput!] reports: [TrustCenterDocumentAccessInput!]
trustCenterFiles: [TrustCenterDocumentAccessInput!] trustCenterFiles: [TrustCenterDocumentAccessInput!]

View File

@@ -1511,7 +1511,6 @@ type ComplexityRoot struct {
} }
TrustCenterAccess struct { TrustCenterAccess struct {
Active func(childComplexity int) int
ActiveCount func(childComplexity int) int ActiveCount func(childComplexity int) int
AvailableDocumentAccesses func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterDocumentAccessOrderField]) int AvailableDocumentAccesses func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterDocumentAccessOrderField]) int
CreatedAt func(childComplexity int) int CreatedAt func(childComplexity int) int
@@ -1522,6 +1521,7 @@ type ComplexityRoot struct {
Name func(childComplexity int) int Name func(childComplexity int) int
PendingRequestCount func(childComplexity int) int PendingRequestCount func(childComplexity int) int
Permission func(childComplexity int, action string) int Permission func(childComplexity int, action string) int
State func(childComplexity int) int
UpdatedAt func(childComplexity int) int UpdatedAt func(childComplexity int) int
} }
@@ -8662,12 +8662,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.TrustCenter.UpdatedAt(childComplexity), true return e.complexity.TrustCenter.UpdatedAt(childComplexity), true
case "TrustCenterAccess.active":
if e.complexity.TrustCenterAccess.Active == nil {
break
}
return e.complexity.TrustCenterAccess.Active(childComplexity), true
case "TrustCenterAccess.activeCount": case "TrustCenterAccess.activeCount":
if e.complexity.TrustCenterAccess.ActiveCount == nil { if e.complexity.TrustCenterAccess.ActiveCount == nil {
break break
@@ -8738,6 +8732,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
} }
return e.complexity.TrustCenterAccess.Permission(childComplexity, args["action"].(string)), true return e.complexity.TrustCenterAccess.Permission(childComplexity, args["action"].(string)), true
case "TrustCenterAccess.state":
if e.complexity.TrustCenterAccess.State == nil {
break
}
return e.complexity.TrustCenterAccess.State(childComplexity), true
case "TrustCenterAccess.updatedAt": case "TrustCenterAccess.updatedAt":
if e.complexity.TrustCenterAccess.UpdatedAt == nil { if e.complexity.TrustCenterAccess.UpdatedAt == nil {
break break
@@ -11528,6 +11528,20 @@ enum TrustCenterAccessOrderField
) )
} }
enum TrustCenterAccessState
@goModel(
model: "go.probo.inc/probo/pkg/coredata.TrustCenterAccessState"
) {
ACTIVE
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.TrustCenterAccessStateActive"
)
INACTIVE
@goEnum(
value: "go.probo.inc/probo/pkg/coredata.TrustCenterAccessStateInactive"
)
}
enum TrustCenterDocumentAccessOrderField enum TrustCenterDocumentAccessOrderField
@goModel( @goModel(
model: "go.probo.inc/probo/pkg/coredata.TrustCenterDocumentAccessOrderField" model: "go.probo.inc/probo/pkg/coredata.TrustCenterDocumentAccessOrderField"
@@ -12925,7 +12939,7 @@ type TrustCenterAccess implements Node {
id: ID! id: ID!
email: EmailAddr! email: EmailAddr!
name: String! name: String!
active: Boolean! state: TrustCenterAccessState!
hasAcceptedNonDisclosureAgreement: Boolean! hasAcceptedNonDisclosureAgreement: Boolean!
createdAt: Datetime! createdAt: Datetime!
updatedAt: Datetime! updatedAt: Datetime!
@@ -13811,7 +13825,6 @@ input CreateTrustCenterAccessInput {
trustCenterId: ID! trustCenterId: ID!
email: EmailAddr! email: EmailAddr!
name: String! name: String!
active: Boolean!
} }
input TrustCenterDocumentAccessInput { input TrustCenterDocumentAccessInput {
@@ -13822,7 +13835,7 @@ input TrustCenterDocumentAccessInput {
input UpdateTrustCenterAccessInput { input UpdateTrustCenterAccessInput {
id: ID! id: ID!
name: String name: String
active: Boolean state: TrustCenterAccessState
documents: [TrustCenterDocumentAccessInput!] documents: [TrustCenterDocumentAccessInput!]
reports: [TrustCenterDocumentAccessInput!] reports: [TrustCenterDocumentAccessInput!]
trustCenterFiles: [TrustCenterDocumentAccessInput!] trustCenterFiles: [TrustCenterDocumentAccessInput!]
@@ -51094,30 +51107,30 @@ func (ec *executionContext) fieldContext_TrustCenterAccess_name(_ context.Contex
return fc, nil return fc, nil
} }
func (ec *executionContext) _TrustCenterAccess_active(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenterAccess) (ret graphql.Marshaler) { func (ec *executionContext) _TrustCenterAccess_state(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenterAccess) (ret graphql.Marshaler) {
return graphql.ResolveField( return graphql.ResolveField(
ctx, ctx,
ec.OperationContext, ec.OperationContext,
field, field,
ec.fieldContext_TrustCenterAccess_active, ec.fieldContext_TrustCenterAccess_state,
func(ctx context.Context) (any, error) { func(ctx context.Context) (any, error) {
return obj.Active, nil return obj.State, nil
}, },
nil, nil,
ec.marshalNBoolean2bool, ec.marshalNTrustCenterAccessState2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState,
true, true,
true, true,
) )
} }
func (ec *executionContext) fieldContext_TrustCenterAccess_active(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { func (ec *executionContext) fieldContext_TrustCenterAccess_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{ fc = &graphql.FieldContext{
Object: "TrustCenterAccess", Object: "TrustCenterAccess",
Field: field, Field: field,
IsMethod: false, IsMethod: false,
IsResolver: false, IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Boolean does not have child fields") return nil, errors.New("field of type TrustCenterAccessState does not have child fields")
}, },
} }
return fc, nil return fc, nil
@@ -51520,8 +51533,8 @@ func (ec *executionContext) fieldContext_TrustCenterAccessEdge_node(_ context.Co
return ec.fieldContext_TrustCenterAccess_email(ctx, field) return ec.fieldContext_TrustCenterAccess_email(ctx, field)
case "name": case "name":
return ec.fieldContext_TrustCenterAccess_name(ctx, field) return ec.fieldContext_TrustCenterAccess_name(ctx, field)
case "active": case "state":
return ec.fieldContext_TrustCenterAccess_active(ctx, field) return ec.fieldContext_TrustCenterAccess_state(ctx, field)
case "hasAcceptedNonDisclosureAgreement": case "hasAcceptedNonDisclosureAgreement":
return ec.fieldContext_TrustCenterAccess_hasAcceptedNonDisclosureAgreement(ctx, field) return ec.fieldContext_TrustCenterAccess_hasAcceptedNonDisclosureAgreement(ctx, field)
case "createdAt": case "createdAt":
@@ -54373,8 +54386,8 @@ func (ec *executionContext) fieldContext_UpdateTrustCenterAccessPayload_trustCen
return ec.fieldContext_TrustCenterAccess_email(ctx, field) return ec.fieldContext_TrustCenterAccess_email(ctx, field)
case "name": case "name":
return ec.fieldContext_TrustCenterAccess_name(ctx, field) return ec.fieldContext_TrustCenterAccess_name(ctx, field)
case "active": case "state":
return ec.fieldContext_TrustCenterAccess_active(ctx, field) return ec.fieldContext_TrustCenterAccess_state(ctx, field)
case "hasAcceptedNonDisclosureAgreement": case "hasAcceptedNonDisclosureAgreement":
return ec.fieldContext_TrustCenterAccess_hasAcceptedNonDisclosureAgreement(ctx, field) return ec.fieldContext_TrustCenterAccess_hasAcceptedNonDisclosureAgreement(ctx, field)
case "createdAt": case "createdAt":
@@ -63154,7 +63167,7 @@ func (ec *executionContext) unmarshalInputCreateTrustCenterAccessInput(ctx conte
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"trustCenterId", "email", "name", "active"} fieldsInOrder := [...]string{"trustCenterId", "email", "name"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -63182,13 +63195,6 @@ func (ec *executionContext) unmarshalInputCreateTrustCenterAccessInput(ctx conte
return it, err return it, err
} }
it.Name = data it.Name = data
case "active":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("active"))
data, err := ec.unmarshalNBoolean2bool(ctx, v)
if err != nil {
return it, err
}
it.Active = data
} }
} }
@@ -68055,7 +68061,7 @@ func (ec *executionContext) unmarshalInputUpdateTrustCenterAccessInput(ctx conte
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"id", "name", "active", "documents", "reports", "trustCenterFiles"} fieldsInOrder := [...]string{"id", "name", "state", "documents", "reports", "trustCenterFiles"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -68076,13 +68082,13 @@ func (ec *executionContext) unmarshalInputUpdateTrustCenterAccessInput(ctx conte
return it, err return it, err
} }
it.Name = data it.Name = data
case "active": case "state":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("active")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("state"))
data, err := ec.unmarshalOBoolean2ᚖbool(ctx, v) data, err := ec.unmarshalOTrustCenterAccessState2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState(ctx, v)
if err != nil { if err != nil {
return it, err return it, err
} }
it.Active = data it.State = data
case "documents": case "documents":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("documents")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("documents"))
data, err := ec.unmarshalOTrustCenterDocumentAccessInput2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐTrustCenterDocumentAccessInputᚄ(ctx, v) data, err := ec.unmarshalOTrustCenterDocumentAccessInput2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐTrustCenterDocumentAccessInputᚄ(ctx, v)
@@ -85235,8 +85241,8 @@ func (ec *executionContext) _TrustCenterAccess(ctx context.Context, sel ast.Sele
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1) atomic.AddUint32(&out.Invalids, 1)
} }
case "active": case "state":
out.Values[i] = ec._TrustCenterAccess_active(ctx, field, obj) out.Values[i] = ec._TrustCenterAccess_state(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1) atomic.AddUint32(&out.Invalids, 1)
} }
@@ -96901,6 +96907,34 @@ var (
} }
) )
func (ec *executionContext) unmarshalNTrustCenterAccessState2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState(ctx context.Context, v any) (coredata.TrustCenterAccessState, error) {
tmp, err := graphql.UnmarshalString(v)
res := unmarshalNTrustCenterAccessState2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState[tmp]
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNTrustCenterAccessState2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState(ctx context.Context, sel ast.SelectionSet, v coredata.TrustCenterAccessState) graphql.Marshaler {
_ = sel
res := graphql.MarshalString(marshalNTrustCenterAccessState2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState[v])
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow")
}
}
return res
}
var (
unmarshalNTrustCenterAccessState2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState = map[string]coredata.TrustCenterAccessState{
"ACTIVE": coredata.TrustCenterAccessStateActive,
"INACTIVE": coredata.TrustCenterAccessStateInactive,
}
marshalNTrustCenterAccessState2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState = map[coredata.TrustCenterAccessState]string{
coredata.TrustCenterAccessStateActive: "ACTIVE",
coredata.TrustCenterAccessStateInactive: "INACTIVE",
}
)
func (ec *executionContext) marshalNTrustCenterDocumentAccess2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐTrustCenterDocumentAccess(ctx context.Context, sel ast.SelectionSet, v *types.TrustCenterDocumentAccess) graphql.Marshaler { func (ec *executionContext) marshalNTrustCenterDocumentAccess2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐTrustCenterDocumentAccess(ctx context.Context, sel ast.SelectionSet, v *types.TrustCenterDocumentAccess) graphql.Marshaler {
if v == nil { if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
@@ -100605,6 +100639,36 @@ func (ec *executionContext) unmarshalOTrustCenterAccessOrder2ᚖgoᚗproboᚗinc
return &res, graphql.ErrorOnPath(ctx, err) return &res, graphql.ErrorOnPath(ctx, err)
} }
func (ec *executionContext) unmarshalOTrustCenterAccessState2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState(ctx context.Context, v any) (*coredata.TrustCenterAccessState, error) {
if v == nil {
return nil, nil
}
tmp, err := graphql.UnmarshalString(v)
res := unmarshalOTrustCenterAccessState2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState[tmp]
return &res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalOTrustCenterAccessState2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState(ctx context.Context, sel ast.SelectionSet, v *coredata.TrustCenterAccessState) graphql.Marshaler {
if v == nil {
return graphql.Null
}
_ = sel
_ = ctx
res := graphql.MarshalString(marshalOTrustCenterAccessState2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState[*v])
return res
}
var (
unmarshalOTrustCenterAccessState2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState = map[string]coredata.TrustCenterAccessState{
"ACTIVE": coredata.TrustCenterAccessStateActive,
"INACTIVE": coredata.TrustCenterAccessStateInactive,
}
marshalOTrustCenterAccessState2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐTrustCenterAccessState = map[coredata.TrustCenterAccessState]string{
coredata.TrustCenterAccessStateActive: "ACTIVE",
coredata.TrustCenterAccessStateInactive: "INACTIVE",
}
)
func (ec *executionContext) unmarshalOTrustCenterDocumentAccessInput2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐTrustCenterDocumentAccessInputᚄ(ctx context.Context, v any) ([]*types.TrustCenterDocumentAccessInput, error) { func (ec *executionContext) unmarshalOTrustCenterDocumentAccessInput2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐTrustCenterDocumentAccessInputᚄ(ctx context.Context, v any) ([]*types.TrustCenterDocumentAccessInput, error) {
if v == nil { if v == nil {
return nil, nil return nil, nil

View File

@@ -21,18 +21,6 @@ import (
type TrustCenterAccessOrderBy = OrderBy[coredata.TrustCenterAccessOrderField] type TrustCenterAccessOrderBy = OrderBy[coredata.TrustCenterAccessOrderField]
func NewTrustCenterAccess(tca *coredata.TrustCenterAccess) *TrustCenterAccess {
return &TrustCenterAccess{
ID: tca.ID,
Email: tca.Email,
Name: tca.Name,
Active: tca.Active,
HasAcceptedNonDisclosureAgreement: tca.HasAcceptedNonDisclosureAgreement,
CreatedAt: tca.CreatedAt,
UpdatedAt: tca.UpdatedAt,
}
}
func NewTrustCenterAccessConnection( func NewTrustCenterAccessConnection(
page *page.Page[*coredata.TrustCenterAccess, coredata.TrustCenterAccessOrderField], page *page.Page[*coredata.TrustCenterAccess, coredata.TrustCenterAccessOrderField],
) *TrustCenterAccessConnection { ) *TrustCenterAccessConnection {
@@ -54,3 +42,15 @@ func NewTrustCenterAccessEdge(tca *coredata.TrustCenterAccess, orderBy coredata.
Node: NewTrustCenterAccess(tca), Node: NewTrustCenterAccess(tca),
} }
} }
func NewTrustCenterAccess(tca *coredata.TrustCenterAccess) *TrustCenterAccess {
return &TrustCenterAccess{
ID: tca.ID,
Email: tca.Email,
Name: tca.Name,
State: tca.State,
HasAcceptedNonDisclosureAgreement: tca.HasAcceptedNonDisclosureAgreement,
CreatedAt: tca.CreatedAt,
UpdatedAt: tca.UpdatedAt,
}
}

View File

@@ -615,7 +615,6 @@ type CreateTrustCenterAccessInput struct {
TrustCenterID gid.GID `json:"trustCenterId"` TrustCenterID gid.GID `json:"trustCenterId"`
Email mail.Addr `json:"email"` Email mail.Addr `json:"email"`
Name string `json:"name"` Name string `json:"name"`
Active bool `json:"active"`
} }
type CreateTrustCenterAccessPayload struct { type CreateTrustCenterAccessPayload struct {
@@ -1862,7 +1861,7 @@ type TrustCenterAccess struct {
ID gid.GID `json:"id"` ID gid.GID `json:"id"`
Email mail.Addr `json:"email"` Email mail.Addr `json:"email"`
Name string `json:"name"` Name string `json:"name"`
Active bool `json:"active"` State coredata.TrustCenterAccessState `json:"state"`
HasAcceptedNonDisclosureAgreement bool `json:"hasAcceptedNonDisclosureAgreement"` HasAcceptedNonDisclosureAgreement bool `json:"hasAcceptedNonDisclosureAgreement"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"` UpdatedAt time.Time `json:"updatedAt"`
@@ -2256,7 +2255,7 @@ type UpdateTransferImpactAssessmentPayload struct {
type UpdateTrustCenterAccessInput struct { type UpdateTrustCenterAccessInput struct {
ID gid.GID `json:"id"` ID gid.GID `json:"id"`
Name *string `json:"name,omitempty"` Name *string `json:"name,omitempty"`
Active *bool `json:"active,omitempty"` State *coredata.TrustCenterAccessState `json:"state,omitempty"`
Documents []*TrustCenterDocumentAccessInput `json:"documents,omitempty"` Documents []*TrustCenterDocumentAccessInput `json:"documents,omitempty"`
Reports []*TrustCenterDocumentAccessInput `json:"reports,omitempty"` Reports []*TrustCenterDocumentAccessInput `json:"reports,omitempty"`
TrustCenterFiles []*TrustCenterDocumentAccessInput `json:"trustCenterFiles,omitempty"` TrustCenterFiles []*TrustCenterDocumentAccessInput `json:"trustCenterFiles,omitempty"`

View File

@@ -1921,7 +1921,7 @@ func (r *mutationResolver) UpdateTrustCenterAccess(ctx context.Context, input ty
&probo.UpdateTrustCenterAccessRequest{ &probo.UpdateTrustCenterAccessRequest{
ID: input.ID, ID: input.ID,
Name: input.Name, Name: input.Name,
Active: input.Active, State: input.State,
DocumentAccesses: documentAccesses, DocumentAccesses: documentAccesses,
ReportAccesses: reportAccesses, ReportAccesses: reportAccesses,
TrustCenterFileAccesses: fileAccesses, TrustCenterFileAccesses: fileAccesses,

View File

@@ -148,7 +148,7 @@ func (s TrustCenterAccessService) Request(
TrustCenterID: req.TrustCenterID, TrustCenterID: req.TrustCenterID,
Email: req.Email, Email: req.Email,
Name: req.FullName, Name: req.FullName,
Active: false, State: coredata.TrustCenterAccessStateInactive,
HasAcceptedNonDisclosureAgreement: false, HasAcceptedNonDisclosureAgreement: false,
CreatedAt: now, CreatedAt: now,
UpdatedAt: now, UpdatedAt: now,
@@ -301,7 +301,7 @@ func (s TrustCenterAccessService) LoadDocumentAccess(
return fmt.Errorf("cannot load trust center access: %w", err) return fmt.Errorf("cannot load trust center access: %w", err)
} }
if !access.Active { if access.State != coredata.TrustCenterAccessStateActive {
return ErrMembershipInactive return ErrMembershipInactive
} }
@@ -344,7 +344,7 @@ func (s TrustCenterAccessService) LoadReportAccess(
return fmt.Errorf("cannot load trust center access: %w", err) return fmt.Errorf("cannot load trust center access: %w", err)
} }
if !access.Active { if access.State != coredata.TrustCenterAccessStateActive {
return ErrMembershipInactive return ErrMembershipInactive
} }
@@ -387,7 +387,7 @@ func (s TrustCenterAccessService) LoadTrustCenterFileAccess(
return fmt.Errorf("cannot load trust center access: %w", err) return fmt.Errorf("cannot load trust center access: %w", err)
} }
if !access.Active { if access.State != coredata.TrustCenterAccessStateActive {
return ErrMembershipInactive return ErrMembershipInactive
} }
@@ -430,7 +430,7 @@ func (s *TrustCenterAccessService) GrantByIDs(
return fmt.Errorf("cannot load trust center access: %w", err) return fmt.Errorf("cannot load trust center access: %w", err)
} }
shouldSendEmail := !access.Active shouldSendEmail := access.State != coredata.TrustCenterAccessStateActive
now := time.Now() now := time.Now()
if len(documentIDs) > 0 { if len(documentIDs) > 0 {
@@ -450,7 +450,7 @@ func (s *TrustCenterAccessService) GrantByIDs(
} }
if shouldSendEmail { if shouldSendEmail {
access.Active = true access.State = coredata.TrustCenterAccessStateActive
access.UpdatedAt = now access.UpdatedAt = now
if err := access.Update(ctx, tx, s.svc.scope); err != nil { if err := access.Update(ctx, tx, s.svc.scope); err != nil {
return fmt.Errorf("cannot update trust center access: %w", err) return fmt.Errorf("cannot update trust center access: %w", err)