First step of mitigation migration
Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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 "
|
||||
{framework.name}"? 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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
132
apps/console/src/pages/organizations/frameworks/__generated__/FrameworkViewDeleteMutation.graphql.ts
generated
Normal file
132
apps/console/src/pages/organizations/frameworks/__generated__/FrameworkViewDeleteMutation.graphql.ts
generated
Normal 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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
}
|
||||
>
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) => ({
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) => ({
|
||||
|
||||
22
apps/console/src/pages/organizations/vendors/__generated__/VendorViewQuery.graphql.ts
generated
vendored
22
apps/console/src/pages/organizations/vendors/__generated__/VendorViewQuery.graphql.ts
generated
vendored
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user