mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-10-15 08:19:38 +00:00
201 lines
5.4 KiB
JavaScript
201 lines
5.4 KiB
JavaScript
import CisMenuLink from "./Link.js";
|
|
|
|
export default {
|
|
name: 'CisMenuEntry',
|
|
components: {
|
|
CisMenuLink
|
|
},
|
|
props: {
|
|
entry: Object,
|
|
level: {
|
|
type: Number,
|
|
default: 1
|
|
},
|
|
activeContent: [String, Number],
|
|
highestMatchingUrlCount: Number,
|
|
openMenuHierarchy: Array,
|
|
precedingMenuHierarchy: {
|
|
type: Array,
|
|
default: [],
|
|
},
|
|
},
|
|
data: () => {
|
|
return {
|
|
collapse: null,
|
|
urlCount:0,
|
|
}
|
|
},
|
|
inject: ['setActiveEntry', 'setOpenMenuHierarchy', 'addUrlCount'],
|
|
watch:{
|
|
highestMatchingUrlCount: function(newValue)
|
|
{
|
|
// if this entry has the most matching url parts then it should be active
|
|
if (this.activeContent == null && newValue == this.urlCount)
|
|
{
|
|
this.setActiveEntry(this.entry.content_id);
|
|
this.setOpenMenuHierarchy(this.menuHierarchy);
|
|
}
|
|
},
|
|
openMenuHierarchy() {
|
|
if (!this.hasChilds) return;
|
|
|
|
if (this.$props.openMenuHierarchy.length && this.$props.openMenuHierarchy[0] === this.$props.entry.content_id) {
|
|
this.$props.entry.menu_open = true;
|
|
} else {
|
|
this.$props.entry.menu_open = false;
|
|
}
|
|
},
|
|
'entry.menu_open': function (isMenuOpen) {
|
|
if (!this.collapse)
|
|
return;
|
|
|
|
if (isMenuOpen) {
|
|
this.collapse.show();
|
|
} else {
|
|
this.collapse.hide();
|
|
}
|
|
},
|
|
},
|
|
computed: {
|
|
hasFullLink() {
|
|
return this.entry.url.startsWith(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router)
|
|
},
|
|
target() {
|
|
if (this.entry?.target) {
|
|
return this.entry.target;
|
|
}
|
|
return '_self';
|
|
},
|
|
hasChilds() {
|
|
return this.entry.childs && this.entry.childs.length !== 0;
|
|
},
|
|
menuHierarchy() {
|
|
return [...this.$props.precedingMenuHierarchy, this.$props.entry.content_id];
|
|
},
|
|
menuNodeHref() {
|
|
if (this.hasChilds) {
|
|
return this.hasFullLink ? this.$props.entry.url : null;
|
|
} else {
|
|
return this.$props.entry.url;
|
|
}
|
|
},
|
|
},
|
|
methods: {
|
|
getUrlMatchPoints(url,link){
|
|
let splitted_link = link.split('/');
|
|
let splitted_url = url.href.split('/');
|
|
let count = 0;
|
|
|
|
for (let part_url of splitted_url) {
|
|
for (let part_link of splitted_link) {
|
|
if (part_url === part_link) {
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.urlCount = count;
|
|
this.addUrlCount(count);
|
|
},
|
|
checkActiveUrl(url){
|
|
this.getUrlMatchPoints(url,this.entry.url);
|
|
|
|
let url_hash_spaceSymbol_regex = new RegExp("%20","gi");
|
|
let url_hash_sharpSymbol_regex = new RegExp("^#");
|
|
let url_hash = url.hash;
|
|
url_hash = url_hash.replace(url_hash_spaceSymbol_regex, " ").replace(url_hash_sharpSymbol_regex,"");
|
|
|
|
if (url_hash == this.entry.titel || url.href == this.entry.url) {
|
|
this.setActiveEntry(this.entry.content_id);
|
|
this.setOpenMenuHierarchy(this.menuHierarchy);
|
|
}
|
|
},
|
|
searchRecursiveChild(entry,property,value){
|
|
if (typeof entry.childs == 'object' && !Array.isArray(entry.childs) && Object.entries(entry.childs).length > 0){
|
|
entry.childs = Object.values(entry.childs);
|
|
}
|
|
for (let child of entry.childs) {
|
|
if (child[property] == value) {
|
|
return true;
|
|
}
|
|
if ((child.childs instanceof Array && child.childs.length > 0) || Object.values(child.childs).length > 0) {
|
|
if (this.searchRecursiveChild(child, property, value)){
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
toggleCollapse() {
|
|
if (!this.$props.entry.menu_open) {
|
|
this.setOpenMenuHierarchy(this.menuHierarchy);
|
|
} else {
|
|
this.setOpenMenuHierarchy(this.precedingMenuHierarchy);
|
|
}
|
|
},
|
|
handleClickOnMenuNode() {
|
|
if (this.hasFullLink) {
|
|
this.setActiveEntry(this.$props.entry.content_id);
|
|
if (this.hasChilds) {
|
|
this.setOpenMenuHierarchy(this.menuHierarchy);
|
|
}
|
|
} else if (this.hasChilds) {
|
|
this.toggleCollapse();
|
|
}
|
|
},
|
|
},
|
|
mounted() {
|
|
if (this.$refs.children) {
|
|
if (this.entry.menu_open)
|
|
this.$refs.children.className += ' show';
|
|
this.collapse = new bootstrap.Collapse(this.$refs.children, { toggle: false });
|
|
}
|
|
|
|
this.checkActiveUrl(new URL(window.location.href));
|
|
},
|
|
template: /*html*/`
|
|
<div v-if="entry.template_kurzbz == 'include'">
|
|
INCLUDE
|
|
</div>
|
|
<template v-else>
|
|
<div class="btn-group w-100">
|
|
<cis-menu-link
|
|
@click="handleClickOnMenuNode($event)"
|
|
:href="menuNodeHref"
|
|
:target="target"
|
|
class="btn btn-default rounded-0 text-start"
|
|
:class="{
|
|
['btn-level-' + level]: true,
|
|
'fw-bold': $props.activeContent === $props.entry.content_id
|
|
}"
|
|
:style="'padding-left: calc(var(--bs-btn-padding-x) * ' + $props.level + ');'"
|
|
>
|
|
{{ entry.titel }}
|
|
</cis-menu-link>
|
|
<button
|
|
v-if="hasChilds"
|
|
@click.prevent="toggleCollapse()"
|
|
:aria-expanded="entry.menu_open"
|
|
class="btn btn-default rounded-0 dropdown-toggle dropdown-toggle-split flex-grow-0"
|
|
:class="{ collapsed: !entry.menu_open }"
|
|
>
|
|
<span class="visually-hidden">Toggle Dropdown</span>
|
|
</button>
|
|
</div>
|
|
<ul v-if="hasChilds" ref="children" class="nav w-100 collapse" >
|
|
<li>
|
|
<cis-menu-entry
|
|
v-for="child in entry.childs"
|
|
:key="child"
|
|
:highestMatchingUrlCount="highestMatchingUrlCount"
|
|
:activeContent="activeContent"
|
|
:entry="child"
|
|
:level="level + 1"
|
|
:openMenuHierarchy="$props.openMenuHierarchy.slice(1)"
|
|
:precedingMenuHierarchy="menuHierarchy"
|
|
/>
|
|
</li>
|
|
</ul>
|
|
</template>`
|
|
};
|