更新local_ai_agent_toolbar.vue
This commit is contained in:
parent
67119d3265
commit
deccb557c0
@ -1,9 +1,57 @@
|
||||
<template>
|
||||
<n-space :size="8">
|
||||
<n-space align="center">
|
||||
<!-- 侧边栏位置切换按钮 -->
|
||||
<n-button
|
||||
type="default"
|
||||
size="medium"
|
||||
:disabled="executing"
|
||||
@click="$emit('toggle-sidebar-position')"
|
||||
:title="sidebarPosition === 'left' ? '切换到右侧' : '切换到左侧'"
|
||||
class="header-action-btn"
|
||||
>
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<Icon :icon="sidebarPosition === 'left' ? 'fluent:panel-right-16-regular' : 'fluent:panel-left-16-regular'" />
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
|
||||
<!-- 刷新按钮 -->
|
||||
<n-button
|
||||
type="default"
|
||||
size="medium"
|
||||
@click="$emit('refresh')"
|
||||
:disabled="loading || isNew"
|
||||
:title="t('Refresh')"
|
||||
class="header-action-btn"
|
||||
>
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<Icon icon="tabler:refresh" />
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
|
||||
<!-- 删除按钮 -->
|
||||
<n-button
|
||||
type="default"
|
||||
size="medium"
|
||||
@click="$emit('delete')"
|
||||
:disabled="loading || isNew"
|
||||
:title="t('Delete')"
|
||||
class="header-action-btn delete-btn"
|
||||
>
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<Icon icon="tabler:trash" />
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
|
||||
<!-- 执行按钮 -->
|
||||
<n-button
|
||||
type="default"
|
||||
size="medium"
|
||||
:disabled="executing || loading"
|
||||
@click="handleExecute"
|
||||
v-if="!isNew"
|
||||
class="toolbar-btn execute-btn"
|
||||
@ -13,10 +61,13 @@
|
||||
</template>
|
||||
{{ executing ? t('Executing...') : t('Execute') }}
|
||||
</n-button>
|
||||
|
||||
<!-- 流程编排按钮 -->
|
||||
<n-button
|
||||
type="default"
|
||||
size="medium"
|
||||
@click="handleFlowBuilder"
|
||||
:disabled="loading"
|
||||
class="toolbar-btn flow-builder-btn"
|
||||
>
|
||||
<template #icon>
|
||||
@ -24,38 +75,102 @@
|
||||
</template>
|
||||
{{ t('Flow Builder') }}
|
||||
</n-button>
|
||||
|
||||
<!-- 返回按钮 -->
|
||||
<n-button type="default" size="medium" @click="$emit('go-back')" :disabled="loading">
|
||||
<template #icon>
|
||||
<n-icon><Icon icon="tabler:arrow-left" /></n-icon>
|
||||
</template>
|
||||
{{ t('Back') }}
|
||||
</n-button>
|
||||
|
||||
<!-- 保存按钮 -->
|
||||
<n-button
|
||||
type="primary"
|
||||
size="medium"
|
||||
:disabled="loading"
|
||||
@click="$emit('save')"
|
||||
v-if="canEdit"
|
||||
class="save-btn-brand"
|
||||
>
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<Icon icon="tabler:check" />
|
||||
</n-icon>
|
||||
</template>
|
||||
{{ t('Save') }}
|
||||
</n-button>
|
||||
</n-space>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { NSpace, NButton, NIcon, useMessage } from 'naive-ui'
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { NButton, NSpace, NIcon, useMessage } from 'naive-ui'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { t } from '@/shared/i18n'
|
||||
|
||||
const props = defineProps<{ context: {
|
||||
entity: any
|
||||
id: any
|
||||
record: any
|
||||
canEdit: any
|
||||
loading: any
|
||||
save: () => Promise<void> | void
|
||||
router: any
|
||||
t: (k: string) => string
|
||||
} }>()
|
||||
interface Props {
|
||||
entity: string
|
||||
id: string
|
||||
record?: any
|
||||
canEdit: boolean
|
||||
loading: boolean
|
||||
sidebarPosition?: 'left' | 'right'
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'toggle-sidebar-position'): void
|
||||
(e: 'refresh'): void
|
||||
(e: 'delete'): void
|
||||
(e: 'go-back'): void
|
||||
(e: 'save'): void
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
sidebarPosition: 'left',
|
||||
record: () => ({})
|
||||
})
|
||||
|
||||
defineEmits<Emits>()
|
||||
|
||||
const message = useMessage()
|
||||
const router = useRouter()
|
||||
const executing = ref(false)
|
||||
|
||||
const t = props.context.t
|
||||
const isNew = computed(() => String(props.context.id?.value || props.context.id) === 'new')
|
||||
// 计算是否为新建记录
|
||||
const isNew = computed(() => {
|
||||
const idValue = props.id
|
||||
return idValue === 'new' || idValue.startsWith('new-')
|
||||
})
|
||||
|
||||
// 从 localStorage 读取侧边栏位置(如果父组件没有传入)
|
||||
const sidebarPosition = ref<'left' | 'right'>(props.sidebarPosition || 'left')
|
||||
|
||||
// 监听 props 变化
|
||||
watch(() => props.sidebarPosition, (newPos) => {
|
||||
if (newPos) {
|
||||
sidebarPosition.value = newPos
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
onMounted(() => {
|
||||
// 如果没有传入 sidebarPosition,尝试从 localStorage 读取
|
||||
if (!props.sidebarPosition) {
|
||||
const savedPosition = localStorage.getItem('jingrow-sidebar-position')
|
||||
if (savedPosition === 'left' || savedPosition === 'right') {
|
||||
sidebarPosition.value = savedPosition
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 执行按钮处理函数
|
||||
async function handleExecute() {
|
||||
if (isNew.value) return
|
||||
try {
|
||||
executing.value = true
|
||||
const id = String(props.context.id?.value || props.context.id)
|
||||
const name = props.context.record?.value?.agent_name || props.context.record?.agent_name || ''
|
||||
const id = String(props.id)
|
||||
const name = props.record?.agent_name || ''
|
||||
const response = await fetch('/jingrow/agents/execute', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@ -78,27 +193,120 @@ async function handleExecute() {
|
||||
}
|
||||
}
|
||||
|
||||
// 流程编排按钮处理函数
|
||||
async function handleFlowBuilder() {
|
||||
try {
|
||||
const raw = props.context.record?.value?.agent_flow ?? props.context.record?.agent_flow ?? {}
|
||||
const raw = props.record?.agent_flow ?? {}
|
||||
let flowData: any = raw
|
||||
if (typeof raw === 'string') {
|
||||
try { flowData = JSON.parse(raw) } catch { flowData = {} }
|
||||
}
|
||||
const agentId = props.context.record?.value?.name || props.context.record?.name || ''
|
||||
const agentId = props.record?.name || ''
|
||||
|
||||
const { useFlowBuilderStore } = await import('@/shared/stores/flowBuilder')
|
||||
const flowBuilderStore = useFlowBuilderStore()
|
||||
|
||||
flowBuilderStore.activateFlowBuilder(flowData, agentId)
|
||||
|
||||
props.context.router.push({ name: 'FlowBuilder', query: { agentId } })
|
||||
router.push({ name: 'FlowBuilder', query: { agentId } })
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 头部操作按钮统一样式 */
|
||||
.header-action-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 删除按钮悬浮时使用红色 */
|
||||
.header-action-btn.delete-btn:hover:not(:disabled) {
|
||||
background: #ef4444 !important;
|
||||
border-color: #ef4444 !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.header-action-btn.delete-btn:hover:not(:disabled) :deep(.n-button__border),
|
||||
.header-action-btn.delete-btn:hover:not(:disabled) :deep(.n-button__state-border) {
|
||||
border-color: #ef4444 !important;
|
||||
}
|
||||
|
||||
/* 保存按钮 - 使用柔和的品牌色系,与列表页创建按钮一致 */
|
||||
.save-btn-brand {
|
||||
background: #e6f8f0 !important;
|
||||
border: 1px solid #1fc76f !important;
|
||||
color: #0d684b !important;
|
||||
}
|
||||
|
||||
.save-btn-brand :deep(.n-button__border) {
|
||||
border: none !important;
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
.save-btn-brand :deep(.n-button__state-border) {
|
||||
border: none !important;
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
.save-btn-brand:hover {
|
||||
background: #dcfce7 !important;
|
||||
border-color: #1fc76f !important;
|
||||
border: 1px solid #1fc76f !important;
|
||||
color: #166534 !important;
|
||||
box-shadow: 0 2px 8px rgba(31, 199, 111, 0.15) !important;
|
||||
}
|
||||
|
||||
.save-btn-brand:hover :deep(.n-button__border),
|
||||
.save-btn-brand:hover :deep(.n-button__state-border) {
|
||||
border: none !important;
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
.save-btn-brand:focus {
|
||||
background: #dcfce7 !important;
|
||||
border-color: #1fc76f !important;
|
||||
border: 1px solid #1fc76f !important;
|
||||
color: #166534 !important;
|
||||
box-shadow: 0 0 0 2px rgba(31, 199, 111, 0.2) !important;
|
||||
}
|
||||
|
||||
.save-btn-brand:focus :deep(.n-button__border),
|
||||
.save-btn-brand:focus :deep(.n-button__state-border) {
|
||||
border: none !important;
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
.save-btn-brand:active {
|
||||
background: #1fc76f !important;
|
||||
border-color: #1fc76f !important;
|
||||
border: 1px solid #1fc76f !important;
|
||||
color: white !important;
|
||||
box-shadow: 0 1px 4px rgba(31, 199, 111, 0.2) !important;
|
||||
}
|
||||
|
||||
.save-btn-brand:active :deep(.n-button__border),
|
||||
.save-btn-brand:active :deep(.n-button__state-border) {
|
||||
border: none !important;
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
.save-btn-brand:disabled {
|
||||
background: #f1f5f9 !important;
|
||||
border: 1px solid #e2e8f0 !important;
|
||||
border-color: #e2e8f0 !important;
|
||||
color: #94a3b8 !important;
|
||||
opacity: 0.6 !important;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
.save-btn-brand:disabled :deep(.n-button__border),
|
||||
.save-btn-brand:disabled :deep(.n-button__state-border) {
|
||||
border: none !important;
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
/* 工具栏按钮基础样式 - 与返回按钮一致,使用badge配色方案 */
|
||||
.toolbar-btn {
|
||||
background: #f3f4f6 !important;
|
||||
@ -165,4 +373,3 @@ async function handleFlowBuilder() {
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user