bump ts code

This commit is contained in:
Jérémy Munsch 2024-06-19 16:28:34 +02:00
parent 1538e17a6b
commit bc18f01f3e
No known key found for this signature in database
GPG key ID: 18361AF3BFEC0FEC
11 changed files with 944 additions and 846 deletions

View file

@ -67,9 +67,9 @@ import type VueTagsInput from "@sipec/vue3-tags-input";
import { VueTagsInput as VueTagsInputCls } from "@sipec/vue3-tags-input";
import slugify from "slugify";
import { defineComponent } from "vue";
import parseLaravelErrorMessages from "./../../modules/parseLaravelErrorMessages";
import route from "./../../modules/route";
import trans from "./../../modules/trans";
import parseLaravelErrorMessages from "../../modules/parseLaravelErrorMessages";
import route from "../../modules/route";
import trans from "../../modules/trans";
export default defineComponent({
name: "BelongsToManyDropdownComponent",

File diff suppressed because it is too large Load diff

View file

@ -1,108 +1,103 @@
<template>
<WordCounter
:id="intId"
:id="id"
class="ck-word-count"
/>
<textarea
ref="textarea"
:id="intId"
:class="`input-text-auto-component ${intClass}`"
:name="intName"
:aria-describedby="intAriaDescribedby"
:placeholder="intPlaceholder"
:required="intRequired"
@input="onInput"
:id="id"
:class="`input-text-auto-component ${classPath}`"
:name="name"
:aria-describedby="ariaDescribedby"
:placeholder="placeholder"
:required="required"
@input="styleElement(checkInput())"
@blur="onBlur"
v-model="intValue"
v-model="value"
/>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import trans from "./../../modules/trans";
<script lang="ts" setup>
import { computed, nextTick, onBeforeMount, onMounted, ref, useAttrs } from "vue";
import WordCounter from "./WordCounterComponent.vue";
const textarea = ref<HTMLTextAreaElement | null>(null);
export default defineComponent({
name: "InputTextAutoComponent",
inheritAttrs: false,
mixins: [trans],
components: {
WordCounter,
},
setup() {
return { textarea };
},
beforeMount() {
if (!this.$attrs.json) {
throw new Error("this component requires json");
}
},
mounted() {
const json = String(this.$attrs.json ?? "{}"),
data = JSON.parse(json);
this.intId = String(data.id);
this.intClass = String(data.class);
this.intName = String(data.name);
this.intPlaceholder = String(data.placeholder);
this.intAriaDescribedby = String(data.ariaDescribedby);
this.intValue = String(data.value);
if (data.required) {
this.intRequired = true;
}
if (this.textarea) {
// Default input init
this.textarea.setAttribute("style", "height: 1rem;overflow-y: hidden;");
}
// * Init input
this.$nextTick(this.onInput);
},
data(): {
intId: string;
intClass: string;
intName: string;
intPlaceholder: string;
intAriaDescribedby: string;
intRequired: boolean;
intValue: string;
} {
return {
intId: "",
intClass: "",
intName: "",
intPlaceholder: "",
intAriaDescribedby: "",
intRequired: false,
intValue: "",
};
},
methods: {
onBlur() {
const el = textarea.value;
if (!el) {
throw new Error("undefined textarea element");
}
// * Remove every new line char
el.value = el.value.replace(/[\n\r]/g, "");
this.$nextTick(() => {
el.style.height = "auto";
el.style.height = `${el.scrollHeight}px`;
});
},
onInput() {
const el = textarea.value;
if (!el) {
throw new Error("undefined textarea element");
}
el.style.height = "auto";
el.style.height = `${el.scrollHeight}px`;
},
},
defineOptions({
name: "InputTextAutoComponent"
});
// * ATTRIBUTES
const attrs = useAttrs();
// * REFS
const textarea = ref<HTMLTextAreaElement|null>(null);
// * DATA
/** Hack to set the id for wordCounterComponent. */
const id = ref<string>(JSON.parse(String(attrs.json ?? "{}")).id);
const classPath = ref<string>("");
const name = ref<string>("");
const placeholder = ref<string>("");
const ariaDescribedby = ref<string>("");
const value = ref<string>("");
const required = ref<boolean>(true);
// * COMPUTED
const isUsedWithProps = computed<boolean>(() => attrs.json === undefined);
onBeforeMount(() => {
if (isUsedWithProps.value) {
throw new Error("this component requires json");
}
});
// * LIFECYCLE
onMounted(() => {
const json = String(attrs.json ?? "{}"),
data = JSON.parse(json);
if (!isUsedWithProps.value) {
id.value = String(data.id);
classPath.value = String(data.class);
name.value = String(data.name);
placeholder.value = String(data.placeholder);
ariaDescribedby.value = String(data.ariaDescribedby);
value.value = String(data.value);
required.value = data.required;
textarea.value?.setAttribute("style", "height:1rem;overflow-y:hidden;");
}
nextTick(() => {
styleElement(checkInput());
});
});
// * METHODS
/** When the textarea get the focus. */
function onBlur() {
const el = checkInput();
/** Remove every new line char */
el.value = el.value.replace(/[\n\r]/g, "");
nextTick(() => {
styleElement(el);
});
}
/** Check if the element is an HTMLTextAreaElement. */
function checkInput(): HTMLTextAreaElement {
const el = textarea.value;
if (!el) {
throw new Error("undefined textarea element");
}
return el;
}
/** Style the textarea element. */
function styleElement(el: HTMLTextAreaElement): void {
el.style.height = "auto";
el.style.height = `${el.scrollHeight}px`;
}
</script>
<style lang="scss">
<style lang="scss" scopped>
.input-text-auto-component {
resize: none;
}

View file

@ -1,26 +1,36 @@
<template>
<button
ref="passwordVisibility"
@click.prevent="toggleVisibility()"
@keydown="keydown"
:class="`btn btn-primary rounded-0 rounded-end password-visibility-${inputId} h-100`"
:class="`btn btn-primary rounded-0 rounded-end password-visibility password-visibility-${id} h-100 border-0 p-0 overflow-hidden`"
:aria-pressed="visible"
>
<span
class="text-bg-primary reveal d-flex justify-content-center align-items-center h-100"
:class="{
'text-bg-primary reveal d-flex justify-content-center align-items-center h-100': true,
'd-none': visible
}"
type="button"
:title="visible ? __('vue.PasswordVisibility.hide') : __('vue.PasswordVisibility.show')"
:title="trans.methods.__('vue.PasswordVisibility.hide')"
data-bs-toggle="tooltip"
>
<FontAwesomeIcon
v-if="visible"
icon="fas fa-eye-slash"
:aria-hidden="true"
/>
</span>
<span
ref="passwordVisibilitySpan"
:class="{
'text-bg-primary reveal d-flex justify-content-center align-items-center h-100': true,
'd-none': !visible
}"
type="button"
:title="trans.methods.__('vue.PasswordVisibility.show')"
data-bs-toggle="tooltip"
>
<FontAwesomeIcon
v-else
icon="fas fa-eye"
:aria-hidden="true"
/>
@ -28,84 +38,85 @@
</button>
</template>
<script lang="ts">
<script lang="ts" setup>
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { defineComponent } from "vue";
import bsTooltips from "./../../modules/bsTooltips";
import trans from "./../../modules/trans";
import { onMounted, ref, useAttrs } from "vue";
import { Tooltips } from "../../modules/bsTooltips";
import trans from "../../modules/trans";
export default defineComponent({
name: "PasswordVisibility",
mixins: [bsTooltips, 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.initTooltips();
});
},
methods: {
keydown(e:KeyboardEvent):void {
if (
e.key === " " ||
e.code === "Space" ||
e.keyCode === 32 ||
e.key === "Enter" ||
e.code === "Enter" ||
e.keyCode === 13
) {
this.toggleVisibility();
e.preventDefault();
}
},
/**
* 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.initTooltips();
});
},
},
defineOptions({
name: "PasswordVisibility"
});
// * ATTRIBUTES
const attrs = useAttrs();
// * REFS
const passwordVisibility = ref<HTMLButtonElement|null>(null);
// * DATA
const id = ref<string>("");
const input = ref<HTMLInputElement>(document.createElement("input"));
const visible = ref<boolean>(true);
const tooltips = ref<Tooltips | null>(null);
// * LIFECYCLE
onMounted(() => {
const json = String(attrs.json ?? "{}"),
data = JSON.parse(json);
id.value = data.id;
input.value = document.getElementById(id.value) as HTMLInputElement;
if (!input.value) {
throw new Error(`Cannot find input id '${id.value}'`);
}
if (input.value.tagName !== "INPUT") {
throw new Error(`id '${id.value}' is not an input`);
}
if ((input.value as HTMLInputElement).type !== "password") {
throw new Error(`id '${id.value}' is not an input password`);
}
initTooltips();
});
// * METHODS
/** Set event on key down. */
function keydown(e: KeyboardEvent): void {
if (
e.key === " " ||
e.code === "Space" ||
e.keyCode === 32 ||
e.key === "Enter" ||
e.code === "Enter" ||
e.keyCode === 13
) {
toggleVisibility();
e.preventDefault();
}
}
/** Update password status (visible, hidden). */
function toggleVisibility(): void {
input.value.type = (input.value.type === "password") ? "text" : "password";
visible.value = (input.value.type === "password") ? true : false;
}
/** Initialise all tooltips in the component. */
function initTooltips(): void {
setTimeout(() => {
tooltips.value = Tooltips.make({
type: "dom",
elements: passwordVisibility.value!.querySelectorAll("[data-bs-toggle=\"tooltip\"]")
});
}, 500);
}
</script>
<style lang="scss">
.reveal {
<style lang="scss" scopped>
.password-visibility {
border-top-right-radius: 0 !important;
}
.password-visibility .reveal {
width: 52px;
}
</style>

View file

@ -11,7 +11,7 @@
<script lang="ts">
import { defineComponent } from "vue";
import trans from "./../../modules/trans";
import trans from "../../modules/trans";
export default defineComponent({
name: "WordCounterComponent",
@ -106,8 +106,6 @@ export default defineComponent({
<style lang="scss">
#word-counter + input[type="text"],
.word-counter + input[type="text"],
#word-counter + input[type="url"],
.word-counter + input[type="url"],
#word-counter + textarea,
.word-counter + textarea,
#word-counter-varchar + textarea,

View file

@ -1,6 +1,6 @@
import axios from "axios";
import * as bootstrap from "bootstrap";
import bsTooltips from "./../../modules/bsTooltips";
import { Tooltips } from "./../../modules/bsTooltips";
/**
* We'll load the axios HTTP library which allows us to easily issue requests
@ -18,4 +18,4 @@ axios.defaults.headers.common = {
window.axios = axios;
window.bootstrap = bootstrap;
bsTooltips.methods.initTooltips();
Tooltips.make();

View file

@ -1,6 +1,6 @@
import axios from "axios";
import * as bootstrap from "bootstrap";
import bsTooltips from "./../../modules/bsTooltips";
import { Tooltips } from "./../../modules/bsTooltips";
/**
* We'll load the axios HTTP library which allows us to easily issue requests
@ -18,4 +18,4 @@ axios.defaults.headers.common = {
window.axios = axios;
window.bootstrap = bootstrap;
bsTooltips.methods.initTooltips();
Tooltips.make();

View file

@ -69,6 +69,7 @@ declare global {
type LaravelModelList = ModelList;
type LaravelPaginator = Paginator;
type LaravelPaginatorLink = PaginatorLink;
type ValueOf<T> = T[keyof T];
type Enum = EnumInterface;

View file

@ -1,45 +1,114 @@
import type * as bootstrap from "bootstrap";
import { Tooltip } from "bootstrap";
let tooltips: Array<bootstrap.Tooltip> = [];
export default {
methods: {
/**
* Initialize all Bootstrap tooltips.
*/
initTooltips() {
this.disableBootstrapTooltip();
tooltips = [].slice
.call(document.querySelectorAll("[data-bs-toggle=\"tooltip\"]"))
.map(function (tooltipTriggerEl) {
return new window.bootstrap.Tooltip(tooltipTriggerEl, {
customClass: "large-tooltip",
delay: {
show: 1250,
hide: 0,
},
});
});
type ConstructorTypeParent = "parent";
type ConstructorTypeDom = "dom";
interface ParentSelectorTooltips {
type: ConstructorTypeParent
/** The parent element that contains Dom elements for which tooltips shall be created. */
parentSelector: string;
}
interface DomProvidedTooltips {
type: ConstructorTypeDom;
/** Dom elements for which tooltips shall be created. */
elements: HTMLElement | NodeListOf<HTMLElement>;
}
interface TooltipsOptions {
/** Tooltip options. */
options?: Partial<Tooltip.Options>|null|undefined;
}
export type TooltipsConstructor = TooltipsOptions & (ParentSelectorTooltips|DomProvidedTooltips);
export class Tooltips {
/** BS tooltips instances */
private tooltips: Array<Tooltip> = [];
/** The parent element that contains Dom elements for which tooltips shall be created. */
private parentSelector: string | null = null;
/** Dom elements for which tooltips shall be created. */
private elements: Array<HTMLElement> = [];
/** Tooltip default options. */
private static defaultOptions: Partial<Tooltip.Options> = {
delay: {
show: 1250,
hide: 0,
},
/**
* Disable all Bootstrap tooltips.
*/
disableBootstrapTooltip() {
tooltips.forEach((tooltip) => {
tooltip.disable();
tooltip.hide();
});
},
/**
* Close all Bootstrap tooltips.
*/
closeBootstrapTooltip() {
[].slice
.call(document.querySelectorAll("[data-bs-toggle=\"tooltip\"]"))
.forEach((tooltip: HTMLElement) => {
tooltip.blur();
window.bootstrap.Tooltip.getInstance(tooltip)?.hide();
});
},
},
};
};
/** Tooltip options. */
private options: Partial<Tooltip.Options> = {};
/**
* @param parentSelector
* @param options Tooltip options.
*/
constructor(params: TooltipsConstructor) {
if (params.type === "parent") {
this.parentSelectorConstructor(params);
}
if (params.type === "dom") {
this.domPrividedTooltipsContructor(params);
}
}
public static make(params: TooltipsConstructor = { type: "parent", parentSelector: "body"}
) {
const fullParams = { ...{ type: "parent", options: {} }, ...params };
return new Tooltips(fullParams);
}
private parentSelectorConstructor({ parentSelector, options }: TooltipsOptions & ParentSelectorTooltips) {
this.parentSelector = parentSelector;
this.options = { ...Tooltips.defaultOptions, ...options };
this.initTooltips();
}
private domPrividedTooltipsContructor({ elements, options }: TooltipsOptions & DomProvidedTooltips) {
if (elements instanceof HTMLElement) {
this.elements = [elements];
} else {
this.elements = Array.from(elements);
}
this.options = { ...Tooltips.defaultOptions, ...options };
this.initTooltips();
}
/**
* Close all Bootstrap tooltips and reinstanciate them.
*/
public refreshTooltips(): void {
this.closeBootstrapTooltip();
this.initTooltips();
}
/**
* Close all Bootstrap tooltips for ever.
*/
public closeBootstrapTooltip(): void {
this.tooltips.forEach((tooltip) => {
tooltip.hide();
// * Prevent pending tooltips beeing shown after we asked to hide them
tooltip.disable();
});
}
/**
* Initialize tooltips
*/
private initTooltips() {
this.closeBootstrapTooltip();
/** data-bs-toggle tooltips elements */
const elements = this.parentSelector ? [].slice
.call(document.querySelectorAll(`${this.parentSelector} [data-bs-toggle="tooltip"]`)) :
this.elements;
this.tooltips = elements.map((tooltipTriggerEl) => {
return new Tooltip(tooltipTriggerEl, this.options);
});
}
}

View file

@ -38,9 +38,9 @@ export default {
allErrors: Record<string, Array<string>> = {}
): string | null {
let errorList = [] as Array<string>;
Object.keys(allErrors).filter((value, index) => {
Object.keys(allErrors).filter((value) => {
if (value == inputName) {
errorList = allErrors[index];
errorList = allErrors[inputName];
}
});
return errorList.length

View file

@ -16,7 +16,7 @@ const route = {
routeName: string,
parameters: Record<
string,
string | number | Array<string | number>
string | number | null | undefined | Array<string | number>
> = {},
keepActualQueries: boolean = false,
keepActualHashes: boolean = false