Bo dynamic menu ok
This commit is contained in:
parent
4a8d615387
commit
eb2afed1a7
8 changed files with 212 additions and 107 deletions
|
|
@ -27,14 +27,24 @@ class UpdateMenuNodeDataRequest extends FormRequest
|
|||
*/
|
||||
public function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'text' => str($this->input('text'))->value(),
|
||||
'link_target' => $this->boolean('link_target'),
|
||||
'link_status' => $this->boolean('link_status'),
|
||||
'picture_status' => $this->boolean('picture_status'),
|
||||
]);
|
||||
$this->mergePicture('picture');
|
||||
$this->mergePicture('background_picture');
|
||||
if ($this->has('text')) {
|
||||
$this->merge(['text' => str($this->input('text'))->value()]);
|
||||
}
|
||||
if ($this->has('link_target')) {
|
||||
$this->merge(['link_target' => $this->boolean('link_target')]);
|
||||
}
|
||||
if ($this->has('link_status')) {
|
||||
$this->merge(['link_status' => $this->boolean('link_status')]);
|
||||
}
|
||||
if ($this->has('picture_status')) {
|
||||
$this->merge(['picture_status' => $this->boolean('picture_status')]);
|
||||
}
|
||||
if ($this->has('picture')) {
|
||||
$this->mergePicture('picture');
|
||||
}
|
||||
if ($this->has('background_picture')) {
|
||||
$this->mergePicture('background_picture');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -45,24 +55,22 @@ class UpdateMenuNodeDataRequest extends FormRequest
|
|||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'title' => 'required|string|min:4|max:255',
|
||||
'text' => 'present|string|max:255',
|
||||
'link_url' => 'string|max:255',
|
||||
'link_title' => 'required|string|between:3,255',
|
||||
'link_target' => 'required|boolean',
|
||||
'link_status' => 'string|boolean',
|
||||
'picture' => 'string|max:255',
|
||||
'picture_alt' => 'string|between:3,255',
|
||||
'picture_title' => 'string|between:3,255',
|
||||
'picture_status' => 'string|boolean',
|
||||
'background_picture' => 'string|max:255',
|
||||
'background_picture_alt' => 'string|between:3,255',
|
||||
'background_picture_title' => 'string|between:3,255',
|
||||
'title' => 'sometimes|required|string|min:4|max:255',
|
||||
'text' => 'sometimes|required|string|max:255',
|
||||
'link_url' => 'sometimes|required|string|max:255',
|
||||
'link_title' => 'sometimes|required|string|between:3,255',
|
||||
'link_target' => 'sometimes|present|boolean',
|
||||
'link_status' => 'sometimes|present|boolean',
|
||||
'picture_alt' => 'sometimes|required|string|between:3,255',
|
||||
'picture_title' => 'sometimes|required|string|between:3,255',
|
||||
'picture_status' => 'sometimes|required|string|boolean',
|
||||
'background_picture_alt' => 'sometimes|required|string|between:3,255',
|
||||
'background_picture_title' => 'sometimes|required|string|between:3,255',
|
||||
];
|
||||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', 180, 228, 180, 228),
|
||||
$this->pictureRules('background_picture', 500, 231, 500, 231),
|
||||
$this->pictureRules('picture', 180, 228, 180, 228, nullable: false, sometimes: true),
|
||||
$this->pictureRules('background_picture', 500, 231, 500, 231, nullable: false, sometimes: true),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ trait HasPicture
|
|||
* @param integer|null $size
|
||||
* @param string|null $requiredWith
|
||||
* @param string|null $requiredWithout
|
||||
* @param boolean $sometimes
|
||||
* @return array
|
||||
*/
|
||||
public function pictureRules(
|
||||
|
|
@ -61,6 +62,7 @@ trait HasPicture
|
|||
?int $size = null,
|
||||
?string $requiredWith = null,
|
||||
?string $requiredWithout = null,
|
||||
bool $sometimes = false,
|
||||
): array {
|
||||
$dimensions = (object)[
|
||||
'minWidth' => $minWidth ?? $this->minWidth,
|
||||
|
|
@ -70,6 +72,7 @@ trait HasPicture
|
|||
];
|
||||
return [
|
||||
$name => [
|
||||
$sometimes ? 'sometimes' : '',
|
||||
!$nullable ? 'required' : 'nullable',
|
||||
(strlen($requiredWith)) ? 'required_with:' . $requiredWith : '',
|
||||
(strlen($requiredWithout)) ? 'required_without:' . $requiredWithout : '',
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@
|
|||
<script setup lang="ts">
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
import Cropper from "cropperjs";
|
||||
import { computed, defineEmits, defineOptions, nextTick, onMounted, reactive, ref, useAttrs, watch } from "vue";
|
||||
import { computed, defineOptions, nextTick, onMounted, reactive, ref, useAttrs, watch } from "vue";
|
||||
import { Tooltips } from "./../../modules/bsTooltips";
|
||||
import trans from "./../../modules/trans";
|
||||
|
||||
|
|
@ -442,8 +442,6 @@ type CropperParameters = {
|
|||
scaleY: MirrorScale
|
||||
};
|
||||
|
||||
type ValueOf<T> = T[keyof T];
|
||||
|
||||
// * CONSTANTS
|
||||
const UNITS = [
|
||||
"byte",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
<template>
|
||||
<div class="container-fluid main-menu-component my-3">
|
||||
<fieldset
|
||||
class="container-fluid main-menu-component my-3"
|
||||
:disabled="loading"
|
||||
>
|
||||
<div class="row justify-content-start mb-3">
|
||||
<div class="col">
|
||||
<span class="h5">{{ trans.methods.__('Réorganisez le menu principal comme vous le souhaitez ou ajoutez un lien.') }}</span>
|
||||
|
|
@ -11,7 +14,7 @@
|
|||
<div class="col col-xl-4 my-3">
|
||||
<fieldset
|
||||
class="border p-4"
|
||||
:disabled="nodeIndexToEdit !== null || loading"
|
||||
:disabled="nodeIndexToEdit !== null"
|
||||
>
|
||||
<legend>
|
||||
<span class="fs-5">{{ trans.methods.__('Ordonancement du menu') }}</span>
|
||||
|
|
@ -80,7 +83,8 @@
|
|||
<MainMenuNodeDataEditor
|
||||
v-if="nodeDataToEdit !== null && nodeDataToEdit.type !== MenuNodeTypeEnum.link"
|
||||
:menu-node-data="getNodeData(nodeDataToEdit.type)"
|
||||
@updated-node-data="(value) => { saveMenuNodeData(value) }"
|
||||
:errors="menuNodeDataErrors"
|
||||
@updated-node-data="(prop, value) => nodeDataToEdit ? saveMenuNodeData(nodeDataToEdit.type, prop, value) : null"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
@ -91,7 +95,7 @@
|
|||
:value="JSON.stringify(nodeList)"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
|
@ -99,6 +103,7 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
|||
import axios, { type AxiosResponse } from "axios";
|
||||
import { computed, defineOptions, onMounted, ref, useAttrs } from "vue";
|
||||
import Draggable from "vuedraggable";
|
||||
import type { IMenuNodeDataInputInterface } from "../../interfaces/IMenuNodeDataInputInterface";
|
||||
import route from "../../modules/route";
|
||||
import toast from "../../modules/toast";
|
||||
import trans from "../../modules/trans";
|
||||
|
|
@ -123,6 +128,7 @@ const menuNodeDataList = ref<Array<MenuNodeDataInterface>>([]);
|
|||
const nodeTypeEnumList = ref<Map<MenuNodeTypeEnum,Enum>>(new Map<MenuNodeTypeEnum,Enum>());
|
||||
/** If set not null then opens the node editor */
|
||||
const nodeIndexToEdit = ref<number|null>(null);
|
||||
const menuNodeDataErrors = ref<LaravelValidationErrors>({});
|
||||
|
||||
// * COMPUTED
|
||||
const nodeToEdit = computed(() => nodeIndexToEdit.value !== null && nodeList.value[nodeIndexToEdit.value] !== undefined ?
|
||||
|
|
@ -180,35 +186,6 @@ function getNodeData(type: MenuNodeTypeEnum): MenuNodeDataInterface
|
|||
}
|
||||
return NodeData;
|
||||
}
|
||||
async function saveMenuNodeData(menuNodeData: MenuNodeDataInterface): Promise<boolean>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
const menuNodeDataListRoute = route.methods.route("bo.menu_node_data.index");
|
||||
if(!menuNodeDataListRoute) {
|
||||
throw new Error("Could not load route 'bo.menu_node_data.index'");
|
||||
}
|
||||
|
||||
if(loading.value) {
|
||||
toast.methods.errorNotify("An action is already occuring");
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
|
||||
axios.post<boolean>(menuNodeDataListRoute, menuNodeData).then(() => resolve(true))
|
||||
.catch(() => resolve(false))
|
||||
.finally(() => { loading.value = false; });
|
||||
});
|
||||
}
|
||||
|
||||
function getEnum(tsEnum: MenuNodeTypeEnum): Enum {
|
||||
const enumValue: Enum|undefined = Object.values(nodeTypeEnumList.value).find((value) => value.value === tsEnum);
|
||||
if (!enumValue) {
|
||||
throw new Error(`Undefined enumValue for ${tsEnum}`);
|
||||
}
|
||||
return enumValue;
|
||||
}
|
||||
|
||||
async function fetchMenuNodeDataList(): Promise<Array<MenuNodeDataInterface>>
|
||||
{
|
||||
|
|
@ -234,6 +211,61 @@ async function fetchMenuNodeDataList(): Promise<Array<MenuNodeDataInterface>>
|
|||
}).finally(() => { loading.value = false; });
|
||||
});
|
||||
}
|
||||
|
||||
async function saveMenuNodeData(
|
||||
type: MenuNodeTypeEnum,
|
||||
prop: string,
|
||||
menuNodeData: ValueOf<IMenuNodeDataInputInterface>
|
||||
): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const menuNodeDataListRoute = route.methods.route("bo.menu_node_data.update", {MENU_NODE_DATA: type});
|
||||
if(!menuNodeDataListRoute) {
|
||||
reject();
|
||||
throw new Error("Could not load route 'bo.menu_node_data.update'");
|
||||
}
|
||||
|
||||
if(loading.value) {
|
||||
toast.methods.errorNotify("An action is already occuring");
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
|
||||
axios.patch<boolean>(menuNodeDataListRoute, {
|
||||
[prop]: menuNodeData
|
||||
}).then(() => {
|
||||
loading.value = false;
|
||||
menuNodeDataErrors.value = {};
|
||||
fetchMenuNodeDataList().then((dataList) => { menuNodeDataList.value = dataList; });
|
||||
resolve(true);
|
||||
}).catch((error) => {
|
||||
let message = "Une erreur est survenue merci de ressayer plus tard";
|
||||
if (error.response.status === 422) {
|
||||
menuNodeDataErrors.value = error.response?.data?.errors ?? {};
|
||||
return;
|
||||
}
|
||||
if (error.response) {
|
||||
console.error(error.response.data);
|
||||
} else if (error.request) {
|
||||
console.error(error.request);
|
||||
} else {
|
||||
// Something happened in setting up the request that triggered an Error
|
||||
console.error("Error", error.message);
|
||||
}
|
||||
toast.methods.errorNotify(message);
|
||||
resolve(false);
|
||||
}).finally(() => { loading.value = false; });
|
||||
});
|
||||
}
|
||||
|
||||
function getEnum(tsEnum: MenuNodeTypeEnum): Enum {
|
||||
const enumValue: Enum|undefined = Object.values(nodeTypeEnumList.value).find((value) => value.value === tsEnum);
|
||||
if (!enumValue) {
|
||||
throw new Error(`Undefined enumValue for ${tsEnum}`);
|
||||
}
|
||||
return enumValue;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -7,33 +7,38 @@
|
|||
<!-- TITLE -->
|
||||
<div class="mb-3 row">
|
||||
<label
|
||||
for="type"
|
||||
for="title-text"
|
||||
class="col-sm-2 col-form-label"
|
||||
>
|
||||
{{ trans.methods.__("Titre") }}
|
||||
</label>
|
||||
<div class="col-sm-4">
|
||||
<input
|
||||
id="title-text"
|
||||
type="text"
|
||||
class="form-control"
|
||||
:value="menuNodeData.title"
|
||||
@blur="($event) => saveNodeDataInput('title', ($event.target as HTMLInputElement).value)"
|
||||
>
|
||||
<small v-if="errors.title" v-for="(message) of errors.title" class="text-danger">"{{ message }}"</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TEXT -->
|
||||
<div class="mb-3 row">
|
||||
<label
|
||||
for="type"
|
||||
for="text-text"
|
||||
class="col-sm-2 col-form-label"
|
||||
>
|
||||
{{ trans.methods.__("Text") }}
|
||||
</label>
|
||||
<div class="col-sm-4">
|
||||
<input
|
||||
id="text-text"
|
||||
type="text"
|
||||
class="form-control"
|
||||
:value="menuNodeData.text"
|
||||
@blur="($event) => saveNodeDataInput('text', ($event.target as HTMLInputElement).value)"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -42,59 +47,75 @@
|
|||
<div class="mb-3 row">
|
||||
<!-- LINK URL -->
|
||||
<label
|
||||
for="type"
|
||||
for="link-text"
|
||||
class="col-sm-2 col-form-label p-2"
|
||||
>
|
||||
{{ trans.methods.__("Link url") }}
|
||||
</label>
|
||||
<div class="col-sm-4 p-2">
|
||||
<input
|
||||
id="link-text"
|
||||
type="text"
|
||||
class="form-control"
|
||||
:value="menuNodeData.link_url"
|
||||
@blur="($event) => saveNodeDataInput('link_url', ($event.target as HTMLInputElement).value)"
|
||||
>
|
||||
</div>
|
||||
<!-- LINK TITLE -->
|
||||
<label
|
||||
for="type"
|
||||
for="link-title-text"
|
||||
class="col-sm-2 col-form-label p-2"
|
||||
>
|
||||
{{ trans.methods.__("Link title") }}
|
||||
</label>
|
||||
<div class="col-sm-4 p-2">
|
||||
<input
|
||||
id="link-title-text"
|
||||
type="text"
|
||||
class="form-control"
|
||||
:value="menuNodeData.link_url"
|
||||
:value="menuNodeData.link_title"
|
||||
@blur="($event) => saveNodeDataInput('link_title', ($event.target as HTMLInputElement).value)"
|
||||
>
|
||||
</div>
|
||||
<!-- LINK TARGET -->
|
||||
<label
|
||||
for="type"
|
||||
for="link-target-checkbox"
|
||||
class="col-sm-2 col-form-label p-2"
|
||||
>
|
||||
{{ trans.methods.__("Link target") }}
|
||||
</label>
|
||||
<div class="col-sm-4 p-2">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
:value="menuNodeData.link_target"
|
||||
>
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
name="link_target"
|
||||
class="form-check-input pt-3"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id="link-target-checkbox"
|
||||
:checked="menuNodeData.link_target"
|
||||
@change="($event) => saveNodeDataInput('link_target', ($event.target as HTMLInputElement).checked)"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<!-- LINK STATUS -->
|
||||
<label
|
||||
for="type"
|
||||
class="col-sm-2 col-form-label p-2"
|
||||
for="link-status-checkbox"
|
||||
>
|
||||
{{ trans.methods.__("Link status") }}
|
||||
</label>
|
||||
<div class="col-sm-4 p-2">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
:value="menuNodeData.link_status"
|
||||
>
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
name="link_status"
|
||||
class="form-check-input pt-3"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id="link-status-checkbox"
|
||||
:checked="menuNodeData.link_status"
|
||||
@change="($event) => saveNodeDataInput('link_status', ($event.target as HTMLInputElement).checked)"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -104,104 +125,134 @@
|
|||
<!-- PICTURE -->
|
||||
<div class="mb-3 row">
|
||||
<!-- PICTURE -->
|
||||
<label
|
||||
for="picture-input"
|
||||
class="col-sm-2 col-form-label p-2"
|
||||
>
|
||||
{{ trans.methods.__("Picture") }}
|
||||
</label>
|
||||
<ImageInputComponent
|
||||
:required="false"
|
||||
id="picture-input"
|
||||
:required="true"
|
||||
:show-labels="true"
|
||||
name="picture"
|
||||
helper="picture"
|
||||
:width="100"
|
||||
:height="100"
|
||||
:value="menuNodeData.picture"
|
||||
:preview="true"
|
||||
:preview="false"
|
||||
:browse-event="false"
|
||||
@image-file=""
|
||||
@image-file="(file) => file ? saveNodeDataInput('picture', file) : null"
|
||||
/>
|
||||
<!-- PICTURE ALT -->
|
||||
<label
|
||||
for="type"
|
||||
for="picture-alt-text"
|
||||
class="col-sm-2 col-form-label p-2"
|
||||
>
|
||||
{{ trans.methods.__("Picture alt") }}
|
||||
</label>
|
||||
<div class="col-sm-4 p-2">
|
||||
<input
|
||||
id="picture-alt-text"
|
||||
type="text"
|
||||
class="form-control"
|
||||
:value="menuNodeData.picture_alt"
|
||||
@blur="($event) => saveNodeDataInput('picture_alt', ($event.target as HTMLInputElement).value)"
|
||||
>
|
||||
</div>
|
||||
<!-- PICTURE TITLE -->
|
||||
<label
|
||||
for="type"
|
||||
for="picture-title-text"
|
||||
class="col-sm-2 col-form-label p-2"
|
||||
>
|
||||
{{ trans.methods.__("Picture title") }}
|
||||
</label>
|
||||
<div class="col-sm-4 p-2">
|
||||
<input
|
||||
id="picture-title-text"
|
||||
type="text"
|
||||
class="form-control"
|
||||
:value="menuNodeData.picture_title"
|
||||
@blur="($event) => saveNodeDataInput('picture_title', ($event.target as HTMLInputElement).value)"
|
||||
>
|
||||
</div>
|
||||
<!-- PICTURE STATUS -->
|
||||
<label
|
||||
for="type"
|
||||
class="col-sm-2 col-form-label p-2"
|
||||
for="picture-status-checkbox"
|
||||
>
|
||||
{{ trans.methods.__("Picture status") }}
|
||||
</label>
|
||||
<div class="col-sm-4 p-2">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
:value="menuNodeData.picture_status"
|
||||
>
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
name="picture_status"
|
||||
class="form-check-input pt-3"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id="picture-status-checkbox"
|
||||
:checked="menuNodeData.picture_status"
|
||||
@change="($event) => saveNodeDataInput('picture_status', ($event.target as HTMLInputElement).checked)"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- --- -->
|
||||
<hr>
|
||||
|
||||
<!-- BACKGROUND PICTURE -->
|
||||
<!-- BACKGROUND PICTURE-->
|
||||
<div class="mb-3 row">
|
||||
<label
|
||||
for="background-picture-input"
|
||||
class="col-sm-2 col-form-label p-2"
|
||||
>
|
||||
{{ trans.methods.__("Background Picture") }}
|
||||
</label>
|
||||
<!-- BACKGROUND PICTURE -->
|
||||
<ImageInputComponent
|
||||
:required="false"
|
||||
id="background-picture-input"
|
||||
:required="true"
|
||||
:show-labels="true"
|
||||
helper="picture"
|
||||
name="background_picture"
|
||||
helper="background_picture"
|
||||
:width="100"
|
||||
:height="100"
|
||||
:value="menuNodeData.background_picture"
|
||||
:preview="true"
|
||||
:preview="false"
|
||||
:browse-event="false"
|
||||
@image-file="(file) => file ? saveNodeDataInput('background_picture', file) : null"
|
||||
/>
|
||||
<!-- BACKGROUND PICTURE ALT -->
|
||||
<label
|
||||
for="type"
|
||||
for="background-picture-alt-text"
|
||||
class="col-sm-2 col-form-label p-2"
|
||||
>
|
||||
{{ trans.methods.__("Picture alt") }}
|
||||
{{ trans.methods.__("Background Picture alt") }}
|
||||
</label>
|
||||
<div class="col-sm-4 p-2">
|
||||
<input
|
||||
id="background-picture-alt-text"
|
||||
type="text"
|
||||
class="form-control"
|
||||
:value="menuNodeData.background_picture_alt"
|
||||
@blur="($event) => saveNodeDataInput('background_picture_alt', ($event.target as HTMLInputElement).value)"
|
||||
>
|
||||
</div>
|
||||
<!-- BACKGROUND PICTURE TITLE -->
|
||||
<label
|
||||
for="type"
|
||||
for="background-picture-title-text"
|
||||
class="col-sm-2 col-form-label p-2"
|
||||
>
|
||||
{{ trans.methods.__("Background picture title") }}
|
||||
</label>
|
||||
<div class="col-sm-4 p-2">
|
||||
<input
|
||||
id="background-picture-title-text"
|
||||
type="text"
|
||||
class="form-control"
|
||||
:value="menuNodeData.background_picture_title"
|
||||
@blur="($event) => saveNodeDataInput('background_picture_title', ($event.target as HTMLInputElement).value)"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -210,6 +261,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { defineOptions, onMounted, ref, watch, type PropType } from "vue";
|
||||
import type { IMenuNodeDataInputInterface } from "../../interfaces/IMenuNodeDataInputInterface";
|
||||
import trans from "../../modules/trans";
|
||||
import type { MenuNodeDataInterface } from "../../types/models/MenuNodeData";
|
||||
import ImageInputComponent from "./ImageInputComponent.vue";
|
||||
|
|
@ -220,7 +272,7 @@ defineOptions({
|
|||
|
||||
// * EMITS
|
||||
const emits = defineEmits<{
|
||||
updatedNodeData: [menuNode: MenuNodeDataInterface],
|
||||
updatedNodeData: [prop: string, value: ValueOf<IMenuNodeDataInputInterface> ],
|
||||
}>();
|
||||
|
||||
// * ATTRIBUTES
|
||||
|
|
@ -231,6 +283,10 @@ const props = defineProps({
|
|||
menuNodeData: {
|
||||
type: Object as PropType<MenuNodeDataInterface>,
|
||||
required: true
|
||||
},
|
||||
errors: {
|
||||
type: Object as PropType<LaravelValidationErrors>,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -240,16 +296,14 @@ const menuNodeData = ref<MenuNodeDataInterface>(Object.assign({}, props.menuNode
|
|||
|
||||
// * LIFECYCLE
|
||||
onMounted(() => {});
|
||||
watch(menuNodeData, (newValue) => {
|
||||
emits("updatedNodeData", newValue);
|
||||
}, { deep: true });
|
||||
|
||||
watch(props, () => {
|
||||
menuNodeData.value = Object.assign({}, props.menuNodeData);;
|
||||
})
|
||||
|
||||
// * METHODS
|
||||
// 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;
|
||||
// }
|
||||
function saveNodeDataInput(inputName: string, inputValue: ValueOf<IMenuNodeDataInputInterface>): void {
|
||||
emits("updatedNodeData", inputName, inputValue);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
11
resources/ts/index.d.ts
vendored
11
resources/ts/index.d.ts
vendored
|
|
@ -1,8 +1,8 @@
|
|||
export { };
|
||||
import type VueTagsInput from "@sipec/vue3-tags-input";
|
||||
import { AxiosStatic } from "axios";
|
||||
import type Swiper from "swiper";
|
||||
import type { MenuNodeInterface } from "./types/models/MenuNode";
|
||||
import type VueTagsInput from "@sipec/vue3-tags-input";
|
||||
import { AxiosStatic } from "axios";
|
||||
import type Swiper from "swiper";
|
||||
import type { MenuNodeInterface } from "./types/models/MenuNode";
|
||||
|
||||
// * Enum
|
||||
interface EnumInterface {
|
||||
|
|
@ -78,6 +78,9 @@ declare global {
|
|||
swiper: Swiper;
|
||||
};
|
||||
|
||||
type ValueOf<T> = T[keyof T];
|
||||
type LaravelValidationErrors = Record<string, string[]>;
|
||||
|
||||
interface Window {
|
||||
axios: AxiosStatic;
|
||||
Swal: Function;
|
||||
|
|
|
|||
6
resources/ts/interfaces/IMenuNodeDataInputInterface.ts
Normal file
6
resources/ts/interfaces/IMenuNodeDataInputInterface.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import type { MenuNodeDataInterface } from "../types/models/MenuNodeData";
|
||||
|
||||
export interface IMenuNodeDataInputInterface extends Omit<MenuNodeDataInterface, "picture" | "background_picture"> {
|
||||
picture: File;
|
||||
background_picture: File;
|
||||
}
|
||||
|
|
@ -10,4 +10,5 @@
|
|||
window.__SYSTEM._routes['fo.contact.show'] = '{{ route('fo.contact.show') }}';
|
||||
window.__SYSTEM._routes['fo.add-single-optin'] = "{{ route('fo.add-single-optin') }}";
|
||||
window.__SYSTEM._routes['bo.menu_node_data.index'] = '{{ route('bo.menu_node_data.index') }}';
|
||||
window.__SYSTEM._routes['bo.menu_node_data.update'] = '{{ route('bo.menu_node_data.update', ['menu_node_data' => 'MENU_NODE_DATA']) }}';
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue