Kaynağa Gözat

fix/missing-functionalities (#61)

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into fix/missing-functionalities

fix: refreshing issue

feat: implement devices screen

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into fix/missing-functionalities

feat: implement new layout

Merge branch 'master' of git.bubblev.org:bubblev/bubble-web into fix/missing-functionalities

feat: implement new layout

fix: header

fix: showing error on add ssh modal

fix: login by enter key

Co-authored-by: Tyler <everdev0923@gmail.com>
Reviewed-on: https://git.bubblev.org/bubblev/bubble-web/pulls/61
pull/68/head
Tyler Chen 4 yıl önce
committed by jonathan
ebeveyn
işleme
dbba7517d4
7 değiştirilmiş dosya ile 258 ekleme ve 171 silme
  1. +40
    -2
      package-lock.json
  2. +17
    -5
      src/_components/layout/Sidebar.vue
  3. +167
    -2
      src/_pages/Layout.vue
  4. +3
    -1
      src/_pages/auth/Register.vue
  5. +1
    -1
      src/_pages/auth/VerifyEmail.vue
  6. +29
    -137
      src/_pages/main/Layout.vue
  7. +1
    -23
      src/_router/index.js

+ 40
- 2
package-lock.json Dosyayı Görüntüle

@@ -2524,6 +2524,11 @@
"entities": "^1.1.1"
}
},
"dom-walk": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
},
"domain-browser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
@@ -3432,6 +3437,15 @@
}
}
},
"global": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
"integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
"requires": {
"min-document": "^2.19.0",
"process": "^0.11.10"
}
},
"global-modules": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
@@ -4550,6 +4564,14 @@
"mime-db": "1.44.0"
}
},
"min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
"requires": {
"dom-walk": "^0.1.0"
}
},
"minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@@ -5504,8 +5526,7 @@
"process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
"dev": true
"integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
},
"process-nextick-args": {
"version": "2.0.1",
@@ -7665,6 +7686,23 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz",
"integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ=="
},
"vue-carousel": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/vue-carousel/-/vue-carousel-0.18.0.tgz",
"integrity": "sha512-a2zxh7QJioDxNMguqcuJ7TPbfgK5bGDaAXIia7NWxPAWsEvNE4ZtHgsGu40L5Aha4uyjmNKXvleB14QAXFoKig==",
"requires": {
"global": "^4.3.2",
"regenerator-runtime": "^0.12.1",
"vue": "^2.5.17"
},
"dependencies": {
"regenerator-runtime": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
"integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
}
}
},
"vue-click-outside": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/vue-click-outside/-/vue-click-outside-1.1.0.tgz",


+ 17
- 5
src/_components/layout/Sidebar.vue Dosyayı Görüntüle

@@ -31,7 +31,11 @@

<!-- Navigation -->
<div class="navigation">
<router-link to="/bubble" class="navigation-item" @click.native="closeMenu()">
<router-link
to="/bubble"
class="navigation-item"
@click.native="closeMenu()"
>
<i class="fa fa-home icon icon-home"></i>
<span>{{ messages.label_menu_network }}</span>
</router-link>
@@ -72,16 +76,24 @@
<span>{{ messages.label_menu_settings }}</span>
</router-link> -->

<router-link to="/support" class="navigation-item" @click.native="closeMenu()">
<router-link
to="/support"
class="navigation-item"
@click.native="closeMenu()"
>
<i class="fa fa-question-circle icon icon-help"></i>
<span>{{ messages.label_menu_help }}</span>
</router-link>
</div>
<!-- Upgrade Plan -->

<div class="flex-grow-1"></div>
<!-- <div class="flex-grow-1"></div> -->
<!-- Logout -->
<router-link to="/logout" class="logout-button" @click.native="closeMenu()">
<router-link
to="/logout"
class="logout-button"
@click.native="closeMenu()"
>
<Button color="outline" block>
{{ messages.log_out }}
</Button>
@@ -281,7 +293,7 @@ export default {
closeMenu() {
console.log('click.nativeed');
this.menuVisible = false;
}
},
},
};
</script>

