perf: 模型管理界面重做

This commit is contained in:
2026-03-11 20:33:04 +08:00
parent 219fa566ef
commit 373d7f8201
37 changed files with 4120 additions and 2108 deletions

View File

@@ -6,7 +6,7 @@ interface Props {
contentPadding?: number | string;
dense?: boolean;
stickyToolbar?: boolean;
surface?: 'panel' | 'subtle';
surface?: 'panel' | 'plain' | 'subtle';
}
const props = withDefaults(defineProps<Props>(), {
@@ -141,6 +141,18 @@ const contentStyle = computed((): CSSProperties => {
box-shadow: none;
}
.list-page-shell.is-plain .list-page-shell__content {
background: hsl(var(--surface-panel) / 0.96);
border: 1px solid hsl(var(--divider-faint) / 0.58);
border-radius: 20px;
box-shadow: none;
backdrop-filter: none;
}
.list-page-shell.is-plain .list-page-shell__content::before {
display: none;
}
.list-page-shell__content::before {
position: absolute;
inset: 0 0 auto;

View File

@@ -0,0 +1,112 @@
import {mount} from '@vue/test-utils';
import {describe, expect, it, vi} from 'vitest';
import CardList from '../CardList.vue';
const { hasAccessByCodes } = vi.hoisted(() => ({
hasAccessByCodes: vi.fn((codes: string[]) => codes[0] !== 'blocked'),
}));
vi.mock('@easyflow/access', () => ({
useAccess: () => ({
hasAccessByCodes,
}),
}));
describe('CardList', () => {
function mountCardList(props: Record<string, unknown>) {
return mount(CardList, {
props: {
data: [
{
id: 'bot-1',
title: '演示卡片',
description: '用于验证主次交互是否正常工作',
},
],
defaultIcon: '/favicon.svg',
...props,
},
global: {
stubs: {
IconifyIcon: {
props: ['icon'],
template: '<span class="iconify-icon">{{ icon }}</span>',
},
},
},
});
}
it('点击卡片空白区域时触发主动作', async () => {
const primaryAction = vi.fn();
const wrapper = mountCardList({
primaryAction: {
text: '进入设置',
onClick: primaryAction,
},
});
await wrapper.get('.card-item').trigger('click');
expect(primaryAction).toHaveBeenCalledTimes(1);
expect(primaryAction).toHaveBeenCalledWith(
expect.objectContaining({ id: 'bot-1' }),
);
});
it('点击次级按钮时不会冒泡触发主动作', async () => {
const primaryAction = vi.fn();
const inlineAction = vi.fn();
const wrapper = mountCardList({
primaryAction: {
text: '进入设置',
onClick: primaryAction,
},
actions: [
{
text: '编辑',
placement: 'inline',
onClick: inlineAction,
},
],
});
await wrapper.get('.card-action-btn').trigger('click');
expect(inlineAction).toHaveBeenCalledTimes(1);
expect(primaryAction).not.toHaveBeenCalled();
});
it('键盘 Enter 可以触发主动作', async () => {
const primaryAction = vi.fn();
const wrapper = mountCardList({
primaryAction: {
text: '进入设计',
onClick: primaryAction,
},
});
await wrapper.get('.card-item').trigger('keydown.enter');
expect(primaryAction).toHaveBeenCalledTimes(1);
});
it('未提供主动作时保持旧卡片模式,不会把卡片变成可点击入口', async () => {
const legacyAction = vi.fn();
const wrapper = mountCardList({
actions: [
{
text: '编辑',
onClick: legacyAction,
},
],
});
await wrapper.get('.card-item').trigger('click');
await wrapper.get('.card-action-btn').trigger('click');
expect(wrapper.get('.card-item').attributes('role')).toBeUndefined();
expect(legacyAction).toHaveBeenCalledTimes(1);
});
});