Refatcor policies management
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -290,7 +290,7 @@ function BreadcrumbPolicyOverview() {
|
||||
policy: node(id: $policyId) {
|
||||
id
|
||||
... on Policy {
|
||||
name
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -306,7 +306,7 @@ function BreadcrumbPolicyOverview() {
|
||||
<BreadcrumbNavLink
|
||||
to={`/organizations/${organizationId}/policies/${policyId}`}
|
||||
>
|
||||
{data.policy?.name}
|
||||
{data.policy?.title}
|
||||
</BreadcrumbNavLink>
|
||||
</BreadcrumbItem>
|
||||
<Outlet />
|
||||
|
||||
@@ -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() {
|
||||
<Route path="mesures/:mesureId/edit" element={<EditMesurePage />} />
|
||||
<Route path="vendors/:vendorId" element={<VendorPage />} />
|
||||
<Route path="policies" element={<PolicyListPage />} />
|
||||
<Route path="policies/new" element={<NewPolicyPage />} />
|
||||
<Route path="policies/:policyId" element={<PolicyPage />} />
|
||||
<Route path="policies/:policyId/edit" element={<EditPolicyPage />} />
|
||||
<Route path="policies/:policyId" element={<ShowPolicyPage />} />
|
||||
<Route path="policies/:policyId/versions/:versionId/edit" element={<EditPolicyPage />} />
|
||||
<Route path="risks" element={<ListRiskPage />} />
|
||||
<Route path="risks/new" element={<NewRiskPage />} />
|
||||
<Route path="risks/:riskId" element={<ShowRiskView />} />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<5f81eaad8c66c579401d9c73180f8f91>>
|
||||
* @generated SignedSource<<ca410ce7df7231383e55d134d37916bd>>
|
||||
* @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;
|
||||
|
||||
@@ -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({
|
||||
<thead className="sticky top-0 bg-white">
|
||||
<tr className="border-b text-left text-sm text-secondary bg-invert-bg">
|
||||
<th className="py-3 px-4 font-medium">Name</th>
|
||||
<th className="py-3 px-4 font-medium">Status</th>
|
||||
<th className="py-3 px-4 font-medium">
|
||||
Review Date
|
||||
</th>
|
||||
<th className="py-3 px-4 font-medium">Review Date</th>
|
||||
<th className="py-3 px-4 font-medium text-right">
|
||||
Actions
|
||||
</th>
|
||||
@@ -1093,17 +1100,6 @@ export function Control({
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
<td className="py-3 px-4">
|
||||
<div
|
||||
className={`px-2 py-0.5 rounded-full text-xs ${
|
||||
policy.status === "ACTIVE"
|
||||
? "bg-success-bg text-success"
|
||||
: "bg-secondary-bg text-secondary"
|
||||
} inline-block`}
|
||||
>
|
||||
{policy.status}
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-3 px-4">
|
||||
{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 ? (
|
||||
<Loader2 className="w-4 h-4 animate-spin" />
|
||||
@@ -1193,7 +1189,6 @@ export function Control({
|
||||
<thead>
|
||||
<tr className="border-b text-left text-sm text-secondary bg-invert-bg">
|
||||
<th className="py-3 px-4 font-medium">Name</th>
|
||||
<th className="py-3 px-4 font-medium">Status</th>
|
||||
<th className="py-3 px-4 font-medium">Review Date</th>
|
||||
<th className="py-3 px-4 font-medium text-right">
|
||||
Actions
|
||||
@@ -1214,17 +1209,6 @@ export function Control({
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
<td className="py-3 px-4">
|
||||
<div
|
||||
className={`px-2 py-0.5 rounded-full text-xs ${
|
||||
policy.status === "ACTIVE"
|
||||
? "bg-success-bg text-success"
|
||||
: "bg-secondary-bg text-secondary"
|
||||
} inline-block`}
|
||||
>
|
||||
{policy.status}
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-3 px-4">
|
||||
{policy.reviewDate
|
||||
? new Date(policy.reviewDate).toLocaleDateString()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<cfe85b9fdabaf24f9a7f575eca8a6417>>
|
||||
* @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;
|
||||
|
||||
@@ -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<EditPolicyViewQuery>;
|
||||
}) {
|
||||
const navigate = useNavigate();
|
||||
const { organizationId, policyId } = useParams();
|
||||
const { organizationId, policyId, versionId } = useParams();
|
||||
const data = usePreloadedQuery<EditPolicyViewQuery>(
|
||||
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<string | null>(
|
||||
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<EditPolicyViewMutationType>(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({
|
||||
<CardTitle>Policy Information</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="name">Policy Name</Label>
|
||||
<Input
|
||||
id="name"
|
||||
placeholder="Enter policy name"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="content">Policy Content</Label>
|
||||
<div className="min-h-[300px]">
|
||||
<PolicyEditor
|
||||
initialContent={content}
|
||||
onChange={(html) => setContent(html)}
|
||||
<div className="min-h-[500px]">
|
||||
<Textarea
|
||||
id="content"
|
||||
placeholder="Enter policy description"
|
||||
value={content}
|
||||
onChange={(e) => setContent(e.target.value)}
|
||||
required
|
||||
rows={20}
|
||||
className="min-h-[500px] resize-y"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label>Status</Label>
|
||||
<RadioGroup
|
||||
value={status}
|
||||
onValueChange={(value) =>
|
||||
setStatus(value as "DRAFT" | "ACTIVE")
|
||||
}
|
||||
className="flex space-x-4"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="DRAFT" id="draft" />
|
||||
<Label htmlFor="draft" className="cursor-pointer">
|
||||
Draft
|
||||
</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="ACTIVE" id="active" />
|
||||
<Label htmlFor="active" className="cursor-pointer">
|
||||
Active
|
||||
</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="owner" className="flex items-center gap-2">
|
||||
<User className="h-4 w-4" />
|
||||
Policy Owner
|
||||
</Label>
|
||||
<PeopleSelector
|
||||
organizationRef={data.organization}
|
||||
selectedPersonId={ownerId}
|
||||
onSelect={setOwnerId}
|
||||
placeholder="Select policy owner"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="reviewDate" className="flex items-center gap-2">
|
||||
<Calendar className="h-4 w-4" />
|
||||
Review Date
|
||||
</Label>
|
||||
<Input
|
||||
id="reviewDate"
|
||||
type="date"
|
||||
value={reviewDate}
|
||||
onChange={(e) => setReviewDate(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -250,15 +160,17 @@ function EditPolicyViewContent({
|
||||
}
|
||||
|
||||
export default function EditPolicyView() {
|
||||
const { organizationId, policyId } = useParams();
|
||||
const { organizationId, policyId, versionId } = useParams();
|
||||
const [queryRef, loadQuery] =
|
||||
useQueryLoader<EditPolicyViewQuery>(editPolicyViewQuery);
|
||||
|
||||
useEffect(() => {
|
||||
if (organizationId && policyId) {
|
||||
loadQuery({ organizationId, policyId });
|
||||
}
|
||||
}, [organizationId, policyId, loadQuery]);
|
||||
loadQuery({
|
||||
organizationId: organizationId!,
|
||||
policyId: policyId!,
|
||||
policyVersionId: versionId!,
|
||||
});
|
||||
}, [organizationId, policyId, versionId]);
|
||||
|
||||
if (!queryRef) {
|
||||
return <EditPolicyViewSkeleton />;
|
||||
@@ -266,7 +178,7 @@ export default function EditPolicyView() {
|
||||
|
||||
return (
|
||||
<Suspense fallback={<EditPolicyViewSkeleton />}>
|
||||
{queryRef && <EditPolicyViewContent queryRef={queryRef} />}
|
||||
<EditPolicyViewContent queryRef={queryRef}/>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import { PageTemplateSkeleton } from "@/components/PageTemplate";
|
||||
import { Suspense } from "react";
|
||||
import { useLocation } from "react-router";
|
||||
import { ErrorBoundaryWithLocation } from "../ErrorBoundary";
|
||||
import { lazy } from "@probo/react-lazy";
|
||||
|
||||
const NewPolicyView = lazy(() => import("./NewPolicyView"));
|
||||
|
||||
export function NewPolicyViewSkeleton() {
|
||||
return (
|
||||
<PageTemplateSkeleton
|
||||
title="New Policy"
|
||||
description="Add a new policy for your organization"
|
||||
>
|
||||
<div className="bg-subtle-bg animate-pulse rounded-lg h-[600px]" />
|
||||
</PageTemplateSkeleton>
|
||||
);
|
||||
}
|
||||
|
||||
export function NewPolicyPage() {
|
||||
const location = useLocation();
|
||||
|
||||
return (
|
||||
<Suspense key={location.pathname} fallback={<NewPolicyViewSkeleton />}>
|
||||
<ErrorBoundaryWithLocation>
|
||||
<NewPolicyView />
|
||||
</ErrorBoundaryWithLocation>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
@@ -1,281 +0,0 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { useNavigate, useParams } from "react-router";
|
||||
import {
|
||||
ConnectionHandler,
|
||||
graphql,
|
||||
useMutation,
|
||||
useQueryLoader,
|
||||
usePreloadedQuery,
|
||||
PreloadedQuery,
|
||||
} from "react-relay";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { Calendar, User } from "lucide-react";
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
import PolicyEditor from "@/components/PolicyEditor";
|
||||
import PeopleSelector from "@/components/PeopleSelector";
|
||||
import { Suspense } from "react";
|
||||
import type { NewPolicyViewMutation } from "./__generated__/NewPolicyViewMutation.graphql";
|
||||
import type { NewPolicyViewQuery } from "./__generated__/NewPolicyViewQuery.graphql";
|
||||
import { PageTemplate } from "@/components/PageTemplate";
|
||||
import { NewPolicyViewSkeleton } from "./NewPolicyPage";
|
||||
|
||||
const newPolicyQuery = graphql`
|
||||
query NewPolicyViewQuery($organizationId: ID!) {
|
||||
organization: node(id: $organizationId) {
|
||||
...PeopleSelector_organization
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const CreatePolicyMutation = graphql`
|
||||
mutation NewPolicyViewMutation(
|
||||
$input: CreatePolicyInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
createPolicy(input: $input) {
|
||||
policyEdge @prependEdge(connections: $connections) {
|
||||
node {
|
||||
id
|
||||
name
|
||||
content
|
||||
status
|
||||
reviewDate
|
||||
owner {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
function CreatePolicyForm({
|
||||
queryRef,
|
||||
}: {
|
||||
queryRef: PreloadedQuery<NewPolicyViewQuery>;
|
||||
}) {
|
||||
const navigate = useNavigate();
|
||||
const { organizationId } = useParams();
|
||||
const data = usePreloadedQuery<NewPolicyViewQuery>(newPolicyQuery, queryRef);
|
||||
const [name, setName] = useState("");
|
||||
const [content, setContent] = useState("");
|
||||
const [status, setStatus] = useState<"DRAFT" | "ACTIVE">("DRAFT");
|
||||
const [reviewDate, setReviewDate] = useState("");
|
||||
const [ownerId, setOwnerId] = useState<string | null>(null);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const { toast } = useToast();
|
||||
|
||||
console.log(
|
||||
"NewPolicyView state - content:",
|
||||
content
|
||||
? content.substring(0, 50) + (content.length > 50 ? "..." : "")
|
||||
: "empty"
|
||||
);
|
||||
|
||||
const [createPolicy] =
|
||||
useMutation<NewPolicyViewMutation>(CreatePolicyMutation);
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!ownerId) {
|
||||
toast({
|
||||
title: "Error",
|
||||
description: "Please select an owner for the policy.",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setIsSubmitting(true);
|
||||
|
||||
// Convert reviewDate string to ISO format for the API
|
||||
let reviewDateValue = null;
|
||||
if (reviewDate) {
|
||||
reviewDateValue = new Date(reviewDate).toISOString();
|
||||
}
|
||||
|
||||
const input = {
|
||||
organizationId: organizationId!,
|
||||
name,
|
||||
content,
|
||||
status,
|
||||
reviewDate: reviewDateValue,
|
||||
ownerId,
|
||||
};
|
||||
|
||||
createPolicy({
|
||||
variables: {
|
||||
input,
|
||||
connections: [
|
||||
ConnectionHandler.getConnectionID(
|
||||
organizationId!,
|
||||
"PolicyListView_policies"
|
||||
),
|
||||
],
|
||||
},
|
||||
onCompleted: (response, errors) => {
|
||||
setIsSubmitting(false);
|
||||
if (errors) {
|
||||
console.error("Error creating policy:", errors);
|
||||
toast({
|
||||
title: "Error",
|
||||
description: "Failed to create policy. Please try again.",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
toast({
|
||||
title: "Success",
|
||||
description: "Policy created successfully!",
|
||||
});
|
||||
|
||||
navigate(
|
||||
`/organizations/${organizationId}/policies/${response.createPolicy.policyEdge.node.id}`
|
||||
);
|
||||
},
|
||||
onError: (error) => {
|
||||
setIsSubmitting(false);
|
||||
console.error("Error creating policy:", error);
|
||||
toast({
|
||||
title: "Error",
|
||||
description: "Failed to create policy. Please try again.",
|
||||
variant: "destructive",
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<PageTemplate
|
||||
title="Create Policy"
|
||||
description="Create a new policy for your organization"
|
||||
>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="grid gap-6">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Policy Information</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="name">Policy Name</Label>
|
||||
<Input
|
||||
id="name"
|
||||
placeholder="Enter policy name"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="content">Policy Content</Label>
|
||||
<div className="min-h-[300px]">
|
||||
<PolicyEditor
|
||||
initialContent={content}
|
||||
onChange={(html) => setContent(html)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label>Status</Label>
|
||||
<RadioGroup
|
||||
value={status}
|
||||
onValueChange={(value: "DRAFT" | "ACTIVE") =>
|
||||
setStatus(value)
|
||||
}
|
||||
className="flex space-x-4"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="DRAFT" id="draft" />
|
||||
<Label htmlFor="draft" className="cursor-pointer">
|
||||
Draft
|
||||
</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="ACTIVE" id="active" />
|
||||
<Label htmlFor="active" className="cursor-pointer">
|
||||
Active
|
||||
</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="owner" className="flex items-center gap-2">
|
||||
<User className="h-4 w-4" />
|
||||
Policy Owner
|
||||
</Label>
|
||||
<PeopleSelector
|
||||
organizationRef={data.organization}
|
||||
selectedPersonId={ownerId}
|
||||
onSelect={setOwnerId}
|
||||
placeholder="Select policy owner"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="reviewDate" className="flex items-center gap-2">
|
||||
<Calendar className="h-4 w-4" />
|
||||
Review Date
|
||||
</Label>
|
||||
<Input
|
||||
id="reviewDate"
|
||||
type="date"
|
||||
value={reviewDate}
|
||||
onChange={(e) => setReviewDate(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<div className="flex justify-end gap-4">
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={() =>
|
||||
navigate(`/organizations/${organizationId}/policies`)
|
||||
}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="submit" disabled={isSubmitting}>
|
||||
{isSubmitting ? "Creating..." : "Create Policy"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</PageTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
export default function NewPolicyView() {
|
||||
const { organizationId } = useParams();
|
||||
const [queryRef, loadQuery] =
|
||||
useQueryLoader<NewPolicyViewQuery>(newPolicyQuery);
|
||||
|
||||
useEffect(() => {
|
||||
if (organizationId) {
|
||||
loadQuery({ organizationId });
|
||||
}
|
||||
}, [organizationId, loadQuery]);
|
||||
|
||||
if (!queryRef) {
|
||||
return <NewPolicyViewSkeleton />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Suspense fallback={<NewPolicyViewSkeleton />}>
|
||||
{<CreatePolicyForm queryRef={queryRef} />}
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
MoreHorizontal,
|
||||
Trash2,
|
||||
Eye,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import {
|
||||
@@ -24,24 +25,59 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import type { PolicyListViewQuery as PolicyListViewQueryType } from "./__generated__/PolicyListViewQuery.graphql";
|
||||
import { format } from "date-fns";
|
||||
import type { PolicyListViewQuery, PolicyListViewQuery$data } from "./__generated__/PolicyListViewQuery.graphql";
|
||||
import type { PolicyListViewDeleteMutation } from "./__generated__/PolicyListViewDeleteMutation.graphql";
|
||||
import type { PolicyListViewCreateMutation } from "./__generated__/PolicyListViewCreateMutation.graphql";
|
||||
import { PageTemplate } from "@/components/PageTemplate";
|
||||
import { PolicyListViewSkeleton } from "./PolicyListPage";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Avatar } from "@/components/ui/avatar";
|
||||
import { cn } from "@/lib/utils";
|
||||
import PeopleSelector from "@/components/PeopleSelector";
|
||||
import type { PeopleSelector_organization$key } from "@/components/__generated__/PeopleSelector_organization.graphql";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
|
||||
const PolicyListViewQuery = graphql`
|
||||
const policyListViewQuery = graphql`
|
||||
query PolicyListViewQuery($organizationId: ID!) {
|
||||
viewer {
|
||||
user {
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
organization: node(id: $organizationId) {
|
||||
... on Organization {
|
||||
policies(first: 100) @connection(key: "PolicyListView_policies") {
|
||||
...PeopleSelector_organization
|
||||
policies(first: 50, orderBy: {field: TITLE, direction: ASC}) @connection(key: "PolicyListView_policies") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
content
|
||||
title
|
||||
description
|
||||
currentPublishedVersion
|
||||
createdAt
|
||||
updatedAt
|
||||
status
|
||||
owner {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
versions(first: 1) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
status
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,29 +97,47 @@ const DeletePolicyMutation = graphql`
|
||||
}
|
||||
`;
|
||||
|
||||
const createPolicyMutation = graphql`
|
||||
mutation PolicyListViewCreateMutation(
|
||||
$input: CreatePolicyInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
createPolicy(input: $input) {
|
||||
policyEdge @prependEdge(connections: $connections) {
|
||||
node {
|
||||
id
|
||||
title
|
||||
description
|
||||
createdAt
|
||||
updatedAt
|
||||
owner {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
function PolicyTableRow({
|
||||
policy,
|
||||
organizationId,
|
||||
}: {
|
||||
policy: {
|
||||
id: string;
|
||||
name: string;
|
||||
content?: string;
|
||||
status?: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
policy: NonNullable<PolicyListViewQuery$data["organization"]["policies"]>["edges"][0]["node"];
|
||||
organizationId: string;
|
||||
}) {
|
||||
const navigate = useNavigate();
|
||||
const { toast } = useToast();
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
const [commitDeleteMutation] = useMutation<PolicyListViewDeleteMutation>(DeletePolicyMutation);
|
||||
const [deletePolicy, isDeleting] = useMutation<PolicyListViewDeleteMutation>(DeletePolicyMutation);
|
||||
|
||||
const handleDelete = (e: React.MouseEvent) => {
|
||||
const latestVersion = policy.versions?.edges[0]?.node;
|
||||
const status = latestVersion?.status || "DRAFT";
|
||||
|
||||
const handleDeletePolicy = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
if (window.confirm("Are you sure you want to delete this policy? This action cannot be undone.")) {
|
||||
setIsDeleting(true);
|
||||
commitDeleteMutation({
|
||||
deletePolicy({
|
||||
variables: {
|
||||
input: {
|
||||
policyId: policy.id,
|
||||
@@ -96,7 +150,6 @@ function PolicyTableRow({
|
||||
],
|
||||
},
|
||||
onCompleted: (_, errors) => {
|
||||
setIsDeleting(false);
|
||||
if (errors) {
|
||||
console.error("Error deleting policy:", errors);
|
||||
toast({
|
||||
@@ -112,7 +165,6 @@ function PolicyTableRow({
|
||||
});
|
||||
},
|
||||
onError: (error) => {
|
||||
setIsDeleting(false);
|
||||
console.error("Error deleting policy:", error);
|
||||
toast({
|
||||
title: "Error",
|
||||
@@ -131,27 +183,33 @@ function PolicyTableRow({
|
||||
|
||||
return (
|
||||
<tr
|
||||
className="border-t border-[#ECEFEC] hover:bg-[rgba(5,77,5,0.01)] cursor-pointer"
|
||||
className="border-t border-solid-b hover:bg-subtle-bg cursor-pointer"
|
||||
onClick={() => {
|
||||
navigate(`/organizations/${organizationId}/policies/${policy.id}`);
|
||||
}}
|
||||
>
|
||||
<td className="py-4 px-6">
|
||||
<div className="flex flex-col">
|
||||
<span className="font-medium text-[#141E12]">{policy.name}</span>
|
||||
<span className="text-sm text-[#818780]">
|
||||
Description
|
||||
<span className="font-medium text-primary">{policy.title}</span>
|
||||
<span className="text-sm text-tertiary">
|
||||
{policy.description || "No description provided"}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-4 px-6">
|
||||
<span className="text-sm text-[#141E12]">Mon, 8 Mar. 2025</span>
|
||||
<span className="text-sm text-primary">
|
||||
{format(new Date(policy.updatedAt), "MMM d, yyyy")}
|
||||
</span>
|
||||
</td>
|
||||
<td className="py-4 px-6">
|
||||
<Badge
|
||||
className="bg-[rgba(5,77,5,0.03)] text-[#6B716A] font-medium border-0 py-0 px-[6px] h-5 text-xs rounded-md"
|
||||
className={`font-medium border-0 py-0 px-[6px] h-5 text-xs rounded-md ${
|
||||
status === "PUBLISHED"
|
||||
? "bg-success-bg text-success"
|
||||
: "bg-secondary-bg text-tertiary"
|
||||
}`}
|
||||
>
|
||||
Draft
|
||||
{status === "PUBLISHED" ? "Published" : "Draft"}
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="py-4 px-6 text-right">
|
||||
@@ -172,8 +230,8 @@ function PolicyTableRow({
|
||||
View
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={handleDelete}
|
||||
className="text-red-600 focus:text-red-600 focus:bg-red-50"
|
||||
onClick={handleDeletePolicy}
|
||||
className="text-danger focus:text-danger focus:bg-danger-bg"
|
||||
disabled={isDeleting}
|
||||
>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
@@ -186,60 +244,264 @@ function PolicyTableRow({
|
||||
);
|
||||
}
|
||||
|
||||
function CreatePolicyModal({
|
||||
open,
|
||||
onOpenChange,
|
||||
organizationId,
|
||||
organizationRef,
|
||||
}: {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
organizationId: string;
|
||||
organizationRef: PeopleSelector_organization$key;
|
||||
}) {
|
||||
const { toast } = useToast();
|
||||
const [title, setTitle] = useState("");
|
||||
const [content, setContent] = useState("");
|
||||
const [ownerId, setOwnerId] = useState<string | null>(null);
|
||||
|
||||
const [createPolicy, isCreating] = useMutation<PolicyListViewCreateMutation>(createPolicyMutation);
|
||||
|
||||
// Reset form fields
|
||||
const resetForm = () => {
|
||||
setTitle("");
|
||||
setContent("");
|
||||
setOwnerId(null);
|
||||
};
|
||||
|
||||
const handleCreatePolicy = () => {
|
||||
if (!title.trim()) {
|
||||
toast({
|
||||
title: "Error",
|
||||
description: "Please enter a policy title.",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ownerId) {
|
||||
toast({
|
||||
title: "Error",
|
||||
description: "Please select an owner for the policy.",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const input = {
|
||||
organizationId,
|
||||
title,
|
||||
content,
|
||||
ownerId,
|
||||
};
|
||||
|
||||
createPolicy({
|
||||
variables: {
|
||||
input,
|
||||
connections: [
|
||||
ConnectionHandler.getConnectionID(
|
||||
organizationId,
|
||||
"PolicyListView_policies",
|
||||
{orderBy: {field: "TITLE", direction: "ASC"}}
|
||||
),
|
||||
],
|
||||
},
|
||||
onCompleted: (response, errors) => {
|
||||
if (errors) {
|
||||
console.error("Error creating policy:", errors);
|
||||
toast({
|
||||
title: "Error",
|
||||
description: "Failed to create policy. Please try again.",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
toast({
|
||||
title: "Success",
|
||||
description: "Policy created successfully!",
|
||||
});
|
||||
|
||||
resetForm();
|
||||
onOpenChange(false);
|
||||
},
|
||||
onError: (error) => {
|
||||
console.error("Error creating policy:", error);
|
||||
toast({
|
||||
title: "Error",
|
||||
description: "Failed to create policy. Please try again.",
|
||||
variant: "destructive",
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// Reset form when modal closes
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
resetForm();
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="sm:max-w-[1080px] h-[700px] max-h-[700px] p-0 gap-0 flex flex-col">
|
||||
<DialogTitle className="sr-only">Create new policy</DialogTitle>
|
||||
<DialogDescription className="sr-only">Form to create a new policy with title, content, and owner information.</DialogDescription>
|
||||
<div className="flex justify-between items-center py-2 px-4 border-b border-solid-b h-[40px]">
|
||||
<div className="flex items-center gap-1 text-sm">
|
||||
<span className="text-tertiary">Policies</span>
|
||||
<ChevronDown className="h-3 w-3 text-quaternary rotate-[270deg]" />
|
||||
<span className="font-medium">New policy</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 overflow-hidden">
|
||||
<div className="flex-1 p-6 overflow-y-auto">
|
||||
<div className="mb-6">
|
||||
<h1
|
||||
className={`text-4xl leading-tight font-bold outline-none focus:outline-none ${!title ? 'text-gray-400' : 'text-black'}`}
|
||||
contentEditable
|
||||
suppressContentEditableWarning
|
||||
onBlur={(e) => setTitle(e.currentTarget.textContent || "")}
|
||||
style={{ WebkitTapHighlightColor: 'transparent' }}
|
||||
onClick={(e) => {
|
||||
if (!title) {
|
||||
e.currentTarget.textContent = '';
|
||||
}
|
||||
}}
|
||||
onFocus={(e) => {
|
||||
if (!title) {
|
||||
e.currentTarget.textContent = '';
|
||||
}
|
||||
}}
|
||||
>
|
||||
{title || "Enter policy title..."}
|
||||
</h1>
|
||||
</div>
|
||||
<Textarea
|
||||
placeholder="This Privacy Policy outlines how NovaSoft collects, uses, and protects personal information provided by users of its services. By accessing or using our platform, you agree to the collection and use of information in accordance with this policy..."
|
||||
className="min-h-[300px] border-none resize-none p-0 focus-visible:ring-0 focus-visible:ring-offset-0"
|
||||
value={content}
|
||||
onChange={(e) => setContent(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-[420px] bg-[rgba(5,77,5,0.03)] p-6 flex flex-col gap-4">
|
||||
<h3 className="font-medium text-base">Properties</h3>
|
||||
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex justify-between items-center py-2 border-t border-[rgba(2,42,2,0.08)]">
|
||||
<span className="text-sm font-medium text-tertiary">Status</span>
|
||||
<div className="bg-[rgba(0,39,0,0.05)] py-1.5 px-2 rounded-lg">
|
||||
<span className="text-sm font-medium">Draft</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between items-center py-2 border-t border-[rgba(2,42,2,0.08)]">
|
||||
<span className="text-sm font-medium text-tertiary">Owner</span>
|
||||
<div className="relative">
|
||||
<PeopleSelector
|
||||
organizationRef={organizationRef}
|
||||
selectedPersonId={ownerId}
|
||||
onSelect={setOwnerId}
|
||||
placeholder="Select owner"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between items-center py-2 border-t border-[rgba(2,42,2,0.08)]">
|
||||
<span className="text-sm font-medium text-tertiary">Review date</span>
|
||||
<Button size="icon" variant="outline" className="h-8 w-8 rounded-full bg-[rgba(0,39,0,0.05)] border-none">
|
||||
<Plus className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter className="flex justify-end items-center gap-3 px-4 py-2 border-t border-solid-b h-[60px]">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => onOpenChange(false)}
|
||||
className="h-9"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleCreatePolicy}
|
||||
disabled={isCreating}
|
||||
className="h-9"
|
||||
>
|
||||
{isCreating ? "Creating..." : "Create policy"}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
function PolicyListViewContent({
|
||||
queryRef,
|
||||
}: {
|
||||
queryRef: PreloadedQuery<PolicyListViewQueryType>;
|
||||
queryRef: PreloadedQuery<PolicyListViewQuery>;
|
||||
}) {
|
||||
const data = usePreloadedQuery<PolicyListViewQueryType>(
|
||||
PolicyListViewQuery,
|
||||
const data = usePreloadedQuery<PolicyListViewQuery>(
|
||||
policyListViewQuery,
|
||||
queryRef
|
||||
);
|
||||
const { organizationId } = useParams();
|
||||
const policies =
|
||||
data.organization.policies?.edges.map((edge) => edge?.node) ?? [];
|
||||
data.organization?.policies?.edges.map((edge) => edge?.node) ?? [];
|
||||
|
||||
const [createModalOpen, setCreateModalOpen] = useState(false);
|
||||
|
||||
const handleOpenModal = () => {
|
||||
setCreateModalOpen(true);
|
||||
};
|
||||
|
||||
const handleCloseModal = (open: boolean) => {
|
||||
setCreateModalOpen(open);
|
||||
};
|
||||
|
||||
return (
|
||||
<PageTemplate
|
||||
title="Policies"
|
||||
actions={
|
||||
<Button asChild>
|
||||
<Link to={`/organizations/${organizationId}/policies/new`}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Create policy
|
||||
</Link>
|
||||
<Button onClick={handleOpenModal}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
New policy
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
{/* Policy table */}
|
||||
<div className="rounded-lg border border-[#ECEFEC] overflow-hidden bg-white">
|
||||
<div className="rounded-lg border border-solid-b overflow-hidden bg-level-1">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="bg-white text-left">
|
||||
<th className="py-3 px-6 text-xs font-medium text-[#818780] border-b border-[rgba(2,42,2,0.08)]">
|
||||
<tr className="bg-level-1 text-left">
|
||||
<th className="py-3 px-6 text-xs font-medium text-tertiary border-b border-low-b">
|
||||
<div className="flex items-center gap-1">
|
||||
Vendor
|
||||
<ChevronDown className="h-3 w-3 text-[#C3C8C2]" />
|
||||
Policy
|
||||
<ChevronDown className="h-3 w-3 text-quaternary" />
|
||||
</div>
|
||||
</th>
|
||||
<th className="py-3 px-6 text-xs font-medium text-[#818780] border-b border-[rgba(2,42,2,0.08)]">
|
||||
<th className="py-3 px-6 text-xs font-medium text-tertiary border-b border-low-b">
|
||||
<div className="flex items-center gap-1">
|
||||
Last update
|
||||
<ChevronDown className="h-3 w-3 text-[#C3C8C2]" />
|
||||
<ChevronDown className="h-3 w-3 text-quaternary" />
|
||||
</div>
|
||||
</th>
|
||||
<th className="py-3 px-6 text-xs font-medium text-[#818780] border-b border-[rgba(2,42,2,0.08)]">
|
||||
<th className="py-3 px-6 text-xs font-medium text-tertiary border-b border-low-b">
|
||||
<div className="flex items-center gap-1">
|
||||
Status
|
||||
<ChevronDown className="h-3 w-3 text-[#C3C8C2]" />
|
||||
<ChevronDown className="h-3 w-3 text-quaternary" />
|
||||
</div>
|
||||
</th>
|
||||
<th className="py-3 px-6 text-right text-xs font-medium text-[#818780] border-b border-[rgba(2,42,2,0.08)]"></th>
|
||||
<th className="py-3 px-6 text-right text-xs font-medium text-tertiary border-b border-low-b"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="bg-white">
|
||||
<tbody className="bg-level-1">
|
||||
{policies.length > 0 ? (
|
||||
policies.map((policy) => (
|
||||
policies.map((policy: any) => (
|
||||
<PolicyTableRow
|
||||
key={policy.id}
|
||||
policy={policy}
|
||||
@@ -251,14 +513,12 @@ function PolicyListViewContent({
|
||||
<td colSpan={4} className="py-12 text-center">
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<h3 className="text-lg font-medium">No policies found</h3>
|
||||
<p className="text-[#818780]">
|
||||
<p className="text-tertiary">
|
||||
Create your first policy to get started
|
||||
</p>
|
||||
<Button asChild>
|
||||
<Link to={`/organizations/${organizationId}/policies/new`}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Create policy
|
||||
</Link>
|
||||
<Button onClick={handleOpenModal}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Create policy
|
||||
</Button>
|
||||
</div>
|
||||
</td>
|
||||
@@ -267,13 +527,20 @@ function PolicyListViewContent({
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<CreatePolicyModal
|
||||
open={createModalOpen}
|
||||
onOpenChange={handleCloseModal}
|
||||
organizationId={organizationId!}
|
||||
organizationRef={data.organization}
|
||||
/>
|
||||
</PageTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PolicyListView() {
|
||||
const [queryRef, loadQuery] =
|
||||
useQueryLoader<PolicyListViewQueryType>(PolicyListViewQuery);
|
||||
useQueryLoader<PolicyListViewQuery>(policyListViewQuery);
|
||||
|
||||
const { organizationId } = useParams();
|
||||
|
||||
|
||||
@@ -1,423 +0,0 @@
|
||||
import { Suspense, useEffect, useState, useCallback } from "react";
|
||||
import { useParams, Link, useNavigate } from "react-router";
|
||||
import {
|
||||
graphql,
|
||||
PreloadedQuery,
|
||||
usePreloadedQuery,
|
||||
useQueryLoader,
|
||||
useMutation,
|
||||
ConnectionHandler,
|
||||
} from "react-relay";
|
||||
import { Edit, Download, Shield, User, FileText, Calendar } from "lucide-react";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import type { PolicyViewQuery as PolicyViewQueryType } from "./__generated__/PolicyViewQuery.graphql";
|
||||
import type { PolicyViewDeleteMutation } from "./__generated__/PolicyViewDeleteMutation.graphql";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { PageTemplate } from "@/components/PageTemplate";
|
||||
import { PolicyViewSkeleton } from "./PolicyPage";
|
||||
|
||||
const PolicyViewQuery = graphql`
|
||||
query PolicyViewQuery($policyId: ID!) {
|
||||
node(id: $policyId) {
|
||||
id
|
||||
... on Policy {
|
||||
name
|
||||
content
|
||||
createdAt
|
||||
updatedAt
|
||||
reviewDate
|
||||
status
|
||||
owner {
|
||||
id
|
||||
fullName
|
||||
primaryEmailAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const DeletePolicyMutation = graphql`
|
||||
mutation PolicyViewDeleteMutation(
|
||||
$input: DeletePolicyInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deletePolicy(input: $input) {
|
||||
deletedPolicyId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
function PolicyViewContent({
|
||||
queryRef,
|
||||
}: {
|
||||
queryRef: PreloadedQuery<PolicyViewQueryType>;
|
||||
}) {
|
||||
const data = usePreloadedQuery(PolicyViewQuery, queryRef);
|
||||
const policy = data.node;
|
||||
const { organizationId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const [activeTab, setActiveTab] = useState("content");
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
const { toast } = useToast();
|
||||
|
||||
const [commitDeleteMutation] =
|
||||
useMutation<PolicyViewDeleteMutation>(DeletePolicyMutation);
|
||||
|
||||
const handleDeletePolicy = useCallback(() => {
|
||||
if (
|
||||
window.confirm(
|
||||
"Are you sure you want to delete this policy? This action cannot be undone."
|
||||
)
|
||||
) {
|
||||
setIsDeleting(true);
|
||||
|
||||
commitDeleteMutation({
|
||||
variables: {
|
||||
input: {
|
||||
policyId: policy.id,
|
||||
},
|
||||
connections: [
|
||||
ConnectionHandler.getConnectionID(
|
||||
organizationId!,
|
||||
"PolicyListPage_policies"
|
||||
),
|
||||
],
|
||||
},
|
||||
onCompleted: (_, errors) => {
|
||||
setIsDeleting(false);
|
||||
if (errors) {
|
||||
console.error("Error deleting policy:", errors);
|
||||
toast({
|
||||
title: "Error",
|
||||
description: "Failed to delete policy. Please try again.",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
toast({
|
||||
title: "Success",
|
||||
description: "Policy deleted successfully.",
|
||||
});
|
||||
|
||||
navigate(`/organizations/${organizationId}/policies`);
|
||||
},
|
||||
onError: (error) => {
|
||||
setIsDeleting(false);
|
||||
console.error("Error deleting policy:", error);
|
||||
toast({
|
||||
title: "Error",
|
||||
description: "Failed to delete policy. Please try again.",
|
||||
variant: "destructive",
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}, [policy.id, organizationId, commitDeleteMutation, navigate]);
|
||||
|
||||
// Extract a short description from the content
|
||||
const getDescription = (content: string | undefined) => {
|
||||
if (!content) return "No description available";
|
||||
|
||||
// Remove HTML tags
|
||||
const withoutTags = content.replace(/<[^>]*>/g, "");
|
||||
// Decode HTML entities
|
||||
const decoded = withoutTags
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, "'")
|
||||
.replace(/ /g, " ");
|
||||
|
||||
// Get first paragraph or first 150 characters
|
||||
const firstParagraph = decoded.split("\n\n")[0].trim();
|
||||
return firstParagraph.length > 150
|
||||
? firstParagraph.substring(0, 150) + "..."
|
||||
: firstParagraph;
|
||||
};
|
||||
|
||||
const formatDate = (dateString: string | undefined) => {
|
||||
if (!dateString) return "N/A";
|
||||
const date = new Date(dateString);
|
||||
return date.toISOString().split("T")[0]; // YYYY-MM-DD format
|
||||
};
|
||||
|
||||
return (
|
||||
<PageTemplate
|
||||
title={policy.name ?? ""}
|
||||
description={
|
||||
<div className="flex items-center gap-2 text-tertiary">
|
||||
<Badge variant={policy.status === "ACTIVE" ? "default" : "outline"}>
|
||||
{policy.status === "ACTIVE" ? "Active" : "Draft"}
|
||||
</Badge>
|
||||
{policy.owner && (
|
||||
<div className="flex items-center gap-1">
|
||||
<User className="h-3 w-3" />
|
||||
<Link
|
||||
to={`/organizations/${organizationId}/people/${policy.owner.id}`}
|
||||
className="hover:underline"
|
||||
>
|
||||
{policy.owner.fullName}
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
{policy.reviewDate && (
|
||||
<div className="flex items-center gap-1">
|
||||
<Calendar className="h-3 w-3" />
|
||||
<span>Review: {formatDate(policy.reviewDate)}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
actions={
|
||||
<div className="flex gap-2">
|
||||
<Button variant="secondary" asChild>
|
||||
<Link
|
||||
to={`/organizations/${organizationId}/policies/${policy.id}/edit`}
|
||||
>
|
||||
<Edit className="h-4 w-4 mr-2" />
|
||||
Edit
|
||||
</Link>
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
// Logic to download policy content as PDF or text
|
||||
const element = document.createElement("a");
|
||||
const file = new Blob([policy.content || ""], {
|
||||
type: "text/plain",
|
||||
});
|
||||
element.href = URL.createObjectURL(file);
|
||||
element.download = `${policy.name}.txt`;
|
||||
document.body.appendChild(element);
|
||||
element.click();
|
||||
document.body.removeChild(element);
|
||||
}}
|
||||
>
|
||||
<Download className="h-4 w-4 mr-2" />
|
||||
Download
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<div className="lg:col-span-2">
|
||||
<Card className="border shadow-sm">
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="p-2 rounded-md bg-slate-100">
|
||||
<Shield className="h-6 w-6" />
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
{policy.status && (
|
||||
<Badge
|
||||
className={`px-3 py-1 rounded-md font-medium ${
|
||||
policy.status === "ACTIVE"
|
||||
? "bg-success-bg text-success hover:bg-h-success-bg"
|
||||
: policy.status === "DRAFT"
|
||||
? "bg-warning-bg text-warning hover:bg-h-warning-bg"
|
||||
: "bg-secondary-bg text-secondary hover:bg-h-secondary-bg"
|
||||
}`}
|
||||
>
|
||||
{policy.status === "ACTIVE"
|
||||
? "Active"
|
||||
: policy.status === "DRAFT"
|
||||
? "Draft"
|
||||
: policy.status}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 className="text-3xl font-bold mb-3">{policy.name}</h1>
|
||||
|
||||
<p className="text-tertiary mb-6">
|
||||
{getDescription(policy.content)}
|
||||
</p>
|
||||
|
||||
<Tabs
|
||||
defaultValue="content"
|
||||
value={activeTab}
|
||||
onValueChange={setActiveTab}
|
||||
className="mb-6"
|
||||
>
|
||||
<TabsList className="border-b w-full rounded-none p-0 h-auto">
|
||||
<TabsTrigger
|
||||
value="content"
|
||||
className={`px-4 py-2 font-medium ${
|
||||
activeTab === "content"
|
||||
? "border-primary text-primary"
|
||||
: "text-tertiary"
|
||||
}`}
|
||||
>
|
||||
Policy Content
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="history"
|
||||
className={`px-4 py-2 font-medium ${
|
||||
activeTab === "history"
|
||||
? "border-primary text-primary"
|
||||
: "text-tertiary"
|
||||
}`}
|
||||
>
|
||||
Version History
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="approvals"
|
||||
className={`px-4 py-2 font-medium ${
|
||||
activeTab === "approvals"
|
||||
? "border-primary text-primary"
|
||||
: "text-tertiary"
|
||||
}`}
|
||||
>
|
||||
Approvals
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="content" className="pt-6">
|
||||
<div className="prose prose-sm md:prose-base lg:prose-lg max-w-none">
|
||||
<div
|
||||
className="policy-content"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: policy.content || "",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="history" className="pt-6">
|
||||
<div className="text-center py-12">
|
||||
<p className="text-tertiary">
|
||||
Version history will be available soon.
|
||||
</p>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="approvals" className="pt-6">
|
||||
<div className="text-center py-12">
|
||||
<p className="text-tertiary">
|
||||
Approval workflow will be available soon.
|
||||
</p>
|
||||
</div>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="lg:col-span-1">
|
||||
<Card className="border shadow-sm mb-6">
|
||||
<CardContent className="p-6">
|
||||
<h2 className="text-xl font-semibold mb-6">Policy Details</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<div className="flex items-center gap-2 text-tertiary mb-1">
|
||||
<FileText className="h-4 w-4" />
|
||||
<span className="text-sm">Last Updated</span>
|
||||
</div>
|
||||
<p className="font-medium">{formatDate(policy.updatedAt)}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex items-center gap-2 text-tertiary mb-1">
|
||||
<FileText className="h-4 w-4" />
|
||||
<span className="text-sm">Review Due</span>
|
||||
</div>
|
||||
<p className="font-medium">
|
||||
{policy.reviewDate
|
||||
? formatDate(policy.reviewDate)
|
||||
: "Not set"}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex items-center gap-2 text-tertiary mb-1">
|
||||
<User className="h-4 w-4" />
|
||||
<span className="text-sm">Owner</span>
|
||||
</div>
|
||||
<Link
|
||||
to={`/organizations/${organizationId}/people/${policy.owner?.id}`}
|
||||
className="hover:underline"
|
||||
>
|
||||
<p className="font-medium">
|
||||
{policy.owner ? policy.owner.fullName : "Not assigned"}
|
||||
</p>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Button asChild className="w-full">
|
||||
<Link
|
||||
to={`/organizations/${organizationId}/policies/${policy.id}/edit`}
|
||||
>
|
||||
<Edit className="mr-2 h-4 w-4" />
|
||||
Edit Policy
|
||||
</Link>
|
||||
</Button>
|
||||
|
||||
<Card className="border shadow-sm mt-6 bg-danger-bg">
|
||||
<CardContent className="p-6">
|
||||
<h3 className="text-danger font-semibold mb-3">Danger Zone</h3>
|
||||
<p className="text-sm text-tertiary mb-4">
|
||||
Permanently delete this policy and all of its data. This action
|
||||
cannot be undone.
|
||||
</p>
|
||||
<Button
|
||||
variant="destructive"
|
||||
className="w-full"
|
||||
onClick={handleDeletePolicy}
|
||||
disabled={isDeleting}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="mr-2"
|
||||
>
|
||||
<path d="M3 6h18"></path>
|
||||
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
|
||||
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
|
||||
</svg>
|
||||
{isDeleting ? "Deleting..." : "Delete Policy"}
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</PageTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PolicyView() {
|
||||
const [queryRef, loadQuery] =
|
||||
useQueryLoader<PolicyViewQueryType>(PolicyViewQuery);
|
||||
|
||||
const { policyId } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
loadQuery({ policyId: policyId! });
|
||||
}, [loadQuery, policyId]);
|
||||
|
||||
if (!queryRef) {
|
||||
return <PolicyViewSkeleton />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Suspense fallback={<PolicyViewSkeleton />}>
|
||||
{queryRef && <PolicyViewContent queryRef={queryRef} />}
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
@@ -5,9 +5,9 @@ import { useLocation } from "react-router";
|
||||
import { ErrorBoundaryWithLocation } from "../ErrorBoundary";
|
||||
import { lazy } from "@probo/react-lazy";
|
||||
|
||||
const PolicyView = lazy(() => import("./PolicyView"));
|
||||
const ShowPolicyView = lazy(() => import("./ShowPolicyView"));
|
||||
|
||||
export function PolicyViewSkeleton() {
|
||||
export function ShowPolicyViewSkeleton() {
|
||||
return (
|
||||
<PageTemplateSkeleton
|
||||
withDescription
|
||||
@@ -108,13 +108,13 @@ export function PolicyViewSkeleton() {
|
||||
);
|
||||
}
|
||||
|
||||
export function PolicyPage() {
|
||||
export function ShowPolicyPage() {
|
||||
const location = useLocation();
|
||||
|
||||
return (
|
||||
<Suspense key={location.pathname} fallback={<PolicyViewSkeleton />}>
|
||||
<Suspense key={location.pathname} fallback={<ShowPolicyViewSkeleton />}>
|
||||
<ErrorBoundaryWithLocation>
|
||||
<PolicyView />
|
||||
<ShowPolicyView />
|
||||
</ErrorBoundaryWithLocation>
|
||||
</Suspense>
|
||||
);
|
||||
426
apps/console/src/pages/organizations/policies/ShowPolicyView.tsx
Normal file
426
apps/console/src/pages/organizations/policies/ShowPolicyView.tsx
Normal file
@@ -0,0 +1,426 @@
|
||||
import { Suspense, useEffect, useState, useCallback, ReactNode } from "react";
|
||||
import { useParams, Link, useNavigate } from "react-router";
|
||||
import {
|
||||
graphql,
|
||||
PreloadedQuery,
|
||||
usePreloadedQuery,
|
||||
useQueryLoader,
|
||||
useMutation,
|
||||
} from "react-relay";
|
||||
import { Clock, Download, Edit, Trash2, MoreHorizontal, X, FileSignature } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { PageTemplate } from "@/components/PageTemplate";
|
||||
import type { ShowPolicyViewQuery } from "./__generated__/ShowPolicyViewQuery.graphql";
|
||||
import { ShowPolicyViewPublishMutation } from "./__generated__/ShowPolicyViewPublishMutation.graphql";
|
||||
import { ShowPolicyViewCreateDraftMutation } from "./__generated__/ShowPolicyViewCreateDraftMutation.graphql";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import { ShowPolicyViewSkeleton } from "./ShowPolicyPage";
|
||||
import { format } from "date-fns";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { SignaturesModal } from "./SignaturesModal";
|
||||
import { VersionHistoryModal } from "./VersionHistoryModal";
|
||||
|
||||
const policyViewQuery = graphql`
|
||||
query ShowPolicyViewQuery($policyId: ID!) {
|
||||
node(id: $policyId) {
|
||||
id
|
||||
... on Policy {
|
||||
title
|
||||
description
|
||||
createdAt
|
||||
updatedAt
|
||||
currentPublishedVersion
|
||||
owner {
|
||||
id
|
||||
fullName
|
||||
primaryEmailAddress
|
||||
}
|
||||
|
||||
...SignaturesModal_policyVersions
|
||||
...VersionHistoryModal_policyVersions
|
||||
|
||||
latestVersion: versions(first: 1) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
version
|
||||
status
|
||||
content
|
||||
changelog
|
||||
publishedAt
|
||||
publishedBy {
|
||||
fullName
|
||||
}
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const publishPolicyVersionMutation = graphql`
|
||||
mutation ShowPolicyViewPublishMutation($input: PublishPolicyVersionInput!) {
|
||||
publishPolicyVersion(input: $input) {
|
||||
policy {
|
||||
id
|
||||
currentPublishedVersion
|
||||
}
|
||||
policyVersion {
|
||||
id
|
||||
status
|
||||
publishedAt
|
||||
publishedBy {
|
||||
fullName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const createDraftPolicyVersionMutation = graphql`
|
||||
mutation ShowPolicyViewCreateDraftMutation($input: CreateDraftPolicyVersionInput!) {
|
||||
createDraftPolicyVersion(input: $input) {
|
||||
policyVersionEdge {
|
||||
node {
|
||||
id
|
||||
version
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
function ShowPolicyContent({
|
||||
queryRef,
|
||||
}: {
|
||||
queryRef: PreloadedQuery<ShowPolicyViewQuery>;
|
||||
}) {
|
||||
const data = usePreloadedQuery<ShowPolicyViewQuery>(policyViewQuery, queryRef);
|
||||
const policy = data.node;
|
||||
const { organizationId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const { toast } = useToast();
|
||||
const [queryRef2, loadQuery] = useQueryLoader<ShowPolicyViewQuery>(policyViewQuery);
|
||||
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
const [isVersionHistoryOpen, setIsVersionHistoryOpen] = useState(false);
|
||||
const [isSignaturesModalOpen, setIsSignaturesModalOpen] = useState(false);
|
||||
|
||||
const [publishDraft, isPublishInFlight] = useMutation<ShowPolicyViewPublishMutation>(publishPolicyVersionMutation);
|
||||
const [createDraft, isCreateDraftInFlight] = useMutation<ShowPolicyViewCreateDraftMutation>(createDraftPolicyVersionMutation);
|
||||
|
||||
const latestVersionEdge = policy.latestVersion?.edges[0];
|
||||
const latestVersionNode = latestVersionEdge?.node;
|
||||
|
||||
const isDraft = latestVersionNode?.status === "DRAFT";
|
||||
|
||||
useEffect(() => {
|
||||
// No need to update selectedVersion state since we're using the VersionHistoryModal component
|
||||
}, []);
|
||||
|
||||
|
||||
// Handle delete policy
|
||||
const handleDeletePolicy = useCallback(() => {
|
||||
setIsDeleteDialogOpen(true);
|
||||
}, []);
|
||||
|
||||
// Confirm delete policy
|
||||
const confirmDeletePolicy = useCallback(() => {
|
||||
setIsDeleting(true);
|
||||
|
||||
setTimeout(() => {
|
||||
toast({
|
||||
title: "Policy deleted",
|
||||
description: "The policy has been deleted successfully",
|
||||
});
|
||||
setIsDeleting(false);
|
||||
setIsDeleteDialogOpen(false);
|
||||
navigate(`/organizations/${organizationId}/policies`);
|
||||
}, 1000);
|
||||
}, [toast, navigate, organizationId]);
|
||||
|
||||
// Navigate to publish flow
|
||||
const handlePublish = useCallback(() => {
|
||||
if (!policy.id) return;
|
||||
|
||||
publishDraft({
|
||||
variables: {
|
||||
input: {
|
||||
policyId: policy.id
|
||||
}
|
||||
},
|
||||
onCompleted: (_, errors) => {
|
||||
if (errors) {
|
||||
toast({
|
||||
title: "Error publishing policy",
|
||||
description: errors[0]?.message || "An unknown error occurred",
|
||||
variant: "destructive"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
toast({
|
||||
title: "Policy published",
|
||||
description: `The policy has been published successfully`,
|
||||
});
|
||||
|
||||
// Reload the query to refresh the data
|
||||
loadQuery({ policyId: policy.id });
|
||||
},
|
||||
onError: (error) => {
|
||||
toast({
|
||||
title: "Error publishing policy",
|
||||
description: error.message || "An unknown error occurred",
|
||||
variant: "destructive"
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [policy.id, publishDraft, toast, loadQuery]);
|
||||
|
||||
// Open version history modal
|
||||
const handleVersionHistoryClick = useCallback(() => {
|
||||
setIsVersionHistoryOpen(true);
|
||||
}, []);
|
||||
|
||||
// Restore version
|
||||
const handleRestoreVersion = useCallback((versionNumber: number) => {
|
||||
// Here you would implement the logic to restore a version
|
||||
toast({
|
||||
title: "Version restored",
|
||||
description: `Version ${versionNumber} has been restored`,
|
||||
});
|
||||
setIsVersionHistoryOpen(false);
|
||||
// Reload the query to refresh the data
|
||||
if (policy.id) {
|
||||
loadQuery({ policyId: policy.id });
|
||||
}
|
||||
}, [policy.id, loadQuery, toast]);
|
||||
|
||||
// Handle edit policy
|
||||
const handleEditPolicy = useCallback(() => {
|
||||
if (!policy.id) return;
|
||||
|
||||
if (latestVersionNode?.status === "PUBLISHED") {
|
||||
// Create a new draft version first
|
||||
createDraft({
|
||||
variables: {
|
||||
input: {
|
||||
policyID: policy.id
|
||||
}
|
||||
},
|
||||
onCompleted: (response, errors) => {
|
||||
if (errors) {
|
||||
toast({
|
||||
title: "Error creating draft",
|
||||
description: errors[0]?.message || "An unknown error occurred",
|
||||
variant: "destructive"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const newDraftId = response.createDraftPolicyVersion.policyVersionEdge.node.id;
|
||||
navigate(`/organizations/${organizationId}/policies/${policy.id}/versions/${newDraftId}/edit`);
|
||||
},
|
||||
onError: (error) => {
|
||||
toast({
|
||||
title: "Error creating draft",
|
||||
description: error.message || "An unknown error occurred",
|
||||
variant: "destructive"
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Navigate directly to edit if it's already a draft
|
||||
navigate(`/organizations/${organizationId}/policies/${policy.id}/versions/${latestVersionNode?.id}/edit`);
|
||||
}
|
||||
}, [policy.id, latestVersionNode, createDraft, navigate, organizationId, toast]);
|
||||
|
||||
// Format date helper
|
||||
const formatDate = (dateString?: string) => {
|
||||
if (!dateString) return "N/A";
|
||||
const date = new Date(dateString);
|
||||
return format(date, "MMM d, yyyy");
|
||||
};
|
||||
|
||||
return (
|
||||
<PageTemplate
|
||||
title={policy.title!}
|
||||
actions={
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="rounded-full h-9 px-3 gap-1.5 shadow-sm border-[#022A0214] bg-white text-[#141E12]"
|
||||
onClick={handleVersionHistoryClick}
|
||||
>
|
||||
<Clock className="h-4 w-4" />
|
||||
<span className="font-medium">Version history</span>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="rounded-full h-9 px-3 gap-1.5 shadow-sm border-[#022A0214] bg-white text-[#141E12]"
|
||||
onClick={() => setIsSignaturesModalOpen(true)}
|
||||
>
|
||||
<FileSignature className="h-4 w-4" />
|
||||
<span className="font-medium">Signature history</span>
|
||||
</Button>
|
||||
|
||||
{isDraft && (
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
className="rounded-full h-9 px-3 gap-1.5 shadow-sm"
|
||||
onClick={handlePublish}
|
||||
disabled={isPublishInFlight}
|
||||
>
|
||||
<span className="font-medium">Publish version</span>
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="rounded-full h-9 w-9 shadow-sm border-[#022A0214] bg-white text-[#141E12]"
|
||||
>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem asChild>
|
||||
<div onClick={handleEditPolicy}>
|
||||
<Edit className="mr-2 h-4 w-4" />
|
||||
{latestVersionNode?.status === "PUBLISHED" ? "Create new draft" : "Edit draft policy"}
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={handleDeletePolicy}
|
||||
className="text-danger focus:text-danger focus:bg-danger-bg"
|
||||
>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
Delete policy
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="space-y-4">
|
||||
{latestVersionNode ? (
|
||||
<div className="bg-white rounded-lg border border-solid-b shadow-sm p-6">
|
||||
{latestVersionNode.changelog && (
|
||||
<div className="mb-6 p-4 bg-level-1 rounded-md border border-solid-b">
|
||||
<div className="text-xs text-tertiary uppercase font-medium mb-1">Change summary</div>
|
||||
<div className="text-sm text-secondary">
|
||||
{latestVersionNode.changelog}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="prose prose-olive max-w-none">
|
||||
<ReactMarkdown>
|
||||
{latestVersionNode.content || "No content available"}
|
||||
</ReactMarkdown>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 pt-4 border-t border-solid-b text-xs text-tertiary flex justify-between items-center">
|
||||
<div>
|
||||
{latestVersionNode.status === "PUBLISHED"
|
||||
? `Published on ${formatDate(latestVersionNode.publishedAt || "")}${latestVersionNode.publishedBy ? ` by ${latestVersionNode.publishedBy.fullName}` : ''}`
|
||||
: `Last modified on ${formatDate(latestVersionNode.updatedAt)} by ${policy.owner?.fullName || 'Unknown'}`}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="bg-white rounded-lg border border-solid-b shadow-sm p-6 text-center text-tertiary">
|
||||
No content available
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Signatures Modal */}
|
||||
<SignaturesModal
|
||||
isOpen={isSignaturesModalOpen}
|
||||
onClose={() => setIsSignaturesModalOpen(false)}
|
||||
policyRef={policy}
|
||||
owner={policy.owner}
|
||||
/>
|
||||
|
||||
{/* Version History Modal */}
|
||||
<VersionHistoryModal
|
||||
isOpen={isVersionHistoryOpen}
|
||||
onClose={() => setIsVersionHistoryOpen(false)}
|
||||
policyRef={policy}
|
||||
onRestoreVersion={handleRestoreVersion}
|
||||
/>
|
||||
|
||||
{/* Delete Confirmation Dialog */}
|
||||
<Dialog open={isDeleteDialogOpen} onOpenChange={setIsDeleteDialogOpen}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Delete Policy</DialogTitle>
|
||||
<DialogDescription>
|
||||
Are you sure you want to delete the policy "{policy.title}"? This action cannot be undone.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setIsDeleteDialogOpen(false)}
|
||||
disabled={isDeleting}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="destructive"
|
||||
onClick={confirmDeletePolicy}
|
||||
disabled={isDeleting}
|
||||
>
|
||||
{isDeleting ? "Deleting..." : "Delete"}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</PageTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ShowPolicyView() {
|
||||
const [queryRef, loadQuery] = useQueryLoader<ShowPolicyViewQuery>(policyViewQuery);
|
||||
const { policyId } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
loadQuery({ policyId: policyId! });
|
||||
}, [loadQuery, policyId]);
|
||||
|
||||
if (!queryRef) {
|
||||
return <ShowPolicyViewSkeleton />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Suspense fallback={<ShowPolicyViewSkeleton />}>
|
||||
<ShowPolicyContent queryRef={queryRef} />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { format } from "date-fns";
|
||||
|
||||
interface PolicyVersionSignature {
|
||||
id: string;
|
||||
state: "REQUESTED" | "SIGNED";
|
||||
signedBy: {
|
||||
fullName: string;
|
||||
};
|
||||
signedAt?: string;
|
||||
requestedAt: string;
|
||||
requestedBy: {
|
||||
fullName: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface SignaturesListProps {
|
||||
signatures: PolicyVersionSignature[];
|
||||
}
|
||||
|
||||
export function SignaturesList({ signatures }: SignaturesListProps) {
|
||||
const formatDateTime = (dateString: string) => {
|
||||
const date = new Date(dateString);
|
||||
return format(date, "h:mm a • MMM d, yyyy");
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{signatures.map((signature) => (
|
||||
<div key={signature.id} className="bg-white rounded-lg border border-solid-b shadow-sm p-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<Avatar className="h-10 w-10">
|
||||
<AvatarImage src="" alt={signature.signedBy.fullName} />
|
||||
<AvatarFallback>
|
||||
{signature.signedBy.fullName.charAt(0)}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<div className="font-medium">{signature.signedBy.fullName}</div>
|
||||
<div className="text-sm text-tertiary">
|
||||
{signature.state === "SIGNED" && signature.signedAt
|
||||
? formatDateTime(signature.signedAt)
|
||||
: formatDateTime(signature.requestedAt)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<div className="text-sm">
|
||||
<span className="text-muted-foreground">Status:</span>{" "}
|
||||
<span className={`px-2 py-0.5 rounded-full ${
|
||||
signature.state === "SIGNED"
|
||||
? "bg-green-100 text-green-800"
|
||||
: "bg-yellow-100 text-yellow-800"
|
||||
}`}>
|
||||
{signature.state}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-sm">
|
||||
<span className="text-muted-foreground">Requested by:</span>{" "}
|
||||
{signature.requestedBy.fullName}
|
||||
</div>
|
||||
{signature.state === "SIGNED" && signature.signedAt && (
|
||||
<div className="text-sm">
|
||||
<span className="text-muted-foreground">Signed at:</span>{" "}
|
||||
{formatDateTime(signature.signedAt)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,469 @@
|
||||
import { Dialog, DialogContent } from "@/components/ui/dialog";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { format } from "date-fns";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useState, useEffect } from "react";
|
||||
import { graphql, useFragment, useMutation, useQueryLoader, usePreloadedQuery, ConnectionHandler } from "react-relay";
|
||||
import type { SignaturesModal_policyVersions$data, SignaturesModal_policyVersions$key } from "./__generated__/SignaturesModal_policyVersions.graphql";
|
||||
import type { SignaturesModalRequestSignatureMutation } from "./__generated__/SignaturesModalRequestSignatureMutation.graphql";
|
||||
import type { SignaturesModalOrganizationQuery } from "./__generated__/SignaturesModalOrganizationQuery.graphql";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { useParams } from "react-router";
|
||||
import { Loader2, CheckCircle2, Clock } from "lucide-react";
|
||||
import { PreloadedQuery } from "react-relay";
|
||||
|
||||
export const policyVersionsFragment = graphql`
|
||||
fragment SignaturesModal_policyVersions on Policy {
|
||||
title
|
||||
policyVersions: versions(first: 10) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
version
|
||||
status
|
||||
publishedAt
|
||||
updatedAt
|
||||
publishedBy {
|
||||
fullName
|
||||
}
|
||||
signatures(first: 100) @connection(key: "SignaturesModal_policyVersions_signatures") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
state
|
||||
signedAt
|
||||
requestedAt
|
||||
signedBy {
|
||||
fullName
|
||||
id
|
||||
}
|
||||
requestedBy {
|
||||
fullName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const requestSignatureMutation = graphql`
|
||||
mutation SignaturesModalRequestSignatureMutation($input: RequestSignatureInput!, $connections: [ID!]!) {
|
||||
requestSignature(input: $input) {
|
||||
policyVersionSignatureEdge @prependEdge(connections: $connections) {
|
||||
node {
|
||||
id
|
||||
state
|
||||
signedAt
|
||||
requestedAt
|
||||
signedBy {
|
||||
fullName
|
||||
id
|
||||
}
|
||||
requestedBy {
|
||||
fullName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const organizationQuery = graphql`
|
||||
query SignaturesModalOrganizationQuery($organizationId: ID!) {
|
||||
organization: node(id: $organizationId) {
|
||||
... on Organization {
|
||||
id
|
||||
peoples(first: 100, orderBy: { direction: ASC, field: FULL_NAME }) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
fullName
|
||||
primaryEmailAddress
|
||||
kind
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
interface SignaturesModalProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
policyRef: SignaturesModal_policyVersions$key;
|
||||
owner?: {
|
||||
fullName: string;
|
||||
} | null;
|
||||
}
|
||||
|
||||
// Define the signature type based on the GraphQL response
|
||||
// interface Signature {
|
||||
// id: string;
|
||||
// state: string;
|
||||
// signedAt?: string | null;
|
||||
// requestedAt: string;
|
||||
// signedBy: {
|
||||
// fullName: string;
|
||||
// id: string;
|
||||
// } | null;
|
||||
// requestedBy: {
|
||||
// fullName: string;
|
||||
// } | null;
|
||||
// }
|
||||
|
||||
export function SignaturesModal({
|
||||
isOpen,
|
||||
onClose,
|
||||
policyRef,
|
||||
owner,
|
||||
}: SignaturesModalProps) {
|
||||
const data = useFragment<SignaturesModal_policyVersions$key>(
|
||||
policyVersionsFragment,
|
||||
policyRef
|
||||
);
|
||||
|
||||
// Safely access and extract version nodes
|
||||
const versionNodes = (data?.policyVersions?.edges?.map(edge => edge.node) || []);
|
||||
|
||||
// Filter to just published versions and sort by version number
|
||||
const publishedVersions = versionNodes
|
||||
.filter(v => v.status === "PUBLISHED")
|
||||
.sort((a, b) => b.version - a.version);
|
||||
|
||||
const [selectedVersion, setSelectedVersion] = useState<number>(
|
||||
publishedVersions[0]?.version || 0
|
||||
);
|
||||
|
||||
const selectedVersionData = versionNodes.find(v => v.version === selectedVersion);
|
||||
|
||||
const { organizationId } = useParams();
|
||||
const [queryRef, loadQuery] = useQueryLoader<SignaturesModalOrganizationQuery>(organizationQuery);
|
||||
const { toast } = useToast();
|
||||
const [isRequesting, setIsRequesting] = useState<string | null>(null);
|
||||
|
||||
const [commitRequestSignature] = useMutation<SignaturesModalRequestSignatureMutation>(requestSignatureMutation);
|
||||
|
||||
// Load organization data when the modal opens and we have a valid version selected
|
||||
useEffect(() => {
|
||||
if (isOpen && organizationId && selectedVersionData?.status === "PUBLISHED") {
|
||||
loadQuery({ organizationId });
|
||||
}
|
||||
}, [isOpen, organizationId, loadQuery, selectedVersionData]);
|
||||
|
||||
const formatDateTime = (dateString?: string | null) => {
|
||||
if (!dateString) return "N/A";
|
||||
const date = new Date(dateString);
|
||||
return format(date, "h:mm a • MMM d, yyyy");
|
||||
};
|
||||
|
||||
// Safely type signatures as our defined Signature interface
|
||||
const signatures = selectedVersionData?.signatures?.edges?.map(edge => edge.node) || [];
|
||||
|
||||
const handleRequestSignature = (personId: string) => {
|
||||
if (!selectedVersionData) return;
|
||||
|
||||
setIsRequesting(personId);
|
||||
|
||||
commitRequestSignature({
|
||||
variables: {
|
||||
input: {
|
||||
policyVersionId: selectedVersionData.id,
|
||||
signatoryId: personId,
|
||||
},
|
||||
connections: [
|
||||
ConnectionHandler.getConnectionID(
|
||||
selectedVersionData.id,
|
||||
"SignaturesModal_policyVersions_signatures"
|
||||
),
|
||||
],
|
||||
},
|
||||
onCompleted: () => {
|
||||
toast({
|
||||
title: "Success",
|
||||
description: "Signature request sent successfully",
|
||||
});
|
||||
setIsRequesting(null);
|
||||
},
|
||||
onError: (error) => {
|
||||
toast({
|
||||
title: "Error",
|
||||
description: error.message,
|
||||
variant: "destructive",
|
||||
});
|
||||
setIsRequesting(null);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={onClose}>
|
||||
<DialogContent className="max-w-[1080px] h-[744px] p-0 overflow-hidden flex flex-col">
|
||||
<div className="flex flex-1 overflow-hidden">
|
||||
{/* Version History Sidebar */}
|
||||
<div className="w-[316px] border-r border-solid-b h-full overflow-y-auto">
|
||||
<h2 className="text-lg font-semibold p-6 pb-4">Version history</h2>
|
||||
<div className="overflow-y-auto">
|
||||
{versionNodes.length > 0 ? (
|
||||
versionNodes.map(version => {
|
||||
const isPublished = version.status === "PUBLISHED";
|
||||
const isSelected = selectedVersion === version.version;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={version.id}
|
||||
className={`flex items-center gap-3 p-6 py-4 ${
|
||||
isPublished ? 'cursor-pointer' : 'cursor-not-allowed opacity-50'
|
||||
} ${isSelected ? 'bg-slate-50' : ''}`}
|
||||
onClick={() => isPublished && setSelectedVersion(version.version)}
|
||||
>
|
||||
<Avatar className="h-10 w-10">
|
||||
<AvatarImage src="" alt={version.publishedBy?.fullName || owner?.fullName || ""} />
|
||||
<AvatarFallback>
|
||||
{(version.publishedBy?.fullName || owner?.fullName || "").charAt(0)}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium">Version {version.version}</span>
|
||||
{isPublished ? (
|
||||
<span className="text-xs px-2 py-0.5 rounded-full bg-green-100 text-green-800">
|
||||
Published
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-xs px-2 py-0.5 rounded-full bg-yellow-100 text-yellow-800">
|
||||
Draft
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-sm text-tertiary">
|
||||
{version.publishedBy?.fullName || owner?.fullName || "Unknown"} • {formatDateTime(version.publishedAt || version.updatedAt)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<div className="p-6 text-center text-tertiary">
|
||||
No versions available
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main Content Area */}
|
||||
<div className="flex-1 flex flex-col overflow-hidden">
|
||||
{/* Section header */}
|
||||
<div className="p-6 border-b border-solid-b">
|
||||
<h2 className="text-2xl font-semibold mb-2">
|
||||
{selectedVersionData?.status === "PUBLISHED" ? "Signatures & Requests" : "Signatures"}
|
||||
</h2>
|
||||
{selectedVersionData?.status === "PUBLISHED" && (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Click request to ask for a signature from people in your organization
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Content area with unified people and signatures list */}
|
||||
<div className="flex-1 overflow-y-auto p-6">
|
||||
{selectedVersionData ? (
|
||||
selectedVersionData.status === "PUBLISHED" && queryRef ? (
|
||||
<PeopleAndSignaturesList
|
||||
queryRef={queryRef}
|
||||
onRequestSignature={handleRequestSignature}
|
||||
requestingId={isRequesting}
|
||||
existingSignatures={signatures}
|
||||
formatDateTime={formatDateTime}
|
||||
/>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
{signatures.length > 0 ? (
|
||||
<div className="divide-y divide-border">
|
||||
{signatures.map(signature => (
|
||||
<div key={signature.id} className="py-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center gap-3">
|
||||
<Avatar className="h-10 w-10">
|
||||
<AvatarFallback>
|
||||
{signature.signedBy?.fullName?.charAt(0) || signature.requestedBy?.fullName?.charAt(0)}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<div className="font-medium">{signature.signedBy?.fullName || signature.requestedBy?.fullName}</div>
|
||||
<div className="text-sm text-tertiary">
|
||||
{signature.state === "SIGNED"
|
||||
? `Signed on ${formatDateTime(signature.signedAt)}`
|
||||
: `Requested on ${formatDateTime(signature.requestedAt)}`}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span className={`text-xs px-2 py-0.5 rounded-full ${
|
||||
signature.state === "SIGNED"
|
||||
? 'bg-green-100 text-green-800'
|
||||
: 'bg-yellow-100 text-yellow-800'
|
||||
}`}>
|
||||
{signature.state === "SIGNED" ? "Signed" : "Pending"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center py-8">
|
||||
<p className="text-tertiary">No signatures available for this version</p>
|
||||
{selectedVersionData.status !== "PUBLISHED" && (
|
||||
<p className="text-sm text-muted-foreground mt-2">Only published versions can have signatures</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
<div className="text-center text-tertiary py-8">
|
||||
No version selected
|
||||
</div>
|
||||
)}
|
||||
|
||||
{selectedVersionData?.status === "PUBLISHED" && !queryRef && (
|
||||
<div className="py-8 text-center">
|
||||
<Loader2 className="h-6 w-6 animate-spin mx-auto mb-2" />
|
||||
<p className="text-tertiary">Loading...</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end p-4 border-t border-solid-b mt-auto">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={onClose}
|
||||
className="mr-2"
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
// Combined people and signatures list component
|
||||
function PeopleAndSignaturesList({
|
||||
queryRef,
|
||||
onRequestSignature,
|
||||
requestingId,
|
||||
existingSignatures,
|
||||
formatDateTime,
|
||||
}: {
|
||||
queryRef: PreloadedQuery<SignaturesModalOrganizationQuery>,
|
||||
onRequestSignature: (personId: string) => void,
|
||||
requestingId: string | null,
|
||||
existingSignatures: Array<SignaturesModal_policyVersions$data["policyVersions"]["edges"][0]["node"]["signatures"]["edges"][0]["node"]>,
|
||||
formatDateTime: (date?: string | null) => string,
|
||||
}) {
|
||||
const data = usePreloadedQuery<SignaturesModalOrganizationQuery>(
|
||||
organizationQuery,
|
||||
queryRef
|
||||
);
|
||||
|
||||
const people = data?.organization?.peoples?.edges || [];
|
||||
|
||||
if (!data?.organization) {
|
||||
return (
|
||||
<div className="text-center py-8">
|
||||
Organization not found
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (people.length === 0) {
|
||||
return (
|
||||
<div className="text-center py-8">
|
||||
No people available to request signatures from
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Create lookup for signatures by person ID
|
||||
const signaturesByPersonId = new Map();
|
||||
existingSignatures.forEach(sig => {
|
||||
if (sig.signedBy?.id) {
|
||||
signaturesByPersonId.set(sig.signedBy.id, sig);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="divide-y divide-border">
|
||||
{people.map((edge: any) => {
|
||||
const person = edge.node;
|
||||
const signature = signaturesByPersonId.get(person.id);
|
||||
const isRequesting = requestingId === person.id;
|
||||
|
||||
return (
|
||||
<div key={person.id} className="py-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center gap-3">
|
||||
<Avatar className="h-10 w-10">
|
||||
<AvatarFallback>
|
||||
{person.fullName.charAt(0)}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<div className="font-medium">{person.fullName}</div>
|
||||
<div className="text-sm text-tertiary">
|
||||
{signature ? (
|
||||
signature.state === "SIGNED" ? (
|
||||
<div className="flex items-center gap-1 text-green-700">
|
||||
<CheckCircle2 className="h-3.5 w-3.5" />
|
||||
<span>Signed on {formatDateTime(signature.signedAt)}</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center gap-1 text-amber-700">
|
||||
<Clock className="h-3.5 w-3.5" />
|
||||
<span>Requested on {formatDateTime(signature.requestedAt)}</span>
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
person.primaryEmailAddress
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{signature ? (
|
||||
<span className={`text-xs px-2 py-0.5 rounded-full ${
|
||||
signature.state === "SIGNED"
|
||||
? 'bg-green-100 text-green-800'
|
||||
: 'bg-yellow-100 text-yellow-800'
|
||||
}`}>
|
||||
{signature.state === "SIGNED" ? "Signed" : "Pending"}
|
||||
</span>
|
||||
) : (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onRequestSignature(person.id)}
|
||||
disabled={isRequesting}
|
||||
>
|
||||
{isRequesting ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 mr-2 animate-spin" />
|
||||
Requesting...
|
||||
</>
|
||||
) : (
|
||||
"Request Signature"
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
import { Dialog, DialogContent } from "@/components/ui/dialog";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { format } from "date-fns";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useState } from "react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import { graphql, useFragment } from "react-relay";
|
||||
import type { VersionHistoryModal_policyVersions$key } from "./__generated__/VersionHistoryModal_policyVersions.graphql";
|
||||
|
||||
export const policyVersionsFragment = graphql`
|
||||
fragment VersionHistoryModal_policyVersions on Policy {
|
||||
title
|
||||
owner {
|
||||
fullName
|
||||
}
|
||||
versionHistory: versions(first: 20) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
version
|
||||
status
|
||||
content
|
||||
changelog
|
||||
publishedAt
|
||||
updatedAt
|
||||
publishedBy {
|
||||
fullName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
interface VersionHistoryModalProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
policyRef: VersionHistoryModal_policyVersions$key;
|
||||
onRestoreVersion?: (versionNumber: number) => void;
|
||||
}
|
||||
|
||||
export function VersionHistoryModal({
|
||||
isOpen,
|
||||
onClose,
|
||||
policyRef,
|
||||
onRestoreVersion
|
||||
}: VersionHistoryModalProps) {
|
||||
const data = useFragment<VersionHistoryModal_policyVersions$key>(
|
||||
policyVersionsFragment,
|
||||
policyRef
|
||||
);
|
||||
|
||||
// Safely access and extract version nodes
|
||||
const versionNodes = data?.versionHistory?.edges?.map(edge => edge.node) || [];
|
||||
|
||||
// Sort versions by version number (descending)
|
||||
const versions = [...versionNodes].sort((a, b) => b.version - a.version);
|
||||
|
||||
const latestVersion = versions.length > 0 ? versions[0].version : 0;
|
||||
const [selectedVersion, setSelectedVersion] = useState<number>(latestVersion);
|
||||
|
||||
const currentVersionData = versions.find(v => v.version === selectedVersion);
|
||||
|
||||
// Format time helper for version history
|
||||
const formatDateTime = (dateString?: string | null) => {
|
||||
if (!dateString) return "N/A";
|
||||
const date = new Date(dateString);
|
||||
return format(date, "h:mm a • MMM d, yyyy");
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={onClose}>
|
||||
<DialogContent className="max-w-[1080px] h-[744px] p-0 overflow-hidden flex flex-col">
|
||||
<div className="flex flex-1 overflow-hidden">
|
||||
{/* Version History Sidebar */}
|
||||
<div className="w-[316px] border-r border-solid-b h-full overflow-y-auto">
|
||||
<h2 className="text-lg font-semibold p-6 pb-4">Version history</h2>
|
||||
<div className="overflow-y-auto">
|
||||
{versions.map((version) => (
|
||||
<div
|
||||
key={version.id}
|
||||
className={`flex items-center gap-3 p-6 py-4 cursor-pointer ${selectedVersion === version.version ? 'bg-slate-50' : ''}`}
|
||||
onClick={() => setSelectedVersion(version.version)}
|
||||
>
|
||||
<Avatar className="h-10 w-10">
|
||||
<AvatarImage src="" alt={version.publishedBy?.fullName || data.owner?.fullName || ""} />
|
||||
<AvatarFallback>
|
||||
{(version.publishedBy?.fullName || data.owner?.fullName || "").charAt(0)}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium">Version {version.version}</span>
|
||||
{version.status === "PUBLISHED" ? (
|
||||
<span className="text-xs px-2 py-0.5 rounded-full bg-green-100 text-green-800">
|
||||
Published
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-xs px-2 py-0.5 rounded-full bg-yellow-100 text-yellow-800">
|
||||
Draft
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-sm text-tertiary">
|
||||
{version.publishedBy?.fullName || data.owner?.fullName || "Unknown"} • {formatDateTime(version.publishedAt || version.updatedAt)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content Area */}
|
||||
<div className="flex-1 p-6 relative overflow-y-auto">
|
||||
<h2 className="text-2xl font-semibold mb-6">{data.title}</h2>
|
||||
|
||||
<div className="prose prose-olive max-w-none">
|
||||
{selectedVersion && (
|
||||
<ReactMarkdown>
|
||||
{versions.find(v => v.version === selectedVersion)?.content || "No content available"}
|
||||
</ReactMarkdown>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end p-4 border-t border-solid-b mt-auto">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={onClose}
|
||||
className="mr-2"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
|
||||
{onRestoreVersion && (
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={() => onRestoreVersion(selectedVersion)}
|
||||
disabled={selectedVersion === latestVersion}
|
||||
>
|
||||
Restore version
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<171200736f3a443faae3f8b7c2085f4f>>
|
||||
* @generated SignedSource<<d8d76cb73e37916ddc34017550ff3702>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -9,30 +9,18 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type PolicyStatus = "ACTIVE" | "DRAFT";
|
||||
export type UpdatePolicyInput = {
|
||||
content?: string | null | undefined;
|
||||
id: string;
|
||||
name?: string | null | undefined;
|
||||
ownerId?: string | null | undefined;
|
||||
reviewDate?: string | null | undefined;
|
||||
status?: PolicyStatus | null | undefined;
|
||||
export type UpdatePolicyVersionInput = {
|
||||
content: string;
|
||||
policyVersionId: string;
|
||||
};
|
||||
export type EditPolicyViewMutation$variables = {
|
||||
input: UpdatePolicyInput;
|
||||
input: UpdatePolicyVersionInput;
|
||||
};
|
||||
export type EditPolicyViewMutation$data = {
|
||||
readonly updatePolicy: {
|
||||
readonly policy: {
|
||||
readonly updatePolicyVersion: {
|
||||
readonly policyVersion: {
|
||||
readonly content: string;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly owner: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
};
|
||||
readonly reviewDate: string | null | undefined;
|
||||
readonly status: PolicyStatus;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -49,14 +37,7 @@ var v0 = [
|
||||
"name": "input"
|
||||
}
|
||||
],
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v2 = [
|
||||
v1 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
@@ -66,25 +47,24 @@ v2 = [
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
"concreteType": "UpdatePolicyPayload",
|
||||
"concreteType": "UpdatePolicyVersionPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "updatePolicy",
|
||||
"name": "updatePolicyVersion",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Policy",
|
||||
"concreteType": "PolicyVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "policy",
|
||||
"name": "policyVersion",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
@@ -93,39 +73,6 @@ v2 = [
|
||||
"kind": "ScalarField",
|
||||
"name": "content",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "reviewDate",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "owner",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
@@ -140,7 +87,7 @@ return {
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "EditPolicyViewMutation",
|
||||
"selections": (v2/*: any*/),
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
@@ -149,19 +96,19 @@ return {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "EditPolicyViewMutation",
|
||||
"selections": (v2/*: any*/)
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "643990a3ab54cb51144f434b023531e7",
|
||||
"cacheID": "02b56043d606c6237dd502a7695fea50",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "EditPolicyViewMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation EditPolicyViewMutation(\n $input: UpdatePolicyInput!\n) {\n updatePolicy(input: $input) {\n policy {\n id\n name\n content\n status\n reviewDate\n owner {\n id\n fullName\n }\n }\n }\n}\n"
|
||||
"text": "mutation EditPolicyViewMutation(\n $input: UpdatePolicyVersionInput!\n) {\n updatePolicyVersion(input: $input) {\n policyVersion {\n id\n content\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "41d4945568bc1f43eeedc727a968654d";
|
||||
(node as any).hash = "556fbcc4fadc0011c1a2154dcffeb389";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<312876323f4072e43048dfe1b2e21d08>>
|
||||
* @generated SignedSource<<7738a95cc83ee25c08f6ddc556f144c1>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -10,25 +10,26 @@
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type PolicyStatus = "ACTIVE" | "DRAFT";
|
||||
export type EditPolicyViewQuery$variables = {
|
||||
organizationId: string;
|
||||
policyId: string;
|
||||
policyVersionId: string;
|
||||
};
|
||||
export type EditPolicyViewQuery$data = {
|
||||
readonly organization: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"PeopleSelector_organization">;
|
||||
};
|
||||
readonly policy: {
|
||||
readonly content?: string;
|
||||
readonly id: string;
|
||||
readonly name?: string;
|
||||
readonly owner?: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
};
|
||||
readonly reviewDate?: string | null | undefined;
|
||||
readonly status?: PolicyStatus;
|
||||
readonly title?: string;
|
||||
};
|
||||
readonly policyVersion: {
|
||||
readonly content?: string;
|
||||
readonly id: string;
|
||||
};
|
||||
};
|
||||
export type EditPolicyViewQuery = {
|
||||
@@ -47,56 +48,61 @@ v1 = {
|
||||
"kind": "LocalArgument",
|
||||
"name": "policyId"
|
||||
},
|
||||
v2 = [
|
||||
v2 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "policyVersionId"
|
||||
},
|
||||
v3 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "policyId"
|
||||
"variableName": "policyVersionId"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v5 = {
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "content",
|
||||
"storageKey": null
|
||||
},
|
||||
}
|
||||
],
|
||||
"type": "PolicyVersion",
|
||||
"abstractKey": null
|
||||
},
|
||||
v6 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "policyId"
|
||||
}
|
||||
],
|
||||
v7 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
},
|
||||
v8 = {
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "reviewDate",
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
@@ -107,8 +113,8 @@ v5 = {
|
||||
"name": "owner",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/)
|
||||
(v4/*: any*/),
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
@@ -116,21 +122,21 @@ v5 = {
|
||||
"type": "Policy",
|
||||
"abstractKey": null
|
||||
},
|
||||
v6 = [
|
||||
v9 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "organizationId"
|
||||
}
|
||||
],
|
||||
v7 = {
|
||||
v10 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v8 = [
|
||||
v11 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
@@ -149,32 +155,46 @@ return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
(v1/*: any*/),
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "EditPolicyViewQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "policy",
|
||||
"args": (v2/*: any*/),
|
||||
"alias": "policyVersion",
|
||||
"args": (v3/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "organization",
|
||||
"alias": "policy",
|
||||
"args": (v6/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v4/*: any*/),
|
||||
(v8/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v9/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"args": null,
|
||||
@@ -192,41 +212,56 @@ return {
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
(v0/*: any*/),
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "EditPolicyViewQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "policy",
|
||||
"args": (v2/*: any*/),
|
||||
"alias": "policyVersion",
|
||||
"args": (v3/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v7/*: any*/),
|
||||
(v3/*: any*/),
|
||||
(v10/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "organization",
|
||||
"alias": "policy",
|
||||
"args": (v6/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v7/*: any*/),
|
||||
(v3/*: any*/),
|
||||
(v10/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v8/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v9/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v10/*: any*/),
|
||||
(v4/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v8/*: any*/),
|
||||
"args": (v11/*: any*/),
|
||||
"concreteType": "PeopleConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "peoples",
|
||||
@@ -248,8 +283,8 @@ return {
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v7/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -257,7 +292,7 @@ return {
|
||||
"name": "primaryEmailAddress",
|
||||
"storageKey": null
|
||||
},
|
||||
(v7/*: any*/)
|
||||
(v10/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
@@ -301,7 +336,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v8/*: any*/),
|
||||
"args": (v11/*: any*/),
|
||||
"filters": [
|
||||
"orderBy"
|
||||
],
|
||||
@@ -320,16 +355,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "4d52d22f9d8acc7912a57d974f558248",
|
||||
"cacheID": "4d586701fc5f2e4976bb87d9be61c594",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "EditPolicyViewQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query EditPolicyViewQuery(\n $policyId: ID!\n $organizationId: ID!\n) {\n policy: node(id: $policyId) {\n __typename\n id\n ... on Policy {\n name\n content\n status\n reviewDate\n owner {\n id\n fullName\n }\n }\n }\n organization: node(id: $organizationId) {\n __typename\n ...PeopleSelector_organization\n id\n }\n}\n\nfragment PeopleSelector_organization on Organization {\n id\n peoples(first: 100, orderBy: {direction: ASC, field: FULL_NAME}) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
|
||||
"text": "query EditPolicyViewQuery(\n $policyId: ID!\n $organizationId: ID!\n $policyVersionId: ID!\n) {\n policyVersion: node(id: $policyVersionId) {\n __typename\n id\n ... on PolicyVersion {\n content\n }\n }\n policy: node(id: $policyId) {\n __typename\n id\n ... on Policy {\n title\n owner {\n id\n fullName\n }\n }\n }\n organization: node(id: $organizationId) {\n __typename\n ...PeopleSelector_organization\n id\n }\n}\n\nfragment PeopleSelector_organization on Organization {\n id\n peoples(first: 100, orderBy: {direction: ASC, field: FULL_NAME}) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d16bdd881b27b1aa5368130ce036fd20";
|
||||
(node as any).hash = "2a934195ed33bd073e3976e8cc19a925";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,230 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<84789bb949f94e924de1c9b9d566b4a5>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type NewPolicyViewQuery$variables = {
|
||||
organizationId: string;
|
||||
};
|
||||
export type NewPolicyViewQuery$data = {
|
||||
readonly organization: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"PeopleSelector_organization">;
|
||||
};
|
||||
};
|
||||
export type NewPolicyViewQuery = {
|
||||
response: NewPolicyViewQuery$data;
|
||||
variables: NewPolicyViewQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "organizationId"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "organizationId"
|
||||
}
|
||||
],
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
},
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "orderBy",
|
||||
"value": {
|
||||
"direction": "ASC",
|
||||
"field": "FULL_NAME"
|
||||
}
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "NewPolicyViewQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "PeopleSelector_organization"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "NewPolicyViewQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v4/*: any*/),
|
||||
"concreteType": "PeopleConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "peoples",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PeopleEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "primaryEmailAddress",
|
||||
"storageKey": null
|
||||
},
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "peoples(first:100,orderBy:{\"direction\":\"ASC\",\"field\":\"FULL_NAME\"})"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v4/*: any*/),
|
||||
"filters": [
|
||||
"orderBy"
|
||||
],
|
||||
"handle": "connection",
|
||||
"key": "PeopleSelector_organization_peoples",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "peoples"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "552067b4b0632972c14f7a8dcaf171aa",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "NewPolicyViewQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query NewPolicyViewQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ...PeopleSelector_organization\n id\n }\n}\n\nfragment PeopleSelector_organization on Organization {\n id\n peoples(first: 100, orderBy: {direction: ASC, field: FULL_NAME}) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "98fa41bfaf0d76adce1c91cf8d6ade28";
|
||||
|
||||
export default node;
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<2026b385ee5eb895da6ca9c919762913>>
|
||||
* @generated SignedSource<<885dc2a54ba3b8d4663e197cfe61d704>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -9,39 +9,36 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type PolicyStatus = "ACTIVE" | "DRAFT";
|
||||
export type CreatePolicyInput = {
|
||||
content: string;
|
||||
name: string;
|
||||
organizationId: string;
|
||||
ownerId: string;
|
||||
reviewDate?: string | null | undefined;
|
||||
status: PolicyStatus;
|
||||
title: string;
|
||||
};
|
||||
export type NewPolicyViewMutation$variables = {
|
||||
export type PolicyListViewCreateMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: CreatePolicyInput;
|
||||
};
|
||||
export type NewPolicyViewMutation$data = {
|
||||
export type PolicyListViewCreateMutation$data = {
|
||||
readonly createPolicy: {
|
||||
readonly policyEdge: {
|
||||
readonly node: {
|
||||
readonly content: string;
|
||||
readonly createdAt: string;
|
||||
readonly description: string;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly owner: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
};
|
||||
readonly reviewDate: string | null | undefined;
|
||||
readonly status: PolicyStatus;
|
||||
readonly title: string;
|
||||
readonly updatedAt: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export type NewPolicyViewMutation = {
|
||||
response: NewPolicyViewMutation$data;
|
||||
variables: NewPolicyViewMutation$variables;
|
||||
export type PolicyListViewCreateMutation = {
|
||||
response: PolicyListViewCreateMutation$data;
|
||||
variables: PolicyListViewCreateMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
@@ -90,28 +87,28 @@ 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": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "reviewDate",
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
@@ -147,7 +144,7 @@ return {
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "NewPolicyViewMutation",
|
||||
"name": "PolicyListViewCreateMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
@@ -172,7 +169,7 @@ return {
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "NewPolicyViewMutation",
|
||||
"name": "PolicyListViewCreateMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
@@ -205,16 +202,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "aa29cde3106d1c8d35c6ae8e74f310b7",
|
||||
"cacheID": "f7aae6d7a0d276e71caec643e43b5ee5",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "NewPolicyViewMutation",
|
||||
"name": "PolicyListViewCreateMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation NewPolicyViewMutation(\n $input: CreatePolicyInput!\n) {\n createPolicy(input: $input) {\n policyEdge {\n node {\n id\n name\n content\n status\n reviewDate\n owner {\n id\n fullName\n }\n }\n }\n }\n}\n"
|
||||
"text": "mutation PolicyListViewCreateMutation(\n $input: CreatePolicyInput!\n) {\n createPolicy(input: $input) {\n policyEdge {\n node {\n id\n title\n description\n createdAt\n updatedAt\n owner {\n id\n fullName\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "f6dcabf6c51e3858c9750e00fcc0cc15";
|
||||
(node as any).hash = "d55ac010a7ad352d830d3a38f2f8d5a8";
|
||||
|
||||
export default node;
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<391e3817107bb96f50aad61d20cad0a8>>
|
||||
* @generated SignedSource<<5b24e53258fceb03535363014f57a15e>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -9,7 +9,8 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type PolicyStatus = "ACTIVE" | "DRAFT";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type PolicyStatus = "DRAFT" | "PUBLISHED";
|
||||
export type PolicyListViewQuery$variables = {
|
||||
organizationId: string;
|
||||
};
|
||||
@@ -18,15 +19,34 @@ export type PolicyListViewQuery$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 status: PolicyStatus;
|
||||
readonly owner: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
};
|
||||
readonly title: string;
|
||||
readonly updatedAt: string;
|
||||
readonly versions: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly status: PolicyStatus;
|
||||
readonly updatedAt: string;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly " $fragmentSpreads": FragmentRefs<"PeopleSelector_organization">;
|
||||
};
|
||||
readonly viewer: {
|
||||
readonly user: {
|
||||
readonly id: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
export type PolicyListViewQuery = {
|
||||
@@ -42,28 +62,94 @@ var v0 = [
|
||||
"name": "organizationId"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "organizationId"
|
||||
}
|
||||
],
|
||||
v2 = {
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = {
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "User",
|
||||
"kind": "LinkedField",
|
||||
"name": "user",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "organizationId"
|
||||
}
|
||||
],
|
||||
v4 = {
|
||||
"kind": "Literal",
|
||||
"name": "orderBy",
|
||||
"value": {
|
||||
"direction": "ASC",
|
||||
"field": "TITLE"
|
||||
}
|
||||
},
|
||||
v5 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v6 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
},
|
||||
v7 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = [
|
||||
v8 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
},
|
||||
v9 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
v10 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -80,19 +166,26 @@ v4 = [
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"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": "currentPublishedVersion",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
@@ -102,66 +195,103 @@ v4 = [
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
(v5/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "updatedAt",
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "owner",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
(v6/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 1
|
||||
}
|
||||
],
|
||||
"concreteType": "PolicyVersionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "versions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
(v5/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "versions(first:1)"
|
||||
},
|
||||
(v3/*: any*/)
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
(v8/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
(v9/*: any*/)
|
||||
],
|
||||
v5 = [
|
||||
v11 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
},
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "orderBy",
|
||||
"value": {
|
||||
"direction": "ASC",
|
||||
"field": "FULL_NAME"
|
||||
}
|
||||
}
|
||||
],
|
||||
v12 = [
|
||||
"orderBy"
|
||||
],
|
||||
v13 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 50
|
||||
},
|
||||
(v4/*: any*/)
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
@@ -170,9 +300,21 @@ return {
|
||||
"metadata": null,
|
||||
"name": "PolicyListViewQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Viewer",
|
||||
"kind": "LinkedField",
|
||||
"name": "viewer",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v1/*: any*/),
|
||||
"args": (v3/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
@@ -182,14 +324,21 @@ return {
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "policies",
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "PeopleSelector_organization"
|
||||
},
|
||||
{
|
||||
"alias": "policies",
|
||||
"args": [
|
||||
(v4/*: any*/)
|
||||
],
|
||||
"concreteType": "PolicyConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__PolicyListView_policies_connection",
|
||||
"plural": false,
|
||||
"selections": (v4/*: any*/),
|
||||
"storageKey": null
|
||||
"selections": (v10/*: any*/),
|
||||
"storageKey": "__PolicyListView_policies_connection(orderBy:{\"direction\":\"ASC\",\"field\":\"TITLE\"})"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
@@ -208,32 +357,100 @@ return {
|
||||
"kind": "Operation",
|
||||
"name": "PolicyListViewQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Viewer",
|
||||
"kind": "LinkedField",
|
||||
"name": "viewer",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v1/*: any*/),
|
||||
"args": (v3/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v7/*: any*/),
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v5/*: any*/),
|
||||
"args": (v11/*: any*/),
|
||||
"concreteType": "PeopleConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "peoples",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PeopleEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
(v6/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "primaryEmailAddress",
|
||||
"storageKey": null
|
||||
},
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v8/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v9/*: any*/)
|
||||
],
|
||||
"storageKey": "peoples(first:100,orderBy:{\"direction\":\"ASC\",\"field\":\"FULL_NAME\"})"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v11/*: any*/),
|
||||
"filters": (v12/*: any*/),
|
||||
"handle": "connection",
|
||||
"key": "PeopleSelector_organization_peoples",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "peoples"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v13/*: any*/),
|
||||
"concreteType": "PolicyConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "policies",
|
||||
"plural": false,
|
||||
"selections": (v4/*: any*/),
|
||||
"storageKey": "policies(first:100)"
|
||||
"selections": (v10/*: any*/),
|
||||
"storageKey": "policies(first:50,orderBy:{\"direction\":\"ASC\",\"field\":\"TITLE\"})"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v5/*: any*/),
|
||||
"filters": null,
|
||||
"args": (v13/*: any*/),
|
||||
"filters": (v12/*: any*/),
|
||||
"handle": "connection",
|
||||
"key": "PolicyListView_policies",
|
||||
"kind": "LinkedHandle",
|
||||
@@ -242,15 +459,14 @@ return {
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
},
|
||||
(v2/*: any*/)
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "6434c8135f68ac64eb2f06983ddc3595",
|
||||
"cacheID": "ed650f54cc226d3adea27a78a777890c",
|
||||
"id": null,
|
||||
"metadata": {
|
||||
"connection": [
|
||||
@@ -267,11 +483,11 @@ return {
|
||||
},
|
||||
"name": "PolicyListViewQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query PolicyListViewQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n policies(first: 100) {\n edges {\n node {\n id\n name\n content\n createdAt\n updatedAt\n status\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n}\n"
|
||||
"text": "query PolicyListViewQuery(\n $organizationId: ID!\n) {\n viewer {\n user {\n id\n }\n id\n }\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...PeopleSelector_organization\n policies(first: 50, orderBy: {field: TITLE, direction: ASC}) {\n edges {\n node {\n id\n title\n description\n currentPublishedVersion\n createdAt\n updatedAt\n owner {\n id\n fullName\n }\n versions(first: 1) {\n edges {\n node {\n id\n status\n updatedAt\n }\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n}\n\nfragment PeopleSelector_organization on Organization {\n id\n peoples(first: 100, orderBy: {direction: ASC, field: FULL_NAME}) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "5567339ad9b2be90b94edc8b1a16fe1e";
|
||||
(node as any).hash = "b3b0798be0779c09013a4743d015e87f";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<4e559f39bd9ec2b3782113ef034cad03>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type DeletePolicyInput = {
|
||||
policyId: string;
|
||||
};
|
||||
export type PolicyViewDeleteMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: DeletePolicyInput;
|
||||
};
|
||||
export type PolicyViewDeleteMutation$data = {
|
||||
readonly deletePolicy: {
|
||||
readonly deletedPolicyId: string;
|
||||
};
|
||||
};
|
||||
export type PolicyViewDeleteMutation = {
|
||||
response: PolicyViewDeleteMutation$data;
|
||||
variables: PolicyViewDeleteMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deletedPolicyId",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "PolicyViewDeleteMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeletePolicyPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deletePolicy",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "PolicyViewDeleteMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeletePolicyPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deletePolicy",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "deleteEdge",
|
||||
"key": "",
|
||||
"kind": "ScalarHandle",
|
||||
"name": "deletedPolicyId",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "67e67147e0c7ec0489346b1ad86899c9",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "PolicyViewDeleteMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation PolicyViewDeleteMutation(\n $input: DeletePolicyInput!\n) {\n deletePolicy(input: $input) {\n deletedPolicyId\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "7d421e9b068f3f676a4c3069769b1c18";
|
||||
|
||||
export default node;
|
||||
@@ -1,199 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<eaeef5694bdd615c03bea3b3f8957df3>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type PolicyStatus = "ACTIVE" | "DRAFT";
|
||||
export type PolicyViewQuery$variables = {
|
||||
policyId: string;
|
||||
};
|
||||
export type PolicyViewQuery$data = {
|
||||
readonly node: {
|
||||
readonly content?: string;
|
||||
readonly createdAt?: string;
|
||||
readonly id: string;
|
||||
readonly name?: string;
|
||||
readonly owner?: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
readonly primaryEmailAddress: string;
|
||||
};
|
||||
readonly reviewDate?: string | null | undefined;
|
||||
readonly status?: PolicyStatus;
|
||||
readonly updatedAt?: string;
|
||||
};
|
||||
};
|
||||
export type PolicyViewQuery = {
|
||||
response: PolicyViewQuery$data;
|
||||
variables: PolicyViewQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "policyId"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "policyId"
|
||||
}
|
||||
],
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = {
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "content",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "reviewDate",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"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
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "primaryEmailAddress",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Policy",
|
||||
"abstractKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "PolicyViewQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "PolicyViewQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "26bf57eeab9c600a3146e01085ecae8e",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "PolicyViewQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query PolicyViewQuery(\n $policyId: ID!\n) {\n node(id: $policyId) {\n __typename\n id\n ... on Policy {\n name\n content\n createdAt\n updatedAt\n reviewDate\n status\n owner {\n id\n fullName\n primaryEmailAddress\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "0fcc28fc290df69d14d7d549bd09216f";
|
||||
|
||||
export default node;
|
||||
135
apps/console/src/pages/organizations/policies/__generated__/ShowPolicyViewCreateDraftMutation.graphql.ts
generated
Normal file
135
apps/console/src/pages/organizations/policies/__generated__/ShowPolicyViewCreateDraftMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @generated SignedSource<<290d3c4fb382c7b99c60eeee5cfa8c5a>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type PolicyStatus = "DRAFT" | "PUBLISHED";
|
||||
export type CreateDraftPolicyVersionInput = {
|
||||
policyID: string;
|
||||
};
|
||||
export type ShowPolicyViewCreateDraftMutation$variables = {
|
||||
input: CreateDraftPolicyVersionInput;
|
||||
};
|
||||
export type ShowPolicyViewCreateDraftMutation$data = {
|
||||
readonly createDraftPolicyVersion: {
|
||||
readonly policyVersionEdge: {
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly status: PolicyStatus;
|
||||
readonly version: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export type ShowPolicyViewCreateDraftMutation = {
|
||||
response: ShowPolicyViewCreateDraftMutation$data;
|
||||
variables: ShowPolicyViewCreateDraftMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
"concreteType": "CreateDraftPolicyVersionPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "createDraftPolicyVersion",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "policyVersionEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "version",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "ShowPolicyViewCreateDraftMutation",
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "ShowPolicyViewCreateDraftMutation",
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "e96d226e93260cd989dc122193fbcbce",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ShowPolicyViewCreateDraftMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation ShowPolicyViewCreateDraftMutation(\n $input: CreateDraftPolicyVersionInput!\n) {\n createDraftPolicyVersion(input: $input) {\n policyVersionEdge {\n node {\n id\n version\n status\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "49282edca41fc2bdca1a1c6db4b2dc11";
|
||||
|
||||
export default node;
|
||||
211
apps/console/src/pages/organizations/policies/__generated__/ShowPolicyViewPublishMutation.graphql.ts
generated
Normal file
211
apps/console/src/pages/organizations/policies/__generated__/ShowPolicyViewPublishMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,211 @@
|
||||
/**
|
||||
* @generated SignedSource<<024ec8d58aa5f37adad3ac5e98c15a90>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type PolicyStatus = "DRAFT" | "PUBLISHED";
|
||||
export type PublishPolicyVersionInput = {
|
||||
policyId: string;
|
||||
};
|
||||
export type ShowPolicyViewPublishMutation$variables = {
|
||||
input: PublishPolicyVersionInput;
|
||||
};
|
||||
export type ShowPolicyViewPublishMutation$data = {
|
||||
readonly publishPolicyVersion: {
|
||||
readonly policy: {
|
||||
readonly currentPublishedVersion: number | null | undefined;
|
||||
readonly id: string;
|
||||
};
|
||||
readonly policyVersion: {
|
||||
readonly id: string;
|
||||
readonly publishedAt: string | null | undefined;
|
||||
readonly publishedBy: {
|
||||
readonly fullName: string;
|
||||
} | null | undefined;
|
||||
readonly status: PolicyStatus;
|
||||
};
|
||||
};
|
||||
};
|
||||
export type ShowPolicyViewPublishMutation = {
|
||||
response: ShowPolicyViewPublishMutation$data;
|
||||
variables: ShowPolicyViewPublishMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Policy",
|
||||
"kind": "LinkedField",
|
||||
"name": "policy",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "currentPublishedVersion",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
v5 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "publishedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v6 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "ShowPolicyViewPublishMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": "PublishPolicyVersionPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "publishPolicyVersion",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "policyVersion",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "publishedBy",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v6/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "ShowPolicyViewPublishMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": "PublishPolicyVersionPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "publishPolicyVersion",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "policyVersion",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "publishedBy",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v6/*: any*/),
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "2047a011abeae6642230cb7b31080b08",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ShowPolicyViewPublishMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation ShowPolicyViewPublishMutation(\n $input: PublishPolicyVersionInput!\n) {\n publishPolicyVersion(input: $input) {\n policy {\n id\n currentPublishedVersion\n }\n policyVersion {\n id\n status\n publishedAt\n publishedBy {\n fullName\n id\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d81485a797858cf5f2834cf131d248cc";
|
||||
|
||||
export default node;
|
||||
606
apps/console/src/pages/organizations/policies/__generated__/ShowPolicyViewQuery.graphql.ts
generated
Normal file
606
apps/console/src/pages/organizations/policies/__generated__/ShowPolicyViewQuery.graphql.ts
generated
Normal file
@@ -0,0 +1,606 @@
|
||||
/**
|
||||
* @generated SignedSource<<351444982c4868267f30cc9fc8a2399a>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type PolicyStatus = "DRAFT" | "PUBLISHED";
|
||||
export type ShowPolicyViewQuery$variables = {
|
||||
policyId: string;
|
||||
};
|
||||
export type ShowPolicyViewQuery$data = {
|
||||
readonly node: {
|
||||
readonly createdAt?: string;
|
||||
readonly currentPublishedVersion?: number | null | undefined;
|
||||
readonly description?: string;
|
||||
readonly id: string;
|
||||
readonly latestVersion?: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly changelog: string;
|
||||
readonly content: string;
|
||||
readonly createdAt: string;
|
||||
readonly id: string;
|
||||
readonly publishedAt: string | null | undefined;
|
||||
readonly publishedBy: {
|
||||
readonly fullName: string;
|
||||
} | null | undefined;
|
||||
readonly status: PolicyStatus;
|
||||
readonly updatedAt: string;
|
||||
readonly version: number;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly owner?: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
readonly primaryEmailAddress: string;
|
||||
};
|
||||
readonly title?: string;
|
||||
readonly updatedAt?: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"SignaturesModal_policyVersions" | "VersionHistoryModal_policyVersions">;
|
||||
};
|
||||
};
|
||||
export type ShowPolicyViewQuery = {
|
||||
response: ShowPolicyViewQuery$data;
|
||||
variables: ShowPolicyViewQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "policyId"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "policyId"
|
||||
}
|
||||
],
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
v5 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v6 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v7 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "currentPublishedVersion",
|
||||
"storageKey": null
|
||||
},
|
||||
v8 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
},
|
||||
v9 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "owner",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v8/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "primaryEmailAddress",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
v10 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 1
|
||||
}
|
||||
],
|
||||
v11 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "version",
|
||||
"storageKey": null
|
||||
},
|
||||
v12 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
v13 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "content",
|
||||
"storageKey": null
|
||||
},
|
||||
v14 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "changelog",
|
||||
"storageKey": null
|
||||
},
|
||||
v15 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "publishedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v16 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v17 = [
|
||||
(v8/*: any*/),
|
||||
(v2/*: any*/)
|
||||
],
|
||||
v18 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "publishedBy",
|
||||
"plural": false,
|
||||
"selections": (v17/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
v19 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "ShowPolicyViewQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/),
|
||||
(v6/*: any*/),
|
||||
(v7/*: any*/),
|
||||
(v9/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "SignaturesModal_policyVersions"
|
||||
},
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "VersionHistoryModal_policyVersions"
|
||||
},
|
||||
{
|
||||
"alias": "latestVersion",
|
||||
"args": (v10/*: any*/),
|
||||
"concreteType": "PolicyVersionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "versions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/),
|
||||
(v13/*: any*/),
|
||||
(v14/*: any*/),
|
||||
(v15/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "publishedBy",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v8/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v5/*: any*/),
|
||||
(v6/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "versions(first:1)"
|
||||
}
|
||||
],
|
||||
"type": "Policy",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "ShowPolicyViewQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v16/*: any*/),
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/),
|
||||
(v6/*: any*/),
|
||||
(v7/*: any*/),
|
||||
(v9/*: any*/),
|
||||
{
|
||||
"alias": "policyVersions",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 10
|
||||
}
|
||||
],
|
||||
"concreteType": "PolicyVersionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "versions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/),
|
||||
(v15/*: any*/),
|
||||
(v6/*: any*/),
|
||||
(v18/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v19/*: any*/),
|
||||
"concreteType": "PolicyVersionSignatureConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "signatures",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionSignatureEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionSignature",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "signedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "requestedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "signedBy",
|
||||
"plural": false,
|
||||
"selections": (v17/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "requestedBy",
|
||||
"plural": false,
|
||||
"selections": (v17/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
(v16/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "signatures(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v19/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "SignaturesModal_policyVersions_signatures",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "signatures"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "versions(first:10)"
|
||||
},
|
||||
{
|
||||
"alias": "versionHistory",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 20
|
||||
}
|
||||
],
|
||||
"concreteType": "PolicyVersionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "versions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/),
|
||||
(v13/*: any*/),
|
||||
(v14/*: any*/),
|
||||
(v15/*: any*/),
|
||||
(v6/*: any*/),
|
||||
(v18/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "versions(first:20)"
|
||||
},
|
||||
{
|
||||
"alias": "latestVersion",
|
||||
"args": (v10/*: any*/),
|
||||
"concreteType": "PolicyVersionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "versions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/),
|
||||
(v13/*: any*/),
|
||||
(v14/*: any*/),
|
||||
(v15/*: any*/),
|
||||
(v18/*: any*/),
|
||||
(v5/*: any*/),
|
||||
(v6/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "versions(first:1)"
|
||||
}
|
||||
],
|
||||
"type": "Policy",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "751e6cc23218ca2da7b5bf44d3eef59c",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ShowPolicyViewQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query ShowPolicyViewQuery(\n $policyId: ID!\n) {\n node(id: $policyId) {\n __typename\n id\n ... on Policy {\n title\n description\n createdAt\n updatedAt\n currentPublishedVersion\n owner {\n id\n fullName\n primaryEmailAddress\n }\n ...SignaturesModal_policyVersions\n ...VersionHistoryModal_policyVersions\n latestVersion: versions(first: 1) {\n edges {\n node {\n id\n version\n status\n content\n changelog\n publishedAt\n publishedBy {\n fullName\n id\n }\n createdAt\n updatedAt\n }\n }\n }\n }\n }\n}\n\nfragment SignaturesModal_policyVersions on Policy {\n title\n policyVersions: versions(first: 10) {\n edges {\n node {\n id\n version\n status\n publishedAt\n updatedAt\n publishedBy {\n fullName\n id\n }\n signatures(first: 100) {\n edges {\n node {\n id\n state\n signedAt\n requestedAt\n signedBy {\n fullName\n id\n }\n requestedBy {\n fullName\n id\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n }\n}\n\nfragment VersionHistoryModal_policyVersions on Policy {\n title\n owner {\n fullName\n id\n }\n versionHistory: versions(first: 20) {\n edges {\n node {\n id\n version\n status\n content\n changelog\n publishedAt\n updatedAt\n publishedBy {\n fullName\n id\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "58adb8690071648aecb252b2f807ea7d";
|
||||
|
||||
export default node;
|
||||
206
apps/console/src/pages/organizations/policies/__generated__/SignaturesModalOrganizationQuery.graphql.ts
generated
Normal file
206
apps/console/src/pages/organizations/policies/__generated__/SignaturesModalOrganizationQuery.graphql.ts
generated
Normal file
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
* @generated SignedSource<<070580dfc3d76a6f1ca8b0227dc8c1c6>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type PeopleKind = "CONTRACTOR" | "EMPLOYEE" | "SERVICE_ACCOUNT";
|
||||
export type SignaturesModalOrganizationQuery$variables = {
|
||||
organizationId: string;
|
||||
};
|
||||
export type SignaturesModalOrganizationQuery$data = {
|
||||
readonly organization: {
|
||||
readonly id?: string;
|
||||
readonly peoples?: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
readonly kind: PeopleKind;
|
||||
readonly primaryEmailAddress: string;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
};
|
||||
};
|
||||
export type SignaturesModalOrganizationQuery = {
|
||||
response: SignaturesModalOrganizationQuery$data;
|
||||
variables: SignaturesModalOrganizationQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "organizationId"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "organizationId"
|
||||
}
|
||||
],
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
},
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "orderBy",
|
||||
"value": {
|
||||
"direction": "ASC",
|
||||
"field": "FULL_NAME"
|
||||
}
|
||||
}
|
||||
],
|
||||
"concreteType": "PeopleConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "peoples",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PeopleEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "primaryEmailAddress",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "kind",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "peoples(first:100,orderBy:{\"direction\":\"ASC\",\"field\":\"FULL_NAME\"})"
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "SignaturesModalOrganizationQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "SignaturesModalOrganizationQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "a2551c513c1c12a46c0da5328086475a",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "SignaturesModalOrganizationQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query SignaturesModalOrganizationQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n peoples(first: 100, orderBy: {direction: ASC, field: FULL_NAME}) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n kind\n }\n }\n }\n }\n id\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "39bec552bdf8762487cec72839225b84";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,264 @@
|
||||
/**
|
||||
* @generated SignedSource<<fda822cf46d8b9a49852a53edd8e363d>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type PolicyVersionSignatureState = "REQUESTED" | "SIGNED";
|
||||
export type RequestSignatureInput = {
|
||||
policyVersionId: string;
|
||||
signatoryId: string;
|
||||
};
|
||||
export type SignaturesModalRequestSignatureMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: RequestSignatureInput;
|
||||
};
|
||||
export type SignaturesModalRequestSignatureMutation$data = {
|
||||
readonly requestSignature: {
|
||||
readonly policyVersionSignatureEdge: {
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly requestedAt: string;
|
||||
readonly requestedBy: {
|
||||
readonly fullName: string;
|
||||
};
|
||||
readonly signedAt: string | null | undefined;
|
||||
readonly signedBy: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
};
|
||||
readonly state: PolicyVersionSignatureState;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export type SignaturesModalRequestSignatureMutation = {
|
||||
response: SignaturesModalRequestSignatureMutation$data;
|
||||
variables: SignaturesModalRequestSignatureMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
},
|
||||
v5 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "signedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v6 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "requestedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v7 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
},
|
||||
v8 = [
|
||||
(v7/*: any*/),
|
||||
(v3/*: any*/)
|
||||
],
|
||||
v9 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "signedBy",
|
||||
"plural": false,
|
||||
"selections": (v8/*: any*/),
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "SignaturesModalRequestSignatureMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "RequestSignaturePayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "requestSignature",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionSignatureEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "policyVersionSignatureEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionSignature",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/),
|
||||
(v6/*: any*/),
|
||||
(v9/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "requestedBy",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "SignaturesModalRequestSignatureMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "RequestSignaturePayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "requestSignature",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionSignatureEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "policyVersionSignatureEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionSignature",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/),
|
||||
(v6/*: any*/),
|
||||
(v9/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "requestedBy",
|
||||
"plural": false,
|
||||
"selections": (v8/*: any*/),
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "prependEdge",
|
||||
"key": "",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "policyVersionSignatureEdge",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "4c6a5b6ed95c76c157f8627409a4481b",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "SignaturesModalRequestSignatureMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation SignaturesModalRequestSignatureMutation(\n $input: RequestSignatureInput!\n) {\n requestSignature(input: $input) {\n policyVersionSignatureEdge {\n node {\n id\n state\n signedAt\n requestedAt\n signedBy {\n fullName\n id\n }\n requestedBy {\n fullName\n id\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "2b17fe4feae2614a6697c63a7334a1cf";
|
||||
|
||||
export default node;
|
||||
298
apps/console/src/pages/organizations/policies/__generated__/SignaturesModal_policyVersions.graphql.ts
generated
Normal file
298
apps/console/src/pages/organizations/policies/__generated__/SignaturesModal_policyVersions.graphql.ts
generated
Normal file
@@ -0,0 +1,298 @@
|
||||
/**
|
||||
* @generated SignedSource<<ee81b03b50b0bc65932295b898b856d4>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
export type PolicyStatus = "DRAFT" | "PUBLISHED";
|
||||
export type PolicyVersionSignatureState = "REQUESTED" | "SIGNED";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type SignaturesModal_policyVersions$data = {
|
||||
readonly policyVersions: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly publishedAt: string | null | undefined;
|
||||
readonly publishedBy: {
|
||||
readonly fullName: string;
|
||||
} | null | undefined;
|
||||
readonly signatures: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly requestedAt: string;
|
||||
readonly requestedBy: {
|
||||
readonly fullName: string;
|
||||
};
|
||||
readonly signedAt: string | null | undefined;
|
||||
readonly signedBy: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
};
|
||||
readonly state: PolicyVersionSignatureState;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly status: PolicyStatus;
|
||||
readonly updatedAt: string;
|
||||
readonly version: number;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly title: string;
|
||||
readonly " $fragmentType": "SignaturesModal_policyVersions";
|
||||
};
|
||||
export type SignaturesModal_policyVersions$key = {
|
||||
readonly " $data"?: SignaturesModal_policyVersions$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"SignaturesModal_policyVersions">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
},
|
||||
v2 = [
|
||||
(v1/*: any*/)
|
||||
];
|
||||
return {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": null,
|
||||
"cursor": null,
|
||||
"direction": "forward",
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "SignaturesModal_policyVersions",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "policyVersions",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 10
|
||||
}
|
||||
],
|
||||
"concreteType": "PolicyVersionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "versions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "version",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "publishedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "publishedBy",
|
||||
"plural": false,
|
||||
"selections": (v2/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "signatures",
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionSignatureConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__SignaturesModal_policyVersions_signatures_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionSignatureEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionSignature",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "signedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "requestedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "signedBy",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "requestedBy",
|
||||
"plural": false,
|
||||
"selections": (v2/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "versions(first:10)"
|
||||
}
|
||||
],
|
||||
"type": "Policy",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "da9bf0fc12618afb0f9ec8f2337b9b9b";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
* @generated SignedSource<<21626cad90fcb579071d73bc47e3fb7a>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
export type PolicyStatus = "DRAFT" | "PUBLISHED";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type VersionHistoryModal_policyVersions$data = {
|
||||
readonly owner: {
|
||||
readonly fullName: string;
|
||||
};
|
||||
readonly title: string;
|
||||
readonly versionHistory: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly changelog: string;
|
||||
readonly content: string;
|
||||
readonly id: string;
|
||||
readonly publishedAt: string | null | undefined;
|
||||
readonly publishedBy: {
|
||||
readonly fullName: string;
|
||||
} | null | undefined;
|
||||
readonly status: PolicyStatus;
|
||||
readonly updatedAt: string;
|
||||
readonly version: number;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly " $fragmentType": "VersionHistoryModal_policyVersions";
|
||||
};
|
||||
export type VersionHistoryModal_policyVersions$key = {
|
||||
readonly " $data"?: VersionHistoryModal_policyVersions$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"VersionHistoryModal_policyVersions">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "VersionHistoryModal_policyVersions",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "owner",
|
||||
"plural": false,
|
||||
"selections": (v0/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "versionHistory",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 20
|
||||
}
|
||||
],
|
||||
"concreteType": "PolicyVersionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "versions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PolicyVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "version",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "content",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "changelog",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "publishedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "publishedBy",
|
||||
"plural": false,
|
||||
"selections": (v0/*: any*/),
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "versions(first:20)"
|
||||
}
|
||||
],
|
||||
"type": "Policy",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "09cd9142880cfbb239ce866ea81afe48";
|
||||
|
||||
export default node;
|
||||
@@ -101,8 +101,7 @@ const showRiskViewQuery = graphql`
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
status
|
||||
title
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
@@ -155,8 +154,7 @@ const organizationPoliciesQuery = graphql`
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
status
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -530,7 +528,7 @@ function ShowRiskViewContent({
|
||||
return policies.filter((policy) => {
|
||||
return (
|
||||
!policySearchQuery ||
|
||||
policy.name.toLowerCase().includes(policySearchQuery.toLowerCase())
|
||||
policy.title.toLowerCase().includes(policySearchQuery.toLowerCase())
|
||||
);
|
||||
});
|
||||
}, [getPolicies, policySearchQuery]);
|
||||
@@ -731,7 +729,7 @@ function ShowRiskViewContent({
|
||||
|
||||
toast({
|
||||
title: "Success",
|
||||
description: `Linked policy "${policy.name}" to this risk.`,
|
||||
description: `Linked policy "${policy.title}" to this risk.`,
|
||||
});
|
||||
},
|
||||
onError: (error) => {
|
||||
@@ -803,7 +801,7 @@ function ShowRiskViewContent({
|
||||
|
||||
toast({
|
||||
title: "Success",
|
||||
description: `Unlinked policy "${policy.name}" from this risk.`,
|
||||
description: `Unlinked policy "${policy.title}" from this risk.`,
|
||||
});
|
||||
},
|
||||
onError: (error) => {
|
||||
@@ -1090,15 +1088,26 @@ function ShowRiskViewContent({
|
||||
<TabsContent value="policies" className="space-y-4">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h2 className="text-xl font-semibold">Risk Policies</h2>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setIsPolicyDialogOpen(true);
|
||||
loadPoliciesData();
|
||||
}}
|
||||
>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Link Policy
|
||||
</Button>
|
||||
<div className="flex space-x-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
asChild
|
||||
>
|
||||
<Link to={`/organizations/${organizationId}/policies/new?riskId=${risk.id}`}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
New Version
|
||||
</Link>
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setIsPolicyDialogOpen(true);
|
||||
loadPoliciesData();
|
||||
}}
|
||||
>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Link Policy
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{policies.length > 0 ? (
|
||||
<div className="rounded-md border">
|
||||
@@ -1117,7 +1126,7 @@ function ShowRiskViewContent({
|
||||
to={`/organizations/${organizationId}/policies/${policy.id}`}
|
||||
className="font-medium text-blue-600 hover:underline"
|
||||
>
|
||||
{policy.name}
|
||||
{policy.title}
|
||||
</Link>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
@@ -1350,7 +1359,7 @@ function ShowRiskViewContent({
|
||||
>
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center gap-2">
|
||||
<h3 className="font-medium">{policy.name}</h3>
|
||||
<h3 className="font-medium">{policy.title}</h3>
|
||||
</div>
|
||||
{isLinked ? (
|
||||
<Button
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<86be887d4ec59050fd69900fd80863a2>>
|
||||
* @generated SignedSource<<0335bb26d78f02170c02c7c2279a6bfd>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -9,7 +9,6 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type PolicyStatus = "ACTIVE" | "DRAFT";
|
||||
export type ShowRiskViewOrganizationPoliciesQuery$variables = {
|
||||
organizationId: string;
|
||||
};
|
||||
@@ -20,8 +19,7 @@ export type ShowRiskViewOrganizationPoliciesQuery$data = {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly status: PolicyStatus;
|
||||
readonly title: string;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
@@ -83,14 +81,7 @@ v4 = [
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
(v3/*: any*/)
|
||||
@@ -228,7 +219,7 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "a229f1f805e79f8de378305e021d7fea",
|
||||
"cacheID": "a92a6b2390e95e67b42fd18cc1030a9a",
|
||||
"id": null,
|
||||
"metadata": {
|
||||
"connection": [
|
||||
@@ -245,11 +236,11 @@ return {
|
||||
},
|
||||
"name": "ShowRiskViewOrganizationPoliciesQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query ShowRiskViewOrganizationPoliciesQuery(\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 status\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
|
||||
"text": "query ShowRiskViewOrganizationPoliciesQuery(\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 __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "26cbf19cd716aee7413931357b9c5354";
|
||||
(node as any).hash = "b47adf6c3a247367a6b23dd161df2702";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<e318c9e0fe4355eb4923acb54da59ebb>>
|
||||
* @generated SignedSource<<5d1745636bcff5f05d946bcd613463e5>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type MesureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
|
||||
export type PolicyStatus = "ACTIVE" | "DRAFT";
|
||||
export type RiskTreatment = "ACCEPTED" | "AVOIDED" | "MITIGATED" | "TRANSFERRED";
|
||||
export type ShowRiskViewQuery$variables = {
|
||||
riskId: string;
|
||||
@@ -56,8 +55,7 @@ export type ShowRiskViewQuery$data = {
|
||||
readonly node: {
|
||||
readonly createdAt: string;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly status: PolicyStatus;
|
||||
readonly title: string;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
@@ -285,12 +283,11 @@ v18 = [
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
(v12/*: any*/),
|
||||
@@ -517,7 +514,7 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "05f0fe48c916ecda883f606eed0c9244",
|
||||
"cacheID": "a88eba4c398c292d41deaddd1d77bb3b",
|
||||
"id": null,
|
||||
"metadata": {
|
||||
"connection": [
|
||||
@@ -552,11 +549,11 @@ return {
|
||||
},
|
||||
"name": "ShowRiskViewQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query ShowRiskViewQuery(\n $riskId: ID!\n) {\n node(id: $riskId) {\n __typename\n id\n ... on Risk {\n name\n description\n treatment\n owner {\n id\n fullName\n }\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n note\n createdAt\n updatedAt\n mesures(first: 100) {\n edges {\n node {\n id\n name\n description\n category\n createdAt\n state\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n policies(first: 100) {\n edges {\n node {\n id\n name\n status\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n controls(first: 100) {\n edges {\n node {\n id\n referenceId\n name\n description\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
|
||||
"text": "query ShowRiskViewQuery(\n $riskId: ID!\n) {\n node(id: $riskId) {\n __typename\n id\n ... on Risk {\n name\n description\n treatment\n owner {\n id\n fullName\n }\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n note\n createdAt\n updatedAt\n mesures(first: 100) {\n edges {\n node {\n id\n name\n description\n category\n createdAt\n state\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n policies(first: 100) {\n edges {\n node {\n id\n title\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n controls(first: 100) {\n edges {\n node {\n id\n referenceId\n name\n description\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "25e67618b61999a955716e937a53a470";
|
||||
(node as any).hash = "96158658ecb7c406fc969e086917c03e";
|
||||
|
||||
export default node;
|
||||
|
||||
Reference in New Issue
Block a user