adminforth 2.4.0-next.161 → 2.4.0-next.162
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/configValidator.d.ts.map +1 -1
- package/dist/modules/configValidator.js +3 -0
- package/dist/modules/configValidator.js.map +1 -1
- package/dist/modules/restApi.d.ts.map +1 -1
- package/dist/modules/restApi.js +1 -0
- package/dist/modules/restApi.js.map +1 -1
- package/dist/spa/package-lock.json +5 -4
- package/dist/spa/package.json +1 -1
- package/dist/spa/src/App.vue +33 -173
- package/dist/spa/src/components/MenuLink.vue +37 -13
- package/dist/spa/src/components/Sidebar.vue +411 -0
- package/dist/spa/src/spa_types/core.ts +4 -0
- package/dist/spa/src/types/Back.ts +13 -0
- package/dist/spa/src/types/Common.ts +4 -0
- package/dist/types/Back.d.ts +11 -0
- package/dist/types/Back.d.ts.map +1 -1
- package/dist/types/Back.js.map +1 -1
- package/dist/types/Common.d.ts +4 -0
- package/dist/types/Common.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/spa/src/App.vue
CHANGED
|
@@ -72,123 +72,21 @@
|
|
|
72
72
|
</div>
|
|
73
73
|
</nav>
|
|
74
74
|
|
|
75
|
-
<
|
|
76
|
-
ref="sidebarAside"
|
|
75
|
+
<Sidebar
|
|
77
76
|
v-if="loggedIn && routerIsReady && loginRedirectCheckIsReady && defaultLayout"
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
<div class="af-logo-title-wrapper flex ms-2 m-4">
|
|
84
|
-
<img v-if="coreStore.config?.showBrandLogoInSidebar !== false" :src="loadFile(coreStore.config?.brandLogo || '@/assets/logo.svg')" :alt="`${ coreStore.config?.brandName } Logo`" class="af-logo h-8 me-3" />
|
|
85
|
-
<span
|
|
86
|
-
v-if="coreStore.config?.showBrandNameInSidebar"
|
|
87
|
-
class="af-title self-center text-lightNavbarText-size font-semibold sm:text-lightNavbarText-size whitespace-nowrap dark:text-darkSidebarText text-lightSidebarText"
|
|
88
|
-
>
|
|
89
|
-
{{ coreStore.config?.brandName }}
|
|
90
|
-
</span>
|
|
91
|
-
<div class="flex items-center gap-2 w-auto" :class="{'w-full justify-end': coreStore.config?.showBrandLogoInSidebar === false}">
|
|
92
|
-
<component
|
|
93
|
-
v-for="c in coreStore?.config?.globalInjections?.sidebarTop || []"
|
|
94
|
-
:is="getCustomComponent(c)"
|
|
95
|
-
:meta="c.meta"
|
|
96
|
-
:adminUser="coreStore.adminUser"
|
|
97
|
-
/>
|
|
98
|
-
</div>
|
|
99
|
-
</div>
|
|
100
|
-
|
|
101
|
-
<ul class="af-sidebar-container space-y-2 font-medium">
|
|
102
|
-
<template v-for="(item, i) in coreStore.menu" :key="`menu-${i}`">
|
|
103
|
-
<div v-if="item.type === 'divider'" class="border-t border-lightSidebarDevider dark:border-darkSidebarDevider"></div>
|
|
104
|
-
<div v-else-if="item.type === 'gap'" class="flex items-center justify-center h-8"></div>
|
|
105
|
-
<div v-else-if="item.type === 'heading'" class="flex items-center justify-left pl-2 h-8 text-lightSidebarHeading dark:text-darkSidebarHeading
|
|
106
|
-
">{{ item.label }}</div>
|
|
107
|
-
<li v-else-if="item.children" class="af-sidebar-expand-container">
|
|
108
|
-
<button @click="clickOnMenuItem(i)" type="button" class="af-sidebar-expand-button flex items-center w-full p-2 text-base text-lightSidebarText rounded-default transition duration-75 group hover:bg-lightSidebarItemHover hover:text-lightSidebarTextHover dark:text-darkSidebarText dark:hover:bg-darkSidebarHover dark:hover:text-darkSidebarTextHover"
|
|
109
|
-
:class="opened.includes(i) ? 'af-sidebar-dropdown-expanded' : 'af-sidebar-dropdown-collapsed'"
|
|
110
|
-
:aria-controls="`dropdown-example${i}`"
|
|
111
|
-
:data-collapse-toggle="`dropdown-example${i}`"
|
|
112
|
-
>
|
|
113
|
-
|
|
114
|
-
<component v-if="item.icon" :is="getIcon(item.icon)" class="w-5 h-5 text-lightSidebarIcons group-hover:text-lightSidebarIconsHover transition duration-75 dark:group-hover:text-darkSidebarIconsHover dark:text-darkSidebarIcons" ></component>
|
|
115
|
-
|
|
116
|
-
<span class="text-ellipsis overflow-hidden flex-1 ms-3 text-left rtl:text-right whitespace-nowrap">{{ item.label }}
|
|
117
|
-
|
|
118
|
-
<span v-if="item.badge" class="inline-flex items-center justify-center w-3 h-3 p-3 ms-3 text-sm font-medium rounded-full bg-lightAnnouncementBG dark:bg-darkAnnouncementBG
|
|
119
|
-
fill-lightAnnouncementText dark:fill-darkAccent text-lightAnnouncementText dark:text-darkAccent">
|
|
120
|
-
<Tooltip v-if="item.badgeTooltip">
|
|
121
|
-
{{ item.badge }}
|
|
122
|
-
<template #tooltip>
|
|
123
|
-
{{ item.badgeTooltip }}
|
|
124
|
-
</template>
|
|
125
|
-
</Tooltip>
|
|
126
|
-
<template v-else>
|
|
127
|
-
{{ item.badge }}
|
|
128
|
-
</template>
|
|
129
|
-
</span>
|
|
130
|
-
</span>
|
|
131
|
-
|
|
132
|
-
<svg :class="{'rotate-180': opened.includes(i) }" class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
|
133
|
-
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4"/>
|
|
134
|
-
</svg>
|
|
135
|
-
</button>
|
|
136
|
-
|
|
137
|
-
<ul :id="`dropdown-example${i}`" role="none" class="af-sidebar-dropdown pt-1 space-y-1" :class="{ 'hidden': !opened.includes(i) }">
|
|
138
|
-
<template v-for="(child, j) in item.children" :key="`menu-${i}-${j}`">
|
|
139
|
-
<li class="af-sidebar-menu-link">
|
|
140
|
-
<MenuLink :item="child" isChild="true" @click="hideSidebar"/>
|
|
141
|
-
</li>
|
|
142
|
-
</template>
|
|
143
|
-
</ul>
|
|
144
|
-
</li>
|
|
145
|
-
<li v-else class="af-sidebar-menu-link">
|
|
146
|
-
<MenuLink :item="item" @click="hideSidebar"/>
|
|
147
|
-
</li>
|
|
148
|
-
</template>
|
|
149
|
-
</ul>
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
<div id="dropdown-cta" class="p-4 mt-6 rounded-lg bg-lightAnnouncementBG dark:bg-darkAnnouncementBG
|
|
153
|
-
fill-lightAnnouncementText dark:fill-darkAccent text-lightAnnouncementText dark:text-darkAccent text-sm" role="alert"
|
|
154
|
-
v-if="ctaBadge"
|
|
155
|
-
>
|
|
156
|
-
<div class="flex items-center mb-3" :class="!ctaBadge.title ? 'float-right' : ''">
|
|
157
|
-
<!-- <span class="bg-lightPrimaryOpacity dark:bg-darkPrimaryOpacity text-sm font-semibold me-2 px-2.5 py-0.5 rounded "
|
|
158
|
-
v-if="ctaBadge.title"
|
|
159
|
-
> -->
|
|
160
|
-
<span>
|
|
161
|
-
{{ctaBadge.title}}
|
|
162
|
-
</span>
|
|
163
|
-
<button type="button"
|
|
164
|
-
class="ms-auto -mx-1.5 -my-1.5 bg-lightPrimaryOpacity dark:bg-darkPrimaryOpacity inline-flex justify-center items-center w-6 h-6 rounded-lg p-1 hover:brightness-110"
|
|
165
|
-
|
|
166
|
-
data-dismiss-target="#dropdown-cta" aria-label="Close"
|
|
167
|
-
v-if="ctaBadge?.closable" @click="closeCTA"
|
|
168
|
-
>
|
|
169
|
-
<span class="sr-only">Close</span>
|
|
170
|
-
<svg class="w-2.5 h-2.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
|
|
171
|
-
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
|
|
172
|
-
</svg>
|
|
173
|
-
</button>
|
|
174
|
-
</div>
|
|
175
|
-
<p class="mb-3 text-sm " v-if="ctaBadge.html" v-html="ctaBadge.html"></p>
|
|
176
|
-
<p class="mb-3 text-sm fill-lightNavbarText dark:fill-darkPrimary text-lightNavbarText dark:text-darkNavbarPrimary" v-else>
|
|
177
|
-
{{ ctaBadge.text }}
|
|
178
|
-
</p>
|
|
179
|
-
<!-- <a class="text-sm text-lightPrimary underline font-medium hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300" href="#">Turn new navigation off</a> -->
|
|
180
|
-
</div>
|
|
181
|
-
|
|
182
|
-
<component
|
|
183
|
-
v-for="c in coreStore?.config?.globalInjections?.sidebar || []"
|
|
184
|
-
:is="getCustomComponent(c)"
|
|
185
|
-
:meta="c.meta"
|
|
186
|
-
:adminUser="coreStore.adminUser"
|
|
187
|
-
/>
|
|
188
|
-
</div>
|
|
189
|
-
</aside>
|
|
77
|
+
:sideBarOpen="sideBarOpen"
|
|
78
|
+
@hideSidebar="hideSidebar"
|
|
79
|
+
@loadMenu="loadMenu"
|
|
80
|
+
@sidebarStateChange="handleSidebarStateChange"
|
|
81
|
+
/>
|
|
190
82
|
|
|
191
|
-
<div class="
|
|
83
|
+
<div class="transition-all duration-300 ease-in-out max-w-[100vw]"
|
|
84
|
+
:class="{
|
|
85
|
+
'sm:ml-18': isSidebarIconOnly,
|
|
86
|
+
'sm:ml-64': !isSidebarIconOnly,
|
|
87
|
+
'sm:max-w-[calc(100%-4.5rem)]': isSidebarIconOnly,
|
|
88
|
+
'sm:max-w-[calc(100%-16rem)]': !isSidebarIconOnly
|
|
89
|
+
}"
|
|
192
90
|
v-if="loggedIn && routerIsReady && loginRedirectCheckIsReady && defaultLayout">
|
|
193
91
|
<div class="p-0 dark:border-gray-700 mt-14">
|
|
194
92
|
<RouterView/>
|
|
@@ -248,10 +146,20 @@
|
|
|
248
146
|
@apply opacity-100;
|
|
249
147
|
}
|
|
250
148
|
|
|
149
|
+
@media (min-width: 640px) {
|
|
150
|
+
.sm\:ml-18 {
|
|
151
|
+
margin-left: 4.5rem;
|
|
152
|
+
}
|
|
153
|
+
.sm\:max-w-\[calc\(100\%-4\.5rem\)\] {
|
|
154
|
+
max-width: calc(100% - 4.5rem);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
|
|
251
159
|
</style>
|
|
252
160
|
|
|
253
161
|
<script setup lang="ts">
|
|
254
|
-
import { computed, onMounted, ref, watch, onBeforeMount
|
|
162
|
+
import { computed, onMounted, ref, watch, onBeforeMount } from 'vue';
|
|
255
163
|
import { RouterView } from 'vue-router';
|
|
256
164
|
import { Dropdown } from 'flowbite'
|
|
257
165
|
import './index.scss'
|
|
@@ -259,16 +167,12 @@ import { useCoreStore } from '@/stores/core';
|
|
|
259
167
|
import { useUserStore } from '@/stores/user';
|
|
260
168
|
import { IconMoonSolid, IconSunSolid } from '@iconify-prerendered/vue-flowbite';
|
|
261
169
|
import AcceptModal from './components/AcceptModal.vue';
|
|
262
|
-
import
|
|
170
|
+
import Sidebar from './components/Sidebar.vue';
|
|
263
171
|
import { useRoute, useRouter } from 'vue-router';
|
|
264
|
-
import { getIcon, verySimpleHash } from '@/utils';
|
|
265
172
|
import { createHead } from 'unhead'
|
|
266
|
-
import {
|
|
173
|
+
import { getCustomComponent } from '@/utils';
|
|
267
174
|
import Toast from './components/Toast.vue';
|
|
268
175
|
import {useToastStore} from '@/stores/toast';
|
|
269
|
-
import { getCustomComponent } from '@/utils';
|
|
270
|
-
import type { AdminForthConfigMenuItem, AnnouncementBadgeResponse } from './types/Common';
|
|
271
|
-
import { Tooltip } from '@/afcl';
|
|
272
176
|
import { initFrontedAPI } from '@/adminforth';
|
|
273
177
|
import adminforth from '@/adminforth';
|
|
274
178
|
import UserMenuSettingsButton from './components/UserMenuSettingsButton.vue';
|
|
@@ -284,16 +188,15 @@ const sideBarOpen = ref(false);
|
|
|
284
188
|
const defaultLayout = ref(true);
|
|
285
189
|
const route = useRoute();
|
|
286
190
|
const router = useRouter();
|
|
287
|
-
//create a ref to store the opened menu items with ts type;
|
|
288
|
-
const opened = ref<(string|number)[]>([]);
|
|
289
191
|
const publicConfigLoaded = ref(false);
|
|
290
192
|
const dropdownUserButton = ref(null);
|
|
291
193
|
|
|
292
|
-
const sidebarAside = ref(null);
|
|
293
194
|
|
|
294
195
|
const routerIsReady = ref(false);
|
|
295
196
|
const loginRedirectCheckIsReady = ref(false);
|
|
296
197
|
|
|
198
|
+
const isSidebarIconOnly = ref(localStorage.getItem('afIconOnlySidebar') === 'true');
|
|
199
|
+
|
|
297
200
|
const loggedIn = computed(() => !!coreStore?.adminUser);
|
|
298
201
|
|
|
299
202
|
const theme = ref('light');
|
|
@@ -302,19 +205,16 @@ function hideSidebar(): void {
|
|
|
302
205
|
sideBarOpen.value = false;
|
|
303
206
|
}
|
|
304
207
|
|
|
208
|
+
function handleSidebarStateChange(state: { isSidebarIconOnly: boolean }) {
|
|
209
|
+
isSidebarIconOnly.value = state.isSidebarIconOnly;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
|
|
305
213
|
function toggleTheme() {
|
|
306
214
|
theme.value = theme.value === 'light' ? 'dark' : 'light';
|
|
307
215
|
coreStore.toggleTheme();
|
|
308
216
|
}
|
|
309
217
|
|
|
310
|
-
function clickOnMenuItem(label: string | number) {
|
|
311
|
-
if (opened.value.includes(label)) {
|
|
312
|
-
opened.value = opened.value.filter((item) => item !== label);
|
|
313
|
-
} else {
|
|
314
|
-
opened.value.push(label);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
}
|
|
318
218
|
|
|
319
219
|
async function logout() {
|
|
320
220
|
userStore.unauthorize();
|
|
@@ -374,13 +274,6 @@ watch([route, () => coreStore.resourceById, () => coreStore.config], async () =>
|
|
|
374
274
|
|
|
375
275
|
});
|
|
376
276
|
|
|
377
|
-
watch(()=>coreStore.menu, () => {
|
|
378
|
-
coreStore.menu.forEach((item, i) => {
|
|
379
|
-
if (item.open) {
|
|
380
|
-
opened.value.push(i);
|
|
381
|
-
};
|
|
382
|
-
});
|
|
383
|
-
})
|
|
384
277
|
|
|
385
278
|
watch(dropdownUserButton, (dropdownUserButton) => {
|
|
386
279
|
if (dropdownUserButton) {
|
|
@@ -399,11 +292,6 @@ async function loadPublicConfig() {
|
|
|
399
292
|
publicConfigLoaded.value = true;
|
|
400
293
|
}
|
|
401
294
|
|
|
402
|
-
watch(sidebarAside, (sidebarAside) => {
|
|
403
|
-
if (sidebarAside) {
|
|
404
|
-
coreStore.fetchMenuBadges();
|
|
405
|
-
}
|
|
406
|
-
})
|
|
407
295
|
|
|
408
296
|
// initialize components based on data attribute selectors
|
|
409
297
|
onMounted(async () => {
|
|
@@ -431,32 +319,4 @@ watch(() => coreStore.config?.singleTheme, (singleTheme) => {
|
|
|
431
319
|
}
|
|
432
320
|
}, { immediate: true })
|
|
433
321
|
|
|
434
|
-
|
|
435
|
-
const ctaBadge: Ref<(AnnouncementBadgeResponse & { hash: string; }) | null> = computed(() => {
|
|
436
|
-
const badge = coreStore.config?.announcementBadge;
|
|
437
|
-
if (!badge) {
|
|
438
|
-
return null;
|
|
439
|
-
}
|
|
440
|
-
const hash = badge.closable ? verySimpleHash(JSON.stringify(badge)) : '';
|
|
441
|
-
if (badge.closable && window.localStorage.getItem(`ctaBadge-${hash}`)) {
|
|
442
|
-
return null;
|
|
443
|
-
}
|
|
444
|
-
return {...badge, hash};
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
function closeCTA() {
|
|
448
|
-
if (!ctaBadge.value) {
|
|
449
|
-
return;
|
|
450
|
-
}
|
|
451
|
-
const hash = ctaBadge.value.hash;
|
|
452
|
-
window.localStorage.setItem(`ctaBadge-${hash}`, '1');
|
|
453
|
-
nextTick( async() => {
|
|
454
|
-
loadMenu();
|
|
455
|
-
await coreStore.fetchMenuBadges();
|
|
456
|
-
adminforth.menu.refreshMenuBadges();
|
|
457
|
-
})
|
|
458
|
-
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
|
|
462
322
|
</script>
|
|
@@ -1,24 +1,46 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<RouterLink
|
|
3
3
|
:to="{name: item.resourceId ? 'resource-list' : item.path, params: item.resourceId ? { resourceId: item.resourceId }: {}}"
|
|
4
|
-
class="flex group items-center py-2 text-lightSidebarText dark:text-darkSidebarText rounded-default
|
|
4
|
+
class="af-menu-link flex group relative items-center w-full py-2 text-lightSidebarText dark:text-darkSidebarText rounded-default transition-all duration-200 ease-in-out"
|
|
5
5
|
:class="{
|
|
6
|
-
'
|
|
7
|
-
'
|
|
6
|
+
'ml-1': isSidebarIconOnly && !isSidebarHovering && isChild,
|
|
7
|
+
'hover:bg-lightSidebarItemHover hover:text-lightSidebarTextHover dark:hover:bg-darkSidebarItemHover dark:hover:text-darkSidebarTextHover active:bg-lightSidebarActive dark:active:bg-darkSidebarHover': !['divider', 'gap', 'heading'].includes(item.type),
|
|
8
|
+
'px-6': (isChild && !isSidebarIconOnly && !isSidebarHovering) || (isChild && isSidebarIconOnly && isSidebarHovering),
|
|
9
|
+
'px-3.5': !isChild || (isSidebarIconOnly && !isSidebarHovering),
|
|
10
|
+
'max-w-13': isSidebarIconOnly && !isSidebarHovering,
|
|
8
11
|
'bg-lightSidebarItemActive dark:bg-darkSidebarItemActive': item.resourceId ?
|
|
9
12
|
($route.params.resourceId === item.resourceId && $route.name === 'resource-list') :
|
|
10
13
|
($route.name === item.path)
|
|
11
14
|
}"
|
|
12
15
|
>
|
|
13
|
-
<component v-if="item.icon" :is="getIcon(item.icon)"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
<component v-if="item.icon" :is="getIcon(item.icon)"
|
|
17
|
+
class="text-lightSidebarIcons dark:text-darkSidebarIcons group-hover:text-lightSidebarIconsHover dark:group-hover:text-darkSidebarIconsHover transition-all duration-200 ease-in-out"
|
|
18
|
+
:class="{
|
|
19
|
+
'min-w-4 min-h-4': isSidebarIconOnly && !isSidebarHovering && isChild,
|
|
20
|
+
'min-w-5 min-h-5': !(isSidebarIconOnly && !isSidebarHovering && isChild)
|
|
21
|
+
}" >
|
|
22
|
+
</component>
|
|
23
|
+
<span
|
|
24
|
+
class="overflow-hidden block ms-3 text-left rtl:text-right transition-all duration-200 ease-in-out"
|
|
25
|
+
:class="{
|
|
26
|
+
'opacity-0 ms-0 translate-x-4 flex-none': isSidebarIconOnly && !isSidebarHovering,
|
|
27
|
+
'opacity-100 ms-3 translate-x-0 flex-none': isSidebarIconOnly && isSidebarHovering,
|
|
28
|
+
'opacity-100 ms-3 translate-x-0 flex-1': !isSidebarIconOnly
|
|
29
|
+
}"
|
|
30
|
+
:style="isSidebarIconOnly ? {
|
|
31
|
+
minWidth: isChild
|
|
32
|
+
? 'calc(16.5rem - 0.75rem*2 - 1.5rem*2 - 1.25rem - 0.75rem)'
|
|
33
|
+
: 'calc(16.5rem - 0.75rem*2 - 0.875rem*2 - 1.25rem - 0.75rem)',
|
|
34
|
+
width: isChild
|
|
35
|
+
? 'calc(16.5rem - 0.75rem*2 - 1.5rem*2 - 1.25rem - 0.75rem)'
|
|
36
|
+
: 'calc(16.5rem - 0.75rem*2 - 0.875rem*2 - 1.25rem - 0.75rem)'
|
|
37
|
+
} : {}"
|
|
16
38
|
>
|
|
17
|
-
|
|
39
|
+
{{ item.label }}
|
|
40
|
+
<template v-if="item.badge && (!isSidebarIconOnly || (isSidebarIconOnly && isSidebarHovering))">
|
|
18
41
|
<Tooltip v-if="item.badgeTooltip">
|
|
19
42
|
<div class="af-badge inline-flex items-center justify-center h-3 py-3 px-1 ms-3 text-sm font-medium rounded-full bg-lightAnnouncementBG dark:bg-darkAnnouncementBG
|
|
20
43
|
fill-lightAnnouncementText dark:fill-darkAccent text-lightAnnouncementText dark:text-darkAccent min-w-[1.5rem] max-w-[3rem]">{{ item.badge }}</div>
|
|
21
|
-
|
|
22
44
|
<template #tooltip>
|
|
23
45
|
{{ item.badgeTooltip }}
|
|
24
46
|
</template>
|
|
@@ -26,17 +48,19 @@
|
|
|
26
48
|
<template v-else>
|
|
27
49
|
<div class="af-badge inline-flex items-center justify-center h-3 py-3 px-1 ms-3 text-sm font-medium rounded-full bg-lightAnnouncementBG dark:bg-darkAnnouncementBG
|
|
28
50
|
fill-lightAnnouncementText dark:fill-darkAccent text-lightAnnouncementText dark:text-darkAccent min-w-[1.5rem] max-w-[3rem]">{{ item.badge }}</div>
|
|
29
|
-
</template>
|
|
30
|
-
|
|
51
|
+
</template>
|
|
52
|
+
</template>
|
|
31
53
|
</span>
|
|
32
|
-
|
|
54
|
+
<div v-if="item.badge && isSidebarIconOnly && !isSidebarHovering" class="af-badge absolute right-1 top-1/2 -translate-y-1/2 inline-flex items-center justify-center h-2 w-2 text-sm font-medium rounded-full bg-lightAnnouncementBG dark:bg-darkAnnouncementBG
|
|
55
|
+
fill-lightAnnouncementText dark:fill-darkAccent text-lightAnnouncementText dark:text-darkAccent">
|
|
56
|
+
</div>
|
|
33
57
|
</RouterLink>
|
|
34
58
|
</template>
|
|
35
59
|
|
|
36
|
-
<script setup lang="ts">
|
|
60
|
+
<script setup lang="ts">
|
|
37
61
|
import { getIcon } from '@/utils';
|
|
38
62
|
import { Tooltip } from '@/afcl';
|
|
39
|
-
const props = defineProps(['item', 'isChild']);
|
|
40
63
|
|
|
64
|
+
defineProps(['item', 'isChild', 'isSidebarIconOnly', 'isSidebarHovering']);
|
|
41
65
|
|
|
42
66
|
</script>
|