Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ui/src/components/COMPONENT_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ Element Plus Dropdown 属性和事件通过 `$attrs` 传入,并暴露 `handleO

```vue
<MkDropdown trigger="click" placement="bottom-end">
<button type="button">打开菜单</button>
<el-button text>打开菜单</el-button>
<template #dropdown>
<MkDropdownMenu>
<MkDropdownItem :icon="Setting">设置</MkDropdownItem>
Expand Down Expand Up @@ -338,7 +338,7 @@ Element Plus Dropdown 属性和事件通过 `$attrs` 传入,并暴露 `handleO
```vue
<MkFilterableDropdown v-model="selectedWorkspaceId" :options="workspaces" :props="{ label: 'name', value: 'id' }" @select="handleWorkspaceSelect">
<template #default="{ text }">
<button type="button">{{ text }}</button>
<el-button text>{{ text }}</el-button>
</template>
<template #option="{ option }">
<span class="truncate" :title="option.name">{{ option.name }}</span>
Expand Down
9 changes: 7 additions & 2 deletions ui/src/components/business/workspace-dropdown/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ const emit = defineEmits<{ select: [option: WorkspaceItem] }>()
</script>

<template>
<MkFilterableDropdown v-model="selectedWorkspaceId" :options="props.options" :props="{ label: 'name', value: 'id' }" @select="emit('select', $event)">
<MkFilterableDropdown
v-model="selectedWorkspaceId"
:options="props.options"
:props="{ label: 'name', value: 'id' }"
@select="emit('select', $event)"
>
<template #default="{ text }">
<el-button text class="flex max-w-50 items-center gap-1 rounded-md px-2! py-[7px]! text-N900!">
<MkIcon name="icon_moments-categories_outlined" class="mr-1" />
<span class="min-w-0 flex-1 truncate" :title="text">{{ text }}</span>
<MkIcon :icon="CaretBottom" :size="14" class="ml-1 shrink-0 text-N600!" />
<MkIcon :icon="CaretBottom" :size="14" class="ml-1 text-N600!" />
</el-button>
</template>

Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/mk-drag-upload/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ defineExpose({ clearFiles })
<span class="text-sm text-N500">{{ formatFileSize(selectedFile.size) }}</span>
</div>
<div class="flex shrink-0 items-center gap-1">
<slot name="download" :file="selectedFile" />
<slot name="download" :file="selectedFile"/>
<el-button aria-label="删除文件" :disabled="disabled" text @click="handleRemove">
<MkIcon name="icon_delete-trash_outlined" :size="16" class="text-N600" />
</el-button>
Expand Down
4 changes: 2 additions & 2 deletions ui/src/styles/STYLE_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ Tailwind 类。
`--color-*` 注册后可以组合生成文字、背景、边框、轮廓等颜色工具类:

