diff --git a/frontend/src/components/common/TitleBar.vue b/frontend/src/components/common/TitleBar.vue index da5819a..cc087c8 100644 --- a/frontend/src/components/common/TitleBar.vue +++ b/frontend/src/components/common/TitleBar.vue @@ -6,6 +6,7 @@ import { useEditorStore } from '@/stores/editor' import { useThemeStore } from '@/stores/theme' import { Moon, Sunny } from '@element-plus/icons-vue' import AppIcon from './AppIcon.vue' +import TitleBarMenu from './TitleBarMenu.vue' import { t } from '@/i18n' import { isDesktop } from '@/services/platform/desktop' import { minimizeWindow, requestWindowClose, toggleMaximizeWindow } from '@/services/platform/windowControls' @@ -61,6 +62,7 @@ function toggleFromTitlebar(event: MouseEvent) { {{ currentFileName }} +
NotesAgent diff --git a/frontend/src/components/common/TitleBarMenu.spec.ts b/frontend/src/components/common/TitleBarMenu.spec.ts new file mode 100644 index 0000000..c13c061 --- /dev/null +++ b/frontend/src/components/common/TitleBarMenu.spec.ts @@ -0,0 +1,42 @@ +// @vitest-environment happy-dom +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { mount } from '@vue/test-utils' +import { createPinia, setActivePinia } from 'pinia' +import { useEditorStore } from '@/stores/editor' +import TitleBarMenu from './TitleBarMenu.vue' + +const execute = vi.hoisted(() => vi.fn()) +vi.mock('@/services/editorCommandService', () => ({ executeEditorCommand: execute })) + +beforeEach(() => { + setActivePinia(createPinia()) + execute.mockReset().mockResolvedValue({ ok: true }) +}) + +describe('桌面顶部段落菜单', () => { + it('源码笔记通过统一编辑命令执行属性导入', async () => { + const editor = useEditorStore() + editor.mode = 'source' + editor.currentFilePath = '/示例.md' + editor.saveStatus = 'saved' + const wrapper = mount(TitleBarMenu) + await wrapper.get('.menu-trigger').trigger('click') + const item = wrapper.get('[role="menuitem"]') + expect((item.element as HTMLButtonElement).disabled).toBe(false) + await item.trigger('click') + expect(execute).toHaveBeenCalledWith('editor.import-note-properties') + expect(wrapper.find('[role="menu"]').exists()).toBe(false) + wrapper.unmount() + }) + + it('写作模式显示入口但禁止绕过编辑器能力', async () => { + const editor = useEditorStore() + editor.mode = 'wysiwyg' + editor.currentFilePath = '/示例.md' + const wrapper = mount(TitleBarMenu) + await wrapper.get('.menu-trigger').trigger('click') + expect((wrapper.get('[role="menuitem"]').element as HTMLButtonElement).disabled).toBe(true) + expect(wrapper.text()).toContain('请在无冲突的 Markdown 源码笔记中使用') + wrapper.unmount() + }) +}) diff --git a/frontend/src/components/common/TitleBarMenu.vue b/frontend/src/components/common/TitleBarMenu.vue new file mode 100644 index 0000000..9918929 --- /dev/null +++ b/frontend/src/components/common/TitleBarMenu.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/frontend/src/features/workspace/WorkspaceView.vue b/frontend/src/features/workspace/WorkspaceView.vue index 04291e7..9a35808 100644 --- a/frontend/src/features/workspace/WorkspaceView.vue +++ b/frontend/src/features/workspace/WorkspaceView.vue @@ -33,7 +33,7 @@ const workspaceStore = useWorkspaceStore()