ldc-supportweb/resources/ts/bo/components/PasswordVisibility.vue
2023-10-12 15:56:11 +02:00

124 lines
3.2 KiB
Vue

<template>
<div :class="`password-visibility-${inputId} h-100`">
<span
v-if="visible"
class="text-bg-primary reveal d-flex justify-content-center align-items-center h-100"
@click.prevent="toggleVisibility()"
type="button"
:title="__('Cacher le mot de passe')"
data-bs="tooltip"
>
<FontAwesomeIcon
icon="fas fa-eye-slash"
:aria-hidden="true"
/>
</span>
<span
v-else
class="text-bg-primary reveal d-flex justify-content-center align-items-center h-100"
@click.prevent="toggleVisibility()"
type="button"
:title="__('Dévoiler le mot de passe')"
data-bs="tooltip"
>
<FontAwesomeIcon
icon="fas fa-eye"
:aria-hidden="true"
/>
</span>
</div>
</template>
<script lang="ts">
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { Tooltip } from "bootstrap";
import { defineComponent } from "vue";
import trans from "./../../modules/trans";
export default defineComponent({
name: "PasswordVisibility",
mixins: [trans],
components: { FontAwesomeIcon },
data(): {
inputId: string;
input: HTMLInputElement;
visible: boolean;
tooltipList: HTMLButtonElement[];
} {
return {
inputId: "",
input: document.createElement("input"),
visible: false,
tooltipList: [],
};
},
computed: {},
mounted() {
const json = String(this.$attrs.json ?? "{}"),
data = JSON.parse(json);
this.inputId = data.inputId;
this.input = document.getElementById(this.inputId) as HTMLInputElement;
if (!this.input) {
throw new Error(`Cannot find input id '${this.inputId}'`);
}
if (this.input.tagName !== "INPUT") {
throw new Error(`id '${this.inputId}' is not an input`);
}
if ((this.input as HTMLInputElement).type !== "password") {
throw new Error(`id '${this.inputId}' is not an input password`);
}
this.input = this.input as HTMLInputElement;
this.$nextTick(() => {
this.updateBootstrapTooltip();
});
},
methods: {
/**
* Update password status (visible, hidden).
*/
toggleVisibility(): void {
if (this.input.type === "password") {
this.input.type = "text";
this.visible = true;
} else {
this.input.type = "password";
this.visible = false;
}
this.$nextTick(() => {
this.updateBootstrapTooltip();
});
},
/**
* Update Bootstrap tooltips.
*/
updateBootstrapTooltip() {
let newTooltipList = [].slice.call(
document.querySelectorAll(
".password-visibility-" + this.inputId + " [data-bs=\"tooltip\"]"
)
) as HTMLButtonElement[];
let tmp = newTooltipList.filter((x) => !this.tooltipList.includes(x));
tmp.map((tooltip) => {
return new Tooltip(tooltip);
});
this.closeBootstrapTooltip();
this.tooltipList = newTooltipList;
},
/**
* Close all Bootstrap tooltips.
*/
closeBootstrapTooltip() {
this.tooltipList.forEach((tooltip) => {
tooltip.blur();
Tooltip.getInstance(tooltip)?.hide();
});
},
},
});
</script>
<style lang="scss">
.reveal {
width: 52px;
}
</style>