Skip to content

Commit ded33a3

Browse files
committed
Properly apply the changes specified in user features
1 parent bf223da commit ded33a3

File tree

1 file changed

+97
-95
lines changed

1 file changed

+97
-95
lines changed

src/dashboard/Dashboard.js

Lines changed: 97 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ let Empty = createClass({
6363
});
6464

6565
const AccountSettingsPage = () => (
66-
<AccountView section='Account Settings'>
67-
<AccountOverview />
68-
</AccountView>
69-
);
66+
<AccountView section='Account Settings'>
67+
<AccountOverview/>
68+
</AccountView>
69+
);
7070

7171
const PARSE_DOT_COM_SERVER_INFO = {
7272
features: {
@@ -121,8 +121,8 @@ export default class Dashboard extends React.Component {
121121
}
122122

123123
componentDidMount() {
124-
get('/parse-dashboard-config.json').then(({ apps, newFeaturesInLatestVersion = [] }) => {
125-
this.setState({ newFeaturesInLatestVersion });
124+
get('/parse-dashboard-config.json').then(({apps, newFeaturesInLatestVersion = []}) => {
125+
this.setState({newFeaturesInLatestVersion});
126126
let appInfoPromises = apps.map(app => {
127127
if (app.serverURL.startsWith('https://api.parse.com/1')) {
128128
//api.parse.com doesn't have feature availability endpoint, fortunately we know which features
@@ -135,25 +135,27 @@ export default class Dashboard extends React.Component {
135135
'GET',
136136
'serverInfo',
137137
{},
138-
{ useMasterKey: true }
138+
{useMasterKey: true}
139139
).then(async serverInfo => {
140140
const allowed = await get('/allowed-features.json');
141-
if(Object.keys(allowed).length === 0){
142-
console.log('allowed', allowed, app);
141+
if (Object.keys(allowed).length === 0) {
143142
app.serverInfo = serverInfo;
144143
return app;
145144
}
146-
if (serverInfo.features.schemas && !allowed.schemas) {
147-
delete serverInfo.features.schemas;
148-
} else if (serverInfo.features.schemas && allowed.schemas) {
149-
serverInfo.features.schemas = allowed.schemas;
150-
}
151-
if (serverInfo.features.push && !allowed.push) {
152-
delete serverInfo.features.push;
153-
} else if (serverInfo.features.push && allowed.push) {
154-
serverInfo.features.push = allowed.push;
145+
for (const feature in serverInfo.features) {
146+
switch (allowed[feature]) {
147+
case false:
148+
delete serverInfo.features[feature]; //remove feature
149+
break;
150+
case true:
151+
continue; //use unmodified
152+
default:
153+
for (const detail in serverInfo.features[feature]) {
154+
if (false === allowed[feature][detail])
155+
serverInfo.features[feature][detail] = false //disable detail
156+
}
157+
}
155158
}
156-
console.log(serverInfo);
157159
app.serverInfo = serverInfo;
158160
return app;
159161
}, error => {
@@ -183,12 +185,12 @@ export default class Dashboard extends React.Component {
183185
}
184186
});
185187
return Promise.all(appInfoPromises);
186-
}).then(function(resolvedApps) {
188+
}).then(function (resolvedApps) {
187189
resolvedApps.forEach(app => {
188190
AppsManager.addApp(app);
189191
});
190-
this.setState({ configLoadingState: AsyncStatus.SUCCESS });
191-
}.bind(this)).catch(({ error }) => {
192+
this.setState({configLoadingState: AsyncStatus.SUCCESS});
193+
}.bind(this)).catch(({error}) => {
192194
this.setState({
193195
configLoadingError: error,
194196
configLoadingState: AsyncStatus.FAILED
@@ -205,7 +207,7 @@ export default class Dashboard extends React.Component {
205207
return <div className={styles.empty}>
206208
<div className={center}>
207209
<div className={styles.cloud}>
208-
<Icon width={110} height={110} name='cloud-surprise' fill='#1e3b4d' />
210+
<Icon width={110} height={110} name='cloud-surprise' fill='#1e3b4d'/>
209211
</div>
210212
{/* use non-breaking hyphen for the error message to keep the filename on one line */}
211213
<div className={styles.loadingError}>{this.state.configLoadingError.replace(/-/g, '\u2011')}</div>
@@ -219,128 +221,128 @@ export default class Dashboard extends React.Component {
219221
</AccountView>
220222
);
221223

222-
const SettingsRoute = ({ match }) => (
223-
<SettingsData params={ match.params }>
224+
const SettingsRoute = ({match}) => (
225+
<SettingsData params={match.params}>
224226
<Switch>
225-
<Route path={ match.url + '/general' } component={GeneralSettings} />
226-
<Route path={ match.url + '/keys' } component={SecuritySettings} />
227-
<Route path={ match.url + '/users' } component={UsersSettings} />
228-
<Route path={ match.url + '/push' } component={PushSettings} />
229-
<Route path={ match.url + '/hosting' } component={HostingSettings} />
227+
<Route path={match.url + '/general'} component={GeneralSettings}/>
228+
<Route path={match.url + '/keys'} component={SecuritySettings}/>
229+
<Route path={match.url + '/users'} component={UsersSettings}/>
230+
<Route path={match.url + '/push'} component={PushSettings}/>
231+
<Route path={match.url + '/hosting'} component={HostingSettings}/>
230232
</Switch>
231233
</SettingsData>
232234
)
233235

234236
const JobsRoute = (props) => (
235237
<Switch>
236-
<Route exact path={ props.match.path + '/new' } render={(props) => (
238+
<Route exact path={props.match.path + '/new'} render={(props) => (
237239
<JobsData {...props} params={props.match.params}>
238240
<JobEdit params={props.match.params}/>
239241
</JobsData>
240-
)} />
241-
<Route path={ props.match.path + '/edit/:jobId' } render={(props) => (
242+
)}/>
243+
<Route path={props.match.path + '/edit/:jobId'} render={(props) => (
242244
<JobsData {...props} params={props.match.params}>
243245
<JobEdit params={props.match.params}/>
244246
</JobsData>
245-
)} />
246-
<Route path={ props.match.path + '/:section' } render={(props) => (
247+
)}/>
248+
<Route path={props.match.path + '/:section'} render={(props) => (
247249
<JobsData {...props} params={props.match.params}>
248250
<Jobs {...props} params={props.match.params}/>
249251
</JobsData>
250-
)} />
251-
<Redirect from={ props.match.path } to='/apps/:appId/jobs/all' />
252+
)}/>
253+
<Redirect from={props.match.path} to='/apps/:appId/jobs/all'/>
252254
</Switch>
253255
)
254256

255-
const AnalyticsRoute = ({ match }) => (
257+
const AnalyticsRoute = ({match}) => (
256258
<Switch>
257-
<Route path={ match.path + '/overview' } component={AnalyticsOverview} />
258-
<Redirect exact from={ match.path + '/explorer' } to='/apps/:appId/analytics/explorer/chart' />
259-
<Route path={ match.path + '/explorer/:displayType' } component={Explorer} />
260-
<Route path={ match.path + '/retention' } component={Retention} />
261-
<Route path={ match.path + '/performance' } component={Performance} />
262-
<Route path={ match.path + '/slow_queries' } component={SlowQueries} />
259+
<Route path={match.path + '/overview'} component={AnalyticsOverview}/>
260+
<Redirect exact from={match.path + '/explorer'} to='/apps/:appId/analytics/explorer/chart'/>
261+
<Route path={match.path + '/explorer/:displayType'} component={Explorer}/>
262+
<Route path={match.path + '/retention'} component={Retention}/>
263+
<Route path={match.path + '/performance'} component={Performance}/>
264+
<Route path={match.path + '/slow_queries'} component={SlowQueries}/>
263265
</Switch>
264266
);
265267

266268
const BrowserRoute = (props) => {
267269
if (ShowSchemaOverview) {
268-
return <SchemaOverview {...props} params={props.match.params} />
270+
return <SchemaOverview {...props} params={props.match.params}/>
269271
}
270-
return <Browser {...props} params={ props.match.params } />
272+
return <Browser {...props} params={props.match.params}/>
271273
}
272274

273275
const ApiConsoleRoute = (props) => (
274276
<Switch>
275-
<Route path={ props.match.path + '/rest' } render={props => (
277+
<Route path={props.match.path + '/rest'} render={props => (
276278
<ApiConsole {...props}>
277-
<RestConsole />
279+
<RestConsole/>
278280
</ApiConsole>
279-
)} />
280-
<Route path={ props.match.path + '/graphql' } render={props => (
281+
)}/>
282+
<Route path={props.match.path + '/graphql'} render={props => (
281283
<ApiConsole {...props}>
282-
<GraphQLConsole />
284+
<GraphQLConsole/>
283285
</ApiConsole>
284-
)} />
285-
<Route path={ props.match.path + '/js_console' } render={props => (
286+
)}/>
287+
<Route path={props.match.path + '/js_console'} render={props => (
286288
<ApiConsole {...props}>
287-
<Playground />
289+
<Playground/>
288290
</ApiConsole>
289-
)} />
290-
<Redirect from={ props.match.path } to='/apps/:appId/api_console/rest' />
291+
)}/>
292+
<Redirect from={props.match.path} to='/apps/:appId/api_console/rest'/>
291293
</Switch>
292294
)
293295

294-
const AppRoute = ({ match }) => (
295-
<AppData params={ match.params }>
296+
const AppRoute = ({match}) => (
297+
<AppData params={match.params}>
296298
<Switch>
297-
<Route path={ match.path + '/getting_started' } component={Empty} />
298-
<Route path={ match.path + '/browser/:className/:entityId/:relationName' } component={BrowserRoute} />
299-
<Route path={ match.path + '/browser/:className' } component={BrowserRoute} />
300-
<Route path={ match.path + '/browser' } component={BrowserRoute} />
301-
<Route path={ match.path + '/cloud_code' } component={CloudCode} />
302-
<Route path={ match.path + '/cloud_code/*' } component={CloudCode} />
303-
<Route path={ match.path + '/webhooks' } component={Webhooks} />
299+
<Route path={match.path + '/getting_started'} component={Empty}/>
300+
<Route path={match.path + '/browser/:className/:entityId/:relationName'} component={BrowserRoute}/>
301+
<Route path={match.path + '/browser/:className'} component={BrowserRoute}/>
302+
<Route path={match.path + '/browser'} component={BrowserRoute}/>
303+
<Route path={match.path + '/cloud_code'} component={CloudCode}/>
304+
<Route path={match.path + '/cloud_code/*'} component={CloudCode}/>
305+
<Route path={match.path + '/webhooks'} component={Webhooks}/>
304306

305-
<Route path={ match.path + '/jobs' } component={JobsRoute}/>
307+
<Route path={match.path + '/jobs'} component={JobsRoute}/>
306308

307-
<Route path={ match.path + '/logs/:type' } render={(props) => (
308-
<Logs {...props} params={props.match.params} />
309-
)} />
310-
<Redirect from={ match.path + '/logs' } to='/apps/:appId/logs/info' />
309+
<Route path={match.path + '/logs/:type'} render={(props) => (
310+
<Logs {...props} params={props.match.params}/>
311+
)}/>
312+
<Redirect from={match.path + '/logs'} to='/apps/:appId/logs/info'/>
311313

312-
<Route path={ match.path + '/config' } component={Config} />
313-
<Route path={ match.path + '/api_console' } component={ApiConsoleRoute} />
314-
<Route path={ match.path + '/migration' } component={Migration} />
314+
<Route path={match.path + '/config'} component={Config}/>
315+
<Route path={match.path + '/api_console'} component={ApiConsoleRoute}/>
316+
<Route path={match.path + '/migration'} component={Migration}/>
315317

316318

317-
<Redirect exact from={ match.path + '/push' } to='/apps/:appId/push/new' />
318-
<Redirect exact from={ match.path + '/push/activity' } to='/apps/:appId/push/activity/all' />
319+
<Redirect exact from={match.path + '/push'} to='/apps/:appId/push/new'/>
320+
<Redirect exact from={match.path + '/push/activity'} to='/apps/:appId/push/activity/all'/>
319321

320-
<Route path={ match.path + '/push/activity/:category' } render={(props) => (
321-
<PushIndex {...props} params={props.match.params} />
322-
)} />
323-
<Route path={ match.path + '/push/audiences' } component={PushAudiencesIndex} />
324-
<Route path={ match.path + '/push/new' } component={PushNew} />
325-
<Route path={ match.path + '/push/:pushId' } render={(props) => (
326-
<PushDetails {...props} params={props.match.params} />
327-
)} />
322+
<Route path={match.path + '/push/activity/:category'} render={(props) => (
323+
<PushIndex {...props} params={props.match.params}/>
324+
)}/>
325+
<Route path={match.path + '/push/audiences'} component={PushAudiencesIndex}/>
326+
<Route path={match.path + '/push/new'} component={PushNew}/>
327+
<Route path={match.path + '/push/:pushId'} render={(props) => (
328+
<PushDetails {...props} params={props.match.params}/>
329+
)}/>
328330

329331
{/* Unused routes... */}
330-
<Redirect exact from={ match.path + '/analytics' } to='/apps/:appId/analytics/overview' />
331-
<Route path={ match.path + '/analytics' } component={AnalyticsRoute}/>
332-
<Redirect exact from={ match.path + '/settings' } to='/apps/:appId/settings/general' />
333-
<Route path={ match.path + '/settings' } component={SettingsRoute}/>
332+
<Redirect exact from={match.path + '/analytics'} to='/apps/:appId/analytics/overview'/>
333+
<Route path={match.path + '/analytics'} component={AnalyticsRoute}/>
334+
<Redirect exact from={match.path + '/settings'} to='/apps/:appId/settings/general'/>
335+
<Route path={match.path + '/settings'} component={SettingsRoute}/>
334336
</Switch>
335337
</AppData>
336338
)
337339

338340
const Index = () => (
339341
<div>
340342
<Switch>
341-
<Redirect exact from='/apps/:appId' to='/apps/:appId/browser' />
342-
<Route exact path='/apps' component={AppsIndexPage} />
343-
<Route path='/apps/:appId' component={AppRoute} />
343+
<Redirect exact from='/apps/:appId' to='/apps/:appId/browser'/>
344+
<Route exact path='/apps' component={AppsIndexPage}/>
345+
<Route path='/apps/:appId' component={AppRoute}/>
344346
</Switch>
345347
</div>
346348
)
@@ -351,11 +353,11 @@ export default class Dashboard extends React.Component {
351353
<title>Parse Dashboard</title>
352354
</Helmet>
353355
<Switch>
354-
<Route path='/apps' component={Index} />
355-
<Route path='/account/overview' component={AccountSettingsPage} />
356-
<Redirect from='/account' to='/account/overview' />
357-
<Redirect from='/' to='/apps' />
358-
<Route path='*' component={FourOhFour} />
356+
<Route path='/apps' component={Index}/>
357+
<Route path='/account/overview' component={AccountSettingsPage}/>
358+
<Redirect from='/account' to='/account/overview'/>
359+
<Redirect from='/' to='/apps'/>
360+
<Route path='*' component={FourOhFour}/>
359361
</Switch>
360362
</div>
361363
</Router>

0 commit comments

Comments
 (0)