Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/8raven #705

Merged
merged 48 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
c86a444
Title not editable in standalone mode
8Rav3n Aug 24, 2023
f17cc9a
standalone load v1 (working)
8Rav3n Aug 25, 2023
94dc1f8
load from database refinements with new conf var
8Rav3n Aug 28, 2023
9e5e109
config.json reset to defaults
8Rav3n Aug 28, 2023
ceda481
first implementation - needs few refinements
8Rav3n Aug 29, 2023
bdfeaca
index on feature/log: ceda481c first implementation - needs few refin…
8Rav3n Aug 30, 2023
7ca55af
On feature/log: temp stash
8Rav3n Aug 30, 2023
3551f2e
added Tooltip for Save button in standalone mode
8Rav3n Aug 30, 2023
a826d1a
polished
8Rav3n Aug 30, 2023
15fac3e
fix on error notification
8Rav3n Aug 31, 2023
7b88f4e
minor refinement in documentation
8Rav3n Aug 31, 2023
f6f4471
Merge pull request #1 from 8Rav3n/feature/readonly
8Rav3n Aug 31, 2023
8204105
Merge branch 'fork-release' into feature/log
8Rav3n Aug 31, 2023
fdb38c7
Merge pull request #2 from 8Rav3n/feature/log
8Rav3n Aug 31, 2023
7f97533
hide logout button in standalone mode
8Rav3n Aug 31, 2023
f6e1a3a
man merge d137081cfde4b2d5dcf1192b8a9be675e953bd0b
8Rav3n Aug 31, 2023
ff6b05a
man chg 0484e44ed345e8a9008fcebc8753ddf881f038f1
8Rav3n Sep 1, 2023
bccc090
added configuration to allow multiple data DBs
8Rav3n Sep 8, 2023
5f1c206
standalone connect to multiple DBs
8Rav3n Sep 8, 2023
67e5921
fix on config-entrypoint and reorder parameters
8Rav3n Sep 8, 2023
610af3c
bugfix on config-entrypoint.sh
8Rav3n Sep 20, 2023
aaa6bbd
fix to update standaloneDB for standaloneMultiDB
8Rav3n Sep 27, 2023
a0f06e4
added useffect in card.tsx to save DB
8Rav3n Oct 13, 2023
d930e38
query modified in saveDashboardThunks
8Rav3n Oct 13, 2023
118d21a
updated config-entrypoint
8Rav3n Oct 13, 2023
e57d8aa
added config parameter to set cusom Header
8Rav3n Oct 13, 2023
f5f6546
Merge branch 'feature/persistLabels' into fork-release
8Rav3n Oct 13, 2023
061f0f4
Merge branch 'feature/styleConfigInDocker' into fork-release
8Rav3n Oct 13, 2023
b642bbe
Merge branch 'feature/graphDatabase' into fork-release
8Rav3n Oct 13, 2023
2dc5484
documentation
8Rav3n Oct 13, 2023
f6eb901
Documenttion update merge
8Rav3n Oct 13, 2023
13af4c6
fix dirt in style.config
8Rav3n Oct 13, 2023
7a02432
merge fix
8Rav3n Oct 13, 2023
821c06f
fix dirt in config.json
8Rav3n Oct 13, 2023
f7dfa85
fix merge
8Rav3n Oct 13, 2023
f3a234d
Update ApplicationConfig.ts fix dirt
8Rav3n Oct 13, 2023
5d30622
moving logging logic to its own reducer
alfredorubin96 Nov 14, 2023
6c21e5a
fixing new selector and small refactorings
alfredorubin96 Nov 20, 2023
3a43fab
cleaning code and testing standalone
alfredorubin96 Nov 20, 2023
06c0ba7
adding database list check
alfredorubin96 Nov 21, 2023
46a15ba
changing version to 3.18 to address address Cve-2023-4863 and cve-202…
alfredorubin96 Nov 21, 2023
0e865fd
Merge branch 'fork-release' of https://github.com/8Rav3n/neodash into…
alfredorubin96 Nov 21, 2023
7f9e5a8
removing unused imports
alfredorubin96 Nov 21, 2023
710294b
working on final release
alfredorubin96 Nov 21, 2023
cf1c1a4
fixed dashboards sidebar error when the db doesn't contain any dashbo…
alfredorubin96 Nov 21, 2023
5a95e1d
removing useless import
alfredorubin96 Nov 21, 2023
172dd1c
removing change in runCypherQuery and reusing the status of the query…
alfredorubin96 Nov 24, 2023
bdb5711
removing change in runCypherQuery and reusing the status of the query…
alfredorubin96 Nov 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion docs/modules/ROOT/pages/developer-guide/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ will look like this:
"standaloneDatabase": "neo4j",
"standaloneDashboardName": "My Dashboard",
"standaloneDashboardDatabase": "dashboards",
"standaloneDashboardURL": ""
"standaloneDashboardURL": "",
"standaloneAllowLoad": true,
"standaloneLoadFromOtherDatabases": false
}
....

