From 1481441e73f788471cc19500810bea64c3ae4bfc Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 18 Oct 2023 21:56:18 +0800 Subject: [PATCH] content-editable can be persisted into database --- .../PropertiesPanelContent/DetailsPane.tsx | 4 +- .../VisualizationView/VisualizationView.tsx | 30 +++++++++- .../PropertiesTable/PropertiesTable.tsx | 58 +++++++++++++------ .../DefaultDetailsPane.tsx | 6 +- .../Graph/GraphEventHandlerModel.ts | 2 + .../GraphVisualizer/GraphVisualizer.tsx | 1 + .../GraphVisualizer/NodeInspectorPanel.tsx | 6 +- src/neo4j-arc/graph-visualization/index.ts | 5 +- 8 files changed, 88 insertions(+), 24 deletions(-) diff --git a/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/DetailsPane.tsx b/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/DetailsPane.tsx index d1ce432d8ea..1105f08978f 100644 --- a/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/DetailsPane.tsx +++ b/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/DetailsPane.tsx @@ -30,7 +30,8 @@ export const DETAILS_PANE_STEP_SIZE = 1000 export function DetailsPane({ vizItem, graphStyle, - nodeInspectorWidth + nodeInspectorWidth, + onGraphInteraction }: DetailsPaneProps): JSX.Element { const [maxPropertiesCount, setMaxPropertiesCount] = useState( DETAILS_PANE_STEP_SIZE @@ -93,6 +94,7 @@ export function DetailsPane({ moreStep={DETAILS_PANE_STEP_SIZE} totalNumItems={allItemProperties.length} nodeInspectorWidth={nodeInspectorWidth} + onGraphInteraction={onGraphInteraction} /> diff --git a/src/browser/modules/Stream/CypherFrame/VisualizationView/VisualizationView.tsx b/src/browser/modules/Stream/CypherFrame/VisualizationView/VisualizationView.tsx index e3381dadb3d..e1686feb4b9 100644 --- a/src/browser/modules/Stream/CypherFrame/VisualizationView/VisualizationView.tsx +++ b/src/browser/modules/Stream/CypherFrame/VisualizationView/VisualizationView.tsx @@ -28,7 +28,8 @@ import { GraphInteractionCallBack, GraphModel, GraphVisualizer, - NODE_ON_CANVAS_CREATE + NODE_ON_CANVAS_CREATE, + NODE_PROP_UPDATE } from 'neo4j-arc/graph-visualization' import { StyledVisContainer } from './VisualizationView.styled' @@ -277,6 +278,33 @@ LIMIT ${maxNewNeighbours}` } onGraphInteraction: GraphInteractionCallBack = (event, properties) => { + if (event == NODE_PROP_UPDATE) { + if (properties == null) { + throw new Error('') + } + + const nodeId = properties['nodeId'] + const propKey = properties['propKey'] + const propVal = properties['propVal'] + + const query = `MATCH (n) WHERE ID(n) = ${nodeId} SET n.${propKey} = "${propVal}"` + console.log(query) + + this.props.bus.self( + CYPHER_REQUEST, + { + query, + params: { nodeId, propKey, propVal }, + queryType: NEO4J_BROWSER_USER_ACTION_QUERY + }, + (response: any) => { + if (!response.success) { + throw new Error(response.error) + } + } + ) + } + if (event == NODE_ON_CANVAS_CREATE) { if (properties == null) { throw new Error( diff --git a/src/neo4j-arc/common/components/PropertiesTable/PropertiesTable.tsx b/src/neo4j-arc/common/components/PropertiesTable/PropertiesTable.tsx index c341ae52cec..51796c1dd5d 100644 --- a/src/neo4j-arc/common/components/PropertiesTable/PropertiesTable.tsx +++ b/src/neo4j-arc/common/components/PropertiesTable/PropertiesTable.tsx @@ -31,32 +31,31 @@ import { import { ClipboardCopier } from '../ClipboardCopier' import { ShowMoreOrAll } from '../ShowMoreOrAll/ShowMoreOrAll' import { VizItemProperty } from 'neo4j-arc/common' +import { + GraphInteractionCallBack, + NODE_PROP_UPDATE +} from '../../../graph-visualization' export const ELLIPSIS = '\u2026' export const WIDE_VIEW_THRESHOLD = 900 export const MAX_LENGTH_NARROW = 150 export const MAX_LENGTH_WIDE = 300 type ExpandableValueProps = { + nodeId: string + propKey: string value: string width: number type: string + onGraphInteraction: GraphInteractionCallBack } - -// https://stackoverflow.com/a/49639256 -const ContentEditable = ({ children }: any): JSX.Element => { - return ( -
- console.log('content editable clicked!!!' + e.currentTarget.textContent) - } - > - {children} -
- ) -} - -function ExpandableValue({ value, width, type }: ExpandableValueProps) { +function ExpandableValue({ + nodeId, + propKey, + value, + width, + type, + onGraphInteraction +}: ExpandableValueProps) { const [expanded, setExpanded] = useState(false) const maxLength = @@ -71,7 +70,16 @@ function ExpandableValue({ value, width, type }: ExpandableValueProps) { valueShown += valueIsTrimmed ? ELLIPSIS : '' return ( - +
+ onGraphInteraction(NODE_PROP_UPDATE, { + nodeId: nodeId, + propKey: propKey, + propVal: e.currentTarget.textContent + }) + } + > {type.startsWith('Array') && '['} {valueIsTrimmed && ( @@ -80,7 +88,7 @@ function ExpandableValue({ value, width, type }: ExpandableValueProps) { )} {type.startsWith('Array') && ']'} - +
) } @@ -90,14 +98,23 @@ type PropertiesViewProps = { totalNumItems: number moreStep: number nodeInspectorWidth: number + onGraphInteraction?: GraphInteractionCallBack } export const PropertiesTable = ({ visibleProperties, totalNumItems, onMoreClick, moreStep, - nodeInspectorWidth + nodeInspectorWidth, + onGraphInteraction }: PropertiesViewProps): JSX.Element => { + let id = '' + for (let i = 0; i < visibleProperties.length; i++) { + if (visibleProperties[i].key == '') { + id = visibleProperties[i].value + } + } + return ( <> @@ -110,9 +127,12 @@ export const PropertiesTable = ({ undefined)} /> diff --git a/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/DefaultDetailsPane.tsx b/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/DefaultDetailsPane.tsx index 0c8363018f5..a02a7c0cf86 100644 --- a/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/DefaultDetailsPane.tsx +++ b/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/DefaultDetailsPane.tsx @@ -26,17 +26,20 @@ import { PaneBody, PaneHeader, PaneTitle, PaneWrapper } from './styled' import { NodeLabel } from './NodeLabel' import { RelType } from './RelType' import { GraphStyleModel } from '../../models/GraphStyle' +import { GraphInteractionCallBack } from '../Graph/GraphEventHandlerModel' export const DETAILS_PANE_STEP_SIZE = 1000 export type DetailsPaneProps = { vizItem: NodeItem | RelationshipItem graphStyle: GraphStyleModel nodeInspectorWidth: number + onGraphInteraction?: GraphInteractionCallBack } export function DefaultDetailsPane({ vizItem, graphStyle, - nodeInspectorWidth + nodeInspectorWidth, + onGraphInteraction }: DetailsPaneProps): JSX.Element { const [maxPropertiesCount, setMaxPropertiesCount] = useState( DETAILS_PANE_STEP_SIZE @@ -99,6 +102,7 @@ export function DefaultDetailsPane({ moreStep={DETAILS_PANE_STEP_SIZE} totalNumItems={allItemProperties.length} nodeInspectorWidth={nodeInspectorWidth} + onGraphInteraction={onGraphInteraction} /> diff --git a/src/neo4j-arc/graph-visualization/GraphVisualizer/Graph/GraphEventHandlerModel.ts b/src/neo4j-arc/graph-visualization/GraphVisualizer/Graph/GraphEventHandlerModel.ts index aa15f6afc54..8113c4f02c5 100644 --- a/src/neo4j-arc/graph-visualization/GraphVisualizer/Graph/GraphEventHandlerModel.ts +++ b/src/neo4j-arc/graph-visualization/GraphVisualizer/Graph/GraphEventHandlerModel.ts @@ -31,6 +31,7 @@ import { import { Visualization } from './visualization/Visualization' export const NODE_ON_CANVAS_CREATE = 'NODE_ON_CANVAS_CREATE' +export const NODE_PROP_UPDATE = 'NODE_PROP_UPDATE' export type GraphInteraction = | 'NODE_EXPAND' @@ -38,6 +39,7 @@ export type GraphInteraction = | 'NODE_DISMISSED' | 'NODE_ON_CANVAS_CREATE' | typeof NODE_ON_CANVAS_CREATE + | typeof NODE_PROP_UPDATE export type GraphInteractionCallBack = ( event: GraphInteraction, diff --git a/src/neo4j-arc/graph-visualization/GraphVisualizer/GraphVisualizer.tsx b/src/neo4j-arc/graph-visualization/GraphVisualizer/GraphVisualizer.tsx index b67b1360344..87bc6c09ad6 100644 --- a/src/neo4j-arc/graph-visualization/GraphVisualizer/GraphVisualizer.tsx +++ b/src/neo4j-arc/graph-visualization/GraphVisualizer/GraphVisualizer.tsx @@ -297,6 +297,7 @@ export class GraphVisualizer extends Component< }} DetailsPaneOverride={this.props.DetailsPaneOverride} OverviewPaneOverride={this.props.OverviewPaneOverride} + onGraphInteraction={this.props.onGraphInteraction} /> ) diff --git a/src/neo4j-arc/graph-visualization/GraphVisualizer/NodeInspectorPanel.tsx b/src/neo4j-arc/graph-visualization/GraphVisualizer/NodeInspectorPanel.tsx index 734d813b09e..12d9572c1e7 100644 --- a/src/neo4j-arc/graph-visualization/GraphVisualizer/NodeInspectorPanel.tsx +++ b/src/neo4j-arc/graph-visualization/GraphVisualizer/NodeInspectorPanel.tsx @@ -38,6 +38,7 @@ import { Resizable } from 're-resizable' import { GraphStats } from '../utils/mapper' import { GraphStyleModel } from '../models/GraphStyle' import { VizItem } from '../types' +import { GraphInteractionCallBack } from './Graph/GraphEventHandlerModel' interface NodeInspectorPanelProps { expanded: boolean @@ -51,6 +52,7 @@ interface NodeInspectorPanelProps { width: number DetailsPaneOverride?: React.FC OverviewPaneOverride?: React.FC + onGraphInteraction?: GraphInteractionCallBack } export const defaultPanelWidth = (): number => @@ -68,7 +70,8 @@ export class NodeInspectorPanel extends Component { toggleExpanded, width, DetailsPaneOverride, - OverviewPaneOverride + OverviewPaneOverride, + onGraphInteraction } = this.props const relevantItems = ['node', 'relationship'] const hoveringNodeOrRelationship = @@ -120,6 +123,7 @@ export class NodeInspectorPanel extends Component { vizItem={shownEl} graphStyle={graphStyle} nodeInspectorWidth={width} + onGraphInteraction={onGraphInteraction} /> ) : (