@@ -19,6 +19,8 @@ import Tabs from "react-materialize/lib/Tabs";
1919import Tab from "react-materialize/lib/Tab" ;
2020import NeoTextInput from "./component/NeoTextInput" ;
2121import 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