@ai-matrx/records-ui 0.101.30 → 0.101.33
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 +18 -0
- package/dist/index.cjs +78 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +78 -22
- package/dist/index.js.map +1 -1
- package/dist/pickers.cjs +84 -17
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.js +71 -4
- package/dist/pickers.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -584,8 +584,16 @@ interface ReferenceChipRef {
|
|
|
584
584
|
* archived (chair ruling B3-21), so the chip still names it and draws the archived state.
|
|
585
585
|
*/
|
|
586
586
|
archived?: boolean | undefined;
|
|
587
|
+
/** The record's (or its table's) icon — an emoji or short glyph — when the host knows one. */
|
|
588
|
+
icon?: string | null | undefined;
|
|
587
589
|
}
|
|
588
590
|
interface RecordsUiHost {
|
|
591
|
+
/**
|
|
592
|
+
* Draws an icon kept as a NAME ("Briefcase" — how the store keeps an icon a person picked from the
|
|
593
|
+
* icon list). A relation cell in an embedded table wears its record's icon; an emoji is drawn as
|
|
594
|
+
* text and a name only through this port. Unbound (or `null` back), the page glyph stands in.
|
|
595
|
+
*/
|
|
596
|
+
renderIcon?: ((name: string) => ReactNode) | undefined;
|
|
589
597
|
/**
|
|
590
598
|
* TEMPORARY (one-grid merge, steps 5-8). Which table grid draws: `classic` — the default Grid
|
|
591
599
|
* as it shipped in 0.86; `merged` — the same grid with the older /data grid's control layer on
|
|
@@ -2142,7 +2150,8 @@ declare const NO_COLUMNS_WHY: string;
|
|
|
2142
2150
|
* ordered by the table's own sort exactly as before, and offers no Reorder.
|
|
2143
2151
|
*/
|
|
2144
2152
|
interface GridViewOrder {
|
|
2145
|
-
|
|
2153
|
+
/** The saved view's id; `null` for a view a host holds inline (it still carries its own `sorts`). */
|
|
2154
|
+
viewId: Uuid | null;
|
|
2146
2155
|
/** The view's own order word (`definition.order`). */
|
|
2147
2156
|
order: ViewOrder;
|
|
2148
2157
|
/** The view's own sort (`definition.sorts`) — where a sorted view OPENS, over the table's. */
|
|
@@ -2324,6 +2333,11 @@ interface ViewReading {
|
|
|
2324
2333
|
*/
|
|
2325
2334
|
type LabelLookup = ((field: Field$1, id: string) => string | null) & {
|
|
2326
2335
|
archived?: (field: Field$1, id: string) => boolean;
|
|
2336
|
+
/** The linked record's own icon, and its table's icon for one that has none (same call as the words). */
|
|
2337
|
+
icons?: (field: Field$1, id: string) => {
|
|
2338
|
+
icon: string | null;
|
|
2339
|
+
tableIcon: string | null;
|
|
2340
|
+
} | undefined;
|
|
2327
2341
|
};
|
|
2328
2342
|
/**
|
|
2329
2343
|
* HOW LONG A CELL MAY SAY "Loading…" BEFORE IT HAS TO SAY WHAT IT IS WAITING
|
|
@@ -3372,6 +3386,7 @@ declare function useChoiceNudge(enabled?: boolean): ChoiceNudge | null;
|
|
|
3372
3386
|
interface EmbeddedLook {
|
|
3373
3387
|
blankEmpty: boolean;
|
|
3374
3388
|
choiceDot: boolean;
|
|
3389
|
+
plainRelation: boolean;
|
|
3375
3390
|
}
|
|
3376
3391
|
|
|
3377
3392
|
/** The envelope for one key, when the document carries one. */
|
package/dist/index.d.ts
CHANGED
|
@@ -584,8 +584,16 @@ interface ReferenceChipRef {
|
|
|
584
584
|
* archived (chair ruling B3-21), so the chip still names it and draws the archived state.
|
|
585
585
|
*/
|
|
586
586
|
archived?: boolean | undefined;
|
|
587
|
+
/** The record's (or its table's) icon — an emoji or short glyph — when the host knows one. */
|
|
588
|
+
icon?: string | null | undefined;
|
|
587
589
|
}
|
|
588
590
|
interface RecordsUiHost {
|
|
591
|
+
/**
|
|
592
|
+
* Draws an icon kept as a NAME ("Briefcase" — how the store keeps an icon a person picked from the
|
|
593
|
+
* icon list). A relation cell in an embedded table wears its record's icon; an emoji is drawn as
|
|
594
|
+
* text and a name only through this port. Unbound (or `null` back), the page glyph stands in.
|
|
595
|
+
*/
|
|
596
|
+
renderIcon?: ((name: string) => ReactNode) | undefined;
|
|
589
597
|
/**
|
|
590
598
|
* TEMPORARY (one-grid merge, steps 5-8). Which table grid draws: `classic` — the default Grid
|
|
591
599
|
* as it shipped in 0.86; `merged` — the same grid with the older /data grid's control layer on
|
|
@@ -2142,7 +2150,8 @@ declare const NO_COLUMNS_WHY: string;
|
|
|
2142
2150
|
* ordered by the table's own sort exactly as before, and offers no Reorder.
|
|
2143
2151
|
*/
|
|
2144
2152
|
interface GridViewOrder {
|
|
2145
|
-
|
|
2153
|
+
/** The saved view's id; `null` for a view a host holds inline (it still carries its own `sorts`). */
|
|
2154
|
+
viewId: Uuid | null;
|
|
2146
2155
|
/** The view's own order word (`definition.order`). */
|
|
2147
2156
|
order: ViewOrder;
|
|
2148
2157
|
/** The view's own sort (`definition.sorts`) — where a sorted view OPENS, over the table's. */
|
|
@@ -2324,6 +2333,11 @@ interface ViewReading {
|
|
|
2324
2333
|
*/
|
|
2325
2334
|
type LabelLookup = ((field: Field$1, id: string) => string | null) & {
|
|
2326
2335
|
archived?: (field: Field$1, id: string) => boolean;
|
|
2336
|
+
/** The linked record's own icon, and its table's icon for one that has none (same call as the words). */
|
|
2337
|
+
icons?: (field: Field$1, id: string) => {
|
|
2338
|
+
icon: string | null;
|
|
2339
|
+
tableIcon: string | null;
|
|
2340
|
+
} | undefined;
|
|
2327
2341
|
};
|
|
2328
2342
|
/**
|
|
2329
2343
|
* HOW LONG A CELL MAY SAY "Loading…" BEFORE IT HAS TO SAY WHAT IT IS WAITING
|
|
@@ -3372,6 +3386,7 @@ declare function useChoiceNudge(enabled?: boolean): ChoiceNudge | null;
|
|
|
3372
3386
|
interface EmbeddedLook {
|
|
3373
3387
|
blankEmpty: boolean;
|
|
3374
3388
|
choiceDot: boolean;
|
|
3389
|
+
plainRelation: boolean;
|
|
3375
3390
|
}
|
|
3376
3391
|
|
|
3377
3392
|
/** The envelope for one key, when the document carries one. */
|
package/dist/index.js
CHANGED
|
@@ -1844,10 +1844,10 @@ function shown(value) {
|
|
|
1844
1844
|
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
1845
1845
|
return null;
|
|
1846
1846
|
}
|
|
1847
|
-
function tellApart(rows,
|
|
1847
|
+
function tellApart(rows, nameOf2) {
|
|
1848
1848
|
const byName = /* @__PURE__ */ new Map();
|
|
1849
1849
|
for (const row of rows) {
|
|
1850
|
-
const name =
|
|
1850
|
+
const name = nameOf2(row.id).trim().toLowerCase();
|
|
1851
1851
|
byName.set(name, [...byName.get(name) ?? [], row]);
|
|
1852
1852
|
}
|
|
1853
1853
|
const out = /* @__PURE__ */ new Map();
|
|
@@ -2455,6 +2455,7 @@ function RecordLabelProvider({ children }) {
|
|
|
2455
2455
|
const client = useRecordsClient3();
|
|
2456
2456
|
const [names, setNames] = useState7({});
|
|
2457
2457
|
const [archivedRefs, setArchivedRefs] = useState7({});
|
|
2458
|
+
const [iconsOf, setIconsOf] = useState7({});
|
|
2458
2459
|
const [settled, setSettled] = useState7({});
|
|
2459
2460
|
const [waitingLines, setWaitingLines] = useState7({});
|
|
2460
2461
|
const asked3 = useRef3(/* @__PURE__ */ new Set());
|
|
@@ -2537,6 +2538,7 @@ function RecordLabelProvider({ children }) {
|
|
|
2537
2538
|
void (async () => {
|
|
2538
2539
|
const learned = {};
|
|
2539
2540
|
const archivedNow = {};
|
|
2541
|
+
const iconsNow = {};
|
|
2540
2542
|
await Promise.all(
|
|
2541
2543
|
batch.map(async ({ field: field2, ids }) => {
|
|
2542
2544
|
const wanted = [...ids];
|
|
@@ -2549,10 +2551,12 @@ function RecordLabelProvider({ children }) {
|
|
|
2549
2551
|
learned[id] = !result.ok ? UNREAD_RECORD_LABEL : typeof words2 === "string" && words2 !== "" ? words2 : WITHHELD_RECORD_LABEL;
|
|
2550
2552
|
}
|
|
2551
2553
|
if (result.ok) for (const id of result.archived ?? []) archivedNow[`${field2.id}:${id}`] = true;
|
|
2554
|
+
if (result.ok) for (const [id, pair] of Object.entries(result.icons ?? {})) iconsNow[id] = pair;
|
|
2552
2555
|
})
|
|
2553
2556
|
);
|
|
2554
2557
|
setNames((current) => ({ ...current, ...learned }));
|
|
2555
2558
|
if (Object.keys(archivedNow).length > 0) setArchivedRefs((current) => ({ ...current, ...archivedNow }));
|
|
2559
|
+
if (Object.keys(iconsNow).length > 0) setIconsOf((current) => ({ ...current, ...iconsNow }));
|
|
2556
2560
|
for (const { field: field2 } of batch) stopWaitClock(field2.id);
|
|
2557
2561
|
})();
|
|
2558
2562
|
}, [client, stopWaitClock]);
|
|
@@ -2600,9 +2604,10 @@ function RecordLabelProvider({ children }) {
|
|
|
2600
2604
|
() => {
|
|
2601
2605
|
const answer = ((field2, id) => lookupWords(field2, id));
|
|
2602
2606
|
answer.archived = (field2, id) => archivedRefs[`${field2.id}:${id}`] === true;
|
|
2607
|
+
answer.icons = (_field, id) => iconsOf[id];
|
|
2603
2608
|
return answer;
|
|
2604
2609
|
},
|
|
2605
|
-
[lookupWords, archivedRefs]
|
|
2610
|
+
[lookupWords, archivedRefs, iconsOf]
|
|
2606
2611
|
);
|
|
2607
2612
|
const waiting = useCallback2((field2) => waitingLines[field2.id] ?? null, [waitingLines]);
|
|
2608
2613
|
const value = useMemo5(() => ({ lookup, want, waiting }), [lookup, want, waiting]);
|
|
@@ -5157,7 +5162,7 @@ import { Badge as Badge5, cn as cn17 } from "@ai-matrx/design-system";
|
|
|
5157
5162
|
|
|
5158
5163
|
// src/embeddedLook.tsx
|
|
5159
5164
|
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
5160
|
-
var EMBEDDED_LOOK = { blankEmpty: true, choiceDot: true };
|
|
5165
|
+
var EMBEDDED_LOOK = { blankEmpty: true, choiceDot: true, plainRelation: true };
|
|
5161
5166
|
var EmbeddedLookContext = createContext4(null);
|
|
5162
5167
|
var EmbeddedLookProvider = EmbeddedLookContext.Provider;
|
|
5163
5168
|
function useEmbeddedLook() {
|
|
@@ -5173,6 +5178,7 @@ var EMBEDDED_TABLE_CLASS = [
|
|
|
5173
5178
|
"[&_thead_th]:border-border",
|
|
5174
5179
|
"[&_thead_th:last-child]:border-r-0"
|
|
5175
5180
|
].join(" ");
|
|
5181
|
+
var EMBEDDED_PLAIN_FOOTER_CLASS = "[&_tfoot]:bg-transparent [&_tfoot]:border-t-0";
|
|
5176
5182
|
|
|
5177
5183
|
// src/enumLabels.ts
|
|
5178
5184
|
function exhaustiveValuesOf() {
|
|
@@ -5465,6 +5471,20 @@ function kindLabel(kind) {
|
|
|
5465
5471
|
|
|
5466
5472
|
// src/ReferenceChips.tsx
|
|
5467
5473
|
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
5474
|
+
function glyphOf(icon) {
|
|
5475
|
+
const text = (icon ?? "").trim();
|
|
5476
|
+
return text !== "" && text.length <= 8 && /[^\u0000-\u007f]/.test(text) ? text : null;
|
|
5477
|
+
}
|
|
5478
|
+
function nameOf(icon) {
|
|
5479
|
+
const text = (icon ?? "").trim();
|
|
5480
|
+
return /^[A-Za-z][A-Za-z0-9_-]{1,40}$/.test(text) ? text : null;
|
|
5481
|
+
}
|
|
5482
|
+
function iconOf(pair) {
|
|
5483
|
+
const own3 = glyphOf(pair?.icon) ?? nameOf(pair?.icon);
|
|
5484
|
+
const table = glyphOf(pair?.tableIcon) ?? nameOf(pair?.tableIcon);
|
|
5485
|
+
const chosen = own3 ?? table;
|
|
5486
|
+
return chosen ? { icon: chosen } : {};
|
|
5487
|
+
}
|
|
5468
5488
|
function referencesOf(field2, value, kind, labels) {
|
|
5469
5489
|
if (kind === "entity_reference") {
|
|
5470
5490
|
return entityRefsOf2(value).map((r) => ({ token: r.token, id: r.id, label: r.label }));
|
|
@@ -5476,15 +5496,45 @@ function referencesOf(field2, value, kind, labels) {
|
|
|
5476
5496
|
id,
|
|
5477
5497
|
label: labels?.(field2, id) ?? null,
|
|
5478
5498
|
tableId,
|
|
5499
|
+
...iconOf(labels?.icons?.(field2, id)),
|
|
5479
5500
|
...labels?.archived?.(field2, id) ? { archived: true } : {}
|
|
5480
5501
|
}));
|
|
5481
5502
|
}
|
|
5482
5503
|
var ARCHIVED_REFERENCE_WORD = "Archived";
|
|
5483
5504
|
var ARCHIVED_REFERENCE_TIP = "In the Archived view; restore it to use it again";
|
|
5505
|
+
function PageGlyph() {
|
|
5506
|
+
return /* @__PURE__ */ jsxs18("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: 14, height: 14, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "data-records-page-glyph": "", children: [
|
|
5507
|
+
/* @__PURE__ */ jsx22("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
5508
|
+
/* @__PURE__ */ jsx22("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
|
|
5509
|
+
/* @__PURE__ */ jsx22("path", { d: "M10 13H8" }),
|
|
5510
|
+
/* @__PURE__ */ jsx22("path", { d: "M16 17H8" })
|
|
5511
|
+
] });
|
|
5512
|
+
}
|
|
5484
5513
|
function ReferenceChip({ reference, waiting }) {
|
|
5485
5514
|
const host = useRecordsUi();
|
|
5486
5515
|
const words2 = reference.label ?? (reference.token === "record" ? waiting ?? "Loading\u2026" : WITHHELD_ENTITY_LABEL);
|
|
5487
5516
|
const drawn = host.renderReference ? host.renderReference({ ...reference, label: reference.label ?? words2 }) : null;
|
|
5517
|
+
const look = useEmbeddedLook();
|
|
5518
|
+
if (look?.plainRelation) {
|
|
5519
|
+
return /* @__PURE__ */ jsxs18(
|
|
5520
|
+
"span",
|
|
5521
|
+
{
|
|
5522
|
+
className: cn15(
|
|
5523
|
+
"inline-flex max-w-full min-w-0 items-center gap-1.5 text-sm text-foreground hover:underline [&_a]:text-inherit [&_a]:no-underline [&_a:hover]:underline",
|
|
5524
|
+
reference.archived && "opacity-70"
|
|
5525
|
+
),
|
|
5526
|
+
"data-records-reference-chip": reference.token,
|
|
5527
|
+
"data-records-reference-plain": "",
|
|
5528
|
+
"data-records-reference-archived": reference.archived ? "" : void 0,
|
|
5529
|
+
title: reference.archived ? ARCHIVED_REFERENCE_TIP : words2,
|
|
5530
|
+
children: [
|
|
5531
|
+
/* @__PURE__ */ jsx22("span", { "aria-hidden": "true", "data-records-reference-icon": "", className: "inline-flex size-4 shrink-0 items-center justify-center text-muted-foreground", children: glyphOf(reference.icon) ? /* @__PURE__ */ jsx22("span", { className: "text-sm leading-none", children: reference.icon }) : reference.icon && host.renderIcon?.(reference.icon) || /* @__PURE__ */ jsx22(PageGlyph, {}) }),
|
|
5532
|
+
drawn ?? /* @__PURE__ */ jsx22("span", { className: "truncate", children: words2 }),
|
|
5533
|
+
reference.archived ? /* @__PURE__ */ jsx22("span", { className: "shrink-0 text-muted-foreground", children: ARCHIVED_REFERENCE_WORD }) : null
|
|
5534
|
+
]
|
|
5535
|
+
}
|
|
5536
|
+
);
|
|
5537
|
+
}
|
|
5488
5538
|
return /* @__PURE__ */ jsxs18(
|
|
5489
5539
|
Badge4,
|
|
5490
5540
|
{
|
|
@@ -6215,7 +6265,7 @@ function renderValue(field2, value, document2, labels, stillWaitingFor, look) {
|
|
|
6215
6265
|
"data-records-choice-chip": "",
|
|
6216
6266
|
...chip.tinted ? { "data-records-choice-tint": "" } : {},
|
|
6217
6267
|
children: [
|
|
6218
|
-
look?.choiceDot ? /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", "data-records-choice-dot": "", className: cn17("mr-1.5 inline-block size-1.5 shrink-0 rounded-full", chip.dot) }) : null,
|
|
6268
|
+
look?.choiceDot ? /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", "data-matrx-pill-ink": "", "data-records-choice-dot": "", className: cn17("mr-1.5 inline-block size-1.5 shrink-0 rounded-full", chip.dot) }) : null,
|
|
6219
6269
|
statusMark(field2, item, Array.isArray(value) ? void 0 : document2),
|
|
6220
6270
|
scalarText(field2, item, labels, Array.isArray(value) ? void 0 : stillWaitingFor)
|
|
6221
6271
|
]
|
|
@@ -6370,7 +6420,7 @@ function RecordValue({
|
|
|
6370
6420
|
const shape = shown4 && (shown4.id === "date" || shown4.id === "datetime") && isDateField(field2) ? dateFormatFor(field2, value) : void 0;
|
|
6371
6421
|
const dated = shape ? { ...shape, ...shown4?.options ? { options: shown4.options } : {} } : void 0;
|
|
6372
6422
|
const formatted = shown4 ? formatColumnValue({ format: dated ?? shown4 }, value) : null;
|
|
6373
|
-
if (formatted) return /* @__PURE__ */ jsx26(FormattedValue, { value, format: dated ?? shown4 });
|
|
6423
|
+
if (formatted && !(embeddedLook?.blankEmpty && formatted.empty)) return /* @__PURE__ */ jsx26(FormattedValue, { value, format: dated ?? shown4 });
|
|
6374
6424
|
return /* @__PURE__ */ jsx26(Fragment6, { children: renderValue(field2, value, document2, labels, stillWaitingFor, embeddedLook) });
|
|
6375
6425
|
}
|
|
6376
6426
|
var ONE_FIELD_ARRAYS = /* @__PURE__ */ new WeakMap();
|
|
@@ -16124,7 +16174,7 @@ function opensOnKey(event) {
|
|
|
16124
16174
|
}
|
|
16125
16175
|
return true;
|
|
16126
16176
|
}
|
|
16127
|
-
function withOpenRecord(columns, onOpen,
|
|
16177
|
+
function withOpenRecord(columns, onOpen, nameOf2, place = "end", hrefOf) {
|
|
16128
16178
|
if (!onOpen) return columns;
|
|
16129
16179
|
return columns.map((column, index) => {
|
|
16130
16180
|
const original = column.cell;
|
|
@@ -16134,8 +16184,8 @@ function withOpenRecord(columns, onOpen, nameOf, place = "end", hrefOf) {
|
|
|
16134
16184
|
{
|
|
16135
16185
|
type: "button",
|
|
16136
16186
|
"data-records-open-record": row.id,
|
|
16137
|
-
"aria-label": openRecordLabel(
|
|
16138
|
-
title: `${openRecordLabel(
|
|
16187
|
+
"aria-label": openRecordLabel(nameOf2(row)),
|
|
16188
|
+
title: `${openRecordLabel(nameOf2(row))} (Space)`,
|
|
16139
16189
|
className: "shrink-0 rounded px-1 text-xs leading-5 text-muted-foreground opacity-40 hover:bg-muted hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover/matrx-row:opacity-100",
|
|
16140
16190
|
onClick: (event) => {
|
|
16141
16191
|
event.stopPropagation();
|
|
@@ -22288,7 +22338,7 @@ function GridBody({
|
|
|
22288
22338
|
[storePaged, query, queryTotal, classicInCard, records.data?.total]
|
|
22289
22339
|
);
|
|
22290
22340
|
const showAddLine = mayAddRow && rows.length > 0;
|
|
22291
|
-
const showSummaryLine = rows.length > 0 && (!merged || Object.keys(chosenSummaries).length > 0);
|
|
22341
|
+
const showSummaryLine = rows.length > 0 && (embedded ? Object.keys(chosenSummaries).length > 0 : !merged || Object.keys(chosenSummaries).length > 0);
|
|
22292
22342
|
const footerFace = JSON.stringify([
|
|
22293
22343
|
showAddLine ? added.busy : null,
|
|
22294
22344
|
showSummaryLine ? [chosenSummaries, summaries.values, summaries.rowCount, summaries.loading] : null
|
|
@@ -22471,7 +22521,7 @@ function GridBody({
|
|
|
22471
22521
|
mode: phone ? "sheet" : toolbarFold2 >= 3 ? "menu" : "inline",
|
|
22472
22522
|
pinned: /* @__PURE__ */ jsxs61(Fragment23, { children: [
|
|
22473
22523
|
/* @__PURE__ */ jsx68(UndoRedoLive, { source: undoSource }),
|
|
22474
|
-
!readOnly && rights.write ? /* @__PURE__ */ jsx68(
|
|
22524
|
+
!embedded && !readOnly && rights.write ? /* @__PURE__ */ jsx68(
|
|
22475
22525
|
NewFromTemplateMenu,
|
|
22476
22526
|
{
|
|
22477
22527
|
tableId,
|
|
@@ -22483,7 +22533,8 @@ function GridBody({
|
|
|
22483
22533
|
// NEW RECORD NEVER LEAVES THE ROW (live walk 2026-10-05: at 1440 px with the
|
|
22484
22534
|
// side chat open it and "From template" both vanished behind the "…"). When the
|
|
22485
22535
|
// row is short, "From template", undo and the rest ride the "…"; this stays.
|
|
22486
|
-
|
|
22536
|
+
// EMBEDDED: the "+ New page" line under the table is the create action.
|
|
22537
|
+
...!embedded && !readOnly && rights.write ? {
|
|
22487
22538
|
primary: /* @__PURE__ */ jsx68(
|
|
22488
22539
|
NewRecordControl,
|
|
22489
22540
|
{
|
|
@@ -22548,7 +22599,7 @@ function GridBody({
|
|
|
22548
22599
|
// 2026-09-28: with the Forms rail open "New record" read "New reco", faded
|
|
22549
22600
|
// under the slot's edge). Pinned, it sticks to the row's right edge and what
|
|
22550
22601
|
// scrolls passes under it — the merged grid's rule, not a second one.
|
|
22551
|
-
...!readOnly && rights.write ? {
|
|
22602
|
+
...!embedded && !readOnly && rights.write ? {
|
|
22552
22603
|
overflow: {
|
|
22553
22604
|
mode: "inline",
|
|
22554
22605
|
pinned: /* @__PURE__ */ jsx68(Button42, { size: "sm", className: "shrink-0", disabled: editingBusy, onClick: () => void addRecord(), children: editingBusy ? "Adding\u2026" : "New record" })
|
|
@@ -22799,7 +22850,8 @@ function GridBody({
|
|
|
22799
22850
|
tableClassName: cn34(
|
|
22800
22851
|
!look.wrap && "[&_tbody_td]:max-w-[28rem] [&_tbody_td]:overflow-hidden [&_tbody_td]:text-ellipsis [&_tbody_td]:whitespace-nowrap! [&_tbody_td_*]:whitespace-nowrap!",
|
|
22801
22852
|
look.fit === "scroll" && "sm:[&>table]:w-max! sm:[&>table]:max-w-none! sm:[&>table]:min-w-full!",
|
|
22802
|
-
embedded && EMBEDDED_TABLE_CLASS
|
|
22853
|
+
embedded && EMBEDDED_TABLE_CLASS,
|
|
22854
|
+
embedded && !showSummaryLine && EMBEDDED_PLAIN_FOOTER_CLASS
|
|
22803
22855
|
),
|
|
22804
22856
|
footerRows,
|
|
22805
22857
|
...embedded ? { copy: false } : copyConfig ? { copy: copyConfig } : {},
|
|
@@ -31396,7 +31448,11 @@ function ViewSwitcher({
|
|
|
31396
31448
|
onUseSort: (sort) => change({ sorts: [sort], order: "sorted" })
|
|
31397
31449
|
} : {}
|
|
31398
31450
|
}
|
|
31399
|
-
} :
|
|
31451
|
+
} : (view.sorts?.length ?? 0) > 0 || local.sorts ? (
|
|
31452
|
+
/* A VIEW THE HOST HOLDS INLINE (Spaces) has no saved id but still has its sort: the
|
|
31453
|
+
grid opens in it, never in the table's own order. */
|
|
31454
|
+
{ viewOrder: { viewId: null, order: null, sorts: local.sorts ?? view.sorts ?? [] } }
|
|
31455
|
+
) : {}
|
|
31400
31456
|
}
|
|
31401
31457
|
) : /* @__PURE__ */ jsx105(
|
|
31402
31458
|
Board,
|
|
@@ -45796,22 +45852,22 @@ function RailFrame({
|
|
|
45796
45852
|
return /* @__PURE__ */ jsx152("aside", { "data-rail-column": "", className: "w-[26rem] shrink-0 overflow-y-auto rounded-md border p-3", children });
|
|
45797
45853
|
}
|
|
45798
45854
|
function filterInWords(filter, fields) {
|
|
45799
|
-
const
|
|
45855
|
+
const nameOf2 = (key) => {
|
|
45800
45856
|
const field2 = fields.find((f) => f.key === key);
|
|
45801
45857
|
return field2 ? fieldName(field2) : humanizeIdentifier17(key);
|
|
45802
45858
|
};
|
|
45803
45859
|
const parts = Object.keys(filter).map((key) => {
|
|
45804
45860
|
const value = filter[key];
|
|
45805
|
-
if (value === null || value === void 0) return `${
|
|
45861
|
+
if (value === null || value === void 0) return `${nameOf2(key)} is not filled in`;
|
|
45806
45862
|
if (typeof value === "object") {
|
|
45807
45863
|
const from = (value.from ?? "").toString().trim();
|
|
45808
45864
|
const to = (value.to ?? "").toString().trim();
|
|
45809
|
-
if (from !== "" && to !== "") return `${
|
|
45810
|
-
if (from !== "") return `${
|
|
45811
|
-
if (to !== "") return `${
|
|
45812
|
-
return `${
|
|
45865
|
+
if (from !== "" && to !== "") return `${nameOf2(key)} from ${from} up to ${to}`;
|
|
45866
|
+
if (from !== "") return `${nameOf2(key)} from ${from} onwards`;
|
|
45867
|
+
if (to !== "") return `${nameOf2(key)} up to ${to}`;
|
|
45868
|
+
return `${nameOf2(key)} in a period nobody named`;
|
|
45813
45869
|
}
|
|
45814
|
-
return `${
|
|
45870
|
+
return `${nameOf2(key)} is ${String(value)}`;
|
|
45815
45871
|
});
|
|
45816
45872
|
if (parts.length === 0) return "";
|
|
45817
45873
|
if (parts.length === 1) return parts[0];
|