```html
<button class="bg-primary text-white">确认</button>
<div class="bg-primary text-white">确认</div>
<a class="text-primary">链接文字</a>
<div class="border border-primary">主题色边框</div>
<input class="outline-primary" />
Expand All @@ -311,7 +311,7 @@ Tailwind 类。
交互状态直接添加 Tailwind 状态前缀:

```html
<button class="bg-primary hover:bg-primary/90 focus:ring-2 focus:ring-primary">确认</button>
<div class="bg-primary hover:bg-primary/90 focus:ring-2 focus:ring-primary">确认</div>
```

在颜色类后添加 `/透明度`,可以使用主题色叠加透明效果:
Expand Down
24 changes: 19 additions & 5 deletions ui/src/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,16 @@ h6 {
}
}


// 资源菜单的导入按钮
.mk-import-button {
width: 100%;
.el-upload {
width: 100%;
}
}


/*
标题前带竖线样式
*/
Expand Down Expand Up @@ -209,11 +219,15 @@ h6 {
grid-template-columns: repeat(auto-fill, minmax(min(100%, 270px), 1fr));
}

// 资源菜单的导入按钮
.mk-import-button {
width: 100%;
.el-upload {
width: 100%;


.mk-scrollbar-right {
&.el-scrollbar {
margin-right: calc(var(--spacing) * -4);

> .el-scrollbar__wrap > .el-scrollbar__view {
padding-right: calc(var(--spacing) * 4);
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions ui/src/styles/element-plus.scss
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@
--el-popover-border-radius: var(--el-border-radius-base);
&.el-popper {
padding: 0;
color: var(--el-text-color-primary) !important;
}
}

Expand Down Expand Up @@ -895,6 +896,7 @@
&__content {
min-height: 0;
flex: 1;
overflow: visible;
}
&__item {
padding: 0 14px;
Expand Down
33 changes: 21 additions & 12 deletions ui/src/views/system/chat/authentication/AuthenticationView.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, type Component } from 'vue'
import { computed, ref, type Component } from 'vue'
import { LOGIN_METHOD } from '@/api/enums'
import LDAP from './components/LDAP.vue'
import CAS from './components/CAS.vue'
Expand All @@ -21,21 +21,30 @@ const authenticationTabs: AuthenticationTab[] = [
{ label: 'OAuth2', name: LOGIN_METHOD.OAUTH2, component: OAuth2 },
{ label: '扫码登录', name: 'SCAN', component: SCAN },
]
const activeAuthenticationComponent = computed(() => authenticationTabs.find((tab) => tab.name === activeName.value)?.component)
</script>

<template>
<MkViewLayout class="system-settings-authentication">
<el-tabs v-model="activeName" class="authentication-tabs min-h-0 flex-1 flex-col">
<template v-for="authenticationTab in authenticationTabs" :key="authenticationTab.name">
<el-tab-pane class="h-full" :label="authenticationTab.label" :name="authenticationTab.name" lazy>
<el-scrollbar>
<div class="py-4">
<component :is="authenticationTab.component" />
</div>
</el-scrollbar>
</el-tab-pane>
</template>
</el-tabs>
<template #default="{ title, Header }">
<component :is="Header">
<div class="w-full">
<h4 class="mb-4">{{ title }}</h4>
<el-tabs v-model="activeName">
<el-tab-pane
v-for="authenticationTab in authenticationTabs"
:key="authenticationTab.name"
:label="authenticationTab.label"
:name="authenticationTab.name"
/>
</el-tabs>
</div>
</component>

<KeepAlive>
<component :is="activeAuthenticationComponent" :key="activeName" />
</KeepAlive>
</template>
</MkViewLayout>
</template>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ onMounted(loadQrPlatforms)
</script>

<template>
<div class="space-y-4 pr-2">
<div class="space-y-4">
<template v-for="platform in qrLoginPlatforms" :key="platform.key">
<el-card shadow="hover">
<div class="flex-between mb-4">
Expand Down
33 changes: 21 additions & 12 deletions ui/src/views/system/settings/authentication/AuthenticationView.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, type Component } from 'vue'
import { computed, ref, type Component } from 'vue'
import { LOGIN_METHOD } from '@/api/enums'
import LDAP from './components/LDAP.vue'
import CAS from './components/CAS.vue'
Expand All @@ -25,21 +25,30 @@ const authenticationTabs: AuthenticationTab[] = [
{ label: 'SAML2', name: LOGIN_METHOD.SAML2, component: Saml2 },
{ label: '扫码登录', name: 'SCAN', component: SCAN },
]
const activeAuthenticationComponent = computed(() => authenticationTabs.find((tab) => tab.name === activeName.value)?.component)
</script>

<template>
<MkViewLayout class="system-settings-authentication">
<el-tabs v-model="activeName" class="authentication-tabs min-h-0 flex-1 flex-col">
<template v-for="authenticationTab in authenticationTabs" :key="authenticationTab.name">
<el-tab-pane class="h-full" :label="authenticationTab.label" :name="authenticationTab.name" lazy>
<el-scrollbar>
<div class="py-4">
<component :is="authenticationTab.component" />
</div>
</el-scrollbar>
</el-tab-pane>
</template>
</el-tabs>
<template #default="{ title, Header }">
<component :is="Header">
<div class="w-full">
<h4 class="mb-4">{{ title }}</h4>
<el-tabs v-model="activeName">
<el-tab-pane
v-for="authenticationTab in authenticationTabs"
:key="authenticationTab.name"
:label="authenticationTab.label"
:name="authenticationTab.name"
/>
</el-tabs>
</div>
</component>

<KeepAlive>
<component :is="activeAuthenticationComponent" :key="activeName" />
</KeepAlive>
</template>
</MkViewLayout>
</template>

Expand Down
2 changes: 1 addition & 1 deletion ui/src/workflow-canvas/icons/ai-chat-node-icon.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<el-avatar class="ai-avatar-gradient" shape="square">
<img src="@/assets/workflow/icon_ai_chat.svg" style="width: 75%" alt="" />
<img src="@/assets/workflow/icon_ai_chat.svg" style="width: 74%" alt="" />
</el-avatar>
</template>
<script setup lang="ts"></script>
30 changes: 16 additions & 14 deletions ui/src/workflow-canvas/node-menu/BasicNodeMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,27 @@ function handleNodeDragStart(event: PointerEvent, workflowNode: WorkflowMenuNode
</script>

<template>
<div>
<div class="p-4">
<MkSearchInput v-model="searchKeyword" placeholder="按名称搜索" />

<el-scrollbar height="500">
<el-scrollbar height="450" class="mk-scrollbar-right">
<template v-if="filteredComponentGroups.length">
<template v-for="group in filteredComponentGroups" :key="group.label">
<p class="mb-3 mt-3 text-N600">{{ group.label }}</p>
<p class="mb-3 mt-3 font-semibold text-sm text-N600">{{ group.label }}</p>
<div class="grid grid-cols-2 gap-3">
<button
v-for="workflowNode in group.list"
:key="workflowNode.type"
type="button"
class="flex h-10 cursor-grab items-center gap-3 rounded-md border border-N300 px-3 text-left text-N900 hover:border-primary hover:text-primary active:cursor-grabbing"
@click="emit('select', workflowNode)"
@pointerdown="handleNodeDragStart($event, workflowNode)"
>
<component :is="iconComponent(`${workflowNode.type}-icon`)" class="shrink-0" :size="24" />
<span>{{ workflowNode.label }}</span>
</button>
<template v-for="workflowNode in group.list" :key="workflowNode.type">
<el-card
class="small cursor-pointer"
shadow="never"
@click="emit('select', workflowNode)"
@pointerdown="handleNodeDragStart($event, workflowNode)"
>
<div class="flex items-center gap-2">
<component :is="iconComponent(`${workflowNode.type}-icon`)" :size="20" />
<span>{{ workflowNode.label }}</span>
</div>
</el-card>
</template>
</div>
</template>
</template>
Expand Down
75 changes: 35 additions & 40 deletions ui/src/workflow-canvas/node-menu/ResourceNodeMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import { cloneDeep } from 'lodash'
import ApplicationApi from '@/api/admin/workspace/application/application'
import SharedApi from '@/api/admin/workspace/shared'
import ToolApi from '@/api/admin/workspace/tool/tool'
import { APPLICATION_TYPE, RESOURCE_TYPE, TOOL_TYPE } from '@/api/enums'
import { RESOURCE_TYPE, TOOL_TYPE } from '@/api/enums'
import type { ApplicationDetail, ApplicationType, FolderItem, ToolItem, ToolType } from '@/api/types'
import FolderTree from '@/components/business/folder-tree/index.vue'
import type { NodeMenuItem, NodeMenuResourceSource } from './types'
import { FOLDER_ENTRY_ID } from '@/constants'
import { isWorkFlow } from '@/utils/application'
import FolderTree from '@/components/business/folder-tree/index.vue'
import { applicationNode, toolLibNode, toolWorkflowLibNode } from '@/workflow-canvas/config/node-data'
import type { NodeMenuItem, NodeMenuResourceSource } from './types'

defineOptions({ name: 'ResourceNodeMenu' })

Expand Down Expand Up @@ -127,8 +128,8 @@ onMounted(() => {
</script>

<template>
<div class="flex h-[450px] min-h-0">
<aside class="flex w-60 shrink-0 border-r pt-3">
<div class="flex h-140 min-h-0">
<aside class="w-sidebar-expanded border-r pt-3">
<FolderTree v-model="currentFolderId" :can-edit="false" :show-shared="isToolMenu" :source="source" @select="loadResources" />
</aside>

Expand All @@ -139,41 +140,35 @@ onMounted(() => {

<el-scrollbar class="min-h-0 flex-1">
<div v-if="filteredResourceItems.length" class="grid grid-cols-2 gap-3 px-3 pb-3">
<el-popover
v-for="resource in filteredResourceItems"
:key="resource.id"
placement="right"
:width="280"
:show-after="500"
:persistent="false"
>
<template #reference>
<button
type="button"
class="flex h-10 min-w-0 cursor-grab items-center gap-2 rounded-md border border-N300 px-3 text-left text-N900 hover:border-primary hover:text-primary active:cursor-grabbing"
@click="emit('select', resource.node)"
@pointerdown="handleNodeDragStart($event, resource.node)"
>
<ToolIcon v-if="isToolMenu" :icon="resource.icon" :size="20" :type="resource.toolType" />
<ApplicationIcon v-else :icon="resource.icon" :size="20" />
<span class="min-w-0 flex-1 truncate" :title="resource.name">{{ resource.name }}</span>
</button>
</template>

<div class="flex min-w-0 items-center gap-2">
<ToolIcon v-if="isToolMenu" :icon="resource.icon" :size="24" :type="resource.toolType" />
<ApplicationIcon v-else :icon="resource.icon" :size="24" />
<h6 class="min-w-0 flex-1 break-all">{{ resource.name }}</h6>
<el-tag
v-if="resource.applicationType"
size="small"
:type="resource.applicationType === APPLICATION_TYPE.WORK_FLOW ? 'warning' : 'primary'"
>
{{ resource.applicationType === APPLICATION_TYPE.WORK_FLOW ? '高级智能体' : '简易智能体' }}
</el-tag>
</div>
<p v-if="resource.desc" class="mt-2 text-sm text-N600">{{ resource.desc }}</p>
</el-popover>
<template v-for="resource in filteredResourceItems" :key="resource.id">
<el-popover placement="right" :width="280" :show-after="500" :persistent="false">
<template #reference>
<el-card
class="small cursor-pointer"
shadow="never"
@click="emit('select', resource.node)"
@pointerdown="handleNodeDragStart($event, resource.node)"
>
<div class="flex items-center gap-2">
<ToolIcon v-if="isToolMenu" :icon="resource.icon" :size="20" :type="resource.toolType" />
<ApplicationIcon v-else :icon="resource.icon" :size="20" />
<span class="min-w-0 flex-1 truncate" :title="resource.name">{{ resource.name }}</span>
</div>
</el-card>
</template>
<div class="p-3">
<div class="flex min-w-0 items-center gap-2">
<ToolIcon v-if="isToolMenu" :icon="resource.icon" :size="24" :type="resource.toolType" />
<ApplicationIcon v-else :icon="resource.icon" :size="24" />
<p class="min-w-0 flex-1 break-all truncate">{{ resource.name }}</p>
<el-tag v-if="resource.applicationType" size="small" :type="isWorkFlow(resource.applicationType) ? 'warning' : 'primary'">
{{ isWorkFlow(resource.applicationType) ? '高级' : '简易' }}
</el-tag>
</div>
<p v-if="resource.desc" class="mt-2 text-sm text-N600">{{ resource.desc }}</p>
</div>
</el-popover>
</template>
</div>
<MkEmpty v-else :type="searchKeyword ? 'search' : 'default'" :image-size="72" />
</el-scrollbar>
Expand Down
Loading
Loading