討論 #1423
是由 陳國瑋 於 17 天 前更新
> **閱讀基準:** [主需求 #1422](https://redmine.sylksoft.com/issues/1422) 與 [HTML Mock v0.3/附件 #1117](https://redmine.sylksoft.com/attachments/1117)。以下沿用主票區塊編號,依畫面由上到下、由左到右說明。Mock 數字皆為假資料;功能適用所有案場,A17 不是固定規則。 **完整清單固定排序(UI-DEC-020)**:Drawer 不提供排序選單、可點擊欄位排序或其他使用者排序控制;搜尋與篩選只縮小結果,Backend 仍依既定營運優先層級及 deterministic tie-breaker 排序後再分頁。Dashboard 不使用使用者輸入的 `sidx`/`sord`。
## 06|Connector 即時狀態:本票要完成什麼 > **完整清單固定分頁(UI-DEC-019)**:Drawer 的 REST search 固定每頁 20 筆;Footer 只提供「上一頁/下一頁」與「第 X / Y 頁・共 N 個」,結果 1~20 筆時隱藏換頁控制。搜尋或篩選改變時回到第 1 頁,Backend 對完整資料集重新查詢;V1 不提供每頁筆數選擇、直接跳頁或 virtualization。
**讓不同規模案場都能先看整體狀態,再看優先項目,最後按需打開完整清單。** > **完整清單 Drawer 狀態範圍(UI-DEC-018)**:搜尋、篩選與頁碼只保留在目前 Dashboard 不把所有 page session;關閉再開啟時維持,頁面重新整理或離開後返回時恢復預設。不寫入 URL、localStorage/sessionStorage,Backend 也不保存。
> **Status Summary 互動(UI-DEC-017)**:五個狀態摘要項目維持純資訊、不可點擊;不開啟 Drawer、不套用篩選、不導頁,也不成為鍵盤 Tab stop。Connector detail 仍由下方 preview card 開啟,完整清單仍由「查看全部」開啟。
> **Status Summary 零值呈現(UI-DEC-016)**:只要 Connector 無上限展開,也不因只有 1~2 個就把卡片拉滿整列。 `total > 0`,五個固定 bucket 全部顯示,即使某一類 `count = 0`;`CONNECTOR_LIVE_BLOCK_UPDATED` 仍 replacement 整個 summary + Top-8 preview,其中 Status Summary 維持五個固定項目並更新 counts,不得讓分類項目出現/消失。只有 `total = 0` 時才隱藏整組 Status summary,改顯示 Connector Empty State;0 是有效數值,不得當成 Loading、Error 或 Unknown。
本票對應主票中下段的整列區塊。UI-DEC-001~020 的結果已整理進下方正文;已撤回的 008/009 只保留追溯,不是待開發需求。 > **Status Summary 五類 Mapping(UI-DEC-015)**:固定依序使用 `NEEDS_ATTENTION`「需留意」、`CHARGING`「充電進行中」、`WAITING`「準備/排隊」、`AVAILABLE`「可用」、`OTHER`「其他狀態」。Backend 依此 precedence 讓每個 Connector 恰好歸一類;`NEEDS_ATTENTION` count 必須等於 `abnormalTotal`。
```text
> **Status Summary 互斥計數(UI-DEC-014)**:每個 Connector 即時狀態 總數/更新時間/品質/連線
↓
五項摘要:需留意|充電進行中|準備/排隊|可用|其他狀態
(純資訊,不可點擊)
↓
優先項目卡片:依 在摘要中恰好歸入一個 Backend 順序,桌面8/平板6/手機4
↓
已顯示/總數、另有多少異常未顯示 查看全部
│ │
點卡片 → 單支詳情 完整清單 Drawer
搜尋/篩選 → 固定20筆分頁
``` authoritative `displayBucket`,所有 bucket count 加總必須等於 `total`;Card/Drawer 仍分層顯示 OCPP connection、Connector runtime 與 Queue 原始狀態。
## 1. 區塊標題列與資料時間 > **Connector Preview 單一 Payload(UI-DEC-013)**:Backend 對完整 Connector 集合完成排序與異常分類後,只回傳最多前 8 筆 `items`,並附 `total`、`abnormalTotal`;Frontend 不傳 viewport、不重排或重判異常,只依畫面寬度顯示前 8/6/4 筆並計算純顯示用隱藏數量。REST bootstrap 與 `CONNECTOR_LIVE_BLOCK_UPDATED` 共用同一 contract。
由左到右顯示「Connector 即時狀態」、Connector 總數、最後更新時間、freshness/stale 與即時連線狀態。 > **一般 REST 更新規則(#1424 DEC-032)**:頁面首次載入可用 Overview bootstrap 顯示 Connector 區塊;WebSocket 接手後,本區只接受 `CONNECTOR_LIVE_BLOCK_UPDATED`。全頁每 5 分鐘及手動 Overview refresh 不得覆寫本區 live state,socket 中斷時也不得形成 REST fallback;手動刷新不重建 socket。
- 案場/資料範圍由 > **傳輸規則更新(#1424 DEC-031)**:Connector 即時狀態仍是 V1 兩個 WebSocket 區塊之一;一個案場只建立一條 Dashboard socket,使用 Backend 決定,不在本區切案場。
- 連線正常不代表所有來源都新鮮;資料品質與 WebSocket connection 分開呈現。
- 本區沒有專用 Refresh/Retry。Socket 失敗或中斷,保留最後資料與時間,提示「已停止更新」;無資料為「—」,不是 0。整頁 reload 才重新嘗試,詳見第 7 節。 排序後的整區 replacement,不建立每張 Card 一條連線。斷線時保留最後 preview 與時間並顯示「已停止更新」,不做 REST fallback、custom backoff 或自動重連。完整清單/搜尋/分頁仍使用 REST。
## 2. 五個摘要:先看完整統計,不從預覽卡推算 背景
### 2.1 固定分類與判定順序 A17 Dashboard 主需求為 #1422。
Backend 依同一份完整 「Connector 即時狀態」區塊必須適應不同案場規模。案場可能只有 0、1、2 個 Connector,也可能有 20、30 個或更多;若單純把所有 Connector snapshot 分類,由上往下命中;一個 卡片無上限展開,Dashboard 高度與資訊密度會隨案場規模失控。
本票的 UI-DEC-001~020 已完成需求確認,Connector 數量彈性顯示與完整清單 UI 規則已鎖定。內容待全 Dashboard 鎖版後整併至最終 v1.0 需求文件,議題仍維持 New/0%,不代表已進入開發。
## 建議原則
Dashboard 的 Connector 只屬於一類。**分類只是唯讀呈現,不能覆寫原本的 OCPP/runtime/Queue。**(UI-DEC-014/015) 區塊定位為:
> 固定資訊層級的狀態摘要 + 優先項目預覽 + 查看全部
不是完整 Connector inventory。完整搜尋、篩選與大量清單由 Drawer 或 Connector 管理頁處理。
## Confirmed Display Rules
| 順序/code Connector 總數 | 固定中文 Dashboard 顯示方式 | 分類條件 |
|---|---|---| |---:|---|
| 0 | Empty state,顯示尚未建立 Connector 與管理頁連結 |
| 1 NEEDS_ATTENTION | 需留意 顯示 1 張完整卡片;Desktop 最大寬度約 360px,不拉滿區塊 | isAbnormal=true;包含 OCPP OFFLINE、FAULTED、資料 STALE、Queue BLOCKED、SUSPENDED_EVSE、UNAVAILABLE、null/unknown/資料不足。 |
| 2 CHARGING | 充電進行中 顯示 2 張卡片;Desktop 雙欄、Mobile 單欄,卡片左對齊 | 排除第一類後,runtime CHARGING/SUSPENDED_EV/FINISHING。 |
| 3 WAITING - 8 | 準備/排隊 全部顯示,使用 responsive card grid | 排除前兩類後,runtime PREPARING/ENQUEUED,或 Queue ELIGIBLE。
| 9 - 30 | Backend 固定回排序後前 8 筆;Desktop/Tablet/Mobile 分別顯示前 8/6/4 張,並提供「查看全部 N 個」 |
| 4 AVAILABLE 30 以上 | 可用 維持 8/4 張預覽;完整資料進 Drawer 或 Connector 管理頁 | 排除前三類及下列特殊中性狀態後,runtime AVAILABLE。 |
| 5 OTHER 100 以上 | 其他狀態 完整清單固定使用 REST server pagination、每頁 20 筆;Dashboard preview 規則不變,V1 不導入 virtualization | RESERVED、Queue NOT_PLUGGED/PAUSED/FINISHED,及已辨識、非異常且不屬前四類者;Unknown 不可放這裡。 |
NOT_PLUGGED 固定歸 OTHER,不當 WAITING;沿用 UI-DEC-015 的既定 mapping,不從中文 label 猜類別。這裡的「充電進行中」是顯示分類;上方 #1486 的同名 KPI 則計 canonical ACTIVE Session,不能要求兩者數字相等。 ## 區塊結構
### 2.2 統計不變條件 1. Header
- Connector 即時狀態
- Connector 總數
- 最後更新時間
- freshness/stale
- 即時連線狀態(本區不提供 Refresh/Retry;整頁 reload 才重新連線)
2. Status summary
- 五類 固定順序:`NEEDS_ATTENTION`「需留意」→ `CHARGING`「充電進行中」→ `WAITING`「準備/排隊」→ `AVAILABLE`「可用」→ `OTHER`「其他狀態」
- Backend 依上述 precedence 為每個 Connector 指定且只指定一個 `displayBucket`;各 bucket count 無重複、無遺漏,加總=total。 加總必須等於 Connector `total`
- `NEEDS_ATTENTION` 與 `isAbnormal = true` 使用相同分類,故其 count 必須等於 `abnormalTotal`
- Card/Drawer 仍分別顯示 OCPP connection、Connector runtime、Queue status,不以 `displayBucket` 取代原始狀態
- `total > 0` 時五個 bucket 全部顯示,`count = 0` 的 bucket 也保留,不因即時數字更新增減項目
- `total = 0` 時隱藏整組 summary,改顯示 Connector Empty State;有效的 0 不得轉成 Loading/Error/Unknown
- 五個摘要項目只呈現分類名稱與數量,不使用 link/button/tabindex,不提供 hover、focus、click 或 keyboard action
- 單支 Connector detail 由 preview card 開啟;完整清單由「查看全部」開啟,summary 不成為第三套入口
3. Search/Filters
- Dashboard preview block 不顯示搜尋或篩選,維持營運摘要定位
- 僅在「查看全部」responsive Drawer 內固定提供
- 可依 Connector ID、Charge Point ID、車位、Charge Group、status 搜尋/篩選
- 不使用 Connector 總數 9 作為顯示門檻;Drawer 是否可開啟由各 viewport preview limit/查看全部規則決定
- 搜尋、篩選與頁碼只保存於目前頁面的 FE memory;關閉/重開保留,reload/navigation 後重設,不寫 URL 或持久化儲存
- 搜尋文字或任一篩選條件改變時,立即將目前頁碼重設為第 1 頁,並把完整條件交給 Server 查詢;不得只篩選目前載入的 20 筆
4. Preview grid
- Backend payload 最多包含排序後前 8 筆,不依 viewport 改變 contract
- Desktop/Tablet/Mobile 分別顯示前 8/6/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
規則:
- NEEDS_ATTENTION.count=abnormalTotal。 同一層級先依異常/狀態持續時間由久至新排列,最後以 Connector ID 作 deterministic tie-breaker。
- item 的 displayBucket=NEEDS_ATTENTION 所有異常項目優先進入 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 與 isAbnormal=true 必須一致。 waiting duration
- 每個 item 保留 priorityReason/severity;同屬「需留意」仍可有不同細部排序。 last updated/stale
- 此分類不額外建立 #1463 的 Attention category 或告警。Backend counts 才是完整統計,FE 不從最多 點擊開啟 detail drawer
## Responsive
### Desktop >= 1240px
- 卡片寬度約 240 - 320px
- 自動換欄、左對齊
- 最多顯示 8 張 preview 重算。
### 2.3 零值與互動(UI-DEC-016/017) Tablet 640 - 1239px
| 條件 | 顯示/互動 | - 2 - 3 欄
|---|---| - Filter 可收合
| total>0 | 五項全部顯示,包含 count=0,固定順序;數字從0變非0不新增/移除項目。 | - 固定顯示 6 張 preview;寬版 3 欄 × 2 列,窄版 2 欄 × 3 列
### Mobile < 640px
- 單欄
| total=0 | 隱藏摘要,顯示「尚未建立 Connector」與既有管理頁連結;Backend 仍回五個0,response shape 不變。 | - 顯示前 4 張 preview
| Loading/Error/Unknown | 不以 falsy 判斷當成0,不顯示假正常空狀態。 | - 「查看全部」進全螢幕 Drawer/頁面
| 任一摘要項目 | **不可點擊、不可觸發篩選、不開 Drawer、不導頁、不送request。** | - 不使用頁面級水平捲軸
摘要用一般內容語意,不是 link/button/role=button,不設 tabindex、手型cursor、hover action、focus indicator、pressed/selected state。單支詳情仍由卡片、完整清單仍由「查看全部」負責。
例:只有1個 AVAILABLE,顯示「需留意0、充電進行中0、準備/排隊0、可用1、其他狀態0」,不是只剩一個摘要。
## 3. 預覽卡如何適應 1、2、30 或更多 Connector Full List 建議
### 3.1 一份 Top-8 payload,FE 只取前 8/6/4 優先方案:
| 寬度 | 最多顯示 | 排版 | - Desktop:大型右側 Drawer,約 70 - 80vw
|---|---|---| - Mobile:全螢幕
| Desktop ≥1240px | 8張 | 卡片約240~320px,左對齊、自動換欄;單卡最大寬度約360px,不拉滿。 | - 提供搜尋、status、Charge Group filters;採單一 responsive list,不提供 Grid/Table 切換,也不提供排序選單、可點擊欄位排序或其他使用者排序控制
| Tablet 640~1239px | 6張 | 寬時3欄×2列,窄時2欄×3列;不足以容納必要資訊就降欄。 | - 完整結果固定沿用 Backend priority hierarchy;搜尋/篩選只縮小集合,不改變排序規則
| Mobile <640px | 4張 | 單欄;查看全部用全螢幕 Drawer。 | - 固定每頁 20 筆;Footer 顯示上一頁/下一頁與「第 X / Y 頁・共 N 個」,結果不超過 20 筆時隱藏換頁控制,只保留總筆數
- 第一頁停用上一頁,最後一頁停用下一頁;V1 不提供 page-size selector、頁碼列、直接跳頁或 virtualization
- 可進一步 deep link 至既有 Connector 管理頁
欄數依可用寬度,不依 user-agent;不截斷 ID、status、stale 等必要資訊。(UI-DEC-001~003/013) Dashboard V1 避免在 block 內放固定高度的 nested scrollbar。若最後採用 scroll container,必須可由鍵盤 focus 與捲動。
| 總數 | 桌面/平板/手機顯示筆數 | 重點 | ## API Implication
Overview API 建議只回 summary 與 bounded preview:
```json
|---|---|---| {
"connectorSummary": {
"total": 30,
"buckets": [
{ "code": "NEEDS_ATTENTION", "count": 10 },
{ "code": "CHARGING", "count": 6 },
{ "code": "WAITING", "count": 3 },
{ "code": "AVAILABLE", "count": 9 },
{ "code": "OTHER", "count": 2 }
]
},
"connectorPreview": {
"maxItems": 8,
"total": 30,
"abnormalTotal": 10,
"items": [
{
"connectorId": "B2-04",
"isAbnormal": true,
"severity": "ERROR",
"priorityReason": "CONNECTOR_FAULTED",
"displayBucket": "NEEDS_ATTENTION"
}
]
}
| 0 | 空狀態 | 不顯示假卡。 | }
| ```
- 查看全部:使用/擴充既有 `POST /api/connector/search`
- Request 沿用既有分頁欄位 `page`、`size`,Dashboard Drawer 固定送出 `size = 20`;畫面頁碼從第 1 | 1/1/1 | 保留正常卡寬並靠左。 | 頁顯示,API adapter 沿用既有 endpoint 的 page convention,不另建立 `pageSize` 欄位
| 2 | 2/2/2 | 桌面雙卡靠左、手機單欄,不補空卡。 | - Response 沿用既有 Spring Page metadata:`content`、`totalElements`、`totalPages`、`size`、`number`、`numberOfElements`、`first`、`last`、`empty`;不另建立 Dashboard 專用分頁格式
| 5 | 5/5/4 | 手機已有未顯示資料,不能用「9個以上」才提供查看全部。 | - 搜尋/篩選必須在 Server 對完整 Connector 集合執行。既有 DTO 已有 keyword/status 等條件;Charge Point ID/Charge Group 等本需求條件須於實作時確認並補足 query 欄位,不得只做 client-side current-page filter
| 7 | 7/6/4 | 平板與手機依自身上限。 | - 為避免改變既有 Connector 管理頁的通用欄位排序,`SearchConnectorDto` 增加 stable `sortMode`;Dashboard Drawer 固定送 `sortMode = DASHBOARD_PRIORITY`。Backend 在此 mode 下忽略空白/非互動的 `sidx`/`sord`,先套搜尋/篩選,再使用與 preview 相同的 priority ranking,最後做 server pagination
| 8 | 8/6/4 | 只有桌面完整顯示8筆。 | - 既有 Connector 管理頁未使用 `DASHBOARD_PRIORITY` 時,仍保留原本的 `sidx`/`sord` 欄位排序;UI-DEC-020 不移除或改變管理頁功能
| 9、30、100或更多 | 8/6/4 | 不隨總數無限增加首頁高度;完整資料走Drawer。 |
- 點擊單卡:`GET /api/connector/info/{connectorId}`
- Overview 不內嵌所有 Connector 完整 detail
- Preview sorting、`isAbnormal`、`severity`、`priorityReason`、`total` 與 `abnormalTotal` 由 Backend 對完整集合分類排序後回最多8筆,少於8回實際筆數。FE 統一,避免 FE、REST bootstrap、WebSocket 與其他 client 規則漂移
- Frontend 不傳 viewport/device/requestedLimit、不要求三種 response,不重排或重判異常。 viewport/preview limit;單一 Top-8 response 同時支援 Desktop/Tablet/Mobile
- `connectorSummary.buckets` 使用 UI-DEC-015 五個 stable codes 與固定 precedence;Backend 對任何 `total` 都固定回五項(允許 `count = 0`),不回 raw status 動態 key,Frontend 不自行合併類別
- `NEEDS_ATTENTION` count 必須等於 `connectorPreview.abnormalTotal`;每個 item 的 `displayBucket = NEEDS_ATTENTION` 與 `isAbnormal = true` 必須一致
### 3.2 卡片由上至下的必要內容 ## Acceptance Criteria
| 內容 | 規則 | - [ ] 0、1、2、8、9、30、100 個 Connector fixture 均不破版
|---|---| - [ ] 1 個 Connector 卡片不被拉滿整個區塊
| - [ ] 30 個 Connector ID/車位 | 讓使用者辨識設備,不因卡片窄而截掉必要識別。 | 不會使 Dashboard block 無限制增高
| 所屬 Charge Point 連線 badge | OCPP ONLINE/OFFLINE/UNKNOWN,與runtime分開。 | - [ ] Faulted/Offline/Stale/Blocked 永遠優先於 Available
| - [ ] 異常超過 preview limit 時可看到剩餘異常數量
- [ ] 每個 Connector 恰好有一個 `displayBucket`;Status summary 無重複、無遺漏,各 bucket count 加總恰好等於 `total`
- [ ] Card/Drawer 仍可同時看見 OCPP connection、Connector runtime | 如CHARGING/FAULTED/SUSPENDED;不能只剩一個綜合「在線」。 | 與 Queue 原始狀態,不會被 `displayBucket` 覆蓋
| 目前功率 | - [ ] 五類 code、中文名稱與顯示順序固定;`NEEDS_ATTENTION` count = `abnormalTotal`,Unknown 不會落入 AVAILABLE
- [ ] NOT_PLUGGED 不會落入 WAITING,與「等待供電」KPI 的既有定義一致
- [ ] `total > 0` 時五個 bucket 依固定順序全部可見,零值 bucket 不隱藏;`CONNECTOR_LIVE_BLOCK_UPDATED` 更新 counts 時不造成項目出現/消失,並可同時 replacement Top-8 preview
- [ ] `total = 0` 時隱藏 Status summary 並顯示 Connector Empty State;0 不會被誤顯示為 Loading、Error 或 Unknown
- [ ] 五個 Status summary 項目不是 link/button、不可點擊且不進入 Tab 順序;點擊/觸控不開 Drawer、不套 filter、不導頁、不送出 API 有效數值與單位;未知null顯示無資料/—,不是0。 | request
| Active Session/Queue | 若排隊顯示既有source、status、priority、statusReason、waitingSince/持續時間。 | - [ ] Connector preview card 與「查看全部」仍分別支援 detail/完整清單互動及 keyboard focus,不受 summary 純資訊規則影響
| 最後更新/stale | 與來源品質一致;異常要有文字,不只靠色彩。 | - [ ] Drawer 關閉再開啟時,搜尋、篩選與頁碼維持不變;頁面 reload 或離開後返回時恢復預設排序與第一頁
| 點擊行為 | 開啟單支detail drawer,有鍵盤操作與清楚focus。 |
```text - [ ] Drawer state 不出現在 URL,不寫 localStorage/sessionStorage,不呼叫 Backend preference API,也不透過 WebSocket 同步
同一個 - [ ] 未套條件的 30 筆結果正確分為 2 頁,100 筆正確分為 5 頁;每頁最多 20 筆,且 total/totalPages 與內容一致
- [ ] 結果 0~20 筆時不顯示上一頁/下一頁;0 筆同時顯示 Empty State,總筆數為 0
- [ ] 多頁結果顯示「第 X / Y 頁・共 N 個」;第一頁停用上一頁、最後一頁停用下一頁,換頁不改變搜尋/篩選條件
- [ ] 搜尋文字或任一篩選改變時回到第 1 頁,Server 使用完整條件重新查詢;不得只篩選目前 20 筆
- [ ] Drawer 不提供 page-size selector、直接跳頁或 virtualization
- [ ] Drawer 不出現排序下拉選單、可點擊欄位排序或排序狀態;keyboard/touch 也不能觸發排序
- [ ] 未篩選與篩選後結果皆由 Backend 依 UI-DEC-007 的固定 priority hierarchy 排序;同層級依狀態持續時間由久至新,最後以 Connector 可以同時有: ID 穩定排序
CP:OFFLINE - [ ] Dashboard request 固定使用 `sortMode = DASHBOARD_PRIORITY`,不接受使用者產生的 `sidx`/`sord`;Server 在完整結果排序後才切 20 筆頁面
runtime:CHARGING - [ ] `/connector/list` 管理頁原有欄位排序不受 Dashboard Drawer 規則影響
Queue:BLOCKED
↓ - [ ] 390/768/1024/1440 px 無頁面級水平捲軸
保留三層原始事實,summary只歸一個顯示分類;不寫回狀態。 - [ ] Dashboard preview 不顯示 Search/Filters;完整清單 Drawer 固定提供且可操作
``` - [ ] Keyboard 可操作卡片、filter、Drawer 與 scrollable content
- [ ] Unknown status 與 `null` 數值不會 fallback 為 Available/0
- [ ] Dashboard preview 與完整 Connector list 的資料規則一致
- [ ] REST bootstrap 與 `CONNECTOR_LIVE_BLOCK_UPDATED` 都只回同一份 Top-8 payload,不存在 Desktop/Tablet/Mobile 三種 response
- [ ] FE 只對 `items` 做前 8/6/4 筆顯示截取;`hiddenCount` 與 `hiddenAbnormalCount` 的結果在各 breakpoint 正確
## 待確認事項
- [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 source 區塊只顯示既有 `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/slot 調度機制,**不是新 queue source enum**。等待時間只是資訊,不據此推導 timeout/SLA/isOverdue。(UI-DEC-010/011) `MANUAL`/`OFF_PEAK`;`ROTATION` 僅為既有 dispatch mode,不新增 enum 或 Dashboard 作業規則。
- [x] V1 不提供 Grid/Table view toggle;Dashboard preview 固定 Cards,完整清單 Drawer 採單一 responsive list,不保存顯示模式偏好。
- [x] Connector preview 採單一 Top-8 payload:Backend 排序/分類並回 `total`、`abnormalTotal`;FE 僅依 viewport 顯示 8/6/4 筆及計算隱藏數量。
- [x] Status summary 採互斥 `displayBucket`:每個 Connector 恰好歸一類、bucket counts 加總等於 total;Card/Drawer 保留所有分層原始狀態。
- [x] Bucket 固定為 NEEDS_ATTENTION/CHARGING/WAITING/AVAILABLE/OTHER,依此順序判定與顯示;NOT_PLUGGED 歸 OTHER、Unknown 歸 NEEDS_ATTENTION。
- [x] `total > 0` 固定顯示五個 bucket(包含零值);`total = 0` 隱藏 summary 並顯示 Connector Empty State。
- [x] 五個 Status summary 項目維持純資訊、不可點擊;所有互動仍由 Connector preview card 與「查看全部」負責。
- [x] 「查看全部」Drawer 的搜尋/篩選/頁碼只保留於目前 Dashboard page session;關閉重開保留,reload/navigation 後重設,不寫 URL 或持久化儲存。
- [x] UI-DEC-019:完整清單固定每頁 20 筆;只提供上一頁/下一頁與頁次/總筆數,1~20 筆隱藏換頁控制;搜尋/篩選改變後回第 1 頁並由 Server 重查完整結果。
- [x] UI-DEC-020:完整清單不提供使用者排序控制;固定使用 Backend priority hierarchy 與 deterministic tie-breaker,搜尋/篩選不改變排序規則。
## 4. 哪些卡片排前面:Backend 統一排序 已確認決策
Preview、完整清單與 WebSocket 共用同一 ranking service/snapshot;同一 Connector 命中多條只採最高層級、不重複卡,保留其他原因供顯示。(UI-DEC-006/007/020) ### 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 張。
| 1 | CP OFFLINE 且 - Preview 依既定 severity/operational priority 排序,不得單純依 Connector 有 Active Transaction | ID 截取前 8 張。
| 2 | - 異常項目超過 8 張時,preview 仍維持 8 張上限,Footer 顯示「另有 N 個異常 Connector」及「查看全部 N 個 Connector」。
- Connector FAULTED | 數量少於一列容量時,卡片維持既定寬度並左對齊,不可為填滿區塊而無限制拉寬。
| 3 | CP OFFLINE、資料 STALE、Queue BLOCKED | - Desktop 上限只控制 Dashboard preview 高度,不限制完整 Connector list/Drawer 的資料筆數。
| - 0、1、2、8、9、30、100 個 Connector fixture 均須納入視覺與互動驗收。
### UI-DEC-002:Mobile Preview Limit 為 4 | SUSPENDED_EVSE、UNAVAILABLE | 張
**狀態:已確認(2026-09-03,Ken)**
- Mobile viewport `< 640px` 時,Connector preview 使用單欄 cards,最多顯示 4 張。
| - Connector 總數 1–4 時全部顯示;總數 5 | SUSPENDED_EV | 以上時只顯示 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 | CHARGING | 張
**狀態:已確認(2026-09-03,Ken)**
- Tablet viewport `640–1239px` 時,Connector Dashboard block 最多顯示 6 張 preview cards。
| - 版面空間允許時使用 3 欄 × 2 列;較窄時使用 2 欄 × 3 列,避免卡片內容被過度壓縮。
- Connector 總數 1–6 時全部顯示;總數 7 | PREPARING/Waiting | 以上時只顯示 Backend 統一排序後的前 6 張。
| 8 | AVAILABLE | - 異常項目超過 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 search request 不傳 `buildingId`;Backend 必須使用與 Overview 相同的 current-building resolver 自動限制資料範圍,不能依賴 FE filter 決定 scope。
- 關閉 Drawer 後,keyboard focus 必須回到原「查看全部」按鈕;支援 Escape 關閉、focus trap、可辨識標題與 loading/empty/error states。
- Drawer 內點選 Connector 可再開啟詳細內容或導向既有 detail page,但不得同時建立無上限的 per-Connector WebSocket connections。
- Drawer 的 search/filter/page 依 UI-DEC-018 只保留在目前 Dashboard page session:關閉再開啟時維持;reload 或離開頁面後返回時恢復預設。不寫 URL、localStorage/sessionStorage,Backend 也不保存。
### 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 穩定排序。SUSPENDED_EVSE 與車位;篩選至少支援 status 與 SUSPENDED_EV 分開;Unknown 不 fallback AVAILABLE,Backend 提供保守且可解釋的 reason/severity。異常優先,未滿預覽再由其餘狀態補足。 Charge Group。
- Search/filter 條件必須送至 REST search API 由 Server 執行,不能只篩選目前已載入頁面或 Dashboard preview items。
- Filter 結果、total、pagination 與 empty state 必須使用同一查詢條件,避免顯示筆數與內容不一致。
- Drawer 初次開啟使用預設 priority sorting;使用者套用搜尋/篩選後仍保留 deterministic secondary sort。
- V1 不提供 building selector;整頁 reload 或離開 Dashboard 後返回時重設 page-session search/filter state,並依 Backend-resolved Building 重新查詢。
- 本段較早提出的「status summary 可作為 Drawer 篩選捷徑」已由 UI-DEC-017 取代:V1 的五個摘要項目固定為純資訊,不可點擊,不開啟 Drawer 或套用篩選。
**舊文案更正:** 第一層仍保留排序,但「提醒可能仍在離線充電或待 reconciliation」的舊解釋,已被 #1422、#1463 ATT-DEC-008/#1486 KPI-DEC-011 的較新邊界取代。只呈現連線與交易事實,不新增這些推測性 badge/原因/文案;本次不改排序、交易計數或作業狀態。
### Footer 顯示多少沒被看見 UI-DEC-006:Preview Priority Sorting 由 Backend 負責
```text **狀態:已確認(2026-09-03,Ken)**
- Backend 是 Connector preview priority ranking 與 abnormal classification 的唯一 owner,負責跨 status layer 計算、排序並截取最多前 8 筆。
hiddenCount - REST Overview bootstrap 與 Dashboard WebSocket `CONNECTOR_LIVE_BLOCK_UPDATED` 必須共用相同 ranking service/policy 與 payload contract,回傳順序不得因 transport 不同而改變。
- Backend response 固定回 `total`、`abnormalTotal`,每個 item 回 Backend 判定的 `isAbnormal`、stable `priorityReason`/severity code;FE 不從中文 label、runtime 或 queue 欄位重判。
- FE 依 Backend `items` 原順序,Desktop/Tablet/Mobile 分別顯示前 8/6/4 筆;這是純 UI 截取,不是重新排序或商業分類。
- FE 可計算 `hiddenCount = max(0, total - visibleCount)
hiddenAbnormalCount visibleCount)`;`hiddenAbnormalCount = max(0, abnormalTotal - visibleAbnormalCount) visibleAbnormalCount)`,其中 `visibleAbnormalCount` 只計 visible slice 內 Backend 已標記 `isAbnormal = true` 的項目。
```
visibleAbnormalCount 只計可見slice中 - Backend 標 isAbnormal=true 者。這是FE純顯示計算,不是重建分類;數據不一致須顯示Partial/Error,不能靠clamp後宣稱正常。
例如total30、abnormalTotal10、桌面可見8筆且8筆異常:Footer 顯示另有22筆未顯示、另有2個異常,以及「查看全部30個Connector」。異常再多也不突破8/6/4上限。
## 5. 單支詳情與「查看全部」不是同一層
| 入口 | 打開什麼 | 資料與連線 | 不接受 viewport/device/preview limit 參數,也不回傳三套 payload;同一份最多 8 筆 response 支援所有 breakpoint。
|---|---|---| - 相同 priority 的 tie-breaker 必須 deterministic,建議依狀態持續時間/最近異動時間,再以 Connector ID 作最後穩定排序;精確規則與狀態 precedence 另行確認。
| 預覽卡 | 單支 detail drawer | GET /api/connector/info/{connectorId};沿用既有單Connector detail flow,開啟才使用其既有socket,關閉釋放,見#1424。 |
| 查看全部 N 個 Connector | - 完整清單 responsive Drawer | REST search/分頁;不擴大Dashboard WS payload,不建立全清單每卡socket。 | 固定使用與 preview 相同的 priority policy,不提供使用者其他排序;此項已由 UI-DEC-020 取代原本可選排序的較早構想。
- 未知 status/null source 不得被當成 AVAILABLE;Backend 應以保守、可觀測的 unknown ranking 處理。
Overview 不內嵌所有Connector完整detail,Drawer內可看單支詳情或前往既有管理頁,但不能開出無上限per-Connector連線。 ### UI-DEC-007:Connector Preview Priority Hierarchy
## 6. 完整清單 Drawer:搜尋 → 固定排序 → 每頁20筆 **狀態:已確認(2026-09-03,Ken)**
### 6.1 畫面從上到下(UI-DEC-004/005/012) Backend 依以下層級由高至低排序:
1. 標題、關閉:桌面右側約75vw(合理min/max);平板/手機全螢幕Drawer/Sheet。 Charge Point OFFLINE 且 Connector 有 Active Transaction。
2. 搜尋:Connector ID、Charge Point ID、車位。 Connector FAULTED。
3. 篩選:status、Charge Group。**只在Drawer提供**,首頁preview沒有搜尋/篩選,也沒有依總數9才出現的門檻。 Charge Point OFFLINE、資料 STALE、Queue BLOCKED。
4. 單一responsive list:桌面緊湊列、窄畫面堆疊必要欄位,沒有Grid/Table切換。 SUSPENDED_EVSE、UNAVAILABLE。
5. Footer:總筆數、頁次、上一頁/下一頁;另有既有Connector管理頁deep link。 SUSPENDED_EV。
6. CHARGING。
7. PREPARING/Waiting。
8. AVAILABLE。
關閉時focus回原「查看全部」按鈕,支援Escape、focus trap、可辨識標題及Loading/Empty/Error。首頁preview避免固定高度nested scrollbar;若使用scroll container須能鍵盤focus與捲動。Drawer內欄位與filter不因RWD改變語意。 補充規則:
### 6.2 每次都對完整資料集查詢(UI-DEC-019/020)
```text - 同層級以異常/狀態持續時間由久至新排序,再以 Connector ID 作最後 tie-breaker。
搜尋/篩選條件改變 → 回第1頁
↓ - 一個 Connector 同時符合多項條件時採最高層級,並保留其他 reason 供 UI 顯示,不得產生重複 card。
POST /api/connector/search - OFFLINE + Active Transaction 必須高於一般 OFFLINE,提醒可能仍在離線充電或待 reconciliation。
目前案場完整集合 → filter → 共用priority sort → paginate(20)
↓ - SUSPENDED_EVSE 與 SUSPENDED_EV 必須分開;前者為設備端暫停,優先級高於車端暫停。
content+Spring Page metadata → 當頁畫面/總數/頁次 - Unknown/資料不足不得 fallback 為 AVAILABLE。
``` - Backend 必須回傳 stable priority reason/severity code;FE 不自行推導權重。
- Queue `BLOCKED` 沿用既有 Backend 狀態進入異常層級;WAITING/ELIGIBLE 的持續時間只供顯示,不因時間長短升級為異常。
- Ranking、summary counts、Top-8 preview、`isAbnormal` 與 `abnormalTotal` 使用同一份 snapshot/policy。
### UI-DEC-008/009:Queue Timeout/Override(已撤回)
**狀態:已由 UI-DEC-011 取代(2026-09-03,Ken)**
- Request沿用page/size,固定size=20、sortMode=DASHBOARD_PRIORITY;不另建pageSize或Dashboard專用search endpoint。 先前討論的 Queue SLA、`isOverdue`、threshold、Building/Charge Group override 與 Admin 設定,會讓唯讀 Dashboard 擴張成新的營運規則,故不納入 V1。
- 畫面頁次從1開始;API adapter沿用既有endpoint的page convention,不改共用契約。 FE/BE 不需實作上述 timeout policy、欄位、設定來源或管理介面;歷史討論保留於 Redmine journal 供追溯。
### UI-DEC-010:Queue Source 語意對齊
**狀態:保留並簡化(2026-09-03,Ken)**
- 現行 `ChargingRequestSource` 維持 `MANUAL`、`OFF_PEAK`,供 Dashboard 正確顯示既有 queue source。
- Response沿用content、totalElements、totalPages、size、number、numberOfElements、first、last、empty。 `ROTATION` 是既有 dispatch/slot 調度機制,不是 queue source;Dashboard 不新增 `ROTATION` enum。
- Search request不傳buildingId;Backend用與Overview相同resolver限制案場,不依賴FE filter授權。 V1 不新增 Rotation scheduler-health、missed-tick 或 dispatch-lag 判定;只顯示目前系統已有的 queue/rotation 資訊。
### UI-DEC-011:Dashboard V1 為唯讀資訊投影
**狀態:已確認(2026-09-03,Ken)**
- Dashboard 的目的為查詢、彙整與顯示既有營運資訊,不建立新的充電或排程業務規則。
- 既有keyword/status可重用;Charge Point ID/Charge Group等缺少條件須補DTO、query、OpenAPI、contract tests。不能只篩目前20筆或Top-8。 Queue 卡片/Drawer 顯示既有 source、status、priority、statusReason、waitingSince 與 waiting duration;waiting duration 是資訊,不是 SLA 或 timeout。
- Drawer沒有排序選單、可點欄位、升降冪或sorting state;不接使用者sidx/sord,Backend在Dashboard mode以priority為準。 既有 `BLOCKED` 可列入 Needs Attention 並使用異常樣式;WAITING/ELIGIBLE 不因等待時間長短自動變成異常。
- 未使用Dashboard mode的 /connector/list,原sidx/sord排序保留;不縮減管理頁能力。 Backend 開發限於 read model、query/aggregation、DTO、REST bootstrap、WebSocket update 與顯示排序,不得因此修改 queue lifecycle、priority、slot allocation、rotation dispatch、OCPP command 或充電流程。
- 不提供page-size selector、頁碼列、直接跳頁、virtualization或view-mode欄位。 FE 開發限於呈現 Backend 既有狀態與時間資訊,不推導新的 `isOverdue`、severity 或業務狀態。
- V1 不新增 Queue timeout 設定、override precedence、Admin 設定頁、設定權限/audit table 或 Rotation health monitor。
- 若未來營運方明確需要 Queue SLA 或 scheduler monitoring,必須另案進行需求確認;本次不先建立子票。
| 結果筆數 | Footer | ### UI-DEC-012:單一 Responsive 呈現,不提供 Grid/Table Toggle
**狀態:已確認(2026-09-03,Ken)**
- Dashboard Connector preview 固定使用 responsive Cards,不提供顯示模式切換。
|---|---| - 「查看全部」Drawer 採單一 responsive list:Desktop 使用緊湊列式呈現,Tablet/Mobile 依寬度自動堆疊欄位。
| 0 | Empty、「共0個」,無換頁控制 | - Breakpoint 只改變排版,不改變資料欄位、status 語意、搜尋/篩選、排序或 pagination 規則。
| 1~20 | 「共N個」,無換頁控制 | - FE 不實作 Grid/Table toggle、view-mode URL parameter、local storage/使用者偏好保存或兩套可切換 renderer。
| >20 | 「第X/Y頁・共N個」+前後頁;第一頁停用上一頁、最後頁停用下一頁 | - Backend 不新增 `viewMode` request/response 欄位,也不依顯示模式提供不同資料 contract。
- 驗收只需覆蓋既定 Desktop/Tablet/Mobile responsive layout,不增加兩種 view mode 的交叉測試矩陣。
30筆2頁、100筆5頁;換頁保留篩選,改任一條件回第1頁,total/內容/頁次必須屬同一查詢。
### 6.3 狀態只保留在本次頁面(UI-DEC-018) UI-DEC-013:Connector Preview 使用單一 Top-8 Payload
| 行為 | 搜尋/篩選/頁碼 | **狀態:已確認(2026-09-04,Ken)**
- Backend 對目前 building 的完整 Connector 集合套用 UI-DEC-007 排序與異常分類,再固定回傳最多前 8 筆 `items`;總數少於 8 時回傳全部,不補空白資料。
|---|---| - Payload 同時回 `total` 與 `abnormalTotal`,每個 item 帶 Backend authoritative `isAbnormal`、`severity`、`priorityReason`;完整欄位仍依 Card Minimum Content 提供。
| 關閉再開、尚未離開Dashboard | 保留,避免看完detail丟失位置。 | - Desktop 顯示前 8 筆、Tablet 前 6 筆、Mobile 前 4 筆。Frontend 只能依目前 breakpoint 截取既有順序,不得要求 Backend 另產生 viewport-specific payload,也不得重排、重判 abnormal 或從未載入資料推測分類。
| 整頁reload或離開後返回 | 空搜尋、全部篩選、第一頁、固定priority。 | - Footer 的隱藏總數與隱藏異常數由 FE 使用 Backend totals 與 visible slice 作純顯示運算;這不構成新的 domain rule。負數一律 clamp 為 0,資料不一致時顯示區塊 Partial/Error,而不是自行修正 Backend 值。
- REST Overview bootstrap 與 WebSocket `CONNECTOR_LIVE_BLOCK_UPDATED` 使用同一份 service、snapshot 與 contract;WebSocket 每次仍 replacement 整個 summary + Top-8 preview,不傳完整 Connector inventory。
- 「查看全部」Drawer 另呼叫 REST search API 取得完整清單、搜尋、篩選與 server pagination;Dashboard socket 不因 Drawer 開啟而擴大 payload。
- 本決策取代「Backend 依 Desktop/Tablet/Mobile 各自截取」及「Backend 直接回 `remainingAbnormalCount`」的舊解讀;API 不需要 viewport、device 或 requestedLimit 欄位。
不寫URL query、browser history、localStorage/sessionStorage,不新增Backend preference,也不以WS同步;不保存viewMode或sorting state。 ### UI-DEC-014:Status Summary 採互斥 Display Bucket
## 7. REST/WebSocket 契約與ownership **狀態:已確認(2026-09-04,Ken)**
| 時機 | 如何更新 | - Status summary 是 Dashboard 專用的唯讀顯示分類。Backend 必須依目前 building 的同一份 authoritative Connector snapshot,替每個 Connector 指定且只指定一個 `displayBucket`。
|---|---| - Summary 回傳 `total` 與各 bucket count;所有 bucket count 必須無重複、無遺漏,且加總恰好等於 `total`。Frontend 直接呈現 Backend counts,不可從 Top-8 preview 重算。
| 頁面首載 | - `displayBucket` 不取代原始 domain state。Card、完整清單 Drawer 與 detail 仍分層顯示 Charge Point OCPP connection、Connector runtime status、Queue status/reason;同一 Connector 可以在原始資料中同時出現 OFFLINE、CHARGING、BLOCKED 等訊號,但摘要只歸一類。
- 分類只能讀取既有狀態並套用顯示 precedence,不可回寫 Connector/Queue、不觸發狀態轉換,也不新增 SLA、timeout、scheduler-health、設備控制或自動修正。
- REST Overview bootstrap可顯示初始summary+Top-8。 | bootstrap 與 `CONNECTOR_LIVE_BLOCK_UPDATED` 必須共用同一 bucket aggregation;每個 Top-8 item 也回傳自己的 `displayBucket`,供 FE 樣式與可存取文案使用。
| 一條Dashboard socket接手 | initial DASHBOARD_LIVE_SNAPSHOT之後,本區以CONNECTOR_LIVE_BLOCK_UPDATED整包replacement summary+Top-8。 | - Bucket code、顯示名稱、狀態 mapping 與 precedence 已由 UI-DEC-015 確認;FE/BE 必須使用該固定 contract,不再自行選定。
### UI-DEC-015:Status Summary 固定五類 Bucket 與 Precedence
**狀態:已確認(2026-09-04,Ken)**
Backend 必須依下列順序,由上而下命中第一個符合條件的 bucket;一旦命中即停止,不得重複計數:
1. `NEEDS_ATTENTION`/「需留意」:`isAbnormal = true`;包含 OCPP OFFLINE、Connector FAULTED、資料 STALE、Queue BLOCKED、SUSPENDED_EVSE、UNAVAILABLE,以及 null/unknown/資料不足。這只是 Dashboard 顯示分類,不會額外建立 #1463 Attention category 或新告警規則。
| 5分鐘/手動Overview | 更新一般區塊,不覆寫本區live state、不重建socket。 | 2. `CHARGING`/「充電進行中」:排除第一類後,Connector runtime 為 CHARGING、SUSPENDED_EV 或 FINISHING。
| Socket失敗/中斷 | Header與本區提示、保留最後資料/時間,無資料—;不REST fallback、backoff、自動重連或gap recovery。 | 3. `WAITING`/「準備/排隊」:排除前兩類後,Connector runtime 為 PREPARING/ENQUEUED,或 Queue status 為 ELIGIBLE。
| 整頁reload | 重新取bootstrap/ticket、建立socket。 | 4. `AVAILABLE`/「可用」:排除前三類及 OTHER 所列特殊中性狀態後,Connector runtime 為 AVAILABLE。
| 完整清單/detail | 依第5~6節既有REST與detail flow,不擴充Dashboard socket。 | 5. `OTHER`/「其他狀態」:RESERVED、Queue NOT_PLUGGED/PAUSED/FINISHED,以及其他已辨識、非異常但未落入前四類的狀態。Unknown 不得歸入 OTHER 或 AVAILABLE。
(#1424 DEC-031~041) Contract 與不變條件:
| Payload位置 | 需要回傳 | - Summary `buckets` 固定使用上述 stable codes 與顯示順序;中文 label 固定由 FE 映射,不依 Backend 任意字串產生。
|---|---| - 每個 Connector 恰好一個 bucket;五類 count 加總等於 `total`。
| connectorSummary | total、固定五個buckets的code/count | - `NEEDS_ATTENTION` 與既有 abnormal classification 是同一集合,因此 `NEEDS_ATTENTION.count = abnormalTotal`;Top-8 item 的 `displayBucket = NEEDS_ATTENTION` 時 `isAbnormal` 必須為 true,反之亦然。
| connectorPreview | maxItems=8、total、abnormalTotal、items | - Preview ranking 的細部 priority reason 仍保留。例如 OFFLINE + Active Transaction 與一般 OFFLINE 都屬 NEEDS_ATTENTION,但前者仍透過 `priorityReason` 排在較前面。
| 每個item | connectorId、displayBucket、isAbnormal、severity、priorityReason、卡片必要內容 | - NOT_PLUGGED 固定歸 OTHER,不歸 WAITING,避免與已確認的「等待供電」KPI(只計 distinct ELIGIBLE)語意衝突。
| 共用metadata | buildingId、來源時間/品質與受支援schemaVersion,依#1424 | - `displayBucket` 只控制 Status summary 與 Card presentation,不改寫 OCPP/runtime/Queue state,不新增 mismatch、timeout、SLA、scheduler-health、設備控制或資料修正。
REST/WS共用同一service與contract,沒有三種viewport response,Backend不直接回各畫面remainingAbnormalCount;Footer由FE依同一totals計算。空案場仍五bucket,不回動態raw status keys。 ### UI-DEC-016:非空案場固定顯示五類;空案場顯示 Empty State
## 8. 開發分工與驗收 **狀態:已確認(2026-09-05,Ken)**
| 負責方 | 交付 | - 為維持單一 API/WebSocket contract,Backend 的 `connectorSummary.buckets` 對任何 `total` 都固定回傳五個 stable bucket,順序沿用 UI-DEC-015;每個 `count` 可為 0。
|---|---| - `total > 0` 時,Frontend 必須依固定順序顯示全部五個摘要項目。某類 `count = 0` 仍顯示,例如只有 1 個 AVAILABLE Connector 時顯示「需留意 0、充電進行中 0、準備/排隊 0、可用 1、其他狀態 0」。
| Backend | 完整集合分類/排序/Top-8、統計不變條件、原始狀態分層、REST/WS同contract;擴充既有search與固定20筆分頁。 | - 在 `CONNECTOR_LIVE_BLOCK_UPDATED` 的整區 replacement 中,Status Summary 子區塊更新既有五項的 counts 與相關可存取文字;不得因 count 在 0 與非 0 間切換而新增、移除或重排摘要項目,避免即時更新造成 layout shift。事件中的 Top-8 preview 仍依同一 payload 一併 replacement。
| FE | 依本票畫面順序實作標題、純資訊summary、8/6/4 cards、Footer、detail與Full List;RWD/focus/Loading/Empty/Partial/Error/Stale。 | - `total = 0` 時,Frontend 隱藏整組 Status summary,顯示「尚未建立 Connector」Empty State 與既有 Connector 管理頁連結。Backend 仍回五個 count = 0 的 bucket,不建立第二種 response shape。
| QA | 數量/斷點矩陣、priority/bucket不同層語意、隱藏數、搜尋完整集合、固定排序/分頁/page session、socket failure與管理頁無回歸。 | - 0 是成功取得的有效數值,與 Loading、Error、Unknown/null 不同;Frontend 不得用 truthy/falsy 判斷把 0 當成缺值。
- 本決策只規範呈現與固定 contract,不新增輪詢、WebSocket 備援、狀態推導或任何充電作業邏輯。
### UI-DEC-017:Status Summary 維持純資訊、不可點擊
**狀態:已確認(2026-09-05,Ken)**
- [ ] 0/1/2/8/9/30/100筆+390/768/1024/1440px;手機另4/5、平板另6/7的上限邊界正確。 `NEEDS_ATTENTION`、`CHARGING`、`WAITING`、`AVAILABLE`、`OTHER` 五個摘要項目只負責顯示分類名稱與數量,不是操作控制項。
- [ ] 少量靠左不拉滿、內容不截斷,大量不無限增高;無頁面水平捲軸。 Frontend 使用一般清單/內容語意呈現,不得實作為 link、button、`role="button"` 或加入 `tabindex`;不得顯示手型 cursor、hover action、focus indicator、pressed/selected state。
- [ ] 五bucket互斥、合計total、需留意=abnormalTotal、item異常一致;Unknown不當AVAILABLE、NOT_PLUGGED不當WAITING。 使用者點擊、觸控或以鍵盤瀏覽摘要項目時,不開啟 Drawer、不套用篩選、不導向 Connector 管理頁,也不發送 REST/WebSocket request。
- [ ] total>0固定含0五項、total=0明確Empty;五摘要不可點、不進Tab、不發request。 單支 Connector detail 的入口仍是下方 preview card;完整清單、搜尋與篩選的入口仍是「查看全部 N 個 Connector」。兩者既有 pointer/keyboard/focus 行為不受影響。
- [ ] Backend ranking穩定、同層持續時間/ID;多條件不重複卡,FE只取8/6/4,隱藏總數/異常數正確。 不新增 bucket-to-filter mapping、summary click API、URL query 欄位或 WebSocket event;UI-DEC-015~016 的五項 counts contract 完全不變。
- [ ] 三層原始狀態與卡片minimum content保留;未知功率不填0,不推論離線充電。 本決策正式取代 UI-DEC-005 中「可於 FE plan 決定是否把 summary 作為 Drawer 篩選捷徑」的較早文字,FE 不得再自行啟用該捷徑。
### UI-DEC-018:Drawer 狀態只保留於目前 Dashboard Page Session
**狀態:已確認(2026-09-05,Ken)**
- Frontend 以目前已掛載的 Dashboard page memory 保存完整清單 Drawer 的搜尋文字、各項篩選與目前頁碼。
- [ ] 完整Drawer桌面側邊、平板手機全螢幕;搜尋/filter固定存在,Escape/focus trap/返回焦點正確。 使用者關閉 Drawer 後,在未 reload、未離開 Dashboard 的情況下重新開啟,必須還原剛才的搜尋、篩選與頁碼,避免查看 detail 後失去清單位置。
- [ ] 對完整集合filter→sort→paginate;30/100筆為2/5頁,0~20無換頁,first/last按鈕與metadata一致。 重新整理頁面,或離開 Dashboard route 後再返回時,Drawer 恢復預設 priority sorting、空白搜尋、全部篩選與第一頁。
- [ ] 無使用者排序/page-size/直接跳頁/Grid-Table/virtualization;管理頁原排序正常。 V1 不把 Drawer state 寫入 URL query、browser history、localStorage 或 sessionStorage;Backend 不新增使用者偏好欄位/API,WebSocket 也不傳遞此 state。
- [ ] close/reopen保留條件頁碼、reload/navigation重設,不持久化、不傳buildingId。 本決策只定義 state 的生命週期;固定 page size、換頁控制與條件變更後的頁碼處理由 UI-DEC-019 定義。
- [ ] 首載REST、後續WS整包同contract;一般REST不覆寫live,斷線無備援/自動重連,detail socket關閉釋放。 Mock 可用假資料驗證 close/reopen 狀態保留與 30/100 筆分頁互動,但不得以 Mock 宣稱 production REST pagination 已完成或通過。
### UI-DEC-019:完整清單固定每頁 20 筆,只提供前後換頁
**狀態:已確認(2026-09-05,Ken)**
- Drawer 使用/擴充既有 `POST /api/connector/search`,Request 沿用 `page` 與 `size`,固定 `size = 20`;不另建 `pageSize` 或 Dashboard 專用清單 endpoint。
- [ ] Keyboard可操作卡片、filter、Drawer與捲動內容;production不使用fixture fallback。 使用者看到的頁次從第 1 頁開始;Frontend API adapter 依既有 endpoint 的 page convention 轉換,不在本需求改寫共用 pagination contract。
- [ ] 無Queue SLA/isOverdue、override/設定介面/audit、Rotation health、充電指令或業務狀態寫回。
Response 沿用既有 Spring Page metadata(`content`、`totalElements`、`totalPages`、`size`、`number`、`numberOfElements`、`first`、`last`、`empty`)。
- Footer 只提供「上一頁」、「下一頁」與「第 X / Y 頁・共 N 個」;第一頁停用上一頁,最後一頁停用下一頁。結果 1~20 筆時隱藏換頁控制並顯示「共 N 個」;0 筆顯示 Empty State 與「共 0 個」。
- 搜尋文字、status 或 Charge Group 等任一條件改變時,Frontend 將目前頁碼重設為第 1 頁,並把全部條件送到 Server;Backend 對完整資料集篩選後再分頁,不得只篩選目前載入的 20 筆。
- V1 不提供每頁筆數選擇、頁碼列、直接跳頁或 virtualization;避免為唯讀 Dashboard 增加不必要控制與狀態。
- UI-DEC-018 的生命週期規則不變:換頁後關閉/重開 Drawer 保留頁碼與條件,reload/navigation 後重設。
- 現有 `SearchConnectorDto` 已具 keyword/status 與共用分頁欄位;Charge Point ID/Charge Group 等 Drawer 條件是否已完整支援,須在實作時補齊 DTO/query 與 contract tests。
- Mock ?connectors=30/100僅模擬UI,不能當正式REST pagination已通過;正式search與權限仍須integration/E2E驗證。 的 `?connectors=30`/`?connectors=100` 只模擬 Server 查詢後的 UI 分頁,分別應為 2/5 頁;正式 REST 行為仍須由 integration/E2E 驗證。
## 9. 決策索引與已取代內容 ### UI-DEC-020:完整清單固定 Backend Priority Sorting,不提供使用者排序控制
| 決策 | 本文位置/狀態 | **狀態:已確認(2026-09-05,Ken)**
- Drawer 不顯示排序下拉選單、升冪/降冪按鈕、可點擊欄位標題或其他排序控制,也不為排序建立額外 keyboard/touch interaction。
|---|---| - Backend 是完整清單排序的唯一 owner;先對完整 Connector 集合套用搜尋與篩選,再依 UI-DEC-007 的固定營運優先層級排序,最後依 UI-DEC-019 每 20 筆分頁。不得分頁後才在單頁內排序。
| UI-DEC-001~003 數量/RWD | 第3節;2026-09-03已確認 | - 同一 priority 層級依異常/狀態持續時間由久至新排列,最後以 Connector ID 作 deterministic tie-breaker;搜尋與篩選只縮小結果,不改變此規則。
| UI-DEC-004/005 Drawer/搜尋位置 | 第5~6節;2026-09-03已確認 | - Dashboard Drawer 透過既有 `POST /api/connector/search` 固定要求 `sortMode = DASHBOARD_PRIORITY`;Frontend 不把 `sidx`/`sord` 連接到任何使用者輸入,Backend 在此 mode 下以 Dashboard priority 為準。
| UI-DEC-006/007 排序owner/層級 | 第4節;2026-09-03已確認,推測文案依較新決策撤回 | - `DASHBOARD_PRIORITY` 必須重用 preview ranking service/規則,避免 Top-8、完整清單及 WebSocket 的 priority 漂移。
| UI-DEC-008/009 Queue timeout/override | 已被011撤回,不實作 | - 既有 `/connector/list` 管理頁未使用此 mode 時,原本的欄位排序仍可保留;本決策只限制 Dashboard Drawer,不縮減既有管理頁能力。
| UI-DEC-010/011 Queue來源/只讀界線;012單一list | 第3、6、8節;2026-09-03已確認 | - UI-DEC-018 的 page-memory state 不增加 sorting state;close/reopen 只保留搜尋、篩選與頁碼。
| UI-DEC-013 Top-8;014互斥;015 mapping | 第2~4、7節;2026-09-04已確認 | - 本決策只定義唯讀排序與呈現,不修改 Connector status、Queue priority、rotation dispatch、OCPP 或 charging lifecycle。
| UI-DEC-016零值/017不可點 | 第2.3節;2026-09-05已確認 |
| UI-DEC-018 page memory;019分頁;020排序 | 第6節;2026-09-05已確認 | - Mock 不顯示排序控制,並以完整假資料先做固定 priority sort、再篩選與分頁;Mock 不能代替正式 Backend contract/integration 驗證。
已取代的舊文字包括「3~8一律全顯示/30以上8或4」(須按8/6/4斷點)、9筆才出現搜尋、summary篩選捷徑、可選排序、virtualization、三套viewport payload、Backend直接回剩餘異常數。舊討論保留於journals,不再混在現行開發規則。
相關票:#1424 API/WS與權限;#1463需留意事項;#1486 KPI。此票仍沿用現有指派與進度。
## 需求管理與本次編輯 需求管理狀態
- 本票仍是已確認需求的追蹤票,不代表已完成開發或通過測試;指派、狀態、進度、附件與父子關係均維持原狀。 Parent:#1422
- 全 Requirement status:**UI-DEC-001~020 已確認,Connector 數量彈性顯示子需求已完成需求確認;議題仍維持 New/0%,待 Dashboard 完成一致性 review 後,才依 整體鎖版後再進入開發**
- Final specification:確認後整併至 #1422 DOC-DEC-001 發布同版號 PDF/Markdown/HTML 套件;現有 v0.3 Draft 不覆寫,本次不發布新版附件。 的 v1.0 最終需求文件
- 2026-09-14:僅重整 Description、說明與排版,將已確認決策併入對應畫面/工程工作;決策編號保留供追溯。E2E impact:No catalog change(沒有修改產品行為、公式或 API 契約);功能實作時仍須遵循主票與本票驗收。
Implementation tickets:需求鎖定後才建立 FE/BE/QA child issues
返回