@@ -77,7 +77,7 @@ function CreatePolicyForm({
|
||||
: "empty"
|
||||
);
|
||||
|
||||
const [commitMutation] =
|
||||
const [createPolicy] =
|
||||
useMutation<NewPolicyViewMutation>(CreatePolicyMutation);
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
@@ -109,13 +109,13 @@ function CreatePolicyForm({
|
||||
ownerId,
|
||||
};
|
||||
|
||||
commitMutation({
|
||||
createPolicy({
|
||||
variables: {
|
||||
input,
|
||||
connections: [
|
||||
ConnectionHandler.getConnectionID(
|
||||
organizationId!,
|
||||
"PolicyListPage_policies"
|
||||
"PolicyListView_policies"
|
||||
),
|
||||
],
|
||||
},
|
||||
|
||||
@@ -4,35 +4,28 @@ import {
|
||||
PreloadedQuery,
|
||||
usePreloadedQuery,
|
||||
useQueryLoader,
|
||||
useMutation,
|
||||
ConnectionHandler,
|
||||
} from "react-relay";
|
||||
import { Card, CardContent, CardFooter } from "@/components/ui/card";
|
||||
import { Link, useParams } from "react-router";
|
||||
import { Link, useParams, useNavigate } from "react-router";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import {
|
||||
Plus,
|
||||
FileText,
|
||||
Search,
|
||||
Clock,
|
||||
Filter,
|
||||
ArrowUpDown,
|
||||
ChevronDown,
|
||||
MoreHorizontal,
|
||||
Trash2,
|
||||
Eye,
|
||||
} from "lucide-react";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { format } from "date-fns";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import type { PolicyListViewQuery as PolicyListViewQueryType } from "./__generated__/PolicyListViewQuery.graphql";
|
||||
import type { PolicyListViewDeleteMutation } from "./__generated__/PolicyListViewDeleteMutation.graphql";
|
||||
import { PageTemplate } from "@/components/PageTemplate";
|
||||
import { PolicyListViewSkeleton } from "./PolicyListPage";
|
||||
|
||||
@@ -40,7 +33,7 @@ const PolicyListViewQuery = graphql`
|
||||
query PolicyListViewQuery($organizationId: ID!) {
|
||||
organization: node(id: $organizationId) {
|
||||
... on Organization {
|
||||
policies(first: 25) @connection(key: "PolicyListView_policies") {
|
||||
policies(first: 100) @connection(key: "PolicyListView_policies") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
@@ -57,105 +50,139 @@ const PolicyListViewQuery = graphql`
|
||||
}
|
||||
`;
|
||||
|
||||
function PolicyCard({
|
||||
title,
|
||||
content,
|
||||
status,
|
||||
updatedAt,
|
||||
}: {
|
||||
title: string;
|
||||
content?: string;
|
||||
status?: string;
|
||||
updatedAt: string;
|
||||
}) {
|
||||
const formattedUpdatedAt = new Date(updatedAt);
|
||||
const DeletePolicyMutation = graphql`
|
||||
mutation PolicyListViewDeleteMutation(
|
||||
$input: DeletePolicyInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deletePolicy(input: $input) {
|
||||
deletedPolicyId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
// Extract a short description from the content and strip HTML tags
|
||||
const stripHtmlTags = (html: string) => {
|
||||
// First remove HTML tags
|
||||
const withoutTags = html.replace(/<[^>]*>/g, "");
|
||||
// Then decode HTML entities
|
||||
const decoded = withoutTags
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, "'")
|
||||
.replace(/ /g, " ");
|
||||
// Remove markdown headers
|
||||
return decoded.replace(/#.*?\n/, "").trim();
|
||||
function PolicyTableRow({
|
||||
policy,
|
||||
organizationId,
|
||||
}: {
|
||||
policy: {
|
||||
id: string;
|
||||
name: string;
|
||||
content?: string;
|
||||
status?: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
organizationId: string;
|
||||
}) {
|
||||
const navigate = useNavigate();
|
||||
const { toast } = useToast();
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
const [commitDeleteMutation] = useMutation<PolicyListViewDeleteMutation>(DeletePolicyMutation);
|
||||
|
||||
const handleDelete = (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({
|
||||
variables: {
|
||||
input: {
|
||||
policyId: policy.id,
|
||||
},
|
||||
connections: [
|
||||
ConnectionHandler.getConnectionID(
|
||||
organizationId,
|
||||
"PolicyListView_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.",
|
||||
});
|
||||
},
|
||||
onError: (error) => {
|
||||
setIsDeleting(false);
|
||||
console.error("Error deleting policy:", error);
|
||||
toast({
|
||||
title: "Error",
|
||||
description: "Failed to delete policy. Please try again.",
|
||||
variant: "destructive",
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const description = content
|
||||
? stripHtmlTags(content).substring(0, 120) +
|
||||
(content.length > 120 ? "..." : "")
|
||||
: "No description available";
|
||||
const handleView = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
navigate(`/organizations/${organizationId}/policies/${policy.id}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className="relative overflow-hidden border transition-all hover:shadow-md h-full flex flex-col">
|
||||
<CardContent className="p-6 flex-grow">
|
||||
<div className="flex flex-col h-full">
|
||||
<div className="flex justify-between items-start mb-3">
|
||||
<h3 className="font-semibold text-xl">{title}</h3>
|
||||
{status && (
|
||||
<Badge
|
||||
variant={
|
||||
status === "ACTIVE"
|
||||
? "success"
|
||||
: status === "DRAFT"
|
||||
? "warning"
|
||||
: "secondary"
|
||||
}
|
||||
>
|
||||
{status === "ACTIVE"
|
||||
? "Security"
|
||||
: status === "DRAFT"
|
||||
? "Draft"
|
||||
: status}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<p className="text-tertiary text-sm line-clamp-3 mb-4">
|
||||
{description}
|
||||
</p>
|
||||
|
||||
<div className="flex items-center gap-2 text-sm text-tertiary mt-auto">
|
||||
<Clock className="h-4 w-4" />
|
||||
<span>
|
||||
Last updated: {format(formattedUpdatedAt, "yyyy-MM-dd")}
|
||||
</span>
|
||||
</div>
|
||||
<tr
|
||||
className="border-t border-[#ECEFEC] hover:bg-[rgba(5,77,5,0.01)] 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>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter className="p-0 border-t">
|
||||
<div className="w-full grid grid-cols-2">
|
||||
<Button variant="ghost" className="rounded-none h-12 border-r">
|
||||
<FileText className="h-5 w-5 mr-2" />
|
||||
View Policy
|
||||
</Button>
|
||||
<Button variant="ghost" className="rounded-none h-12">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="mr-2"
|
||||
</td>
|
||||
<td className="py-4 px-6">
|
||||
<span className="text-sm text-[#141E12]">Mon, 8 Mar. 2025</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"
|
||||
>
|
||||
Draft
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="py-4 px-6 text-right">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
||||
<polyline points="7 10 12 15 17 10" />
|
||||
<line x1="12" y1="15" x2="12" y2="3" />
|
||||
</svg>
|
||||
Download
|
||||
</Button>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={handleView}>
|
||||
<Eye className="mr-2 h-4 w-4" />
|
||||
View
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={handleDelete}
|
||||
className="text-red-600 focus:text-red-600 focus:bg-red-50"
|
||||
disabled={isDeleting}
|
||||
>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
{isDeleting ? "Deleting..." : "Delete"}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -172,177 +199,73 @@ function PolicyListViewContent({
|
||||
const policies =
|
||||
data.organization.policies?.edges.map((edge) => edge?.node) ?? [];
|
||||
|
||||
// State for search, filtering and sorting
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [statusFilter, setStatusFilter] = useState("ALL");
|
||||
const [sortBy, setSortBy] = useState("name-asc");
|
||||
|
||||
// Filter and sort policies
|
||||
const filteredPolicies = policies
|
||||
.filter((policy) => {
|
||||
// Filter by search query
|
||||
const matchesSearch = policy.name
|
||||
.toLowerCase()
|
||||
.includes(searchQuery.toLowerCase());
|
||||
|
||||
// Filter by status
|
||||
const matchesStatus =
|
||||
statusFilter === "ALL" || policy.status === statusFilter;
|
||||
|
||||
return matchesSearch && matchesStatus;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
// Sort policies
|
||||
switch (sortBy) {
|
||||
case "name-asc":
|
||||
return a.name.localeCompare(b.name);
|
||||
case "name-desc":
|
||||
return b.name.localeCompare(a.name);
|
||||
case "updated-desc":
|
||||
return (
|
||||
new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
||||
);
|
||||
case "updated-asc":
|
||||
return (
|
||||
new Date(a.updatedAt).getTime() - new Date(b.updatedAt).getTime()
|
||||
);
|
||||
case "created-desc":
|
||||
return (
|
||||
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
|
||||
);
|
||||
case "created-asc":
|
||||
return (
|
||||
new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
|
||||
);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<PageTemplate
|
||||
title="Policies"
|
||||
description="Manage your organization's policies"
|
||||
actions={
|
||||
<Button asChild>
|
||||
<Link to={`/organizations/${organizationId}/policies/new`}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Create Policy
|
||||
Create policy
|
||||
</Link>
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
{/* Search and filter mesures */}
|
||||
<div className="flex flex-col md:flex-row gap-4 mb-6">
|
||||
<div className="relative flex-1">
|
||||
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-tertiary" />
|
||||
<Input
|
||||
placeholder="Search policies..."
|
||||
className="pl-10"
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<Select value={statusFilter} onValueChange={setStatusFilter}>
|
||||
<SelectTrigger className="w-[180px]">
|
||||
<div className="flex items-center gap-2">
|
||||
<Filter className="h-4 w-4" />
|
||||
<SelectValue placeholder="Filter by status" />
|
||||
</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="ALL">All Statuses</SelectItem>
|
||||
<SelectItem value="ACTIVE">Active</SelectItem>
|
||||
<SelectItem value="DRAFT">Draft</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="secondary" className="flex items-center gap-2">
|
||||
<ArrowUpDown className="h-4 w-4" />
|
||||
Sort
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={() => setSortBy("name-asc")}>
|
||||
Name (A-Z)
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setSortBy("name-desc")}>
|
||||
Name (Z-A)
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setSortBy("updated-desc")}>
|
||||
Recently Updated
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setSortBy("updated-asc")}>
|
||||
Oldest Updated
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setSortBy("created-desc")}>
|
||||
Recently Created
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setSortBy("created-asc")}>
|
||||
Oldest Created
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Results summary */}
|
||||
<div className="mb-4 text-sm text-tertiary">
|
||||
Showing {filteredPolicies.length} of {policies.length} policies
|
||||
</div>
|
||||
|
||||
{/* Policy grid */}
|
||||
<div className="space-y-6">
|
||||
{filteredPolicies.length > 0 ? (
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{filteredPolicies.map((policy) => (
|
||||
<Link
|
||||
key={policy.id}
|
||||
to={`/organizations/${organizationId}/policies/${policy.id}`}
|
||||
className="group"
|
||||
>
|
||||
<PolicyCard
|
||||
title={policy.name}
|
||||
content={policy.content}
|
||||
status={policy.status}
|
||||
updatedAt={policy.updatedAt}
|
||||
{/* Policy table */}
|
||||
<div className="rounded-lg border border-[#ECEFEC] overflow-hidden bg-white">
|
||||
<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)]">
|
||||
<div className="flex items-center gap-1">
|
||||
Vendor
|
||||
<ChevronDown className="h-3 w-3 text-[#C3C8C2]" />
|
||||
</div>
|
||||
</th>
|
||||
<th className="py-3 px-6 text-xs font-medium text-[#818780] border-b border-[rgba(2,42,2,0.08)]">
|
||||
<div className="flex items-center gap-1">
|
||||
Last update
|
||||
<ChevronDown className="h-3 w-3 text-[#C3C8C2]" />
|
||||
</div>
|
||||
</th>
|
||||
<th className="py-3 px-6 text-xs font-medium text-[#818780] border-b border-[rgba(2,42,2,0.08)]">
|
||||
<div className="flex items-center gap-1">
|
||||
Status
|
||||
<ChevronDown className="h-3 w-3 text-[#C3C8C2]" />
|
||||
</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>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="bg-white">
|
||||
{policies.length > 0 ? (
|
||||
policies.map((policy) => (
|
||||
<PolicyTableRow
|
||||
key={policy.id}
|
||||
policy={policy}
|
||||
organizationId={organizationId!}
|
||||
/>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center py-12 border rounded-lg bg-subtle-bg/20">
|
||||
<FileText className="mx-auto h-8 w-8 text-tertiary mb-3" />
|
||||
<h3 className="text-lg font-medium">No policies found</h3>
|
||||
<p className="text-tertiary mb-4">
|
||||
{searchQuery || statusFilter !== "ALL"
|
||||
? "Try adjusting your search or filters"
|
||||
: "Create your first policy to get started"}
|
||||
</p>
|
||||
{searchQuery || statusFilter !== "ALL" ? (
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
setSearchQuery("");
|
||||
setStatusFilter("ALL");
|
||||
}}
|
||||
>
|
||||
Clear filters
|
||||
</Button>
|
||||
))
|
||||
) : (
|
||||
<Button asChild>
|
||||
<Link to={`/organizations/${organizationId}/policies/new`}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Create Policy
|
||||
</Link>
|
||||
</Button>
|
||||
<tr>
|
||||
<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]">
|
||||
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>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</PageTemplate>
|
||||
);
|
||||
|
||||
132
apps/console/src/pages/organizations/policies/__generated__/PolicyListViewDeleteMutation.graphql.ts
generated
Normal file
132
apps/console/src/pages/organizations/policies/__generated__/PolicyListViewDeleteMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* @generated SignedSource<<c71120e2c59cabbcb2f9e55dacd2be6c>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type DeletePolicyInput = {
|
||||
policyId: string;
|
||||
};
|
||||
export type PolicyListViewDeleteMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: DeletePolicyInput;
|
||||
};
|
||||
export type PolicyListViewDeleteMutation$data = {
|
||||
readonly deletePolicy: {
|
||||
readonly deletedPolicyId: string;
|
||||
};
|
||||
};
|
||||
export type PolicyListViewDeleteMutation = {
|
||||
response: PolicyListViewDeleteMutation$data;
|
||||
variables: PolicyListViewDeleteMutation$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": "PolicyListViewDeleteMutation",
|
||||
"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": "PolicyListViewDeleteMutation",
|
||||
"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": "3a182fce4a0616599bea274ddf7b95a1",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "PolicyListViewDeleteMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation PolicyListViewDeleteMutation(\n $input: DeletePolicyInput!\n) {\n deletePolicy(input: $input) {\n deletedPolicyId\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d2a47c3563b6dcbbb88e78b954345768";
|
||||
|
||||
export default node;
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<605e2b8b9bc6fdd85a121a1f1904cc00>>
|
||||
* @generated SignedSource<<391e3817107bb96f50aad61d20cad0a8>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -160,7 +160,7 @@ v5 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 25
|
||||
"value": 100
|
||||
}
|
||||
];
|
||||
return {
|
||||
@@ -228,7 +228,7 @@ return {
|
||||
"name": "policies",
|
||||
"plural": false,
|
||||
"selections": (v4/*: any*/),
|
||||
"storageKey": "policies(first:25)"
|
||||
"storageKey": "policies(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
@@ -250,7 +250,7 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "361b81169a803b656d673b7b8d1c5583",
|
||||
"cacheID": "6434c8135f68ac64eb2f06983ddc3595",
|
||||
"id": null,
|
||||
"metadata": {
|
||||
"connection": [
|
||||
@@ -267,11 +267,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: 25) {\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 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"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "c0ed3d1334a535f752062c6479ed3a7e";
|
||||
(node as any).hash = "5567339ad9b2be90b94edc8b1a16fe1e";
|
||||
|
||||
export default node;
|
||||
|
||||
Reference in New Issue
Block a user