diff --git a/ui/AGENTS.md b/ui/AGENTS.md index 3335014f868..53b24c53091 100644 --- a/ui/AGENTS.md +++ b/ui/AGENTS.md @@ -56,8 +56,9 @@ ui/ │ ├── api/ # Request infrastructure, business APIs, and shared API types │ │ ├── types/ # Types shared by APIs and their View or Component consumers │ │ └── API_README.md # API layering, placement, typing, and request rules -│ ├── components/ # Shared UI components +│ ├── components/ # Shared UI and cross-page business components │ │ ├── COMPONENT_README.md # Shared component conventions and usage +│ │ ├── business/ # Cross-page business components, imported explicitly │ │ ├── global/ # Frequently used components auto-registered by Vite │ │ │ └── mk-icon/ # Unified SVG Symbol and Element Plus icon component │ │ └── / # Less-frequent shared components imported explicitly @@ -95,6 +96,8 @@ Directories marked as reserved may be empty while their feature is being introdu Structural responsibilities: +- Put cross-page business components in `components/business/`, name them after their business + responsibility without the `Mk` prefix, and keep page-specific components in their owning View. - Put reusable application chrome in `layout/`, not in individual route views. - Put server communication in `api/`, isolate Admin and Chat request systems, and group business APIs by domain and resource according to `src/api/API_README.md`. diff --git a/ui/package.json b/ui/package.json index 46c9b08dcaf..da03db621c8 100644 --- a/ui/package.json +++ b/ui/package.json @@ -17,6 +17,7 @@ }, "dependencies": { "@element-plus/icons-vue": "^2.3.2", + "@he-tree/vue": "^2.10.5", "axios": "^1.19.0", "dingtalk-jsapi": "^3.2.9", "element-plus": "^2.14.2", diff --git a/ui/src/api/admin/workspace/folder.ts b/ui/src/api/admin/workspace/folder.ts new file mode 100644 index 00000000000..dd9a32282eb --- /dev/null +++ b/ui/src/api/admin/workspace/folder.ts @@ -0,0 +1,59 @@ +import { del, get, post, put } from '../core/request' +import type { + FolderSource, + WorkspaceFolder, + WorkspaceFolderCreatePayload, + WorkspaceFolderQuery, + WorkspaceFolderUpdatePayload, +} from '@/api/types' + +const getPrefix = (workspaceId: string, source: FolderSource) => + `/workspace/${workspaceId}/${source}/folder` + +/** 获取指定资源模块的 Workspace 文件夹树。 */ +const getFolderTree = (workspaceId: string, source: FolderSource, query?: WorkspaceFolderQuery) => { + return get(getPrefix(workspaceId, source), query) +} + +/** 获取指定 Workspace 文件夹详情。 */ +const getFolderDetail = (workspaceId: string, source: FolderSource, folderId: string) => { + return get(`${getPrefix(workspaceId, source)}/${folderId}`) +} + +/** 在指定资源模块中创建 Workspace 文件夹。 */ +const postFolder = ( + workspaceId: string, + source: FolderSource, + payload: WorkspaceFolderCreatePayload, +) => { + return post( + getPrefix(workspaceId, source), + payload, + ) +} + +/** 更新指定 Workspace 文件夹。 */ +const putFolder = ( + workspaceId: string, + source: FolderSource, + folderId: string, + payload: WorkspaceFolderUpdatePayload, +) => { + return put( + `${getPrefix(workspaceId, source)}/${folderId}`, + payload, + ) +} + +/** 删除指定 Workspace 文件夹及其中的资源。 */ +const deleteFolder = (workspaceId: string, source: FolderSource, folderId: string) => { + return del(`${getPrefix(workspaceId, source)}/${folderId}`) +} + +export default { + deleteFolder, + getFolderDetail, + getFolderTree, + postFolder, + putFolder, +} diff --git a/ui/src/api/admin/workspace/tool/tool.ts b/ui/src/api/admin/workspace/tool/tool.ts index 50568ba4bd0..ee215d88bac 100644 --- a/ui/src/api/admin/workspace/tool/tool.ts +++ b/ui/src/api/admin/workspace/tool/tool.ts @@ -2,8 +2,6 @@ import { del, get, post, put } from '../../core/request' import type { ParamsPage, ResponsePage } from '../../core/types' import type { ToolCatalogResponse, - ToolFolder, - ToolFolderPayload, ToolListQuery, ToolPayload, ToolTreeResponse, @@ -11,7 +9,6 @@ import type { } from '@/api/types' const getPrefix = (workspaceId: string) => `/workspace/${workspaceId}/tool` -const getFolderPrefix = (workspaceId: string) => `/workspace/${workspaceId}/TOOL/folder` /** 获取当前目录下的工具和子文件夹。 */ const getToolTree = (workspaceId: string, query?: ToolListQuery) => { @@ -31,26 +28,6 @@ const getToolPage = (workspaceId: string, page: ParamsPage, query?: ToolListQuer ) } -/** 获取工具文件夹树。 */ -const getToolFolderTree = (workspaceId: string) => { - return get(getFolderPrefix(workspaceId)) -} - -/** 创建工具文件夹。 */ -const postToolFolder = (workspaceId: string, payload: ToolFolderPayload) => { - return post(getFolderPrefix(workspaceId), payload) -} - -/** 更新工具文件夹。 */ -const putToolFolder = (workspaceId: string, folderId: string, payload: ToolFolderPayload) => { - return put(`${getFolderPrefix(workspaceId)}/${folderId}`, payload) -} - -/** 删除工具文件夹及其内容。 */ -const deleteToolFolder = (workspaceId: string, folderId: string) => { - return del(`${getFolderPrefix(workspaceId)}/${folderId}`) -} - /** 创建工作空间工具。 */ const postTool = (workspaceId: string, payload: ToolPayload) => { return post(getPrefix(workspaceId), payload) @@ -93,17 +70,13 @@ const putBatchMoveTools = (workspaceId: string, toolIds: string[], folderId: str export default { deleteTool, - deleteToolFolder, getToolCatalog, getToolDetail, - getToolFolderTree, getToolPage, getToolTree, postTool, - postToolFolder, postToolTestConnection, putBatchDeleteTools, putBatchMoveTools, putTool, - putToolFolder, } diff --git a/ui/src/api/types/index.ts b/ui/src/api/types/index.ts index 87b4c7c4986..b39aa8fc968 100644 --- a/ui/src/api/types/index.ts +++ b/ui/src/api/types/index.ts @@ -11,3 +11,5 @@ export type * from './system-operate-log' export * from './system-role' export type * from './system-email' export * from './workspace-model' +export * from './workspace-folder' +export * from './workspace-tool' diff --git a/ui/src/api/types/workspace-folder.ts b/ui/src/api/types/workspace-folder.ts new file mode 100644 index 00000000000..7245b1d52e0 --- /dev/null +++ b/ui/src/api/types/workspace-folder.ts @@ -0,0 +1,38 @@ +/** Workspace 下多个资源模块共用的文件夹业务类型。 */ + +export const FOLDER_SOURCE = { + APPLICATION: 'APPLICATION', + KNOWLEDGE: 'KNOWLEDGE', + TOOL: 'TOOL', +} as const + +export type FolderSource = (typeof FOLDER_SOURCE)[keyof typeof FOLDER_SOURCE] + +export interface WorkspaceFolder { + children?: WorkspaceFolder[] + create_time?: string + desc?: string | null + id: string + name: string + parent_id?: string | null + update_time?: string + user_id?: string | null + workspace_id: string +} + +export interface WorkspaceFolderCreatePayload { + desc?: string | null + name: string + parent_id?: string | null +} + +export interface WorkspaceFolderUpdatePayload { + desc?: string | null + name?: string + parent_id?: string | null +} + +export interface WorkspaceFolderQuery { + name?: string + [key: string]: unknown +} diff --git a/ui/src/api/types/workspace-tool.ts b/ui/src/api/types/workspace-tool.ts new file mode 100644 index 00000000000..3234818bf26 --- /dev/null +++ b/ui/src/api/types/workspace-tool.ts @@ -0,0 +1,84 @@ +/** Workspace 工具列表和工具维护共用的业务类型。 */ + +import type { WorkspaceFolder } from './workspace-folder' + +export const TOOL_SCOPE = { + INTERNAL: 'INTERNAL', + SHARED: 'SHARED', + WORKSPACE: 'WORKSPACE', +} as const + +export const TOOL_TYPE = { + CUSTOM: 'CUSTOM', + DATA_SOURCE: 'DATA_SOURCE', + INTERNAL: 'INTERNAL', + MCP: 'MCP', + SKILL: 'SKILL', + WORKFLOW: 'WORKFLOW', +} as const + +export type ToolScope = (typeof TOOL_SCOPE)[keyof typeof TOOL_SCOPE] +export type ToolType = (typeof TOOL_TYPE)[keyof typeof TOOL_TYPE] + +export interface WorkspaceTool { + code?: string + create_time?: string + desc?: string | null + folder_id?: string + icon?: string + id: string + init_field_list?: Record[] + init_params?: Record | string | null + input_field_list?: Record[] + is_active: boolean + label?: string | null + name: string + nick_name?: string | null + scope: ToolScope + source?: 'shared' | 'workspace' + template_id?: string | null + tool_type: ToolType + update_time?: string + user_id?: string | null + version?: string | null + workspace_id: string +} + +export interface ToolCatalogResponse { + shared_tools: WorkspaceTool[] + tools: WorkspaceTool[] +} + +export interface ToolTreeResponse { + folders: WorkspaceFolder[] + tools: WorkspaceTool[] +} + +export interface ToolListQuery { + create_user?: string + folder_id?: string + name?: string + scope?: ToolScope + tool_type?: ToolType + 'tool_type_list[]'?: ToolType[] + [key: string]: unknown +} + +export interface ToolPayload { + code?: string + desc?: string | null + folder_id?: string | null + icon?: string + init_field_list?: Record[] + init_params?: Record | null + input_field_list?: Record[] + is_active?: boolean + name?: string + scope?: ToolScope + tool_type?: ToolType +} + +export interface AddStoreToolPayload { + folder_id?: string | null + name?: string +} diff --git a/ui/src/assets/iconfont.js b/ui/src/assets/iconfont.js index 6c155e627b9..b7499a89dc6 100644 --- a/ui/src/assets/iconfont.js +++ b/ui/src/assets/iconfont.js @@ -1 +1 @@ -window._iconfont_svg_string_5200172='',(l=>{var a=(h=(h=document.getElementsByTagName("script"))[h.length-1]).getAttribute("data-injectcss"),h=h.getAttribute("data-disable-injectsvg");if(!h){var v,o,t,i,c,e=function(a,h){h.parentNode.insertBefore(a,h)};if(a&&!l.__iconfont__svg__cssinject__){l.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(a){console&&console.log(a)}}v=function(){var a,h=document.createElement("div");h.innerHTML=l._iconfont_svg_string_5200172,(h=h.getElementsByTagName("svg")[0])&&(h.setAttribute("aria-hidden","true"),h.style.position="absolute",h.style.width=0,h.style.height=0,h.style.overflow="hidden",h=h,(a=document.body).firstChild?e(h,a.firstChild):a.appendChild(h))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(v,0):(o=function(){document.removeEventListener("DOMContentLoaded",o,!1),v()},document.addEventListener("DOMContentLoaded",o,!1)):document.attachEvent&&(t=v,i=l.document,c=!1,m(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,d())})}function d(){c||(c=!0,t())}function m(){try{i.documentElement.doScroll("left")}catch(a){return void setTimeout(m,50)}d()}})(window); \ No newline at end of file +window._iconfont_svg_string_5200172='',(l=>{var a=(h=(h=document.getElementsByTagName("script"))[h.length-1]).getAttribute("data-injectcss"),h=h.getAttribute("data-disable-injectsvg");if(!h){var v,o,t,i,c,e=function(a,h){h.parentNode.insertBefore(a,h)};if(a&&!l.__iconfont__svg__cssinject__){l.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(a){console&&console.log(a)}}v=function(){var a,h=document.createElement("div");h.innerHTML=l._iconfont_svg_string_5200172,(h=h.getElementsByTagName("svg")[0])&&(h.setAttribute("aria-hidden","true"),h.style.position="absolute",h.style.width=0,h.style.height=0,h.style.overflow="hidden",h=h,(a=document.body).firstChild?e(h,a.firstChild):a.appendChild(h))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(v,0):(o=function(){document.removeEventListener("DOMContentLoaded",o,!1),v()},document.addEventListener("DOMContentLoaded",o,!1)):document.attachEvent&&(t=v,i=l.document,c=!1,m(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,d())})}function d(){c||(c=!0,t())}function m(){try{i.documentElement.doScroll("left")}catch(a){return void setTimeout(m,50)}d()}})(window); \ No newline at end of file diff --git a/ui/src/components/COMPONENT_README.md b/ui/src/components/COMPONENT_README.md index 2fe52542432..4dc80b24422 100644 --- a/ui/src/components/COMPONENT_README.md +++ b/ui/src/components/COMPONENT_README.md @@ -2,18 +2,19 @@ 本文档是项目公共组件规则的唯一依据。新增、修改、移动或使用公共组件前,应先阅读本文档。 -`src/components` 只存放跨页面或跨业务模块复用的 UI 组件。仅在单个功能内使用的组件,应放在 -对应的 `views//components` 中。 +`src/components` 存放跨页面或跨业务模块复用的 UI 组件与业务组件。仅在单个功能内使用的组件, +应放在对应的 `views//components` 中。 ## 组件选型 按以下顺序选择组件: 1. 首先检查 `src/components/global`,优先使用全局自动注册的 Mk 封装组件。 -2. 全局组件无法满足时,检查 `src/components` 中需要手动导入的共享组件。 -3. 没有对应 Mk 组件时,再使用 Element Plus 现成组件。 -4. 通过 Props、事件、插槽、公开方法、Tailwind class 或必要的样式覆盖适配设计稿。 -5. 现有组件无法满足必要的结构或行为时,再新增自定义组件。 +2. 涉及固定跨页面业务时,检查 `src/components/business` 中手动导入的业务组件。 +3. 以上组件无法满足时,检查 `src/components` 直属目录中手动导入的共享 UI 组件。 +4. 没有对应 Mk 组件时,再使用 Element Plus 现成组件。 +5. 通过 Props、事件、插槽、公开方法、Tailwind class 或必要的样式覆盖适配设计稿。 +6. 现有组件无法满足必要的结构或行为时,再新增自定义组件。 已有全局 Mk 组件封装相同能力时,业务页面和业务组件必须使用该封装,不要绕过它直接使用 底层 Element Plus 组件,也不要在功能目录重复封装。例如对话框使用 `MkDialog`、抽屉使用 @@ -32,6 +33,17 @@ Element Plus 已在 `src/main.ts` 和 `src/chat.ts` 中全局注册,Vue 模板 ```text src/components/ ├── COMPONENT_README.md +├── business/ # 跨页面复用的业务组件,不使用 Mk 前缀 +│ ├── folder-tree/ # Workspace 文件夹虚拟树及固定 CRUD 业务 +│ │ ├── index.vue +│ │ ├── FolderFormDialog.vue +│ │ ├── MoveFolderDialog.vue +│ │ ├── VirtualizedTree.vue +│ │ └── types.ts +│ ├── workspace-dropdown/ +│ │ └── index.vue # 工作空间选择下拉框 +│ └── workspace-relation-tags/ +│ └── index.vue # 标签及关联工作空间展示 ├── global/ # 高频、稳定的基础组件,自动注册 │ ├── mk-complex-search/ │ │ └── index.vue # 字段选择与输入或枚举条件组合搜索框 @@ -67,14 +79,10 @@ src/components/ │ └── mk-list-item.vue # 列表与业务分组列表复用的行结构 ├── mk-form-list/ │ └── index.vue # 可动态增删的表单行列表,手动导入 -├── mk-source-card/ +└── mk-source-card/ │ ├── index.vue # 来源资源的统一卡片结构,手动导入 │ ├── mk-source-card-action.vue # 卡片悬浮操作容器 │ └── mk-source-card-action-dropdown.vue # 卡片 More 下拉菜单 -├── mk-workspace-dropdown/ -│ └── index.vue # 工作空间选择下拉框,手动导入 -└── mk-workspace-relation-tags/ - └── index.vue # 标签及关联工作空间展示,手动导入 ``` Vite 的 `unplugin-vue-components` 只扫描 `src/components/global`。该目录中的组件可以直接在 @@ -85,8 +93,9 @@ import MkSearchList from '@/components/mk-search-list/index.vue' import MkListItem from '@/components/mk-search-list/mk-list-item.vue' import MkFormList from '@/components/mk-form-list/index.vue' import MkSourceCard from '@/components/mk-source-card/index.vue' -import MkWorkspaceDropdown from '@/components/mk-workspace-dropdown/index.vue' -import MkWorkspaceRelationTags from '@/components/mk-workspace-relation-tags/index.vue' +import FolderTree from '@/components/business/folder-tree/index.vue' +import WorkspaceDropdown from '@/components/business/workspace-dropdown/index.vue' +import WorkspaceRelationTags from '@/components/business/workspace-relation-tags/index.vue' ``` 自动注册只适用于 Vue 模板。脚本中的类型、常量和 Element Plus 图标仍需显式导入。自动生成 @@ -95,8 +104,9 @@ import MkWorkspaceRelationTags from '@/components/mk-workspace-relation-tags/ind ## 组件约定 - 高频、稳定、跨多数页面使用的基础组件放入 `global`。 -- 使用页面较少、有明确业务含义或依赖较重的共享组件放在 - `components/`,由使用方手动导入。 +- 跨页面复用且依赖业务类型、固定业务接口或领域交互的组件放入 `business/`, + 由使用方手动导入。业务组件不使用 `Mk` 前缀,也不再按 Workspace 等上级领域增加额外目录。 +- 不依赖固定业务的共享组合 UI 组件放在 `components/`,由使用方手动导入。 - 一个公共组件使用一个 kebab-case 目录,入口统一为 `index.vue`。 - 组件名使用 PascalCase;目录名使用 kebab-case,例如 `MkIcon` 对应 `mk-icon/index.vue`。 @@ -348,9 +358,9 @@ Element Plus Dropdown 属性和事件通过 `$attrs` 传入,并暴露 `handleO - `src/assets/iconfont.js` 只允许整体替换,不要手动编辑;Symbol ID 变化时同步更新所有引用。 ```vue - + - + ``` ### MkSearchInput @@ -651,7 +661,38 @@ function selectItem(item: SearchListItem, index: number) { `props` 中未传的字段保留默认值,例如只传 `:props="{ label: 'title' }"` 时,唯一值字段仍为 `id`。 -### MkWorkspaceDropdown +## 跨页面业务组件 + +业务组件可以调用其固定业务 API,但应将通用展示部分拆成内部纯 UI 组件;页面继续负责资源列表 +查询、路由跳转等所属页面业务。业务组件必须显式导入,不参与全局自动注册。 + +### FolderTree + +Workspace 的文件夹虚拟树业务组件。组件根据 `workspaceId` 和 `source` 调用统一文件夹接口,负责 +文件夹树查询、搜索、排序、创建、编辑、移动和删除。通过 `v-model` 控制当前文件夹 ID,选择 +文件夹时触发 `select`;`beforeTree` 插槽用于“全部”“共享”等不属于文件夹接口的固定入口。 + +```vue + + + + + +``` + +页面顶部需要触发根目录创建时,通过页面语义处理方法调用组件暴露的 `openCreate()`;外部数据变化 +后可调用 `refresh()` 重新加载文件夹树。`VirtualizedTree.vue` 基于 `@he-tree/vue` 的 `Draggable` +实现虚拟渲染和拖拽交互,只负责树 UI,不调用 API;不要替换为 Element Plus `el-tree-v2`。 + +### WorkspaceDropdown 统一工作空间下拉框的图标和触发器布局。通过 `options` 传入工作空间选项,通过 `v-model` 控制选中值,选择后通过 `select` 返回完整选项。组件不读取 Store,也不执行导航;路由切换和 @@ -659,17 +700,17 @@ function selectItem(item: SearchListItem, index: number) { ```vue - ``` -### MkWorkspaceRelationTags +### WorkspaceRelationTags 用于展示标签组,并在悬浮表格中展示每个标签关联的工作空间。 `tags` 控制表格单元格中的折叠标签;`tagWorkspace` 使用标签名称作为键、工作空间 @@ -678,10 +719,10 @@ import MkWorkspaceDropdown from '@/components/mk-workspace-dropdown/index.vue' ```vue -/index.vue` 创建组件,并声明多单词组件名。 3. 使用类型化 Props、Emits 和 Slots。 4. `global` 组件在模板中直接使用;其他共享组件由使用方从具体路径导入。 diff --git a/ui/src/components/business/folder-tree/FolderFormDialog.vue b/ui/src/components/business/folder-tree/FolderFormDialog.vue new file mode 100644 index 00000000000..f60e5fa9611 --- /dev/null +++ b/ui/src/components/business/folder-tree/FolderFormDialog.vue @@ -0,0 +1,115 @@ + + + diff --git a/ui/src/components/business/folder-tree/MoveFolderDialog.vue b/ui/src/components/business/folder-tree/MoveFolderDialog.vue new file mode 100644 index 00000000000..f3b063c214d --- /dev/null +++ b/ui/src/components/business/folder-tree/MoveFolderDialog.vue @@ -0,0 +1,107 @@ + + + diff --git a/ui/src/components/business/folder-tree/VirtualizedTree.vue b/ui/src/components/business/folder-tree/VirtualizedTree.vue new file mode 100644 index 00000000000..a0f1be35173 --- /dev/null +++ b/ui/src/components/business/folder-tree/VirtualizedTree.vue @@ -0,0 +1,278 @@ + + + + + diff --git a/ui/src/components/business/folder-tree/index.vue b/ui/src/components/business/folder-tree/index.vue new file mode 100644 index 00000000000..e3c92f68d2e --- /dev/null +++ b/ui/src/components/business/folder-tree/index.vue @@ -0,0 +1,280 @@ + + + diff --git a/ui/src/components/business/folder-tree/types.ts b/ui/src/components/business/folder-tree/types.ts new file mode 100644 index 00000000000..0358428d25f --- /dev/null +++ b/ui/src/components/business/folder-tree/types.ts @@ -0,0 +1,24 @@ +import type { + WorkspaceFolder, + WorkspaceFolderCreatePayload, + WorkspaceFolderUpdatePayload, +} from '@/api/types' + +export const FOLDER_SORT = { + CREATE_TIME_ASC: 'create_time_asc', + CREATE_TIME_DESC: 'create_time_desc', + NAME_ASC: 'name_asc', + NAME_DESC: 'name_desc', +} as const + +export type FolderSort = (typeof FOLDER_SORT)[keyof typeof FOLDER_SORT] + +export interface FolderFormSubmit { + folderId?: string + payload: WorkspaceFolderCreatePayload | WorkspaceFolderUpdatePayload +} + +export interface FolderMoveSubmit { + folder: WorkspaceFolder + targetFolderId: string +} diff --git a/ui/src/components/mk-workspace-dropdown/index.vue b/ui/src/components/business/workspace-dropdown/index.vue similarity index 76% rename from ui/src/components/mk-workspace-dropdown/index.vue rename to ui/src/components/business/workspace-dropdown/index.vue index c44fbdfda26..da44253b9b8 100644 --- a/ui/src/components/mk-workspace-dropdown/index.vue +++ b/ui/src/components/business/workspace-dropdown/index.vue @@ -2,10 +2,7 @@ import { CaretBottom } from '@element-plus/icons-vue' import type { WorkspaceItem } from '@/api/types' -defineOptions({ name: 'MkWorkspaceDropdown' }) - -/* 此组件专属为工作空间 dropdown 使用,图标(icon_moments-categories_outlined)已硬编码。 - 若其他场景需要替换图标,后续应完善 props,将图标作为可配置参数传入。*/ +defineOptions({ name: 'WorkspaceDropdown' }) const props = defineProps<{ options: WorkspaceItem[] @@ -27,7 +24,7 @@ const emit = defineEmits<{ {{ text }} - + diff --git a/ui/src/components/business/workspace-relation-tags/index.vue b/ui/src/components/business/workspace-relation-tags/index.vue new file mode 100644 index 00000000000..c77373535a9 --- /dev/null +++ b/ui/src/components/business/workspace-relation-tags/index.vue @@ -0,0 +1,37 @@ + + + diff --git a/ui/src/components/mk-search-list/mk-list-item.vue b/ui/src/components/mk-search-list/mk-list-item.vue index d9685469926..e93cd5a16ec 100644 --- a/ui/src/components/mk-search-list/mk-list-item.vue +++ b/ui/src/components/mk-search-list/mk-list-item.vue @@ -42,7 +42,7 @@ const slotRow = computed(() => row as T)
diff --git a/ui/src/components/mk-source-card/index.vue b/ui/src/components/mk-source-card/index.vue index 5005cececbd..9a8ff5a873f 100644 --- a/ui/src/components/mk-source-card/index.vue +++ b/ui/src/components/mk-source-card/index.vue @@ -79,7 +79,7 @@ const slots = defineSlots<{
-