2023-09-04 20:37:55 +03:00
|
|
|
import { useCallback, useMemo, useState } from 'react';
|
|
|
|
import { GraphCanvas,GraphEdge, GraphNode } from 'reagraph';
|
2023-08-01 21:55:18 +03:00
|
|
|
|
2023-09-11 17:56:32 +03:00
|
|
|
import Modal, { ModalProps } from '../../components/Common/Modal';
|
2023-08-01 21:55:18 +03:00
|
|
|
import { useConceptTheme } from '../../context/ThemeContext';
|
2023-09-11 20:31:54 +03:00
|
|
|
import { SyntaxTree } from '../../models/rslang';
|
2023-09-04 20:37:55 +03:00
|
|
|
import { graphDarkT, graphLightT } from '../../utils/color';
|
2023-08-01 21:55:18 +03:00
|
|
|
import { resources } from '../../utils/constants';
|
2023-09-04 20:37:55 +03:00
|
|
|
import { getASTNodeColor, getASTNodeLabel } from '../../utils/staticUI';
|
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(
|
2023-09-09 20:36:55 +03:00
|
|
|
() => syntaxTree.find(node => node.uid === hoverID)
|
|
|
|
, [hoverID, syntaxTree]);
|
|
|
|
|
2023-08-01 21:55:18 +03:00
|
|
|
const nodes: GraphNode[] = useMemo(
|
2023-09-09 20:36:55 +03:00
|
|
|
() => syntaxTree.map(node => ({
|
|
|
|
id: String(node.uid),
|
|
|
|
label: getASTNodeLabel(node),
|
|
|
|
fill: getASTNodeColor(node, colors),
|
|
|
|
})), [syntaxTree, colors]);
|
2023-08-01 21:55:18 +03:00
|
|
|
|
|
|
|
const edges: GraphEdge[] = useMemo(
|
|
|
|
() => {
|
|
|
|
const result: GraphEdge[] = [];
|
|
|
|
syntaxTree.forEach(node => {
|
2023-08-22 20:29:07 +03:00
|
|
|
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(
|
2023-09-09 20:36:55 +03:00
|
|
|
(node: GraphNode) => setHoverID(Number(node.id))
|
|
|
|
, []);
|
2023-09-04 20:37:55 +03:00
|
|
|
|
|
|
|
const handleHoverOut = useCallback(
|
2023-09-09 20:36:55 +03:00
|
|
|
() => setHoverID(undefined)
|
|
|
|
, []);
|
2023-09-04 20:37:55 +03:00
|
|
|
|
2023-07-29 03:31:21 +03:00
|
|
|
return (
|
|
|
|
<Modal
|
|
|
|
hideWindow={hideWindow}
|
2023-08-08 23:04:21 +03:00
|
|
|
readonly
|
2023-07-29 03:31:21 +03:00
|
|
|
>
|
2023-08-01 21:55:18 +03:00
|
|
|
<div className='flex flex-col items-start gap-2'>
|
2023-09-04 20:37:55 +03:00
|
|
|
<div className='w-full text-lg text-center'>
|
|
|
|
{!hoverNode && expression}
|
|
|
|
{hoverNode &&
|
|
|
|
<div className='flex justify-center whitespace-pre'>
|
|
|
|
<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>
|
|
|
|
}
|
|
|
|
</div>
|
2023-08-01 21:55:18 +03:00
|
|
|
<div className='flex-wrap w-full h-full overflow-auto'>
|
2023-09-05 23:18:21 +03:00
|
|
|
<div className='relative' style={{width: 'calc(100vw - 6rem - 2px)', height: 'calc(100vh - 14rem - 2px)'}}>
|
2023-08-01 21:55:18 +03:00
|
|
|
<GraphCanvas
|
|
|
|
nodes={nodes}
|
|
|
|
edges={edges}
|
|
|
|
layoutType='hierarchicalTd'
|
|
|
|
labelFontUrl={resources.graph_font}
|
2023-09-04 20:37:55 +03:00
|
|
|
theme={darkMode ? graphDarkT : graphLightT}
|
|
|
|
onNodePointerOver={handleHoverIn}
|
|
|
|
onNodePointerOut={handleHoverOut}
|
2023-08-01 21:55:18 +03:00
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
2023-07-29 03:31:21 +03:00
|
|
|
</div>
|
|
|
|
</Modal>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export default DlgShowAST;
|