storj/web/satellite/src/views/DashboardArea.vue

280 lines
8.3 KiB
Vue
Raw Normal View History

2019-01-24 20:15:10 +00:00
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
<template>
<div class="dashboard">
<div v-if="isLoading" class="loading-overlay active">
<LoaderImage class="loading-icon"/>
</div>
<div v-if="isBetaSatellite" class="dashboard__beta-banner">
<p class="dashboard__beta-banner__message">
Thanks for testing the {{satelliteName}} Beta satellite | Data may be deleted during this beta | Submit testing feedback
<a class="dashboard__beta-banner__message__link" :href="betaFeedbackURL" target="_blank" rel="noopener noreferrer">here</a>
| Request support
<a class="dashboard__beta-banner__message__link" :href="betaSupportURL" target="_blank" rel="noopener noreferrer">here</a>
</p>
</div>
<div v-if="!isLoading" class="dashboard__wrap">
<DashboardHeader/>
<div class="dashboard__wrap__main-area">
<NavigationArea class="regular-navigation"/>
<div class="dashboard__wrap__main-area__content">
<router-view/>
2019-03-26 16:56:38 +00:00
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
2019-09-09 11:33:39 +01:00
import { Component, Vue } from 'vue-property-decorator';
import DashboardHeader from '@/components/header/HeaderArea.vue';
2019-09-09 11:33:39 +01:00
import NavigationArea from '@/components/navigation/NavigationArea.vue';
import LoaderImage from '@/../static/images/common/loader.svg';
import { ErrorUnauthorized } from '@/api/errors/ErrorUnauthorized';
2019-09-09 11:33:39 +01:00
import { RouteConfig } from '@/router';
import { ACCESS_GRANTS_ACTIONS } from '@/store/modules/accessGrants';
import { PAYMENTS_ACTIONS } from '@/store/modules/payments';
2019-09-09 11:33:39 +01:00
import { PROJECTS_ACTIONS } from '@/store/modules/projects';
import { USER_ACTIONS } from '@/store/modules/users';
import { Project } from '@/types/projects';
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
2019-09-09 11:33:39 +01:00
import { AppState } from '@/utils/constants/appStateEnum';
import { LocalData } from '@/utils/localData';
import { MetaUtils } from '@/utils/meta';
2019-09-09 11:33:39 +01:00
const {
SETUP_ACCOUNT,
GET_BALANCE,
GET_PROJECT_USAGE_AND_CHARGES_CURRENT_ROLLUP,
} = PAYMENTS_ACTIONS;
2019-09-09 11:33:39 +01:00
@Component({
components: {
NavigationArea,
DashboardHeader,
LoaderImage,
},
2019-09-09 11:33:39 +01:00
})
export default class DashboardArea extends Vue {
/**
* Lifecycle hook before initial render.
* Sets access grants web worker.
*/
public async beforeMount(): Promise<void> {
try {
await this.$store.dispatch(ACCESS_GRANTS_ACTIONS.STOP_ACCESS_GRANTS_WEB_WORKER);
await this.$store.dispatch(ACCESS_GRANTS_ACTIONS.SET_ACCESS_GRANTS_WEB_WORKER);
} catch (error) {
await this.$notify.error(`Unable to set access grants wizard. ${error.message}`);
}
}
/**
* Lifecycle hook after initial render.
* Pre fetches user`s and project information.
*/
public async mounted(): Promise<void> {
try {
await this.$store.dispatch(USER_ACTIONS.GET);
} catch (error) {
if (!(error instanceof ErrorUnauthorized)) {
await this.$store.dispatch(APP_STATE_ACTIONS.CHANGE_STATE, AppState.ERROR);
await this.$notify.error(error.message);
}
setTimeout(async () => await this.$router.push(RouteConfig.Login.path), 1000);
return;
}
2019-09-09 11:33:39 +01:00
try {
await this.$store.dispatch(SETUP_ACCOUNT);
} catch (error) {
await this.$notify.error(`Unable to setup account. ${error.message}`);
}
let projects: Project[] = [];
2019-09-09 11:33:39 +01:00
try {
projects = await this.$store.dispatch(PROJECTS_ACTIONS.FETCH);
} catch (error) {
await this.$notify.error(error.message);
2019-09-09 11:33:39 +01:00
return;
}
2019-09-09 11:33:39 +01:00
if (!projects.length) {
await this.$store.dispatch(APP_STATE_ACTIONS.CHANGE_STATE, AppState.LOADED);
try {
await this.$router.push(RouteConfig.OnboardingTour.with(RouteConfig.OverviewStep).path);
} catch (error) {
return;
}
return;
}
this.selectProject(projects);
2019-09-09 11:33:39 +01:00
await this.$store.dispatch(APP_STATE_ACTIONS.CHANGE_STATE, AppState.LOADED);
2019-09-09 11:33:39 +01:00
}
/**
* Returns satellite name from store (config).
*/
public get satelliteName(): string {
return MetaUtils.getMetaContent('satellite-name');
}
/**
* Returns feedback URL from config for beta satellites.
*/
public get betaFeedbackURL(): string {
return MetaUtils.getMetaContent('beta-satellite-feedback-url');
}
/**
* Returns support URL from config for beta satellites.
*/
public get betaSupportURL(): string {
return MetaUtils.getMetaContent('beta-satellite-support-url');
}
/**
* Indicates if satellite is in beta.
*/
public get isBetaSatellite(): boolean {
return this.$store.state.appStateModule.isBetaSatellite;
}
/**
* Indicates if loading screen is active.
*/
2019-09-09 11:33:39 +01:00
public get isLoading(): boolean {
return this.$store.state.appStateModule.appState.fetchState === AppState.LOADING;
}
/**
* Checks if stored project is in fetched projects array and selects it.
* Selects first fetched project if check is not successful.
* @param fetchedProjects - fetched projects array
*/
private selectProject(fetchedProjects: Project[]): void {
const storedProjectID = LocalData.getSelectedProjectId();
const isProjectInFetchedProjects = fetchedProjects.some(project => project.id === storedProjectID);
if (storedProjectID && isProjectInFetchedProjects) {
this.storeProject(storedProjectID);
return;
}
// Length of fetchedProjects array is checked before selectProject() function call.
this.storeProject(fetchedProjects[0].id);
}
/**
* Stores project to vuex store and browser's local storage.
* @param projectID - project id string
*/
private storeProject(projectID: string): void {
this.$store.dispatch(PROJECTS_ACTIONS.SELECT, projectID);
LocalData.setSelectedProjectId(projectID);
}
2019-09-09 11:33:39 +01:00
}
</script>
<style scoped lang="scss">
.loading-overlay {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(134, 134, 148, 0.3);
visibility: hidden;
opacity: 0;
-webkit-transition: all 0.5s linear;
-moz-transition: all 0.5s linear;
-o-transition: all 0.5s linear;
transition: all 0.5s linear;
}
.loading-overlay.active {
visibility: visible;
opacity: 1;
}
.loading-icon {
width: 100px;
height: 100px;
}
.dashboard {
height: 100%;
background-color: #f5f6fa;
display: flex;
flex-direction: column;
&__beta-banner {
width: calc(100% - 60px);
padding: 0 30px;
display: flex;
align-items: center;
justify-content: space-between;
font-family: 'font_regular', sans-serif;
background-color: red;
&__message {
font-weight: normal;
font-size: 14px;
line-height: 16px;
color: #fff;
&__link {
font-size: 14px;
line-height: 16px;
color: #fff;
text-decoration: underline;
&:hover {
text-decoration: none;
}
}
}
}
&__wrap {
display: flex;
flex-direction: column;
height: 100%;
2019-03-26 16:56:38 +00:00
&__main-area {
2019-03-26 16:56:38 +00:00
display: flex;
height: 100%;
&__content {
overflow-y: scroll;
height: calc(100vh - 62px);
width: 100%;
position: relative;
}
2019-03-26 16:56:38 +00:00
}
}
}
@media screen and (max-width: 1280px) {
.regular-navigation {
display: none;
}
}
2019-03-26 16:56:38 +00:00
</style>