Rename mitigation into mesure

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-04-12 21:09:49 -07:00
parent daff5e6670
commit 3711bb4bbb
80 changed files with 3397 additions and 3472 deletions

View File

@@ -134,10 +134,10 @@ export function NavMain() {
function getNavItems(organizationId?: string): NavItem[] {
return [
{
title: "Mitigations",
title: "Mesures",
icon: ClipboardList,
url: organizationId
? `/organizations/${organizationId}/mitigations`
? `/organizations/${organizationId}/mesures`
: undefined,
},
{

View File

@@ -69,7 +69,7 @@ const SidebarProvider = React.forwardRef<
const [openMobile, setOpenMobile] = React.useState(false);
// This is the internal state of the sidebar.
// We use openProp and setOpenProp for mitigation from outside the component.
// We use openProp and setOpenProp for mesure from outside the component.
const [_open, _setOpen] = React.useState(defaultOpen);
const open = openProp ?? _open;
const setOpen = React.useCallback(

View File

@@ -2,5 +2,5 @@ import { Navigate, useParams } from "react-router";
export default function HomePage() {
const { organizationId } = useParams();
return <Navigate to={`/organizations/${organizationId}/mitigations`} />;
return <Navigate to={`/organizations/${organizationId}/mesures`} />;
}

View File

@@ -16,7 +16,7 @@ import { OrganizationBreadcrumbBreadcrumbPeopleOverviewQuery } from "./__generat
import { OrganizationBreadcrumbBreadcrumbPolicyOverviewQuery } from "./__generated__/OrganizationBreadcrumbBreadcrumbPolicyOverviewQuery.graphql";
import { OrganizationBreadcrumbBreadcrumbVendorOverviewQuery } from "./__generated__/OrganizationBreadcrumbBreadcrumbVendorOverviewQuery.graphql";
import { OrganizationBreadcrumbOrganizationQuery } from "./__generated__/OrganizationBreadcrumbOrganizationQuery.graphql";
import { OrganizationBreadcrumbBreadcrumbMitigationViewQuery } from "./__generated__/OrganizationBreadcrumbBreadcrumbMitigationViewQuery.graphql";
import { OrganizationBreadcrumbBreadcrumbMesureViewQuery } from "./__generated__/OrganizationBreadcrumbBreadcrumbMesureViewQuery.graphql";
import { OrganizationBreadcrumbBreadcrumbControlQuery } from "./__generated__/OrganizationBreadcrumbBreadcrumbControlQuery.graphql";
import { OrganizationBreadcrumbBreadcrumbRiskShowQuery } from "./__generated__/OrganizationBreadcrumbBreadcrumbRiskShowQuery.graphql";
import ErrorBoundary from "@/components/ErrorBoundary";
@@ -314,15 +314,15 @@ function BreadcrumbPolicyOverview() {
);
}
function BreadcrumbMitigationList() {
function BreadcrumbMesureList() {
const { organizationId } = useParams();
return (
<>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbNavLink to={`/organizations/${organizationId}/mitigations`}>
Mitigations
<BreadcrumbNavLink to={`/organizations/${organizationId}/mesures`}>
Mesures
</BreadcrumbNavLink>
</BreadcrumbItem>
<Outlet />
@@ -330,24 +330,22 @@ function BreadcrumbMitigationList() {
);
}
function BreadcrumbMitigationView() {
const { organizationId, mitigationId } = useParams();
function BreadcrumbMesureView() {
const { organizationId, mesureId } = useParams();
const data =
useLazyLoadQuery<OrganizationBreadcrumbBreadcrumbMitigationViewQuery>(
useLazyLoadQuery<OrganizationBreadcrumbBreadcrumbMesureViewQuery>(
graphql`
query OrganizationBreadcrumbBreadcrumbMitigationViewQuery(
$mitigationId: ID!
) {
mitigation: node(id: $mitigationId) {
query OrganizationBreadcrumbBreadcrumbMesureViewQuery($mesureId: ID!) {
mesure: node(id: $mesureId) {
id
... on Mitigation {
... on Mesure {
name
category
}
}
}
`,
{ mitigationId: mitigationId! }
{ mesureId: mesureId! }
);
return (
@@ -355,17 +353,17 @@ function BreadcrumbMitigationView() {
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbNavLink
to={`/organizations/${organizationId}/mitigations#${data.mitigation.category}`}
to={`/organizations/${organizationId}/mesures#${data.mesure.category}`}
>
{data.mitigation.category}
{data.mesure.category}
</BreadcrumbNavLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbNavLink
to={`/organizations/${organizationId}/mitigations/${mitigationId}`}
to={`/organizations/${organizationId}/mesures/${mesureId}`}
>
{data.mitigation.name}
{data.mesure.name}
</BreadcrumbNavLink>
</BreadcrumbItem>
<Outlet />
@@ -463,13 +461,13 @@ export function BreadCrumb() {
</ErrorBoundary>
}
>
<Route path="mitigations" element={<BreadcrumbMitigationList />}>
<Route path="mesures" element={<BreadcrumbMesureList />}>
<Route path="new" element={<New />} />
<Route
path=":mitigationId"
path=":mesureId"
element={
<Suspense>
<BreadcrumbMitigationView />
<BreadcrumbMesureView />
</Suspense>
}
>

View File

@@ -11,10 +11,10 @@ import { FrameworkListPage } from "./frameworks/FrameworkListPage";
import { FrameworkPage } from "./frameworks/FrameworkPage";
import { NewFrameworkPage } from "./frameworks/NewFrameworkPage";
import { ControlPage } from "./frameworks/controls/ControlPage";
import { EditMitigationPage } from "./mitigations/EditMitigationPage";
import { MitigationListPage } from "./mitigations/MitigationListPage";
import { MitigationPage } from "./mitigations/MitigationPage";
import { NewMitigationPage } from "./mitigations/NewMitigationPage";
import { EditMesurePage } from "./mesures/EditMesurePage";
import { MesureListPage } from "./mesures/MesureListPage";
import { MesurePage } from "./mesures/MesurePage";
import { NewMesurePage } from "./mesures/NewMesurePage";
import { NewPeoplePage } from "./people/NewPeoplePage";
import { PeopleListPage } from "./people/PeopleListPage";
import { PeoplePage } from "./people/PeoplePage";
@@ -48,13 +48,10 @@ export function OrganizationsRoutes() {
<Route path="edit" element={<EditFrameworkPage />} />
<Route path="*" element={<NotFoundPage />} />
</Route>
<Route path="mitigations" element={<MitigationListPage />} />
<Route path="mitigations/new" element={<NewMitigationPage />} />
<Route path="mitigations/:mitigationId" element={<MitigationPage />} />
<Route
path="mitigations/:mitigationId/edit"
element={<EditMitigationPage />}
/>
<Route path="mesures" element={<MesureListPage />} />
<Route path="mesures/new" element={<NewMesurePage />} />
<Route path="mesures/:mesureId" element={<MesurePage />} />
<Route path="mesures/:mesureId/edit" element={<EditMesurePage />} />
<Route path="vendors/:vendorId" element={<VendorPage />} />
<Route path="policies" element={<PolicyListPage />} />
<Route path="policies/new" element={<NewPolicyPage />} />

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<5297fe6c58e18534c0e9684cfea6b319>>
* @generated SignedSource<<a8e66e7606187f54d173cddac8bcd316>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,19 +9,19 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type OrganizationBreadcrumbBreadcrumbMitigationViewQuery$variables = {
mitigationId: string;
export type OrganizationBreadcrumbBreadcrumbMesureViewQuery$variables = {
mesureId: string;
};
export type OrganizationBreadcrumbBreadcrumbMitigationViewQuery$data = {
readonly mitigation: {
export type OrganizationBreadcrumbBreadcrumbMesureViewQuery$data = {
readonly mesure: {
readonly category?: string;
readonly id: string;
readonly name?: string;
};
};
export type OrganizationBreadcrumbBreadcrumbMitigationViewQuery = {
response: OrganizationBreadcrumbBreadcrumbMitigationViewQuery$data;
variables: OrganizationBreadcrumbBreadcrumbMitigationViewQuery$variables;
export type OrganizationBreadcrumbBreadcrumbMesureViewQuery = {
response: OrganizationBreadcrumbBreadcrumbMesureViewQuery$data;
variables: OrganizationBreadcrumbBreadcrumbMesureViewQuery$variables;
};
const node: ConcreteRequest = (function(){
@@ -29,14 +29,14 @@ var v0 = [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "mitigationId"
"name": "mesureId"
}
],
v1 = [
{
"kind": "Variable",
"name": "id",
"variableName": "mitigationId"
"variableName": "mesureId"
}
],
v2 = {
@@ -64,7 +64,7 @@ v3 = {
"storageKey": null
}
],
"type": "Mitigation",
"type": "Mesure",
"abstractKey": null
};
return {
@@ -72,10 +72,10 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "OrganizationBreadcrumbBreadcrumbMitigationViewQuery",
"name": "OrganizationBreadcrumbBreadcrumbMesureViewQuery",
"selections": [
{
"alias": "mitigation",
"alias": "mesure",
"args": (v1/*: any*/),
"concreteType": null,
"kind": "LinkedField",
@@ -95,10 +95,10 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "OrganizationBreadcrumbBreadcrumbMitigationViewQuery",
"name": "OrganizationBreadcrumbBreadcrumbMesureViewQuery",
"selections": [
{
"alias": "mitigation",
"alias": "mesure",
"args": (v1/*: any*/),
"concreteType": null,
"kind": "LinkedField",
@@ -120,16 +120,16 @@ return {
]
},
"params": {
"cacheID": "dcc05f69cfc1d38fae2488aa4740f109",
"cacheID": "f6183e3013438a1cff8e91c6ff80f452",
"id": null,
"metadata": {},
"name": "OrganizationBreadcrumbBreadcrumbMitigationViewQuery",
"name": "OrganizationBreadcrumbBreadcrumbMesureViewQuery",
"operationKind": "query",
"text": "query OrganizationBreadcrumbBreadcrumbMitigationViewQuery(\n $mitigationId: ID!\n) {\n mitigation: node(id: $mitigationId) {\n __typename\n id\n ... on Mitigation {\n name\n category\n }\n }\n}\n"
"text": "query OrganizationBreadcrumbBreadcrumbMesureViewQuery(\n $mesureId: ID!\n) {\n mesure: node(id: $mesureId) {\n __typename\n id\n ... on Mesure {\n name\n category\n }\n }\n}\n"
}
};
})();
(node as any).hash = "0b8d38ad84bd4c5a684711285c29e5a4";
(node as any).hash = "67fd3d426bbfcbe90457c3033dade1b3";
export default node;

View File

@@ -10,7 +10,7 @@ export function NewFrameworkViewSkeleton() {
return (
<PageTemplateSkeleton
title="Create Framework"
description="Create a new framework to organize your mitigations"
description="Create a new framework to organize your mesures"
>
<div className="max-w-2xl aspect-square bg-subtle-bg rounded-xl animate-pulse" />
</PageTemplateSkeleton>

View File

@@ -170,7 +170,7 @@ function NewFrameworkViewContent() {
return (
<PageTemplate
title="Create Framework"
description="Create a new framework to organize your mitigations"
description="Create a new framework to organize your mesures"
>
<Card className="max-w-2xl">
<form onSubmit={handleSubmit} className="p-6 space-y-6">

View File

@@ -26,13 +26,13 @@ import {
} from "react-relay";
import { useParams, Link } from "react-router";
import {
ControlLinkedMitigationsQuery$data,
ControlLinkedMitigationsQuery,
} from "./__generated__/ControlLinkedMitigationsQuery.graphql";
ControlLinkedMesuresQuery$data,
ControlLinkedMesuresQuery,
} from "./__generated__/ControlLinkedMesuresQuery.graphql";
import {
ControlOrganizationMitigationsQuery$data,
ControlOrganizationMitigationsQuery,
} from "./__generated__/ControlOrganizationMitigationsQuery.graphql";
ControlOrganizationMesuresQuery$data,
ControlOrganizationMesuresQuery,
} from "./__generated__/ControlOrganizationMesuresQuery.graphql";
import { ControlFragment_Control$key } from "./__generated__/ControlFragment_Control.graphql";
import {
ControlLinkedPoliciesQuery$data,
@@ -52,13 +52,13 @@ const controlFragment = graphql`
}
`;
// New query to fetch linked mitigations
const linkedMitigationsQuery = graphql`
query ControlLinkedMitigationsQuery($controlId: ID!) {
// New query to fetch linked mesures
const linkedMesuresQuery = graphql`
query ControlLinkedMesuresQuery($controlId: ID!) {
control: node(id: $controlId) {
id
... on Control {
mitigations(first: 100) @connection(key: "Control__mitigations") {
mesures(first: 100) @connection(key: "Control__mesures") {
edges {
node {
id
@@ -75,13 +75,13 @@ const linkedMitigationsQuery = graphql`
}
`;
// Query to fetch all mitigations for the organization
const organizationMitigationsQuery = graphql`
query ControlOrganizationMitigationsQuery($organizationId: ID!) {
// Query to fetch all mesures for the organization
const organizationMesuresQuery = graphql`
query ControlOrganizationMesuresQuery($organizationId: ID!) {
organization: node(id: $organizationId) {
id
... on Organization {
mitigations(first: 100) @connection(key: "Organization__mitigations") {
mesures(first: 100) @connection(key: "Organization__mesures") {
edges {
node {
id
@@ -142,23 +142,23 @@ const organizationPoliciesQuery = graphql`
}
`;
// Mutation to create a mapping between a control and a mitigation
const createMitigationMappingMutation = graphql`
mutation ControlCreateMitigationMappingMutation(
$input: CreateControlMitigationMappingInput!
// Mutation to create a mapping between a control and a mesure
const createMesureMappingMutation = graphql`
mutation ControlCreateMesureMappingMutation(
$input: CreateControlMesureMappingInput!
) {
createControlMitigationMapping(input: $input) {
createControlMesureMapping(input: $input) {
success
}
}
`;
// Mutation to delete a mapping between a control and a mitigation
const deleteMitigationMappingMutation = graphql`
mutation ControlDeleteMitigationMappingMutation(
$input: DeleteControlMitigationMappingInput!
// Mutation to delete a mapping between a control and a mesure
const deleteMesureMappingMutation = graphql`
mutation ControlDeleteMesureMappingMutation(
$input: DeleteControlMesureMappingInput!
) {
deleteControlMitigationMapping(input: $input) {
deleteControlMesureMapping(input: $input) {
success
}
}
@@ -199,17 +199,17 @@ export function Control({
const { toast } = useToast();
const environment = useRelayEnvironment();
// State for mitigation mapping
const [isMitigationMappingDialogOpen, setIsMitigationMappingDialogOpen] =
// State for mesure mapping
const [isMesureMappingDialogOpen, setIsMesureMappingDialogOpen] =
useState(false);
const [linkedMitigationsData, setLinkedMitigationsData] =
useState<ControlLinkedMitigationsQuery$data | null>(null);
const [organizationMitigationsData, setOrganizationMitigationsData] =
useState<ControlOrganizationMitigationsQuery$data | null>(null);
const [mitigationSearchQuery, setMitigationSearchQuery] = useState("");
const [isLoadingMitigations, setIsLoadingMitigations] = useState(false);
const [isLinkingMitigation, setIsLinkingMitigation] = useState(false);
const [isUnlinkingMitigation, setIsUnlinkingMitigation] = useState(false);
const [linkedMesuresData, setLinkedMesuresData] =
useState<ControlLinkedMesuresQuery$data | null>(null);
const [organizationMesuresData, setOrganizationMesuresData] =
useState<ControlOrganizationMesuresQuery$data | null>(null);
const [mesureSearchQuery, setMesureSearchQuery] = useState("");
const [isLoadingMesures, setIsLoadingMesures] = useState(false);
const [isLinkingMesure, setIsLinkingMesure] = useState(false);
const [isUnlinkingMesure, setIsUnlinkingMesure] = useState(false);
const [categoryFilter, setCategoryFilter] = useState<string | null>(null);
// Policy state
@@ -225,85 +225,73 @@ export function Control({
const [isUnlinkingPolicy, setIsUnlinkingPolicy] = useState(false);
// Create mutation hooks
const [commitCreateMitigationMapping] = useMutation(
createMitigationMappingMutation
);
const [commitDeleteMitigationMapping] = useMutation(
deleteMitigationMappingMutation
);
const [commitCreateMesureMapping] = useMutation(createMesureMappingMutation);
const [commitDeleteMesureMapping] = useMutation(deleteMesureMappingMutation);
const [commitCreatePolicyMapping] = useMutation(createPolicyMappingMutation);
const [commitDeletePolicyMapping] = useMutation(deletePolicyMappingMutation);
// Load initial linked mitigations data
// Load initial linked mesures data
useEffect(() => {
if (control.id) {
setIsLoadingMitigations(true);
fetchQuery<ControlLinkedMitigationsQuery>(
environment,
linkedMitigationsQuery,
{
controlId: control.id,
}
).subscribe({
setIsLoadingMesures(true);
fetchQuery<ControlLinkedMesuresQuery>(environment, linkedMesuresQuery, {
controlId: control.id,
}).subscribe({
next: (data) => {
setLinkedMitigationsData(data);
setIsLoadingMitigations(false);
setLinkedMesuresData(data);
setIsLoadingMesures(false);
},
error: (error: Error) => {
console.error("Error loading initial mitigations:", error);
setIsLoadingMitigations(false);
console.error("Error loading initial mesures:", error);
setIsLoadingMesures(false);
},
});
}
}, [control.id, environment]);
// Load mitigations data
const loadMitigationsData = useCallback(() => {
// Load mesures data
const loadMesuresData = useCallback(() => {
if (!organizationId || !control.id) return;
setIsLoadingMitigations(true);
setIsLoadingMesures(true);
// Fetch all mitigations for the organization
fetchQuery<ControlOrganizationMitigationsQuery>(
// Fetch all mesures for the organization
fetchQuery<ControlOrganizationMesuresQuery>(
environment,
organizationMitigationsQuery,
organizationMesuresQuery,
{
organizationId,
}
).subscribe({
next: (data) => {
setOrganizationMitigationsData(data);
setOrganizationMesuresData(data);
},
complete: () => {
// Fetch linked mitigations for this control
fetchQuery<ControlLinkedMitigationsQuery>(
environment,
linkedMitigationsQuery,
{
controlId: control.id,
}
).subscribe({
// Fetch linked mesures for this control
fetchQuery<ControlLinkedMesuresQuery>(environment, linkedMesuresQuery, {
controlId: control.id,
}).subscribe({
next: (data) => {
setLinkedMitigationsData(data);
setIsLoadingMitigations(false);
setLinkedMesuresData(data);
setIsLoadingMesures(false);
},
error: (error: Error) => {
console.error("Error fetching linked mitigations:", error);
setIsLoadingMitigations(false);
console.error("Error fetching linked mesures:", error);
setIsLoadingMesures(false);
toast({
title: "Error",
description: "Failed to load linked mitigations.",
description: "Failed to load linked mesures.",
variant: "destructive",
});
},
});
},
error: (error: Error) => {
console.error("Error fetching organization mitigations:", error);
setIsLoadingMitigations(false);
console.error("Error fetching organization mesures:", error);
setIsLoadingMesures(false);
toast({
title: "Error",
description: "Failed to load mitigations.",
description: "Failed to load mesures.",
variant: "destructive",
});
},
@@ -311,197 +299,190 @@ export function Control({
}, [control.id, environment, organizationId, toast]);
// Helper functions
const getMitigations = useCallback(() => {
if (!organizationMitigationsData?.organization?.mitigations?.edges)
return [];
return organizationMitigationsData.organization.mitigations.edges.map(
const getMesures = useCallback(() => {
if (!organizationMesuresData?.organization?.mesures?.edges) return [];
return organizationMesuresData.organization.mesures.edges.map(
(edge) => edge.node
);
}, [organizationMitigationsData]);
}, [organizationMesuresData]);
const getLinkedMitigations = useCallback(() => {
if (!linkedMitigationsData?.control?.mitigations?.edges) return [];
return linkedMitigationsData.control.mitigations.edges.map(
(edge) => edge.node
);
}, [linkedMitigationsData]);
const getLinkedMesures = useCallback(() => {
if (!linkedMesuresData?.control?.mesures?.edges) return [];
return linkedMesuresData.control.mesures.edges.map((edge) => edge.node);
}, [linkedMesuresData]);
const isMitigationLinked = useCallback(
(mitigationId: string) => {
const linkedMitigations = getLinkedMitigations();
return linkedMitigations.some(
(mitigation) => mitigation.id === mitigationId
);
const isMesureLinked = useCallback(
(mesureId: string) => {
const linkedMesures = getLinkedMesures();
return linkedMesures.some((mesure) => mesure.id === mesureId);
},
[getLinkedMitigations]
[getLinkedMesures]
);
const getMitigationCategories = useCallback(() => {
const mitigations = getMitigations();
const getMesureCategories = useCallback(() => {
const mesures = getMesures();
const categories = new Set<string>();
mitigations.forEach((mitigation) => {
if (mitigation.category) {
categories.add(mitigation.category);
mesures.forEach((mesure) => {
if (mesure.category) {
categories.add(mesure.category);
}
});
return Array.from(categories).sort();
}, [getMitigations]);
}, [getMesures]);
const filteredMitigations = useCallback(() => {
const mitigations = getMitigations();
if (!mitigationSearchQuery && !categoryFilter) return mitigations;
const filteredMesures = useCallback(() => {
const mesures = getMesures();
if (!mesureSearchQuery && !categoryFilter) return mesures;
return mitigations.filter((mitigation) => {
return mesures.filter((mesure) => {
// Filter by search query
const matchesSearch =
!mitigationSearchQuery ||
mitigation.name
.toLowerCase()
.includes(mitigationSearchQuery.toLowerCase()) ||
(mitigation.description &&
mitigation.description
!mesureSearchQuery ||
mesure.name.toLowerCase().includes(mesureSearchQuery.toLowerCase()) ||
(mesure.description &&
mesure.description
.toLowerCase()
.includes(mitigationSearchQuery.toLowerCase()));
.includes(mesureSearchQuery.toLowerCase()));
// Filter by category
const matchesCategory =
!categoryFilter ||
categoryFilter === "all" ||
mitigation.category === categoryFilter;
mesure.category === categoryFilter;
return matchesSearch && matchesCategory;
});
}, [categoryFilter, getMitigations, mitigationSearchQuery]);
}, [categoryFilter, getMesures, mesureSearchQuery]);
// Handle link/unlink functions
const handleLinkMitigation = useCallback(
(mitigationId: string) => {
const handleLinkMesure = useCallback(
(mesureId: string) => {
if (!control.id) return;
setIsLinkingMitigation(true);
setIsLinkingMesure(true);
commitCreateMitigationMapping({
commitCreateMesureMapping({
variables: {
input: {
controlId: control.id,
mitigationId: mitigationId,
mesureId: mesureId,
},
},
onCompleted: (_, errors) => {
setIsLinkingMitigation(false);
setIsLinkingMesure(false);
if (errors) {
console.error("Error linking mitigation:", errors);
console.error("Error linking mesure:", errors);
toast({
title: "Error",
description: "Failed to link mitigation. Please try again.",
description: "Failed to link mesure. Please try again.",
variant: "destructive",
});
return;
}
// Refresh linked mitigations data
fetchQuery<ControlLinkedMitigationsQuery>(
// Refresh linked mesures data
fetchQuery<ControlLinkedMesuresQuery>(
environment,
linkedMitigationsQuery,
linkedMesuresQuery,
{
controlId: control.id,
}
).subscribe({
next: (data) => {
setLinkedMitigationsData(data);
setLinkedMesuresData(data);
},
error: (error: Error) => {
console.error("Error refreshing linked mitigations:", error);
console.error("Error refreshing linked mesures:", error);
},
});
toast({
title: "Success",
description: "Mitigation successfully linked to control.",
description: "Mesure successfully linked to control.",
});
},
onError: (error) => {
setIsLinkingMitigation(false);
console.error("Error linking mitigation:", error);
setIsLinkingMesure(false);
console.error("Error linking mesure:", error);
toast({
title: "Error",
description: "Failed to link mitigation. Please try again.",
description: "Failed to link mesure. Please try again.",
variant: "destructive",
});
},
});
},
[commitCreateMitigationMapping, control.id, environment, toast]
[commitCreateMesureMapping, control.id, environment, toast]
);
const handleUnlinkMitigation = useCallback(
(mitigationId: string) => {
const handleUnlinkMesure = useCallback(
(mesureId: string) => {
if (!control.id) return;
setIsUnlinkingMitigation(true);
setIsUnlinkingMesure(true);
commitDeleteMitigationMapping({
commitDeleteMesureMapping({
variables: {
input: {
controlId: control.id,
mitigationId: mitigationId,
mesureId: mesureId,
},
},
onCompleted: (_, errors) => {
setIsUnlinkingMitigation(false);
setIsUnlinkingMesure(false);
if (errors) {
console.error("Error unlinking mitigation:", errors);
console.error("Error unlinking mesure:", errors);
toast({
title: "Error",
description: "Failed to unlink mitigation. Please try again.",
description: "Failed to unlink mesure. Please try again.",
variant: "destructive",
});
return;
}
// Refresh linked mitigations data
fetchQuery<ControlLinkedMitigationsQuery>(
// Refresh linked mesures data
fetchQuery<ControlLinkedMesuresQuery>(
environment,
linkedMitigationsQuery,
linkedMesuresQuery,
{
controlId: control.id,
}
).subscribe({
next: (data) => {
setLinkedMitigationsData(data);
setLinkedMesuresData(data);
},
error: (error: Error) => {
console.error("Error refreshing linked mitigations:", error);
console.error("Error refreshing linked mesures:", error);
},
});
toast({
title: "Success",
description: "Mitigation successfully unlinked from control.",
description: "Mesure successfully unlinked from control.",
});
},
onError: (error) => {
setIsUnlinkingMitigation(false);
console.error("Error unlinking mitigation:", error);
setIsUnlinkingMesure(false);
console.error("Error unlinking mesure:", error);
toast({
title: "Error",
description: "Failed to unlink mitigation. Please try again.",
description: "Failed to unlink mesure. Please try again.",
variant: "destructive",
});
},
});
},
[commitDeleteMitigationMapping, control.id, environment, toast]
[commitDeleteMesureMapping, control.id, environment, toast]
);
const handleOpenMitigationMappingDialog = useCallback(() => {
loadMitigationsData();
setIsMitigationMappingDialogOpen(true);
}, [loadMitigationsData]);
const handleOpenMesureMappingDialog = useCallback(() => {
loadMesuresData();
setIsMesureMappingDialogOpen(true);
}, [loadMesuresData]);
// Load initial linked policies data
useEffect(() => {
@@ -824,10 +805,10 @@ export function Control({
{/* Security Measures Section */}
<div className="mt-8">
{/* Mitigation Mapping Dialog */}
{/* Mesure Mapping Dialog */}
<Dialog
open={isMitigationMappingDialogOpen}
onOpenChange={setIsMitigationMappingDialogOpen}
open={isMesureMappingDialogOpen}
onOpenChange={setIsMesureMappingDialogOpen}
>
<DialogContent className="max-w-3xl max-h-[80vh] overflow-hidden flex flex-col">
<DialogHeader>
@@ -844,8 +825,8 @@ export function Control({
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-tertiary" />
<Input
placeholder="Search security measures by name or description..."
value={mitigationSearchQuery}
onChange={(e) => setMitigationSearchQuery(e.target.value)}
value={mesureSearchQuery}
onChange={(e) => setMesureSearchQuery(e.target.value)}
className="w-full pl-10"
/>
</div>
@@ -862,7 +843,7 @@ export function Control({
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All categories</SelectItem>
{getMitigationCategories().map((category) => (
{getMesureCategories().map((category) => (
<SelectItem key={category} value={category}>
{category}
</SelectItem>
@@ -873,14 +854,14 @@ export function Control({
</div>
<div className="flex-1 overflow-hidden">
{isLoadingMitigations ? (
{isLoadingMesures ? (
<div className="flex items-center justify-center h-full">
<Loader2 className="w-8 h-8 animate-spin text-info" />
<span className="ml-2">Loading security measures...</span>
</div>
) : (
<div className="max-h-[50vh] overflow-y-auto pr-2">
{filteredMitigations().length === 0 ? (
{filteredMesures().length === 0 ? (
<div className="text-center py-8 text-secondary">
No security measures found. Try adjusting your search or
select a different category.
@@ -900,39 +881,39 @@ export function Control({
</tr>
</thead>
<tbody>
{filteredMitigations().map((mitigation) => {
const isLinked = isMitigationLinked(mitigation.id);
{filteredMesures().map((mesure) => {
const isLinked = isMesureLinked(mesure.id);
return (
<tr
key={mitigation.id}
key={mesure.id}
className="border-b hover:bg-invert-bg"
>
<td className="py-3 px-4">
<div className="font-medium">
{mitigation.name}
{mesure.name}
</div>
{mitigation.description && (
{mesure.description && (
<div className="text-xs text-secondary line-clamp-1 mt-0.5">
{mitigation.description}
{mesure.description}
</div>
)}
</td>
<td className="py-3 px-4">
<div
className={`px-2 py-0.5 rounded-full text-xs ${getImportanceColor(
mitigation.importance
mesure.importance
)} inline-block`}
>
{formatImportance(mitigation.importance)}
{formatImportance(mesure.importance)}
</div>
</td>
<td className="py-3 px-4">
<div
className={`px-2 py-0.5 rounded-full text-xs ${getStateColor(
mitigation.state
mesure.state
)} inline-block`}
>
{formatState(mitigation.state)}
{formatState(mesure.state)}
</div>
</td>
<td className="py-3 px-4 text-right whitespace-nowrap">
@@ -941,12 +922,12 @@ export function Control({
variant="outline"
size="sm"
onClick={() =>
handleUnlinkMitigation(mitigation.id)
handleUnlinkMesure(mesure.id)
}
disabled={isUnlinkingMitigation}
disabled={isUnlinkingMesure}
className="text-xs h-7 text-danger border-danger-b hover:bg-h-danger-bg"
>
{isUnlinkingMitigation ? (
{isUnlinkingMesure ? (
<Loader2 className="w-4 h-4 animate-spin" />
) : (
<X className="w-4 h-4" />
@@ -958,12 +939,12 @@ export function Control({
variant="secondary"
size="sm"
onClick={() =>
handleLinkMitigation(mitigation.id)
handleLinkMesure(mesure.id)
}
disabled={isLinkingMitigation}
disabled={isLinkingMesure}
className="text-xs h-7 text-info border-info-b hover:bg-h-info-bg"
>
{isLinkingMitigation ? (
{isLinkingMesure ? (
<Loader2 className="w-4 h-4 animate-spin" />
) : (
<LinkIcon className="w-4 h-4" />
@@ -983,14 +964,14 @@ export function Control({
</div>
<DialogFooter className="mt-4">
<Button onClick={() => setIsMitigationMappingDialogOpen(false)}>
<Button onClick={() => setIsMesureMappingDialogOpen(false)}>
Close
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
{/* Linked Mitigations List */}
{/* Linked Mesures List */}
<div>
<div className="flex justify-between items-center mb-4">
<h3 className="text-xl font-medium text-secondary">
@@ -1000,20 +981,20 @@ export function Control({
variant="outline"
size="sm"
className="flex items-center gap-1"
onClick={handleOpenMitigationMappingDialog}
onClick={handleOpenMesureMappingDialog}
>
<LinkIcon className="w-4 h-4" />
<span>Link Security Measures</span>
</Button>
</div>
{isLoadingMitigations ? (
{isLoadingMesures ? (
<div className="flex items-center justify-center h-24">
<Loader2 className="w-6 h-6 animate-spin text-info" />
<span className="ml-2">Loading security measures...</span>
</div>
) : linkedMitigationsData?.control?.mitigations?.edges &&
linkedMitigationsData.control.mitigations.edges.length > 0 ? (
) : linkedMesuresData?.control?.mesures?.edges &&
linkedMesuresData.control.mesures.edges.length > 0 ? (
<div className="overflow-x-auto border rounded-md">
<table className="w-full">
<thead>
@@ -1027,35 +1008,35 @@ export function Control({
</tr>
</thead>
<tbody>
{getLinkedMitigations().map((mitigation) => (
{getLinkedMesures().map((mesure) => (
<tr
key={mitigation.id}
key={mesure.id}
className="border-b hover:bg-invert-bg"
>
<td className="py-3 px-4">
<div className="font-medium">{mitigation.name}</div>
{mitigation.description && (
<div className="font-medium">{mesure.name}</div>
{mesure.description && (
<div className="text-xs text-secondary line-clamp-1 mt-0.5">
{mitigation.description}
{mesure.description}
</div>
)}
</td>
<td className="py-3 px-4">
<div
className={`px-2 py-0.5 rounded-full text-xs ${getImportanceColor(
mitigation.importance
mesure.importance
)} inline-block`}
>
{formatImportance(mitigation.importance)}
{formatImportance(mesure.importance)}
</div>
</td>
<td className="py-3 px-4">
<div
className={`px-2 py-0.5 rounded-full text-xs ${getStateColor(
mitigation.state
mesure.state
)} inline-block`}
>
{formatState(mitigation.state)}
{formatState(mesure.state)}
</div>
</td>
<td className="py-3 px-4 text-right whitespace-nowrap">
@@ -1067,7 +1048,7 @@ export function Control({
className="text-xs h-7"
>
<Link
to={`/organizations/${organizationId}/mitigations/${mitigation.id}`}
to={`/organizations/${organizationId}/mesures/${mesure.id}`}
>
View
</Link>
@@ -1075,10 +1056,8 @@ export function Control({
<Button
variant="outline"
size="sm"
onClick={() =>
handleUnlinkMitigation(mitigation.id)
}
disabled={isUnlinkingMitigation}
onClick={() => handleUnlinkMesure(mesure.id)}
disabled={isUnlinkingMesure}
className="text-xs h-7 text-danger border-danger-b hover:bg-h-danger-bg"
>
Unlink

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<53f255c3852774870c7d294d64e6808d>>
* @generated SignedSource<<aad63785dac93ad7f8db05ee4f219109>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,21 +9,21 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type CreateControlMitigationMappingInput = {
export type CreateControlMesureMappingInput = {
controlId: string;
mitigationId: string;
mesureId: string;
};
export type MitigationViewCreateControlMappingMutation$variables = {
input: CreateControlMitigationMappingInput;
export type ControlCreateMesureMappingMutation$variables = {
input: CreateControlMesureMappingInput;
};
export type MitigationViewCreateControlMappingMutation$data = {
readonly createControlMitigationMapping: {
export type ControlCreateMesureMappingMutation$data = {
readonly createControlMesureMapping: {
readonly success: boolean;
};
};
export type MitigationViewCreateControlMappingMutation = {
response: MitigationViewCreateControlMappingMutation$data;
variables: MitigationViewCreateControlMappingMutation$variables;
export type ControlCreateMesureMappingMutation = {
response: ControlCreateMesureMappingMutation$data;
variables: ControlCreateMesureMappingMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -44,9 +44,9 @@ v1 = [
"variableName": "input"
}
],
"concreteType": "CreateControlMitigationMappingPayload",
"concreteType": "CreateControlMesureMappingPayload",
"kind": "LinkedField",
"name": "createControlMitigationMapping",
"name": "createControlMesureMapping",
"plural": false,
"selections": [
{
@@ -65,7 +65,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewCreateControlMappingMutation",
"name": "ControlCreateMesureMappingMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
@@ -74,20 +74,20 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MitigationViewCreateControlMappingMutation",
"name": "ControlCreateMesureMappingMutation",
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "fa46c5cf8b96b70117d12cf985247824",
"cacheID": "589fad9dec58fb2efe52e8e587c8ce85",
"id": null,
"metadata": {},
"name": "MitigationViewCreateControlMappingMutation",
"name": "ControlCreateMesureMappingMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewCreateControlMappingMutation(\n $input: CreateControlMitigationMappingInput!\n) {\n createControlMitigationMapping(input: $input) {\n success\n }\n}\n"
"text": "mutation ControlCreateMesureMappingMutation(\n $input: CreateControlMesureMappingInput!\n) {\n createControlMesureMapping(input: $input) {\n success\n }\n}\n"
}
};
})();
(node as any).hash = "af6e4d7933e5c428eec0e97cdf0b73dd";
(node as any).hash = "8974d4f4025f6e1eaba2a6b30e357486";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<f34a09cd4eda414409384386a4cea5b4>>
* @generated SignedSource<<272b7b4a8bc0c81baa4a8d8f3656be0c>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,21 +9,21 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type DeleteControlMitigationMappingInput = {
export type DeleteControlMesureMappingInput = {
controlId: string;
mitigationId: string;
mesureId: string;
};
export type MitigationViewDeleteControlMappingMutation$variables = {
input: DeleteControlMitigationMappingInput;
export type ControlDeleteMesureMappingMutation$variables = {
input: DeleteControlMesureMappingInput;
};
export type MitigationViewDeleteControlMappingMutation$data = {
readonly deleteControlMitigationMapping: {
export type ControlDeleteMesureMappingMutation$data = {
readonly deleteControlMesureMapping: {
readonly success: boolean;
};
};
export type MitigationViewDeleteControlMappingMutation = {
response: MitigationViewDeleteControlMappingMutation$data;
variables: MitigationViewDeleteControlMappingMutation$variables;
export type ControlDeleteMesureMappingMutation = {
response: ControlDeleteMesureMappingMutation$data;
variables: ControlDeleteMesureMappingMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -44,9 +44,9 @@ v1 = [
"variableName": "input"
}
],
"concreteType": "DeleteControlMitigationMappingPayload",
"concreteType": "DeleteControlMesureMappingPayload",
"kind": "LinkedField",
"name": "deleteControlMitigationMapping",
"name": "deleteControlMesureMapping",
"plural": false,
"selections": [
{
@@ -65,7 +65,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewDeleteControlMappingMutation",
"name": "ControlDeleteMesureMappingMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
@@ -74,20 +74,20 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MitigationViewDeleteControlMappingMutation",
"name": "ControlDeleteMesureMappingMutation",
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "b18a11215ba33a6c770cc08c88a28769",
"cacheID": "66b2b12e57f8a150825f0e3f25494093",
"id": null,
"metadata": {},
"name": "MitigationViewDeleteControlMappingMutation",
"name": "ControlDeleteMesureMappingMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewDeleteControlMappingMutation(\n $input: DeleteControlMitigationMappingInput!\n) {\n deleteControlMitigationMapping(input: $input) {\n success\n }\n}\n"
"text": "mutation ControlDeleteMesureMappingMutation(\n $input: DeleteControlMesureMappingInput!\n) {\n deleteControlMesureMapping(input: $input) {\n success\n }\n}\n"
}
};
})();
(node as any).hash = "f4f01abb45a3288558d7e8a1d19ce1ed";
(node as any).hash = "64e6f03a12a22a87e4893a335e58379b";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<d03d81a6969d83d42491f33bcbd1fc00>>
* @generated SignedSource<<03360061cfc99eaa1ec9921a815f9fa0>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,31 +9,31 @@
// @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 ControlLinkedMitigationsQuery$variables = {
export type MesureImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type MesureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type ControlLinkedMesuresQuery$variables = {
controlId: string;
};
export type ControlLinkedMitigationsQuery$data = {
export type ControlLinkedMesuresQuery$data = {
readonly control: {
readonly id: string;
readonly mitigations?: {
readonly mesures?: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly category: string;
readonly description: string;
readonly id: string;
readonly importance: MitigationImportance;
readonly importance: MesureImportance;
readonly name: string;
readonly state: MitigationState;
readonly state: MesureState;
};
}>;
};
};
};
export type ControlLinkedMitigationsQuery = {
response: ControlLinkedMitigationsQuery$data;
variables: ControlLinkedMitigationsQuery$variables;
export type ControlLinkedMesuresQuery = {
response: ControlLinkedMesuresQuery$data;
variables: ControlLinkedMesuresQuery$variables;
};
const node: ConcreteRequest = (function(){
@@ -69,7 +69,7 @@ v4 = [
{
"alias": null,
"args": null,
"concreteType": "MitigationEdge",
"concreteType": "MesureEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
@@ -77,7 +77,7 @@ v4 = [
{
"alias": null,
"args": null,
"concreteType": "Mitigation",
"concreteType": "Mesure",
"kind": "LinkedField",
"name": "node",
"plural": false,
@@ -170,7 +170,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "ControlLinkedMitigationsQuery",
"name": "ControlLinkedMesuresQuery",
"selections": [
{
"alias": "control",
@@ -185,11 +185,11 @@ return {
"kind": "InlineFragment",
"selections": [
{
"alias": "mitigations",
"alias": "mesures",
"args": null,
"concreteType": "MitigationConnection",
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "__Control__mitigations_connection",
"name": "__Control__mesures_connection",
"plural": false,
"selections": (v4/*: any*/),
"storageKey": null
@@ -209,7 +209,7 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "ControlLinkedMitigationsQuery",
"name": "ControlLinkedMesuresQuery",
"selections": [
{
"alias": "control",
@@ -227,21 +227,21 @@ return {
{
"alias": null,
"args": (v5/*: any*/),
"concreteType": "MitigationConnection",
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "mitigations",
"name": "mesures",
"plural": false,
"selections": (v4/*: any*/),
"storageKey": "mitigations(first:100)"
"storageKey": "mesures(first:100)"
},
{
"alias": null,
"args": (v5/*: any*/),
"filters": null,
"handle": "connection",
"key": "Control__mitigations",
"key": "Control__mesures",
"kind": "LinkedHandle",
"name": "mitigations"
"name": "mesures"
}
],
"type": "Control",
@@ -253,7 +253,7 @@ return {
]
},
"params": {
"cacheID": "082617925f3db2937654823bd7dc8833",
"cacheID": "19d9240a60b26d765a93e00be9e1e83f",
"id": null,
"metadata": {
"connection": [
@@ -263,18 +263,18 @@ return {
"direction": "forward",
"path": [
"control",
"mitigations"
"mesures"
]
}
]
},
"name": "ControlLinkedMitigationsQuery",
"name": "ControlLinkedMesuresQuery",
"operationKind": "query",
"text": "query ControlLinkedMitigationsQuery(\n $controlId: ID!\n) {\n control: node(id: $controlId) {\n __typename\n id\n ... on Control {\n mitigations(first: 100) {\n edges {\n node {\n id\n name\n description\n category\n importance\n state\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
"text": "query ControlLinkedMesuresQuery(\n $controlId: ID!\n) {\n control: node(id: $controlId) {\n __typename\n id\n ... on Control {\n mesures(first: 100) {\n edges {\n node {\n id\n name\n description\n category\n importance\n state\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "3d61e207c8a46a72f19e3414152438b8";
(node as any).hash = "acb01a862fb268c4b4b557edc3090a0e";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<3c11f3c5fa5a298493ba19d950baa7d2>>
* @generated SignedSource<<345a2b05f66a0bb630eea3c12f549e52>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,31 +9,31 @@
// @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 ControlOrganizationMitigationsQuery$variables = {
export type MesureImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type MesureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type ControlOrganizationMesuresQuery$variables = {
organizationId: string;
};
export type ControlOrganizationMitigationsQuery$data = {
export type ControlOrganizationMesuresQuery$data = {
readonly organization: {
readonly id: string;
readonly mitigations?: {
readonly mesures?: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly category: string;
readonly description: string;
readonly id: string;
readonly importance: MitigationImportance;
readonly importance: MesureImportance;
readonly name: string;
readonly state: MitigationState;
readonly state: MesureState;
};
}>;
};
};
};
export type ControlOrganizationMitigationsQuery = {
response: ControlOrganizationMitigationsQuery$data;
variables: ControlOrganizationMitigationsQuery$variables;
export type ControlOrganizationMesuresQuery = {
response: ControlOrganizationMesuresQuery$data;
variables: ControlOrganizationMesuresQuery$variables;
};
const node: ConcreteRequest = (function(){
@@ -69,7 +69,7 @@ v4 = [
{
"alias": null,
"args": null,
"concreteType": "MitigationEdge",
"concreteType": "MesureEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
@@ -77,7 +77,7 @@ v4 = [
{
"alias": null,
"args": null,
"concreteType": "Mitigation",
"concreteType": "Mesure",
"kind": "LinkedField",
"name": "node",
"plural": false,
@@ -170,7 +170,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "ControlOrganizationMitigationsQuery",
"name": "ControlOrganizationMesuresQuery",
"selections": [
{
"alias": "organization",
@@ -185,11 +185,11 @@ return {
"kind": "InlineFragment",
"selections": [
{
"alias": "mitigations",
"alias": "mesures",
"args": null,
"concreteType": "MitigationConnection",
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "__Organization__mitigations_connection",
"name": "__Organization__mesures_connection",
"plural": false,
"selections": (v4/*: any*/),
"storageKey": null
@@ -209,7 +209,7 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "ControlOrganizationMitigationsQuery",
"name": "ControlOrganizationMesuresQuery",
"selections": [
{
"alias": "organization",
@@ -227,21 +227,21 @@ return {
{
"alias": null,
"args": (v5/*: any*/),
"concreteType": "MitigationConnection",
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "mitigations",
"name": "mesures",
"plural": false,
"selections": (v4/*: any*/),
"storageKey": "mitigations(first:100)"
"storageKey": "mesures(first:100)"
},
{
"alias": null,
"args": (v5/*: any*/),
"filters": null,
"handle": "connection",
"key": "Organization__mitigations",
"key": "Organization__mesures",
"kind": "LinkedHandle",
"name": "mitigations"
"name": "mesures"
}
],
"type": "Organization",
@@ -253,7 +253,7 @@ return {
]
},
"params": {
"cacheID": "21e0815f3ed8b62621aa0d7824a93036",
"cacheID": "59ceb60db60754876774a3856686b35c",
"id": null,
"metadata": {
"connection": [
@@ -263,18 +263,18 @@ return {
"direction": "forward",
"path": [
"organization",
"mitigations"
"mesures"
]
}
]
},
"name": "ControlOrganizationMitigationsQuery",
"name": "ControlOrganizationMesuresQuery",
"operationKind": "query",
"text": "query ControlOrganizationMitigationsQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n mitigations(first: 100) {\n edges {\n node {\n id\n name\n description\n category\n importance\n state\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
"text": "query ControlOrganizationMesuresQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n mesures(first: 100) {\n edges {\n node {\n id\n name\n description\n category\n importance\n state\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "54b1b5a6966cf761d49739da3a988db8";
(node as any).hash = "cc43b07a1a1f5831f5d09fbd13d8805d";
export default node;

View File

@@ -4,26 +4,26 @@ import { lazy } from "@probo/react-lazy";
import { useLocation } from "react-router";
import { ErrorBoundaryWithLocation } from "../ErrorBoundary";
const NewMitigationView = lazy(() => import("./NewMitigationView"));
const EditMesureView = lazy(() => import("./EditMesureView"));
export function NewMitigationViewSkeleton() {
export function EditMesureViewSkeleton() {
return (
<PageTemplateSkeleton
title="New Mitigation"
description="Add a new mitigation. You will be able to link it to control and risks"
title="Edit Mesure"
description="Edit a Mesure. You will be able to link it to control and risks"
>
<div className="max-w-2xl aspect-square bg-subtle-bg rounded-xl animate-pulse" />
</PageTemplateSkeleton>
);
}
export function NewMitigationPage() {
export function EditMesurePage() {
const location = useLocation();
return (
<Suspense key={location.pathname} fallback={<NewMitigationViewSkeleton />}>
<Suspense key={location.pathname} fallback={<EditMesureViewSkeleton />}>
<ErrorBoundaryWithLocation>
<NewMitigationView />
<EditMesureView />
</ErrorBoundaryWithLocation>
</Suspense>
);

View File

@@ -9,19 +9,19 @@ import {
import { useParams, useNavigate } from "react-router";
import { PageTemplate } from "@/components/PageTemplate";
import { useToast } from "@/hooks/use-toast";
import { EditMitigationViewUpdateMitigationMutation } from "./__generated__/EditMitigationViewUpdateMitigationMutation.graphql";
import { EditMesureViewUpdateMesureMutation } from "./__generated__/EditMesureViewUpdateMesureMutation.graphql";
import { EditableField } from "@/components/EditableField";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { cn } from "@/lib/utils";
import { EditMitigationViewSkeleton } from "./EditMitigationPage";
import { EditMitigationViewQuery } from "./__generated__/EditMitigationViewQuery.graphql";
import { EditMesureViewSkeleton } from "./EditMesurePage";
import { EditMesureViewQuery } from "./__generated__/EditMesureViewQuery.graphql";
const editMitigationQuery = graphql`
query EditMitigationViewQuery($mitigationId: ID!) {
node(id: $mitigationId) {
... on Mitigation {
const editMesureQuery = graphql`
query EditMesureViewQuery($mesureId: ID!) {
node(id: $mesureId) {
... on Mesure {
id
name
description
@@ -32,12 +32,10 @@ const editMitigationQuery = graphql`
}
`;
const updateMitigationMutation = graphql`
mutation EditMitigationViewUpdateMitigationMutation(
$input: UpdateMitigationInput!
) {
updateMitigation(input: $input) {
mitigation {
const updateMesureMutation = graphql`
mutation EditMesureViewUpdateMesureMutation($input: UpdateMesureInput!) {
updateMesure(input: $input) {
mesure {
id
name
description
@@ -46,29 +44,27 @@ const updateMitigationMutation = graphql`
}
`;
function EditMitigationViewContent({
function EditMesureViewContent({
queryRef,
}: {
queryRef: PreloadedQuery<EditMitigationViewQuery>;
queryRef: PreloadedQuery<EditMesureViewQuery>;
}) {
const { organizationId } = useParams<{
organizationId: string;
}>();
const { mitigationId } = useParams();
const { mesureId } = useParams();
const navigate = useNavigate();
const { toast } = useToast();
const { node: mitigation } = usePreloadedQuery(editMitigationQuery, queryRef);
const { node: mesure } = usePreloadedQuery(editMesureQuery, queryRef);
const [formData, setFormData] = useState({
name: mitigation.name ?? "",
description: mitigation.description ?? "",
category: mitigation.category ?? "",
importance: mitigation.importance,
name: mesure.name ?? "",
description: mesure.description ?? "",
category: mesure.category ?? "",
importance: mesure.importance,
});
const [commit, isInFlight] =
useMutation<EditMitigationViewUpdateMitigationMutation>(
updateMitigationMutation
);
useMutation<EditMesureViewUpdateMesureMutation>(updateMesureMutation);
const handleFieldChange = (field: keyof typeof formData, value: unknown) => {
setFormData((prev) => ({
@@ -92,7 +88,7 @@ function EditMitigationViewContent({
commit({
variables: {
input: {
id: mitigationId!,
id: mesureId!,
name: formData.name,
description: formData.description,
category: formData.category,
@@ -103,7 +99,7 @@ function EditMitigationViewContent({
if (errors) {
toast({
title: "Error",
description: errors[0]?.message || "Failed to update mitigation",
description: errors[0]?.message || "Failed to update mesure",
variant: "destructive",
});
return;
@@ -111,12 +107,10 @@ function EditMitigationViewContent({
toast({
title: "Success",
description: "Mitigation updated successfully",
description: "Mesure updated successfully",
});
navigate(
`/organizations/${organizationId}/mitigations/${mitigationId}`
);
navigate(`/organizations/${organizationId}/mesures/${mesureId}`);
},
onError(error) {
toast({
@@ -130,8 +124,8 @@ function EditMitigationViewContent({
return (
<PageTemplate
title="Edit Mitigation"
description="Edit a mitigation. You will be able to link it to control and risks"
title="Edit Mesure"
description="Edit a mesure. You will be able to link it to control and risks"
>
<Card className="max-w-2xl">
<form onSubmit={handleSubmit} className="p-6 space-y-6">
@@ -148,7 +142,7 @@ function EditMitigationViewContent({
onChange={(value) => handleFieldChange("description", value)}
required
multiline
helpText="Provide a detailed description of the mitigation"
helpText="Provide a detailed description of the mesure"
/>
<EditableField
@@ -209,15 +203,13 @@ function EditMitigationViewContent({
type="button"
variant="outline"
onClick={() =>
navigate(
`/organizations/${organizationId}/mitigations/${mitigationId}`
)
navigate(`/organizations/${organizationId}/mesures/${mesureId}`)
}
>
Cancel
</Button>
<Button type="submit" disabled={isInFlight}>
{isInFlight ? "Updating..." : "Update Mitigation"}
{isInFlight ? "Updating..." : "Update Mesure"}
</Button>
</div>
</form>
@@ -226,24 +218,24 @@ function EditMitigationViewContent({
);
}
export default function EditMitigationView() {
const { mitigationId } = useParams();
export default function EditMesureView() {
const { mesureId } = useParams();
const [queryRef, loadQuery] =
useQueryLoader<EditMitigationViewQuery>(editMitigationQuery);
useQueryLoader<EditMesureViewQuery>(editMesureQuery);
useEffect(() => {
if (mitigationId) {
loadQuery({ mitigationId });
if (mesureId) {
loadQuery({ mesureId });
}
}, [mitigationId, loadQuery]);
}, [mesureId, loadQuery]);
if (!queryRef) {
return <EditMitigationViewSkeleton />;
return <EditMesureViewSkeleton />;
}
return (
<Suspense fallback={<EditMitigationViewSkeleton />}>
<EditMitigationViewContent queryRef={queryRef} />
<Suspense fallback={<EditMesureViewSkeleton />}>
<EditMesureViewContent queryRef={queryRef} />
</Suspense>
);
}

View File

@@ -4,13 +4,13 @@ import { lazy } from "@probo/react-lazy";
import { useLocation } from "react-router";
import { ErrorBoundaryWithLocation } from "../ErrorBoundary";
const MitigationListView = lazy(() => import("./MitigationListView"));
const MesureListView = lazy(() => import("./MesureListView"));
export function MitigationListViewSkeleton() {
export function MesureListViewSkeleton() {
return (
<PageTemplateSkeleton
title="Mitigations"
description="Mitigations are actions taken to reduce the risk of a risk."
title="Mesures"
description="Mesures are actions taken to reduce the risk of a risk."
>
<div className="space-y-6">
<div className="h-[72px] bg-subtle-bg animate-pulse rounded-xl" />
@@ -31,13 +31,13 @@ export function MitigationListViewSkeleton() {
);
}
export function MitigationListPage() {
export function MesureListPage() {
const location = useLocation();
return (
<Suspense key={location.pathname} fallback={<MitigationListViewSkeleton />}>
<Suspense key={location.pathname} fallback={<MesureListViewSkeleton />}>
<ErrorBoundaryWithLocation>
<MitigationListView />
<MesureListView />
</ErrorBoundaryWithLocation>
</Suspense>
);

View File

@@ -21,11 +21,11 @@ import {
} from "lucide-react";
import { PageTemplate } from "@/components/PageTemplate";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { MitigationListViewQuery as MitigationListViewQueryType } from "./__generated__/MitigationListViewQuery.graphql";
import { MitigationListViewSkeleton } from "./MitigationListPage";
import { MesureListViewQuery as MesureListViewQueryType } from "./__generated__/MesureListViewQuery.graphql";
import { MesureListViewSkeleton } from "./MesureListPage";
import { Button } from "@/components/ui/button";
import { useToast } from "@/hooks/use-toast";
import { MitigationListViewImportMitigationMutation as MitigationListViewImportMitigationMutationType } from "./__generated__/MitigationListViewImportMitigationMutation.graphql";
import { MesureListViewImportMesureMutation as MesureListViewImportMesureMutationType } from "./__generated__/MesureListViewImportMesureMutation.graphql";
import {
Tooltip,
TooltipContent,
@@ -38,13 +38,12 @@ import {
PopoverTrigger,
} from "@/components/ui/popover";
const mitigationListViewQuery = graphql`
query MitigationListViewQuery($organizationId: ID!, $first: Int) {
const mesureListViewQuery = graphql`
query MesureListViewQuery($organizationId: ID!, $first: Int) {
organization: node(id: $organizationId) {
id
... on Organization {
mitigations(first: $first)
@connection(key: "MitigationListView_mitigations") {
mesures(first: $first) @connection(key: "MesureListView_mesures") {
edges {
node {
id
@@ -63,13 +62,13 @@ const mitigationListViewQuery = graphql`
}
`;
const importMitigationMutation = graphql`
mutation MitigationListViewImportMitigationMutation(
$input: ImportMitigationInput!
const importMesureMutation = graphql`
mutation MesureListViewImportMesureMutation(
$input: ImportMesureInput!
$connections: [ID!]!
) {
importMitigation(input: $input) {
mitigationEdges @appendEdge(connections: $connections) {
importMesure(input: $input) {
mesureEdges @appendEdge(connections: $connections) {
node {
id
name
@@ -85,7 +84,7 @@ const importMitigationMutation = graphql`
}
`;
interface Mitigation {
interface Mesure {
id?: string;
name?: string;
description?: string;
@@ -102,7 +101,7 @@ interface Category {
name: string;
description: string;
progress: number;
mitigations: Mitigation[];
mesures: Mesure[];
doneCount: number;
totalCount: number;
}
@@ -110,21 +109,21 @@ interface Category {
interface OrganizationData {
organization: {
id: string;
mitigations?: {
mesures?: {
edges: Array<{
node: Mitigation;
node: Mesure;
}>;
};
};
}
function MitigationListContent({
function MesureListContent({
queryRef,
}: {
queryRef: PreloadedQuery<MitigationListViewQueryType>;
queryRef: PreloadedQuery<MesureListViewQueryType>;
}) {
const data = usePreloadedQuery<MitigationListViewQueryType>(
mitigationListViewQuery,
const data = usePreloadedQuery<MesureListViewQueryType>(
mesureListViewQuery,
queryRef
) as unknown as OrganizationData;
@@ -133,10 +132,8 @@ function MitigationListContent({
const [isImporting, setIsImporting] = useState(false);
const { toast } = useToast();
const [importMitigation] =
useMutation<MitigationListViewImportMitigationMutationType>(
importMitigationMutation
);
const [importMesure] =
useMutation<MesureListViewImportMesureMutationType>(importMesureMutation);
// Monitor URL hash for changes and update state accordingly
const [initialHashCategory] = useState(() =>
@@ -181,10 +178,10 @@ function MitigationListContent({
};
}, [expandedCategories]);
const mitigations =
data.organization.mitigations?.edges.map((edge) => edge.node) ?? [];
const mesures =
data.organization.mesures?.edges.map((edge) => edge.node) ?? [];
// Map mitigation state to status for the new design
// Map mesure state to status for the new design
const mapStateToStatus = (state?: string): string => {
if (!state) return "incomplete";
switch (state) {
@@ -201,48 +198,48 @@ function MitigationListContent({
}
};
const processedMitigations = mitigations.map((mitigation: Mitigation) => ({
...mitigation,
status: mapStateToStatus(mitigation.state),
const processedMesures = mesures.map((mesure: Mesure) => ({
...mesure,
status: mapStateToStatus(mesure.state),
}));
// Calculate global progress
const implementedCount = processedMitigations.filter(
(mitigation: Mitigation) => mitigation.status === "complete"
const implementedCount = processedMesures.filter(
(mesure: Mesure) => mesure.status === "complete"
).length;
const notApplicableCount = processedMitigations.filter(
(mitigation: Mitigation) => mitigation.status === "not-applicable"
const notApplicableCount = processedMesures.filter(
(mesure: Mesure) => mesure.status === "not-applicable"
).length;
const totalMitigations = processedMitigations.length;
const totalMesures = processedMesures.length;
// Include not-applicable as effectively "complete" for progress percentage
const effectiveCompletedCount = implementedCount + notApplicableCount;
const globalProgress = totalMitigations
? Math.round((effectiveCompletedCount / totalMitigations) * 100)
const globalProgress = totalMesures
? Math.round((effectiveCompletedCount / totalMesures) * 100)
: 0;
// Get global status counts
const globalStatusCounts = processedMitigations.reduce(
(acc: Record<string, number>, mitigation: Mitigation) => {
if (mitigation.status) {
acc[mitigation.status] = (acc[mitigation.status] || 0) + 1;
const globalStatusCounts = processedMesures.reduce(
(acc: Record<string, number>, mesure: Mesure) => {
if (mesure.status) {
acc[mesure.status] = (acc[mesure.status] || 0) + 1;
}
return acc;
},
{} as Record<string, number>
);
// Group mitigations by category
const mitigationsByCategory = processedMitigations.reduce(
(acc: Record<string, Mitigation[]>, mitigation: Mitigation) => {
if (!mitigation?.category) return acc;
if (!acc[mitigation.category]) {
acc[mitigation.category] = [];
// Group mesures by category
const mesuresByCategory = processedMesures.reduce(
(acc: Record<string, Mesure[]>, mesure: Mesure) => {
if (!mesure?.category) return acc;
if (!acc[mesure.category]) {
acc[mesure.category] = [];
}
acc[mitigation.category].push(mitigation);
acc[mesure.category].push(mesure);
return acc;
},
{} as Record<string, Mitigation[]>
{} as Record<string, Mesure[]>
);
// Function to toggle a category's expanded state
@@ -256,17 +253,17 @@ function MitigationListContent({
});
};
const categories: Category[] = Object.entries(mitigationsByCategory)
.map(([categoryName, categoryMitigations]: [string, Mitigation[]]) => {
const catImplementedCount = categoryMitigations.filter(
(mitigation) => mitigation.status === "complete"
const categories: Category[] = Object.entries(mesuresByCategory)
.map(([categoryName, categoryMesures]: [string, Mesure[]]) => {
const catImplementedCount = categoryMesures.filter(
(mesure) => mesure.status === "complete"
).length;
const catNotApplicableCount = categoryMitigations.filter(
(mitigation) => mitigation.status === "not-applicable"
const catNotApplicableCount = categoryMesures.filter(
(mesure) => mesure.status === "not-applicable"
).length;
// Consider both "complete" and "not-applicable" as done for category progress
const catDoneCount = catImplementedCount + catNotApplicableCount;
const catTotalCount = categoryMitigations.length;
const catTotalCount = categoryMesures.length;
const progress = catTotalCount
? Math.round((catDoneCount / catTotalCount) * 100)
: 0;
@@ -274,16 +271,16 @@ function MitigationListContent({
return {
id: categoryName,
name: categoryName,
description: `Mitigations related to ${categoryName.toLowerCase()}`,
description: `Mesures related to ${categoryName.toLowerCase()}`,
progress: progress,
mitigations: categoryMitigations.sort((a, b) =>
mesures: categoryMesures.sort((a, b) =>
(a.name || "").localeCompare(b.name || "")
),
doneCount: catDoneCount,
totalCount: catTotalCount,
};
})
.filter((category) => category.mitigations.length > 0)
.filter((category) => category.mesures.length > 0)
.sort((a, b) => a.name.localeCompare(b.name));
const getStatusIcon = (status: string) => {
@@ -309,12 +306,12 @@ function MitigationListContent({
setIsImporting(true);
importMitigation({
importMesure({
variables: {
connections: [
ConnectionHandler.getConnectionID(
data.organization.id,
"MitigationListView_mitigations"
"MesureListView_mesures"
),
],
input: {
@@ -328,8 +325,8 @@ function MitigationListContent({
onCompleted: () => {
setIsImporting(false);
toast({
title: "Mitigations imported",
description: "Mitigations have been imported successfully.",
title: "Mesures imported",
description: "Mesures have been imported successfully.",
variant: "default",
});
if (fileInputRef.current) {
@@ -339,7 +336,7 @@ function MitigationListContent({
onError: (error) => {
setIsImporting(false);
toast({
title: "Error importing mitigations",
title: "Error importing mesures",
description: error.message,
variant: "destructive",
});
@@ -349,8 +346,8 @@ function MitigationListContent({
return (
<PageTemplate
title="Mitigations"
description="Mitigations are actions taken to reduce the risk. Add them to track their implementation status."
title="Mesures"
description="Mesures are actions taken to reduce the risk. Add them to track their implementation status."
actions={
<div className="flex gap-4">
<Button
@@ -358,17 +355,17 @@ function MitigationListContent({
onClick={() => fileInputRef.current?.click()}
disabled={isImporting}
>
{isImporting ? "Importing..." : "Import Mitigations"}
{isImporting ? "Importing..." : "Import Mesures"}
</Button>
<Button asChild>
<Link to={`/organizations/${organizationId}/mitigations/new`}>
New Mitigation
<Link to={`/organizations/${organizationId}/mesures/new`}>
New Mesure
</Link>
</Button>
</div>
}
>
{/* Hidden file input for mitigation import */}
{/* Hidden file input for mesure import */}
<input
type="file"
ref={fileInputRef}
@@ -380,7 +377,7 @@ function MitigationListContent({
{/* Global Progress Summary */}
<div className="mb-8">
<div className="flex items-center justify-between mb-1">
<h3 className="text-lg font-medium">Mitigation Implementation</h3>
<h3 className="text-lg font-medium">Mesure Implementation</h3>
<span className="text-sm text-tertiary">
{globalProgress}% complete
</span>
@@ -396,7 +393,7 @@ function MitigationListContent({
className="bg-green-500 h-full"
style={{
width: `${
(globalStatusCounts.complete / totalMitigations) * 100
(globalStatusCounts.complete / totalMesures) * 100
}%`,
}}
/>
@@ -407,7 +404,7 @@ function MitigationListContent({
className="bg-blue-500 h-full"
style={{
width: `${
(globalStatusCounts["in-progress"] / totalMitigations) * 100
(globalStatusCounts["in-progress"] / totalMesures) * 100
}%`,
}}
/>
@@ -418,7 +415,7 @@ function MitigationListContent({
className="bg-red-500 h-full"
style={{
width: `${
(globalStatusCounts.incomplete / totalMitigations) * 100
(globalStatusCounts.incomplete / totalMesures) * 100
}%`,
}}
/>
@@ -429,8 +426,7 @@ function MitigationListContent({
className="bg-primary-bg h-full"
style={{
width: `${
(globalStatusCounts["not-applicable"] / totalMitigations) *
100
(globalStatusCounts["not-applicable"] / totalMesures) * 100
}%`,
}}
/>
@@ -441,7 +437,7 @@ function MitigationListContent({
className="bg-secondary h-full"
style={{
width: `${
(globalStatusCounts["not-started"] / totalMitigations) * 100
(globalStatusCounts["not-started"] / totalMesures) * 100
}%`,
}}
/>
@@ -521,7 +517,7 @@ function MitigationListContent({
{isExpanded && (
<CardContent className="p-0">
{category.mitigations.length > 0 ? (
{category.mesures.length > 0 ? (
<div className="w-full">
<table className="w-full">
<thead>
@@ -532,26 +528,24 @@ function MitigationListContent({
<th className="w-24 px-4 py-2 text-left">
Status
</th>
<th className="px-4 py-2 text-left">
Mitigation
</th>
<th className="px-4 py-2 text-left">Mesure</th>
</tr>
</thead>
<tbody className="divide-y">
{category.mitigations.map((mitigation) => (
{category.mesures.map((mesure) => (
<tr
key={mitigation.id || Math.random().toString()}
key={mesure.id || Math.random().toString()}
className="hover:bg-h-subtle-bg cursor-pointer"
>
<td className="w-24 px-4 py-3 align-middle">
<Badge variant="outline" className="text-xs">
{mitigation.importance}
{mesure.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)
{mesure.status
? getStatusIcon(mesure.status)
: null}
</div>
</td>
@@ -561,11 +555,11 @@ function MitigationListContent({
<Tooltip>
<TooltipTrigger asChild>
<Link
to={`/organizations/${organizationId}/mitigations/${mitigation.id}`}
to={`/organizations/${organizationId}/mesures/${mesure.id}`}
className="font-medium group flex items-center relative"
>
<span className="mr-1">
{mitigation.name}
{mesure.name}
</span>
<span className="absolute bottom-0 left-0 w-full h-0.5 bg-primary-bg scale-x-0 group-hover:scale-x-100 transition-transform"></span>
</Link>
@@ -584,7 +578,7 @@ function MitigationListContent({
<Button
variant="ghost"
className="p-0 h-6 w-6 rounded-full hover:bg-primary-bg"
aria-label="Learn more about this mitigation"
aria-label="Learn more about this mesure"
>
<HelpCircle className="h-5 w-5 text-primary hover:text-primary" />
</Button>
@@ -597,26 +591,26 @@ function MitigationListContent({
<div className="space-y-3">
<div className="flex justify-between items-start">
<h4 className="font-bold text-md">
{mitigation.name}
{mesure.name}
</h4>
<Badge
variant="outline"
className="text-xs"
>
{mitigation.importance}
{mesure.importance}
</Badge>
</div>
{mitigation.description && (
{mesure.description && (
<div className="text-sm">
<p className="font-semibold mb-1">
Why is this important:
</p>
<p>
{mitigation.description.startsWith(
{mesure.description.startsWith(
"##"
)
? mitigation.description
? mesure.description
.split("\n")
.find((line) =>
line.startsWith(
@@ -626,16 +620,16 @@ function MitigationListContent({
?.replace("## Why?", "")
?.replace("## Why", "")
?.trim() ||
mitigation.description.split(
mesure.description.split(
"\n"
)[1] ||
""
: mitigation.description.substring(
: mesure.description.substring(
0,
180
) +
(mitigation.description
.length > 180
(mesure.description.length >
180
? "..."
: "")}
</p>
@@ -650,7 +644,7 @@ function MitigationListContent({
asChild
>
<Link
to={`/organizations/${organizationId}/mitigations/${mitigation.id}`}
to={`/organizations/${organizationId}/mesures/${mesure.id}`}
>
<span>
Implementation guide
@@ -671,7 +665,7 @@ function MitigationListContent({
</div>
) : (
<div className="flex items-center justify-center p-6 text-center text-tertiary">
No mitigations in this category
No mesures in this category
</div>
)}
</CardContent>
@@ -685,10 +679,9 @@ function MitigationListContent({
);
}
export default function MitigationListView() {
const [queryRef, loadQuery] = useQueryLoader<MitigationListViewQueryType>(
mitigationListViewQuery
);
export default function MesureListView() {
const [queryRef, loadQuery] =
useQueryLoader<MesureListViewQueryType>(mesureListViewQuery);
const { organizationId } = useParams();
@@ -700,12 +693,12 @@ export default function MitigationListView() {
}, [loadQuery, organizationId]);
if (!queryRef) {
return <MitigationListViewSkeleton />;
return <MesureListViewSkeleton />;
}
return (
<Suspense fallback={<MitigationListViewSkeleton />}>
<MitigationListContent queryRef={queryRef} />
<Suspense fallback={<MesureListViewSkeleton />}>
<MesureListContent queryRef={queryRef} />
</Suspense>
);
}

View File

@@ -5,9 +5,9 @@ import { lazy } from "@probo/react-lazy";
import { useLocation } from "react-router";
import { ErrorBoundaryWithLocation } from "../ErrorBoundary";
const MitigationView = lazy(() => import("./MitigationView"));
const MesureView = lazy(() => import("./MesureView"));
export function MitigationViewSkeleton() {
export function MesureViewSkeleton() {
return (
<PageTemplateSkeleton
actions={
@@ -32,13 +32,13 @@ export function MitigationViewSkeleton() {
);
}
export function MitigationPage() {
export function MesurePage() {
const location = useLocation();
return (
<Suspense key={location.pathname} fallback={<MitigationViewSkeleton />}>
<Suspense key={location.pathname} fallback={<MesureViewSkeleton />}>
<ErrorBoundaryWithLocation>
<MitigationView />
<MesureView />
</ErrorBoundaryWithLocation>
</Suspense>
);

View File

@@ -79,26 +79,26 @@ import {
import { Badge } from "@/components/ui/badge";
import { PageTemplate } from "@/components/PageTemplate";
import { MitigationViewSkeleton } from "./MitigationPage";
import { MitigationViewUpdateTaskStateMutation as MitigationViewUpdateTaskStateMutationType } from "./__generated__/MitigationViewUpdateTaskStateMutation.graphql";
import { MitigationViewCreateTaskMutation as MitigationViewCreateTaskMutationType } from "./__generated__/MitigationViewCreateTaskMutation.graphql";
import { MitigationViewDeleteTaskMutation as MitigationViewDeleteTaskMutationType } from "./__generated__/MitigationViewDeleteTaskMutation.graphql";
import { MitigationViewDeleteEvidenceMutation as MitigationViewDeleteEvidenceMutationType } from "./__generated__/MitigationViewDeleteEvidenceMutation.graphql";
import { MitigationViewAssignTaskMutation as MitigationViewAssignTaskMutationType } from "./__generated__/MitigationViewAssignTaskMutation.graphql";
import { MitigationViewUnassignTaskMutation as MitigationViewUnassignTaskMutationType } from "./__generated__/MitigationViewUnassignTaskMutation.graphql";
import { MitigationViewUpdateMitigationStateMutation as MitigationViewUpdateMitigationStateMutationType } from "./__generated__/MitigationViewUpdateMitigationStateMutation.graphql";
import { MitigationViewQuery as MitigationViewQueryType } from "./__generated__/MitigationViewQuery.graphql";
import { MitigationViewOrganizationQuery$data } from "./__generated__/MitigationViewOrganizationQuery.graphql";
import { MesureViewSkeleton } from "./MesurePage";
import { MesureViewUpdateTaskStateMutation as MesureViewUpdateTaskStateMutationType } from "./__generated__/MesureViewUpdateTaskStateMutation.graphql";
import { MesureViewCreateTaskMutation as MesureViewCreateTaskMutationType } from "./__generated__/MesureViewCreateTaskMutation.graphql";
import { MesureViewDeleteTaskMutation as MesureViewDeleteTaskMutationType } from "./__generated__/MesureViewDeleteTaskMutation.graphql";
import { MesureViewDeleteEvidenceMutation as MesureViewDeleteEvidenceMutationType } from "./__generated__/MesureViewDeleteEvidenceMutation.graphql";
import { MesureViewAssignTaskMutation as MesureViewAssignTaskMutationType } from "./__generated__/MesureViewAssignTaskMutation.graphql";
import { MesureViewUnassignTaskMutation as MesureViewUnassignTaskMutationType } from "./__generated__/MesureViewUnassignTaskMutation.graphql";
import { MesureViewUpdateMesureStateMutation as MesureViewUpdateMesureStateMutationType } from "./__generated__/MesureViewUpdateMesureStateMutation.graphql";
import { MesureViewQuery as MesureViewQueryType } from "./__generated__/MesureViewQuery.graphql";
import { MesureViewOrganizationQuery$data } from "./__generated__/MesureViewOrganizationQuery.graphql";
import {
MitigationViewFrameworksQuery,
MitigationViewFrameworksQuery$data,
} from "./__generated__/MitigationViewFrameworksQuery.graphql";
MesureViewFrameworksQuery,
MesureViewFrameworksQuery$data,
} from "./__generated__/MesureViewFrameworksQuery.graphql";
import {
MitigationViewLinkedControlsQuery,
MitigationViewLinkedControlsQuery$data,
} from "./__generated__/MitigationViewLinkedControlsQuery.graphql";
import { MitigationViewCreateEvidenceMutation as MitigationViewCreateEvidenceMutationType } from "./__generated__/MitigationViewCreateEvidenceMutation.graphql";
import { MitigationViewFulfillEvidenceMutation as MitigationViewFulfillEvidenceMutationType } from "./__generated__/MitigationViewFulfillEvidenceMutation.graphql";
MesureViewLinkedControlsQuery,
MesureViewLinkedControlsQuery$data,
} from "./__generated__/MesureViewLinkedControlsQuery.graphql";
import { MesureViewCreateEvidenceMutation as MesureViewCreateEvidenceMutationType } from "./__generated__/MesureViewCreateEvidenceMutation.graphql";
import { MesureViewFulfillEvidenceMutation as MesureViewFulfillEvidenceMutationType } from "./__generated__/MesureViewFulfillEvidenceMutation.graphql";
// Function to format ISO8601 duration to human-readable format
const formatDuration = (isoDuration: string): string => {
@@ -137,17 +137,17 @@ const formatDuration = (isoDuration: string): string => {
}
};
const mitigationViewQuery = graphql`
query MitigationViewQuery($mitigationId: ID!) {
mitigation: node(id: $mitigationId) {
const mesureViewQuery = graphql`
query MesureViewQuery($mesureId: ID!) {
mesure: node(id: $mesureId) {
id
... on Mitigation {
... on Mesure {
name
description
state
importance
category
tasks(first: 100) @connection(key: "MitigationView_tasks") {
tasks(first: 100) @connection(key: "MesureView_tasks") {
__id
edges {
node {
@@ -161,8 +161,7 @@ const mitigationViewQuery = graphql`
fullName
primaryEmailAddress
}
evidences(first: 50)
@connection(key: "MitigationView_evidences") {
evidences(first: 50) @connection(key: "MesureView_evidences") {
__id
edges {
node {
@@ -187,7 +186,7 @@ const mitigationViewQuery = graphql`
`;
const updateTaskStateMutation = graphql`
mutation MitigationViewUpdateTaskStateMutation($input: UpdateTaskInput!) {
mutation MesureViewUpdateTaskStateMutation($input: UpdateTaskInput!) {
updateTask(input: $input) {
task {
id
@@ -199,7 +198,7 @@ const updateTaskStateMutation = graphql`
`;
const createTaskMutation = graphql`
mutation MitigationViewCreateTaskMutation(
mutation MesureViewCreateTaskMutation(
$input: CreateTaskInput!
$connections: [ID!]!
) {
@@ -223,7 +222,7 @@ const createTaskMutation = graphql`
`;
const deleteTaskMutation = graphql`
mutation MitigationViewDeleteTaskMutation(
mutation MesureViewDeleteTaskMutation(
$input: DeleteTaskInput!
$connections: [ID!]!
) {
@@ -234,7 +233,7 @@ const deleteTaskMutation = graphql`
`;
const createEvidenceMutation = graphql`
mutation MitigationViewCreateEvidenceMutation(
mutation MesureViewCreateEvidenceMutation(
$input: CreateEvidenceInput!
$connections: [ID!]!
) {
@@ -258,7 +257,7 @@ const createEvidenceMutation = graphql`
`;
const deleteEvidenceMutation = graphql`
mutation MitigationViewDeleteEvidenceMutation(
mutation MesureViewDeleteEvidenceMutation(
$input: DeleteEvidenceInput!
$connections: [ID!]!
) {
@@ -270,7 +269,7 @@ const deleteEvidenceMutation = graphql`
// Add a GraphQL query to fetch the fileUrl for an evidence item
const getEvidenceFileUrlQuery = graphql`
query MitigationViewGetEvidenceFileUrlQuery($evidenceId: ID!) {
query MesureViewGetEvidenceFileUrlQuery($evidenceId: ID!) {
node(id: $evidenceId) {
... on Evidence {
id
@@ -281,7 +280,7 @@ const getEvidenceFileUrlQuery = graphql`
`;
const assignTaskMutation = graphql`
mutation MitigationViewAssignTaskMutation($input: AssignTaskInput!) {
mutation MesureViewAssignTaskMutation($input: AssignTaskInput!) {
assignTask(input: $input) {
task {
id
@@ -296,7 +295,7 @@ const assignTaskMutation = graphql`
`;
const unassignTaskMutation = graphql`
mutation MitigationViewUnassignTaskMutation($input: UnassignTaskInput!) {
mutation MesureViewUnassignTaskMutation($input: UnassignTaskInput!) {
unassignTask(input: $input) {
task {
id
@@ -310,12 +309,10 @@ const unassignTaskMutation = graphql`
}
`;
const updateMitigationStateMutation = graphql`
mutation MitigationViewUpdateMitigationStateMutation(
$input: UpdateMitigationInput!
) {
updateMitigation(input: $input) {
mitigation {
const updateMesureStateMutation = graphql`
mutation MesureViewUpdateMesureStateMutation($input: UpdateMesureInput!) {
updateMesure(input: $input) {
mesure {
id
state
}
@@ -324,12 +321,12 @@ const updateMitigationStateMutation = graphql`
`;
const organizationQuery = graphql`
query MitigationViewOrganizationQuery($organizationId: ID!) {
query MesureViewOrganizationQuery($organizationId: ID!) {
organization: node(id: $organizationId) {
id
... on Organization {
peoples(first: 100, orderBy: { direction: ASC, field: FULL_NAME })
@connection(key: "MitigationView_peoples") {
@connection(key: "MesureView_peoples") {
edges {
node {
id
@@ -345,7 +342,7 @@ const organizationQuery = graphql`
// New queries and mutations for Control Mapping
const frameworksQuery = graphql`
query MitigationViewFrameworksQuery($organizationId: ID!) {
query MesureViewFrameworksQuery($organizationId: ID!) {
organization: node(id: $organizationId) {
id
... on Organization {
@@ -373,11 +370,11 @@ const frameworksQuery = graphql`
`;
const linkedControlsQuery = graphql`
query MitigationViewLinkedControlsQuery($mitigationId: ID!) {
mitigation: node(id: $mitigationId) {
query MesureViewLinkedControlsQuery($mesureId: ID!) {
mesure: node(id: $mesureId) {
id
... on Mitigation {
controls(first: 100) @connection(key: "Mitigation__controls") {
... on Mesure {
controls(first: 100) @connection(key: "MesureView_controls") {
edges {
node {
id
@@ -393,20 +390,20 @@ const linkedControlsQuery = graphql`
`;
const createControlMappingMutation = graphql`
mutation MitigationViewCreateControlMappingMutation(
$input: CreateControlMitigationMappingInput!
mutation MesureViewCreateControlMappingMutation(
$input: CreateControlMesureMappingInput!
) {
createControlMitigationMapping(input: $input) {
createControlMesureMapping(input: $input) {
success
}
}
`;
const deleteControlMappingMutation = graphql`
mutation MitigationViewDeleteControlMappingMutation(
$input: DeleteControlMitigationMappingInput!
mutation MesureViewDeleteControlMappingMutation(
$input: DeleteControlMesureMappingInput!
) {
deleteControlMitigationMapping(input: $input) {
deleteControlMesureMapping(input: $input) {
success
}
}
@@ -414,7 +411,7 @@ const deleteControlMappingMutation = graphql`
// Add a mutation to fulfill evidence
const fulfillEvidenceMutation = graphql`
mutation MitigationViewFulfillEvidenceMutation(
mutation MesureViewFulfillEvidenceMutation(
$input: FulfillEvidenceInput!
$connections: [ID!]!
) {
@@ -437,13 +434,13 @@ const fulfillEvidenceMutation = graphql`
}
`;
// Add query to fetch risks linked to a mitigation
const mitigationRisksQuery = graphql`
query MitigationViewRisksQuery($mitigationId: ID!) {
mitigation: node(id: $mitigationId) {
// Add query to fetch risks linked to a mesure
const mesureRisksQuery = graphql`
query MesureViewRisksQuery($mesureId: ID!) {
mesure: node(id: $mesureId) {
id
... on Mitigation {
risks(first: 100) @connection(key: "MitigationView_risks") {
... on Mesure {
risks(first: 100) @connection(key: "MesureView_risks") {
edges {
node {
id
@@ -499,8 +496,8 @@ type RiskNode = {
};
// Define the risks data type
type MitigationRisksData = {
mitigation?: {
type MesureRisksData = {
mesure?: {
id: string;
risks?: {
edges: Array<{
@@ -510,17 +507,17 @@ type MitigationRisksData = {
};
};
function MitigationViewContent({
function MesureViewContent({
queryRef,
}: {
queryRef: PreloadedQuery<MitigationViewQueryType>;
queryRef: PreloadedQuery<MesureViewQueryType>;
}) {
const data = usePreloadedQuery<MitigationViewQueryType>(
mitigationViewQuery,
const data = usePreloadedQuery<MesureViewQueryType>(
mesureViewQuery,
queryRef
);
const { toast } = useToast();
const { organizationId, mitigationId } = useParams();
const { organizationId, mesureId } = useParams();
const navigate = useNavigate();
const environment = useRelayEnvironment();
@@ -533,15 +530,15 @@ function MitigationViewContent({
// Load organization data for people selector
const [organizationData, setOrganizationData] =
useState<MitigationViewOrganizationQuery$data | null>(null);
useState<MesureViewOrganizationQuery$data | null>(null);
// Control mapping state
const [isControlMappingDialogOpen, setIsControlMappingDialogOpen] =
useState(false);
const [frameworksData, setFrameworksData] =
useState<MitigationViewFrameworksQuery$data | null>(null);
useState<MesureViewFrameworksQuery$data | null>(null);
const [linkedControlsData, setLinkedControlsData] =
useState<MitigationViewLinkedControlsQuery$data | null>(null);
useState<MesureViewLinkedControlsQuery$data | null>(null);
const [controlSearchQuery, setControlSearchQuery] = useState("");
const [selectedFrameworkId, setSelectedFrameworkId] = useState<string | null>(
null
@@ -562,7 +559,7 @@ function MitigationViewContent({
if (organizationId) {
fetchQuery(environment, organizationQuery, { organizationId }).subscribe({
next: (data: unknown) => {
setOrganizationData(data as MitigationViewOrganizationQuery$data);
setOrganizationData(data as MesureViewOrganizationQuery$data);
},
error: (error: Error) => {
console.error("Error fetching organization:", error);
@@ -573,36 +570,34 @@ function MitigationViewContent({
// Load linked controls when component mounts
useEffect(() => {
if (mitigationId) {
fetchQuery(environment, linkedControlsQuery, { mitigationId }).subscribe({
if (mesureId) {
fetchQuery(environment, linkedControlsQuery, { mesureId }).subscribe({
next: (data: unknown) => {
setLinkedControlsData(data as MitigationViewLinkedControlsQuery$data);
setLinkedControlsData(data as MesureViewLinkedControlsQuery$data);
},
error: (error: Error) => {
console.error("Error fetching linked controls:", error);
},
});
}
}, [environment, mitigationId]);
}, [environment, mesureId]);
// Add state for risks data
const [risksData, setRisksData] = useState<MitigationRisksData | null>(null);
const [risksData, setRisksData] = useState<MesureRisksData | null>(null);
// Load risks data when component mounts
useEffect(() => {
if (mitigationId) {
fetchQuery(environment, mitigationRisksQuery, { mitigationId }).subscribe(
{
next: (data: unknown) => {
setRisksData(data as MitigationRisksData);
},
error: (error: Error) => {
console.error("Error fetching risks:", error);
},
}
);
if (mesureId) {
fetchQuery(environment, mesureRisksQuery, { mesureId }).subscribe({
next: (data: unknown) => {
setRisksData(data as MesureRisksData);
},
error: (error: Error) => {
console.error("Error fetching risks:", error);
},
});
}
}, [environment, mitigationId]);
}, [environment, mesureId]);
const formatImportance = (importance: string | undefined): string => {
if (!importance) return "";
@@ -656,33 +651,30 @@ function MitigationViewContent({
return "bg-secondary-bg text-primary";
};
const [updateTask] = useMutation<MitigationViewUpdateTaskStateMutationType>(
const [updateTask] = useMutation<MesureViewUpdateTaskStateMutationType>(
updateTaskStateMutation
);
const [createTask] =
useMutation<MitigationViewCreateTaskMutationType>(createTaskMutation);
useMutation<MesureViewCreateTaskMutationType>(createTaskMutation);
const [deleteTask] =
useMutation<MitigationViewDeleteTaskMutationType>(deleteTaskMutation);
const [createEvidence] =
useMutation<MitigationViewCreateEvidenceMutationType>(
createEvidenceMutation
);
const [deleteEvidence] =
useMutation<MitigationViewDeleteEvidenceMutationType>(
deleteEvidenceMutation
);
useMutation<MesureViewDeleteTaskMutationType>(deleteTaskMutation);
const [createEvidence] = useMutation<MesureViewCreateEvidenceMutationType>(
createEvidenceMutation
);
const [deleteEvidence] = useMutation<MesureViewDeleteEvidenceMutationType>(
deleteEvidenceMutation
);
const [assignTask] =
useMutation<MitigationViewAssignTaskMutationType>(assignTaskMutation);
useMutation<MesureViewAssignTaskMutationType>(assignTaskMutation);
const [unassignTask] =
useMutation<MitigationViewUnassignTaskMutationType>(unassignTaskMutation);
const [fulfillEvidence] =
useMutation<MitigationViewFulfillEvidenceMutationType>(
fulfillEvidenceMutation
);
useMutation<MesureViewUnassignTaskMutationType>(unassignTaskMutation);
const [fulfillEvidence] = useMutation<MesureViewFulfillEvidenceMutationType>(
fulfillEvidenceMutation
);
const [updateMitigationState] =
useMutation<MitigationViewUpdateMitigationStateMutationType>(
updateMitigationStateMutation
const [updateMesureState] =
useMutation<MesureViewUpdateMesureStateMutationType>(
updateMesureStateMutation
);
const [isCreateTaskOpen, setIsCreateTaskOpen] = useState(false);
@@ -765,7 +757,7 @@ function MitigationViewContent({
// Track if task panel is open
const [isTaskPanelOpen, setIsTaskPanelOpen] = useState(false);
const tasks = data.mitigation.tasks?.edges.map((edge) => edge.node) || [];
const tasks = data.mesure.tasks?.edges.map((edge) => edge.node) || [];
// Add useEffect to handle URL parameters for task selection
useEffect(() => {
@@ -907,10 +899,10 @@ function MitigationViewContent({
return;
}
if (!data.mitigation.id) {
if (!data.mesure.id) {
toast({
title: "Error creating task",
description: "Mitigation ID is missing",
description: "Mesure ID is missing",
variant: "destructive",
});
return;
@@ -920,9 +912,9 @@ function MitigationViewContent({
createTask({
variables: {
connections: [`${data.mitigation.tasks?.__id}`],
connections: [`${data.mesure.tasks?.__id}`],
input: {
mitigationId: data.mitigation.id,
mesureId: data.mesure.id,
name: newTaskName,
description: newTaskDescription,
timeEstimate: isoTimeEstimate === "" ? null : isoTimeEstimate,
@@ -960,7 +952,7 @@ function MitigationViewContent({
deleteTask({
variables: {
connections: [`${data.mitigation.tasks?.__id}`],
connections: [`${data.mesure.tasks?.__id}`],
input: {
taskId: taskToDelete.id,
},
@@ -983,10 +975,8 @@ function MitigationViewContent({
});
};
const handleEditMitigation = () => {
navigate(
`/organizations/${organizationId}/mitigations/${mitigationId}/edit`
);
const handleEditMesure = () => {
navigate(`/organizations/${organizationId}/mesures/${mesureId}/edit`);
};
const handleCreateEvidence = (taskId: string, taskName: string) => {
@@ -1458,12 +1448,12 @@ function MitigationViewContent({
});
};
// Function to handle mitigation state change
const handleMitigationStateChange = (newState: string) => {
updateMitigationState({
// Function to handle mesure state change
const handleMesureStateChange = (newState: string) => {
updateMesureState({
variables: {
input: {
id: data.mitigation.id,
id: data.mesure.id,
state: newState as
| "NOT_STARTED"
| "IN_PROGRESS"
@@ -1473,15 +1463,15 @@ function MitigationViewContent({
},
onCompleted: () => {
toast({
title: "Mitigation state updated",
description: `Mitigation state has been updated to ${formatState(
title: "Mesure state updated",
description: `Mesure state has been updated to ${formatState(
newState
)}.`,
});
},
onError: (error) => {
toast({
title: "Error updating mitigation state",
title: "Error updating mesure state",
description: error.message,
variant: "destructive",
});
@@ -1612,12 +1602,12 @@ function MitigationViewContent({
// Control mapping functions
const loadFrameworksAndControls = useCallback(() => {
if (!organizationId || !mitigationId) return;
if (!organizationId || !mesureId) return;
setIsLoadingControls(true);
// Fetch all frameworks and their controls
fetchQuery<MitigationViewFrameworksQuery>(environment, frameworksQuery, {
fetchQuery<MesureViewFrameworksQuery>(environment, frameworksQuery, {
organizationId,
}).subscribe({
next: (data) => {
@@ -1635,14 +1625,12 @@ function MitigationViewContent({
}
},
complete: () => {
// Fetch already linked controls for this mitigation
// Fetch already linked controls for this mesure
fetchQuery(environment, linkedControlsQuery, {
mitigationId,
mesureId,
}).subscribe({
next: (data: unknown) => {
setLinkedControlsData(
data as MitigationViewLinkedControlsQuery$data
);
setLinkedControlsData(data as MesureViewLinkedControlsQuery$data);
setIsLoadingControls(false);
},
error: (error: Error) => {
@@ -1666,7 +1654,7 @@ function MitigationViewContent({
});
},
});
}, [environment, mitigationId, organizationId, selectedFrameworkId, toast]);
}, [environment, mesureId, organizationId, selectedFrameworkId, toast]);
const getControls = useCallback(() => {
if (!frameworksData?.organization?.frameworks?.edges) return [];
@@ -1691,8 +1679,8 @@ function MitigationViewContent({
}, [frameworksData, selectedFrameworkId]);
const getLinkedControls = useCallback(() => {
if (!linkedControlsData?.mitigation?.controls?.edges) return [];
return (linkedControlsData.mitigation.controls.edges || []).map(
if (!linkedControlsData?.mesure?.controls?.edges) return [];
return (linkedControlsData.mesure.controls.edges || []).map(
(edge) => edge.node
);
}, [linkedControlsData]);
@@ -1709,7 +1697,7 @@ function MitigationViewContent({
const handleLinkControl = useCallback(
(controlId: string) => {
if (!mitigationId) return;
if (!mesureId) return;
setIsLinkingControl(true);
@@ -1717,7 +1705,7 @@ function MitigationViewContent({
variables: {
input: {
controlId,
mitigationId,
mesureId,
},
},
onCompleted: (_, errors) => {
@@ -1734,11 +1722,11 @@ function MitigationViewContent({
}
// Refresh linked controls data
fetchQuery<MitigationViewLinkedControlsQuery>(
fetchQuery<MesureViewLinkedControlsQuery>(
environment,
linkedControlsQuery,
{
mitigationId,
mesureId,
}
).subscribe({
next: (data) => {
@@ -1751,7 +1739,7 @@ function MitigationViewContent({
toast({
title: "Success",
description: "Control successfully linked to mitigation.",
description: "Control successfully linked to mesure.",
});
},
onError: (error) => {
@@ -1765,12 +1753,12 @@ function MitigationViewContent({
},
});
},
[commitCreateControlMapping, environment, mitigationId, toast]
[commitCreateControlMapping, environment, mesureId, toast]
);
const handleUnlinkControl = useCallback(
(controlId: string) => {
if (!mitigationId) return;
if (!mesureId) return;
setIsUnlinkingControl(true);
@@ -1778,7 +1766,7 @@ function MitigationViewContent({
variables: {
input: {
controlId,
mitigationId,
mesureId,
},
},
onCompleted: (_, errors) => {
@@ -1796,12 +1784,10 @@ function MitigationViewContent({
// Refresh linked controls data
fetchQuery(environment, linkedControlsQuery, {
mitigationId,
mesureId,
}).subscribe({
next: (data: unknown) => {
setLinkedControlsData(
data as MitigationViewLinkedControlsQuery$data
);
setLinkedControlsData(data as MesureViewLinkedControlsQuery$data);
},
error: (error: Error) => {
console.error("Error refreshing linked controls:", error);
@@ -1810,7 +1796,7 @@ function MitigationViewContent({
toast({
title: "Success",
description: "Control successfully unlinked from mitigation.",
description: "Control successfully unlinked from mesure.",
});
},
onError: (error) => {
@@ -1824,7 +1810,7 @@ function MitigationViewContent({
},
});
},
[commitDeleteControlMapping, environment, mitigationId, toast]
[commitDeleteControlMapping, environment, mesureId, toast]
);
const handleOpenControlMappingDialog = useCallback(() => {
@@ -1882,21 +1868,21 @@ function MitigationViewContent({
return (
<PageTemplate
title={data.mitigation.name ?? ""}
title={data.mesure.name ?? ""}
actions={
<div className="flex items-center gap-2">
<Button onClick={handleEditMitigation}>Edit Mitigation</Button>
<Button onClick={handleEditMesure}>Edit Mesure</Button>
<Select
defaultValue={data.mitigation.state}
onValueChange={handleMitigationStateChange}
defaultValue={data.mesure.state}
onValueChange={handleMesureStateChange}
>
<SelectTrigger className="w-[160px] h-10 text-sm">
<div
className={`${getStateColor(
data.mitigation.state
data.mesure.state
)} px-2 py-0.5 rounded-sm text-sm w-full text-center`}
>
{formatState(data.mitigation.state)}
{formatState(data.mesure.state)}
</div>
</SelectTrigger>
<SelectContent>
@@ -1908,10 +1894,10 @@ function MitigationViewContent({
</Select>
<div
className={`${getImportanceColor(
data.mitigation.importance
data.mesure.importance
)} px-3 py-1 rounded-full text-sm`}
>
{formatImportance(data.mitigation.importance)}
{formatImportance(data.mesure.importance)}
</div>
</div>
}
@@ -1920,7 +1906,7 @@ function MitigationViewContent({
<Card className="mt-4">
<CardContent className="pt-6">
<div className="prose prose-gray prose-sm md:prose-base text-secondary max-w-3xl">
<ReactMarkdown>{data.mitigation.description}</ReactMarkdown>
<ReactMarkdown>{data.mesure.description}</ReactMarkdown>
</div>
</CardContent>
</Card>
@@ -1946,20 +1932,20 @@ function MitigationViewContent({
<TabsTrigger value="controls" className="flex items-center gap-2">
<ShieldCheck className="w-4 h-4" />
Controls
{linkedControlsData?.mitigation?.controls?.edges &&
linkedControlsData.mitigation.controls.edges.length > 0 && (
{linkedControlsData?.mesure?.controls?.edges &&
linkedControlsData.mesure.controls.edges.length > 0 && (
<span className="ml-1.5 bg-blue-100 text-blue-800 rounded-full text-xs px-2 py-0.5">
{linkedControlsData.mitigation.controls.edges.length}
{linkedControlsData.mesure.controls.edges.length}
</span>
)}
</TabsTrigger>
<TabsTrigger value="risks" className="flex items-center gap-2">
<AlertTriangle className="w-4 h-4" />
Risks
{risksData?.mitigation?.risks?.edges &&
risksData.mitigation.risks.edges.length > 0 && (
{risksData?.mesure?.risks?.edges &&
risksData.mesure.risks.edges.length > 0 && (
<span className="ml-1.5 bg-blue-100 text-blue-800 rounded-full text-xs px-2 py-0.5">
{risksData.mitigation.risks.edges.length}
{risksData.mesure.risks.edges.length}
</span>
)}
</TabsTrigger>
@@ -1988,10 +1974,10 @@ function MitigationViewContent({
>
<DialogContent className="max-w-3xl max-h-[80vh] overflow-hidden flex flex-col">
<DialogHeader>
<DialogTitle>Map Mitigation to Controls</DialogTitle>
<DialogTitle>Map Mesure to Controls</DialogTitle>
<DialogDescription>
Search and select controls to link to this mitigation. This
helps track which controls are addressed by this mitigation.
Search and select controls to link to this mesure. This
helps track which controls are addressed by this mesure.
</DialogDescription>
</DialogHeader>
@@ -2140,8 +2126,8 @@ function MitigationViewContent({
{/* Linked Controls List */}
<Card>
<CardContent className="p-4">
{linkedControlsData?.mitigation?.controls?.edges &&
linkedControlsData.mitigation.controls.edges.length > 0 ? (
{linkedControlsData?.mesure?.controls?.edges &&
linkedControlsData.mesure.controls.edges.length > 0 ? (
<div className="overflow-x-auto">
<table className="w-full">
<thead>
@@ -2189,8 +2175,8 @@ function MitigationViewContent({
</div>
) : (
<div className="text-center py-8 text-secondary">
No controls linked to this mitigation yet. Click &quot;Map
to Controls&quot; to link controls.
No controls linked to this mesure yet. Click &quot;Map to
Controls&quot; to link controls.
</div>
)}
</CardContent>
@@ -2222,7 +2208,7 @@ function MitigationViewContent({
<DialogHeader>
<DialogTitle>Create New Task</DialogTitle>
<DialogDescription>
Add a new task to this mitigation. Click save when
Add a new task to this mesure. Click save when
you&apos;re done.
</DialogDescription>
</DialogHeader>
@@ -2809,8 +2795,8 @@ function MitigationViewContent({
<Card>
<CardContent className="p-4">
{risksData?.mitigation?.risks?.edges &&
risksData.mitigation.risks.edges.length > 0 ? (
{risksData?.mesure?.risks?.edges &&
risksData.mesure.risks.edges.length > 0 ? (
<div className="overflow-x-auto">
<table className="w-full">
<thead>
@@ -2830,7 +2816,7 @@ function MitigationViewContent({
</tr>
</thead>
<tbody>
{risksData.mitigation.risks.edges.map(({ node }) => (
{risksData.mesure.risks.edges.map(({ node }) => (
<tr
key={node.id}
className="border-b hover:bg-invert-bg"
@@ -2870,7 +2856,7 @@ function MitigationViewContent({
</div>
) : (
<div className="text-center py-8 text-secondary">
No risks linked to this mitigation yet.
No risks linked to this mesure yet.
</div>
)}
</CardContent>
@@ -3674,24 +3660,24 @@ function MitigationViewContent({
);
}
export default function MitigationView() {
const { mitigationId } = useParams();
export default function MesureView() {
const { mesureId } = useParams();
const [queryRef, loadQuery] =
useQueryLoader<MitigationViewQueryType>(mitigationViewQuery);
useQueryLoader<MesureViewQueryType>(mesureViewQuery);
useEffect(() => {
if (mitigationId) {
loadQuery({ mitigationId });
if (mesureId) {
loadQuery({ mesureId });
}
}, [mitigationId, loadQuery]);
}, [mesureId, loadQuery]);
if (!queryRef) {
return <MitigationViewSkeleton />;
return <MesureViewSkeleton />;
}
return (
<Suspense fallback={<MitigationViewSkeleton />}>
<MitigationViewContent queryRef={queryRef} />
<Suspense fallback={<MesureViewSkeleton />}>
<MesureViewContent queryRef={queryRef} />
</Suspense>
);
}

View File

@@ -4,26 +4,26 @@ import { lazy } from "@probo/react-lazy";
import { useLocation } from "react-router";
import { ErrorBoundaryWithLocation } from "../ErrorBoundary";
const EditMitigationView = lazy(() => import("./EditMitigationView"));
const NewMesureView = lazy(() => import("./NewMesureView"));
export function EditMitigationViewSkeleton() {
export function NewMesureViewSkeleton() {
return (
<PageTemplateSkeleton
title="Edit Mitigation"
description="Edit a mitigation. You will be able to link it to control and risks"
title="New Mesure"
description="Add a new mesure. You will be able to link it to control and risks"
>
<div className="max-w-2xl aspect-square bg-subtle-bg rounded-xl animate-pulse" />
</PageTemplateSkeleton>
);
}
export function EditMitigationPage() {
export function NewMesurePage() {
const location = useLocation();
return (
<Suspense key={location.pathname} fallback={<EditMitigationViewSkeleton />}>
<Suspense key={location.pathname} fallback={<NewMesureViewSkeleton />}>
<ErrorBoundaryWithLocation>
<EditMitigationView />
<NewMesureView />
</ErrorBoundaryWithLocation>
</Suspense>
);

View File

@@ -3,20 +3,20 @@ import { ConnectionHandler, graphql, useMutation } from "react-relay";
import { useParams, useNavigate } from "react-router";
import { PageTemplate } from "@/components/PageTemplate";
import { useToast } from "@/hooks/use-toast";
import { NewMitigationViewCreateMitigationMutation } from "./__generated__/NewMitigationViewCreateMitigationMutation.graphql";
import { NewMesureViewCreateMesureMutation } from "./__generated__/NewMesureViewCreateMesureMutation.graphql";
import { EditableField } from "@/components/EditableField";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { cn } from "@/lib/utils";
const createMitigationMutation = graphql`
mutation NewMitigationViewCreateMitigationMutation(
$input: CreateMitigationInput!
const createMesureMutation = graphql`
mutation NewMesureViewCreateMesureMutation(
$input: CreateMesureInput!
$connections: [ID!]!
) {
createMitigation(input: $input) {
mitigationEdge @prependEdge(connections: $connections) {
createMesure(input: $input) {
mesureEdge @prependEdge(connections: $connections) {
node {
id
name
@@ -27,7 +27,7 @@ const createMitigationMutation = graphql`
}
`;
export default function NewMitigationView() {
export default function NewMesureView() {
const { organizationId } = useParams<{
organizationId: string;
}>();
@@ -41,9 +41,7 @@ export default function NewMitigationView() {
});
const [commit, isInFlight] =
useMutation<NewMitigationViewCreateMitigationMutation>(
createMitigationMutation
);
useMutation<NewMesureViewCreateMesureMutation>(createMesureMutation);
const handleFieldChange = (field: keyof typeof formData, value: unknown) => {
setFormData((prev) => ({
@@ -66,7 +64,7 @@ export default function NewMitigationView() {
const connectionId = ConnectionHandler.getConnectionID(
organizationId!,
"MitigationListView_mitigations"
"MesureListView_mesures"
);
commit({
@@ -84,7 +82,7 @@ export default function NewMitigationView() {
if (errors) {
toast({
title: "Error",
description: errors[0]?.message || "Failed to create mitigation",
description: errors[0]?.message || "Failed to create mesure",
variant: "destructive",
});
return;
@@ -92,17 +90,17 @@ export default function NewMitigationView() {
toast({
title: "Success",
description: "Mitigation created successfully",
description: "Mesure created successfully",
});
navigate(
`/organizations/${organizationId}/mitigations/${data.createMitigation.mitigationEdge.node.id}`
`/organizations/${organizationId}/mesures/${data.createMesure.mesureEdge.node.id}`
);
},
onError(error) {
toast({
title: "Error",
description: error.message || "Failed to create mitigation",
description: error.message || "Failed to create mesure",
variant: "destructive",
});
},
@@ -111,8 +109,8 @@ export default function NewMitigationView() {
return (
<PageTemplate
title="New Mitigation"
description="Add a new mitigation. You will be able to link it to control and risks"
title="New Mesure"
description="Add a new mesure. You will be able to link it to control and risks"
>
<Card className="max-w-2xl">
<form onSubmit={handleSubmit} className="p-6 space-y-6">
@@ -129,7 +127,7 @@ export default function NewMitigationView() {
onChange={(value) => handleFieldChange("description", value)}
required
multiline
helpText="Provide a detailed description of the mitigation"
helpText="Provide a detailed description of the mesure"
/>
<EditableField
@@ -190,13 +188,13 @@ export default function NewMitigationView() {
type="button"
variant="outline"
onClick={() =>
navigate(`/organizations/${organizationId}/mitigations`)
navigate(`/organizations/${organizationId}/mesures`)
}
>
Cancel
</Button>
<Button type="submit" disabled={isInFlight}>
{isInFlight ? "Creating..." : "Create Mitigation"}
{isInFlight ? "Creating..." : "Create Mesure"}
</Button>
</div>
</form>

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<851436cc3003fed7f1e384d153eff0b7>>
* @generated SignedSource<<7a5c27ece406a4250a38977e9ed9173f>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,22 +9,22 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type MitigationImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type EditMitigationViewQuery$variables = {
mitigationId: string;
export type MesureImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type EditMesureViewQuery$variables = {
mesureId: string;
};
export type EditMitigationViewQuery$data = {
export type EditMesureViewQuery$data = {
readonly node: {
readonly category?: string;
readonly description?: string;
readonly id?: string;
readonly importance?: MitigationImportance;
readonly importance?: MesureImportance;
readonly name?: string;
};
};
export type EditMitigationViewQuery = {
response: EditMitigationViewQuery$data;
variables: EditMitigationViewQuery$variables;
export type EditMesureViewQuery = {
response: EditMesureViewQuery$data;
variables: EditMesureViewQuery$variables;
};
const node: ConcreteRequest = (function(){
@@ -32,14 +32,14 @@ var v0 = [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "mitigationId"
"name": "mesureId"
}
],
v1 = [
{
"kind": "Variable",
"name": "id",
"variableName": "mitigationId"
"variableName": "mesureId"
}
],
v2 = {
@@ -82,7 +82,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "EditMitigationViewQuery",
"name": "EditMesureViewQuery",
"selections": [
{
"alias": null,
@@ -101,7 +101,7 @@ return {
(v5/*: any*/),
(v6/*: any*/)
],
"type": "Mitigation",
"type": "Mesure",
"abstractKey": null
}
],
@@ -115,7 +115,7 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "EditMitigationViewQuery",
"name": "EditMesureViewQuery",
"selections": [
{
"alias": null,
@@ -141,7 +141,7 @@ return {
(v5/*: any*/),
(v6/*: any*/)
],
"type": "Mitigation",
"type": "Mesure",
"abstractKey": null
}
],
@@ -150,16 +150,16 @@ return {
]
},
"params": {
"cacheID": "df8ca216b15dda843c6da7f82bc4fb37",
"cacheID": "d38df91a88f32d80da84fc47b7ca17ca",
"id": null,
"metadata": {},
"name": "EditMitigationViewQuery",
"name": "EditMesureViewQuery",
"operationKind": "query",
"text": "query EditMitigationViewQuery(\n $mitigationId: ID!\n) {\n node(id: $mitigationId) {\n __typename\n ... on Mitigation {\n id\n name\n description\n category\n importance\n }\n id\n }\n}\n"
"text": "query EditMesureViewQuery(\n $mesureId: ID!\n) {\n node(id: $mesureId) {\n __typename\n ... on Mesure {\n id\n name\n description\n category\n importance\n }\n id\n }\n}\n"
}
};
})();
(node as any).hash = "bb3db4a2e4bcdcd77f8847d302f74340";
(node as any).hash = "abca56f710248363bacef919222a8420";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<ef4c93d248af00040b679e1bdb225a64>>
* @generated SignedSource<<869dc4adbc0716aa90912098821ce101>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,31 +9,31 @@
// @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 UpdateMitigationInput = {
export type MesureImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type MesureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type UpdateMesureInput = {
category?: string | null | undefined;
description?: string | null | undefined;
id: string;
importance?: MitigationImportance | null | undefined;
importance?: MesureImportance | null | undefined;
name?: string | null | undefined;
state?: MitigationState | null | undefined;
state?: MesureState | null | undefined;
};
export type EditMitigationViewUpdateMitigationMutation$variables = {
input: UpdateMitigationInput;
export type EditMesureViewUpdateMesureMutation$variables = {
input: UpdateMesureInput;
};
export type EditMitigationViewUpdateMitigationMutation$data = {
readonly updateMitigation: {
readonly mitigation: {
export type EditMesureViewUpdateMesureMutation$data = {
readonly updateMesure: {
readonly mesure: {
readonly description: string;
readonly id: string;
readonly name: string;
};
};
};
export type EditMitigationViewUpdateMitigationMutation = {
response: EditMitigationViewUpdateMitigationMutation$data;
variables: EditMitigationViewUpdateMitigationMutation$variables;
export type EditMesureViewUpdateMesureMutation = {
response: EditMesureViewUpdateMesureMutation$data;
variables: EditMesureViewUpdateMesureMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -54,17 +54,17 @@ v1 = [
"variableName": "input"
}
],
"concreteType": "UpdateMitigationPayload",
"concreteType": "UpdateMesurePayload",
"kind": "LinkedField",
"name": "updateMitigation",
"name": "updateMesure",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Mitigation",
"concreteType": "Mesure",
"kind": "LinkedField",
"name": "mitigation",
"name": "mesure",
"plural": false,
"selections": [
{
@@ -100,7 +100,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "EditMitigationViewUpdateMitigationMutation",
"name": "EditMesureViewUpdateMesureMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
@@ -109,20 +109,20 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "EditMitigationViewUpdateMitigationMutation",
"name": "EditMesureViewUpdateMesureMutation",
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "b28b509d2111119e074541df44720f4f",
"cacheID": "ab674147338f145102c150b220578304",
"id": null,
"metadata": {},
"name": "EditMitigationViewUpdateMitigationMutation",
"name": "EditMesureViewUpdateMesureMutation",
"operationKind": "mutation",
"text": "mutation EditMitigationViewUpdateMitigationMutation(\n $input: UpdateMitigationInput!\n) {\n updateMitigation(input: $input) {\n mitigation {\n id\n name\n description\n }\n }\n}\n"
"text": "mutation EditMesureViewUpdateMesureMutation(\n $input: UpdateMesureInput!\n) {\n updateMesure(input: $input) {\n mesure {\n id\n name\n description\n }\n }\n}\n"
}
};
})();
(node as any).hash = "30ac146016e936fd8912b480286c93de";
(node as any).hash = "5f00ce5e7a705abecd93b06e727d5587";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<d4590a13a15cf248104340854bc46aa7>>
* @generated SignedSource<<251663bea47f61a5857366afa4cc0d28>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,35 +9,35 @@
// @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 ImportMitigationInput = {
export type MesureImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type MesureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type ImportMesureInput = {
file: any;
organizationId: string;
};
export type MitigationListViewImportMitigationMutation$variables = {
export type MesureListViewImportMesureMutation$variables = {
connections: ReadonlyArray<string>;
input: ImportMitigationInput;
input: ImportMesureInput;
};
export type MitigationListViewImportMitigationMutation$data = {
readonly importMitigation: {
readonly mitigationEdges: ReadonlyArray<{
export type MesureListViewImportMesureMutation$data = {
readonly importMesure: {
readonly mesureEdges: ReadonlyArray<{
readonly node: {
readonly category: string;
readonly createdAt: string;
readonly description: string;
readonly id: string;
readonly importance: MitigationImportance;
readonly importance: MesureImportance;
readonly name: string;
readonly state: MitigationState;
readonly state: MesureState;
readonly updatedAt: string;
};
}>;
};
};
export type MitigationListViewImportMitigationMutation = {
response: MitigationListViewImportMitigationMutation$data;
variables: MitigationListViewImportMitigationMutation$variables;
export type MesureListViewImportMesureMutation = {
response: MesureListViewImportMesureMutation$data;
variables: MesureListViewImportMesureMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -61,15 +61,15 @@ v2 = [
v3 = {
"alias": null,
"args": null,
"concreteType": "MitigationEdge",
"concreteType": "MesureEdge",
"kind": "LinkedField",
"name": "mitigationEdges",
"name": "mesureEdges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Mitigation",
"concreteType": "Mesure",
"kind": "LinkedField",
"name": "node",
"plural": false,
@@ -144,14 +144,14 @@ return {
],
"kind": "Fragment",
"metadata": null,
"name": "MitigationListViewImportMitigationMutation",
"name": "MesureListViewImportMesureMutation",
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "ImportMitigationPayload",
"concreteType": "ImportMesurePayload",
"kind": "LinkedField",
"name": "importMitigation",
"name": "importMesure",
"plural": false,
"selections": [
(v3/*: any*/)
@@ -169,14 +169,14 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
"name": "MitigationListViewImportMitigationMutation",
"name": "MesureListViewImportMesureMutation",
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "ImportMitigationPayload",
"concreteType": "ImportMesurePayload",
"kind": "LinkedField",
"name": "importMitigation",
"name": "importMesure",
"plural": false,
"selections": [
(v3/*: any*/),
@@ -187,7 +187,7 @@ return {
"handle": "appendEdge",
"key": "",
"kind": "LinkedHandle",
"name": "mitigationEdges",
"name": "mesureEdges",
"handleArgs": [
{
"kind": "Variable",
@@ -202,16 +202,16 @@ return {
]
},
"params": {
"cacheID": "84c038c572378999bfaacb87e8172b1e",
"cacheID": "179ac701005009dc5f30388570061264",
"id": null,
"metadata": {},
"name": "MitigationListViewImportMitigationMutation",
"name": "MesureListViewImportMesureMutation",
"operationKind": "mutation",
"text": "mutation MitigationListViewImportMitigationMutation(\n $input: ImportMitigationInput!\n) {\n importMitigation(input: $input) {\n mitigationEdges {\n node {\n id\n name\n description\n category\n state\n importance\n createdAt\n updatedAt\n }\n }\n }\n}\n"
"text": "mutation MesureListViewImportMesureMutation(\n $input: ImportMesureInput!\n) {\n importMesure(input: $input) {\n mesureEdges {\n node {\n id\n name\n description\n category\n state\n importance\n createdAt\n updatedAt\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "59e3d4a8e71cee0dcee606b93d706dad";
(node as any).hash = "c1c9deeaa806b9553b7eb25d8832818c";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<cfd9a630fcbe359cd0b4db0e940dd564>>
* @generated SignedSource<<90d959a85cf60161201cb5736ac6abcf>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,34 +9,34 @@
// @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 MitigationListViewQuery$variables = {
export type MesureImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type MesureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type MesureListViewQuery$variables = {
first?: number | null | undefined;
organizationId: string;
};
export type MitigationListViewQuery$data = {
export type MesureListViewQuery$data = {
readonly organization: {
readonly id: string;
readonly mitigations?: {
readonly mesures?: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly category: string;
readonly createdAt: string;
readonly description: string;
readonly id: string;
readonly importance: MitigationImportance;
readonly importance: MesureImportance;
readonly name: string;
readonly state: MitigationState;
readonly state: MesureState;
readonly updatedAt: string;
};
}>;
};
};
};
export type MitigationListViewQuery = {
response: MitigationListViewQuery$data;
variables: MitigationListViewQuery$variables;
export type MesureListViewQuery = {
response: MesureListViewQuery$data;
variables: MesureListViewQuery$variables;
};
const node: ConcreteRequest = (function(){
@@ -75,7 +75,7 @@ v5 = [
{
"alias": null,
"args": null,
"concreteType": "MitigationEdge",
"concreteType": "MesureEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
@@ -83,7 +83,7 @@ v5 = [
{
"alias": null,
"args": null,
"concreteType": "Mitigation",
"concreteType": "Mesure",
"kind": "LinkedField",
"name": "node",
"plural": false,
@@ -193,7 +193,7 @@ return {
],
"kind": "Fragment",
"metadata": null,
"name": "MitigationListViewQuery",
"name": "MesureListViewQuery",
"selections": [
{
"alias": "organization",
@@ -208,11 +208,11 @@ return {
"kind": "InlineFragment",
"selections": [
{
"alias": "mitigations",
"alias": "mesures",
"args": null,
"concreteType": "MitigationConnection",
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "__MitigationListView_mitigations_connection",
"name": "__MesureListView_mesures_connection",
"plural": false,
"selections": (v5/*: any*/),
"storageKey": null
@@ -235,7 +235,7 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
"name": "MitigationListViewQuery",
"name": "MesureListViewQuery",
"selections": [
{
"alias": "organization",
@@ -253,9 +253,9 @@ return {
{
"alias": null,
"args": (v6/*: any*/),
"concreteType": "MitigationConnection",
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "mitigations",
"name": "mesures",
"plural": false,
"selections": (v5/*: any*/),
"storageKey": null
@@ -265,9 +265,9 @@ return {
"args": (v6/*: any*/),
"filters": null,
"handle": "connection",
"key": "MitigationListView_mitigations",
"key": "MesureListView_mesures",
"kind": "LinkedHandle",
"name": "mitigations"
"name": "mesures"
}
],
"type": "Organization",
@@ -279,7 +279,7 @@ return {
]
},
"params": {
"cacheID": "9951f5e4be50df7a883af63426fe5fde",
"cacheID": "9f6e9e1487bd34be972a52077bc91ee8",
"id": null,
"metadata": {
"connection": [
@@ -289,18 +289,18 @@ return {
"direction": "forward",
"path": [
"organization",
"mitigations"
"mesures"
]
}
]
},
"name": "MitigationListViewQuery",
"name": "MesureListViewQuery",
"operationKind": "query",
"text": "query MitigationListViewQuery(\n $organizationId: ID!\n $first: Int\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n mitigations(first: $first) {\n edges {\n node {\n id\n name\n description\n category\n state\n importance\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
"text": "query MesureListViewQuery(\n $organizationId: ID!\n $first: Int\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n mesures(first: $first) {\n edges {\n node {\n id\n name\n description\n category\n state\n importance\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "6b2de4417fd7175dd9ccd34549e097b7";
(node as any).hash = "47928382749f3bac585927423bcdd09e";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<c176425ad01ae9a330d0b8217a54841f>>
* @generated SignedSource<<d85f0048d0939eddb1152b5e0b361749>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -13,10 +13,10 @@ export type AssignTaskInput = {
assignedToId: string;
taskId: string;
};
export type MitigationViewAssignTaskMutation$variables = {
export type MesureViewAssignTaskMutation$variables = {
input: AssignTaskInput;
};
export type MitigationViewAssignTaskMutation$data = {
export type MesureViewAssignTaskMutation$data = {
readonly assignTask: {
readonly task: {
readonly assignedTo: {
@@ -28,9 +28,9 @@ export type MitigationViewAssignTaskMutation$data = {
};
};
};
export type MitigationViewAssignTaskMutation = {
response: MitigationViewAssignTaskMutation$data;
variables: MitigationViewAssignTaskMutation$variables;
export type MesureViewAssignTaskMutation = {
response: MesureViewAssignTaskMutation$data;
variables: MesureViewAssignTaskMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -110,7 +110,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewAssignTaskMutation",
"name": "MesureViewAssignTaskMutation",
"selections": (v2/*: any*/),
"type": "Mutation",
"abstractKey": null
@@ -119,20 +119,20 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MitigationViewAssignTaskMutation",
"name": "MesureViewAssignTaskMutation",
"selections": (v2/*: any*/)
},
"params": {
"cacheID": "c01a2f758aea8268b73365c426b7c08a",
"cacheID": "6d3f95b9e223f40d7e333b951193abcc",
"id": null,
"metadata": {},
"name": "MitigationViewAssignTaskMutation",
"name": "MesureViewAssignTaskMutation",
"operationKind": "mutation",
"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"
"text": "mutation MesureViewAssignTaskMutation(\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 = "2b01502cb830a0d914553e01ceb2445f";
(node as any).hash = "28bc00cb45866a86eb79ebe0c1396a65";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<2eea3e72c7001db14095958b3bcd750a>>
* @generated SignedSource<<f5d09284634ce1975ceff8ce576884c9>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,21 +9,21 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type CreateControlMitigationMappingInput = {
export type CreateControlMesureMappingInput = {
controlId: string;
mitigationId: string;
mesureId: string;
};
export type ControlCreateMitigationMappingMutation$variables = {
input: CreateControlMitigationMappingInput;
export type MesureViewCreateControlMappingMutation$variables = {
input: CreateControlMesureMappingInput;
};
export type ControlCreateMitigationMappingMutation$data = {
readonly createControlMitigationMapping: {
export type MesureViewCreateControlMappingMutation$data = {
readonly createControlMesureMapping: {
readonly success: boolean;
};
};
export type ControlCreateMitigationMappingMutation = {
response: ControlCreateMitigationMappingMutation$data;
variables: ControlCreateMitigationMappingMutation$variables;
export type MesureViewCreateControlMappingMutation = {
response: MesureViewCreateControlMappingMutation$data;
variables: MesureViewCreateControlMappingMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -44,9 +44,9 @@ v1 = [
"variableName": "input"
}
],
"concreteType": "CreateControlMitigationMappingPayload",
"concreteType": "CreateControlMesureMappingPayload",
"kind": "LinkedField",
"name": "createControlMitigationMapping",
"name": "createControlMesureMapping",
"plural": false,
"selections": [
{
@@ -65,7 +65,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "ControlCreateMitigationMappingMutation",
"name": "MesureViewCreateControlMappingMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
@@ -74,20 +74,20 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "ControlCreateMitigationMappingMutation",
"name": "MesureViewCreateControlMappingMutation",
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "955241a049e81cd7faed45d69ce3b145",
"cacheID": "78c1205d1a787ee2cc4e1173e3ef463f",
"id": null,
"metadata": {},
"name": "ControlCreateMitigationMappingMutation",
"name": "MesureViewCreateControlMappingMutation",
"operationKind": "mutation",
"text": "mutation ControlCreateMitigationMappingMutation(\n $input: CreateControlMitigationMappingInput!\n) {\n createControlMitigationMapping(input: $input) {\n success\n }\n}\n"
"text": "mutation MesureViewCreateControlMappingMutation(\n $input: CreateControlMesureMappingInput!\n) {\n createControlMesureMapping(input: $input) {\n success\n }\n}\n"
}
};
})();
(node as any).hash = "ffbcf187d7f2d3c65a2d1fb5c6a180bb";
(node as any).hash = "cdbbc7ebd2c99ef1d19bac274af5a147";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<487ccddf967e20c9111c5074548bebae>>
* @generated SignedSource<<0601ac43da57ebf5dffbd0e3ce9abde7>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -19,11 +19,11 @@ export type CreateEvidenceInput = {
type: EvidenceType;
url?: string | null | undefined;
};
export type MitigationViewCreateEvidenceMutation$variables = {
export type MesureViewCreateEvidenceMutation$variables = {
connections: ReadonlyArray<string>;
input: CreateEvidenceInput;
};
export type MitigationViewCreateEvidenceMutation$data = {
export type MesureViewCreateEvidenceMutation$data = {
readonly createEvidence: {
readonly evidenceEdge: {
readonly node: {
@@ -41,9 +41,9 @@ export type MitigationViewCreateEvidenceMutation$data = {
};
};
};
export type MitigationViewCreateEvidenceMutation = {
response: MitigationViewCreateEvidenceMutation$data;
variables: MitigationViewCreateEvidenceMutation$variables;
export type MesureViewCreateEvidenceMutation = {
response: MesureViewCreateEvidenceMutation$data;
variables: MesureViewCreateEvidenceMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -164,7 +164,7 @@ return {
],
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewCreateEvidenceMutation",
"name": "MesureViewCreateEvidenceMutation",
"selections": [
{
"alias": null,
@@ -189,7 +189,7 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
"name": "MitigationViewCreateEvidenceMutation",
"name": "MesureViewCreateEvidenceMutation",
"selections": [
{
"alias": null,
@@ -222,16 +222,16 @@ return {
]
},
"params": {
"cacheID": "899aada42838cb5db77546be2bd6adb2",
"cacheID": "550cd90cddee628ec42ebd53ac749af0",
"id": null,
"metadata": {},
"name": "MitigationViewCreateEvidenceMutation",
"name": "MesureViewCreateEvidenceMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewCreateEvidenceMutation(\n $input: CreateEvidenceInput!\n) {\n createEvidence(input: $input) {\n evidenceEdge {\n node {\n id\n filename\n fileUrl\n mimeType\n type\n url\n size\n state\n createdAt\n description\n }\n }\n }\n}\n"
"text": "mutation MesureViewCreateEvidenceMutation(\n $input: CreateEvidenceInput!\n) {\n createEvidence(input: $input) {\n evidenceEdge {\n node {\n id\n filename\n fileUrl\n mimeType\n type\n url\n size\n state\n createdAt\n description\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "ca8611e07bcf9233313c3a1580bfc7eb";
(node as any).hash = "2a00046ec29c9dc07b563b5442a85d2d";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<e544ac1f4a0b6d728cba2b66a2f97520>>
* @generated SignedSource<<fa3e50475f102e38ffd517849b9aedf2>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -13,15 +13,15 @@ export type TaskState = "DONE" | "TODO";
export type CreateTaskInput = {
assignedToId?: string | null | undefined;
description: string;
mitigationId: string;
mesureId: string;
name: string;
timeEstimate?: any | null | undefined;
};
export type MitigationViewCreateTaskMutation$variables = {
export type MesureViewCreateTaskMutation$variables = {
connections: ReadonlyArray<string>;
input: CreateTaskInput;
};
export type MitigationViewCreateTaskMutation$data = {
export type MesureViewCreateTaskMutation$data = {
readonly createTask: {
readonly taskEdge: {
readonly node: {
@@ -39,9 +39,9 @@ export type MitigationViewCreateTaskMutation$data = {
};
};
};
export type MitigationViewCreateTaskMutation = {
response: MitigationViewCreateTaskMutation$data;
variables: MitigationViewCreateTaskMutation$variables;
export type MesureViewCreateTaskMutation = {
response: MesureViewCreateTaskMutation$data;
variables: MesureViewCreateTaskMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -154,7 +154,7 @@ return {
],
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewCreateTaskMutation",
"name": "MesureViewCreateTaskMutation",
"selections": [
{
"alias": null,
@@ -179,7 +179,7 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
"name": "MitigationViewCreateTaskMutation",
"name": "MesureViewCreateTaskMutation",
"selections": [
{
"alias": null,
@@ -212,16 +212,16 @@ return {
]
},
"params": {
"cacheID": "273c3d2ae0de44280e85e47db23db892",
"cacheID": "453cd7da016798ce86c012c9d1cf29f1",
"id": null,
"metadata": {},
"name": "MitigationViewCreateTaskMutation",
"name": "MesureViewCreateTaskMutation",
"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 assignedTo {\n id\n fullName\n primaryEmailAddress\n }\n }\n }\n }\n}\n"
"text": "mutation MesureViewCreateTaskMutation(\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 = "ad8a56e4976e9dc15f4ee8e1b32d9fa9";
(node as any).hash = "19abdc1f9accd5deb6bc36a88a91b04d";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<7c4ad77e70fa42cf8257113897a607ec>>
* @generated SignedSource<<aa1cb94133ffcc770185dddcf490492e>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,21 +9,21 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type DeleteControlMitigationMappingInput = {
export type DeleteControlMesureMappingInput = {
controlId: string;
mitigationId: string;
mesureId: string;
};
export type ControlDeleteMitigationMappingMutation$variables = {
input: DeleteControlMitigationMappingInput;
export type MesureViewDeleteControlMappingMutation$variables = {
input: DeleteControlMesureMappingInput;
};
export type ControlDeleteMitigationMappingMutation$data = {
readonly deleteControlMitigationMapping: {
export type MesureViewDeleteControlMappingMutation$data = {
readonly deleteControlMesureMapping: {
readonly success: boolean;
};
};
export type ControlDeleteMitigationMappingMutation = {
response: ControlDeleteMitigationMappingMutation$data;
variables: ControlDeleteMitigationMappingMutation$variables;
export type MesureViewDeleteControlMappingMutation = {
response: MesureViewDeleteControlMappingMutation$data;
variables: MesureViewDeleteControlMappingMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -44,9 +44,9 @@ v1 = [
"variableName": "input"
}
],
"concreteType": "DeleteControlMitigationMappingPayload",
"concreteType": "DeleteControlMesureMappingPayload",
"kind": "LinkedField",
"name": "deleteControlMitigationMapping",
"name": "deleteControlMesureMapping",
"plural": false,
"selections": [
{
@@ -65,7 +65,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "ControlDeleteMitigationMappingMutation",
"name": "MesureViewDeleteControlMappingMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
@@ -74,20 +74,20 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "ControlDeleteMitigationMappingMutation",
"name": "MesureViewDeleteControlMappingMutation",
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "3d09a29c8ae06a97d098e565a7f2d172",
"cacheID": "5293df3ec3b7a9c5dab1ae7c41177186",
"id": null,
"metadata": {},
"name": "ControlDeleteMitigationMappingMutation",
"name": "MesureViewDeleteControlMappingMutation",
"operationKind": "mutation",
"text": "mutation ControlDeleteMitigationMappingMutation(\n $input: DeleteControlMitigationMappingInput!\n) {\n deleteControlMitigationMapping(input: $input) {\n success\n }\n}\n"
"text": "mutation MesureViewDeleteControlMappingMutation(\n $input: DeleteControlMesureMappingInput!\n) {\n deleteControlMesureMapping(input: $input) {\n success\n }\n}\n"
}
};
})();
(node as any).hash = "6905236aeeb313e5deed3e569a0c7c54";
(node as any).hash = "14d324c311f9f5aa0a27c0d705fe7bb6";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<c7cba05f3dbc917afc82d3a3dae6045c>>
* @generated SignedSource<<5819ea12b0c6baff2a21d28b6d22bf29>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -12,18 +12,18 @@ import { ConcreteRequest } from 'relay-runtime';
export type DeleteEvidenceInput = {
evidenceId: string;
};
export type MitigationViewDeleteEvidenceMutation$variables = {
export type MesureViewDeleteEvidenceMutation$variables = {
connections: ReadonlyArray<string>;
input: DeleteEvidenceInput;
};
export type MitigationViewDeleteEvidenceMutation$data = {
export type MesureViewDeleteEvidenceMutation$data = {
readonly deleteEvidence: {
readonly deletedEvidenceId: string;
};
};
export type MitigationViewDeleteEvidenceMutation = {
response: MitigationViewDeleteEvidenceMutation$data;
variables: MitigationViewDeleteEvidenceMutation$variables;
export type MesureViewDeleteEvidenceMutation = {
response: MesureViewDeleteEvidenceMutation$data;
variables: MesureViewDeleteEvidenceMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -59,7 +59,7 @@ return {
],
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewDeleteEvidenceMutation",
"name": "MesureViewDeleteEvidenceMutation",
"selections": [
{
"alias": null,
@@ -84,7 +84,7 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
"name": "MitigationViewDeleteEvidenceMutation",
"name": "MesureViewDeleteEvidenceMutation",
"selections": [
{
"alias": null,
@@ -117,16 +117,16 @@ return {
]
},
"params": {
"cacheID": "4770e84f6f87fb95b9f102cf8e572f44",
"cacheID": "26fbd71aca06943318c6154a0079d6d7",
"id": null,
"metadata": {},
"name": "MitigationViewDeleteEvidenceMutation",
"name": "MesureViewDeleteEvidenceMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewDeleteEvidenceMutation(\n $input: DeleteEvidenceInput!\n) {\n deleteEvidence(input: $input) {\n deletedEvidenceId\n }\n}\n"
"text": "mutation MesureViewDeleteEvidenceMutation(\n $input: DeleteEvidenceInput!\n) {\n deleteEvidence(input: $input) {\n deletedEvidenceId\n }\n}\n"
}
};
})();
(node as any).hash = "993f84f2e310e888a78200abb9b79ae0";
(node as any).hash = "1121dd991a7505864bcd00f06065f2eb";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<c91c57e5263b695d85ca6d95f14acc1d>>
* @generated SignedSource<<c70fd910b41f49426916f3f3aa1433bd>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -12,18 +12,18 @@ import { ConcreteRequest } from 'relay-runtime';
export type DeleteTaskInput = {
taskId: string;
};
export type MitigationViewDeleteTaskMutation$variables = {
export type MesureViewDeleteTaskMutation$variables = {
connections: ReadonlyArray<string>;
input: DeleteTaskInput;
};
export type MitigationViewDeleteTaskMutation$data = {
export type MesureViewDeleteTaskMutation$data = {
readonly deleteTask: {
readonly deletedTaskId: string;
};
};
export type MitigationViewDeleteTaskMutation = {
response: MitigationViewDeleteTaskMutation$data;
variables: MitigationViewDeleteTaskMutation$variables;
export type MesureViewDeleteTaskMutation = {
response: MesureViewDeleteTaskMutation$data;
variables: MesureViewDeleteTaskMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -59,7 +59,7 @@ return {
],
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewDeleteTaskMutation",
"name": "MesureViewDeleteTaskMutation",
"selections": [
{
"alias": null,
@@ -84,7 +84,7 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
"name": "MitigationViewDeleteTaskMutation",
"name": "MesureViewDeleteTaskMutation",
"selections": [
{
"alias": null,
@@ -117,16 +117,16 @@ return {
]
},
"params": {
"cacheID": "f586e9c07d233eb31a72c2564c448fe4",
"cacheID": "a5096acddc7796fbc89521cc80b5538e",
"id": null,
"metadata": {},
"name": "MitigationViewDeleteTaskMutation",
"name": "MesureViewDeleteTaskMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewDeleteTaskMutation(\n $input: DeleteTaskInput!\n) {\n deleteTask(input: $input) {\n deletedTaskId\n }\n}\n"
"text": "mutation MesureViewDeleteTaskMutation(\n $input: DeleteTaskInput!\n) {\n deleteTask(input: $input) {\n deletedTaskId\n }\n}\n"
}
};
})();
(node as any).hash = "2d6cfcb4704b95bc89f9f4715488d133";
(node as any).hash = "42867b2a8776a0facd18b0b24499ccc9";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<641911581864265e2933d2d5f2705bfe>>
* @generated SignedSource<<296196d78af980e2c7456af3192b29ef>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,10 +9,10 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type MitigationViewFrameworksQuery$variables = {
export type MesureViewFrameworksQuery$variables = {
organizationId: string;
};
export type MitigationViewFrameworksQuery$data = {
export type MesureViewFrameworksQuery$data = {
readonly organization: {
readonly frameworks?: {
readonly edges: ReadonlyArray<{
@@ -35,9 +35,9 @@ export type MitigationViewFrameworksQuery$data = {
readonly id: string;
};
};
export type MitigationViewFrameworksQuery = {
response: MitigationViewFrameworksQuery$data;
variables: MitigationViewFrameworksQuery$variables;
export type MesureViewFrameworksQuery = {
response: MesureViewFrameworksQuery$data;
variables: MesureViewFrameworksQuery$variables;
};
const node: ConcreteRequest = (function(){
@@ -163,7 +163,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewFrameworksQuery",
"name": "MesureViewFrameworksQuery",
"selections": [
{
"alias": "organization",
@@ -240,7 +240,7 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MitigationViewFrameworksQuery",
"name": "MesureViewFrameworksQuery",
"selections": [
{
"alias": "organization",
@@ -331,7 +331,7 @@ return {
]
},
"params": {
"cacheID": "34e6669a992e649351d4284a2d66c66a",
"cacheID": "68ea9b6b474fc4c715eda4e5814b3343",
"id": null,
"metadata": {
"connection": [
@@ -352,13 +352,13 @@ return {
}
]
},
"name": "MitigationViewFrameworksQuery",
"name": "MesureViewFrameworksQuery",
"operationKind": "query",
"text": "query MitigationViewFrameworksQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n frameworks(first: 100) {\n edges {\n node {\n id\n name\n controls(first: 100) {\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 __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
"text": "query MesureViewFrameworksQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n frameworks(first: 100) {\n edges {\n node {\n id\n name\n controls(first: 100) {\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 __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "f4f9ed0abc3a0d36365801dcc60c4333";
(node as any).hash = "c66b330acf51a54f75ac9b4238c30ec1";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<780fd466293ec923661adc90f801380a>>
* @generated SignedSource<<a690863c83d2e67fa057c3fe63b63979>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -17,11 +17,11 @@ export type FulfillEvidenceInput = {
name?: string | null | undefined;
url?: string | null | undefined;
};
export type MitigationViewFulfillEvidenceMutation$variables = {
export type MesureViewFulfillEvidenceMutation$variables = {
connections: ReadonlyArray<string>;
input: FulfillEvidenceInput;
};
export type MitigationViewFulfillEvidenceMutation$data = {
export type MesureViewFulfillEvidenceMutation$data = {
readonly fulfillEvidence: {
readonly evidenceEdge: {
readonly node: {
@@ -39,9 +39,9 @@ export type MitigationViewFulfillEvidenceMutation$data = {
};
};
};
export type MitigationViewFulfillEvidenceMutation = {
response: MitigationViewFulfillEvidenceMutation$data;
variables: MitigationViewFulfillEvidenceMutation$variables;
export type MesureViewFulfillEvidenceMutation = {
response: MesureViewFulfillEvidenceMutation$data;
variables: MesureViewFulfillEvidenceMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -162,7 +162,7 @@ return {
],
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewFulfillEvidenceMutation",
"name": "MesureViewFulfillEvidenceMutation",
"selections": [
{
"alias": null,
@@ -187,7 +187,7 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
"name": "MitigationViewFulfillEvidenceMutation",
"name": "MesureViewFulfillEvidenceMutation",
"selections": [
{
"alias": null,
@@ -220,16 +220,16 @@ return {
]
},
"params": {
"cacheID": "efdf549604c425e8bb58ccf51df580c9",
"cacheID": "605c054b1e501d03ded168635513d859",
"id": null,
"metadata": {},
"name": "MitigationViewFulfillEvidenceMutation",
"name": "MesureViewFulfillEvidenceMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewFulfillEvidenceMutation(\n $input: FulfillEvidenceInput!\n) {\n fulfillEvidence(input: $input) {\n evidenceEdge {\n node {\n id\n filename\n fileUrl\n mimeType\n type\n url\n size\n state\n createdAt\n description\n }\n }\n }\n}\n"
"text": "mutation MesureViewFulfillEvidenceMutation(\n $input: FulfillEvidenceInput!\n) {\n fulfillEvidence(input: $input) {\n evidenceEdge {\n node {\n id\n filename\n fileUrl\n mimeType\n type\n url\n size\n state\n createdAt\n description\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "2a7f04e50e4e6fc39457a861a22baf08";
(node as any).hash = "049b31ff4cf60918ec33c2c10fcb9b46";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<c39e6569df1609b4a9cf0a6c1673df3a>>
* @generated SignedSource<<d3565063e8e1b68e794fe4347c923138>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,18 +9,18 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type MitigationViewGetEvidenceFileUrlQuery$variables = {
export type MesureViewGetEvidenceFileUrlQuery$variables = {
evidenceId: string;
};
export type MitigationViewGetEvidenceFileUrlQuery$data = {
export type MesureViewGetEvidenceFileUrlQuery$data = {
readonly node: {
readonly fileUrl?: string | null | undefined;
readonly id?: string;
};
};
export type MitigationViewGetEvidenceFileUrlQuery = {
response: MitigationViewGetEvidenceFileUrlQuery$data;
variables: MitigationViewGetEvidenceFileUrlQuery$variables;
export type MesureViewGetEvidenceFileUrlQuery = {
response: MesureViewGetEvidenceFileUrlQuery$data;
variables: MesureViewGetEvidenceFileUrlQuery$variables;
};
const node: ConcreteRequest = (function(){
@@ -57,7 +57,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewGetEvidenceFileUrlQuery",
"name": "MesureViewGetEvidenceFileUrlQuery",
"selections": [
{
"alias": null,
@@ -87,7 +87,7 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MitigationViewGetEvidenceFileUrlQuery",
"name": "MesureViewGetEvidenceFileUrlQuery",
"selections": [
{
"alias": null,
@@ -119,16 +119,16 @@ return {
]
},
"params": {
"cacheID": "1dc81a5d665b9141b5cd62ef893ff0e1",
"cacheID": "05edf89cc90a90e1a96bd02f8448b629",
"id": null,
"metadata": {},
"name": "MitigationViewGetEvidenceFileUrlQuery",
"name": "MesureViewGetEvidenceFileUrlQuery",
"operationKind": "query",
"text": "query MitigationViewGetEvidenceFileUrlQuery(\n $evidenceId: ID!\n) {\n node(id: $evidenceId) {\n __typename\n ... on Evidence {\n id\n fileUrl\n }\n id\n }\n}\n"
"text": "query MesureViewGetEvidenceFileUrlQuery(\n $evidenceId: ID!\n) {\n node(id: $evidenceId) {\n __typename\n ... on Evidence {\n id\n fileUrl\n }\n id\n }\n}\n"
}
};
})();
(node as any).hash = "9d7bbfc81ce73246b671989102da3192";
(node as any).hash = "2bef4c934e725a40e5140a812bd31bc8";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<c9c1170d3b2dcef033fe6f69b6a9b11e>>
* @generated SignedSource<<7f9c4ed295020bbeadd37ac046817d51>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,11 +9,11 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type MitigationViewLinkedControlsQuery$variables = {
mitigationId: string;
export type MesureViewLinkedControlsQuery$variables = {
mesureId: string;
};
export type MitigationViewLinkedControlsQuery$data = {
readonly mitigation: {
export type MesureViewLinkedControlsQuery$data = {
readonly mesure: {
readonly controls?: {
readonly edges: ReadonlyArray<{
readonly node: {
@@ -27,9 +27,9 @@ export type MitigationViewLinkedControlsQuery$data = {
readonly id: string;
};
};
export type MitigationViewLinkedControlsQuery = {
response: MitigationViewLinkedControlsQuery$data;
variables: MitigationViewLinkedControlsQuery$variables;
export type MesureViewLinkedControlsQuery = {
response: MesureViewLinkedControlsQuery$data;
variables: MesureViewLinkedControlsQuery$variables;
};
const node: ConcreteRequest = (function(){
@@ -37,14 +37,14 @@ var v0 = [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "mitigationId"
"name": "mesureId"
}
],
v1 = [
{
"kind": "Variable",
"name": "id",
"variableName": "mitigationId"
"variableName": "mesureId"
}
],
v2 = {
@@ -152,10 +152,10 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewLinkedControlsQuery",
"name": "MesureViewLinkedControlsQuery",
"selections": [
{
"alias": "mitigation",
"alias": "mesure",
"args": (v1/*: any*/),
"concreteType": null,
"kind": "LinkedField",
@@ -171,13 +171,13 @@ return {
"args": null,
"concreteType": "ControlConnection",
"kind": "LinkedField",
"name": "__Mitigation__controls_connection",
"name": "__MesureView_controls_connection",
"plural": false,
"selections": (v4/*: any*/),
"storageKey": null
}
],
"type": "Mitigation",
"type": "Mesure",
"abstractKey": null
}
],
@@ -191,10 +191,10 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MitigationViewLinkedControlsQuery",
"name": "MesureViewLinkedControlsQuery",
"selections": [
{
"alias": "mitigation",
"alias": "mesure",
"args": (v1/*: any*/),
"concreteType": null,
"kind": "LinkedField",
@@ -221,12 +221,12 @@ return {
"args": (v5/*: any*/),
"filters": null,
"handle": "connection",
"key": "Mitigation__controls",
"key": "MesureView_controls",
"kind": "LinkedHandle",
"name": "controls"
}
],
"type": "Mitigation",
"type": "Mesure",
"abstractKey": null
}
],
@@ -235,7 +235,7 @@ return {
]
},
"params": {
"cacheID": "7429166728b5a233e15cb0f4cb33d15c",
"cacheID": "84229c9d2f99008d1b85401ad2c0e185",
"id": null,
"metadata": {
"connection": [
@@ -244,19 +244,19 @@ return {
"cursor": null,
"direction": "forward",
"path": [
"mitigation",
"mesure",
"controls"
]
}
]
},
"name": "MitigationViewLinkedControlsQuery",
"name": "MesureViewLinkedControlsQuery",
"operationKind": "query",
"text": "query MitigationViewLinkedControlsQuery(\n $mitigationId: ID!\n) {\n mitigation: node(id: $mitigationId) {\n __typename\n id\n ... on Mitigation {\n controls(first: 100) {\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"
"text": "query MesureViewLinkedControlsQuery(\n $mesureId: ID!\n) {\n mesure: node(id: $mesureId) {\n __typename\n id\n ... on Mesure {\n controls(first: 100) {\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 = "0748d068025e5f577ab56a8014ee38cc";
(node as any).hash = "c9a7971b4e7f8e4a708d69211333bb8a";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<780c10208a633b2ce7cd34ccc580cf25>>
* @generated SignedSource<<c50d4f287a6322e4dada5685bc5d830f>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,10 +9,10 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type MitigationViewOrganizationQuery$variables = {
export type MesureViewOrganizationQuery$variables = {
organizationId: string;
};
export type MitigationViewOrganizationQuery$data = {
export type MesureViewOrganizationQuery$data = {
readonly organization: {
readonly id: string;
readonly peoples?: {
@@ -26,9 +26,9 @@ export type MitigationViewOrganizationQuery$data = {
};
};
};
export type MitigationViewOrganizationQuery = {
response: MitigationViewOrganizationQuery$data;
variables: MitigationViewOrganizationQuery$variables;
export type MesureViewOrganizationQuery = {
response: MesureViewOrganizationQuery$data;
variables: MesureViewOrganizationQuery$variables;
};
const node: ConcreteRequest = (function(){
@@ -153,7 +153,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewOrganizationQuery",
"name": "MesureViewOrganizationQuery",
"selections": [
{
"alias": "organization",
@@ -174,10 +174,10 @@ return {
],
"concreteType": "PeopleConnection",
"kind": "LinkedField",
"name": "__MitigationView_peoples_connection",
"name": "__MesureView_peoples_connection",
"plural": false,
"selections": (v5/*: any*/),
"storageKey": "__MitigationView_peoples_connection(orderBy:{\"direction\":\"ASC\",\"field\":\"FULL_NAME\"})"
"storageKey": "__MesureView_peoples_connection(orderBy:{\"direction\":\"ASC\",\"field\":\"FULL_NAME\"})"
}
],
"type": "Organization",
@@ -194,7 +194,7 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MitigationViewOrganizationQuery",
"name": "MesureViewOrganizationQuery",
"selections": [
{
"alias": "organization",
@@ -226,7 +226,7 @@ return {
"orderBy"
],
"handle": "connection",
"key": "MitigationView_peoples",
"key": "MesureView_peoples",
"kind": "LinkedHandle",
"name": "peoples"
}
@@ -240,7 +240,7 @@ return {
]
},
"params": {
"cacheID": "3d1fc2d02bc6eea68edcabc6fc6f0b56",
"cacheID": "cc07a873a9d2756876763a8491fd305a",
"id": null,
"metadata": {
"connection": [
@@ -255,13 +255,13 @@ return {
}
]
},
"name": "MitigationViewOrganizationQuery",
"name": "MesureViewOrganizationQuery",
"operationKind": "query",
"text": "query MitigationViewOrganizationQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\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 }\n}\n"
"text": "query MesureViewOrganizationQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\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 }\n}\n"
}
};
})();
(node as any).hash = "73abf70f60b6f5a07b25f3c83676e02f";
(node as any).hash = "4d0f80a682d98e8b90102b47ec2a7cb3";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<8b25e364318ac90f1c1eaf313a6286cb>>
* @generated SignedSource<<911e86f76b51015804e409479ee4068c>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -11,20 +11,20 @@
import { ConcreteRequest } from 'relay-runtime';
export type EvidenceState = "FULFILLED" | "REQUESTED";
export type EvidenceType = "FILE" | "LINK";
export type MitigationImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type MitigationState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type MesureImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type MesureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type TaskState = "DONE" | "TODO";
export type MitigationViewQuery$variables = {
mitigationId: string;
export type MesureViewQuery$variables = {
mesureId: string;
};
export type MitigationViewQuery$data = {
readonly mitigation: {
export type MesureViewQuery$data = {
readonly mesure: {
readonly category?: string;
readonly description?: string;
readonly id: string;
readonly importance?: MitigationImportance;
readonly importance?: MesureImportance;
readonly name?: string;
readonly state?: MitigationState;
readonly state?: MesureState;
readonly tasks?: {
readonly __id: string;
readonly edges: ReadonlyArray<{
@@ -60,9 +60,9 @@ export type MitigationViewQuery$data = {
};
};
};
export type MitigationViewQuery = {
response: MitigationViewQuery$data;
variables: MitigationViewQuery$variables;
export type MesureViewQuery = {
response: MesureViewQuery$data;
variables: MesureViewQuery$variables;
};
const node: ConcreteRequest = (function(){
@@ -70,14 +70,14 @@ var v0 = [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "mitigationId"
"name": "mesureId"
}
],
v1 = [
{
"kind": "Variable",
"name": "id",
"variableName": "mitigationId"
"variableName": "mesureId"
}
],
v2 = {
@@ -298,10 +298,10 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewQuery",
"name": "MesureViewQuery",
"selections": [
{
"alias": "mitigation",
"alias": "mesure",
"args": (v1/*: any*/),
"concreteType": null,
"kind": "LinkedField",
@@ -322,7 +322,7 @@ return {
"args": null,
"concreteType": "TaskConnection",
"kind": "LinkedField",
"name": "__MitigationView_tasks_connection",
"name": "__MesureView_tasks_connection",
"plural": false,
"selections": [
{
@@ -352,7 +352,7 @@ return {
"args": null,
"concreteType": "EvidenceConnection",
"kind": "LinkedField",
"name": "__MitigationView_evidences_connection",
"name": "__MesureView_evidences_connection",
"plural": false,
"selections": (v14/*: any*/),
"storageKey": null
@@ -371,7 +371,7 @@ return {
"storageKey": null
}
],
"type": "Mitigation",
"type": "Mesure",
"abstractKey": null
}
],
@@ -385,10 +385,10 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MitigationViewQuery",
"name": "MesureViewQuery",
"selections": [
{
"alias": "mitigation",
"alias": "mesure",
"args": (v1/*: any*/),
"concreteType": null,
"kind": "LinkedField",
@@ -450,7 +450,7 @@ return {
"args": (v16/*: any*/),
"filters": null,
"handle": "connection",
"key": "MitigationView_evidences",
"key": "MesureView_evidences",
"kind": "LinkedHandle",
"name": "evidences"
},
@@ -472,12 +472,12 @@ return {
"args": (v15/*: any*/),
"filters": null,
"handle": "connection",
"key": "MitigationView_tasks",
"key": "MesureView_tasks",
"kind": "LinkedHandle",
"name": "tasks"
}
],
"type": "Mitigation",
"type": "Mesure",
"abstractKey": null
}
],
@@ -486,7 +486,7 @@ return {
]
},
"params": {
"cacheID": "711b5dac4db6ca883144ece5d4bc48c3",
"cacheID": "e4c3abf8e8559e732088a9123863a375",
"id": null,
"metadata": {
"connection": [
@@ -501,19 +501,19 @@ return {
"cursor": null,
"direction": "forward",
"path": [
"mitigation",
"mesure",
"tasks"
]
}
]
},
"name": "MitigationViewQuery",
"name": "MesureViewQuery",
"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 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 description\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 MesureViewQuery(\n $mesureId: ID!\n) {\n mesure: node(id: $mesureId) {\n __typename\n id\n ... on Mesure {\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 description\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 = "cb5d73e09aa6168901bf5db0f931e24c";
(node as any).hash = "38c0abd51a589411fc60391269af0227";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<b7154e691d26fef3b8f64ec3a39304fd>>
* @generated SignedSource<<a6bd25e3b378dcc7ac26ba611a054fbe>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,11 +9,11 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type MitigationViewRisksQuery$variables = {
mitigationId: string;
export type MesureViewRisksQuery$variables = {
mesureId: string;
};
export type MitigationViewRisksQuery$data = {
readonly mitigation: {
export type MesureViewRisksQuery$data = {
readonly mesure: {
readonly id: string;
readonly risks?: {
readonly edges: ReadonlyArray<{
@@ -30,9 +30,9 @@ export type MitigationViewRisksQuery$data = {
};
};
};
export type MitigationViewRisksQuery = {
response: MitigationViewRisksQuery$data;
variables: MitigationViewRisksQuery$variables;
export type MesureViewRisksQuery = {
response: MesureViewRisksQuery$data;
variables: MesureViewRisksQuery$variables;
};
const node: ConcreteRequest = (function(){
@@ -40,14 +40,14 @@ var v0 = [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "mitigationId"
"name": "mesureId"
}
],
v1 = [
{
"kind": "Variable",
"name": "id",
"variableName": "mitigationId"
"variableName": "mesureId"
}
],
v2 = {
@@ -176,10 +176,10 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewRisksQuery",
"name": "MesureViewRisksQuery",
"selections": [
{
"alias": "mitigation",
"alias": "mesure",
"args": (v1/*: any*/),
"concreteType": null,
"kind": "LinkedField",
@@ -195,13 +195,13 @@ return {
"args": null,
"concreteType": "RiskConnection",
"kind": "LinkedField",
"name": "__MitigationView_risks_connection",
"name": "__MesureView_risks_connection",
"plural": false,
"selections": (v4/*: any*/),
"storageKey": null
}
],
"type": "Mitigation",
"type": "Mesure",
"abstractKey": null
}
],
@@ -215,10 +215,10 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MitigationViewRisksQuery",
"name": "MesureViewRisksQuery",
"selections": [
{
"alias": "mitigation",
"alias": "mesure",
"args": (v1/*: any*/),
"concreteType": null,
"kind": "LinkedField",
@@ -245,12 +245,12 @@ return {
"args": (v5/*: any*/),
"filters": null,
"handle": "connection",
"key": "MitigationView_risks",
"key": "MesureView_risks",
"kind": "LinkedHandle",
"name": "risks"
}
],
"type": "Mitigation",
"type": "Mesure",
"abstractKey": null
}
],
@@ -259,7 +259,7 @@ return {
]
},
"params": {
"cacheID": "6e8982bef70e90ee745d6985c82c597e",
"cacheID": "b8095743d31791d2084177fde0203ed4",
"id": null,
"metadata": {
"connection": [
@@ -268,19 +268,19 @@ return {
"cursor": null,
"direction": "forward",
"path": [
"mitigation",
"mesure",
"risks"
]
}
]
},
"name": "MitigationViewRisksQuery",
"name": "MesureViewRisksQuery",
"operationKind": "query",
"text": "query MitigationViewRisksQuery(\n $mitigationId: ID!\n) {\n mitigation: node(id: $mitigationId) {\n __typename\n id\n ... on Mitigation {\n risks(first: 100) {\n edges {\n node {\n id\n name\n description\n inherentLikelihood\n inherentImpact\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
"text": "query MesureViewRisksQuery(\n $mesureId: ID!\n) {\n mesure: node(id: $mesureId) {\n __typename\n id\n ... on Mesure {\n risks(first: 100) {\n edges {\n node {\n id\n name\n description\n inherentLikelihood\n inherentImpact\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "0fe825c558627da60c1025efa825f91e";
(node as any).hash = "0609b3e58837ae65fb4df484b967060a";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<a0f8386de345c2c768657efd4358518c>>
* @generated SignedSource<<1a725a74db916d1672685d90c48def81>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -12,10 +12,10 @@ import { ConcreteRequest } from 'relay-runtime';
export type UnassignTaskInput = {
taskId: string;
};
export type MitigationViewUnassignTaskMutation$variables = {
export type MesureViewUnassignTaskMutation$variables = {
input: UnassignTaskInput;
};
export type MitigationViewUnassignTaskMutation$data = {
export type MesureViewUnassignTaskMutation$data = {
readonly unassignTask: {
readonly task: {
readonly assignedTo: {
@@ -27,9 +27,9 @@ export type MitigationViewUnassignTaskMutation$data = {
};
};
};
export type MitigationViewUnassignTaskMutation = {
response: MitigationViewUnassignTaskMutation$data;
variables: MitigationViewUnassignTaskMutation$variables;
export type MesureViewUnassignTaskMutation = {
response: MesureViewUnassignTaskMutation$data;
variables: MesureViewUnassignTaskMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -109,7 +109,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewUnassignTaskMutation",
"name": "MesureViewUnassignTaskMutation",
"selections": (v2/*: any*/),
"type": "Mutation",
"abstractKey": null
@@ -118,20 +118,20 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MitigationViewUnassignTaskMutation",
"name": "MesureViewUnassignTaskMutation",
"selections": (v2/*: any*/)
},
"params": {
"cacheID": "6cf554a835936763f3b4f55f04c9771f",
"cacheID": "3f91f027e7a8a935f306386469bbac21",
"id": null,
"metadata": {},
"name": "MitigationViewUnassignTaskMutation",
"name": "MesureViewUnassignTaskMutation",
"operationKind": "mutation",
"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"
"text": "mutation MesureViewUnassignTaskMutation(\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 = "07d79596fef3416fdc001077d2d51c75";
(node as any).hash = "c5c62c4c4d16dfd6147a1d44aa35b8fe";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<1d924bb487fd93636fa7207c5aa08cdc>>
* @generated SignedSource<<9dac57f235ab6d16f6b3f78002c83dcc>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,30 +9,30 @@
// @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 UpdateMitigationInput = {
export type MesureImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type MesureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type UpdateMesureInput = {
category?: string | null | undefined;
description?: string | null | undefined;
id: string;
importance?: MitigationImportance | null | undefined;
importance?: MesureImportance | null | undefined;
name?: string | null | undefined;
state?: MitigationState | null | undefined;
state?: MesureState | null | undefined;
};
export type MitigationViewUpdateMitigationStateMutation$variables = {
input: UpdateMitigationInput;
export type MesureViewUpdateMesureStateMutation$variables = {
input: UpdateMesureInput;
};
export type MitigationViewUpdateMitigationStateMutation$data = {
readonly updateMitigation: {
readonly mitigation: {
export type MesureViewUpdateMesureStateMutation$data = {
readonly updateMesure: {
readonly mesure: {
readonly id: string;
readonly state: MitigationState;
readonly state: MesureState;
};
};
};
export type MitigationViewUpdateMitigationStateMutation = {
response: MitigationViewUpdateMitigationStateMutation$data;
variables: MitigationViewUpdateMitigationStateMutation$variables;
export type MesureViewUpdateMesureStateMutation = {
response: MesureViewUpdateMesureStateMutation$data;
variables: MesureViewUpdateMesureStateMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -53,17 +53,17 @@ v1 = [
"variableName": "input"
}
],
"concreteType": "UpdateMitigationPayload",
"concreteType": "UpdateMesurePayload",
"kind": "LinkedField",
"name": "updateMitigation",
"name": "updateMesure",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Mitigation",
"concreteType": "Mesure",
"kind": "LinkedField",
"name": "mitigation",
"name": "mesure",
"plural": false,
"selections": [
{
@@ -92,7 +92,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewUpdateMitigationStateMutation",
"name": "MesureViewUpdateMesureStateMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
@@ -101,20 +101,20 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MitigationViewUpdateMitigationStateMutation",
"name": "MesureViewUpdateMesureStateMutation",
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "7e4a92a089fa5927b0239004c3fb5f47",
"cacheID": "59db8143f555230677a401f5bed6a6c3",
"id": null,
"metadata": {},
"name": "MitigationViewUpdateMitigationStateMutation",
"name": "MesureViewUpdateMesureStateMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewUpdateMitigationStateMutation(\n $input: UpdateMitigationInput!\n) {\n updateMitigation(input: $input) {\n mitigation {\n id\n state\n }\n }\n}\n"
"text": "mutation MesureViewUpdateMesureStateMutation(\n $input: UpdateMesureInput!\n) {\n updateMesure(input: $input) {\n mesure {\n id\n state\n }\n }\n}\n"
}
};
})();
(node as any).hash = "e985902d55a537a08b8a2d4482abe0b3";
(node as any).hash = "ae0f63f654568f052621f28e73382172";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<a68054962a4ec7ae205dc2976fe8d2bf>>
* @generated SignedSource<<efb9132cf25dca5dff1df4fa6f139cd1>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -17,10 +17,10 @@ export type UpdateTaskInput = {
taskId: string;
timeEstimate?: any | null | undefined;
};
export type MitigationViewUpdateTaskStateMutation$variables = {
export type MesureViewUpdateTaskStateMutation$variables = {
input: UpdateTaskInput;
};
export type MitigationViewUpdateTaskStateMutation$data = {
export type MesureViewUpdateTaskStateMutation$data = {
readonly updateTask: {
readonly task: {
readonly id: string;
@@ -29,9 +29,9 @@ export type MitigationViewUpdateTaskStateMutation$data = {
};
};
};
export type MitigationViewUpdateTaskStateMutation = {
response: MitigationViewUpdateTaskStateMutation$data;
variables: MitigationViewUpdateTaskStateMutation$variables;
export type MesureViewUpdateTaskStateMutation = {
response: MesureViewUpdateTaskStateMutation$data;
variables: MesureViewUpdateTaskStateMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -98,7 +98,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewUpdateTaskStateMutation",
"name": "MesureViewUpdateTaskStateMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
@@ -107,20 +107,20 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MitigationViewUpdateTaskStateMutation",
"name": "MesureViewUpdateTaskStateMutation",
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "f8d2ca86f8e7856b3d24bcd810490a6a",
"cacheID": "3af3e26a5c5be4c129b6d1706d3d1b59",
"id": null,
"metadata": {},
"name": "MitigationViewUpdateTaskStateMutation",
"name": "MesureViewUpdateTaskStateMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewUpdateTaskStateMutation(\n $input: UpdateTaskInput!\n) {\n updateTask(input: $input) {\n task {\n id\n state\n timeEstimate\n }\n }\n}\n"
"text": "mutation MesureViewUpdateTaskStateMutation(\n $input: UpdateTaskInput!\n) {\n updateTask(input: $input) {\n task {\n id\n state\n timeEstimate\n }\n }\n}\n"
}
};
})();
(node as any).hash = "7ab07c94be8f56a93d39178828d85823";
(node as any).hash = "fd909d70346802420c83942efa30ef20";
export default node;

View File

@@ -0,0 +1,221 @@
/**
* @generated SignedSource<<6e5efc598a8e6657fd0a1375e6104ff6>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from "relay-runtime";
export type EvidenceState = "FULLFILLED" | "REQUESTED";
export type EvidenceType = "FILE" | "LINK";
export type UploadEvidenceInput = {
description: string;
file?: any | null | undefined;
name: string;
taskId: string;
type: EvidenceType;
url?: string | null | undefined;
};
export type MesureViewUploadEvidenceMutation$variables = {
connections: ReadonlyArray<string>;
input: UploadEvidenceInput;
};
export type MesureViewUploadEvidenceMutation$data = {
readonly uploadEvidence: {
readonly evidenceEdge: {
readonly node: {
readonly createdAt: string;
readonly fileUrl: string | null | undefined;
readonly filename: string;
readonly id: string;
readonly mimeType: string;
readonly size: number;
readonly state: EvidenceState;
readonly type: EvidenceType;
readonly url: string | null | undefined;
};
};
};
};
export type MesureViewUploadEvidenceMutation = {
response: MesureViewUploadEvidenceMutation$data;
variables: MesureViewUploadEvidenceMutation$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,
concreteType: "EvidenceEdge",
kind: "LinkedField",
name: "evidenceEdge",
plural: false,
selections: [
{
alias: null,
args: null,
concreteType: "Evidence",
kind: "LinkedField",
name: "node",
plural: false,
selections: [
{
alias: null,
args: null,
kind: "ScalarField",
name: "id",
storageKey: null,
},
{
alias: null,
args: null,
kind: "ScalarField",
name: "filename",
storageKey: null,
},
{
alias: null,
args: null,
kind: "ScalarField",
name: "fileUrl",
storageKey: null,
},
{
alias: null,
args: null,
kind: "ScalarField",
name: "mimeType",
storageKey: null,
},
{
alias: null,
args: null,
kind: "ScalarField",
name: "type",
storageKey: null,
},
{
alias: null,
args: null,
kind: "ScalarField",
name: "url",
storageKey: null,
},
{
alias: null,
args: null,
kind: "ScalarField",
name: "size",
storageKey: null,
},
{
alias: null,
args: null,
kind: "ScalarField",
name: "state",
storageKey: null,
},
{
alias: null,
args: null,
kind: "ScalarField",
name: "createdAt",
storageKey: null,
},
],
storageKey: null,
},
],
storageKey: null,
};
return {
fragment: {
argumentDefinitions: [v0 /*: any*/, v1 /*: any*/],
kind: "Fragment",
metadata: null,
name: "MesureViewUploadEvidenceMutation",
selections: [
{
alias: null,
args: v2 /*: any*/,
concreteType: "UploadEvidencePayload",
kind: "LinkedField",
name: "uploadEvidence",
plural: false,
selections: [v3 /*: any*/],
storageKey: null,
},
],
type: "Mutation",
abstractKey: null,
},
kind: "Request",
operation: {
argumentDefinitions: [v1 /*: any*/, v0 /*: any*/],
kind: "Operation",
name: "MesureViewUploadEvidenceMutation",
selections: [
{
alias: null,
args: v2 /*: any*/,
concreteType: "UploadEvidencePayload",
kind: "LinkedField",
name: "uploadEvidence",
plural: false,
selections: [
v3 /*: any*/,
{
alias: null,
args: null,
filters: null,
handle: "appendEdge",
key: "",
kind: "LinkedHandle",
name: "evidenceEdge",
handleArgs: [
{
kind: "Variable",
name: "connections",
variableName: "connections",
},
],
},
],
storageKey: null,
},
],
},
params: {
cacheID: "30a6915055d3f6b63d96836b26f05a45",
id: null,
metadata: {},
name: "MesureViewUploadEvidenceMutation",
operationKind: "mutation",
text: "mutation MesureViewUploadEvidenceMutation(\n $input: UploadEvidenceInput!\n) {\n uploadEvidence(input: $input) {\n evidenceEdge {\n node {\n id\n filename\n fileUrl\n mimeType\n type\n url\n size\n state\n createdAt\n }\n }\n }\n}\n",
},
};
})();
(node as any).hash = "4cf5430a0971ba1ddf476765df614e30";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<50b15dea665515ca83a54c39e03453c2>>
* @generated SignedSource<<3b585f9a06a084982155a0f356838402>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,21 +9,21 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type MitigationImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type CreateMitigationInput = {
export type MesureImportance = "ADVANCED" | "MANDATORY" | "PREFERRED";
export type CreateMesureInput = {
category: string;
description: string;
importance: MitigationImportance;
importance: MesureImportance;
name: string;
organizationId: string;
};
export type NewMitigationViewCreateMitigationMutation$variables = {
export type NewMesureViewCreateMesureMutation$variables = {
connections: ReadonlyArray<string>;
input: CreateMitigationInput;
input: CreateMesureInput;
};
export type NewMitigationViewCreateMitigationMutation$data = {
readonly createMitigation: {
readonly mitigationEdge: {
export type NewMesureViewCreateMesureMutation$data = {
readonly createMesure: {
readonly mesureEdge: {
readonly node: {
readonly description: string;
readonly id: string;
@@ -32,9 +32,9 @@ export type NewMitigationViewCreateMitigationMutation$data = {
};
};
};
export type NewMitigationViewCreateMitigationMutation = {
response: NewMitigationViewCreateMitigationMutation$data;
variables: NewMitigationViewCreateMitigationMutation$variables;
export type NewMesureViewCreateMesureMutation = {
response: NewMesureViewCreateMesureMutation$data;
variables: NewMesureViewCreateMesureMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -58,15 +58,15 @@ v2 = [
v3 = {
"alias": null,
"args": null,
"concreteType": "MitigationEdge",
"concreteType": "MesureEdge",
"kind": "LinkedField",
"name": "mitigationEdge",
"name": "mesureEdge",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Mitigation",
"concreteType": "Mesure",
"kind": "LinkedField",
"name": "node",
"plural": false,
@@ -106,14 +106,14 @@ return {
],
"kind": "Fragment",
"metadata": null,
"name": "NewMitigationViewCreateMitigationMutation",
"name": "NewMesureViewCreateMesureMutation",
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "CreateMitigationPayload",
"concreteType": "CreateMesurePayload",
"kind": "LinkedField",
"name": "createMitigation",
"name": "createMesure",
"plural": false,
"selections": [
(v3/*: any*/)
@@ -131,14 +131,14 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
"name": "NewMitigationViewCreateMitigationMutation",
"name": "NewMesureViewCreateMesureMutation",
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "CreateMitigationPayload",
"concreteType": "CreateMesurePayload",
"kind": "LinkedField",
"name": "createMitigation",
"name": "createMesure",
"plural": false,
"selections": [
(v3/*: any*/),
@@ -149,7 +149,7 @@ return {
"handle": "prependEdge",
"key": "",
"kind": "LinkedHandle",
"name": "mitigationEdge",
"name": "mesureEdge",
"handleArgs": [
{
"kind": "Variable",
@@ -164,16 +164,16 @@ return {
]
},
"params": {
"cacheID": "9615313ab1f2555f58a79b85741684f4",
"cacheID": "de8b930c9628c62ae4272bd427076ebd",
"id": null,
"metadata": {},
"name": "NewMitigationViewCreateMitigationMutation",
"name": "NewMesureViewCreateMesureMutation",
"operationKind": "mutation",
"text": "mutation NewMitigationViewCreateMitigationMutation(\n $input: CreateMitigationInput!\n) {\n createMitigation(input: $input) {\n mitigationEdge {\n node {\n id\n name\n description\n }\n }\n }\n}\n"
"text": "mutation NewMesureViewCreateMesureMutation(\n $input: CreateMesureInput!\n) {\n createMesure(input: $input) {\n mesureEdge {\n node {\n id\n name\n description\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "6b6ead3a24d113ec969c98680956ebb9";
(node as any).hash = "94532353875a658b6e0b87a8181eab5e";
export default node;

View File

@@ -1,229 +0,0 @@
/**
* @generated SignedSource<<6e5efc598a8e6657fd0a1375e6104ff6>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type EvidenceState = "FULLFILLED" | "REQUESTED";
export type EvidenceType = "FILE" | "LINK";
export type UploadEvidenceInput = {
description: string;
file?: any | null | undefined;
name: string;
taskId: string;
type: EvidenceType;
url?: string | null | undefined;
};
export type MitigationViewUploadEvidenceMutation$variables = {
connections: ReadonlyArray<string>;
input: UploadEvidenceInput;
};
export type MitigationViewUploadEvidenceMutation$data = {
readonly uploadEvidence: {
readonly evidenceEdge: {
readonly node: {
readonly createdAt: string;
readonly fileUrl: string | null | undefined;
readonly filename: string;
readonly id: string;
readonly mimeType: string;
readonly size: number;
readonly state: EvidenceState;
readonly type: EvidenceType;
readonly url: string | null | undefined;
};
};
};
};
export type MitigationViewUploadEvidenceMutation = {
response: MitigationViewUploadEvidenceMutation$data;
variables: MitigationViewUploadEvidenceMutation$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,
"concreteType": "EvidenceEdge",
"kind": "LinkedField",
"name": "evidenceEdge",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Evidence",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "filename",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fileUrl",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "mimeType",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "type",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "url",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "size",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "state",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "createdAt",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
};
return {
"fragment": {
"argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/)
],
"kind": "Fragment",
"metadata": null,
"name": "MitigationViewUploadEvidenceMutation",
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "UploadEvidencePayload",
"kind": "LinkedField",
"name": "uploadEvidence",
"plural": false,
"selections": [
(v3/*: any*/)
],
"storageKey": null
}
],
"type": "Mutation",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": [
(v1/*: any*/),
(v0/*: any*/)
],
"kind": "Operation",
"name": "MitigationViewUploadEvidenceMutation",
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "UploadEvidencePayload",
"kind": "LinkedField",
"name": "uploadEvidence",
"plural": false,
"selections": [
(v3/*: any*/),
{
"alias": null,
"args": null,
"filters": null,
"handle": "appendEdge",
"key": "",
"kind": "LinkedHandle",
"name": "evidenceEdge",
"handleArgs": [
{
"kind": "Variable",
"name": "connections",
"variableName": "connections"
}
]
}
],
"storageKey": null
}
]
},
"params": {
"cacheID": "30a6915055d3f6b63d96836b26f05a45",
"id": null,
"metadata": {},
"name": "MitigationViewUploadEvidenceMutation",
"operationKind": "mutation",
"text": "mutation MitigationViewUploadEvidenceMutation(\n $input: UploadEvidenceInput!\n) {\n uploadEvidence(input: $input) {\n evidenceEdge {\n node {\n id\n filename\n fileUrl\n mimeType\n type\n url\n size\n state\n createdAt\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "4cf5430a0971ba1ddf476765df614e30";
export default node;

View File

@@ -16,7 +16,7 @@ export function PolicyListViewSkeleton() {
<div className="bg-subtle-bg animate-pulse h-9 w-1/6 rounded-lg" />
}
>
{/* Search and filter mitigations skeleton */}
{/* Search and filter mesures skeleton */}
<div className="flex flex-col md:flex-row gap-4 mb-6">
<div className="flex-1 h-10 bg-subtle-bg animate-pulse rounded" />
<div className="flex gap-2">

View File

@@ -232,7 +232,7 @@ function PolicyListViewContent({
</Button>
}
>
{/* Search and filter mitigations */}
{/* Search and filter mesures */}
<div className="flex flex-col md:flex-row gap-4 mb-6">
<div className="relative flex-1">
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-tertiary" />

View File

@@ -54,11 +54,11 @@ import {
TableRow,
} from "@/components/ui/table";
import {
ShowRiskViewOrganizationMitigationsQuery,
ShowRiskViewOrganizationMitigationsQuery$data,
} from "./__generated__/ShowRiskViewOrganizationMitigationsQuery.graphql";
import { ShowRiskViewCreateRiskMitigationMappingMutation } from "./__generated__/ShowRiskViewCreateRiskMitigationMappingMutation.graphql";
import { ShowRiskViewDeleteRiskMitigationMappingMutation } from "./__generated__/ShowRiskViewDeleteRiskMitigationMappingMutation.graphql";
ShowRiskViewOrganizationMesuresQuery,
ShowRiskViewOrganizationMesuresQuery$data,
} from "./__generated__/ShowRiskViewOrganizationMesuresQuery.graphql";
import { ShowRiskViewCreateRiskMesureMappingMutation } from "./__generated__/ShowRiskViewCreateRiskMesureMappingMutation.graphql";
import { ShowRiskViewDeleteRiskMesureMappingMutation } from "./__generated__/ShowRiskViewDeleteRiskMesureMappingMutation.graphql";
import {
ShowRiskViewOrganizationPoliciesQuery,
ShowRiskViewOrganizationPoliciesQuery$data,
@@ -84,7 +84,7 @@ const showRiskViewQuery = graphql`
residualImpact
createdAt
updatedAt
mitigations(first: 100) @connection(key: "Risk__mitigations") {
mesures(first: 100) @connection(key: "Risk__mesures") {
edges {
node {
id
@@ -122,13 +122,13 @@ const showRiskViewQuery = graphql`
}
`;
// Add query to fetch all mitigations for the organization
const organizationMitigationsQuery = graphql`
query ShowRiskViewOrganizationMitigationsQuery($organizationId: ID!) {
// Add query to fetch all mesures for the organization
const organizationMesuresQuery = graphql`
query ShowRiskViewOrganizationMesuresQuery($organizationId: ID!) {
organization: node(id: $organizationId) {
id
... on Organization {
mitigations(first: 100) @connection(key: "Organization__mitigations") {
mesures(first: 100) @connection(key: "Organization__mesures") {
edges {
node {
id
@@ -164,23 +164,23 @@ const organizationPoliciesQuery = graphql`
}
`;
// Add mutation to create risk-mitigation mapping
const createRiskMitigationMappingMutation = graphql`
mutation ShowRiskViewCreateRiskMitigationMappingMutation(
$input: CreateRiskMitigationMappingInput!
// Add mutation to create risk-mesure mapping
const createRiskMesureMappingMutation = graphql`
mutation ShowRiskViewCreateRiskMesureMappingMutation(
$input: CreateRiskMesureMappingInput!
) {
createRiskMitigationMapping(input: $input) {
createRiskMesureMapping(input: $input) {
success
}
}
`;
// Add mutation to delete risk-mitigation mapping
const deleteRiskMitigationMappingMutation = graphql`
mutation ShowRiskViewDeleteRiskMitigationMappingMutation(
$input: DeleteRiskMitigationMappingInput!
// Add mutation to delete risk-mesure mapping
const deleteRiskMesureMappingMutation = graphql`
mutation ShowRiskViewDeleteRiskMesureMappingMutation(
$input: DeleteRiskMesureMappingInput!
) {
deleteRiskMitigationMapping(input: $input) {
deleteRiskMesureMapping(input: $input) {
success
}
}
@@ -238,8 +238,8 @@ function ShowRiskViewContent({
risk.inherentImpact!
);
// Fix typing for mitigations
const mitigations = risk.mitigations?.edges?.map((edge) => edge.node) || [];
// Fix typing for mesures
const mesures = risk.mesures?.edges?.map((edge) => edge.node) || [];
const residualSeverity = getRiskSeverity(
risk.residualLikelihood!,
risk.residualImpact!
@@ -251,17 +251,17 @@ function ShowRiskViewContent({
// Fix typing for controls
const controls = risk.controls?.edges?.map((edge) => edge.node) || [];
// Add state for mitigation mapping dialog
const [isMitigationDialogOpen, setIsMitigationDialogOpen] = useState(false);
const [organizationMitigationsData, setOrganizationMitigationsData] =
useState<ShowRiskViewOrganizationMitigationsQuery$data | null>(null);
const [mitigationSearchQuery, setMitigationSearchQuery] = useState("");
// Add state for mesure mapping dialog
const [isMesureDialogOpen, setIsMesureDialogOpen] = useState(false);
const [organizationMesuresData, setOrganizationMesuresData] =
useState<ShowRiskViewOrganizationMesuresQuery$data | null>(null);
const [mesureSearchQuery, setMesureSearchQuery] = useState("");
const [categoryFilter, setCategoryFilter] = useState<string | null>(null);
const [isLoadingMitigations, setIsLoadingMitigations] = useState(false);
const [linkingMitigations, setLinkingMitigations] = useState<
Record<string, boolean>
>({});
const [unlinkingMitigations, setUnlinkingMitigations] = useState<
const [isLoadingMesures, setIsLoadingMesures] = useState(false);
const [linkingMesures, setLinkingMesures] = useState<Record<string, boolean>>(
{}
);
const [unlinkingMesures, setUnlinkingMesures] = useState<
Record<string, boolean>
>({});
@@ -279,13 +279,13 @@ function ShowRiskViewContent({
>({});
// Setup mutation hooks
const [createRiskMitigationMapping] =
useMutation<ShowRiskViewCreateRiskMitigationMappingMutation>(
createRiskMitigationMappingMutation
const [createRiskMesureMapping] =
useMutation<ShowRiskViewCreateRiskMesureMappingMutation>(
createRiskMesureMappingMutation
);
const [deleteRiskMitigationMapping] =
useMutation<ShowRiskViewDeleteRiskMitigationMappingMutation>(
deleteRiskMitigationMappingMutation
const [deleteRiskMesureMapping] =
useMutation<ShowRiskViewDeleteRiskMesureMappingMutation>(
deleteRiskMesureMappingMutation
);
// Setup policy mutation hooks
@@ -300,13 +300,13 @@ function ShowRiskViewContent({
// Clear filters when dialog closes
useEffect(() => {
if (!isMitigationDialogOpen) {
setMitigationSearchQuery("");
if (!isMesureDialogOpen) {
setMesureSearchQuery("");
setCategoryFilter(null);
setLinkingMitigations({});
setUnlinkingMitigations({});
setLinkingMesures({});
setUnlinkingMesures({});
}
}, [isMitigationDialogOpen]);
}, [isMesureDialogOpen]);
// Clear filters when policy dialog closes
useEffect(() => {
@@ -317,30 +317,30 @@ function ShowRiskViewContent({
}
}, [isPolicyDialogOpen]);
// Load mitigations data when needed
const loadMitigationsData = useCallback(() => {
// Load mesures data when needed
const loadMesuresData = useCallback(() => {
if (!organizationId || !risk.id) return;
setIsLoadingMitigations(true);
setIsLoadingMesures(true);
// Fetch all mitigations for the organization
fetchQuery<ShowRiskViewOrganizationMitigationsQuery>(
// Fetch all mesures for the organization
fetchQuery<ShowRiskViewOrganizationMesuresQuery>(
environment,
organizationMitigationsQuery,
organizationMesuresQuery,
{
organizationId,
}
).subscribe({
next: (data) => {
setOrganizationMitigationsData(data);
setIsLoadingMitigations(false);
setOrganizationMesuresData(data);
setIsLoadingMesures(false);
},
error: (error: Error) => {
console.error("Error fetching organization mitigations:", error);
setIsLoadingMitigations(false);
console.error("Error fetching organization mesures:", error);
setIsLoadingMesures(false);
toast({
title: "Error",
description: "Failed to load mitigations.",
description: "Failed to load mesures.",
variant: "destructive",
});
},
@@ -378,52 +378,49 @@ function ShowRiskViewContent({
}, [risk.id, environment, organizationId, toast]);
// Helper functions
const getMitigations = useCallback(() => {
if (!organizationMitigationsData?.organization?.mitigations?.edges)
return [];
return organizationMitigationsData.organization.mitigations.edges.map(
const getMesures = useCallback(() => {
if (!organizationMesuresData?.organization?.mesures?.edges) return [];
return organizationMesuresData.organization.mesures.edges.map(
(edge) => edge.node
);
}, [organizationMitigationsData]);
}, [organizationMesuresData]);
const getMitigationCategories = useCallback(() => {
const mitigations = getMitigations();
const getMesureCategories = useCallback(() => {
const mesures = getMesures();
const categories = new Set<string>();
mitigations.forEach((mitigation) => {
if (mitigation.category) {
categories.add(mitigation.category);
mesures.forEach((mesure) => {
if (mesure.category) {
categories.add(mesure.category);
}
});
return Array.from(categories).sort();
}, [getMitigations]);
}, [getMesures]);
const filteredMitigations = useCallback(() => {
const mitigations = getMitigations();
if (!mitigationSearchQuery && !categoryFilter) return mitigations;
const filteredMesures = useCallback(() => {
const mesures = getMesures();
if (!mesureSearchQuery && !categoryFilter) return mesures;
return mitigations.filter((mitigation) => {
return mesures.filter((mesure) => {
// Filter by search query
const matchesSearch =
!mitigationSearchQuery ||
mitigation.name
.toLowerCase()
.includes(mitigationSearchQuery.toLowerCase()) ||
(mitigation.description &&
mitigation.description
!mesureSearchQuery ||
mesure.name.toLowerCase().includes(mesureSearchQuery.toLowerCase()) ||
(mesure.description &&
mesure.description
.toLowerCase()
.includes(mitigationSearchQuery.toLowerCase()));
.includes(mesureSearchQuery.toLowerCase()));
// Filter by category
const matchesCategory =
!categoryFilter ||
categoryFilter === "all" ||
mitigation.category === categoryFilter;
mesure.category === categoryFilter;
return matchesSearch && matchesCategory;
});
}, [getMitigations, mitigationSearchQuery, categoryFilter]);
}, [getMesures, mesureSearchQuery, categoryFilter]);
// Helper functions for policies
const getPolicies = useCallback(() => {
@@ -445,38 +442,38 @@ function ShowRiskViewContent({
});
}, [getPolicies, policySearchQuery]);
// Handle linking a mitigation to this risk
const handleLinkMitigation = useCallback(
// Handle linking a mesure to this risk
const handleLinkMesure = useCallback(
(
mitigation: NonNullable<
mesure: NonNullable<
NonNullable<
ShowRiskViewOrganizationMitigationsQuery$data["organization"]
>["mitigations"]
ShowRiskViewOrganizationMesuresQuery$data["organization"]
>["mesures"]
>["edges"][0]["node"]
) => {
if (!risk.id) return;
// Track this specific mitigation as linking
setLinkingMitigations((prev) => ({ ...prev, [mitigation.id]: true }));
// Track this specific mesure as linking
setLinkingMesures((prev) => ({ ...prev, [mesure.id]: true }));
createRiskMitigationMapping({
createRiskMesureMapping({
variables: {
input: {
riskId: risk.id,
mitigationId: mitigation.id,
mesureId: mesure.id,
},
},
onCompleted: (_, errors) => {
setLinkingMitigations((prev) => ({
setLinkingMesures((prev) => ({
...prev,
[mitigation.id]: false,
[mesure.id]: false,
}));
if (errors && errors.length > 0) {
console.error("Error linking mitigation:", errors);
console.error("Error linking mesure:", errors);
toast({
title: "Error",
description: "Failed to link mitigation. Please try again.",
description: "Failed to link mesure. Please try again.",
variant: "destructive",
});
return;
@@ -497,58 +494,58 @@ function ShowRiskViewContent({
toast({
title: "Success",
description: `Linked mitigation "${mitigation.name}" to this risk.`,
description: `Linked mesure "${mesure.name}" to this risk.`,
});
},
onError: (error) => {
setLinkingMitigations((prev) => ({
setLinkingMesures((prev) => ({
...prev,
[mitigation.id]: false,
[mesure.id]: false,
}));
console.error("Error linking mitigation:", error);
console.error("Error linking mesure:", error);
toast({
title: "Error",
description: "Failed to link mitigation. Please try again.",
description: "Failed to link mesure. Please try again.",
variant: "destructive",
});
},
});
},
[risk.id, createRiskMitigationMapping, toast, environment, loadQuery]
[risk.id, createRiskMesureMapping, toast, environment, loadQuery]
);
// Handle unlinking a mitigation from this risk
const handleUnlinkMitigation = useCallback(
// Handle unlinking a mesure from this risk
const handleUnlinkMesure = useCallback(
(
mitigation: NonNullable<
mesure: NonNullable<
NonNullable<
ShowRiskViewOrganizationMitigationsQuery$data["organization"]
>["mitigations"]
ShowRiskViewOrganizationMesuresQuery$data["organization"]
>["mesures"]
>["edges"][0]["node"]
) => {
if (!risk.id) return;
// Track this specific mitigation as unlinking
setUnlinkingMitigations((prev) => ({ ...prev, [mitigation.id]: true }));
// Track this specific mesure as unlinking
setUnlinkingMesures((prev) => ({ ...prev, [mesure.id]: true }));
deleteRiskMitigationMapping({
deleteRiskMesureMapping({
variables: {
input: {
riskId: risk.id,
mitigationId: mitigation.id,
mesureId: mesure.id,
},
},
onCompleted: (_, errors) => {
setUnlinkingMitigations((prev) => ({
setUnlinkingMesures((prev) => ({
...prev,
[mitigation.id]: false,
[mesure.id]: false,
}));
if (errors && errors.length > 0) {
console.error("Error unlinking mitigation:", errors);
console.error("Error unlinking mesure:", errors);
toast({
title: "Error",
description: "Failed to unlink mitigation. Please try again.",
description: "Failed to unlink mesure. Please try again.",
variant: "destructive",
});
return;
@@ -569,24 +566,24 @@ function ShowRiskViewContent({
toast({
title: "Success",
description: `Unlinked mitigation "${mitigation.name}" from this risk.`,
description: `Unlinked mesure "${mesure.name}" from this risk.`,
});
},
onError: (error) => {
setUnlinkingMitigations((prev) => ({
setUnlinkingMesures((prev) => ({
...prev,
[mitigation.id]: false,
[mesure.id]: false,
}));
console.error("Error unlinking mitigation:", error);
console.error("Error unlinking mesure:", error);
toast({
title: "Error",
description: "Failed to unlink mitigation. Please try again.",
description: "Failed to unlink mesure. Please try again.",
variant: "destructive",
});
},
});
},
[risk.id, deleteRiskMitigationMapping, toast, environment, loadQuery]
[risk.id, deleteRiskMesureMapping, toast, environment, loadQuery]
);
// Handle linking a policy to this risk
@@ -871,8 +868,8 @@ function ShowRiskViewContent({
</Badge>
</p>
<p className="text-xs text-secondary mt-1">
{mitigations.length} mitigation
{mitigations.length !== 1 ? "s" : ""} applied
{mesures.length} mesure
{mesures.length !== 1 ? "s" : ""} applied
</p>
</div>
</div>
@@ -880,56 +877,53 @@ function ShowRiskViewContent({
</CardContent>
</Card>
<Tabs defaultValue="mitigations" className="w-full">
<Tabs defaultValue="mesures" className="w-full">
<TabsList>
<TabsTrigger value="mitigations">Mitigations</TabsTrigger>
<TabsTrigger value="mesures">Mesures</TabsTrigger>
<TabsTrigger value="policies">Policies</TabsTrigger>
<TabsTrigger value="controls">Controls</TabsTrigger>
</TabsList>
<TabsContent value="mitigations" className="space-y-4">
<TabsContent value="mesures" className="space-y-4">
<div className="flex justify-between items-center mb-4">
<h2 className="text-xl font-semibold">Risk Mitigations</h2>
<h2 className="text-xl font-semibold">Risk Mesures</h2>
<Button
onClick={() => {
setIsMitigationDialogOpen(true);
loadMitigationsData();
setIsMesureDialogOpen(true);
loadMesuresData();
}}
>
<Plus className="mr-2 h-4 w-4" />
Link Mitigation
Link Mesure
</Button>
</div>
{risk.mitigations?.edges?.length &&
risk.mitigations?.edges?.length > 0 ? (
{risk.mesures?.edges?.length && risk.mesures?.edges?.length > 0 ? (
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-full">Mitigation</TableHead>
<TableHead className="w-full">Mesure</TableHead>
<TableHead className="w-20">Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{risk.mitigations?.edges.map(({ node: mitigation }) => (
<TableRow key={mitigation.id}>
{risk.mesures?.edges.map(({ node: mesure }) => (
<TableRow key={mesure.id}>
<TableCell>
<Link
to={`/organizations/${organizationId}/mitigations/${mitigation.id}`}
to={`/organizations/${organizationId}/mesures/${mesure.id}`}
className="font-medium text-blue-600 hover:underline"
>
{mitigation.name}
{mesure.name}
</Link>
</TableCell>
<TableCell>
<Button
variant="ghost"
size="icon"
onClick={() => handleUnlinkMitigation(mitigation)}
disabled={
unlinkingMitigations[mitigation.id] || false
}
title="Unlink mitigation"
onClick={() => handleUnlinkMesure(mesure)}
disabled={unlinkingMesures[mesure.id] || false}
title="Unlink mesure"
>
<Trash2 className="h-4 w-4 text-danger" />
</Button>
@@ -941,7 +935,7 @@ function ShowRiskViewContent({
</div>
) : (
<div className="text-center py-10 text-secondary">
<p>No mitigations associated with this risk.</p>
<p>No mesures associated with this risk.</p>
</div>
)}
</TabsContent>
@@ -1039,18 +1033,15 @@ function ShowRiskViewContent({
</TabsContent>
</Tabs>
{/* Dialog for linking mitigations */}
<Dialog
open={isMitigationDialogOpen}
onOpenChange={setIsMitigationDialogOpen}
>
{/* Dialog for linking mesures */}
<Dialog open={isMesureDialogOpen} onOpenChange={setIsMesureDialogOpen}>
<DialogContent className="max-w-3xl">
<DialogHeader>
<div className="flex justify-between items-center">
<div>
<DialogTitle>Manage Risk Mitigations</DialogTitle>
<DialogTitle>Manage Risk Mesures</DialogTitle>
<DialogDescription>
Link or unlink mitigations to manage this risk.
Link or unlink mesures to manage this risk.
</DialogDescription>
</div>
</div>
@@ -1062,10 +1053,10 @@ function ShowRiskViewContent({
<div className="relative">
<Search className="absolute left-2 top-2.5 h-4 w-4 text-tertiary" />
<Input
placeholder="Search mitigations..."
placeholder="Search mesures..."
className="pl-8"
value={mitigationSearchQuery}
onChange={(e) => setMitigationSearchQuery(e.target.value)}
value={mesureSearchQuery}
onChange={(e) => setMesureSearchQuery(e.target.value)}
/>
</div>
</div>
@@ -1080,7 +1071,7 @@ function ShowRiskViewContent({
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All Categories</SelectItem>
{getMitigationCategories().map((category) => (
{getMesureCategories().map((category) => (
<SelectItem key={category} value={category}>
{category}
</SelectItem>
@@ -1090,37 +1081,35 @@ function ShowRiskViewContent({
</div>
<div className="border rounded-md max-h-96 overflow-y-auto">
{isLoadingMitigations ? (
<div className="p-4 text-center">Loading mitigations...</div>
) : filteredMitigations().length === 0 ? (
<div className="p-4 text-center">No mitigations found.</div>
{isLoadingMesures ? (
<div className="p-4 text-center">Loading mesures...</div>
) : filteredMesures().length === 0 ? (
<div className="p-4 text-center">No mesures found.</div>
) : (
<div className="divide-y">
{filteredMitigations().map((mitigation) => {
{filteredMesures().map((mesure) => {
// For each render, recalculate linked status directly against the current risk data
const isLinked = risk.mitigations?.edges?.some(
(edge) => edge.node.id === mitigation.id
const isLinked = risk.mesures?.edges?.some(
(edge) => edge.node.id === mesure.id
);
const isLinking =
linkingMitigations[mitigation.id] || false;
const isUnlinking =
unlinkingMitigations[mitigation.id] || false;
const isLinking = linkingMesures[mesure.id] || false;
const isUnlinking = unlinkingMesures[mesure.id] || false;
return (
<div
key={mitigation.id}
key={mesure.id}
className="relative p-4 hover:bg-blue-50 transition-colors duration-150"
>
<div className="flex justify-between items-center">
<div className="flex items-center gap-2">
<h3 className="font-medium">{mitigation.name}</h3>
{mitigation.category && (
<h3 className="font-medium">{mesure.name}</h3>
{mesure.category && (
<Badge
variant="outline"
className="text-xs font-normal"
>
<Tag className="h-3 w-3 mr-1" />
{mitigation.category}
{mesure.category}
</Badge>
)}
</div>
@@ -1129,9 +1118,7 @@ function ShowRiskViewContent({
size="sm"
variant="outline"
disabled={isUnlinking}
onClick={() =>
handleUnlinkMitigation(mitigation)
}
onClick={() => handleUnlinkMesure(mesure)}
className="text-red-600 border-red-200 hover:bg-red-50"
>
{isUnlinking ? "Unlinking..." : "Unlink"}
@@ -1140,7 +1127,7 @@ function ShowRiskViewContent({
<Button
size="sm"
disabled={isLinking}
onClick={() => handleLinkMitigation(mitigation)}
onClick={() => handleLinkMesure(mesure)}
>
{isLinking ? "Linking..." : "Link"}
</Button>
@@ -1157,7 +1144,7 @@ function ShowRiskViewContent({
<DialogFooter>
<Button
variant="outline"
onClick={() => setIsMitigationDialogOpen(false)}
onClick={() => setIsMesureDialogOpen(false)}
>
Close
</Button>

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<73623cc6511c56dd418345cd64d500d5>>
* @generated SignedSource<<b2d5c0102cdcaff05ca490a75b797625>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,21 +9,21 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type CreateRiskMitigationMappingInput = {
mitigationId: string;
export type CreateRiskMesureMappingInput = {
mesureId: string;
riskId: string;
};
export type ShowRiskViewCreateRiskMitigationMappingMutation$variables = {
input: CreateRiskMitigationMappingInput;
export type ShowRiskViewCreateRiskMesureMappingMutation$variables = {
input: CreateRiskMesureMappingInput;
};
export type ShowRiskViewCreateRiskMitigationMappingMutation$data = {
readonly createRiskMitigationMapping: {
export type ShowRiskViewCreateRiskMesureMappingMutation$data = {
readonly createRiskMesureMapping: {
readonly success: boolean;
};
};
export type ShowRiskViewCreateRiskMitigationMappingMutation = {
response: ShowRiskViewCreateRiskMitigationMappingMutation$data;
variables: ShowRiskViewCreateRiskMitigationMappingMutation$variables;
export type ShowRiskViewCreateRiskMesureMappingMutation = {
response: ShowRiskViewCreateRiskMesureMappingMutation$data;
variables: ShowRiskViewCreateRiskMesureMappingMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -44,9 +44,9 @@ v1 = [
"variableName": "input"
}
],
"concreteType": "CreateRiskMitigationMappingPayload",
"concreteType": "CreateRiskMesureMappingPayload",
"kind": "LinkedField",
"name": "createRiskMitigationMapping",
"name": "createRiskMesureMapping",
"plural": false,
"selections": [
{
@@ -65,7 +65,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "ShowRiskViewCreateRiskMitigationMappingMutation",
"name": "ShowRiskViewCreateRiskMesureMappingMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
@@ -74,20 +74,20 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "ShowRiskViewCreateRiskMitigationMappingMutation",
"name": "ShowRiskViewCreateRiskMesureMappingMutation",
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "5a8744dfb9cf5f977c2702d848aab7ae",
"cacheID": "f7d34307825549877c07678c77ca17c6",
"id": null,
"metadata": {},
"name": "ShowRiskViewCreateRiskMitigationMappingMutation",
"name": "ShowRiskViewCreateRiskMesureMappingMutation",
"operationKind": "mutation",
"text": "mutation ShowRiskViewCreateRiskMitigationMappingMutation(\n $input: CreateRiskMitigationMappingInput!\n) {\n createRiskMitigationMapping(input: $input) {\n success\n }\n}\n"
"text": "mutation ShowRiskViewCreateRiskMesureMappingMutation(\n $input: CreateRiskMesureMappingInput!\n) {\n createRiskMesureMapping(input: $input) {\n success\n }\n}\n"
}
};
})();
(node as any).hash = "bdb664dab4a9e655c0923cfdd4ab0fe9";
(node as any).hash = "e1d7cdd482d6658c2befddd478a3397d";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<406a706e512ed01c1924632306a4f81c>>
* @generated SignedSource<<0fc791ecc00bfd6b1aa3a8da262df36c>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,21 +9,21 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type DeleteRiskMitigationMappingInput = {
mitigationId: string;
export type DeleteRiskMesureMappingInput = {
mesureId: string;
riskId: string;
};
export type ShowRiskViewDeleteRiskMitigationMappingMutation$variables = {
input: DeleteRiskMitigationMappingInput;
export type ShowRiskViewDeleteRiskMesureMappingMutation$variables = {
input: DeleteRiskMesureMappingInput;
};
export type ShowRiskViewDeleteRiskMitigationMappingMutation$data = {
readonly deleteRiskMitigationMapping: {
export type ShowRiskViewDeleteRiskMesureMappingMutation$data = {
readonly deleteRiskMesureMapping: {
readonly success: boolean;
};
};
export type ShowRiskViewDeleteRiskMitigationMappingMutation = {
response: ShowRiskViewDeleteRiskMitigationMappingMutation$data;
variables: ShowRiskViewDeleteRiskMitigationMappingMutation$variables;
export type ShowRiskViewDeleteRiskMesureMappingMutation = {
response: ShowRiskViewDeleteRiskMesureMappingMutation$data;
variables: ShowRiskViewDeleteRiskMesureMappingMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -44,9 +44,9 @@ v1 = [
"variableName": "input"
}
],
"concreteType": "DeleteRiskMitigationMappingPayload",
"concreteType": "DeleteRiskMesureMappingPayload",
"kind": "LinkedField",
"name": "deleteRiskMitigationMapping",
"name": "deleteRiskMesureMapping",
"plural": false,
"selections": [
{
@@ -65,7 +65,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "ShowRiskViewDeleteRiskMitigationMappingMutation",
"name": "ShowRiskViewDeleteRiskMesureMappingMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
@@ -74,20 +74,20 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "ShowRiskViewDeleteRiskMitigationMappingMutation",
"name": "ShowRiskViewDeleteRiskMesureMappingMutation",
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "9a4b56b457c7fb53dc2583da93a3aaa4",
"cacheID": "d46920306e833fb33b4f10dca6aa1c5a",
"id": null,
"metadata": {},
"name": "ShowRiskViewDeleteRiskMitigationMappingMutation",
"name": "ShowRiskViewDeleteRiskMesureMappingMutation",
"operationKind": "mutation",
"text": "mutation ShowRiskViewDeleteRiskMitigationMappingMutation(\n $input: DeleteRiskMitigationMappingInput!\n) {\n deleteRiskMitigationMapping(input: $input) {\n success\n }\n}\n"
"text": "mutation ShowRiskViewDeleteRiskMesureMappingMutation(\n $input: DeleteRiskMesureMappingInput!\n) {\n deleteRiskMesureMapping(input: $input) {\n success\n }\n}\n"
}
};
})();
(node as any).hash = "d9fece39ecffbd551662d6491088ce4c";
(node as any).hash = "e55c8d6490fbcfe0d287053200b6347d";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<da6cda7380aec978f37e3adc35942e03>>
* @generated SignedSource<<1fdd1781c11f4c88aeb14ba52fc3e884>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,29 +9,29 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type MitigationState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type ShowRiskViewOrganizationMitigationsQuery$variables = {
export type MesureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type ShowRiskViewOrganizationMesuresQuery$variables = {
organizationId: string;
};
export type ShowRiskViewOrganizationMitigationsQuery$data = {
export type ShowRiskViewOrganizationMesuresQuery$data = {
readonly organization: {
readonly id: string;
readonly mitigations?: {
readonly mesures?: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly category: string;
readonly description: string;
readonly id: string;
readonly name: string;
readonly state: MitigationState;
readonly state: MesureState;
};
}>;
};
};
};
export type ShowRiskViewOrganizationMitigationsQuery = {
response: ShowRiskViewOrganizationMitigationsQuery$data;
variables: ShowRiskViewOrganizationMitigationsQuery$variables;
export type ShowRiskViewOrganizationMesuresQuery = {
response: ShowRiskViewOrganizationMesuresQuery$data;
variables: ShowRiskViewOrganizationMesuresQuery$variables;
};
const node: ConcreteRequest = (function(){
@@ -67,7 +67,7 @@ v4 = [
{
"alias": null,
"args": null,
"concreteType": "MitigationEdge",
"concreteType": "MesureEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
@@ -75,7 +75,7 @@ v4 = [
{
"alias": null,
"args": null,
"concreteType": "Mitigation",
"concreteType": "Mesure",
"kind": "LinkedField",
"name": "node",
"plural": false,
@@ -161,7 +161,7 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "ShowRiskViewOrganizationMitigationsQuery",
"name": "ShowRiskViewOrganizationMesuresQuery",
"selections": [
{
"alias": "organization",
@@ -176,11 +176,11 @@ return {
"kind": "InlineFragment",
"selections": [
{
"alias": "mitigations",
"alias": "mesures",
"args": null,
"concreteType": "MitigationConnection",
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "__Organization__mitigations_connection",
"name": "__Organization__mesures_connection",
"plural": false,
"selections": (v4/*: any*/),
"storageKey": null
@@ -200,7 +200,7 @@ return {
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "ShowRiskViewOrganizationMitigationsQuery",
"name": "ShowRiskViewOrganizationMesuresQuery",
"selections": [
{
"alias": "organization",
@@ -218,21 +218,21 @@ return {
{
"alias": null,
"args": (v5/*: any*/),
"concreteType": "MitigationConnection",
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "mitigations",
"name": "mesures",
"plural": false,
"selections": (v4/*: any*/),
"storageKey": "mitigations(first:100)"
"storageKey": "mesures(first:100)"
},
{
"alias": null,
"args": (v5/*: any*/),
"filters": null,
"handle": "connection",
"key": "Organization__mitigations",
"key": "Organization__mesures",
"kind": "LinkedHandle",
"name": "mitigations"
"name": "mesures"
}
],
"type": "Organization",
@@ -244,7 +244,7 @@ return {
]
},
"params": {
"cacheID": "a73345064022bd2f11ef2f971cd898b5",
"cacheID": "af9a0c71ad20ea7e65e3c625e30b00d8",
"id": null,
"metadata": {
"connection": [
@@ -254,18 +254,18 @@ return {
"direction": "forward",
"path": [
"organization",
"mitigations"
"mesures"
]
}
]
},
"name": "ShowRiskViewOrganizationMitigationsQuery",
"name": "ShowRiskViewOrganizationMesuresQuery",
"operationKind": "query",
"text": "query ShowRiskViewOrganizationMitigationsQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n mitigations(first: 100) {\n edges {\n node {\n id\n name\n description\n category\n state\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
"text": "query ShowRiskViewOrganizationMesuresQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n mesures(first: 100) {\n edges {\n node {\n id\n name\n description\n category\n state\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "76ce05cd9f5a367595eb31b5df24a679";
(node as any).hash = "addb9873294354cedf28bc3262cb736a";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<486518520656d7e1392a34ee1877fe22>>
* @generated SignedSource<<166b32236b296d1d0a4956cabacb1715>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,7 +9,7 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type MitigationState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type MesureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
export type PolicyStatus = "ACTIVE" | "DRAFT";
export type RiskTreatment = "ACCEPTED" | "AVOIDED" | "MITIGATED" | "TRANSFERRED";
export type ShowRiskViewQuery$variables = {
@@ -33,7 +33,7 @@ export type ShowRiskViewQuery$data = {
readonly id: string;
readonly inherentImpact?: number;
readonly inherentLikelihood?: number;
readonly mitigations?: {
readonly mesures?: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly category: string;
@@ -41,7 +41,7 @@ export type ShowRiskViewQuery$data = {
readonly description: string;
readonly id: string;
readonly name: string;
readonly state: MitigationState;
readonly state: MesureState;
};
}>;
};
@@ -218,7 +218,7 @@ v16 = [
{
"alias": null,
"args": null,
"concreteType": "MitigationEdge",
"concreteType": "MesureEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
@@ -226,7 +226,7 @@ v16 = [
{
"alias": null,
"args": null,
"concreteType": "Mitigation",
"concreteType": "Mesure",
"kind": "LinkedField",
"name": "node",
"plural": false,
@@ -371,11 +371,11 @@ return {
(v11/*: any*/),
(v12/*: any*/),
{
"alias": "mitigations",
"alias": "mesures",
"args": null,
"concreteType": "MitigationConnection",
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "__Risk__mitigations_connection",
"name": "__Risk__mesures_connection",
"plural": false,
"selections": (v16/*: any*/),
"storageKey": null
@@ -443,21 +443,21 @@ return {
{
"alias": null,
"args": (v19/*: any*/),
"concreteType": "MitigationConnection",
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "mitigations",
"name": "mesures",
"plural": false,
"selections": (v16/*: any*/),
"storageKey": "mitigations(first:100)"
"storageKey": "mesures(first:100)"
},
{
"alias": null,
"args": (v19/*: any*/),
"filters": null,
"handle": "connection",
"key": "Risk__mitigations",
"key": "Risk__mesures",
"kind": "LinkedHandle",
"name": "mitigations"
"name": "mesures"
},
{
"alias": null,
@@ -507,7 +507,7 @@ return {
]
},
"params": {
"cacheID": "8867786ee5bfa23bfd16d52d0023beeb",
"cacheID": "b315b57d1b366f87758e300825909da0",
"id": null,
"metadata": {
"connection": [
@@ -517,7 +517,7 @@ return {
"direction": "forward",
"path": [
"node",
"mitigations"
"mesures"
]
},
{
@@ -542,11 +542,11 @@ return {
},
"name": "ShowRiskViewQuery",
"operationKind": "query",
"text": "query ShowRiskViewQuery(\n $riskId: ID!\n) {\n node(id: $riskId) {\n __typename\n id\n ... on Risk {\n name\n description\n treatment\n owner {\n id\n fullName\n }\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n createdAt\n updatedAt\n mitigations(first: 100) {\n edges {\n node {\n id\n name\n description\n category\n createdAt\n state\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n policies(first: 100) {\n edges {\n node {\n id\n name\n status\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n controls(first: 100) {\n edges {\n node {\n id\n referenceId\n name\n description\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
"text": "query ShowRiskViewQuery(\n $riskId: ID!\n) {\n node(id: $riskId) {\n __typename\n id\n ... on Risk {\n name\n description\n treatment\n owner {\n id\n fullName\n }\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n createdAt\n updatedAt\n mesures(first: 100) {\n edges {\n node {\n id\n name\n description\n category\n createdAt\n state\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n policies(first: 100) {\n edges {\n node {\n id\n name\n status\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n controls(first: 100) {\n edges {\n node {\n id\n referenceId\n name\n description\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "264f7dd097e487eda41cdc4d04a14274";
(node as any).hash = "bbb709790492c573d25ee19412956501";
export default node;