+ 167
- 2
src/_pages/Layout.vue Dosyayı Görüntüle

@@ -1,8 +1,173 @@
<!-- Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ -->
<template>
<router-view></router-view>
<router-view v-if="isPageAvailable"></router-view>
</template>

<script>
export default {};
import { mapState, mapActions } from 'vuex';
import { util } from '~/_helpers';
import { isAuthenticator, isNotAuthenticator } from '~/_store/users.module';

export default {
data: () => ({
verifiedContacts: null,
verifiedContactRefresher: null,
accountPlan: {
currentUser: null,
name: '',
domain: '',
locale: null,
timezone: '',
plan: 'bubble',
footprint: 'Worldwide',
paymentMethodObject: {
uuid: null,
paymentMethodType: null,
paymentInfo: null,
},
sshKey: '',
forkHost: '',
syncAccount: true,
launchLock: false,
sendErrors: true,
sendMetrics: true,
},
payMethods: null,
}),

computed: {
...mapState('users', ['policy']),
...mapState('paymentMethods', ['accountPaymentMethods']),
...mapState('system', ['configs', 'messages']),

isPageAvailable() {
return (
!this.currentUser || (this.verifiedContacts || this.currentUser.admin)
);
},
},

created() {
this.currentUser = util.currentUser();
if (this.currentUser) {
this.locale = this.currentUser.locale;
}
},

mounted() {
this.initDefaults();
},

methods: {
...mapActions('users', ['getPolicyByUserId']),
...mapActions('paymentMethods', ['getAllAccountPaymentMethods']),

initDefaults() {
const selectedLocale =
this.currentUser !== null &&
typeof this.currentUser.locale !== 'undefined' &&
this.currentUser.locale !== null
? this.currentUser.locale
: 'detect';
if (this.currentUser && !this.currentUser.admin) {
this.getPolicyByUserId({
userId: this.currentUser.uuid,
messages: this.messages,
errors: this.errors,
});
}
},

hasVerifiedContact(policy) {
if (policy && policy.accountContacts) {
const contacts = policy.accountContacts;
for (let i = 0; i < contacts.length; i++) {
if (contacts[i].verified && isNotAuthenticator(contacts[i]))
return true;
}
return false;
}
return false;
},

navigateToVerifyEmail() {
if (this.$route.path !== '/verifyEmail') {
this.$router.push('/verifyEmail');
}
},

navigateToPaymentPage() {
if (this.$route.path !== '/payment') {
this.$router.push('/payment');
}
},

navigateToDashboard() {
if (
this.$route.path === '/payment' ||
this.$route.path === '/verifyEmail'
) {
this.$router.push('/');
}
},
},

watch: {
policy(p) {
this.verifiedContacts = this.hasVerifiedContact(p);
const currentUser = util.currentUser();
if (!this.verifiedContacts && !currentUser.admin) {
this.navigateToVerifyEmail();
if (this.verifiedContactRefresher === null) {
const vue = this;
const currentUser = util.currentUser();
this.verifiedContactRefresher = window.setInterval(() => {
vue.getPolicyByUserId({
userId: currentUser.uuid,
messages: vue.messages,
errors: vue.errors,
});
}, 5000);
}
} else {
const currentUser = util.currentUser();
this.getAllAccountPaymentMethods({
userId: currentUser.uuid,
messages: this.messages,
errors: this.errors,
});
if (this.verifiedContactRefresher !== null) {
window.clearInterval(this.verifiedContactRefresher);
this.verifiedContactRefresher = null;
}
}
},

accountPaymentMethods(pms, oldpms) {
if (pms && this.configs.paymentsEnabled) {
const payMethods = [];
for (let i = 0; i < pms.length; i++) {
const pm = pms[i];
if (
(typeof pm.promotion === 'undefined' ||
pm.promotion === null ||
!pm.promotion) &&
(typeof pm.deleted === 'undefined' || pm.deleted === null)
) {
payMethods.push(pm);
}
}

if (
this.accountPlan.paymentMethodObject.uuid === null &&
payMethods.length > 0
) {
this.navigateToDashboard();
} else {
this.navigateToPaymentPage();
}
}
},
},
};
</script>

