web/satellite: create access grant: result step

WHAT:
result step for access grant flow

WHY:
to show user access gratn key

Change-Id: I0426691ce670efd1d280ba819ecb0281b514452a
This commit is contained in:
VitaliiShpital 2020-11-20 17:09:08 +02:00 committed by Vitalii Shpital
parent 84fb8eee11
commit 257c8682d3
12 changed files with 428 additions and 31 deletions

View File

@ -150,6 +150,7 @@ export default class ConfirmDeletePopup extends Vue {
line-height: 18px;
color: #e30011;
font-family: 'font_medium', sans-serif;
white-space: nowrap;
}
&__list {

View File

@ -21,6 +21,7 @@ import ProgressBar from '@/components/accessGrants/ProgressBar.vue';
import CloseCrossIcon from '@/../static/images/common/closeCross.svg';
import { RouteConfig } from '@/router';
import { ACCESS_GRANTS_ACTIONS } from '@/store/modules/accessGrants';
@Component({
components: {
@ -33,6 +34,7 @@ export default class CreateAccessGrant extends Vue {
* Closes popup.
*/
public onCloseClick(): void {
this.$store.dispatch(ACCESS_GRANTS_ACTIONS.CLEAR_SELECTION);
this.$router.push(RouteConfig.AccessGrants.path);
}
@ -46,6 +48,13 @@ export default class CreateAccessGrant extends Vue {
</script>
<style scoped lang="scss">
::-webkit-scrollbar,
::-webkit-scrollbar-track,
::-webkit-scrollbar-thumb {
margin: 0;
width: 0;
}
.create-grant {
position: fixed;
top: 0;
@ -59,10 +68,10 @@ export default class CreateAccessGrant extends Vue {
justify-content: center;
&__container {
background: #fff;
background: #f5f6fa;
border-radius: 6px;
display: flex;
align-items: center;
align-items: flex-start;
position: relative;
&__close-cross-container {
@ -82,4 +91,54 @@ export default class CreateAccessGrant extends Vue {
}
}
}
@media screen and (max-height: 800px) {
.create-grant {
padding: 50px 0 20px 0;
overflow-y: scroll;
}
}
@media screen and (max-height: 750px) {
.create-grant {
padding: 100px 0 20px 0;
}
}
@media screen and (max-height: 700px) {
.create-grant {
padding: 150px 0 20px 0;
}
}
@media screen and (max-height: 650px) {
.create-grant {
padding: 200px 0 20px 0;
}
}
@media screen and (max-height: 600px) {
.create-grant {
padding: 250px 0 20px 0;
}
}
@media screen and (max-height: 550px) {
.create-grant {
padding: 300px 0 20px 0;
}
}
@media screen and (max-height: 500px) {
.create-grant {
padding: 350px 0 20px 0;
}
}
</style>

View File

@ -68,6 +68,7 @@ export default class ProgressBar extends Vue {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
background: #f5f6fa;
height: 380px;
border-radius: 6px 0 0 6px;

View File

@ -11,6 +11,8 @@
flex-direction: column;
align-items: center;
position: relative;
background-color: #fff;
border-radius: 6px;
&__back-icon {
position: absolute;

View File

@ -51,7 +51,12 @@ export default class CLIStep extends Vue {
* Redirects to upload step.
*/
public onDoneClick(): void {
this.$router.push(RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.UploadStep)).path);
this.$router.push({
name: RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.UploadStep)).name,
params: {
isUplinkSectionEnabled: 'true',
},
});
}
/**

View File

@ -59,6 +59,7 @@
width="100%"
height="48px"
:on-press="onNextClick"
:is-disabled="isLoading"
/>
</div>
</template>
@ -88,7 +89,7 @@ export default class CreatePassphraseStep extends Vue {
private key: string = '';
private access: string = '';
private worker: Worker;
private isLoading: boolean = false;
private isLoading: boolean = true;
public isGenerateState: boolean = true;
public isCreateState: boolean = false;
@ -99,14 +100,14 @@ export default class CreatePassphraseStep extends Vue {
* Lifecycle hook after initial render.
* Sets local key from props value.
*/
public mounted(): void {
public async mounted(): Promise<void> {
if (!this.$route.params.key) {
this.$router.push(RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.NameStep)).path);
await this.$router.push(RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.NameStep)).path);
}
this.key = this.$route.params.key;
this.passphrase = bip39.generateMnemonic();
this.worker = new Worker('/static/static/wasm/webWorker.js');
this.worker = await new Worker('/static/static/wasm/webWorker.js');
this.worker.onmessage = (event: MessageEvent) => {
const data = event.data;
if (data.error) {
@ -115,13 +116,15 @@ export default class CreatePassphraseStep extends Vue {
return;
}
this.$notify.success('Access Grant was generated successfully');
this.access = data.value;
this.$notify.success('Access Grant was generated successfully');
};
this.worker.onerror = (error: ErrorEvent) => {
this.$notify.error(error.message);
};
this.isLoading = false;
}
/**
@ -196,6 +199,7 @@ export default class CreatePassphraseStep extends Vue {
name: RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.ResultStep)).name,
params: {
access: this.access,
key: this.key,
},
});
}, 1000);
@ -228,6 +232,8 @@ export default class CreatePassphraseStep extends Vue {
flex-direction: column;
align-items: center;
position: relative;
background-color: #fff;
border-radius: 0 6px 6px 0;
&__back-icon {
position: absolute;
@ -252,7 +258,7 @@ export default class CreatePassphraseStep extends Vue {
width: calc(100% - 40px);
background: #fff9f7;
border: 1px solid #f84b00;
margin-bottom: 30px;
margin-bottom: 35px;
border-radius: 8px;
&__label {

View File

@ -19,6 +19,7 @@
width="100%"
height="48px"
:on-press="onNextClick"
:is-disabled="isLoading"
/>
</div>
</template>
@ -45,7 +46,7 @@ export default class EnterPassphraseStep extends Vue {
private key: string = '';
private access: string = '';
private worker: Worker;
private isLoading: boolean = false;
private isLoading: boolean = true;
public passphrase: string = '';
public errorMessage: string = '';
@ -54,13 +55,13 @@ export default class EnterPassphraseStep extends Vue {
* Lifecycle hook after initial render.
* Sets local key from props value.
*/
public mounted(): void {
public async mounted(): Promise<void> {
if (!this.$route.params.key) {
this.$router.push(RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.NameStep)).path);
await this.$router.push(RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.NameStep)).path);
}
this.key = this.$route.params.key;
this.worker = new Worker('/static/static/wasm/webWorker.js');
this.worker = await new Worker('/static/static/wasm/webWorker.js');
this.worker.onmessage = (event: MessageEvent) => {
const data = event.data;
if (data.error) {
@ -69,13 +70,15 @@ export default class EnterPassphraseStep extends Vue {
return;
}
this.$notify.success('Access Grant was generated successfully');
this.access = data.value;
this.$notify.success('Access Grant was generated successfully');
};
this.worker.onerror = (error: ErrorEvent) => {
this.$notify.error(error.message);
};
this.isLoading = false;
}
/**
@ -118,6 +121,7 @@ export default class EnterPassphraseStep extends Vue {
name: RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.ResultStep)).name,
params: {
access: this.access,
key: this.key,
},
});
}, 1000);
@ -150,6 +154,8 @@ export default class EnterPassphraseStep extends Vue {
flex-direction: column;
align-items: center;
position: relative;
background-color: #fff;
border-radius: 0 6px 6px 0;
&__back-icon {
position: absolute;
@ -178,7 +184,7 @@ export default class EnterPassphraseStep extends Vue {
}
&__input {
width: calc(100% - 8px);
width: calc(100% - 12px);
}
&__next-button {

View File

@ -132,6 +132,8 @@ export default class NameStep extends Vue {
display: flex;
flex-direction: column;
align-items: center;
background-color: #fff;
border-radius: 0 6px 6px 0;
&__title {
font-family: 'font_bold', sans-serif;
@ -152,14 +154,14 @@ export default class NameStep extends Vue {
}
&__input {
width: calc(100% - 10px);
width: calc(100% - 12px);
}
&__buttons-area {
width: 100%;
display: flex;
align-items: center;
margin-top: 100px;
margin-top: 130px;
}
}

View File

@ -91,7 +91,7 @@ export default class PermissionsStep extends Vue {
private restrictedKey: string = '';
private worker: Worker;
public isLoading: boolean = false;
public isLoading: boolean = true;
public isDownload: boolean = true;
public isUpload: boolean = true;
public isList: boolean = true;
@ -108,7 +108,7 @@ export default class PermissionsStep extends Vue {
}
this.key = this.$route.params.key;
this.worker = new Worker('/static/static/wasm/webWorker.js');
this.worker = await new Worker('/static/static/wasm/webWorker.js');
this.worker.onmessage = (event: MessageEvent) => {
const data = event.data;
if (data.error) {
@ -117,9 +117,9 @@ export default class PermissionsStep extends Vue {
return;
}
this.$notify.success('Permissions were set successfully');
this.restrictedKey = data.value;
this.$notify.success('Permissions were set successfully');
};
this.worker.onerror = (error: ErrorEvent) => {
this.$notify.error(error.message);
@ -130,6 +130,8 @@ export default class PermissionsStep extends Vue {
} catch (error) {
await this.$notify.error(`Unable to fetch all bucket names. ${error.message}`);
}
this.isLoading = false;
}
/**
@ -246,6 +248,8 @@ export default class PermissionsStep extends Vue {
flex-direction: column;
align-items: center;
position: relative;
background-color: #fff;
border-radius: 0 6px 6px 0;
&__back-icon {
position: absolute;
@ -269,7 +273,7 @@ export default class PermissionsStep extends Vue {
line-height: 21px;
color: #000;
text-align: center;
margin: 0 0 50px 0;
margin: 0 0 70px 0;
}
&__content {

View File

@ -2,24 +2,313 @@
// See LICENSE for copying information.
<template>
<div class="generate-grant">
<BackIcon class="generate-grant__back-icon" @click="onBackClick"/>
<h1 class="generate-grant__title">Generate Access Grant</h1>
<div class="generate-grant__warning">
<div class="generate-grant__warning__header">
<WarningIcon/>
<h2 class="generate-grant__warning__header__label">This Information is Only Displayed Once</h2>
</div>
<p class="generate-grant__warning__message">
Save this information in a password manager, or wherever you prefer to store sensitive information.
</p>
</div>
<div class="generate-grant__grant-area">
<h3 class="generate-grant__grant-area__label">Access Grant</h3>
<div class="generate-grant__grant-area__container">
<p class="generate-grant__grant-area__container__value">{{ access }}</p>
<VButton
class="generate-grant__grant-area__container__button"
label="Copy"
width="66px"
height="30px"
:on-press="onCopyClick"
/>
</div>
</div>
<div class="generate-grant__gateway-area">
<div class="generate-grant__gateway-area__toggle" @click="toggleCredentialsVisibility">
<h3 class="generate-grant__gateway-area__toggle__label">Gateway Credentials</h3>
<ExpandIcon v-if="!areGatewayCredentialsVisible"/>
<HideIcon v-else/>
</div>
<div class="generate-grant__gateway-area__container" v-if="areGatewayCredentialsVisible">
<h3 class="generate-grant__gateway-area__container__title">
Using Gateway Credentials Enables Server-Side Encryption.
</h3>
<p class="generate-grant__gateway-area__container__disclaimer">
By generating gateway credentials, you are opting in to Server-side encryption
</p>
<VButton
class="generate-grant__gateway-area__container__button"
label="Generate Gateway Credentials"
width="100%"
height="48px"
:on-press="onGenerateCredentialsClick"
is-disabled="true"
/>
</div>
</div>
<VButton
class="generate-grant__done-button"
label="Done"
width="100%"
height="48px"
:on-press="onDoneClick"
/>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import VButton from '@/components/common/VButton.vue';
import BackIcon from '@/../static/images/accessGrants/back.svg';
import WarningIcon from '@/../static/images/accessGrants/warning.svg';
import ExpandIcon from '@/../static/images/common/BlackArrowExpand.svg';
import HideIcon from '@/../static/images/common/BlackArrowHide.svg';
import { RouteConfig } from '@/router';
@Component
@Component({
components: {
BackIcon,
WarningIcon,
VButton,
ExpandIcon,
HideIcon,
},
})
export default class ResultStep extends Vue {
public access: string = '';
public areGatewayCredentialsVisible: boolean = false;
/**
* Lifecycle hook after initial render.
* Sets local access from props value.
*/
public mounted(): void {
if (!this.$route.params.access) {
if (!this.$route.params.access || !this.$route.params.key) {
this.$router.push(RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.NameStep)).path);
}
this.access = this.$route.params.access;
}
/**
* Toggles gateway credentials section visibility.
*/
public toggleCredentialsVisibility(): void {
this.areGatewayCredentialsVisible = !this.areGatewayCredentialsVisible;
}
/**
* Holds on copy button click logic.
* Copies token to clipboard.
*/
public onCopyClick(): void {
this.$copyText(this.access);
this.$notify.success('Token was copied successfully');
}
/**
* Holds on back button click logic.
* Redirects to previous step.
*/
public onBackClick(): void {
if (this.accessGrantsAmount > 1) {
this.$router.push({
name: RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.EnterPassphraseStep)).name,
params: {
key: this.$route.params.key,
},
});
return;
}
this.$router.push({
name: RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.CreatePassphraseStep)).name,
params: {
key: this.$route.params.key,
},
});
}
/**
* Holds on done button click logic.
* Proceed to upload data step.
*/
public onDoneClick(): void {
this.$router.push({
name: RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.UploadStep)).name,
params: {
isUplinkSectionEnabled: 'false',
},
});
}
/**
* Holds on generate credentials button click logic.
* Generates gateway credentials.
*/
public onGenerateCredentialsClick(): void {
return;
}
/**
* Returns amount of access grants from store.
*/
private get accessGrantsAmount(): number {
return this.$store.state.accessGrantsModule.page.accessGrants.length;
}
}
</script>
<style scoped lang="scss">
.generate-grant {
height: calc(100% - 60px);
padding: 30px 65px;
max-width: 475px;
min-width: 475px;
font-family: 'font_regular', sans-serif;
font-style: normal;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
background-color: #fff;
border-radius: 0 6px 6px 0;
&__back-icon {
position: absolute;
top: 30px;
left: 65px;
cursor: pointer;
}
&__title {
font-family: 'font_bold', sans-serif;
font-weight: bold;
font-size: 22px;
line-height: 27px;
color: #000;
margin: 0 0 30px 0;
}
&__warning {
padding: 20px;
width: calc(100% - 40px);
background: #fff9f7;
border: 1px solid #f84b00;
border-radius: 8px;
&__header {
display: flex;
align-items: center;
&__label {
font-style: normal;
font-family: 'font_bold', sans-serif;
font-size: 16px;
line-height: 19px;
color: #1b2533;
margin: 0 0 0 15px;
}
}
&__message {
font-size: 16px;
line-height: 22px;
color: #1b2533;
margin: 8px 0 0 0;
}
}
&__grant-area {
margin: 40px 0;
width: 100%;
&__label {
font-family: 'font_bold', sans-serif;
font-size: 16px;
line-height: 21px;
color: #354049;
margin: 0 0 10px 0;
}
&__container {
display: flex;
align-items: center;
border-radius: 9px;
padding: 10px;
width: calc(100% - 20px);
border: 1px solid rgba(56, 75, 101, 0.4);
&__value {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
margin: 0;
}
&__button {
min-width: 66px;
min-height: 30px;
margin-left: 10px;
}
}
}
&__gateway-area {
display: flex;
flex-direction: column;
align-items: center;
&__toggle {
display: flex;
align-items: center;
cursor: pointer;
&__label {
font-family: 'font_bold', sans-serif;
font-size: 16px;
line-height: 23px;
color: #49515c;
margin: 0 15px 0 0;
}
}
&__container {
background: #f5f6fa;
border-radius: 6px;
padding: 40px 50px;
width: calc(100% - 100px);
margin-top: 30px;
&__title {
font-family: 'font_bold', sans-serif;
font-size: 18px;
line-height: 24px;
color: #000;
margin: 0 0 20px 0;
text-align: center;
}
&__disclaimer {
font-size: 16px;
line-height: 28px;
color: #000;
margin: 0 0 25px 0;
text-align: center;
}
}
}
&__done-button {
margin-top: 30px;
}
}
</style>

