Skip to content

Commit

Permalink
Merge pull request #886 from neo4j-labs/develop
Browse files Browse the repository at this point in the history
Release notes for release 2.4.7
  • Loading branch information
mariusconjeaud authored May 7, 2024
2 parents 2fc0983 + ce7a21d commit c504094
Show file tree
Hide file tree
Showing 20 changed files with 625 additions and 376 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/master-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:
context: .
file: ./Dockerfile
push: true
tags: ${{ secrets.DOCKER_HUB_LABS_USERNAME }}/neodash:latest,${{ secrets.DOCKER_HUB_LABS_USERNAME }}/neodash:2.4.6
tags: ${{ secrets.DOCKER_HUB_LABS_USERNAME }}/neodash:latest,${{ secrets.DOCKER_HUB_LABS_USERNAME }}/neodash:2.4.7
build-docker-legacy:
needs: build-test
runs-on: neodash-runners
Expand All @@ -103,7 +103,7 @@ jobs:
context: .
file: ./Dockerfile
push: true
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/neodash:latest,${{ secrets.DOCKER_HUB_USERNAME }}/neodash:2.4.6
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/neodash:latest,${{ secrets.DOCKER_HUB_USERNAME }}/neodash:2.4.7
deploy-gallery:
runs-on: neodash-runners
strategy:
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ USER nginx
EXPOSE $NGINX_PORT

HEALTHCHECK cmd curl --fail "http://localhost:$NGINX_PORT" || exit 1
LABEL version="2.4.6"
LABEL version="2.4.7"
12 changes: 12 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## NeoDash 2.4.7
This is a minor release containing a few critical fixes and general code quality improvements:

