import { t } from 'i18next'; import { useCallback, useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import { toast } from 'sonner'; import SimpleInput from '@/components/input/SimpleInput'; import SelectDropdown from '../../../../../components/dropdown/SelectDropdown'; import UITable, { Column } from '../../../../../components/table/UITable'; import { useSortableTable } from '../../../../../hooks/useSortableTable'; import { useTableFiltering } from '../../../../../hooks/useTableFiltering'; import type { FindingByLocale, Language } from '../../../../../services/audits'; import { addFinding, addVuln, getLanguages, getVulnByLanguage, } from '../../../../../services/audits'; import { useAuditContext } from '../../useAuditContext'; import DivWrapper from './DivWrapper'; import NewVulnButton from './NewVulnButton'; type ListItem = { id: number; value: string; label?: string; }; type LanguagesData = { language: string; locale: string; }; type TableData = { id: string; title: string; category: string; type: string; }; let dataLanguage: { status: string; datas: Language[] } = { status: '', datas: [], }; export const Add = () => { const { handlerFindings } = useAuditContext(); const [languages, setLanguages] = useState([]); const [currentLanguage, setCurrentLanguage] = useState(null); const [loadingLanguages, setLoadingLanguages] = useState(true); const [newVulnTitle, setNewVulnTitle] = useState(''); const { auditId } = useParams(); const columns: Column[] = [ { header: t('title'), accessor: 'title', sortable: true, filterable: true, }, { header: t('category'), accessor: 'category', sortable: false, filterable: true, }, { header: t('type'), accessor: 'type', sortable: false, filterable: true, }, ]; const [filteredData, setFilteredData] = useState([]); const [tableData, handleSorting, setTableData] = useSortableTable( filteredData, columns, ); const [filters, handleFilterChange] = useTableFiltering( filteredData, columns, setTableData, ); useEffect(() => { getLanguages() .then(res => { dataLanguage = res; }) .catch(console.error); }, []); useEffect(() => { const fetchData = async () => { try { const languagesName = dataLanguage.datas.map( (item: LanguagesData, index: number) => ({ id: index, value: item.locale, label: item.language, }), ); setLanguages(languagesName); setLoadingLanguages(false); if (languagesName.length > 0 && currentLanguage === null) { setCurrentLanguage(languagesName[0]); } const vulns = await getVulnByLanguage( currentLanguage ? currentLanguage.value : 'en', ); const vulnsName = vulns.datas.map( (item: FindingByLocale): TableData => ({ id: item._id, title: item.detail.title, category: item.category ?? t('noCategory'), type: item.detail.vulnType ?? t('undefined'), }), ); setTableData(vulnsName); setFilteredData(vulnsName); } catch (err) { setLoadingLanguages(false); } }; fetchData().catch(console.error); }, [currentLanguage, setTableData, dataLanguage]); const handleAddVuln = useCallback( async (item: TableData) => { try { const res = await addVuln( item.id, auditId ?? '', currentLanguage ? currentLanguage.value : 'en', ); if (res.status === 'success') { setNewVulnTitle(''); toast.success(t('msg.findingCreateOk')); await handlerFindings(); } else { toast.error(res.datas); } } catch (error) { console.error(error); } }, [auditId, currentLanguage, handlerFindings], ); const rowActions = [ { label: 'Add', onClick: handleAddVuln, }, ]; const handleAddFinding = useCallback(() => { addFinding(newVulnTitle, auditId ?? '') .then(async res => { if (res.status === 'success') { await handlerFindings(); setNewVulnTitle(''); toast.success(t('msg.findingCreateOk')); } else { toast.error(res.datas); } }) .catch(console.error); }, [newVulnTitle, auditId, handlerFindings]); return (
{!loadingLanguages ? ( ) : null}
item.id} onFilter={handleFilterChange} onSort={handleSorting} rowActions={rowActions} sortable={true} />
); };