Skip to content

Commit 885e76c

Browse files
committed
feat: enhance settings routing
1 parent 0cb2ed2 commit 885e76c

File tree

3 files changed

+67
-6
lines changed

3 files changed

+67
-6
lines changed

adminforth/spa/src/afcl/VerticalTabs.vue

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<a
66
href="#"
77
@click="activeTab = tab"
8-
class="inline-flex items-center px-4 py-3 rounded-lg w-full"
8+
class="inline-flex items-center rounded-lg w-full"
99
:class="tab === activeTab ? 'text-lightVerticalTabsTextActive bg-lightVerticalTabsBackgroundActive active dark:bg-darkVerticalTabsBackgroundActive dark:text-darkVerticalTabsTextActive' : 'text-lightVerticalTabsText dark:text-darkVerticalTabsText hover:text-lightVerticalTabsTextHover bg-lightVerticalTabsBackground hover:bg-lightVerticalTabsBackgroundHover dark:bg-darkVerticalTabsBackground dark:hover:bg-darkVerticalTabsBackgroundHover dark:hover:darkVerticalTabsTextHover'"
1010
aria-current="page"
1111
>
@@ -31,6 +31,11 @@
3131
const emites = defineEmits([
3232
'update:activeTab',
3333
]);
34+
35+
defineExpose({
36+
setActiveTab
37+
});
38+
3439
onMounted(() => {
3540
const slots = useSlots();
3641
tabs.value = Object.keys(slots).reduce((tbs: string[], tb: string) => {
@@ -43,4 +48,10 @@
4348
activeTab.value = tabs.value[0];
4449
}
4550
});
51+
52+
function setActiveTab(tab: string) {
53+
if (tabs.value.includes(tab)) {
54+
activeTab.value = tab;
55+
}
56+
}
4657
</script>

adminforth/spa/src/router/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const router = createRouter({
6363
]
6464
},
6565
{
66-
path: '/settings',
66+
path: '/settings/:page?',
6767
name: 'settings',
6868
component: () => import('@/views/SettingsView.vue'),
6969
meta: {

adminforth/spa/src/views/SettingsView.vue

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@
7474
<div v-if="!coreStore?.config?.settingPages || coreStore?.config?.settingPages.length === 0">
7575
<p>No setting pages configured or still loading...</p>
7676
</div>
77-
<VerticalTabs v-else>
77+
<VerticalTabs v-else ref="VerticalTabsRef">
7878
<template v-for="(c,i) in coreStore?.config?.settingPages" :key="`tab:${settingPageSlotName(c,i)}`" v-slot:['tab:'+settingPageSlotName(c,i)]>
79-
<div class="flex items-center justify-center whitespace-nowrap px-4 mx-4 gap-2">
79+
<div class="flex items-center justify-center whitespace-nowrap px-8 py-3 gap-2" @click="setURL(c)">
8080
<component v-if="c.icon" :is="getIcon(c.icon)" class="w-5 h-5 group-hover:text-lightSidebarIconsHover transition duration-75 dark:group-hover:text-darkSidebarIconsHover dark:text-darkSidebarIcons" ></component>
8181
{{ c.pageLabel }}
8282
</div>
@@ -103,7 +103,9 @@ import { Dropdown } from 'flowbite';
103103
import { IconMoonSolid, IconSunSolid } from '@iconify-prerendered/vue-flowbite';
104104
import adminforth from '@/adminforth';
105105
import { VerticalTabs } from '@/afcl'
106+
import { useRoute } from 'vue-router'
106107
108+
const route = useRoute()
107109
const coreStore = useCoreStore();
108110
const userStore = useUserStore();
109111
const router = useRouter();
@@ -114,6 +116,7 @@ const loginRedirectCheckIsReady = ref(false);
114116
const sideBarOpen = ref(false);
115117
const theme = ref('light');
116118
const dropdownUserButton = ref<HTMLElement | null>(null);
119+
const VerticalTabsRef = ref();
117120
118121
async function initRouter() {
119122
await router.isReady();
@@ -155,8 +158,27 @@ onMounted(async () => {
155158
await loadMenu();
156159
await loadPublicConfig();
157160
loginRedirectCheckIsReady.value = true;
158-
console.log('Setting pages:', coreStore?.config?.settingPages);
159-
console.log('Full config:', coreStore?.config);
161+
const routeParamsPage = route?.params?.page;
162+
if (!routeParamsPage) {
163+
if (coreStore.config?.settingPages?.[0]) {
164+
setURL(coreStore.config.settingPages[0]);
165+
}
166+
} else {
167+
let isParamInTabs;
168+
for (const c of coreStore?.config?.settingPages || []) {
169+
if (c.slug ? c.slug === routeParamsPage : slugifyString(c.pageLabel) === routeParamsPage) {
170+
isParamInTabs = true;
171+
break;
172+
}
173+
}
174+
if (isParamInTabs) {
175+
VerticalTabsRef.value.setActiveTab(routeParamsPage);
176+
} else {
177+
if (coreStore.config?.settingPages?.[0]) {
178+
setURL(coreStore.config.settingPages[0]);
179+
}
180+
}
181+
}
160182
});
161183
162184
async function loadPublicConfig() {
@@ -168,4 +190,32 @@ async function loadMenu() {
168190
await coreStore.fetchMenuAndResource();
169191
}
170192
193+
function slugifyString(str: string): string {
194+
return str
195+
.toString()
196+
.toLowerCase()
197+
.replace(/\s+/g, '-')
198+
.replace(/[^a-z0-9-_]/g, '-');
199+
}
200+
201+
function setURL(item: {
202+
icon?: string | undefined;
203+
pageLabel: string;
204+
slug?: string | undefined;
205+
component?: string | undefined;
206+
}) {
207+
const slug = item?.slug;
208+
if (slug) {
209+
router.replace({
210+
name: 'settings',
211+
params: { page: slug }
212+
});
213+
} else {
214+
const slugified = slugifyString(item.pageLabel);
215+
router.replace({
216+
name: 'settings',
217+
params: { page: slugified }
218+
});
219+
}
220+
}
171221
</script>

0 commit comments

Comments
 (0)