88import React from 'react' ;
99import Sidebar from 'components/Sidebar/Sidebar.react' ;
1010import styles from 'dashboard/Dashboard.scss' ;
11+ import Icon from 'components/Icon/Icon.react' ;
12+ import baseStyles from 'stylesheets/base.scss' ;
13+ import Button from 'components/Button/Button.react' ;
1114import { CurrentApp } from 'context/currentApp' ;
1215
1316export default class DashboardView extends React . Component {
1417 static contextType = CurrentApp ;
15-
1618 /* A DashboardView renders two pieces: the sidebar, and the app itself */
19+
20+ constructor ( ) {
21+ super ( ) ;
22+ this . state = {
23+ route : '' ,
24+ } ;
25+ }
26+
27+ componentDidUpdate ( ) {
28+ this . onRouteChanged ( ) ;
29+ }
30+ componentDidMount ( ) {
31+ this . onRouteChanged ( ) ;
32+ }
33+
34+ onRouteChanged ( ) {
35+ const appId = this . context . applicationId ;
36+ const path = this . props . location ?. pathname ?? window . location . pathname ;
37+ const route = path . split ( appId ) [ 1 ] . split ( '/' ) [ 1 ] ;
38+ if ( route !== this . state . route ) {
39+ this . setState ( { route } ) ;
40+ }
41+ }
42+
1743 render ( ) {
1844 let sidebarChildren = null ;
1945 if ( typeof this . renderSidebar === 'function' ) {
2046 sidebarChildren = this . renderSidebar ( ) ;
2147 }
22- let appSlug = ( this . context ? this . context . slug : '' ) ;
48+ let appSlug = this . context ? this . context . slug : '' ;
2349
2450 if ( ! this . context . hasCheckedForMigraton ) {
25- this . context . getMigrations ( ) . promise
26- . then ( ( ) => this . forceUpdate ( ) , ( ) => { } ) ;
51+ this . context . getMigrations ( ) . promise . then (
52+ ( ) => this . forceUpdate ( ) ,
53+ ( ) => { }
54+ ) ;
2755 }
2856
2957 let features = this . context . serverInfo . features ;
3058
3159 let coreSubsections = [ ] ;
32- if ( features . schemas &&
60+ if (
61+ features . schemas &&
3362 features . schemas . addField &&
3463 features . schemas . removeField &&
3564 features . schemas . addClass &&
36- features . schemas . removeClass ) {
65+ features . schemas . removeClass
66+ ) {
3767 coreSubsections . push ( {
3868 name : 'Browser' ,
39- link : '/browser'
69+ link : '/browser' ,
4070 } ) ;
4171 }
4272
4373 if ( features . cloudCode && features . cloudCode . viewCode ) {
4474 coreSubsections . push ( {
4575 name : 'Cloud Code' ,
46- link : '/cloud_code'
76+ link : '/cloud_code' ,
4777 } ) ;
4878 }
4979
5080 //webhooks requires removal of heroku link code, then it should work.
51- if ( features . hooks && features . hooks . create && features . hooks . read && features . hooks . update && features . hooks . delete ) {
81+ if (
82+ features . hooks &&
83+ features . hooks . create &&
84+ features . hooks . read &&
85+ features . hooks . update &&
86+ features . hooks . delete
87+ ) {
5288 coreSubsections . push ( {
5389 name : 'Webhooks' ,
54- link : '/webhooks'
90+ link : '/webhooks' ,
5591 } ) ;
5692 }
5793
5894 if ( features . cloudCode && features . cloudCode . jobs ) {
5995 coreSubsections . push ( {
6096 name : 'Jobs' ,
61- link : '/jobs'
97+ link : '/jobs' ,
6298 } ) ;
6399 }
64100
65- if ( features . logs && Object . keys ( features . logs ) . some ( key => features . logs [ key ] ) ) {
101+ if (
102+ features . logs &&
103+ Object . keys ( features . logs ) . some ( ( key ) => features . logs [ key ] )
104+ ) {
66105 coreSubsections . push ( {
67106 name : 'Logs' ,
68- link : '/logs'
107+ link : '/logs' ,
69108 } ) ;
70109 }
71110
72- if ( features . globalConfig &&
111+ if (
112+ features . globalConfig &&
73113 features . globalConfig . create &&
74114 features . globalConfig . read &&
75115 features . globalConfig . update &&
76- features . globalConfig . delete ) {
116+ features . globalConfig . delete
117+ ) {
77118 coreSubsections . push ( {
78119 name : 'Config' ,
79- link : '/config'
120+ link : '/config' ,
80121 } ) ;
81122 }
82123
83- coreSubsections . push ( {
84- name : 'API Console' ,
85- link : '/api_console'
86- } ) ;
124+ if ( ! this . context . serverInfo . error ) {
125+ coreSubsections . push ( {
126+ name : 'API Console' ,
127+ link : '/api_console' ,
128+ } ) ;
129+ }
87130
88131 if ( this . context . migration ) {
89132 coreSubsections . push ( {
@@ -96,21 +139,21 @@ export default class DashboardView extends React.Component {
96139 if ( features . push && features . push . immediatePush ) {
97140 pushSubsections . push ( {
98141 name : 'Send New Push' ,
99- link : '/push/new'
142+ link : '/push/new' ,
100143 } ) ;
101144 }
102145
103146 if ( features . push && features . push . storedPushData ) {
104147 pushSubsections . push ( {
105148 name : 'Past Pushes' ,
106- link : '/push/activity'
149+ link : '/push/activity' ,
107150 } ) ;
108151 }
109152
110153 if ( features . push && features . push . pushAudiences ) {
111154 pushSubsections . push ( {
112155 name : 'Audiences' ,
113- link : '/push/audiences'
156+ link : '/push/audiences' ,
114157 } ) ;
115158 }
116159
@@ -195,7 +238,7 @@ export default class DashboardView extends React.Component {
195238 });
196239 }*/
197240
198- let appSidebarSections = [ ]
241+ let appSidebarSections = [ ] ;
199242
200243 if ( coreSubsections . length > 0 ) {
201244 appSidebarSections . push ( {
@@ -211,7 +254,7 @@ export default class DashboardView extends React.Component {
211254 name : 'Push' ,
212255 icon : 'push-outline' ,
213256 link : '/push' ,
214- style : { paddingLeft : '16px' } ,
257+ style : { paddingLeft : '16px' } ,
215258 subsections : pushSubsections ,
216259 } ) ;
217260 }
@@ -221,7 +264,7 @@ export default class DashboardView extends React.Component {
221264 name : 'Analytics' ,
222265 icon : 'analytics-outline' ,
223266 link : '/analytics' ,
224- subsections : analyticsSidebarSections
267+ subsections : analyticsSidebarSections ,
225268 } ) ;
226269 }
227270
@@ -230,29 +273,77 @@ export default class DashboardView extends React.Component {
230273 name : 'App Settings' ,
231274 icon : 'gear-solid' ,
232275 link : '/settings' ,
233- subsections : settingsSections
276+ subsections : settingsSections ,
234277 } ) ;
235278 }
236279
237280 let sidebar = (
238- < Sidebar
239- sections = { appSidebarSections }
240- appSelector = { true }
241- section = { this . section }
242- subsection = { this . subsection }
243- prefix = { '/apps/' + appSlug }
244- action = { this . action }
245- primaryBackgroundColor = { this . context . primaryBackgroundColor }
246- secondaryBackgroundColor = { this . context . secondaryBackgroundColor }
281+ < Sidebar
282+ sections = { appSidebarSections }
283+ appSelector = { true }
284+ section = { this . section }
285+ subsection = { this . subsection }
286+ prefix = { '/apps/' + appSlug }
287+ action = { this . action }
288+ primaryBackgroundColor = { this . context . primaryBackgroundColor }
289+ secondaryBackgroundColor = { this . context . secondaryBackgroundColor }
247290 >
248- { sidebarChildren }
249- </ Sidebar > ) ;
291+ { sidebarChildren }
292+ </ Sidebar >
293+ ) ;
294+
295+ let content = < div className = { styles . content } > { this . renderContent ( ) } </ div > ;
296+ const canRoute = [ ...coreSubsections , ...pushSubsections ]
297+ . map ( ( { link } ) => link . split ( '/' ) [ 1 ] )
298+ . includes ( this . state . route ) ;
299+
300+ if ( ! canRoute ) {
301+ content = (
302+ < div className = { styles . empty } >
303+ < div className = { baseStyles . center } >
304+ < div className = { styles . cloud } >
305+ < Icon
306+ width = { 110 }
307+ height = { 110 }
308+ name = "cloud-surprise"
309+ fill = "#1e3b4d"
310+ />
311+ </ div >
312+ < div className = { styles . loadingError } > Feature unavailable</ div >
313+ </ div >
314+ </ div >
315+ ) ;
316+ }
317+
318+ if ( this . context . serverInfo . error ) {
319+ content = (
320+ < div className = { styles . empty } >
321+ < div className = { baseStyles . center } >
322+ < div className = { styles . cloud } >
323+ < Icon
324+ width = { 110 }
325+ height = { 110 }
326+ name = "cloud-surprise"
327+ fill = "#1e3b4d"
328+ />
329+ </ div >
330+ < div className = { styles . loadingError } >
331+ { this . context . serverInfo . error . replace ( / - / g, '\u2011' ) }
332+ </ div >
333+ < Button
334+ color = "white"
335+ value = "Reload"
336+ width = "120px"
337+ onClick = { ( ) => location . reload ( ) }
338+ />
339+ </ div >
340+ </ div >
341+ ) ;
342+ }
250343
251344 return (
252345 < div className = { styles . dashboard } >
253- < div className = { styles . content } >
254- { this . renderContent ( ) }
255- </ div >
346+ { content }
256347 { sidebar }
257348 </ div >
258349 ) ;
0 commit comments