@wordrhyme/auto-crud 1.17.1 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1939,7 +1939,7 @@ container resizing and translated text widths, without changing other tables.
1939
1939
 
1940
1940
  ## 保存视图与动态标签
1941
1941
 
1942
- 在 `QueryClientProvider` 内配置一次服务,所有带稳定 `id` 的 `AutoCrudTable` 自动显示视图菜单:
1942
+ 视图默认关闭。在 `QueryClientProvider` 内配置存储服务后,通过 `table={{ views: true }}` 为带稳定 `id` 的 `AutoCrudTable` 开启视图菜单:
1943
1943
 
1944
1944
  ```tsx
1945
1945
  import {
@@ -1948,7 +1948,7 @@ import {
1948
1948
  createLocalViewStorage,
1949
1949
  } from '@wordrhyme/auto-crud';
1950
1950
 
1951
- // 服务对象应保持引用稳定。后端存储只需实现 ViewStorage 的四个方法。
1951
+ // 服务对象应保持引用稳定。后端存储实现 ViewStorage 的四个必需方法,可选实现 reorder。
1952
1952
  const viewStorage = createLocalViewStorage(`${organizationId}:${userId}`);
1953
1953
 
1954
1954
  <QueryClientProvider client={queryClient}>
@@ -1959,6 +1959,7 @@ const viewStorage = createLocalViewStorage(`${organizationId}:${userId}`);
1959
1959
  >
1960
1960
  <AutoCrudTable
1961
1961
  id="crm.customers"
1962
+ table={{ views: true }}
1962
1963
  schema={schema}
1963
1964
  resource={resource}
1964
1965
  fields={{
@@ -1969,7 +1970,7 @@ const viewStorage = createLocalViewStorage(`${organizationId}:${userId}`);
1969
1970
  </QueryClientProvider>;
1970
1971
  ```
1971
1972
 
1972
- - 视图保存筛选条件、条件间的 AND/OR、搜索词和排序;不保存分页、选中行。支持新建、复制、重命名、删除、保存和放弃修改。`table={{ views: false }}` 可在某个表关闭。
1973
+ - 视图保存筛选条件、条件间的 AND/OR、搜索词和排序;不保存分页、选中行。支持新建、复制、重命名、删除、保存和放弃修改。省略 `views` 或传 `false` 时关闭,传 `true` 或配置对象时开启。独立 `AutoTable` 使用 `views={true}`,并提供稳定的 `resourceId`。全局 `viewStorage` 和本地展示偏好不会自动开启视图。之前依赖自动开启的列表需补充 `table={{ views: true }}`。
1973
1974
  - 视图支持下拉与 Tab 两种展示:下拉放在搜索框前,设置收在下拉菜单内;Tab 放在筛选栏上方,末尾仅提供设置图标,新建操作与下拉模式一致,放在设置菜单内。在设置菜单的“展示方式”中切换,当前视图及未保存修改会保留。有修改时显示状态点、“保存修改”和“还原”。无本地偏好时默认使用下拉;`table={{ views: { selector: 'tabs' } }}` 可设置初始展示。独立使用 `AutoTable` 时传 `views={{ selector: 'tabs' }}`。本地记忆优先于 `selector`,展示方式不写入已保存的查询。
1974
1975
  - `scope` 必须包含当前用户与租户;切换时重置组件状态。`createLocalViewStorage` 仅保存当前浏览器中的视图。换用后端时传入 `ViewStorage`,组件调用方式不变。
1975
1976
  - `TagService.list` 接收 `resourceId/field` 和可选的 `query/page/pageSize/signal`,统一返回 `{ options: TagOption[], hasMore: boolean }`,两个字段都必须提供。每个选项包含稳定 ID `value`、名称 `label` 和颜色 `color`。`resolve` 返回指定稳定 ID 对应的名称与颜色。用户新建标签只增加选项,不增加 schema 字段。
@@ -1983,6 +1984,37 @@ const viewStorage = createLocalViewStorage(`${organizationId}:${userId}`);
1983
1984
 
