Use href as the view value to simplify logic

This commit is contained in:
Girish Ramakrishnan
2025-10-04 22:58:50 +02:00
parent 444d3eeb7c
commit 99a0c78fe4
+58 -67
View File
@@ -43,35 +43,35 @@ import GroupsView from './views/GroupsView.vue';
import VolumesView from './views/VolumesView.vue';
const VIEWS = {
APP: 'app',
APPEARANCE: 'appearance',
APPS: 'apps',
APPSTORE: 'appstore',
BACKUP_SITES: 'backup-sites',
BACKUP_LIST: 'backup-list',
BACKUP_APP_ARCHIVE: 'backup-app-archive',
CLOUDRON_ACCOUNT: 'cloudron-account',
DOMAINS: 'domains',
EMAIL_DOMAIN: 'email-domain',
EMAIL_DOMAINS: 'email-domains',
EMAIL_MAILBOXES: 'email-mailboxes',
EMAIL_MAILINGLISTS: 'email-mailinglists',
EMAIL_SETTINGS: 'email-settings',
EMAIL_EVENTLOG: 'email-eventlog',
SYSTEM_INFO: 'system-info',
NETWORK: 'network',
PROFILE: 'profile',
SERVICES: 'services',
SYSTEM_LOCALE: 'system-locale',
SYSTEM_DOCKER: 'system-docker',
SYSTEM_EVENTLOG: 'system-eventlog',
SYSTEM_UPDATE: 'system-update',
USER_DIRECTORY_SETTINGS: 'user-directory-settings',
USER_DIRECTORY_LDAP_SERVER: 'user-directory-ldap-server',
USER_DIRECTORY_OPENID_PROVIDER: 'user-directory-openid-provider',
USERS: 'users',
GROUPS: 'users-groups',
VOLUMES: 'volumes',
APP: '#/app', // this is a prefix
APPEARANCE: '#/appearance',
APPS: '#/apps',
APPSTORE: '#/appstore', // this is a prefix
BACKUP_SITES: '#/backup-sites',
BACKUP_LIST: '#/backup-list',
BACKUP_APP_ARCHIVE: '#/backup-app-archive',
CLOUDRON_ACCOUNT: '#/cloudron-account',
DOMAINS: '#/domains',
EMAIL_DOMAIN: '#/email-domain',
EMAIL_DOMAINS: '#/email-domains',
EMAIL_MAILBOXES: '#/email-mailboxes',
EMAIL_MAILINGLISTS: '#/email-mailinglists',
EMAIL_SETTINGS: '#/email-settings',
EMAIL_EVENTLOG: '#/email-eventlog',
SYSTEM_INFO: '#/system-info',
NETWORK: '#/network',
PROFILE: '#/profile',
SERVICES: '#/services',
SYSTEM_LOCALE: '#/system-locale',
SYSTEM_DOCKER: '#/system-docker',
SYSTEM_EVENTLOG: '#/system-eventlog',
SYSTEM_UPDATE: '#/system-update',
USER_DIRECTORY_SETTINGS: '#/user-directory-settings',
USER_DIRECTORY_LDAP_SERVER: '#/user-directory-ldap-server',
USER_DIRECTORY_OPENID_PROVIDER: '#/user-directory-openid-provider',
USERS: '#/users',
GROUPS: '#/users-groups',
VOLUMES: '#/volumes',
};
const offlineOverlay = useTemplateRef('offlineOverlay');
@@ -122,7 +122,6 @@ function onSidebarClose() {
sidebar.value.close();
}
const activeSidebarItem = ref('');
const activeSidebarGroups = ref({
'backup': false,
'email': false,
@@ -135,15 +134,7 @@ function onToggleGroup(group) {
}
function onHashChange() {
const v = location.hash.slice(2);
activeSidebarItem.value = v;
if (activeSidebarItem.value.indexOf('backup') === 0) activeSidebarGroups.value['backup'] = true;
else if (activeSidebarItem.value.indexOf('email') === 0) activeSidebarGroups.value['email'] = true;
else if (activeSidebarItem.value.indexOf('system') === 0) activeSidebarGroups.value['system'] = true;
else if (activeSidebarItem.value.indexOf('user-directory') === 0) activeSidebarGroups.value['user-directory'] = true;
else if (activeSidebarItem.value.indexOf('users') === 0) activeSidebarGroups.value['users'] = true;
const v = location.hash;
if (v === VIEWS.APPS) {
view.value = VIEWS.APPS;
@@ -179,7 +170,7 @@ function onHashChange() {
view.value = VIEWS.SYSTEM_INFO;
} else if (v === VIEWS.NETWORK && profile.value.isAtLeastAdmin) {
view.value = VIEWS.NETWORK;
} else if (v.indexOf(VIEWS.PROFILE) === 0) {
} else if (v === VIEWS.PROFILE) {
view.value = VIEWS.PROFILE;
} else if (v === VIEWS.SERVICES && profile.value.isAtLeastAdmin) {
view.value = VIEWS.SERVICES;
@@ -187,7 +178,7 @@ function onHashChange() {
view.value = VIEWS.SYSTEM_LOCALE;
} else if (v === VIEWS.SYSTEM_DOCKER && profile.value.isAtLeastAdmin) {
view.value = VIEWS.SYSTEM_DOCKER;
} else if (v.indexOf(VIEWS.SYSTEM_EVENTLOG) === 0 && profile.value.isAtLeastAdmin) {
} else if (v === VIEWS.SYSTEM_EVENTLOG && profile.value.isAtLeastAdmin) {
view.value = VIEWS.SYSTEM_EVENTLOG;
} else if (v === VIEWS.SYSTEM_UPDATE && profile.value.isAtLeastAdmin) {
view.value = VIEWS.SYSTEM_UPDATE;
@@ -288,70 +279,70 @@ onMounted(async () => {
<img :src="avatarUrl" :alt="(config.cloudronName || 'Cloudron') + ' icon'" width="40" height="40"/> {{ config.cloudronName || 'Cloudron' }}
</a>
<div class="sidebar-list">
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'apps' }" href="#/apps" @click="onSidebarClose()"><i class="fa fa-grip fa-fw"></i> {{ $t('apps.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'appstore' }" v-show="profile.isAtLeastAdmin" href="#/appstore" @click="onSidebarClose()"><i class="fa fa-cloud-download-alt fa-fw"></i> {{ $t('appstore.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.APPS || view === VIEWS.APP }" :href="VIEWS.APPS" @click="onSidebarClose()"><i class="fa fa-grip fa-fw"></i> {{ $t('apps.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.APPSTORE }" v-show="profile.isAtLeastAdmin" :href="VIEWS.APPSTORE" @click="onSidebarClose()"><i class="fa fa-cloud-download-alt fa-fw"></i> {{ $t('appstore.title') }}</a>
<hr/>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'appearance' }" v-show="profile.isAtLeastAdmin" href="#/appearance" @click="onSidebarClose()"><i class="fa fa-pen-ruler fa-fw"></i> {{ $t('appearance.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.APPEARANCE }" v-show="profile.isAtLeastAdmin" :href="VIEWS.APPEARANCE" @click="onSidebarClose()"><i class="fa fa-pen-ruler fa-fw"></i> {{ $t('appearance.title') }}</a>
<div class="sidebar-item" v-show="profile.isAtLeastAdmin" @click="onToggleGroup('backup')"><i class="fa fa-archive fa-fw"></i> {{ $t('backups.title') }} <i class="collapse fa-solid fa-angle-right" :class="{ expanded: activeSidebarGroups['backup'] }" style="margin-left: 6px;"></i></div>
<Transition name="sidebar-item-group-animation">
<div class="sidebar-item-group" v-if="activeSidebarGroups['backup']">
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'backup-sites' }" href="#/backup-sites" @click="onSidebarClose()"><i class="fa fa-fw fa-hard-drive"></i> {{ $t('backups.sites.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'backup-list' }" href="#/backup-list" @click="onSidebarClose()"><i class="fa fa-fw fa-list-check"></i> {{ $t('backups.listing.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'backup-app-archive' }" href="#/backup-app-archive" @click="onSidebarClose()"><i class="fa fa-fw fa-grip"></i> {{ $t('backups.archives.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.BACKUP_SITES }" :href="VIEWS.BACKUP_SITES" @click="onSidebarClose()"><i class="fa fa-fw fa-hard-drive"></i> {{ $t('backups.sites.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.BACKUP_LIST }" :href="VIEWS.BACKUP_LIST" @click="onSidebarClose()"><i class="fa fa-fw fa-list-check"></i> {{ $t('backups.listing.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.BACKUP_APP_ARCHIVE }" :href="VIEWS.BACKUP_APP_ARCHIVE" @click="onSidebarClose()"><i class="fa fa-fw fa-grip"></i> {{ $t('backups.archives.title') }}</a>
</div>
</Transition>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'domains' }" v-show="profile.isAtLeastAdmin" href="#/domains" @click="onSidebarClose()"><i class="fa fa-globe fa-fw"></i> {{ $t('domains.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.DOMAINS }" v-show="profile.isAtLeastAdmin" :href="VIEWS.DOMAINS" @click="onSidebarClose()"><i class="fa fa-globe fa-fw"></i> {{ $t('domains.title') }}</a>
<div class="sidebar-item" v-show="profile.isAtLeastMailManager" @click="onToggleGroup('email')"><i class="fa fa-envelope fa-fw"></i> {{ $t('emails.title') }} <i class="collapse fa-solid fa-angle-right" :class="{ expanded: activeSidebarGroups['email'] }" style="margin-left: 6px;"></i></div>
<Transition name="sidebar-item-group-animation">
<div class="sidebar-item-group" v-if="activeSidebarGroups['email']">
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'email-domains' }" href="#/email-domains" @click="onSidebarClose()"><i class="fa fa-fw fa-globe"></i> Domains</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'email-mailboxes' }" href="#/email-mailboxes" @click="onSidebarClose()"><i class="fa fa-fw fa-inbox"></i> {{ $t('email.incoming.mailboxes.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'email-mailinglists' }" href="#/email-mailinglists" @click="onSidebarClose()"><i class="fa fa-fw-solid fa-envelopes-bulk"></i> {{ $t('email.incoming.mailinglists.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'email-eventlog' }" href="#/email-eventlog" @click="onSidebarClose()"><i class="fa fa-fw fa-list-alt"></i> {{ $t('emails.eventlog.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'email-settings' }" href="#/email-settings" @click="onSidebarClose()"><i class="fa fa-fw fa-cog"></i> {{ $t('emails.settings.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.EMAIL_DOMAINS || view === VIEWS.EMAIL_DOMAIN }" :href="VIEWS.EMAIL_DOMAINS" @click="onSidebarClose()"><i class="fa fa-fw fa-globe"></i> Domains</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.EMAIL_MAILBOXES }" :href="VIEWS.EMAIL_MAILBOXES" @click="onSidebarClose()"><i class="fa fa-fw fa-inbox"></i> {{ $t('email.incoming.mailboxes.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.EMAIL_MAILINGLISTS }" :href="VIEWS.EMAIL_MAILINGLISTS" @click="onSidebarClose()"><i class="fa fa-fw-solid fa-envelopes-bulk"></i> {{ $t('email.incoming.mailinglists.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.EMAIL_EVENTLOG }" :href="VIEWS.EMAIL_EVENTLOG" @click="onSidebarClose()"><i class="fa fa-fw fa-list-alt"></i> {{ $t('emails.eventlog.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.EMAIL_SETTINGS }" :href="VIEWS.EMAIL_SETTINGS" @click="onSidebarClose()"><i class="fa fa-fw fa-cog"></i> {{ $t('emails.settings.title') }}</a>
</div>
</Transition>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'network' }" v-show="profile.isAtLeastAdmin" href="#/network" @click="onSidebarClose()"><i class="fas fa-network-wired fa-fw"></i> {{ $t('network.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.NETWORK }" v-show="profile.isAtLeastAdmin" :href="VIEWS.NETWORK" @click="onSidebarClose()"><i class="fas fa-network-wired fa-fw"></i> {{ $t('network.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'services' }" v-show="profile.isAtLeastAdmin" href="#/services" @click="onSidebarClose()"><i class="fa fa-cogs fa-fw"></i> {{ $t('services.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.SERVICES }" v-show="profile.isAtLeastAdmin" :href="VIEWS.SERVICES" @click="onSidebarClose()"><i class="fa fa-cogs fa-fw"></i> {{ $t('services.title') }}</a>
<div class="sidebar-item" v-show="profile.isAtLeastAdmin" @click="onToggleGroup('system')"><i class="fa fa-wrench fa-fw"></i> {{ $t('settings.title') }} <i class="collapse fa-solid fa-angle-right" :class="{ expanded: activeSidebarGroups['system'] }" style="margin-left: 6px;"></i></div>
<Transition name="sidebar-item-group-animation">
<div class="sidebar-item-group" v-if="activeSidebarGroups['system']">
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'system-docker' }" href="#/system-docker" @click="onSidebarClose()"><i class="fa-brands fa-fw fa-docker"></i> {{ $t('dockerRegistries.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'system-eventlog' }" href="#/system-eventlog" @click="onSidebarClose()"><i class="fa fa-list-alt fa-fw"></i> {{ $t('eventlog.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'system-locale' }" href="#/system-locale" @click="onSidebarClose()"><i class="fa fa-fw fa-language"></i> {{ $t('system.locale.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'system-update' }" href="#/system-update" @click="onSidebarClose()"><i class="fa fa-fw fa-square-up-right"></i> {{ $t('settings.updates.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.SYSTEM_DOCKER }" :href="VIEWS.SYSTEM_DOCKER" @click="onSidebarClose()"><i class="fa-brands fa-fw fa-docker"></i> {{ $t('dockerRegistries.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.SYSTEM_EVENTLOG }" :href="VIEWS.SYSTEM_EVENTLOG" @click="onSidebarClose()"><i class="fa fa-list-alt fa-fw"></i> {{ $t('eventlog.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.SYSTEM_LOCALE }" :href="VIEWS.SYSTEM_LOCALE" @click="onSidebarClose()"><i class="fa fa-fw fa-language"></i> {{ $t('system.locale.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.SYSTEM_UPDATE }" :href="VIEWS.SYSTEM_DOCKER" @click="onSidebarClose()"><i class="fa fa-fw fa-square-up-right"></i> {{ $t('settings.updates.title') }}</a>
</div>
</Transition>
<div class="sidebar-item" v-show="profile.isAtLeastUserManager" @click="onToggleGroup('users')"><i class="fa fa-users-gear fa-fw"></i> {{ $t('users.title') }} <i class="collapse fa-solid fa-angle-right" :class="{ expanded: activeSidebarGroups['users'] }" style="margin-left: 6px;"></i></div>
<Transition name="sidebar-item-group-animation">
<div class="sidebar-item-group" v-if="activeSidebarGroups['users']">
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'users' }" v-show="profile.isAtLeastUserManager" href="#/users" @click="onSidebarClose()"><i class="fa fa-user fa-fw"></i> {{ $t('main.navbar.users') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'users-groups' }" v-show="profile.isAtLeastUserManager" href="#/users-groups" @click="onSidebarClose()"><i class="fa fa-users fa-fw"></i> {{ $t('main.navbar.groups') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.USERS }" v-show="profile.isAtLeastUserManager" :href="VIEWS.USERS" @click="onSidebarClose()"><i class="fa fa-user fa-fw"></i> {{ $t('main.navbar.users') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.GROUPS }" v-show="profile.isAtLeastUserManager" :href="VIEWS.GROUPS" @click="onSidebarClose()"><i class="fa fa-users fa-fw"></i> {{ $t('main.navbar.groups') }}</a>
</div>
</Transition>
<div class="sidebar-item" v-show="profile.isAtLeastAdmin" @click="onToggleGroup('user-directory')"><i class="fa fa-address-book fa-fw"></i> {{ $t('userDirectory.title') }} <i class="collapse fa-solid fa-angle-right" :class="{ expanded: activeSidebarGroups['user-directory'] }" style="margin-left: 6px;"></i></div>
<Transition name="sidebar-item-group-animation">
<div class="sidebar-item-group" v-if="activeSidebarGroups['user-directory']">
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'user-directory-ldap-server' }" href="#/user-directory-ldap-server" @click="onSidebarClose()"><i class="fa fa-fw fa-users-rays"></i> {{ $t('users.exposedLdap.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'user-directory-openid-provider' }" href="#/user-directory-openid-provider" @click="onSidebarClose()"><i class="fa fa-fw fa-brands fa-openid"></i> {{ $t('oidc.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'user-directory-settings' }" href="#/user-directory-settings" @click="onSidebarClose()"><i class="fa fa-fw fa-cog"></i> {{ $t('userdirectory.settings.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.USER_DIRECTORY_LDAP_SERVER }" :href="VIEWS.USER_DIRECTORY_LDAP_SERVER" @click="onSidebarClose()"><i class="fa fa-fw fa-users-rays"></i> {{ $t('users.exposedLdap.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.USER_DIRECTORY_OPENID_PROVIDER }" :href="VIEWS.USER_DIRECTORY_OPENID_PROVIDER" @click="onSidebarClose()"><i class="fa fa-fw fa-brands fa-openid"></i> {{ $t('oidc.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.USER_DIRECTORY_SETTINGS }" :href="VIEWS.USER_DIRECTORY_SETTINGS" @click="onSidebarClose()"><i class="fa fa-fw fa-cog"></i> {{ $t('userdirectory.settings.title') }}</a>
</div>
</Transition>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'volumes' }" v-show="profile.isAtLeastAdmin" href="#/volumes" @click="onSidebarClose()"><i class="fa fa-hdd fa-fw"></i> {{ $t('volumes.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.VOLUMES }" v-show="profile.isAtLeastAdmin" :href="VIEWS.VOLUMES" @click="onSidebarClose()"><i class="fa fa-hdd fa-fw"></i> {{ $t('volumes.title') }}</a>
<hr v-show="profile.isAtLeastAdmin"/>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'system-info' }" v-show="profile.isAtLeastAdmin" href="#/system-info" @click="onSidebarClose()"><i class="fa fa-chart-area fa-fw"></i> {{ $t('system.title') }}</a>
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'cloudron-account' }" v-show="profile.isAtLeastOwner" href="#/cloudron-account" @click="onSidebarClose()"><i class="fa fa-crown fa-fw"></i> {{ $t('settings.appstoreAccount.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.SYSTEM_INFO }" v-show="profile.isAtLeastAdmin" :href="VIEWS.SYSTEM_INFO" @click="onSidebarClose()"><i class="fa fa-chart-area fa-fw"></i> {{ $t('system.title') }}</a>
<a class="sidebar-item" :class="{ active: view === VIEWS.CLOUDRON_ACCOUNT }" v-show="profile.isAtLeastOwner" :href="VIEWS.CLOUDRON_ACCOUNT" @click="onSidebarClose()"><i class="fa fa-crown fa-fw"></i> {{ $t('settings.appstoreAccount.title') }}</a>
</div>
</SideBar>