討論 #1423
是由 陳國瑋 於 15 天 前更新
> **閱讀基準:** [主需求 #1422](https://redmine.sylksoft.com/issues/1422) 與 [HTML Mock v0.3/附件 #1117](https://redmine.sylksoft.com/attachments/1117)。以下沿用主票區塊編號,依畫面由上到下、由左到右說明。Mock 數字皆為假資料;功能適用所有案場,A17 不是固定規則。
## 06|Connector 即時狀態:本票要完成什麼
**讓不同規模案場都能先看整體狀態,再看優先項目,最後按需打開完整清單。** Dashboard 不把所有 Connector 無上限展開,也不因只有 1~2 個就把卡片拉滿整列。
本票對應主票中下段的整列區塊。UI-DEC-001~021 本票對應主票中下段的整列區塊。UI-DEC-001~020 的結果已整理進下方正文;已撤回的 008/009 只保留追溯,不是待開發需求。
```text
Connector 即時狀態 總數/更新時間/品質/連線
↓
五項摘要:需留意|充電進行中|準備/排隊|可用|其他狀態
(純資訊,不可點擊)
↓
優先項目卡片:依 Backend 順序,桌面8/平板6/手機4
↓
已顯示/總數、另有多少異常未顯示 查看全部
│ │
點卡片 → 單支詳情 完整清單 Drawer
搜尋/摘要分類/Charge Group 搜尋/篩選 → 固定20筆分頁
```
## 1. 區塊標題列與資料時間
由左到右顯示「Connector 即時狀態」、Connector 總數、最後更新時間、freshness/stale 與即時連線狀態。
- 案場/資料範圍由 Backend 決定,不在本區切案場。
- 連線正常不代表所有來源都新鮮;資料品質與 WebSocket connection 分開呈現。
- 本區沒有專用 Refresh/Retry。Socket 失敗或中斷,保留最後資料與時間,提示「已停止更新」;無資料為「—」,不是 0。整頁 reload 才重新嘗試,詳見第 7 節。
## 2. 五個摘要:先看完整統計,不從預覽卡推算
### 2.1 固定分類與判定順序
Backend 依同一份完整 Connector snapshot 分類,由上往下命中;一個 Connector 只屬於一類。**分類只是唯讀呈現,不能覆寫原本的 OCPP/runtime/Queue。**(UI-DEC-014/015)
| 順序/code | 固定中文 | 分類條件 |
|---|---|---|
| 1 NEEDS_ATTENTION | 需留意 | isAbnormal=true;包含 OCPP OFFLINE、FAULTED、資料 STALE、Queue BLOCKED、SUSPENDED_EVSE、UNAVAILABLE、null/unknown/資料不足。 |
| 2 CHARGING | 充電進行中 | 排除第一類後,runtime CHARGING/SUSPENDED_EV/FINISHING。 |
| 3 WAITING | 準備/排隊 | 排除前兩類後,runtime PREPARING/ENQUEUED,或 Queue ELIGIBLE。 |
| 4 AVAILABLE | 可用 | 排除前三類及下列特殊中性狀態後,runtime AVAILABLE。 |
| 5 OTHER | 其他狀態 | RESERVED、Queue NOT_PLUGGED/PAUSED/FINISHED,及已辨識、非異常且不屬前四類者;Unknown 不可放這裡。 |
NOT_PLUGGED 固定歸 OTHER,不當 WAITING;沿用 UI-DEC-015 的既定 mapping,不從中文 label 猜類別。這裡的「充電進行中」是顯示分類;上方 #1486 的同名 KPI 則計 canonical ACTIVE Session,不能要求兩者數字相等。
### 2.2 統計不變條件
- 五類 count 無重複、無遺漏,加總=total。
- NEEDS_ATTENTION.count=abnormalTotal。
- item 的 displayBucket=NEEDS_ATTENTION 與 isAbnormal=true 必須一致。
- 每個 item 保留 priorityReason/severity;同屬「需留意」仍可有不同細部排序。
- 此分類不額外建立 #1463 的 Attention category 或告警。Backend counts 才是完整統計,FE 不從最多 8 張 preview 重算。
### 2.3 零值與互動(UI-DEC-016/017)
| 條件 | 顯示/互動 |
|---|---|
| total>0 | 五項全部顯示,包含 count=0,固定順序;數字從0變非0不新增/移除項目。 |
| total=0 | 隱藏摘要,顯示「尚未建立 Connector」與既有管理頁連結;Backend 仍回五個0,response shape 不變。 |
| Loading/Error/Unknown | 不以 falsy 判斷當成0,不顯示假正常空狀態。 |
| 任一摘要項目 | **不可點擊、不可觸發篩選、不開 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
### 3.1 一份 Top-8 payload,FE 只取前 8/6/4
| 寬度 | 最多顯示 | 排版 |
|---|---|---|
| Desktop ≥1240px | 8張 | 卡片約240~320px,左對齊、自動換欄;單卡最大寬度約360px,不拉滿。 |
| Tablet 640~1239px | 6張 | 寬時3欄×2列,窄時2欄×3列;不足以容納必要資訊就降欄。 |
| Mobile <640px | 4張 | 單欄;查看全部用全螢幕 Drawer。 |
欄數依可用寬度,不依 user-agent;不截斷 ID、status、stale 等必要資訊。(UI-DEC-001~003/013)
| 總數 | 桌面/平板/手機顯示筆數 | 重點 |
|---|---|---|
| 0 | 空狀態 | 不顯示假卡。 |
| 1 | 1/1/1 | 保留正常卡寬並靠左。 |
| 2 | 2/2/2 | 桌面雙卡靠左、手機單欄,不補空卡。 |
| 5 | 5/5/4 | 手機已有未顯示資料,不能用「9個以上」才提供查看全部。 |
| 7 | 7/6/4 | 平板與手機依自身上限。 |
| 8 | 8/6/4 | 只有桌面完整顯示8筆。 |
| 9、30、100或更多 | 8/6/4 | 不隨總數無限增加首頁高度;完整資料走Drawer。 |
Backend 對完整集合分類排序後回最多8筆,少於8回實際筆數。FE 不傳 viewport/device/requestedLimit、不要求三種 response,不重排或重判異常。
### 3.2 卡片由上至下的必要內容
| 內容 | 規則 |
|---|---|
| Connector ID/車位 | 讓使用者辨識設備,不因卡片窄而截掉必要識別。 |
| 所屬 Charge Point 連線 badge | OCPP ONLINE/OFFLINE/UNKNOWN,與runtime分開。 |
| Connector runtime | 如CHARGING/FAULTED/SUSPENDED;不能只剩一個綜合「在線」。 |
| 目前功率 | API 有效數值與單位;未知null顯示無資料/—,不是0。 |
| Active Session/Queue | 若排隊顯示既有source、status、priority、statusReason、waitingSince/持續時間。 |
| 最後更新/stale | 與來源品質一致;異常要有文字,不只靠色彩。 |
| 點擊行為 | 開啟單支detail drawer,有鍵盤操作與清楚focus。 |
```text
同一個 Connector 可以同時有:
CP:OFFLINE
runtime:CHARGING
Queue:BLOCKED
↓
保留三層原始事實,summary只歸一個顯示分類;不寫回狀態。
```
Queue source 維持 MANUAL/OFF_PEAK。ROTATION 是既有 dispatch/slot 調度機制,**不是新 queue source enum**。等待時間只是資訊,不據此推導 timeout/SLA/isOverdue。(UI-DEC-010/011)
## 4. 哪些卡片排前面:Backend 統一排序
Preview、完整清單與 WebSocket 共用同一 ranking service/snapshot;同一 Connector 命中多條只採最高層級、不重複卡,保留其他原因供顯示。(UI-DEC-006/007/020)
| 優先層級 | 已確認條件 |
|---|---|
| 1 | CP OFFLINE 且 Connector 有 Active Transaction |
| 2 | Connector FAULTED |
| 3 | CP OFFLINE、資料 STALE、Queue BLOCKED |
| 4 | SUSPENDED_EVSE、UNAVAILABLE |
| 5 | SUSPENDED_EV |
| 6 | CHARGING |
| 7 | PREPARING/Waiting |
| 8 | AVAILABLE |
同層先按異常/狀態持續時間由久至新,再以 Connector ID 穩定排序。SUSPENDED_EVSE 與 SUSPENDED_EV 分開;Unknown 不 fallback AVAILABLE,Backend 提供保守且可解釋的 reason/severity。異常優先,未滿預覽再由其餘狀態補足。
**舊文案更正:** 第一層仍保留排序,但「提醒可能仍在離線充電或待 reconciliation」的舊解釋,已被 #1422、#1463 ATT-DEC-008/#1486 KPI-DEC-011 的較新邊界取代。只呈現連線與交易事實,不新增這些推測性 badge/原因/文案;本次不改排序、交易計數或作業狀態。
### Footer 顯示多少沒被看見
```text
hiddenCount = max(0, total - visibleCount)
hiddenAbnormalCount = max(0, abnormalTotal - visibleAbnormalCount)
```
visibleAbnormalCount 只計可見slice中 Backend 標 isAbnormal=true 者。這是FE純顯示計算,不是重建分類;數據不一致須顯示Partial/Error,不能靠clamp後宣稱正常。
例如total30、abnormalTotal10、桌面可見8筆且8筆異常:Footer 顯示另有22筆未顯示、另有2個異常,以及「查看全部30個Connector」。異常再多也不突破8/6/4上限。
## 5. 單支詳情與「查看全部」不是同一層
| 入口 | 打開什麼 | 資料與連線 |
|---|---|---|
| 預覽卡 | 單支 detail drawer | GET /api/connector/info/{connectorId};沿用既有單Connector detail flow,開啟才使用其既有socket,關閉釋放,見#1424。 |
| 查看全部 N 個 Connector | 完整清單 responsive Drawer | REST search/分頁;不擴大Dashboard WS payload,不建立全清單每卡socket。 |
Overview 不內嵌所有Connector完整detail,Drawer內可看單支詳情或前往既有管理頁,但不能開出無上限per-Connector連線。
**這裡的 Drawer 是什麼:** 它不是跳到另一頁,而是從目前畫面右側滑出的暫時面板。桌面版保留部分 Dashboard 在背景;平板/手機可使用全螢幕 Sheet。使用者關閉後回到原入口與原 Dashboard 位置。單支 detail Drawer 只看一個 Connector;Full List Drawer 才是多筆搜尋、篩選與分頁。
## 6. 完整清單 Drawer:搜尋 → 固定排序 → 每頁20筆
### 6.1 畫面從上到下(UI-DEC-004/005/012/021) 畫面從上到下(UI-DEC-004/005/012)
1. 標題、關閉:桌面右側約75vw(合理min/max);平板/手機全螢幕Drawer/Sheet。
2. 搜尋:Connector ID、Charge Point ID、車位。
3. 篩選:「摘要分類」、Charge Group。**只在 Drawer 提供**,首頁 preview 沒有搜尋/篩選,也沒有依總數 9 才出現的門檻。 篩選:status、Charge Group。**只在Drawer提供**,首頁preview沒有搜尋/篩選,也沒有依總數9才出現的門檻。
4. 單一responsive list:桌面緊湊列、窄畫面堆疊必要欄位,沒有Grid/Table切換。
5. Footer:總筆數、頁次、上一頁/下一頁;另有既有Connector管理頁deep link。
「摘要分類」固定選項如下,與首頁五個摘要使用同一套 `displayBucket`;預設為「全部」。
| UI 選項 | Request `displayBucket` |
|---|---|
| 全部 | 不傳/null |
| 需留意 | NEEDS_ATTENTION |
| 充電進行中 | CHARGING |
| 準備/排隊 | WAITING |
| 可用 | AVAILABLE |
| 其他狀態 | OTHER |
首頁五項摘要仍是純資訊、不可點擊,不會開啟 Drawer 或預先套用篩選。V1 不把 Connector runtime status 與 Queue status 混成第三套 selector;兩者仍在每列中分層顯示。
關閉時focus回原「查看全部」按鈕,支援Escape、focus trap、可辨識標題及Loading/Empty/Error。首頁preview避免固定高度nested scrollbar;若使用scroll container須能鍵盤focus與捲動。Drawer內欄位與filter不因RWD改變語意。
### 6.2 每次都對完整資料集查詢(UI-DEC-019/020)
```text
搜尋/篩選條件改變 → 回第1頁
↓
POST /api/connector/search
目前案場完整集合 → filter → 共用priority sort → paginate(20)
↓
content+Spring Page metadata → 當頁畫面/總數/頁次
```
- Request沿用page/size,固定size=20、sortMode=DASHBOARD_PRIORITY;不另建pageSize或Dashboard專用search endpoint。
- 畫面頁次從1開始;API adapter沿用既有endpoint的page convention,不改共用契約。
- Response沿用content、totalElements、totalPages、size、number、numberOfElements、first、last、empty。
- Search request不傳buildingId;Backend用與Overview相同resolver限制案場,不依賴FE filter授權。
- 既有 search 基礎可重用,但 Dashboard mode 必須新增 `displayBucket` 與 Charge Group;keyword 需涵蓋 Connector ID、Charge 既有keyword/status可重用;Charge Point ID、車位。缺少欄位須補 DTO、query、OpenAPI、contract tests。 ID/Charge Group等缺少條件須補DTO、query、OpenAPI、contract tests。不能只篩目前20筆或Top-8。
- 既有管理頁的原始 `status` 條件保留相容性;Dashboard Full List Drawer 不使用它來混合 runtime/Queue 語意。不能只篩目前20筆或Top-8。
- Drawer沒有排序選單、可點欄位、升降冪或sorting state;不接使用者sidx/sord,Backend在Dashboard mode以priority為準。
- 未使用Dashboard mode的 /connector/list,原sidx/sord排序保留;不縮減管理頁能力。
- 不提供page-size selector、頁碼列、直接跳頁、virtualization或view-mode欄位。
| 結果筆數 | Footer |
|---|---|
| 0 | Empty、「共0個」,無換頁控制 |
| 1~20 | 「共N個」,無換頁控制 |
| >20 | 「第X/Y頁・共N個」+前後頁;第一頁停用上一頁、最後頁停用下一頁 |
30筆2頁、100筆5頁;換頁保留篩選,改任一條件回第1頁,total/內容/頁次必須屬同一查詢。
### 6.3 Full List request/response 最小契約(UI-DEC-021) 狀態只保留在本次頁面(UI-DEC-018)
Request 至少包含下列欄位;欄位名稱可依既有 DTO 慣例調整,但語意不可改變。
| 欄位 | 規則 |
|---|---|
| page | 沿用既有 API page convention;UI 顯示從 1 開始。 |
| size | 固定 20。 |
| keyword | 可搜尋 Connector ID、Charge Point ID、車位;未填不過濾。 |
| displayBucket | 可省略;值限 NEEDS_ATTENTION/CHARGING/WAITING/AVAILABLE/OTHER。 |
| chargeGroupId | 可省略;只限制目前案場可見的 Charge Group。 |
| sortMode | 固定 DASHBOARD_PRIORITY;不是使用者可選欄位。 |
| buildingId | **不得由 FE 傳入**;Backend 依登入者與 Overview 相同 resolver 決定案場。 |
每一筆 response item 至少要足以完成 Mock 的一列與狀態分層:
| 類別 | 最小欄位 |
|---|---|
| 識別/位置 | connectorId、chargePointId、location、floor、parkingSpaceNo |
| 群組 | chargeGroupId、chargeGroupName;沒有群組時明確為 null |
| Dashboard 呈現 | displayBucket、isAbnormal、severity、priorityReason |
| 原始狀態 | ocppConnectionStatus、runtimeStatus、queueStatus、queueReason;不適用者為 null |
| 即時值/時間 | currentPowerKw(未知為 null)、updatedAt、freshness |
Page 外層仍沿用 content 與 Spring Page metadata。Backend 對完整集合完成 keyword/displayBucket/Charge Group filter,再做固定 priority sort 與 paginate;FE 不根據文字重新分類或重排。
### 6.4 條件只保留在本次頁面(UI-DEC-018)
| 行為 | 搜尋/篩選/頁碼 |
|---|---|
| 關閉再開、尚未離開Dashboard | 保留,避免看完detail丟失位置。 |
| 整頁reload或離開後返回 | 空搜尋、全部篩選、第一頁、固定priority。 |
不寫URL query、browser history、localStorage/sessionStorage,不新增Backend preference,也不以WS同步;不保存viewMode或sorting state。
## 7. REST/WebSocket 契約與ownership
| 時機 | 如何更新 |
|---|---|
| 頁面首載 | Overview bootstrap可顯示初始summary+Top-8。 |
| 一條Dashboard socket接手 | initial DASHBOARD_LIVE_SNAPSHOT之後,本區以CONNECTOR_LIVE_BLOCK_UPDATED整包replacement summary+Top-8。 |
| 5分鐘/手動Overview | 更新一般區塊,不覆寫本區live state、不重建socket。 |
| Socket失敗/中斷 | Header與本區提示、保留最後資料/時間,無資料—;不REST fallback、backoff、自動重連或gap recovery。 |
| 整頁reload | 重新取bootstrap/ticket、建立socket。 |
| 完整清單/detail | 依第5~6節既有REST與detail flow,不擴充Dashboard socket。 |
(#1424 DEC-031~041)
| Payload位置 | 需要回傳 |
|---|---|
| connectorSummary | total、固定五個buckets的code/count |
| connectorPreview | maxItems=8、total、abnormalTotal、items |
| 每個item | connectorId、displayBucket、isAbnormal、severity、priorityReason、卡片必要內容 |
| 共用metadata | buildingId、來源時間/品質與受支援schemaVersion,依#1424 |
REST/WS共用同一service與contract,沒有三種viewport response,Backend不直接回各畫面remainingAbnormalCount;Footer由FE依同一totals計算。空案場仍五bucket,不回動態raw status keys。
## 8. 開發分工與驗收
| 負責方 | 交付 |
|---|---|
| Backend | 完整集合分類/排序/Top-8、統計不變條件、原始狀態分層、REST/WS同contract;擴充既有search的 displayBucket/keyword/Charge Group、最小response欄位與固定20筆分頁。 完整集合分類/排序/Top-8、統計不變條件、原始狀態分層、REST/WS同contract;擴充既有search與固定20筆分頁。 |
| FE | 依本票畫面順序實作標題、純資訊summary、8/6/4 cards、Footer、detail與Full List;RWD/focus/Loading/Empty/Partial/Error/Stale。 |
| QA | 數量/斷點矩陣、priority/bucket不同層語意、隱藏數、搜尋完整集合、固定排序/分頁/page session、socket failure與管理頁無回歸。 |
- [ ] 0/1/2/8/9/30/100筆+390/768/1024/1440px;手機另4/5、平板另6/7的上限邊界正確。
- [ ] 少量靠左不拉滿、內容不截斷,大量不無限增高;無頁面水平捲軸。
- [ ] 五bucket互斥、合計total、需留意=abnormalTotal、item異常一致;Unknown不當AVAILABLE、NOT_PLUGGED不當WAITING。
- [ ] total>0固定含0五項、total=0明確Empty;五摘要不可點、不進Tab、不發request。
- [ ] Backend ranking穩定、同層持續時間/ID;多條件不重複卡,FE只取8/6/4,隱藏總數/異常數正確。
- [ ] 三層原始狀態與卡片minimum content保留;未知功率不填0,不推論離線充電。
- [ ] 完整Drawer桌面側邊、平板手機全螢幕;搜尋/「摘要分類」/Charge Group固定存在,Escape/focus 完整Drawer桌面側邊、平板手機全螢幕;搜尋/filter固定存在,Escape/focus trap/返回焦點正確。
- [ ] 「摘要分類」固定六選項且直接對應 displayBucket;首頁五摘要不可點、不帶入條件,runtime/Queue status仍分層顯示。 對完整集合filter→sort→paginate;30/100筆為2/5頁,0~20無換頁,first/last按鈕與metadata一致。
- [ ] 對完整集合filter→sort→paginate;30/100筆為2/5頁,0~20無換頁,first/last按鈕與metadata一致;request/response符合第6.3節。
- [ ] 無使用者排序/page-size/直接跳頁/Grid-Table/virtualization;管理頁原排序正常。
- [ ] close/reopen保留條件頁碼、reload/navigation重設,不持久化、不傳buildingId。
- [ ] 首載REST、後續WS整包同contract;一般REST不覆寫live,斷線無備援/自動重連,detail socket關閉釋放。
- [ ] Keyboard可操作卡片、filter、Drawer與捲動內容;production不使用fixture fallback。
- [ ] 無Queue SLA/isOverdue、override/設定介面/audit、Rotation health、充電指令或業務狀態寫回。
Mock ?connectors=30/100僅模擬UI,不能當正式REST pagination已通過;正式search與權限仍須integration/E2E驗證。
## 9. 決策索引與已取代內容
| 決策 | 本文位置/狀態 |
|---|---|
| UI-DEC-001~003 數量/RWD | 第3節;2026-09-03已確認 |
| UI-DEC-004/005 Drawer/搜尋位置 | 第5~6節;2026-09-03已確認 |
| UI-DEC-006/007 排序owner/層級 | 第4節;2026-09-03已確認,推測文案依較新決策撤回 |
| UI-DEC-008/009 Queue timeout/override | 已被011撤回,不實作 |
| UI-DEC-010/011 Queue來源/只讀界線;012單一list | 第3、6、8節;2026-09-03已確認 |
| UI-DEC-013 Top-8;014互斥;015 mapping | 第2~4、7節;2026-09-04已確認 |
| UI-DEC-016零值/017不可點 | 第2.3節;2026-09-05已確認 |
| UI-DEC-018 page memory;019分頁;020排序 | 第6節;2026-09-05已確認 |
| UI-DEC-021 Full List「摘要分類」與最小契約 | 第5~6節;2026-09-16已確認 |
已取代的舊文字包括「3~8一律全顯示/30以上8或4」(須按8/6/4斷點)、9筆才出現搜尋、summary篩選捷徑、可選排序、virtualization、三套viewport payload、Backend直接回剩餘異常數。舊討論保留於journals,不再混在現行開發規則。
相關票:#1424 API/WS與權限;#1463需留意事項;#1486 KPI。此票仍沿用現有指派與進度。
## 需求管理與本次編輯
- 本票仍是已確認需求的追蹤票,不代表已完成開發或通過測試;指派、狀態、進度、附件與父子關係均維持原狀。
- 全 Dashboard 完成一致性 review 後,才依 #1422 DOC-DEC-001 發布同版號 PDF/Markdown/HTML 套件;現有 v0.3 Draft 不覆寫,本次不發布新版附件。
- 2026-09-14:僅重整 Description、說明與排版,將已確認決策併入對應畫面/工程工作;決策編號保留供追溯。E2E impact:No catalog change(沒有修改產品行為、公式或 API 契約);功能實作時仍須遵循主票與本票驗收。
- 2026-09-16:依 Ken 確認新增 UI-DEC-021;Full List 的篩選命名為「摘要分類」,直接使用 displayBucket,並明列 search request/response 最小契約。首頁摘要的不可點擊規則不變;本輪只更新需求,不發布附件、不更動 Issue 狀態/進度。
返回