From a7cd94956a7316711b3b892b5506ff8b602a17ed Mon Sep 17 00:00:00 2001 From: Bryan Frimin Date: Mon, 28 Apr 2025 16:03:42 -0700 Subject: [PATCH] Refatcor policies management Signed-off-by: Bryan Frimin --- apps/console/public/icons/arrow-inbox.svg | 3 + apps/console/public/icons/clock.svg | 3 + .../public/icons/dot-grid-1x3-horizontal.svg | 5 + .../public/images/dot-grid-1x3-horizontal.svg | 5 + .../organizations/OrganizationBreadcrumb.tsx | 4 +- .../src/pages/organizations/Routes.tsx | 8 +- ...mbBreadcrumbPolicyOverviewQuery.graphql.ts | 12 +- .../frameworks/controls/Control.tsx | 58 +- .../ControlLinkedPoliciesQuery.graphql.ts | 56 +- ...ontrolOrganizationPoliciesQuery.graphql.ts | 56 +- .../organizations/policies/EditPolicyView.tsx | 162 +- .../organizations/policies/NewPolicyPage.tsx | 30 - .../organizations/policies/NewPolicyView.tsx | 281 - .../organizations/policies/PolicyListView.tsx | 381 +- .../organizations/policies/PolicyView.tsx | 423 -- .../{PolicyPage.tsx => ShowPolicyPage.tsx} | 10 +- .../organizations/policies/ShowPolicyView.tsx | 426 ++ .../organizations/policies/SignaturesList.tsx | 74 + .../policies/SignaturesModal.tsx | 469 ++ .../policies/VersionHistoryModal.tsx | 149 + .../EditPolicyViewMutation.graphql.ts | 89 +- .../EditPolicyViewQuery.graphql.ts | 149 +- .../NewPolicyViewQuery.graphql.ts | 230 - ...> PolicyListViewCreateMutation.graphql.ts} | 45 +- .../PolicyListViewQuery.graphql.ts | 364 +- .../PolicyViewDeleteMutation.graphql.ts | 132 - .../__generated__/PolicyViewQuery.graphql.ts | 199 - ...owPolicyViewCreateDraftMutation.graphql.ts | 135 + .../ShowPolicyViewPublishMutation.graphql.ts | 211 + .../ShowPolicyViewQuery.graphql.ts | 606 +++ ...ignaturesModalOrganizationQuery.graphql.ts | 206 + ...esModalRequestSignatureMutation.graphql.ts | 264 + .../SignaturesModal_policyVersions.graphql.ts | 298 ++ ...sionHistoryModal_policyVersions.graphql.ts | 181 + .../organizations/risks/ShowRiskView.tsx | 45 +- ...skViewOrganizationPoliciesQuery.graphql.ts | 21 +- .../ShowRiskViewQuery.graphql.ts | 15 +- pkg/coredata/entity_type_reg.go | 2 + pkg/coredata/migrations/20250424T094500Z.sql | 60 + pkg/coredata/migrations/20250425T012700Z.sql | 22 + pkg/coredata/migrations/20250428T024800Z.sql | 15 + pkg/coredata/people.go | 4 +- pkg/coredata/policy.go | 130 +- pkg/coredata/policy_order_field.go | 2 +- pkg/coredata/policy_status.go | 10 +- pkg/coredata/policy_version.go | 344 ++ pkg/coredata/policy_version_order_field.go | 41 + pkg/coredata/policy_version_signature.go | 197 + .../policy_version_signature_order_field.go | 41 + .../policy_version_signature_state.go | 74 + pkg/probo/people_service.go | 3 +- pkg/probo/policy_service.go | 333 +- pkg/server/api/console/v1/schema.graphql | 188 +- pkg/server/api/console/v1/schema/schema.go | 4579 ++++++++++++++++- pkg/server/api/console/v1/types/policy.go | 12 +- .../api/console/v1/types/policy_version.go | 56 + .../v1/types/policy_version_signature.go | 54 + pkg/server/api/console/v1/types/types.go | 138 +- pkg/server/api/console/v1/v1_resolver.go | 305 +- 59 files changed, 10112 insertions(+), 2303 deletions(-) create mode 100644 apps/console/public/icons/arrow-inbox.svg create mode 100644 apps/console/public/icons/clock.svg create mode 100644 apps/console/public/icons/dot-grid-1x3-horizontal.svg create mode 100644 apps/console/public/images/dot-grid-1x3-horizontal.svg delete mode 100644 apps/console/src/pages/organizations/policies/NewPolicyPage.tsx delete mode 100644 apps/console/src/pages/organizations/policies/NewPolicyView.tsx delete mode 100644 apps/console/src/pages/organizations/policies/PolicyView.tsx rename apps/console/src/pages/organizations/policies/{PolicyPage.tsx => ShowPolicyPage.tsx} (95%) create mode 100644 apps/console/src/pages/organizations/policies/ShowPolicyView.tsx create mode 100644 apps/console/src/pages/organizations/policies/SignaturesList.tsx create mode 100644 apps/console/src/pages/organizations/policies/SignaturesModal.tsx create mode 100644 apps/console/src/pages/organizations/policies/VersionHistoryModal.tsx delete mode 100644 apps/console/src/pages/organizations/policies/__generated__/NewPolicyViewQuery.graphql.ts rename apps/console/src/pages/organizations/policies/__generated__/{NewPolicyViewMutation.graphql.ts => PolicyListViewCreateMutation.graphql.ts} (76%) delete mode 100644 apps/console/src/pages/organizations/policies/__generated__/PolicyViewDeleteMutation.graphql.ts delete mode 100644 apps/console/src/pages/organizations/policies/__generated__/PolicyViewQuery.graphql.ts create mode 100644 apps/console/src/pages/organizations/policies/__generated__/ShowPolicyViewCreateDraftMutation.graphql.ts create mode 100644 apps/console/src/pages/organizations/policies/__generated__/ShowPolicyViewPublishMutation.graphql.ts create mode 100644 apps/console/src/pages/organizations/policies/__generated__/ShowPolicyViewQuery.graphql.ts create mode 100644 apps/console/src/pages/organizations/policies/__generated__/SignaturesModalOrganizationQuery.graphql.ts create mode 100644 apps/console/src/pages/organizations/policies/__generated__/SignaturesModalRequestSignatureMutation.graphql.ts create mode 100644 apps/console/src/pages/organizations/policies/__generated__/SignaturesModal_policyVersions.graphql.ts create mode 100644 apps/console/src/pages/organizations/policies/__generated__/VersionHistoryModal_policyVersions.graphql.ts create mode 100644 pkg/coredata/migrations/20250424T094500Z.sql create mode 100644 pkg/coredata/migrations/20250425T012700Z.sql create mode 100644 pkg/coredata/migrations/20250428T024800Z.sql create mode 100644 pkg/coredata/policy_version.go create mode 100644 pkg/coredata/policy_version_order_field.go create mode 100644 pkg/coredata/policy_version_signature.go create mode 100644 pkg/coredata/policy_version_signature_order_field.go create mode 100644 pkg/coredata/policy_version_signature_state.go create mode 100644 pkg/server/api/console/v1/types/policy_version.go create mode 100644 pkg/server/api/console/v1/types/policy_version_signature.go diff --git a/apps/console/public/icons/arrow-inbox.svg b/apps/console/public/icons/arrow-inbox.svg new file mode 100644 index 000000000..d65d6d200 --- /dev/null +++ b/apps/console/public/icons/arrow-inbox.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/console/public/icons/clock.svg b/apps/console/public/icons/clock.svg new file mode 100644 index 000000000..4d4200ddd --- /dev/null +++ b/apps/console/public/icons/clock.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/console/public/icons/dot-grid-1x3-horizontal.svg b/apps/console/public/icons/dot-grid-1x3-horizontal.svg new file mode 100644 index 000000000..8e9422bec --- /dev/null +++ b/apps/console/public/icons/dot-grid-1x3-horizontal.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/console/public/images/dot-grid-1x3-horizontal.svg b/apps/console/public/images/dot-grid-1x3-horizontal.svg new file mode 100644 index 000000000..8e9422bec --- /dev/null +++ b/apps/console/public/images/dot-grid-1x3-horizontal.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/console/src/pages/organizations/OrganizationBreadcrumb.tsx b/apps/console/src/pages/organizations/OrganizationBreadcrumb.tsx index 6c6d1b8ac..791264474 100644 --- a/apps/console/src/pages/organizations/OrganizationBreadcrumb.tsx +++ b/apps/console/src/pages/organizations/OrganizationBreadcrumb.tsx @@ -290,7 +290,7 @@ function BreadcrumbPolicyOverview() { policy: node(id: $policyId) { id ... on Policy { - name + title } } } @@ -306,7 +306,7 @@ function BreadcrumbPolicyOverview() { - {data.policy?.name} + {data.policy?.title} diff --git a/apps/console/src/pages/organizations/Routes.tsx b/apps/console/src/pages/organizations/Routes.tsx index b53a6144a..1ca98669e 100644 --- a/apps/console/src/pages/organizations/Routes.tsx +++ b/apps/console/src/pages/organizations/Routes.tsx @@ -19,9 +19,8 @@ import { NewPeoplePage } from "./people/NewPeoplePage"; import { PeopleListPage } from "./people/PeopleListPage"; import { PeoplePage } from "./people/PeoplePage"; import { EditPolicyPage } from "./policies/EditPolicyPage"; -import { NewPolicyPage } from "./policies/NewPolicyPage"; import { PolicyListPage } from "./policies/PolicyListPage"; -import { PolicyPage } from "./policies/PolicyPage"; +import { ShowPolicyPage } from "./policies/ShowPolicyPage"; import { EditRiskPage } from "./risks/EditRiskPage"; import { NewRiskPage } from "./risks/NewRiskPage"; import { ListRiskPage } from "./risks/ListRiskPage"; @@ -54,9 +53,8 @@ export function OrganizationsRoutes() { } /> } /> } /> - } /> - } /> - } /> + } /> + } /> } /> } /> } /> diff --git a/apps/console/src/pages/organizations/__generated__/OrganizationBreadcrumbBreadcrumbPolicyOverviewQuery.graphql.ts b/apps/console/src/pages/organizations/__generated__/OrganizationBreadcrumbBreadcrumbPolicyOverviewQuery.graphql.ts index 27dfa88e7..15c92c766 100644 --- a/apps/console/src/pages/organizations/__generated__/OrganizationBreadcrumbBreadcrumbPolicyOverviewQuery.graphql.ts +++ b/apps/console/src/pages/organizations/__generated__/OrganizationBreadcrumbBreadcrumbPolicyOverviewQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<5f81eaad8c66c579401d9c73180f8f91>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -15,7 +15,7 @@ export type OrganizationBreadcrumbBreadcrumbPolicyOverviewQuery$variables = { export type OrganizationBreadcrumbBreadcrumbPolicyOverviewQuery$data = { readonly policy: { readonly id: string; - readonly name?: string; + readonly title?: string; }; }; export type OrganizationBreadcrumbBreadcrumbPolicyOverviewQuery = { @@ -52,7 +52,7 @@ v3 = { "alias": null, "args": null, "kind": "ScalarField", - "name": "name", + "name": "title", "storageKey": null } ], @@ -112,16 +112,16 @@ return { ] }, "params": { - "cacheID": "13d6ac9cf6f904f8a03f141b6b6e2564", + "cacheID": "bc0b04bbe75c94660de230461532773a", "id": null, "metadata": {}, "name": "OrganizationBreadcrumbBreadcrumbPolicyOverviewQuery", "operationKind": "query", - "text": "query OrganizationBreadcrumbBreadcrumbPolicyOverviewQuery(\n $policyId: ID!\n) {\n policy: node(id: $policyId) {\n __typename\n id\n ... on Policy {\n name\n }\n }\n}\n" + "text": "query OrganizationBreadcrumbBreadcrumbPolicyOverviewQuery(\n $policyId: ID!\n) {\n policy: node(id: $policyId) {\n __typename\n id\n ... on Policy {\n title\n }\n }\n}\n" } }; })(); -(node as any).hash = "6ed45dd2d1fa369329edde6b77eec92d"; +(node as any).hash = "ced380d1e6eb1c31ecc5f2dc9096133b"; export default node; diff --git a/apps/console/src/pages/organizations/frameworks/controls/Control.tsx b/apps/console/src/pages/organizations/frameworks/controls/Control.tsx index 26f09ff34..ffe43404e 100644 --- a/apps/console/src/pages/organizations/frameworks/controls/Control.tsx +++ b/apps/console/src/pages/organizations/frameworks/controls/Control.tsx @@ -106,10 +106,15 @@ const linkedPoliciesQuery = graphql` edges { node { id - name - content - status - reviewDate + title + description + currentPublishedVersion + createdAt + updatedAt + owner { + id + fullName + } } } } @@ -128,10 +133,15 @@ const organizationPoliciesQuery = graphql` edges { node { id - name - content - status - reviewDate + title + description + currentPublishedVersion + createdAt + updatedAt + owner { + id + fullName + } } } } @@ -582,7 +592,7 @@ export function Control({ return policies.filter((policy) => { return ( !policySearchQuery || - policy.name.toLowerCase().includes(policySearchQuery.toLowerCase()) || + policy.name?.toLowerCase().includes(policySearchQuery.toLowerCase()) || (policy.content && policy.content .toLowerCase() @@ -1066,10 +1076,7 @@ export function Control({ Name - Status - - Review Date - + Review Date Actions @@ -1093,17 +1100,6 @@ export function Control({ )} - -
- {policy.status} -
- {policy.reviewDate ? new Date( @@ -1137,7 +1133,7 @@ export function Control({ handleLinkPolicy(policy.id) } disabled={isLinkingPolicy} - className="text-xs h-7 text-info border-info-b hover:bg-h-info-bg" + className="text-xs h-7 text-info border-info-b hover:bg-h-info-bg" > {isLinkingPolicy ? ( @@ -1193,7 +1189,6 @@ export function Control({ Name - Status Review Date Actions @@ -1214,17 +1209,6 @@ export function Control({ )} - -
- {policy.status} -
- {policy.reviewDate ? new Date(policy.reviewDate).toLocaleDateString() diff --git a/apps/console/src/pages/organizations/frameworks/controls/__generated__/ControlLinkedPoliciesQuery.graphql.ts b/apps/console/src/pages/organizations/frameworks/controls/__generated__/ControlLinkedPoliciesQuery.graphql.ts index c31c8654e..dcca1dfbb 100644 --- a/apps/console/src/pages/organizations/frameworks/controls/__generated__/ControlLinkedPoliciesQuery.graphql.ts +++ b/apps/console/src/pages/organizations/frameworks/controls/__generated__/ControlLinkedPoliciesQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<9bddb18bf52f14881a85995793bdc1ca>> + * @generated SignedSource<<85bdd7f83672d1a88247d958f4b7dfaf>> * @lightSyntaxTransform * @nogrep */ @@ -9,7 +9,6 @@ // @ts-nocheck import { ConcreteRequest } from 'relay-runtime'; -export type PolicyStatus = "ACTIVE" | "DRAFT"; export type ControlLinkedPoliciesQuery$variables = { controlId: string; }; @@ -19,11 +18,16 @@ export type ControlLinkedPoliciesQuery$data = { readonly policies?: { readonly edges: ReadonlyArray<{ readonly node: { - readonly content: string; + readonly createdAt: string; + readonly currentPublishedVersion: number | null | undefined; + readonly description: string; readonly id: string; - readonly name: string; - readonly reviewDate: string | null | undefined; - readonly status: PolicyStatus; + readonly owner: { + readonly fullName: string; + readonly id: string; + }; + readonly title: string; + readonly updatedAt: string; }; }>; }; @@ -85,28 +89,54 @@ v4 = [ "alias": null, "args": null, "kind": "ScalarField", - "name": "name", + "name": "title", "storageKey": null }, { "alias": null, "args": null, "kind": "ScalarField", - "name": "content", + "name": "description", "storageKey": null }, { "alias": null, "args": null, "kind": "ScalarField", - "name": "status", + "name": "currentPublishedVersion", "storageKey": null }, { "alias": null, "args": null, "kind": "ScalarField", - "name": "reviewDate", + "name": "createdAt", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "updatedAt", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "People", + "kind": "LinkedField", + "name": "owner", + "plural": false, + "selections": [ + (v2/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "fullName", + "storageKey": null + } + ], "storageKey": null }, (v3/*: any*/) @@ -244,7 +274,7 @@ return { ] }, "params": { - "cacheID": "67f9bf1d5f255f5406e932abde540e08", + "cacheID": "24c5ce380772f28348df8cf089a58a8e", "id": null, "metadata": { "connection": [ @@ -261,11 +291,11 @@ return { }, "name": "ControlLinkedPoliciesQuery", "operationKind": "query", - "text": "query ControlLinkedPoliciesQuery(\n $controlId: ID!\n) {\n control: node(id: $controlId) {\n __typename\n id\n ... on Control {\n policies(first: 100) {\n edges {\n node {\n id\n name\n content\n status\n reviewDate\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n" + "text": "query ControlLinkedPoliciesQuery(\n $controlId: ID!\n) {\n control: node(id: $controlId) {\n __typename\n id\n ... on Control {\n policies(first: 100) {\n edges {\n node {\n id\n title\n description\n currentPublishedVersion\n createdAt\n updatedAt\n owner {\n id\n fullName\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n" } }; })(); -(node as any).hash = "3904c2344754177177fa7c16129dc894"; +(node as any).hash = "d4d16cac2a05ea1d38fde55d04f21c01"; export default node; diff --git a/apps/console/src/pages/organizations/frameworks/controls/__generated__/ControlOrganizationPoliciesQuery.graphql.ts b/apps/console/src/pages/organizations/frameworks/controls/__generated__/ControlOrganizationPoliciesQuery.graphql.ts index ac483608f..8e139a145 100644 --- a/apps/console/src/pages/organizations/frameworks/controls/__generated__/ControlOrganizationPoliciesQuery.graphql.ts +++ b/apps/console/src/pages/organizations/frameworks/controls/__generated__/ControlOrganizationPoliciesQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<1f9de20276a5c0b1291c5e25dc11990b>> * @lightSyntaxTransform * @nogrep */ @@ -9,7 +9,6 @@ // @ts-nocheck import { ConcreteRequest } from 'relay-runtime'; -export type PolicyStatus = "ACTIVE" | "DRAFT"; export type ControlOrganizationPoliciesQuery$variables = { organizationId: string; }; @@ -19,11 +18,16 @@ export type ControlOrganizationPoliciesQuery$data = { readonly policies?: { readonly edges: ReadonlyArray<{ readonly node: { - readonly content: string; + readonly createdAt: string; + readonly currentPublishedVersion: number | null | undefined; + readonly description: string; readonly id: string; - readonly name: string; - readonly reviewDate: string | null | undefined; - readonly status: PolicyStatus; + readonly owner: { + readonly fullName: string; + readonly id: string; + }; + readonly title: string; + readonly updatedAt: string; }; }>; }; @@ -85,28 +89,54 @@ v4 = [ "alias": null, "args": null, "kind": "ScalarField", - "name": "name", + "name": "title", "storageKey": null }, { "alias": null, "args": null, "kind": "ScalarField", - "name": "content", + "name": "description", "storageKey": null }, { "alias": null, "args": null, "kind": "ScalarField", - "name": "status", + "name": "currentPublishedVersion", "storageKey": null }, { "alias": null, "args": null, "kind": "ScalarField", - "name": "reviewDate", + "name": "createdAt", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "updatedAt", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "People", + "kind": "LinkedField", + "name": "owner", + "plural": false, + "selections": [ + (v2/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "fullName", + "storageKey": null + } + ], "storageKey": null }, (v3/*: any*/) @@ -244,7 +274,7 @@ return { ] }, "params": { - "cacheID": "3a3c91f3e18e8a4b66011aa583e262e4", + "cacheID": "94e32c7758c8df264b99a44150de687d", "id": null, "metadata": { "connection": [ @@ -261,11 +291,11 @@ return { }, "name": "ControlOrganizationPoliciesQuery", "operationKind": "query", - "text": "query ControlOrganizationPoliciesQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n policies(first: 100) {\n edges {\n node {\n id\n name\n content\n status\n reviewDate\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n" + "text": "query ControlOrganizationPoliciesQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n policies(first: 100) {\n edges {\n node {\n id\n title\n description\n currentPublishedVersion\n createdAt\n updatedAt\n owner {\n id\n fullName\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n" } }; })(); -(node as any).hash = "f4699d729e6df6192efd201047689204"; +(node as any).hash = "47aaf55ffb65d3220df2b0fe2688bc12"; export default node; diff --git a/apps/console/src/pages/organizations/policies/EditPolicyView.tsx b/apps/console/src/pages/organizations/policies/EditPolicyView.tsx index 5ffc9d121..a1e60a434 100644 --- a/apps/console/src/pages/organizations/policies/EditPolicyView.tsx +++ b/apps/console/src/pages/organizations/policies/EditPolicyView.tsx @@ -10,27 +10,30 @@ import { import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; import { Label } from "@/components/ui/label"; import { toast } from "@/hooks/use-toast"; -import { Calendar, User } from "lucide-react"; -import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { Suspense } from "react"; -import PolicyEditor from "@/components/PolicyEditor"; import PeopleSelector from "@/components/PeopleSelector"; import type { EditPolicyViewQuery } from "./__generated__/EditPolicyViewQuery.graphql"; import type { EditPolicyViewMutation as EditPolicyViewMutationType } from "./__generated__/EditPolicyViewMutation.graphql"; import { PageTemplate } from "@/components/PageTemplate"; import { EditPolicyViewSkeleton } from "./EditPolicyPage"; +import { User } from "lucide-react"; const editPolicyViewQuery = graphql` - query EditPolicyViewQuery($policyId: ID!, $organizationId: ID!) { + query EditPolicyViewQuery($policyId: ID!, $organizationId: ID!, $policyVersionId: ID!) { + policyVersion: node(id: $policyVersionId) { + id + ... on PolicyVersion { + content + } + } + policy: node(id: $policyId) { id ... on Policy { - name - content - status - reviewDate + title owner { id fullName @@ -44,18 +47,11 @@ const editPolicyViewQuery = graphql` `; const UpdatePolicyMutation = graphql` - mutation EditPolicyViewMutation($input: UpdatePolicyInput!) { - updatePolicy(input: $input) { - policy { + mutation EditPolicyViewMutation($input: UpdatePolicyVersionInput!) { + updatePolicyVersion(input: $input) { + policyVersion { id - name content - status - reviewDate - owner { - id - fullName - } } } } @@ -67,56 +63,28 @@ function EditPolicyViewContent({ queryRef: PreloadedQuery; }) { const navigate = useNavigate(); - const { organizationId, policyId } = useParams(); + const { organizationId, policyId, versionId } = useParams(); const data = usePreloadedQuery( editPolicyViewQuery, queryRef ); - console.log("EditPolicyView data:", data.policy); + const [content, setContent] = useState(data.policyVersion.content || ""); - const [name, setName] = useState(data.policy.name); - const [content, setContent] = useState(data.policy.content || ""); - const [status, setStatus] = useState(data.policy.status); - const [reviewDate, setReviewDate] = useState(data.policy.reviewDate || ""); - const [ownerId, setOwnerId] = useState( - data.policy.owner?.id || null - ); - const [isSubmitting, setIsSubmitting] = useState(false); - - console.log( - "EditPolicyView state - content:", - content - ? content.substring(0, 50) + (content.length > 50 ? "..." : "") - : "empty" - ); - - const [commitMutation] = + const [updatePolicy, isSubmitting] = useMutation(UpdatePolicyMutation); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - setIsSubmitting(true); - // Convert reviewDate string to ISO format for the API - let reviewDateValue = null; - if (reviewDate) { - reviewDateValue = new Date(reviewDate).toISOString(); - } - - commitMutation({ + updatePolicy({ variables: { input: { - id: data.policy.id, - name, + policyVersionId: data.policyVersion.id, content, - status, - reviewDate: reviewDateValue, - ownerId, }, }, - onCompleted: (response, errors) => { - setIsSubmitting(false); + onCompleted: (_, errors) => { if (errors) { console.error("Error updating policy:", errors); toast({ @@ -134,7 +102,6 @@ function EditPolicyViewContent({ navigate(`/organizations/${organizationId}/policies/${policyId}`); }, onError: (error) => { - setIsSubmitting(false); console.error("Error updating policy:", error); toast({ title: "Error", @@ -153,77 +120,20 @@ function EditPolicyViewContent({ Policy Information -
- - setName(e.target.value)} - required - /> -
-
-
- setContent(html)} +
+