@ai-matrx/records-ui 0.69.0 → 0.70.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 +27 -0
- package/dist/index.cjs +60 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +74 -43
- package/dist/index.d.ts +74 -43
- package/dist/index.js +61 -17
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/records-ui
|
|
2
2
|
|
|
3
|
+
## 0.70.0
|
|
4
|
+
|
|
5
|
+
**The bar that said four now opens four.** (lane DRILL.)
|
|
6
|
+
|
|
7
|
+
* **`TablePage` takes a `filter`** — the store's one `RecordFilter` — and hands it to the grid
|
|
8
|
+
AND the board, so switching layout after a drill-through does not quietly widen back to the
|
|
9
|
+
whole table. It is a question for this visit, like `activeView` and `activeGroupField`, and
|
|
10
|
+
is never written onto the saved view. `Grid` and `ViewSwitcher` (and `useViewRecords`) take
|
|
11
|
+
it too; the narrowing happens in the STORE, never in the browser, because this screen holds
|
|
12
|
+
one page and a browser-side filter would drop every match on page two.
|
|
13
|
+
* **`cameFromLine` says the narrow thing, and means it.** TAILS-6 shipped *"This is every
|
|
14
|
+
record grouped into the same columns the chart used — not only the ones that number
|
|
15
|
+
counted"*, which was TRUE and useless: no door took a filter. It now reads *"These are only
|
|
16
|
+
the records that number counted: Status is Cancelled. Everything else in this table is being
|
|
17
|
+
held back"*, and it still refuses to claim narrowing when no question came with the click.
|
|
18
|
+
* **`filterInWords`** turns the question into the words of the person whose business it is —
|
|
19
|
+
the Field's own name through the same `fieldName` the column headers use, never a column
|
|
20
|
+
key. `null` becomes "Status is not filled in"; a window becomes "from … up to …", because
|
|
21
|
+
the store's windows are half-open and "to 2026-02-01" would read as including February 1st.
|
|
22
|
+
* **`DigestScheduler.filters` is a `RecordFilter`**, and `DashboardCanvas`'s
|
|
23
|
+
`as Record<string, unknown>` is gone — that cast was the seam where the dashboard's filter,
|
|
24
|
+
the saved view it schedules over and the drill-through it opens could have drifted apart.
|
|
25
|
+
* **Guard `a-number-opens-only-its-own-rows.test.tsx`** asserts the DOOR the page opened and
|
|
26
|
+
the argument it carried, and refuses by name the moment anything opens the unfiltered
|
|
27
|
+
`read_records` while holding a filter. Shown RED on the pre-fix bytes (four clauses,
|
|
28
|
+
including the old sentence) and green on these.
|
|
29
|
+
|
|
3
30
|
## 0.69.0
|
|
4
31
|
|
|
5
32
|
**She can make the one that is missing, from where she is looking for it.** (lane TAILS-7.)
|
package/dist/index.cjs
CHANGED
|
@@ -3557,6 +3557,7 @@ var NO_COLUMNS_WHY = "A column is what a record holds \u2014 a name, a date, an
|
|
|
3557
3557
|
function Grid({
|
|
3558
3558
|
tableId,
|
|
3559
3559
|
pageSize = 50,
|
|
3560
|
+
filter,
|
|
3560
3561
|
onOpenRecord,
|
|
3561
3562
|
onAddField,
|
|
3562
3563
|
onNewRecordForm,
|
|
@@ -3572,7 +3573,7 @@ function Grid({
|
|
|
3572
3573
|
const table = (0, import_react21.useTable)(tableId);
|
|
3573
3574
|
const fields = (0, import_react21.useFields)(tableId);
|
|
3574
3575
|
const [page, setPage] = (0, import_react20.useState)(0);
|
|
3575
|
-
const records = (0, import_react21.useRecords)(tableId, { pageSize, page });
|
|
3576
|
+
const records = (0, import_react21.useRecords)(tableId, { pageSize, page, ...filter ? { filter } : {} });
|
|
3576
3577
|
const rights = useTableRights(table.data);
|
|
3577
3578
|
const rows = (0, import_react20.useMemo)(() => records.data?.rows ?? [], [records.data]);
|
|
3578
3579
|
const rowIds = (0, import_react20.useMemo)(() => rows.map((row) => row.id), [rows]);
|
|
@@ -7321,9 +7322,12 @@ function unplacedName(record, field, labels) {
|
|
|
7321
7322
|
// src/ViewSwitcher.tsx
|
|
7322
7323
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
7323
7324
|
var NO_FIELDS = [];
|
|
7324
|
-
function useViewRecords(view, pageSize = 200) {
|
|
7325
|
+
function useViewRecords(view, pageSize = 200, filter) {
|
|
7325
7326
|
const client = (0, import_react49.useRecordsClient)();
|
|
7326
|
-
const table = (0, import_react49.useRecords)(view.ruleId ? null : view.subject, {
|
|
7327
|
+
const table = (0, import_react49.useRecords)(view.ruleId ? null : view.subject, {
|
|
7328
|
+
pageSize,
|
|
7329
|
+
...filter ? { filter } : {}
|
|
7330
|
+
});
|
|
7327
7331
|
const [ruled, setRuled] = (0, import_react48.useState)({
|
|
7328
7332
|
rows: [],
|
|
7329
7333
|
loading: Boolean(view.ruleId),
|
|
@@ -7378,6 +7382,7 @@ function ViewSwitcher({
|
|
|
7378
7382
|
onNewRecordForm,
|
|
7379
7383
|
onAskWhoChanged,
|
|
7380
7384
|
pageSize = 200,
|
|
7385
|
+
filter,
|
|
7381
7386
|
className
|
|
7382
7387
|
}) {
|
|
7383
7388
|
const [layout, setLayout] = (0, import_react48.useState)(view.layout);
|
|
@@ -7415,6 +7420,7 @@ function ViewSwitcher({
|
|
|
7415
7420
|
{
|
|
7416
7421
|
tableId: view.subject,
|
|
7417
7422
|
pageSize,
|
|
7423
|
+
...filter ? { filter } : {},
|
|
7418
7424
|
...local.presentation ?? view.presentation ? { presentation: local.presentation ?? view.presentation } : {},
|
|
7419
7425
|
...onViewChange ? { onPresentationChange: (next) => change({ presentation: next }) } : {},
|
|
7420
7426
|
...onOpenRecord ? { onOpenRecord } : {},
|
|
@@ -7426,6 +7432,7 @@ function ViewSwitcher({
|
|
|
7426
7432
|
{
|
|
7427
7433
|
view: { ...view, ...local, layout },
|
|
7428
7434
|
pageSize,
|
|
7435
|
+
...filter ? { filter } : {},
|
|
7429
7436
|
onChange: change,
|
|
7430
7437
|
remembered: Boolean(onViewChange),
|
|
7431
7438
|
...onOpenRecord ? { onOpenRecord } : {},
|
|
@@ -7473,13 +7480,14 @@ function boardColumnChoice(fields, chosenKey, stage) {
|
|
|
7473
7480
|
function Board({
|
|
7474
7481
|
view,
|
|
7475
7482
|
pageSize,
|
|
7483
|
+
filter,
|
|
7476
7484
|
onChange,
|
|
7477
7485
|
remembered,
|
|
7478
7486
|
onOpenRecord,
|
|
7479
7487
|
onMoved
|
|
7480
7488
|
}) {
|
|
7481
7489
|
const fields = (0, import_react49.useFields)(view.subject);
|
|
7482
|
-
const records = useViewRecords(view, pageSize);
|
|
7490
|
+
const records = useViewRecords(view, pageSize, filter);
|
|
7483
7491
|
const stage = useStageField(view.subject);
|
|
7484
7492
|
if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(RefusalNotice, { error: fields.error });
|
|
7485
7493
|
if (records.error) return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(RefusalNotice, { error: records.error });
|
|
@@ -13000,14 +13008,20 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, className }) {
|
|
|
13000
13008
|
rights.admin ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_design_system44.Button, { size: "sm", variant: "ghost", onClick: () => void remove(board), children: "Delete" }) : null
|
|
13001
13009
|
] }) : null
|
|
13002
13010
|
] }),
|
|
13003
|
-
board && scheduling ?
|
|
13004
|
-
|
|
13005
|
-
|
|
13006
|
-
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
|
|
13010
|
-
|
|
13011
|
+
board && scheduling ? (
|
|
13012
|
+
// ONE SHAPE, SO NO CAST. The dashboard's own filter, the saved view it
|
|
13013
|
+
// schedules over and the drill-through it opens are all the same
|
|
13014
|
+
// `RecordFilter`; the `as Record<string, unknown>` that used to be here
|
|
13015
|
+
// was the seam where they could have drifted.
|
|
13016
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
13017
|
+
DigestScheduler,
|
|
13018
|
+
{
|
|
13019
|
+
tableId,
|
|
13020
|
+
subjectName: board.name,
|
|
13021
|
+
...filter ? { filters: filter } : {},
|
|
13022
|
+
onClose: () => setScheduling(false)
|
|
13023
|
+
}
|
|
13024
|
+
)
|
|
13011
13025
|
) : null,
|
|
13012
13026
|
board ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
13013
13027
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
@@ -15007,9 +15021,35 @@ var import_react111 = require("react");
|
|
|
15007
15021
|
var import_react112 = require("@ai-matrx/records/react");
|
|
15008
15022
|
var import_design_system54 = require("@ai-matrx/design-system");
|
|
15009
15023
|
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
15010
|
-
function
|
|
15011
|
-
const
|
|
15012
|
-
|
|
15024
|
+
function filterInWords(filter, fields) {
|
|
15025
|
+
const nameOf = (key) => {
|
|
15026
|
+
const field = fields.find((f) => f.key === key);
|
|
15027
|
+
return field ? fieldName(field) : humanize(key);
|
|
15028
|
+
};
|
|
15029
|
+
const parts = Object.keys(filter).map((key) => {
|
|
15030
|
+
const value = filter[key];
|
|
15031
|
+
if (value === null || value === void 0) return `${nameOf(key)} is not filled in`;
|
|
15032
|
+
if (typeof value === "object") {
|
|
15033
|
+
const from = (value.from ?? "").toString().trim();
|
|
15034
|
+
const to = (value.to ?? "").toString().trim();
|
|
15035
|
+
if (from !== "" && to !== "") return `${nameOf(key)} from ${from} up to ${to}`;
|
|
15036
|
+
if (from !== "") return `${nameOf(key)} from ${from} onwards`;
|
|
15037
|
+
if (to !== "") return `${nameOf(key)} up to ${to}`;
|
|
15038
|
+
return `${nameOf(key)} in a period nobody named`;
|
|
15039
|
+
}
|
|
15040
|
+
return `${nameOf(key)} is ${String(value)}`;
|
|
15041
|
+
});
|
|
15042
|
+
if (parts.length === 0) return "";
|
|
15043
|
+
if (parts.length === 1) return parts[0];
|
|
15044
|
+
return `${parts.slice(0, -1).join(", ")} and ${parts[parts.length - 1]}`;
|
|
15045
|
+
}
|
|
15046
|
+
function cameFromLine(label, groupField, question) {
|
|
15047
|
+
const asked = (question ?? "").trim();
|
|
15048
|
+
if (asked === "") {
|
|
15049
|
+
const grouped = groupField ? " grouped into the same columns the chart used" : "";
|
|
15050
|
+
return `You came here from \u201C${label}\u201D. This is every record in this table${grouped} \u2014 that number was counted over all of them.`;
|
|
15051
|
+
}
|
|
15052
|
+
return `You came here from \u201C${label}\u201D. These are only the records that number counted: ${asked}. Everything else in this table is being held back \u2014 clear the filter to see all of it.`;
|
|
15013
15053
|
}
|
|
15014
15054
|
var TABLE_NOT_REACHABLE = "This table is not in the organization you are working in, so there is nothing here to show. Switch to the organization that owns it and open it again \u2014 or it may have been deleted.";
|
|
15015
15055
|
var DEFAULT_VIEW_NAME = "All records";
|
|
@@ -15056,11 +15096,14 @@ function TablePage({
|
|
|
15056
15096
|
onViewChanged,
|
|
15057
15097
|
activeGroupField,
|
|
15058
15098
|
cameFrom,
|
|
15099
|
+
filter,
|
|
15059
15100
|
className
|
|
15060
15101
|
}) {
|
|
15061
15102
|
const client = (0, import_react112.useRecordsClient)();
|
|
15062
15103
|
const table = (0, import_react112.useTable)(tableId);
|
|
15063
15104
|
const rights = useTableRights(table.data);
|
|
15105
|
+
const pageFields = (0, import_react112.useFields)(filter ? tableId : null);
|
|
15106
|
+
const askedInWords = filter ? filterInWords(filter, pageFields.data ?? []) : null;
|
|
15064
15107
|
const organizationId = (0, import_react112.useRecordsClient)().config.organizationId;
|
|
15065
15108
|
const [view, setView] = (0, import_react111.useState)(null);
|
|
15066
15109
|
const opening = openingRail(activeRecordId);
|
|
@@ -15254,7 +15297,7 @@ function TablePage({
|
|
|
15254
15297
|
{
|
|
15255
15298
|
"data-testid": "came-from-a-number",
|
|
15256
15299
|
className: "rounded-md border px-3 py-2 text-xs leading-relaxed text-muted-foreground",
|
|
15257
|
-
children: cameFromLine(cameFrom, activeGroupField ?? null)
|
|
15300
|
+
children: cameFromLine(cameFrom, activeGroupField ?? null, askedInWords)
|
|
15258
15301
|
}
|
|
15259
15302
|
) : null,
|
|
15260
15303
|
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
@@ -15268,6 +15311,7 @@ function TablePage({
|
|
|
15268
15311
|
...activeGroupField ? { groupField: activeGroupField } : {}
|
|
15269
15312
|
},
|
|
15270
15313
|
pageSize,
|
|
15314
|
+
...filter ? { filter } : {},
|
|
15271
15315
|
onLayoutChange: (layout) => {
|
|
15272
15316
|
setLayoutFromLink(layout);
|
|
15273
15317
|
onViewChanged?.(layout);
|