ConceptPortal-public/rsconcept/frontend/src/dialogs/DlgShowAST.tsx

91 lines
2.6 KiB
TypeScript
Raw Normal View History

'use client';
2023-09-04 20:37:55 +03:00
import { useCallback, useMemo, useState } from 'react';
2023-08-01 21:55:18 +03:00
import GraphUI, { GraphEdge, GraphNode } from '@/components/Common/GraphUI';
import Modal, { ModalProps } from '@/components/Common/Modal';
import { useConceptTheme } from '@/context/ThemeContext';
import { SyntaxTree } from '@/models/rslang';
import { graphDarkT, graphLightT } from '@/utils/color';
2023-12-26 14:23:51 +03:00
import { colorBgSyntaxTree } from '@/utils/color';
import { resources } from '@/utils/constants';
import { labelSyntaxTree } from '@/utils/labels';
2023-07-29 03:31:21 +03:00
2023-09-11 17:56:32 +03:00
interface DlgShowASTProps
extends Pick<ModalProps, 'hideWindow'> {
2023-07-29 03:31:21 +03:00
syntaxTree: SyntaxTree
2023-08-01 21:55:18 +03:00
expression: string
2023-07-29 03:31:21 +03:00
}
2023-08-01 21:55:18 +03:00
function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
2023-09-04 20:37:55 +03:00
const { darkMode, colors } = useConceptTheme();
const [hoverID, setHoverID] = useState<number | undefined>(undefined);
const hoverNode = useMemo(
() => syntaxTree.find(node => node.uid === hoverID)
, [hoverID, syntaxTree]);
2023-08-01 21:55:18 +03:00
const nodes: GraphNode[] = useMemo(
() => syntaxTree.map(node => ({
id: String(node.uid),
2023-09-21 14:58:01 +03:00
label: labelSyntaxTree(node),
2023-12-26 14:23:51 +03:00
fill: colorBgSyntaxTree(node, colors),
})), [syntaxTree, colors]);
2023-08-01 21:55:18 +03:00
const edges: GraphEdge[] = useMemo(
() => {
const result: GraphEdge[] = [];
syntaxTree.forEach(node => {
if (node.parent !== node.uid) {
2023-08-01 21:55:18 +03:00
result.push({
id: String(node.uid),
source: String(node.parent),
target: String(node.uid)
});
}
});
return result;
}, [syntaxTree]);
2023-07-29 03:31:21 +03:00
2023-09-04 20:37:55 +03:00
const handleHoverIn = useCallback(
(node: GraphNode) => setHoverID(Number(node.id))
, []);
2023-09-04 20:37:55 +03:00
const handleHoverOut = useCallback(
() => setHoverID(undefined)
, []);
2023-09-04 20:37:55 +03:00
2023-07-29 03:31:21 +03:00
return (
2023-12-07 01:21:27 +03:00
<Modal readonly
2023-12-04 14:19:54 +03:00
hideWindow={hideWindow}
2023-12-07 01:21:27 +03:00
className='px-6'
2023-12-04 14:19:54 +03:00
>
<div className='my-2 text-lg text-center'>
2023-12-04 14:19:54 +03:00
{!hoverNode ? expression : null}
{hoverNode ?
<div>
<span>{expression.slice(0, hoverNode.start)}</span>
<span className='clr-selected'>{expression.slice(hoverNode.start, hoverNode.finish)}</span>
<span>{expression.slice(hoverNode.finish)}</span>
</div> : null}
</div>
<div
className='relative'
style={{
width: 'calc(100vw - 6rem - 2px)',
height: 'calc(100vh - 14rem - 2px)'
}}
2023-07-29 03:31:21 +03:00
>
<GraphUI
2023-12-04 14:19:54 +03:00
nodes={nodes}
edges={edges}
layoutType='hierarchicalTd'
labelFontUrl={resources.graph_font}
theme={darkMode ? graphDarkT : graphLightT}
onNodePointerOver={handleHoverIn}
onNodePointerOut={handleHoverOut}
/>
</div>
</Modal>);
2023-07-29 03:31:21 +03:00
}
export default DlgShowAST;