myCRM/assets/js/layout/AppMenuItem.vue
olli b4974b93ef feat: integrate ApiPlatformBundle and enhance settings access control
- Added ApiPlatformBundle to the project configuration.
- Updated SettingsController to use custom access control for viewing and managing settings.
- Modified AppFixtures to reflect new module structure and permissions for project management.
- Adjusted ProjectStatus and ProjectTask entities to align with new permission checks.
- Enhanced User entity to include a method for retrieving module permissions.
- Implemented CleanupModulesCommand to deactivate or remove unimplemented modules.
- Added CSRF protection configuration for forms.
- Introduced property_info configuration for enhanced property handling.
- Updated base template to include user module permissions in the frontend.
- Created test_permissions.php for testing user permissions and roles.
2025-12-28 09:49:18 +01:00

111 lines
3.4 KiB
Vue

<script setup>
import { useLayout } from './composables/layout';
import { onBeforeMount, ref, watch, computed } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
const { layoutState, setActiveMenuItem, toggleMenu } = useLayout();
const props = defineProps({
item: {
type: Object,
default: () => ({})
},
index: {
type: Number,
default: 0
},
root: {
type: Boolean,
default: true
},
parentItemKey: {
type: String,
default: null
}
});
const isActiveMenu = ref(false);
const itemKey = ref(null);
// Prüfe ob Item sichtbar sein soll
const isVisible = computed(() => {
const visible = props.item.visible;
// Wenn visible eine Funktion ist, aufrufen
if (typeof visible === 'function') {
return visible();
}
// Wenn visible undefined ist, Item anzeigen
if (visible === undefined) {
return true;
}
// Sonst boolean-Wert verwenden
return visible;
});
onBeforeMount(() => {
itemKey.value = props.parentItemKey ? props.parentItemKey + '-' + props.index : String(props.index);
const activeItem = layoutState.activeMenuItem;
isActiveMenu.value = activeItem === itemKey.value || activeItem ? activeItem.startsWith(itemKey.value + '-') : false;
});
watch(
() => layoutState.activeMenuItem,
(newVal) => {
isActiveMenu.value = newVal === itemKey.value || newVal.startsWith(itemKey.value + '-');
}
);
function itemClick(event, item) {
if (item.disabled) {
event.preventDefault();
return;
}
if ((item.to || item.url) && (layoutState.staticMenuMobileActive || layoutState.overlayMenuActive)) {
toggleMenu();
}
if (item.command) {
item.command({ originalEvent: event, item: item });
}
const foundItemKey = item.items ? (isActiveMenu.value ? props.parentItemKey : itemKey) : itemKey.value;
setActiveMenuItem(foundItemKey);
}
function checkActiveRoute(item) {
return route.path === item.to;
}
</script>
<template>
<li v-if="isVisible" :class="{ 'layout-root-menuitem': root, 'active-menuitem': isActiveMenu }">
<div v-if="root" class="layout-menuitem-root-text">{{ item.label }}</div>
<a v-if="!item.to || item.items" :href="item.url" @click="itemClick($event, item, index)" :class="item.class" :target="item.target" tabindex="0">
<i :class="item.icon" class="layout-menuitem-icon"></i>
<span class="layout-menuitem-text">{{ item.label }}</span>
<i class="pi pi-fw pi-angle-down layout-submenu-toggler" v-if="item.items"></i>
</a>
<router-link v-if="item.to && !item.items" @click="itemClick($event, item, index)" :class="[item.class, { 'active-route': checkActiveRoute(item) }]" tabindex="0" :to="item.to">
<i :class="item.icon" class="layout-menuitem-icon"></i>
<span class="layout-menuitem-text">{{ item.label }}</span>
<i class="pi pi-fw pi-angle-down layout-submenu-toggler" v-if="item.items"></i>
</router-link>
<Transition v-if="item.items" name="layout-submenu">
<ul v-show="root ? true : isActiveMenu" class="layout-submenu">
<app-menu-item v-for="(child, i) in item.items" :key="child" :index="i" :item="child" :parentItemKey="itemKey" :root="false"></app-menu-item>
</ul>
</Transition>
</li>
</template>
<style lang="scss" scoped></style>