Переглянути джерело

feat/ui-layout (#47)

feat: update header

feat: change header to have more links

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

feat: implement Restore page

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

feat: implement my bubble page

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

feat: replace old pages with new pages

feat: implement devices page

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

feat: implement account policy page

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

feat: implement payment and bills page

Merge branch 'feat/ui-layout' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

feat: change config to accept env files

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

feat: make a stripe element component

Merge branch 'master' into feat/ui-layout

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

feat: implement manage ssh key page

feat: set password page

feat: implement change password page

fix: change design

feat: implement my account page

feat: implement animation control for launching bubble screen

fix: navigating to network page

feat: implement Launching bubble page

feat: integrate launch bubble api

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

feat: implement MFA in login

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

feat: implement adding ssh key

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

fix: showing default values

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

feat: implement selector placeholders and default values

Merge branch 'feat/ui-layout' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

fix: getting user information after setting payment method

Merge branch 'master' into feat/ui-layout

feat: implement setting payment plan in payment page

feat: populate options for advanced settings modal

fix: remove showing advanced settings modal when loading the page

feat: implement Advanced Settings Modal layout

feat: implement modal and selector components

feat: implement launch bubble screen

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into feat/ui-layout

Co-authored-by: Tyler <everdev0923@gmail.com>
Co-authored-by: jonathan <jonathan@noreply.git.bubblev.org>
Reviewed-on: https://git.bubblev.org/bubblev/bubble-web/pulls/47
pull/56/head
Tyler Chen 4 роки тому
committed by jonathan
джерело
коміт
6dd8a5c9e3
3 змінених файлів з 284 додано та 60 видалено
  1. +67
    -7
      src/_components/layout/Header.vue
  2. +213
    -0
      src/_pages/main/bubble/Restore.vue
  3. +4
    -53
      src/_router/index.js

+ 67
- 7
src/_components/layout/Header.vue Переглянути файл

@@ -4,7 +4,7 @@
<div class="d-flex justify-content-center align-items-center container ">
<img src="/small-BubbleLogo-Horizontal-BlackText.png" height="40" />
<div class="flex-grow-1"></div>
<div class="navbar d-none d-md-flex">
<div class="navbar d-none d-lg-flex">
<!--- If not logged in --->
<div
v-if="status.loggedIn !== true"
@@ -41,6 +41,38 @@
{{ messages.label_menu_network }}
</Button>
</router-link>
<router-link
to="/devices"
class="d-flex align-items-center"
v-if="!configs.sageLauncher"
>
<Button headerLink>
{{ messages.label_menu_devices }}
</Button>
</router-link>
<router-link
to="/apps"
class="d-flex align-items-center"
v-if="!configs.sageLauncher"
>
<Button headerLink>
{{ messages.label_menu_apps }}
</Button>
</router-link>
<router-link
to="/admin/accounts"
class="d-flex align-items-center"
v-if="!configs.sageLauncher"
>
<Button headerLink>
{{ messages.label_menu_admin_users }}
</Button>
</router-link>
<router-link to="/me" class="d-flex align-items-center">
<Button headerLink>
{{ messages.label_menu_account }}
</Button>
</router-link>
<router-link to="/help" class="d-flex align-items-center">
<Button headerLink>
{{ messages.button_label_help }}
@@ -53,14 +85,14 @@
</router-link>
</div>
</div>
<div class="navbar d-md-none" @click="toggleNavbar()">
<div class="navbar d-lg-none" @click="toggleNavbar()">
<i class="fas fa-bars"></i>
</div>
</div>

<div
class="dropdown-menu dropdown-menu-right d-md-none w-100 my-0"
:class="{ show: menuVisible }"
class="dropdown-menu dropdown-menu-right w-100 my-0"
v-click-outside="hide"
>
<div v-if="status.loggedIn === false">
@@ -81,6 +113,30 @@
<router-link class="dropdown-item" to="/bubbles">
{{ messages.label_menu_network }}
</router-link>
<router-link
to="/devices"
class="dropdown-item"
v-if="!configs.sageLauncher"
>
{{ messages.label_menu_devices }}
</router-link>
<router-link
to="/apps"
class="dropdown-item"
v-if="!configs.sageLauncher"
>
{{ messages.label_menu_apps }}
</router-link>
<router-link
to="/admin/accounts"
class="dropdown-item"
v-if="!configs.sageLauncher"
>
{{ messages.label_menu_admin_users }}
</router-link>
<router-link to="/me" class="dropdown-item">
{{ messages.label_menu_account }}
</router-link>
<router-link class="dropdown-item" to="/help">
{{ messages.button_label_help }}
</router-link>
@@ -135,7 +191,7 @@ export default {
data() {
return {
menuVisible: false,
prevVisibleState: false
timerId: null,
};
},

@@ -146,11 +202,15 @@ export default {

methods: {
toggleNavbar() {
this.menuVisible = !this.prevVisibleState;
this.menuVisible = !this.menuVisible;
this.timerId = setTimeout(() => {
this.timerId = null;
}, 100);
},
hide() {
this.prevVisibleState = this.menuVisible;
this.menuVisible = false;
if (!this.timerId) {
this.menuVisible = false;
}
},
},
};


+ 213
- 0
src/_pages/main/bubble/Restore.vue Переглянути файл

@@ -0,0 +1,213 @@
<!-- Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ -->
<template>
<div class="bubble-form">
<h2>{{ messages.form_title_restore }}</h2>

<div v-if="!configs"><img :src="loadingImgSrc" /></div>

<div v-else-if="configs.restoreInProgress" class="alert alert-info">
{{ messages.message_restore_in_progress }}
<hr />
<a href="/">{{ messages.message_back_to_root }}</a>
</div>

<div v-else>
<form @submit.prevent="handleSubmit">
<fieldset :disabled="status.uploadingRestoreRequestData">
<div class="form-group">
<Input
type="text"
v-model="restoreShortKey"
name="restoreShortKey"
class="form-control"
:class="{ 'is-invalid': submitted && !restoreShortKey }"
:placeholder="messages.field_label_restore_short_key"
/>
<div
v-show="submitted && !restoreShortKey"
class="invalid-feedback"
>
{{ messages.err_restoreShortKey_required }}
</div>
<div
v-if="submitted && errors.has('restoreShortKey')"
class="invalid-feedback d-block"
>
{{ errors.first('restoreShortKey') }}
</div>
</div>

<div class="form-group">
<div style="border: 2px solid #000;">
<label htmlFor="restoreLongNetworkKeyFile">
{{ messages.field_label_restore_long_key }}
</label>
<input
type="file"
ref="restoreLongNetworkKeyFile"
@change="readUploadedKeyFile"
class="form-control"
:class="{ 'is-invalid': fileFieldsConstaintFailed }"
/>
<div
v-if="submitted && errors.has('restoreLongNetworkKey')"
class="invalid-feedback d-block"
>
{{ errors.first('restoreLongNetworkKey') }}
</div>

<div style="text-align: center">{{ messages.label_or }}</div>

<label htmlFor="restoreBackupPackageFile">
{{ messages.field_label_restore_backup_package }}
</label>
<input
type="file"
ref="restoreBackupPackageFile"
@change="setBackupFileForUpload"
class="form-control"
:class="{ 'is-invalid': fileFieldsConstaintFailed }"
/>
<div
v-if="submitted && errors.has('restoreBackupPackageFileRef')"
class="invalid-feedback d-block"
>
{{ errors.first('restoreBackupPackageFileRef') }}
</div>
</div>

<div
class="invalid-feedback"
:class="{ 'd-block': fileFieldsConstaintFailed }"
>
{{ messages.err_restoreFile_constraint }}
</div>
</div>

<div class="form-group">
<Input
type="password"
v-model="password"
name="password"
class="form-control"
:class="{ 'is-invalid': submitted && !password }"
:placeholder="messages.field_label_password"
/>
<div v-show="submitted && !password" class="invalid-feedback">
{{ messages.err_password_required }}
</div>
<div
v-if="submitted && errors.has('password')"
class="invalid-feedback d-block"
>
{{ errors.first('password') }}
</div>
</div>

<div class="form-group">
<Button
color="default"
class="btn btn-primary"
:disabled="status.uploadingRestoreRequestData"
>
{{ messages.button_label_restore }}
</Button>
<img
v-show="status.uploadingRestoreRequestData"
:src="loadingImgSrc"
/>
</div>
</fieldset>
</form>
</div>
</div>
</template>

<style lang="scss" scoped>
@import '../../../_scss/components/form';
@import '../../../_scss/breakpoints';

.bubble-form {
width: 800px;
}
</style>

<script>
import { mapState, mapActions } from 'vuex';
import { loadingImgSrc } from '~/_store';

import { Input, Button } from '~/_components/shared';

export default {
components: {
Input,
Button,
},
data() {
return {
restoreShortKey:
this.$route.query && this.$route.query.k ? this.$route.query.k : null,
restoreLongNetworkKey: null,
restoreBackupPackageFileRef: null,
password: '',
submitted: false,
loadingImgSrc: loadingImgSrc,
};
},
created() {
this.loadSystemConfigs();
},
computed: {
...mapState('account', ['status']),
...mapState('system', ['configs', 'messages']),
fileFieldsConstaintFailed() {
// only and exactly 1 file may be uploaded - either file including long network key, or full backup package
return (
this.submitted &&
((!this.restoreLongNetworkKey && !this.restoreBackupPackageFileRef) ||
(this.restoreLongNetworkKey && this.restoreBackupPackageFileRef))
);
},
},
methods: {
...mapActions('account', ['restore', 'restoreFromPackage']),
...mapActions('system', ['loadSystemConfigs']),
handleSubmit(e) {
this.errors.clear();
const { restoreShortKey, password } = this;
this.submitted = true;
if (!this.fileFieldsConstaintFailed) {
if (this.restoreLongNetworkKey) {
this.restore({
shortKey: restoreShortKey,
longKey: this.restoreLongNetworkKey,
password: password,
systemConfigs: this.configs,
messages: this.messages,
errors: this.errors,
});
} else if (this.restoreBackupPackageFileRef) {
this.restoreFromPackage({
shortKey: restoreShortKey,
backupFileRef: this.restoreBackupPackageFileRef,
password: password,
systemConfigs: this.configs,
messages: this.messages,
errors: this.errors,
});
}
}
},
readUploadedKeyFile() {
var uploadedFile = this.$refs.restoreLongNetworkKeyFile.files[0];
var reader = new FileReader();
reader.onload = (event) =>
(this.restoreLongNetworkKey = event.target.result);
reader.readAsText(uploadedFile);
},
setBackupFileForUpload() {
this.restoreBackupPackageFileRef = this.$refs.restoreBackupPackageFile.files[0];
},
},
};
</script>

+ 4
- 53
src/_router/index.js Переглянути файл

@@ -79,65 +79,16 @@ export const router = new Router({
path: '',
component: () => import('~/_pages/main/account/Layout'),
children: [
{
path: 'verify-email',
component: () => import('~/_pages/main/account/VerifyEmail'),
},
{
path: 'payment',
component: () => import('~/_pages/main/account/Payment'),
},
{
path: 'me',
exact: true,
component: () => import('~/_pages/main/account/MyAccount'),
},
{
path: 'me/change-password',
component: () =>
import('~/_pages/main/account/ChangePassword'),
},
{
path: 'me/set-password/:code',
component: () => import('~/_pages/main/account/SetPassword'),
},
{
path: 'me/keys',
component: () => import('~/_pages/main/account/ManageSSH'),
},
{
path: 'me/payment',
component: () =>
import('~/_pages/main/account/PaymentMethods'),
},
{
path: 'me/bills',
component: () => import('~/_pages/main/account/Bills'),
},
{
path: 'me/policy',
component: () => import('~/_pages/main/account/Policy'),
},

{
path: 'devices',
component: () => import('~/_pages/main/account/Devices'),
},

{
path: 'bubble/:id',
component: () => import('~/_pages/main/bubble/Network'),
},
{
path: 'restore',
component: () => import('~/_pages/main/bubble/Restore'),
},
],
},
{
path: 'launch-bubble',
component: () => import('~/_pages/main/bubble/LaunchBubble'),
},
{
path: 'launching-bubble/:id',
component: () => import('~/_pages/main/bubble/LaunchingBubble'),
},
{
path: 'test',
component: () => import('~/_pages/main/Test'),


Завантаження…
Відмінити
Зберегти