make-app-filter

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

make-app-filter

make-app-filter

Use this skill for Make App filtering. A keyword-search-only list that sends
filter.expression
uses the package compiler without enabling advanced filtering. Desktop/tablet lists that use advanced filters, condition builders, table filtering, or CanvasTable header "按该字段筛选" deliver one integrated feature:
  • package-backed toolbar advanced filter using
    @qfei-design/make-app-filter
  • host-owned CanvasTable header filter UI/menu
  • linkage from header "按该字段筛选" to the same package controller and toolbar panel
  • Entity Preset advanced-filter save, load, hydration, and clear behavior
  • Service
    filter.expression
    payload integration
When advanced filtering is in scope, phones use the same package controller, Preset and Service
filter.expression
, but expose only the medium-sized filter trigger in the compact phone toolbar and
AdvancedFilterPanel layout="mobile"
in
MobileFilterSheet
from
@qfei-design/make-app-mobile/primitives
. Phone Select controls use
MobileFilterSelect
from its
/pickers
entry; keep desktop/tablet controls on the existing UI library. 手机顶部筛选不需要 CanvasTable 表头联动,也不得挂载隐藏 CanvasTable 来满足桌面合同。
On desktop/tablet, do not implement only advanced filter or only header filter in Make record-list pages. They must be done together or not done.
This skill owns the consumer-side package integration contract, advanced-filter behavior, field support, Entity Preset filter persistence, Service filter payload shape, host-owned header-linkage semantics, URL/deep-link filter echo, and filter-specific tests. It consumes list-access state from
make-app-permission
; it does not define permission policy. It does not own sorting (
make-app-sort
), grouping (
make-app-group
), page shell/layout (
makeui
), CanvasTable rendering internals or header menu API details (
canvas-table-integration
), Service route implementation (
make-app-service
), auth (
make-app-auth
), runtime packaging (
make-app-runtime
), DSL modeling (
makedsl
), or Make CLI execution (
makecli
).
本技能用于 Make App 的筛选场景。仅发送
filter.expression
的关键词搜索列表使用包的编译器能力,不启用高级筛选。使用高级筛选、条件构建器、表格筛选或 CanvasTable 表头「按该字段筛选」的桌面/平板端列表,提供以下一体化能力:
  • 基于
    @qfei-design/make-app-filter
    包实现的工具栏高级筛选
  • 宿主侧自研的 CanvasTable 表头筛选 UI/菜单
  • 表头「按该字段筛选」与同一包控制器和工具栏面板的联动
  • 实体预设(Entity Preset)的高级筛选保存、加载、hydration 和清除行为
  • Service
    filter.expression
    载荷集成
当涉及高级筛选时,移动端使用相同的包控制器、预设和 Service
filter.expression
,但仅在紧凑的手机工具栏中展示中等尺寸的筛选触发器,并在
@qfei-design/make-app-mobile/primitives
提供的
MobileFilterSheet
中使用
AdvancedFilterPanel layout="mobile"
。移动端的 Select 控件使用其
/pickers
入口导出的
MobileFilterSelect
;桌面/平板端控件继续使用现有 UI 库。手机顶部筛选不需要 CanvasTable 表头联动,也不得挂载隐藏 CanvasTable 来满足桌面端约定。
在桌面/平板端,Make 记录列表页面不得只实现高级筛选或只实现表头筛选,二者必须同时实现或都不实现。
本技能负责消费侧的包集成约定、高级筛选行为、字段支持、实体预设筛选持久化、Service 筛选载荷格式、宿主侧表头联动语义、URL/深度链接筛选回显,以及筛选相关的测试。它依赖
make-app-permission
提供的列表访问状态;不定义权限策略。本技能不负责排序(
make-app-sort
)、分组(
make-app-group
)、页面外壳/布局(
makeui
)、CanvasTable 渲染内部逻辑或表头菜单 API 细节(
canvas-table-integration
)、Service 路由实现(
make-app-service
)、鉴权(
make-app-auth
)、运行时打包(
make-app-runtime
)、DSL 建模(
makedsl
)或 Make CLI 执行(
makecli
)。

Capability modes

能力模式

Choose the mode before following the workflow. Panel, controller, filter Preset and mobile-layout requirements below apply only to
advanced-filter
unless explicitly stated otherwise.
ModeQueryFilter PresetUI and package gate
search-only
compileListFilter({ fields, searchText })
no filter Preset GET/PATCH or hydrationno controller, panel, or mobile layout gate; use the package core compiler
advanced-filter
compileListFilter({ fields, searchText, advancedFilter })
GET/hydrate before the first records query; PATCH the filter dimension only after confirmationpackage controller and panel; phone requires public
layout="mobile"
search-only
does not load or apply a saved advanced-filter expression behind an absent filter UI. If sorting or grouping independently requires a shared Entity Preset, its own coordinator may still load that Preset; this Skill does not consume its
filter
dimension until advanced filtering is enabled. Both modes still obey the list-access gate and send the package compiler result unchanged to Service.
请在遵循工作流之前选择模式。以下面板、控制器、筛选预设和移动端布局要求仅适用于
advanced-filter
模式,除非另有明确说明。
模式查询方式筛选预设UI 和包准入
search-only
compileListFilter({ fields, searchText })
无筛选预设的 GET/PATCH 或 hydration无控制器、面板或移动端布局准入;使用包核心编译器
advanced-filter
compileListFilter({ fields, searchText, advancedFilter })
首次记录查询前 GET/hydration;仅在确认后 PATCH 筛选维度包控制器和面板;移动端需要公开的
layout="mobile"
search-only
模式不会在无筛选 UI 的情况下,后台加载或应用已保存的高级筛选表达式。如果排序或分组独立需要共享的实体预设,其自身的协调器仍可加载该预设;本技能在启用高级筛选之前不会消费其
filter
维度。两种模式都需遵守列表访问准入规则,并将包编译器的结果原样发送给 Service。

