fix: 优化移动端工作台筛选与工具栏
将形态图片状态筛选合并为下拉框,统一筛选容器内边距并调整背景。重新排列分镜与镜头生产移动端工具栏,隐藏重复统计并补充交互测试。
This commit is contained in:
+28
-27
@@ -1,49 +1,48 @@
|
|||||||
# Design QA
|
# Design QA
|
||||||
|
|
||||||
- Source visual truth:
|
- Source visual truth:
|
||||||
- `/workspace/scratch/6e52996114b8/upload/83e0987d-5b6e-46b1-b39b-0674bf374f43.png`
|
- `/workspace/scratch/6e52996114b8/upload/75026374-fe20-45b3-9596-b704e404f14e.png`
|
||||||
- `/workspace/scratch/6e52996114b8/upload/60e23391-685b-4538-95a2-46f6334f5f6d.png`
|
- `/workspace/scratch/6e52996114b8/upload/672c002e-13b3-4a89-88ae-657cce7b1554.png`
|
||||||
- `/workspace/scratch/6e52996114b8/upload/430bec04-93fd-429f-a820-1edefdafc792.png`
|
- `/workspace/scratch/6e52996114b8/upload/bddc4895-360d-48d0-b248-d384283085bc.png`
|
||||||
- Source pixel dimensions: `2048 × 819`, `447 × 203`, `238 × 198`.
|
- Source pixel dimensions: `466 × 307`, `486 × 213`, `496 × 358`.
|
||||||
- Intended implementation viewport: desktop dark theme; the primary reference is `2048 × 819`.
|
- Intended implementation viewport: mobile dark theme, approximately `393px` CSS width.
|
||||||
- Implementation screenshot: unavailable.
|
- Implementation screenshot: unavailable.
|
||||||
- CSS size and density normalization: unavailable because the implementation could not be opened in the cloud browser.
|
- CSS size and density normalization: unavailable because the implementation could not be opened in the cloud browser.
|
||||||
- State: 主体身份详情页已有身份母版;形态图库默认筛选和布局切换状态。
|
- State: 形态图片默认筛选、分镜设计已完成统计、镜头生产首帧工具栏。
|
||||||
|
|
||||||
## Full-view comparison evidence
|
## Full-view comparison evidence
|
||||||
|
|
||||||
The source images were opened and inspected. The first source shows the generic `.asset-image` width expanding the identity-anchor summary image across the detail panel and squeezing its explanatory copy into a narrow column on the far right. The second source shows the gallery summary/actions and filter panel consuming too much vertical space. The third source establishes the compact dark workspace density used by the surrounding pages.
|
The three source images were opened and inspected. The first source shows two checkbox filters consuming a full mobile row and a redundant result count beside the layout switch. The second and third sources show desktop flex toolbar behavior wrapping on mobile, leaving unused horizontal regions before actions or after metrics.
|
||||||
|
|
||||||
The implementation passed lint, formatting, TypeScript, component/unit tests, and the production build. A local Sites preview started successfully at the required port, but the cloud browser rejected `terminal.local` with `net::ERR_BLOCKED_BY_CLIENT` on both the existing tab and one fresh tab. Therefore no browser-rendered implementation evidence is available.
|
The implementation passed formatting, TypeScript, focused component tests, and the production build. A local Sites preview started successfully at the required port, but the cloud browser rejected `terminal.local` with `net::ERR_BLOCKED_BY_CLIENT`. Therefore no browser-rendered implementation evidence is available.
|
||||||
|
|
||||||
## Focused region comparison evidence
|
## Focused region comparison evidence
|
||||||
|
|
||||||
- Identity anchor: `.identity-anchor > .asset-image` now has a component-local `80 × 80` square constraint with higher selector specificity than the generic AssetImage width rule. The adjacent copy has `min-width: 0`.
|
- 形态筛选:两个复选框合并为“全部状态 / 缺少主图 / 身份过期”单选下拉;筛选容器使用统一 `12px` 内边距和更浅的混合背景;`460px` 以下隐藏结果数量,并让状态下拉与布局切换并排。
|
||||||
- Identity detail container: the detail scrollbar, its container/content, and the panel now explicitly use `width: 100%`, `min-width: 0`, and `max-width: 100%` to contain long content.
|
- 分镜设计:`760px` 以下工具栏改为单列网格,剧集、统计、操作分别占满整行;统计两端分布,操作从左侧开始排列。
|
||||||
- Gallery density: the summary/actions moved into the `WorkspacePage` header and the filter region's vertical padding changed from `14px` to `5px`.
|
- 镜头生产:`760px` 以下隐藏与镜头目录重复的“本集 N 镜”统计,工具栏操作从左侧连续排列。
|
||||||
- Page headers: every `WorkspacePage` caller now uses compact mode.
|
|
||||||
|
|
||||||
These are code-level checks only and do not replace a rendered focused-region comparison.
|
These are code-level checks only and do not replace a rendered focused-region comparison.
|
||||||
|
|
||||||
## Required fidelity surfaces
|
## Required fidelity surfaces
|
||||||
|
|
||||||
- Fonts and typography: existing project font stack, sizes, weights, and wrapping were preserved; browser comparison is blocked.
|
- Fonts and typography: existing project font stack, sizes, weights, truncation, and copy were preserved; browser comparison is blocked.
|
||||||
- Spacing and layout rhythm: the requested header compaction and `5px` gallery filter padding are implemented; browser measurement is blocked.
|
- Spacing and layout rhythm: component-local responsive rules remove the marked mobile gaps and keep the existing compact header density; exact browser measurement is blocked.
|
||||||
- Colors and visual tokens: existing dark/light CSS variables were preserved; browser comparison is blocked.
|
- Colors and visual tokens: the filter background remains based on `--app-subtle` and is lightened with `color-mix`; browser sampling is blocked.
|
||||||
- Image quality and asset fidelity: no source assets were replaced or generated; existing backend images remain in use. Browser crop verification is blocked.
|
- Image quality and asset fidelity: no image assets or crop rules changed.
|
||||||
- Copy and content: existing product copy is retained except where video generation now describes the formal strict-quality workflow.
|
- Copy and content: existing product copy remains unchanged except the two checkbox labels now appear as equivalent dropdown options; the mobile-only duplicate shot count is visually hidden.
|
||||||
|
|
||||||
## Findings
|
## Findings
|
||||||
|
|
||||||
- [P1] Browser-rendered comparison unavailable
|
- [P1] Browser-rendered comparison unavailable
|
||||||
- Location: all three target states.
|
- Location: all three target mobile states.
|
||||||
- Evidence: the preview process is healthy, but the required cloud browser returns `net::ERR_BLOCKED_BY_CLIENT` for `http://terminal.local:4173/`.
|
- Evidence: the preview process is healthy, but the required cloud browser returns `net::ERR_BLOCKED_BY_CLIENT` for `http://terminal.local:4173/`.
|
||||||
- Impact: exact visual fidelity, responsive behavior, interactions, and console state cannot be certified from the browser.
|
- Impact: exact responsive spacing, rendered Naive UI select behavior, primary interactions, and console state cannot be visually certified.
|
||||||
- Fix: open the same preview in an available Work Mode cloud browser, reproduce the target data/theme, capture the three states, and rerun this QA.
|
- Fix: open the same branch in an available browser with project data, capture the three target routes at `393px` width, and rerun this comparison.
|
||||||
|
|
||||||
## Primary interactions tested
|
## Primary interactions tested
|
||||||
|
|
||||||
Automated component tests cover filters, layout switching, workspace drawers, project-level formal storyboard actions, video quality API parameters, disabled states, receipts, and navigation. Browser interactions were not available.
|
Automated component tests cover search, subject type and image-status dropdown filtering, result count changes, layout switching, affected-shot selection, and reset behavior. Browser interactions were not available.
|
||||||
|
|
||||||
## Console errors checked
|
## Console errors checked
|
||||||
|
|
||||||
@@ -51,14 +50,16 @@ Not checked because the page could not be opened in the cloud browser.
|
|||||||
|
|
||||||
## Comparison history
|
## Comparison history
|
||||||
|
|
||||||
- Iteration 1: identified the P1 implementation-capture blocker after the local preview started. No visual iteration could be completed.
|
- Iteration 1: replaced the checkbox row, removed the mobile result count, and changed both workflow toolbars to deterministic mobile rows based on the three source annotations.
|
||||||
|
- Iteration 2: updated component contracts and interaction tests after the filter changed from checkboxes to a select. All focused tests passed; browser capture remained blocked.
|
||||||
|
|
||||||
## Implementation checklist
|
## Implementation checklist
|
||||||
|
|
||||||
- [x] Constrain the identity anchor thumbnail and detail width.
|
- [x] Replace the two image-state checkboxes with one dropdown.
|
||||||
- [x] Move gallery summary/actions into the compact header.
|
- [x] Hide the mobile result count and keep the layout switch available.
|
||||||
- [x] Change gallery filter vertical padding from 14px to 5px.
|
- [x] Use equal filter-container padding and a lighter token-derived background.
|
||||||
- [x] Apply compact mode to all workspace pages.
|
- [x] Remove marked mobile toolbar gaps in storyboard and production.
|
||||||
- [ ] Capture and compare the rendered identity and gallery states in the cloud browser.
|
- [x] Hide the duplicate mobile shot count in production.
|
||||||
|
- [ ] Capture and compare the three rendered states in the cloud browser.
|
||||||
|
|
||||||
final result: blocked
|
final result: blocked
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ watch(
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<WorkspacePage split compact
|
<WorkspacePage split compact class="production-workspace-page"
|
||||||
><template #header
|
><template #header
|
||||||
><div class="workspace-toolbar">
|
><div class="workspace-toolbar">
|
||||||
<div class="toolbar-episode">
|
<div class="toolbar-episode">
|
||||||
@@ -733,6 +733,20 @@ watch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media (max-width: 760px) {
|
@media (max-width: 760px) {
|
||||||
|
/* 移动端隐藏可由镜头目录获知的重复统计,并让操作从左侧连续排列。 */
|
||||||
|
.production-workspace-page .workspace-toolbar {
|
||||||
|
@apply grid grid-cols-[minmax(0,_1fr)] gap-2;
|
||||||
|
}
|
||||||
|
.production-workspace-page .toolbar-episode,
|
||||||
|
.production-workspace-page .toolbar-actions {
|
||||||
|
@apply w-full min-w-0 m-0;
|
||||||
|
}
|
||||||
|
.production-workspace-page .toolbar-summary {
|
||||||
|
@apply hidden;
|
||||||
|
}
|
||||||
|
.production-workspace-page .toolbar-actions {
|
||||||
|
@apply justify-start;
|
||||||
|
}
|
||||||
.production-workspace {
|
.production-workspace {
|
||||||
@apply grid-cols-[minmax(0,_1fr)] grid-rows-[184px_minmax(0,_1fr)];
|
@apply grid-cols-[minmax(0,_1fr)] grid-rows-[184px_minmax(0,_1fr)];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -468,6 +468,21 @@ watch(
|
|||||||
@apply p-0;
|
@apply p-0;
|
||||||
}
|
}
|
||||||
@media (max-width: 760px) {
|
@media (max-width: 760px) {
|
||||||
|
/* 移动端按整行排列剧集、统计和操作,避免 flex 自动换行留下不规则空白。 */
|
||||||
|
.storyboard-workspace-page .workspace-toolbar {
|
||||||
|
@apply grid grid-cols-[minmax(0,_1fr)] gap-2;
|
||||||
|
}
|
||||||
|
.storyboard-workspace-page .toolbar-episode,
|
||||||
|
.storyboard-workspace-page .toolbar-metrics,
|
||||||
|
.storyboard-workspace-page .toolbar-actions {
|
||||||
|
@apply w-full min-w-0 m-0;
|
||||||
|
}
|
||||||
|
.storyboard-workspace-page .toolbar-metrics {
|
||||||
|
@apply justify-between;
|
||||||
|
}
|
||||||
|
.storyboard-workspace-page .toolbar-actions {
|
||||||
|
@apply justify-start;
|
||||||
|
}
|
||||||
.storyboard-workspace {
|
.storyboard-workspace {
|
||||||
@apply grid-cols-[minmax(0,_1fr)] grid-rows-[184px_minmax(0,_1fr)];
|
@apply grid-cols-[minmax(0,_1fr)] grid-rows-[184px_minmax(0,_1fr)];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,8 +137,14 @@ const search = ref('')
|
|||||||
/** 切换排版复用同一份卡片和查询结果,不重新读取图库或清空筛选。 */
|
/** 切换排版复用同一份卡片和查询结果,不重新读取图库或清空筛选。 */
|
||||||
const layout = ref<GalleryLayout>('grid')
|
const layout = ref<GalleryLayout>('grid')
|
||||||
const module = ref('all')
|
const module = ref('all')
|
||||||
const onlyMissing = ref(false)
|
/** 形态图片状态筛选;单选下拉避免移动端复选项占据两行。 */
|
||||||
const onlyStale = ref(false)
|
type ImageStatusFilter = 'all' | 'missing' | 'stale'
|
||||||
|
const statusFilter = ref<ImageStatusFilter>('all')
|
||||||
|
const statusFilterOptions: Array<{ label: string; value: ImageStatusFilter }> = [
|
||||||
|
{ label: '全部状态', value: 'all' },
|
||||||
|
{ label: '缺少主图', value: 'missing' },
|
||||||
|
{ label: '身份过期', value: 'stale' }
|
||||||
|
]
|
||||||
/** 保存每张卡片的尺寸观察器,切换回网格时及时释放。 */
|
/** 保存每张卡片的尺寸观察器,切换回网格时及时释放。 */
|
||||||
const masonryCardObservers = new WeakMap<HTMLElement, ResizeObserver>()
|
const masonryCardObservers = new WeakMap<HTMLElement, ResizeObserver>()
|
||||||
|
|
||||||
@@ -223,8 +229,8 @@ const filtered = computed(() =>
|
|||||||
form =>
|
form =>
|
||||||
(!targetFormId.value || form.id === targetFormId.value) &&
|
(!targetFormId.value || form.id === targetFormId.value) &&
|
||||||
(module.value === 'all' || form.subject.module === module.value) &&
|
(module.value === 'all' || form.subject.module === module.value) &&
|
||||||
(!onlyMissing.value || !primaryImage(form.images)) &&
|
(statusFilter.value !== 'missing' || !primaryImage(form.images)) &&
|
||||||
(!onlyStale.value || isPrimaryIdentityStale(form)) &&
|
(statusFilter.value !== 'stale' || isPrimaryIdentityStale(form)) &&
|
||||||
`${form.subject.name} ${form.subject.ref} ${form.name}`
|
`${form.subject.name} ${form.subject.ref} ${form.name}`
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.includes(search.value.trim().toLowerCase())
|
.includes(search.value.trim().toLowerCase())
|
||||||
@@ -235,8 +241,7 @@ watch(
|
|||||||
() => {
|
() => {
|
||||||
search.value = targetFormId.value ? '' : queryText(route.query.subjectRef)
|
search.value = targetFormId.value ? '' : queryText(route.query.subjectRef)
|
||||||
module.value = 'all'
|
module.value = 'all'
|
||||||
onlyMissing.value = false
|
statusFilter.value = 'all'
|
||||||
onlyStale.value = false
|
|
||||||
galleryOpen.value = false
|
galleryOpen.value = false
|
||||||
generateOpen.value = false
|
generateOpen.value = false
|
||||||
promptOpen.value = false
|
promptOpen.value = false
|
||||||
@@ -272,8 +277,7 @@ function exportReceipt() {
|
|||||||
function resetFilters() {
|
function resetFilters() {
|
||||||
search.value = ''
|
search.value = ''
|
||||||
module.value = 'all'
|
module.value = 'all'
|
||||||
onlyMissing.value = false
|
statusFilter.value = 'all'
|
||||||
onlyStale.value = false
|
|
||||||
void router.replace({
|
void router.replace({
|
||||||
query: { ...route.query, subjectFormId: undefined, subjectRef: undefined, sourceShotId: undefined }
|
query: { ...route.query, subjectFormId: undefined, subjectRef: undefined, sourceShotId: undefined }
|
||||||
})
|
})
|
||||||
@@ -298,8 +302,7 @@ async function showStaleForms() {
|
|||||||
})
|
})
|
||||||
search.value = ''
|
search.value = ''
|
||||||
module.value = 'all'
|
module.value = 'all'
|
||||||
onlyMissing.value = false
|
statusFilter.value = 'stale'
|
||||||
onlyStale.value = true
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -571,10 +574,12 @@ async function showStaleForms() {
|
|||||||
{ label: String('道具'), value: 'prop' }
|
{ label: String('道具'), value: 'prop' }
|
||||||
]"
|
]"
|
||||||
></NSelect>
|
></NSelect>
|
||||||
<div class="filter-toggles">
|
<NSelect
|
||||||
<NCheckbox v-model:checked="onlyMissing">仅看缺少主图</NCheckbox>
|
v-model:value="statusFilter"
|
||||||
<NCheckbox v-model:checked="onlyStale">仅看身份过期</NCheckbox>
|
:options="statusFilterOptions"
|
||||||
</div>
|
aria-label="筛选图片状态"
|
||||||
|
class="status-filter"
|
||||||
|
/>
|
||||||
<div class="form-image-display-controls">
|
<div class="form-image-display-controls">
|
||||||
<span class="filter-result-count">{{ filtered.length }} 个形态</span>
|
<span class="filter-result-count">{{ filtered.length }} 个形态</span>
|
||||||
<div class="gallery-layout-switch" role="group" aria-label="图库显示方式">
|
<div class="gallery-layout-switch" role="group" aria-label="图库显示方式">
|
||||||
@@ -853,7 +858,8 @@ async function showStaleForms() {
|
|||||||
@apply [overflow-anchor:none];
|
@apply [overflow-anchor:none];
|
||||||
}
|
}
|
||||||
.form-image-filter-region {
|
.form-image-filter-region {
|
||||||
@apply my-4 py-[5px] px-4 bg-(--app-subtle);
|
@apply my-4 p-3;
|
||||||
|
background: color-mix(in srgb, var(--app-subtle) 96%, white);
|
||||||
container-type: inline-size;
|
container-type: inline-size;
|
||||||
}
|
}
|
||||||
.form-image-toolbar {
|
.form-image-toolbar {
|
||||||
@@ -875,17 +881,11 @@ async function showStaleForms() {
|
|||||||
@apply min-w-0;
|
@apply min-w-0;
|
||||||
}
|
}
|
||||||
.form-image-filters {
|
.form-image-filters {
|
||||||
@apply grid grid-cols-[minmax(200px,_360px)_152px_minmax(260px,_1fr)_auto] items-center gap-y-3 gap-x-4;
|
@apply grid grid-cols-[minmax(200px,_360px)_152px_160px_auto] items-center gap-y-3 gap-x-4;
|
||||||
}
|
}
|
||||||
.form-image-filters > * {
|
.form-image-filters > * {
|
||||||
@apply min-w-0;
|
@apply min-w-0;
|
||||||
}
|
}
|
||||||
.filter-toggles {
|
|
||||||
@apply flex items-center flex-wrap gap-y-2.5 gap-x-4 text-xs;
|
|
||||||
}
|
|
||||||
.filter-toggles .n-checkbox__label {
|
|
||||||
@apply whitespace-nowrap;
|
|
||||||
}
|
|
||||||
.filter-result-count {
|
.filter-result-count {
|
||||||
@apply justify-self-end text-muted text-xs whitespace-nowrap;
|
@apply justify-self-end text-muted text-xs whitespace-nowrap;
|
||||||
}
|
}
|
||||||
@@ -905,14 +905,20 @@ async function showStaleForms() {
|
|||||||
.form-image-filters {
|
.form-image-filters {
|
||||||
@apply grid-cols-[minmax(0,_1fr)_152px];
|
@apply grid-cols-[minmax(0,_1fr)_152px];
|
||||||
}
|
}
|
||||||
|
.status-filter {
|
||||||
|
@apply col-start-1 row-start-2;
|
||||||
|
}
|
||||||
.form-image-display-controls {
|
.form-image-display-controls {
|
||||||
@apply col-[1/-1];
|
@apply col-start-2 row-start-2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@container (max-width: 460px) {
|
@container (max-width: 460px) {
|
||||||
.form-image-filters {
|
.form-image-filters {
|
||||||
@apply grid-cols-[minmax(0,_1fr)_120px] gap-x-2.5;
|
@apply grid-cols-[minmax(0,_1fr)_120px] gap-x-2.5;
|
||||||
}
|
}
|
||||||
|
.filter-result-count {
|
||||||
|
@apply hidden;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.asset-impact-context {
|
.asset-impact-context {
|
||||||
@apply flex flex-col gap-2.5 py-[5px] px-4 bg-(--app-subtle) m-0 min-w-0;
|
@apply flex flex-col gap-2.5 py-[5px] px-4 bg-(--app-subtle) m-0 min-w-0;
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ describe('统一目录条目', () => {
|
|||||||
expect(css).toMatch(/\.workspace-tabs\.n-tabs\s*\{[^}]*width:\s*100%;[^}]*min-width:\s*0/)
|
expect(css).toMatch(/\.workspace-tabs\.n-tabs\s*\{[^}]*width:\s*100%;[^}]*min-width:\s*0/)
|
||||||
expect(css).toMatch(/\.workspace-tabs \.n-tabs-nav-scroll-wrapper\s*\{[^}]*min-width:\s*0/)
|
expect(css).toMatch(/\.workspace-tabs \.n-tabs-nav-scroll-wrapper\s*\{[^}]*min-width:\s*0/)
|
||||||
expect(css).toMatch(
|
expect(css).toMatch(
|
||||||
/\.form-image-filters\s*\{[^}]*grid-template-columns:\s*minmax\(200px, 360px\) 152px minmax\(260px, 1fr\) auto/
|
/\.form-image-filters\s*\{[^}]*grid-template-columns:\s*minmax\(200px, 360px\) 152px 160px auto/
|
||||||
)
|
)
|
||||||
expect(css).toMatch(
|
expect(css).toMatch(
|
||||||
/@container \(max-width: 900px\)\s*\{\s*\.form-image-filters\s*\{[^}]*minmax\(0, 1fr\) 152px/
|
/@container \(max-width: 900px\)\s*\{\s*\.form-image-filters\s*\{[^}]*minmax\(0, 1fr\) 152px/
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ describe('全站平面主题', () => {
|
|||||||
// DOM 环境不计算几何;保护容器宽度断点和居中契约,真实坐标仍需浏览器验收。
|
// DOM 环境不计算几何;保护容器宽度断点和居中契约,真实坐标仍需浏览器验收。
|
||||||
const css = readAllStyles()
|
const css = readAllStyles()
|
||||||
expect(css).toMatch(
|
expect(css).toMatch(
|
||||||
/\.form-image-filter-region\s*\{[^}]*padding(?:-block)?:\s*5px;[^}]*background:\s*var\(--app-subtle\);/
|
/\.form-image-filter-region\s*\{[^}]*padding:\s*12px;[^}]*background:\s*color-mix\(in srgb, var\(--app-subtle\) 96%, white\);/
|
||||||
)
|
)
|
||||||
expect(css).toMatch(/\.form-image-toolbar\s*\{[^}]*align-items:\s*center;[^}]*gap:\s*12px 16px;/)
|
expect(css).toMatch(/\.form-image-toolbar\s*\{[^}]*align-items:\s*center;[^}]*gap:\s*12px 16px;/)
|
||||||
expect(css).toMatch(
|
expect(css).toMatch(
|
||||||
@@ -197,6 +197,9 @@ describe('全站平面主题', () => {
|
|||||||
expect(css).toMatch(/\.asset-impact-context\s*\{[^}]*gap:\s*10px/)
|
expect(css).toMatch(/\.asset-impact-context\s*\{[^}]*gap:\s*10px/)
|
||||||
expect(css).toMatch(/\.asset-impact-context\s*\{[^}]*padding(?:-block)?:\s*5px/)
|
expect(css).toMatch(/\.asset-impact-context\s*\{[^}]*padding(?:-block)?:\s*5px/)
|
||||||
expect(css).toMatch(/\.asset-impact-context\s*\{[^}]*margin:\s*0/)
|
expect(css).toMatch(/\.asset-impact-context\s*\{[^}]*margin:\s*0/)
|
||||||
|
expect(css).toMatch(
|
||||||
|
/@container \(max-width: 460px\)\s*\{[^}]*\.form-image-filters\s*\{[^}]*grid-template-columns:\s*minmax\(0, 1fr\) 120px;[^}]*\}[^}]*\.filter-result-count\s*\{[^}]*display:\s*none;/
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('单图标按钮以当前控件高度为边长,尺寸与内容按钮互不影响', () => {
|
it('单图标按钮以当前控件高度为边长,尺寸与内容按钮互不影响', () => {
|
||||||
|
|||||||
@@ -347,7 +347,11 @@ describe('过期首帧到具体素材定位', () => {
|
|||||||
expect(toolbar.classes()).toContain('has-impact-picker')
|
expect(toolbar.classes()).toContain('has-impact-picker')
|
||||||
expect(picker.nextElementSibling).toBe(toolbar.get('.form-image-filters').element)
|
expect(picker.nextElementSibling).toBe(toolbar.get('.form-image-filters').element)
|
||||||
expect(toolbar.find('input[aria-label="搜索形态图片"]').exists()).toBe(true)
|
expect(toolbar.find('input[aria-label="搜索形态图片"]').exists()).toBe(true)
|
||||||
expect(toolbar.findAll('.filter-toggles [role="checkbox"]')).toHaveLength(2)
|
expect(
|
||||||
|
toolbar
|
||||||
|
.findAllComponents(NSelect)
|
||||||
|
.some((item: VueWrapper) => item.attributes('aria-label') === '筛选图片状态')
|
||||||
|
).toBe(true)
|
||||||
expect(wrapper!.find('.asset-impact-context').exists()).toBe(false)
|
expect(wrapper!.find('.asset-impact-context').exists()).toBe(false)
|
||||||
const select = wrapper!
|
const select = wrapper!
|
||||||
.findAllComponents(NSelect)
|
.findAllComponents(NSelect)
|
||||||
|
|||||||
@@ -806,7 +806,7 @@ describe('视觉风格与主体身份工作区', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('工作台页面交互', () => {
|
describe('工作台页面交互', () => {
|
||||||
it('形态筛选搜索、类型和勾选组合仍只过滤本地显示,控件与结果数处于同一工具栏', async () => {
|
it('形态筛选搜索、类型和图片状态仍只过滤本地显示,控件与结果数处于同一工具栏', async () => {
|
||||||
const person = formFixture()
|
const person = formFixture()
|
||||||
const scene = {
|
const scene = {
|
||||||
...formFixture(),
|
...formFixture(),
|
||||||
@@ -823,8 +823,8 @@ describe('工作台页面交互', () => {
|
|||||||
expect(wrapper!.findAll('.form-image-filters')).toHaveLength(1)
|
expect(wrapper!.findAll('.form-image-filters')).toHaveLength(1)
|
||||||
expect(filters.get('.filter-result-count').text()).toBe('2 个形态')
|
expect(filters.get('.filter-result-count').text()).toBe('2 个形态')
|
||||||
expect(filters.find('input[aria-label="搜索形态图片"]').exists()).toBe(true)
|
expect(filters.find('input[aria-label="搜索形态图片"]').exists()).toBe(true)
|
||||||
expect(filters.findAll('.filter-toggles [role="checkbox"]')).toHaveLength(2)
|
selectControl(wrapper!, 'aria-label', '筛选图片状态').vm.$emit('update:value', 'missing')
|
||||||
await filters.findAll('.filter-toggles [role="checkbox"]')[0]!.trigger('click')
|
await flushPromises()
|
||||||
expect(wrapper!.findAll('.form-image-card')).toHaveLength(1)
|
expect(wrapper!.findAll('.form-image-card')).toHaveLength(1)
|
||||||
expect(wrapper!.get('.form-image-card').text()).toContain('旧书店')
|
expect(wrapper!.get('.form-image-card').text()).toContain('旧书店')
|
||||||
selectControl(wrapper!, 'aria-label', '筛选主体类型').vm.$emit('update:value', 'character')
|
selectControl(wrapper!, 'aria-label', '筛选主体类型').vm.$emit('update:value', 'character')
|
||||||
@@ -833,7 +833,8 @@ describe('工作台页面交互', () => {
|
|||||||
selectControl(wrapper!, 'aria-label', '筛选主体类型').vm.$emit('update:value', 'all')
|
selectControl(wrapper!, 'aria-label', '筛选主体类型').vm.$emit('update:value', 'all')
|
||||||
await filters.get('input[aria-label="搜索形态图片"]').setValue('旧书店')
|
await filters.get('input[aria-label="搜索形态图片"]').setValue('旧书店')
|
||||||
expect(filters.get('.filter-result-count').text()).toBe('1 个形态')
|
expect(filters.get('.filter-result-count').text()).toBe('1 个形态')
|
||||||
await filters.findAll('.filter-toggles [role="checkbox"]')[1]!.trigger('click')
|
selectControl(wrapper!, 'aria-label', '筛选图片状态').vm.$emit('update:value', 'stale')
|
||||||
|
await flushPromises()
|
||||||
expect(filters.get('.filter-result-count').text()).toBe('0 个形态')
|
expect(filters.get('.filter-result-count').text()).toBe('0 个形态')
|
||||||
expect(fetcher.mock.calls.every(([, init]) => init?.method === 'GET')).toBe(true)
|
expect(fetcher.mock.calls.every(([, init]) => init?.method === 'GET')).toBe(true)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user