Define main menu as a js object structure

This commit is contained in:
Johannes Zellner
2025-12-15 18:52:03 +01:00
parent fa859a3b5d
commit 350315fa56
3 changed files with 337 additions and 152 deletions
+173 -1
View File
@@ -1,5 +1,9 @@
<script setup>
import { useI18n } from 'vue-i18n';
const i18n = useI18n();
const t = i18n.t;
import { onMounted, ref, useTemplateRef, provide } from 'vue';
import { Notification, fetcher } from '@cloudron/pankow';
import { setLanguage } from './i18n.js';
@@ -74,6 +78,174 @@ const VIEWS = Object.freeze({
VOLUMES: '#/volumes',
});
const menuItems = ref([{
label: t('apps.title'),
icon: 'fa fa-grip fa-fw',
route: VIEWS.APPS,
active: () => view.value === VIEWS.APPS || view.value === VIEWS.APP,
}, {
label: t('appstore.title'),
icon: 'fa fa-cloud-download-alt fa-fw',
route: VIEWS.APPSTORE,
active: () => view.value === VIEWS.APPSTORE,
visible: () => profile.value.isAtLeastAdmin,
}, {
separator: true,
}, {
label: t('domains.title'),
icon: 'fa fa-globe fa-fw',
route: VIEWS.DOMAINS,
active: () => view.value === VIEWS.DOMAINS,
visible: () => profile.value.isAtLeastAdmin,
}, {
label: t('users.title'),
icon: 'fa fa-users-gear fa-fw',
visible: () => profile.value.isAtLeastUserManager,
active: () => view.value === VIEWS.APPS || view.value === VIEWS.APP,
childItems: [{
label: t('main.navbar.users'),
icon: 'fa fa-user fa-fw',
route: VIEWS.USERS,
active: () => view.value === VIEWS.USERS,
visible: () => profile.value.isAtLeastUserManager,
}, {
label: t('main.navbar.groups'),
icon: 'fa fa-users fa-fw',
route: VIEWS.GROUPS,
active: () => view.value === VIEWS.GROUPS,
visible: () => profile.value.isAtLeastUserManager,
}, {
label: 'LDAP',
icon: 'fa fa-fw fa-users-rays',
route: VIEWS.LDAP,
active: () => view.value === VIEWS.LDAP,
visible: () => profile.value.isAtLeastAdmin,
}, {
label: 'OpenID',
icon: 'fa fa-fw fa-brands fa-openid',
route: VIEWS.OPENID,
active: () => view.value === VIEWS.OPENID,
visible: () => profile.value.isAtLeastAdmin,
}, {
label: t('userdirectory.settings.title'),
icon: 'fa fa-fw fa-screwdriver-wrench',
route: VIEWS.USER_DIRECTORY_SETTINGS,
active: () => view.value === VIEWS.USER_DIRECTORY_SETTINGS,
visible: () => profile.value.isAtLeastAdmin,
}],
}, {
label: t('emails.title'),
icon: 'fa fa-envelope fa-fw',
visible: () => profile.value.isAtLeastMailManager,
childItems: [{
label: 'Domains',
icon: 'fa fa-fw fa-globe',
route: VIEWS.EMAIL_DOMAINS,
active: () => view.value === VIEWS.EMAIL_DOMAINS || view.value === VIEWS.EMAIL_DOMAIN,
visible: () => profile.value.isAtLeastAdmin,
}, {
label: t('email.incoming.mailboxes.title'),
icon: 'fa fa-fw fa-inbox',
route: VIEWS.MAILBOXES,
active: () => view.value === VIEWS.MAILBOXES,
}, {
label: t('email.incoming.mailinglists.title'),
icon: 'fa fa-fw-solid fa-envelopes-bulk',
route: VIEWS.MAILINGLISTS,
active: () => view.value === VIEWS.MAILINGLISTS,
}, {
label: t('emails.eventlog.title'),
icon: 'fa fa-fw fa-list-alt',
route: VIEWS.EMAIL_EVENTLOG,
active: () => view.value === VIEWS.EMAIL_EVENTLOG,
visible: () => profile.value.isAtLeastAdmin,
}, {
label: t('emails.settings.title'),
icon: 'fa fa-fw fa-screwdriver-wrench',
route: VIEWS.EMAIL_SETTINGS,
active: () => view.value === VIEWS.EMAIL_SETTINGS,
visible: () => profile.value.isAtLeastAdmin,
}]
}, {
label: t('network.title'),
icon: 'fas fa-network-wired fa-fw',
route: VIEWS.NETWORK,
active: () => view.value === VIEWS.NETWORK,
visible: () => profile.value.isAtLeastAdmin,
}, {
label: t('volumes.title'),
icon: 'fa fa-hdd fa-fw',
route: VIEWS.VOLUMES,
active: () => view.value === VIEWS.VOLUMES,
visible: () => profile.value.isAtLeastAdmin,
}, {
label: t('backups.title'),
icon: 'fa fa-archive fa-fw',
visible: () => profile.value.isAtLeastAdmin,
childItems: [{
label: t('backups.sites.title'),
icon: 'fa fa-fw fa-hard-drive',
route: VIEWS.BACKUP_SITES,
active: () => view.value === VIEWS.BACKUP_SITES,
}, {
label: t('backups.archives.title'),
icon: 'fa fa-fw fa-grip',
route: VIEWS.APP_ARCHIVE,
active: () => view.value === VIEWS.APP_ARCHIVE,
}]
}, {
label: t('appearance.title'),
icon: 'fa fa-pen-ruler fa-fw',
route: VIEWS.APPEARANCE,
active: () => view.value === VIEWS.APPEARANCE,
visible: () => profile.value.isAtLeastAdmin,
}, {
label: t('system.title'),
icon: 'fa fa-server fa-fw',
visible: () => profile.value.isAtLeastAdmin,
childItems: [{
label: 'Docker',
icon: 'fa-brands fa-fw fa-docker',
route: VIEWS.DOCKER,
active: () => view.value === VIEWS.DOCKER,
}, {
label: t('services.title'),
icon: 'fa fa-diagram-project fa-fw',
route: VIEWS.SERVICES,
active: () => view.value === VIEWS.SERVICES,
}, {
label: t('eventlog.title'),
icon: 'fa fa-list-alt fa-fw',
route: VIEWS.SYSTEM_EVENTLOG,
active: () => view.value === VIEWS.SYSTEM_EVENTLOG,
}, {
label: t('settings.updates.title'),
icon: 'fa fa-fw fa-square-up-right',
route: VIEWS.SYSTEM_UPDATE,
active: () => view.value === VIEWS.SYSTEM_UPDATE,
}, {
label: t('system.settings.title'),
icon: 'fa fa-fw fa-screwdriver-wrench',
route: VIEWS.SYSTEM_SETTINGS,
active: () => view.value === VIEWS.SYSTEM_SETTINGS,
}]
}, {
separator: true,
visible: () => profile.value.isAtLeastAdmin,
}, {
label: t('server.title'),
icon: 'fa fa-fw fa-microchip',
route: VIEWS.SERVER,
active: () => view.value === VIEWS.SERVER,
visible: () => profile.value.isAtLeastAdmin,
}, {
label: t('settings.appstoreAccount.title'),
icon: 'fa fa-fw fa-crown',
route: VIEWS.CLOUDRON_ACCOUNT,
active: () => view.value === VIEWS.CLOUDRON_ACCOUNT,
visible: () => profile.value.isAtLeastOwner,
}]);
const offlineOverlay = useTemplateRef('offlineOverlay');
fetcher.globalOptions.errorHook = (error) => {
@@ -272,7 +444,7 @@ onMounted(async () => {
<RequestErrorDialog/>
<div v-if="ready" style="display: flex; flex-direction: row; overflow: hidden; height: 100%;">
<SideBar v-if="profile.isAtLeastUserManager" :profile="profile" :active-view="view" :VIEWS="VIEWS" :cloudron-name="config.cloudronName" :cloudron-avatar-url="avatarUrl"/>
<SideBar v-if="profile.isAtLeastUserManager" :items="menuItems" :cloudron-name="config.cloudronName" :cloudron-avatar-url="avatarUrl"/>
<div style="flex-grow: 1; display: flex; flex-direction: column; overflow: hidden; height: 100%;">
<Headerbar :config="config" :subscription="subscription"/>