web/storagenode: loading screen added
Change-Id: I7d966d2dfba1c275d98259eb7b368297559f9f2d
This commit is contained in:
parent
9dbd511396
commit
6c5d948b82
@ -10,12 +10,14 @@
|
||||
<SNOFooter />
|
||||
</div>
|
||||
</div>
|
||||
<LoadingScreen v-if="isLoading" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
|
||||
import LoadingScreen from '@/app/components/LoadingScreen.vue';
|
||||
import SNOFooter from '@/app/components/SNOFooter.vue';
|
||||
import SNOHeader from '@/app/components/SNOHeader.vue';
|
||||
|
||||
@ -42,15 +44,30 @@ const elementsClassesToRemoveOnScroll: string[] = [
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
LoadingScreen,
|
||||
SNOHeader,
|
||||
SNOFooter,
|
||||
},
|
||||
})
|
||||
export default class App extends Vue {
|
||||
|
||||
/**
|
||||
* Indicates if loading screen is active.
|
||||
*/
|
||||
public get isLoading(): boolean {
|
||||
return this.$store.state.appStateModule.isLoading;
|
||||
}
|
||||
|
||||
public async beforeCreate(): Promise<void> {
|
||||
document.body.classList.add('js-loading');
|
||||
window.onload = () => {
|
||||
document.body.classList.remove('js-loading');
|
||||
};
|
||||
|
||||
// TODO: place key to server config.
|
||||
await this.$telemetry.init('DTEcoJRlUAN2VylCWMiLrqoknW800GNO');
|
||||
}
|
||||
|
||||
public onScroll(): void {
|
||||
elementsIdsToRemoveOnScroll.forEach(id => {
|
||||
this.removeElementById(id);
|
||||
@ -120,6 +137,12 @@ export default class App extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
.js-loading *,
|
||||
.js-loading *:before,
|
||||
.js-loading *:after {
|
||||
animation-play-state: paused !important;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-display: swap;
|
||||
font-family: 'font_regular';
|
||||
|
110
web/storagenode/src/app/components/LoadingScreen.vue
Normal file
110
web/storagenode/src/app/components/LoadingScreen.vue
Normal file
@ -0,0 +1,110 @@
|
||||
// Copyright (C) 2020 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
<template>
|
||||
<transition name="fade" mode="in-out">
|
||||
<div class="loading-screen">
|
||||
<StorjLogo class="logo"/>
|
||||
<svg height="100" width="100" class="loader">
|
||||
<circle cx="50" cy="50" r="40" class="background" />
|
||||
<circle cx="50" cy="50" r="40" class="circle" />
|
||||
</svg>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
|
||||
import StorjLogo from '@/../static/images/LogoWithoutText.svg';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
StorjLogo,
|
||||
},
|
||||
})
|
||||
export default class LoadingScreen extends Vue {}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.loading-screen {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100vh;
|
||||
z-index: 99999;
|
||||
background-color: var(--loading-screen-background-color);
|
||||
opacity: 1;
|
||||
|
||||
.logo {
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
.storj-logo {
|
||||
|
||||
path {
|
||||
fill: var(--loader-logo-color);
|
||||
}
|
||||
}
|
||||
|
||||
.loader {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.circle {
|
||||
fill: none;
|
||||
stroke: #c4c4c4;
|
||||
stroke-width: 20;
|
||||
stroke-dasharray: 250;
|
||||
stroke-dashoffset: 250;
|
||||
stroke-linecap: round;
|
||||
animation: rotate 2s linear infinite, fill 1s linear infinite;
|
||||
}
|
||||
|
||||
.background {
|
||||
fill: none;
|
||||
stroke: rgba(206, 206, 206, 0.2);
|
||||
stroke-width: 20;
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
|
||||
50% {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dashoffset: -250;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fill {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
stroke: #c4c4c4;
|
||||
}
|
||||
|
||||
50% {
|
||||
stroke: var(--loader-fill-color);
|
||||
}
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.5s;
|
||||
}
|
||||
|
||||
.fade-enter,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
@ -151,6 +151,8 @@ export default class SNOHeader extends Vue {
|
||||
}
|
||||
|
||||
public async onRefresh(): Promise<void> {
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_LOADING, true);
|
||||
|
||||
const selectedSatellite = this.$store.state.node.selectedSatellite.id;
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_NO_PAYOUT_DATA, false);
|
||||
|
||||
@ -161,6 +163,8 @@ export default class SNOHeader extends Vue {
|
||||
} catch (error) {
|
||||
console.error(`${error.message} satellite data.`);
|
||||
}
|
||||
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_LOADING, false);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -78,6 +78,8 @@ export default class SatelliteSelectionDropdown extends Vue {
|
||||
* Fires on satellite click and selects it.
|
||||
*/
|
||||
public async onSatelliteClick(id: string): Promise<void> {
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_LOADING, true);
|
||||
|
||||
try {
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.TOGGLE_SATELLITE_SELECTION);
|
||||
await this.$store.dispatch(NODE_ACTIONS.SELECT_SATELLITE, id);
|
||||
@ -85,12 +87,16 @@ export default class SatelliteSelectionDropdown extends Vue {
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
}
|
||||
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_LOADING, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires on all satellites click and sets selected satellite id to null.
|
||||
*/
|
||||
public async onAllSatellitesClick(): Promise<void> {
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_LOADING, true);
|
||||
|
||||
try {
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.TOGGLE_SATELLITE_SELECTION);
|
||||
await this.$store.dispatch(NODE_ACTIONS.SELECT_SATELLITE, null);
|
||||
@ -98,6 +104,8 @@ export default class SatelliteSelectionDropdown extends Vue {
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
}
|
||||
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_LOADING, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,6 +11,7 @@ export const APPSTATE_MUTATIONS = {
|
||||
CLOSE_ALL_POPUPS: 'CLOSE_ALL_POPUPS',
|
||||
SET_DARK: 'SET_DARK',
|
||||
SET_NO_PAYOUT_INFO: 'SET_NO_PAYOUT_INFO',
|
||||
SET_LOADING_STATE: 'SET_LOADING_STATE',
|
||||
};
|
||||
|
||||
export const APPSTATE_ACTIONS = {
|
||||
@ -23,6 +24,7 @@ export const APPSTATE_ACTIONS = {
|
||||
CLOSE_ALL_POPUPS: 'CLOSE_ALL_POPUPS',
|
||||
SET_DARK_MODE: 'SET_DARK_MODE',
|
||||
SET_NO_PAYOUT_DATA: 'SET_NO_PAYOUT_DATA',
|
||||
SET_LOADING: 'SET_LOADING',
|
||||
};
|
||||
|
||||
const {
|
||||
@ -44,6 +46,7 @@ export const appStateModule = {
|
||||
isPayoutCalendarShown: false,
|
||||
isDarkMode: false,
|
||||
isNoPayoutData: false,
|
||||
isLoading: true,
|
||||
},
|
||||
mutations: {
|
||||
[TOGGLE_SATELLITE_SELECTION](state: any): void {
|
||||
@ -72,6 +75,9 @@ export const appStateModule = {
|
||||
[APPSTATE_MUTATIONS.SET_NO_PAYOUT_INFO](state: any, value): void {
|
||||
state.isNoPayoutData = value;
|
||||
},
|
||||
[APPSTATE_MUTATIONS.SET_LOADING_STATE](state: any, value): void {
|
||||
state.isLoading = value;
|
||||
},
|
||||
[CLOSE_ALL_POPUPS](state: any): void {
|
||||
state.isSatelliteSelectionShown = false;
|
||||
},
|
||||
@ -117,6 +123,10 @@ export const appStateModule = {
|
||||
[APPSTATE_ACTIONS.SET_NO_PAYOUT_DATA]: function ({commit}: any, value: boolean): void {
|
||||
commit(APPSTATE_MUTATIONS.SET_NO_PAYOUT_INFO, value);
|
||||
},
|
||||
[APPSTATE_ACTIONS.SET_LOADING]: function ({commit}: any, value: boolean): void {
|
||||
value ? commit(APPSTATE_MUTATIONS.SET_LOADING_STATE, value) :
|
||||
setTimeout(() => { commit(APPSTATE_MUTATIONS.SET_LOADING_STATE, value); }, 1000);
|
||||
},
|
||||
[APPSTATE_ACTIONS.CLOSE_ADDITIONAL_CHARTS]: function ({commit}: any): void {
|
||||
commit(APPSTATE_MUTATIONS.CLOSE_ADDITIONAL_CHARTS);
|
||||
},
|
||||
|
@ -16,6 +16,7 @@ import { Component, Vue } from 'vue-property-decorator';
|
||||
import SNOContentFilling from '@/app/components/SNOContentFilling.vue';
|
||||
import SNOContentTitle from '@/app/components/SNOContentTitle.vue';
|
||||
|
||||
import { APPSTATE_ACTIONS } from '@/app/store/modules/appState';
|
||||
import { NODE_ACTIONS } from '@/app/store/modules/node';
|
||||
import { NOTIFICATIONS_ACTIONS } from '@/app/store/modules/notifications';
|
||||
import { PAYOUT_ACTIONS } from '@/app/store/modules/payout';
|
||||
@ -34,6 +35,8 @@ export default class Dashboard extends Vue {
|
||||
* Fetches notifications and total payout information for all satellites.
|
||||
*/
|
||||
public async mounted(): Promise<void> {
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_LOADING, true);
|
||||
|
||||
try {
|
||||
await this.$store.dispatch(NODE_ACTIONS.SELECT_SATELLITE, null);
|
||||
} catch (error) {
|
||||
@ -52,6 +55,8 @@ export default class Dashboard extends Vue {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_LOADING, false);
|
||||
|
||||
this.$telemetry.identify(this.$store.state.node.info.id);
|
||||
this.$telemetry.view(TelemetryViews.MainPage);
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ import SatelliteSelection from '@/app/components/SatelliteSelection.vue';
|
||||
|
||||
import BackArrowIcon from '@/../static/images/notifications/backArrow.svg';
|
||||
|
||||
import { APPSTATE_ACTIONS } from '@/app/store/modules/appState';
|
||||
import { NODE_ACTIONS } from '@/app/store/modules/node';
|
||||
import { NOTIFICATIONS_ACTIONS } from '@/app/store/modules/notifications';
|
||||
import { PAYOUT_ACTIONS } from '@/app/store/modules/payout';
|
||||
@ -70,6 +71,8 @@ export default class PayoutArea extends Vue {
|
||||
* Fetches payout information.
|
||||
*/
|
||||
public async mounted(): Promise<any> {
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_LOADING, true);
|
||||
|
||||
try {
|
||||
await this.$store.dispatch(NODE_ACTIONS.SELECT_SATELLITE, null);
|
||||
} catch (error) {
|
||||
@ -87,6 +90,8 @@ export default class PayoutArea extends Vue {
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
await this.$store.dispatch(APPSTATE_ACTIONS.SET_LOADING, false);
|
||||
}
|
||||
|
||||
public get totalHeld(): number {
|
||||
|
@ -43,6 +43,9 @@
|
||||
--egress-tooltip-info-background-color: rgba(211, 242, 204, 0.3);
|
||||
--disk-stat-chart-text-color: #657284;
|
||||
--expand-button-background-color: rgba(226, 236, 247, 0.45);
|
||||
--loading-screen-background-color: #e9ecf2;
|
||||
--loader-fill-color: #133e9c;
|
||||
--loader-logo-color: #929baf;
|
||||
--tooltip-background-path: url('../../static/images/tooltipBack.png');
|
||||
--tooltip-arrow-path: url('../../static/images/tooltipArrow.png');
|
||||
--info-image-arrow-middle-path: url('../../static/images/Message.png');
|
||||
@ -92,6 +95,9 @@
|
||||
--egress-tooltip-info-background-color: #212329;
|
||||
--disk-stat-chart-text-color: white;
|
||||
--expand-button-background-color: #31343d;
|
||||
--loading-screen-background-color: #1e1e26;
|
||||
--loader-fill-color: #4f97f7;
|
||||
--loader-logo-color: #414148;
|
||||
--tooltip-background-path: url('../../static/images/tooltipBackDark.png');
|
||||
--tooltip-arrow-path: url('../../static/images/tooltipArrowDark.png');
|
||||
--info-image-arrow-middle-path: url('../../static/images/MessageDark.png');
|
||||
|
14
web/storagenode/tests/unit/components/LoadingScreen.spec.ts
Normal file
14
web/storagenode/tests/unit/components/LoadingScreen.spec.ts
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright (C) 2020 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
import LoadingScreen from '@/app/components/LoadingScreen.vue';
|
||||
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
|
||||
describe('LoadingScreen', (): void => {
|
||||
it('renders correctly', (): void => {
|
||||
const wrapper = shallowMount(LoadingScreen);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
@ -0,0 +1,12 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`LoadingScreen renders correctly 1`] = `
|
||||
<transition-stub name="fade" mode="in-out">
|
||||
<div class="loading-screen">
|
||||
<storjlogo-stub class="logo"></storjlogo-stub> <svg height="100" width="100" class="loader">
|
||||
<circle cx="50" cy="50" r="40" class="background"></circle>
|
||||
<circle cx="50" cy="50" r="40" class="circle"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</transition-stub>
|
||||
`;
|
Loading…
Reference in New Issue
Block a user