Expand Down Expand Up @@ -84,6 +86,17 @@ 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 |false |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.

|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.
|===

== Configuring SSO
Expand Down
2 changes: 2 additions & 0 deletions docs/modules/ROOT/pages/developer-guide/state-management.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ standalone mode.
"standaloneDatabase": "neo4j",
"standaloneDashboardName": "My Dashboard",
"standaloneDashboardDatabase": "dashboards",
"standaloneAllowLoad": false,
"standaloneLoadFromOtherDatabases ": false,
"notificationIsDismissable": null
}
....
4 changes: 3 additions & 1 deletion public/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@
"standaloneDatabase": "neo4j",
"standaloneDashboardName": "My Dashboard",
"standaloneDashboardDatabase": "dashboards",
"standaloneDashboardURL": ""
"standaloneDashboardURL": "",
"standaloneAllowLoad": false,
"standaloneLoadFromOtherDatabases": false
}
4 changes: 3 additions & 1 deletion scripts/config-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ echo " \
\"standalonePassword\": \"${standalonePassword:=}\", \
\"standaloneDashboardName\": \"${standaloneDashboardName:='My Dashboard'}\", \
\"standaloneDashboardDatabase\": \"${standaloneDashboardDatabase:='neo4j'}\", \
\"standaloneDashboardURL\": \"${standaloneDashboardURL:=}\" \
\"standaloneDashboardURL\": \"${standaloneDashboardURL:=}\", \
\"standaloneAllowLoad\": \"${standaloneAllowLoad:=false}\", \
\"standaloneLoadFromOtherDatabases\": \"${standaloneLoadFromOtherDatabases:=false}\" \
}" > /usr/share/nginx/html/config.json
6 changes: 5 additions & 1 deletion src/application/ApplicationActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ export const setStandaloneEnabled = (
standaloneDashboardDatabase: string,
standaloneDashboardURL: string,
standaloneUsername: string,
standalonePassword: string
standalonePassword: string,
standaloneAllowLoad: boolean,
standaloneLoadFromOtherDatabases: boolean
) => ({
type: SET_STANDALONE_ENABLED,
payload: {
Expand All @@ -157,6 +159,8 @@ export const setStandaloneEnabled = (
standaloneDashboardURL,
standaloneUsername,
standalonePassword,
standaloneAllowLoad,
standaloneLoadFromOtherDatabases,
},
});

Expand Down
4 changes: 4 additions & 0 deletions src/application/ApplicationReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ export const applicationReducer = (state = initialState, action: { type: any; pa
standaloneDashboardURL,
standaloneUsername,
standalonePassword,
standaloneAllowLoad,
standaloneLoadFromOtherDatabases
} = payload;
state = update(state, {
standalone: standalone,
Expand All @@ -146,6 +148,8 @@ export const applicationReducer = (state = initialState, action: { type: any; pa
standaloneDashboardURL: standaloneDashboardURL,
standaloneUsername: standaloneUsername,
standalonePassword: standalonePassword,
standaloneAllowLoad: standaloneAllowLoad,
standaloneLoadFromOtherDatabases: standaloneLoadFromOtherDatabases,
});
return state;
}
Expand Down
2 changes: 2 additions & 0 deletions src/application/ApplicationSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ export const applicationGetStandaloneSettings = (state: any) => {
standaloneDashboardURL: state.application.standaloneDashboardURL,
standaloneUsername: state.application.standaloneUsername,
standalonePassword: state.application.standalonePassword,
standaloneAllowLoad: state.application.standaloneAllowLoad,
standaloneLoadFromOtherDatabases: state.application.standaloneLoadFromOtherDatabases,
};
};

Expand Down
6 changes: 5 additions & 1 deletion src/application/ApplicationThunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,8 @@ export const loadApplicationConfigThunk = () => async (dispatch: any, getState:
standaloneDashboardName: 'My Dashboard',
standaloneDashboardDatabase: 'dashboards',
standaloneDashboardURL: '',
standaloneAllowLoad: false,
standaloneLoadFromOtherDatabases: false,
};
try {
config = await (await fetch('config.json')).json();
Expand Down Expand Up @@ -390,7 +392,9 @@ export const loadApplicationConfigThunk = () => async (dispatch: any, getState:
config.standaloneDashboardDatabase,
config.standaloneDashboardURL,
config.standaloneUsername,
config.standalonePassword
config.standalonePassword,
config.standaloneAllowLoad,
config.standaloneLoadFromOtherDatabases,
)
);
dispatch(setConnectionModalOpen(false));
Expand Down
28 changes: 16 additions & 12 deletions src/dashboard/header/DashboardTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -21,7 +21,7 @@ export const NeoDashboardTitle = ({
dashboardTitle,
setDashboardTitle,
editable,
isStandalone,
standaloneSettings,
dashboardSettings,
extensions,
updateDashboardSetting,
Expand Down Expand Up @@ -70,7 +70,8 @@ export const NeoDashboardTitle = ({
return (
<div className='n-flex n-flex-row n-flex-wrap n-justify-between n-items-center'>
{/* 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 && !standaloneSettings.standalone ? (
<div className={'n-flex n-flex-row n-flex-wrap n-justify-between n-items-center'}>
<TextInput
autoFocus={true}
Expand Down Expand Up @@ -99,7 +100,7 @@ export const NeoDashboardTitle = ({
</IconButton>
</Tooltip>
</div>
) : (
) : !standaloneSettings.standalone? ( /* out of edit mode - if Not Standalone we display the edit button */
<div className={'n-flex n-flex-row n-flex-wrap n-justify-between n-items-center'}>
<Typography variant='h3'>{dashboardTitle}</Typography>
<Tooltip title={'Edit'} disableInteractive>
Expand All @@ -118,11 +119,15 @@ export const NeoDashboardTitle = ({
)}
</Tooltip>
</div>
):( /* if we are in Standalone just title is displayed with no edit button */
<div className={'n-flex n-flex-row n-flex-wrap n-justify-between n-items-center'}>
<Typography variant='h3'>{dashboardTitle}</Typography>
</div>
)}
{/* If the app is not running in standalone mode (i.e. in edit mode) always show dashboard settings. */}
{!isStandalone ? (
{!standaloneSettings.standalone ? (
<div className='flex flex-row flex-wrap items-center gap-2'>
{editable ? <NeoExtensionsModal closeMenu={handleSettingsMenuClose} /> : <></>}
{(editable && !standaloneSettings.standalone) ? <NeoExtensionsModal closeMenu={handleSettingsMenuClose} /> : <></>}
<IconButton aria-label='Dashboard actions' onClick={handleSettingsMenuOpen}>
<EllipsisHorizontalIconOutline />
</IconButton>
Expand Down Expand Up @@ -153,23 +158,22 @@ export const NeoDashboardTitle = ({
<NeoShareModal />
{renderExtensionsButtons()}
</>
) : (
<></>
) : ( /* in standalone we allow load is standaloneAllowLoad parameter is enabled */
<></>
)}
</MenuItems>
</Menu>
</div>
) : (
<></>
)}
) : standaloneSettings.standaloneAllowLoad ? <NeoLoadModal /> : <></>
}
</div>
);
};

const mapStateToProps = (state) => ({
dashboardTitle: getDashboardTitle(state),
editable: getDashboardIsEditable(state),
isStandalone: applicationIsStandalone(state),
standaloneSettings: applicationGetStandaloneSettings(state),
dashboardSettings: getDashboardSettings(state),
extensions: getDashboardExtensions(state),
connection: applicationGetConnection(state),
Expand Down
39 changes: 31 additions & 8 deletions src/modal/LoadModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,39 @@ 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 { applicationGetStandaloneSettings, applicationIsStandalone } from '../application/ApplicationSelectors';
import { Tooltip } from '@mui/material';

/**
* 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 = ({
loadDashboard,
loadDatabaseListFromNeo4j,
loadDashboardFromNeo4j,
loadDashboardListFromNeo4j,
isStandalone,
standaloneSettings
}) => {
const [loadModalOpen, setLoadModalOpen] = React.useState(false);
const [loadFromNeo4jModalOpen, setLoadFromNeo4jModalOpen] = React.useState(false);
const [text, setText] = React.useState('');
const [rows, setRows] = React.useState([]);
const { driver } = useContext<Neo4jContextState>(Neo4jContext);
const [dashboardDatabase, setDashboardDatabase] = React.useState('neo4j');
const [databases, setDatabases] = React.useState(['neo4j']);
//database values are initialized using standalone settings if the app is running in standalone mode
const [dashboardDatabase, setDashboardDatabase] = React.useState(standaloneSettings.standalone ? standaloneSettings.standaloneDashboardDatabase : 'neo4j');
const [databases, setDatabases] = React.useState([standaloneSettings.standalone? standaloneSettings.standaloneDatabase : 'neo4j']);
const loadFromFile = useRef(null);

const handleClickOpen = () => {
Expand Down Expand Up @@ -97,7 +104,17 @@ export const NeoLoadModal = ({

return (
<>
<MenuItem title='Load' onClick={handleClickOpen} icon={<CloudArrowUpIconOutline />} />
{!isStandalone?
(
<MenuItem title='Load' onClick={handleClickOpen} icon={<CloudArrowUpIconOutline />} />
):(
<Tooltip title={'Load Dashboard'}>
<IconButton className='n-mx-1' aria-label='Extensions' onClick={handleClickOpen}>
<CloudArrowUpIconOutline />
</IconButton>
</Tooltip>
)
}

<Dialog size='large' open={loadModalOpen == true} onClose={handleClose} aria-labelledby='form-dialog-title'>
<Dialog.Header id='form-dialog-title'>
Expand All @@ -123,6 +140,7 @@ export const NeoLoadModal = ({
Select from Neo4j
<DatabaseAddCircleIcon className='btn-icon-base-r' />
</Button>
{!isStandalone ?
<Button
onClick={() => {
loadFromFile.current.click();
Expand All @@ -135,8 +153,8 @@ export const NeoLoadModal = ({
<input type='file' ref={loadFromFile} onChange={(e) => uploadDashboard(e)} hidden />
Select From File
<DocumentPlusIconOutline className='btn-icon-base-r' />
</Button>

</Button> : <></>
}
<Button
onClick={text.length > 0 ? handleCloseAndLoad : null}
style={{
Expand Down Expand Up @@ -198,6 +216,8 @@ export const NeoLoadModal = ({
setRows(result);
});
},
//if application is running standalone and standaloneLoadFromOtherDatabases is not enabled, we do not allow changing database
isDisabled: standaloneSettings.standalone&&!standaloneSettings.standaloneLoadFromOtherDatabases?true:false,
options: databases.map((database) => ({ label: database, value: database })),
value: { label: dashboardDatabase, value: dashboardDatabase },
menuPlacement: 'auto',
Expand All @@ -210,7 +230,10 @@ export const NeoLoadModal = ({
);
};

const mapStateToProps = () => ({});
const mapStateToProps = (state) => ({
isStandalone: applicationIsStandalone(state),
standaloneSettings: applicationGetStandaloneSettings(state),
});

const mapDispatchToProps = (dispatch) => ({
loadDashboard: (text) => dispatch(loadDashboardThunk(text)),
Expand Down