- Fix multiple parameter select ([881](https://github.com/neo4j-labs/neodash/pull/881)).
- Fix parameter casting error when loading dashboards([874](https://github.com/neo4j-labs/neodash/pull/874)).
- Fix the fraud demo in the [Example Gallery](https://neodash-gallery.graphapp.io/).

Thanks to all the contributors for this release:
- [alfredorubin96](https://github.com/alfredorubin96),
- [MariusC](https://github.com/mariusconjeaud),
- [elizarp](https://github.com/elizarp).

## NeoDash 2.4.6
This is a minor release containing a few critical fixes and some extra style customizations:

Expand Down
154 changes: 154 additions & 0 deletions cypress/e2e/render/array.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { stringArrayCypherQuery, intArrayCypherQuery, pathArrayCypherQuery } from '../../fixtures/cypher_queries';
import {
enableReportActions,
createReportOfType,
closeSettings,
toggleTableTranspose,
openReportActionsMenu,
selectReportOfType,
openAdvancedSettings,
updateDropdownAdvancedSetting,
} from '../utils';

const WAITING_TIME = 20000;
const CARD_SELECTOR = 'main .react-grid-item:eq(2)';
// Ignore warnings that may appear when using the Cypress dev server
Cypress.on('uncaught:exception', (err, runnable) => {
console.log(err, runnable);
return false;
});

describe('Testing array rendering', () => {
beforeEach('open neodash', () => {
cy.viewport(1920, 1080);
cy.visit('/', {
onBeforeLoad(win) {
win.localStorage.clear();
},
});

cy.get('#form-dialog-title', { WAITING_TIME: WAITING_TIME })
.should('contain', 'NeoDash - Neo4j Dashboard Builder')
.click();

cy.get('#form-dialog-title').then(($div) => {
const text = $div.text();
if (text == 'NeoDash - Neo4j Dashboard Builder') {
cy.wait(500);
// Create new dashboard
cy.contains('New Dashboard').click();
}
});

cy.get('#form-dialog-title', { WAITING_TIME: WAITING_TIME }).should('contain', 'Connect to Neo4j');

cy.get('#url').clear().type('localhost');
cy.get('#dbusername').clear().type('neo4j');
cy.get('#dbpassword').type('test1234');
cy.get('button').contains('Connect').click();
cy.wait(100);
});

it('creates a table that contains string arrays', () => {
cy.checkInitialState();
enableReportActions();
createReportOfType('Table', stringArrayCypherQuery, true, true);

// Standard array, displays strings joined with comma and whitespace
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(0)`).should('have.text', 'initial, list');
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(1)`).should('have.text', 'other, list');

// Now, transpose the table
toggleTableTranspose(CARD_SELECTOR, true);
cy.get(`${CARD_SELECTOR} .MuiDataGrid-columnHeaderTitle:eq(1)`, { timeout: WAITING_TIME }).should(
'have.text',
'initial,list'
);
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(1)`).should('have.text', 'other, list');

// Transpose back
// And add a report action
toggleTableTranspose(CARD_SELECTOR, false);
openReportActionsMenu(CARD_SELECTOR);
cy.get('.ndl-modal').find('button[aria-label="add"]').click();
cy.get('.ndl-modal').find('input:eq(2)').type('column');
cy.get('.ndl-modal').find('input:eq(5)').type('test_param');
cy.get('.ndl-modal').find('input:eq(6)').type('column');
cy.get('.ndl-modal').find('button').contains('Save').click();
closeSettings(CARD_SELECTOR);
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(0)`)
.find('button')
.should('be.visible')
.should('have.text', 'initial, list')
.click();

// Previous step's click set a parameter from the array
// Test that parameter rendering works
cy.get(`${CARD_SELECTOR} .MuiCardHeader-root`).find('input').type('$neodash_test_param').blur();
cy.get(`${CARD_SELECTOR} .MuiCardHeader-root`).find('input').should('have.value', 'initial, list');
});

it('creates a table that contains int arrays', () => {
cy.checkInitialState();
createReportOfType('Table', intArrayCypherQuery, true, true);

// Standard array, displays strings joined with comma and whitespace
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(0)`).should('have.text', '1, 2');
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(1)`).should('have.text', '3, 4');

// Now, transpose the table
toggleTableTranspose(CARD_SELECTOR, true);
cy.get(`${CARD_SELECTOR} .MuiDataGrid-columnHeaderTitle:eq(1)`, { timeout: WAITING_TIME }).should(
'have.text',
'1,2'
);
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(1)`).should('have.text', '3, 4');
});

it('creates a table that contains nodes and rels', () => {
cy.checkInitialState();
createReportOfType('Table', pathArrayCypherQuery, true, true);

// Standard array, displays a path with two nodes and a relationship
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(0)`).should('have.text', 'PersonACTED_INMovie');
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(0) button`).should('have.length', 2);
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(0) button:eq(0)`).should('have.text', 'Person');
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(0) button:eq(1)`).should('have.text', 'Movie');
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(0) .MuiChip-root`).should('have.length', 1);
cy.get(`${CARD_SELECTOR} .MuiDataGrid-cell:eq(0) .MuiChip-root`).should('have.text', 'ACTED_IN');
});

it('creates a single value report which is an array', () => {
cy.checkInitialState();
createReportOfType('Single Value', stringArrayCypherQuery, true, true);
cy.get(CARD_SELECTOR).should('have.text', 'initial, list');
});

it('creates a multi parameter select', () => {
cy.checkInitialState();
selectReportOfType('Parameter Select');
cy.get('main .react-grid-item:eq(2) label[for="Selection Type"]').siblings('div').click();
// Set up the parameter select
cy.contains('Node Property').click();
cy.wait(100);
cy.contains('Node Label').click();
cy.contains('Node Label').siblings('div').find('input').type('Movie');
cy.wait(1000);
cy.get('.MuiAutocomplete-popper').contains('Movie').click();
cy.contains('Property Name').click();
cy.contains('Property Name').siblings('div').find('input').type('title');
cy.wait(1000);
cy.get('.MuiAutocomplete-popper').contains('title').click();
// Enable multiple selection
closeSettings(CARD_SELECTOR);
updateDropdownAdvancedSetting(CARD_SELECTOR, 'Multiple Selection', 'on');
// Finally, select a few values in the parameter select
cy.get(CARD_SELECTOR).contains('Movie title').click();
cy.get(CARD_SELECTOR).contains('Movie title').siblings('div').find('input').type('a');
cy.get('.MuiAutocomplete-popper').contains('Apollo 13').click();
cy.get(CARD_SELECTOR).contains('Movie title').siblings('div').find('input').type('t');
cy.get('.MuiAutocomplete-popper').contains('The Matrix').click();
cy.get(CARD_SELECTOR).contains('Apollo 13').should('be.visible');
cy.get(CARD_SELECTOR).contains('The Matrix').should('be.visible');
});
});
44 changes: 1 addition & 43 deletions cypress/e2e/start_page.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
gaugeChartCypherQuery,
formCypherQuery,
} from '../fixtures/cypher_queries';
import { createReportOfType, selectReportOfType, enableAdvancedVisualizations, enableFormsExtension } from './utils';

const WAITING_TIME = 20000;
// Ignore warnings that may appear when using the Cypress dev server
Expand Down Expand Up @@ -293,46 +294,3 @@ describe('NeoDash E2E Tests', () => {
}
});
});

function enableAdvancedVisualizations() {
cy.get('main button[aria-label="Extensions').should('be.visible').click();
cy.get('#checkbox-advanced-charts').should('be.visible').click();
cy.get('.ndl-dialog-close').scrollIntoView().should('be.visible').click();
cy.wait(200);
}

function enableFormsExtension() {
cy.get('main button[aria-label="Extensions').should('be.visible').click();
cy.get('#checkbox-forms').scrollIntoView();
cy.get('#checkbox-forms').should('be.visible').click();
cy.get('.ndl-dialog-close').scrollIntoView().should('be.visible').click();
cy.wait(200);
}

