This commit is contained in:
2026-09-04 14:43:34 +08:00
parent e4ba4cbb2c
commit 2fc84d249c
4 changed files with 37 additions and 9 deletions
@@ -14,6 +14,7 @@ describe('InboundMeasurementDialog', () => {
expect(source).toContain('class="inbound-measurement-workspace-dialog"') expect(source).toContain('class="inbound-measurement-workspace-dialog"')
expect(source).toContain('width="min(1240px, calc(100vw - 32px))"') expect(source).toContain('width="min(1240px, calc(100vw - 32px))"')
expect(source).toContain('height: 92vh') expect(source).toContain('height: 92vh')
expect(source).toContain('padding: 10px 20px')
expect(source).toContain('<WeightOcrPanel') expect(source).toContain('<WeightOcrPanel')
expect(source).toContain('<InboundMeasurementPanel') expect(source).toContain('<InboundMeasurementPanel')
expect(source).toContain('class="measurement-dialog-weight"') expect(source).toContain('class="measurement-dialog-weight"')
@@ -130,7 +130,7 @@ function handleSubmitted() {
<style> <style>
.inbound-measurement-workspace-dialog.el-dialog { display: flex; max-width: calc(100vw - 32px); height: 92vh; max-height: 92vh; margin-bottom: 0; flex-direction: column; overflow: hidden; } .inbound-measurement-workspace-dialog.el-dialog { display: flex; max-width: calc(100vw - 32px); height: 92vh; max-height: 92vh; margin-bottom: 0; flex-direction: column; overflow: hidden; }
.inbound-measurement-workspace-dialog .el-dialog__header { flex: 0 0 auto; margin: 0; padding: 18px 24px; border-bottom: 1px solid var(--cc-border); } .inbound-measurement-workspace-dialog .el-dialog__header { flex: 0 0 auto; margin: 0; padding: 10px 20px; border-bottom: 1px solid var(--cc-border); }
.inbound-measurement-workspace-dialog .el-dialog__body { min-height: 0; flex: 1 1 auto; overflow-y: auto; padding: 20px 24px; } .inbound-measurement-workspace-dialog .el-dialog__body { min-height: 0; flex: 1 1 auto; overflow-y: auto; padding: 20px 24px; }
.inbound-measurement-workspace-dialog .el-dialog__footer { flex: 0 0 auto; padding: 14px 24px; border-top: 1px solid var(--cc-border); } .inbound-measurement-workspace-dialog .el-dialog__footer { flex: 0 0 auto; padding: 14px 24px; border-top: 1px solid var(--cc-border); }
.inbound-measurement-workspace-dialog .measurement-panel { border: 0; border-radius: 0; box-shadow: none; } .inbound-measurement-workspace-dialog .measurement-panel { border: 0; border-radius: 0; box-shadow: none; }
+14 -1
View File
@@ -8,12 +8,13 @@ import AppDialog from './AppDialog.vue'
const ElDialogStub = defineComponent({ const ElDialogStub = defineComponent({
props: { props: {
modelValue: Boolean, modelValue: Boolean,
title: String,
showClose: Boolean, showClose: Boolean,
closeOnClickModal: Boolean, closeOnClickModal: Boolean,
closeOnPressEscape: Boolean, closeOnPressEscape: Boolean,
fullscreen: Boolean, fullscreen: Boolean,
}, },
template: '<section data-testid="dialog"><slot name="header" /><slot /><slot name="footer" /></section>', template: '<section data-testid="dialog"><h2 v-if="!$slots.header" data-testid="native-title">{{ title }}</h2><slot name="header" /><slot /><slot name="footer" /></section>',
}) })
const ElButtonStub = defineComponent({ const ElButtonStub = defineComponent({
@@ -73,6 +74,9 @@ describe('AppDialog', () => {
const wrapper = mountDialog({ fullscreenable: true, defaultFullscreen: true }) const wrapper = mountDialog({ fullscreenable: true, defaultFullscreen: true })
expect(wrapper.getComponent(ElDialogStub).props('fullscreen')).toBe(true) expect(wrapper.getComponent(ElDialogStub).props('fullscreen')).toBe(true)
expect(wrapper.get('[data-testid="native-title"]').text()).toBe('编辑资料')
expect(wrapper.find('.app-dialog__header').exists()).toBe(false)
expect(wrapper.find('.app-dialog__native-fullscreen-control').exists()).toBe(true)
expect(wrapper.find('button[aria-label="退出全屏"]').exists()).toBe(true) expect(wrapper.find('button[aria-label="退出全屏"]').exists()).toBe(true)
await wrapper.get('button[aria-label="退出全屏"]').trigger('click') await wrapper.get('button[aria-label="退出全屏"]').trigger('click')
@@ -88,4 +92,13 @@ describe('AppDialog', () => {
expect(source).toContain(':global(.app-dialog .el-dialog__body) { min-height: 0; overflow-y: auto;') expect(source).toContain(':global(.app-dialog .el-dialog__body) { min-height: 0; overflow-y: auto;')
expect(source).toContain('max-height: calc(100svh - 20px)') expect(source).toContain('max-height: calc(100svh - 20px)')
}) })
it('keeps the native title bar when fullscreen is enabled without a custom header', () => {
const source = readFileSync(resolve(process.cwd(), 'src/shared/components/AppDialog.vue'), 'utf8')
expect(source).toContain('<template v-if="$slots.header" #header>')
expect(source).not.toContain('<template v-if="$slots.header || fullscreenable" #header>')
expect(source).toContain("fullscreenable && !$slots.header")
expect(source).toContain('app-dialog__native-fullscreen-control')
})
}) })
+21 -7
View File
@@ -80,22 +80,33 @@ function closeDialog() {
:close-on-press-escape="closeOnPressEscape && !submittingLocked" :close-on-press-escape="closeOnPressEscape && !submittingLocked"
:destroy-on-close="destroyOnClose" :destroy-on-close="destroyOnClose"
:fullscreen="fullscreenable && fullscreen" :fullscreen="fullscreenable && fullscreen"
:class="{ 'has-native-fullscreen-control': fullscreenable && !$slots.header }"
> >
<template v-if="$slots.header || fullscreenable" #header> <template v-if="$slots.header" #header>
<div v-if="fullscreenable" class="app-dialog__header"> <div class="app-dialog__header">
<div class="app-dialog__header-content"> <div class="app-dialog__header-content">
<slot v-if="$slots.header" name="header" :fullscreen="fullscreen" :toggle-fullscreen="toggleFullscreen" /> <slot name="header" :fullscreen="fullscreen" :toggle-fullscreen="toggleFullscreen" />
<span v-else>{{ title }}</span>
</div> </div>
<el-tooltip :content="fullscreen ? '退出全屏' : '展开全屏'" placement="bottom"> <el-tooltip v-if="fullscreenable" :content="fullscreen ? '退出全屏' : '展开全屏'" placement="bottom">
<el-button text :aria-label="fullscreen ? '退出全屏' : '展开全屏'" @click="toggleFullscreen"> <el-button text :aria-label="fullscreen ? '退出全屏' : '展开全屏'" @click="toggleFullscreen">
<Minimize2 v-if="fullscreen" :size="18" /> <Minimize2 v-if="fullscreen" :size="18" />
<Maximize2 v-else :size="18" /> <Maximize2 v-else :size="18" />
</el-button> </el-button>
</el-tooltip> </el-tooltip>
</div> </div>
<slot v-else name="header" />
</template> </template>
<el-tooltip v-if="fullscreenable && !$slots.header" :content="fullscreen ? '退出全屏' : '展开全屏'" placement="bottom">
<el-button
class="app-dialog__native-fullscreen-control"
:class="{ 'is-without-close': !showClose || submittingLocked }"
text
:aria-label="fullscreen ? '退出全屏' : '展开全屏'"
@click="toggleFullscreen"
>
<Minimize2 v-if="fullscreen" :size="18" />
<Maximize2 v-else :size="18" />
</el-button>
</el-tooltip>
<div v-loading="loading" class="app-dialog__body" :aria-busy="loading || confirmLoading"> <div v-loading="loading" class="app-dialog__body" :aria-busy="loading || confirmLoading">
<slot /> <slot />
</div> </div>
@@ -117,13 +128,16 @@ function closeDialog() {
</template> </template>
<style scoped> <style scoped>
:global(.app-dialog.el-dialog) { display: flex; max-height: min(90vh, 900px); flex-direction: column; overflow: hidden; } :global(.app-dialog.el-dialog) { position: relative; display: flex; max-height: min(90vh, 900px); flex-direction: column; overflow: hidden; }
:global(.app-dialog.el-dialog.is-fullscreen) { width: 100%; max-width: 100%; height: 100vh; max-height: 100vh; margin: 0 !important; border-radius: 0; } :global(.app-dialog.el-dialog.is-fullscreen) { width: 100%; max-width: 100%; height: 100vh; max-height: 100vh; margin: 0 !important; border-radius: 0; }
:global(.app-dialog .el-dialog__header), :global(.app-dialog .el-dialog__footer) { flex: 0 0 auto; } :global(.app-dialog .el-dialog__header), :global(.app-dialog .el-dialog__footer) { flex: 0 0 auto; }
:global(.app-dialog .el-dialog__body) { min-height: 0; overflow-y: auto; overscroll-behavior: contain; } :global(.app-dialog .el-dialog__body) { min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
:global(.app-dialog.has-native-fullscreen-control .el-dialog__title) { display: block; padding-right: 44px; }
.app-dialog__header { display: flex; width: 100%; min-width: 0; align-items: center; justify-content: space-between; gap: 12px; color: var(--cc-text); font-size: 18px; font-weight: 600; line-height: 24px; } .app-dialog__header { display: flex; width: 100%; min-width: 0; align-items: center; justify-content: space-between; gap: 12px; color: var(--cc-text); font-size: 18px; font-weight: 600; line-height: 24px; }
.app-dialog__header-content { min-width: 0; flex: 1; } .app-dialog__header-content { min-width: 0; flex: 1; }
.app-dialog__header > :deep(.el-button) { flex: 0 0 auto; margin-right: 24px; color: var(--cc-muted); } .app-dialog__header > :deep(.el-button) { flex: 0 0 auto; margin-right: 24px; color: var(--cc-muted); }
.app-dialog__native-fullscreen-control { position: absolute; z-index: 2; top: 10px; right: 48px; color: var(--cc-muted); }
.app-dialog__native-fullscreen-control.is-without-close { right: 12px; }
.app-dialog__body { min-height: 0; } .app-dialog__body { min-height: 0; }
.app-dialog__footer { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; } .app-dialog__footer { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; }
.app-dialog__footer :deep(.el-button) { margin-left: 0; } .app-dialog__footer :deep(.el-button) { margin-left: 0; }