diff --git a/src/app/DomesticOutboundListLayout.test.ts b/src/app/DomesticOutboundListLayout.test.ts new file mode 100644 index 00000000..73bd1633 --- /dev/null +++ b/src/app/DomesticOutboundListLayout.test.ts @@ -0,0 +1,52 @@ +import { readFileSync } from 'node:fs' +import { resolve } from 'node:path' +import { describe, expect, it } from 'vitest' + +const pages = [ + ['src/modules/container-loading/pages/ContainersView.vue', "key: 'cabinetNo'"], + ['src/modules/loading-lists/components/LoadingListsView.vue', "key: 'preloadNo'"], + ['src/modules/ocean-bookings/pages/OceanBookingsView.vue', "prop: 'bookingNo'"], + ['src/modules/port-schedules/pages/PortSchedulesView.vue', "prop: 'schedule.scheduleNo'"], + ['src/modules/trucking/pages/TruckAppointmentsView.vue', "key: 'appointmentNo'"], + ['src/modules/customs/pages/CustomsCasesView.vue', "prop: 'customsNo'"], + ['src/modules/outbound-dispatch/pages/OutboundDispatchesView.vue', "prop: 'orderNo'"], +] as const + +function source(path: string) { + return readFileSync(resolve(process.cwd(), path), 'utf8') +} + +describe('domestic outbound list responsive contracts', () => { + it.each(pages)('%s keeps the operation column first and fixed left', (path, firstBusinessColumn) => { + const content = source(path) + const firstAction = content.indexOf("label: '操作'") + expect(firstAction).toBeGreaterThan(-1) + expect(firstAction).toBeLessThan(content.indexOf(firstBusinessColumn, firstAction)) + const actionObjects = [...content.matchAll(/\{[^{}]*label: '操作'[^{}]*\}/g)].map((match) => match[0]) + expect(actionObjects.length).toBeGreaterThan(0) + for (const column of actionObjects) expect(column).toContain("fixed: 'left'") + }) + + it.each(pages)('%s gives every business column a stable width constraint', (path) => { + const content = source(path) + const columns = [...content.matchAll(/\{[^{}]*(?:key|prop): '[^']+'[^{}]*label: '[^']+'[^{}]*\}/g)] + .map((match) => match[0]) + .filter((column) => !column.includes("type: 'input'") && !column.includes("type: 'select'") && !column.includes("type: 'daterange'")) + expect(columns.length).toBeGreaterThan(1) + for (const column of columns) expect(column).toMatch(/\b(?:width|minWidth):\s*\d+/) + }) + + it('keeps shared 320px degradation rules for filters, actions and pagination', () => { + const queryToolbar = source('src/shared/components/QueryToolbar.vue') + const dataTable = source('src/shared/components/DataTable.vue') + const listLayout = source('src/shared/components/ListPageLayout.vue') + + expect(queryToolbar).toContain('@media (max-width: 720px)') + expect(queryToolbar).toContain('.query-toolbar__field { width: 100%; }') + expect(queryToolbar).toContain('grid-template-columns: repeat(auto-fit, minmax(120px, 1fr))') + expect(dataTable).toContain('@media (max-width: 720px)') + expect(dataTable).toContain('flex-direction: column') + expect(dataTable).toContain('.data-table__page-buttons { flex-wrap: wrap; }') + expect(listLayout).toContain('min-width: 0') + }) +}) diff --git a/src/modules/customers/pages/CustomerDetailView.vue b/src/modules/customers/pages/CustomerDetailView.vue index 8fff3977..cd7cc53d 100644 --- a/src/modules/customers/pages/CustomerDetailView.vue +++ b/src/modules/customers/pages/CustomerDetailView.vue @@ -324,7 +324,7 @@ watch(orderPage, (page, previousPage) => {
返回列表 - +