@ai-matrx/records-ui 0.53.0 → 0.57.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 CHANGED
@@ -1,5 +1,122 @@
1
1
  # Changelog — @ai-matrx/records-ui
2
2
 
3
+ ## 0.57.0
4
+
5
+ **The builders are usable where a person actually reaches them: a 384px rail.**
6
+
7
+ The first browser walk (lane BUILDERS, Ironline Fitness, 2026-09-21) pressed
8
+ "Build the form" on a real gym's members table and got a preview of an empty
9
+ form and **no controls at all**. `FormBuilder` was authored as two desktop
10
+ columns — controls left, live preview in a `w-96` aside right — and the rail it
11
+ is mounted in is itself `w-96`, so the fixed-width preview took the entire rail
12
+ and squeezed the controls to nothing. The screen looked like a builder and could
13
+ not build.
14
+
15
+ A viewport breakpoint cannot fix that: the viewport was 1680px wide while the
16
+ container was 384px. Every split in these four screens is now a **container
17
+ query**, so they are the same screen in a rail, a dialog or a full page:
18
+
19
+ * `FormBuilder` stacks to one column and its preview goes full-width below the
20
+ controls until the component itself is wide enough for two (`@3xl`).
21
+ * `BookingBuilder`, `PortalBuilder` and `DigestScheduler` drop their two-column
22
+ grids and fixed-width inputs to one column under `@md`.
23
+
24
+ **Consumer action:** none. The host must already scan this package's `dist` for
25
+ Tailwind classes (`@source "…/@ai-matrx/records-ui/dist"`), which matrx-frontend
26
+ does; the container variants are generated from there like every other class.
27
+
28
+ ## 0.56.0
29
+
30
+ **A condition the builder cannot draw is said in words, not blanked.**
31
+
32
+ Found by a screenshot, which is what the screenshots were for. The Birchwood
33
+ Avenue renovation's own rule demands "a second quote from a DIFFERENT
34
+ contractor" — a `sibling_count`, which the one-clause builder cannot draw — and
35
+ the editor rendered it as **"— pick a column —"**. That is the screen saying
36
+ there is no condition when there is one, beside a live Save button, on a rule
37
+ that is turning people's work away right now.
38
+
39
+ It now reads: *"it cannot get here unless **how many others there are for the
40
+ same Room from a different Contractor** — this part of the rule is not something
41
+ this builder can draw yet, so it is shown as it reads"*, with a **Replace it**
42
+ button. Replacing is a thing a person DID, never a thing that happened to them
43
+ because a control looked empty — and until they press it, the clause they cannot
44
+ draw is still the one that saves.
45
+
46
+ `conditionIsSimple` and `conditionInWords` are exported, so every screen that
47
+ mounts the builder gets the same honesty rather than each deciding for itself.
48
+
49
+ ## 0.55.0
50
+
51
+ **Three things the bulk paste got wrong on its first real fifty rows.**
52
+
53
+ Proved headlessly on **Rincon Plumbing Co's September billing run** — fifty real
54
+ invoices, `INV-5100`…`INV-5149`, a `$1,250.50` and a `(285.00)` credit, two
55
+ cells deliberately wrong. The paste itself worked end to end: the preview
56
+ appeared with the store untouched, the money arrived as `1250.5` rather than the
57
+ sheet's string, the bracketed credit as `-285`, and the outcome read *"All 198
58
+ values are in the table — read back out of it, not just accepted"*, confirmed by
59
+ an independent read as the same identity. These are the three things that were
60
+ wrong with it anyway.
61
+
62
+ * **Every refusal said "Row 0" and named a raw column key.** `validateCell` and
63
+ the planner ask the same question, and for a cell on a row that already exists
64
+ the primitive asks first — so the refusal arrived already decided, with a
65
+ column id and no line, and the planner's correct "Row 12, Amount Due" could
66
+ only ever fire for an overflow row. The refused cells are folded back into the
67
+ block with their own values (design-system 0.31.0 keeps them) and the planner
68
+ judges the whole thing: one place deciding, one set of words, a line number and
69
+ the column's own name on every refusal. With fifty rows on a clipboard that is
70
+ the difference between a fixable cell and a shrug.
71
+ * **"This will change 28 Invoicess and create 22 new Invoicess."** The sentence
72
+ appended an "s" to `label_singular`, which for that table is already
73
+ "Invoices". A plural is a word a table knows (`label_plural`), never a rule
74
+ applied to another word.
75
+ * **Every pasted date drew one day early**, systematically, across all fifty.
76
+ `2026-09-01` parsed as an INSTANT is midnight UTC, and a Ventura grid renders
77
+ that as 31 August. A date field holds a DAY — the day the invoice was issued is
78
+ the same day in Ventura and in Berlin — so a pasted day is kept as that day,
79
+ and only a field that actually declares a time becomes an instant. A
80
+ spreadsheet's own format ("9/1/2026") keeps the day the reader can see, not the
81
+ UTC one.
82
+
83
+ **And the demo harness could not stand up in a fresh organization.** All four
84
+ `ensure*Field` helpers updated the Table's `fields` list BEFORE inserting the
85
+ Field definition, which `custom._claimed_column_guard` refuses outright — *"Records
86
+ UI Demo says it has a column called \"signed_by\", and there is no such field."*
87
+ The harness only worked in organizations provisioned before that guard landed.
88
+ The order is the fix; the guard stays.
89
+
90
+ Needs `@ai-matrx/design-system` 0.31.0.
91
+
92
+ ## 0.54.0
93
+
94
+ **The grid shows a column the panel beside it just added, without a reload.**
95
+
96
+ Measured on production 2026-09-21, Ridgeline Physical Therapy's patients table:
97
+ "Add field" succeeded, the panel confirmed the column with its own read-back and
98
+ closed — and the grid did not show it until the page was reloaded. The panel was
99
+ telling the truth; the grid next to it was drawing a table that no longer
100
+ existed.
101
+
102
+ The cause is not in this package's screens, and that is the point: the grid and
103
+ the field panel are siblings, each calling `useFields(tableId)`, each holding
104
+ its own copy, with nothing joining them. Fixing the pair that surfaced it would
105
+ have left the same staleness between every other pair — the rail and the grid,
106
+ the filter and the form builder. So the signal is `@ai-matrx/records` 0.39.0's
107
+ `tableShapeChanged`, which every shape-changing door announces and every reader
108
+ subscribes to, and this package simply inherits it.
109
+
110
+ `src/shape-changed.test.tsx` holds the five clauses at the pair a person
111
+ actually sees, against the real client through the real doors: a column added in
112
+ the panel appears in the grid beside it; every screen on that table re-reads,
113
+ not one; a screen on a DIFFERENT table is left alone (a signal that woke the
114
+ whole app would be a storm with a sensible name on it); the tick carries no data
115
+ and the listener re-reads through the door; and a retired column disappears the
116
+ same way. Four of the five are RED on 0.53.0's bytes.
117
+
118
+ Needs `@ai-matrx/records` 0.39.0.
119
+
3
120
  ## 0.53.0
4
121
 
5
122
  **Every card on every board said "Loading…", forever.**