feat(projects): 工作台小组件设计
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { VNode } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import { objectContextDomainConfigs } from '@/constants/object-context';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { useWorkbenchStore } from '@/store/modules/workbench';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
@@ -28,20 +30,27 @@ const { routerPushByKey } = useRouterPush();
|
||||
interface FlatMenu {
|
||||
key: string;
|
||||
label: string;
|
||||
icon?: string;
|
||||
/** 来自 routeStore.menus 的 icon VNode(SvgIconVNode 渲染产物,与侧栏菜单同源) */
|
||||
icon?: VNode;
|
||||
}
|
||||
|
||||
// 与 picker 保持一致:对象域入口(project_list / product_list)当叶子,
|
||||
// 其下的对象上下文页不进入快捷入口候选范围。
|
||||
const OBJECT_DOMAIN_ENTRY_KEYS = new Set(objectContextDomainConfigs.map(c => c.entryRouteKey));
|
||||
|
||||
function flatten(menus: typeof routeStore.menus): FlatMenu[] {
|
||||
const out: FlatMenu[] = [];
|
||||
function walk(list: typeof menus) {
|
||||
list.forEach((m: any) => {
|
||||
if (m.children && m.children.length) {
|
||||
const isDomainEntry = OBJECT_DOMAIN_ENTRY_KEYS.has(m.key);
|
||||
const hasChildren = !isDomainEntry && m.children && m.children.length > 0;
|
||||
if (hasChildren) {
|
||||
walk(m.children);
|
||||
} else {
|
||||
out.push({
|
||||
key: m.key,
|
||||
label: m.label as string,
|
||||
icon: m.i18nKey || m.icon || ''
|
||||
icon: m.icon
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -90,8 +99,15 @@ function handleConfirm(keys: string[]) {
|
||||
</div>
|
||||
<div v-else class="shortcut-grid">
|
||||
<button v-for="item in selected" :key="item.key" class="shortcut-item" @click="handleClick(item.key)">
|
||||
<SvgIcon icon="mdi:link-variant" />
|
||||
<span>{{ item.label }}</span>
|
||||
<ElIcon v-if="item.icon" class="shortcut-item__icon">
|
||||
<component :is="item.icon" />
|
||||
</ElIcon>
|
||||
<SvgIcon v-else icon="mdi:link-variant" class="shortcut-item__icon" />
|
||||
<span class="shortcut-item__label">{{ item.label }}</span>
|
||||
</button>
|
||||
<button class="shortcut-item shortcut-item--add" title="添加快捷入口" @click="openPicker">
|
||||
<SvgIcon icon="mdi:plus" />
|
||||
<span>添加</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -121,11 +137,37 @@ function handleConfirm(keys: string[]) {
|
||||
transition: all 120ms;
|
||||
}
|
||||
|
||||
.shortcut-item__icon {
|
||||
font-size: 20px;
|
||||
color: var(--el-color-primary);
|
||||
transition: color 120ms;
|
||||
}
|
||||
|
||||
.shortcut-item__label {
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.shortcut-item:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.shortcut-item--add {
|
||||
border-style: dashed;
|
||||
border-color: var(--el-border-color);
|
||||
background: transparent;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
.shortcut-item--add:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
background: var(--el-color-primary-light-9);
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.shortcut-empty {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user