Skip to content

Commit

Permalink
Make details pane title editable (#44)
Browse files Browse the repository at this point in the history
* Make details pane title editable

* Add E2E test

* Version bump

* Self-review

* Self-review
  • Loading branch information
QubitPi authored Dec 4, 2023
1 parent 4529991 commit a69a622
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 8 deletions.
28 changes: 28 additions & 0 deletions e2e_tests/integration/node-inspection-panel.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ describe('Node Inspection Panel rendering', () => {
cy.ensureConnection()
})

afterEach(() => {
cy.executeCommand('MATCH (n) DETACH DELETE n')
})

it('should display node/rel caption as panel title', () => {
cy.executeCommand(':clear')
cy.executeCommand(`CREATE (s:SourceNode {name: 'My Node'}) RETURN s`, {
Expand All @@ -38,4 +42,28 @@ describe('Node Inspection Panel rendering', () => {
.get('[data-testid="viz-details-pane-title"]')
.contains('My Node')
})

it('details pane title should be editable', () => {
cy.executeCommand(':clear')
cy.executeCommand(`CREATE (s:SourceNode {name: 'My Node'}) RETURN s`, {
parseSpecialCharSequences: false
})

cy.get(`[aria-label^="graph-node"]`)
.trigger('mouseover', { force: true })
.trigger('mouseenter', { force: true })
.get('[data-testid="viz-details-pane-title"]')
.find('[contenteditable]')
.clear()
.type('New Title{enter}', { force: true })

cy.wait(1500)

cy.get(`[aria-label^="graph-node"]`)
.first()
.trigger('mouseover', { force: true })
.trigger('mouseenter', { force: true })
.get('[data-testid="viz-details-pane-title"]')
.contains('New Title')
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ 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'

export const DETAILS_PANE_STEP_SIZE = 1000
export function DetailsPane({
vizItem,
graphStyle,
nodeInspectorWidth,
onGraphInteraction
onGraphInteraction = () => undefined
}: DetailsPaneProps): JSX.Element {
const [maxPropertiesCount, setMaxPropertiesCount] = useState(
DETAILS_PANE_STEP_SIZE
Expand Down Expand Up @@ -62,6 +64,7 @@ export function DetailsPane({
const item = vizItem.item
const captionPropertyKey = graphStyle
.pickupCaptionPropertyKey(item)
// strip off sorounding "{}" because pickupCaptionPropertyKey(item) returns something like "{title}"
.replace(/[{}]/g, '')
for (let i = 0; i < item.propertyList.length; i++) {
if (item.propertyList[i].key == captionPropertyKey) {
Expand All @@ -73,7 +76,23 @@ export function DetailsPane({
<PaneWrapper>
<PaneHeader>
<PaneTitle data-testid="viz-details-pane-title">
<span>{`${paneTitle}`}</span>
<div
suppressContentEditableWarning={true}
contentEditable="true"
onKeyUp={(event: any) => {
if (event.keyCode === 13) {
event.preventDefault()
onGraphInteraction(DETAILS_PANE_TITLE_UPDATE, {
isNode: vizItem.type === 'node',
nodeOrRelId: vizItem.item.id,
titlePropertyKey: captionPropertyKey,
newTitle: event.currentTarget.textContent
})
}
}}
>
<span>{`${paneTitle}`}</span>
</div>
<ClipboardCopier
textToCopy={allItemProperties
.map(prop => `${prop.key}: ${prop.value}`)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ import {
NODE_ON_CANVAS_CREATE,
NODE_PROP_UPDATE,
NODE_LABEL_UPDATE,
REL_TYPE_UPDATE
REL_TYPE_UPDATE,
DETAILS_PANE_TITLE_UPDATE
} from 'neo4j-arc/graph-visualization'

import { StyledVisContainer } from './VisualizationView.styled'
Expand Down Expand Up @@ -437,6 +438,40 @@ LIMIT ${maxNewNeighbours}`
const action = executeCommand(cmd, { source: commandSources.rerunFrame })
this.props.bus.send(action.type, action)
}

if (event == DETAILS_PANE_TITLE_UPDATE) {
if (properties == null) {
throw new Error('DETAILS_PANE_TITLE_UPDATE: properties map is required')
}

const nodeOrRelId = properties['nodeOrRelId']
const titlePropertyKey = properties['titlePropertyKey']
const newTitle = properties['newTitle']

const isNode = properties['isNode']
const query =
isNode == 'true'
? `MATCH (n) WHERE ID(n) = ${nodeOrRelId} SET n.${titlePropertyKey} = '${newTitle}'`
: `MATCH ()-[r]-() WHERE ID(r) = ${nodeOrRelId} SET r.${titlePropertyKey} = '${newTitle}'`

this.props.bus.self(
CYPHER_REQUEST,
{
query,
params: { nodeOrRelId, titlePropertyKey, newTitle },
queryType: NEO4J_BROWSER_USER_ACTION_QUERY
},
(response: any) => {
if (!response.success) {
throw new Error(response.error)
}
}
)

const cmd = 'MATCH (n) RETURN n;'
const action = executeCommand(cmd, { source: commandSources.rerunFrame })
this.props.bus.send(action.type, action)
}
}

render(): React.ReactNode {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ 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'
import {
DETAILS_PANE_TITLE_UPDATE,
GraphInteractionCallBack
} from '../Graph/GraphEventHandlerModel'

export const DETAILS_PANE_STEP_SIZE = 1000
export type DetailsPaneProps = {
Expand All @@ -39,7 +42,7 @@ export function DefaultDetailsPane({
vizItem,
graphStyle,
nodeInspectorWidth,
onGraphInteraction
onGraphInteraction = () => undefined
}: DetailsPaneProps): JSX.Element {
const [maxPropertiesCount, setMaxPropertiesCount] = useState(
DETAILS_PANE_STEP_SIZE
Expand Down Expand Up @@ -70,6 +73,7 @@ export function DefaultDetailsPane({
const item = vizItem.item
const captionPropertyKey = graphStyle
.pickupCaptionPropertyKey(item)
// strip off sorounding "{}" because pickupCaptionPropertyKey(item) returns something like "{title}"
.replace(/[{}]/g, '')
for (let i = 0; i < item.propertyList.length; i++) {
if (item.propertyList[i].key == captionPropertyKey) {
Expand All @@ -81,7 +85,23 @@ export function DefaultDetailsPane({
<PaneWrapper>
<PaneHeader>
<PaneTitle data-testid="viz-details-pane-title">
<span>{`${paneTitle}`}</span>
<div
suppressContentEditableWarning={true}
contentEditable="true"
onKeyUp={(event: any) => {
if (event.keyCode === 13) {
event.preventDefault()
onGraphInteraction(DETAILS_PANE_TITLE_UPDATE, {
isNode: vizItem.type === 'node',
nodeOrRelId: vizItem.item.id,
titlePropertyKey: captionPropertyKey,
newTitle: event.currentTarget.textContent
})
}
}}
>
<span>{`${paneTitle}`}</span>
</div>
<ClipboardCopier
textToCopy={allItemProperties
.map(prop => `${prop.key}: ${prop.value}`)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const NODE_PROP_UPDATE = 'NODE_PROP_UPDATE'
export const NODE_LABEL_UPDATE = 'NODE_LABEL_UPDATE'
export const REL_ON_CANVAS_CREATE = 'REL_ON_CANVAS_CREATE'
export const REL_TYPE_UPDATE = 'REL_TYPE_UPDATE'
export const DETAILS_PANE_TITLE_UPDATE = 'DETAILS_PANE_TITLE_UPDATE'

export type GraphInteraction =
| 'NODE_EXPAND'
Expand All @@ -45,6 +46,7 @@ export type GraphInteraction =
| typeof NODE_LABEL_UPDATE
| typeof REL_ON_CANVAS_CREATE
| typeof REL_TYPE_UPDATE
| typeof DETAILS_PANE_TITLE_UPDATE

export type GraphInteractionCallBack = (
event: GraphInteraction,
Expand Down
3 changes: 2 additions & 1 deletion src/neo4j-arc/graph-visualization/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ export {
NODE_ON_CANVAS_CREATE,
NODE_PROP_UPDATE,
NODE_LABEL_UPDATE,
REL_TYPE_UPDATE
REL_TYPE_UPDATE,
DETAILS_PANE_TITLE_UPDATE
} from './GraphVisualizer/Graph/GraphEventHandlerModel'
export type { GraphInteractionCallBack } from './GraphVisualizer/Graph/GraphEventHandlerModel'

Expand Down
2 changes: 1 addition & 1 deletion src/neo4j-arc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "neo4j-devtools-arc",
"version": "0.0.73",
"version": "0.0.74",
"main": "dist/neo4j-arc.js",
"author": "Neo4j Inc.",
"license": "GPL-3.0",
Expand Down

0 comments on commit a69a622

Please sign in to comment.