'use client'; import { useState } from 'react'; import { toast } from 'react-toastify'; import clsx from 'clsx'; import { type ILibraryItem } from '@/features/library'; import { SelectLibraryItem } from '@/features/library/components'; import { MiniButton } from '@/components/control'; import { createColumnHelper, DataTable, type IConditionalStyle } from '@/components/data-table'; import { IconAccept, IconPageLeft, IconPageRight, IconRemove, IconReplace } from '@/components/icons'; import { type Styling } from '@/components/props'; import { NoData } from '@/components/view'; import { APP_COLORS } from '@/styling/colors'; import { errorMsg } from '@/utils/labels'; import { type ICstSubstitute } from '../backend/types'; import { type IConstituenta, type IRSForm } from '../models/rsform'; import { BadgeConstituenta } from './badge-constituenta'; import { SelectConstituenta } from './select-constituenta'; interface IMultiSubstitution { original_source: ILibraryItem; original: IConstituenta; substitution: IConstituenta; substitution_source: ILibraryItem; is_suggestion: boolean; } interface PickSubstitutionsProps extends Styling { value: ICstSubstitute[]; onChange: (newValue: ICstSubstitute[]) => void; suggestions?: ICstSubstitute[]; rows?: number; allowSelfSubstitution?: boolean; schemas: IRSForm[]; filterCst?: (cst: IConstituenta) => boolean; } const columnHelper = createColumnHelper(); export function PickSubstitutions({ value, onChange, suggestions, rows, schemas, filterCst, allowSelfSubstitution, className, ...restProps }: PickSubstitutionsProps) { const [leftArgument, setLeftArgument] = useState(schemas.length === 1 ? schemas[0] : null); const [rightArgument, setRightArgument] = useState( schemas.length === 1 && allowSelfSubstitution ? schemas[0] : null ); const leftItems = !leftArgument ? [] : (leftArgument as IRSForm).items.filter( cst => !value.find(item => item.original === cst.id) && (!filterCst || filterCst(cst)) ); const [leftCst, setLeftCst] = useState(null); const [rightCst, setRightCst] = useState(null); const rightItems = !rightArgument ? [] : (rightArgument as IRSForm).items.filter( cst => !value.find(item => item.original === cst.id) && (!filterCst || filterCst(cst)) ); const [deleteRight, setDeleteRight] = useState(true); const toggleDelete = () => setDeleteRight(prev => !prev); const [ignores, setIgnores] = useState([]); const filteredSuggestions = suggestions?.filter( item => !ignores.find(ignore => ignore.original === item.original && ignore.substitution === item.substitution) ) ?? []; const substitutionData: IMultiSubstitution[] = [ ...value.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 })) ]; function getSchemaByCst(id: number): IRSForm | undefined { for (const schema of schemas) { const cst = schema.cstByID.get(id); if (cst) { return schema; } } return undefined; } function getConstituenta(id: number): IConstituenta | undefined { for (const schema of schemas) { const cst = schema.cstByID.get(id); if (cst) { return cst; } } return undefined; } function addSubstitution() { if (!leftCst || !rightCst) { return; } const newSubstitution: ICstSubstitute = { original: deleteRight ? rightCst.id : leftCst.id, substitution: deleteRight ? leftCst.id : rightCst.id }; const toDelete = value.map(item => item.original); const replacements = value.map(item => item.substitution); if ( toDelete.includes(newSubstitution.original) || toDelete.includes(newSubstitution.substitution) || replacements.includes(newSubstitution.original) ) { toast.error(errorMsg.reuseOriginal); return; } if (leftArgument === rightArgument) { if ((deleteRight && rightCst?.is_inherited) || (!deleteRight && leftCst?.is_inherited)) { toast.error(errorMsg.substituteInherited); return; } } onChange([...value, newSubstitution]); setLeftCst(null); setRightCst(null); } function handleDeclineSuggestion(item: IMultiSubstitution) { setIgnores([...value, { original: item.original.id, substitution: item.substitution.id }]); } function handleAcceptSuggestion(item: IMultiSubstitution) { onChange([...value, { original: item.original.id, substitution: item.substitution.id }]); } function handleDeleteSubstitution(target: IMultiSubstitution) { handleDeclineSuggestion(target); onChange( value.filter(item => item.original !== target.original.id || item.substitution !== target.substitution.id) ); } const columns = [ 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)} />
) }) ]; const conditionalRowStyles: IConditionalStyle[] = [ { when: (item: IMultiSubstitution) => item.is_suggestion, style: { backgroundColor: APP_COLORS.bgOrange50 } } ]; return (
item.id !== rightArgument?.id)} value={leftArgument} onChange={setLeftArgument} />
) : ( ) } /> } disabled={!leftCst || !rightCst || (leftCst === rightCst && !allowSelfSubstitution)} onClick={addSubstitution} />
item.id !== leftArgument?.id)} value={rightArgument} onChange={setRightArgument} />

Список пуст

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

} conditionalRowStyles={conditionalRowStyles} />
); }