Kaynağa Gözat

Integrate Login API for new login page (#22)

Merge branch 'master' into feat/ui-layout

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

feat: integrate api for new login page

feat: implement responsive header

feat: implement checkbox

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

fix: checkbox event issue

feat: implement register page

feat: implement registration page

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

feat: implement UI for forgot-password

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

feat: implement new login page

feat: implement input shared component

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

feat: implement auth header

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

capitalize filename

fix: webpack config to add output default url

Merge branch 'master' into feat/ui-layout

Merge branch 'master' into feat/ui-layout

feat: integrate lazy loading and new page structure

feat: use different layout for new Pages

Co-authored-by: jonathan <jonathan@noreply.git.bubblev.org>
Co-authored-by: Tyler <everdev0923@gmail.com>
Co-authored-by: Jonathan Cobb <jonathan@kyuss.org>
Reviewed-on: https://git.bubblev.org/bubblev/bubble-web/pulls/22
pull/32/head
Tyler Chen 4 yıl önce
committed by jonathan
ebeveyn
işleme
7dba5df011
6 değiştirilmiş dosya ile 219 ekleme ve 13 silme
  1. +10
    -0
      package-lock.json
  2. +2
    -0
      package.json
  3. +0
    -7
      src/_components/shared/Button.vue
  4. +202
    -4
      src/_pages/auth/Login.vue
  5. +0
    -2
      src/_router/index.js
  6. +5
    -0
      src/_scss/components/_form.scss

+ 10
- 0
package-lock.json Dosyayı Görüntüle

@@ -7677,6 +7677,11 @@
"resolved": "https://registry.npmjs.org/vue-select/-/vue-select-3.10.5.tgz",
"integrity": "sha512-32kJNHE9FqV2RzuIfwAYHny40+EltZjf86Jf4cIHc0QUy2/yAr0PM7cET1MBJe+puJdYrItGTwnmTC4I9gKLWg=="
},
"vue-spinner": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/vue-spinner/-/vue-spinner-1.0.4.tgz",
"integrity": "sha512-GNG2F+8BLX201JT/jUX+84Gsi3ZteVQwt9K7mues3ts9FcQ95dGn7uu6a5ndSxdYYUEzfh1KngZiOE0u+l4itA=="
},
"vue-style-loader": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",
@@ -7703,6 +7708,11 @@
"integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=",
"dev": true
},
"vuelidate": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.7.5.tgz",
"integrity": "sha512-GAAG8QAFVp7BFeQlNaThpTbimq3+HypBPNwdkCkHZZeVaD5zmXXfhp357dcUJXHXTZjSln0PvP6wiwLZXkFTwg=="
},
"vuex": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.1.1.tgz",


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

@@ -22,6 +22,8 @@
"vue-datetime": "^1.0.0-beta.11",
"vue-router": "^3.0.6",
"vue-select": "^3.4.0",
"vue-spinner": "^1.0.4",
"vuelidate": "^0.7.5",
"vuex": "^3.1.1"
},
"devDependencies": {


+ 0
- 7
src/_components/shared/Button.vue Dosyayı Görüntüle

@@ -1,7 +1,6 @@
<template>
<button
v-bind="$attrs"
@click="click($event)"
:class="{
round: round,
block: block,
@@ -118,11 +117,5 @@ export default {
};
},
},

methods: {
click(event) {
this.$emit('click', event);
},
},
};
</script>

+ 202
- 4
src/_pages/auth/Login.vue Dosyayı Görüntüle

@@ -7,25 +7,127 @@
{{ messages.login_blurb }}
</h4>

<form class="auth-form">
<form class="auth-form" @submit.prevent="submit">
<h4
v-if="submitted && errors.has('approvalToken')"
class="invalid-feedback d-block"
>
{{ errors.first('approvalToken') }}
</h4>

<div class="form-group">
<Input
class="form-control"
:class="{
'is-invalid': submitted && emailErrors && emailErrors.length,
}"
v-model="email"
@input="$v.email.$touch()"
:placeholder="messages.field_email_hint"
/>
<span
class="form-error"
v-if="submitted && emailErrors && emailErrors.length"
>
{{ emailErrors.join(', ') }}
</span>
<div
v-if="submitted && errors.has('account')"
class="invalid-feedback d-block"
>
{{ errors.first('account') }}
</div>
<div
v-if="submitted && errors.has('name')"
class="invalid-feedback d-block"
>
{{ errors.first('name') }}
</div>
</div>
<div class="form-group">
<Input
class="form-control"
type="password"
:class="{
'is-invalid': submitted && passwordErrors && passwordErrors.length,
}"
v-model="password"
@input="$v.password.$touch()"
:placeholder="messages.field_label_password"
/>
<span
class="form-error"
v-if="submitted && passwordErrors && passwordErrors.length"
>
{{ passwordErrors.join(', ') }}
</span>
<div
v-if="submitted && errors.has('password')"
class="invalid-feedback d-block"
>
{{ errors.first('password') }}
</div>
</div>

