From c86a44480d9495b395b061c7e8d94ae17f35ba02 Mon Sep 17 00:00:00 2001
From: BlackRaven
Date: Thu, 24 Aug 2023 18:56:52 -0400
Subject: [PATCH 01/36] Title not editable in standalone mode
---
src/dashboard/header/DashboardTitle.tsx | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/dashboard/header/DashboardTitle.tsx b/src/dashboard/header/DashboardTitle.tsx
index 43c5ecb9f..e6cd18d85 100644
--- a/src/dashboard/header/DashboardTitle.tsx
+++ b/src/dashboard/header/DashboardTitle.tsx
@@ -70,7 +70,8 @@ export const NeoDashboardTitle = ({
return (
{/* TODO : Replace with editable field if dashboard is editable */}
- {editing ? (
+ {/* only allow edit title if dashboard is not standalone - here we are in Title edit mode*/}
+ {editing && !isStandalone ? (
- ) : (
+ ) : !isStandalone? ( /* out of edit mode - if Not Standalone we display the edit button */
+ ):( /* if we are in Standalone just title is displayed with no edit button */
+
+ {dashboardTitle}
+
)}
{/* If the app is not running in standalone mode (i.e. in edit mode) always show dashboard settings. */}
{!isStandalone ? (
From f17cc9a1aa55662ff7af6c467d4ae8135e8e3287 Mon Sep 17 00:00:00 2001
From: BlackRaven
Date: Fri, 25 Aug 2023 19:24:08 -0400
Subject: [PATCH 02/36] standalone load v1 (working)
---
.../pages/developer-guide/configuration.adoc | 9 ++++++-
.../developer-guide/state-management.adoc | 1 +
public/config.json | 7 ++---
scripts/config-entrypoint.sh | 3 ++-
src/application/ApplicationActions.ts | 4 ++-
src/application/ApplicationReducer.ts | 2 ++
src/application/ApplicationSelectors.ts | 1 +
src/application/ApplicationThunks.ts | 4 ++-
src/dashboard/header/DashboardTitle.tsx | 23 ++++++++--------
src/modal/LoadModal.tsx | 27 ++++++++++++++-----
10 files changed, 56 insertions(+), 25 deletions(-)
diff --git a/docs/modules/ROOT/pages/developer-guide/configuration.adoc b/docs/modules/ROOT/pages/developer-guide/configuration.adoc
index 6df3fdfba..7a039ee7a 100644
--- a/docs/modules/ROOT/pages/developer-guide/configuration.adoc
+++ b/docs/modules/ROOT/pages/developer-guide/configuration.adoc
@@ -24,7 +24,8 @@ will look like this:
"standaloneDatabase": "neo4j",
"standaloneDashboardName": "My Dashboard",
"standaloneDashboardDatabase": "dashboards",
- "standaloneDashboardURL": ""
+ "standaloneDashboardURL": "",
+ "standaloneAllowLoad": true
}
....
@@ -84,6 +85,12 @@ use multiple databases.
inside Neo4j and would like to run a standalone mode deployment with a
dashboard from a URL, set this parameter to the complete URL pointing to
the dashboard JSON.
+
+|standaloneAllowLoad |boolean |true |If set t yes the "Load Dashboard"
+button will be enabled in standalone mode, allowing users to load
+additional dashboards from Neo4J.
+*NOTE*: when Load is enabled in standalone mode, only Database is available
+as a source, not file.
|===
== Configuring SSO
diff --git a/docs/modules/ROOT/pages/developer-guide/state-management.adoc b/docs/modules/ROOT/pages/developer-guide/state-management.adoc
index c7513269d..a2ee906d1 100644
--- a/docs/modules/ROOT/pages/developer-guide/state-management.adoc
+++ b/docs/modules/ROOT/pages/developer-guide/state-management.adoc
@@ -134,6 +134,7 @@ standalone mode.
"standaloneDatabase": "neo4j",
"standaloneDashboardName": "My Dashboard",
"standaloneDashboardDatabase": "dashboards",
+ "standaloneAllowLoad": true,
"notificationIsDismissable": null
}
....
diff --git a/public/config.json b/public/config.json
index 6a203041f..07477d5ce 100644
--- a/public/config.json
+++ b/public/config.json
@@ -1,12 +1,13 @@
{
"ssoEnabled": false,
"ssoDiscoveryUrl": "https://example.com",
- "standalone": false,
+ "standalone": true,
"standaloneProtocol": "neo4j",
"standaloneHost": "localhost",
"standalonePort": "7687",
- "standaloneDatabase": "neo4j",
+ "standaloneDatabase": "movies",
"standaloneDashboardName": "My Dashboard",
"standaloneDashboardDatabase": "dashboards",
- "standaloneDashboardURL": ""
+ "standaloneDashboardURL": "",
+ "standaloneAllowLoad": true
}
diff --git a/scripts/config-entrypoint.sh b/scripts/config-entrypoint.sh
index 25374b647..fa67391d1 100644
--- a/scripts/config-entrypoint.sh
+++ b/scripts/config-entrypoint.sh
@@ -15,5 +15,6 @@ echo " \
\"standalonePassword\": \"${standalonePassword:=}\", \
\"standaloneDashboardName\": \"${standaloneDashboardName:='My Dashboard'}\", \
\"standaloneDashboardDatabase\": \"${standaloneDashboardDatabase:='neo4j'}\", \
- \"standaloneDashboardURL\": \"${standaloneDashboardURL:=}\" \
+ \"standaloneDashboardURL\": \"${standaloneDashboardURL:=}\", \
+ \"standaloneAllowLoad\": \"${standaloneAllowLoad:=true}\" \
}" > /usr/share/nginx/html/config.json
diff --git a/src/application/ApplicationActions.ts b/src/application/ApplicationActions.ts
index 49311d768..e9c2094df 100644
--- a/src/application/ApplicationActions.ts
+++ b/src/application/ApplicationActions.ts
@@ -143,7 +143,8 @@ export const setStandaloneEnabled = (
standaloneDashboardDatabase: string,
standaloneDashboardURL: string,
standaloneUsername: string,
- standalonePassword: string
+ standalonePassword: string,
+ standaloneAllowLoad: boolean
) => ({
type: SET_STANDALONE_ENABLED,
payload: {
@@ -157,6 +158,7 @@ export const setStandaloneEnabled = (
standaloneDashboardURL,
standaloneUsername,
standalonePassword,
+ standaloneAllowLoad,
},
});
diff --git a/src/application/ApplicationReducer.ts b/src/application/ApplicationReducer.ts
index 23dcdd9a1..52833221d 100644
--- a/src/application/ApplicationReducer.ts
+++ b/src/application/ApplicationReducer.ts
@@ -134,6 +134,7 @@ export const applicationReducer = (state = initialState, action: { type: any; pa
standaloneDashboardURL,
standaloneUsername,
standalonePassword,
+ standaloneAllowLoad
} = payload;
state = update(state, {
standalone: standalone,
@@ -146,6 +147,7 @@ export const applicationReducer = (state = initialState, action: { type: any; pa
standaloneDashboardURL: standaloneDashboardURL,
standaloneUsername: standaloneUsername,
standalonePassword: standalonePassword,
+ standaloneAllowLoad: standaloneAllowLoad,
});
return state;
}
diff --git a/src/application/ApplicationSelectors.ts b/src/application/ApplicationSelectors.ts
index 263fae4bf..a20543610 100644
--- a/src/application/ApplicationSelectors.ts
+++ b/src/application/ApplicationSelectors.ts
@@ -81,6 +81,7 @@ export const applicationGetStandaloneSettings = (state: any) => {
standaloneDashboardURL: state.application.standaloneDashboardURL,
standaloneUsername: state.application.standaloneUsername,
standalonePassword: state.application.standalonePassword,
+ standaloneAllowLoad: state.application.standaloneAllowLoad,
};
};
diff --git a/src/application/ApplicationThunks.ts b/src/application/ApplicationThunks.ts
index d09ee1ed5..a1b298da5 100644
--- a/src/application/ApplicationThunks.ts
+++ b/src/application/ApplicationThunks.ts
@@ -349,6 +349,7 @@ export const loadApplicationConfigThunk = () => async (dispatch: any, getState:
standaloneDashboardName: 'My Dashboard',
standaloneDashboardDatabase: 'dashboards',
standaloneDashboardURL: '',
+ standaloneAllowLoad: true,
};
try {
config = await (await fetch('config.json')).json();
@@ -390,7 +391,8 @@ export const loadApplicationConfigThunk = () => async (dispatch: any, getState:
config.standaloneDashboardDatabase,
config.standaloneDashboardURL,
config.standaloneUsername,
- config.standalonePassword
+ config.standalonePassword,
+ config.standaloneAllowLoad,
)
);
dispatch(setConnectionModalOpen(false));
diff --git a/src/dashboard/header/DashboardTitle.tsx b/src/dashboard/header/DashboardTitle.tsx
index e6cd18d85..2f4868578 100644
--- a/src/dashboard/header/DashboardTitle.tsx
+++ b/src/dashboard/header/DashboardTitle.tsx
@@ -2,7 +2,7 @@ import React, { Suspense, useCallback, useEffect, useState } from 'react';
import debounce from 'lodash/debounce';
import { connect } from 'react-redux';
import { setDashboardTitle } from '../DashboardActions';
-import { applicationGetConnection, applicationIsStandalone } from '../../application/ApplicationSelectors';
+import { applicationGetConnection, applicationGetStandaloneSettings } from '../../application/ApplicationSelectors';
import { getDashboardTitle, getDashboardExtensions, getDashboardSettings } from '../DashboardSelectors';
import { getDashboardIsEditable } from '../../settings/SettingsSelectors';
import { updateDashboardSetting } from '../../settings/SettingsActions';
@@ -21,7 +21,7 @@ export const NeoDashboardTitle = ({
dashboardTitle,
setDashboardTitle,
editable,
- isStandalone,
+ standaloneSettings,
dashboardSettings,
extensions,
updateDashboardSetting,
@@ -71,7 +71,7 @@ export const NeoDashboardTitle = ({
{/* TODO : Replace with editable field if dashboard is editable */}
{/* only allow edit title if dashboard is not standalone - here we are in Title edit mode*/}
- {editing && !isStandalone ? (
+ {editing && !standaloneSettings.standalone ? (
- ) : !isStandalone? ( /* out of edit mode - if Not Standalone we display the edit button */
+ ) : !standaloneSettings.standalone? ( /* out of edit mode - if Not Standalone we display the edit button */
)}
{/* If the app is not running in standalone mode (i.e. in edit mode) always show dashboard settings. */}
- {!isStandalone ? (
+ {!standaloneSettings.standalone ? (
);
};
@@ -174,7 +173,7 @@ export const NeoDashboardTitle = ({
const mapStateToProps = (state) => ({
dashboardTitle: getDashboardTitle(state),
editable: getDashboardIsEditable(state),
- isStandalone: applicationIsStandalone(state),
+ standaloneSettings: applicationGetStandaloneSettings(state),
dashboardSettings: getDashboardSettings(state),
extensions: getDashboardExtensions(state),
connection: applicationGetConnection(state),
diff --git a/src/modal/LoadModal.tsx b/src/modal/LoadModal.tsx
index 1331612ae..c57c12184 100644
--- a/src/modal/LoadModal.tsx
+++ b/src/modal/LoadModal.tsx
@@ -9,17 +9,20 @@ import {
} from '../dashboard/DashboardThunks';
import { DataGrid } from '@mui/x-data-grid';
import { Neo4jContext, Neo4jContextState } from 'use-neo4j/dist/neo4j.context';
-import { MenuItem, Button, Dialog, Dropdown } from '@neo4j-ndl/react';
+import { MenuItem, Button, Dialog, Dropdown, IconButton } from '@neo4j-ndl/react';
import {
CloudArrowUpIconOutline,
PlayIconSolid,
DatabaseAddCircleIcon,
DocumentPlusIconOutline,
} from '@neo4j-ndl/react/icons';
+import { applicationIsStandalone } from '../application/ApplicationSelectors';
/**
* A modal to save a dashboard as a JSON text string.
- * The button to open the modal is intended to use in a drawer at the side of the page.
+ * The button to open the modal is renderedd as:
+ * - a ListItem to use in a drawer at the side of the page if the app is in Editor Mode.
+ * - a Button to be diplayed by itself if the app is in Standalone Mode.
*/
export const NeoLoadModal = ({
@@ -27,6 +30,7 @@ export const NeoLoadModal = ({
loadDatabaseListFromNeo4j,
loadDashboardFromNeo4j,
loadDashboardListFromNeo4j,
+ isStandalone
}) => {
const [loadModalOpen, setLoadModalOpen] = React.useState(false);
const [loadFromNeo4jModalOpen, setLoadFromNeo4jModalOpen] = React.useState(false);
@@ -97,7 +101,15 @@ export const NeoLoadModal = ({
return (
<>
- } />
+ {!isStandalone?
+ (
+ } />
+ ):(
+
+
+
+ )
+ }
);
- alert ('I am here and I am a dashboard')
return content;
};
diff --git a/src/dashboard/DashboardThunks.ts b/src/dashboard/DashboardThunks.ts
index eca09c110..a7e8f6990 100644
--- a/src/dashboard/DashboardThunks.ts
+++ b/src/dashboard/DashboardThunks.ts
@@ -7,8 +7,6 @@ import { updateGlobalParametersThunk, updateParametersToNeo4jTypeThunk } from '.
import { createUUID } from '../utils/uuid';
import { createLogThunk } from '../application/ApplicationThunks';
import { applicationGetLoggingSettings, applicationGetConnectionUser, applicationIsStandalone } from '../application/ApplicationSelectors';
-// import { Neo4jContext, Neo4jContextState } from 'use-neo4j/dist/neo4j.context';
-// import { useContext } from 'react';
export const removePageThunk = (number) => (dispatch: any, getState: any) => {
try {
@@ -56,12 +54,7 @@ export const movePageThunk = (oldIndex: number, newIndex: number) => (dispatch:
};
export const loadDashboardThunk = (text) => (dispatch: any, getState: any) => {
- const loggingState = getState();
- const loggingSettings = applicationGetLoggingSettings(loggingState)
- const loguser = applicationGetConnectionUser(loggingState)
- const neodashMode = applicationIsStandalone(loggingState) ? 'Standalone' : 'Editor'
-
- try {
+ try {
if (text.length == 0) {
throw 'No dashboard file specified. Did you select a file?';
}
@@ -75,7 +68,6 @@ export const loadDashboardThunk = (text) => (dispatch: any, getState: any) => {
if (dashboard._persist && dashboard.application && dashboard.dashboard) {
dispatch(
createNotificationThunk('Loaded a Debug Report', "Recovery-mode active. All report types were set to 'table'.")
-
);
dashboard.dashboard.pages.map((p) => {
p.reports.map((r) => {
@@ -142,9 +134,9 @@ export const loadDashboardThunk = (text) => (dispatch: any, getState: any) => {
// Reverse engineer the minimal set of fields from the selection loaded.
dashboard.pages.forEach((p) => {
- r.fields = [];
- p.reports.forEach((r) => {
+ p.reports.forEach((r) => {
if (r.selection) {
+ r.fields = [];
Object.keys(r.selection).forEach((f) => {
r.fields.push([f, r.selection[f]]);
});
@@ -153,21 +145,6 @@ export const loadDashboardThunk = (text) => (dispatch: any, getState: any) => {
});
dispatch(setDashboard(dashboard));
- // if(loggingSettings.loggingMode > '1') {
- // const { driver } = useContext(Neo4jContext);
- // dispatch(
- // createLogThunk(
- // driver,
- // loggingSettings.loggingDatabase,
- // neodashMode,
- // loguser,
- // 'INF - load dashboard from file',
- // loggingSettings.loggingDatabase,
- // 'Name:'+dashboard.title,
- // 'User '+loguser+' Loaded dashboard from file in '+neodashMode+' mode at '+Date.now()
- // )
- // )
- // }
const { application } = getState();
@@ -175,21 +152,6 @@ export const loadDashboardThunk = (text) => (dispatch: any, getState: any) => {
dispatch(setParametersToLoadAfterConnecting(null));
dispatch(updateParametersToNeo4jTypeThunk());
} catch (e) {
- // if(loggingSettings.loggingMode > '1') {
- // const { driver } = useContext(Neo4jContext);
- // dispatch(
- // createLogThunk(
- // driver,
- // loggingSettings.loggingDatabase,
- // neodashMode,
- // loguser,
- // 'ERR - load dashboard from file',
- // loggingSettings.loggingDatabase,
- // 'Name:Not Parsed',
- // 'Error while trying to load dashboard from file in '+neodashMode+' mode at '+Date.now()
- // )
- // )
- // }
dispatch(createNotificationThunk('Unable to load dashboard', e));
}
};
@@ -197,12 +159,12 @@ export const loadDashboardThunk = (text) => (dispatch: any, getState: any) => {
export const saveDashboardToNeo4jThunk =
(driver, database, dashboard, date, user, overwrite = false) =>
(dispatch: any, getState: any) => {
- const loggingState = getState();
- const loggingSettings = applicationGetLoggingSettings(loggingState)
- const loguser = applicationGetConnectionUser(loggingState)
- const neodashMode = applicationIsStandalone(loggingState) ? 'Standalone' : 'Editor'
+ const loggingState = getState();
+ const loggingSettings = applicationGetLoggingSettings(loggingState)
+ const loguser = applicationGetConnectionUser(loggingState)
+ const neodashMode = applicationIsStandalone(loggingState) ? 'Standalone' : 'Editor'
- try {
+ try {
const uuid = createUUID();
const { title, version } = dashboard;
@@ -229,6 +191,20 @@ export const saveDashboardToNeo4jThunk =
(records) => {
if (records && records[0] && records[0]._fields && records[0]._fields[0] && records[0]._fields[0] == uuid) {
dispatch(createNotificationThunk('🎉 Success!', 'Your current dashboard was saved to Neo4j.'));
+ if (loggingSettings.loggingMode > '1'){
+ dispatch(
+ createLogThunk(
+ driver,
+ loggingSettings.loggingDatabase,
+ neodashMode,
+ loguser,
+ 'INF - save dashboard',
+ database,
+ 'Name:'+title,
+ 'User '+loguser+' saved dashboard to Neo4J in '+neodashMode+' mode at '+Date(Date.now()).substring(0,33)
+ )
+ );
+ }
} else {
dispatch(
createNotificationThunk(
@@ -236,11 +212,41 @@ export const saveDashboardToNeo4jThunk =
`Do you have write access to the '${database}' database?`
)
);
+ if (loggingSettings.loggingMode > '1'){
+ dispatch(
+ createLogThunk(
+ driver,
+ loggingSettings.loggingDatabase,
+ neodashMode,
+ loguser,
+ 'ERR - save dashboard',
+ database,
+ 'Name:'+title,
+ 'Error while trying to save dashboard to Neo4J in '+neodashMode+' mode at '+Date(Date.now()).substring(0,33)
+ )
+ );
+ }
+
}
}
);
} catch (e) {
dispatch(createNotificationThunk('Unable to save dashboard to Neo4j', e));
+ if (loggingSettings.loggingMode > '1'){
+ dispatch(
+ createLogThunk(
+ driver,
+ loggingSettings.loggingDatabase,
+ neodashMode,
+ loguser,
+ 'ERR - save dashboard',
+ database,
+ 'Name:Not fetched',
+ 'Error while trying to save dashboard to Neo4J in '+neodashMode+' mode at '+Date(Date.now()).substring(0,33)
+ )
+ );
+ }
+
}
};
@@ -276,7 +282,7 @@ try {
'ERR - load dashboard',
database,
'UUID:'+uuid,
- 'Error while trying to load dashboard by UUID in '+neodashMode+' mode at '+Date.now()
+ 'Error while trying to load dashboard by UUID in '+neodashMode+' mode at '+Date(Date.now()).substring(0,33)
)
);
}
@@ -291,7 +297,7 @@ try {
'INF - load dashboard',
database,
'UUID:'+uuid,
- 'User '+loguser+' Loaded dashboard by UUID in '+neodashMode+' mode at '+Date.now()
+ 'User '+loguser+' Loaded dashboard by UUID in '+neodashMode+' mode at '+Date(Date.now()).substring(0,33)
)
);
}
@@ -310,7 +316,7 @@ try {
'ERR - load dashboard',
database,
'UUID:'+uuid,
- 'Error while trying to load dashboard by UUID in '+neodashMode+' mode at '+Date.now()
+ 'Error while trying to load dashboard by UUID in '+neodashMode+' mode at '+Date(Date.now()).substring(0,33)
)
);
}
@@ -322,7 +328,6 @@ export const loadDashboardFromNeo4jByNameThunk = (driver, database, name, callba
const loggingSettings = applicationGetLoggingSettings(loggingState)
const loguser = applicationGetConnectionUser(loggingState)
const neodashMode = applicationIsStandalone(loggingState) ? 'Standalone' : 'Editor'
- alert('loggingsettings: '+loggingSettings.loggingMode+'\n'+loggingSettings.loggingDatabase+'\n'+loguser+'\n'+neodashMode)
try {
const query =
'MATCH (d:_Neodash_Dashboard) WHERE d.title = $name RETURN d.content as dashboard ORDER by d.date DESC LIMIT 1';
@@ -351,7 +356,7 @@ export const loadDashboardFromNeo4jByNameThunk = (driver, database, name, callba
'ERR - load dashboard',
database,
'Name:'+name,
- 'Error while trying to load dashboard by Name in '+neodashMode+' mode at '+Date.now()
+ 'Error while trying to load dashboard by Name in '+neodashMode+' mode at '+Date(Date.now()).substring(0,33)
)
);
}
@@ -370,7 +375,7 @@ export const loadDashboardFromNeo4jByNameThunk = (driver, database, name, callba
'ERR - load dashboard',
database,
'Name:'+name,
- 'Error while trying to load dashboard by Name in '+neodashMode+' mode at '+Date.now()
+ 'Error while trying to load dashboard by Name in '+neodashMode+' mode at '+Date(Date.now()).substring(0,33)
)
);
}
@@ -387,7 +392,7 @@ export const loadDashboardFromNeo4jByNameThunk = (driver, database, name, callba
'INF - load dashboard',
database,
'Name:'+name,
- 'User '+loguser+' Loaded dashboard by UUID in '+neodashMode+' mode at '+Date.now()
+ 'User '+loguser+' Loaded dashboard by UUID in '+neodashMode+' mode at '+Date(Date.now()).substring(0,33)
)
);
}
diff --git a/src/modal/ConnectionModal.tsx b/src/modal/ConnectionModal.tsx
index ad98a65b3..bb9d931a8 100644
--- a/src/modal/ConnectionModal.tsx
+++ b/src/modal/ConnectionModal.tsx
@@ -217,8 +217,8 @@ export default function NeoConnectionModal({
{standaloneSettings.standaloneDashboardURL === '' ? (
<>
- Sign in to continue. You will be connected to Neo4j, and load a dashboard called
- {standaloneSettings.standaloneDashboardName}.
+ Sign in to continue. You will be connected to Neo4j, and load a dashboard called
+ {standaloneSettings.standaloneDashboardName}.
>
) : (
<> Sign in to continue. You will be connected to Neo4j, and load a dashboard.>
From 15fac3e5667b250dac8f3a7dd2d2415e85d10406 Mon Sep 17 00:00:00 2001
From: BlackRaven
Date: Thu, 31 Aug 2023 01:06:23 -0400
Subject: [PATCH 09/36] fix on error notification
---
src/application/ApplicationActions.ts | 4 +--
src/application/ApplicationReducer.ts | 2 +-
src/application/ApplicationSelectors.ts | 5 ---
src/application/ApplicationThunks.ts | 45 ++++++++++++++++---------
4 files changed, 32 insertions(+), 24 deletions(-)
diff --git a/src/application/ApplicationActions.ts b/src/application/ApplicationActions.ts
index d2e5d838e..2993431ba 100644
--- a/src/application/ApplicationActions.ts
+++ b/src/application/ApplicationActions.ts
@@ -185,9 +185,9 @@ export const setLoggingDatabase = (loggingDatabase: string) => ({
});
export const SET_LOG_ERROR_NOTIFICATION = 'APPLICATION/SET_LOG_ERROR_NOTIFICATION';
-export const setLogErrorNotification = (parameters: any) => ({
+export const setLogErrorNotification = (logErrorNotification: any) => ({
type: SET_LOG_ERROR_NOTIFICATION,
- payload: { parameters },
+ payload: { logErrorNotification },
});
export const SET_SSO_ENABLED = 'APPLICATION/SET_SSO_ENABLED';
diff --git a/src/application/ApplicationReducer.ts b/src/application/ApplicationReducer.ts
index 4a6f56f46..13dbf8e6f 100644
--- a/src/application/ApplicationReducer.ts
+++ b/src/application/ApplicationReducer.ts
@@ -54,7 +54,7 @@ const initialState = {
waitForSSO: false,
standalone: false,
loggingMode: '0',
- logErrorNotification: 3,
+ logErrorNotification: '3',
};
export const applicationReducer = (state = initialState, action: { type: any; payload: any }) => {
const { type, payload } = action;
diff --git a/src/application/ApplicationSelectors.ts b/src/application/ApplicationSelectors.ts
index 7a57b3bb5..4200bed73 100644
--- a/src/application/ApplicationSelectors.ts
+++ b/src/application/ApplicationSelectors.ts
@@ -96,11 +96,6 @@ export const applicationGetLoggingSettings = (state: any) => {
return {
loggingMode: state.application.loggingMode,
loggingDatabase: state.application.loggingDatabase,
- };
-};
-
-export const applicationGetLogErrorNotification = (state: any) => {
- return {
logErrorNotification: state.application.logErrorNotification,
};
};
diff --git a/src/application/ApplicationThunks.ts b/src/application/ApplicationThunks.ts
index 0c201a373..61e07c352 100644
--- a/src/application/ApplicationThunks.ts
+++ b/src/application/ApplicationThunks.ts
@@ -42,8 +42,9 @@ import {
setReportHelpModalOpen,
} from './ApplicationActions';
import { version } from '../modal/AboutModal';
-import { applicationGetLoggingSettings, applicationIsStandalone, applicationGetLogErrorNotification } from './ApplicationSelectors';
+import { applicationGetLoggingSettings, applicationIsStandalone } from './ApplicationSelectors';
import { createUUID } from '../utils/uuid';
+import { valueIsRelationship } from '../chart/ChartUtils';
/**
* Application Thunks (https://redux.js.org/usage/writing-logic-thunks) handle complex state manipulations.
@@ -83,7 +84,7 @@ export const createConnectionThunk =
'ERR - connect to DB',
database,
'',
- 'Error while trying to establish connection to Neo4j DB in ' +neodashMode+' mode at '+Date.now()
+ 'Error while trying to establish connection to Neo4j DB in ' +neodashMode+' mode at '+Date(Date.now()).substring(0,33)
)
);
}
@@ -104,7 +105,7 @@ export const createConnectionThunk =
'INF - connect to DB',
database,
'',
- username +'established connection to Neo4j DB in ' +neodashMode+' mode at '+Date.now()
+ username +'established connection to Neo4j DB in ' +neodashMode+' mode at '+Date(Date.now()).substring(0,33)
)
);
}
@@ -387,6 +388,7 @@ export const loadApplicationConfigThunk = () => async (dispatch: any, getState:
standaloneDashboardURL: '',
loggingMode: '0',
loggingDatabase: 'logs',
+ logErrorNotification: '3',
};
try {
config = await (await fetch('config.json')).json();
@@ -434,6 +436,7 @@ export const loadApplicationConfigThunk = () => async (dispatch: any, getState:
dispatch(setLoggingMode(config.loggingMode));
dispatch(setLoggingDatabase(config.loggingDatabase));
+ dispatch(setLogErrorNotification('3'));
dispatch(setConnectionModalOpen(false));
@@ -644,7 +647,6 @@ export const createLogThunk =
(dispatch: any, getState: any) => {
try {
const uuid = createUUID();
-
// Generate a cypher query to save the log.
const query = 'CREATE (n:_Neodash_Log) SET n.uuid = $uuid, n.user = $user, n.date = datetime(), n.neodash_mode = $neodashMode, n.action = $logAction, n.database = $logDatabase, n.dashboard = $logDashboard, n.message = $logMessage RETURN $uuid as uuid'
@@ -670,26 +672,37 @@ export const createLogThunk =
} else {
//we only show error notification one time
const state = getState()
- const LogErrorNotification : number = Number(applicationGetLogErrorNotification(state))
- if (LogErrorNotification > 0 ) {
- dispatch(
+ const loggingSettings = applicationGetLoggingSettings (state);
+ var LogErrorNotificationNum = Number(loggingSettings.logErrorNotification)
+ console.log('Error creating log for '+((LogErrorNotificationNum-4)*(-1))+' times')
+ if (LogErrorNotificationNum > 0 ) {
+ dispatch(
createNotificationThunk(
'Error creating log',
- `Please check logging configuration with your Neodash administrator`
- )
+ LogErrorNotificationNum>1 ? `Please check logging configuration with your Neodash administrator`:`Please check logging configuration with your Neodash administrator - This message will not be displayed anymore in the current session`
+ )
);
- dispatch(setLogErrorNotification (LogErrorNotification - 1));
}
- }
+ LogErrorNotificationNum = LogErrorNotificationNum-1
+ dispatch(setLogErrorNotification (LogErrorNotificationNum.toString()));
+ }
}
);
} catch (e) {
//we only show error notification 3 times
const state = getState()
- const LogErrorNotification : number = Number(applicationGetLogErrorNotification(state))
- if (LogErrorNotification > 0 ) {
- dispatch(createNotificationThunk('Error creating log', e));
- dispatch(setLogErrorNotification (LogErrorNotification - 1));
+ const loggingSettings = applicationGetLoggingSettings (state);
+ var LogErrorNotificationNum = Number(loggingSettings.logErrorNotification)
+ console.log('Error creating log for '+((LogErrorNotificationNum-4)*(-1))+' times')
+ if (LogErrorNotificationNum > 0 ) {
+ dispatch(
+ createNotificationThunk(
+ 'Error creating log',
+ LogErrorNotificationNum>1 ? `Please check logging configuration with your Neodash administrator`:`Please check logging configuration with your Neodash administrator - This message will not be displayed anymore in the current session`
+ )
+ );
}
- }
+ LogErrorNotificationNum = LogErrorNotificationNum-1
+ dispatch(setLogErrorNotification (LogErrorNotificationNum.toString()));
+ }
};
\ No newline at end of file
From 7b88f4eb2d1b1c232620fbf1b2c74ef0fbda7c4f Mon Sep 17 00:00:00 2001
From: BlackRaven
Date: Thu, 31 Aug 2023 08:33:13 -0400
Subject: [PATCH 10/36] minor refinement in documentation
---
.../pages/developer-guide/configuration.adoc | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/docs/modules/ROOT/pages/developer-guide/configuration.adoc b/docs/modules/ROOT/pages/developer-guide/configuration.adoc
index 12fec8955..65f61982e 100644
--- a/docs/modules/ROOT/pages/developer-guide/configuration.adoc
+++ b/docs/modules/ROOT/pages/developer-guide/configuration.adoc
@@ -164,7 +164,19 @@ NeoDash mode (neodash_mmode), Action (action) and a short message (message).
⚠️ Logs are created using the credentials of the current user (either from
logon or, if configured, from standaloneUsername), therefore, for it to work,
administrator must ensure that every neodash user has write access to the
-__Neodash_Log_ label in the database confugred in the loggingDatabase prameter (which must also be available on the same Neo4J instance where dashboards and data are stored).
+__Neodash_Log_ label in the database confugred in the loggingDatabase prameter
+(which must also be available on the same Neo4J instance where dashboards and
+data are stored).
This can be achieved by creating a standard NeoDashUser role in Neo4j with
such permissions and assigning this role to every neoDash user. For more
-details on Neo4J granular access control please refer to the link:https://neo4j.com/docs/operations-manual/current/authentication-authorization/access-control/[product documentation]
+details on Neo4J granular access control please refer to the link:
+https://neo4j.com/docs/operations-manual/current/authentication-authorization/access-control/[product documentation]
+In case of any misconfiguration (e.g. user not having grants to write in the
+loggingDatabase), the application will show an error notification every time
+a log creation fails (e.g. for a loggingMode set to '2', at user connection
+attempt and any subsequent attempt to load or save a dashboard); the error will
+not block the application flow (users will still be able to connect, load and
+save dashboards normally); additionally, to limit user discomfort in such
+scenario, the notification is shown for 3 times only in a single user session.
+After 3rd time, a line will still be logged in the javascript console of user
+browser but interactive notifictions will be suppressed.
\ No newline at end of file
From 7f97533d5c594a0f6d9405dee2acd78be6710293 Mon Sep 17 00:00:00 2001
From: BlackRaven
Date: Thu, 31 Aug 2023 18:06:27 -0400
Subject: [PATCH 11/36] hide logout button in standalone mode
---
.../header/DashboardHeaderLogoutButton.tsx | 30 +++++++++----------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/src/dashboard/header/DashboardHeaderLogoutButton.tsx b/src/dashboard/header/DashboardHeaderLogoutButton.tsx
index c0fe918db..7d339b556 100644
--- a/src/dashboard/header/DashboardHeaderLogoutButton.tsx
+++ b/src/dashboard/header/DashboardHeaderLogoutButton.tsx
@@ -11,22 +11,20 @@ await StyleConfig.getInstance();
export const NeoLogoutButton = ({ standalone, onConnectionModalOpen }) => {
return (
-
- {
- if (!standalone) {
- onConnectionModalOpen();
- }
- }}
- size='large'
- clean
- >
-
-
-
+ !standalone ? (
+
+ {onConnectionModalOpen();}}
+ size='large'
+ clean
+ >
+
+
+
+ ):(<>>)
);
};
From f6e1a3a1b20bc0ae9b8f562eb3b4843d805bc7d3 Mon Sep 17 00:00:00 2001
From: BlackRaven
Date: Thu, 31 Aug 2023 18:23:48 -0400
Subject: [PATCH 12/36] man merge d137081cfde4b2d5dcf1192b8a9be675e953bd0b
---
src/application/ApplicationThunks.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/application/ApplicationThunks.ts b/src/application/ApplicationThunks.ts
index 30b30cb57..d0e54f8ff 100644
--- a/src/application/ApplicationThunks.ts
+++ b/src/application/ApplicationThunks.ts
@@ -677,7 +677,7 @@ export const createLogThunk =
//we only show error notification one time
const state = getState()
const loggingSettings = applicationGetLoggingSettings (state);
- var LogErrorNotificationNum = Number(loggingSettings.logErrorNotification)
+ let LogErrorNotificationNum = Number(loggingSettings.logErrorNotification)
console.log('Error creating log for '+((LogErrorNotificationNum-4)*(-1))+' times')
if (LogErrorNotificationNum > 0 ) {
dispatch(
@@ -687,7 +687,7 @@ export const createLogThunk =
)
);
}
- LogErrorNotificationNum = LogErrorNotificationNum-1
+ LogErrorNotificationNum -= 1
dispatch(setLogErrorNotification (LogErrorNotificationNum.toString()));
}
}
@@ -696,7 +696,7 @@ export const createLogThunk =
//we only show error notification 3 times
const state = getState()
const loggingSettings = applicationGetLoggingSettings (state);
- var LogErrorNotificationNum = Number(loggingSettings.logErrorNotification)
+ let LogErrorNotificationNum = Number(loggingSettings.logErrorNotification)
console.log('Error creating log for '+((LogErrorNotificationNum-4)*(-1))+' times')
if (LogErrorNotificationNum > 0 ) {
dispatch(
@@ -706,7 +706,7 @@ export const createLogThunk =
)
);
}
- LogErrorNotificationNum = LogErrorNotificationNum-1
+ LogErrorNotificationNum -= 1
dispatch(setLogErrorNotification (LogErrorNotificationNum.toString()));
}
};
\ No newline at end of file
From ff6b05a24403b7bb73fc3deb93e560c2196b2ae7 Mon Sep 17 00:00:00 2001
From: BlackRaven
Date: Fri, 1 Sep 2023 12:45:53 -0400
Subject: [PATCH 13/36] man chg 0484e44ed345e8a9008fcebc8753ddf881f038f1
---
src/dashboard/DashboardThunks.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/dashboard/DashboardThunks.ts b/src/dashboard/DashboardThunks.ts
index a7e8f6990..6ba1db59b 100644
--- a/src/dashboard/DashboardThunks.ts
+++ b/src/dashboard/DashboardThunks.ts
@@ -288,6 +288,7 @@ try {
}
}
if (loggingSettings.loggingMode > '1'){
+ const dashboard = JSON.parse(records[0]._fields[0])
dispatch(
createLogThunk(
driver,
@@ -296,7 +297,7 @@ try {
loguser,
'INF - load dashboard',
database,
- 'UUID:'+uuid,
+ 'Name:'+dashboard.title,
'User '+loguser+' Loaded dashboard by UUID in '+neodashMode+' mode at '+Date(Date.now()).substring(0,33)
)
);
From bccc09064a569d3ec93e56f6c2ab2332e8ec197a Mon Sep 17 00:00:00 2001
From: BlackRaven
Date: Fri, 8 Sep 2023 10:54:25 -0400
Subject: [PATCH 14/36] added configuration to allow multiple data DBs
---
.../pages/developer-guide/configuration.adoc | 50 +++++++++++++++----
.../developer-guide/standalone-mode.adoc | 5 ++
.../developer-guide/state-management.adoc | 3 ++
public/config.json | 5 +-
scripts/config-entrypoint.sh | 4 +-
src/application/ApplicationActions.ts | 6 ++-
src/application/ApplicationReducer.ts | 6 ++-
src/application/ApplicationSelectors.ts | 2 +
src/application/ApplicationThunks.ts | 4 ++
src/dashboard/header/DashboardHeader.tsx | 9 ++--
.../header/DashboardHeaderLogoutButton.tsx | 34 ++++++-------
src/modal/ConnectionModal.tsx | 49 ++++++++++++++----
12 files changed, 131 insertions(+), 46 deletions(-)
diff --git a/docs/modules/ROOT/pages/developer-guide/configuration.adoc b/docs/modules/ROOT/pages/developer-guide/configuration.adoc
index af9b9d071..fd448ae18 100644
--- a/docs/modules/ROOT/pages/developer-guide/configuration.adoc
+++ b/docs/modules/ROOT/pages/developer-guide/configuration.adoc
@@ -25,8 +25,10 @@ will look like this:
"standaloneDashboardName": "My Dashboard",
"standaloneDashboardDatabase": "dashboards",
"standaloneDashboardURL": "",
- "standaloneAllowLoad": true,
- "standaloneLoadFromOtherDatabases": false
+ "standaloneAllowLoad": false,
+ "standaloneLoadFromOtherDatabases": false,
+ "standaloneMultiDatabase": false,
+ "standaloneDatabaseList": "neo4j"
}
....
@@ -87,16 +89,32 @@ inside Neo4j and would like to run a standalone mode deployment with a
dashboard from a URL, set this parameter to the complete URL pointing to
the dashboard JSON.
-|standaloneAllowLoad |boolean |false |If set t yes the "Load Dashboard"
-button will be enabled in standalone mode, allowing users to load
-additional dashboards from Neo4J.
+|standaloneAllowLoad |boolean |false |If set to yes the "Load Dashboard"
+button will be enabled in standalone mode, allowing users to load
+additional dashboards from Neo4J. This parameter is false by default
+_unless you are using Neo4j Enterprise Edition_, which lets you use multiple
+databases.
*NOTE*: when Load is enabled in standalone mode, only Database is available
as a source, not file.
-|standaloneLoadFromOtherDatabases|boolean |false |If standaloneAllowLoad is
-set to true, this parmeter enables or not users to load dashboards from
-other databases than the one deifned in standaloneDashboardDatabase. If
-standaloneAllowLoad is set to false this parameters has no effect.
+|standaloneLoadFromOtherDatabases |boolean |false |If _standaloneAllowLoad_ is
+set to true, this parmeter enables or not users to load dashboards from
+other databases than the one deifned in _standaloneDashboardDatabase_. If
+_standaloneAllowLoad_ is set to false this parameters has no effect.
+
+|standaloneMultiDatabase |boolean |false |If this parameter set to true, the
+standalone configuration will ignore the _standaloneDatabase_ parameter and
+allow users to choose which database to connect to in the login screen, among
+the ones provided in _standaloneDatabaseList_, with a dropdown list. This
+parameter is false by default _unless you are using Neo4j Enterprise Edition_,
+which lets you use multiple databases.
+
+|standaloneDatabaseList |string |neo4j |If _standaloneMultiDatabase_ is
+set to true, this parmeter must contain a comma separated list of database
+names that will be displayed as options in the Database dropdown at user
+login (e.g. 'neo4j,database1,database2' will populate the database dropdown
+with the values 'neo4j','database1' and 'database2' in the connection screen).
+If _standaloneMultiDatabase_ is set to false this parameters has no effect.
|===
== Configuring SSO
@@ -139,7 +157,7 @@ be enabled by changing the `standalone` config parameter:
* If standalone mode is `false`, all other configuration parameters are
ignored. NeoDash will run in Editor mode, and require a manual sign-in.
* If standalone mode is `true`, NeoDash will read all configuration
-parameters. A *fixed dashboard* will be auto-loaded, and no changes to
+parameters. A *predefined dashboard* will be auto-loaded, and no changes to
the dashboard can be made. There are two types of valid standalone
deployments:
** A standalone deployment that *reads the fixed dashboard from Neo4j*.
@@ -147,3 +165,15 @@ The `standaloneDashboardName` and `standaloneDashboardDatabase` config
parameters are used to define these.
** A standalone deployment that *reads the fixed dashboard from a URL*.
The `standaloneDashboardURL` config parameter is used to define this.
+
+* Standalone mode can also be configured to allow users load a different
+dashboard after the predefined one is loaded (a `Load Dashboard` button
+will be displayed on the right side of dashboard title).
+The `standaloneAllowLoad` and `standaloneLoadFromOtherDatabases` are used
+to define this.
+* When allowing users to load dashboards dyamically in standalone mode,
+they may also need to connect to different databases, depending on the
+specific dashboard bing loaded. this can be enabled setting
+`standaloneMultiDatabase` to true and providing a comma separated list
+of the allowed database names in the`standaloneDatabaseList` parameter.
+
diff --git a/docs/modules/ROOT/pages/developer-guide/standalone-mode.adoc b/docs/modules/ROOT/pages/developer-guide/standalone-mode.adoc
index 1259143ed..6a5392e6d 100644
--- a/docs/modules/ROOT/pages/developer-guide/standalone-mode.adoc
+++ b/docs/modules/ROOT/pages/developer-guide/standalone-mode.adoc
@@ -47,6 +47,11 @@ docker run -it --rm -p 5005:5005 \
-e standaloneDatabase="neo4j" \
-e standaloneDashboardName="My Dashboard" \
-e standaloneDashboardDatabase="dashboards" \
+ -e standaloneDashboardURL="dashboards" \
+ -e standaloneAllowLoad=false \
+ -e standaloneLoadFromOtherDatabases=false \
+ -e standaloneMultiDatabase=false \
+ -e standaloneDatabaseList="neo4j" \
neo4jlabs/neodash
....
diff --git a/docs/modules/ROOT/pages/developer-guide/state-management.adoc b/docs/modules/ROOT/pages/developer-guide/state-management.adoc
index 78ff4aa74..653d4148e 100644
--- a/docs/modules/ROOT/pages/developer-guide/state-management.adoc
+++ b/docs/modules/ROOT/pages/developer-guide/state-management.adoc
@@ -134,8 +134,11 @@ standalone mode.
"standaloneDatabase": "neo4j",
"standaloneDashboardName": "My Dashboard",
"standaloneDashboardDatabase": "dashboards",
+ "standaloneDashboardURL": "dashboards",
"standaloneAllowLoad": false,
"standaloneLoadFromOtherDatabases ": false,
+ "standaloneMultiDatabase": false,
+ "standaloneDatabaseList": "neo4j",
"notificationIsDismissable": null
}
....
diff --git a/public/config.json b/public/config.json
index 762820f28..9db04f5fa 100644
--- a/public/config.json
+++ b/public/config.json
@@ -10,5 +10,8 @@
"standaloneDashboardDatabase": "dashboards",
"standaloneDashboardURL": "",
"standaloneAllowLoad": false,
- "standaloneLoadFromOtherDatabases": false
+ "standaloneLoadFromOtherDatabases": false,
+ "standaloneMultiDatabase": false,
+ "standaloneDatabaseList": "neo4j"
+
}
diff --git a/scripts/config-entrypoint.sh b/scripts/config-entrypoint.sh
index de2fc22b4..74297829e 100644
--- a/scripts/config-entrypoint.sh
+++ b/scripts/config-entrypoint.sh
@@ -17,5 +17,7 @@ echo " \
\"standaloneDashboardDatabase\": \"${standaloneDashboardDatabase:='neo4j'}\", \
\"standaloneDashboardURL\": \"${standaloneDashboardURL:=}\", \
\"standaloneAllowLoad\": \"${standaloneAllowLoad:=false}\", \
- \"standaloneLoadFromOtherDatabases\": \"${standaloneLoadFromOtherDatabases:=false}\" \
+ \"standaloneLoadFromOtherDatabases\": \"${standaloneLoadFromOtherDatabases:=false}\", \
+ \"standaloneMultiDatabase\": ${standaloneMultiDatabase:=false}\", \
+ \"standaloneDatabaseList\": ${standaloneDatabaseList:='neo4j'}\" \
}" > /usr/share/nginx/html/config.json
diff --git a/src/application/ApplicationActions.ts b/src/application/ApplicationActions.ts
index 296cdaac4..91b7fbb1c 100644
--- a/src/application/ApplicationActions.ts
+++ b/src/application/ApplicationActions.ts
@@ -145,7 +145,9 @@ export const setStandaloneEnabled = (
standaloneUsername: string,
standalonePassword: string,
standaloneAllowLoad: boolean,
- standaloneLoadFromOtherDatabases: boolean
+ standaloneLoadFromOtherDatabases: boolean,
+ standaloneMultiDatabase: boolean,
+ standaloneDatabaseList: string
) => ({
type: SET_STANDALONE_ENABLED,
payload: {
@@ -161,6 +163,8 @@ export const setStandaloneEnabled = (
standalonePassword,
standaloneAllowLoad,
standaloneLoadFromOtherDatabases,
+ standaloneMultiDatabase,
+ standaloneDatabaseList,
},
});
diff --git a/src/application/ApplicationReducer.ts b/src/application/ApplicationReducer.ts
index 6c8ad2338..3ddb6a004 100644
--- a/src/application/ApplicationReducer.ts
+++ b/src/application/ApplicationReducer.ts
@@ -135,7 +135,9 @@ export const applicationReducer = (state = initialState, action: { type: any; pa
standaloneUsername,
standalonePassword,
standaloneAllowLoad,
- standaloneLoadFromOtherDatabases
+ standaloneLoadFromOtherDatabases,
+ standaloneMultiDatabase,
+ standaloneDatabaseList,
} = payload;
state = update(state, {
standalone: standalone,
@@ -150,6 +152,8 @@ export const applicationReducer = (state = initialState, action: { type: any; pa
standalonePassword: standalonePassword,
standaloneAllowLoad: standaloneAllowLoad,
standaloneLoadFromOtherDatabases: standaloneLoadFromOtherDatabases,
+ standaloneMultiDatabase: standaloneMultiDatabase,
+ standaloneDatabaseList: standaloneDatabaseList,
});
return state;
}
diff --git a/src/application/ApplicationSelectors.ts b/src/application/ApplicationSelectors.ts
index 81223fce5..f651dd42c 100644
--- a/src/application/ApplicationSelectors.ts
+++ b/src/application/ApplicationSelectors.ts
@@ -83,6 +83,8 @@ export const applicationGetStandaloneSettings = (state: any) => {
standalonePassword: state.application.standalonePassword,
standaloneAllowLoad: state.application.standaloneAllowLoad,
standaloneLoadFromOtherDatabases: state.application.standaloneLoadFromOtherDatabases,
+ standaloneMultiDatabase: state.application.standaloneMultiDatabase,
+ standaloneDatabaseList: state.application.standaloneDatabaseList,
};
};
diff --git a/src/application/ApplicationThunks.ts b/src/application/ApplicationThunks.ts
index e9661edcb..e671122e6 100644
--- a/src/application/ApplicationThunks.ts
+++ b/src/application/ApplicationThunks.ts
@@ -351,6 +351,8 @@ export const loadApplicationConfigThunk = () => async (dispatch: any, getState:
standaloneDashboardURL: '',
standaloneAllowLoad: false,
standaloneLoadFromOtherDatabases: false,
+ standaloneMultiDatabase: false,
+ standaloneDatabaseList: 'neo4j',
};
try {
config = await (await fetch('config.json')).json();
@@ -395,6 +397,8 @@ export const loadApplicationConfigThunk = () => async (dispatch: any, getState:
config.standalonePassword,
config.standaloneAllowLoad,
config.standaloneLoadFromOtherDatabases,
+ config.standaloneMultiDatabase,
+ config.standaloneDatabaseList,
)
);
dispatch(setConnectionModalOpen(false));
diff --git a/src/dashboard/header/DashboardHeader.tsx b/src/dashboard/header/DashboardHeader.tsx
index a218bc4be..b981540c3 100644
--- a/src/dashboard/header/DashboardHeader.tsx
+++ b/src/dashboard/header/DashboardHeader.tsx
@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import { setDashboardTitle } from '../DashboardActions';
import { getDashboardSettings, getDashboardTheme, getDashboardTitle, getPages } from '../DashboardSelectors';
import { setConnectionModalOpen } from '../../application/ApplicationActions';
-import { applicationIsStandalone } from '../../application/ApplicationSelectors';
+import { applicationGetStandaloneSettings } from '../../application/ApplicationSelectors';
import { getDashboardIsEditable, getPageNumber } from '../../settings/SettingsSelectors';
import { NeoDashboardHeaderLogo } from './DashboardHeaderLogo';
import NeoAboutButton from './DashboardHeaderAboutButton';
@@ -15,7 +15,7 @@ import { DASHBOARD_HEADER_BUTTON_COLOR } from '../../config/ApplicationConfig';
import { Tooltip } from '@mui/material';
export const NeoDashboardHeader = ({
- standalone,
+ standaloneSettings,
dashboardTitle,
connection,
settings,
@@ -45,7 +45,6 @@ export const NeoDashboardHeader = ({
useEffect(() => {
setTheme(isDarkMode ? 'dark' : 'light');
}, [isDarkMode]);
-
const content = (
diff --git a/src/modal/ConnectionModal.tsx b/src/modal/ConnectionModal.tsx
index 81d52b41c..d31063ac0 100644
--- a/src/modal/ConnectionModal.tsx
+++ b/src/modal/ConnectionModal.tsx
@@ -2,6 +2,7 @@ import React, { useEffect } from 'react';
import { SSOLoginButton } from '../component/sso/SSOLoginButton';
import { Button, Dialog, Switch, TextInput, Dropdown, TextLink } from '@neo4j-ndl/react';
import { PlayIconOutline } from '@neo4j-ndl/react/icons';
+
/**
* Configures setting the current Neo4j database connection for the dashboard.
*/
@@ -25,6 +26,7 @@ export default function NeoConnectionModal({
const [username, setUsername] = React.useState(connection.username);
const [password, setPassword] = React.useState(connection.password);
const [database, setDatabase] = React.useState(connection.database);
+ const [standaloneDatabase, setStandaloneDatabases] = React.useState([standaloneSettings.standalone? standaloneSettings.standaloneDatabase : 'neo4j']);
// Make sure local vars are updated on external connection updates.
useEffect(() => {
@@ -151,8 +153,10 @@ export default function NeoConnectionModal({
label='Database'
type='select'
selectProps={{
- onChange: (newValue) => {setDatabase(newValue.value);},
- //if application is running standalone and standaloneLoadFromOtherDatabases is not enabled, we do not allow changing database
+ onChange: (newValue) => {
+ setDatabase(newValue.value);
+ setStandaloneDatabases(newValue.value);
+ },
options: databaseList.map((option) => ({
label: option,
value: option,
From a0f06e49cb85243d41f4f775d40e03450bb947e9 Mon Sep 17 00:00:00 2001
From: BlackRaven
Date: Fri, 13 Oct 2023 01:18:37 -0400
Subject: [PATCH 18/36] added useffect in card.tsx to save DB
---
src/card/Card.tsx | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/card/Card.tsx b/src/card/Card.tsx
index fe6ffe0d9..4e14d7aea 100644
--- a/src/card/Card.tsx
+++ b/src/card/Card.tsx
@@ -54,6 +54,7 @@ const NeoCard = ({
onDatabaseChanged, // action to take when the user changes the database related to the card
loadDatabaseListFromNeo4j, // Thunk to get the list of databases
createNotification, // Thunk to create a global notification pop-up.
+ saveDatabase, // added to ensure the database is always saved in the session as soon as the card is created (and added in the dahsboard JSON)
}) => {
// Will be used to fetch the list of current databases
const { driver } = useContext(Neo4jContext);
@@ -117,6 +118,10 @@ const NeoCard = ({
setCollapseTimeout(report.collapseTimeout);
}, [report.collapseTimeout]);
+ useEffect(() => {
+ saveDatabase(id, database);
+ }, [database]);
+
// TODO - get rid of some of the props-drilling here...
const component = (