diff --git a/docs/modules/ROOT/pages/operations/on-canvas-operations.adoc b/docs/modules/ROOT/pages/operations/on-canvas-operations.adoc
index dc4025b883d..babbbd913fb 100644
--- a/docs/modules/ROOT/pages/operations/on-canvas-operations.adoc
+++ b/docs/modules/ROOT/pages/operations/on-canvas-operations.adoc
@@ -32,4 +32,12 @@ image:modifying-node-label-example.png[width=600]
== Creating On-Canvas Relationships
Alt-clicking one node, release the alk key, and alt-clicking another node will create a relationship between the two
-
\ No newline at end of file
+
+== Editing the Relationshiop Type and Properties in Node Inspection Panel
+
+[NOTE]
+====
+Make sure APOC plugin is enabled in Neo4J database:
+
+image:enable-apoc.png[width=600]
+====
\ No newline at end of file
diff --git a/e2e_tests/integration/node-inspection-panel.spec.ts b/e2e_tests/integration/node-inspection-panel.spec.ts
deleted file mode 100644
index b8e4186f3b7..00000000000
--- a/e2e_tests/integration/node-inspection-panel.spec.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright Jiaqi Liu
- *
- * 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 .
- */
-
-/* global Cypress, cy, before */
-
-describe('Node Inspection Panel rendering', () => {
- before(function () {
- cy.visit(Cypress.config('url')).title().should('include', 'Neo4j Browser')
- cy.wait(3000)
- 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`, {
- parseSpecialCharSequences: false
- })
-
- cy.get(`[aria-label^="graph-node"]`)
- .trigger('mouseover', { force: true })
- .trigger('mouseenter', { force: true })
- .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')
- })
-})
diff --git a/e2e_tests/integration/node-inspectior-panel.spec.ts b/e2e_tests/integration/node-inspectior-panel.spec.ts
new file mode 100644
index 00000000000..39284ca5123
--- /dev/null
+++ b/e2e_tests/integration/node-inspectior-panel.spec.ts
@@ -0,0 +1,137 @@
+/*
+ * Copyright Jiaqi Liu
+ *
+ * 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 .
+ */
+
+/* global Cypress, cy, before */
+
+describe('Node Inspection Panel rendering', () => {
+ before(function () {
+ cy.visit(Cypress.config('url')).title().should('include', 'Neo4j Browser')
+ cy.wait(3000)
+ 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`, {
+ parseSpecialCharSequences: false
+ })
+
+ cy.get(`[aria-label^="graph-node"]`)
+ .trigger('mouseover', { force: true })
+ .trigger('mouseenter', { force: true })
+ .get('[data-testid="viz-details-pane-title"]')
+ .contains('My Node')
+ })
+
+ it('details pane title should be editable and pressing enter does not insert a line break at the end of new title', () => {
+ 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')
+ .should(title => {
+ expect(title.text()).to.equal('New Title')
+ })
+ })
+
+ it('can directly modify node label in node inspector panel and pressing enter does not insert a line break at the end of new label', () => {
+ cy.executeCommand(':clear')
+ cy.executeCommand(`CREATE (a:TestLabel {name: 'testNode'}) RETURN a`, {
+ parseSpecialCharSequences: false
+ })
+
+ cy.get(`[aria-label^="graph-node"]`)
+ .first()
+ .trigger('mouseover', { force: true })
+ .trigger('mouseenter', { force: true })
+ .trigger('click', { force: true })
+ .get('[data-testid="styleable-node-label"]', { timeout: 5000 })
+ .clear()
+ .type('New Label{enter}', { force: true })
+ .wait(1500)
+ .get('[data-testid="styleable-node-label"]', { timeout: 5000 })
+ .contains('New Label')
+ .should(label => {
+ expect(label.text()).to.equal('New Label')
+ })
+ })
+
+ it('can directly modify relationship type in node inspector panel', () => {
+ cy.executeCommand(':clear')
+ cy.executeCommand(
+ 'CREATE (a:TestLabel)-[:CONNECTS]->(b:TestLabel) RETURN a, b'
+ )
+ .wait(3000)
+ .get('.relationship', { timeout: 5000 })
+ .trigger('click', { force: true })
+ .get('[data-testid="styleable-rel-type"]', { timeout: 5000 })
+ .first()
+ .clear()
+ .type('New Link Label{enter}', { force: true })
+ .wait(1500)
+ .get('[data-testid="styleable-rel-type"]', { timeout: 5000 })
+ .contains('New Link Label')
+ })
+
+ it('can directly modify properties table value and pressing enter does not insert a line break at the end of new value', () => {
+ cy.executeCommand(':clear')
+ cy.executeCommand(`CREATE (a:TestLabel {name: 'testNode'}) RETURN a`, {
+ parseSpecialCharSequences: false
+ })
+ .wait(3000)
+ .get(`[aria-label^="graph-node"]`)
+ .first()
+ .trigger('mouseover', { force: true })
+ .trigger('mouseenter', { force: true })
+ .trigger('click', { force: true })
+ .get('[data-testid="properties-table-name-value-cell"]', {
+ timeout: 5000
+ })
+ .clear()
+ .type('New Name{enter}', { force: true })
+ .wait(1500)
+ .get('[data-testid="properties-table-name-value-cell"]', {
+ timeout: 5000
+ })
+ .contains('New Name')
+ .should(cellValue => {
+ expect(cellValue.text()).to.equal('New Name')
+ })
+ })
+})
diff --git a/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/StyleableNodeLabel.tsx b/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/StyleableNodeLabel.tsx
index 8b753785672..f066fc7d21a 100644
--- a/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/StyleableNodeLabel.tsx
+++ b/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/StyleableNodeLabel.tsx
@@ -57,6 +57,7 @@ export function StyleableNodeLabel({
return (
{
diff --git a/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/StyleableRelType.tsx b/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/StyleableRelType.tsx
index 1e936ff2ed3..b44fd7a45bc 100644
--- a/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/StyleableRelType.tsx
+++ b/src/browser/modules/Stream/CypherFrame/VisualizationView/PropertiesPanelContent/StyleableRelType.tsx
@@ -50,17 +50,26 @@ export function StyleableRelType({
})
return (
- onGraphInteraction(REL_TYPE_UPDATE, {
- relId: relId,
- sourceNodeId: sourceNodeId,
- targetNodeId: targetNodeId,
- oldType: selectedRelType.relType,
- newType: e.currentTarget.textContent
- })
- }
+ onKeyDown={(event: any) => {
+ if (event.key == 'Enter') {
+ event.preventDefault() // prevent new line char on Enter (https://stackoverflow.com/a/60008550)
+ }
+ }}
+ onKeyUp={(event: any) => {
+ if (event.keyCode === 13) {
+ event.preventDefault()
+ onGraphInteraction(REL_TYPE_UPDATE, {
+ relId: relId,
+ sourceNodeId: sourceNodeId,
+ targetNodeId: targetNodeId,
+ oldType: selectedRelType.relType,
+ newType: event.currentTarget.textContent
+ })
+ }
+ }}
>
{
diff --git a/src/neo4j-arc/common/components/PropertiesTable/PropertiesTable.tsx b/src/neo4j-arc/common/components/PropertiesTable/PropertiesTable.tsx
index 66b620723b2..9915dfa74d2 100644
--- a/src/neo4j-arc/common/components/PropertiesTable/PropertiesTable.tsx
+++ b/src/neo4j-arc/common/components/PropertiesTable/PropertiesTable.tsx
@@ -75,6 +75,7 @@ function ExpandableValue({
return (
{
diff --git a/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/DefaultDetailsPane.tsx b/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/DefaultDetailsPane.tsx
index 1f32ea56679..15f2e2df234 100644
--- a/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/DefaultDetailsPane.tsx
+++ b/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/DefaultDetailsPane.tsx
@@ -123,6 +123,7 @@ export function DefaultDetailsPane({
}}
graphStyle={graphStyle}
onGraphInteraction={onGraphInteraction}
+ relId={vizItem.item.id}
sourceNodeId={vizItem.item.source.id}
targetNodeId={vizItem.item.target.id}
/>
diff --git a/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/RelType.tsx b/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/RelType.tsx
index a62811e0523..e9576ca0c1d 100644
--- a/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/RelType.tsx
+++ b/src/neo4j-arc/graph-visualization/GraphVisualizer/DefaultPanelContent/RelType.tsx
@@ -30,6 +30,7 @@ export type RelTypeProps = {
graphStyle: GraphStyleModel
selectedRelType: { relType: string; propertyKeys: string[]; count?: number }
onGraphInteraction?: GraphInteractionCallBack
+ relId?: string
sourceNodeId?: string
targetNodeId?: string
}
@@ -40,6 +41,7 @@ export function RelType({
selectedRelType,
graphStyle,
onGraphInteraction = () => undefined,
+ relId,
sourceNodeId,
targetNodeId
}: RelTypeProps): JSX.Element {
@@ -59,6 +61,7 @@ export function RelType({
if (event.keyCode === 13) {
event.preventDefault()
onGraphInteraction(REL_TYPE_UPDATE, {
+ relId: relId,
sourceNodeId: sourceNodeId,
targetNodeId: targetNodeId,
oldType: selectedRelType.relType,
diff --git a/src/neo4j-arc/graph-visualization/GraphVisualizer/Graph/GraphEventHandlerModel.ts b/src/neo4j-arc/graph-visualization/GraphVisualizer/Graph/GraphEventHandlerModel.ts
index 9a87578e308..943f6327e3e 100644
--- a/src/neo4j-arc/graph-visualization/GraphVisualizer/Graph/GraphEventHandlerModel.ts
+++ b/src/neo4j-arc/graph-visualization/GraphVisualizer/Graph/GraphEventHandlerModel.ts
@@ -42,8 +42,8 @@ export type GraphInteraction =
| 'NODE_UNPINNED'
| 'NODE_DISMISSED'
| typeof NODE_ON_CANVAS_CREATE
- | typeof NODE_LABEL_UPDATE
| typeof REL_ON_CANVAS_CREATE
+ | typeof NODE_LABEL_UPDATE
| typeof REL_TYPE_UPDATE
| typeof PROP_UPDATE
| typeof DETAILS_PANE_TITLE_UPDATE
diff --git a/src/neo4j-arc/package.json b/src/neo4j-arc/package.json
index 91755065db5..55f261d3e53 100644
--- a/src/neo4j-arc/package.json
+++ b/src/neo4j-arc/package.json
@@ -1,6 +1,6 @@
{
"name": "neo4j-devtools-arc",
- "version": "0.0.79",
+ "version": "0.0.80",
"main": "dist/neo4j-arc.js",
"author": "Neo4j Inc.",
"license": "GPL-3.0",