Skip to content

Commit b20e820

Browse files
committed
Better pagination (adding/deleting/improved styling
1 parent 82863c9 commit b20e820

File tree

2 files changed

+211
-58
lines changed

2 files changed

+211
-58
lines changed

public/style.css

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,69 @@ code {
6969
#root {
7070
background-color: #efefef;
7171
}
72+
.tabs .indicator {
73+
display: none;
74+
}
75+
.tab a.active {
76+
border-bottom: 2px solid white;
77+
}
78+
.tabs {
79+
overflow-y: auto; !important;
80+
81+
/*overflow-y: fragments;*/
82+
height: auto !important;
83+
}
84+
.btn-add-tab {
85+
width: 30px;
86+
height: 30px;
87+
line-height: 30px;
88+
background-color: #444;
89+
opacity: 0.2;
90+
margin-left: 15px;
91+
margin-top: -6px;
92+
margin-right: 15px;
93+
}
7294

95+
.tabs .disabled {
96+
width: auto !important;
97+
}
98+
.tabs .disabled a .input-field input {
99+
width: auto !important;
100+
margin-left: auto !important;
101+
}
102+
.tab a .input-field input {
103+
width: 200px;
104+
margin-left: -20px;
105+
}
106+
.tab {
107+
width: 250px;
108+
}
109+
.tab a .input-field input {
110+
width: 200px;
111+
margin-left: -20px;
112+
}
113+
.btn-center-align :hover {
114+
background-color: #444 !important;
115+
opacity: 0.7;
116+
}
117+
.btn-add-tab i {
118+
margin-top: -13px;
119+
}
120+
.btn-remove-tab {
121+
122+
width: 30px;
123+
height: 30px;
124+
line-height: 30px;
125+
126+
background-color: transparent;
127+
opacity: 0.2;
128+
margin-top: -97.5px;
129+
margin-left: 220px;
130+
}
131+
132+
.btn-remove-tab i {
133+
margin-top: -13px;
134+
}
73135
.btn-center-align {
74136

75137
margin-left: 45%;

src/NeoDash.js

Lines changed: 149 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import Tabs from "react-materialize/lib/Tabs";
1919
import Tab from "react-materialize/lib/Tab";
2020
import NeoTextInput from "./component/NeoTextInput";
2121
import TextInput from "react-materialize/lib/TextInput";
22+
import Card from "react-materialize/lib/Card";
23+
import NeoTextButton from "./component/NeoTextButton";
2224

2325

2426
/**
@@ -217,27 +219,27 @@ class NeoDash extends React.Component {
217219
return page.title
218220
});
219221

220-
this.state.pagenumber = 0; //loaded.pagenumber ? loaded.pagenumber : 0;
222+
this.state.pagenumber = loaded.pagenumber ? loaded.pagenumber : 0;
221223
this.state.pageState = loaded.pages.map((page) => {
222-
return page.reports.map((report,index) => {
224+
return page.reports.map((report, index) => {
223225
return {
224226
connection: this.connection,
225227
globalParameters: this.state.globalParameters,
226-
page :report.page,
227-
width : report.width,
228-
height : report.height,
229-
kkey : this.state.count + index,
230-
key : this.state.count + index,
231-
id : index,
232-
session : this.session,
233-
onChange : this.stateChanged,
234-
editable : this.state.editable,
235-
type : report.type,
236-
propertiesSelected : report.properties,
237-
title : report.title,
238-
query : report.query,
239-
parameters : report.parameters,
240-
refresh : report.refresh
228+
page: report.page,
229+
width: report.width,
230+
height: report.height,
231+
kkey: this.state.count + index,
232+
key: this.state.count + index,
233+
id: index,
234+
session: this.session,
235+
onChange: this.stateChanged,
236+
editable: this.state.editable,
237+
type: report.type,
238+
propertiesSelected: report.properties,
239+
title: report.title,
240+
query: report.query,
241+
parameters: report.parameters,
242+
refresh: report.refresh
241243
}
242244
})
243245
})
@@ -315,10 +317,48 @@ class NeoDash extends React.Component {
315317
if (update.label === "GlobalParameterChanged") {
316318
this.updateGlobalParametersForAllCards(update);
317319
}
320+
if (update.label === "AddPage") {
321+
// Adds a new page & switches to the new page
322+
this.state.pageState.push([{}])
323+
this.state.pageTitles.push("new page")
324+
this.buildJSONFromReportsState();
325+
326+
}
327+
if (update.label === "AskForDeletePage") {
328+
this.createPageDeletionPopupModal();
329+
this.state.count += 1;
330+
}
331+
if (update.label === "DeletePage") {
332+
if (this.state.pageState.length <= 1) {
333+
this.stateChanged({
334+
label: "CreateError",
335+
value: "You cannot delete the only page of a dashboard."
336+
})
337+
this.state.count += 1;
338+
return
339+
}
340+
this.state.pageState.splice(this.state.pagenumber, 1);
341+
this.state.pageTitles.splice(this.state.pagenumber, 1);
342+
if (this.state.pagenumber > this.state.pageState.length - 1) {
343+
this.state.pagenumber = this.state.pageState.length - 1;
344+
}
345+
this.buildJSONFromReportsState();
346+
let loaded = JSON.parse(this.state.json)
347+
this.generateDashboardCardComponents(loaded)
348+
this.state.count += 1;
349+
}
318350
if (update.label === "PageChanged") {
351+
if (update.value.tagName !== "INPUT") {
352+
// We should always click an Input element when switching pages
353+
return
354+
}
355+
console.log(update.value)
356+
console.log(update.value.parentNode)
357+
console.log(update.value.parentNode.parentNode)
358+
console.log(update.value.parentNode.parentNode.parentNode)
319359
let tabClicked = update.value.parentNode.parentNode.parentNode;
320360
let index = Array.from(tabClicked.parentNode.children).indexOf(tabClicked);
321-
if (this.state.pagenumber === index){
361+
if (this.state.pagenumber === index) {
322362
return;
323363
}
324364
this.state.pagenumber = index;
@@ -480,6 +520,41 @@ class NeoDash extends React.Component {
480520
return value.toLowerCase().replace(/ /g, "_");
481521
}
482522

523+
/**
524+
* Creates a pop-up window (Modal). Used for displaying errors and other notifications.
525+
*/
526+
createPageDeletionPopupModal() {
527+
let header = "Delete Page";
528+
let content = "Are you sure you want to delete the current page? This cannot be undone.";
529+
530+
531+
// Create the modal object
532+
this.errorModal = <NeoModal header={header}
533+
open={true}
534+
trigger={null}
535+
content={<p>{content}</p>}
536+
key={this.state.count}
537+
id={this.state.count}
538+
root={document.getElementById("root")}
539+
actions={[
540+
<Button flat modal="close"
541+
node="button"
542+
waves="red">Cancel</Button>,
543+
<NeoTextButton right modal="close"
544+
color={"white-color"}
545+
icon='delete'
546+
node="button"
547+
modal="close"
548+
style={{backgroundColor: "red"}}
549+
onClick={e => this.stateChanged({
550+
label: "DeletePage",
551+
value: e.target.value
552+
})}
553+
text={"delete"}
554+
waves="red"/>
555+
]}/>
556+
}
557+
483558
/**
484559
* Creates a pop-up window (Modal). Used for displaying errors and other notifications.
485560
*/
@@ -550,7 +625,7 @@ class NeoDash extends React.Component {
550625
"title": this.state.title,
551626
"version": "1.1",
552627
"editable": this.state.editable,
553-
"pagenumber": 0,
628+
"pagenumber": (this.state.pagenumber) ? this.state.pagenumber : 0,
554629
"pages": this.state.pageState.map((p, pagenumber) => {
555630
return {
556631
"title": this.state.pageTitles[pagenumber],
@@ -632,49 +707,65 @@ class NeoDash extends React.Component {
632707
* Creates the navigation bar of the dashboard.
633708
*/
634709
createDashboardNavbar(saveLoadModal) {
635-
let title = <Textarea disabled={!this.state.editable} noLayout={true}
636-
className="card-title editable-title"
637-
key={this.state.count}
638-
value={this.state.title}
639-
onChange={e => this.stateChanged({
640-
label: "DashboardTitleChanged",
641-
value: e.target.value
642-
})}/>;
643-
let tabslist = [
644-
<Tab className="white-text" options={{
710+
let dashboardTitle = <Textarea disabled={!this.state.editable} noLayout={true}
711+
className="card-title editable-title"
712+
key={this.state.count}
713+
value={this.state.title}
714+
onChange={e => this.stateChanged({
715+
label: "DashboardTitleChanged",
716+
value: e.target.value
717+
})}/>;
718+
719+
// if the page titles are loaded, build the list of tabs
720+
let tabslist = (this.state.pageTitles) ? this.state.pageTitles.map((t, i) => {
721+
let deletePageButton = <Button className="btn-floating btn-remove-tab"
722+
onClick={e => {
723+
if (this.state.editable) this.stateChanged({
724+
label: "AskForDeletePage",
725+
value: "delete"
726+
})
727+
}}><Icon>close</Icon></Button>;
728+
return <Tab active={this.state.pagenumber === i} className="white-text tab-page" options={{
645729
duration: 300,
646730
onShow: null,
647731
responsiveThreshold: Infinity,
648732
swipeable: false
649-
}} title={ <TextInput disabled={!this.state.editable} noLayout={true}
650-
className="card-page-nav editable-page-nav tabs tab"
651-
key={0}
652-
value={(this.state.pageTitles) ? this.state.pageTitles[0] : ""}
653-
onChange={e => this.stateChanged({
654-
label: "PageTitleChanged",
655-
value: e.target
656-
})}/>}>
657-
</Tab>,
658-
<Tab active className="white-text" options={{
659-
duration: 300,
660-
responsiveThreshold: Infinity,
661-
swipeable: false
662-
}} title={<TextInput disabled={!this.state.editable} noLayout={true}
663-
664-
className="card-page-nav editable-page-nav tabs tab"
665-
key={1}
666-
value={(this.state.pageTitles) ? this.state.pageTitles[1] : ""}
667-
onChange={e => this.stateChanged({
668-
label: "PageTitleChanged",
669-
value: e.target
670-
})}/>}>
671-
672-
</Tab>];
673-
let tabs = <Tabs className="tabs-transparent tabs-grey"
674-
onChange={e => this.stateChanged({label: "PageChanged", value: e.target})}>
675-
{tabslist}
676-
</Tabs>;
677-
return <Navbar alignLinks="right" brand={title} centerLogo id="mobile-nav"
733+
}} title={<><TextInput noLayout={true}
734+
className="card-page-nav editable-page-nav tabs tab"
735+
key={i}
736+
value={t ? t : ""}
737+
onChange={e => {
738+
if (this.state.editable) {
739+
this.stateChanged({
740+
label: "PageTitleChanged",
741+
value: e.target
742+
})
743+
}
744+
}}/> {(this.state.pagenumber === i) ? deletePageButton : <></>}</>}>
745+
</Tab>
746+
}) : [];
747+
748+
let addNewTab = <Tab disabled className="white-text" options={{
749+
duration: 300,
750+
onShow: null,
751+
responsiveThreshold: Infinity,
752+
swipeable: false
753+
}} title={<Button className="btn-floating btn-add-tab"
754+
onClick={e => this.stateChanged({
755+
label: "AddPage",
756+
value: e.target
757+
})}><Icon>add</Icon></Button>}>
758+
</Tab>
759+
760+
let tabs = (this.state.pageTitles) ? <Tabs className="tabs-transparent tabs-grey"
761+
onChange={e => this.stateChanged({
762+
label: "PageChanged",
763+
value: e.target
764+
})}>
765+
{tabslist}{(this.state.editable) ? addNewTab : <></>}
766+
</Tabs> : <></>;
767+
768+
return <Navbar alignLinks="right" brand={dashboardTitle} centerLogo id="mobile-nav"
678769
menuIcon={<Icon>menu</Icon>}
679770
options={{
680771
draggable: true,

0 commit comments

Comments
 (0)