Files
Starlight_Lancher/.agents/skills/oil-frontend/references/state-and-loading-contract.md

108 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 状态与加载规则
> 当任务涉及 loading、refreshing、empty、error、processing、异步确认或后台长任务时读取数据归属和操作范围由数据与操作范围规则负责。
## 状态矩阵
| 范围 | Loading | Empty | Error | Processing | Ready |
| --- | --- | --- | --- | --- | --- |
| 应用启动 / 路由 | 品牌全局加载组件 | 不适用 | 全局恢复入口 | 不适用 | 应用骨架 |
| 页面 / 集合 | 与最终布局同构的顶部骨架 | 原因 + 一个恢复动作 | 错误说明 + 重试 | 单项状态留在对象上 | 正常内容 |
| 面板 / 弹窗 | 局部骨架并保持尺寸 | 局部空状态 | 局部重试 | 状态文字和必要进度 | 正常详情 |
| 按钮提交 | 共享按钮 `loading` 状态 | 不适用 | 就近错误反馈 | 防重复提交 | 成功结果 |
| 长任务单项 | 不使用持续 spinner | 不适用 | 失败原因 + 恢复动作 | 等待 / 处理中 | 完成 |
## 状态词汇
- `loading`:首次获取当前区域的数据,尚无可保留内容。
- `refreshing`:当前区域已有可保留内容,正在获取新的查询结果。
- `ready`:当前区域已有可使用内容。
- `empty`:资源集合本身为空。
- `filtered-empty`:资源集合可能存在,但当前筛选或搜索没有匹配结果。
- `processing`:当前区域的操作正在执行。
- `queued`:长任务已被接受,正在等待执行。
- `error`:当前区域加载或操作失败,并需要解释或恢复动作。
界面文案可以本地化,但状态判断、组件属性和验证报告统一使用以上词汇。
## 硬性规则
- 禁止大面积 spinner、旋转环和无内容遮罩。
- 禁止把页面加载误做成居中的空状态。
- 禁止让有限骨架占满剩余视口并漂在内容区中央。
- 禁止让骨架复制与最终布局无关的通用矩形。
- 禁止用 spinner 长期表达后台任务状态。
- 禁止同时显示 loading 与 empty或 processing 与 “no results”。
- 禁止把 loading 放入 EmptyState 或复用空状态容器。
- 同一对象和同一范围只显示一种加载反馈。
- 禁止在每个页面自行实现加载动画。
- 禁止异步确认一提交就关闭弹窗,再让用户从未变化的底层界面猜测请求是否完成。
## 全局加载
全局加载只负责应用初始化或路由级切换。使用唯一共享组件,保持品牌信号和稳定位置。全局组件自行拥有视觉,不复用按钮、列表或单项任务的局部进度组件。页面不得覆写其视觉,也不得把它替换为集合骨架。
## 加载结构由谁负责
- 共享骨架原语只负责颜色、圆角和动画,不负责猜测页面结构。
- 被加载的共享业务组件或布局组件负责骨架的页面结构、数量、尺寸和排列。
- 骨架复用最终组件对应的内容区域、相对比例和内容轨道,不复制会造成额外滚动的最小宽度、固定高度或完整数据量。
- 禁止让万能加载器根据粗粒度布局名称猜测页面结构。
- 可以由共享业务组件提供 `loading` 状态或同目录骨架组件;禁止使用组件的页面重新发明动画。
## 页面与集合骨架
骨架必须:
- 位于最终内容出现的位置;
- 保留最终页面中稳定存在的 Header、Toolbar、表头和容器只替换尚未返回的数据
- 由最终资源卡片、列表行、表格行或面板结构组合;
- 保持内容轨道宽度;
- 从顶部开始;
- 高度由占位内容决定,不用剩余视口高度把有限行数拉成整屏;
- 不得产生最终内容之外的滚动;宽表骨架压缩展示当前视口可见的列,不复刻完整表格的最小宽度;
- 在数据到达后不产生明显布局位移。
## 加载范围
| 情况 | 呈现 |
| --- | --- |
| 首次加载且没有旧数据 | 与最终内容同构的骨架 |
| 刷新、筛选或翻页且已有数据 | 保留同一已提交查询快照,在触发控件或容器上表达 `refreshing`;列表与总数在新响应完成后一起更新 |
| 按钮提交 | 按钮自身的 `loading` 状态 |
| 单个资源加载 | 只更新对应资源、媒体槽或状态位置 |
| 后台长任务 | 对象状态和必要进度,不持续占用操作控件 |
不要因为局部请求清空整个页面,也不要为同一请求同时显示活动图标、骨架、进度条和状态文字。
## 按钮加载
按钮加载由共享操作组件拥有。组件需:
- 保持原按钮宽度;
- 保留或稳定表达原动作;
- 禁用重复提交;
- 使用紧凑、非旋转或品牌一致的进度信号。
禁止在使用组件的位置手工插入加载动画、改内边距或写临时宽度。
## 异步确认弹窗
删除、移除、撤销、发布、保存等需要等待请求结果的确认动作,必须遵守同一生命周期:
1. 提交后保持弹窗、确认对象和影响说明不变,确认按钮进入共享 `loading` 状态并阻止重复提交。
2. 请求没有真实取消能力时,处理中禁用取消、关闭、点击遮罩和 `Escape` 关闭;不能让弹窗消失后请求仍在后台继续。
3. 只有请求成功且原界面的可见状态已经提交或刷新后,才关闭弹窗。不得先关闭弹窗,再等待列表、详情或状态可能更新。
4. 请求失败时保持弹窗和原对象,恢复确认按钮,并在弹窗内或紧邻操作的位置显示可恢复的错误;不得要求用户重新找到对象并再次打开确认流程。
5. 只有动作明确转为可观察的 `queued` / `processing` 长任务,且原界面已经显示对应对象状态时,弹窗才可以在任务最终完成前关闭。
这套生命周期由共享确认弹窗和负责业务请求的数据流共同保证。页面不得只关闭本地弹窗状态而丢弃仍在处理的对象,也不得用全页 busy 代替确认按钮的局部反馈。
## 后台任务
后台长任务应成为对象生命周期:
`queued → processing → ready | error`
列表显示短状态;详情显示解释、进度、错误和恢复动作。状态变化不得要求用户靠观察 spinner 猜测。