<div class="form-group" v-if="showTotp">
<Input
class="form-control"
:class="{
'is-invalid': submitted && totpErrors && totpErrors.length,
}"
v-model="totpToken"
@input="$v.totpToken.$touch()"
:placeholder="messages.field_label_totp_code"
/>
<span
class="form-error"
v-if="submitted && totpErrors && totpErrors.length"
>
{{ totpErrors.join(', ') }}
</span>
<div
v-if="submitted && errors.has('totpToken')"
class="invalid-feedback d-block"
>
{{ errors.first('totpToken') }}
</div>
</div>
<div
class="form-group"
v-if="
configs &&
configs.locked === true &&
(configs.launchLock === null || configs.launchLock)
"
>
<Input
class="form-control"
:class="{
'is-invalid':
submitted && unlockKeyErrors && unlockKeyErrors.length,
}"
v-model="unlockKey"
@input="$v.unlockKey.$touch()"
:placeholder="messages.field_label_unlock_key"
/>
<span
class="form-error"
v-if="submitted && unlockKeyErrors && unlockKeyErrors.length"
>
{{ unlockKeyErrors.join(', ') }}
</span>
<div
v-if="submitted && errors.has('unlockKey')"
class="invalid-feedback d-block"
>
{{ errors.first('unlockKey') }}
</div>
</div>

<router-link to="/new_pages/forgot-password">
{{ messages.button_label_forgotPassword }}
</router-link>
<Button color="default" class="auth-form-submit">
<Button color="default" class="auth-form-submit" @click="submit">
{{ messages.button_label_sign_in }}
</Button>
<p
@@ -51,7 +153,9 @@
</style>

<script>
import { mapState } from 'vuex';
import { mapState, mapActions } from 'vuex';
import { validationMixin } from 'vuelidate';
import { required, email, minLength } from 'vuelidate/lib/validators';

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

@@ -61,15 +165,109 @@ export default {
Input,
},

mixins: [validationMixin],
validations: {
email: { required, email },
password: { required, minLength: minLength(8) },
},

data() {
return {
email: '',
password: '',
totpToken: null,
unlockKey:
this.$route.query && this.$route.query.k ? this.$route.query.k : null,
showTotp: false,
submitted: false,
};
},

created() {
this.loadSystemConfigs();
},

computed: {
...mapState('system', ['messages']),
...mapState('account', [
'status',
'loginError',
'resetPasswordMessageSent',
]),
...mapState('system', ['configs', 'messages']),

emailErrors() {
const errors = [];
if (!this.$v.email.$dirty) return errors;
!this.$v.email.email && errors.push(this.messages['err.email.invalid']);
!this.$v.email.required &&
errors.push(this.messages['err.email.required']);
return errors;
},

passwordErrors() {
const errors = [];
if (!this.$v.password.$dirty) return errors;
!this.$v.password.minLength &&
errors.push(this.messages['err.password.tooShort']);
!this.$v.password.required &&
errors.push(this.messages['err.password.required']);
return errors;
},

totpErrors() {
const errors = [];
if (!this.$v.totpToken.$dirty) return errors;
!this.$v.totpToken.required &&
errors.push(this.messages['err.totpToken.invalid']);
return errors;
},

unlockKeyErrors() {
const errors = [];
if (!this.$v.unlockKey.$dirty) return errors;
!this.$v.unlockKey.required &&
errors.push(this.messages['err.unlock.required']);
return errors;
},
},

methods: {
...mapActions('account', ['login', 'logout']),
...mapActions('system', ['loadSystemConfigs']),

submit() {
this.errors.clear();
this.$v.$touch();
this.submitted = true;
if (!this.$v.$invalid) {
this.login({
user: {
name: this.email,
password: this.password,
totpToken: this.totpToken,
unlockKey: this.unlockKey,
},
systemConfigs: this.configs,
messages: this.messages,
errors: this.errors,
});
}
},
},

watch: {
loginError(e) {
if (
(e && e === 'err_totpToken_required') ||
e === 'err_totpToken_invalid'
) {
this.showTotp = true;
}
},

error(e) {
console.log('watch error', e);
},
},
};
</script>

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

@@ -214,7 +214,6 @@ router.beforeEach((to, from, next) => {
publicPages.filter((p) => to.path.startsWith(p)).length === 0;
const user = util.currentUser();

console.log('test', to.path, authRequired);
if (authRequired) {
// redirect to login page if not logged in and trying to access a restricted page
if (!user) {
@@ -225,6 +224,5 @@ router.beforeEach((to, from, next) => {
// redirect to home page if not admin and trying to access an admin page
if (to.path.startsWith('/admin') && user.admin !== true) return next('/');
}
console.log('next');
next();
});

+ 5
- 0
src/_scss/components/_form.scss Dosyayı Görüntüle

@@ -50,3 +50,8 @@ $form-border-radius: 2px;
width: 100%;
background-color: $border-color;
}

.form-error {
font-size: 12px;
color: red;
}

Yükleniyor…
İptal
Kaydet