1984
1985
  展示方式与当前选中视图的 ID 自动存入浏览器 `localStorage`,键为 `auto-crud:view-preferences:${encodeURIComponent(scope)}:${encodeURIComponent(resourceId)}`,按用户/租户和资源隔离,独立于 `ViewStorage` 的本地或服务端实现。刷新或重新进入时恢复展示方式;视图列表加载成功后恢复选中项。URL 已有筛选、搜索、排序或分页参数时保留 URL 查询,否则应用上次视图的保存条件,使用 replace 更新 URL。上次视图已删除或字段不可用时清除其选中记忆,保留 URL 查询。本地数据损坏或存储不可用时使用配置的初始展示方式,仍可在当前页面切换。未保存的查询不另存到本地偏好中。
1985
1986
 
1987
+ ### 默认视图、分享链接与排列顺序
1988
+
1989
+ ```tsx
1990
+ <AutoCrudTable
1991
+ id="crm.customers"
1992
+ schema={schema}
1993
+ resource={resource}
1994
+ table={{
1995
+ views: { defaultView: 'vip-customers', selector: 'tabs' },
1996
+ // 可选;同页多个列表或字段名与 view 冲突时使用不同的 URL 参数名。
1997
+ queryKeys: { view: 'customerView' },
1998
+ }}
1999
+ />
2000
+ ```
2001
+
2002
+ `defaultView` 接受视图的 slug 或 ID,独立 `AutoTable` 使用 `views={{ defaultView: 'vip-customers' }}`。初始化优先级为 URL 指定、用户本地选中记忆、`defaultView`、全部;本地明确记住“全部”也优先于默认值。默认项不存在时回到全部,不自动选择其他视图。`views` 仍须显式开启,本地偏好与 URL 都不会自动开启视图功能。
2003
+
2004
+ 视图可包含可选的 `slug`,例如 `{ id: 'view-123', slug: 'vip-customers', name: '重点客户', query }`。新建时按名称建议 slug,可手动修改;重命名保持原 slug。slug 为 1–80 个文字、数字或连接用的短横线,区分大小写。`ViewStorage.create/update` 须保存并返回该字段,`update` 未传 slug 时保留原值;已有数据无需迁移,没有 slug 时继续使用 ID。同一资源内 ID 和 slug 必须唯一,slug 也不能与另一视图的 ID 相同。服务端须在用户/租户/资源边界内校验唯一性;修改 slug 后旧 slug 链接失效,稳定 ID 仍可定位。
2005
+
2006
+ 默认参数为 `?view=vip-customers`,也接受 `?view=view-123`;若配置上例的 `queryKeys.view`,则使用 `?customerView=vip-customers`。切换视图会同步参数并创建浏览器历史记录,前进/后退恢复 URL 指定的视图。有 slug 时写入规范 slug,只有 ID 的旧链接会以 replace 规范化。`?view=` 明确表示“全部”。仅带视图参数的链接会应用保存条件;若同时带筛选、搜索、排序或分页参数,保留完整 URL 查询,便于分享未保存的调整。无权访问、已删除或查询字段失效时显示错误并保留 URL 查询,不回退到另一个视图。链接接收者仍需有权限读取该视图及资源,URL 不授予访问权限。
2007
+
2008
+ 下拉和 Tab 都按 `ViewStorage.list()` 的返回顺序展示,“全部”固定在最前。存储提供可选方法后,设置菜单显示“调整顺序”,拖动手柄(也支持键盘)后点击保存;取消或保存失败不会改变显示顺序或当前选中项:
2009
+
2010
+ ```ts
2011
+ reorder?: (resourceId: string, ids: string[]) => Promise<void>;
2012
+ ```
2013
+
2014
+ `ids` 必须包含该资源的全部视图 ID,顺序即新顺序。服务端应在事务中校验并保存,拒绝重复、未知或缺失 ID;并发新增/删除导致列表不一致时返回错误,让用户刷新后重试。成功后组件重新调用 `list()`。排序不修改视图 ID、slug 或查询条件;服务未实现 `reorder` 时不展示排序入口。`createLocalViewStorage` 已实现本地排序持久化。
2015
+
2016
+ Storybook 的 **Default View** 演示按 slug 默认选中,“视图设置 → 调整顺序”可体验排序;所有 Saved views and tags 示例共用本地视图存储,首次加载补齐演示视图;视图、删除操作和排列顺序刷新后保留。客户标签仍为刷新后重置的内存数据。
2017
+
1986
2018
  标签列表调用示例:
