'use client'; import clsx from 'clsx'; import { useCallback, useMemo, useState } from 'react'; import { toast } from 'react-toastify'; import BadgeConstituenta from '@/components/info/BadgeConstituenta'; import SelectConstituenta from '@/components/select/SelectConstituenta'; import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable'; import MiniButton from '@/components/ui/MiniButton'; import { useConceptOptions } from '@/context/ConceptOptionsContext'; import { ILibraryItem } from '@/models/library'; import { ICstSubstitute, IMultiSubstitution } from '@/models/oss'; import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform'; import { errors } from '@/utils/labels'; import { IconAccept, IconPageLeft, IconPageRight, IconRemove, IconReplace } from '../Icons'; import { CProps } from '../props'; import NoData from '../ui/NoData'; import SelectLibraryItem from './SelectLibraryItem'; interface PickSubstitutionsProps extends CProps.Styling { substitutions: ICstSubstitute[]; setSubstitutions: React.Dispatch>; suggestions?: ICstSubstitute[]; prefixID: string; rows?: number; allowSelfSubstitution?: boolean; schemas: IRSForm[]; filter?: (cst: IConstituenta) => boolean; } const columnHelper = createColumnHelper(); function PickSubstitutions({ substitutions, setSubstitutions, suggestions, prefixID, rows, schemas, filter, allowSelfSubstitution, className, ...restProps }: PickSubstitutionsProps) { const { colors } = useConceptOptions(); const [leftArgument, setLeftArgument] = useState( schemas.length === 1 ? schemas[0] : undefined ); const [rightArgument, setRightArgument] = useState( schemas.length === 1 && allowSelfSubstitution ? schemas[0] : undefined ); const [leftCst, setLeftCst] = useState(undefined); const [rightCst, setRightCst] = useState(undefined); const [deleteRight, setDeleteRight] = useState(true); const toggleDelete = () => setDeleteRight(prev => !prev); const [ignores, setIgnores] = useState([]); const filteredSuggestions = useMemo( () => suggestions?.filter( item => !ignores.find(ignore => ignore.original === item.original && ignore.substitution === item.substitution) ) ?? [], [ignores, suggestions] ); const getSchemaByCst = useCallback( (id: ConstituentaID): IRSForm | undefined => { for (const schema of schemas) { const cst = schema.cstByID.get(id); if (cst) { return schema; } } return undefined; }, [schemas] ); const getConstituenta = useCallback( (id: ConstituentaID): IConstituenta | undefined => { for (const schema of schemas) { const cst = schema.cstByID.get(id); if (cst) { return cst; } } return undefined; }, [schemas] ); const substitutionData: IMultiSubstitution[] = useMemo( () => [ ...substitutions.map(item => ({ original_source: getSchemaByCst(item.original)!, original: getConstituenta(item.original)!, substitution: getConstituenta(item.substitution)!, substitution_source: getSchemaByCst(item.substitution)!, is_suggestion: false })), ...filteredSuggestions.map(item => ({ original_source: getSchemaByCst(item.original)!, original: getConstituenta(item.original)!, substitution: getConstituenta(item.substitution)!, substitution_source: getSchemaByCst(item.substitution)!, is_suggestion: true })) ], [getConstituenta, getSchemaByCst, substitutions, filteredSuggestions] ); function addSubstitution() { if (!leftCst || !rightCst) { return; } const newSubstitution: ICstSubstitute = { original: deleteRight ? rightCst.id : leftCst.id, substitution: deleteRight ? leftCst.id : rightCst.id }; const toDelete = substitutions.map(item => item.original); const replacements = substitutions.map(item => item.substitution); if ( toDelete.includes(newSubstitution.original) || toDelete.includes(newSubstitution.substitution) || replacements.includes(newSubstitution.original) ) { toast.error(errors.reuseOriginal); return; } if (leftArgument === rightArgument) { if ((deleteRight && rightCst?.is_inherited) || (!deleteRight && leftCst?.is_inherited)) { toast.error(errors.substituteInherited); return; } } setSubstitutions(prev => [...prev, newSubstitution]); setLeftCst(undefined); setRightCst(undefined); } const handleDeclineSuggestion = useCallback( (item: IMultiSubstitution) => { setIgnores(prev => [...prev, { original: item.original.id, substitution: item.substitution.id }]); }, [setIgnores] ); const handleAcceptSuggestion = useCallback( (item: IMultiSubstitution) => { setSubstitutions(prev => [...prev, { original: item.original.id, substitution: item.substitution.id }]); }, [setSubstitutions] ); const handleDeleteSubstitution = useCallback( (target: IMultiSubstitution) => { handleDeclineSuggestion(target); setSubstitutions(prev => { const newItems: ICstSubstitute[] = []; prev.forEach(item => { if (item.original !== target.original.id || item.substitution !== target.substitution.id) { newItems.push(item); } }); return newItems; }); }, [setSubstitutions, handleDeclineSuggestion] ); const columns = useMemo( () => [ columnHelper.accessor(item => item.substitution_source.alias, { id: 'left_schema', size: 100, cell: props =>
{props.getValue()}
}), columnHelper.accessor(item => item.substitution.alias, { id: 'left_alias', size: 65, cell: props => ( ) }), columnHelper.display({ id: 'status', size: 0, cell: () => }), columnHelper.accessor(item => item.original.alias, { id: 'right_alias', size: 65, cell: props => ( ) }), columnHelper.accessor(item => item.original_source.alias, { id: 'right_schema', size: 100, cell: props =>
{props.getValue()}
}), columnHelper.display({ id: 'actions', size: 0, cell: props => props.row.original.is_suggestion ? (
} onClick={() => handleAcceptSuggestion(props.row.original)} /> } onClick={() => handleDeclineSuggestion(props.row.original)} />
) : (
} onClick={() => handleDeleteSubstitution(props.row.original)} />
) }) ], [handleDeleteSubstitution, handleDeclineSuggestion, handleAcceptSuggestion, colors, prefixID] ); const conditionalRowStyles = useMemo( (): IConditionalStyle[] => [ { when: (item: IMultiSubstitution) => item.is_suggestion, style: { backgroundColor: colors.bgOrange50 } } ], [colors] ); return (
item.id !== rightArgument?.id)} value={leftArgument} onSelectValue={setLeftArgument} /> !substitutions.find(item => item.original === cst.id) && (!filter || filter(cst)) )} value={leftCst} onSelectValue={setLeftCst} />
) : ( ) } /> } disabled={!leftCst || !rightCst || leftCst === rightCst} onClick={addSubstitution} />
item.id !== leftArgument?.id)} value={rightArgument} onSelectValue={setRightArgument} /> !substitutions.find(item => item.original === cst.id) && (!filter || filter(cst)) )} value={rightCst} onSelectValue={setRightCst} />

Список пуст

Добавьте отождествление

} conditionalRowStyles={conditionalRowStyles} />
); } export default PickSubstitutions;