mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
F: Add TypeGraph for RSForm
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run
This commit is contained in:
parent
18601a2ee7
commit
15c292d240
|
@ -100,6 +100,7 @@ export { LuSubscript as IconAlias } from 'react-icons/lu';
|
||||||
export { TbMathFunction as IconFormula } from 'react-icons/tb';
|
export { TbMathFunction as IconFormula } from 'react-icons/tb';
|
||||||
export { BiFontFamily as IconText } from 'react-icons/bi';
|
export { BiFontFamily as IconText } from 'react-icons/bi';
|
||||||
export { BiFont as IconTextOff } from 'react-icons/bi';
|
export { BiFont as IconTextOff } from 'react-icons/bi';
|
||||||
|
export { TbCar4Wd as IconTypeGraph } from 'react-icons/tb';
|
||||||
export { RiTreeLine as IconTree } from 'react-icons/ri';
|
export { RiTreeLine as IconTree } from 'react-icons/ri';
|
||||||
export { FaRegKeyboard as IconControls } from 'react-icons/fa6';
|
export { FaRegKeyboard as IconControls } from 'react-icons/fa6';
|
||||||
export { RiLockLine as IconImmutable } from 'react-icons/ri';
|
export { RiLockLine as IconImmutable } from 'react-icons/ri';
|
||||||
|
|
|
@ -6,24 +6,22 @@ import { ReactFlowProvider } from 'reactflow';
|
||||||
|
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal, { ModalProps } from '@/components/ui/Modal';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
import { IArgumentInfo } from '@/models/rslang';
|
import { ITypeInfo } from '@/models/rslang';
|
||||||
import { TMGraph } from '@/models/TMGraph';
|
import { TMGraph } from '@/models/TMGraph';
|
||||||
import { errors } from '@/utils/labels';
|
import { errors } from '@/utils/labels';
|
||||||
|
|
||||||
import MGraphFlow from './MGraphFlow';
|
import MGraphFlow from './MGraphFlow';
|
||||||
|
|
||||||
interface DlgShowTypificationProps extends Pick<ModalProps, 'hideWindow'> {
|
interface DlgShowTypeGraphProps extends Pick<ModalProps, 'hideWindow'> {
|
||||||
alias: string;
|
items: ITypeInfo[];
|
||||||
resultTypification: string;
|
|
||||||
args: IArgumentInfo[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function DlgShowTypification({ hideWindow, alias, resultTypification, args }: DlgShowTypificationProps) {
|
function DlgShowTypeGraph({ hideWindow, items }: DlgShowTypeGraphProps) {
|
||||||
const graph = useMemo(() => {
|
const graph = useMemo(() => {
|
||||||
const result = new TMGraph();
|
const result = new TMGraph();
|
||||||
result.addConstituenta(alias, resultTypification, args);
|
items.forEach(item => result.addConstituenta(item.alias, item.result, item.args));
|
||||||
return result;
|
return result;
|
||||||
}, [alias, resultTypification, args]);
|
}, [items]);
|
||||||
|
|
||||||
if (graph.nodes.length === 0) {
|
if (graph.nodes.length === 0) {
|
||||||
toast.error(errors.typeStructureFailed);
|
toast.error(errors.typeStructureFailed);
|
||||||
|
@ -33,7 +31,7 @@ function DlgShowTypification({ hideWindow, alias, resultTypification, args }: Dl
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
header='Структура типизации'
|
header='Граф ступеней'
|
||||||
readonly
|
readonly
|
||||||
hideWindow={hideWindow}
|
hideWindow={hideWindow}
|
||||||
className='flex flex-col justify-stretch w-[calc(100dvw-3rem)] h-[calc(100dvh-6rem)]'
|
className='flex flex-col justify-stretch w-[calc(100dvw-3rem)] h-[calc(100dvh-6rem)]'
|
||||||
|
@ -46,4 +44,4 @@ function DlgShowTypification({ hideWindow, alias, resultTypification, args }: Dl
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DlgShowTypification;
|
export default DlgShowTypeGraph;
|
|
@ -1,3 +1,6 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useMemo } from 'react';
|
||||||
import { Handle, Position } from 'reactflow';
|
import { Handle, Position } from 'reactflow';
|
||||||
|
|
||||||
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
||||||
|
@ -8,16 +11,23 @@ import { globals } from '@/utils/constants';
|
||||||
function MGraphNode(node: MGraphNodeInternal) {
|
function MGraphNode(node: MGraphNodeInternal) {
|
||||||
const { colors } = useConceptOptions();
|
const { colors } = useConceptOptions();
|
||||||
|
|
||||||
|
const tooltipText = useMemo(
|
||||||
|
() =>
|
||||||
|
(node.data.annotations.length === 0 ? '' : `Конституенты: ${node.data.annotations.join(' ')}<br/>`) +
|
||||||
|
node.data.text,
|
||||||
|
[node.data]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Handle type='source' position={Position.Top} style={{ opacity: 0 }} />
|
<Handle type='source' position={Position.Top} style={{ opacity: 0 }} />
|
||||||
<div
|
<div
|
||||||
className='w-full h-full cursor-default flex items-center justify-center rounded-full'
|
className='w-full h-full cursor-default flex items-center justify-center rounded-full'
|
||||||
data-tooltip-id={globals.tooltip}
|
data-tooltip-id={globals.tooltip}
|
||||||
data-tooltip-content={node.data.text}
|
data-tooltip-html={tooltipText}
|
||||||
style={{ backgroundColor: colorBgTMGraphNode(node.data, colors) }}
|
style={{ backgroundColor: colorBgTMGraphNode(node.data, colors) }}
|
||||||
>
|
>
|
||||||
{node.data.rank === 0 ? node.data.text : ''}
|
{node.data.rank === 0 ? node.data.text : node.data.annotations.length > 0 ? node.data.annotations.length : ''}
|
||||||
</div>
|
</div>
|
||||||
<Handle type='target' position={Position.Bottom} style={{ opacity: 0 }} />
|
<Handle type='target' position={Position.Bottom} style={{ opacity: 0 }} />
|
||||||
</>
|
</>
|
|
@ -0,0 +1 @@
|
||||||
|
export { default } from './DlgShowTypeGraph';
|
|
@ -1 +0,0 @@
|
||||||
export { default } from './DlgShowTypification';
|
|
|
@ -72,6 +72,13 @@ export interface IArgumentInfo {
|
||||||
typification: string;
|
typification: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Represents global identifier type info. */
|
||||||
|
export interface ITypeInfo {
|
||||||
|
alias: string;
|
||||||
|
result: string;
|
||||||
|
args: IArgumentInfo[];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents function argument value.
|
* Represents function argument value.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -15,7 +15,8 @@ import {
|
||||||
IconOSS,
|
IconOSS,
|
||||||
IconReset,
|
IconReset,
|
||||||
IconRotate3D,
|
IconRotate3D,
|
||||||
IconText
|
IconText,
|
||||||
|
IconTypeGraph
|
||||||
} from '@/components/Icons';
|
} from '@/components/Icons';
|
||||||
import Divider from '@/components/ui/Divider';
|
import Divider from '@/components/ui/Divider';
|
||||||
import LinkTopic from '@/components/ui/LinkTopic';
|
import LinkTopic from '@/components/ui/LinkTopic';
|
||||||
|
@ -81,6 +82,10 @@ function HelpRSGraphTerm() {
|
||||||
<li>
|
<li>
|
||||||
<IconFitImage className='inline-icon' /> Вписать в экран
|
<IconFitImage className='inline-icon' /> Вписать в экран
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<IconTypeGraph className='inline-icon' /> Открыть{' '}
|
||||||
|
<LinkTopic text='граф ступеней' topic={HelpTopic.UI_TYPE_GRAPH} />
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<IconImage className='inline-icon' /> Сохранить в формат PNG
|
<IconImage className='inline-icon' /> Сохранить в формат PNG
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -13,7 +13,8 @@ function HelpTypeGraph() {
|
||||||
Портале кратные ребра представлены перечислением индексов компонент произведения.
|
Портале кратные ребра представлены перечислением индексов компонент произведения.
|
||||||
</p>
|
</p>
|
||||||
<li>ребра без надписей означают взятие булеана</li>
|
<li>ребра без надписей означают взятие булеана</li>
|
||||||
<li>цифры означают номера компонент декартова произведения</li>
|
<li>цифры на ребрах означают номера компонент декартова произведения</li>
|
||||||
|
<li>цифры на узлах означают количество конституент в данной ступени</li>
|
||||||
<li>основаниями дерева являются ступени базисных, константных множеств</li>
|
<li>основаниями дерева являются ступени базисных, константных множеств</li>
|
||||||
<li>ступень терм-функции - произведение ступеней результата и аргументов</li>
|
<li>ступень терм-функции - произведение ступеней результата и аргументов</li>
|
||||||
<li>ступень предикат-функции - произведение ступеней аргументов</li>
|
<li>ступень предикат-функции - произведение ступеней аргументов</li>
|
||||||
|
|
|
@ -14,7 +14,7 @@ import SubmitButton from '@/components/ui/SubmitButton';
|
||||||
import TextArea from '@/components/ui/TextArea';
|
import TextArea from '@/components/ui/TextArea';
|
||||||
import AnimateFade from '@/components/wrap/AnimateFade';
|
import AnimateFade from '@/components/wrap/AnimateFade';
|
||||||
import { useRSForm } from '@/context/RSFormContext';
|
import { useRSForm } from '@/context/RSFormContext';
|
||||||
import DlgShowTypification from '@/dialogs/DlgShowTypification';
|
import DlgShowTypeGraph from '@/dialogs/DlgShowTypeGraph';
|
||||||
import { ConstituentaID, CstType, IConstituenta, ICstUpdateData } from '@/models/rsform';
|
import { ConstituentaID, CstType, IConstituenta, ICstUpdateData } from '@/models/rsform';
|
||||||
import { isBaseSet, isBasicConcept, isFunctional } from '@/models/rsformAPI';
|
import { isBaseSet, isBasicConcept, isFunctional } from '@/models/rsformAPI';
|
||||||
import { IExpressionParse, ParsingStatus } from '@/models/rslang';
|
import { IExpressionParse, ParsingStatus } from '@/models/rslang';
|
||||||
|
@ -60,6 +60,17 @@ function FormConstituenta({
|
||||||
const [typification, setTypification] = useState('N/A');
|
const [typification, setTypification] = useState('N/A');
|
||||||
const [showTypification, setShowTypification] = useState(false);
|
const [showTypification, setShowTypification] = useState(false);
|
||||||
const [localParse, setLocalParse] = useState<IExpressionParse | undefined>(undefined);
|
const [localParse, setLocalParse] = useState<IExpressionParse | undefined>(undefined);
|
||||||
|
const typeInfo = useMemo(
|
||||||
|
() =>
|
||||||
|
state
|
||||||
|
? {
|
||||||
|
alias: state.alias,
|
||||||
|
result: localParse ? localParse.typification : state.parse.typification,
|
||||||
|
args: localParse ? localParse.args : state.parse.args
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
[state, localParse]
|
||||||
|
);
|
||||||
|
|
||||||
const [forceComment, setForceComment] = useState(false);
|
const [forceComment, setForceComment] = useState(false);
|
||||||
|
|
||||||
|
@ -147,12 +158,7 @@ function FormConstituenta({
|
||||||
<AnimateFade className='mx-0 md:mx-auto pt-[2rem] xs:pt-0'>
|
<AnimateFade className='mx-0 md:mx-auto pt-[2rem] xs:pt-0'>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{showTypification && state ? (
|
{showTypification && state ? (
|
||||||
<DlgShowTypification
|
<DlgShowTypeGraph items={typeInfo ? [typeInfo] : []} hideWindow={() => setShowTypification(false)} />
|
||||||
alias={state.alias}
|
|
||||||
resultTypification={localParse ? localParse.typification : state.parse.typification}
|
|
||||||
args={localParse ? localParse.args : state.parse.args}
|
|
||||||
hideWindow={() => setShowTypification(false)}
|
|
||||||
/>
|
|
||||||
) : null}
|
) : null}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
{state ? (
|
{state ? (
|
||||||
|
|
|
@ -10,7 +10,8 @@ import {
|
||||||
IconNewItem,
|
IconNewItem,
|
||||||
IconRotate3D,
|
IconRotate3D,
|
||||||
IconText,
|
IconText,
|
||||||
IconTextOff
|
IconTextOff,
|
||||||
|
IconTypeGraph
|
||||||
} from '@/components/Icons';
|
} from '@/components/Icons';
|
||||||
import BadgeHelp from '@/components/info/BadgeHelp';
|
import BadgeHelp from '@/components/info/BadgeHelp';
|
||||||
import MiniSelectorOSS from '@/components/select/MiniSelectorOSS';
|
import MiniSelectorOSS from '@/components/select/MiniSelectorOSS';
|
||||||
|
@ -116,6 +117,11 @@ function ToolbarTermGraph({
|
||||||
onClick={onDelete}
|
onClick={onDelete}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
<MiniButton
|
||||||
|
icon={<IconTypeGraph size='1.25rem' className='icon-primary' />}
|
||||||
|
title='Граф ступеней'
|
||||||
|
onClick={() => controller.showTypeGraph()}
|
||||||
|
/>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
icon={<IconImage size='1.25rem' className='icon-primary' />}
|
icon={<IconImage size='1.25rem' className='icon-primary' />}
|
||||||
title='Сохранить изображение'
|
title='Сохранить изображение'
|
||||||
|
|
|
@ -22,6 +22,7 @@ import DlgEditVersions from '@/dialogs/DlgEditVersions';
|
||||||
import DlgEditWordForms from '@/dialogs/DlgEditWordForms';
|
import DlgEditWordForms from '@/dialogs/DlgEditWordForms';
|
||||||
import DlgInlineSynthesis from '@/dialogs/DlgInlineSynthesis';
|
import DlgInlineSynthesis from '@/dialogs/DlgInlineSynthesis';
|
||||||
import DlgRenameCst from '@/dialogs/DlgRenameCst';
|
import DlgRenameCst from '@/dialogs/DlgRenameCst';
|
||||||
|
import DlgShowTypeGraph from '@/dialogs/DlgShowTypeGraph';
|
||||||
import DlgSubstituteCst from '@/dialogs/DlgSubstituteCst';
|
import DlgSubstituteCst from '@/dialogs/DlgSubstituteCst';
|
||||||
import DlgUploadRSForm from '@/dialogs/DlgUploadRSForm';
|
import DlgUploadRSForm from '@/dialogs/DlgUploadRSForm';
|
||||||
import {
|
import {
|
||||||
|
@ -106,6 +107,8 @@ export interface IRSEditContext extends ILibraryItemEditor {
|
||||||
produceStructure: () => void;
|
produceStructure: () => void;
|
||||||
inlineSynthesis: () => void;
|
inlineSynthesis: () => void;
|
||||||
substitute: () => void;
|
substitute: () => void;
|
||||||
|
|
||||||
|
showTypeGraph: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RSEditContext = createContext<IRSEditContext | null>(null);
|
const RSEditContext = createContext<IRSEditContext | null>(null);
|
||||||
|
@ -169,6 +172,7 @@ export const RSEditState = ({
|
||||||
const [showCreateVersion, setShowCreateVersion] = useState(false);
|
const [showCreateVersion, setShowCreateVersion] = useState(false);
|
||||||
const [showEditVersions, setShowEditVersions] = useState(false);
|
const [showEditVersions, setShowEditVersions] = useState(false);
|
||||||
const [showInlineSynthesis, setShowInlineSynthesis] = useState(false);
|
const [showInlineSynthesis, setShowInlineSynthesis] = useState(false);
|
||||||
|
const [showTypeGraph, setShowTypeGraph] = useState(false);
|
||||||
|
|
||||||
const [createInitialData, setCreateInitialData] = useState<ICstCreateData>();
|
const [createInitialData, setCreateInitialData] = useState<ICstCreateData>();
|
||||||
const [showCreateCst, setShowCreateCst] = useState(false);
|
const [showCreateCst, setShowCreateCst] = useState(false);
|
||||||
|
@ -179,6 +183,18 @@ export const RSEditState = ({
|
||||||
const [insertCstID, setInsertCstID] = useState<ConstituentaID | undefined>(undefined);
|
const [insertCstID, setInsertCstID] = useState<ConstituentaID | undefined>(undefined);
|
||||||
const [showTemplates, setShowTemplates] = useState(false);
|
const [showTemplates, setShowTemplates] = useState(false);
|
||||||
|
|
||||||
|
const typeInfo = useMemo(
|
||||||
|
() =>
|
||||||
|
model.schema
|
||||||
|
? model.schema.items.map(item => ({
|
||||||
|
alias: item.alias,
|
||||||
|
result: item.parse.typification,
|
||||||
|
args: item.parse.args
|
||||||
|
}))
|
||||||
|
: [],
|
||||||
|
[model.schema]
|
||||||
|
);
|
||||||
|
|
||||||
useLayoutEffect(
|
useLayoutEffect(
|
||||||
() =>
|
() =>
|
||||||
setAccessLevel(prev => {
|
setAccessLevel(prev => {
|
||||||
|
@ -662,7 +678,9 @@ export const RSEditState = ({
|
||||||
reorder,
|
reorder,
|
||||||
inlineSynthesis,
|
inlineSynthesis,
|
||||||
produceStructure,
|
produceStructure,
|
||||||
substitute
|
substitute,
|
||||||
|
|
||||||
|
showTypeGraph: () => setShowTypeGraph(true)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{model.schema ? (
|
{model.schema ? (
|
||||||
|
@ -762,6 +780,8 @@ export const RSEditState = ({
|
||||||
onInlineSynthesis={handleInlineSynthesis}
|
onInlineSynthesis={handleInlineSynthesis}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
{showTypeGraph ? <DlgShowTypeGraph items={typeInfo} hideWindow={() => setShowTypeGraph(false)} /> : null}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user