From 85bdf36c9b6fa80c033dc3fc91277ac810620a96 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 19 Dec 2023 18:43:40 +0800 Subject: [PATCH] Integrate Lexical editor into Details Pane --- package.json | 2 + .../PropertiesPanelContent/DetailsPane.tsx | 6 +- .../DefaultDetailsPane.tsx | 2 + .../Editor/DefaultEditor.tsx | 157 +++++++++++++++++ .../DefaultPanelContent/Editor/styled.tsx | 24 +++ src/neo4j-arc/graph-visualization/index.ts | 4 + yarn.lock | 162 +++++++++++++++++- 7 files changed, 355 insertions(+), 2 deletions(-) create mode 100644 src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/Editor/DefaultEditor.tsx create mode 100644 src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/Editor/styled.tsx diff --git a/package.json b/package.json index 7d462234eb2..990b57874fb 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "@babel/preset-env": "^7.1.0", "@babel/preset-react": "^7.0.0", "@hot-loader/react-dom": "^17.0.2", + "@lexical/react": "^0.12.5", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", "@testing-library/jest-dom": "^5.15.0", "@testing-library/react": "^12.1.2", @@ -137,6 +138,7 @@ "jest-canvas-mock": "^1.1.0", "js2xmlparser": "^3.0.0", "json-loader": "^0.5.7", + "lexical": "^0.12.5", "lint-staged": "^4.1.3", "mini-css-extract-plugin": "^0.4.4", "mockdate": "^2.0.5", diff --git a/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/DetailsPane.tsx b/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/DetailsPane.tsx index 58c366f53e1..86b1cf748d8 100644 --- a/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/DetailsPane.tsx +++ b/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/DetailsPane.tsx @@ -26,7 +26,10 @@ import { StyleableRelType } from './StyleableRelType' import { PaneBody, PaneHeader, PaneTitle, PaneWrapper } from './styled' import { DetailsPaneProps } from 'neo4j-arc' -import { DETAILS_PANE_TITLE_UPDATE } from 'neo4j-arc/graph-visualization' +import { + DETAILS_PANE_TITLE_UPDATE, + Editor +} from 'neo4j-arc/graph-visualization' export const DETAILS_PANE_STEP_SIZE = 1000 export function DetailsPane({ @@ -147,6 +150,7 @@ export function DetailsPane({ nodeInspectorWidth={nodeInspectorWidth} onGraphInteraction={onGraphInteraction} /> + {vizItem.type === 'node' && } )} diff --git a/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/DefaultDetailsPane.tsx b/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/DefaultDetailsPane.tsx index 8e90e9db650..ad498cc90ec 100644 --- a/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/DefaultDetailsPane.tsx +++ b/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/DefaultDetailsPane.tsx @@ -30,6 +30,7 @@ import { DETAILS_PANE_TITLE_UPDATE, GraphInteractionCallBack } from '../Graph/GraphEventHandlerModel' +import DefaultEditor from './Editor/DefaultEditor' export const DETAILS_PANE_STEP_SIZE = 1000 export type DetailsPaneProps = { @@ -157,6 +158,7 @@ export function DefaultDetailsPane({ /> )} + {vizItem.type === 'node' && } ) } diff --git a/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/Editor/DefaultEditor.tsx b/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/Editor/DefaultEditor.tsx new file mode 100644 index 00000000000..9000aab8723 --- /dev/null +++ b/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/Editor/DefaultEditor.tsx @@ -0,0 +1,157 @@ +/* + * Copyright Jiaqi Liu + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +import React, { useState } from 'react' + +import { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin' +import { LexicalComposer } from '@lexical/react/LexicalComposer' +import { ContentEditable } from '@lexical/react/LexicalContentEditable' +import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary' +import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin' +import { HeadingNode, QuoteNode } from '@lexical/rich-text' +import { TableCellNode, TableNode, TableRowNode } from '@lexical/table' +import { ListItemNode, ListNode } from '@lexical/list' +import { CodeHighlightNode, CodeNode } from '@lexical/code' +import { AutoLinkNode, LinkNode } from '@lexical/link' +import { StyledDefaultEditor } from './styled' + +export default function DefaultEditor(): JSX.Element { + const initialConfig = { + namespace: 'DefaultDetailsPaneEditor', + onError: (error: Error) => { + throw error + }, + nodes: [ + HeadingNode, + ListNode, + ListItemNode, + QuoteNode, + CodeNode, + CodeHighlightNode, + TableNode, + TableCellNode, + TableRowNode, + AutoLinkNode, + LinkNode + ], + theme: { + ltr: 'ltr', + rtl: 'rtl', + placeholder: 'editor-placeholder', + paragraph: 'editor-paragraph', + quote: 'editor-quote', + heading: { + h1: 'editor-heading-h1', + h2: 'editor-heading-h2', + h3: 'editor-heading-h3', + h4: 'editor-heading-h4', + h5: 'editor-heading-h5' + }, + list: { + nested: { + listitem: 'editor-nested-listitem' + }, + ol: 'editor-list-ol', + ul: 'editor-list-ul', + listitem: 'editor-listitem' + }, + image: 'editor-image', + link: 'editor-link', + text: { + bold: 'editor-text-bold', + italic: 'editor-text-italic', + overflowed: 'editor-text-overflowed', + hashtag: 'editor-text-hashtag', + underline: 'editor-text-underline', + strikethrough: 'editor-text-strikethrough', + underlineStrikethrough: 'editor-text-underlineStrikethrough', + code: 'editor-text-code' + }, + code: 'editor-code', + codeHighlight: { + atrule: 'editor-tokenAttr', + attr: 'editor-tokenAttr', + boolean: 'editor-tokenProperty', + builtin: 'editor-tokenSelector', + cdata: 'editor-tokenComment', + char: 'editor-tokenSelector', + class: 'editor-tokenFunction', + 'class-name': 'editor-tokenFunction', + comment: 'editor-tokenComment', + constant: 'editor-tokenProperty', + deleted: 'editor-tokenProperty', + doctype: 'editor-tokenComment', + entity: 'editor-tokenOperator', + function: 'editor-tokenFunction', + important: 'editor-tokenVariable', + inserted: 'editor-tokenSelector', + keyword: 'editor-tokenAttr', + namespace: 'editor-tokenVariable', + number: 'editor-tokenProperty', + operator: 'editor-tokenOperator', + prolog: 'editor-tokenComment', + property: 'editor-tokenProperty', + punctuation: 'editor-tokenPunctuation', + regex: 'editor-tokenVariable', + selector: 'editor-tokenSelector', + string: 'editor-tokenSelector', + symbol: 'editor-tokenProperty', + tag: 'editor-tokenProperty', + url: 'editor-tokenOperator', + variable: 'editor-tokenVariable' + } + } + } + + const [floatingAnchorElem, setFloatingAnchorElem] = + useState(null) + + const onRef = (_floatingAnchorElem: HTMLDivElement) => { + if (_floatingAnchorElem !== null) { + setFloatingAnchorElem(_floatingAnchorElem) + } + } + + return ( + + +
+
+ + } + contentEditable={ +
+
+ +
+
+ } + ErrorBoundary={LexicalErrorBoundary} + /> +
+
+
+
+ ) +} + +function Placeholder() { + return
Enter some plain text...
+} diff --git a/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/Editor/styled.tsx b/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/Editor/styled.tsx new file mode 100644 index 00000000000..5aa14935caa --- /dev/null +++ b/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/Editor/styled.tsx @@ -0,0 +1,24 @@ +/* + * Copyright Jiaqi Liu + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +import styled from 'styled-components' + +export const StyledDefaultEditor = styled.div` + height: 100px; +` diff --git a/src/neo4j-arc/graph-visualization/index.ts b/src/neo4j-arc/graph-visualization/index.ts index aaebacb2479..72ec8dd9fd5 100644 --- a/src/neo4j-arc/graph-visualization/index.ts +++ b/src/neo4j-arc/graph-visualization/index.ts @@ -18,6 +18,8 @@ * along with this program. If not, see . */ +import DefaultEditor from './GraphVisualizer/DefaultPanelContent/Editor/DefaultEditor' + export { NodeModel } from './models/Node' export { GraphModel } from './models/Graph' export { GraphStyleModel, Selector } from './models/GraphStyle' @@ -62,3 +64,5 @@ export const resources = { } } } + +export { default as Editor } from './GraphVisualizer/DefaultPanelContent/Editor/DefaultEditor' diff --git a/yarn.lock b/yarn.lock index 3b39dbce2da..1ea78d81d57 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1723,6 +1723,161 @@ resolved "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.3.1.tgz" integrity sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw== +"@lexical/clipboard@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/clipboard/-/clipboard-0.12.5.tgz#8b6f3711a958b0d32483b5ef07abe7b59f0d2348" + integrity sha512-A0k0g5mCHDgROLF33TwiKdjMWEfajyPcIF64lsHapZ19ZTi1iabGkXvpHnyHaMq79py1Se/e6tOcmFe9nOJkrQ== + dependencies: + "@lexical/html" "0.12.5" + "@lexical/list" "0.12.5" + "@lexical/selection" "0.12.5" + "@lexical/utils" "0.12.5" + +"@lexical/code@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/code/-/code-0.12.5.tgz#cd7ff744782ea526a82019d9005f1ef465dbac6d" + integrity sha512-YV879sO2C0efWXgj4ZUzpowPWxbid8T5I0vysQIzuWPiaQG0fjilz1maYV+X95hD2VXW8yhyOnEdScfeKk62Zg== + dependencies: + "@lexical/utils" "0.12.5" + prismjs "^1.27.0" + +"@lexical/dragon@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/dragon/-/dragon-0.12.5.tgz#22099c2ba5e1c67b43418018427e3b38e90f99eb" + integrity sha512-RFU6wIIUS0/ab5JtLp2rKaUi7nltDT96+GdmvNVHpAfa7TZuepYsoi7PtZB9aF/Outye4U7dQU2tNwesDBf8kg== + +"@lexical/hashtag@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/hashtag/-/hashtag-0.12.5.tgz#1a8006213a93d28dcf52d41fc8699e11a21a11df" + integrity sha512-nlPFScTiuZgUtuBSnRkHK9AuRDV35zZug4JLG1Hkky+Fh1PJ+0MK+/K8mhoatp13zm7GqN2fMOrrUGufqEingw== + dependencies: + "@lexical/utils" "0.12.5" + +"@lexical/history@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/history/-/history-0.12.5.tgz#4258f613959e90415b8e481eb56a710b0823aead" + integrity sha512-nF5TurEE4qRbuNP/i5pDtVfWHQXb4ONof+MvKmHNfLRJbxSj7Ee33MVG9x851PjAzXoXuGJvw6FMBCasGXQx7A== + dependencies: + "@lexical/utils" "0.12.5" + +"@lexical/html@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/html/-/html-0.12.5.tgz#86d31d76abde29497801ba949938734cca0e2cd8" + integrity sha512-OzsWKVcr9wUGvAbgyUdG+32/cI2RclI4I4JmIyfLbiYMBYdafu+j160cjohNWu9gQFjVFszIjG4CBxfwRM+Sag== + dependencies: + "@lexical/selection" "0.12.5" + "@lexical/utils" "0.12.5" + +"@lexical/link@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/link/-/link-0.12.5.tgz#054b2ac9267466753998698bfebe636b61d50581" + integrity sha512-h7p5G+XXKqNrb4lk55mJL23Us5pz2szbzZevccADJ9Om6o3i4aNyjv1MeC29WXjmgS0YKHDlYcnKEgyAPKvVMw== + dependencies: + "@lexical/utils" "0.12.5" + +"@lexical/list@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/list/-/list-0.12.5.tgz#4098d55cbcaf33bcb2dc3a385184d68d5a5e6ea3" + integrity sha512-KNJ262krlpcDZ2U1LC8xp86uw2nqt88iEQgpF+khv3SAqqLbhT8tMpyZ6+eWbW3mHPhQIxFutJGazMAqMW3uUA== + dependencies: + "@lexical/utils" "0.12.5" + +"@lexical/mark@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/mark/-/mark-0.12.5.tgz#eb3311da2f697235da5d193c6476fb0afc8272b3" + integrity sha512-61ctAYrxTGl4uMDTnE5fRH4yrs8sqnRyivuNWyOmQR6W/G3s0gHwkUZC7akOSnPLYhfnXRl3C4haY8pH93sWQg== + dependencies: + "@lexical/utils" "0.12.5" + +"@lexical/markdown@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/markdown/-/markdown-0.12.5.tgz#4548b46b9903de04d7d4f3ab0dcbc3d29da04395" + integrity sha512-F3cBcuhoGWxxCqERUXF4fYfJhceK7gFYQPRsXir5mYriSNZIQIMhJoeAt8Pjer0UjFyQvNfQ+AzzXHu5xYNLLA== + dependencies: + "@lexical/code" "0.12.5" + "@lexical/link" "0.12.5" + "@lexical/list" "0.12.5" + "@lexical/rich-text" "0.12.5" + "@lexical/text" "0.12.5" + "@lexical/utils" "0.12.5" + +"@lexical/offset@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/offset/-/offset-0.12.5.tgz#420afc5a8f09c0cfc91ac51c25439777c1ea8580" + integrity sha512-K+Mt4tOmwKarsJ1esdqNgN9Ep/JaeFa9ZQ7DKx8KIOkXL35nPb9NXuBvYyJjh1crP/iwsuP15kymgDjxj9ciMw== + +"@lexical/overflow@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/overflow/-/overflow-0.12.5.tgz#ba7b284f6cad8735e86069b1606c99f35bdb87d4" + integrity sha512-boP1oTgBbNmbo8+1tgpDAs1P/lbTk4oWZ6x88E9VNVBJSkG2ZrmQKQoJzKzHwpjXbm+Cechf77JxfgTOabzYxw== + +"@lexical/plain-text@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/plain-text/-/plain-text-0.12.5.tgz#5e5fffb735715f5c1bd71c5a754cfb1249fac75e" + integrity sha512-n24aQvTIy4AN+LaoQce6BIuSY4pUshiTp4OpiRh48o5c9NU0DmzEa0l9fBS1GfvjZL9bN5luiINFYn/bMB49nA== + +"@lexical/react@^0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/react/-/react-0.12.5.tgz#76167b655ae9de46662e51eb5a674e789b483d79" + integrity sha512-pAbJQksin223Yp1p1VsPKxkRtSppVij+HcLTzP89q2QuSA0z0p/T+f5jZjs8eV6tecMtmrjizhdLTbk0jkej1w== + dependencies: + "@lexical/clipboard" "0.12.5" + "@lexical/code" "0.12.5" + "@lexical/dragon" "0.12.5" + "@lexical/hashtag" "0.12.5" + "@lexical/history" "0.12.5" + "@lexical/link" "0.12.5" + "@lexical/list" "0.12.5" + "@lexical/mark" "0.12.5" + "@lexical/markdown" "0.12.5" + "@lexical/overflow" "0.12.5" + "@lexical/plain-text" "0.12.5" + "@lexical/rich-text" "0.12.5" + "@lexical/selection" "0.12.5" + "@lexical/table" "0.12.5" + "@lexical/text" "0.12.5" + "@lexical/utils" "0.12.5" + "@lexical/yjs" "0.12.5" + react-error-boundary "^3.1.4" + +"@lexical/rich-text@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/rich-text/-/rich-text-0.12.5.tgz#63c140bc1f3940e2f6f493110a221df7afee8163" + integrity sha512-33R8ODRI5kKGbF70A/FWdISbbSPk+q4hKtiEJaV67zYPBuzrz0YHcni+tgKiykS05LgCksI/e43sfEkiykjrVQ== + +"@lexical/selection@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/selection/-/selection-0.12.5.tgz#b5e8f83558b0fc3ac24acfbc4db64bb1ed6499f7" + integrity sha512-oWJ87T4j6plf2yQzElOeudUyv7kdwTkuhzTZbcCTBNH/cSMdp55/Kv2doBynxhfHYEceuBKE7f8rci//T9DUPQ== + +"@lexical/table@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/table/-/table-0.12.5.tgz#f08911b9b0e8129247362e8af702263012d49f40" + integrity sha512-vgSTsjvGw+TrYYBmf3FR0kYJ+j1oOlBmrO1sqvuIrGPXKWmvYL+RbKIkm2xhtApVHVYgqfFvxNiZrPL5Wf9dXg== + dependencies: + "@lexical/utils" "0.12.5" + +"@lexical/text@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/text/-/text-0.12.5.tgz#efccd16d373baae589feba0770d50ced012e7814" + integrity sha512-PU1ntXQCqon3HTjrEPl/HdKB/boyW36vKgiPvojoaAhBhkEnuiN+Pq9hrexORBcZPyLFp6wYoWXjKSO4fJVYeA== + +"@lexical/utils@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/utils/-/utils-0.12.5.tgz#ec0dd7ab473012ab33ba75f85e3f1862fe858641" + integrity sha512-wPVyvi1Cvtf7aHwVKlG/9RlgHxSUzpGvXm87t889Rg7uZfOteyvXHJStjpSCZ3pvZ60y5ETin4OoetaVZciPfw== + dependencies: + "@lexical/list" "0.12.5" + "@lexical/selection" "0.12.5" + "@lexical/table" "0.12.5" + +"@lexical/yjs@0.12.5": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@lexical/yjs/-/yjs-0.12.5.tgz#bcecad3a7c8e7e36eab2312083af5dbb3d0082e7" + integrity sha512-GNiRND/8ePdTWuSDFloPo/1355V0ce6OtH/25qxCq5D9MLNiIkAcwqQfnWFUdOtVMuNJOVc4OfCE9ARCGuEjyQ== + dependencies: + "@lexical/offset" "0.12.5" + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz" @@ -8769,6 +8924,11 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lexical@^0.12.5: + version "0.12.5" + resolved "https://registry.yarnpkg.com/lexical/-/lexical-0.12.5.tgz#e8de986032721a7482a073a6d6e2d66e69a3d170" + integrity sha512-ZMqisIxNe+JBqaUa1Qmz7ghpvnmARHxgYz+F0rcXRtSPZtgEL8OT2c9xk8CJ4ccVpf+qRQlONzCEIZfQQHd/RA== + lie@3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz" @@ -11744,7 +11904,7 @@ react-dropzone@^14.0.0: file-selector "^0.6.0" prop-types "^15.8.1" -react-error-boundary@^3.1.0: +react-error-boundary@^3.1.0, react-error-boundary@^3.1.4: version "3.1.4" resolved "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz" integrity "sha1-JV25KyMZcQh1eoiLAeW3KZGaveA= sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA=="