diff --git a/.github/workflows/develop-deployment.yml b/.github/workflows/develop-deployment.yml index c2a43f7d3..e8479f292 100644 --- a/.github/workflows/develop-deployment.yml +++ b/.github/workflows/develop-deployment.yml @@ -31,7 +31,7 @@ jobs: uses: cypress-io/github-action@v4 with: build: yarn run build - start: yarn run dev + start: yarn run prod wait-on: "http://localhost:3000" browser: chrome build-s3: diff --git a/.github/workflows/develop-test.yml b/.github/workflows/develop-test.yml index 7a49bd807..a60d505cc 100644 --- a/.github/workflows/develop-test.yml +++ b/.github/workflows/develop-test.yml @@ -31,7 +31,7 @@ jobs: uses: cypress-io/github-action@v4 with: build: yarn run build - start: yarn run dev + start: yarn run prod wait-on: 'http://localhost:3000' browser: chrome - name: Upload coverage reports to Codecov diff --git a/.github/workflows/master-deployment.yml b/.github/workflows/master-deployment.yml index 535890aec..06c1d1087 100644 --- a/.github/workflows/master-deployment.yml +++ b/.github/workflows/master-deployment.yml @@ -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.3.4 + tags: ${{ secrets.DOCKER_HUB_LABS_USERNAME }}/neodash:latest,${{ secrets.DOCKER_HUB_LABS_USERNAME }}/neodash:2.3.5 build-docker-legacy: needs: build-test runs-on: neodash-runners @@ -103,7 +103,7 @@ jobs: context: . file: ./Dockerfile push: true - tags: ${{ secrets.DOCKER_HUB_USERNAME }}/neodash:latest,${{ secrets.DOCKER_HUB_USERNAME }}/neodash:2.3.4 + tags: ${{ secrets.DOCKER_HUB_USERNAME }}/neodash:latest,${{ secrets.DOCKER_HUB_USERNAME }}/neodash:2.3.5 deploy-gallery: runs-on: neodash-runners strategy: diff --git a/Dockerfile b/Dockerfile index 912fcd034..c31f51ae8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,4 +43,4 @@ USER nginx EXPOSE $NGINX_PORT HEALTHCHECK cmd curl --fail "http://localhost:$NGINX_PORT" || exit 1 -LABEL version="2.3.4" +LABEL version="2.3.5" diff --git a/changelog.md b/changelog.md index 5a98bd8ee..1e203fa53 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,17 @@ +## NeoDash 2.3.5 +This is a bugfix / stability release directly following 2.3.4. + +Improvements: +- Fixed issue where orphan relationships prevented graph charts from working ([@BennuFire](https://github.com/BennuFire), [#586](https://github.com/neo4j-labs/neodash/pull/586)) +- Fix issue where only one style rule was used a time on tables. ([@BennuFire](https://github.com/BennuFire), [#632](https://github.com/neo4j-labs/neodash/pull/632)) +- Added information about source and target on Graph Chart information modal . ([@BennuFire](https://github.com/BennuFire), [#627](https://github.com/neo4j-labs/neodash/pull/627)) Based on [@brahmprakashMishra](https://github.com/brahmprakashMishra) PR +- Fixed issue where bar charts where displaying black bars instead of scheme colors. ([@BennuFire](https://github.com/BennuFire), [#626](https://github.com/neo4j-labs/neodash/pull/626)) +- Added right subpath replacement on shared links redirection while in self deployments. ([@m-o-n-i-s-h](https://github.com/m-o-n-i-s-h), [#618](https://github.com/neo4j-labs/neodash/pull/618)) +- Dark theme tweaks. ([@BennuFire](https://github.com/BennuFire), [#585](https://github.com/neo4j-labs/neodash/pull/585)) +- Fixed parameter selector search where numbers were not found and sporadically displayed with decimal points. ([@BennuFire](https://github.com/BennuFire), [#633](https://github.com/neo4j-labs/neodash/pull/633)) +- Added a configuration in order to list sso providers to be used whenever a database has more than one configured. ([@BennuFire](https://github.com/BennuFire), [#624](https://github.com/neo4j-labs/neodash/pull/624)) +- Added 'Ignore undefined parameters' advanced setting support for optional parameters on a query. Now queries will assume a null value instead of returning the error 'Parameter not defined'. ([@BennuFire](https://github.com/BennuFire), [#625](https://github.com/neo4j-labs/neodash/pull/625)) + ## NeoDash 2.3.3 & 2.3.4 This is a bugfix / stability release directly following 2.3.2. diff --git a/cypress.config.ts b/cypress.config.ts index 2678d3e84..73948909e 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -13,7 +13,7 @@ export default defineConfig({ }, retries: { runMode: 2, - openMode: 0, + openMode: 2, }, }, env: { diff --git a/docs/modules/ROOT/pages/developer-guide/configuration.adoc b/docs/modules/ROOT/pages/developer-guide/configuration.adoc index 6df3fdfba..a56946281 100644 --- a/docs/modules/ROOT/pages/developer-guide/configuration.adoc +++ b/docs/modules/ROOT/pages/developer-guide/configuration.adoc @@ -16,6 +16,7 @@ will look like this: .... { "ssoEnabled": false, + "ssoProviders": [], "ssoDiscoveryUrl": "https://example.com", "standalone": false, "standaloneProtocol": "neo4j", @@ -37,6 +38,8 @@ will look like this: using SSO. This requires the app to be running in standalone mode, and a valid ssoDiscoveryUrl to be set. +|ssoProviders |List |[] |When using multiple SSO providers on the database, you can configure the list of providers (by id) to be used on Neodash. If empty, all providers will be displayed. + |ssoDiscoveryUrl |string |https://example.com |If ssoEnabled is true & standalone mode is enabled, the URL to retrieve SSO auth config from. diff --git a/docs/modules/ROOT/pages/developer-guide/deploy-a-build.adoc b/docs/modules/ROOT/pages/developer-guide/deploy-a-build.adoc index 9454c7168..72942f3a1 100644 --- a/docs/modules/ROOT/pages/developer-guide/deploy-a-build.adoc +++ b/docs/modules/ROOT/pages/developer-guide/deploy-a-build.adoc @@ -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.3.4 username@host:/usr/share/nginx/html +scp neodash-2.3.5 username@host:/usr/share/nginx/html ``` NeoDash should now be visible by visiting your (sub)domain in the browser. diff --git a/docs/modules/ROOT/pages/developer-guide/standalone-mode.adoc b/docs/modules/ROOT/pages/developer-guide/standalone-mode.adoc index 1259143ed..b40bda419 100644 --- a/docs/modules/ROOT/pages/developer-guide/standalone-mode.adoc +++ b/docs/modules/ROOT/pages/developer-guide/standalone-mode.adoc @@ -39,6 +39,7 @@ variables to Docker: .... docker run -it --rm -p 5005:5005 \ -e ssoEnabled=false \ + -e ssoProviders=[] \ -e ssoDiscoveryUrl="https://example.com" \ -e standalone=true \ -e standaloneProtocol="neo4j" \ diff --git a/docs/modules/ROOT/pages/developer-guide/state-management.adoc b/docs/modules/ROOT/pages/developer-guide/state-management.adoc index c7513269d..231f98483 100644 --- a/docs/modules/ROOT/pages/developer-guide/state-management.adoc +++ b/docs/modules/ROOT/pages/developer-guide/state-management.adoc @@ -127,6 +127,7 @@ standalone mode. "standalone": false, "oldDashboard": null, "ssoEnabled": false, + "ssoProviders": [], "ssoDiscoveryUrl": "https://example.com", "standaloneProtocol": "neo4j", "standaloneHost": "localhost", diff --git a/docs/modules/ROOT/pages/quickstart.adoc b/docs/modules/ROOT/pages/quickstart.adoc index f4872cc27..fea4b67ad 100644 --- a/docs/modules/ROOT/pages/quickstart.adoc +++ b/docs/modules/ROOT/pages/quickstart.adoc @@ -8,7 +8,7 @@ https://neodash.graphapp.io. App Gallery]. . Using Docker: ``` -docker pull neo4jlabs/neodash:latest +docker pull neo4jlabs/neodash:latest docker run -it --rm -p 5005:5005 neo4jlabs/neodash ``` diff --git a/docs/modules/ROOT/pages/user-guide/reports/pie-chart.adoc b/docs/modules/ROOT/pages/user-guide/reports/pie-chart.adoc index e5979b32f..9300388a7 100644 --- a/docs/modules/ROOT/pages/user-guide/reports/pie-chart.adoc +++ b/docs/modules/ROOT/pages/user-guide/reports/pie-chart.adoc @@ -49,6 +49,8 @@ the pie slices in order of size. |Show Values in Slices |on/off |off |If enabled, show the category values inside the pie slices. +|Labels font Size |Number |13 |Define the size of the font for internal and external labels on the pie. + |Show categories next to Slices |on/off |off |If enabled, show the category values next to the pie slices. @@ -73,13 +75,13 @@ slice. |Margin Left (px) |number |50 |The margin in pixels on the left side of the visualization. -|Margin Right (px) |number |24 |The margin in pixels on the right side +|Margin Right (px) |number |50 |The margin in pixels on the right side of the visualization. -|Margin Top (px) |number |24 |The margin in pixels on the top side of +|Margin Top (px) |number |50 |The margin in pixels on the top side of the visualization. -|Margin Bottom (px) |number |40 |The margin in pixels on the bottom side +|Margin Bottom (px) |number |50 |The margin in pixels on the bottom side of the visualization. |Hide Selections |on/off |off |If enabled, hides the property selector diff --git a/package.json b/package.json index 414c889b7..b430ce577 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "neodash", - "version": "2.3.4", + "version": "2.3.5", "description": "NeoDash - Neo4j Dashboard Builder", "neo4jDesktop": { "apiVersion": "^1.2.0" @@ -22,6 +22,7 @@ ], "scripts": { "dev": "yarn webpack-dev-server --mode development", + "prod": "yarn webpack-dev-server --mode production", "debug": "yarn --node-options='--inspect' webpack-dev-server --mode development", "build": "yarn webpack --mode production --env production && cp -r public/* dist/", "build-minimal": "yarn webpack --mode production --env production && cp -r public/* dist/", @@ -43,8 +44,8 @@ "@mui/x-data-grid": "5.17.26", "@mui/x-date-pickers": "^5.0.17", "@neo4j-cypher/react-codemirror": "^1.0.3", - "@neo4j-ndl/base": "1.10.1", - "@neo4j-ndl/react": "1.10.2", + "@neo4j-ndl/base": "1.10.3", + "@neo4j-ndl/react": "1.10.8", "@nivo/bar": "^0.83.0", "@nivo/circle-packing": "^0.83.0", "@nivo/core": "^0.83.0", @@ -67,6 +68,7 @@ "leaflet": "^1.7.1", "lodash.debounce": "^4.0.8", "lodash.isequal": "^4.5.0", + "lodash.merge": "^4.6.2", "mui-color": "^2.0.0-beta.2", "mui-nested-menu": "^3.2.1", "neo4j-client-sso": "^1.2.2", @@ -116,7 +118,7 @@ "babel-loader": "^8.2.3", "babel-plugin-istanbul": "^6.1.1", "css-loader": "^3.6.0", - "cypress": "^10.11.0", + "cypress": "^12.17.4", "eslint": "^8.26.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-import": "^2.26.0", diff --git a/public/config.json b/public/config.json index 6a203041f..17754d56b 100644 --- a/public/config.json +++ b/public/config.json @@ -1,5 +1,6 @@ { "ssoEnabled": false, + "ssoProviders": [], "ssoDiscoveryUrl": "https://example.com", "standalone": false, "standaloneProtocol": "neo4j", diff --git a/public/index.html b/public/index.html index 0c9cc4dd5..10499f7b3 100644 --- a/public/index.html +++ b/public/index.html @@ -30,6 +30,7 @@ +
diff --git a/public/style.css b/public/style.css index a0a93e449..16ccc2fb5 100644 --- a/public/style.css +++ b/public/style.css @@ -228,4 +228,11 @@ transform: scale(0.95); box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); } -} \ No newline at end of file +} + +/* Workaround for Needle not handling menu placement of dropdowns on modals */ +#overlay { + z-index: 99 !important; + position: absolute; +} +/* End workaround */ \ No newline at end of file diff --git a/release-notes.md b/release-notes.md index eafcfbd33..905e4f77f 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,11 +1,13 @@ -## NeoDash 2.3.3 & 2.3.4 -This is a bugfix / stability release directly following 2.3.2. +## NeoDash 2.3.5 +This is a bugfix / stability release directly following 2.3.4. Improvements: -- Cleaned up dependencies, add lazy loading and code splitting in the bundle file for faster loading times. ([@BennuFire](https://github.com/BennuFire), [#545](https://github.com/neo4j-labs/neodash/pull/571)) -- Migrated all icons from Material UI to Needle icons. ([@BennuFire](https://github.com/BennuFire), [#545](https://github.com/neo4j-labs/neodash/pull/571)) -- Improved contrast for light and dark theme. ([@nielsdejong](https://github.com/nielsdejong), [#545](https://github.com/neo4j-labs/neodash/pull/566)) -- Fixed issue where dashboards were locked in read-only mode, after toggling in the dashboard settings. ([@nielsdejong](https://github.com/nielsdejong), [#545](https://github.com/neo4j-labs/neodash/pull/566)) -- Fixed issue where editing the name of a non-selected page changed the wrong page data. ([@BennuFire](https://github.com/BennuFire), [#545](https://github.com/neo4j-labs/neodash/pull/571)) -- Fixed issue where color picker was only working on popup selections. ([@BennuFire](https://github.com/BennuFire), [#579](https://github.com/neo4j-labs/neodash/pull/579)) -- Add user agent to driver session for better logging of NeoDash queries. ([@nielsdejong](https://github.com/nielsdejong), [#545](https://github.com/neo4j-labs/neodash/pull/574)) \ No newline at end of file +- Fixed issue where orphan relationships prevented graph charts from working ([@BennuFire](https://github.com/BennuFire), [#586](https://github.com/neo4j-labs/neodash/pull/586)) +- Fix issue where only one style rule was used a time on tables. ([@BennuFire](https://github.com/BennuFire), [#632](https://github.com/neo4j-labs/neodash/pull/632)) +- Added information about source and target on Graph Chart information modal . ([@BennuFire](https://github.com/BennuFire), [#627](https://github.com/neo4j-labs/neodash/pull/627)) Based on [@brahmprakashMishra](https://github.com/brahmprakashMishra) PR +- Fixed issue where bar charts where displaying black bars instead of scheme colors. ([@BennuFire](https://github.com/BennuFire), [#626](https://github.com/neo4j-labs/neodash/pull/626)) +- Added right subpath replacement on shared links redirection while in self deployments. ([@m-o-n-i-s-h](https://github.com/m-o-n-i-s-h), [#618](https://github.com/neo4j-labs/neodash/pull/618)) +- Dark theme tweaks. ([@BennuFire](https://github.com/BennuFire), [#585](https://github.com/neo4j-labs/neodash/pull/585)) +- Fixed parameter selector search where numbers were not found and sporadically displayed with decimal points. ([@BennuFire](https://github.com/BennuFire), [#633](https://github.com/neo4j-labs/neodash/pull/633)) +- Added a configuration in order to list sso providers to be used whenever a database has more than one configured. ([@BennuFire](https://github.com/BennuFire), [#624](https://github.com/neo4j-labs/neodash/pull/624)) +- Added 'Ignore undefined parameters' advanced setting support for optional parameters on a query. Now queries will assume a null value instead of returning the error 'Parameter not defined'. ([@BennuFire](https://github.com/BennuFire), [#625](https://github.com/neo4j-labs/neodash/pull/625)) \ No newline at end of file diff --git a/scripts/config-entrypoint.sh b/scripts/config-entrypoint.sh index 25374b647..2eb04129c 100644 --- a/scripts/config-entrypoint.sh +++ b/scripts/config-entrypoint.sh @@ -5,6 +5,7 @@ set -e echo " \ { \ \"ssoEnabled\": ${ssoEnabled:=false}, \ + \"ssoProviders\": ${ssoProviders:=[]}, \ \"ssoDiscoveryUrl\": \"${ssoDiscoveryUrl:='https://example.com'}\", \ \"standalone\": "${standalone:=false}", \ \"standaloneProtocol\": \"${standaloneProtocol:='neo4j+s'}\", \ diff --git a/src/application/ApplicationActions.ts b/src/application/ApplicationActions.ts index 49311d768..4f85a17c5 100644 --- a/src/application/ApplicationActions.ts +++ b/src/application/ApplicationActions.ts @@ -178,6 +178,12 @@ export const setSSOEnabled = (enabled: boolean, discoveryUrl: string) => ({ payload: { enabled, discoveryUrl }, }); +export const SET_SSO_PROVIDERS = 'APPLICATION/SET_SSO_PROVIDERS'; +export const setSSOProviders = (providers: []) => ({ + type: SET_SSO_PROVIDERS, + payload: { providers }, +}); + export const SET_WAIT_FOR_SSO = 'APPLICATION/SET_WAIT_FOR_SSO'; export const setWaitForSSO = (wait: boolean) => ({ type: SET_WAIT_FOR_SSO, diff --git a/src/application/ApplicationReducer.ts b/src/application/ApplicationReducer.ts index 23dcdd9a1..5e01776c7 100644 --- a/src/application/ApplicationReducer.ts +++ b/src/application/ApplicationReducer.ts @@ -21,6 +21,7 @@ import { SET_SESSION_PARAMETERS, SET_SHARE_DETAILS_FROM_URL, SET_SSO_ENABLED, + SET_SSO_PROVIDERS, SET_STANDALONE_DASHBOARD_DATEBASE, SET_STANDALONE_ENABLED, SET_STANDALONE_MODE, @@ -112,6 +113,11 @@ export const applicationReducer = (state = initialState, action: { type: any; pa state = update(state, { ssoEnabled: enabled, ssoDiscoveryUrl: discoveryUrl }); return state; } + case SET_SSO_PROVIDERS: { + const { providers } = payload; + state = update(state, { ssoProviders: providers }); + return state; + } case SET_WAIT_FOR_SSO: { const { wait } = payload; state = update(state, { waitForSSO: wait }); diff --git a/src/application/ApplicationSelectors.ts b/src/application/ApplicationSelectors.ts index 263fae4bf..e99758185 100644 --- a/src/application/ApplicationSelectors.ts +++ b/src/application/ApplicationSelectors.ts @@ -64,6 +64,7 @@ export const applicationHasReportHelpModalOpen = (state: any) => { export const applicationGetSsoSettings = (state: any) => { return { ssoEnabled: state.application.ssoEnabled, + ssoProviders: state.application.ssoProviders, ssoDiscoveryUrl: state.application.ssoDiscoveryUrl, cachedSSODiscoveryUrl: state.application.cachedSSODiscoveryUrl, }; diff --git a/src/application/ApplicationThunks.ts b/src/application/ApplicationThunks.ts index d09ee1ed5..38590733b 100644 --- a/src/application/ApplicationThunks.ts +++ b/src/application/ApplicationThunks.ts @@ -30,6 +30,7 @@ import { clearDesktopConnectionProperties, clearNotification, setSSOEnabled, + setSSOProviders, setStandaloneEnabled, setAboutModalOpen, setStandaloneMode, @@ -124,7 +125,7 @@ export const createConnectionThunk = query, parameters, 1, - () => {}, + () => { }, (records) => validateConnection(records) ); } catch (e) { @@ -254,7 +255,7 @@ export const handleSharedDashboardsThunk = () => (dispatch: any) => { dispatch(onConfirmLoadSharedDashboardThunk()); } - window.history.pushState({}, document.title, '/'); + window.history.pushState({}, document.title, window.location.pathname); } else { dispatch(setConnectionModalOpen(false)); // dispatch(setWelcomeScreenOpen(false)); @@ -273,7 +274,7 @@ export const handleSharedDashboardsThunk = () => (dispatch: any) => { false ) ); - window.history.pushState({}, document.title, '/'); + window.history.pushState({}, document.title, window.location.pathname); } } else { // dispatch(resetShareDetails()); @@ -340,6 +341,7 @@ export const onConfirmLoadSharedDashboardThunk = () => (dispatch: any, getState: export const loadApplicationConfigThunk = () => async (dispatch: any, getState: any) => { let config = { ssoEnabled: false, + ssoProviders: [], ssoDiscoveryUrl: 'http://example.com', standalone: false, standaloneProtocol: 'neo4j', @@ -377,6 +379,7 @@ export const loadApplicationConfigThunk = () => async (dispatch: any, getState: } const state = getState(); dispatch(setSSOEnabled(config.ssoEnabled, state.application.cachedSSODiscoveryUrl)); + dispatch(setSSOProviders(config.ssoProviders)); const { standalone } = config; dispatch( diff --git a/src/card/settings/CardSettings.tsx b/src/card/settings/CardSettings.tsx index c2bd3cb92..583bcf167 100644 --- a/src/card/settings/CardSettings.tsx +++ b/src/card/settings/CardSettings.tsx @@ -91,7 +91,11 @@ const NeoCardSettings = ({ ); return ( -
+
{cardSettingsHeader} {cardSettingsContent} diff --git a/src/card/settings/CardSettingsContent.tsx b/src/card/settings/CardSettingsContent.tsx index a51ef44f7..9ea7c06ff 100644 --- a/src/card/settings/CardSettingsContent.tsx +++ b/src/card/settings/CardSettingsContent.tsx @@ -111,7 +111,7 @@ const NeoCardSettingsContent = ({ label: report?.label || '', value: report?.label || '', }, - menuPortalTarget: document.querySelector('body'), + menuPortalTarget: document.querySelector('#overlay'), }} fluid style={{ marginLeft: '0px', marginRight: '10px', width: '47%', maxWidth: '200px', display: 'inline-block' }} @@ -133,7 +133,7 @@ const NeoCardSettingsContent = ({ value: database, })), value: { label: databaseText, value: databaseText }, - menuPortalTarget: document.querySelector('body'), + menuPortalTarget: document.querySelector('#overlay'), }} fluid style={{ marginLeft: '0px', marginRight: '10px', width: '47%', maxWidth: '200px', display: 'inline-block' }} diff --git a/src/card/view/CardView.tsx b/src/card/view/CardView.tsx index 5a87fdb4b..ff4bd05b6 100644 --- a/src/card/view/CardView.tsx +++ b/src/card/view/CardView.tsx @@ -12,6 +12,8 @@ import { identifyStyleRuleParameters } from '../../extensions/styling/StyleRuleE import { IconButton } from '@neo4j-ndl/react'; import { PlayCircleIconSolid } from '@neo4j-ndl/react/icons'; import { extensionEnabled } from '../../utils/ReportUtils'; +import { objMerge } from '../../utils/ObjectManipulation'; +import { REPORT_TYPES } from '../../config/ReportConfig'; const NeoCardView = ({ id, @@ -46,6 +48,14 @@ const NeoCardView = ({ const cardHeight = heightPx - CARD_FOOTER_HEIGHT + 23; const ref = React.useRef(); + const settingsSelector = Object.keys( + Object.fromEntries(Object.entries(REPORT_TYPES[type]?.settings || {}).filter(([_, value]) => value.refresh)) + ).reduce((obj, key) => { + return Object.assign(obj, { + [key]: settings[key], + }); + }, {}); + const [lastRunTimestamp, setLastRunTimestamp] = useState(Date.now()); // TODO : selectorChange should handle every case where query execution needs to be re-executed @@ -69,9 +79,13 @@ const NeoCardView = ({ localQueryVariables.push(match[1]); } - return Object.fromEntries( + let params = Object.fromEntries( Object.entries(globalParameters).filter(([local]) => localQueryVariables.includes(local)) ); + + return settings.ignoreNonDefinedParams + ? objMerge(Object.fromEntries(localQueryVariables.map((name) => [name, null])), params) + : params; }; // @ts-ignore @@ -135,7 +149,7 @@ const NeoCardView = ({ useEffect(() => { setSelectorChange(true); - }, [query, type]); + }, [query, type, JSON.stringify(settingsSelector)]); // TODO - understand why CardContent is throwing a warning based on this style config. const cardContentStyle = { @@ -213,7 +227,9 @@ const NeoCardView = ({ return (
{reportHeader} diff --git a/src/card/view/CardViewFooter.tsx b/src/card/view/CardViewFooter.tsx index 135306180..790e2be19 100644 --- a/src/card/view/CardViewFooter.tsx +++ b/src/card/view/CardViewFooter.tsx @@ -121,7 +121,7 @@ const NeoCardViewFooter = ({ : { label: selection[selectable], value: selection[selectable] }, isMulti: selectableFields[selectable].multiple, isClearable: false, - menuPortalTarget: document.querySelector('body'), + menuPortalTarget: document.querySelector('#overlay'), }} fluid style={{ diff --git a/src/card/view/CardViewHeader.tsx b/src/card/view/CardViewHeader.tsx index 5a8514043..255da3bf0 100644 --- a/src/card/view/CardViewHeader.tsx +++ b/src/card/view/CardViewHeader.tsx @@ -71,6 +71,9 @@ const NeoCardViewHeader = ({ text: { primary: 'rgb(var(--palette-neutral-text))', }, + action: { + disabled: 'rgb(var(--palette-neutral-text-weak))', + }, }, }); @@ -103,7 +106,7 @@ const NeoCardViewHeader = ({ onBlur={() => { setEditing(false); }} - className={'n-text-palette-neutral-text-default no-underline large'} + className={'no-underline large'} label='' disabled={!editable} placeholder='Report name...' @@ -117,6 +120,11 @@ const NeoCardViewHeader = ({ size={'small'} style={{ paddingTop: '0px important!' }} variant={'standard'} + sx={{ + '& .MuiInputBase-input.Mui-disabled': { + WebkitTextFillColor: 'inherit', + }, + }} /> diff --git a/src/chart/ChartUtils.ts b/src/chart/ChartUtils.ts index daa62e7b2..d6c011395 100644 --- a/src/chart/ChartUtils.ts +++ b/src/chart/ChartUtils.ts @@ -140,6 +140,11 @@ export function getRecordType(value) { return 'objectNumber'; } return 'object'; + } else if (typeof value === 'string' || value instanceof String) { + if (value.startsWith('http') || value.startsWith('https')) { + return 'link'; + } + return 'string'; } // Use string as default type diff --git a/src/chart/Utils.ts b/src/chart/Utils.ts index 124eac425..049edb87f 100644 --- a/src/chart/Utils.ts +++ b/src/chart/Utils.ts @@ -121,14 +121,14 @@ export const themeNivo = { textColor: 'rgb(var(--palette-neutral-text-default))', text: { fill: 'rgb(var(--palette-neutral-text-default))' }, axis: { - ticks: { text: { fill: 'rgb(var(--palette-light-neutral-text-default))' } }, + ticks: { text: { fill: 'rgb(var(--palette-neutral-text-default))' } }, legend: { text: { fill: 'rgb(var(--palette-neutral-text-default))' } }, }, legends: { - text: { fill: 'rgb(var(--palette-neutral-text-weak))' }, - title: { text: { fill: 'rgb(var(--palette-neutral-text-weak))' } }, - ticks: { text: { fill: 'rgb(var(--palette-neutral-text-weak))' } }, - hidden: { text: { fill: 'rgb(var(--palette-neutral-text-weak))' } }, + text: { fill: 'rgb(var(--palette-neutral-text-default))' }, + title: { text: { fill: 'rgb(var(--palette-neutral-text-default))' } }, + ticks: { text: { fill: 'rgb(var(--palette-neutral-text-default))' } }, + hidden: { text: { fill: 'rgb(var(--palette-neutral-text-default))' } }, }, markers: { text: { fill: 'rgb(var(--palette-neutral-text-default))' }, diff --git a/src/chart/bar/BarChart.tsx b/src/chart/bar/BarChart.tsx index 52b3218e0..e62d17ed3 100644 --- a/src/chart/bar/BarChart.tsx +++ b/src/chart/bar/BarChart.tsx @@ -28,7 +28,7 @@ const NeoBarChart = (props: ChartProps) => { const { records, selection } = props; - const [keys, setKeys] = React.useState({}); + const [keys, setKeys] = React.useState([]); const [data, setData] = React.useState[]>([]); useEffect(() => { @@ -72,7 +72,7 @@ const NeoBarChart = (props: ChartProps) => { return row; }); - setKeys(newKeys); + setKeys(Object.keys(newKeys)); setData(newData); }, [selection]); @@ -114,8 +114,8 @@ const NeoBarChart = (props: ChartProps) => { const chartColorsByScheme = getD3ColorsByScheme(colorScheme); // Compute bar color based on rules - overrides default color scheme completely. const getBarColor = (bar) => { - let { data, id } = bar; - let colorIndex = Object.keys(data).indexOf(id); + let { id } = bar; + let colorIndex = keys.indexOf(id); if (colorIndex >= chartColorsByScheme.length) { colorIndex %= chartColorsByScheme.length; } @@ -218,7 +218,7 @@ const NeoBarChart = (props: ChartProps) => { layout={layout} groupMode={groupMode == 'stacked' ? 'stacked' : 'grouped'} enableLabel={enableLabel} - keys={Object.keys(keys)} + keys={keys} indexBy='index' margin={{ top: marginTop, diff --git a/src/chart/graph/component/GraphChartInspectModal.tsx b/src/chart/graph/component/GraphChartInspectModal.tsx index 53009d9a9..5c5835606 100644 --- a/src/chart/graph/component/GraphChartInspectModal.tsx +++ b/src/chart/graph/component/GraphChartInspectModal.tsx @@ -17,7 +17,9 @@ export const NeoGraphChartInspectModal = (props: GraphChartVisualizationProps) = aria-labelledby='form-dialog-title' > - {props.interactivity.selectedEntity ? getEntityHeader(props.interactivity.selectedEntity) : ''} + {props.interactivity.selectedEntity + ? getEntityHeader(props.interactivity.selectedEntity, props.engine.selection) + : ''} diff --git a/src/chart/graph/util/NodeUtils.ts b/src/chart/graph/util/NodeUtils.ts index 20d318f2e..f40b5ee58 100644 --- a/src/chart/graph/util/NodeUtils.ts +++ b/src/chart/graph/util/NodeUtils.ts @@ -24,8 +24,26 @@ export const parseNodeIconConfig = (iconStyle) => { } }; -export const getEntityHeader = (entity) => { - return (entity.labels && entity.labels.join(', ')) || entity.type; +const getSelectedNodeProperty = (entity: any, sourceOrTarget: string, propertySelections: any) => { + const selection = propertySelections[entity[sourceOrTarget]?.mainLabel]; + switch (selection) { + case '(label)': + return entity[sourceOrTarget]?.mainLabel; + case '(id)': + return entity[sourceOrTarget]?.id; + default: + return entity[sourceOrTarget]?.properties[selection]; + } +}; + +const getRelPatternString = (entity: any, selection: any) => { + const sourceTitle = getSelectedNodeProperty(entity, 'source', selection); + const targetTitle = getSelectedNodeProperty(entity, 'target', selection); + return `(${sourceTitle ? sourceTitle : '[no value]'} --> ${targetTitle ? targetTitle : '[no value]'})`; +}; + +export const getEntityHeader = (entity: any, selection: any) => { + return entity.labels?.join(', ') || `${entity.type} ${getRelPatternString(entity, selection)}`; }; export const drawDataURIOnCanvas = (node, strDataURI, canvas, defaultNodeSize) => { diff --git a/src/chart/graph/util/RecordUtils.ts b/src/chart/graph/util/RecordUtils.ts index a1767aea9..462366451 100644 --- a/src/chart/graph/util/RecordUtils.ts +++ b/src/chart/graph/util/RecordUtils.ts @@ -122,6 +122,12 @@ function extractGraphEntitiesFromField( } } +const isValidLink = (link, nodes) => { + if (nodes[link.source] == null || nodes[link.target] == null) { + return false; + } + return true; +}; export function buildGraphVisualizationObjectFromRecords( records: any[], // Neo4jRecord[], nodes: Record[], @@ -162,6 +168,7 @@ export function buildGraphVisualizationObjectFromRecords( ); }); }); + // Assign proper curvatures and colors to relationships. // Assigning curvature is needed for pairs of nodes that have multiple relationships between them, or self-loops. const linksList = Object.values(links).map((linkArray) => { @@ -176,6 +183,12 @@ export function buildGraphVisualizationObjectFromRecords( }); }); + linksList.forEach((link, idx, object) => { + if (!isValidLink(link[0], nodes)) { + object.splice(idx, 1); + } + }); + // Assign proper colors to nodes. const totalColors = colorScheme ? colorScheme.length : 0; const nodeLabelsList = fields.map((e) => e[0]); diff --git a/src/chart/parameter/component/FreeTextParameterSelect.tsx b/src/chart/parameter/component/FreeTextParameterSelect.tsx index d9e22c260..aded7fafb 100644 --- a/src/chart/parameter/component/FreeTextParameterSelect.tsx +++ b/src/chart/parameter/component/FreeTextParameterSelect.tsx @@ -38,8 +38,12 @@ const FreeTextParameterSelectComponent = (props: ParameterSelectProps) => { return; } - if (value == null && clearParameterOnFieldClear) { - debouncedSetParameterValue(defaultValue); + if (value == '') { + if (clearParameterOnFieldClear) { + debouncedSetParameterValue(undefined); + } else { + debouncedSetParameterValue(defaultValue); + } } else { debouncedSetParameterValue(value); } diff --git a/src/chart/parameter/component/NodePropertyParameterSelect.tsx b/src/chart/parameter/component/NodePropertyParameterSelect.tsx index c4332be87..f29374cd7 100644 --- a/src/chart/parameter/component/NodePropertyParameterSelect.tsx +++ b/src/chart/parameter/component/NodePropertyParameterSelect.tsx @@ -120,6 +120,7 @@ const NodePropertyParameterSelectComponent = (props: ParameterSelectProps) => { handleParametersUpdate(newValue, newDisplay, manualParameterSave); }; + return (
{ variant='outlined' /> )} - getOptionLabel={(option) => RenderSubValue(option)} + getOptionLabel={(option) => option?.toString() || ''} /> {manualParameterSave ? manualHandleParametersUpdate()} /> : <>}
diff --git a/src/chart/pie/PieChart.tsx b/src/chart/pie/PieChart.tsx index cee7b3bdd..739ba7471 100644 --- a/src/chart/pie/PieChart.tsx +++ b/src/chart/pie/PieChart.tsx @@ -7,6 +7,7 @@ import { ChartProps } from '../Chart'; import { convertRecordObjectToString, recordToNative } from '../ChartUtils'; import { themeNivo } from '../Utils'; import { extensionEnabled } from '../../utils/ReportUtils'; +import { objMerge } from '../../utils/ObjectManipulation'; /** * Embeds a PieChart (from Nivo) into NeoDash. @@ -73,10 +74,10 @@ const NeoPieChart = (props: ChartProps) => { const settings = props.settings ? props.settings : {}; const legendHeight = 20; // TODO to retrieve all defaults from the ReportConfig.ts file instead of hardcoding them in the file - const marginRight = settings.marginRight ? settings.marginRight : 24; - const marginLeft = settings.marginLeft ? settings.marginLeft : 24; - const marginTop = settings.marginTop ? settings.marginTop : 24; - const marginBottom = settings.marginBottom ? settings.marginBottom : 40; + const marginRight = settings.marginRight ? settings.marginRight : 50; + const marginLeft = settings.marginLeft ? settings.marginLeft : 50; + const marginTop = settings.marginTop ? settings.marginTop : 50; + const marginBottom = settings.marginBottom ? settings.marginBottom : 50; const sortByValue = settings.sortByValue ? settings.sortByValue : false; const enableArcLabels = settings.enableArcLabels !== undefined ? settings.enableArcLabels : true; const enableArcLinkLabels = settings.enableArcLinkLabels !== undefined ? settings.enableArcLinkLabels : true; @@ -90,6 +91,8 @@ const NeoPieChart = (props: ChartProps) => { const cornerRadius = settings.cornerRadius ? settings.cornerRadius : 1; const arcLabelsSkipAngle = settings.arcLabelsSkipAngle ? settings.arcLabelsSkipAngle : 10; + const arcLabelsFontSize = settings.arcLabelsFontSize ? settings.arcLabelsFontSize : 13; + const legend = settings.legend ? settings.legend : false; const colorScheme = settings.colors ? settings.colors : 'set2'; const styleRules = useStyleRules( @@ -131,9 +134,14 @@ const NeoPieChart = (props: ChartProps) => { return ; } + const theme = objMerge(themeNivo, { + labels: { + text: { fontSize: arcLabelsFontSize }, + }, + }); return ( { ColumnSortedAscendingIcon: () => <>, }} getRowClassName={(params) => { - return `rule${evaluateRulesOnDict(params.row, styleRules, ['row color', 'row text color'])}`; + return ['row color', 'row text color'] + .map((e) => { + return `rule${evaluateRulesOnDict(params.row, styleRules, [e])}`; + }) + .join(' '); }} getCellClassName={(params) => { - return `rule${evaluateRulesOnDict({ [params.field]: params.value }, styleRules, [ - 'cell color', - 'cell text color', - ])}`; + return ['cell color', 'cell text color'] + .map((e) => { + return `rule${evaluateRulesOnDict({ [params.field]: params.value }, styleRules, [e])}`; + }) + .join(' '); }} />
diff --git a/src/component/sso/SSOLoginButton.tsx b/src/component/sso/SSOLoginButton.tsx index f771c610c..b22b47163 100644 --- a/src/component/sso/SSOLoginButton.tsx +++ b/src/component/sso/SSOLoginButton.tsx @@ -4,14 +4,20 @@ import { getDiscoveryDataInfo } from './SSOUtils'; import { ShieldCheckIconOutline } from '@neo4j-ndl/react/icons'; import { Button, IconButton } from '@neo4j-ndl/react'; -export const SSOLoginButton = ({ discoveryAPIUrl, hostname, port, onSSOAttempt, onClick }) => { +export const SSOLoginButton = ({ discoveryAPIUrl, hostname, port, onSSOAttempt, onClick, providers }) => { const [savedSSOProviders, setSSOProviders] = useState([]); const [discoveryUrlValidated, setDiscoveryUrlValidated] = useState(undefined); + + const filterByProvidersList = (discoveredProviders, validProviders) => { + return validProviders == null || validProviders.length == 0 + ? discoveredProviders + : discoveredProviders.filter((p) => validProviders.includes(p.id)); + }; const attemptManualSSOProviderRetrieval = () => { // Do an extra check to see if the hostname provides some SSO provider configuration. getDiscoveryDataInfo(`https://${hostname}:${port}`) .then((mergedSSOProviders) => { - setSSOProviders(mergedSSOProviders); + setSSOProviders(filterByProvidersList(mergedSSOProviders, providers)); if (mergedSSOProviders.length == 0) { setDiscoveryUrlValidated(undefined); } else { @@ -26,7 +32,7 @@ export const SSOLoginButton = ({ discoveryAPIUrl, hostname, port, onSSOAttempt, // First, try to get the SSO discovery URL from the config.json configuration file and see if it contains anything. getDiscoveryDataInfo(discoveryAPIUrl) .then((mergedSSOProviders) => { - setSSOProviders(mergedSSOProviders); + setSSOProviders(filterByProvidersList(mergedSSOProviders, providers)); if (mergedSSOProviders.length == 0) { attemptManualSSOProviderRetrieval(); } else { diff --git a/src/config/ReportConfig.tsx b/src/config/ReportConfig.tsx index c14bf5cfb..879199d96 100644 --- a/src/config/ReportConfig.tsx +++ b/src/config/ReportConfig.tsx @@ -13,6 +13,7 @@ import NeoMarkdownChart from '../chart/markdown/MarkdownChart'; import { SELECTION_TYPES } from './CardConfig'; import NeoLineChart from '../chart/line/LineChart'; import NeoScatterPlot from '../chart/scatter/ScatterPlotChart'; +import { objMerge, objectMap } from '../utils/ObjectManipulation'; // TODO: make the reportConfig a interface with not self-documented code // Use Neo4j 4.0 subqueries to limit the number of rows returned by overriding the query. @@ -25,7 +26,7 @@ export const RUN_QUERY_DELAY_MS = 300; export const DEFAULT_ROW_LIMIT = 100; // A dictionary of available reports (visualizations). -export const REPORT_TYPES = { +const _REPORT_TYPES = { table: { label: 'Table', helperText: 'A table will contain all returned data.', @@ -33,11 +34,6 @@ export const REPORT_TYPES = { useReturnValuesAsFields: true, maxRecords: 1000, settings: { - backgroundColor: { - label: 'Background Color', - type: SELECTION_TYPES.COLOR, - default: '#fafafa', - }, transposed: { label: 'Transpose Rows & Columns', type: SELECTION_TYPES.LIST, @@ -96,11 +92,6 @@ export const REPORT_TYPES = { type: SELECTION_TYPES.NUMBER, default: '0 (No refresh)', }, - description: { - label: 'Report Description', - type: SELECTION_TYPES.MULTILINE_TEXT, - default: 'Enter markdown here...', - }, }, }, graph: { @@ -120,11 +111,6 @@ export const REPORT_TYPES = { // between the different options (EX: if operator is false, then it must be the opposite of the setting it depends on) disabledDependency: { relationshipParticleSpeed: { dependsOn: 'relationshipParticles', operator: false } }, settings: { - backgroundColor: { - label: 'Background Color', - type: SELECTION_TYPES.COLOR, - default: '#fafafa', - }, nodeColorScheme: { label: 'Node Color Scheme', type: SELECTION_TYPES.LIST, @@ -316,11 +302,6 @@ export const REPORT_TYPES = { values: [true, false], default: false, }, - description: { - label: 'Report Description', - type: SELECTION_TYPES.MULTILINE_TEXT, - default: 'Enter markdown here...', - }, }, }, bar: { @@ -350,11 +331,6 @@ export const REPORT_TYPES = { }, maxRecords: 250, settings: { - backgroundColor: { - label: 'Background Color', - type: SELECTION_TYPES.COLOR, - default: '#fafafa', - }, legend: { label: 'Show Legend', type: SELECTION_TYPES.LIST, @@ -488,11 +464,6 @@ export const REPORT_TYPES = { type: SELECTION_TYPES.NUMBER, default: '0 (No refresh)', }, - description: { - label: 'Report Description', - type: SELECTION_TYPES.MULTILINE_TEXT, - default: 'Enter markdown here...', - }, }, }, pie: { @@ -522,11 +493,6 @@ export const REPORT_TYPES = { }, maxRecords: 250, settings: { - backgroundColor: { - label: 'Background Color', - type: SELECTION_TYPES.COLOR, - default: '#fafafa', - }, legend: { label: 'Show Legend', type: SELECTION_TYPES.LIST, @@ -550,6 +516,11 @@ export const REPORT_TYPES = { type: SELECTION_TYPES.NUMBER, default: 10, }, + arcLabelsFontSize: { + label: 'Labels font Size', + type: SELECTION_TYPES.NUMBER, + default: 13, + }, enableArcLinkLabels: { label: 'Show categories next to slices', type: SELECTION_TYPES.LIST, @@ -606,22 +577,22 @@ export const REPORT_TYPES = { marginLeft: { label: 'Margin Left (px)', type: SELECTION_TYPES.NUMBER, - default: 24, + default: 50, }, marginRight: { label: 'Margin Right (px)', type: SELECTION_TYPES.NUMBER, - default: 24, + default: 50, }, marginTop: { label: 'Margin Top (px)', type: SELECTION_TYPES.NUMBER, - default: 24, + default: 50, }, marginBottom: { label: 'Margin Bottom (px)', type: SELECTION_TYPES.NUMBER, - default: 40, + default: 50, }, refreshButtonEnabled: { label: 'Refreshable', @@ -652,11 +623,6 @@ export const REPORT_TYPES = { type: SELECTION_TYPES.NUMBER, default: '0 (No refresh)', }, - description: { - label: 'Report Description', - type: SELECTION_TYPES.MULTILINE_TEXT, - default: 'Enter markdown here...', - }, }, }, line: { @@ -683,11 +649,6 @@ export const REPORT_TYPES = { }, maxRecords: 250, settings: { - backgroundColor: { - label: 'Background Color', - type: SELECTION_TYPES.COLOR, - default: '#fafafa', - }, legend: { label: 'Show Legend', type: SELECTION_TYPES.LIST, @@ -839,11 +800,6 @@ export const REPORT_TYPES = { type: SELECTION_TYPES.NUMBER, default: '0 (No refresh)', }, - description: { - label: 'Report Description', - type: SELECTION_TYPES.MULTILINE_TEXT, - default: 'Enter markdown here...', - }, }, }, // TODO - move to advanced visualization. @@ -1039,11 +995,6 @@ export const REPORT_TYPES = { component: NeoMapChart, maxRecords: 1000, settings: { - backgroundColor: { - label: 'Background Color', - type: SELECTION_TYPES.COLOR, - default: '#fafafa', - }, layerType: { label: 'Layer Type', type: SELECTION_TYPES.LIST, @@ -1133,11 +1084,6 @@ export const REPORT_TYPES = { values: [true, false], default: true, }, - description: { - label: 'Report Description', - type: SELECTION_TYPES.MULTILINE_TEXT, - default: 'Enter markdown here...', - }, }, }, value: { @@ -1146,11 +1092,6 @@ export const REPORT_TYPES = { component: NeoSingleValueChart, maxRecords: 1, settings: { - backgroundColor: { - label: 'Background Color', - type: SELECTION_TYPES.COLOR, - default: '#fafafa', - }, fontSize: { label: 'Font Size', type: SELECTION_TYPES.NUMBER, @@ -1214,11 +1155,6 @@ export const REPORT_TYPES = { type: SELECTION_TYPES.NUMBER, default: '0 (No refresh)', }, - description: { - label: 'Report Description', - type: SELECTION_TYPES.MULTILINE_TEXT, - default: 'Enter markdown here...', - }, }, }, json: { @@ -1234,11 +1170,6 @@ export const REPORT_TYPES = { values: ['json', 'yml'], default: 'json', }, - backgroundColor: { - label: 'Background Color', - type: SELECTION_TYPES.COLOR, - default: '#fafafa', - }, refreshButtonEnabled: { label: 'Refreshable', type: SELECTION_TYPES.LIST, @@ -1268,11 +1199,6 @@ export const REPORT_TYPES = { type: SELECTION_TYPES.NUMBER, default: '0 (No refresh)', }, - description: { - label: 'Report Description', - type: SELECTION_TYPES.MULTILINE_TEXT, - default: 'Enter markdown here...', - }, }, }, select: { @@ -1285,11 +1211,6 @@ export const REPORT_TYPES = { textOnly: true, maxRecords: 100, settings: { - backgroundColor: { - label: 'Background Color', - type: SELECTION_TYPES.COLOR, - default: '#fafafa', - }, multiSelector: { label: 'Multiple Selection', type: SELECTION_TYPES.LIST, @@ -1369,11 +1290,6 @@ export const REPORT_TYPES = { values: [true, false], default: false, }, - description: { - label: 'Report Description', - type: SELECTION_TYPES.MULTILINE_TEXT, - default: 'Enter markdown here...', - }, }, }, iframe: { @@ -1387,11 +1303,6 @@ export const REPORT_TYPES = { maxRecords: 1, allowScrolling: true, settings: { - backgroundColor: { - label: 'Background Color', - type: SELECTION_TYPES.COLOR, - default: '#fafafa', - }, replaceGlobalParameters: { label: 'Replace global parameters in URL', type: SELECTION_TYPES.LIST, @@ -1410,11 +1321,6 @@ export const REPORT_TYPES = { values: [true, false], default: false, }, - description: { - label: 'Report Description', - type: SELECTION_TYPES.MULTILINE_TEXT, - default: 'Enter markdown here...', - }, }, }, text: { @@ -1427,11 +1333,6 @@ export const REPORT_TYPES = { maxRecords: 1, allowScrolling: true, settings: { - backgroundColor: { - label: 'Background Color', - type: SELECTION_TYPES.COLOR, - default: '#fafafa', - }, replaceGlobalParameters: { label: 'Replace global parameters in Markdown', type: SELECTION_TYPES.LIST, @@ -1450,11 +1351,30 @@ export const REPORT_TYPES = { values: [true, false], default: false, }, - description: { - label: 'Report Description', - type: SELECTION_TYPES.MULTILINE_TEXT, - default: 'Enter markdown here...', - }, }, }, }; + +export const COMMON_REPORT_SETTINGS = { + backgroundColor: { + label: 'Background Color', + type: SELECTION_TYPES.COLOR, + default: '#fafafa', + }, + description: { + label: 'Selector Description', + type: SELECTION_TYPES.MULTILINE_TEXT, + default: 'Enter markdown here...', + }, + ignoreNonDefinedParams: { + label: 'Ignore undefined parameters', + type: SELECTION_TYPES.LIST, + values: [true, false], + default: false, + refresh: true, + }, +}; + +export const REPORT_TYPES = objectMap(_REPORT_TYPES, (value: any) => { + return objMerge({ settings: COMMON_REPORT_SETTINGS }, value); +}); diff --git a/src/extensions/query-translator/clients/const.ts b/src/extensions/query-translator/clients/const.ts index ac6362c0f..2258fa4a5 100644 --- a/src/extensions/query-translator/clients/const.ts +++ b/src/extensions/query-translator/clients/const.ts @@ -74,7 +74,7 @@ export const reportExampleQueries = { 'Single Value': 'MATCH (n) RETURN COUNT(n)', 'Gauge Chart': 'MATCH (c:CPU) WHERE c.id = 1 RETURN c.load_percentage * 100', 'Raw JSON': 'MATCH (n) RETURN COUNT(n)', - 'Pie Chart': 'Match (n:Person)-[e]->(m:Movie) RETURN m.title as Title, COUNT(p) as People LIMIT 10', + 'Pie Chart': 'Match (p:Person)-[e]->(m:Movie) RETURN m.title as Title, COUNT(p) as People LIMIT 10', }; export const TASK_DEFINITION = `Task: Generate Cypher queries to query a Neo4j graph database based on the provided schema definition. These queries will be used inside NeoDash reports. diff --git a/src/index.tsx b/src/index.tsx index 21bdcc270..75c85d607 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -11,22 +11,26 @@ import './index.pcss'; import StyleConfig from './config/StyleConfig'; import * as Sentry from '@sentry/react'; -Sentry.init({ - dsn: 'https://25edb17cc4c14c8cb726e7ac1ff74e3b@o110884.ingest.sentry.io/4505397810167808', - integrations: [ - new Sentry.BrowserTracing({ - // Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled - tracePropagationTargets: [/^https:\/\/neodash\.graphapp\.io/, /^http:\/\/neodash\.graphapp\.io/], - }), - new Sentry.Replay(), - ], - // Performance Monitoring - tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production! - // Session Replay - replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production. - replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur. -}); - +if (window.location.href.includes('//neodash.graphapp.io/')) { + Sentry.init({ + dsn: 'https://25edb17cc4c14c8cb726e7ac1ff74e3b@o110884.ingest.sentry.io/4505397810167808', + allowUrls: [/^https:\/\/neodash\.graphapp\.io/, /^http:\/\/neodash\.graphapp\.io/], + integrations: [ + new Sentry.BrowserTracing({ + // Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled + tracePropagationTargets: [/^https:\/\/neodash\.graphapp\.io/, /^http:\/\/neodash\.graphapp\.io/], + }), + new Sentry.Replay({ + networkDetailAllowUrls: [/^https:\/\/neodash\.graphapp\.io/, /^http:\/\/neodash\.graphapp\.io/], + }), + ], + // Performance Monitoring + tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production! + // Session Replay + replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production. + replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur. + }); +} /** * Set up the NeoDash application and wrap it in the needed providers. */ diff --git a/src/modal/AboutModal.tsx b/src/modal/AboutModal.tsx index 12b7e1d10..733e7e92a 100644 --- a/src/modal/AboutModal.tsx +++ b/src/modal/AboutModal.tsx @@ -3,7 +3,7 @@ import { Button, Dialog, TextLink } from '@neo4j-ndl/react'; import { BookOpenIconOutline, BeakerIconOutline } from '@neo4j-ndl/react/icons'; import { Section, SectionTitle, SectionContent } from './ModalUtils'; -export const version = '2.3.4'; +export const version = '2.3.5'; export const NeoAboutModal = ({ open, handleClose, getDebugState }) => { const downloadDebugFile = () => { diff --git a/src/modal/ConnectionModal.tsx b/src/modal/ConnectionModal.tsx index ad98a65b3..0cf451839 100644 --- a/src/modal/ConnectionModal.tsx +++ b/src/modal/ConnectionModal.tsx @@ -186,6 +186,7 @@ export default function NeoConnectionModal({ // Remember credentials on click setConnectionProperties(protocol, url, port, database, '', ''); }} + providers={ssoSettings.ssoProviders} /> ) : (