Quick start

快速开始

  1. Treat any Make record-list request containing "筛选", "高级筛选", "条件筛选", "表格筛选", "表头筛选", "列头筛选", or "按字段筛选" as the same filtering requirement. Desktop/tablet implement both the package-backed toolbar advanced filter and CanvasTable header linkage. Phone uses the package-backed top filter entry without CanvasTable/header linkage.
  2. Locate the host UI package, usually
    apps/ui/package.json
    . If no UI package exists, stop and report the missing host package.
  3. Ensure
    @qfei-design/make-app-filter@^1.0.0
    is installed for compiler-only or desktop/tablet use. Phone advanced filtering uses
    @qfei-design/make-app-filter@^1.1.0
    together with
    @qfei-design/make-app-mobile@^0.1.11
    , after the host compatibility gate. The former supplies 32px
    middle
    controls and mobile-scoped control classes; the latter supplies
    MobileFilterSheet
    ,
    MobileFilterSelect
    , and date-trigger
    className
    . Check the resolved filter package's public React declaration for the
    "mobile"
    layout; earlier filter 1.0.0–1.0.3 lack it. Search-only phone lists need only the public core compiler, without either mobile panel gate. Do not substitute default/stacked layout or hand-write package internals.
  4. Read package docs before designing code. Prefer installed package docs; if the host is working in the package repo, read source docs.
  5. In advanced-filter mode, import
    @qfei-design/make-app-filter/styles.css
    once in the host UI entry; search-only compiler use does not need panel styles.
  6. Both modes use the package core compiler. Advanced-filter mode additionally uses package panel, controller, adapter, validation, and CEL parse APIs. Do not copy or hand-write these capabilities in the host.
  7. In advanced-filter mode, keep presentation-specific toolbar trigger, desktop Popover or phone
    MobileFilterSheet
    , applied state, candidate APIs, Service request adapter, and desktop/tablet CanvasTable header filter UI/menu in the host. The phone panel passes
    layout="mobile"
    and receives a mobile-only component adapter using
    MobileFilterSelect
    ; the package Sheet owns the height and scroll boundary. Search-only has no panel surface.
  8. On desktop/tablet, wire header "按该字段筛选" to the same package controller/panel; do not create separate header-only state or a local filter implementation. Phone has no header entry.
  9. Align with the backend Record list filter contract: Service sends
    filter: { expression }
    , blank expressions mean no filter, and field support must match runtime metadata plus package public APIs. Submit
    compileListFilter
    output unchanged; never rewrite CEL/DNF in the host.
  10. For entity object lists, consume the list-access gate from
    make-app-permission
    . Only when advanced filtering is enabled and list access is allowed, load the current Entity Preset before the first records query and hydrate the saved filter through package public APIs using a permission-aware
    { enabled, entityKey, generation }
    context. Search-only does not load or hydrate the filter Preset, and toolbar search remains session-only.
  11. On filter confirm, PATCH only the Preset
    filter
    dimension. After success, update applied state synchronously; let the records query react to applied state instead of reloading inside the persistence callback. Preserve the old applied filter and current draft on failure.
  12. When the writable list uses
    make-app-actions
    , hand off the successfully applied filter generation so actions clear selection and invalidate pending precheck/submit work before the new query is actionable. Draft edits, cancel, and save/apply failure preserve the current action selection.
  13. In advanced-filter mode, preserve the required fixed three-region layout: top fixed header, scrollable condition body, and bottom fixed footer. Header/footer controls must remain visible while condition rows scroll.
  14. Before finishing, verify package compilation, empty filter omission, Service payload shape and list-access behavior in both modes. For search-only, verify no filter Preset GET/PATCH, hydration, panel or mobile-layout gate. For advanced filtering, also verify fixed panel layout, search merge, Preset save/load/clear, draft confirm/discard, candidates, desktop/tablet header linkage, phone no-CanvasTable behavior, nested picker stacking, 32px panel controls, selected-value echo during remote search, package/backend field-support drift and conditional action-selection invalidation.
  1. 任何包含「筛选」、「高级筛选」、「条件筛选」、「表格筛选」、「表头筛选」、「列头筛选」或「按字段筛选」的 Make 记录列表需求,都视为同一类筛选需求。桌面/平板端需同时实现基于包的工具栏高级筛选和 CanvasTable 表头联动;移动端使用基于包的顶部筛选入口,无需 CanvasTable/表头联动。
  2. 找到宿主 UI 包,通常为
    apps/ui/package.json
    。如果不存在 UI 包,停止并上报宿主包缺失问题。
  3. 确保已安装
    @qfei-design/make-app-filter@^1.0.0
    ,用于仅编译器场景或桌面/平板端使用。移动端高级筛选需在宿主兼容性准入通过后,搭配使用
    @qfei-design/make-app-filter@^1.1.0
    和
    @qfei-design/make-app-mobile@^0.1.11
    。前者提供 32px 的
    middle
    尺寸控件和移动端作用域的控件类;后者提供
    MobileFilterSheet
    、
    MobileFilterSelect
    和日期触发器的
    className
    。请检查已解析的筛选包的公开 React 声明中是否包含
    "mobile"
    布局;早期的 1.0.0–1.0.3 版本不支持该布局。仅搜索模式的移动端列表仅需要公开的核心编译器,无需移动端面板准入。不得使用默认/堆叠布局替代,也不得手写包内部逻辑。
  4. 设计代码前请先阅读包文档。优先使用已安装的包文档;如果宿主在包仓库内开发,请阅读源码文档。
  5. 在高级筛选模式下,在宿主 UI 入口处一次性导入
    @qfei-design/make-app-filter/styles.css
    ;仅搜索模式的编译器使用不需要面板样式。
  6. 两种模式都使用包的核心编译器。高级筛选模式额外使用包的面板、控制器、适配器、校验和 CEL 解析 API。不得在宿主中复制或手写这些能力。
  7. 在高级筛选模式下,将展示层相关的工具栏触发器、桌面端 Popover 或移动端
    MobileFilterSheet
    、应用状态、候选值 API、Service 请求适配器,以及桌面/平板端 CanvasTable 表头筛选 UI/菜单保留在宿主侧。移动端面板传入
    layout="mobile"
    ,并接收使用
    MobileFilterSelect
    的移动端专属组件适配器;包提供的 Sheet 负责高度和滚动边界。仅搜索模式无面板界面。
  8. 在桌面/平板端,将表头「按该字段筛选」绑定到同一包控制器/面板;不得创建单独的表头专属状态或本地筛选实现。移动端无表头入口。
  9. 与后端记录列表筛选约定对齐:Service 发送
    filter: { expression }
    ,空表达式表示无筛选,字段支持必须与运行时元数据和包公开 API 匹配。原样提交
    compileListFilter
    的输出;绝不在宿主中重写 CEL/DNF。
  10. 对于实体对象列表,消费
    make-app-permission
    提供的列表访问准入。仅当启用高级筛选且允许列表访问时,在首次记录查询前加载当前实体预设,并通过包公开 API 使用支持权限感知的
    { enabled, entityKey, generation }
    上下文对已保存的筛选进行 hydration。仅搜索模式不加载或 hydration 筛选预设,工具栏搜索仅在会话内有效。
  11. 筛选确认时,仅 PATCH 预设的
    filter
    维度。成功后同步更新应用状态;让记录查询响应应用状态的变化,而不是在持久化回调内重新加载。失败时保留旧的已应用筛选和当前草稿。
  12. 当可写列表使用
    make-app-actions
    时,传递成功应用的筛选版本号,以便操作在新查询生效前清除选中项并作废待处理的预检查/提交工作。草稿编辑、取消和保存/应用失败时保留当前操作选中项。
  13. 在高级筛选模式下,保留要求的固定三区域布局:顶部固定表头、可滚动条件主体、底部固定页脚。条件行滚动时,表头/页脚控件必须保持可见。
  14. 完成前,验证两种模式下的包编译、空筛选省略、Service 载荷格式和列表访问行为。对于仅搜索模式,验证无筛选预设的 GET/PATCH、hydration、面板或移动端布局准入。对于高级筛选,还需验证固定面板布局、搜索合并、预设保存/加载/清除、草稿确认/丢弃、候选值、桌面/平板端表头联动、移动端无 CanvasTable 行为、嵌套选择器堆叠、32px 面板控件、远程搜索时的选中值回显、包/后端字段支持差异,以及条件性操作选中项作废逻辑。

