Provide managers with a dedicated page to analyze hold lots across all stations. Extends existing service functions (get_hold_detail_summary, get_hold_detail_lots, get_wip_matrix) with optional parameters for backward compatibility, adds one new function (get_hold_overview_treemap), and registers the page in the portal navigation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
9.7 KiB
9.7 KiB
ADDED Requirements
Requirement: Hold Overview page SHALL display a filter bar with Hold Type and Reason
The page SHALL provide a filter bar for selecting hold type and hold reason.
Scenario: Hold Type radio default
- WHEN the page loads
- THEN the Hold Type filter SHALL default to "品質異常"
- THEN three radio options SHALL display: 品質異常, 非品質異常, 全部
Scenario: Hold Type change reloads all data
- WHEN user changes the Hold Type selection
- THEN all four API calls (summary, matrix, treemap, lots) SHALL reload with the new hold_type parameter
- THEN any active matrix and treemap filters SHALL be cleared
Scenario: Reason dropdown populated from current data
- WHEN summary data is loaded
- THEN the Reason dropdown SHALL display "全部" plus all distinct hold reasons from the treemap data
- THEN selecting a specific reason SHALL reload all four API calls filtered by that reason
- THEN any active matrix and treemap filters SHALL be cleared
Requirement: Hold Overview page SHALL display summary KPI cards
The page SHALL show summary statistics for all hold lots matching the current filter.
Scenario: Summary cards rendering
- WHEN summary data is loaded from
GET /api/hold-overview/summary - THEN five cards SHALL display: Hold Lots, Hold QTY, 站別數, 平均滯留天數, 最大滯留天數
- THEN lot and QTY values SHALL use zh-TW number formatting
- THEN age values SHALL display with "天" suffix and one decimal place
Scenario: Summary reflects filter bar only
- WHEN user clicks a matrix cell or treemap block
- THEN summary cards SHALL NOT change (they only respond to filter bar changes)
Requirement: Hold Overview page SHALL display a Workcenter x Package matrix
The page SHALL display a cross-tabulation matrix of workcenters vs packages for hold lots.
Scenario: Matrix table rendering
- WHEN matrix data is loaded from
GET /api/hold-overview/matrix - THEN the table SHALL display workcenters as rows and packages as columns
- THEN cell values SHALL show QTY with zh-TW number formatting
- THEN the first column (Workcenter) SHALL be sticky on horizontal scroll
- THEN a Total row and Total column SHALL be displayed
- THEN cells with zero value SHALL display "-"
Scenario: Matrix cell click filters TreeMap and lot table
- WHEN user clicks a QTY cell in the matrix (intersection of workcenter and package)
- THEN
matrixFilterSHALL be set to{ workcenter, package } - THEN TreeMap SHALL reload showing only data for that workcenter + package combination
- THEN lot table SHALL reload filtered by that workcenter + package
- THEN the clicked cell SHALL show an active highlight
Scenario: Matrix workcenter row click
- WHEN user clicks a workcenter name or its Total cell
- THEN
matrixFilterSHALL be set to{ workcenter }(all packages) - THEN TreeMap and lot table SHALL reload filtered by that workcenter
Scenario: Matrix package column click
- WHEN user clicks a package column header or its Total cell
- THEN
matrixFilterSHALL be set to{ package }(all workcenters) - THEN TreeMap and lot table SHALL reload filtered by that package
Scenario: Matrix click toggle
- WHEN user clicks the same cell/row/column that is already active
- THEN
matrixFilterSHALL be cleared - THEN TreeMap and lot table SHALL reload without matrix filter
Scenario: Matrix reflects filter bar only
- WHEN user clicks a treemap block
- THEN matrix SHALL NOT change (it only responds to filter bar changes)
Requirement: Hold Overview page SHALL display active filter indicators
The page SHALL show a clear indicator of active cascade filters.
Scenario: Matrix filter indicator
- WHEN a matrix filter is active
- THEN a filter indicator SHALL display between the matrix and TreeMap sections
- THEN the indicator SHALL show the active workcenter and/or package name
- THEN a clear button (✕) SHALL remove the matrix filter
Scenario: TreeMap filter indicator
- WHEN a treemap filter is active
- THEN a filter indicator SHALL display between the TreeMap and lot table sections
- THEN the indicator SHALL show the active workcenter and reason name
- THEN a clear button (✕) SHALL remove the treemap filter
Scenario: Clear all filters
- WHEN user clicks a "清除所有篩選" button
- THEN both matrixFilter and treemapFilter SHALL be cleared
- THEN TreeMap and lot table SHALL reload without cascade filters
Requirement: Hold Overview page SHALL display a TreeMap visualization
The page SHALL display a TreeMap chart showing hold lot distribution by workcenter and reason.
Scenario: TreeMap rendering
- WHEN treemap data is loaded from
GET /api/hold-overview/treemap - THEN the TreeMap SHALL display with two levels: Workcenter (parent) → Hold Reason (child)
- THEN block area SHALL represent QTY
- THEN block color SHALL represent average age at current station using a 4-level color scale
- THEN the color scale legend SHALL display: 綠(<1天), 黃(1-3天), 橙(3-7天), 紅(>7天)
Scenario: TreeMap tooltip
- WHEN user hovers over a TreeMap block
- THEN a tooltip SHALL display: Workcenter, Reason, Lots count, QTY, and average age
Scenario: TreeMap narrows on matrix filter (Option A)
- WHEN a matrix filter is active (e.g., workcenter=WC-MOLD, package=PKG-A)
- THEN the TreeMap SHALL only show data matching the matrix filter
- THEN the TreeMap API SHALL be called with workcenter and/or package parameters
Scenario: TreeMap click filters lot table
- WHEN user clicks a leaf block in the TreeMap (a specific reason within a workcenter)
- THEN
treemapFilterSHALL be set to{ workcenter, reason } - THEN lot table SHALL reload filtered by that workcenter + reason
- THEN the clicked block SHALL show a visual highlight (border or opacity change)
Scenario: TreeMap click toggle
- WHEN user clicks the same block that is already active
- THEN
treemapFilterSHALL be cleared - THEN lot table SHALL reload without treemap filter
Scenario: Empty TreeMap
- WHEN treemap data returns zero items
- THEN the TreeMap area SHALL display "目前無 Hold 資料"
Requirement: Hold Overview page SHALL display paginated lot details
The page SHALL display a detailed lot table with server-side pagination.
Scenario: Lot table rendering
- WHEN lot data is loaded from
GET /api/hold-overview/lots - THEN a table SHALL display with columns: LOTID, WORKORDER, QTY, Package, Workcenter, Hold Reason, Age, Hold By, Dept, Hold Comment
- THEN age values SHALL display with "天" suffix
Scenario: Lot table responds to all cascade filters
- WHEN matrixFilter is
{ workcenter: WC-A, package: PKG-1 }and treemapFilter is{ reason: 品質確認 } - THEN lots API SHALL be called with
workcenter=WC-A&package=PKG-1&treemap_reason=品質確認 - THEN only lots matching all active filters SHALL be displayed
Scenario: Pagination
- WHEN total lots exceeds per_page (50)
- THEN Prev/Next buttons and page info SHALL display
- THEN page info SHALL show "顯示 {start} - {end} / {total}"
Scenario: Filter changes reset pagination
- WHEN any filter changes (filter bar, matrix click, or treemap click)
- THEN pagination SHALL reset to page 1
Scenario: Empty lot result
- WHEN a query returns zero lots
- THEN the lot table SHALL display a "No data" placeholder
Requirement: Hold Overview page SHALL auto-refresh and handle request cancellation
The page SHALL automatically refresh data and prevent stale request pile-up.
Scenario: Auto-refresh interval
- WHEN the page is loaded
- THEN data SHALL auto-refresh every 10 minutes using
useAutoRefreshcomposable - THEN auto-refresh SHALL be skipped when the tab is hidden
Scenario: Visibility change refresh
- WHEN the tab becomes visible after being hidden
- THEN data SHALL refresh immediately
Scenario: Request cancellation
- WHEN a new data load is triggered while a previous request is in-flight
- THEN the previous request SHALL be cancelled via AbortController
- THEN the cancelled request SHALL NOT update the UI
Scenario: Manual refresh
- WHEN user clicks the "重新整理" button
- THEN all data SHALL reload and the auto-refresh timer SHALL reset
- THEN all cascade filters (matrixFilter, treemapFilter) SHALL be preserved during refresh
Requirement: Hold Overview page SHALL handle loading and error states
The page SHALL display appropriate feedback during API calls and on errors.
Scenario: Initial loading overlay
- WHEN the page first loads
- THEN a full-page loading overlay SHALL display until all data is loaded
Scenario: API error handling
- WHEN an API call fails
- THEN an error banner SHALL display with the error message
- THEN the page SHALL NOT crash or become unresponsive
Scenario: Refresh indicator
- WHEN data is being refreshed (not initial load)
- THEN a spinning refresh indicator SHALL display in the header
- THEN a success checkmark SHALL flash briefly on completion
Requirement: Hold Overview page SHALL have back navigation
The page SHALL provide navigation back to WIP Overview.
Scenario: Back button
- WHEN user clicks the "← WIP Overview" button in the header
- THEN the page SHALL navigate to
/wip-overview