feat(admin-ui): implement RuoYi sidebar shell
This commit is contained in:
1 parent
96612607e5
commit
f6c5ad589f
3 files changed
+399
No files matched your search
@@ -0,0 +1,75 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import LayoutIcon from "@/components/layout/LayoutIcon.vue";
|
||||
import { getMenuIconName, visibleNavigableMenus } from "@/lib/menu-display";
|
||||
import type { NavigationType } from "@/lib/layout-settings";
|
||||
import type { AdminMenu } from "@/types";
|
||||
|
||||
type SidebarMenu = AdminMenu & { isVisible?: boolean };
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
menu: SidebarMenu;
|
||||
basePath?: string;
|
||||
collapsed?: boolean;
|
||||
navigationType?: NavigationType;
|
||||
}>(), {
|
||||
basePath: "",
|
||||
collapsed: false,
|
||||
navigationType: "left",
|
||||
});
|
||||
|
||||
function resolveMenuPath(basePath: string, menuPath: string | null | undefined): string | undefined {
|
||||
if (!menuPath) return undefined;
|
||||
if (menuPath.startsWith("/")) return menuPath;
|
||||
|
||||
const normalizedBasePath = basePath.replace(/^\/+|\/+$/g, "");
|
||||
const normalizedMenuPath = menuPath.trim().replace(/^\/+/, "");
|
||||
if (!normalizedMenuPath) return normalizedBasePath ? `/${normalizedBasePath}` : undefined;
|
||||
|
||||
return `/${[normalizedBasePath, normalizedMenuPath].filter(Boolean).join("/")}`.replace(/\/{2,}/g, "/");
|
||||
}
|
||||
|
||||
const resolvedPath = computed(() => resolveMenuPath(props.basePath, props.menu.path));
|
||||
const visibleChildren = computed(() => visibleNavigableMenus(props.menu.children ?? []));
|
||||
const childBasePath = computed(() => resolvedPath.value || props.basePath || "/");
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-sub-menu
|
||||
v-if="menu.type === 'directory' && visibleChildren.length > 0"
|
||||
:index="resolvedPath || menu.id"
|
||||
:aria-label="menu.name"
|
||||
:class="['sidebar-item', `sidebar-item--${navigationType}`]"
|
||||
>
|
||||
<template #title>
|
||||
<el-tooltip :content="menu.name" :disabled="!collapsed" placement="right">
|
||||
<span class="sidebar-item__content">
|
||||
<LayoutIcon :name="getMenuIconName(menu)" :title="collapsed ? menu.name : undefined" size="18" />
|
||||
<span v-if="!collapsed" class="sidebar-item__label">{{ menu.name }}</span>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<SidebarItem
|
||||
v-for="child in visibleChildren"
|
||||
:key="child.id"
|
||||
:menu="child"
|
||||
:base-path="childBasePath"
|
||||
:collapsed="collapsed"
|
||||
:navigation-type="navigationType"
|
||||
/>
|
||||
</el-sub-menu>
|
||||
|
||||
<el-menu-item
|
||||
v-else-if="menu.type === 'page' && resolvedPath"
|
||||
:index="resolvedPath"
|
||||
:aria-label="menu.name"
|
||||
:class="['sidebar-item', `sidebar-item--${navigationType}`]"
|
||||
>
|
||||
<el-tooltip :content="menu.name" :disabled="!collapsed" placement="right">
|
||||
<span class="sidebar-item__content">
|
||||
<LayoutIcon :name="getMenuIconName(menu)" :title="collapsed ? menu.name : undefined" size="18" />
|
||||
<span v-if="!collapsed" class="sidebar-item__label">{{ menu.name }}</span>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
Reference in new issue
Block a user