1987
2019
 
1988
2020
  ```ts
@@ -2031,7 +2063,7 @@ const loadViewCounts: NonNullable<SavedViewsConfig['counts']> = async ({
2031
2063
 
2032
2064
  首次加载显示 `…`,零结果显示 `0`,缺失或无效数量显示 `—`;请求失败显示 `—` 和重试入口。保存视图条件后重新统计;表格数据引用或 `counts` 回调引用变化时也会重新获取。数量由查询缓存管理,不写入视图存储。独立 `AutoTable` 使用 `views={{ selector: 'tabs', counts: loadViewCounts }}`。
2033
2065
 
2034
- Storybook 的 **Auto CRUD / Saved views and tags / Tabs With Counts** 使用内存视图与标签数据,模拟 300ms 请求延迟,预置数量为 3、2、1、0 的视图。列表和数量共用筛选逻辑,修改客户标签后会重新计算;刷新页面后重置示例数据。
2066
+ Storybook 的 **Auto CRUD / Saved views and tags / Tabs With Counts** 与其他视图示例共用本地视图存储,模拟 300ms 统计请求延迟;首次加载预置数量为 3、2、1、0 的视图。列表和数量共用筛选逻辑,修改客户标签后会重新计算。视图与排列顺序刷新后保留,客户标签刷新后重置。
2035
2067
 
2036
2068
  ### 视图 Tab 样式
2037
2069
 
@@ -2063,6 +2095,31 @@ Storybook 的 **Auto CRUD / Saved views and tags / Tabs With Counts** 使用内
2063
2095
 
2064
2096
  Storybook 提供 **Line Tabs**(下方蓝色强调线)和 **Top Line Tabs**(上方强调线)示例,均带视图数量;可通过 Controls 切换样式和线条位置。已有本地展示偏好时,仍可在视图设置中切换到 Tab。
2065
2097
 
2098
+ ### 自动标签接入
2099
+
2100
+ 字段声明 `tags: true` 后,`AutoCrudTable` 自动展示标签、启用标签筛选,并生成行操作和批量操作的设置入口:
2101
+
2102
+ ```tsx
2103
+ const schema = z.object({
2104
+ id: z.string(),
2105
+ recordTags: z.array(z.string()).optional(),
2106
+ });
2107
+
2108
+ <AutoCrudTable
2109
+ id="crm.customers"
2110
+ schema={schema}
2111
+ resource={resource}
2112
+ permissions={permissions}
2113
+ fields={{ recordTags: { label: '标签', form: false, tags: true } }}
2114
+ />;
2115
+ ```
2116
+
2117
+ 应用级 `AutoCrudProvider` 提供 `tagService`,页面无需再维护 `TagAssignment`、弹窗状态或选中记录转换。资源 ID 复用表格 `id`,记录主键复用 `resource.idKey`(默认 `id`),保存后调用 `resource.handlers.refresh`。未填写的标签值按空数组处理。
2118
+
2119
+ 自动入口跟随 `permissions.can.update`,字段 `hidden: true` 或被 `permissions.deny` 禁止时不生成入口;服务未提供 `assign` 时只展示和筛选。已有行操作、批量操作和注册扩展仍会保留。自动操作的稳定 ID 为 `tags:<字段名>`,可通过现有操作注册机制调整。`locale.tagAssignment` 可覆盖入口与弹窗标题。
2120
+
2121
+ `tags: true` 默认补充 `filter.variant: 'tags'`,显式筛选配置优先,`filter: false` 仍可禁用筛选且保留标签展示和设置入口。省略或设置 `tags: false` 不生成自动入口,已有 `filter.variant: 'tags'` 和手动弹窗接入方式保持兼容。标签仍由现有服务读写,无需新增页面接口或业务表。
2122
+
2066
2123
  ### 自定义标签编辑入口
2067
2124
 
2068
2125
  `TagAssignment` 是受控弹窗,不包含按钮。打开后直接显示搜索和标签列表,已有标签默认选中,通过勾选/取消勾选编辑,无需选择添加或移除。已选标签的名称、颜色实时显示;清空和保存位于同一行,点击保存后才提交记录的标签关联。