fix: 将全部业务抽屉提升为全局全高侧栏
This commit is contained in:
@@ -1,14 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { NScrollbar } from 'naive-ui'
|
||||
import { provide, ref } from 'vue'
|
||||
import { workspaceHostKey } from './workspaceContext'
|
||||
/** 工作区固定标题和操作区;仅内容容器滚动,不向 document 传播滚动。 */
|
||||
defineProps<{ split?: boolean; compact?: boolean }>()
|
||||
const host = ref<HTMLElement | null>(null)
|
||||
provide(workspaceHostKey, host)
|
||||
</script>
|
||||
<template>
|
||||
<section ref="host" class="workspace-page" :class="{ 'content-first-workspace': compact }">
|
||||
<section class="workspace-page" :class="{ 'content-first-workspace': compact }">
|
||||
<NScrollbar v-if="$slots.header" class="workspace-heading-scroll"
|
||||
><header class="workspace-heading"><slot name="header" /></header
|
||||
></NScrollbar>
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
import { NButton, NDrawer, NDrawerContent } from 'naive-ui'
|
||||
import { Settings2, X } from '@lucide/vue'
|
||||
import { workspaceHostKey } from './workspaceContext'
|
||||
|
||||
/** 低频配置、批量动作与回执在抽屉中查看,开关面板不影响页面查询和后台任务。 */
|
||||
/** 所有业务抽屉挂到 body,以完整视口为边界;开关面板不影响草稿、页面查询和后台任务。 */
|
||||
withDefaults(defineProps<{ title: string; label?: string; hasReceipt?: boolean }>(), { label: '操作与回执' })
|
||||
const open = defineModel<boolean>('open', { default: false })
|
||||
const host = inject(workspaceHostKey, undefined)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -23,10 +20,10 @@ const host = inject(workspaceHostKey, undefined)
|
||||
</NButton>
|
||||
<NDrawer
|
||||
v-model:show="open"
|
||||
:to="host ?? undefined"
|
||||
to="body"
|
||||
width="min(960px, 100%)"
|
||||
placement="right"
|
||||
:block-scroll="false"
|
||||
:block-scroll="true"
|
||||
display-directive="show"
|
||||
class="workspace-tools-drawer"
|
||||
:aria-label="title"
|
||||
|
||||
@@ -12,6 +12,7 @@ import ConfirmAction from '../../features/workflows/ConfirmAction.vue'
|
||||
import ThemeToggle from './ThemeToggle.vue'
|
||||
import { projectsApi } from '../../features/projects/api'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { drawerPanel } from '../../testing/naive'
|
||||
|
||||
let wrapper: VueWrapper | undefined
|
||||
afterEach(() => {
|
||||
@@ -188,7 +189,7 @@ describe('管理后台组件边界', () => {
|
||||
expect(document.querySelector('.dialog-body-scroll .n-scrollbar-container')).not.toBeNull()
|
||||
})
|
||||
|
||||
it('常用工具固定在列表外,批量抽屉挂载于工作区,开关保留列表与配置草稿', async () => {
|
||||
it('抽屉挂载 body 覆盖完整视口,开关保留列表与配置草稿', async () => {
|
||||
wrapper = mount(WorkspacePage, {
|
||||
attachTo: document.body,
|
||||
props: { split: true, compact: true },
|
||||
@@ -202,18 +203,36 @@ describe('管理后台组件边界', () => {
|
||||
expect(wrapper.get('.workspace-heading').find('[data-workspace-tools]').exists()).toBe(true)
|
||||
await wrapper.get('[data-workspace-tools]').trigger('click')
|
||||
await flushPromises()
|
||||
expect(wrapper.getComponent(NDrawer).props('to')).toBe(wrapper.get('.workspace-page').element)
|
||||
expect(wrapper.getComponent(NDrawer).props()).toMatchObject({
|
||||
to: 'body',
|
||||
blockScroll: true,
|
||||
placement: 'right',
|
||||
width: 'min(960px, 100%)',
|
||||
trapFocus: true,
|
||||
closeOnEsc: true
|
||||
})
|
||||
expect(wrapper.getComponent(NDrawerContent).props('nativeScrollbar')).toBe(false)
|
||||
expect(wrapper.get('.workspace-tools-drawer').element.closest('.workspace-split')).toBeNull()
|
||||
expect(wrapper.find('.workspace-tools-drawer .n-scrollbar-container').exists()).toBe(true)
|
||||
await wrapper.get('input[aria-label="配置草稿"]').setValue('保留配置')
|
||||
await wrapper.get('[aria-label="关闭操作面板"]').trigger('click')
|
||||
expect(wrapper.find('.workspace-tools-drawer').exists()).toBe(false)
|
||||
const container = drawerPanel().element.closest('.n-drawer-container')!
|
||||
expect(container.parentElement).toBe(document.body)
|
||||
expect(container.closest('main, .admin-content, .workspace-page')).toBeNull()
|
||||
expect(container.querySelector('.n-drawer-mask')).not.toBeNull()
|
||||
expect(drawerPanel().find('.n-scrollbar-container').exists()).toBe(true)
|
||||
await drawerPanel().get('input[aria-label="配置草稿"]').setValue('保留配置')
|
||||
await drawerPanel().get('[aria-label="关闭操作面板"]').trigger('click')
|
||||
await flushPromises()
|
||||
expect(wrapper.getComponent(NDrawer).props('show')).toBe(false)
|
||||
expect(wrapper.get('.test-list').element).toBe(list)
|
||||
await wrapper.get('[data-workspace-tools]').trigger('click')
|
||||
await flushPromises()
|
||||
expect(wrapper.get<HTMLInputElement>('input[aria-label="配置草稿"]').element.value).toBe('保留配置')
|
||||
expect(drawerPanel().get<HTMLInputElement>('input[aria-label="配置草稿"]').element.value).toBe('保留配置')
|
||||
container.querySelector<HTMLElement>('.n-drawer-mask')!.click()
|
||||
await flushPromises()
|
||||
expect(wrapper.getComponent(NDrawer).props('show')).toBe(false)
|
||||
expect(wrapper.get('.test-list').element).toBe(list)
|
||||
wrapper.unmount()
|
||||
wrapper = undefined
|
||||
expect(document.querySelector('.n-drawer-container')).toBeNull()
|
||||
})
|
||||
|
||||
it('完成项目解锁全部左侧链接,标题不再显示状态标签和刷新按钮', async () => {
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import type { InjectionKey, Ref } from 'vue'
|
||||
|
||||
/** 操作抽屉挂载到当前工作区,覆盖内容而不挤压列表或遮住整个应用导航。 */
|
||||
export const workspaceHostKey: InjectionKey<Ref<HTMLElement | null>> = Symbol('workspace-host')
|
||||
Reference in New Issue
Block a user