8
8
import React from 'react' ;
9
9
import Sidebar from 'components/Sidebar/Sidebar.react' ;
10
10
import 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' ;
11
14
import { CurrentApp } from 'context/currentApp' ;
12
15
13
16
export default class DashboardView extends React . Component {
14
17
static contextType = CurrentApp ;
15
-
16
18
/* 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
+
17
43
render ( ) {
18
44
let sidebarChildren = null ;
19
45
if ( typeof this . renderSidebar === 'function' ) {
20
46
sidebarChildren = this . renderSidebar ( ) ;
21
47
}
22
- let appSlug = ( this . context ? this . context . slug : '' ) ;
48
+ let appSlug = this . context ? this . context . slug : '' ;
23
49
24
50
if ( ! this . context . hasCheckedForMigraton ) {
25
- this . context . getMigrations ( ) . promise
26
- . then ( ( ) => this . forceUpdate ( ) , ( ) => { } ) ;
51
+ this . context . getMigrations ( ) . promise . then (
52
+ ( ) => this . forceUpdate ( ) ,
53
+ ( ) => { }
54
+ ) ;
27
55
}
28
56
29
57
let features = this . context . serverInfo . features ;
30
58
31
59
let coreSubsections = [ ] ;
32
- if ( features . schemas &&
60
+ if (
61
+ features . schemas &&
33
62
features . schemas . addField &&
34
63
features . schemas . removeField &&
35
64
features . schemas . addClass &&
36
- features . schemas . removeClass ) {
65
+ features . schemas . removeClass
66
+ ) {
37
67
coreSubsections . push ( {
38
68
name : 'Browser' ,
39
- link : '/browser'
69
+ link : '/browser' ,
40
70
} ) ;
41
71
}
42
72
43
73
if ( features . cloudCode && features . cloudCode . viewCode ) {
44
74
coreSubsections . push ( {
45
75
name : 'Cloud Code' ,
46
- link : '/cloud_code'
76
+ link : '/cloud_code' ,
47
77
} ) ;
48
78
}
49
79
50
80
//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
+ ) {
52
88
coreSubsections . push ( {
53
89
name : 'Webhooks' ,
54
- link : '/webhooks'
90
+ link : '/webhooks' ,
55
91
} ) ;
56
92
}
57
93
58
94
if ( features . cloudCode && features . cloudCode . jobs ) {
59
95
coreSubsections . push ( {
60
96
name : 'Jobs' ,
61
- link : '/jobs'
97
+ link : '/jobs' ,
62
98
} ) ;
63
99
}
64
100
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
+ ) {
66
105
coreSubsections . push ( {
67
106
name : 'Logs' ,
68
- link : '/logs'
107
+ link : '/logs' ,
69
108
} ) ;
70
109
}
71
110
72
- if ( features . globalConfig &&
111
+ if (
112
+ features . globalConfig &&
73
113
features . globalConfig . create &&
74
114
features . globalConfig . read &&
75
115
features . globalConfig . update &&
76
- features . globalConfig . delete ) {
116
+ features . globalConfig . delete
117
+ ) {
77
118
coreSubsections . push ( {
78
119
name : 'Config' ,
79
- link : '/config'
120
+ link : '/config' ,
80
121
} ) ;
81
122
}
82
123
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
+ }
87
130
88
131
if ( this . context . migration ) {
89
132
coreSubsections . push ( {
@@ -96,21 +139,21 @@ export default class DashboardView extends React.Component {
96
139
if ( features . push && features . push . immediatePush ) {
97
140
pushSubsections . push ( {
98
141
name : 'Send New Push' ,
99
- link : '/push/new'
142
+ link : '/push/new' ,
100
143
} ) ;
101
144
}
102
145
103
146
if ( features . push && features . push . storedPushData ) {
104
147
pushSubsections . push ( {
105
148
name : 'Past Pushes' ,
106
- link : '/push/activity'
149
+ link : '/push/activity' ,
107
150
} ) ;
108
151
}
109
152
110
153
if ( features . push && features . push . pushAudiences ) {
111
154
pushSubsections . push ( {
112
155
name : 'Audiences' ,
113
- link : '/push/audiences'
156
+ link : '/push/audiences' ,
114
157
} ) ;
115
158
}
116
159
@@ -195,7 +238,7 @@ export default class DashboardView extends React.Component {
195
238
});
196
239
}*/
197
240
198
- let appSidebarSections = [ ]
241
+ let appSidebarSections = [ ] ;
199
242
200
243
if ( coreSubsections . length > 0 ) {
201
244
appSidebarSections . push ( {
@@ -211,7 +254,7 @@ export default class DashboardView extends React.Component {
211
254
name : 'Push' ,
212
255
icon : 'push-outline' ,
213
256
link : '/push' ,
214
- style : { paddingLeft : '16px' } ,
257
+ style : { paddingLeft : '16px' } ,
215
258
subsections : pushSubsections ,
216
259
} ) ;
217
260
}
@@ -221,7 +264,7 @@ export default class DashboardView extends React.Component {
221
264
name : 'Analytics' ,
222
265
icon : 'analytics-outline' ,
223
266
link : '/analytics' ,
224
- subsections : analyticsSidebarSections
267
+ subsections : analyticsSidebarSections ,
225
268
} ) ;
226
269
}
227
270
@@ -230,29 +273,77 @@ export default class DashboardView extends React.Component {
230
273
name : 'App Settings' ,
231
274
icon : 'gear-solid' ,
232
275
link : '/settings' ,
233
- subsections : settingsSections
276
+ subsections : settingsSections ,
234
277
} ) ;
235
278
}
236
279
237
280
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 }
247
290
>
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
+ }
250
343
251
344
return (
252
345
< div className = { styles . dashboard } >
253
- < div className = { styles . content } >
254
- { this . renderContent ( ) }
255
- </ div >
346
+ { content }
256
347
{ sidebar }
257
348
</ div >
258
349
) ;
0 commit comments