fix(fleet): preserve drafts before dialog close and respect dashboard permissions

This commit is contained in:
2026-10-07 18:21:03 +08:00
parent 2477667c27
commit 2bc095ecac
11 changed files with 150 additions and 34 deletions
+16 -1
View File
@@ -1,6 +1,6 @@
import { defineComponent } from 'vue'
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import { describe, expect, it, vi } from 'vitest'
import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
import AppDialog from './AppDialog.vue'
@@ -13,6 +13,7 @@ const ElDialogStub = defineComponent({
closeOnClickModal: Boolean,
closeOnPressEscape: Boolean,
fullscreen: Boolean,
beforeClose: Function,
},
template: '<section data-testid="dialog"><h2 v-if="!$slots.header" data-testid="native-title">{{ title }}</h2><slot name="header" /><slot /><slot name="footer" /></section>',
})
@@ -62,6 +63,20 @@ describe('AppDialog', () => {
expect(cancelButton.attributes('disabled')).toBeDefined()
})
it('applies the same opt-in beforeClose hook to native close and the default cancel action', async () => {
let allowClose: (() => void) | undefined
const beforeClose = vi.fn((done: () => void) => { allowClose = done })
const wrapper = mountDialog({ beforeClose })
expect(wrapper.getComponent(ElDialogStub).props('beforeClose')).toBe(beforeClose)
await wrapper.findAll('button')[0]!.trigger('click')
expect(beforeClose).toHaveBeenCalledOnce()
expect(wrapper.emitted('cancel')).toBeUndefined()
expect(wrapper.emitted('update:modelValue')).toBeUndefined()
allowClose!()
expect(wrapper.emitted('cancel')).toHaveLength(1)
expect(wrapper.emitted('update:modelValue')).toEqual([[false]])
})
it('can render a content-only dialog without footer actions', () => {
const wrapper = mountDialog({ showFooter: false })
expect(wrapper.findAll('button')).toHaveLength(0)
+8 -2
View File
@@ -25,6 +25,7 @@ const props = withDefaults(defineProps<{
lockWhileSubmitting?: boolean
fullscreenable?: boolean
defaultFullscreen?: boolean
beforeClose?: (done: () => void) => void | Promise<void>
}>(), {
width: 'min(560px, calc(100vw - 28px))',
loading: false,
@@ -63,8 +64,12 @@ function toggleFullscreen() {
function closeDialog() {
if (submittingLocked.value) return
open.value = false
emit('cancel')
const done = () => {
open.value = false
emit('cancel')
}
if (props.beforeClose) void props.beforeClose(done)
else done()
}
</script>
@@ -79,6 +84,7 @@ function closeDialog() {
:close-on-click-modal="closeOnClickModal && !submittingLocked"
:close-on-press-escape="closeOnPressEscape && !submittingLocked"
:destroy-on-close="destroyOnClose"
:before-close="beforeClose"
:fullscreen="fullscreenable && fullscreen"
:class="{ 'has-native-fullscreen-control': fullscreenable && !$slots.header }"
>