You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit f308adf
Browse filesBrowse the repository at this point in the historyBrowse files
fix(ui): the stage path and the kanban lay a select's options out by their declared lifecycle `kind` (#26612)
7
+
8
+
Clause-②: no
9
+
Metadata-protocol: none
10
+
11
+
A select option may declare `kind: 'open' | 'won' | 'lost'` (`SelectOption.kind` in `@objectstack/spec`). Two readers now follow it instead of the option order or the value's spelling.
12
+
13
+
-**`record:path`.** Once the status field declares a kind on any option, an option without one reads as `open`, the spec's rule for an absent kind, and is never classified from a `closed_won` / `closed_lost` spelling. The stages are laid out by kind: the open options as the steps in their authored order, then every won option as the forward terminus, then the lost options apart from the rail. A lost option authored mid-list no longer pulls the options after it into the lost group. A field that declares no kind keeps the spelling fallback and its positional layout as before, and a dev build now warns once, naming the object, the field and the stages it guessed.
14
+
-**Kanban.** Lanes the board derives from the lane field's options run open → won → lost when the field declares a kind, each class in its authored order, and every lost lane starts collapsed: a spine with its card count that the viewer can open. Authored `columns` and fields that declare no kind keep their order; the board guesses nothing from spelling.
feat(plugin-list): a list block on a page caps its rows and ends with a "View all N" link; a tabbed list block caps each tab and badges each tab with its count
8
+
9
+
Clause-②: yes
10
+
Metadata-protocol: none
11
+
12
+
A `list-view` block in a page region half the page or wider used to draw the whole object list: every row of its query, the toolbar, the `#` column, every column of the view and a horizontal scrollbar. It now draws a capped list:
13
+
14
+
-**The rows.** At most `dataSource.limit` of them, the key every page element's data binding already declares, and 5 when the block states none. The cap is the query's own window (`$top`), so a capped block never fetches the rest.
15
+
-**The columns.** The view's first four visible columns, in a table fixed to the block's width; the rest are dropped, not scrolled. A view that declares no columns draws the object's `highlightFields` led by its name field, else each record's display name.
16
+
-**No object-list chrome.** No toolbar, view tabs, row-number column, pager or record-count bar. A click on a row opens the record, as a grid row does.
17
+
-**The link.** Under the rows, 「View all N →」 (`list.viewAllCount`, new in all ten language packs) opens the object list on the block's bound view, the same destination the compact list's "View all" link opens.
18
+
19
+
A region narrower than half the page keeps the compact list, and a list outside any page region (the object list page, a block with no page around it) keeps the full list.
20
+
21
+
`page:tabs` now badges a tab holding `list-view` blocks with the number of records those blocks' own queries matched, summed with the `record:related_list` counts it already derives. Such a tab is mounted while inactive, hidden, so the badge is there before the tab is opened; a tab with an authored `count` keeps mounting on open only. Nothing an author writes changes. The published surface widens in three places, which is what `Clause-②: yes` declares: the i18n key `list.viewAllCount` in all ten packs; `usePageTabCountReporter`, a new export of `@object-ui/components`, the count channel a `page:tabs` panel opens to the blocks inside it; and `ListView`'s two new optional host props that use it, `capped` and `onTotalChange`.
fix(app-shell,i18n): on a deployment with no AI agent, Home's build chip opens Studio's new-package flow as "New in Studio", and `/ai` says no assistant is enabled instead of redirecting home
7
+
8
+
Clause-②: yes
9
+
Metadata-protocol: none
10
+
11
+
-**Home's build chip reads the agent catalog.** On a deployment whose catalog (`GET /api/v1/ai/agents`) is empty or absent, the greeting row's "Build an app" (「构建应用」) promised a build nothing there could start. There it now reads "New in Studio" (「在 Studio 中新建」) and opens Studio's new-package flow; a session that may not author gets no build chip at all, while "Start with a template" keeps the reason. The chip waits for the catalog's answer, so neither form flashes first. With an agent in the catalog nothing changes.
12
+
-**`/ai` with no agent.**`RequireAiSurface` used to redirect a visit to `/ai` home with no word of why. It now shows the AI-unavailable screen in place (「AI 助手不可用」 · 「当前部署未启用 AI 助手。其他功能一切正常。」), with the way home and, for an admin who may author on a runtime that offers authoring, the same "New in Studio" link. The screen is the one `AiChatPage` already showed for an empty catalog, now its own module (`console/ai/AiUnavailable.tsx`) shared by both. `RequireAiSurface`'s `redirectTo` prop keeps its name and now sets where that screen's way home leads.
13
+
-**Studio deep link.**`/studio?new=package` opens the Studio landing with the create-package dialog open, and drops the param from the address. `STUDIO_NEW_PACKAGE_PATH` (`views/studio-design/studioNewPackage.ts`) is its one spelling.
14
+
-**i18n.** New key `home.build.inStudio` in all ten packs.
fix(plugin-list): the Display popover's Layout row folds its segments to icons when they would not fit
6
+
7
+
Clause-②: no
8
+
Metadata-protocol: none
9
+
10
+
On a list that offers four layouts, the Layout row of the Display popover read 「布局 | 表格 | 看板 | 日历 | 时间线」 and broke each label onto two lines: the popover is a fixed width and the row shares it with its title. In English the labels are longer still.
11
+
12
+
What changes:
13
+
14
+
- The row now measures the width its segments need with every label shown against the width it has, in whatever locale is rendering. When they would not fit, every segment but the selected one shows its icon only. The selected segment keeps its label.
15
+
- A folded segment keeps its accessible name and its tooltip (its `aria-label` and `title`), so it is still announced and still named on hover.
16
+
- The fold is measured, not a count or a breakpoint: two layouts keep their labels, and the same row unfolds wherever it fits again.
17
+
- Labels in the row no longer wrap, and the popover keeps its width.
18
+
19
+
What to do: nothing. Nothing a view or object declares changes.
fix(i18n): the zh chatbot build header separates the verb from the app name
6
+
7
+
Clause-②: no
8
+
Metadata-protocol: none
9
+
10
+
-**zh `chatbot.build.built`** reads `已构建 · APP` instead of `已构建APP`, and **zh `chatbot.build.building`** reads `正在构建 · APP…` instead of `正在构建APP…`. A name pasted straight onto the verb ran on into one word, most visibly with a Latin-script name (「已构建Library Lending Management」). The separator is the ` · ` the sibling `chatbot.build.builtAndLive` (`已搭建并上线 · APP`) already used.
11
+
- The unnamed-build stand-in goes through the same frame, so it now reads `正在构建 · 你的应用…`, the same shape `builtAndLive` already had for an unnamed build.
12
+
- Values only: no key is added, removed or renamed. `ja` (name first, then a particle) and `ko` (already spaced) did not run on and are unchanged; the Latin-script packs are untouched.
// ── Half 1: the enumeration ───────────────────────────────────────────────────
274
275
275
276
/**
276
-
* Every function in `sql-driver.ts`, `sql-driver-cross-field-comparison.ts` and
277
-
* `sql-driver-read-exit-fault.ts` that builds an `INVALID_FILTER` error, by the route it takes. Read with the TypeScript parser, not a regex, so a call
277
+
* Every function in `sql-driver.ts`, `sql-driver-cross-field-comparison.ts`,
278
+
* `sql-driver-read-exit-fault.ts` and `sql-driver-predicate-emitters.ts` that builds an `INVALID_FILTER` error, by the route it takes. Read with the TypeScript parser, not a regex, so a call
278
279
* split across lines, an inline `throw`, or a builder written as a method or an
279
280
* arrow cannot slip past the count.
280
281
*/
@@ -287,10 +288,13 @@ function enumerateRefusalBuilders(): {
287
288
// its own seam module with two of the builders below; the scan reads both.
288
289
// [#25521 cut 15] The read exits' fault terminals moved to a third, with
289
290
// `unresolvableFilterColumnError`; the scan reads it too.
291
+
// [#25521 cut 16] The leaf predicate emitters moved to a fourth, with the two
0 commit comments