Design Pattern: Filter Combo
Visual basis: vortex-1.0 — verify behavior / copy / structure, not pixel style.
Why we're building this
At tens of thousands of devices per organization, browsing to find something no longer scales — the experience has to become filter-first. Filter Combo is the shared answer: one toolbar with a search field plus composable filter chips, working the same way in every module.
And because a filter like Device can't sensibly default to "everything", filters now start empty instead of the old "All".
What value it brings
One filter-first toolbar, everywhere.
- Scales — narrow tens of thousands of devices in a few clicks
- Consistent — the same search + filter chips across modules
- Predictable — filters start empty, so results reflect an explicit choice
工具列結構
Filter Combo 是一條可組合的篩選工具列:一個搜尋框,加上一組 filter chip,最右側是一顆「Reset」。每個頁面只挑自己需要的 chip 放進去,互動方式則完全一致。
所謂「combo」指兩個以上同時作用的 filter(其中一個可以是搜尋框)——多個條件一起對清單取交集。只有單一個搜尋框、沒有其他 filter 時,還構不成 combo(也就不會產生交集)。
「對清單取交集」這件事本身一律成立;但 Sites 與 Devices 之間還多一層關係——Sites 同時定義 Devices 的可選範圍(Sites 是範圍、Devices 是範圍內的細選),見 Section 04。
下圖為一條完整工具列(搜尋 + 多個 chip):
組成 Anatomy
| 區塊 | 說明 |
|---|---|
| 搜尋框 Search | 關鍵字搜尋,永遠放在最左側;搜尋範圍逐頁而定(見 Section 05) |
| 分隔線 Divider | 搜尋框與各 chip、chip 與 chip 之間的 1px 細線 |
| Filter chip | 一個篩選維度一顆(Sites / Statuses / Device type / Event types / Time…);點擊開啟選單 |
| Reset | 當有兩個以上篩選項(chip 或有字的搜尋框,各算一項)偏離預設時才出現在最右側;一鍵重設所有篩選 |
單一 chip 的組成 Chip parts
| 部位 | 說明 |
|---|---|
| 左側 icon(可選) | 部分 chip 有(如 Sites、Statuses),用來輔助辨識;非必要 |
| Label | 空值時顯示維度名稱(如「Sites」)、有值時顯示已選摘要(如「3 sites, 2 areas」) |
| 尾端符號 | 空值時是向下箭頭(chevron)、有值時是清除該 chip 的「X」 |
搜尋框的組成與狀態 Search input — 2 variants × 5 states
搜尋框有兩種變體 × 五種狀態,與 chip 的狀態矩陣同等份量。
| 部位 | 規格 |
|---|---|
| 容器 | 高 32px、左右內距 12px、元素間距 8px、圓角 9999px(全圓)、游標 text;邊框與底色隨情境不同,見下方狀態表 |
| 左側放大鏡 icon | 20×20,@color-icon-03 |
| 輸入區 | 14px / line-height 1.3;placeholder Search,色 @color-text-05 |
| 清除「X」 | 只在有值時出現;20×20 觸控區、icon 16×16、@color-icon-03,hover 轉 @color-text-01 |
篩選按鈕(僅 filter 變體) |
滑桿 icon,同樣 20×20 觸控區 / 16×16 icon / @color-icon-03,hover 轉 @color-text-01 |
| 變體 | 寬度 | 差異 |
|---|---|---|
default |
240px 固定 | 放大鏡 + 輸入區(+ 有值時的 X) |
filter |
320px 固定 | 尾端多一顆滑桿篩選按鈕 |
邊框與底色分兩種情境。 放在 filter 工具列裡時,分組感由工具列容器本身提供,所以搜尋框空值時不畫自己的邊框與底色,等有狀態了才逐步浮現;獨立擺放(不在工具列內)時則一律保留邊框與底色。文字色兩者相同。
| 狀態 | 在工具列內(本 pattern 的情境) | 獨立擺放 | 文字 |
|---|---|---|---|
| 空值 Empty | 邊框與底色皆透明 | 1px @color-outline-04 + 底 @color-surface-01 |
@color-text-05(placeholder 色) |
| Hover | 邊框 @color-outline-04 + 底 @color-surface-04 |
邊框不變,底轉 @color-surface-04 |
@color-text-01 |
| Focused | 邊框 @color-outline-07 + 底 @color-surface-01 |
邊框轉 @color-outline-07,底 @color-surface-01 |
@color-text-01 |
| 有值 Has value | 邊框 @color-outline-04 + 底 @color-surface-01 |
邊框與底色同空值態 | @color-text-01,並出現清除「X」 |
| 停用 Disabled | 兩者相同:底 @color-surface-03 |
同左 | 文字與 icon 全部 @color-text-06 |
停用時尾端的清除與篩選按鈕一併變
@color-text-06且不可點,不是只有輸入區變灰;游標為default。
組合原則 Composition
工具列依頁面情境組合,chip 的名稱也反映該頁的範圍:
| 情境 | 裝置類 chip | Device type chip |
|---|---|---|
| 只有攝影機的頁面(如 Message Center 事件) | 顯示為「Cameras」 / 「{N} cameras」 | 省略(全部都是攝影機,多餘) |
| 一般裝置頁面(混合裝置類型的挑選情境) | 顯示為「Devices」 / 「{N} devices」 | 保留(與類型正交的篩選) |
上表是元件在不同情境的 chip 命名慣例(完整 label 規則見 Section 02「已選狀態 label」);實際 Devices 頁的「類型」是用產品類型分頁(tabs)處理、工具列只放 Statuses + Sites(見 Section 06)。各頁實際的 chip 組合見 Section 06;每個 chip 選單的細節見 Section 03。
篩選預設為空 Empty by default
過去 VORTEX 的 filter 多半預設為「All(全選)」。改版後,幾乎所有 filter 預設為空——使用者主動建立篩選條件,而不是從全選往下刪。
| 面向 | 說明 |
|---|---|
| 根本原因 | 單一 org 的裝置量可達上萬。Device 這類 filter 不可能預設全選,因此「預設為空」一併套用到近乎所有 filter,維持一致。 |
| 少數例外 | 有合理預設值的維度仍保留(如 Message Center 的 Time;預設值見 Sites Related Pages §05)。 |
| 畫面不會空 | 「filter 預設為空」不等於清單空白:頁面初次載入仍會載入固定一批資料(見 Section 05),只是「篩選條件」本身從空開始。 |
Filter chip 狀態
每顆 chip 有兩個層次的變化:是否帶值(空 vs 已選),以及互動狀態(預設 / hover / 聚焦 / 停用)。下圖為 chip 的狀態矩陣(4 種變體 × 4 種狀態):
帶值與否 Empty vs has-value
| 狀態 | 文字 | 尾端 | 左側 icon(若有) |
|---|---|---|---|
| 空值 Empty | 維度名稱,placeholder 色 @color-text-05 |
向下箭頭 chevron | 偏淡 @color-icon-14 |
| 有值 Has value | 已選摘要,@color-text-01 |
清除該 chip 的「X」 | @color-icon-03 |
空值 chip 的文字與 icon 在 hover / 聚焦 / active 時亮起為
@color-text-01/@color-icon-03。
互動狀態 Interaction states
| 狀態 | 外觀 |
|---|---|
| 預設 Default | 空值透明背景;有值時填藍調 @color-surface-51 |
| Hover | 空值背景 @color-surface-04;有值時藍調轉深 @color-surface-53 |
| 聚焦 Focused | 背景同 Hover + 1px 藍色外框(@color-outline-07);選單開啟中即為此態 |
| 停用 Disabled | 文字與 icon 皆 @color-text-06(隨主題換值),不可點、無 hover |
停用 chip 的互動 Disabled interaction
部分 chip 依同一畫面內其他 chip 的選值停用。兩態差異:
| 啟用 Enabled | 停用 Disabled | |
|---|---|---|
| 外觀 | 4 種變體 × 3 種互動狀態(見上表) | 文字與 icon 皆 @color-text-06(隨主題換值) |
| 點擊 | 開啟選單 | 不可點 |
| hover | 進入 Hover 態 | 無 hover 態;游標 not-allowed |
| tooltip | 無 | 有,須寫出啟用條件 |
| 位置 | 保留 | 保留——不移除、不位移其他 chip |
tooltip 須寫出啟用條件。 條件須為使用者可自行達成、或可理解何時成立者。僅寫「目前不可用」
不符本規格。條件文案由呼叫端提供;prototype 的
This filter is disabled until its condition is met. 為通用示意。
維度不適用時停用,不移除 chip。 同一頁或分頁之內,chip 不因其他 chip 的選值出現或消失 (見 Section 06)。
目前的停用案例 Disabled cases
| # | 情境 | 停用的 chip | 啟用條件 | tooltip 文案 |
|---|---|---|---|---|
| 1 | Message Center — Access 分頁:Access control point 取消 Door、只選 All control panels |
Associated site | 重新選入 Door |
You have deselected the 'Door' option from 'Access control point' filter, resulting in the 'Associated site' filter not affecting your search results |
| 2 | VORTEX AI Hub — Deep search | Scene | 只選定單一 camera | Scene search is supported only when a single camera is selected. |
兩例皆已出貨,條件皆取決於同一畫面內另一個 chip 的選值。
案例 1 的文案為出貨原文,22 字,超出
vortex-voice-and-tone對 tooltip 的 20 字上限, 且未寫出啟用動作,待確認是否修訂。規格側僅有message-center-event-type-views · Filter Access event list by associated sites, 未定義Door/All control panels層級。
單選與多選 Single vs multi-select
- 多選 chip(Sites / Devices / Device type / Event types):選單可連續勾選多項、保持開啟;label 見下表。
- 單選 chip(Statuses / Time / Organization role):點一項即選定並關閉選單;選單內只選、不清除,要清除得用 chip 尾端的「X」。
尺寸與 token(高度 32px、圓角 9999px、字體等)以
filter-combo元件規格與 VORTEX 1.0 token 為準。
已選狀態 label Selected-state label
所有 chip 的 label 以本表為準。數量為 1 用單數。
| Chip | 全空 | 選 1 | 選 N |
|---|---|---|---|
| Sites | Sites |
1 site / 1 area |
site、area 分開計,只列非零:3 areas、1 site, 2 areas(計數見 Section 03) |
| Devices | Devices |
1 device |
{N} devices |
| Cameras | Cameras |
1 camera |
{N} cameras |
| Device type | Device type |
類型名稱,如 Camera |
{N} device types |
| Event types | Event types |
1 event type |
{N} event types(數子事件,見 Section 03) |
| Statuses | Statuses |
選項名稱,如 Online |
— |
| Time | 預設 Last 1 hour |
預設區間名稱;Customized:M/D HH:mm – HH:mm(同日)/ M/D HH:mm – M/D HH:mm |
— |
| Organization role | Organization role |
角色名稱 | — |
清除後回到「全空」欄。
各 chip 的選單
點擊任一 chip 會在其下方展開對應選單。選單的結構依維度而不同,但都遵循同一套開關與選取規則(見 Section 04)。
各維度選單一覽 Menu per dimension
| Chip | 選單結構 | 選取方式 |
|---|---|---|
| Sites | 站點階層樹,含兩態 per-node 勾選、頂部搜尋框;預設收合,命中會自動展開祖先 | 多選(two-state per-node) |
| Devices | 平面清單,每列有裝置類型 icon + 頂部搜尋框;Site 有勾選時在頂部顯示範圍摘要列(如 Within 1 site, 7 areas);標頭顯示「N selected」;攝影機列 hover 顯示即時預覽縮圖 |
多選,無數量上限 |
| Device type | 7 列勾選(類型清單見 Sites Related Pages §04);無搜尋、無標頭 | 多選;選 1 項時 chip 顯示該類型名稱,多選時顯示「N device types」 |
| Statuses | 3 列單選(Online / Offline / Updating);192px 寬 | 單選;選單內只選不清,清除用 chip 的 X |
| Event types | N 個父類別(各可展開子事件)的三態樹,含頂部搜尋框;標頭顯示「N selected」;父類別數量依所在頁面而定,預設全空 | 多選 |
| Time | 4 列單選(Last 1 hour / Last 12 hours / Today / Customized);選 Customized 會改開自訂時間區間 | 單選 |
| Organization role | 單選清單:Admin、Member,其後為全部 Custom roles(含未指派);無搜尋、無標頭 | 單選(Users 頁;頁面預設「All roles」) |
Sites 選單 站點樹
這個站點樹是 filter dropdown 自己的元件,不是 Design Pattern: Tree View。Tree View 是常駐在 Sidemenu 的階層控制面板;此處是點 chip 才展開的下拉選單,兩者是不同元件。本選單的來源是 Device Picker 的站點挑選器(見
filter-combo-demo-design.md的 Sites 列與 Search Behavior 註記),搜尋與勾選規則以本節為準。
filter dropdown 內的站點樹規則:
- 預設收合:只顯示第一層,使用者手動展開才看到子層。
- 無輔助線:不繪製縮排輔助線(indent guides)。
- 多選勾選:採兩態 per-node 語意。
兩態語意:每個節點的勾選只回答一個問題——這個節點自己的直屬裝置要不要納入。沒有半選(indeterminate)狀態,也不儲存父子連動;點父節點只是「向下 cascade」的便利操作。
- 勾選(checked):此節點自己的直屬裝置納入。
- 未勾(unchecked):此節點自己的直屬裝置不納入。這不代表子孫的狀態,每個節點各自判斷。
點擊規則:點有子節點的節點,會把它與所有子孫一起切為勾選 / 取消(對稱 cascade);單獨點某個節點只切換它自己,祖先永不自動勾選或取消。
因為裝置可以直接掛在任一層(不限最末端),兩態讓使用者能精確表達任一組合——例如「只要某兩個子區域、不要上層站點本身」,或反過來「只要站點自己的直屬裝置、不要底下的區域」(勾父站點後再把子區域逐一取消)。
站點計數規則 Site / Area count
chip label 與選單標頭都以「被選取的節點」計數,並區分 site 與 area(VORTEX 的 area 是 site 的子層,要分清「選了整個 site」與「只選了 site 內的某些 area」):
- 數出所有被選取的節點:最上層(site)算一個 site,其餘子層算 area。勾選一個節點會自動帶入它底下所有子節點、一起計入;只勾子層時不會把上層 site 也算進去。
- 只顯示非零的部分、單複數自動調整。chip label 例:
3 areas、1 site, 2 areas、1 site;選單標頭在後面加「 selected」(全空時為0 selected)。
下面用一個假想結構示意 —— Site Alpha 底下有區域 North,North 底下有 N-1、N-2;另有一個底下沒有區域的 Site Beta:
| 操作 | 被選取的節點 | 顯示 |
|---|---|---|
| 勾選區域 North(自動帶入 N-1、N-2) | North、N-1、N-2(3 個 area) | 3 areas selected |
| 承上,再取消 N-2 | North、N-1(2 個 area) | 2 areas selected |
| 只勾 N-1、N-2(不勾 North) | N-1、N-2(2 個 area) | 2 areas selected |
| 勾選整個 Site Alpha | Alpha(site) + North、N-1、N-2 | 1 site, 3 areas selected |
| 勾選底下沒有區域的 Site Beta | Beta(site) | 1 site selected |
Devices 選單 裝置清單
平面清單,每列前面是裝置類型 icon;頂部有搜尋框與「N selected」計數,有搜尋字串時改為「N selected · M results」,M 為 1 時用單數 1 result(命中 0 筆寫 0 results)。
選取數量沒有上限(2026-08-17 決議)。計數刻意只顯示已選數、不顯示範圍內總數:清單是捲動載入(見 Section 05),前端永遠只看到部分資料,總數得由後端另外回傳才拿得到。
Sites 全空時,選單列出全部裝置,頂部沒有範圍摘要列:
範圍摘要列 Scope summary
Devices 選單只列出目前 Site 範圍內的裝置(Sites 全空時列全部;規則見 Section 04 的 Sites → Devices 連動)。因為清單是捲動載入,收斂過的清單和沒收斂的清單長度看起來一樣,少了提示使用者無從得知清單已被限縮——所以 Sites 一有勾選,選單頂部就顯示一列範圍摘要,計數口徑刻意與 Sites chip label 一致(最上層算 site、其餘子層算 area,單複數自動調整),讓 chip 的「1 site, 7 areas」與摘要的「Within 1 site, 7 areas」兩行對得起來:
| Sites 勾選狀態 | 範圍摘要列 |
|---|---|
| 全空 | 不顯示(清單為全部裝置) |
| 勾了 1 個 site,連帶其 7 個 area | Within 1 site, 7 areas |
| 只勾了 3 個 area | Within 3 areas |
勾一個 site 後再開 Devices 選單,頂部出現範圍摘要列、清單已被收斂:
Camera 列 hover 縮圖:滑鼠移到「攝影機類型」的列時,會在游標上方浮現一張 128×80 的即時預覽縮圖,幫助用畫面辨識;非攝影機類型的列不顯示縮圖。
Device type 選單 裝置類型
七列勾選,沒有搜尋框、沒有計數標頭——類型是固定的封閉集合,不需要搜尋,數量也少到不必計數。每列是「勾選框 + 類型 icon + 類型名稱」:
- 多選:可同時勾多個類型,取交集後的結果為「屬於任一勾選類型」的裝置。
- chip label:見 Section 02「已選狀態 label」。
- 此選單不被任何其他 chip 收斂,永遠是完整七列(見 Section 04)。
Statuses 選單 連線狀態
三列單選,寬度 192px,同樣無搜尋、無標頭:
- 單選:點一項即選定並關閉選單。
- 選單內只選不清:要清除已選狀態,用 chip 尾端的「X」,選單內不提供「全部」或取消選項(見 Section 04)。
Event types 選單 事件類別
事件類別以父類別 + 子事件兩層樹呈現,頂部有搜尋框(placeholder「Search events」)、下方是「N selected」標頭。父類別數量與名稱依所在頁面而定(Message Center 為 5 類)。
- 搜尋:與 Sites / Devices 選單同一套規則(輸入 2 個字以上、停頓 300ms 才過濾;命中片段 highlight;命中節點的祖先自動展開;無結果顯示選單內空狀態,見本節「選單內空狀態」)。
搜尋命中時,命中的父類別自動展開、命中片段以 highlight 標示,無關的類別隱藏:
- 三態勾選:父類別為單純分類、本身不帶事件,所以沿用常規三態(全選 / 半選 / 未選)——這與 Sites 選單的兩態不同,因為站點節點可以直接掛裝置、需要區分「自己的直屬裝置」。
- 預設全空:不預設選任何事件類別。
事件計數規則 Event type count
chip label 與選單標頭都數已被選取的子事件(葉節點),勾父類別會連帶把它底下的子事件全部計入:
| 操作 | 顯示 |
|---|---|
| 全空 | 標頭 0 selected;chip 顯示維度名稱 |
| 勾某個父類別(假設底下有 3 個子事件) | 標頭 3 selected;chip 3 event types |
| 只勾 1 個子事件 | 標頭 1 selected;chip 1 event type |
Time 選單 時間
四個預設區間單選;選「Customized」會關閉時間選單、改開自訂時間區間 Customized time frame 彈窗(雙月曆 + 起訖時間 + Apply)。
當目前值已是自訂時間區間時,直接點 Time chip 會跳過四列預設選單、直接回到 Customized time frame 彈窗續行編輯,而非重新從第一層選單開始。
Organization role 選單 Users 頁
Users 頁角色篩選 chip,空值 label「Organization role」。單選:Admin、Member,其後為全部 Custom roles(含未指派者,與其他 chip 一致)。預設「All roles」(不篩選);點選即關閉,清除用 chip 的「X」。選未指派角色 → 空狀態。
來源:OpenSpec
unify-search-filter-tag-ux·module-search-bars。單選:2026-09-10 RD 討論。列全部角色:2026-09-16 會議(ADAT-1018),取代原「只列已指派」。畫面:Figma8736:18839/8736:18848。原型刻意不做此 chip,出圖取 Figma。
選單內空狀態 Empty inside a menu
單行置中短句(13px、@color-text-05、上下內距 32px)。不套用平台的 No Matches Found 元件(插圖 + 標題 + 說明),選單寬度放不下。
| 情況 | 文案 |
|---|---|
| 搜尋無命中;Sites 範圍內為 0 | No matches found |
| 組織內為 0 | No sites yet / No devices yet / No cameras yet |
- 標頭
0 selected位置不動;搜尋框照常顯示。 - 其他選單為固定選項,不會為 0。
各選單的資料載入原則(站點樹逐層載入、裝置清單捲動載入、搜尋結果上限 50)以
filter-combo設計為準。
選取與清除
選取流程 Select
- 點 chip → 在其下方展開選單,chip 進入聚焦態(藍框)。
- 在選單內選值:多選 chip 可連續勾選、選單保持開啟;單選 chip(Statuses / Time)點一項即選定並關閉。
- 選完後 chip 由「空值(淡字 + 箭頭)」變為「有值(一般字 + X)」,label 顯示已選摘要。
預設狀態(工具列已組好,所有 filter 皆為預設、還沒出現 Reset):
清除 Clear
| 操作 | 效果 |
|---|---|
| 點某 chip 尾端的「X」 | 只清除該 chip 的值 |
| 點最右側「Reset」 | 重設所有 chip 回各自預設(多數頁面預設為空,等於清空),並清掉搜尋框 |
| Reset 何時出現 | 當偏離預設的篩選項(chip、或有字的搜尋框,各算一項)達到兩個以上時才出現在最右側;一個以下不顯示 |
關閉選單 Dismissal
- 點 chip 本身(已開啟的那顆)→ 關閉選單。
- 單選 chip(Statuses / Time / Organization role):選一個項目 → 立即關閉(Time 選「Customized」會關閉時間選單、改開自訂時間區間彈窗,見 Section 03)。
- 多選 chip:在選單內部連續選取、捲動、打字都保持開啟;點 chip 本身、或 menu 區域以外的任何地方 → 關閉選單。
- 按 Esc → 關閉選單(若開著自訂時間區間,Esc 會先關整個時間區間,再按一次才關選單)。
結果取 AND 交集;Sites 是 Devices 的範圍 Cross-filter policy
- 每個 chip 都是對結果清單的一個獨立 AND 條件——多個條件同時成立才留下(取交集)。這一層沒有變。
- chip 之間大多互不影響彼此選單裡的選項:開 Device type 永遠是完整 7 類、開 Statuses 永遠是 3 項、Sites 樹永遠是完整內容。
- 唯一的例外是 Sites → Devices。 Sites 不只是一個平行的 AND 條件,它同時定義了 Devices 的可選範圍:Sites 是範圍,Devices 是範圍內的細選。
Sites → Devices 連動 Site-scoped device selection
| # | 規則 |
|---|---|
| R1 | Devices 選單只列出目前 Site 範圍內的裝置;Sites 全空時列出全部。選單頂部以範圍摘要列告知已被限縮(見 Section 03) |
| R2 | Site 勾選一有變動,Devices 已選項目立即全部清空——在改動 site checkbox 的當下就清空,不等選單關閉;是全部清空,不是只移除範圍外的那些 |
| R3 | Devices 為空不代表沒有裝置,而是「該範圍內的全部裝置」 |
| R4 | 單向連動。 Devices 永不反向改動 Sites 的勾選集合,也不反向高亮 |
| R5 | Site chip 的承諾是「勾了就會出現」 |
連動只作用於選單的可選範圍與已選集合,不改變結果清單仍取 AND 交集這件事。
R5 是 R2 存在的唯一理由。 若不清空細選,加勾一個 site 會因為舊細選仍在而毫無反應——使用者勾了 site 卻看不到那個 site 的裝置,那正是「找不到東西」的老問題換個位置發作。
R2 為什麼是全部清空、而不是「聰明地只移除失效的」:保留範圍內的已選,等於承認細選集合可以包含範圍外的 id,那條不變式一破,後續每個情境都要各自定義例外。
清空不給任何提示:不 toast、不確認、不提供 undo。回饋來自 chip 本身——label 從 3 devices 變回 Devices。這是 2026-08-18 用「回饋即時性」換來的已知取捨。
驗收條件 QA · Given-When-Then
- Given 在選單內選值,Then chip 由空值態變為有值態、label 顯示摘要。
- Given 有兩個以上篩選項(chip 或有字的搜尋框)偏離預設,Then 最右側出現 Reset;只有一個時不出現。
- Given 點某 chip 的 X,Then 只清該 chip、其餘不動。
- Given 點 Reset,Then 所有 chip 回預設、搜尋框清空、Reset 消失。
- Given 點選單與其 chip 以外之處(或按 Esc),Then 關閉選單。
- Given 已選 Device type,Then Devices 選單仍顯示完整裝置清單(不被 Device type 縮限)。Device type 不收斂任何選單;會收斂 Devices 選單的只有 Sites。(此條原為「禁止任何 chip 收斂選單」的全面版本,2026-08-17 決議要求移除;此處改為僅針對 Device type 的個案而非刪除,因為 Device type 的舊政策本身並未改變,失效的只是那個全稱斷言。)
- Given Sites 已勾 1 個 site,Then Devices 選單只列出該範圍內的裝置,且頂部顯示範圍摘要列「Within 1 site…」(R1)。
- Given Sites 全空,Then Devices 選單列出全部裝置、不顯示範圍摘要列(R1)。
- Given 已選 3 台 device,When 改動任一 site checkbox,Then Devices 已選項目在當下立即全部清空、chip label 回到「Devices」,且不出現 toast 或 undo(R2)。
- Given 已選 device,Then Sites 樹的勾選集合完全不受影響(R4)。
搜尋、觸發與結果
這一節說明使用者操作工具列後,清單如何更新。以 filter-combo-pages(關閉選單即套用)版本為準。
搜尋 Search
- 搜尋範圍逐頁而定。有的清單只搜單一欄位,也有分頁完全沒有搜尋框。各頁的實際範圍以 Sites Related Pages 各頁章節為準,此處不重述。
- 輸入 2 個字以上、停頓 300ms 才觸發;1 個字不觸發。
- 不分大小寫。結果清單不做命中 highlight(highlight 只在選單內)。
- 點 X 立即清除;若已有生效的搜尋(2 個字以上),則重新載入。
選單內的搜尋框(Sites / Devices / Event types,見 Section 03)沿用同一套輸入規則:2 個字以上、停頓 300ms 才過濾,不分大小寫。差別是它只過濾選單內的選項、不觸發清單重新載入,且命中片段會 highlight;樹狀選單(Sites / Event types)還會自動展開命中節點的祖先,無結果時在選單內顯示空狀態。
選單內的空狀態與本節下方「結果與載入」的空狀態是兩套不同規格,不可互換。 選單內是單行置中 短句(文案見 Section 03);頁面清單才是平台的
No Matches Found元件(插圖 + 標題 + 說明)。 選單內的No matches found與它字面相近,版面不同。選單雖有樹狀的(Sites / Event types),也不因此改用樹的空狀態版面。
觸發來源 Trigger sources
| 來源 | 觸發時機 |
|---|---|
| 搜尋框輸入 | 停頓 300ms、且長度 ≥ 2 字 |
| 搜尋框清除(X) | 立即,僅當已有生效的搜尋(2 個字以上) |
| 關閉某 chip 選單 | 僅當這次「開→關」期間值有淨變化,或這次開選單期間清空過 Devices 細選才觸發 |
| chip 尾端 X / Reset | 立即 |
| 點欄位排序標頭(Device name) | 立即(先切換升 / 降冪箭頭) |
| 切換頁面(左側導覽) | 立即,且會先把目的頁的篩選重設為預設 |
淨變化為零仍可能觸發:在 Sites 選單勾了又取消、值回到原狀,但 R2 已即時清空 Devices 細選(見 Section 04)。若只看淨變化就不會重查,清單會停在還帶著細選的舊內容。
觸發後的流程 Pipeline
每次觸發都走同一條流程:
- 進入載入態。
- 等待資料回來(示範中為 0.8–1.5 秒)。
- 以所有條件的 AND 交集 算出結果。
- 顯示結果列,或在無交集時顯示空狀態。
載入期間工具列仍可操作;若載入未完又觸發新的一次,會取消前一次、以新觸發重跑。
結果狀態(裝置清單預設以 device name 排序,見下方「結果與載入」):
無任何交集時的空狀態:
結果與載入 Result & lazy load
- 初次載入:進入頁面時多數 filter 預設為空(Time 等少數例外見 Section 01),但仍會跑同一條流程載入一批預設資料,因此畫面不會空白。
- 預設排序的原則:各清單依自身最自然的識別方式排序,不再一律 location first。site 只作為篩選條件存在——訊息記錄本身沒有 site 識別、後端亦無 API 可解析。各頁的實際排序鍵見 Sites Related Pages 各頁章節,此處不重述。
prototype 已於 2026-09-02 同步:Devices 頁的預設排序改為 device name,可排序欄位一併從 Site 移到 Device name(三個 filter combo pages 變體全部更新)。site 仍是欄位與篩選維度,只是不再是排序鍵。
- 捲動載入:一次先顯示 50 筆;捲到接近底部時顯示 spinner,再載入下一批 50 筆。
- 空狀態:顯示
No Matches Found空狀態,文案與版面見 Design Pattern: Tree View §04。
驗收條件 QA · Given-When-Then
- Given 在搜尋框輸入 2 字以上並停頓,Then 觸發載入並顯示交集結果。
- Given 只輸入 1 個字,Then 不觸發。
- Given 改了某 chip 的值後關閉其選單,Then 觸發載入;未改值且未清空過細選就關閉則不觸發。
- Given 在 Sites 選單裡勾了又取消(淨變化為零)、但 Devices 細選已被清空,When 關閉選單,Then 仍觸發載入。
- Given 多個條件同時成立,Then 結果為各條件的 AND 交集。
- Given 交集為空,Then 顯示「No Matches Found」空狀態。
- Given 結果超過 50 筆,Then 先顯示 50 筆、捲動到底再載入下一批。
- Given 進入裝置清單,Then 預設以 device name 排序;Given 進入 Device / System 事件清單,Then 預設以 client time 排序(Access / Sensor / Archive 另有預設,見 Section 06)。
使用場景
同一套工具列,不同頁面組不同的 chip。以下是四個主要模組的組合。細節以 OpenSpec unify-search-filter-tag-ux 為準,此處只帶高層次。
Devices 依裝置類型分頁
- 頂部分頁:七個裝置類型各自有專屬欄位集;分頁清單、欄位集與欄位可設定性均以 Sites Related Pages §04 為準。
- 工具列:Search(範圍見 Sites Related Pages 的 Devices 章節) + Statuses(單選) + Sites(多選樹)。各分頁工具列一致,含 Unknown。
- 預設排序:sort by device name。
Message Center 依事件類型分頁
- 頂部分頁:Device / System / Access / Sensor,各自有專屬欄位與篩選維度。
- 工具列:Search(System 分頁無搜尋框;各分頁範圍見 Sites Related Pages 的 Message Center 章節) + Sites + Cameras(攝影機專用變體) + Event types + Time(預設值見該章節)。
- Sites 與 Cameras 為連動關係:Sites 定義範圍、Cameras 是範圍內的細選,不是兩個平等的 AND 條件(見 Section 04)。
- 預設排序:Device / System 事件依 client time;Access 事件依 access control point;Sensor 事件依 sensor 名稱。Device / System 事件不以 site 排序——訊息記錄本身沒有 site 識別,site 只作為篩選存在。
Archive 封存清單
- 工具列:Search(範圍見 Sites Related Pages 的 Archive 章節) + 依 site、device、date of footage 篩選。
- site 與 device 為連動關係:site 定義範圍、device 是範圍內的細選(見 Section 04)。
- 預設排序:依 date of archived。
Users 使用者清單
- 工具列:Search(範圍見 Sites Related Pages 的 Users 章節) + Organization role 篩選 chip,構成 filter combo。此頁的 chip 組成以該章節為準。
一致性原則 Consistency
| 面向 | 一致做法 |
|---|---|
| 搜尋 | 搜尋框一律放在工具列最左、輸入規則一致(2 字 + 300ms);但搜尋範圍逐頁而定(見 Section 05) |
| 預設排序 | 原則為「各清單依自身最自然的識別方式」,不再一律 location first;各頁排序鍵見 Sites Related Pages |
| 欄位 | 各頁的欄位集與可顯示 / 隱藏規則見 Sites Related Pages |
| 篩選 | 站點(Sites)篩選在裝置 / 事件 / Archive 清單可用;Users 清單無(只有 Organization role) |
| Sites 的雙重角色 | 在同時有 Devices / Cameras chip 的頁面上,Sites 不只是一個篩選條件,同時定義該 chip 的可選範圍(見 Section 04)。適用於 Message Center、Archive、AI Hub |
| chip 組成的穩定性 | 跨頁面可以不同,同一個頁面或分頁之內不可跳動。 進入某個頁面或分頁後,chip 不因其他 chip 的選值而出現或消失;維度在當下不適用時停用、不移除,並在 tooltip 寫出啟用條件(見 Section 02) |
為什麼不用「移除」表達不適用。 chip 時有時無會讓工具列在使用者眼前重組、後面的 chip 位置位移,且使用者無從得知該維度曾經存在。停用保留位置與可見性,並說明何時可用。
不適用於頁面與分頁之間的組成差異:Users 清單無 Site filter、Message Center 的 System 分頁無搜尋框、四個事件分頁各有專屬篩選維度,皆為組成不同,非同一頁內跳動。 Devices 各類型分頁的工具列一致,含 Unknown。
適用範圍的來源註記:Message Center(ADAT-799)與 Archive(ADAT-802)已實作落地;AI Hub 是 2026-08-31 由 UX 口頭確認納入,尚無書面裁決或實作依據。連動適用範圍在
filter-combo-decision-history.md仍列為待 PM/設計端書面裁決的開放項,AI Hub 另有一點需注意:該頁的篩選觸發採 Apply 按鈕,與本 deck 通篇的「關閉選單即套用」前提不同,連動在該頁的觸發時機需另行確認。
各模組的完整欄位集、篩選維度與行為以 OpenSpec 為準:
unify-search-filter-tag-ux(device-type-list-views / message-center-event-type-views / archive-list-view / module-search-bars),此處不逐一重列。