1 Commits

Author SHA1 Message Date
Sebastian cb45399998 chore(deps): update dependency vuetify to v4.1.8
Build Test / build (pull_request) Successful in 19s
JS Unit Tests / test (pull_request) Successful in 18s
PHP Unit Tests / test (pull_request) Successful in 1m23s
PHP Integration Tests / Integration Tests (pull_request) Failing after 2m1s
2026-08-10 03:02:06 +00:00
5 changed files with 61 additions and 60 deletions
+15 -26
View File
@@ -1,8 +1,7 @@
<script setup lang="ts">
import { computed, watch } from 'vue';
import { computed } from 'vue';
import { useLayoutStore, type MenuMode } from '@KTXC/stores/layoutStore';
import { useIntegrationStore } from '@KTXC/stores/integrationStore';
import type { IntegrationPointType } from '@KTXC/types/integrationTypes';
import { useL10n } from '@KTXC/composables/useL10n';
import Logo from '@KTXC/layouts/logo/LogoDark.vue';
import SystemMenuGroupStatic from './LayoutSystemMenuGroupStatic.vue';
@@ -13,33 +12,25 @@ const layoutStore = useLayoutStore();
const integrationStore = useIntegrationStore();
const { t } = useL10n('core');
const menuPointByMode: Record<MenuMode, IntegrationPointType> = {
apps: 'app_menu',
'user-settings': 'user_settings_menu',
'admin-settings': 'admin_settings_menu',
};
// Get all entries based on current menu mode
const menuEntries = computed(() => integrationStore.getPoint(menuPointByMode[layoutStore.menuMode]));
const menuEntries = computed(() => {
switch (layoutStore.menuMode) {
case 'user-settings':
return integrationStore.getPoint('user_settings_menu');
case 'admin-settings':
return integrationStore.getPoint('admin_settings_menu');
case 'apps':
default:
return integrationStore.getPoint('app_menu');
}
});
// Only show menu modes that currently have visible items.
const menuModes = computed((): Array<{ value: MenuMode; icon: string; label: string }> => {
const modes: Array<{ value: MenuMode; icon: string; label: string }> = [
// Static list of menu modes shown as icon buttons
const menuModes = computed((): Array<{ value: MenuMode; icon: string; label: string }> => [
{ value: 'apps', icon: 'mdi-view-dashboard', label: t('systemMenu.apps', 'Applications') },
{ value: 'user-settings', icon: 'mdi-account-cog', label: t('systemMenu.personalSettings', 'Settings') },
{ value: 'admin-settings', icon: 'mdi-shield-crown', label: t('systemMenu.adminSettings', 'System') },
];
return modes.filter(mode => integrationStore.getPoint(menuPointByMode[mode.value]).length > 0);
});
// If the active menu becomes empty (for example, after a module is disabled),
// move to the first menu that still has content.
watch(menuModes, (availableModes) => {
if (availableModes.length > 0 && !availableModes.some(mode => mode.value === layoutStore.menuMode)) {
layoutStore.setMenuMode(availableModes[0].value);
}
}, { immediate: true });
]);
</script>
<script lang="ts">
@@ -93,7 +84,6 @@ export default {
<!-- Menu Mode Switcher -->
<template v-slot:append>
<div v-if="menuModes.length">
<v-divider />
<div class="menu-mode-switcher d-flex justify-space-around align-center py-2">
<v-tooltip
@@ -117,7 +107,6 @@ export default {
<span>{{ mode.label }}</span>
</v-tooltip>
</div>
</div>
</template>
</v-navigation-drawer>
</template>
+16
View File
@@ -3,11 +3,13 @@ import { computed } from 'vue';
import { useUserStore } from '@KTXC/stores/userStore';
import { useIntegrationStore } from '@KTXC/stores/integrationStore';
import { useLayoutStore } from '@KTXC/stores/layoutStore';
import { useRouter } from 'vue-router';
import { useL10n, t as tGlobal } from '@KTXC/composables/useL10n';
import defaultAvatar from '@KTXC/assets/images/users/avatar-1.png';
const { t } = useL10n('core');
const router = useRouter();
const userStore = useUserStore();
const integrationStore = useIntegrationStore();
const layoutStore = useLayoutStore();
@@ -41,6 +43,12 @@ const cycleTheme = () => {
layoutStore.setTheme(nextThemeMode.value);
};
// Navigate to settings
const goToSettings = () => {
layoutStore.setMenuMode('settings');
// Navigate to first settings item or a default settings route
router.push('/modules'); // TODO: Make this dynamic based on first settings menu item
};
</script>
<template>
@@ -90,6 +98,14 @@ const cycleTheme = () => {
<v-list-item-title class="text-h6">{{ t(MODE_PRESENTATION[nextThemeMode].l10n, MODE_PRESENTATION[nextThemeMode].label) }}</v-list-item-title>
</v-list-item>
<!-- Go to Settings -->
<v-list-item @click="goToSettings" color="primary" rounded="0">
<template v-slot:prepend>
<v-icon>mdi-cog-outline</v-icon>
</template>
<v-list-item-title class="text-h6">{{ t('userMenu.settings', 'Settings') }}</v-list-item-title>
</v-list-item>
<v-divider class="my-2" />
<!-- Logout -->
-4
View File
@@ -156,10 +156,6 @@ export const useIntegrationStore = defineStore('integrationStore', {
return Array.from(point.items.values())
.filter(entry => entry.visible !== false)
.map(entry => 'items' in entry
? { ...entry, items: entry.items.filter(item => item.visible !== false) }
: entry)
.filter(entry => !('items' in entry) || entry.items.length > 0)
.sort((a, b) => (a.priority ?? 100) - (b.priority ?? 100));
},
+2 -2
View File
@@ -32,7 +32,7 @@ export const useLayoutStore = defineStore('layout', () => {
}
const sidebarDrawer = ref<boolean>(booleanSetting('sidebar_drawer', true));
const miniSidebar = ref<boolean>(booleanSetting('mini_sidebar', true));
const miniSidebar = ref<boolean>(booleanSetting('mini_sidebar', false));
const menuMode = ref<MenuMode>('apps');
// Theme mode - user choice, falling back to the tenant default
@@ -60,7 +60,7 @@ export const useLayoutStore = defineStore('layout', () => {
hydratingFromSettings = true;
try {
sidebarDrawer.value = booleanSetting('sidebar_drawer', true);
miniSidebar.value = booleanSetting('mini_sidebar', true);
miniSidebar.value = booleanSetting('mini_sidebar', false);
theme.value = initialTheme();
} finally {
hydratingFromSettings = false;
+4 -4
View File
@@ -6642,9 +6642,9 @@
}
},
"node_modules/vuetify": {
"version": "4.1.6",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-4.1.6.tgz",
"integrity": "sha512-VOsRTsNfs+FE4JXMONZkqX2yznSqC/FXG9/pgVVjsoqIjUvJg+CfFTuOlgyWVFrZYY+crk7LV9uaiN8bZREV/g==",
"version": "4.1.8",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-4.1.8.tgz",
"integrity": "sha512-003D/8b5462uZCD5CMRTZF3smADmOn47mzthNY0aP/xkslovR5yIc1qXjPdFN0LHcu+p3GEAVmMQabldaIQ5pg==",
"license": "MIT",
"funding": {
"type": "github",
@@ -6653,7 +6653,7 @@
"peerDependencies": {
"typescript": ">=4.7",
"vite-plugin-vuetify": ">=2.1.0",
"vue": "^3.5.0",
"vue": "^3.5.0 || ^3.6.0-0",
"webpack-plugin-vuetify": ">=3.1.0"
},
"peerDependenciesMeta": {