import { Checkbox } from '@headlessui/react'; import { CheckIcon } from '@heroicons/react/16/solid'; import { t } from 'i18next'; import { useEffect, useState } from 'react'; type CWERelated = { cwe: string; cweParent?: string; cweGrandParent?: string; }; export type CheckboxButtonProps = { cwesRecommended: CWERelated[]; cweRecommendationSelected: string[]; setCweRecommendationSelected: React.Dispatch>; }; // Returns an object with the total number of properties in the CWE array and an array with the number of properties accumulated in each CWE object const countPropertiesInCWEArray = ( arr: CWERelated[], ): { total: number; breakdown: number[]; } => { let accumulatedTotal = 0; const keys: (keyof CWERelated)[] = ['cwe', 'cweParent', 'cweGrandParent']; const breakdown = arr.map(item => { const count = keys.reduce((sum, key) => sum + (item[key] ? 1 : 0), 0); const currentTotal = accumulatedTotal; accumulatedTotal += count; return currentTotal; }); const total = accumulatedTotal; return { total, breakdown }; }; const MultiCheckboxButton = ({ cwesRecommended, cweRecommendationSelected, setCweRecommendationSelected, }: CheckboxButtonProps) => { const countProperties = countPropertiesInCWEArray(cwesRecommended); const [selectedBox, setSelectedBox] = useState( Array(countProperties.total).fill(false), ); useEffect(() => { if (cweRecommendationSelected.length === 0) { setSelectedBox(Array(countProperties.total).fill(false)); } }, [cweRecommendationSelected.length, countProperties.total]); const allStrings: string[] = cwesRecommended.flatMap(item => { const { cwe, cweParent, cweGrandParent } = item; return [cwe, cweParent, cweGrandParent].filter((value): value is string => Boolean(value), ); }); const [showAncestors, setShowAncestors] = useState( Array(cwesRecommended.length).fill(false), ); const onChange = (index: number) => { const values = selectedBox.map((itemMap, i) => i === index ? !itemMap : itemMap, ); setSelectedBox(values); const selectedOptions = allStrings.filter((_, index) => values[index]); setCweRecommendationSelected([...selectedOptions]); }; const handlerOnClick = (index: number) => { setShowAncestors( showAncestors.map((item, i) => (i === index ? !item : item)), ); }; return (
{t('recommendedCwe')}:
{cwesRecommended.map((option: CWERelated, index: number) => (
onChange(countProperties.breakdown[index])} >

{option.cwe}

{showAncestors[index] ? (
{option.cweParent ? (
onChange(countProperties.breakdown[index] + 1) } >

{option.cweParent}

) : null} {option.cweGrandParent ? (
onChange(countProperties.breakdown[index] + 2) } >

{option.cweGrandParent}

) : null}
) : null}
))}
); }; export default MultiCheckboxButton;