|
@@ -13,6 +13,7 @@ import YaoYaoSidebarIcon from '@/components/common/YaoYaoSidebarIcon.vue'
|
|
|
const AboutDialog = defineAsyncComponent(() => import('./AboutDialog.vue'))
|
|
const AboutDialog = defineAsyncComponent(() => import('./AboutDialog.vue'))
|
|
|
const UpdateCheckDialog = defineAsyncComponent(() => import('./UpdateCheckDialog.vue'))
|
|
const UpdateCheckDialog = defineAsyncComponent(() => import('./UpdateCheckDialog.vue'))
|
|
|
const BotPluginsDialog = defineAsyncComponent(() => import('@/components/workspace/BotPluginsDialog.vue'))
|
|
const BotPluginsDialog = defineAsyncComponent(() => import('@/components/workspace/BotPluginsDialog.vue'))
|
|
|
|
|
+const BotSettingsDialog = defineAsyncComponent(() => import('@/components/workspace/BotSettingsDialog.vue'))
|
|
|
|
|
|
|
|
type NavItem = {
|
|
type NavItem = {
|
|
|
key: 'chat' | 'history' | 'groups' | 'kanban' | 'files'
|
|
key: 'chat' | 'history' | 'groups' | 'kanban' | 'files'
|
|
@@ -33,7 +34,6 @@ type SettingsPage =
|
|
|
| 'system-push'
|
|
| 'system-push'
|
|
|
| 'system-nodes'
|
|
| 'system-nodes'
|
|
|
| 'system-voice'
|
|
| 'system-voice'
|
|
|
- | 'system-local-vm'
|
|
|
|
|
| 'system-update'
|
|
| 'system-update'
|
|
|
|
|
|
|
|
const SIDEBAR_COLLAPSED_KEY = 'hermes-yaoyao:sidebar-collapsed'
|
|
const SIDEBAR_COLLAPSED_KEY = 'hermes-yaoyao:sidebar-collapsed'
|
|
@@ -96,6 +96,7 @@ const emit = defineEmits<{
|
|
|
createAgent: []
|
|
createAgent: []
|
|
|
createRemoteAgent: []
|
|
createRemoteAgent: []
|
|
|
createGroup: []
|
|
createGroup: []
|
|
|
|
|
+ botSettingsChanged: []
|
|
|
}>()
|
|
}>()
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
const route = useRoute()
|
|
@@ -103,7 +104,8 @@ const router = useRouter()
|
|
|
const mobileDrawerOpen = ref(false)
|
|
const mobileDrawerOpen = ref(false)
|
|
|
const profileMenuOpen = ref(false)
|
|
const profileMenuOpen = ref(false)
|
|
|
const settingsOpen = ref(false)
|
|
const settingsOpen = ref(false)
|
|
|
-const standalone = ref<'plugins' | 'about' | 'update' | null>(null)
|
|
|
|
|
|
|
+const standalone = ref<'plugins' | 'about' | 'update' | 'bot-settings' | null>(null)
|
|
|
|
|
+const botSettingsPage = ref<'projects' | 'vm'>('projects')
|
|
|
const standaloneReturnFocus = ref<HTMLElement>()
|
|
const standaloneReturnFocus = ref<HTMLElement>()
|
|
|
const settingsPage = ref<SettingsPage>('agent-identity')
|
|
const settingsPage = ref<SettingsPage>('agent-identity')
|
|
|
const settingsReturnFocus = ref<HTMLButtonElement>()
|
|
const settingsReturnFocus = ref<HTMLButtonElement>()
|
|
@@ -276,16 +278,18 @@ async function openToolsMenu(event: MouseEvent) {
|
|
|
if (toolsMenuOpen.value) { closeToolsMenu(); return }
|
|
if (toolsMenuOpen.value) { closeToolsMenu(); return }
|
|
|
toolsTrigger = event.currentTarget as HTMLButtonElement
|
|
toolsTrigger = event.currentTarget as HTMLButtonElement
|
|
|
const rect = toolsTrigger.getBoundingClientRect()
|
|
const rect = toolsTrigger.getBoundingClientRect()
|
|
|
- toolsPosition.value = { left: `${Math.max(8, Math.min(rect.left, window.innerWidth - 208))}px`, top: `${Math.max(8, rect.top - (window.innerWidth < 768 ? 106 : 90))}px` }
|
|
|
|
|
|
|
+ const height = 3 * (window.innerWidth < 768 ? 44 : 36) + 18
|
|
|
|
|
+ toolsPosition.value = { left: `${Math.max(8, Math.min(rect.left, window.innerWidth - 208))}px`, top: `${Math.max(8, rect.top - height)}px` }
|
|
|
settingsMenuOpen.value = false; createMenuOpen.value = false; toolsMenuOpen.value = true
|
|
settingsMenuOpen.value = false; createMenuOpen.value = false; toolsMenuOpen.value = true
|
|
|
await nextTick(); toolsMenu.value?.querySelector<HTMLElement>('[role="menuitem"]')?.focus()
|
|
await nextTick(); toolsMenu.value?.querySelector<HTMLElement>('[role="menuitem"]')?.focus()
|
|
|
}
|
|
}
|
|
|
-function chooseTool(page: 'apps' | 'automations') {
|
|
|
|
|
|
|
+function chooseTool(page: 'apps' | 'automations' | 'bot-settings') {
|
|
|
toolsMenuOpen.value = false
|
|
toolsMenuOpen.value = false
|
|
|
if (page === 'automations') { void navigate('/conversations/automations?from=' + encodeURIComponent(route.fullPath)); return }
|
|
if (page === 'automations') { void navigate('/conversations/automations?from=' + encodeURIComponent(route.fullPath)); return }
|
|
|
standaloneReturnFocus.value = toolsTrigger?.closest('.mobile-drawer') ? mobileNavigationTrigger.value : toolsTrigger ?? undefined
|
|
standaloneReturnFocus.value = toolsTrigger?.closest('.mobile-drawer') ? mobileNavigationTrigger.value : toolsTrigger ?? undefined
|
|
|
mobileDrawerOpen.value = false
|
|
mobileDrawerOpen.value = false
|
|
|
- standalone.value = 'plugins'
|
|
|
|
|
|
|
+ botSettingsPage.value = 'projects'
|
|
|
|
|
+ standalone.value = page === 'bot-settings' ? 'bot-settings' : 'plugins'
|
|
|
}
|
|
}
|
|
|
function switchInterfaceMode() {
|
|
function switchInterfaceMode() {
|
|
|
if (!props.isAdmin) return
|
|
if (!props.isAdmin) return
|
|
@@ -418,7 +422,12 @@ watch(() => activeNav.value.key, () => {
|
|
|
profileMenuOpen.value = false
|
|
profileMenuOpen.value = false
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
-function showLocalVmSettings(){if(props.isAdmin)openSettings('system-local-vm')}
|
|
|
|
|
|
|
+function showLocalVmSettings(){
|
|
|
|
|
+ if(!props.isAdmin)return
|
|
|
|
|
+ standaloneReturnFocus.value = document.activeElement instanceof HTMLElement ? document.activeElement : undefined
|
|
|
|
|
+ settingsOpen.value = false; settingsMenuOpen.value = false; toolsMenuOpen.value = false; mobileDrawerOpen.value = false
|
|
|
|
|
+ botSettingsPage.value = 'vm'; standalone.value = 'bot-settings'
|
|
|
|
|
+}
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
window.addEventListener('yaoyao:local-vm-settings',showLocalVmSettings)
|
|
window.addEventListener('yaoyao:local-vm-settings',showLocalVmSettings)
|
|
|
try { sidebarCollapsed.value = localStorage.getItem(SIDEBAR_COLLAPSED_KEY) === '1' } catch { /* optional persistence */ }
|
|
try { sidebarCollapsed.value = localStorage.getItem(SIDEBAR_COLLAPSED_KEY) === '1' } catch { /* optional persistence */ }
|
|
@@ -432,7 +441,7 @@ onBeforeUnmount(() => {
|
|
|
document.removeEventListener(SIDEBAR_SEARCH_CLOSE_EVENT, handleSidebarSearchClosed)
|
|
document.removeEventListener(SIDEBAR_SEARCH_CLOSE_EVENT, handleSidebarSearchClosed)
|
|
|
document.removeEventListener('keydown', workspaceKeydown)
|
|
document.removeEventListener('keydown', workspaceKeydown)
|
|
|
})
|
|
})
|
|
|
-defineExpose({openLocalVm:()=>{if(props.isAdmin)openSettings('system-local-vm')}})
|
|
|
|
|
|
|
+defineExpose({openLocalVm:showLocalVmSettings})
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
<template>
|
|
@@ -695,6 +704,7 @@ defineExpose({openLocalVm:()=>{if(props.isAdmin)openSettings('system-local-vm')}
|
|
|
<AboutDialog v-if="standalone === 'about'" @close="closeStandalone" />
|
|
<AboutDialog v-if="standalone === 'about'" @close="closeStandalone" />
|
|
|
<UpdateCheckDialog v-if="standalone === 'update' && isAdmin" @close="closeStandalone" @manage="openUpdateSettings" />
|
|
<UpdateCheckDialog v-if="standalone === 'update' && isAdmin" @close="closeStandalone" @manage="openUpdateSettings" />
|
|
|
<BotPluginsDialog v-if="standalone === 'plugins' && applicationWorkspace" @close="closeStandalone" />
|
|
<BotPluginsDialog v-if="standalone === 'plugins' && applicationWorkspace" @close="closeStandalone" />
|
|
|
|
|
+ <BotSettingsDialog v-if="standalone === 'bot-settings'" :is-admin="isAdmin" :initial-page="botSettingsPage" @close="closeStandalone" @changed="emit('botSettingsChanged')" />
|
|
|
<SettingsCenterDialog
|
|
<SettingsCenterDialog
|
|
|
:open="settingsOpen"
|
|
:open="settingsOpen"
|
|
|
:bot-mode="applicationWorkspace"
|
|
:bot-mode="applicationWorkspace"
|
|
@@ -731,7 +741,7 @@ defineExpose({openLocalVm:()=>{if(props.isAdmin)openSettings('system-local-vm')}
|
|
|
<button v-if="isAdmin" type="button" role="menuitem" @click="chooseSettingsAction('bots')"><AppIcon :name="applicationWorkspace ? 'chat' : 'users'" :size="17" />{{ applicationWorkspace ? '进入聊天模式' : '进入 Bot 模式' }}</button>
|
|
<button v-if="isAdmin" type="button" role="menuitem" @click="chooseSettingsAction('bots')"><AppIcon :name="applicationWorkspace ? 'chat' : 'users'" :size="17" />{{ applicationWorkspace ? '进入聊天模式' : '进入 Bot 模式' }}</button>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- <div v-if="toolsMenuOpen && applicationWorkspace" class="workspace-create-dismiss" @pointerdown.self="closeToolsMenu" @keydown.esc.prevent.stop="closeToolsMenu"><div ref="toolsMenu" class="workspace-create-menu workspace-tools-menu" :style="toolsPosition" role="menu" aria-label="工具" @keydown="actionMenuKeydown"><button type="button" role="menuitem" @click="chooseTool('automations')"><AppIcon name="clock" :size="17" />自动化</button><button type="button" role="menuitem" @click="chooseTool('apps')"><AppIcon name="link" :size="17" />已连接应用</button></div></div>
|
|
|
|
|
|
|
+ <div v-if="toolsMenuOpen && applicationWorkspace" class="workspace-create-dismiss" @pointerdown.self="closeToolsMenu" @keydown.esc.prevent.stop="closeToolsMenu"><div ref="toolsMenu" class="workspace-create-menu workspace-tools-menu" :style="toolsPosition" role="menu" aria-label="工具" @keydown="actionMenuKeydown"><button type="button" role="menuitem" @click="chooseTool('bot-settings')"><AppIcon name="settings" :size="17" />Bot 设置</button><button type="button" role="menuitem" @click="chooseTool('automations')"><AppIcon name="clock" :size="17" />自动化</button><button type="button" role="menuitem" @click="chooseTool('apps')"><AppIcon name="link" :size="17" />已连接应用</button></div></div>
|
|
|
<div v-if="createMenuOpen" class="workspace-create-dismiss" @pointerdown.self="closeCreateMenu" @keydown.esc.prevent.stop="closeCreateMenu">
|
|
<div v-if="createMenuOpen" class="workspace-create-dismiss" @pointerdown.self="closeCreateMenu" @keydown.esc.prevent.stop="closeCreateMenu">
|
|
|
<div ref="createMenu" class="workspace-create-menu" :style="createPosition" role="menu" aria-label="新建聊天" @keydown="actionMenuKeydown">
|
|
<div ref="createMenu" class="workspace-create-menu" :style="createPosition" role="menu" aria-label="新建聊天" @keydown="actionMenuKeydown">
|
|
|
<button type="button" role="menuitem" @click="chooseCreate('agent')"><AppIcon name="users" :size="17" />新建 Bot</button>
|
|
<button type="button" role="menuitem" @click="chooseCreate('agent')"><AppIcon name="users" :size="17" />新建 Bot</button>
|