@@ -1,10 +1,12 @@
|
|||||||
import { Suspense, useEffect, useState } from "react";
|
import { Suspense, useEffect, useState, useCallback } from "react";
|
||||||
import { useParams, Link } from "react-router";
|
import { useParams, Link, useNavigate } from "react-router";
|
||||||
import {
|
import {
|
||||||
graphql,
|
graphql,
|
||||||
PreloadedQuery,
|
PreloadedQuery,
|
||||||
usePreloadedQuery,
|
usePreloadedQuery,
|
||||||
useQueryLoader,
|
useQueryLoader,
|
||||||
|
useMutation,
|
||||||
|
ConnectionHandler,
|
||||||
} from "react-relay";
|
} from "react-relay";
|
||||||
import { Edit, Download, Shield, User, FileText, Calendar } from "lucide-react";
|
import { Edit, Download, Shield, User, FileText, Calendar } from "lucide-react";
|
||||||
import { Card, CardContent } from "@/components/ui/card";
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
@@ -12,8 +14,10 @@ import { Button } from "@/components/ui/button";
|
|||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import type { PolicyOverviewPageQuery as PolicyOverviewPageQueryType } from "./__generated__/PolicyOverviewPageQuery.graphql";
|
import type { PolicyOverviewPageQuery as PolicyOverviewPageQueryType } from "./__generated__/PolicyOverviewPageQuery.graphql";
|
||||||
|
import type { PolicyOverviewPageDeleteMutation } from "./__generated__/PolicyOverviewPageDeleteMutation.graphql";
|
||||||
import { Helmet } from "react-helmet-async";
|
import { Helmet } from "react-helmet-async";
|
||||||
import "../styles/policy-content.css";
|
import "../styles/policy-content.css";
|
||||||
|
import { useToast } from "@/hooks/use-toast";
|
||||||
|
|
||||||
const PolicyOverviewPageQuery = graphql`
|
const PolicyOverviewPageQuery = graphql`
|
||||||
query PolicyOverviewPageQuery($policyId: ID!) {
|
query PolicyOverviewPageQuery($policyId: ID!) {
|
||||||
@@ -36,6 +40,17 @@ const PolicyOverviewPageQuery = graphql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const DeletePolicyMutation = graphql`
|
||||||
|
mutation PolicyOverviewPageDeleteMutation(
|
||||||
|
$input: DeletePolicyInput!
|
||||||
|
$connections: [ID!]!
|
||||||
|
) {
|
||||||
|
deletePolicy(input: $input) {
|
||||||
|
deletedPolicyId @deleteEdge(connections: $connections)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
function PolicyOverviewPageContent({
|
function PolicyOverviewPageContent({
|
||||||
queryRef,
|
queryRef,
|
||||||
}: {
|
}: {
|
||||||
@@ -44,7 +59,65 @@ function PolicyOverviewPageContent({
|
|||||||
const data = usePreloadedQuery(PolicyOverviewPageQuery, queryRef);
|
const data = usePreloadedQuery(PolicyOverviewPageQuery, queryRef);
|
||||||
const policy = data.node;
|
const policy = data.node;
|
||||||
const { organizationId } = useParams();
|
const { organizationId } = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
const [activeTab, setActiveTab] = useState("content");
|
const [activeTab, setActiveTab] = useState("content");
|
||||||
|
const [isDeleting, setIsDeleting] = useState(false);
|
||||||
|
const { toast } = useToast();
|
||||||
|
|
||||||
|
const [commitDeleteMutation] =
|
||||||
|
useMutation<PolicyOverviewPageDeleteMutation>(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
|
// Extract a short description from the content
|
||||||
const getDescription = (content: string | undefined) => {
|
const getDescription = (content: string | undefined) => {
|
||||||
@@ -312,7 +385,12 @@ function PolicyOverviewPageContent({
|
|||||||
Permanently delete this policy and all of its data. This
|
Permanently delete this policy and all of its data. This
|
||||||
action cannot be undone.
|
action cannot be undone.
|
||||||
</p>
|
</p>
|
||||||
<Button variant="destructive" className="w-full">
|
<Button
|
||||||
|
variant="destructive"
|
||||||
|
className="w-full"
|
||||||
|
onClick={handleDeletePolicy}
|
||||||
|
disabled={isDeleting}
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="16"
|
width="16"
|
||||||
@@ -329,7 +407,7 @@ function PolicyOverviewPageContent({
|
|||||||
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></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>
|
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
|
||||||
</svg>
|
</svg>
|
||||||
Delete Policy
|
{isDeleting ? "Deleting..." : "Delete Policy"}
|
||||||
</Button>
|
</Button>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
132
apps/console/src/pages/__generated__/PolicyOverviewPageDeleteMutation.graphql.ts
generated
Normal file
132
apps/console/src/pages/__generated__/PolicyOverviewPageDeleteMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<3f819f2e923960fed57f95a4535782be>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
|
export type DeletePolicyInput = {
|
||||||
|
policyId: string;
|
||||||
|
};
|
||||||
|
export type PolicyOverviewPageDeleteMutation$variables = {
|
||||||
|
connections: ReadonlyArray<string>;
|
||||||
|
input: DeletePolicyInput;
|
||||||
|
};
|
||||||
|
export type PolicyOverviewPageDeleteMutation$data = {
|
||||||
|
readonly deletePolicy: {
|
||||||
|
readonly deletedPolicyId: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export type PolicyOverviewPageDeleteMutation = {
|
||||||
|
response: PolicyOverviewPageDeleteMutation$data;
|
||||||
|
variables: PolicyOverviewPageDeleteMutation$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": "PolicyOverviewPageDeleteMutation",
|
||||||
|
"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": "PolicyOverviewPageDeleteMutation",
|
||||||
|
"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": "0a54108fe8b1d0e8c306ede62182d0b4",
|
||||||
|
"id": null,
|
||||||
|
"metadata": {},
|
||||||
|
"name": "PolicyOverviewPageDeleteMutation",
|
||||||
|
"operationKind": "mutation",
|
||||||
|
"text": "mutation PolicyOverviewPageDeleteMutation(\n $input: DeletePolicyInput!\n) {\n deletePolicy(input: $input) {\n deletedPolicyId\n }\n}\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
(node as any).hash = "2ca6b448cda30ef9d66197344469c15b";
|
||||||
|
|
||||||
|
export default node;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<67ee63bc3751efdd9ecdf2ad9ab5e197>>
|
* @generated SignedSource<<9f20d32c64386c207a4b2374a340b05a>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -16,7 +16,7 @@ export type PolicyOverviewPageQuery$variables = {
|
|||||||
export type PolicyOverviewPageQuery$data = {
|
export type PolicyOverviewPageQuery$data = {
|
||||||
readonly node: {
|
readonly node: {
|
||||||
readonly content?: string;
|
readonly content?: string;
|
||||||
readonly createdAt?: string;
|
readonly createdAt?: any;
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly name?: string;
|
readonly name?: string;
|
||||||
readonly owner?: {
|
readonly owner?: {
|
||||||
@@ -24,9 +24,9 @@ export type PolicyOverviewPageQuery$data = {
|
|||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly primaryEmailAddress: string;
|
readonly primaryEmailAddress: string;
|
||||||
};
|
};
|
||||||
readonly reviewDate?: string | null | undefined;
|
readonly reviewDate?: any | null | undefined;
|
||||||
readonly status?: PolicyStatus;
|
readonly status?: PolicyStatus;
|
||||||
readonly updatedAt?: string;
|
readonly updatedAt?: any;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
export type PolicyOverviewPageQuery = {
|
export type PolicyOverviewPageQuery = {
|
||||||
|
|||||||
Reference in New Issue
Block a user