討論 #1423
是由 陳國瑋 於 27 天 前更新
> **傳輸規則更新(#1424 DEC-031)**:Connector 即時狀態仍是 V1 兩個 WebSocket 區塊之一;一個案場只建立一條 Dashboard socket,使用 Backend 排序後的整區 replacement,不建立每張 Card 一條連線。斷線時保留最後 preview 與時間並顯示「已停止更新」,不做 REST fallback、custom backoff 或自動重連。完整清單/搜尋/分頁仍使用 REST。
## 背景
A17 Dashboard 主需求為 #1422。
「Connector 即時狀態」區塊必須適應不同案場規模。案場可能只有 0、1、2 個 Connector,也可能有 20、30 個或更多;若單純把所有 Connector 卡片無上限展開,Dashboard 高度與資訊密度會隨案場規模失控。
本票用於確認 UI 彈性顯示規則。**目前是 Proposed Design,尚未納入最終 v1.0 需求文件,也不代表已進入開發。**
## 建議原則
Dashboard 的 Connector 區塊定位為:
> 固定資訊層級的狀態摘要 + 優先項目預覽 + 查看全部
不是完整 Connector inventory。完整搜尋、篩選與大量清單由 Drawer 或 Connector 管理頁處理。
## Proposed Display Rules
| Connector 總數 | Dashboard 顯示方式 |
|---:|---|
| 0 | Empty state,顯示尚未建立 Connector 與管理頁連結 |
| 1 | 顯示 1 張完整卡片;Desktop 最大寬度約 360px,不拉滿區塊 |
| 2 | 顯示 2 張卡片;Desktop 雙欄、Mobile 單欄,卡片左對齊 |
| 3 - 8 | 全部顯示,使用 responsive card grid |
| 9 - 30 | Desktop 顯示優先排序後 8 張,Mobile 顯示 4 張;提供「查看全部 N 個」 |
| 30 以上 | 維持 8/4 張預覽;完整資料進 Drawer 或 Connector 管理頁 |
| 100 以上 | 完整清單視量測結果導入 server pagination/virtualization;Dashboard preview 規則不變 |
## 區塊結構
1. Header
- Connector 即時狀態
- Connector 總數
- 最後更新時間
- freshness/stale
- Refresh
2. Status summary
- Faulted
- OCPP Offline
- Unavailable
- Charging
- Preparing/Waiting
- Available
3. Search/Filters
- Dashboard preview block 不顯示搜尋或篩選,維持營運摘要定位
- 僅在「查看全部」responsive Drawer 內固定提供
- 可依 Connector ID、Charge Point ID、車位、Charge Group、status 搜尋/篩選
- 不使用 Connector 總數 9 作為顯示門檻;Drawer 是否可開啟由各 viewport preview limit/查看全部規則決定
4. Preview grid
- Desktop 最多 8 張
- Mobile 最多 4 張
- 卡片不可因數量少而無限制拉寬
5. Footer
- 「查看全部 N 個 Connector」
- 若異常超過預覽上限,顯示「另有 N 個異常 Connector」
## Preview Sorting
**已確認:排序由 Backend 統一計算,依下列層級由高至低排列。**
1. Charge Point OFFLINE 且 Connector 存在 Active Transaction
2. Connector FAULTED
3. Charge Point OFFLINE、資料 STALE、Queue BLOCKED
4. Connector SUSPENDED_EVSE、UNAVAILABLE
5. Connector SUSPENDED_EV
6. Connector CHARGING
7. Connector PREPARING/Waiting
8. Connector AVAILABLE
規則:
- 同一層級先依異常/狀態持續時間由久至新排列,最後以 Connector ID 作 deterministic tie-breaker。
- 所有異常項目優先進入 preview。
- 異常不足 preview limit 時,再以 Charging、Preparing/Waiting、Available 補滿。
- 異常超過 limit 時,Footer 必須顯示剩餘異常數量。
- OCPP connection、Connector runtime、queue status 必須分層顯示,不得合併為單一 status。
- Unknown/資料不足不得歸入 Available;由 Backend 以保守且可解釋的 priority reason 處理。
- Backend 回傳 stable priority reason/severity code,FE 不依中文 label 重算 ranking。
## Card Minimum Content
- Connector ID/車位
- Charge Point connection badge
- Connector runtime status
- 目前功率;未知為 `null`/「無資料」,不可顯示為 0
- Active session;若排隊則顯示既有 queue source、status、priority、statusReason 與 waiting duration
- last updated/stale
- 點擊開啟 detail drawer
## Responsive
### Desktop >= 1240px
- 卡片寬度約 240 - 320px
- 自動換欄、左對齊
- 最多顯示 8 張 preview
### Tablet 640 - 1239px
- 2 - 3 欄
- Filter 可收合
- 最多顯示 6 - 8 張,最終上限待確認
### Mobile < 640px
- 單欄
- 顯示前 4 張 preview
- 「查看全部」進全螢幕 Drawer/頁面
- 不使用頁面級水平捲軸
## Full List 建議
優先方案:
- Desktop:大型右側 Drawer,約 70 - 80vw
- Mobile:全螢幕
- 提供搜尋、status、Charge Group filters 與排序;採單一 responsive list,不提供 Grid/Table 切換
- 可進一步 deep link 至既有 Connector 管理頁
Dashboard V1 避免在 block 內放固定高度的 nested scrollbar。若最後採用 scroll container,必須可由鍵盤 focus 與捲動。
## API Implication
Overview API 建議只回 summary 與 bounded preview:
```json
{
"connectorSummary": {
"total": 30,
"faulted": 2,
"offline": 1,
"charging": 6,
"waiting": 3,
"available": 18
},
"connectorPreview": {
"items": [],
"limit": 8,
"total": 30,
"hasMore": true
}
}
```
- 查看全部:使用/擴充既有 `POST /api/connector/search`
- 點擊單卡:`GET /api/connector/info/{connectorId}`
- Overview 不內嵌所有 Connector 完整 detail
- Preview sorting 由 Backend 統一,避免 FE、REST bootstrap、WebSocket 與其他 client 規則漂移
## Acceptance Criteria
- [ ] 0、1、2、8、9、30、100 個 Connector fixture 均不破版
- [ ] 1 個 Connector 卡片不被拉滿整個區塊
- [ ] 30 個 Connector 不會使 Dashboard block 無限制增高
- [ ] Faulted/Offline/Stale/Blocked 永遠優先於 Available
- [ ] 異常超過 preview limit 時可看到剩餘異常數量
- [ ] Status summary 的各分項加總與 total 規則一致
- [ ] 390/768/1024/1440 px 無頁面級水平捲軸
- [ ] Dashboard preview 不顯示 Search/Filters;完整清單 Drawer 固定提供且可操作
- [ ] Keyboard 可操作卡片、filter、Drawer 與 scrollable content
- [ ] Unknown status 與 `null` 數值不會 fallback 為 Available/0
- [ ] Dashboard preview 與完整 Connector list 的資料規則一致
## 待確認事項
- [x] Desktop(≥ 1240px)preview limit 確定為 8 張。
- [x] Mobile(< 640px)採單欄,preview limit 確定為 4 張。
- [x] Tablet(640–1239px)preview limit 固定為 6 張;寬版 3 欄 × 2 列,窄版 2 欄 × 3 列。
- [x] 「查看全部」採 responsive Drawer,並提供既有 Connector 管理頁 deep link;不新增功能重複的 Dashboard 獨立清單頁。
- [x] 取消依 Connector 數量顯示搜尋/篩選的門檻;Dashboard preview 不顯示,完整清單 Drawer 內固定提供。
- [x] Preview priority sorting 由 Backend 統一負責;FE 依 API/WebSocket items 順序呈現,不重建 ranking。
- [x] Queue 區塊只顯示既有 `MANUAL`/`OFF_PEAK` source、status、priority、statusReason、waitingSince/waiting duration;不從等待時間推導新的業務狀態。
- [x] V1 不新增 Queue SLA、等待逾時、threshold、Building/Charge Group override、Admin 設定頁或 Rotation scheduler-health 規則。
- [x] `ChargingRequestSource` 維持 `MANUAL`/`OFF_PEAK`;`ROTATION` 僅為既有 dispatch mode,不新增 enum 或 Dashboard 作業規則。
- [x] V1 不提供 Grid/Table view toggle;Dashboard preview 固定 Cards,完整清單 Drawer 採單一 responsive list,不保存顯示模式偏好。
## 已確認決策
### UI-DEC-001:Desktop Preview Limit 為 8 張
**狀態:已確認(2026-09-03,Ken)**
- Desktop viewport `>= 1240px` 時,Connector Dashboard block 最多顯示 8 張 preview cards。
- Connector 總數 1–8 時全部顯示;總數 9 以上時只顯示 Backend 統一排序後的前 8 張。
- Preview 依既定 severity/operational priority 排序,不得單純依 Connector ID 截取前 8 張。
- 異常項目超過 8 張時,preview 仍維持 8 張上限,Footer 顯示「另有 N 個異常 Connector」及「查看全部 N 個 Connector」。
- Connector 數量少於一列容量時,卡片維持既定寬度並左對齊,不可為填滿區塊而無限制拉寬。
- Desktop 上限只控制 Dashboard preview 高度,不限制完整 Connector list/Drawer 的資料筆數。
- 0、1、2、8、9、30、100 個 Connector fixture 均須納入視覺與互動驗收。
### UI-DEC-002:Mobile Preview Limit 為 4 張
**狀態:已確認(2026-09-03,Ken)**
- Mobile viewport `< 640px` 時,Connector preview 使用單欄 cards,最多顯示 4 張。
- Connector 總數 1–4 時全部顯示;總數 5 以上時只顯示 Backend 統一排序後的前 4 張。
- 異常項目超過 4 張時,preview 仍維持 4 張上限,Footer 必須顯示剩餘異常數及「查看全部 N 個 Connector」。
- 「查看全部」在 Mobile 開啟全螢幕清單/Drawer,不使用狹窄側邊 Drawer,也不產生頁面級水平捲軸。
- Preview cards、剩餘異常提示及查看全部按鈕都必須支援鍵盤操作與可辨識的 focus state。
- Mobile preview limit 只限制 Dashboard 首頁高度,不限制完整清單搜尋、filter、pagination/virtualization 的資料筆數。
- 390px viewport 必須納入 0、1、2、4、5、30、100 個 Connector fixture 驗收。
### UI-DEC-003:Tablet Preview Limit 為 6 張
**狀態:已確認(2026-09-03,Ken)**
- Tablet viewport `640–1239px` 時,Connector Dashboard block 最多顯示 6 張 preview cards。
- 版面空間允許時使用 3 欄 × 2 列;較窄時使用 2 欄 × 3 列,避免卡片內容被過度壓縮。
- Connector 總數 1–6 時全部顯示;總數 7 以上時只顯示 Backend 統一排序後的前 6 張。
- 異常項目超過 6 張時,preview 維持 6 張上限,Footer 顯示剩餘異常數及「查看全部 N 個 Connector」。
- 欄數由 responsive layout 依可用容器寬度決定,不以裝置 user-agent 判斷;preview 數量上限維持 6。
- 卡片寬度不足以呈現 minimum content 時必須降為較少欄數,不得截斷 Connector ID、status 或 stale indicator 等關鍵資訊。
- 768px、1024px viewport 必須納入 0、1、2、6、7、30、100 個 Connector fixture 驗收。
### UI-DEC-004:「查看全部」採 Responsive Drawer
**狀態:已確認(2026-09-03,Ken)**
- Dashboard 的「查看全部 N 個 Connector」在目前頁面開啟 responsive Drawer,保留 Dashboard 上下文。
- Desktop 使用右側 Drawer,目標寬度約 `75vw`,同時設定合理 `min-width`/`max-width`,避免超寬螢幕內容過度延展。
- Tablet 與 Mobile 使用全螢幕 Drawer/Sheet,避免狹窄側欄壓縮表格、filter 與操作區。
- Drawer 內提供 Connector ID/Charge Point ID/車位搜尋,以及 status、Charge Group 等篩選;實際顯示規則另案逐項確認。
- Drawer 內另提供 deep link 至既有 Connector 管理頁,以支援完整管理作業與可分享 URL。
- V1 不新增另一個與既有 Connector 管理頁功能重疊的 Dashboard full-list route。
- Drawer 的完整資料必須走 REST search API 與 server-side pagination;不得透過 Dashboard WebSocket 傳送全部 Connector detail。
- 開啟 Drawer 時保留 Dashboard 的 buildingId;Backend 仍須驗證該 building scope,不能只依 FE filter。
- 關閉 Drawer 後,keyboard focus 必須回到原「查看全部」按鈕;支援 Escape 關閉、focus trap、可辨識標題與 loading/empty/error states。
- Drawer 內點選 Connector 可再開啟詳細內容或導向既有 detail page,但不得同時建立無上限的 per-Connector WebSocket connections。
- Drawer 是否保存 search/filter/page 至 URL query,需在 FE implementation plan 中明確定義;至少同一輪開關不得無故重設使用者條件。
### UI-DEC-005:搜尋與篩選只存在於完整清單 Drawer
**狀態:已確認(2026-09-03,Ken)**
- Dashboard Connector preview block 不顯示 search input 或 filters,維持「狀態摘要 + 優先項目預覽 + 查看全部」的資訊層級。
- 取消「Connector 總數 9 個以上才顯示搜尋/篩選」的固定門檻;Desktop、Tablet、Mobile 的 preview limit 不同,不能共用總數 9 判斷。
- 使用者開啟「查看全部」responsive Drawer 後,Drawer 內固定提供搜尋與篩選能力。
- 搜尋至少支援 Connector ID、Charge Point ID 與車位;篩選至少支援 status 與 Charge Group。
- Search/filter 條件必須送至 REST search API 由 Server 執行,不能只篩選目前已載入頁面或 Dashboard preview items。
- Filter 結果、total、pagination 與 empty state 必須使用同一查詢條件,避免顯示筆數與內容不一致。
- Drawer 初次開啟使用預設 priority sorting;使用者套用搜尋/篩選後仍保留 deterministic secondary sort。
- 切換 building 時清除不相容的 search/filter state,並重新查詢新 building;不得混用舊 building 結果。
- Preview block 的 status summary chips 可作為進入 Drawer 的篩選捷徑,但不得直接在 preview block 原地重排/隱藏卡片;是否在 V1 提供此捷徑可於 FE plan 決定。
### UI-DEC-006:Preview Priority Sorting 由 Backend 負責
**狀態:已確認(2026-09-03,Ken)**
- Backend 是 Connector preview priority ranking 的唯一 owner,負責跨 status layer 計算、排序及 bounded preview 截取。
- REST overview 與 Dashboard WebSocket `CONNECTOR_OVERVIEW_UPDATED` 必須共用相同 ranking service/policy,回傳順序不得因 transport 不同而改變。
- FE 依 Backend 回傳的 `items` 順序呈現,不自行重建 FAULTED、OFFLINE、STALE、BLOCKED 等權重,也不依中文 label 排序。
- Backend response 應提供可解釋的 stable `priorityReason`/severity code,供 FE 顯示為何此 Connector 被列入 preview;欄位名稱於 API contract 階段確認。
- 相同 priority 的 tie-breaker 必須 deterministic,建議依狀態持續時間/最近異動時間,再以 Connector ID 作最後穩定排序;精確規則與狀態 precedence 另行確認。
- Desktop 8、Tablet 6、Mobile 4 的截取必須在完成 ranking 後執行,不可先依 ID 截取再在 FE 排序。
- 異常總數與 `remainingAbnormalCount` 必須由 Backend 依同一 policy 計算,不得由 FE 只看 preview items 推算。
- 完整清單 Drawer 的預設排序應與 preview policy 一致;使用者主動選擇其他排序時,只影響 Drawer,不回寫或改變 Dashboard preview policy。
- 未知 status/null source 不得被當成 AVAILABLE;Backend 應以保守、可觀測的 unknown ranking 處理。
### UI-DEC-007:Connector Preview Priority Hierarchy
**狀態:已確認(2026-09-03,Ken)**
Backend 依以下層級由高至低排序:
1. Charge Point OFFLINE 且 Connector 有 Active Transaction。
2. Connector FAULTED。
3. Charge Point OFFLINE、資料 STALE、Queue BLOCKED。
4. SUSPENDED_EVSE、UNAVAILABLE。
5. SUSPENDED_EV。
6. CHARGING。
7. PREPARING/Waiting。
8. AVAILABLE。
補充規則:
- 同層級以異常/狀態持續時間由久至新排序,再以 Connector ID 作最後 tie-breaker。
- 一個 Connector 同時符合多項條件時採最高層級,並保留其他 reason 供 UI 顯示,不得產生重複 card。
- OFFLINE + Active Transaction 必須高於一般 OFFLINE,提醒可能仍在離線充電或待 reconciliation。
- SUSPENDED_EVSE 與 SUSPENDED_EV 必須分開;前者為設備端暫停,優先級高於車端暫停。
- Unknown/資料不足不得 fallback 為 AVAILABLE。
- Backend 必須回傳 stable priority reason/severity code;FE 不自行推導權重。
- Queue `BLOCKED` 沿用既有 Backend 狀態進入異常層級;WAITING/ELIGIBLE 的持續時間只供顯示,不因時間長短升級為異常。
- Ranking、summary counts、bounded preview 與 remaining abnormal count 使用同一份 snapshot/policy。
### UI-DEC-008/009:Queue Timeout/Override(已撤回)
**狀態:已由 UI-DEC-011 取代(2026-09-03,Ken)**
- 先前討論的 Queue SLA、`isOverdue`、threshold、Building/Charge Group override 與 Admin 設定,會讓唯讀 Dashboard 擴張成新的營運規則,故不納入 V1。
- FE/BE 不需實作上述 timeout policy、欄位、設定來源或管理介面;歷史討論保留於 Redmine journal 供追溯。
### UI-DEC-010:Queue Source 語意對齊
**狀態:保留並簡化(2026-09-03,Ken)**
- 現行 `ChargingRequestSource` 維持 `MANUAL`、`OFF_PEAK`,供 Dashboard 正確顯示既有 queue source。
- `ROTATION` 是既有 dispatch/slot 調度機制,不是 queue source;Dashboard 不新增 `ROTATION` enum。
- V1 不新增 Rotation scheduler-health、missed-tick 或 dispatch-lag 判定;只顯示目前系統已有的 queue/rotation 資訊。
### UI-DEC-011:Dashboard V1 為唯讀資訊投影
**狀態:已確認(2026-09-03,Ken)**
- Dashboard 的目的為查詢、彙整與顯示既有營運資訊,不建立新的充電或排程業務規則。
- Queue 卡片/Drawer 顯示既有 source、status、priority、statusReason、waitingSince 與 waiting duration;waiting duration 是資訊,不是 SLA 或 timeout。
- 既有 `BLOCKED` 可列入 Needs Attention 並使用異常樣式;WAITING/ELIGIBLE 不因等待時間長短自動變成異常。
- Backend 開發限於 read model、query/aggregation、DTO、REST bootstrap、WebSocket update 與顯示排序,不得因此修改 queue lifecycle、priority、slot allocation、rotation dispatch、OCPP command 或充電流程。
- FE 開發限於呈現 Backend 既有狀態與時間資訊,不推導新的 `isOverdue`、severity 或業務狀態。
- V1 不新增 Queue timeout 設定、override precedence、Admin 設定頁、設定權限/audit table 或 Rotation health monitor。
- 若未來營運方明確需要 Queue SLA 或 scheduler monitoring,必須另案進行需求確認;本次不先建立子票。
### UI-DEC-012:單一 Responsive 呈現,不提供 Grid/Table Toggle
**狀態:已確認(2026-09-03,Ken)**
- Dashboard Connector preview 固定使用 responsive Cards,不提供顯示模式切換。
- 「查看全部」Drawer 採單一 responsive list:Desktop 使用緊湊列式呈現,Tablet/Mobile 依寬度自動堆疊欄位。
- Breakpoint 只改變排版,不改變資料欄位、status 語意、搜尋/篩選、排序或 pagination 規則。
- FE 不實作 Grid/Table toggle、view-mode URL parameter、local storage/使用者偏好保存或兩套可切換 renderer。
- Backend 不新增 `viewMode` request/response 欄位,也不依顯示模式提供不同資料 contract。
- 驗收只需覆蓋既定 Desktop/Tablet/Mobile responsive layout,不增加兩種 view mode 的交叉測試矩陣。
## 需求管理狀態
- Parent:#1422
- Requirement status:**待確認**
- Final specification:確認後整併至 #1422 的 v1.0 最終需求文件
- Implementation tickets:需求鎖定後才建立 FE/BE/QA child issues
返回