Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/dashboard/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,21 @@ export default class Dashboard extends React.Component {
if (error.code === 100) {
app.serverInfo = {
error: 'unable to connect to server',
enabledFeatures: {},
features: {},
parseServerVersion: 'unknown'
}
return Promise.resolve(app);
} else if (error.code === 107) {
app.serverInfo = {
error: 'server version too low',
enabledFeatures: {},
features: {},
parseServerVersion: 'unknown'
}
return Promise.resolve(app);
} else {
app.serverInfo = {
error: error.message || 'unknown error',
enabledFeatures: {},
features: {},
parseServerVersion: 'unknown'
}
return Promise.resolve(app);
Expand Down
21 changes: 21 additions & 0 deletions src/dashboard/Dashboard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,25 @@ body:global(.expanded) {
.content {
margin-left: $sidebarCollapsedWidth;
}
}

.loadingError {
font-size: 58px;
color: #ffffff;
}

.empty {
position: relative;
background: #1e3b4d;
min-height: 100vh;
text-align: center;
}

.cloud {
width: 170px;
height: 170px;
border-radius: 100%;
padding-top: 30px;
background: #3E5566;
margin: 0 auto 14px auto;
}
173 changes: 132 additions & 41 deletions src/dashboard/DashboardView.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,82 +8,125 @@
import React from 'react';
import Sidebar from 'components/Sidebar/Sidebar.react';
import styles from 'dashboard/Dashboard.scss';
import Icon from 'components/Icon/Icon.react';
import baseStyles from 'stylesheets/base.scss';
import Button from 'components/Button/Button.react';
import { CurrentApp } from 'context/currentApp';

export default class DashboardView extends React.Component {
static contextType = CurrentApp;

/* A DashboardView renders two pieces: the sidebar, and the app itself */

constructor() {
super();
this.state = {
route: '',
};
}

componentDidUpdate() {
this.onRouteChanged();
}
componentDidMount() {
this.onRouteChanged();
}

onRouteChanged() {
const appId = this.context.applicationId;
const path = this.props.location?.pathname ?? window.location.pathname;
const route = path.split(appId)[1].split('/')[1];
if (route !== this.state.route) {
this.setState({ route });
}
}

render() {
let sidebarChildren = null;
if (typeof this.renderSidebar === 'function') {
sidebarChildren = this.renderSidebar();
}
let appSlug = (this.context ? this.context.slug : '');
let appSlug = this.context ? this.context.slug : '';

if (!this.context.hasCheckedForMigraton) {
this.context.getMigrations().promise
.then(() => this.forceUpdate(), () => {});
this.context.getMigrations().promise.then(
() => this.forceUpdate(),
() => {}
);
}

let features = this.context.serverInfo.features;

let coreSubsections = [];
if (features.schemas &&
if (
features.schemas &&
features.schemas.addField &&
features.schemas.removeField &&
features.schemas.addClass &&
features.schemas.removeClass) {
features.schemas.removeClass
) {
coreSubsections.push({
name: 'Browser',
link: '/browser'
link: '/browser',
});
}

if (features.cloudCode && features.cloudCode.viewCode) {
coreSubsections.push({
name: 'Cloud Code',
link: '/cloud_code'
link: '/cloud_code',
});
}

//webhooks requires removal of heroku link code, then it should work.
if (features.hooks && features.hooks.create && features.hooks.read && features.hooks.update && features.hooks.delete) {
if (
features.hooks &&
features.hooks.create &&
features.hooks.read &&
features.hooks.update &&
features.hooks.delete
) {
coreSubsections.push({
name: 'Webhooks',
link: '/webhooks'
link: '/webhooks',
});
}

if (features.cloudCode && features.cloudCode.jobs) {
coreSubsections.push({
name: 'Jobs',
link: '/jobs'
link: '/jobs',
});
}

if (features.logs && Object.keys(features.logs).some(key => features.logs[key])) {
if (
features.logs &&
Object.keys(features.logs).some((key) => features.logs[key])
) {
coreSubsections.push({
name: 'Logs',
link: '/logs'
link: '/logs',
});
}

if (features.globalConfig &&
if (
features.globalConfig &&
features.globalConfig.create &&
features.globalConfig.read &&
features.globalConfig.update &&
features.globalConfig.delete) {
features.globalConfig.delete
) {
coreSubsections.push({
name: 'Config',
link: '/config'
link: '/config',
});
}

coreSubsections.push({
name: 'API Console',
link: '/api_console'
});
if (!this.context.serverInfo.error) {
coreSubsections.push({
name: 'API Console',
link: '/api_console',
});
}

if (this.context.migration) {
coreSubsections.push({
Expand All @@ -96,21 +139,21 @@ export default class DashboardView extends React.Component {
if (features.push && features.push.immediatePush) {
pushSubsections.push({
name: 'Send New Push',
link: '/push/new'
link: '/push/new',
});
}

if (features.push && features.push.storedPushData) {
pushSubsections.push({
name: 'Past Pushes',
link: '/push/activity'
link: '/push/activity',
});
}

if (features.push && features.push.pushAudiences) {
pushSubsections.push({
name: 'Audiences',
link: '/push/audiences'
link: '/push/audiences',
});
}

Expand Down Expand Up @@ -195,7 +238,7 @@ export default class DashboardView extends React.Component {
});
}*/

let appSidebarSections = []
let appSidebarSections = [];

if (coreSubsections.length > 0) {
appSidebarSections.push({
Expand All @@ -211,7 +254,7 @@ export default class DashboardView extends React.Component {
name: 'Push',
icon: 'push-outline',
link: '/push',
style: {paddingLeft: '16px'},
style: { paddingLeft: '16px' },
subsections: pushSubsections,
});
}
Expand All @@ -221,7 +264,7 @@ export default class DashboardView extends React.Component {
name: 'Analytics',
icon: 'analytics-outline',
link: '/analytics',
subsections: analyticsSidebarSections
subsections: analyticsSidebarSections,
});
}

Expand All @@ -230,29 +273,77 @@ export default class DashboardView extends React.Component {
name: 'App Settings',
icon: 'gear-solid',
link: '/settings',
subsections: settingsSections
subsections: settingsSections,
});
}

let sidebar = (
<Sidebar
sections={appSidebarSections}
appSelector={true}
section={this.section}
subsection={this.subsection}
prefix={'/apps/' + appSlug}
action={this.action}
primaryBackgroundColor={this.context.primaryBackgroundColor}
secondaryBackgroundColor={this.context.secondaryBackgroundColor}
<Sidebar
sections={appSidebarSections}
appSelector={true}
section={this.section}
subsection={this.subsection}
prefix={'/apps/' + appSlug}
action={this.action}
primaryBackgroundColor={this.context.primaryBackgroundColor}
secondaryBackgroundColor={this.context.secondaryBackgroundColor}
>
{sidebarChildren}
</Sidebar>);
{sidebarChildren}
</Sidebar>
);

let content = <div className={styles.content}>{this.renderContent()}</div>;
const canRoute = [...coreSubsections, ...pushSubsections]
.map(({ link }) => link.split('/')[1])
.includes(this.state.route);

if (!canRoute) {
content = (
<div className={styles.empty}>
<div className={baseStyles.center}>
<div className={styles.cloud}>
<Icon
width={110}
height={110}
name="cloud-surprise"
fill="#1e3b4d"
/>
</div>
<div className={styles.loadingError}>Feature unavailable</div>
</div>
</div>
);
}

if (this.context.serverInfo.error) {
content = (
<div className={styles.empty}>
<div className={baseStyles.center}>
<div className={styles.cloud}>
<Icon
width={110}
height={110}
name="cloud-surprise"
fill="#1e3b4d"
/>
</div>
<div className={styles.loadingError}>
{this.context.serverInfo.error.replace(/-/g, '\u2011')}
</div>
<Button
color="white"
value="Reload"
width="120px"
onClick={() => location.reload()}
/>
</div>
</div>
);
}

return (
<div className={styles.dashboard}>
<div className={styles.content}>
{this.renderContent()}
</div>
{content}
{sidebar}
</div>
);
Expand Down