@ai-matrx/records-ui 0.41.0 → 0.42.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/CHANGELOG.md +32 -0
- package/dist/index.cjs +17 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +17 -5
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/records-ui
|
|
2
2
|
|
|
3
|
+
## 0.42.0
|
|
4
|
+
|
|
5
|
+
**A pipeline table opened as "pick a column", and the board it already had was
|
|
6
|
+
unreachable.**
|
|
7
|
+
|
|
8
|
+
Measured in the real app (lane SCREENS-2, 2026-09-20) against a real pipeline —
|
|
9
|
+
five stages, a moves rule, a requires rule and a WIP limit of 2.
|
|
10
|
+
`custom.pipeline_read` answered `is_pipeline: true` with `stage_field: "stage"`,
|
|
11
|
+
every rule beside it, and the kanban drew
|
|
12
|
+
|
|
13
|
+
> A kanban board needs a Field to make its columns from — pick one and the board
|
|
14
|
+
> appears.
|
|
15
|
+
|
|
16
|
+
Two things stacked. `Board`'s "no grouping field" gate sat ABOVE its pipeline
|
|
17
|
+
branch, and `useIsPipeline` answered `stage.key === groupField` — so a table was
|
|
18
|
+
only a pipeline once somebody had ALREADY guessed which column to group by. The
|
|
19
|
+
store knew the answer the whole time and the screen asked the person for it. A
|
|
20
|
+
board nobody can reach without knowing the answer in advance is not a board.
|
|
21
|
+
|
|
22
|
+
The stage column is now the TABLE's own answer (`custom.table_stage_field`), used
|
|
23
|
+
both to know the table is a pipeline and to know which column its columns come
|
|
24
|
+
from. A view that names its own grouping column still wins — grouping a pipeline
|
|
25
|
+
by its owner is a real thing to want, and it draws the plain board of that column
|
|
26
|
+
and says so. While the table has not answered, NOTHING is claimed in either
|
|
27
|
+
direction: the "pick one" sentence would be a question about to answer itself.
|
|
28
|
+
|
|
29
|
+
`src/pipeline-reach.test.tsx` is at the one seam that decides it
|
|
30
|
+
(`boardColumnChoice`, exported for exactly that reason) and all four clauses fail
|
|
31
|
+
on 0.41.0's bytes.
|
|
32
|
+
|
|
33
|
+
**Consumer action:** none. `ViewSwitcher`'s props are unchanged.
|
|
34
|
+
|
|
3
35
|
## 0.41.0
|
|
4
36
|
|
|
5
37
|
**The last two product screens that could not work at all, rewritten against the
|
package/dist/index.cjs
CHANGED
|
@@ -5439,7 +5439,7 @@ function offerableFields(all, want) {
|
|
|
5439
5439
|
return kind === "datetime" || kind === "date";
|
|
5440
5440
|
});
|
|
5441
5441
|
}
|
|
5442
|
-
function
|
|
5442
|
+
function useStageField(tableId) {
|
|
5443
5443
|
const client = (0, import_react41.useRecordsClient)();
|
|
5444
5444
|
const [stage, setStage] = (0, import_react40.useState)({
|
|
5445
5445
|
asked: false,
|
|
@@ -5456,8 +5456,17 @@ function useIsPipeline(tableId, groupField) {
|
|
|
5456
5456
|
cancelled = true;
|
|
5457
5457
|
};
|
|
5458
5458
|
}, [client, tableId]);
|
|
5459
|
-
|
|
5460
|
-
|
|
5459
|
+
return stage;
|
|
5460
|
+
}
|
|
5461
|
+
function boardColumnChoice(fields, chosenKey, stage) {
|
|
5462
|
+
const has = (key) => key != null && fields.some((f) => f.key === key) ? key : null;
|
|
5463
|
+
const chosen = has(chosenKey);
|
|
5464
|
+
if (chosen) {
|
|
5465
|
+
return { groupKey: chosen, isPipeline: stage.asked ? stage.key === chosen : null, stillAsking: false };
|
|
5466
|
+
}
|
|
5467
|
+
if (!stage.asked) return { groupKey: null, isPipeline: null, stillAsking: true };
|
|
5468
|
+
const fromTable = has(stage.key);
|
|
5469
|
+
return { groupKey: fromTable, isPipeline: fromTable != null, stillAsking: false };
|
|
5461
5470
|
}
|
|
5462
5471
|
function Board({
|
|
5463
5472
|
view,
|
|
@@ -5469,7 +5478,7 @@ function Board({
|
|
|
5469
5478
|
}) {
|
|
5470
5479
|
const fields = (0, import_react41.useFields)(view.subject);
|
|
5471
5480
|
const records = useViewRecords(view, pageSize);
|
|
5472
|
-
const
|
|
5481
|
+
const stage = useStageField(view.subject);
|
|
5473
5482
|
if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(RefusalNotice, { error: fields.error });
|
|
5474
5483
|
if (records.error) return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(RefusalNotice, { error: records.error });
|
|
5475
5484
|
if (fields.loading || records.loading) return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_design_system19.Skeleton, { className: "h-40 w-full" });
|
|
@@ -5477,7 +5486,9 @@ function Board({
|
|
|
5477
5486
|
const byKey = (key) => all.find((f) => f.key === key);
|
|
5478
5487
|
const titleField = byKey(view.groupField) ? all.find((f) => f.key !== view.groupField) ?? all[0] : all[0];
|
|
5479
5488
|
if (view.layout === "kanban") {
|
|
5480
|
-
const
|
|
5489
|
+
const choice = boardColumnChoice(all, view.groupField, stage);
|
|
5490
|
+
const groupField = byKey(choice.groupKey);
|
|
5491
|
+
const isPipeline = choice.isPipeline;
|
|
5481
5492
|
const picker = /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5482
5493
|
FieldPicker,
|
|
5483
5494
|
{
|
|
@@ -5489,6 +5500,7 @@ function Board({
|
|
|
5489
5500
|
onPick: (key) => onChange({ groupField: key })
|
|
5490
5501
|
}
|
|
5491
5502
|
);
|
|
5503
|
+
if (choice.stillAsking) return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_design_system19.Skeleton, { className: "h-40 w-full" });
|
|
5492
5504
|
if (!groupField) return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Needs, { layout: "kanban", picker });
|
|
5493
5505
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex min-h-0 flex-col gap-2", children: [
|
|
5494
5506
|
picker,
|