Package pre-flight

包前置检查

New Make Apps and Apps undergoing an explicit runtime migration use the
make-app-runtime
runtime contract: the workspace root declares
"packageManager": "pnpm@10.20.0"
plus
"engines": { "node": "22.20.0", "pnpm": "10.20.0" }
, and package operations run through
corepack pnpm
. For those Apps, install the dependency in the actual UI package, for example
corepack pnpm add @qfei-design/make-app-filter@^1.0.0
from its directory; a new App with no lockfile first needs the runtime declaration and a generated pnpm workspace.
Existing Make Apps retain their declared runtime during filter work. Before installing or upgrading, locate the UI package and workspace root, inspect
packageManager
, Node engines, React/React DOM peers, the existing lockfile, and the repository's established install/CI workflow. Use the matching existing manager and workspace target:
  • pnpm-lock.yaml
    with a compatible pnpm declaration/workflow: use that project's declared pnpm version through Corepack to add
    @qfei-design/make-app-filter@^1.0.0
    to the UI package.
  • package-lock.json
    with a compatible npm declaration/workflow: use the existing npm workspace install command targeting the UI package, or install from that package directory if the repository is not a workspace.
  • yarn.lock
    with a compatible Yarn declaration/workflow: use the existing Yarn workspace add command targeting the UI package, or add from that package directory if the repository is not a workspace. Preserve the project's Yarn version and configuration.
Do not rewrite an existing App's
packageManager
, Node selection, workspace layout, or lockfile type merely to add filtering. Never generate a second lockfile. If the declaration, lockfile, CI workflow, Node/peer constraints, or target workspace conflict—or an existing App has no unambiguous install workflow—stop and report a compatibility blocker to
make-app-runtime
; do not silently migrate it or force
corepack pnpm
into an npm/Yarn project. The phone filter package upgrade follows the same gate.
For phone advanced filtering, use that same existing manager and target UI package to install
@qfei-design/make-app-filter@^1.1.0
and
@qfei-design/make-app-mobile@^0.1.11
together. The
^1.0.0
examples above remain the general compiler/desktop baseline. Check the versions actually resolved by the lockfile; a declared range alone is not proof that both phone capabilities are installed.
Migrate any retired pre-1.0 package dependency to
@qfei-design/make-app-filter@^1.0.0
and update public imports together. If an unrelated advanced-filter package is already used, stop and ask before replacing it. Do not fall back to a pre-1.0 release.
Required read procedure for installed
1.0.0+
packages:
  1. node_modules/@qfei-design/make-app-filter/package.ai.json
  2. Parse
    package.ai.json.readOrder
    and resolve every entry relative to
    node_modules/@qfei-design/make-app-filter
    .
  3. Verify each referenced file exists in the installed package before relying on it.
  4. Read the remaining entries in the declared order, skipping the already-read
    package.ai.json
    entry.
