177 lines
4.4 KiB
Vue
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>
|