import { useState, useMemo, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { Box, styled } from '@mui/material'; import { Extension } from '@mui/icons-material'; import { Table, SortableTableHeader, TableBody, TableCell, TableRow, TablePlaceholder, } from 'component/common/Table'; import { ActionCell } from 'component/common/Table/cells/ActionCell/ActionCell'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { PageContent } from 'component/common/PageContent/PageContent'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { formatStrategyName } from 'utils/strategyNames'; import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies'; import useStrategiesApi from 'hooks/api/actions/useStrategiesApi/useStrategiesApi'; import useToast from 'hooks/useToast'; import { formatUnknownError } from 'utils/formatUnknownError'; import { IStrategy } from 'interfaces/strategy'; import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell'; import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; import { sortTypes } from 'utils/sortTypes'; import { useTable, useGlobalFilter, useSortBy } from 'react-table'; import { AddStrategyButton } from './AddStrategyButton/AddStrategyButton'; import { StrategySwitch } from './StrategySwitch/StrategySwitch'; import { StrategyEditButton } from './StrategyEditButton/StrategyEditButton'; import { StrategyDeleteButton } from './StrategyDeleteButton/StrategyDeleteButton'; import { Search } from 'component/common/Search/Search'; import { Badge } from 'component/common/Badge/Badge'; interface IDialogueMetaData { show: boolean; title: string; onConfirm: () => void; } const StyledBadge = styled(Badge)(({ theme }) => ({ marginLeft: theme.spacing(1), display: 'inline-block', })); export const StrategiesList = () => { const navigate = useNavigate(); const [dialogueMetaData, setDialogueMetaData] = useState( { show: false, title: '', onConfirm: () => {}, } ); const { strategies, refetchStrategies, loading } = useStrategies(); const { removeStrategy, deprecateStrategy, reactivateStrategy } = useStrategiesApi(); const { setToastData, setToastApiError } = useToast(); const data = useMemo(() => { if (loading) { return Array(5).fill({ name: 'Context name', description: 'Context description when loading', }); } return strategies.map( ({ name, description, editable, deprecated }) => ({ name, description, editable, deprecated, }) ); }, [strategies, loading]); const onToggle = useCallback( (strategy: IStrategy) => (deprecated: boolean) => { if (deprecated) { setDialogueMetaData({ show: true, title: 'Really reactivate strategy?', onConfirm: async () => { try { await reactivateStrategy(strategy); refetchStrategies(); setToastData({ type: 'success', title: 'Success', text: 'Strategy reactivated successfully', }); } catch (error: unknown) { setToastApiError(formatUnknownError(error)); } }, }); } else { setDialogueMetaData({ show: true, title: 'Really deprecate strategy?', onConfirm: async () => { try { await deprecateStrategy(strategy); refetchStrategies(); setToastData({ type: 'success', title: 'Success', text: 'Strategy deprecated successfully', }); } catch (error: unknown) { setToastApiError(formatUnknownError(error)); } }, }); } }, [ deprecateStrategy, reactivateStrategy, refetchStrategies, setToastApiError, setToastData, ] ); const onDeleteStrategy = useCallback( (strategy: IStrategy) => { setDialogueMetaData({ show: true, title: 'Really delete strategy?', onConfirm: async () => { try { await removeStrategy(strategy); refetchStrategies(); setToastData({ type: 'success', title: 'Success', text: 'Strategy deleted successfully', }); } catch (error: unknown) { setToastApiError(formatUnknownError(error)); } }, }); }, [removeStrategy, refetchStrategies, setToastApiError, setToastData] ); const onEditStrategy = useCallback( (strategy: IStrategy) => { navigate(`/strategies/${strategy.name}/edit`); }, [navigate] ); const columns = useMemo( () => [ { id: 'Icon', Cell: () => ( ), disableGlobalFilter: true, }, { Header: 'Name', accessor: 'name', width: '90%', Cell: ({ row: { original: { name, description, deprecated, editable }, }, }: any) => { const subTitleText = deprecated ? `${description} (deprecated)` : description; return ( ( Predefined )} /> ); }, sortType: 'alphanumeric', }, { Header: 'Actions', id: 'Actions', align: 'center', Cell: ({ row: { original } }: any) => ( onEditStrategy(original)} /> onDeleteStrategy(original)} /> ), width: 150, disableGlobalFilter: true, disableSortBy: true, }, { accessor: 'description', disableSortBy: true, }, { accessor: 'sortOrder', disableGlobalFilter: true, sortType: 'number', }, ], [onToggle, onEditStrategy, onDeleteStrategy] ); const initialState = useMemo( () => ({ sortBy: [{ id: 'name', desc: false }], hiddenColumns: ['description', 'sortOrder'], }), [] ); const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow, state: { globalFilter }, setGlobalFilter, } = useTable( { columns: columns as any[], // TODO: fix after `react-table` v8 update data, initialState, sortTypes, autoResetGlobalFilter: false, autoResetSortBy: false, disableSortRemove: true, }, useGlobalFilter, useSortBy ); const onDialogConfirm = () => { dialogueMetaData?.onConfirm(); setDialogueMetaData((prev: IDialogueMetaData) => ({ ...prev, show: false, })); }; return ( } /> } > {rows.map(row => { prepareRow(row); return ( {row.cells.map(cell => ( {cell.render('Cell')} ))} ); })}
0} show={ No strategies found matching “ {globalFilter} ” } elseShow={ No strategies available. Get started by adding one. } /> } /> setDialogueMetaData((prev: IDialogueMetaData) => ({ ...prev, show: false, })) } />
); };