View File

@ -8,8 +8,8 @@
From here, youll set up Tardigrade to store data for your project using our S3 Gateway, Uplink CLI, or
select from our growing library of connectors to build apps on Tardigrade.
</p>
<div class="upload-data__docs-area">
<div class="upload-data__docs-area__option">
<div class="upload-data__docs-area" :class="{ justify: !isUplinkSectionEnabled }">
<div class="upload-data__docs-area__option" :class="{ margin: !isUplinkSectionEnabled }">
<h2 class="upload-data__docs-area__option__title">
Migrate Data from your Existing AWS buckets
</h2>
@ -29,7 +29,7 @@
S3 Gateway Docs
</a>
</div>
<div class="upload-data__docs-area__option uplink-option">
<div class="upload-data__docs-area__option uplink-option" v-if="isUplinkSectionEnabled">
<h2 class="upload-data__docs-area__option__title">
Upload Data from Your Local Environment
</h2>
@ -93,6 +93,20 @@ import { RouteConfig } from '@/router';
},
})
export default class UploadStep extends Vue {
public isUplinkSectionEnabled: boolean = true;
/**
* Lifecycle hook after initial render.
* Sets uplink section visibility from props value.
*/
public mounted(): void {
if (!this.$route.params.isUplinkSectionEnabled) {
this.$router.push(RouteConfig.AccessGrants.with(RouteConfig.CreateAccessGrant.with(RouteConfig.NameStep)).path);
}
this.$route.params.isUplinkSectionEnabled === 'true' ? this.isUplinkSectionEnabled = true : this.isUplinkSectionEnabled = false;
}
/**
* Holds on close button click logic.
* Redirects to access grants page.
@ -202,4 +216,12 @@ export default class UploadStep extends Vue {
.uplink-option {
margin: 0 25px;
}
.justify {
justify-content: center;
}
.margin {
margin-right: 25px;
}
</style>

View File

@ -1,3 +1,3 @@
<svg width="10" height="6" viewBox="0 0 10 6" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.73373 5.74583C9.37871 6.08472 8.80311 6.08472 8.44808 5.74583L5 2.45445L1.55192 5.74583C1.19689 6.08472 0.621288 6.08472 0.266267 5.74583C-0.0887565 5.40694 -0.0887565 4.8575 0.266267 4.51861L5 -4.37114e-07L9.73373 4.51861C10.0888 4.8575 10.0888 5.40695 9.73373 5.74583Z" fill="#2582FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.73373 5.74583C9.37871 6.08472 8.80311 6.08472 8.44808 5.74583L5 2.45445L1.55192 5.74583C1.19689 6.08472 0.621288 6.08472 0.266267 5.74583C-0.0887565 5.40694 -0.0887565 4.8575 0.266267 4.51861L5 -4.37114e-07L9.73373 4.51861C10.0888 4.8575 10.0888 5.40695 9.73373 5.74583Z" fill="#354049"/>
</svg>

Before

Width:  |  Height:  |  Size: 446 B

After

Width:  |  Height:  |  Size: 446 B