mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 21:10:38 +03:00
F: Add suggestions to substitution table
This commit is contained in:
parent
fa6eb49172
commit
2fb64ef69a
|
@ -83,7 +83,6 @@ export { LuNewspaper as IconDefinition } from 'react-icons/lu';
|
||||||
export { LuDna as IconTerminology } from 'react-icons/lu';
|
export { LuDna as IconTerminology } from 'react-icons/lu';
|
||||||
export { FaRegHandshake as IconConvention } from 'react-icons/fa6';
|
export { FaRegHandshake as IconConvention } from 'react-icons/fa6';
|
||||||
export { LiaCloneSolid as IconChild } from 'react-icons/lia';
|
export { LiaCloneSolid as IconChild } from 'react-icons/lia';
|
||||||
export { RiParentLine as IconParent } from 'react-icons/ri';
|
|
||||||
export { TbTopologyRing as IconConsolidation } from 'react-icons/tb';
|
export { TbTopologyRing as IconConsolidation } from 'react-icons/tb';
|
||||||
export { BiSpa as IconPredecessor } from 'react-icons/bi';
|
export { BiSpa as IconPredecessor } from 'react-icons/bi';
|
||||||
export { LuArchive as IconArchive } from 'react-icons/lu';
|
export { LuArchive as IconArchive } from 'react-icons/lu';
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import BadgeConstituenta from '@/components/info/BadgeConstituenta';
|
import BadgeConstituenta from '@/components/info/BadgeConstituenta';
|
||||||
import SelectConstituenta from '@/components/select/SelectConstituenta';
|
import SelectConstituenta from '@/components/select/SelectConstituenta';
|
||||||
import DataTable, { createColumnHelper } from '@/components/ui/DataTable';
|
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
|
||||||
import MiniButton from '@/components/ui/MiniButton';
|
import MiniButton from '@/components/ui/MiniButton';
|
||||||
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
||||||
import { ILibraryItem } from '@/models/library';
|
import { ILibraryItem } from '@/models/library';
|
||||||
|
@ -13,13 +13,14 @@ import { ICstSubstitute, IMultiSubstitution } from '@/models/oss';
|
||||||
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
|
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
|
||||||
import { errors } from '@/utils/labels';
|
import { errors } from '@/utils/labels';
|
||||||
|
|
||||||
import { IconPageLeft, IconPageRight, IconRemove, IconReplace } from '../Icons';
|
import { IconAccept, IconPageLeft, IconPageRight, IconRemove, IconReplace } from '../Icons';
|
||||||
import NoData from '../ui/NoData';
|
import NoData from '../ui/NoData';
|
||||||
import SelectLibraryItem from './SelectLibraryItem';
|
import SelectLibraryItem from './SelectLibraryItem';
|
||||||
|
|
||||||
interface PickSubstitutionsProps {
|
interface PickSubstitutionsProps {
|
||||||
substitutions: ICstSubstitute[];
|
substitutions: ICstSubstitute[];
|
||||||
setSubstitutions: React.Dispatch<React.SetStateAction<ICstSubstitute[]>>;
|
setSubstitutions: React.Dispatch<React.SetStateAction<ICstSubstitute[]>>;
|
||||||
|
suggestions?: ICstSubstitute[];
|
||||||
|
|
||||||
prefixID: string;
|
prefixID: string;
|
||||||
rows?: number;
|
rows?: number;
|
||||||
|
@ -34,6 +35,7 @@ const columnHelper = createColumnHelper<IMultiSubstitution>();
|
||||||
function PickSubstitutions({
|
function PickSubstitutions({
|
||||||
substitutions,
|
substitutions,
|
||||||
setSubstitutions,
|
setSubstitutions,
|
||||||
|
suggestions,
|
||||||
prefixID,
|
prefixID,
|
||||||
rows,
|
rows,
|
||||||
schemas,
|
schemas,
|
||||||
|
@ -55,6 +57,15 @@ function PickSubstitutions({
|
||||||
const [deleteRight, setDeleteRight] = useState(true);
|
const [deleteRight, setDeleteRight] = useState(true);
|
||||||
const toggleDelete = () => setDeleteRight(prev => !prev);
|
const toggleDelete = () => setDeleteRight(prev => !prev);
|
||||||
|
|
||||||
|
const [ignores, setIgnores] = useState<ICstSubstitute[]>([]);
|
||||||
|
const filteredSuggestions = useMemo(
|
||||||
|
() =>
|
||||||
|
suggestions?.filter(
|
||||||
|
item => !ignores.find(ignore => ignore.original === item.original && ignore.substitution === item.substitution)
|
||||||
|
) ?? [],
|
||||||
|
[ignores, suggestions]
|
||||||
|
);
|
||||||
|
|
||||||
const getSchemaByCst = useCallback(
|
const getSchemaByCst = useCallback(
|
||||||
(id: ConstituentaID): IRSForm | undefined => {
|
(id: ConstituentaID): IRSForm | undefined => {
|
||||||
for (const schema of schemas) {
|
for (const schema of schemas) {
|
||||||
|
@ -82,14 +93,23 @@ function PickSubstitutions({
|
||||||
);
|
);
|
||||||
|
|
||||||
const substitutionData: IMultiSubstitution[] = useMemo(
|
const substitutionData: IMultiSubstitution[] = useMemo(
|
||||||
() =>
|
() => [
|
||||||
substitutions.map(item => ({
|
...substitutions.map(item => ({
|
||||||
original_source: getSchemaByCst(item.original)!,
|
original_source: getSchemaByCst(item.original)!,
|
||||||
original: getConstituenta(item.original)!,
|
original: getConstituenta(item.original)!,
|
||||||
substitution: getConstituenta(item.substitution)!,
|
substitution: getConstituenta(item.substitution)!,
|
||||||
substitution_source: getSchemaByCst(item.substitution)!
|
substitution_source: getSchemaByCst(item.substitution)!,
|
||||||
|
is_suggestion: false
|
||||||
})),
|
})),
|
||||||
[getConstituenta, getSchemaByCst, substitutions]
|
...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() {
|
function addSubstitution() {
|
||||||
|
@ -121,19 +141,34 @@ function PickSubstitutions({
|
||||||
setRightCst(undefined);
|
setRightCst(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDeleteRow = useCallback(
|
const handleDeclineSuggestion = useCallback(
|
||||||
(row: number) => {
|
(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 => {
|
setSubstitutions(prev => {
|
||||||
const newItems: ICstSubstitute[] = [];
|
const newItems: ICstSubstitute[] = [];
|
||||||
prev.forEach((item, index) => {
|
prev.forEach(item => {
|
||||||
if (index !== row) {
|
if (item.original !== target.original.id || item.substitution !== target.substitution.id) {
|
||||||
newItems.push(item);
|
newItems.push(item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return newItems;
|
return newItems;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[setSubstitutions]
|
[setSubstitutions, handleDeclineSuggestion]
|
||||||
);
|
);
|
||||||
|
|
||||||
const columns = useMemo(
|
const columns = useMemo(
|
||||||
|
@ -169,19 +204,47 @@ function PickSubstitutions({
|
||||||
}),
|
}),
|
||||||
columnHelper.display({
|
columnHelper.display({
|
||||||
id: 'actions',
|
id: 'actions',
|
||||||
cell: props => (
|
cell: props =>
|
||||||
|
props.row.original.is_suggestion ? (
|
||||||
|
<div className='max-w-fit'>
|
||||||
|
<MiniButton
|
||||||
|
noHover
|
||||||
|
title='Принять предложение'
|
||||||
|
icon={<IconAccept size='1rem' className='icon-green' />}
|
||||||
|
onClick={() => handleAcceptSuggestion(props.row.original)}
|
||||||
|
/>
|
||||||
|
<MiniButton
|
||||||
|
noHover
|
||||||
|
title='Игнорировать предложение'
|
||||||
|
icon={<IconRemove size='1rem' className='icon-red' />}
|
||||||
|
onClick={() => handleDeclineSuggestion(props.row.original)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<div className='max-w-fit'>
|
<div className='max-w-fit'>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
noHover
|
noHover
|
||||||
title='Удалить'
|
title='Удалить'
|
||||||
icon={<IconRemove size='1rem' className='icon-red' />}
|
icon={<IconRemove size='1rem' className='icon-red' />}
|
||||||
onClick={() => handleDeleteRow(props.row.index)}
|
onClick={() => handleDeleteSubstitution(props.row.original)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
[handleDeleteRow, colors, prefixID]
|
[handleDeleteSubstitution, handleDeclineSuggestion, handleAcceptSuggestion, colors, prefixID]
|
||||||
|
);
|
||||||
|
|
||||||
|
const conditionalRowStyles = useMemo(
|
||||||
|
(): IConditionalStyle<IMultiSubstitution>[] => [
|
||||||
|
{
|
||||||
|
when: (item: IMultiSubstitution) => item.is_suggestion,
|
||||||
|
style: {
|
||||||
|
backgroundColor: colors.bgOrange50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[colors]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -265,6 +328,7 @@ function PickSubstitutions({
|
||||||
<p>Добавьте отождествление</p>
|
<p>Добавьте отождествление</p>
|
||||||
</NoData>
|
</NoData>
|
||||||
}
|
}
|
||||||
|
conditionalRowStyles={conditionalRowStyles}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
||||||
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
||||||
|
|
||||||
import BadgeHelp from '@/components/info/BadgeHelp';
|
import BadgeHelp from '@/components/info/BadgeHelp';
|
||||||
|
@ -54,7 +54,10 @@ function DlgEditOperation({ hideWindow, oss, target, onSubmit }: DlgEditOperatio
|
||||||
() => inputOperations.map(operation => operation.result).filter(id => id !== null),
|
() => inputOperations.map(operation => operation.result).filter(id => id !== null),
|
||||||
[inputOperations]
|
[inputOperations]
|
||||||
);
|
);
|
||||||
|
|
||||||
const [substitutions, setSubstitutions] = useState<ICstSubstitute[]>(target.substitutions);
|
const [substitutions, setSubstitutions] = useState<ICstSubstitute[]>(target.substitutions);
|
||||||
|
const [suggestions, setSuggestions] = useState<ICstSubstitute[]>([]);
|
||||||
|
|
||||||
const cache = useRSFormCache();
|
const cache = useRSFormCache();
|
||||||
const schemas = useMemo(
|
const schemas = useMemo(
|
||||||
() => schemasIDs.map(id => cache.getSchema(id)).filter(item => item !== undefined),
|
() => schemasIDs.map(id => cache.getSchema(id)).filter(item => item !== undefined),
|
||||||
|
@ -63,11 +66,11 @@ function DlgEditOperation({ hideWindow, oss, target, onSubmit }: DlgEditOperatio
|
||||||
|
|
||||||
const canSubmit = useMemo(() => alias !== '', [alias]);
|
const canSubmit = useMemo(() => alias !== '', [alias]);
|
||||||
|
|
||||||
useEffect(() => {
|
useLayoutEffect(() => {
|
||||||
cache.preload(schemasIDs);
|
cache.preload(schemasIDs);
|
||||||
}, [schemasIDs]);
|
}, [schemasIDs]);
|
||||||
|
|
||||||
useEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (cache.loading || schemas.length !== schemasIDs.length) {
|
if (cache.loading || schemas.length !== schemasIDs.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -86,13 +89,14 @@ function DlgEditOperation({ hideWindow, oss, target, onSubmit }: DlgEditOperatio
|
||||||
);
|
);
|
||||||
}, [schemasIDs, schemas, cache.loading]);
|
}, [schemasIDs, schemas, cache.loading]);
|
||||||
|
|
||||||
useEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (cache.loading || schemas.length !== schemasIDs.length) {
|
if (cache.loading || schemas.length !== schemasIDs.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const validator = new SubstitutionValidator(schemas, substitutions);
|
const validator = new SubstitutionValidator(schemas, substitutions);
|
||||||
setIsCorrect(validator.validate());
|
setIsCorrect(validator.validate());
|
||||||
setValidationText(validator.msg);
|
setValidationText(validator.msg);
|
||||||
|
setSuggestions(validator.suggestions);
|
||||||
}, [substitutions, cache.loading, schemas, schemasIDs.length]);
|
}, [substitutions, cache.loading, schemas, schemasIDs.length]);
|
||||||
|
|
||||||
const handleSubmit = useCallback(() => {
|
const handleSubmit = useCallback(() => {
|
||||||
|
@ -151,10 +155,11 @@ function DlgEditOperation({ hideWindow, oss, target, onSubmit }: DlgEditOperatio
|
||||||
isCorrect={isCorrect}
|
isCorrect={isCorrect}
|
||||||
substitutions={substitutions}
|
substitutions={substitutions}
|
||||||
setSubstitutions={setSubstitutions}
|
setSubstitutions={setSubstitutions}
|
||||||
|
suggestions={suggestions}
|
||||||
/>
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
),
|
),
|
||||||
[cache.loading, cache.error, substitutions, schemas, validationText, isCorrect]
|
[cache.loading, cache.error, substitutions, suggestions, schemas, validationText, isCorrect]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -16,6 +16,7 @@ interface TabSynthesisProps {
|
||||||
schemas: IRSForm[];
|
schemas: IRSForm[];
|
||||||
substitutions: ICstSubstitute[];
|
substitutions: ICstSubstitute[];
|
||||||
setSubstitutions: React.Dispatch<React.SetStateAction<ICstSubstitute[]>>;
|
setSubstitutions: React.Dispatch<React.SetStateAction<ICstSubstitute[]>>;
|
||||||
|
suggestions: ICstSubstitute[];
|
||||||
}
|
}
|
||||||
|
|
||||||
function TabSynthesis({
|
function TabSynthesis({
|
||||||
|
@ -25,7 +26,8 @@ function TabSynthesis({
|
||||||
validationText,
|
validationText,
|
||||||
isCorrect,
|
isCorrect,
|
||||||
substitutions,
|
substitutions,
|
||||||
setSubstitutions
|
setSubstitutions,
|
||||||
|
suggestions
|
||||||
}: TabSynthesisProps) {
|
}: TabSynthesisProps) {
|
||||||
const { colors } = useConceptOptions();
|
const { colors } = useConceptOptions();
|
||||||
return (
|
return (
|
||||||
|
@ -36,6 +38,7 @@ function TabSynthesis({
|
||||||
rows={10}
|
rows={10}
|
||||||
substitutions={substitutions}
|
substitutions={substitutions}
|
||||||
setSubstitutions={setSubstitutions}
|
setSubstitutions={setSubstitutions}
|
||||||
|
suggestions={suggestions}
|
||||||
/>
|
/>
|
||||||
<TextArea
|
<TextArea
|
||||||
disabled
|
disabled
|
||||||
|
|
|
@ -133,6 +133,7 @@ export interface IMultiSubstitution {
|
||||||
original: IConstituenta;
|
original: IConstituenta;
|
||||||
substitution: IConstituenta;
|
substitution: IConstituenta;
|
||||||
substitution_source: ILibraryItem;
|
substitution_source: ILibraryItem;
|
||||||
|
is_suggestion: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { Graph } from './Graph';
|
||||||
import { ILibraryItem, LibraryItemID } from './library';
|
import { ILibraryItem, LibraryItemID } from './library';
|
||||||
import { ICstSubstitute, IOperation, IOperationSchema, SubstitutionErrorType } from './oss';
|
import { ICstSubstitute, IOperation, IOperationSchema, SubstitutionErrorType } from './oss';
|
||||||
import { ConstituentaID, CstClass, CstType, IConstituenta, IRSForm } from './rsform';
|
import { ConstituentaID, CstClass, CstType, IConstituenta, IRSForm } from './rsform';
|
||||||
import { inferClass } from './rsformAPI';
|
|
||||||
import { AliasMapping, ParsingStatus } from './rslang';
|
import { AliasMapping, ParsingStatus } from './rslang';
|
||||||
import { applyAliasMapping, applyTypificationMapping, extractGlobals, isSetTypification } from './rslangAPI';
|
import { applyAliasMapping, applyTypificationMapping, extractGlobals, isSetTypification } from './rslangAPI';
|
||||||
|
|
||||||
|
@ -59,6 +58,7 @@ type CrossMapping = Map<LibraryItemID, AliasMapping>;
|
||||||
*/
|
*/
|
||||||
export class SubstitutionValidator {
|
export class SubstitutionValidator {
|
||||||
public msg: string = '';
|
public msg: string = '';
|
||||||
|
public suggestions: ICstSubstitute[] = [];
|
||||||
|
|
||||||
private schemas: IRSForm[];
|
private schemas: IRSForm[];
|
||||||
private substitutions: ICstSubstitute[];
|
private substitutions: ICstSubstitute[];
|
||||||
|
@ -102,6 +102,7 @@ export class SubstitutionValidator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public validate(): boolean {
|
public validate(): boolean {
|
||||||
|
this.calculateSuggestions();
|
||||||
if (this.substitutions.length === 0) {
|
if (this.substitutions.length === 0) {
|
||||||
return this.setValid();
|
return this.setValid();
|
||||||
}
|
}
|
||||||
|
@ -118,6 +119,55 @@ export class SubstitutionValidator {
|
||||||
return this.setValid();
|
return this.setValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private calculateSuggestions(): void {
|
||||||
|
const candidates = new Map<ConstituentaID, string>();
|
||||||
|
const minors = new Set<ConstituentaID>();
|
||||||
|
const schemaByCst = new Map<ConstituentaID, IRSForm>();
|
||||||
|
for (const schema of this.schemas) {
|
||||||
|
for (const cst of schema.items) {
|
||||||
|
if (this.originals.has(cst.id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cst.cst_class === CstClass.BASIC) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const inputs = schema.graph.at(cst.id)!.inputs;
|
||||||
|
if (inputs.length === 0 || inputs.some(id => !this.constituents.has(id))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (inputs.some(id => this.originals.has(id))) {
|
||||||
|
minors.add(cst.id);
|
||||||
|
}
|
||||||
|
candidates.set(cst.id, applyAliasMapping(cst.definition_formal, this.mapping.get(schema.id)!).replace(' ', ''));
|
||||||
|
schemaByCst.set(cst.id, schema);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const [key1, value1] of candidates) {
|
||||||
|
for (const [key2, value2] of candidates) {
|
||||||
|
if (key1 >= key2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (schemaByCst.get(key1) === schemaByCst.get(key2)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (value1 != value2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (minors.has(key2)) {
|
||||||
|
this.suggestions.push({
|
||||||
|
original: key2,
|
||||||
|
substitution: key1
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.suggestions.push({
|
||||||
|
original: key1,
|
||||||
|
substitution: key2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private checkTypes(): boolean {
|
private checkTypes(): boolean {
|
||||||
for (const item of this.substitutions) {
|
for (const item of this.substitutions) {
|
||||||
const original = this.cstByID.get(item.original);
|
const original = this.cstByID.get(item.original);
|
||||||
|
@ -242,7 +292,7 @@ export class SubstitutionValidator {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const substitution = this.cstByID.get(item.substitution)!;
|
const substitution = this.cstByID.get(item.substitution)!;
|
||||||
if (original.cst_type === substitution.cst_type && inferClass(original.cst_type) === CstClass.DERIVED) {
|
if (original.cst_type === substitution.cst_type && original.cst_class !== CstClass.BASIC) {
|
||||||
if (!this.checkEqual(original, substitution)) {
|
if (!this.checkEqual(original, substitution)) {
|
||||||
this.reportError(SubstitutionErrorType.unequalExpressions, [substitution.alias, original.alias]);
|
this.reportError(SubstitutionErrorType.unequalExpressions, [substitution.alias, original.alias]);
|
||||||
// Note: do not interrupt the validation process. Only warn about the problem.
|
// Note: do not interrupt the validation process. Only warn about the problem.
|
||||||
|
@ -320,7 +370,6 @@ export class SubstitutionValidator {
|
||||||
} else {
|
} else {
|
||||||
substitutionText = applyAliasMapping(substitution.parse.typification, baseMappings.get(substitution.schema)!);
|
substitutionText = applyAliasMapping(substitution.parse.typification, baseMappings.get(substitution.schema)!);
|
||||||
substitutionText = applyTypificationMapping(substitutionText, result);
|
substitutionText = applyTypificationMapping(substitutionText, result);
|
||||||
console.log(substitutionText);
|
|
||||||
if (!isSetTypification(substitutionText)) {
|
if (!isSetTypification(substitutionText)) {
|
||||||
this.reportError(SubstitutionErrorType.baseSubstitutionNotSet, [
|
this.reportError(SubstitutionErrorType.baseSubstitutionNotSet, [
|
||||||
substitution.alias,
|
substitution.alias,
|
||||||
|
|
|
@ -46,8 +46,9 @@ function HelpConceptOSS() {
|
||||||
<p>
|
<p>
|
||||||
Операция синтеза в рамках ОСС задаются набором операций-аргументов и <b>таблицей отождествлений</b> понятий из
|
Операция синтеза в рамках ОСС задаются набором операций-аргументов и <b>таблицей отождествлений</b> понятий из
|
||||||
КС, привязанных к выбранным аргументам. Таким образом{' '}
|
КС, привязанных к выбранным аргументам. Таким образом{' '}
|
||||||
<LinkTopic text='конституенты' topic={HelpTopic.CC_CONSTITUENTA} /> в каждой КС разделяются на исходные
|
<LinkTopic text='конституенты' topic={HelpTopic.CC_CONSTITUENTA} /> в каждой КС разделяются на исходные и
|
||||||
(дописанные), наследованные, отождествленные (удаляемые).
|
наследованные. При формировании таблицы отождествлений пользователю предлагается синтезировать производные
|
||||||
|
понятия, выражения которых совпадают после проведения заданных отождествлений.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
После задания аргументов и таблицы отождествления необходимо единожды{' '}
|
После задания аргументов и таблицы отождествления необходимо единожды{' '}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { AnimatePresence } from 'framer-motion';
|
||||||
import { useEffect, useLayoutEffect, useMemo, useState } from 'react';
|
import { useEffect, useLayoutEffect, useMemo, useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import { IconChild, IconParent, IconSave } from '@/components/Icons';
|
import { IconChild, IconPredecessor, IconSave } from '@/components/Icons';
|
||||||
import RefsInput from '@/components/RefsInput';
|
import RefsInput from '@/components/RefsInput';
|
||||||
import MiniButton from '@/components/ui/MiniButton';
|
import MiniButton from '@/components/ui/MiniButton';
|
||||||
import Overlay from '@/components/ui/Overlay';
|
import Overlay from '@/components/ui/Overlay';
|
||||||
|
@ -249,14 +249,14 @@ function FormConstituenta({
|
||||||
<Overlay position='top-[0.1rem] left-[0.4rem]' className='cc-icons'>
|
<Overlay position='top-[0.1rem] left-[0.4rem]' className='cc-icons'>
|
||||||
{state?.is_inherited_parent ? (
|
{state?.is_inherited_parent ? (
|
||||||
<MiniButton
|
<MiniButton
|
||||||
icon={<IconChild size='1.25rem' className='clr-text-red' />}
|
icon={<IconPredecessor size='1.25rem' className='clr-text-red' />}
|
||||||
disabled
|
disabled
|
||||||
titleHtml='Внимание!</br> Конституента имеет потомков<br/> в операционной схеме синтеза'
|
titleHtml='Внимание!</br> Конституента имеет потомков<br/> в операционной схеме синтеза'
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
{state?.is_inherited ? (
|
{state?.is_inherited ? (
|
||||||
<MiniButton
|
<MiniButton
|
||||||
icon={<IconParent size='1.25rem' className='clr-text-red' />}
|
icon={<IconChild size='1.25rem' className='clr-text-red' />}
|
||||||
disabled
|
disabled
|
||||||
titleHtml='Внимание!</br> Конституента является наследником<br/>'
|
titleHtml='Внимание!</br> Конституента является наследником<br/>'
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user