'use client'; import clsx from 'clsx'; import { useState } from 'react'; import { toast } from 'react-toastify'; import { MiniButton } from '@/components/Control'; import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/DataTable'; import { IconAccept, IconPageLeft, IconPageRight, IconRemove, IconReplace } from '@/components/Icons'; import { CProps } from '@/components/props'; import { NoData } from '@/components/View'; import SelectLibraryItem from '@/features/library/components/SelectLibraryItem'; import { ILibraryItem } from '@/features/library/models/library'; import { ICstSubstitute, IMultiSubstitution } from '@/features/oss/models/oss'; import { APP_COLORS } from '@/styling/colors'; import { errors } from '@/utils/labels'; import { ConstituentaID, IConstituenta, IRSForm } from '../models/rsform'; import BadgeConstituenta from './BadgeConstituenta'; import SelectConstituenta from './SelectConstituenta'; interface PickSubstitutionsProps extends CProps.Styling { value: ICstSubstitute[]; onChange: (newValue: ICstSubstitute[]) => void; suggestions?: ICstSubstitute[]; rows?: number; allowSelfSubstitution?: boolean; schemas: IRSForm[]; filter?: (cst: IConstituenta) => boolean; } const columnHelper = createColumnHelper(); function PickSubstitutions({ value, onChange, suggestions, rows, schemas, filter, allowSelfSubstitution, className, ...restProps }: PickSubstitutionsProps) { 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 = 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: ConstituentaID): IRSForm | undefined { for (const schema of schemas) { const cst = schema.cstByID.get(id); if (cst) { return schema; } } return undefined; } function getConstituenta(id: ConstituentaID): 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(errors.reuseOriginal); return; } if (leftArgument === rightArgument) { if ((deleteRight && rightCst?.is_inherited) || (!deleteRight && leftCst?.is_inherited)) { toast.error(errors.substituteInherited); return; } } onChange([...value, newSubstitution]); setLeftCst(undefined); setRightCst(undefined); } 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} /> !value.find(item => item.original === cst.id) && (!filter || filter(cst)) )} value={leftCst} onChange={setLeftCst} />
) : ( ) } /> } disabled={!leftCst || !rightCst || leftCst === rightCst} onClick={addSubstitution} />
item.id !== leftArgument?.id)} value={rightArgument} onChange={setRightArgument} /> !value.find(item => item.original === cst.id) && (!filter || filter(cst)) )} value={rightCst} onChange={setRightCst} />

Список пуст

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

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