function selectReportOfType(type) {
cy.get('main .react-grid-item button[aria-label="add report"]').should('be.visible').click();
cy.get('main .react-grid-item')
.contains('No query specified.')
.parentsUntil('.react-grid-item')
.find('button[aria-label="settings"]', { timeout: 2000 })
.should('be.visible')
.click();
cy.get('main .react-grid-item:eq(2) #type', { timeout: 2000 }).should('be.visible').click();
cy.contains(type).click();
cy.wait(100);
}

function createReportOfType(type, query, fast = false, run = true) {
selectReportOfType(type);
if (fast) {
cy.get('main .react-grid-item:eq(2) .ReactCodeMirror').type(query, { delay: 1, parseSpecialCharSequences: false });
} else {
cy.get('main .react-grid-item:eq(2) .ReactCodeMirror').type(query, { parseSpecialCharSequences: false });
}
cy.wait(400);

cy.get('main .react-grid-item:eq(2)').contains('Advanced settings').click();
if (run) {
cy.get('main .react-grid-item:eq(2) button[aria-label="run"]').click();
}
}
84 changes: 84 additions & 0 deletions cypress/e2e/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
export function enableReportActions() {
cy.get('main button[aria-label="Extensions').should('be.visible').click();
cy.get('#checkbox-actions').scrollIntoView();
cy.get('#checkbox-actions').should('be.visible').click();
cy.get('.ndl-dialog-close').scrollIntoView().should('be.visible').click();
cy.wait(200);
}

export function enableAdvancedVisualizations() {
cy.get('main button[aria-label="Extensions').should('be.visible').click();
cy.get('#checkbox-advanced-charts').should('be.visible').click();
cy.get('.ndl-dialog-close').scrollIntoView().should('be.visible').click();
cy.wait(200);
}

export function enableFormsExtension() {
cy.get('main button[aria-label="Extensions').should('be.visible').click();
cy.get('#checkbox-forms').scrollIntoView();
cy.get('#checkbox-forms').should('be.visible').click();
cy.get('.ndl-dialog-close').scrollIntoView().should('be.visible').click();
cy.wait(200);
}

export function selectReportOfType(type) {
cy.get('main .react-grid-item button[aria-label="add report"]').should('be.visible').click();
cy.get('main .react-grid-item')
.contains('No query specified.')
.parentsUntil('.react-grid-item')
.find('button[aria-label="settings"]', { timeout: 2000 })
.should('be.visible')
.click();
cy.get('main .react-grid-item:eq(2) #type', { timeout: 2000 }).should('be.visible').click();
cy.contains(type).click();
cy.wait(100);
}

export function createReportOfType(type, query, fast = false, run = true) {
selectReportOfType(type);
if (fast) {
cy.get('main .react-grid-item:eq(2) .ReactCodeMirror').type(query, { delay: 1, parseSpecialCharSequences: false });
} else {
cy.get('main .react-grid-item:eq(2) .ReactCodeMirror').type(query, { parseSpecialCharSequences: false });
}
cy.wait(400);

if (run) {
closeSettings('main .react-grid-item:eq(2)');
}
}

export function openSettings(cardSelector) {
cy.get(cardSelector).find('button[aria-label="settings"]', { WAITING_TIME: 2000 }).click();
}

export function closeSettings(cardSelector) {
cy.get(`${cardSelector} button[aria-label="run"]`).click();
}

export function openAdvancedSettings(cardSelector) {
openSettings(cardSelector);
cy.get(cardSelector).contains('Advanced settings').click();
}

export function closeAdvancedSettings(cardSelector) {
cy.get(cardSelector).contains('Advanced settings').click();
closeSettings(cardSelector);
}

export function openReportActionsMenu(cardSelector) {
openSettings(cardSelector);
cy.get(cardSelector).find('button[aria-label="custom actions"]').click();
}

export function updateDropdownAdvancedSetting(cardSelector, settingLabel, targetValue) {
openAdvancedSettings(cardSelector);
cy.get(`${cardSelector} .ndl-dropdown`).contains(settingLabel).siblings('div').click();
cy.contains(targetValue).click();
closeAdvancedSettings(cardSelector);
}

export function toggleTableTranspose(cardSelector, enable) {
let transpose = enable ? 'on' : 'off';
updateDropdownAdvancedSetting(cardSelector, 'Transpose Rows & Columns', transpose);
}
8 changes: 8 additions & 0 deletions cypress/fixtures/cypher_queries.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Depending on the webserver type and version, this could be different directory.
As an example - to copy the files to an nginx webserver using `scp`:

```bash
scp neodash-2.4.6 username@host:/usr/share/nginx/html
scp neodash-2.4.7 username@host:/usr/share/nginx/html
```

NeoDash should now be visible by visiting your (sub)domain in the browser.
Expand Down
Loading

0 comments on commit c504094

Please sign in to comment.