import { createColumnHelper } from '@tanstack/react-table'; import { useCallback, useEffect, useLayoutEffect, useMemo, useState } from 'react'; import { useConceptTheme } from '../../context/ThemeContext'; import { getCompatibleGrams, Grammeme, parseEntityReference,parseGrammemes,parseSyntacticReference,ReferenceType } from '../../models/language'; import { CstMatchMode } from '../../models/miscelanious'; import { IConstituenta, matchConstituenta } from '../../models/rsform'; import ConstituentaTooltip from '../../pages/RSFormPage/elements/ConstituentaTooltip'; import { colorfgCstStatus } from '../../utils/color'; import { prefixes } from '../../utils/constants'; import { labelReferenceType } from '../../utils/labels'; import { compareGrammemeOptions, IGrammemeOption, PremadeWordForms, SelectorGrammems, SelectorReferenceType } from '../../utils/selectors'; import ConceptTooltip from '../Common/ConceptTooltip'; import Label from '../Common/Label'; import Modal from '../Common/Modal'; import SelectMulti from '../Common/SelectMulti'; import SelectSingle from '../Common/SelectSingle'; import TextInput from '../Common/TextInput'; import DataTable, { IConditionalStyle } from '../DataTable'; import HelpTerminologyControl from '../Help/HelpTerminologyControl'; import { HelpIcon } from '../Icons'; import TermformButton from './TermformButton'; interface DlgEditReferenceProps { hideWindow: () => void items: IConstituenta[] initialType: ReferenceType initialRef?: string initialText?: string onSave: (newRef: string) => void } const constituentaHelper = createColumnHelper(); function DlgEditReference({ hideWindow, items, initialRef, initialText, initialType, onSave }: DlgEditReferenceProps) { const { colors } = useConceptTheme(); const [type, setType] = useState(ReferenceType.ENTITY); const [nominal, setNominal] = useState(''); const [offset, setOffset] = useState(1); const [alias, setAlias] = useState(''); const [term, setTerm] = useState(''); const [filter, setFilter] = useState(''); const [filteredData, setFilteredData] = useState([]); const [selectedGrams, setSelectedGrams] = useState([]); const [gramOptions, setGramOptions] = useState([]); const isValid = useMemo( () => { if (type === ReferenceType.ENTITY) { return alias !== '' && selectedGrams.length > 0; } else if (type === ReferenceType.SYNTACTIC) { return nominal !== '' && offset !== 0; } else { return false; } }, [type, alias, selectedGrams, nominal, offset]); function produceReference(): string { if (type === ReferenceType.ENTITY) { return `@{${alias}|${selectedGrams.map(gram => gram.value).join(',')}}`; } else if (type === ReferenceType.SYNTACTIC) { return `@{${offset}|${nominal}}`; } else { return ''; } } // Initialization useLayoutEffect( () => { setType(initialType); if (initialRef) { if (initialType === ReferenceType.ENTITY) { const ref = parseEntityReference(initialRef); setAlias(ref.entity); const grams = parseGrammemes(ref.form); setSelectedGrams(SelectorGrammems.filter(data => grams.includes(data.value))); } else if (initialType === ReferenceType.SYNTACTIC) { const ref = parseSyntacticReference(initialRef); setOffset(ref.offset); setNominal(ref.nominal); } } else if (initialText) { setNominal(initialText ?? ''); setFilter(initialText); } }, [initialRef, initialText, initialType, items]); // Filter constituents useEffect( () => { if (filter === '') { setFilteredData(items.filter( (cst) => cst.term_resolved !== '') ); } else { setFilteredData(items.filter( (cst) => matchConstituenta(filter, cst, CstMatchMode.TERM)) ); } }, [filter, items]); // Filter grammemes when input changes useEffect( () => { const compatible = getCompatibleGrams( selectedGrams .filter(data => Object.values(Grammeme).includes(data.value as Grammeme)) .map(data => data.value as Grammeme) ); setGramOptions(SelectorGrammems.filter(({value}) => compatible.includes(value as Grammeme))); }, [selectedGrams]); // Update term when alias changes useEffect( () => { const cst = items.find(item => item.alias === alias) setTerm(cst?.term_resolved ?? '') }, [alias, term, items]); const handleSubmit = () => onSave(produceReference()); function handleSelectConstituenta(cst: IConstituenta) { setAlias(cst.alias); } const handleSelectGrams = useCallback( (grams: Grammeme[]) => { setSelectedGrams(SelectorGrammems.filter(({value}) => grams.includes(value as Grammeme))); }, []); const FormButtons = useMemo(() => { return (
{PremadeWordForms.slice(0, 6).map( (data, index) => selectedGrams.find(item => item.value as Grammeme === gram))} onSelectGrams={handleSelectGrams} /> )}
{PremadeWordForms.slice(6, 12).map( (data, index) => selectedGrams.find(item => item.value as Grammeme === gram))} onSelectGrams={handleSelectGrams} /> )}
); }, [handleSelectGrams, selectedGrams]); const columnsConstituenta = useMemo( () => [ constituentaHelper.accessor('alias', { id: 'alias', header: 'Имя', size: 65, minSize: 65, cell: props => { const cst = props.row.original; return (<>
{cst.alias}
); } }), constituentaHelper.accessor('term_resolved', { id: 'term', header: 'Термин', size: 600, minSize: 350, maxSize: 600 }) ], [colors]); const conditionalRowStyles = useMemo( (): IConditionalStyle[] => [ { when: (cst: IConstituenta) => cst.alias === alias, style: { backgroundColor: colors.bgSelected }, } ], [alias, colors]); return (
setType(data?.value ?? ReferenceType.ENTITY)} />
{type === ReferenceType.SYNTACTIC &&
setOffset(event.target.valueAsNumber)} /> setNominal(event.target.value)} />
} {type === ReferenceType.ENTITY &&
setFilter(event.target.value)} />

Список конституент пуст

Измените параметры фильтра

} onRowClicked={handleSelectConstituenta} />
setAlias(event.target.value)} />
{FormButtons}
}
); } export default DlgEditReference;