ldc-legaulois/resources/ts/bo/components/MainMenuNodeEditor.vue
2024-04-19 12:23:01 +02:00

177 lines
4.4 KiB
Vue

<template>
<!-- NODE PROPS EDITOR -->
<fieldset class="main-menu-node-editor-component container-fluid p-4 border mb-3">
<legend>
<span class="fs-5">{{ trans.methods.__("Modification d'un noeud") }}</span>
<button
class="btn btn-sm btn-dark float-end mt-2"
:title="trans.methods.__('Fermer la modification')"
@click.prevent="closeEditor"
>
<FontAwesomeIcon
icon="fa fa-close"
/>
</button>
</legend>
<!-- NODE TYPE -->
<div class="mb-3 row">
<label
for="type"
class="col-sm-2 col-form-label"
>
{{ trans.methods.__("Type de Noeud") }}
</label>
<div class="col-sm-4">
<input
type="text"
class="form-control"
:value="props.enum.label"
disabled
>
</div>
</div>
<!-- Menu Name -->
<div
class="mb-3 row"
>
<label
for="type"
class="col-sm-6 col-form-label"
>
{{ trans.methods.__("Titre du noeud principal affiché dans le menu") }}
</label>
<div class="col input-group">
<input
type="text"
class="form-control"
:value="menuNode.title"
@blur="menuNode.title = ($event.target as HTMLInputElement).value"
>
</div>
</div>
<!-- ROUTE NAME -->
<div
v-if="props.enum.value !== MenuNodeTypeEnum.link"
class="mb-3 row"
>
<label
for="type"
class="col-sm-2 col-form-label"
>
{{ trans.methods.__("Route") }}
</label>
<div class="col input-group">
<input
type="text"
class="form-control"
:value="route.methods.route(String(menuNode.link.routeName))"
disabled
>
<input
type="text"
class="form-control"
:value="menuNode.link.routeName"
disabled
>
</div>
</div>
<!-- URL -->
<div
v-else
class="mb-3 row"
>
<label
for="type"
class="col-sm-2 col-form-label"
>
{{ trans.methods.__("Url") }}
</label>
<div class="col input-group">
<input
ref="urlInput"
type="text"
class="form-control"
:value="String(menuNode.link.url)"
@blur="saveUrl(($event.target as HTMLInputElement | null)!.value)"
>
</div>
<small
v-if="!urlIsValid"
class="d-block text-danger"
>{{ trans.methods.__("L'url saisie n'est pas valide") }}</small>
</div>
</fieldset>
</template>
<script lang="ts" setup>
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { defineOptions, onMounted, ref, watch, type PropType } from "vue";
import route from "../../modules/route";
import trans from "../../modules/trans";
import type { MenuNodeInterface } from "../../types/models/MenuNode";
import { MenuNodeTypeEnum } from "../enums";
import MainMenuNodeDataEditor from "./MainMenuNodeDataEditor.vue";
defineOptions({
name: "MainMenuNodeEditor",
components: {MainMenuNodeDataEditor}
});
// * EMITS
const emits = defineEmits<{
closeEditor: [],
updatedNode: [menuNode: MenuNodeInterface],
}>();
// * ATTRIBUTES
// const attrs = useAttrs();
// * PROPS
const props = defineProps({
menuNode: {
type: Object as PropType<MenuNodeInterface>,
required: true
},
enum: {
type: Object as PropType<Enum>,
required: true
}
});
// * DATA
const menuNode = ref<MenuNodeInterface>(Object.assign({}, props.menuNode));
const urlIsValid = ref<boolean>(true);
// * LIFECYCLE
onMounted(() => {
urlIsValid.value = isUrlValid(String(menuNode.value.link.url));
});
watch(menuNode, (newValue) => {
emits("updatedNode", newValue);
}, { deep: true });
// * REFS
const urlInput = ref<HTMLInputElement|null>(null);
// * METHODS
function saveUrl(newUrl: string): void {
urlIsValid.value = isUrlValid(newUrl);
menuNode.value.link.url = urlInput.value!.value;
}
function closeEditor(): void {
emits("closeEditor");
}
function isUrlValid(url: string):boolean {
const regex = RegExp("(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+@]*)*(\\?[;&a-z\\d%_.~+=-@]*)?(\\#[-a-z\\d_@]*)?$", "i");
return url.match(regex)?.[0] !== undefined;
}
</script>
<style lang="scss" scoped>
.main-menu-node-editor-component {
max-height: 30rem;
}
</style>