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 { BiFontFamily as IconText } 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 { FaRegKeyboard as IconControls } from 'react-icons/fa6';
|
||||
export { RiLockLine as IconImmutable } from 'react-icons/ri';
|
||||
|
|
|
@ -6,24 +6,22 @@ import { ReactFlowProvider } from 'reactflow';
|
|||
|
||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
||||
import { HelpTopic } from '@/models/miscellaneous';
|
||||
import { IArgumentInfo } from '@/models/rslang';
|
||||
import { ITypeInfo } from '@/models/rslang';
|
||||
import { TMGraph } from '@/models/TMGraph';
|
||||
import { errors } from '@/utils/labels';
|
||||
|
||||
import MGraphFlow from './MGraphFlow';
|
||||
|
||||
interface DlgShowTypificationProps extends Pick<ModalProps, 'hideWindow'> {
|
||||
alias: string;
|
||||
resultTypification: string;
|
||||
args: IArgumentInfo[];
|
||||
interface DlgShowTypeGraphProps extends Pick<ModalProps, 'hideWindow'> {
|
||||
items: ITypeInfo[];
|
||||
}
|
||||
|
||||
function DlgShowTypification({ hideWindow, alias, resultTypification, args }: DlgShowTypificationProps) {
|
||||
function DlgShowTypeGraph({ hideWindow, items }: DlgShowTypeGraphProps) {
|
||||
const graph = useMemo(() => {
|
||||
const result = new TMGraph();
|
||||
result.addConstituenta(alias, resultTypification, args);
|
||||
items.forEach(item => result.addConstituenta(item.alias, item.result, item.args));
|
||||
return result;
|
||||
}, [alias, resultTypification, args]);
|
||||
}, [items]);
|
||||
|
||||
if (graph.nodes.length === 0) {
|
||||
toast.error(errors.typeStructureFailed);
|
||||
|
@ -33,7 +31,7 @@ function DlgShowTypification({ hideWindow, alias, resultTypification, args }: Dl
|
|||
|
||||
return (
|
||||
<Modal
|
||||
header='Структура типизации'
|
||||
header='Граф ступеней'
|
||||
readonly
|
||||
hideWindow={hideWindow}
|
||||
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 { useConceptOptions } from '@/context/ConceptOptionsContext';
|
||||
|
@ -8,16 +11,23 @@ import { globals } from '@/utils/constants';
|
|||
function MGraphNode(node: MGraphNodeInternal) {
|
||||
const { colors } = useConceptOptions();
|
||||
|
||||
const tooltipText = useMemo(
|
||||
() =>
|
||||
(node.data.annotations.length === 0 ? '' : `Конституенты: ${node.data.annotations.join(' ')}<br/>`) +
|
||||
node.data.text,
|
||||
[node.data]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Handle type='source' position={Position.Top} style={{ opacity: 0 }} />
|
||||
<div
|
||||
className='w-full h-full cursor-default flex items-center justify-center rounded-full'
|
||||
data-tooltip-id={globals.tooltip}
|
||||
data-tooltip-content={node.data.text}
|
||||
data-tooltip-html={tooltipText}
|
||||
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>
|
||||
<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;
|
||||
}
|
||||
|
||||
/** Represents global identifier type info. */
|
||||
export interface ITypeInfo {
|
||||
alias: string;
|
||||
result: string;
|
||||
args: IArgumentInfo[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents function argument value.
|
||||
*/
|
||||
|
|
|
@ -15,7 +15,8 @@ import {
|
|||
IconOSS,
|
||||
IconReset,
|
||||
IconRotate3D,
|
||||
IconText
|
||||
IconText,
|
||||
IconTypeGraph
|
||||
} from '@/components/Icons';
|
||||
import Divider from '@/components/ui/Divider';
|
||||
import LinkTopic from '@/components/ui/LinkTopic';
|
||||
|
@ -81,6 +82,10 @@ function HelpRSGraphTerm() {
|
|||
<li>
|
||||
<IconFitImage className='inline-icon' /> Вписать в экран
|
||||
</li>
|
||||
<li>
|
||||
<IconTypeGraph className='inline-icon' /> Открыть{' '}
|
||||
<LinkTopic text='граф ступеней' topic={HelpTopic.UI_TYPE_GRAPH} />
|
||||
</li>
|
||||
<li>
|
||||
<IconImage className='inline-icon' /> Сохранить в формат PNG
|
||||
</li>
|
||||
|
|
|
@ -13,7 +13,8 @@ function HelpTypeGraph() {
|
|||
Портале кратные ребра представлены перечислением индексов компонент произведения.
|
||||
</p>
|
||||
<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 AnimateFade from '@/components/wrap/AnimateFade';
|
||||
import { useRSForm } from '@/context/RSFormContext';
|
||||
import DlgShowTypification from '@/dialogs/DlgShowTypification';
|
||||
import DlgShowTypeGraph from '@/dialogs/DlgShowTypeGraph';
|
||||
import { ConstituentaID, CstType, IConstituenta, ICstUpdateData } from '@/models/rsform';
|
||||
import { isBaseSet, isBasicConcept, isFunctional } from '@/models/rsformAPI';
|
||||
import { IExpressionParse, ParsingStatus } from '@/models/rslang';
|
||||
|
@ -60,6 +60,17 @@ function FormConstituenta({
|
|||
const [typification, setTypification] = useState('N/A');
|
||||
const [showTypification, setShowTypification] = useState(false);
|
||||
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);
|
||||
|
||||
|
@ -147,12 +158,7 @@ function FormConstituenta({
|
|||
<AnimateFade className='mx-0 md:mx-auto pt-[2rem] xs:pt-0'>
|
||||
<AnimatePresence>
|
||||
{showTypification && state ? (
|
||||
<DlgShowTypification
|
||||
alias={state.alias}
|
||||
resultTypification={localParse ? localParse.typification : state.parse.typification}
|
||||
args={localParse ? localParse.args : state.parse.args}
|
||||
hideWindow={() => setShowTypification(false)}
|
||||
/>
|
||||
<DlgShowTypeGraph items={typeInfo ? [typeInfo] : []} hideWindow={() => setShowTypification(false)} />
|
||||
) : null}
|
||||
</AnimatePresence>
|
||||
{state ? (
|
||||
|
|
|
@ -10,7 +10,8 @@ import {
|
|||
IconNewItem,
|
||||
IconRotate3D,
|
||||
IconText,
|
||||
IconTextOff
|
||||
IconTextOff,
|
||||
IconTypeGraph
|
||||
} from '@/components/Icons';
|
||||
import BadgeHelp from '@/components/info/BadgeHelp';
|
||||
import MiniSelectorOSS from '@/components/select/MiniSelectorOSS';
|
||||
|
@ -116,6 +117,11 @@ function ToolbarTermGraph({
|
|||
onClick={onDelete}
|
||||
/>
|
||||
) : null}
|
||||
<MiniButton
|
||||
icon={<IconTypeGraph size='1.25rem' className='icon-primary' />}
|
||||
title='Граф ступеней'
|
||||
onClick={() => controller.showTypeGraph()}
|
||||
/>
|
||||
<MiniButton
|
||||
icon={<IconImage size='1.25rem' className='icon-primary' />}
|
||||
title='Сохранить изображение'
|
||||
|
|
|
@ -22,6 +22,7 @@ import DlgEditVersions from '@/dialogs/DlgEditVersions';
|
|||
import DlgEditWordForms from '@/dialogs/DlgEditWordForms';
|
||||
import DlgInlineSynthesis from '@/dialogs/DlgInlineSynthesis';
|
||||
import DlgRenameCst from '@/dialogs/DlgRenameCst';
|
||||
import DlgShowTypeGraph from '@/dialogs/DlgShowTypeGraph';
|
||||
import DlgSubstituteCst from '@/dialogs/DlgSubstituteCst';
|
||||
import DlgUploadRSForm from '@/dialogs/DlgUploadRSForm';
|
||||
import {
|
||||
|
@ -106,6 +107,8 @@ export interface IRSEditContext extends ILibraryItemEditor {
|
|||
produceStructure: () => void;
|
||||
inlineSynthesis: () => void;
|
||||
substitute: () => void;
|
||||
|
||||
showTypeGraph: () => void;
|
||||
}
|
||||
|
||||
const RSEditContext = createContext<IRSEditContext | null>(null);
|
||||
|
@ -169,6 +172,7 @@ export const RSEditState = ({
|
|||
const [showCreateVersion, setShowCreateVersion] = useState(false);
|
||||
const [showEditVersions, setShowEditVersions] = useState(false);
|
||||
const [showInlineSynthesis, setShowInlineSynthesis] = useState(false);
|
||||
const [showTypeGraph, setShowTypeGraph] = useState(false);
|
||||
|
||||
const [createInitialData, setCreateInitialData] = useState<ICstCreateData>();
|
||||
const [showCreateCst, setShowCreateCst] = useState(false);
|
||||
|
@ -179,6 +183,18 @@ export const RSEditState = ({
|
|||
const [insertCstID, setInsertCstID] = useState<ConstituentaID | undefined>(undefined);
|
||||
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(
|
||||
() =>
|
||||
setAccessLevel(prev => {
|
||||
|
@ -662,7 +678,9 @@ export const RSEditState = ({
|
|||
reorder,
|
||||
inlineSynthesis,
|
||||
produceStructure,
|
||||
substitute
|
||||
substitute,
|
||||
|
||||
showTypeGraph: () => setShowTypeGraph(true)
|
||||
}}
|
||||
>
|
||||
{model.schema ? (
|
||||
|
@ -762,6 +780,8 @@ export const RSEditState = ({
|
|||
onInlineSynthesis={handleInlineSynthesis}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{showTypeGraph ? <DlgShowTypeGraph items={typeInfo} hideWindow={() => setShowTypeGraph(false)} /> : null}
|
||||
</AnimatePresence>
|
||||
) : null}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user