First step of mitigation migration

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-03-27 23:34:35 +01:00
parent 449bd620da
commit 7321862ba9
62 changed files with 4025 additions and 2141 deletions

View File

@@ -1,6 +1,12 @@
"use client";
import { ChevronRight, type LucideIcon } from "lucide-react";
import {
ChevronRight,
ClipboardList,
ListCheck,
NotebookTabs,
type LucideIcon,
} from "lucide-react";
import { Link, useLocation, useParams } from "react-router";
import {
@@ -138,8 +144,14 @@ export function NavMain() {
}
function getNavItems(organizationId?: string): NavItem[] {
// Always return the same structure, but with or without URLs depending on whether an organization is selected
return [
{
title: "Mitigations",
icon: ClipboardList,
url: organizationId
? `/organizations/${organizationId}/mitigations`
: undefined,
},
{
title: "Frameworks",
url: organizationId

View File

@@ -37,14 +37,6 @@ const FrameworkListViewQuery = graphql`
id
name
description
mitigations(first: 100) {
edges {
node {
id
state
}
}
}
createdAt
updatedAt
}
@@ -66,14 +58,6 @@ const FrameworkListViewImportFrameworkMutation = graphql`
id
name
description
mitigations(first: 100) {
edges {
node {
id
state
}
}
}
createdAt
updatedAt
}
@@ -86,14 +70,10 @@ function FrameworkCard({
title,
description,
icon,
status,
progress,
}: {
title: string;
description: string;
icon: React.ReactNode;
status?: string;
progress?: string;
}) {
return (
<Card className="relative overflow-hidden border bg-card p-6">
@@ -111,13 +91,6 @@ function FrameworkCard({
</div>
<p className="text-sm text-muted-foreground">{description}</p>
</div>
{progress && (
<div className="flex items-center gap-2 text-sm">
<span className="size-2 rounded-full bg-yellow-400" />
{progress}
</div>
)}
</div>
</Card>
);
@@ -240,11 +213,6 @@ function FrameworkListViewContent({
<div className="space-y-6">
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-2">
{frameworks.map((framework) => {
const validatedControls = framework.mitigations.edges.filter(
(edge) => edge?.node?.state === "IMPLEMENTED"
).length;
const totalControls = framework.mitigations.edges.length;
return (
<Link
key={framework.id}
@@ -260,16 +228,6 @@ function FrameworkListViewContent({
</span>
</div>
}
status={
validatedControls === totalControls
? "Compliant"
: undefined
}
progress={
validatedControls === totalControls
? "All mitigations validated"
: `${validatedControls}/${totalControls} Controls validated`
}
/>
</Link>
);

View File

@@ -1,24 +1,27 @@
import { Suspense, useEffect, useState } from "react";
import { Suspense, useEffect, useState, useCallback } from "react";
import { useParams, useNavigate, Link } from "react-router";
import {
graphql,
PreloadedQuery,
usePreloadedQuery,
useQueryLoader,
useMutation,
ConnectionHandler,
} from "react-relay";
import {
AlertCircle,
CheckCircle2,
ChevronDown,
ChevronRight,
Clock,
Plus,
X,
} from "lucide-react";
import { Plus } from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { useToast } from "@/hooks/use-toast";
import type { FrameworkViewQuery as FrameworkViewQueryType } from "./__generated__/FrameworkViewQuery.graphql";
import type { FrameworkViewDeleteMutation } from "./__generated__/FrameworkViewDeleteMutation.graphql";
import { PageTemplate } from "@/components/PageTemplate";
import { FrameworkViewSkeleton } from "./FrameworkPage";
@@ -29,15 +32,14 @@ const FrameworkViewQuery = graphql`
... on Framework {
name
description
mitigations(first: 100) @connection(key: "FrameworkView_mitigations") {
controls(first: 100, orderBy: { field: CREATED_AT, direction: ASC })
@connection(key: "FrameworkView_controls") {
edges {
node {
id
referenceId
name
description
state
category
importance
}
}
}
@@ -46,25 +48,16 @@ const FrameworkViewQuery = graphql`
}
`;
interface Mitigation {
id?: string;
name?: string;
description?: string;
state?: string;
category?: string;
importance?: string;
status?: string;
}
interface Category {
id: string;
name: string;
description: string;
progress: number;
mitigations: Mitigation[];
doneCount: number;
totalCount: number;
}
const DeleteFrameworkMutation = graphql`
mutation FrameworkViewDeleteMutation(
$input: DeleteFrameworkInput!
$connections: [ID!]!
) {
deleteFramework(input: $input) {
deletedFrameworkId @deleteEdge(connections: $connections)
}
}
`;
function FrameworkViewContent({
queryRef,
@@ -73,158 +66,73 @@ function FrameworkViewContent({
}) {
const data = usePreloadedQuery(FrameworkViewQuery, queryRef);
const framework = data.node;
const mitigations =
framework.mitigations?.edges.map((edge) => edge?.node) ?? [];
const navigate = useNavigate();
const { organizationId } = useParams();
const { toast } = useToast();
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
const [isDeleting, setIsDeleting] = useState(false);
// Monitor URL hash for changes and update state accordingly
const [hashValue, setHashValue] = useState(window.location.hash);
// Extract controls from the GraphQL response
const controls = framework?.controls?.edges?.map((edge) => edge.node) || [];
// Get the active category from the hash (used when returning from a mitigation)
const hashCategory = hashValue.substring(1)
? decodeURIComponent(hashValue.substring(1))
: "";
// Setup delete mutation
const [commitDeleteMutation] = useMutation<FrameworkViewDeleteMutation>(
DeleteFrameworkMutation
);
// Keep track of manually expanded categories
const [expandedCategories, setExpandedCategories] = useState<string[]>(() => {
return hashCategory ? [hashCategory] : [];
});
const handleDeleteFramework = useCallback(() => {
setIsDeleting(true);
// When hash changes, update expanded categories to include the hash category
useEffect(() => {
if (hashCategory && !expandedCategories.includes(hashCategory)) {
setExpandedCategories((prev) => [...prev, hashCategory]);
}
}, [hashCategory, expandedCategories]);
const connectionId = ConnectionHandler.getConnectionID(
organizationId!,
"FrameworkListView_frameworks"
);
// Listen for hash changes (like when using back button)
useEffect(() => {
const handleHashChange = () => {
setHashValue(window.location.hash);
};
commitDeleteMutation({
variables: {
input: {
frameworkId: framework.id,
},
connections: [connectionId],
},
onCompleted: (_, errors) => {
setIsDeleting(false);
setIsDeleteDialogOpen(false);
window.addEventListener("hashchange", handleHashChange);
if (errors) {
console.error("Error deleting framework:", errors);
toast({
title: "Error",
description: "Failed to delete framework. Please try again.",
variant: "destructive",
});
return;
}
return () => {
window.removeEventListener("hashchange", handleHashChange);
};
}, []);
toast({
title: "Success",
description: "Framework deleted successfully.",
});
// Map mitigation state to status for the new design
const mapStateToStatus = (state?: string): string => {
if (!state) return "incomplete";
switch (state) {
case "IMPLEMENTED":
return "complete";
case "NOT_APPLICABLE":
return "not-applicable";
case "NOT_STARTED":
return "not-started";
default:
return "in-progress";
}
};
const processedControls = mitigations.map((mitigation) => ({
...mitigation,
status: mapStateToStatus(mitigation.state),
}));
// Calculate global progress
const implementedCount = processedControls.filter(
(mitigation) => mitigation.status === "complete"
).length;
const notApplicableCount = processedControls.filter(
(mitigation) => mitigation.status === "not-applicable"
).length;
const totalControls = processedControls.length;
// Include not-applicable as effectively "complete" for progress percentage
const effectiveCompletedCount = implementedCount + notApplicableCount;
const globalProgress = totalControls
? Math.round((effectiveCompletedCount / totalControls) * 100)
: 0;
// Get global status counts
const globalStatusCounts = processedControls.reduce((acc, mitigation) => {
if (mitigation.status) {
acc[mitigation.status] = (acc[mitigation.status] || 0) + 1;
}
return acc;
}, {} as Record<string, number>);
// Group mitigations by category
const controlsByCategory = processedControls.reduce((acc, mitigation) => {
if (!mitigation?.category) return acc;
if (!acc[mitigation.category]) {
acc[mitigation.category] = [];
}
acc[mitigation.category].push(mitigation);
return acc;
}, {} as Record<string, Mitigation[]>);
// Function to toggle a category's expanded state - now supports multiple expanded categories
const toggleCategory = (categoryId: string) => {
setExpandedCategories((prev) => {
if (prev.includes(categoryId)) {
return prev.filter((id) => id !== categoryId);
} else {
return [...prev, categoryId];
}
navigate(`/organizations/${organizationId}/frameworks`);
},
onError: (error) => {
setIsDeleting(false);
setIsDeleteDialogOpen(false);
console.error("Error deleting framework:", error);
toast({
title: "Error",
description: "Failed to delete framework. Please try again.",
variant: "destructive",
});
},
});
};
const categories: Category[] = Object.entries(controlsByCategory)
.map(([categoryName, categoryControls]) => {
const catImplementedCount = categoryControls.filter(
(mitigation) => mitigation.status === "complete"
).length;
const catNotApplicableCount = categoryControls.filter(
(mitigation) => mitigation.status === "not-applicable"
).length;
// Consider both "complete" and "not-applicable" as done for category progress
const catDoneCount = catImplementedCount + catNotApplicableCount;
const catTotalCount = categoryControls.length;
const progress = catTotalCount
? Math.round((catDoneCount / catTotalCount) * 100)
: 0;
return {
id: categoryName,
name: categoryName,
description: `Controls related to ${categoryName.toLowerCase()}`,
progress: progress,
mitigations: categoryControls.sort((a, b) =>
(a.name || "").localeCompare(b.name || "")
),
doneCount: catDoneCount,
totalCount: catTotalCount,
};
})
.filter((category) => category.mitigations.length > 0)
.sort((a, b) => a.name.localeCompare(b.name));
const getStatusIcon = (status: string) => {
switch (status) {
case "complete":
return <CheckCircle2 className="h-5 w-5 text-green-500" />;
case "in-progress":
return <Clock className="h-5 w-5 text-blue-500" />;
case "not-started":
return <AlertCircle className="h-5 w-5 text-gray-200" />;
case "incomplete":
return <AlertCircle className="h-5 w-5 text-red-500" />;
case "not-applicable":
return <X className="h-5 w-5 text-gray-300" />;
default:
return null;
}
};
}, [framework.id, organizationId, commitDeleteMutation, navigate, toast]);
return (
<PageTemplate
title={framework.name ?? ""}
description={framework.description || ""}
actions={
<div className="flex gap-4">
<Button variant="outline" asChild>
@@ -234,242 +142,93 @@ function FrameworkViewContent({
Edit Framework
</Link>
</Button>
<Button asChild>
<Link
to={`/organizations/${organizationId}/frameworks/${framework.id}/mitigations/create`}
>
<Plus className="mr-2 h-4 w-4" />
Create Mitigation
</Link>
<Button
variant="destructive"
onClick={() => setIsDeleteDialogOpen(true)}
>
Delete Framework
</Button>
</div>
}
>
{/* Global Progress Summary */}
<div className="mb-8">
<div className="flex items-center justify-between mb-1">
<h3 className="text-lg font-medium">Framework Implementation</h3>
<span className="text-sm text-muted-foreground">
{globalProgress}% complete
</span>
</div>
{/* Progress bar container */}
<div className="w-full h-5 rounded-full overflow-hidden bg-muted mb-2">
{/* Segmented progress bar */}
<div className="flex h-full">
{/* Complete segment */}
{globalStatusCounts.complete > 0 && (
<div
className="bg-green-500 h-full"
style={{
width: `${
(globalStatusCounts.complete / totalControls) * 100
}%`,
}}
/>
)}
{/* In-progress segment */}
{globalStatusCounts["in-progress"] > 0 && (
<div
className="bg-blue-500 h-full"
style={{
width: `${
(globalStatusCounts["in-progress"] / totalControls) * 100
}%`,
}}
/>
)}
{/* Incomplete segment */}
{globalStatusCounts.incomplete > 0 && (
<div
className="bg-red-500 h-full"
style={{
width: `${
(globalStatusCounts.incomplete / totalControls) * 100
}%`,
}}
/>
)}
{/* Not applicable segment */}
{globalStatusCounts["not-applicable"] > 0 && (
<div
className="bg-gray-600 h-full"
style={{
width: `${
(globalStatusCounts["not-applicable"] / totalControls) * 100
}%`,
}}
/>
)}
{/* Not started segment */}
{globalStatusCounts["not-started"] > 0 && (
<div
className="bg-gray-200 h-full"
style={{
width: `${
(globalStatusCounts["not-started"] / totalControls) * 100
}%`,
}}
/>
)}
</div>
</div>
{/* Status legend - reorder to match progress bar */}
<div className="flex flex-wrap items-center gap-4 text-sm">
{globalStatusCounts.complete > 0 && (
<div className="flex items-center gap-1.5">
<div className="w-3 h-3 rounded-full bg-green-500"></div>
<span>Complete ({globalStatusCounts.complete})</span>
</div>
)}
{globalStatusCounts["in-progress"] > 0 && (
<div className="flex items-center gap-1.5">
<div className="w-3 h-3 rounded-full bg-blue-500"></div>
<span>In Progress ({globalStatusCounts["in-progress"]})</span>
</div>
)}
{globalStatusCounts.incomplete > 0 && (
<div className="flex items-center gap-1.5">
<div className="w-3 h-3 rounded-full bg-red-500"></div>
<span>Incomplete ({globalStatusCounts.incomplete})</span>
</div>
)}
{globalStatusCounts["not-applicable"] > 0 && (
<div className="flex items-center gap-1.5 text-muted-foreground">
<div className="w-3 h-3 rounded-full bg-gray-600"></div>
<span>
Not Applicable ({globalStatusCounts["not-applicable"]})
</span>
</div>
)}
{globalStatusCounts["not-started"] > 0 && (
<div className="flex items-center gap-1.5 text-muted-foreground">
<div className="w-3 h-3 rounded-full bg-gray-200"></div>
<span>Not Started ({globalStatusCounts["not-started"]})</span>
</div>
)}
</div>
</div>
<div className="grid gap-6">
{categories.map((category) => {
const isExpanded = expandedCategories.includes(category.id);
return (
<div
key={category.id}
className="border rounded-lg overflow-hidden"
>
<Card className="border-0 shadow-none">
<CardHeader
className="bg-muted/50 cursor-pointer"
onClick={() => toggleCategory(category.id)}
{controls.length > 0 ? (
controls.map((control) => (
<Card key={control.id} className="overflow-hidden">
<CardHeader className="bg-muted/20">
<div
className="font-medium cursor-pointer flex items-center"
onClick={() => {
navigate(
`/organizations/${organizationId}/frameworks/${framework.id}/controls/${control.id}`
);
}}
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<CardTitle>{category.name}</CardTitle>
</div>
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<span>
{category.doneCount} / {category.totalCount}
</span>
{isExpanded ? (
<ChevronDown className="h-4 w-4" />
) : (
<ChevronRight className="h-4 w-4" />
)}
</div>
<span className="font-mono text-sm mr-3">
{control.referenceId}
</span>
<CardTitle>{control.name}</CardTitle>
</div>
<div className="text-sm text-muted-foreground mt-1">
{control.description}
</div>
</CardHeader>
<CardContent className="pt-4">
<h4 className="text-sm font-semibold mb-3">Mitigations</h4>
<div className="text-sm text-muted-foreground text-center py-4 border rounded-md">
<p>
Mitigations will be displayed here once connected to this
control
</p>
<div className="mt-2">
<Button variant="outline" size="sm" asChild>
<Link
to={`/organizations/${organizationId}/frameworks/${framework.id}/mitigations/create`}
>
<Plus className="h-3 w-3 mr-1" />
Link Mitigation
</Link>
</Button>
</div>
</CardHeader>
{isExpanded && (
<CardContent className="p-0">
{category.mitigations.length > 0 ? (
<div className="w-full">
<table className="w-full">
<thead>
<tr className="bg-muted/30 text-sm font-medium text-muted-foreground">
<th className="w-24 px-4 py-2 text-left">
Importance
</th>
<th className="w-24 px-4 py-2 text-left">
Status
</th>
<th className="px-4 py-2 text-left">
Mitigation
</th>
</tr>
</thead>
<tbody className="divide-y">
{category.mitigations.map((mitigation) => (
<tr
key={mitigation.id || Math.random().toString()}
className="hover:bg-muted/50 cursor-pointer"
onClick={() => {
if (mitigation?.id) {
// Always store just this category in the hash
// This is what will be expanded when returning
const encoded = encodeURIComponent(
category.id
);
window.location.hash = encoded;
setHashValue("#" + encoded);
// Make sure this category is expanded in the local state as well
if (
!expandedCategories.includes(category.id)
) {
setExpandedCategories((prev) => [
...prev,
category.id,
]);
}
// Use a small timeout to ensure the hash change is processed by the browser
setTimeout(() => {
navigate(
`/organizations/${organizationId}/frameworks/${framework.id}/mitigations/${mitigation.id}`
);
}, 100);
}
}}
>
<td className="w-24 px-4 py-3 align-middle">
<Badge variant="outline" className="text-xs">
{mitigation.importance}
</Badge>
</td>
<td className="w-24 px-4 py-3 align-middle">
<div className="flex items-center justify-center">
{mitigation.status
? getStatusIcon(mitigation.status)
: null}
</div>
</td>
<td className="px-4 py-3 align-middle">
<div className="font-medium">
{mitigation.name}
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
) : (
<div className="flex items-center justify-center p-6 text-center text-muted-foreground">
No mitigations in this category
</div>
)}
</CardContent>
)}
</Card>
</div>
);
})}
</div>
</CardContent>
</Card>
))
) : (
<div className="flex items-center justify-center p-6 text-center text-muted-foreground">
No controls available for this framework
</div>
)}
</div>
{/* Delete Confirmation Dialog */}
<Dialog open={isDeleteDialogOpen} onOpenChange={setIsDeleteDialogOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>Delete Framework</DialogTitle>
<DialogDescription>
Are you sure you want to delete the framework &quot;
{framework.name}&quot;? This action cannot be undone.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button
variant="outline"
onClick={() => setIsDeleteDialogOpen(false)}
disabled={isDeleting}
>
Cancel
</Button>
<Button
variant="destructive"
onClick={handleDeleteFramework}
disabled={isDeleting}
>
{isDeleting ? "Deleting..." : "Delete"}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</PageTemplate>
);
}

View File

@@ -29,7 +29,6 @@ const updateFrameworkMutation = graphql`
id
name
description
version
}
}
}
@@ -42,7 +41,6 @@ const updateFrameworkQuery = graphql`
id
name
description
version
}
}
}
@@ -166,7 +164,6 @@ function UpdateFrameworkViewContent({
variables: {
input: {
id: frameworkId!,
expectedVersion: data.node.version!,
name: formData.name,
description: formData.description,
},

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<11936aad3da2565a509b1566774e0ecf>>
* @generated SignedSource<<c1a3bc146c71229f94ea60f820bb43eb>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,7 +9,6 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type MitigationState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type ImportFrameworkInput = {
file: any;
organizationId: string;
@@ -25,14 +24,6 @@ export type FrameworkListViewImportFrameworkMutation$data = {
readonly createdAt: string;
readonly description: string;
readonly id: string;
readonly mitigations: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly id: string;
readonly state: MitigationState;
};
}>;
};
readonly name: string;
readonly updatedAt: string;
};
@@ -63,13 +54,6 @@ v2 = [
}
],
v3 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v4 = {
"alias": null,
"args": null,
"concreteType": "FrameworkEdge",
@@ -85,7 +69,13 @@ v4 = {
"name": "node",
"plural": false,
"selections": [
(v3/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
{
"alias": null,
"args": null,
@@ -100,53 +90,6 @@ v4 = {
"name": "description",
"storageKey": null
},
{
"alias": null,
"args": [
{
"kind": "Literal",
"name": "first",
"value": 100
}
],
"concreteType": "MitigationConnection",
"kind": "LinkedField",
"name": "mitigations",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "MitigationEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Mitigation",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v3/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "state",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": "mitigations(first:100)"
},
{
"alias": null,
"args": null,
@@ -185,7 +128,7 @@ return {
"name": "importFramework",
"plural": false,
"selections": [
(v4/*: any*/)
(v3/*: any*/)
],
"storageKey": null
}
@@ -210,7 +153,7 @@ return {
"name": "importFramework",
"plural": false,
"selections": [
(v4/*: any*/),
(v3/*: any*/),
{
"alias": null,
"args": null,
@@ -233,16 +176,16 @@ return {
]
},
"params": {
"cacheID": "d2d34f8e054d753d956120ea14791f79",
"cacheID": "0d952e4f9f3e106ea7a30d69f7268385",
"id": null,
"metadata": {},
"name": "FrameworkListViewImportFrameworkMutation",
"operationKind": "mutation",
"text": "mutation FrameworkListViewImportFrameworkMutation(\n $input: ImportFrameworkInput!\n) {\n importFramework(input: $input) {\n frameworkEdge {\n node {\n id\n name\n description\n mitigations(first: 100) {\n edges {\n node {\n id\n state\n }\n }\n }\n createdAt\n updatedAt\n }\n }\n }\n}\n"
"text": "mutation FrameworkListViewImportFrameworkMutation(\n $input: ImportFrameworkInput!\n) {\n importFramework(input: $input) {\n frameworkEdge {\n node {\n id\n name\n description\n createdAt\n updatedAt\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "a812db41b10d16c25959a5a733fe6088";
(node as any).hash = "8be3328101831be07eeea8670d47debd";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<6b6bb27f3ae9e9cf720be1c3655c595e>>
* @generated SignedSource<<1d45b549aa04b80f7e0a2951d7910a3f>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,7 +9,6 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type MitigationState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type FrameworkListViewQuery$variables = {
organizationId: string;
};
@@ -21,14 +20,6 @@ export type FrameworkListViewQuery$data = {
readonly createdAt: string;
readonly description: string;
readonly id: string;
readonly mitigations: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly id: string;
readonly state: MitigationState;
};
}>;
};
readonly name: string;
readonly updatedAt: string;
};
@@ -63,21 +54,14 @@ v2 = {
"name": "id",
"storageKey": null
},
v3 = [
{
"kind": "Literal",
"name": "first",
"value": 100
}
],
v4 = {
v3 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
},
v5 = [
v4 = [
{
"alias": null,
"args": null,
@@ -109,47 +93,6 @@ v5 = [
"name": "description",
"storageKey": null
},
{
"alias": null,
"args": (v3/*: any*/),
"concreteType": "MitigationConnection",
"kind": "LinkedField",
"name": "mitigations",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "MitigationEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Mitigation",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v2/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "state",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": "mitigations(first:100)"
},
{
"alias": null,
"args": null,
@@ -164,7 +107,7 @@ v5 = [
"name": "updatedAt",
"storageKey": null
},
(v4/*: any*/)
(v3/*: any*/)
],
"storageKey": null
},
@@ -203,6 +146,13 @@ v5 = [
],
"storageKey": null
}
],
v5 = [
{
"kind": "Literal",
"name": "first",
"value": 100
}
];
return {
"fragment": {
@@ -229,7 +179,7 @@ return {
"kind": "LinkedField",
"name": "__FrameworkListView_frameworks_connection",
"plural": false,
"selections": (v5/*: any*/),
"selections": (v4/*: any*/),
"storageKey": null
}
],
@@ -257,23 +207,23 @@ return {
"name": "node",
"plural": false,
"selections": [
(v4/*: any*/),
(v3/*: any*/),
{
"kind": "InlineFragment",
"selections": [
{
"alias": null,
"args": (v3/*: any*/),
"args": (v5/*: any*/),
"concreteType": "FrameworkConnection",
"kind": "LinkedField",
"name": "frameworks",
"plural": false,
"selections": (v5/*: any*/),
"selections": (v4/*: any*/),
"storageKey": "frameworks(first:100)"
},
{
"alias": null,
"args": (v3/*: any*/),
"args": (v5/*: any*/),
"filters": null,
"handle": "connection",
"key": "FrameworkListView_frameworks",
@@ -291,7 +241,7 @@ return {
]
},
"params": {
"cacheID": "e5d4da21773770d146fb7d91e435caef",
"cacheID": "ad629b287bbe0482ef250bae68c4018c",
"id": null,
"metadata": {
"connection": [
@@ -308,11 +258,11 @@ return {
},
"name": "FrameworkListViewQuery",
"operationKind": "query",
"text": "query FrameworkListViewQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n frameworks(first: 100) {\n edges {\n node {\n id\n name\n description\n mitigations(first: 100) {\n edges {\n node {\n id\n state\n }\n }\n }\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n}\n"
"text": "query FrameworkListViewQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n frameworks(first: 100) {\n edges {\n node {\n id\n name\n description\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n}\n"
}
};
})();
(node as any).hash = "8da147529de5e229e38b836bd584e484";
(node as any).hash = "27aa68a4b7303c125c427acdf6aa9dc4";
export default node;

View File

@@ -0,0 +1,132 @@
/**
* @generated SignedSource<<9f35422e7d027485b106e6fb8879d460>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type DeleteFrameworkInput = {
frameworkId: string;
};
export type FrameworkViewDeleteMutation$variables = {
connections: ReadonlyArray<string>;
input: DeleteFrameworkInput;
};
export type FrameworkViewDeleteMutation$data = {
readonly deleteFramework: {
readonly deletedFrameworkId: string;
};
};
export type FrameworkViewDeleteMutation = {
response: FrameworkViewDeleteMutation$data;
variables: FrameworkViewDeleteMutation$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": "deletedFrameworkId",
"storageKey": null
};
return {
"fragment": {
"argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/)
],
"kind": "Fragment",
"metadata": null,
"name": "FrameworkViewDeleteMutation",
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "DeleteFrameworkPayload",
"kind": "LinkedField",
"name": "deleteFramework",
"plural": false,
"selections": [
(v3/*: any*/)
],
"storageKey": null
}
],
"type": "Mutation",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": [
(v1/*: any*/),
(v0/*: any*/)
],
"kind": "Operation",
"name": "FrameworkViewDeleteMutation",
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "DeleteFrameworkPayload",
"kind": "LinkedField",
"name": "deleteFramework",
"plural": false,
"selections": [
(v3/*: any*/),
{
"alias": null,
"args": null,
"filters": null,
"handle": "deleteEdge",
"key": "",
"kind": "ScalarHandle",
"name": "deletedFrameworkId",
"handleArgs": [
{
"kind": "Variable",
"name": "connections",
"variableName": "connections"
}
]
}
],
"storageKey": null
}
]
},
"params": {
"cacheID": "b10bac4b295c5d2a9a564cbba4569633",
"id": null,
"metadata": {},
"name": "FrameworkViewDeleteMutation",
"operationKind": "mutation",
"text": "mutation FrameworkViewDeleteMutation(\n $input: DeleteFrameworkInput!\n) {\n deleteFramework(input: $input) {\n deletedFrameworkId\n }\n}\n"
}
};
})();
(node as any).hash = "8b20886821651ffb7e335df58fb46fc9";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<1abc57788d51404af0931c7e120c01a7>>
* @generated SignedSource<<0185ea6dc887f2bbb5ca70ec28e916b2>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,27 +9,23 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type MitigationImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type MitigationState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type FrameworkViewQuery$variables = {
frameworkId: string;
};
export type FrameworkViewQuery$data = {
readonly node: {
readonly description?: string;
readonly id: string;
readonly mitigations?: {
readonly controls?: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly category: string;
readonly description: string;
readonly id: string;
readonly importance: MitigationImportance;
readonly name: string;
readonly state: MitigationState;
readonly referenceId: string;
};
}>;
};
readonly description?: string;
readonly id: string;
readonly name?: string;
};
};
@@ -75,17 +71,25 @@ v4 = {
"storageKey": null
},
v5 = {
"kind": "Literal",
"name": "orderBy",
"value": {
"direction": "ASC",
"field": "CREATED_AT"
}
},
v6 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
},
v6 = [
v7 = [
{
"alias": null,
"args": null,
"concreteType": "MitigationEdge",
"concreteType": "ControlEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
@@ -93,36 +97,22 @@ v6 = [
{
"alias": null,
"args": null,
"concreteType": "Mitigation",
"concreteType": "Control",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v2/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "referenceId",
"storageKey": null
},
(v3/*: any*/),
(v4/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "state",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "category",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "importance",
"storageKey": null
},
(v5/*: any*/)
(v6/*: any*/)
],
"storageKey": null
},
@@ -162,12 +152,13 @@ v6 = [
"storageKey": null
}
],
v7 = [
v8 = [
{
"kind": "Literal",
"name": "first",
"value": 100
}
},
(v5/*: any*/)
];
return {
"fragment": {
@@ -191,14 +182,16 @@ return {
(v3/*: any*/),
(v4/*: any*/),
{
"alias": "mitigations",
"args": null,
"concreteType": "MitigationConnection",
"alias": "controls",
"args": [
(v5/*: any*/)
],
"concreteType": "ControlConnection",
"kind": "LinkedField",
"name": "__FrameworkView_mitigations_connection",
"name": "__FrameworkView_controls_connection",
"plural": false,
"selections": (v6/*: any*/),
"storageKey": null
"selections": (v7/*: any*/),
"storageKey": "__FrameworkView_controls_connection(orderBy:{\"direction\":\"ASC\",\"field\":\"CREATED_AT\"})"
}
],
"type": "Framework",
@@ -225,7 +218,7 @@ return {
"name": "node",
"plural": false,
"selections": [
(v5/*: any*/),
(v6/*: any*/),
(v2/*: any*/),
{
"kind": "InlineFragment",
@@ -234,22 +227,24 @@ return {
(v4/*: any*/),
{
"alias": null,
"args": (v7/*: any*/),
"concreteType": "MitigationConnection",
"args": (v8/*: any*/),
"concreteType": "ControlConnection",
"kind": "LinkedField",
"name": "mitigations",
"name": "controls",
"plural": false,
"selections": (v6/*: any*/),
"storageKey": "mitigations(first:100)"
"selections": (v7/*: any*/),
"storageKey": "controls(first:100,orderBy:{\"direction\":\"ASC\",\"field\":\"CREATED_AT\"})"
},
{
"alias": null,
"args": (v7/*: any*/),
"filters": null,
"args": (v8/*: any*/),
"filters": [
"orderBy"
],
"handle": "connection",
"key": "FrameworkView_mitigations",
"key": "FrameworkView_controls",
"kind": "LinkedHandle",
"name": "mitigations"
"name": "controls"
}
],
"type": "Framework",
@@ -261,7 +256,7 @@ return {
]
},
"params": {
"cacheID": "c60a352d14662dd43ab93b9a4dcebee8",
"cacheID": "a1fa5a0efc291c92478c061d32b90e43",
"id": null,
"metadata": {
"connection": [
@@ -271,18 +266,18 @@ return {
"direction": "forward",
"path": [
"node",
"mitigations"
"controls"
]
}
]
},
"name": "FrameworkViewQuery",
"operationKind": "query",
"text": "query FrameworkViewQuery(\n $frameworkId: ID!\n) {\n node(id: $frameworkId) {\n __typename\n id\n ... on Framework {\n name\n description\n mitigations(first: 100) {\n edges {\n node {\n id\n name\n description\n state\n category\n importance\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
"text": "query FrameworkViewQuery(\n $frameworkId: ID!\n) {\n node(id: $frameworkId) {\n __typename\n id\n ... on Framework {\n name\n description\n controls(first: 100, orderBy: {field: CREATED_AT, direction: ASC}) {\n edges {\n node {\n id\n referenceId\n name\n description\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "f65af17f461e1c112573c0d14d08479d";
(node as any).hash = "ff9593fc321c840ae9ef1da48a13c3e5";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<08d71ea16ac38e11d5b1ce3fb11bcaf3>>
* @generated SignedSource<<f6c5cb8b7001a4cee689302191d06ad9>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -17,7 +17,6 @@ export type UpdateFrameworkViewQuery$data = {
readonly description?: string;
readonly id?: string;
readonly name?: string;
readonly version?: number;
};
};
export type UpdateFrameworkViewQuery = {
@@ -60,13 +59,6 @@ v4 = {
"kind": "ScalarField",
"name": "description",
"storageKey": null
},
v5 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
};
return {
"fragment": {
@@ -88,8 +80,7 @@ return {
"selections": [
(v2/*: any*/),
(v3/*: any*/),
(v4/*: any*/),
(v5/*: any*/)
(v4/*: any*/)
],
"type": "Framework",
"abstractKey": null
@@ -127,8 +118,7 @@ return {
"kind": "InlineFragment",
"selections": [
(v3/*: any*/),
(v4/*: any*/),
(v5/*: any*/)
(v4/*: any*/)
],
"type": "Framework",
"abstractKey": null
@@ -139,16 +129,16 @@ return {
]
},
"params": {
"cacheID": "180cbef2756c525af017ca6996a7c2d6",
"cacheID": "5c423e61373989c4576989cb6c732547",
"id": null,
"metadata": {},
"name": "UpdateFrameworkViewQuery",
"operationKind": "query",
"text": "query UpdateFrameworkViewQuery(\n $frameworkId: ID!\n) {\n node(id: $frameworkId) {\n __typename\n ... on Framework {\n id\n name\n description\n version\n }\n id\n }\n}\n"
"text": "query UpdateFrameworkViewQuery(\n $frameworkId: ID!\n) {\n node(id: $frameworkId) {\n __typename\n ... on Framework {\n id\n name\n description\n }\n id\n }\n}\n"
}
};
})();
(node as any).hash = "d644d01f1d8a31b6c87c7f6360996796";
(node as any).hash = "416b7f0dbf33cbfe39578fc3243bf423";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<115402b83869511df5e91ab206ae99e3>>
* @generated SignedSource<<9c98acb5c320005e303cd815550c0d74>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -11,7 +11,6 @@
import { ConcreteRequest } from 'relay-runtime';
export type UpdateFrameworkInput = {
description?: string | null | undefined;
expectedVersion: number;
id: string;
name?: string | null | undefined;
};
@@ -24,7 +23,6 @@ export type UpdateFrameworkViewUpdateFrameworkMutation$data = {
readonly description: string;
readonly id: string;
readonly name: string;
readonly version: number;
};
};
};
@@ -84,13 +82,6 @@ v1 = [
"kind": "ScalarField",
"name": "description",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
}
],
"storageKey": null
@@ -117,16 +108,16 @@ return {
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "08fc83afdc1227aa23cac0778cdd2cc0",
"cacheID": "8a41e224572c2419fc49c7fef6908d63",
"id": null,
"metadata": {},
"name": "UpdateFrameworkViewUpdateFrameworkMutation",
"operationKind": "mutation",
"text": "mutation UpdateFrameworkViewUpdateFrameworkMutation(\n $input: UpdateFrameworkInput!\n) {\n updateFramework(input: $input) {\n framework {\n id\n name\n description\n version\n }\n }\n}\n"
"text": "mutation UpdateFrameworkViewUpdateFrameworkMutation(\n $input: UpdateFrameworkInput!\n) {\n updateFramework(input: $input) {\n framework {\n id\n name\n description\n }\n }\n}\n"
}
};
})();
(node as any).hash = "6dfde24d73c2cbc0c5ca147d076fbd26";
(node as any).hash = "9b201a966e844a77d3d920a7e0165d15";
export default node;

View File

@@ -131,7 +131,6 @@ const mitigationViewQuery = graphql`
state
importance
category
version
tasks(first: 100) @connection(key: "MitigationView_tasks") {
__id
edges {
@@ -141,7 +140,6 @@ const mitigationViewQuery = graphql`
description
state
timeEstimate
version
assignedTo {
id
fullName
@@ -178,7 +176,6 @@ const updateTaskStateMutation = graphql`
id
state
timeEstimate
version
}
}
}
@@ -197,7 +194,6 @@ const createTaskMutation = graphql`
description
timeEstimate
state
version
assignedTo {
id
fullName
@@ -271,7 +267,6 @@ const assignTaskMutation = graphql`
assignTask(input: $input) {
task {
id
version
assignedTo {
id
fullName
@@ -287,7 +282,6 @@ const unassignTaskMutation = graphql`
unassignTask(input: $input) {
task {
id
version
assignedTo {
id
fullName
@@ -306,7 +300,6 @@ const updateMitigationStateMutation = graphql`
mitigation {
id
state
version
}
}
}
@@ -627,11 +620,7 @@ function MitigationViewContent({
setSearchParams(searchParams);
};
const handleToggleTaskState = (
taskId: string,
currentState: string,
version: number
) => {
const handleToggleTaskState = (taskId: string, currentState: string) => {
const newState = currentState === "DONE" ? "TODO" : "DONE";
updateTask({
@@ -639,7 +628,6 @@ function MitigationViewContent({
input: {
taskId,
state: newState,
expectedVersion: version,
},
},
onCompleted: () => {
@@ -647,7 +635,6 @@ function MitigationViewContent({
setSelectedTask({
...selectedTask,
state: newState,
version: version + 1,
});
}
},
@@ -1114,7 +1101,6 @@ function MitigationViewContent({
| "IN_PROGRESS"
| "IMPLEMENTED"
| "NOT_APPLICABLE",
expectedVersion: data.mitigation.version!,
},
},
onCompleted: () => {
@@ -1180,7 +1166,7 @@ function MitigationViewContent({
// Function to handle saving the updated duration
const handleSaveDuration = useCallback(
(taskId: string, version: number) => {
(taskId: string) => {
// Convert to ISO duration format
let duration = "P";
@@ -1211,7 +1197,6 @@ function MitigationViewContent({
input: {
taskId,
timeEstimate,
expectedVersion: version,
},
},
onCompleted: () => {
@@ -1222,7 +1207,6 @@ function MitigationViewContent({
setSelectedTask({
...selectedTask,
timeEstimate,
version: version + 1,
});
}
},
@@ -1495,7 +1479,7 @@ function MitigationViewContent({
onClick={(e) => {
e.stopPropagation(); // Prevent task selection when checkbox is clicked
if (task?.id && task?.state) {
handleToggleTaskState(task.id, task.state, task.version);
handleToggleTaskState(task.id, task.state);
}
}}
>
@@ -1963,12 +1947,7 @@ function MitigationViewContent({
</div>
<button
className="p-1 text-sm text-blue-600 hover:text-blue-800"
onClick={() =>
handleSaveDuration(
selectedTask.id,
selectedTask.version
)
}
onClick={() => handleSaveDuration(selectedTask.id)}
>
Save
</button>
@@ -2256,8 +2235,7 @@ function MitigationViewContent({
onClick={() =>
handleToggleTaskState(
selectedTask.id,
selectedTask.state || "TODO",
selectedTask.version
selectedTask.state || "TODO"
)
}
>
@@ -2271,8 +2249,7 @@ function MitigationViewContent({
onClick={() =>
handleToggleTaskState(
selectedTask.id,
selectedTask.state || "DONE",
selectedTask.version
selectedTask.state || "DONE"
)
}
>

View File

@@ -42,7 +42,6 @@ const updateMitigationMutation = graphql`
category
importance
state
version
}
}
}
@@ -58,7 +57,6 @@ const updateMitigationQuery = graphql`
category
importance
state
version
}
}
}
@@ -191,7 +189,6 @@ function UpdateMitigationViewContent({
const input: {
id: string;
expectedVersion: number;
name?: string;
description?: string;
category?: string;
@@ -199,7 +196,6 @@ function UpdateMitigationViewContent({
importance?: MitigationImportance;
} = {
id: mitigationId!,
expectedVersion: data.node.version,
};
if (editedFields.has("name")) {

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<22a6faa89009d6784bc9a89c2456f12e>>
* @generated SignedSource<<07454812ea72dd51d0b615737e75a2a1>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -14,9 +14,9 @@ export type MitigationState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" |
export type CreateMitigationInput = {
category: string;
description: string;
frameworkId: string;
importance: MitigationImportance;
name: string;
organizationId: string;
};
export type CreateMitigationViewCreateMitigationMutation$variables = {
connections: ReadonlyArray<string>;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<acf83fd1c5826a38f85912ed91e79422>>
* @generated SignedSource<<c176425ad01ae9a330d0b8217a54841f>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -25,7 +25,6 @@ export type MitigationViewAssignTaskMutation$data = {
readonly primaryEmailAddress: string;
} | null | undefined;
readonly id: string;
readonly version: number;
};
};
};
@@ -73,13 +72,6 @@ v2 = [
"plural": false,
"selections": [
(v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
},
{
"alias": null,
"args": null,
@@ -131,16 +123,16 @@ return {
"selections": (v2/*: any*/)
},
"params": {
"cacheID": "b336b45b0dad20968af93b52cd0aac48",
"cacheID": "c01a2f758aea8268b73365c426b7c08a",
"id": null,
"metadata": {},
"name": "MitigationViewAssignTaskMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewAssignTaskMutation(\n $input: AssignTaskInput!\n) {\n assignTask(input: $input) {\n task {\n id\n version\n assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n }\n }\n}\n"
"text": "mutation MitigationViewAssignTaskMutation(\n $input: AssignTaskInput!\n) {\n assignTask(input: $input) {\n task {\n id\n assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "6446830361465b47f185c50b2886a422";
(node as any).hash = "2b01502cb830a0d914553e01ceb2445f";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<958545e211155678a1a43d8ef1717071>>
* @generated SignedSource<<e544ac1f4a0b6d728cba2b66a2f97520>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -35,7 +35,6 @@ export type MitigationViewCreateTaskMutation$data = {
readonly name: string;
readonly state: TaskState;
readonly timeEstimate: any | null | undefined;
readonly version: number;
};
};
};
@@ -115,13 +114,6 @@ v4 = {
"name": "state",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
},
{
"alias": null,
"args": null,
@@ -220,16 +212,16 @@ return {
]
},
"params": {
"cacheID": "dedf546da903060c79209ab7695bde12",
"cacheID": "273c3d2ae0de44280e85e47db23db892",
"id": null,
"metadata": {},
"name": "MitigationViewCreateTaskMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewCreateTaskMutation(\n $input: CreateTaskInput!\n) {\n createTask(input: $input) {\n taskEdge {\n node {\n id\n name\n description\n timeEstimate\n state\n version\n assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n }\n }\n }\n}\n"
"text": "mutation MitigationViewCreateTaskMutation(\n $input: CreateTaskInput!\n) {\n createTask(input: $input) {\n taskEdge {\n node {\n id\n name\n description\n timeEstimate\n state\n assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "683fe4d2a3d33e989a8b5593f99799a5";
(node as any).hash = "ad8a56e4976e9dc15f4ee8e1b32d9fa9";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<d54298db57548f693ed2ca2418c9128c>>
* @generated SignedSource<<5baf9229b2f520bcfa43960bd6af05e0>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -54,11 +54,9 @@ export type MitigationViewQuery$data = {
readonly name: string;
readonly state: TaskState;
readonly timeEstimate: any | null | undefined;
readonly version: number;
};
}>;
};
readonly version?: number;
};
};
export type MitigationViewQuery = {
@@ -124,20 +122,13 @@ v7 = {
"storageKey": null
},
v8 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
},
v9 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "timeEstimate",
"storageKey": null
},
v10 = {
v9 = {
"alias": null,
"args": null,
"concreteType": "People",
@@ -163,21 +154,21 @@ v10 = {
],
"storageKey": null
},
v11 = {
v10 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
},
v12 = {
v11 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cursor",
"storageKey": null
},
v13 = {
v12 = {
"alias": null,
"args": null,
"concreteType": "PageInfo",
@@ -202,7 +193,7 @@ v13 = {
],
"storageKey": null
},
v14 = {
v13 = {
"kind": "ClientExtension",
"selections": [
{
@@ -214,7 +205,7 @@ v14 = {
}
]
},
v15 = [
v14 = [
{
"alias": null,
"args": null,
@@ -275,25 +266,25 @@ v15 = [
"name": "createdAt",
"storageKey": null
},
(v11/*: any*/)
(v10/*: any*/)
],
"storageKey": null
},
(v12/*: any*/)
(v11/*: any*/)
],
"storageKey": null
},
(v13/*: any*/),
(v14/*: any*/)
(v12/*: any*/),
(v13/*: any*/)
],
v16 = [
v15 = [
{
"kind": "Literal",
"name": "first",
"value": 100
}
],
v17 = [
v16 = [
{
"kind": "Literal",
"name": "first",
@@ -324,7 +315,6 @@ return {
(v5/*: any*/),
(v6/*: any*/),
(v7/*: any*/),
(v8/*: any*/),
{
"alias": "tasks",
"args": null,
@@ -353,9 +343,8 @@ return {
(v3/*: any*/),
(v4/*: any*/),
(v5/*: any*/),
(v9/*: any*/),
(v8/*: any*/),
(v10/*: any*/),
(v9/*: any*/),
{
"alias": "evidences",
"args": null,
@@ -363,19 +352,19 @@ return {
"kind": "LinkedField",
"name": "__MitigationView_evidences_connection",
"plural": false,
"selections": (v15/*: any*/),
"selections": (v14/*: any*/),
"storageKey": null
},
(v11/*: any*/)
(v10/*: any*/)
],
"storageKey": null
},
(v12/*: any*/)
(v11/*: any*/)
],
"storageKey": null
},
(v13/*: any*/),
(v14/*: any*/)
(v12/*: any*/),
(v13/*: any*/)
],
"storageKey": null
}
@@ -404,7 +393,7 @@ return {
"name": "node",
"plural": false,
"selections": [
(v11/*: any*/),
(v10/*: any*/),
(v2/*: any*/),
{
"kind": "InlineFragment",
@@ -414,10 +403,9 @@ return {
(v5/*: any*/),
(v6/*: any*/),
(v7/*: any*/),
(v8/*: any*/),
{
"alias": null,
"args": (v16/*: any*/),
"args": (v15/*: any*/),
"concreteType": "TaskConnection",
"kind": "LinkedField",
"name": "tasks",
@@ -443,44 +431,43 @@ return {
(v3/*: any*/),
(v4/*: any*/),
(v5/*: any*/),
(v9/*: any*/),
(v8/*: any*/),
(v10/*: any*/),
(v9/*: any*/),
{
"alias": null,
"args": (v17/*: any*/),
"args": (v16/*: any*/),
"concreteType": "EvidenceConnection",
"kind": "LinkedField",
"name": "evidences",
"plural": false,
"selections": (v15/*: any*/),
"selections": (v14/*: any*/),
"storageKey": "evidences(first:50)"
},
{
"alias": null,
"args": (v17/*: any*/),
"args": (v16/*: any*/),
"filters": null,
"handle": "connection",
"key": "MitigationView_evidences",
"kind": "LinkedHandle",
"name": "evidences"
},
(v11/*: any*/)
(v10/*: any*/)
],
"storageKey": null
},
(v12/*: any*/)
(v11/*: any*/)
],
"storageKey": null
},
(v13/*: any*/),
(v14/*: any*/)
(v12/*: any*/),
(v13/*: any*/)
],
"storageKey": "tasks(first:100)"
},
{
"alias": null,
"args": (v16/*: any*/),
"args": (v15/*: any*/),
"filters": null,
"handle": "connection",
"key": "MitigationView_tasks",
@@ -497,7 +484,7 @@ return {
]
},
"params": {
"cacheID": "8e9c3cef43daff0bdbfff4e33d7c70ad",
"cacheID": "27e466aa3f7c929738fc108627fd5aa8",
"id": null,
"metadata": {
"connection": [
@@ -520,11 +507,11 @@ return {
},
"name": "MitigationViewQuery",
"operationKind": "query",
"text": "query MitigationViewQuery(\n $mitigationId: ID!\n) {\n mitigation: node(id: $mitigationId) {\n __typename\n id\n ... on Mitigation {\n name\n description\n state\n importance\n category\n version\n tasks(first: 100) {\n edges {\n node {\n id\n name\n description\n state\n timeEstimate\n version\n assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n evidences(first: 50) {\n edges {\n node {\n id\n mimeType\n filename\n size\n state\n type\n url\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
"text": "query MitigationViewQuery(\n $mitigationId: ID!\n) {\n mitigation: node(id: $mitigationId) {\n __typename\n id\n ... on Mitigation {\n name\n description\n state\n importance\n category\n tasks(first: 100) {\n edges {\n node {\n id\n name\n description\n state\n timeEstimate\n assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n evidences(first: 50) {\n edges {\n node {\n id\n mimeType\n filename\n size\n state\n type\n url\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "f0baeab367be46290f2f15df836ed153";
(node as any).hash = "c26df14ee0f01a46868fdd73baa76638";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<9cb5a3f1c6f0c2a3265ecdc6ececd13d>>
* @generated SignedSource<<a0f8386de345c2c768657efd4358518c>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -24,7 +24,6 @@ export type MitigationViewUnassignTaskMutation$data = {
readonly primaryEmailAddress: string;
} | null | undefined;
readonly id: string;
readonly version: number;
};
};
};
@@ -72,13 +71,6 @@ v2 = [
"plural": false,
"selections": [
(v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
},
{
"alias": null,
"args": null,
@@ -130,16 +122,16 @@ return {
"selections": (v2/*: any*/)
},
"params": {
"cacheID": "e493ae65ba1e53627dd3f260e8814e41",
"cacheID": "6cf554a835936763f3b4f55f04c9771f",
"id": null,
"metadata": {},
"name": "MitigationViewUnassignTaskMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewUnassignTaskMutation(\n $input: UnassignTaskInput!\n) {\n unassignTask(input: $input) {\n task {\n id\n version\n assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n }\n }\n}\n"
"text": "mutation MitigationViewUnassignTaskMutation(\n $input: UnassignTaskInput!\n) {\n unassignTask(input: $input) {\n task {\n id\n assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "3f5a0d2b753d0a759e3004c0b557c505";
(node as any).hash = "07d79596fef3416fdc001077d2d51c75";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<3aa56a1042b1f9492cfc5bd5d5f55d9d>>
* @generated SignedSource<<1d924bb487fd93636fa7207c5aa08cdc>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -14,7 +14,6 @@ export type MitigationState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" |
export type UpdateMitigationInput = {
category?: string | null | undefined;
description?: string | null | undefined;
expectedVersion: number;
id: string;
importance?: MitigationImportance | null | undefined;
name?: string | null | undefined;
@@ -28,7 +27,6 @@ export type MitigationViewUpdateMitigationStateMutation$data = {
readonly mitigation: {
readonly id: string;
readonly state: MitigationState;
readonly version: number;
};
};
};
@@ -81,13 +79,6 @@ v1 = [
"kind": "ScalarField",
"name": "state",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
}
],
"storageKey": null
@@ -114,16 +105,16 @@ return {
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "4a85c6e15d6ff91ccaa7976f9b0a0c6f",
"cacheID": "7e4a92a089fa5927b0239004c3fb5f47",
"id": null,
"metadata": {},
"name": "MitigationViewUpdateMitigationStateMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewUpdateMitigationStateMutation(\n $input: UpdateMitigationInput!\n) {\n updateMitigation(input: $input) {\n mitigation {\n id\n state\n version\n }\n }\n}\n"
"text": "mutation MitigationViewUpdateMitigationStateMutation(\n $input: UpdateMitigationInput!\n) {\n updateMitigation(input: $input) {\n mitigation {\n id\n state\n }\n }\n}\n"
}
};
})();
(node as any).hash = "2eb2c1f791262f502df22ca0c16682a7";
(node as any).hash = "e985902d55a537a08b8a2d4482abe0b3";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<4aed09b28d5d1ec083abfeeb874b9ce3>>
* @generated SignedSource<<a68054962a4ec7ae205dc2976fe8d2bf>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -12,7 +12,6 @@ import { ConcreteRequest } from 'relay-runtime';
export type TaskState = "DONE" | "TODO";
export type UpdateTaskInput = {
description?: string | null | undefined;
expectedVersion: number;
name?: string | null | undefined;
state?: TaskState | null | undefined;
taskId: string;
@@ -27,7 +26,6 @@ export type MitigationViewUpdateTaskStateMutation$data = {
readonly id: string;
readonly state: TaskState;
readonly timeEstimate: any | null | undefined;
readonly version: number;
};
};
};
@@ -87,13 +85,6 @@ v1 = [
"kind": "ScalarField",
"name": "timeEstimate",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
}
],
"storageKey": null
@@ -120,16 +111,16 @@ return {
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "8de0d061237d4ebcbb366b8eefff6d94",
"cacheID": "f8d2ca86f8e7856b3d24bcd810490a6a",
"id": null,
"metadata": {},
"name": "MitigationViewUpdateTaskStateMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewUpdateTaskStateMutation(\n $input: UpdateTaskInput!\n) {\n updateTask(input: $input) {\n task {\n id\n state\n timeEstimate\n version\n }\n }\n}\n"
"text": "mutation MitigationViewUpdateTaskStateMutation(\n $input: UpdateTaskInput!\n) {\n updateTask(input: $input) {\n task {\n id\n state\n timeEstimate\n }\n }\n}\n"
}
};
})();
(node as any).hash = "81dca6c475859526370ef60b4757428b";
(node as any).hash = "7ab07c94be8f56a93d39178828d85823";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<338c4c7afa073c41eacac21a2996d1f9>>
* @generated SignedSource<<c4f9f399e7a3d6c0e0482af3eccc8492>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -22,7 +22,6 @@ export type UpdateMitigationViewQuery$data = {
readonly importance?: MitigationImportance;
readonly name?: string;
readonly state?: MitigationState;
readonly version?: number;
};
};
export type UpdateMitigationViewQuery = {
@@ -86,13 +85,6 @@ v7 = {
"kind": "ScalarField",
"name": "state",
"storageKey": null
},
v8 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
};
return {
"fragment": {
@@ -117,8 +109,7 @@ return {
(v4/*: any*/),
(v5/*: any*/),
(v6/*: any*/),
(v7/*: any*/),
(v8/*: any*/)
(v7/*: any*/)
],
"type": "Mitigation",
"abstractKey": null
@@ -159,8 +150,7 @@ return {
(v4/*: any*/),
(v5/*: any*/),
(v6/*: any*/),
(v7/*: any*/),
(v8/*: any*/)
(v7/*: any*/)
],
"type": "Mitigation",
"abstractKey": null
@@ -171,16 +161,16 @@ return {
]
},
"params": {
"cacheID": "c2e9133d77f3e090267b19f4ab270c72",
"cacheID": "81b47701802e110078ee303a83c19d88",
"id": null,
"metadata": {},
"name": "UpdateMitigationViewQuery",
"operationKind": "query",
"text": "query UpdateMitigationViewQuery(\n $mitigationId: ID!\n) {\n node(id: $mitigationId) {\n __typename\n ... on Mitigation {\n id\n name\n description\n category\n importance\n state\n version\n }\n id\n }\n}\n"
"text": "query UpdateMitigationViewQuery(\n $mitigationId: ID!\n) {\n node(id: $mitigationId) {\n __typename\n ... on Mitigation {\n id\n name\n description\n category\n importance\n state\n }\n id\n }\n}\n"
}
};
})();
(node as any).hash = "3e977744beb9c403aa8be232c8112a9b";
(node as any).hash = "126fe89ef3da933cfb7847ff05179832";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<39cfe3277c49d7a0ff2099d6ad579e7d>>
* @generated SignedSource<<d6d22035bb11c4fff1db97bac26aa7d1>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -14,7 +14,6 @@ export type MitigationState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" |
export type UpdateMitigationInput = {
category?: string | null | undefined;
description?: string | null | undefined;
expectedVersion: number;
id: string;
importance?: MitigationImportance | null | undefined;
name?: string | null | undefined;
@@ -32,7 +31,6 @@ export type UpdateMitigationViewUpdateMitigationMutation$data = {
readonly importance: MitigationImportance;
readonly name: string;
readonly state: MitigationState;
readonly version: number;
};
};
};
@@ -113,13 +111,6 @@ v1 = [
"kind": "ScalarField",
"name": "state",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
}
],
"storageKey": null
@@ -146,16 +137,16 @@ return {
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "5ebe3d38712b444c98c08661b7431da3",
"cacheID": "4a58a30780331c2d00bab2c3b613635b",
"id": null,
"metadata": {},
"name": "UpdateMitigationViewUpdateMitigationMutation",
"operationKind": "mutation",
"text": "mutation UpdateMitigationViewUpdateMitigationMutation(\n $input: UpdateMitigationInput!\n) {\n updateMitigation(input: $input) {\n mitigation {\n id\n name\n description\n category\n importance\n state\n version\n }\n }\n}\n"
"text": "mutation UpdateMitigationViewUpdateMitigationMutation(\n $input: UpdateMitigationInput!\n) {\n updateMitigation(input: $input) {\n mitigation {\n id\n name\n description\n category\n importance\n state\n }\n }\n}\n"
}
};
})();
(node as any).hash = "c68d76d527359d182749b309d2d8d6dd";
(node as any).hash = "b8cf81c9342fe42160ee39f572b01b24";
export default node;

View File

@@ -37,7 +37,6 @@ const peopleViewQuery = graphql`
kind
createdAt
updatedAt
version
}
}
}
@@ -53,7 +52,6 @@ const updatePeopleMutation = graphql`
additionalEmailAddresses
kind
updatedAt
version
}
}
}
@@ -114,7 +112,6 @@ function PeopleViewContent({
variables: {
input: {
id: data.node.id,
expectedVersion: data.node.version,
...formData,
},
},
@@ -144,7 +141,7 @@ function PeopleViewContent({
}
},
});
}, [commit, data.node.id, data.node.version, formData, loadQuery, toast]);
}, [commit, data.node.id, formData, loadQuery, toast]);
const handleFieldChange = (field: keyof typeof formData, value: unknown) => {
setFormData((prev) => ({

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<207a779cf8cbf3e42191be9825d4b653>>
* @generated SignedSource<<e7d3adf5f8472b181a64cfa98964984c>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -22,7 +22,6 @@ export type PeopleViewQuery$data = {
readonly kind?: PeopleKind;
readonly primaryEmailAddress?: string;
readonly updatedAt?: string;
readonly version?: number;
};
};
export type PeopleViewQuery = {
@@ -93,13 +92,6 @@ v8 = {
"kind": "ScalarField",
"name": "updatedAt",
"storageKey": null
},
v9 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
};
return {
"fragment": {
@@ -125,8 +117,7 @@ return {
(v5/*: any*/),
(v6/*: any*/),
(v7/*: any*/),
(v8/*: any*/),
(v9/*: any*/)
(v8/*: any*/)
],
"type": "People",
"abstractKey": null
@@ -168,8 +159,7 @@ return {
(v5/*: any*/),
(v6/*: any*/),
(v7/*: any*/),
(v8/*: any*/),
(v9/*: any*/)
(v8/*: any*/)
],
"type": "People",
"abstractKey": null
@@ -180,16 +170,16 @@ return {
]
},
"params": {
"cacheID": "c392876240212ba16428ae5edb843d47",
"cacheID": "fba00a5764659b366e4e11829d75854d",
"id": null,
"metadata": {},
"name": "PeopleViewQuery",
"operationKind": "query",
"text": "query PeopleViewQuery(\n $peopleId: ID!\n) {\n node(id: $peopleId) {\n __typename\n ... on People {\n id\n fullName\n primaryEmailAddress\n additionalEmailAddresses\n kind\n createdAt\n updatedAt\n version\n }\n id\n }\n}\n"
"text": "query PeopleViewQuery(\n $peopleId: ID!\n) {\n node(id: $peopleId) {\n __typename\n ... on People {\n id\n fullName\n primaryEmailAddress\n additionalEmailAddresses\n kind\n createdAt\n updatedAt\n }\n id\n }\n}\n"
}
};
})();
(node as any).hash = "4fc97d6cd7fc4590b7be7b5a79ae7ab0";
(node as any).hash = "b7652de1ad8de6028f493255221f6ce5";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<c1c3f4fa54eb6e43c52b088d2b872fee>>
* @generated SignedSource<<552b78c5e34c5ce2065dd1190f47f632>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -12,7 +12,6 @@ import { ConcreteRequest } from 'relay-runtime';
export type PeopleKind = "CONTRACTOR" | "EMPLOYEE" | "SERVICE_ACCOUNT";
export type UpdatePeopleInput = {
additionalEmailAddresses?: ReadonlyArray<string> | null | undefined;
expectedVersion: number;
fullName?: string | null | undefined;
id: string;
kind?: PeopleKind | null | undefined;
@@ -30,7 +29,6 @@ export type PeopleViewUpdatePeopleMutation$data = {
readonly kind: PeopleKind;
readonly primaryEmailAddress: string;
readonly updatedAt: string;
readonly version: number;
};
};
};
@@ -111,13 +109,6 @@ v1 = [
"kind": "ScalarField",
"name": "updatedAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
}
],
"storageKey": null
@@ -144,16 +135,16 @@ return {
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "96bba526a231dd76ef58d32ec01aac3a",
"cacheID": "d09fc02a745b951e278cd492343e49f1",
"id": null,
"metadata": {},
"name": "PeopleViewUpdatePeopleMutation",
"operationKind": "mutation",
"text": "mutation PeopleViewUpdatePeopleMutation(\n $input: UpdatePeopleInput!\n) {\n updatePeople(input: $input) {\n people {\n id\n fullName\n primaryEmailAddress\n additionalEmailAddresses\n kind\n updatedAt\n version\n }\n }\n}\n"
"text": "mutation PeopleViewUpdatePeopleMutation(\n $input: UpdatePeopleInput!\n) {\n updatePeople(input: $input) {\n people {\n id\n fullName\n primaryEmailAddress\n additionalEmailAddresses\n kind\n updatedAt\n }\n }\n}\n"
}
};
})();
(node as any).hash = "957952927fbe2337a180599f34ce961c";
(node as any).hash = "15fece3e846bd713533b9e91a1ceffe2";
export default node;

View File

@@ -30,7 +30,6 @@ const UpdatePolicyViewQuery = graphql`
name
content
status
version
reviewDate
owner {
id
@@ -52,7 +51,6 @@ const UpdatePolicyMutation = graphql`
name
content
status
version
reviewDate
owner {
id
@@ -115,7 +113,6 @@ function UpdatePolicyViewContent({
status,
reviewDate: reviewDateValue,
ownerId,
expectedVersion: data.policy.version!,
},
},
onCompleted: (response, errors) => {

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<9a97197f1f0eec8c00d0a58e0b07e8bc>>
* @generated SignedSource<<efc33f8979f142c09b65b2bd1d6e06be>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -12,7 +12,6 @@ import { ConcreteRequest } from 'relay-runtime';
export type PolicyStatus = "ACTIVE" | "DRAFT";
export type UpdatePolicyInput = {
content?: string | null | undefined;
expectedVersion: number;
id: string;
name?: string | null | undefined;
ownerId?: string | null | undefined;
@@ -34,7 +33,6 @@ export type UpdatePolicyViewMutation$data = {
};
readonly reviewDate: string | null | undefined;
readonly status: PolicyStatus;
readonly version: number;
};
};
};
@@ -103,13 +101,6 @@ v2 = [
"name": "status",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
},
{
"alias": null,
"args": null,
@@ -161,16 +152,16 @@ return {
"selections": (v2/*: any*/)
},
"params": {
"cacheID": "1ba586009eaf6e79dd2ab5862856cc63",
"cacheID": "aae664c7d961ad4e17c8e37464a34865",
"id": null,
"metadata": {},
"name": "UpdatePolicyViewMutation",
"operationKind": "mutation",
"text": "mutation UpdatePolicyViewMutation(\n $input: UpdatePolicyInput!\n) {\n updatePolicy(input: $input) {\n policy {\n id\n name\n content\n status\n version\n reviewDate\n owner {\n id\n fullName\n }\n }\n }\n}\n"
"text": "mutation UpdatePolicyViewMutation(\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"
}
};
})();
(node as any).hash = "47570dfcceba283c51a4ef2f88143d39";
(node as any).hash = "d0f7b9d21b450416900ccb46439e2894";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<b3ede0dedb94e95e89f0d67715a536b3>>
* @generated SignedSource<<e3772627b3bf7e5938d48808edd9fcb8>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -29,7 +29,6 @@ export type UpdatePolicyViewQuery$data = {
};
readonly reviewDate?: string | null | undefined;
readonly status?: PolicyStatus;
readonly version?: number;
};
};
export type UpdatePolicyViewQuery = {
@@ -93,13 +92,6 @@ v5 = {
"name": "status",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
},
{
"alias": null,
"args": null,
@@ -328,16 +320,16 @@ return {
]
},
"params": {
"cacheID": "16bd0bbc57d75f5c4d40eccd560b3da5",
"cacheID": "b7958bceabdd33c39fb403bdc6dbd85e",
"id": null,
"metadata": {},
"name": "UpdatePolicyViewQuery",
"operationKind": "query",
"text": "query UpdatePolicyViewQuery(\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 version\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 UpdatePolicyViewQuery(\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"
}
};
})();
(node as any).hash = "1494ae295ead283c9784cc748c5536f7";
(node as any).hash = "d29279c14662125a7fb14fa4da857f2b";
export default node;

View File

@@ -36,7 +36,6 @@ const vendorViewQuery = graphql`
privacyPolicyUrl
createdAt
updatedAt
version
}
}
}
@@ -57,7 +56,6 @@ const updateVendorMutation = graphql`
termsOfServiceUrl
privacyPolicyUrl
updatedAt
version
}
}
}
@@ -145,7 +143,6 @@ function VendorViewContent({
variables: {
input: {
id: data.node.id,
expectedVersion: data.node.version,
...formattedData,
},
},
@@ -176,7 +173,7 @@ function VendorViewContent({
}
},
});
}, [commit, data.node.id, data.node.version, formData, loadQuery, toast]);
}, [commit, data.node.id, formData, loadQuery, toast]);
const handleFieldChange = (field: keyof typeof formData, value: unknown) => {
setFormData((prev) => ({

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<dd3ffb0b93fc3b99db6d95ae1074922b>>
* @generated SignedSource<<61507551e23b8cc70b401cab8ae4e575>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -28,7 +28,6 @@ export type VendorViewQuery$data = {
readonly statusPageUrl?: string | null | undefined;
readonly termsOfServiceUrl?: string | null | undefined;
readonly updatedAt?: string;
readonly version?: number;
};
};
export type VendorViewQuery = {
@@ -134,13 +133,6 @@ v13 = {
"kind": "ScalarField",
"name": "updatedAt",
"storageKey": null
},
v14 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
};
return {
"fragment": {
@@ -171,8 +163,7 @@ return {
(v10/*: any*/),
(v11/*: any*/),
(v12/*: any*/),
(v13/*: any*/),
(v14/*: any*/)
(v13/*: any*/)
],
"type": "Vendor",
"abstractKey": null
@@ -219,8 +210,7 @@ return {
(v10/*: any*/),
(v11/*: any*/),
(v12/*: any*/),
(v13/*: any*/),
(v14/*: any*/)
(v13/*: any*/)
],
"type": "Vendor",
"abstractKey": null
@@ -231,16 +221,16 @@ return {
]
},
"params": {
"cacheID": "3569222e84bb1fa070b4ce2145d677ac",
"cacheID": "40428ff15eb094ffe4cb5ffb5d135cc1",
"id": null,
"metadata": {},
"name": "VendorViewQuery",
"operationKind": "query",
"text": "query VendorViewQuery(\n $vendorId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n createdAt\n updatedAt\n version\n }\n id\n }\n}\n"
"text": "query VendorViewQuery(\n $vendorId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n createdAt\n updatedAt\n }\n id\n }\n}\n"
}
};
})();
(node as any).hash = "9cdc25f48997786054c22246fb417db8";
(node as any).hash = "dbef9acdc02dd7e8cd546c0bb8793b9a";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<8799e334baf7ee70b0a03519f6da8f97>>
* @generated SignedSource<<7568e87d53b6e76d1db4e3029430f118>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -13,7 +13,6 @@ export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT";
export type ServiceCriticality = "HIGH" | "LOW" | "MEDIUM";
export type UpdateVendorInput = {
description?: string | null | undefined;
expectedVersion: number;
id: string;
name?: string | null | undefined;
privacyPolicyUrl?: string | null | undefined;
@@ -41,7 +40,6 @@ export type VendorViewUpdateVendorMutation$data = {
readonly statusPageUrl: string | null | undefined;
readonly termsOfServiceUrl: string | null | undefined;
readonly updatedAt: string;
readonly version: number;
};
};
};
@@ -157,13 +155,6 @@ v1 = [
"kind": "ScalarField",
"name": "updatedAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "version",
"storageKey": null
}
],
"storageKey": null
@@ -190,16 +181,16 @@ return {
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "d6de753f4ecc8f59921e246e178bf8a0",
"cacheID": "1a49efe0fe5e3da519e1b15a8f81cc1e",
"id": null,
"metadata": {},
"name": "VendorViewUpdateVendorMutation",
"operationKind": "mutation",
"text": "mutation VendorViewUpdateVendorMutation(\n $input: UpdateVendorInput!\n) {\n updateVendor(input: $input) {\n vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n updatedAt\n version\n }\n }\n}\n"
"text": "mutation VendorViewUpdateVendorMutation(\n $input: UpdateVendorInput!\n) {\n updateVendor(input: $input) {\n vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n updatedAt\n }\n }\n}\n"
}
};
})();
(node as any).hash = "836cf8657449473503596456b8deb873";
(node as any).hash = "15ffa38b13259f9c7c6511aa72d07247";
export default node;