fix(admin): 完善弹窗滚动与表单交互布局
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
import ElementPlus, { ElCheckboxButton, ElInputNumber, ElMessage, ElMessageBox, ElOption, ElSelect } from 'element-plus'
|
||||
import { AxiosError } from 'axios'
|
||||
import { createPinia, setActivePinia } from 'pinia'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { DOMWrapper, enableAutoUnmount, flushPromises, mount } from '@vue/test-utils'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import QueryToolbar from '@/shared/components/QueryToolbar.vue'
|
||||
import { listPlatformTenants, type PlatformTenantResource } from '@/modules/iam'
|
||||
import GlobalSmartLoadingView from './GlobalSmartLoadingView.vue'
|
||||
import AppDialog from '@/shared/components/AppDialog.vue'
|
||||
import SmartLoadingDialog from '../components/SmartLoadingDialog.vue'
|
||||
import type { ContainerBookingResource } from '../types'
|
||||
import {
|
||||
assignPendingReviewSmartLoadingOrder,
|
||||
@@ -27,6 +28,8 @@ import {
|
||||
removeSmartLoadingPallet,
|
||||
} from '../api/platformContainerLoading'
|
||||
|
||||
enableAutoUnmount(afterEach)
|
||||
|
||||
const { routerPush } = vi.hoisted(() => ({ routerPush: vi.fn() }))
|
||||
|
||||
vi.mock('vue-router', () => ({
|
||||
@@ -120,7 +123,50 @@ function mockContainerSearch(records: ContainerBookingResource[]) {
|
||||
))))
|
||||
}
|
||||
|
||||
function assignmentDialog() {
|
||||
const root = document.body.querySelector<HTMLElement>('.smart-loading-assignment-dialog')
|
||||
if (!root) throw new Error('assignment dialog is missing')
|
||||
return new DOMWrapper(root)
|
||||
}
|
||||
|
||||
describe('GlobalSmartLoadingView', () => {
|
||||
it('mounts assignment outside the parent workbench and keeps fullscreen and reopen states independent', async () => {
|
||||
const wrapper = mount(SmartLoadingDialog, { attachTo: document.body, props: { modelValue: true }, global: { plugins: [ElementPlus] } })
|
||||
try {
|
||||
await flushPromises()
|
||||
const workbench = wrapper.getComponent(GlobalSmartLoadingView)
|
||||
const openAssignment = async () => {
|
||||
await workbench.get('.candidate-pane .el-table__body-wrapper').findAll('button').find(button => button.text() === '加入')!.trigger('click')
|
||||
await flushPromises()
|
||||
}
|
||||
await openAssignment()
|
||||
const popup = workbench.getComponent(AppDialog)
|
||||
const outer = document.querySelector('.smart-loading-dialog')!
|
||||
const child = assignmentDialog()
|
||||
expect(document.body.contains(child.element)).toBe(true)
|
||||
expect(outer.contains(child.element)).toBe(false)
|
||||
expect(child.element.closest('.global-loading-page')).toBeNull()
|
||||
expect(child.classes()).toEqual(expect.arrayContaining(['admin-density-dialog', 'admin-workbench', 'is-dialog']))
|
||||
popup.getComponent(ElInputNumber).vm.$emit('update:modelValue', 4)
|
||||
await child.get('[aria-label="展开全屏"]').trigger('click')
|
||||
expect(child.classes()).toContain('is-fullscreen')
|
||||
expect(outer.classList.contains('is-fullscreen')).toBe(true)
|
||||
await child.findAll('button').find(button => button.text() === '取消')!.trigger('click')
|
||||
await flushPromises()
|
||||
expect(popup.props('modelValue')).toBe(false)
|
||||
expect(wrapper.getComponent(AppDialog).props('modelValue')).toBe(true)
|
||||
expect(workbench.get('.container-option.selected').attributes('aria-pressed')).toBe('true')
|
||||
await openAssignment()
|
||||
expect(popup.props('modelValue')).toBe(true)
|
||||
expect(assignmentDialog().classes()).not.toContain('is-fullscreen')
|
||||
expect(popup.getComponent(ElInputNumber).props('modelValue')).toBe(candidate.availablePackageCount)
|
||||
expect(outer.classList.contains('is-fullscreen')).toBe(true)
|
||||
expect(assignSmartLoadingItem).not.toHaveBeenCalled()
|
||||
} finally {
|
||||
wrapper.unmount()
|
||||
}
|
||||
})
|
||||
|
||||
it.each(['PACKAGE', 'SEALED_PALLET'] as const)('分配窗口全屏保留来源及输入,按%s原接口提交', async (unitType) => {
|
||||
if (unitType === 'SEALED_PALLET') {
|
||||
vi.mocked(listSmartLoadingCandidates).mockResolvedValue(candidatePage([{
|
||||
@@ -138,7 +184,7 @@ describe('GlobalSmartLoadingView', () => {
|
||||
await wrapper.get('.candidate-pane .el-table__body-wrapper').findAll('button').find(button => button.text() === '加入')!.trigger('click')
|
||||
await flushPromises()
|
||||
const popup = wrapper.getComponent(AppDialog)
|
||||
expect(popup.get('table[aria-label="全局装柜分配来源"]').text()).toContain('CB-1')
|
||||
expect(assignmentDialog().get('table[aria-label="全局装柜分配来源"]').text()).toContain('CB-1')
|
||||
if (unitType === 'PACKAGE') {
|
||||
const input = popup.getComponent(ElInputNumber)
|
||||
expect(input.props('modelValue')).toBe(candidate.availablePackageCount)
|
||||
@@ -146,11 +192,11 @@ describe('GlobalSmartLoadingView', () => {
|
||||
input.vm.$emit('update:modelValue', 4)
|
||||
} else {
|
||||
expect(popup.findComponent(ElInputNumber).exists()).toBe(false)
|
||||
expect(popup.get('details').text()).toContain('I181:9 箱')
|
||||
expect(assignmentDialog().get('details').text()).toContain('I181:9 箱')
|
||||
expect(popup.props('title')).toBe('整托加入当前柜次 · DP-TEST-1')
|
||||
}
|
||||
await popup.get('[aria-label="展开全屏"]').trigger('click')
|
||||
expect(popup.find('.el-dialog.is-fullscreen').exists()).toBe(true)
|
||||
await assignmentDialog().get('[aria-label="展开全屏"]').trigger('click')
|
||||
expect(assignmentDialog().classes()).toContain('is-fullscreen')
|
||||
if (unitType === 'PACKAGE') expect(popup.getComponent(ElInputNumber).props('modelValue')).toBe(4)
|
||||
popup.vm.$emit('confirm'); await flushPromises()
|
||||
if (unitType === 'PACKAGE') {
|
||||
@@ -572,11 +618,11 @@ describe('GlobalSmartLoadingView', () => {
|
||||
expect(document.body.textContent).toContain('不能部分输入、单独分配或单独移除')
|
||||
const popup = wrapper.getComponent(AppDialog)
|
||||
expect(popup.props('title')).toBe('整组加入当前柜次 · CLG-2093539779795795969')
|
||||
const contextRows = popup.findAll('table[aria-label="全局装柜分配来源"] tr')
|
||||
const contextRows = assignmentDialog().findAll('table[aria-label="全局装柜分配来源"] tr')
|
||||
expect(contextRows[0]!.findAll('td').map(cell => cell.text())).toEqual(['CB-1', 'MSCU-1'])
|
||||
expect(contextRows[1]!.findAll('td').map(cell => cell.text())).toEqual(['义乌仓', '美森正班'])
|
||||
await popup.get('[aria-label="展开全屏"]').trigger('click')
|
||||
expect(popup.get('table[aria-label="全局装柜同柜组成员"]').text()).toContain('NYEXX2608290051-B')
|
||||
await assignmentDialog().get('[aria-label="展开全屏"]').trigger('click')
|
||||
expect(assignmentDialog().get('table[aria-label="全局装柜同柜组成员"]').text()).toContain('NYEXX2608290051-B')
|
||||
expect(document.body.textContent).not.toContain('本次分配箱数')
|
||||
;([...document.body.querySelectorAll('button')].find((button) => button.textContent?.includes('确认整组分配')) as HTMLButtonElement).click()
|
||||
await flushPromises()
|
||||
@@ -612,9 +658,9 @@ describe('GlobalSmartLoadingView', () => {
|
||||
await flushPromises()
|
||||
const popup = wrapper.getComponent(AppDialog)
|
||||
expect(popup.props('title')).toBe('加入当前柜次 · EXXHK2609020361')
|
||||
const measurements = popup.findAll('table[aria-label="全局装柜分配填写"] tr').find(row => row.text().includes('平均单箱毛重'))!
|
||||
const measurements = assignmentDialog().findAll('table[aria-label="全局装柜分配填写"] tr').find(row => row.text().includes('平均单箱毛重'))!
|
||||
expect(measurements.findAll('td').map(cell => cell.text())).toEqual(['待测量', '待测量'])
|
||||
const channel = popup.findAll('table[aria-label="全局装柜分配来源"] tr').find(row => row.text().includes('订单渠道'))!
|
||||
const channel = assignmentDialog().findAll('table[aria-label="全局装柜分配来源"] tr').find(row => row.text().includes('订单渠道'))!
|
||||
expect(channel.findAll('td')[0]!.text()).toBe('合德海卡')
|
||||
expect(document.body.textContent).toContain('这是人工装柜分配,确认后仍会加入')
|
||||
expect(document.body.textContent).toContain('智能推荐不会跨渠道')
|
||||
@@ -907,10 +953,10 @@ describe('GlobalSmartLoadingView', () => {
|
||||
await flushPromises()
|
||||
|
||||
// 箱数与上方资料使用同一标签列,保留输入名称与原范围。
|
||||
const label = popup.get('label[for="global-loading-assignment-count"]')
|
||||
const label = assignmentDialog().get('label[for="global-loading-assignment-count"]')
|
||||
expect(label.element.parentElement?.tagName).toBe('TH')
|
||||
expect(label.element.parentElement?.nextElementSibling?.getAttribute('colspan')).toBe('3')
|
||||
expect(popup.find('input#global-loading-assignment-count').exists()).toBe(true)
|
||||
expect(assignmentDialog().find('input#global-loading-assignment-count').exists()).toBe(true)
|
||||
expect(input.props('max')).toBe(candidate.availablePackageCount)
|
||||
popup.vm.$emit('confirm')
|
||||
await flushPromises()
|
||||
@@ -918,11 +964,12 @@ describe('GlobalSmartLoadingView', () => {
|
||||
expect(assignSmartLoadingItem).toHaveBeenCalledWith(plan.id, { inboundId: candidate.inboundId, packageCount: 7, expectedVersion: plan.version })
|
||||
expect(popup.props('modelValue')).toBe(true)
|
||||
expect(input.props('modelValue')).toBe(7)
|
||||
expect(popup.text()).toContain('加入当前柜次失败')
|
||||
expect(popup.text()).toContain('当前账号无权访问该数据')
|
||||
expect(popup.text()).toContain('assign-request')
|
||||
expect(popup.text()).toContain('assign-trace')
|
||||
expect(wrapper.get('.global-loading-page').findAll('.load-error-state')).toHaveLength(1)
|
||||
expect(assignmentDialog().text()).toContain('加入当前柜次失败')
|
||||
expect(assignmentDialog().text()).toContain('当前账号无权访问该数据')
|
||||
expect(assignmentDialog().text()).toContain('assign-request')
|
||||
expect(assignmentDialog().text()).toContain('assign-trace')
|
||||
expect(assignmentDialog().findAll('.load-error-state')).toHaveLength(1)
|
||||
expect(wrapper.get('.global-loading-page').findAll('.load-error-state')).toHaveLength(0)
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user