package.ai.json.readOrder
is the source of truth. Do not hardcode
docs/
,
examples/
, or other package-internal documentation paths. When working directly in the package repo, resolve the same entries from the repository root. If the installed package is older than
1.0.0
, upgrade first instead of relying on older package docs or inferred internals.
新的 Make App 和正在进行显式运行时迁移的 App 使用
make-app-runtime
运行时约定:工作区根目录声明
"packageManager": "pnpm@10.20.0"
以及
"engines": { "node": "22.20.0", "pnpm": "10.20.0" }
,包操作通过
corepack pnpm
执行。对于这类 App,在实际的 UI 包中安装依赖,例如在其目录下执行
corepack pnpm add @qfei-design/make-app-filter@^1.0.0
;没有 lockfile 的新 App 首先需要运行时声明和生成的 pnpm 工作区。
现有 Make App 在筛选开发期间保留其声明的运行时。安装或升级前,找到 UI 包和工作区根目录,检查
packageManager
、Node 引擎、React/React DOM peer 依赖、现有 lockfile,以及仓库已建立的安装/CI 工作流。使用匹配的现有包管理器和工作区目标:
  • 带有兼容 pnpm 声明/工作流的
    pnpm-lock.yaml
    :通过 Corepack 使用项目声明的 pnpm 版本,将
    @qfei-design/make-app-filter@^1.0.0
    添加到 UI 包。
  • 带有兼容 npm 声明/工作流的
    package-lock.json
    :使用针对 UI 包的现有 npm 工作区安装命令,如果仓库不是工作区则从该包目录安装。
  • 带有兼容 Yarn 声明/工作流的
    yarn.lock
    :使用针对 UI 包的现有 Yarn 工作区 add 命令,如果仓库不是工作区则从该包目录添加。保留项目的 Yarn 版本和配置。
不得仅仅为了添加筛选功能就重写现有 App 的
packageManager
、Node 选择、工作区布局或 lockfile 类型。绝不能生成第二个 lockfile。如果声明、lockfile、CI 工作流、Node/peer 约束或目标工作区存在冲突——或者现有 App 没有明确的安装工作流——停止并向
make-app-runtime
上报兼容性阻塞问题;不得静默迁移或强制将
corepack pnpm
引入 npm/Yarn 项目。移动端筛选包升级遵循相同的准入规则。
对于移动端高级筛选,使用相同的现有包管理器和目标 UI 包,同时安装
@qfei-design/make-app-filter@^1.1.0
和
@qfei-design/make-app-mobile@^0.1.11
。上述
^1.0.0
示例仍是通用编译器/桌面端的基线版本。请检查 lockfile 实际解析的版本;仅声明版本范围不能证明两个移动端能力都已安装。
将任何已停用的 1.0 之前的包依赖迁移到
@qfei-design/make-app-filter@^1.0.0
,并同时更新公开导入。如果已经使用了不相关的高级筛选包,停止并在替换前询问。不得回退到 1.0 之前的版本。
已安装的
1.0.0+
版本包的必读流程:
  1. 读取
    node_modules/@qfei-design/make-app-filter/package.ai.json
  2. 解析
    package.ai.json.readOrder
    ,并相对于
    node_modules/@qfei-design/make-app-filter
    解析每个条目
  3. 在依赖每个引用的文件之前,验证其是否存在于已安装的包中
  4. 按声明的顺序读取其余条目,跳过已读取的
    package.ai.json
    条目
package.ai.json.readOrder
是唯一可信来源。不得硬编码
docs/
、
examples/
或其他包内部文档路径。直接在包仓库中开发时,从仓库根目录解析相同的条目。如果已安装的包版本低于
1.0.0
,请先升级,而不是依赖旧的包文档或推断的内部逻辑。

Topic reference map

主题参考映射

Task / topicRead
Keyword search through
filter.expression
without advanced filtering
references/service-translation.md
; use the compiler-only path in
references/filter-model.md
Package install, imports, host/package boundary
references/package-integration.md
Filter IR, controller draft/confirm semantics, search merge, URL echo
references/filter-model.md
Runtime field capability, operator/value-editor APIs, and candidate values
references/operator-matrix.md
Host Popover/container, trigger, panel sizing, validation visuals
references/ui-style.md
CanvasTable header more menu and advanced filter linkage
references/header-table-linkage.md
Service filter contract and CEL expression payload
references/service-translation.md
Advanced-filter Entity Preset load, hydration, save barrier, clear, stale requests
references/preset-integration.md
Tests, smoke checks, common regressions
references/testing-and-pitfalls.md
Backend Record filter contract, CEL subset, DateRange/File/Lookup/system variablesUse
makedsl
; read its EntityDataFilterUsage reference
Group path expression composition and record-groups
groupFilter
Use
make-app-group
; reuse this Skill's DNF expression rules
Toolbar placement and surrounding page layoutUse
makeui
CanvasTable
suffixRender
mechanics
Use
canvas-table-integration
Service route implementation and adapter testsUse
make-app-service
Writable-list selection actions and applied-query invalidationUse
make-app-actions
任务 / 主题阅读内容
无高级筛选、通过
filter.expression
实现的关键词搜索
references/service-translation.md
;使用
references/filter-model.md
中的仅编译器路径
包安装、导入、宿主/包边界
references/package-integration.md
筛选 IR、控制器草稿/确认语义、搜索合并、URL 回显
references/filter-model.md
运行时字段能力、运算符/值编辑器 API、候选值
references/operator-matrix.md
宿主 Popover/容器、触发器、面板尺寸、校验视觉效果
references/ui-style.md
CanvasTable 表头更多菜单与高级筛选联动
references/header-table-linkage.md
Service 筛选约定与 CEL 表达式载荷
references/service-translation.md
高级筛选实体预设加载、hydration、保存屏障、清除、过期请求
references/preset-integration.md
测试、冒烟检查、常见回归问题
references/testing-and-pitfalls.md
后端记录筛选约定、CEL 子集、DateRange/File/Lookup/系统变量使用
makedsl
;阅读其 EntityDataFilterUsage 参考
分组路径表达式组合与 record-groups 的
groupFilter
使用
make-app-group
;复用本技能的 DNF 表达式规则
工具栏位置与周边页面布局使用
makeui
CanvasTable
suffixRender
机制
使用
canvas-table-integration
Service 路由实现与适配器测试使用
make-app-service
可写列表选中操作与应用查询作废使用
make-app-actions

