Skip to content

Commit 48873de

Browse files
committed
More comments added to the code
1 parent 2e45d9a commit 48873de

File tree

11 files changed

+508
-248
lines changed

11 files changed

+508
-248
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "neodash",
33
"description": "NeoDash - Neo4j Dashboard Builder",
4-
"version": "1.0.6",
4+
"version": "1.0.7",
55
"homepage": "./",
66
"neo4jDesktop": {
77
"apiVersion": "^1.2.0"

src/NeoDash.js

Lines changed: 250 additions & 192 deletions
Large diffs are not rendered by default.

src/card/NeoCard.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import NeoLinePropertySelect from "../report/line/NeoLinePropertySelect";
1818
import NeoPropertySelectReport from "../report/select/NeoPropertySelectReport";
1919

2020

21-
let emptyAction = <div key={0}></div>;
21+
let emptyAction = <div key={0}/>;
2222

2323
/**
2424
* A NeoCard represents a single card in a dashboard.
@@ -561,7 +561,7 @@ class NeoCard extends React.Component {
561561
* This button sits in the same list as regular cards.
562562
* After clicking the button, a new card gets added the dashboard.
563563
*/
564-
class AddNeoCardComponent extends React.Component {
564+
class AddNeoCard extends React.Component {
565565
constructor(props) {
566566
super(props);
567567
}
@@ -583,4 +583,4 @@ class AddNeoCardComponent extends React.Component {
583583
}
584584

585585
export const NeoCardComponent = NeoCard;
586-
export const AddNeoCard = AddNeoCardComponent;
586+
export const AddNeoCardComponent = AddNeoCard;

src/card/NeoCardSettings.js

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import NeoTextInput from "../component/NeoTextInput";
66
import NeoAutoCompleteText from "../component/NeoAutoCompleteText";
77

88
/**
9-
* A NeoCardSettings component is the settings window that pops up when you edit a card.
10-
*
9+
* A 'NeoCardSettings' component is the settings window that pops up when you edit a card.
10+
* These settings will allow the user to modify the type of report, size of report, active query, etc.
1111
*/
1212
class NeoCardSettings extends React.Component {
13+
// A dictionary of available report types.
1314
vizOptions = {
1415
'table': 'Table',
1516
'graph': 'Graph',
@@ -19,6 +20,8 @@ class NeoCardSettings extends React.Component {
1920
'select': 'Selection',
2021
'text': 'Markdown',
2122
};
23+
24+
// A dictionary of available card sizes.
2225
sizeOptions = {
2326
4: 'Small (4x4)',
2427
6: 'Medium (6x4)',
@@ -30,15 +33,23 @@ class NeoCardSettings extends React.Component {
3033
24: 'Full (12x8)'
3134
};
3235

36+
/**
37+
* Initializes the card settings and sets default components.
38+
*/
3339
constructor(props) {
3440
super(props);
3541
this.stateChanged = this.stateChanged.bind(this);
3642
this.setDefaultComponents();
3743
}
3844

45+
/**
46+
* Sets the default components of the card settings window:
47+
* - A text area to enter Cypher queries/markdown.
48+
* - Input areas for Cypher parameters, refresh rate, card size, etc.
49+
* - Buttons to move and resize cards.
50+
*/
3951
setDefaultComponents() {
40-
41-
this.neoTextArea =
52+
this.settingsTextArea =
4253
<NeoTextArea placeholder={this.props.placeholder} defaultValue={this.props.query} name="Query"
4354
onChange={this.stateChanged}/>;
4455
this.cypherParamsInput = <NeoTextInput defaultValue={this.props.parameters} onChange={this.stateChanged}
@@ -63,17 +74,28 @@ class NeoCardSettings extends React.Component {
6374

6475
}
6576

77+
setTypeAndSizeSelectionComponents(type) {
78+
this.cardTypeSelect = <NeoOptionSelect label="Type" defaultValue={type} onChange={this.stateChanged}
79+
options={this.vizOptions}/>;
80+
this.cardSizeSelect = <NeoOptionSelect label="Size" defaultValue={this.props.size} onChange={this.stateChanged}
81+
options={this.sizeOptions}/>;
82+
}
83+
6684
/**
67-
* Helper function to convert a string with capital letters and spaces to a lowercase snake case verison.
85+
* Helper function to convert a string with capital letters and spaces to a lowercase snake case version.
6886
*/
6987
toLowerCaseSnakeCase(value) {
7088
return value.toLowerCase().replace(/ /g, "_");
7189
}
7290

91+
/**
92+
* If a 'selection' type is chosen for this card,
93+
* build the components for letting a user selection nodes/properties.
94+
*
95+
* TODO: This is currently (Unnecessarily) called for all types of cards.
96+
*/
7397
buildCustomSelectionSettingsWindow() {
74-
7598
var selectionMessage = "Choose a node label to select.";
76-
7799
let nodeSelectedQuery = "CALL db.schema.nodeTypeProperties() YIELD nodeLabels" +
78100
" UNWIND nodeLabels as nodeLabel WITH DISTINCT nodeLabel as label" +
79101
" WHERE toLower(label) contains toLower($input)" +
@@ -93,8 +115,8 @@ class NeoCardSettings extends React.Component {
93115
defaultValue={(this.props.properties[0]) ? this.props.properties[0] : ""}
94116
/>;
95117

96-
var propertySelectionBox = <div></div>
97-
var propertyIdSelectionBox = <div></div>
118+
var propertySelectionBox = <div/>
119+
var propertyIdSelectionBox = <div/>
98120
if (this.props.properties && this.props.properties[0]) {
99121
selectionMessage = "Choose a node property to select.";
100122
let propertySelectedQuery = "CALL db.schema.nodeTypeProperties() YIELD nodeLabels, propertyName\n" +
@@ -118,10 +140,12 @@ class NeoCardSettings extends React.Component {
118140

119141

120142
/>;
121-
propertyIdSelectionBox = <NeoTextInput numeric defaultValue={this.props.properties[2] ? this.props.properties[2] : ""} onChange={this.stateChanged}
122-
changeEventLabel={"PropertySelectionIdUpdated"}
123-
style={{width: '80px'}} label={"ID"}
124-
placeholder={"(optional)"}/>;
143+
propertyIdSelectionBox =
144+
<NeoTextInput numeric defaultValue={this.props.properties[2] ? this.props.properties[2] : ""}
145+
onChange={this.stateChanged}
146+
changeEventLabel={"PropertySelectionIdUpdated"}
147+
style={{width: '80px'}} label={"ID"}
148+
placeholder={"(optional)"}/>;
125149
}
126150

127151
if (this.props.properties && this.props.properties[0] && this.props.properties[1]) {
@@ -133,41 +157,43 @@ class NeoCardSettings extends React.Component {
133157
value.</>;
134158
}
135159

136-
this.selectionArea = <div style={{width: "100%"}}>
160+
this.settingsSelectionArea = <div style={{width: "100%"}}>
137161
{nodeSelectionBox}
138162
{propertySelectionBox}
139163
{propertyIdSelectionBox}
140164
<p style={{"display": "block", width: '350px'}}>{selectionMessage}</p>
141165
</div>
142166
}
143167

168+
/**
169+
* On change, refresh the default components of the settings window.
170+
*/
144171
componentDidUpdate(prevProps, prevState, snapshot) {
145172
this.setDefaultComponents();
146173
}
147174

175+
/**
176+
* on state change, we possibly re-render the settings component.
177+
*/
148178
stateChanged(data) {
149-
// if the report type changes, we possibly need to re-render the settings component.
150-
if (data["label"] === "TypeChanged") {
151-
}
152179
this.props.onChange(data);
153-
154180
}
155181

182+
/**
183+
* Renders the settings component.
184+
*/
156185
render() {
157186
this.buildCustomSelectionSettingsWindow();
158-
let type = this.props.type;
187+
this.setTypeAndSizeSelectionComponents(this.props.type);
159188
return (
160189
<div>
161190
{this.cardMovementControls}
162-
<NeoOptionSelect label="Type" defaultValue={type} onChange={this.stateChanged}
163-
options={this.vizOptions}/>
164-
<NeoOptionSelect label="Size" defaultValue={this.props.size} onChange={this.stateChanged}
165-
options={this.sizeOptions}/>
166-
167-
{(type !== "select") ? this.cypherParamsInput : <div></div>}
168-
{(type !== "select") ? this.refreshRateInput : <div></div>}
169-
{(type !== "select") ? this.neoTextArea : <div></div>}
170-
{(type === "select") ? this.selectionArea : <div></div>}
191+
{this.cardTypeSelect}
192+
{this.cardSizeSelect}
193+
{(this.props.type !== "select") ? this.cypherParamsInput : <div/>}
194+
{(this.props.type !== "select") ? this.refreshRateInput : <div/>}
195+
{(this.props.type !== "select") ? this.settingsTextArea : <div/>}
196+
{(this.props.type === "select") ? this.settingsSelectionArea : <div/>}
171197
</div>
172198
);
173199
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import Modal from "react-materialize/lib/Modal";
2+
import React from "react";
3+
import Button from "react-materialize/lib/Button";
4+
import Textarea from "react-materialize/lib/Textarea";
5+
import NeoModal from "./NeoModal";
6+
import NavItem from "react-materialize/lib/NavItem";
7+
import NeoTextInput from "./NeoTextInput";
8+
import NeoCheckBox from "./NeoCheckBox";
9+
import NeoTextButton from "./NeoTextButton";
10+
11+
12+
class NeoConnectionModal extends NeoModal {
13+
constructor(props) {
14+
super(props);
15+
}
16+
17+
render() {
18+
return (
19+
<NeoModal
20+
header={'Connect to Neo4j'}
21+
style={{'maxWidth': '520px'}}
22+
key={this.props.key}
23+
id={this.props.key}
24+
footerType={"modal-dark-footer"}
25+
open={this.props.open}
26+
root={document.getElementById("root")}
27+
28+
actions={[
29+
<p>
30+
NeoDash is a tool for prototyping Neo4j dashboards.
31+
Building a production-grade front-end instead? &nbsp;
32+
<u><a style={{color: "white"}} href="#"
33+
onClick={this.props.onGetInTouchClicked}>Get in touch</a></u>!
34+
</p>
35+
36+
]}
37+
trigger={
38+
<NavItem href="" onClick={this.props.navClicked}>Neo4j Connection</NavItem>
39+
}
40+
content={<div className="modal-input-text" style={{margin: '20px'}}>
41+
<img style={{height: '38px', right: '20px', top: '25px', position: 'absolute'}} src={"neo.png"}/>
42+
<p>&nbsp;</p>
43+
<form onSubmit={this.props.onConnect}>
44+
<NeoTextInput onChange={this.props.stateChanged} changeEventLabel={"ConnectURLChanged"}
45+
style={{'width': '100%'}} label={"Connect URL"}
46+
defaultValue={this.props.connection.url}/>
47+
<NeoTextInput onChange={this.stateChanged} changeEventLabel={"DatabaseChanged"}
48+
label={"Database"}
49+
placeholder={'neo4j'}
50+
defaultValue={this.props.connection.database}
51+
/>
52+
<NeoTextInput onChange={this.stateChanged} changeEventLabel={"UsernameChanged"}
53+
label={"Username"}
54+
defaultValue={this.props.connection.username}/>
55+
<NeoTextInput onChange={this.stateChanged} changeEventLabel={"PasswordChanged"}
56+
password={true}
57+
label={"Password"}
58+
defaultValue={this.props.connection.password}
59+
placeholder={''}/>
60+
<div style={{marginTop: "10px"}}>
61+
62+
<NeoCheckBox onChange={this.stateChanged}
63+
changeEventLabel={"EncryptionChanged"}
64+
label={"Encrypted Connection"}
65+
defaultValue={(this.props.connection.encryption === "on") ? "on" : "off"}>
66+
67+
</NeoCheckBox>
68+
<NeoTextButton right modal="close"
69+
color={"neo-color"}
70+
icon='play_arrow'
71+
node="button"
72+
onClick={this.props.connect}
73+
text={"connect"}
74+
waves="green"/>
75+
</div>
76+
77+
78+
<input style={{display: 'none'}} type="submit"/></form>
79+
80+
</div>}
81+
/>
82+
)
83+
}
84+
85+
86+
}
87+
88+
export default (NeoConnectionModal);

src/component/NeoSaveLoadModal.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import Modal from "react-materialize/lib/Modal";
2+
import React from "react";
3+
import Button from "react-materialize/lib/Button";
4+
import Textarea from "react-materialize/lib/Textarea";
5+
import NeoModal from "./NeoModal";
6+
7+
8+
class NeoSaveLoadModal extends NeoModal {
9+
constructor(props) {
10+
super(props);
11+
}
12+
13+
render() {
14+
return (
15+
<NeoModal header={"🖨 Load/Export Dashboard as JSON"}
16+
root={document.getElementById("root")}
17+
json={this.props.json}
18+
placeholder={"Paste a dashboard JSON file here..."}
19+
actions={[
20+
<Button style={{position: 'absolute', right: '20px', top: '20px'}} modal="close"
21+
node="button"
22+
onClick={this.props.loadJson}
23+
waves="green">Save</Button>
24+
]}
25+
trigger={
26+
this.props.trigger
27+
}
28+
componentDidUpdate={this.props.update}
29+
stateChanged={this.props.stateChanged}
30+
content={<Textarea style={{minHeight: '500px'}} id="Textarea-12" l={12} m={12} s={12} xl={12}
31+
onChange={this.props.change} value={this.props.value}
32+
placeholder={this.props.placeholder}/>}
33+
/>
34+
)
35+
}
36+
37+
38+
}
39+
40+
export default (NeoSaveLoadModal);

src/component/NeoTextArea.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
import React from "react";
22
import Textarea from "react-materialize/lib/Textarea";
33

4+
/**
5+
* A NeoTextArea is a multi-line text entry box with page numbers.
6+
* NeoTextAreas are used as Cypher-input boxes or to display errors.
7+
*/
48
class NeoTextArea extends React.Component {
9+
disclaimer = 'Limit a query to 1000 result rows for best performance. Cypher parameter keys & values must be in quotes.';
10+
defaultPlaceholder = "Enter Cypher here... \n";
11+
12+
/**
13+
* Initializes the NeoTextArea with a default value.
14+
*/
515
constructor(props) {
616
super(props);
717
this.state = {
818
value: this.props.defaultValue,
919
}
10-
1120
}
12-
21+
/**
22+
* Renders the component. On change, the method specified in this.props.onChange is called.
23+
*/
1324
render() {
14-
let disclaimer = 'Limit a query to 1000 result rows for best performance. Cypher parameter keys & values must be in quotes.';
1525
return <Textarea
1626
onChange={e => {
1727
let newState = {value: e.target.value};
@@ -23,8 +33,8 @@ class NeoTextArea extends React.Component {
2333
l={12}
2434
m={12}
2535
s={12}
26-
placeholder={(this.props.placeholder) ? this.props.placeholder : "Enter Cypher here... \n"}
27-
xl={12}><p style={{fontSize: 12}}>{disclaimer}</p></Textarea>;
36+
placeholder={(this.props.placeholder) ? this.props.placeholder : this.defaultPlaceholder}
37+
xl={12}><p style={{fontSize: 12}}>{this.disclaimer}</p></Textarea>;
2838
}
2939
}
3040

0 commit comments

Comments
 (0)