@ai-matrx/records-ui 0.83.1 → 0.84.4

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,158 @@
1
1
  # Changelog — @ai-matrx/records-ui
2
2
 
3
+ ## 0.84.4 (unpublished — needs @ai-matrx/records 0.57.1 published first)
4
+
5
+ **The guide re-walk's small wrong things, each fixed as a class.** (lane RECORDS-UI-FIX,
6
+ 2026-09-23.)
7
+
8
+ * **Two records with one name are told apart in the linked-record picker.** Rincon's
9
+ Customers really holds two Patricia Marshes; the picker drew only the name, so the list
10
+ read as duplicates. New `tellApart(rows, nameOf)`: a colliding name carries the first of
11
+ its own columns that differs (an address), and search reads it too.
12
+ * **Charts no longer print their timing ("34.5 ms").** The number stays on the block as
13
+ `data-store-ms` for whoever measures dashboards.
14
+ * **The Bookings suggestion is English** ("a 30-minute appointment … put each one in Jobs",
15
+ never "a 30-minute appointments slot"). `bookingSuggestion` is exported.
16
+ * **Table Settings' Proposed box names no door by its code** and shows no baseless "0"; it
17
+ says proposals wait in the table's Inbox.
18
+ * **A record's history follows the writes on its page.** `HistoryPanel` re-reads on
19
+ `useRecordChangeRevision` (records 0.57.1). This was not the no-op-version class: the
20
+ store had the row, the panel never asked again.
21
+ * A refused value no longer lights the app's error pill — see records 0.57.1.
22
+ * Tests (red on 0.84.3): `two-customers-with-one-name-are-told-apart`,
23
+ `the-history-count-follows-the-writes`, `guide-rewalk-words`, and the reversed ms clause in
24
+ `demo/dashboard-canvas.test.tsx` (it had enshrined printing the timing).
25
+
26
+ **Also, in matrx-frontend (`features/sharing`):** the Share dialog's Access tab no longer
27
+ reads "Internal — readable inside the owning organization" over "Private — only you".
28
+
29
+ ## 0.84.3 (unpublished — rides on top of 0.84.2)
30
+
31
+ **After an import writes, the wizard is a report — never the same import again — and every
32
+ line it names is the line in the person's file.** (lane RECORDS-UI-FIX, VERIFIER-16 H1 + M8,
33
+ VERIFIER-15 M5.)
34
+
35
+ * **No second write of the same file.** A run that landed rows used to leave the pre-write
36
+ notice ("…Nothing has been written yet", now false) and a live "Import N rows" beside the
37
+ result. Once a file has been offered to the store — finished, stopped part-way, or turned
38
+ away as already imported — every pre-write step (what each record is called, the mapping,
39
+ the options, the rule notice, the Import button) is replaced by one sentence saying the
40
+ file was sent, and the report of what landed and what was refused stays. Another run
41
+ means choosing a file again.
42
+ * **Line numbers are the file's.** The store and the rule check number rows from 1 under the
43
+ header; the file has its header on line 1. New export `lineInYourFile(dataRow)` is used on
44
+ the column's refusal, the run's refused rows and past runs' refused rows — the `-3` on
45
+ line 3 is called line 3.
46
+ * **Nothing sits past the rail.** The mapping is one block per column (name, where it goes,
47
+ what it is, what would be refused, first values) instead of a 52rem row in a 26rem rail.
48
+ * **No machine word.** A column the table already has is named from its Field
49
+ (`fieldTypeLabel`), so a number reads "Number", never "range"; an unknown token is written
50
+ out, never shown raw.
51
+ * **Whole sentences.** `refusalLineForAPerson` ends the store's sentence before the remedy
52
+ ("…at least 0. Send this column…"). The report's "The 1 row that was refused is kept".
53
+ * Tests: new `src/the-import-after-a-write-is-a-report.test.tsx` (4, red on 0.84.1 bytes);
54
+ `import-asks-the-rules-first` now expects line 4 for the fourth line (it had enshrined the
55
+ off-by-one); `import-wizard` expects "is kept"; the F9 source guard now forbids a row wider
56
+ than the rail and keeps the 14rem "Goes to" floor.
57
+
58
+ **Consumer action:** none.
59
+
60
+ ## 0.84.2 (unpublished — rides on top of 0.84.1)
61
+
62
+ **A booking link opens that booking page, and the table list's empty sections stop
63
+ describing a product that does not exist.** (lane HUB-FIX, VERIFIER-16 M4 + M6.)
64
+
65
+ * `BookingSlots` gains `activeBookingId`: the page a link named is marked (`data-linked`) and
66
+ scrolled to; a page the rail does not list says `BOOKING_NOT_HERE_LINE`, never a different
67
+ page. `TablePage` hands it `?item=` when `?rail=bookings`.
68
+ * `LANE_EMPTY.mine` said "New table makes one that only you can see" and
69
+ `LANE_EMPTY.organization` said "a table you make is yours until you change its visibility
70
+ to internal" — New table makes an internal table, and no screen here changes visibility.
71
+ Both now say what is true.
72
+ * New export `BOOKING_NOT_HERE_LINE`. Tests: `rail-deep-link.test.tsx` +1,
73
+ `visibility-lanes.test.tsx` +1.
74
+
75
+ **Consumer action (matrx-frontend):** the hub's Bookings row links
76
+ `/data-v2/<table>?rail=bookings&item=<form_id>` (it already can; the item is marked from
77
+ this version).
78
+
79
+ ## 0.84.1 (unpublished — lands with the 2026-09-24 window)
80
+
81
+ **A blank the store can explain is never drawn as a dash.** (lane OLD-TABLES-4, VERIFIER-16.)
82
+ `renderValue` — the one value renderer for the grid, the peek and the forms — now says two
83
+ things a dash used to hide:
84
+
85
+ * **A relation whose record no longer exists** reads *"The record this pointed at no longer
86
+ exists"* (the id it held is in the tooltip). The move of an older table lands such a cell
87
+ empty and keeps the id on the record's provenance entry, `_sources.<ptr>.unresolved.<key>`;
88
+ `unresolvedFor(document, key)` is exported for any other reader of that fact.
89
+ * **A worked-out column with no formula in it yet** reads *"Worked out once its formula is in
90
+ place"* instead of an answer of nothing.
91
+
92
+ Consumer action: none.
93
+
94
+ **The field editor sets the three column settings the older grid carried.** (lane
95
+ STORE-RULE-GAPS.) Existing controls only, no new primitive:
96
+
97
+ * **A pattern's example** — a box beside a "Looks like" check (`rule.example`). A refused value
98
+ is told "Enter it like 949-555-0142.": `refusalForAPerson` reads the example from the store's
99
+ `detail.example` as data, so an example shaped like an identifier ("SKU-12") is never dropped
100
+ by the machine-identity filter.
101
+ * **A length's shortest** — the "Number of characters" check (was "No longer than") has a
102
+ *fewest* box beside its *most* (`rule.min`).
103
+ * **A choice list that takes other values** — one tick, "A value that is not one of the choices
104
+ is added to them" (`allow_other`), on select / multi-select columns only; unticking sends false.
105
+
106
+ Consumer action: none. Needs `@ai-matrx/records` with `FieldRule.example` / `.min` and
107
+ `allow_other` (aidream `290411764c`) and, for the store to honour them, matrx-frontend
108
+ `storerulegaps_an_example_a_shortest_length_and_other_choices.sql` on the database.
109
+
110
+ ## 0.84.0
111
+
112
+ **A refusal is said once, with the doors that fit it, and a change a person made is kept or
113
+ said — never dropped.** (lane RECORDS-UI-FIX, VERIFIER-15 H2, H3, M3, M4, M6, M7.)
114
+
115
+ * **The grid's cell refusal is the one notice.** A rule refusal (`-3` in a column "at least
116
+ 0") used to draw a small red line with *Try again* (which re-sent the refused value) and
117
+ *Keep theirs* (conflict wording when nobody else wrote). It is now `RefusalNotice` with
118
+ **Keep editing** — the cell reopens holding `-3`, the reason still beside it — and
119
+ **Discard**. *Try again* / *Keep theirs* appear only on a real version conflict, beside
120
+ the other person's value. A tick box's refusal carries Discard.
121
+ * **The record form says a refusal once, with Keep editing / Discard, and before Save.** The
122
+ mirror's per-column notice is the store's rule, so the store's copy under the form is no
123
+ longer drawn beside it; the mirror speaks the moment a changed column would be refused.
124
+ What was typed survives the (slower) version read landing late. An edit sends only the
125
+ columns the person changed, and a Save with nothing changed writes nothing.
126
+ * **A board's layout or grouping change is kept, or said.** Every view save carried a version
127
+ read from the view's history, which can stop short of the record, so every Kanban / Group
128
+ by press was refused `stale_write` and dropped in silence. New `saveViewPatch` (the one
129
+ view-save door) writes on the version the refusal names; a save still refused is said
130
+ through `RefusalNotice` with Try again / Discard.
131
+ * **"Someone else wrote first" only when somebody did.** The store's `contested_fields`
132
+ carries each patched column's current value; when every one is still what the screen
133
+ started from, the write goes once more on the winning version (the grid cell session, the
134
+ record form and saved views apply the same rule — internal `updateOnTheWinningVersion`).
135
+ * **The next digest summary is never in the past.** New export `nextSummaryAt(subscription,
136
+ now)` carries a passed due time forward by whole periods to the first slot after now,
137
+ keeping the store's alignment (tested at a fixed clock).
138
+ * **Table Settings never cuts a field name to two letters** — the name wraps with a readable
139
+ minimum and the row wraps its controls first.
140
+ * **On a phone the table's rail is a sheet over the table** — below the design system's
141
+ breakpoint (`useIsMobile`, 768px) it renders through the canonical `BottomSheet`, the way
142
+ `Dialog` and `CommandDialog` already do; dragging it down closes the rail.
143
+ * Tests (each shown failing on the prior bytes): `src/a-refused-cell-keeps-what-you-typed`,
144
+ `src/a-form-refusal-is-said-once-with-its-doors`, `src/a-board-layout-change-is-kept`,
145
+ `src/the-next-summary-is-never-in-the-past`, `src/a-rail-on-a-phone-is-a-sheet`, and a
146
+ new clause in `src/TableSettings.hooks.test`.
147
+
148
+ **Store-side, reported to the chair (not in this package):** `custom.record_update` of an
149
+ unchanged value moves `version` and writes no history row (reproduced on the dev clone), and
150
+ the digest runner computes the next slot from the last summary SENT, so an empty window
151
+ freezes it.
152
+
153
+ **Consumer action (matrx-frontend):** none required — install picks it up. A host that
154
+ shows a digest's next time outside `SubscriptionsPanel` should use `nextSummaryAt`.
155
+
3
156
  ## 0.83.1
4
157
 
5
158
  **A table shared by link is in the World lane, not Community.** (lane HUB-FIX, chair ruling