web/satellite: regular header reworked

WHAT:
removed unnecessary templates splitting
fixed resources dropdown margins
fixes close navigation button responsiveness
aligned logo
added loader for projects dropdown and removed redundant request on dropdown closing
added satellite name to header's right side

WHY:
bug fixes/better user experience

Change-Id: I7ed30f882a1f5484efbf3e0e21ee5d637ef83bf2
This commit is contained in:
Vitalii Shpital 2021-04-27 15:21:13 +03:00
parent a5c1e4b4a5
commit 917e4b81d3
13 changed files with 341 additions and 242 deletions

View File

@ -4,6 +4,12 @@ dist
coverage
temp
# wasm related files
wasm_exec.js
wasm_exec.js.br
*.wasm
*.wasm.br
# local env files
.env.local
.env.*.local

View File

@ -0,0 +1,39 @@
// Copyright (C) 2021 Storj Labs, Inc.
// See LICENSE for copying information.
<template>
<div :style="style" class="loader"/>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class VLoader extends Vue {
@Prop({ default: 'inherit' })
private readonly width: string;
@Prop({ default: 'inherit' })
private readonly height: string;
/**
* Returns loader's width and height from props.
*/
public get style(): Object {
return { width: this.width, height: this.height };
}
}
</script>
<style scoped lang="scss">
.loader {
border: 16px solid #f3f3f3;
border-top: 16px solid #3498db;
border-radius: 50%;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>

View File

@ -1,7 +1,44 @@
// Copyright (C) 2019 Storj Labs, Inc.
// Copyright (C) 2021 Storj Labs, Inc.
// See LICENSE for copying information.
<template src="./headerArea.html"></template>
<template>
<div class="header-container">
<div class="header-container__left-area">
<div class="header-container__left-area__logo-area">
<NavigationMenuIcon
class="header-container__left-area__logo-area__menu-button"
v-if="!isNavigationVisible && !isOnboardingTour"
@click.stop="toggleNavigationVisibility"
/>
<div class="header-container__left-area__logo-area__close-button" v-if="isNavigationVisible" @click.stop="toggleNavigationVisibility">
<NavigationCloseIcon/>
<p class="header-container__left-area__logo-area__close-button__title">Close</p>
</div>
<LogoIcon
class="logo"
@click.stop="onLogoClick"
/>
</div>
<ProjectSelection class="project-selection"/>
<ResourcesSelection class="resources-selection"/>
<SettingsSelection class="settings-selection"/>
</div>
<div class="header-container__right-area">
<div class="header-container__right-area__satellite-area">
<div class="header-container__right-area__satellite-area__checkmark">
<CheckmarkIcon/>
</div>
<p class="header-container__right-area__satellite-area__name">{{ satelliteName }}</p>
</div>
<AccountButton class="header-container__right-area__account-button"/>
</div>
<NavigationArea
class="adapted-navigation"
v-if="isNavigationVisible"
/>
<div class="navigation-blur" v-if="isNavigationVisible" @click.self.stop="toggleNavigationVisibility"/>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@ -12,6 +49,7 @@ import SettingsSelection from '@/components/header/settingsDropdown/SettingsSele
import NavigationArea from '@/components/navigation/NavigationArea.vue';
import LogoIcon from '@/../static/images/dcs-logo.svg';
import CheckmarkIcon from '@/../static/images/header/checkmark.svg';
import NavigationCloseIcon from '@/../static/images/header/navigationClose.svg';
import NavigationMenuIcon from '@/../static/images/header/navigationMenu.svg';
@ -26,6 +64,7 @@ import AccountButton from './accountDropdown/AccountButton.vue';
NavigationMenuIcon,
NavigationCloseIcon,
LogoIcon,
CheckmarkIcon,
ProjectSelection,
ResourcesSelection,
SettingsSelection,
@ -57,7 +96,147 @@ export default class HeaderArea extends Vue {
public get isOnboardingTour(): boolean {
return this.$route.path.includes(RouteConfig.OnboardingTour.path);
}
/**
* Returns satellite name from config.
*/
public get satelliteName(): string {
return this.$store.state.appStateModule.satelliteName;
}
}
</script>
<style src="./headerArea.scss" scoped lang="scss"></style>
<style scoped lang="scss">
.header-container {
font-family: 'font_regular', sans-serif;
min-height: 62px;
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30px 0 10px;
position: relative;
&__left-area {
display: flex;
align-items: center;
&__logo-area {
width: 220px;
margin-right: 20px;
&__menu-button {
display: none;
}
&__close-button {
display: flex;
align-items: center;
cursor: pointer;
&__title {
margin-left: 13px;
font-size: 16px;
line-height: 23px;
color: #a9b5c1;
}
}
}
}
&__right-area {
display: flex;
align-items: center;
&__satellite-area {
height: 36px;
background: #f6f6fa;
border-radius: 58px;
display: flex;
align-items: center;
padding: 0 10px 0 5px;
margin-right: 20px;
&__checkmark {
display: flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
background: #fff;
border-radius: 11px;
}
&__name {
font-weight: 500;
font-size: 14px;
line-height: 18px;
color: #000;
}
}
}
}
.logo {
cursor: pointer;
}
.adapted-navigation {
position: absolute;
top: 62px;
left: 0;
z-index: 100;
height: 100vh;
background: #e6e9ef;
}
.navigation-blur {
height: 100vh;
width: 100%;
position: absolute;
top: 62px;
left: 220px;
z-index: 100;
background: rgba(134, 134, 148, 0.4);
}
.project-selection,
.resources-selection {
margin-right: 35px;
}
@media screen and (min-width: 1281px) {
.adapted-navigation,
.navigation-blur,
.header-container__left-area__logo-area__close-button {
display: none;
}
}
@media screen and (max-width: 1280px) {
.header-container {
padding: 0 40px;
&__left-area {
&__logo-area {
&__menu-button {
display: block;
cursor: pointer;
}
}
}
}
.logo {
display: none;
}
/deep/ .edit-project {
margin-left: 0;
}
}
</style>

View File

@ -1,31 +0,0 @@
<!--Copyright (C) 2019 Storj Labs, Inc.-->
<!--See LICENSE for copying information.-->
<div class="header-container">
<div class="header-container__left-area">
<div class="header-container__left-area__logo-area">
<NavigationMenuIcon
class="header-container__left-area__logo-area__menu-button"
v-if="!isNavigationVisible && !isOnboardingTour"
@click.stop="toggleNavigationVisibility"
/>
<div class="header-container__left-area__logo-area__close-button" v-if="isNavigationVisible" @click.stop="toggleNavigationVisibility">
<NavigationCloseIcon/>
<p class="header-container__left-area__logo-area__close-button__title">Close</p>
</div>
<LogoIcon
class="logo"
@click.stop="onLogoClick"
/>
</div>
<ProjectSelection class="project-selection"/>
<ResourcesSelection class="resources-selection"/>
<SettingsSelection class="settings-selection"/>
</div>
<AccountButton class="header-container__account-button"/>
<NavigationArea
class="adapted-navigation"
v-if="isNavigationVisible"
/>
<div class="navigation-blur" v-if="isNavigationVisible" @click.self.stop="toggleNavigationVisibility"></div>
</div>

View File

@ -1,102 +0,0 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
.header-container {
font-family: 'font_regular', sans-serif;
min-height: 62px;
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30px;
position: relative;
&__left-area {
display: flex;
align-items: center;
&__logo-area {
width: 220px;
&__menu-button {
display: none;
}
&__close-button {
display: flex;
align-items: center;
cursor: pointer;
&__title {
margin-left: 13px;
font-size: 16px;
line-height: 23px;
color: #a9b5c1;
}
}
}
}
}
.logo {
cursor: pointer;
}
.adapted-navigation {
position: absolute;
top: 62px;
left: 0;
z-index: 100;
height: 100vh;
background: #e6e9ef;
}
.navigation-blur {
height: 100vh;
width: 100%;
position: absolute;
top: 62px;
left: 220px;
z-index: 100;
background: rgba(134, 134, 148, 0.4);
}
.project-selection,
.resources-selection {
margin-right: 35px;
}
@media screen and (min-width: 1281px) {
.adapted-navigation,
.navigation-blur,
.header-container__left-area__close-button {
display: none;
}
}
@media screen and (max-width: 1280px) {
.header-container {
padding: 0 40px;
&__left-area {
&__logo-area {
&__menu-button {
display: block;
cursor: pointer;
}
}
}
}
.logo {
display: none;
}
/deep/ .edit-project {
margin-left: 0;
}
}

View File

@ -3,7 +3,13 @@
<template>
<div class="project-dropdown">
<div class="project-dropdown__wrap">
<div class="project-dropdown__loader-container" v-if="isLoading">
<VLoader
width="30px"
height="30px"
/>
</div>
<div class="project-dropdown__wrap" v-else>
<div class="project-dropdown__wrap__choice" @click.prevent.stop="closeDropdown">
<div class="project-dropdown__wrap__choice__mark-container">
<SelectionIcon
@ -34,7 +40,9 @@
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { Component, Prop, Vue } from 'vue-property-decorator';
import VLoader from '@/components/common/VLoader.vue';
import SelectionIcon from '@/../static/images/header/selection.svg';
@ -51,9 +59,13 @@ import { LocalData } from '@/utils/localData';
@Component({
components: {
SelectionIcon,
VLoader,
},
})
export default class ProjectDropdown extends Vue {
@Prop({ default: false })
public readonly isLoading: boolean;
private FIRST_PAGE = 1;
/**
@ -137,6 +149,14 @@ export default class ProjectDropdown extends Vue {
border-radius: 6px;
background-color: #fff;
padding-top: 6px;
min-width: 300px;
&__loader-container {
margin: 10px 0;
display: flex;
align-items: center;
justify-content: center;
}
&__wrap {
overflow-y: scroll;

View File

@ -15,6 +15,7 @@
/>
<ProjectDropdown
v-show="isDropdownShown"
:is-loading="isLoading"
@close="closeDropdown"
v-click-outside="closeDropdown"
/>
@ -74,7 +75,11 @@ export default class ProjectSelection extends Vue {
* Fetches projects related information and than toggles selection popup.
*/
public async toggleSelection(): Promise<void> {
if (this.isLoading || this.isOnboardingTour) return;
if (this.isOnboardingTour) return;
this.toggleDropdown();
if (this.isLoading || !this.isDropdownShown) return;
this.isLoading = true;
@ -83,10 +88,8 @@ export default class ProjectSelection extends Vue {
await this.$store.dispatch(PROJECTS_ACTIONS.GET_LIMITS, this.$store.getters.selectedProject.id);
} catch (error) {
await this.$notify.error(error.message);
this.isLoading = false;
}
this.toggleDropdown();
this.isLoading = false;
}

View File

@ -1,7 +1,37 @@
// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
<template src="./resourcesDropdown.html"></template>
<template>
<div class="resources-dropdown">
<a
class="resources-dropdown__item-container"
href="https://docs.storj.io/"
target="_blank"
rel="noopener noreferrer"
>
<DocsIcon class="resources-dropdown__item-container__image"/>
<p class="resources-dropdown__item-container__title">Docs</p>
</a>
<a
class="resources-dropdown__item-container"
href="https://forum.storj.io/"
target="_blank"
rel="noopener noreferrer"
>
<CommunityIcon class="resources-dropdown__item-container__image"/>
<p class="resources-dropdown__item-container__title">Community</p>
</a>
<a
class="resources-dropdown__item-container"
href="https://supportdcs.storj.io/hc/en-us"
target="_blank"
rel="noopener noreferrer"
>
<SupportIcon class="resources-dropdown__item-container__image"/>
<p class="resources-dropdown__item-container__title">Support</p>
</a>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@ -45,4 +75,46 @@ export default class ResourcesDropdown extends Vue {
}
</script>
<style src="./resourcesDropdown.scss" scoped lang="scss"></style>
<style scoped lang="scss">
.resources-dropdown {
position: absolute;
top: 50px;
left: 0;
padding: 6px 0;
background-color: #f5f6fa;
z-index: 1120;
font-family: 'font_regular', sans-serif;
min-width: 255px;
box-shadow: 0 20px 34px rgba(10, 27, 44, 0.28);
border-radius: 6px;
&__item-container {
display: flex;
align-items: center;
justify-content: flex-start;
padding: 0 20px;
&__image {
min-width: 20px;
object-fit: cover;
}
&__title {
margin: 8px 0 14px 13px;
font-size: 14px;
line-height: 20px;
color: #1b2533;
}
&:hover {
font-family: 'font_bold', sans-serif;
.docs-svg-path,
.community-svg-path,
.support-svg-path {
fill: #2d75d2 !important;
}
}
}
}
</style>

View File

@ -1,35 +0,0 @@
<!--Copyright (C) 2020 Storj Labs, Inc.-->
<!--See LICENSE for copying information.-->
<div class="resources-dropdown">
<a
class="resources-dropdown__item-container"
href="https://docs.storj.io/node"
target="_blank"
rel="noopener noreferrer"
@click="onDocsIconClick"
>
<DocsIcon class="resources-dropdown__item-container__image"/>
<p class="resources-dropdown__item-container__title">Docs</p>
</a>
<a
class="resources-dropdown__item-container"
href="https://storj.io/community/"
target="_blank"
rel="noopener noreferrer"
@click="onCommunityIconClick"
>
<CommunityIcon class="resources-dropdown__item-container__image"/>
<p class="resources-dropdown__item-container__title">Community</p>
</a>
<a
class="resources-dropdown__item-container"
href="mailto:support@storj.io"
target="_blank"
rel="noopener noreferrer"
@click="onSupportIconClick"
>
<SupportIcon class="resources-dropdown__item-container__image"/>
<p class="resources-dropdown__item-container__title">Support</p>
</a>
</div>

View File

@ -1,44 +0,0 @@
// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
.resources-dropdown {
position: absolute;
top: 50px;
left: 0;
padding: 6px 0;
background-color: #f5f6fa;
z-index: 1120;
font-family: 'font_regular', sans-serif;
min-width: 255px;
box-shadow: 0 20px 34px rgba(10, 27, 44, 0.28);
border-radius: 6px;
&__item-container {
display: flex;
align-items: center;
justify-content: flex-start;
padding: 0 20px;
&__image {
min-width: 20px;
object-fit: cover;
}
&__title {
margin: 8px 0 14px 13px;
font-size: 14px;
line-height: 20px;
color: #1b2533;
}
&:hover {
font-family: 'font_bold', sans-serif;
.docs-svg-path,
.community-svg-path,
.support-svg-path {
fill: #2d75d2 !important;
}
}
}
}

View File

@ -10,7 +10,12 @@
<p class="buckets-view__title-area__button__label">New Bucket</p>
</div>
</div>
<div class="buckets-view__loader" v-if="isLoading"/>
<VLoader
width="120px"
height="120px"
class="buckets-view__loader"
v-if="isLoading"
/>
<p class="buckets-view__no-buckets" v-if="!(isLoading || bucketsList.length)">No Buckets</p>
<div class="buckets-view__list" v-if="!isLoading && bucketsList.length">
<div class="buckets-view__list__sorting-header">
@ -59,6 +64,7 @@
import { Bucket } from 'aws-sdk/clients/s3';
import { Component, Vue } from 'vue-property-decorator';
import VLoader from '@/components/common/VLoader.vue';
import BucketItem from '@/components/objects/BucketItem.vue';
import ObjectsPopup from '@/components/objects/ObjectsPopup.vue';
@ -76,6 +82,7 @@ import { Validator } from '@/utils/validation';
BucketIcon,
ObjectsPopup,
BucketItem,
VLoader,
},
})
export default class BucketsView extends Vue {
@ -342,13 +349,6 @@ export default class BucketsView extends Vue {
private get passphrase(): string {
return this.$store.state.objectsModule.passphrase;
}
/**
* Returns access grant from store.
*/
private get accessGrantFromStore(): string {
return this.$store.state.objectsModule.accessGrant;
}
}
</script>
@ -404,12 +404,6 @@ export default class BucketsView extends Vue {
&__loader {
margin-top: 100px;
border: 16px solid #f3f3f3;
border-top: 16px solid #3498db;
border-radius: 50%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
}
&__no-buckets {
@ -461,9 +455,4 @@ export default class BucketsView extends Vue {
background-color: #dadde5;
border-color: #dadde5;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>

View File

@ -38,7 +38,6 @@ import VButton from '@/components/common/VButton.vue';
import { RouteConfig } from '@/router';
@Component({
components: {
VButton,

View File

@ -0,0 +1,4 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.17423 8.83244C0.634669 8.29287 0.634669 7.41807 1.17423 6.8785C1.7138 6.33894 2.5886 6.33894 3.12817 6.8785L6.38473 10.1351C6.92429 10.6746 6.92429 11.5494 6.38473 12.089C5.84516 12.6286 4.97036 12.6286 4.43079 12.089L1.17423 8.83244Z" fill="#2683FF"/>
<path d="M6.38473 12.089C5.84516 12.6286 4.97036 12.6286 4.43079 12.089C3.89123 11.5494 3.89123 10.6746 4.43079 10.1351L10.2926 4.27325C10.8322 3.73369 11.707 3.73369 12.2465 4.27325C12.7861 4.81282 12.7861 5.68762 12.2465 6.22719L6.38473 12.089Z" fill="#2683FF"/>
</svg>

After

Width:  |  Height:  |  Size: 641 B