Skip to content

Commit 82f074a

Browse files
nielsdejongHåkan Löfqvist
andauthored
2.0.15 Release (#126)
* Added support for loading dashboards from a relative URL in standalone mode * Hotfix for broken demo dashboard * Bump to 2.0.15. Added option to replace dashboard parameters in Markdown and iFrame strings * added html to image to lib * W.I.P. on downloading reports/dashboard as image * Added button to download entire dashboard as an image * Updated release notes for 2.0.15 * Dockerfile - Configuration through env variables at runtime (#125) * Configuration throug env variables - Env variables can now be used to define the contents of config.json (when the container starts) - Added tips for setting up single sign on * Cleanup of Dockerfile and README * Removed temporary files * Bumped version number Co-authored-by: Håkan Löfqvist <[email protected]> * Updated release notes * Updated README on Docker deployments Co-authored-by: Håkan Löfqvist <[email protected]>
1 parent 274a08b commit 82f074a

22 files changed

+293
-143
lines changed

Dockerfile

Lines changed: 14 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
# build stage
22
FROM node:lts-alpine AS build-stage
3-
RUN apk add --no-cache git
4-
RUN git clone https://github.com/nielsdejong/neodash.git /usr/local/src/neodash
3+
54
RUN npm install -g typescript jest
65
WORKDIR /usr/local/src/neodash
6+
7+
# Pull source code if you have not cloned the repository
8+
#RUN apk add --no-cache git
9+
#RUN git clone https://github.com/nielsdejong/neodash.git /usr/local/src/neodash
10+
11+
# Copy sources and install/build
712
COPY ./package.json /usr/local/src/neodash/package.json
813
RUN npm install
914
COPY ./ /usr/local/src/neodash
10-
# ENV PUBLIC_URL=/neodash
11-
# RUN git checkout develop
1215
RUN npm run build
1316

1417
# production stage
@@ -17,10 +20,15 @@ RUN apk upgrade
1720
COPY --from=build-stage /usr/local/src/neodash/dist /usr/share/nginx/html
1821

1922
COPY ./conf/default.conf /etc/nginx/conf.d/
23+
COPY ./scripts/config-entrypoint.sh /docker-entrypoint.d/config-entrypoint.sh
24+
COPY ./scripts/message-entrypoint.sh /docker-entrypoint.d/message-entrypoint.sh
2025

2126
RUN chown -R nginx:nginx /var/cache/nginx && \
2227
chown -R nginx:nginx /var/log/nginx && \
23-
chown -R nginx:nginx /etc/nginx/conf.d
28+
chown -R nginx:nginx /etc/nginx/conf.d && \
29+
chown -R nginx:nginx /docker-entrypoint.d/config-entrypoint.sh && \
30+
chmod +x /docker-entrypoint.d/config-entrypoint.sh && \
31+
chmod +x /docker-entrypoint.d/message-entrypoint.sh
2432
RUN touch /var/run/nginx.pid && \
2533
chown -R nginx:nginx /var/run/nginx.pid
2634
RUN chown -R nginx:nginx /usr/share/nginx/html/
@@ -29,42 +37,4 @@ RUN chown -R nginx:nginx /usr/share/nginx/html/
2937
USER nginx
3038
EXPOSE 5005
3139
HEALTHCHECK cmd curl --fail http://localhost:5005 || exit 1
32-
33-
# Set the defaults for the build arguments. When the image is created, these variables can be changed with --build-arg
34-
# Such as --build-arg ssoEnabled=true
35-
ARG ssoEnabled=false
36-
ARG ssoDiscoveryUrl='https://example.com'
37-
ARG standalone=false
38-
ARG standaloneProtocol='neo4j+s'
39-
ARG standaloneHost='test.databases.neo4j.io'
40-
ARG standalonePort=7687
41-
ARG standaloneDatabase='neo4j'
42-
ARG standaloneDashboardName='My Dashboard'
43-
ARG standaloneDashboardDatabase='neo4j'
44-
ARG standaloneDashboardURL=''
45-
46-
LABEL version="2.0.14"
47-
48-
# Dynamically set app config on container startup.
49-
RUN echo " \
50-
{ \
51-
\"ssoEnabled\": ${ssoEnabled}, \
52-
\"ssoDiscoveryUrl\": \"${ssoDiscoveryUrl}\", \
53-
\"standalone\": ${standalone}, \
54-
\"standaloneProtocol\": \"${standaloneProtocol}\", \
55-
\"standaloneHost\": \"${standaloneHost}\", \
56-
\"standalonePort\": ${standalonePort}, \
57-
\"standaloneDatabase\": \"${standaloneDatabase}\", \
58-
\"standaloneDashboardName\": \"${standaloneDashboardName}\", \
59-
\"standaloneDashboardDatabase\": \"${standaloneDashboardDatabase}\", \
60-
\"standaloneDashboardURL\": \"${standaloneDashboardURL}\" \
61-
}" > /usr/share/nginx/html/config.json
62-
63-
CMD echo '-----------------------------------------------------------------------------------------' && \
64-
echo '| NeoDash is available on http://localhost:5005 by default. |' && \
65-
echo '| Make sure your ports are mapped correctly (-p 5005:5005) when starting the container. |' && \
66-
echo '-----------------------------------------------------------------------------------------' && \
67-
/usr/sbin/nginx -g 'daemon off;'
68-
69-
# neodash will be available at http://localhost:5005 inside the container. See `scripts/docker-build-run-unix.bash` on how to map ports.
70-
40+
LABEL version="2.0.15"

README.md

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ docker pull nielsdejong/neodash:latest
2323
docker run -it --rm -p 5005:5005 nielsdejong/neodash
2424
```
2525

26+
> Windows users may need to prefix the `docker run` command with `winpty`.
27+
28+
2629
## Run & Build using npm
2730
NeoDash is built with React. You'll need `npm` installed to run the web app.
2831

@@ -52,15 +55,18 @@ Make sure you have a recent version of `docker` installed to build the multi-sta
5255

5356
On Unix (Mac/Linux) systems:
5457
```
55-
$ ./scripts/docker-build-run-unix.bash
58+
docker build . -t neodash
5659
```
5760

58-
If you use Windows, you should have installed WSL. In WSL, you can run the script as follows:
61+
If you use Windows, you might need to prefix the command with `winpty`:
5962
```
60-
$ ./scripts/docker-build-run-windows.bash
63+
winpty docker build . -t neodash
6164
```
62-
Then visit `http://localhost:5005` in your browser.
6365

66+
After building, you can run the image with:
67+
```
68+
docker run -it --rm -p 5005:5005 neodash
69+
```
6470

6571
## Run in standalone mode
6672
NeoDash can be deployed in a 'standalone mode' for dashboard viewers. This mode will:
@@ -72,9 +78,52 @@ The diagram below illustrates how NeoDash standalone mode can be deployed next t
7278

7379
![](doc/standalone-architecture.png)
7480

75-
You can configure an instance to run as standalone by changing the variables in `scripts/docker-build-run-unix.bash`, or, if you're not using docker, directly modifying `public/config.json`. Note that the editor mode is determined at runtime by the React app, and *not* at build time. You therefore do not need to (re-)build the React application, just the image.
81+
### Option 1 - Standard Deployment (Non-Docker)
82+
First, build NeoDash as described above. Then, you'll have a `dist` directory that you can deploy to a web server.
83+
84+
To configure the app to run in standalone mode, you'll need to edit `dist/config.json` and change the `standalone` property to `true`.
85+
The other variables inside `config.json` should also be configured to match the hostname, port and database name of your Neo4j instance.
86+
87+
As `config.json` gets picked up at runtime by the application, users viewing the application will now access the dashboard in standalone mode.
88+
89+
### Option 2 - Docker Deployment
90+
You can configure the app to run in standalone by passing environment variables to Docker:
91+
```
92+
docker run -it --rm -p 5005:5005 \
93+
-e ssoEnabled=false \
94+
-e ssoDiscoveryUrl="https://example.com" \
95+
-e standalone=true \
96+
-e standaloneProtocol="neo4j" \
97+
-e standaloneHost="localhost" \
98+
-e standalonePort="7687" \
99+
-e standaloneDatabase="neo4j" \
100+
-e standaloneDashboardName="My Dashboard" \
101+
-e standaloneDashboardDatabase="dashboards" \
102+
nielsdejong/neodash
103+
```
104+
105+
106+
> Alternatively, environment variables from docker compose or a kubernetes deployment can also be used.
107+
108+
109+
## Auth Provider (SSO)
110+
111+
To set up NeoDash to use an external identiy provider, you can add a /auth_provider resource to nginx (in `/conf/default.conf`):
112+
113+
```
114+
location /auth_provider {
115+
default_type application/json;
116+
return 200 '{
117+
"auth_config" : {
118+
"oidc_providers" : [ ... ]
119+
}
120+
}';
121+
}
122+
```
123+
124+
For basic deployments it might suffice to route requests to `/auth_provider` on the https port of the neo4j database.
76125

77-
## Extending NeoDash
126+
## Extending NeoDash
78127
There are two categories of extensions to NeoDash you can build:
79128
- Core Dashboard Functionality
80129
- Custom Reports

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "neodash",
3-
"version": "2.0.14",
3+
"version": "2.0.15",
44
"homepage": "",
55
"description": "NeoDash - Neo4j Dashboard Builder",
66
"neo4jDesktop": {
@@ -47,6 +47,7 @@
4747
"codemirror": "^5.65.1",
4848
"cypher-codemirror": "github:nielsdejong/cypher-editor#c0eff97fc97f22355e60b57fb6f8dc26b16f9a5f",
4949
"d3-scale-chromatic": "^3.0.0",
50+
"html2canvas": "^1.4.1",
5051
"leaflet": "^1.7.1",
5152
"material-ui-color-picker": "github:nielsdejong/material-ui-color-picker#c1bae552c1daf81952bf0478d7f71c1a416527d3",
5253
"neo4j-client-sso": "^1.2.2",

release-notes.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
## NeoDash 2.0.15
2+
This is the final minor update before the 2.1 release.
3+
4+
Changes:
5+
- Several stability improvements before the 2.1 release.
6+
- Updated Dockerfile to make better use of caching, and pick up environment variables at run time.
7+
- Added option to replace dashboard parameters in Markdown/iFrames to make them dynamic.
8+
- Removed unneeded index column from the CSV download for tables.
9+
- Added optional dashboard setting to enable image downloads for reports/the entire dashboard.
10+
11+
112
## NeoDash 2.0.14
213
Report features:
314
- Added optional "Download as CSV" button to table reports.

scripts/config-entrypoint.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/sh
2+
###########
3+
set -e
4+
5+
echo " \
6+
{ \
7+
\"ssoEnabled\": ${ssoEnabled:=false}, \
8+
\"ssoDiscoveryUrl\": \"${ssoDiscoveryUrl:='https://example.com'}\", \
9+
\"standalone\": "${standalone:=false}", \
10+
\"standaloneProtocol\": \"${standaloneProtocol:='neo4j+s'}\", \
11+
\"standaloneHost\": \"${standaloneHost:='test.databases.neo4j.io'}\", \
12+
\"standalonePort\": ${standalonePort:=7687}, \
13+
\"standaloneDatabase\": \"${standaloneDatabase:='neo4j'}\", \
14+
\"standaloneDashboardName\": \"${standaloneDashboardName:='My Dashboard'}\", \
15+
\"standaloneDashboardDatabase\": \"${standaloneDashboardDatabase:='neo4j'}\" \
16+
}" > /usr/share/nginx/html/config.json

scripts/message-entrypoint.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/sh
2+
###########
3+
4+
echo '-----------------------------------------------------------------------------------------'
5+
echo '| NeoDash is available on http://localhost:5005 by default. |'
6+
echo '| Make sure your ports are mapped correctly (-p 5005:5005) when starting the container. |'
7+
echo '-----------------------------------------------------------------------------------------'

scripts/push-docker-image.bash

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
docker build --no-cache --label "version=2.0.14" . -t neodash
2-
docker image tag neodash nielsdejong/neodash:2.0.14
1+
docker build --no-cache --label "version=2.0.15" . -t neodash
2+
docker image tag neodash nielsdejong/neodash:2.0.15
33
docker image tag neodash nielsdejong/neodash:latest
4-
docker push nielsdejong/neodash:2.0.14
4+
docker push nielsdejong/neodash:2.0.15
55
docker push nielsdejong/neodash:latest
66

src/application/Application.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import NeoAboutModal from '../modal/AboutModal';
1515
import { NeoUpgradeOldDashboardModal } from '../modal/UpgradeOldDashboardModal';
1616
import { loadDashboardThunk } from '../dashboard/DashboardThunks';
1717
import { NeoLoadSharedDashboardModal } from '../modal/LoadSharedDashboardModal';
18+
import { downloadComponentAsImage } from '../chart/util/ChartUtils';
1819

1920
/**
2021
* This is the main application component for NeoDash.
@@ -37,12 +38,14 @@ const Application = ({ connection, connected, hasCachedDashboard, oldDashboard,
3738
initializeApplication(initialized);
3839
}
3940

41+
const ref = React.useRef();
42+
4043
// Only render the dashboard component if we have an active Neo4j connection.
4144
return (
42-
<div style={{ display: 'flex' }}>
45+
<div ref={ref} style={{ display: 'flex' }}>
4346
<CssBaseline />
44-
<NeoDashboardPlaceholder connected={false}></NeoDashboardPlaceholder>
45-
{(connected) ? <Dashboard></Dashboard> : <></>}
47+
<NeoDashboardPlaceholder connected={connected}></NeoDashboardPlaceholder>
48+
{(connected) ? <Dashboard onDownloadDashboardAsImage={(e)=>downloadComponentAsImage(ref)}></Dashboard> : <></>}
4649
<NeoAboutModal
4750
open={aboutModalOpen}
4851
handleClose={onAboutModalClose}

src/application/ApplicationThunks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const createConnectionThunk = (protocol, url, port, database, username, p
4141

4242
// If we have remembered to load a specific dashboard after connecting to the database, take care of it here.
4343
const application = getState().application;
44-
if (application.dashboardToLoadAfterConnecting && application.dashboardToLoadAfterConnecting.startsWith("http")) {
44+
if (application.dashboardToLoadAfterConnecting && (application.dashboardToLoadAfterConnecting.startsWith("http") || application.dashboardToLoadAfterConnecting.startsWith("./") || application.dashboardToLoadAfterConnecting.startsWith("/"))) {
4545
fetch(application.dashboardToLoadAfterConnecting)
4646
.then(response => response.text())
4747
.then(data => dispatch(loadDashboardThunk(data)));

src/card/view/CardView.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,30 @@ import { CardContent, IconButton } from '@material-ui/core';
77
import { REPORT_TYPES } from '../../config/ReportConfig';
88
import NeoCodeEditorComponent from '../../component/editor/CodeEditorComponent';
99
import PlayCircleFilledIcon from '@material-ui/icons/PlayCircleFilled';
10+
import { downloadComponentAsImage } from '../../chart/util/ChartUtils';
1011

1112
export const CARD_FOOTER_HEIGHT = 64;
1213

13-
const NeoCardView = ({ title, database, query, cypherParameters, globalParameters, width, height, fields, active, setActive,
14+
const NeoCardView = ({ title, database, query, cypherParameters, globalParameters,
15+
width, height, fields, active, setActive,
1416
type, selection, dashboardSettings, settings, settingsOpen, refreshRate, editable,
1517
onGlobalParameterUpdate, onSelectionUpdate, onToggleCardSettings, onTitleUpdate,
1618
onFieldsUpdate, expanded, onToggleCardExpand }) => {
1719

1820
const reportHeight = (97 * height) + (148 * Math.floor((height - 1) / 3));
1921
const cardHeight = (120 * height) + (78 * Math.floor((height - 1) / 3)) - 7;
22+
const ref = React.useRef();
2023

2124
// @ts-ignore
2225
const reportHeader = <NeoCardViewHeader
2326
title={title}
2427
editable={editable}
2528
fullscreenEnabled={dashboardSettings.fullscreenEnabled}
29+
downloadImageEnabled={dashboardSettings.downloadImageEnabled}
2630
onTitleUpdate={onTitleUpdate}
2731
onToggleCardSettings={onToggleCardSettings}
32+
settings={settings}
33+
onDownloadImage={()=> downloadComponentAsImage(ref)}
2834
onToggleCardExpand={onToggleCardExpand}
2935
expanded={expanded}
3036
>
@@ -63,7 +69,7 @@ const NeoCardView = ({ title, database, query, cypherParameters, globalParameter
6369
{reportHeader}
6470
{/* if there's no selection for this report, we don't have a footer, so the report can be taller. */}
6571
<ReportItemContainer style={{ height: expanded ? (withoutFooter ? "calc(100% - 69px)" : "calc(100% - 79px)") : cardHeight }}>
66-
<CardContent style={{
72+
<CardContent ref={ref} style={{
6773
paddingBottom: "0px", paddingLeft: "0px", paddingRight: "0px", paddingTop: "0px", width: "100%", marginTop: "-3px",
6874
height: expanded ? (withoutFooter ? "100%" : `calc(100% - ${CARD_FOOTER_HEIGHT}px)`) : ((withoutFooter) ? reportHeight + CARD_FOOTER_HEIGHT + "px" : reportHeight + "px"),
6975
overflow: "auto", overflowY: "auto", overflowX: "auto"

0 commit comments

Comments
 (0)