diff --git a/apps/console/src/pages/organizations/mitigations/MitigationView.tsx b/apps/console/src/pages/organizations/mitigations/MitigationView.tsx index 82ea1723f..5f4cb5ffb 100644 --- a/apps/console/src/pages/organizations/mitigations/MitigationView.tsx +++ b/apps/console/src/pages/organizations/mitigations/MitigationView.tsx @@ -87,10 +87,14 @@ import { MitigationViewUnassignTaskMutation as MitigationViewUnassignTaskMutatio import { MitigationViewUpdateMitigationStateMutation as MitigationViewUpdateMitigationStateMutationType } from "./__generated__/MitigationViewUpdateMitigationStateMutation.graphql"; import { MitigationViewQuery as MitigationViewQueryType } from "./__generated__/MitigationViewQuery.graphql"; import { MitigationViewOrganizationQuery$data } from "./__generated__/MitigationViewOrganizationQuery.graphql"; -import { MitigationViewFrameworksQuery$data } from "./__generated__/MitigationViewFrameworksQuery.graphql"; -import { MitigationViewLinkedControlsQuery$data } from "./__generated__/MitigationViewLinkedControlsQuery.graphql"; -import { MitigationViewCreateControlMappingMutation$data } from "./__generated__/MitigationViewCreateControlMappingMutation.graphql"; -import { MitigationViewDeleteControlMappingMutation$data } from "./__generated__/MitigationViewDeleteControlMappingMutation.graphql"; +import { + MitigationViewFrameworksQuery, + MitigationViewFrameworksQuery$data, +} from "./__generated__/MitigationViewFrameworksQuery.graphql"; +import { + MitigationViewLinkedControlsQuery, + MitigationViewLinkedControlsQuery$data, +} from "./__generated__/MitigationViewLinkedControlsQuery.graphql"; // Function to format ISO8601 duration to human-readable format const formatDuration = (isoDuration: string): string => { @@ -402,6 +406,31 @@ const deleteControlMappingMutation = graphql` } `; +// Define type for framework structure +type FrameworkEdge = { + node: { + id: string; + name: string; + controls: { + edges: Array<{ + node: { + id: string; + referenceId: string; + name: string; + description?: string; + }; + }>; + }; + }; +}; + +type ControlNode = { + id: string; + referenceId: string; + name: string; + description?: string; +}; + function MitigationViewContent({ queryRef, }: { @@ -427,10 +456,10 @@ function MitigationViewContent({ // Control mapping state const [isControlMappingDialogOpen, setIsControlMappingDialogOpen] = useState(false); - const [frameworksData, setFrameworksData] = useState(null); - const [linkedControlsData, setLinkedControlsData] = useState( - null - ); + const [frameworksData, setFrameworksData] = + useState(null); + const [linkedControlsData, setLinkedControlsData] = + useState(null); const [controlSearchQuery, setControlSearchQuery] = useState(""); const [selectedFrameworkId, setSelectedFrameworkId] = useState( null @@ -450,10 +479,10 @@ function MitigationViewContent({ useEffect(() => { if (organizationId) { fetchQuery(environment, organizationQuery, { organizationId }).subscribe({ - next: (data) => { - setOrganizationData(data); + next: (data: unknown) => { + setOrganizationData(data as MitigationViewOrganizationQuery$data); }, - error: (error) => { + error: (error: Error) => { console.error("Error fetching organization:", error); }, }); @@ -464,10 +493,10 @@ function MitigationViewContent({ useEffect(() => { if (mitigationId) { fetchQuery(environment, linkedControlsQuery, { mitigationId }).subscribe({ - next: (data) => { - setLinkedControlsData(data); + next: (data: unknown) => { + setLinkedControlsData(data as MitigationViewLinkedControlsQuery$data); }, - error: (error) => { + error: (error: Error) => { console.error("Error fetching linked controls:", error); }, }); @@ -1356,15 +1385,21 @@ function MitigationViewContent({ setIsLoadingControls(true); // Fetch all frameworks and their controls - fetchQuery(environment, frameworksQuery, { organizationId }).subscribe({ - next: (data: any) => { + fetchQuery(environment, frameworksQuery, { + organizationId, + }).subscribe({ + next: (data) => { setFrameworksData(data); if ( - data?.organization?.frameworks?.edges?.length > 0 && + data?.organization?.frameworks?.edges && + data.organization.frameworks.edges.length > 0 && !selectedFrameworkId ) { // Select the first framework by default if none is selected - setSelectedFrameworkId(data.organization.frameworks.edges[0].node.id); + const frameworks = data.organization.frameworks.edges; + if (frameworks[0]?.node?.id) { + setSelectedFrameworkId(frameworks[0].node.id); + } } }, complete: () => { @@ -1372,11 +1407,13 @@ function MitigationViewContent({ fetchQuery(environment, linkedControlsQuery, { mitigationId, }).subscribe({ - next: (data: any) => { - setLinkedControlsData(data); + next: (data: unknown) => { + setLinkedControlsData( + data as MitigationViewLinkedControlsQuery$data + ); setIsLoadingControls(false); }, - error: (error) => { + error: (error: Error) => { console.error("Error fetching linked controls:", error); setIsLoadingControls(false); toast({ @@ -1387,7 +1424,7 @@ function MitigationViewContent({ }, }); }, - error: (error) => { + error: (error: Error) => { console.error("Error fetching frameworks:", error); setIsLoadingControls(false); toast({ @@ -1403,28 +1440,27 @@ function MitigationViewContent({ if (!frameworksData?.organization?.frameworks?.edges) return []; // Get controls from the selected framework - const frameworks = frameworksData.organization.frameworks.edges; + const frameworks = frameworksData.organization.frameworks + .edges as Array; if (selectedFrameworkId) { const selectedFramework = frameworks.find( - (edge: any) => edge.node.id === selectedFrameworkId + (edge: FrameworkEdge) => edge.node.id === selectedFrameworkId ); if (selectedFramework?.node?.controls?.edges) { - return selectedFramework.node.controls.edges.map( - (edge: any) => edge.node - ); + return selectedFramework.node.controls.edges.map((edge) => edge.node); } } // If no framework is selected or it doesn't have controls, return controls from all frameworks - return frameworks.flatMap((framework: any) => - framework.node.controls.edges.map((edge: any) => edge.node) + return frameworks.flatMap((framework: FrameworkEdge) => + framework.node.controls.edges.map((edge) => edge.node) ); }, [frameworksData, selectedFrameworkId]); const getLinkedControls = useCallback(() => { if (!linkedControlsData?.mitigation?.controls?.edges) return []; - return linkedControlsData.mitigation.controls.edges.map( + return (linkedControlsData.mitigation.controls.edges || []).map( (edge) => edge.node ); }, [linkedControlsData]); @@ -1432,7 +1468,9 @@ function MitigationViewContent({ const isControlLinked = useCallback( (controlId: string) => { const linkedControls = getLinkedControls(); - return linkedControls.some((control: any) => control.id === controlId); + return linkedControls.some( + (control: ControlNode) => control.id === controlId + ); }, [getLinkedControls] ); @@ -1464,13 +1502,17 @@ function MitigationViewContent({ } // Refresh linked controls data - fetchQuery(environment, linkedControlsQuery, { - mitigationId, - }).subscribe({ - next: (data: any) => { + fetchQuery( + environment, + linkedControlsQuery, + { + mitigationId, + } + ).subscribe({ + next: (data) => { setLinkedControlsData(data); }, - error: (error) => { + error: (error: Error) => { console.error("Error refreshing linked controls:", error); }, }); @@ -1524,10 +1566,12 @@ function MitigationViewContent({ fetchQuery(environment, linkedControlsQuery, { mitigationId, }).subscribe({ - next: (data: any) => { - setLinkedControlsData(data); + next: (data: unknown) => { + setLinkedControlsData( + data as MitigationViewLinkedControlsQuery$data + ); }, - error: (error) => { + error: (error: Error) => { console.error("Error refreshing linked controls:", error); }, }); @@ -1562,7 +1606,7 @@ function MitigationViewContent({ const lowerQuery = controlSearchQuery.toLowerCase(); return controls.filter( - (control: any) => + (control: ControlNode) => control.referenceId.toLowerCase().includes(lowerQuery) || control.name.toLowerCase().includes(lowerQuery) || (control.description && @@ -1673,7 +1717,7 @@ function MitigationViewContent({ All Frameworks {frameworksData?.organization?.frameworks?.edges?.map( - (edge: any) => ( + (edge) => ( {edge.node.name} @@ -1698,7 +1742,7 @@ function MitigationViewContent({ different framework. ) : ( - filteredControls().map((control: any) => { + filteredControls().map((control) => { const isLinked = isControlLinked(control.id); return ( - {linkedControlsData?.mitigation?.controls?.edges?.length > 0 ? ( + {linkedControlsData?.mitigation?.controls?.edges && + linkedControlsData.mitigation.controls.edges.length > 0 ? (
- {getLinkedControls().map((control: any) => ( + {getLinkedControls().map((control: ControlNode) => (
@@ -1821,8 +1866,8 @@ function MitigationViewContent({
) : (
- No controls linked to this mitigation yet. Click "Map to - Controls" to link controls. + No controls linked to this mitigation yet. Click "Map to + Controls" to link controls.
)}