Skip to content

Commit

Permalink
feat(webapp): create generic password field
Browse files Browse the repository at this point in the history
  • Loading branch information
Rotzbua committed Sep 27, 2023
1 parent 4cdd11c commit e10ce28
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 75 deletions.
91 changes: 91 additions & 0 deletions www/webapp/src/components/Field/GenericPassword.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<template>
<v-text-field
v-bind="computedProps"
v-on="$listeners"
@click:append="toggleHide()"
/>
</template>

<script>
import {mdiEye, mdiEyeOff, mdiKey} from '@mdi/js';
import {VTextField} from 'vuetify/lib/components';
export default {
name: 'GenericPassword',
extends: VTextField,
props: {
errorMessages: {
type: [String, Array],
default: () => [],
},
label: {
type: String,
required: false,
},
required: {
type: Boolean,
default: true,
},
standalone: {
type: Boolean,
default: false,
},
new: {
type: Boolean,
required: false,
},
},
data() {
return {
hide_password: true,
};
},
computed: {
computedProps() {
const icon = mdiKey;
const iconToggle = this.hide_password ? mdiEyeOff : mdiEye;
let label = 'Password';
if(!this.required) {
label += ' (Optional)';
}
if(this.new) {
label = 'New ' + label;
}
if(this.label) { // override with custom label
label = this.label;
}
const ruleDefs = {
required: v => !!v || 'Password is required.',
min: v => (v !== undefined && v.length >= 8) || 'Min 8 characters',
};
let rules = []
if(this.required) {
rules.push(ruleDefs.required)
}
if(this.new) {
rules.push(ruleDefs.min)
}
return {
...this.$props,
type: this.hide_password ? 'password' : 'text',
label: label,
autocomplete: this.new ? 'new-password' : '',
prependIcon: this.standalone ? '' : icon,
prependInnerIcon: this.standalone ? icon : '',
appendIcon: iconToggle,
flat: this.standalone,
solo: this.standalone,
outlined: true,
rules: rules,
errorMessages: this.errorMessages,
validateOnInput: true,
}
}
},
methods: {
toggleHide() {
this.hide_password = !this.hide_password;
}
},
};
</script>
29 changes: 9 additions & 20 deletions www/webapp/src/components/ResetPasswordActionHandler.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
<template>
<div>
<div class="text-center" v-if="!success">
<v-text-field
v-model="payload.new_password"
:append-icon="show ? 'mdi-eye' : 'mdi-eye-off'"
label="New password"
required
:disabled="working"
:rules="[rules.required, rules.min]"
:type="show ? 'text' : 'password'"
hint="At least 8 characters"
autocomplete="new-password"
@click:append="show = !show"
tabindex="1"
></v-text-field>
<generic-password
v-model="payload.new_password"
:autofocus="true"
:new="true"
:standalone="true"
tabindex="1"
/>
<v-btn
depressed
color="primary"
Expand All @@ -31,16 +25,11 @@

<script>
import GenericActionHandler from "./GenericActionHandler.vue"
import GenericPassword from "@/components/Field/GenericPassword.vue";
export default {
name: 'ResetPasswordActionHandler',
components: {GenericPassword},
extends: GenericActionHandler,
data: () => ({
rules: {
required: value => !!value || 'Required.',
min: v => (v !== undefined && v.length >= 8) || 'Min 8 characters',
},
show: false,
}),
};
</script>
25 changes: 9 additions & 16 deletions www/webapp/src/views/ChangeEmail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,13 @@
label="Current Email Address"
:readonly="true"
/>
<v-text-field
v-model="password"
:append-icon="show ? 'mdi-eye' : 'mdi-eye-off'"
prepend-icon="mdi-blank"
outlined
label="Password"
required
:rules="[rules.required]"
:type="show ? 'text' : 'password'"
:error-messages="password_errors"
@change="password_errors=[]"
@click:append="show = !show"
ref="password"
tabindex="1"
></v-text-field>

<generic-password
v-model="password"
ref="password"
tabindex="1"
/>

<generic-email
v-model="new_email"
:new="true"
Expand Down Expand Up @@ -82,11 +74,13 @@
import { HTTP, withWorking ,digestError} from '@/utils';
import ErrorAlert from "@/components/ErrorAlert.vue";
import GenericEmail from "@/components/Field/GenericEmail.vue";
import GenericPassword from "@/components/Field/GenericPassword.vue";
export default {
name: 'ChangeEmail',
components: {
GenericEmail,
GenericPassword,
ErrorAlert,
},
data: () => ({
Expand All @@ -102,7 +96,6 @@
/* password field */
password: '',
password_errors: [],
/* email field */
new_email: '',
Expand Down
36 changes: 9 additions & 27 deletions www/webapp/src/views/DeleteAccount.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,13 @@
label="Current Email Address"
:readonly="true"
/>
<v-text-field
v-model="password"
:append-icon="show ? 'mdi-eye' : 'mdi-eye-off'"
prepend-icon="mdi-blank"
outlined
label="Password"
required
:rules="[rules.required]"
:type="show ? 'text' : 'password'"
:error-messages="password_errors"
@change="password_errors=[]"
@click:append="show = !show"
ref="password"
tabindex="1"
></v-text-field>

<generic-password
v-model="password"
:autofocus="true"
ref="password"
tabindex="1"
/>
</v-card-text>
<v-card-actions class="justify-center">
<v-btn
Expand All @@ -75,28 +67,21 @@
import { HTTP, withWorking, digestError } from '@/utils';
import ErrorAlert from "@/components/ErrorAlert.vue";
import GenericEmail from "@/components/Field/GenericEmail.vue";
import GenericPassword from "@/components/Field/GenericPassword.vue";
export default {
name: 'DeleteAccount',
components: {GenericEmail, ErrorAlert},
components: {GenericEmail, GenericPassword, ErrorAlert},
data: () => ({
valid: false,
working: false,
done: false,
errors: [],
email: '',
rules: {
required: v => !!v || 'Required.',
},
show: false,
/* password field */
password: '',
password_errors: [],
}),
mounted() {
this.initialFocus();
},
async created() {
const self = this;
await withWorking(this.error, () => HTTP
Expand All @@ -105,9 +90,6 @@
);
},
methods: {
initialFocus() {
return this.$refs.password.focus();
},
async deleteAccount() {
if (!this.$refs.form.validate()) {
return;
Expand Down
16 changes: 4 additions & 12 deletions www/webapp/src/views/LoginPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,9 @@
:autofocus="true"
tabindex="1"
/>
<v-text-field
<generic-password
v-model="password"
label="Password"
:append-icon="hide_password ? 'mdi-eye' : 'mdi-eye-off'"
:type="hide_password ? 'password' : 'text'"
outlined
required
:rules="password_rules"
tabindex="2"
@click:append="() => (hide_password = !hide_password)"
/>
<v-layout class="justify-center">
<v-checkbox
Expand Down Expand Up @@ -85,11 +78,13 @@ import { HTTP, digestError } from '@/utils';
import ErrorAlert from "@/components/ErrorAlert.vue";
import {useUserStore} from "@/store/user";
import GenericEmail from "@/components/Field/GenericEmail.vue";
import GenericPassword from "@/components/Field/GenericPassword.vue";
export default {
name: 'LoginPage',
components: {
GenericEmail,
GenericPassword,
ErrorAlert,
},
data: () => ({
Expand All @@ -103,10 +98,7 @@ export default {
email_errors: [],
password: '',
password_rules: [
v => !!v || 'Enter your password to log in',
],
hide_password: true,
errors: [],
}),
methods: {
Expand Down

0 comments on commit e10ce28

Please sign in to comment.