+ 3
- 1
src/_pages/auth/Register.vue Dosyayı Görüntüle

@@ -220,6 +220,7 @@ export default {
paymentMethodObject: null,
confirmPassword: '',
submitted: false,
preferredPlan: null,
};
},

@@ -314,6 +315,7 @@ export default {
receivePromotionalMessages: this.receivePromotionalMessages,
agreeToTerms: this.agreeToTerms,
promoCode: this.promoCode,
preferredPlan: this.preferredPlan,
},
messages: this.messages,
errors: this.errors,
@@ -346,7 +348,7 @@ export default {
},
plan(p) {
if (p.uuid) {
this.user.preferredPlan = p.uuid;
this.preferredPlan = p.uuid;
}
},
configs(configs) {


+ 1
- 1
src/_pages/auth/VerifyEmail.vue Dosyayı Görüntüle

@@ -56,7 +56,7 @@
import { mapState, mapActions } from 'vuex';
import Lottie from 'lottie-web';

import { util } from '~/_helpers'
import { util } from '~/_helpers';
import { Features } from '~/_components/sections';

// convenience methods


+ 29
- 137
src/_pages/main/Layout.vue Dosyayı Görüntüle

@@ -1,6 +1,6 @@
<!-- Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ -->
<template>
<div class="container-fluid">
<div class="container-fluid" v-if="isPageAvailable">
<img src="/bubble_bkgrnd.png" alt="" class="background-image" />
<div class="content">
<Sidebar />
@@ -80,166 +80,58 @@ header {
<script>
import { mapState, mapActions } from 'vuex';
import { util } from '~/_helpers';
import { isAuthenticator, isNotAuthenticator } from '~/_store/users.module';
import { Footer, Notification, Sidebar } from '~/_components/layout';

import { Footer, Notification, Sidebar } from '~/_components/layout';
export default {
components: {
Footer,
Notification,
Sidebar,
},

data: () => ({
verifiedContacts: null,
verifiedContactRefresher: null,
accountPlan: {
currentUser: null,
name: '',
domain: '',
locale: null,
timezone: '',
plan: 'bubble',
footprint: 'Worldwide',
paymentMethodObject: {
uuid: null,
paymentMethodType: null,
paymentInfo: null,
},
sshKey: '',
forkHost: '',
syncAccount: true,
launchLock: false,
sendErrors: true,
sendMetrics: true,
},
payMethods: null,
currentUser: null,
hasPaymentMethod: false,
}),

computed: {
...mapState('users', ['policy']),
...mapState('paymentMethods', ['accountPaymentMethods']),
...mapState('system', ['configs', 'messages']),

isPageAvailable() {
return !this.configs.paymentsEnabled || this.hasPaymentMethod;
},
},

created() {
this.currentUser = util.currentUser();
this.locale = this.currentUser.locale;
},

mounted() {
this.initDefaults();
},

methods: {
...mapActions('users', ['getPolicyByUserId']),
...mapActions('paymentMethods', ['getAllAccountPaymentMethods']),

initDefaults() {
const selectedLocale =
this.currentUser !== null &&
typeof this.currentUser.locale !== 'undefined' &&
this.currentUser.locale !== null
? this.currentUser.locale
: 'detect';
if (!this.currentUser.admin) {
this.getPolicyByUserId({
userId: this.currentUser.uuid,
messages: this.messages,
errors: this.errors,
});
}
},

hasVerifiedContact(policy) {
if (policy && policy.accountContacts) {
const contacts = policy.accountContacts;
for (let i = 0; i < contacts.length; i++) {
if (contacts[i].verified && isNotAuthenticator(contacts[i]))
return true;
if (this.configs.paymentsEnabled) {
this.hasPaymentMethod = true;
}
if (this.accountPaymentMethods && this.configs.paymentsEnabled) {
const payMethods = [];
Array.from(this.accountPaymentMethods).forEach((pm) => {
if (
(typeof pm.promotion === 'undefined' ||
pm.promotion === null ||
!pm.promotion) &&
(typeof pm.deleted === 'undefined' || pm.deleted === null)
) {
payMethods.push(pm);
}
return false;
}
return false;
},
});

navigateToVerifyEmail() {
if (this.$route.path !== '/verifyEmail') {
this.$router.push('/verifyEmail');
if (payMethods.length > 0) {
this.hasPaymentMethod = true;
}
},

navigateToPaymentPage() {
if (this.$route.path !== '/payment') {
this.$router.push('/payment');
}
},

navigateToDashboard() {
if (
this.$route.path === '/payment' ||
this.$route.path === '/verifyEmail'
) {
this.$router.push('/');
}
},
}
},

watch: {
policy(p) {
this.verifiedContacts = this.hasVerifiedContact(p);
const currentUser = util.currentUser();
if (!this.verifiedContacts && !currentUser.admin) {
this.navigateToVerifyEmail();
if (this.verifiedContactRefresher === null) {
const vue = this;
const currentUser = util.currentUser();
this.verifiedContactRefresher = window.setInterval(() => {
vue.getPolicyByUserId({
userId: currentUser.uuid,
messages: vue.messages,
errors: vue.errors,
});
}, 5000);
}
} else {
const currentUser = util.currentUser();
this.getAllAccountPaymentMethods({
userId: currentUser.uuid,
messages: this.messages,
errors: this.errors,
});
if (this.verifiedContactRefresher !== null) {
window.clearInterval(this.verifiedContactRefresher);
this.verifiedContactRefresher = null;
}
}
},

accountPaymentMethods(pms, oldpms) {
if (pms && this.configs.paymentsEnabled) {
const payMethods = [];
for (let i = 0; i < pms.length; i++) {
const pm = pms[i];
if (
(typeof pm.promotion === 'undefined' ||
pm.promotion === null ||
!pm.promotion) &&
(typeof pm.deleted === 'undefined' || pm.deleted === null)
) {
payMethods.push(pm);
}
}

if (
this.accountPlan.paymentMethodObject.uuid === null &&
payMethods.length > 0
) {
this.navigateToDashboard();
} else {
this.navigateToPaymentPage();
}
}
},
methods: {
...mapActions('paymentMethods', ['getAllAccountPaymentMethods']),
...mapState('paymentMethods', ['accountPaymentMethods']),
},
};
</script>

+ 1
- 23
src/_router/index.js Dosyayı Görüntüle

@@ -91,28 +91,6 @@ export const router = new Router({
component: () => import('~/_pages/main/Layout'),
children: [
{ path: '', component: DashboardPage },
{
path: 'me/download/:uuid',
redirect: (r) => ({
path: 'me/policy',
query: { download: r.params.uuid },
}),
},
{ path: 'me/action', component: ActionPage },
{ path: 'apps', component: AppsPage },
{ path: 'app/:app', component: AppPage },
{ path: 'app/:app/config/:view', component: AppConfigPage },
{
path: 'app/:app/config/:view/:item',
component: AppConfigPage,
},
{ path: 'app/:app/view/:view', component: AppDataViewPage },
{ path: 'app/:app/site/:site', component: AppSitePage },
{
path: 'app/:app/site/:site/view/:view',
component: AppDataViewPage,
},
{ path: 'notifications', component: NotificationsPage },
{
path: 'bubble',
component: () => import('~/_pages/main/bubble/MyBubble'),
@@ -293,7 +271,7 @@ const publicPages = [
'/activate',
'/legal',

// new Pages
'/me/action',
];

router.beforeEach((to, from, next) => {


Yükleniyor…
İptal
Kaydet