diff --git a/apps/console/src/pages/organizations/risk-assessments/_components/CreateScenarioInScopeDialog.tsx b/apps/console/src/pages/organizations/risk-assessments/_components/CreateScenarioInScopeDialog.tsx index e09cb3aaf..ef7d160df 100644 --- a/apps/console/src/pages/organizations/risk-assessments/_components/CreateScenarioInScopeDialog.tsx +++ b/apps/console/src/pages/organizations/risk-assessments/_components/CreateScenarioInScopeDialog.tsx @@ -27,12 +27,15 @@ import { Select, useDialogRef, } from "@probo/ui"; -import { useState } from "react"; +import { Suspense, useState } from "react"; import { useForm } from "react-hook-form"; -import { graphql, useMutation } from "react-relay"; +import { graphql, useLazyLoadQuery, useMutation } from "react-relay"; +import type { CreateScenarioInScopeDialogLinkRiskMutation } from "#/__generated__/core/CreateScenarioInScopeDialogLinkRiskMutation.graphql"; import type { CreateScenarioInScopeDialogLinkThreatMutation } from "#/__generated__/core/CreateScenarioInScopeDialogLinkThreatMutation.graphql"; import type { CreateScenarioInScopeDialogMutation } from "#/__generated__/core/CreateScenarioInScopeDialogMutation.graphql"; +import type { CreateScenarioInScopeDialogRisksQuery } from "#/__generated__/core/CreateScenarioInScopeDialogRisksQuery.graphql"; +import { useOrganizationId } from "#/hooks/useOrganizationId"; const createScenarioMutation = graphql` mutation CreateScenarioInScopeDialogMutation( @@ -56,11 +59,75 @@ const linkThreatMutation = graphql` $input: LinkRiskAssessmentScenarioThreatInput! ) { linkRiskAssessmentScenarioThreat(input: $input) { - riskAssessmentScenario { id } + riskAssessmentScenario { + id + threats(first: 10) { edges { node { id name } } } + } } } `; +const linkRiskMutation = graphql` + mutation CreateScenarioInScopeDialogLinkRiskMutation( + $input: LinkRiskAssessmentScenarioRiskInput! + ) { + linkRiskAssessmentScenarioRisk(input: $input) { + riskAssessmentScenario { + id + risks(first: 10) { edges { node { id name } } } + } + riskAssessmentScenarioEdge { node { id } } + } + } +`; + +const risksQuery = graphql` + query CreateScenarioInScopeDialogRisksQuery($organizationId: ID!) { + node(id: $organizationId) { + ... on Organization { + risks(first: 100) { + edges { node { id name } } + } + } + } + } +`; + +function RiskSelector(props: { + selectedRisks: Map; + onSelect: (id: string, name: string) => void; +}) { + const { __ } = useTranslate(); + const organizationId = useOrganizationId(); + const data = useLazyLoadQuery( + risksQuery, + { organizationId }, + { fetchPolicy: "store-or-network" }, + ); + const allRisks = data.node?.risks?.edges?.map(e => e.node) ?? []; + const available = allRisks.filter(r => !props.selectedRisks.has(r.id)); + + if (available.length === 0) { + return

{__("No more risks available.")}

; + } + + return ( + + ); +} + export function CreateScenarioInScopeDialog(props: { scopeId: string; threats: { id: string; name: string }[]; @@ -69,8 +136,10 @@ export function CreateScenarioInScopeDialog(props: { const { __ } = useTranslate(); const dialogRef = useDialogRef(); const [selectedThreats, setSelectedThreats] = useState>(new Map()); + const [selectedRisks, setSelectedRisks] = useState>(new Map()); const [createScenario, isCreating] = useMutation(createScenarioMutation); const [linkThreat] = useMutation(linkThreatMutation); + const [linkRisk] = useMutation(linkRiskMutation); const { register, handleSubmit, reset, formState } = useForm({ defaultValues: { name: "", description: "" }, }); @@ -96,8 +165,16 @@ export function CreateScenarioInScopeDialog(props: { }, }); } + for (const riskId of selectedRisks.keys()) { + linkRisk({ + variables: { + input: { riskAssessmentScenarioId: scenarioId, riskId }, + }, + }); + } reset(); setSelectedThreats(new Map()); + setSelectedRisks(new Map()); dialogRef.current?.close(); }, }); @@ -152,6 +229,7 @@ export function CreateScenarioInScopeDialog(props: { )} {availableThreats.length > 0 && (