summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components/Global/InputPasswordToggle.vue57
-rw-r--r--src/locales/en.json3
-rw-r--r--src/views/AccessControl/LocalUserManagement/ModalUser.vue80
3 files changed, 103 insertions, 37 deletions
diff --git a/src/components/Global/InputPasswordToggle.vue b/src/components/Global/InputPasswordToggle.vue
new file mode 100644
index 00000000..8c522525
--- /dev/null
+++ b/src/components/Global/InputPasswordToggle.vue
@@ -0,0 +1,57 @@
+<template>
+ <div class="input-password-toggle-container">
+ <slot></slot>
+ <b-button
+ :aria-label="$t('ariaLabels.showPassword')"
+ variant="link"
+ :class="{ isVisible: isVisible }"
+ @click="toggleVisibility"
+ >
+ <icon-view-off v-if="isVisible" aria-hidden="true" />
+ <icon-view v-else aria-hidden="true" />
+ </b-button>
+ </div>
+</template>
+
+<script>
+import IconView from '@carbon/icons-vue/es/view/20';
+import IconViewOff from '@carbon/icons-vue/es/view--off/20';
+
+export default {
+ name: 'InputPasswordToggle',
+ components: { IconView, IconViewOff },
+ data() {
+ return {
+ isVisible: false
+ };
+ },
+ methods: {
+ toggleVisibility() {
+ const firstChild = this.$children[0];
+ const inputEl = firstChild ? firstChild.$el : null;
+
+ this.isVisible = !this.isVisible;
+
+ if (inputEl.nodeName === 'INPUT') {
+ inputEl.type = this.isVisible ? 'text' : 'password';
+ }
+ }
+ }
+};
+</script>
+
+<style lang="scss" scoped>
+.input-password-toggle-container {
+ position: relative;
+}
+
+.btn {
+ position: absolute;
+ right: 0;
+ top: 0;
+
+ svg {
+ margin-left: 0;
+ }
+}
+</style>
diff --git a/src/locales/en.json b/src/locales/en.json
index d8660027..db3a87bf 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -6,6 +6,9 @@
"on": "on",
"off": "off"
},
+ "ariaLabels": {
+ "showPassword": "Show password as plain text. Note: this will visually expose your password on the screen."
+ },
"login": {
"language": {
"label": "Language"
diff --git a/src/views/AccessControl/LocalUserManagement/ModalUser.vue b/src/views/AccessControl/LocalUserManagement/ModalUser.vue
index d156c3da..448276b5 100644
--- a/src/views/AccessControl/LocalUserManagement/ModalUser.vue
+++ b/src/views/AccessControl/LocalUserManagement/ModalUser.vue
@@ -77,48 +77,52 @@
<!-- TODO: Should be dynamic values -->
Password must between 8 – 20 characters
</b-form-text>
- <b-form-input
- id="password"
- v-model="form.password"
- type="password"
- aria-describedby="password-help-block"
- :state="getValidationState($v.form.password)"
- @input="$v.form.password.$touch()"
- />
- <b-form-invalid-feedback role="alert">
- <template v-if="!$v.form.password.required">
- Field required
- </template>
- <template
- v-if="
- !$v.form.password.minLength || !$v.form.password.maxLength
- "
- >
- Length must be between 8 – 20 characters
- </template>
- </b-form-invalid-feedback>
+ <input-password-toggle>
+ <b-form-input
+ id="password"
+ v-model="form.password"
+ type="password"
+ aria-describedby="password-help-block"
+ :state="getValidationState($v.form.password)"
+ @input="$v.form.password.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.password.required">
+ Field required
+ </template>
+ <template
+ v-if="
+ !$v.form.password.minLength || !$v.form.password.maxLength
+ "
+ >
+ Length must be between 8 – 20 characters
+ </template>
+ </b-form-invalid-feedback>
+ </input-password-toggle>
</b-form-group>
<b-form-group
label="Confirm user password"
label-for="password-confirmation"
>
- <b-form-input
- id="password-confirmation"
- v-model="form.passwordConfirmation"
- type="password"
- :state="getValidationState($v.form.passwordConfirmation)"
- @input="$v.form.passwordConfirmation.$touch()"
- />
- <b-form-invalid-feedback role="alert">
- <template v-if="!$v.form.passwordConfirmation.required">
- Field required
- </template>
- <template
- v-else-if="!$v.form.passwordConfirmation.sameAsPassword"
- >
- Passwords do not match
- </template>
- </b-form-invalid-feedback>
+ <input-password-toggle>
+ <b-form-input
+ id="password-confirmation"
+ v-model="form.passwordConfirmation"
+ type="password"
+ :state="getValidationState($v.form.passwordConfirmation)"
+ @input="$v.form.passwordConfirmation.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.passwordConfirmation.required">
+ Field required
+ </template>
+ <template
+ v-else-if="!$v.form.passwordConfirmation.sameAsPassword"
+ >
+ Passwords do not match
+ </template>
+ </b-form-invalid-feedback>
+ </input-password-toggle>
</b-form-group>
</b-col>
</b-row>
@@ -145,8 +149,10 @@ import {
requiredIf
} from 'vuelidate/lib/validators';
import VuelidateMixin from '../../../components/Mixins/VuelidateMixin.js';
+import InputPasswordToggle from '../../../components/Global/InputPasswordToggle';
export default {
+ components: { InputPasswordToggle },
mixins: [VuelidateMixin],
props: {
user: {