Hard rules

硬性规则

  • Do not create new Make advanced-filter implementations in host apps. No hand-written Filter IR helpers, operator matrix, validator, CEL compiler/parser, or advanced filter panel when the package provides it.
  • Do not deliver advanced filtering partially. Both modes use the package compiler and Service expression payload; advanced-filter mode additionally uses the package controller. Desktop/tablet advanced filtering implements CanvasTable header UI and linkage. Phone advanced filtering uses only its top toolbar filter entry and mobile-safe panel; it does not require or render CanvasTable header linkage.
  • Phone advanced filtering requires the public
    "mobile"
    panel layout,
    MobileFilterSheet
    ,
    MobileFilterSelect
    , and
    AdvancedFilterPanel layout="mobile"
    at the resolved versions above. A desktop Popover on a narrow viewport,
    layout="default"
    , or CSS-shrinking its condition rows is not mobile adaptation. Keep desktop/tablet Popover wiring and layout rules, then check their rendered controls after the shared filter package upgrade. Search-only does not require the mobile panel layout or mobile package filter components.
  • New integrations use the core API from
    @qfei-design/make-app-filter
    ; advanced-filter integrations additionally use
    @qfei-design/make-app-filter/react
    and optional
    @qfei-design/make-app-filter/adapters/antd
    .
  • Advanced-filter integrations import
    @qfei-design/make-app-filter/styles.css
    once. Search-only compiler use does not require panel styles. Host CSS may style the outer overlay/container, but must not fork package internals unless fixing a host-specific containment issue.
  • New filter output uses
    filter: { expression: string }
    . If
    compileListFilter
    returns
    undefined
    , omit
    filter
    .
  • compileListFilter
    is the only host-facing search/advanced-filter compiler. Send its result unchanged; do not parse, redistribute, or rewrite CEL/DNF in host code.
  • The backend Record list handler reads only
    filter.expression
    from the
    Expression
    object and treats missing,
    null
    , or blank expressions as no filter.
  • Do not send
    filter: []
    ,
    filter: {}
    ,
    { expression: "" }
    , blank raw filter strings, or old object-array DSL.
  • Do not filter Make record lists locally. List filtering goes through Service/backend filter APIs.
  • Filter fields come from normalized runtime object/field metadata. Do not read
    apps/dsl/**
    , copied YAML, row samples, or hardcoded demo data as runtime filter metadata.
  • A host field-type registry may help normalize shared runtime metadata, but it must not decide filter operators or value editors. Pass fields to the package and use its capability APIs as the filter source of truth.
  • For Lookup filtering, resolve
    relationKey
    , the opposite Entity, and
    targetFieldKey
    from the complete runtime schema before passing field metadata to the package. Keep the source Lookup field key in Filter IR and CEL expressions; target field metadata only controls operators, values, and validation.
  • User and department filter values are identities, not display names. Candidate sources come from the host contract owned by
    makeui
    /
    make-app-service
    ; do not define transport routes in this Skill.
  • Do not source user/department options from field schema
    options
    , current table rows, local arrays, or display labels. Current applied values may be merged only to keep labels visible while remote candidates load.
  • Backend Record filters support DateRange, File, and Lookup semantics, but the UI may expose a field only when
    @qfei-design/make-app-filter
    public APIs support that field/operator combination. If backend docs and package capabilities differ, stop to upgrade/fix the package or report the mismatch; do not hand-write CEL or guess package internals.
  • In advanced-filter mode, on every entity or permission-enabled context change, increment a monotonic request generation and reset the host panel state. Comparing only
    entityKey
    when a save settles is unsafe because an old
    A -> B -> A
    result or a result from before access revocation can look current. Search-only still invalidates stale record-query responses without creating panel state.
  • In advanced-filter mode, use a committed-context reset such as a keyed wrapper plus layout-effect cleanup. Do not mutate request-generation, saving, or context refs during React render.
  • In advanced-filter mode, if saved CEL is unsupported by the current package, keep its raw expression active in backend requests, keep the trigger visibly active, and show a compatibility warning until an explicit replacement or clear saves successfully.
  • In advanced-filter mode, unsupported package fields must be hidden from desktop/tablet and phone field selectors and from desktop/tablet header "按该字段筛选"; do not call
    openWithField
    for unknown fields, invalid field keys, or package-unsupported field/operator combinations.
  • On desktop/tablet, Header menu filtering is a host integration. It appends a draft condition through the package controller and opens the same toolbar filter panel. It must not submit immediately, reload records, or create a separate header-only state; phone has no header menu.
  • On desktop/tablet, Table scrolling, object switching, outside click, or unmount must close any header menu and restore the header suffix icon to hover-only state.
  • Advanced filter panel layout is mandatory: every Make advanced filter must use the fixed three-region baseline with a fixed header, scrollable body, and fixed footer. A panel where add/confirm/clear actions scroll away with conditions is a readiness blocker and must not be reported as ready, complete, or delivered.
  • Only when advanced filtering is enabled, persist its expression in the current user's Entity Preset and load and hydrate the Preset filter before the first records query. Search-only does not read, hydrate or write the filter Preset.
  • Preset writes are sparse. Saving filter sends only
    { filter }
    , never a possibly stale
    sort
    or
    group
    .
  • Save before apply. Preset save failure keeps the previous applied filter, open panel, and current draft; it must not reload records.
  • If
    make-app-actions
    is present, only a successfully applied filter generation clears its selection and invalidates pending action work. Draft edits, panel cancel, validation failure, Preset save failure, and failed list queries do not clear or redefine the current action selection.
  • Clear advanced filter with
    filter: null
    . Toolbar keyword search remains session-only and must not be persisted.
  • When list access is disabled, block new schema and records requests and invalidate in-flight results. In advanced-filter mode, also block Preset GET/PATCH, close filter surfaces and ignore stale Preset load/save responses after either
    entityKey
    or permission-enabled state changes. Search-only has no filter Preset request or surface to close.
  • 不得在宿主应用中创建新的 Make 高级筛选实现。当包已提供相关能力时,不得手写筛选 IR 辅助函数、运算符矩阵、校验器、CEL 编译器/解析器或高级筛选面板。
  • 不得部分交付高级筛选功能。两种模式都使用包编译器和 Service 表达式载荷;高级筛选模式额外使用包控制器。桌面/平板端高级筛选需实现 CanvasTable 表头 UI 和联动。移动端高级筛选仅使用其顶部工具栏筛选入口和移动端适配的面板;不需要也不渲染 CanvasTable 表头联动。
  • 移动端高级筛选需要上述解析版本的公开
    "mobile"
    面板布局、
    MobileFilterSheet
    、
    MobileFilterSelect
    和
    AdvancedFilterPanel layout="mobile"
    。在窄视口上使用桌面端 Popover、
    layout="default"
    或通过 CSS 压缩条件行都不属于移动端适配。保留桌面/平板端 Popover 的绑定和布局规则,然后在共享筛选包升级后检查其渲染的控件。仅搜索模式不需要移动端面板布局或移动端包筛选组件。
  • 新集成使用
    @qfei-design/make-app-filter
    的核心 API;高级筛选集成额外使用
    @qfei-design/make-app-filter/react
    和可选的
    @qfei-design/make-app-filter/adapters/antd
    。
  • 高级筛选集成需一次性导入
    @qfei-design/make-app-filter/styles.css
    。仅搜索模式的编译器使用不需要面板样式。宿主 CSS 可以设置外层遮罩/容器的样式,但不得分叉包内部逻辑,除非是修复宿主特定的包含问题。
  • 新的筛选输出使用
    filter: { expression: string }
    。如果
    compileListFilter
    返回
    undefined
    ,则省略
    filter
    。
  • compileListFilter
    是唯一面向宿主的搜索/高级筛选编译器。原样发送其结果;不得在宿主代码中解析、重分发或重写 CEL/DNF。
  • 后端记录列表处理器仅从
    Expression
    对象中读取
    filter.expression
    ,并将缺失、
    null
    或空表达式视为无筛选。
  • 不得发送
    filter: []
    、
    filter: {}
    、
    { expression: "" }
    、空原始筛选字符串或旧的对象数组 DSL。
  • 不得在本地对 Make 记录列表进行筛选。列表筛选通过 Service/后端筛选 API 进行。
  • 筛选字段来自规范化的运行时对象/字段元数据。不得将
    apps/dsl/**
    、复制的 YAML、行样本或硬编码的演示数据用作运行时筛选元数据。
  • 宿主字段类型注册表可能有助于规范化共享运行时元数据,但不得决定筛选运算符或值编辑器。将字段传递给包,并将其能力 API 作为筛选的可信来源。
  • 对于 Lookup 筛选,在将字段元数据传递给包之前,从完整的运行时 schema 中解析
    relationKey
    、对端实体和
    targetFieldKey
    。在筛选 IR 和 CEL 表达式中保留源 Lookup 字段键;目标字段元数据仅控制运算符、值和校验。
  • 用户和部门筛选值是身份标识,不是显示名称。候选值来源来自
    makeui
    /
    make-app-service
    负责的宿主约定;本技能不定义传输路由。
  • 不得从字段 schema 的
    options
    、当前表行、本地数组或显示标签中获取用户/部门选项。仅在远程候选值加载时,为了保持标签可见,可以合并当前已应用的值。
  • 后端记录筛选支持 DateRange、File 和 Lookup 语义,但 UI 仅在
    @qfei-design/make-app-filter
    公开 API 支持该字段/运算符组合时才暴露字段。如果后端文档和包能力存在差异,停止升级/修复包或上报不匹配问题;不得手写 CEL 或猜测包内部逻辑。
  • 在高级筛选模式下,每次实体或权限感知上下文变化时,递增单调的请求版本号并重置宿主面板状态。仅在保存完成时比较
    entityKey
    是不安全的,因为旧的
    A -> B -> A
    结果或访问撤销前的结果可能看起来是最新的。仅搜索模式仍会作废过期的记录查询响应,但不会创建面板状态。
  • 在高级筛选模式下,使用提交式上下文重置,例如带 key 的包装器加上 layout-effect 清理。不得在 React 渲染期间变更请求版本号、保存状态或上下文 ref。
  • 在高级筛选模式下,如果已保存的 CEL 不受当前包支持,请在后端请求中保持其原始表达式有效,保持触发器可见的激活状态,并显示兼容性警告,直到明确替换或清除成功保存为止。
  • 在高级筛选模式下,不受支持的包字段必须对桌面/平板端和移动端的字段选择器,以及桌面/平板端表头「按该字段筛选」隐藏;不得为未知字段、无效字段键或包不支持的字段/运算符组合调用
    openWithField
    。
  • 在桌面/平板端,表头菜单筛选是宿主集成功能。它通过包控制器追加草稿条件,并打开同一个工具栏筛选面板。不得立即提交、重新加载记录或创建单独的表头专属状态;移动端无表头菜单。
  • 在桌面/平板端,表格滚动、对象切换、外部点击或卸载时,必须关闭所有表头菜单,并将表头后缀图标恢复为仅悬停状态。
  • 高级筛选面板布局是强制要求:每个 Make 高级筛选都必须使用固定三区域基线,即固定表头、可滚动主体和固定页脚。如果添加/确认/清除操作会随条件一起滚动的面板,属于就绪阻塞问题,不得报告为就绪、完成或已交付。
  • 仅当启用高级筛选时,才将其表达式持久化到当前用户的实体预设中,并在首次记录查询前加载和 hydration 预设筛选。仅搜索模式不读取、hydration 或写入筛选预设。
  • 预设写入是稀疏的。保存筛选时仅发送
    { filter }
    ,绝不能发送可能过期的
    sort
    或
    group
    。
  • 先保存再应用。预设保存失败时保留之前的已应用筛选、打开的面板和当前草稿;不得重新加载记录。
  • 如果存在
    make-app-actions
    ,只有成功应用的筛选版本号才会清除其选中项并作废待处理的操作工作。草稿编辑、面板取消、校验失败、预设保存失败和列表查询失败都不会清除或重新定义当前操作选中项。
  • 使用
    filter: null
    清除高级筛选。工具栏关键词搜索仅在会话内有效,不得持久化。
  • 当列表访问被禁用时,阻止新的 schema 和记录请求,并作废进行中的结果。在高级筛选模式下,还要阻止预设的 GET/PATCH,关闭筛选界面,并在
    entityKey
    或权限启用状态变化后忽略过期的预设加载/保存响应。仅搜索模式没有筛选预设请求或需要关闭的界面。

Default behavior

默认行为

  • Advanced filtering UI is an optional product capability in every presentation mode. Generate its trigger and panel only when requested or already established by the project; enabling the standard phone View alone does not add them. A search-only list that sends
    filter.expression
    uses
    compileListFilter({ fields, searchText })
    without a filter trigger, panel, filter Preset GET/PATCH or hydration; omit
    advancedFilter
    rather than passing an explicit undefined value. When advanced filtering is in scope, adapt it on the phone as well as desktop/tablet rather than leaving a nonfunctional phone trigger.
  • Once advanced filtering is in scope, use the package-backed controller,
    AdvancedFilterPanel
    , draft lifecycle, fixed header/body/footer, field controls and Service
    filter.expression
    . Desktop/tablet use the toolbar trigger, host popover and CanvasTable header
    openWithField
    linkage. 手机/phone uses the top toolbar 筛选 entry and package
    layout="mobile"
    in
    MobileFilterSheet
    ; it does not need CanvasTable、表头或 header linkage.
  • On desktop/tablet, the advanced filter panel must keep its three regions explicit: header top fixed with left
    筛选
    and right
    清空所有
    , body middle containing only condition rows/groups and using the only vertical scroll, footer bottom fixed with left
    + 添加条件
    and
    + 添加条件组
    and right
    确认
    . On phone, retain the fixed three regions but use the package
    layout="mobile"
    defaults (
    设置筛选条件
    and
    完成
    ) inside
    MobileFilterSheet
    ; do not force desktop labels or inline-row styling onto that mode.
  • The host keeps search text separate from advanced filter state. Search-only compiles
    compileListFilter({ fields, searchText })
    ; advanced-filter mode combines applied filter and search through
    compileListFilter({ fields, searchText, advancedFilter })
    .
  • Closing the owning desktop/tablet Popover or phone Sheet without confirmation discards unconfirmed draft changes through the package controller reset flow.
  • The clear action changes only the draft; it affects the applied filter only after the active mode's confirm action (
    确认
    on desktop/tablet,
    完成
    on phone) succeeds.
  • Object/entity or permission-enabled context changes clear transient search state and invalidate old requests. In advanced-filter mode, also clear filter/panel state and reload the Entity Preset only when access is enabled; clear header state and reset desktop/tablet table object-level transient state when mounted. Phone has no header filter UI. Search-only does not reload the filter Preset.
  • 高级筛选 UI 在每种展示模式下都是可选的产品能力。仅在需求提出或项目已确立时才生成其触发器和面板;仅启用标准移动端视图不会添加这些功能。发送
    filter.expression
    的仅搜索列表使用
    compileListFilter({ fields, searchText })
    ,无需筛选触发器、面板、筛选预设的 GET/PATCH 或 hydration;省略
    advancedFilter
    而不是传入显式的 undefined 值。当涉及高级筛选时,移动端和桌面/平板端都要适配,而不是留下一个不可用的移动端触发器。
  • 一旦涉及高级筛选,使用基于包的控制器、
    AdvancedFilterPanel
    、草稿生命周期、固定表头/主体/页脚、字段控件和 Service
    filter.expression
    。桌面/平板端使用工具栏触发器、宿主 popover 和 CanvasTable 表头
    openWithField
    联动。移动端使用顶部工具栏筛选入口和
    MobileFilterSheet
    中的包
    layout="mobile"
    ;不需要 CanvasTable、表头或 header 联动。
  • 在桌面/平板端,高级筛选面板必须明确保持三个区域:顶部固定表头左侧为「筛选」、右侧为「清空所有」,中间主体仅包含条件行/组并使用唯一的垂直滚动,底部固定页脚左侧为「+ 添加条件」和「+ 添加条件组」、右侧为「确认」。在移动端,保留固定三区域,但使用
    MobileFilterSheet
    内的包
    layout="mobile"
    默认值(「设置筛选条件」和「完成」);不得将桌面端标签或行内样式强加到该模式下。
  • 宿主将搜索文本与高级筛选状态分开维护。仅搜索模式编译
    compileListFilter({ fields, searchText })
    ;高级筛选模式通过
    compileListFilter({ fields, searchText, advancedFilter })
    合并已应用的筛选和搜索。
  • 未确认就关闭所属的桌面/平板端 Popover 或移动端 Sheet,会通过包控制器重置流程丢弃未确认的草稿更改。
  • 清除操作仅更改草稿;仅在当前模式的确认操作(桌面/平板端为「确认」,移动端为「完成」)成功后,才会影响已应用的筛选。
  • 对象/实体或权限感知上下文变化会清除临时搜索状态并作废旧请求。在高级筛选模式下,如果访问已启用,还要清除筛选/面板状态并重新加载实体预设;挂载时清除表头状态并重置桌面/平板端表格对象级临时状态。移动端无表头筛选 UI。仅搜索模式不重新加载筛选预设。

Collaboration rules

协作规则

  • With
    makeui
    : use
    makeui
    for the desktop/tablet toolbar and the separate phone top filter entry, page shell, surrounding layout, and candidate-source UI contract; this skill owns filter behavior and package integration.
  • With
    canvas-table-integration
    : use that skill for CanvasTable
    suffixRender
    and header menu mechanics; this skill owns how the host "按该字段筛选" action talks to the package-backed advanced-filter controller.
  • With
    make-app-service
    : this skill defines filter query and Preset filter semantics; Service route validation, adapter logging, and Make request details stay in service.
  • With
    make-app-sort
    : when advanced filtering is enabled, filter and sort share one parent-owned Entity Preset coordinator and load lifecycle but update their dimensions independently. Search-only does not consume the Preset filter dimension. This skill does not define sorting UI or sort validation.
  • With
    make-app-group
    : filter and group share expression syntax; when advanced filtering is enabled they share the Preset lifecycle but update dimensions independently. This skill owns global
    filter.expression
    ;
    make-app-group
    owns transient path
    groupFilter
    composition and record-groups timing.
  • With
    make-app-permission
    : consume the resolved list-access gate in both capability modes; advanced filtering also includes its enabled state in the Preset request generation. This skill does not define permission policy or permission endpoints.
  • With
    make-app-actions
    : only for writable lists using the action workflow, hand off a successfully applied filter generation before the new query becomes actionable so actions clear selection and invalidate pending work. Draft and failure paths preserve selection; this Skill does not manipulate CanvasTable selection APIs directly.
  • With
    makedsl
    : read
    EntityDataFilterUsage.md
    to confirm backend filter semantics such as DNF, system variables, DateRange/File/Lookup, empty filter handling, and error cases. Do not generate DSL from this skill.
  • 与
    makeui
    协作:使用
    makeui
    实现桌面/平板端工具栏和独立的移动端顶部筛选入口、页面外壳、周边布局和候选值来源 UI 约定;本技能负责筛选行为和包集成。
  • 与
    canvas-table-integration
    协作:使用该技能实现 CanvasTable
    suffixRender
    和表头菜单机制;本技能负责宿主「按该字段筛选」操作与基于包的高级筛选控制器的交互方式。
  • 与
    make-app-service
    协作:本技能定义筛选查询和预设筛选语义;Service 路由校验、适配器日志和 Make 请求细节保留在 service 中。
  • 与
    make-app-sort
    协作:启用高级筛选时,筛选和排序共享一个父级负责的实体预设协调器和加载生命周期,但独立更新各自的维度。仅搜索模式不消费预设筛选维度。本技能不定义排序 UI 或排序校验。
  • 与
    make-app-group
    协作:筛选和分组共享表达式语法;启用高级筛选时,它们共享预设生命周期,但独立更新维度。本技能负责全局
    filter.expression
    ;
    make-app-group
    负责临时路径
    groupFilter
    的组合和记录分组的时机。
  • 与
    make-app-permission
    协作:在两种能力模式下都消费已解析的列表访问准入;高级筛选还会将其启用状态包含在预设请求版本号中。本技能不定义权限策略或权限端点。
  • 与
    make-app-actions
    协作:仅对于使用操作工作流的可写列表,在新查询生效前传递成功应用的筛选版本号,以便操作清除选中项并作废待处理工作。草稿和失败路径保留选中项;本技能不直接操作 CanvasTable 选中 API。
  • 与
    makedsl
    协作:阅读
    EntityDataFilterUsage.md
    以确认后端筛选语义,例如 DNF、系统变量、DateRange/File/Lookup、空筛选处理和错误场景。本技能不生成 DSL。