feat(resource): migrate resource-status and resource-history from Jinja2 to Vue 3 + Vite

Rewrite both resource pages (1,697 lines vanilla JS + 3,200 lines Jinja2 templates)
as Vue 3 SFC components. Extract resource-shared/ module with shared CSS, E10 status
constants, and HierarchyTable tree component. History page charts use vue-echarts,
Status page reuses useAutoRefresh composable with 5-minute interval.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
egg
2026-02-09 18:19:32 +08:00
parent a2653b8139
commit 720e190bc6
45 changed files with 5099 additions and 4993 deletions

View File

@@ -0,0 +1,127 @@
## ADDED Requirements
### Requirement: Resource History page SHALL display KPI summary cards
The page SHALL show 9 KPI cards with aggregated performance metrics for the queried period.
#### Scenario: KPI cards rendering
- **WHEN** summary data is loaded from `GET /api/resource/history/summary`
- **THEN** 9 cards SHALL display: OU%, AVAIL%, PRD, SBY, UDT, SDT, EGT, NST, Machine Count
- **THEN** hour values SHALL format with "K" suffix for large numbers (e.g., 2.5K)
- **THEN** percentage values SHALL use `buildResourceKpiFromHours()` from `core/compute.js`
### Requirement: Resource History page SHALL display trend chart
The page SHALL show OU% and Availability% trends over time.
#### Scenario: Trend chart rendering
- **WHEN** summary data is loaded
- **THEN** a line chart with area fill SHALL display OU% and AVAIL% time series
- **THEN** the chart SHALL use vue-echarts with `autoresize` prop
- **THEN** smooth curves with 0.2 opacity area style SHALL render
### Requirement: Resource History page SHALL display stacked status distribution chart
The page SHALL show E10 status hour distribution over time.
#### Scenario: Stacked bar chart rendering
- **WHEN** summary data is loaded
- **THEN** a stacked bar chart SHALL display PRD, SBY, UDT, SDT, EGT, NST hours per period
- **THEN** each status SHALL use its designated color (PRD=green, SBY=blue, UDT=red, SDT=yellow, EGT=purple, NST=gray)
- **THEN** tooltips SHALL show percentages calculated dynamically
### Requirement: Resource History page SHALL display workcenter comparison chart
The page SHALL show top workcenters ranked by OU%.
#### Scenario: Comparison chart rendering
- **WHEN** summary data is loaded
- **THEN** a horizontal bar chart SHALL display top 15 workcenters by OU%
- **THEN** bars SHALL be color-coded: green (≥80%), yellow (≥50%), red (<50%)
- **THEN** data SHALL display in descending OU% order (top to bottom)
### Requirement: Resource History page SHALL display OU% heatmap
The page SHALL show a heatmap of OU% by workcenter and date.
#### Scenario: Heatmap chart rendering
- **WHEN** summary data is loaded
- **THEN** a 2D heatmap SHALL display: workcenters (Y-axis) × dates (X-axis)
- **THEN** color scale SHALL range from red (low OU%) through yellow to green (high OU%)
- **THEN** workcenters SHALL sort by `workcenter_seq` for consistent ordering
### Requirement: Resource History page SHALL display hierarchical detail table
The page SHALL show a three-level expandable table with per-resource performance metrics.
#### Scenario: Detail table rendering
- **WHEN** detail data is loaded from `GET /api/resource/history/detail`
- **THEN** a tree table SHALL display with columns: Name, OU%, AVAIL%, PRD, SBY, UDT, SDT, EGT, NST, Count
- **THEN** Level 0 rows SHALL show workcenter groups with aggregated metrics
- **THEN** Level 1 rows SHALL show resource families with aggregated metrics
- **THEN** Level 2 rows SHALL show individual resources
#### Scenario: Hour and percentage display
- **WHEN** detail data renders
- **THEN** status columns SHALL display hours with percentage: "10.5h (25%)"
- **THEN** KPI values SHALL be computed using `buildResourceKpiFromHours()` from `core/compute.js`
#### Scenario: Tree expand and collapse
- **WHEN** user clicks the expand button on a row
- **THEN** child rows SHALL toggle visibility
- **WHEN** user clicks "Expand All" or "Collapse All"
- **THEN** all rows SHALL expand or collapse accordingly
### Requirement: Resource History page SHALL support date range and granularity selection
The page SHALL allow users to specify time range and aggregation granularity.
#### Scenario: Date range selection
- **WHEN** the page loads
- **THEN** date inputs SHALL default to last 7 days (yesterday minus 6 days)
- **THEN** date range SHALL NOT exceed 730 days (2 years)
#### Scenario: Granularity buttons
- **WHEN** user clicks a granularity button (///)
- **THEN** the active button SHALL highlight
- **THEN** the next query SHALL use the selected granularity (day/week/month/year)
#### Scenario: Query execution
- **WHEN** user clicks the query button
- **THEN** summary and detail APIs SHALL be called in parallel
- **THEN** all 4 charts, KPI cards, and detail table SHALL update with results
### Requirement: Resource History page SHALL support multi-select filtering
The page SHALL provide multi-select dropdown filters for workcenter groups and families.
#### Scenario: Multi-select dropdown
- **WHEN** user clicks a multi-select dropdown trigger
- **THEN** a dropdown SHALL display with checkboxes for each option
- **THEN** "Select All" and "Clear All" buttons SHALL be available
- **THEN** clicking outside the dropdown SHALL close it
#### Scenario: Filter options loading
- **WHEN** the page loads
- **THEN** workcenter groups and families SHALL load from `GET /api/resource/history/options`
#### Scenario: Equipment type checkboxes
- **WHEN** user toggles a checkbox (生產設備, 重點設備, 監控設備)
- **THEN** the next query SHALL include the corresponding filter parameter
### Requirement: Resource History page SHALL support CSV export
The page SHALL allow users to export the current query results as CSV.
#### Scenario: CSV export
- **WHEN** user clicks the "匯出 CSV" button
- **THEN** the browser SHALL download a CSV file from `GET /api/resource/history/export` with current filters
- **THEN** the filename SHALL be `resource_history_{start_date}_to_{end_date}.csv`
### Requirement: Resource History page SHALL handle loading and error states
The page SHALL display appropriate feedback during API calls and on errors.
#### Scenario: Query loading state
- **WHEN** a query is executing
- **THEN** the query button SHALL be disabled
- **THEN** a loading indicator SHALL display
#### Scenario: API error handling
- **WHEN** an API call fails
- **THEN** a toast notification SHALL display the error message
- **THEN** the page SHALL NOT crash or become unresponsive
#### Scenario: No data placeholder
- **WHEN** query returns empty results
- **THEN** charts and table SHALL display "No data" placeholders

View File

@@ -0,0 +1,121 @@
## ADDED Requirements
### Requirement: Resource Status page SHALL display summary KPI cards
The page SHALL show 10 summary cards with aggregated equipment status statistics.
#### Scenario: Summary cards rendering
- **WHEN** equipment data is loaded from `GET /api/resource/status/summary`
- **THEN** 10 cards SHALL display: Total, PRD, SBY, UDT, SDT, EGT, NST, OTHER, OU%, Availability%
- **THEN** each status card SHALL show count and percentage
- **THEN** OU% card SHALL use color coding: green (≥80%), yellow (≥50%), red (<50%)
#### Scenario: Status card click filters equipment
- **WHEN** user clicks a status card (PRD, SBY, UDT, SDT, EGT, NST)
- **THEN** the equipment grid SHALL filter to show only equipment in that status
- **THEN** the clicked card SHALL show an active visual state
- **THEN** clicking the same card again SHALL remove the filter
### Requirement: Resource Status page SHALL display hierarchical matrix table
The page SHALL show a three-level expandable matrix of workcenter group, family, and resource with status columns.
#### Scenario: Matrix table rendering
- **WHEN** equipment data is loaded from `GET /api/resource/status`
- **THEN** a matrix table SHALL display with columns: Name, Total, PRD, SBY, UDT, SDT, EGT, NST, OTHER, OU%
- **THEN** Level 0 rows SHALL show workcenter groups with aggregated counts
- **THEN** Level 1 rows SHALL show resource families with aggregated counts
- **THEN** Level 2 rows SHALL show individual equipment with status indicator
#### Scenario: Status code aggregation
- **WHEN** equipment has status PM or BKD
- **THEN** the status SHALL be aggregated under UDT column
- **WHEN** equipment has status ENG
- **THEN** the status SHALL be aggregated under EGT column
- **WHEN** equipment has status OFF
- **THEN** the status SHALL be aggregated under NST column
#### Scenario: Tree expand and collapse
- **WHEN** user clicks the expand button on a Level 0 row
- **THEN** Level 1 rows (families) for that group SHALL toggle visibility
- **WHEN** user clicks the expand button on a Level 1 row
- **THEN** Level 2 rows (equipment) for that family SHALL toggle visibility
- **WHEN** user clicks "Expand All" or "Collapse All" in the toolbar
- **THEN** all tree rows SHALL expand or collapse accordingly
#### Scenario: Matrix cell click filters equipment
- **WHEN** user clicks a status count cell in the matrix (e.g., PRD count for a workcenter group)
- **THEN** the equipment grid SHALL filter to that workcenter group and status
- **THEN** the clicked cell SHALL show a selected visual state
- **THEN** a filter indicator banner SHALL display showing active filters
- **THEN** clicking the same cell again SHALL remove the filter
### Requirement: Resource Status page SHALL display equipment card grid
The page SHALL show filterable equipment cards with status information.
#### Scenario: Equipment card rendering
- **WHEN** equipment data is loaded
- **THEN** cards SHALL display in a responsive grid (auto-fill, min 280px)
- **THEN** each card SHALL show: resource name, status badge, workcenter, group, family, location
- **THEN** each card SHALL have a colored left border matching its status category
#### Scenario: LOT information tooltip
- **WHEN** user clicks the LOT count indicator on an equipment card
- **THEN** a floating tooltip SHALL display with LOT details: LOTID, QTY, track-in time, employee
- **THEN** the tooltip SHALL be positioned within the viewport (clamp to edges)
- **THEN** clicking outside the tooltip SHALL close it
#### Scenario: JOB information tooltip
- **WHEN** user clicks the JOB indicator on an equipment card
- **THEN** a floating tooltip SHALL display with JOB details: order, status, model, stage, technician, symptom/cause/repair codes
- **THEN** the tooltip SHALL use the same positioning logic as the LOT tooltip
### Requirement: Resource Status page SHALL support workcenter and equipment type filtering
The page SHALL provide filter controls to narrow the displayed equipment.
#### Scenario: Workcenter group filter
- **WHEN** user selects a workcenter group from the dropdown
- **THEN** all data (summary, matrix, equipment) SHALL reload filtered to that group
- **THEN** the dropdown options SHALL be loaded from `GET /api/resource/status/options`
#### Scenario: Equipment type checkboxes
- **WHEN** user toggles a checkbox (生產設備, 重點設備, 監控設備)
- **THEN** all data SHALL reload with the corresponding filter (is_production, is_key, is_monitor)
- **THEN** multiple checkboxes can be active simultaneously
### Requirement: Resource Status page SHALL display cache status
The page SHALL show the real-time cache health and last update time.
#### Scenario: Cache status indicator
- **WHEN** the page loads
- **THEN** the page SHALL call `GET /health` to check cache status
- **THEN** a green dot SHALL display when cache is loaded and enabled
- **THEN** a yellow dot SHALL display when cache is loading
- **THEN** a red dot SHALL display when cache is not enabled
- **THEN** the last update timestamp SHALL display from equipment status cache metadata
### Requirement: Resource Status 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 5 minutes
- **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: Manual refresh
- **WHEN** user clicks the refresh button
- **THEN** data SHALL reload and the auto-refresh timer SHALL reset
### Requirement: Resource Status 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 loading overlay SHALL display until all data is loaded
#### Scenario: API error handling
- **WHEN** an API call fails
- **THEN** the affected section SHALL display an error message
- **THEN** the page SHALL NOT crash or become unresponsive

View File

@@ -46,6 +46,11 @@ The Vite build configuration SHALL support Vue Single File Components alongside
- **THEN** Vite SHALL bundle the shared CSS into each page's output CSS
- **THEN** shared CSS SHALL NOT create a separate shared chunk that requires additional HTTP requests
#### Scenario: Shared composable import across module boundaries
- **WHEN** a migrated page imports a composable from another shared module (e.g., `resource-status` imports `useAutoRefresh` from `wip-shared/`)
- **THEN** the composable SHALL be bundled into the importing page's JS output
- **THEN** cross-module imports SHALL NOT create unexpected shared chunks
### Requirement: Pure Vite pages SHALL handle API calls without legacy MesApi
Pure Vite pages SHALL use the existing `frontend/src/core/api.js` module for API communication without depending on the global `window.MesApi` object from `_base.html`.