mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-08-28 19:47:49 +08:00
fix(shortcuts): scope dynamic close listeners (#716)
This commit is contained in:
@@ -14,6 +14,8 @@ const props = withDefaults(
|
||||
icon?: string
|
||||
maxWidth?: string
|
||||
modelValue?: boolean
|
||||
/** 动态视图是否声明并可能触发 close 事件。 */
|
||||
supportsClose?: boolean
|
||||
subtitle?: string
|
||||
title: string
|
||||
view: Component
|
||||
@@ -25,6 +27,7 @@ const props = withDefaults(
|
||||
icon: 'mdi-cog',
|
||||
maxWidth: '35rem',
|
||||
modelValue: true,
|
||||
supportsClose: false,
|
||||
viewProps: () => ({}),
|
||||
},
|
||||
)
|
||||
@@ -81,7 +84,7 @@ function closeDialog() {
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText :class="bodyClasses">
|
||||
<Component :is="props.view" v-bind="props.viewProps" @close="closeDialog" />
|
||||
<Component :is="props.view" v-bind="props.viewProps" v-on="props.supportsClose ? { close: closeDialog } : {}" />
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
|
||||
@@ -2,20 +2,30 @@ import ShortcutToolDialog from '@/components/dialog/ShortcutToolDialog.vue'
|
||||
import { screen } from '@testing-library/vue'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { renderWithProviders } from '@tests/support/render'
|
||||
import { defineComponent, markRaw } from 'vue'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { defineComponent, h, markRaw } from 'vue'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const ToolView = defineComponent({
|
||||
emits: ['close'],
|
||||
template: '<button type="button" @click="$emit(\'close\')">关闭工具</button>',
|
||||
})
|
||||
|
||||
const FragmentToolView = defineComponent({
|
||||
setup(_, { attrs }) {
|
||||
return () => [
|
||||
h('span', { 'data-testid': 'close-listener-state' }, attrs.onClose ? '已绑定' : '未绑定'),
|
||||
h('span', '普通工具内容'),
|
||||
]
|
||||
},
|
||||
})
|
||||
|
||||
describe('ShortcutToolDialog', () => {
|
||||
it('closes the outer dialog when the active tool requests it', async () => {
|
||||
const user = userEvent.setup()
|
||||
const result = await renderWithProviders(ShortcutToolDialog, {
|
||||
props: {
|
||||
modelValue: true,
|
||||
supportsClose: true,
|
||||
title: '测试工具',
|
||||
view: markRaw(ToolView),
|
||||
},
|
||||
@@ -31,4 +41,26 @@ describe('ShortcutToolDialog', () => {
|
||||
expect(result.emitted()['update:modelValue']).toEqual([[false]])
|
||||
expect(result.emitted().close).toEqual([[]])
|
||||
})
|
||||
|
||||
it('does not pass a close listener to an ordinary fragment view', async () => {
|
||||
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
|
||||
|
||||
await renderWithProviders(ShortcutToolDialog, {
|
||||
props: {
|
||||
modelValue: true,
|
||||
title: '普通工具',
|
||||
view: markRaw(FragmentToolView),
|
||||
},
|
||||
global: {
|
||||
stubs: {
|
||||
VDialogCloseBtn: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(screen.getByTestId('close-listener-state')).toHaveTextContent('未绑定')
|
||||
expect(warn.mock.calls.some(([message]) => String(message).includes('Extraneous non-emits event listeners'))).toBe(
|
||||
false,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -31,6 +31,8 @@ export type ShortcutToolItem = PermissionProtectedItem & {
|
||||
dialogSubtitle?: string
|
||||
icon: string
|
||||
maxWidth?: string
|
||||
/** 动态视图是否声明并可能触发 close 事件。 */
|
||||
supportsClose?: boolean
|
||||
subtitle: string
|
||||
title: string
|
||||
titleText?: string
|
||||
@@ -50,6 +52,7 @@ export function useShortcutTools() {
|
||||
dialog: 'nameTest',
|
||||
component: NameTestView,
|
||||
maxWidth: '65rem',
|
||||
supportsClose: true,
|
||||
titleText: t('shortcut.recognition.title'),
|
||||
},
|
||||
{
|
||||
@@ -143,6 +146,7 @@ export function useShortcutTools() {
|
||||
icon: item.icon,
|
||||
maxWidth: item.maxWidth ?? '35rem',
|
||||
subtitle: item.dialogSubtitle,
|
||||
supportsClose: item.supportsClose,
|
||||
title: item.titleText ?? item.title,
|
||||
view: item.component,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user