@ai-matrx/records-ui 0.51.0 → 0.53.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,84 @@
1
1
  # Changelog — @ai-matrx/records-ui
2
2
 
3
+ ## 0.53.0
4
+
5
+ **Every card on every board said "Loading…", forever.**
6
+
7
+ Birchwood Avenue Renovation is a whole-house remodel run out of a spare bedroom.
8
+ Her quotes board, grouped by Quote stage, had the counts exactly right — Accepted
9
+ 6, Expired 1, Pending 6, Rejected 1, No value 1, off her real quotes — and all
10
+ fifteen cards under those headings read "Loading…" and never resolved. No error,
11
+ no refusal, no spinner that ever stopped. She could count her quotes and could
12
+ not open one.
13
+
14
+ The cause was one missing argument. `scalarText` draws "Loading…" for an id it
15
+ has no resolver for, and `Card` called it with no resolver at all, so a title
16
+ Field of type `list` or `relation` could never resolve on any card, ever — and
17
+ Birchwood's title field is `room`, a relation to her rooms table. `Kanban` asks
18
+ the resolver for the GROUPING field, which is precisely why the headings read
19
+ "Accepted" while the cards beneath them read "Loading…": two halves of one board,
20
+ one asking and one not.
21
+
22
+ `Card` is the card of the **kanban, the calendar and the gallery**, so one
23
+ argument broke three layouts and one fix closes all three. The component that
24
+ draws the value now declares the Field it is about to draw, which is also what
25
+ makes a future surface unable to reintroduce this by forgetting; `want` is keyed
26
+ by Field id, so two hundred cards still ask once.
27
+
28
+ **And a card that cannot load now says why.** Declaring the Field is what lets
29
+ the resolver SETTLE it. Once settled, an id it did not return is chased one at a
30
+ time and comes back either as the record's own name or as the store's own
31
+ sentence for a record this reader may not open
32
+ (`platform.relation_withheld_label()`). "Loading…" is now only ever true.
33
+
34
+ `src/card-names-what-it-draws.test.tsx` — three clauses, two shown RED on
35
+ 0.52.0's bytes ("Loading…") and green on these.
36
+
37
+ ## 0.52.0
38
+
39
+ **Four things this package could make and no screen could reach: a form, a
40
+ booking page, a client portal and a scheduled summary.**
41
+
42
+ The product walk of 2026-09-21 opened a real table filled with a real business's
43
+ records. The Forms, Bookings and Portals rails each said the same thing — *none
44
+ yet, ask an agent for one in a sentence* — and offered nothing else to press;
45
+ dashboards worked and nothing could schedule one. A person who did not know what
46
+ to say to an agent was finished. The agent path is the faster one; it was never
47
+ meant to be the only one.
48
+
49
+ * **`BuildOrAsk`** — the shared empty state every builder now uses. Two buttons,
50
+ one row, every rail identical, the agent named first because it is faster and
51
+ the builder beside it because it always works. "Ask an agent" is the host's new
52
+ `onAskForOne` port and is **absent, never greyed**, when a host has not bound
53
+ it — only a server can honestly speak as an agent.
54
+ * **Forms** — `FormBuilder` opens in place in the Forms rail. It has written the
55
+ same `custom.anon_form` row through the same `custom.form_declare` door since
56
+ 0.33.0 and was reachable from nowhere.
57
+ * **`BookingBuilder`** — Calendly's four decisions: how long an appointment is,
58
+ which hours of the week you are free, the gap kept between them, and what the
59
+ person sees after booking. It declares through `custom.booking_declare` and
60
+ shows the availability the STORE normalised, so the builder and the visitor's
61
+ picker cannot hold two ideas of what is free. `slot`, `status` and
62
+ `booked_with` are never offered — the door refuses a question naming any of
63
+ the three, and an always-refused control is a dead control.
64
+ * **`PortalBuilder`** — four questions, and the second is the product: which
65
+ Table holds the clients, which Field on each exposed Table NAMES one of them,
66
+ what they may read, and separately what they may change. A Table with no
67
+ relation pointing at the client Table gets no field picker at all and the
68
+ remedy is named, because "only theirs" has to be answerable before anything is
69
+ published. Re-stating replaces what a portal shows and the screen says so
70
+ above Save; the invitation is a separate act and the door's own sentence is
71
+ shown verbatim, so "invited" is never read as "signed in".
72
+ * **`DigestScheduler`** — "send this every Monday at 8 to these people", mounted
73
+ on the dashboard and in the notifications rail. It saves the thing in front of
74
+ the person as a view (`custom.view_declare`) and writes the subscription over
75
+ it (`custom.subscription_declare`). No new cron and no second notifier: the one
76
+ pg_cron tick and `communication.notification` do the work. "These people" is
77
+ one subscription each, deliberately — admission is tested as the SUBSCRIBER, so
78
+ three recipients is three tests and three summaries, each holding only what
79
+ that person may see — and the per-person outcome is shown, so a partial success
80
+ is never reported as a whole one.
81
+
3
82
  ## 0.51.0
4
83
 
5
84
  **Paste fifty rows out of a spreadsheet, see what they will become, and only