@ai-matrx/records-ui 0.113.30 → 0.113.32

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.
@@ -1,267 +1,33 @@
1
1
  'use strict';
2
2
 
3
- var core = require('@ai-matrx/records/core');
4
- var uuid = require('@ai-matrx/kit/uuid');
5
- var textCase = require('@ai-matrx/kit/text-case');
6
- var records = require('@ai-matrx/records');
7
- var dataTable = require('@ai-matrx/design-system/data-table');
8
- require('react');
3
+ var firstPage = require('@ai-matrx/records/first-page');
4
+ var base = require('@ai-matrx/records/views');
9
5
  var tableStyle = require('@ai-matrx/design-system/data-table/table-style');
6
+ require('@ai-matrx/design-system/data-table');
10
7
  require('@ai-matrx/design-system/field-formats');
11
- var port = require('@ai-matrx/entity-data/port');
8
+ require('@ai-matrx/records');
12
9
 
13
- // src/firstPage.ts
14
- function fieldName(field2) {
15
- const label = (field2.label ?? "").trim();
16
- if (label !== "" && label === field2.key && /^[a-z0-9]+(?:[_.-][a-z0-9]+)+$/.test(label)) return textCase.humanizeIdentifier(label);
17
- if (label !== "") return label;
18
- const name = (field2.name ?? "").trim();
19
- if (name !== "") return name;
20
- return textCase.humanizeIdentifier(field2.key);
21
- }
22
- var kernelId = (name) => records.KERNEL_TABLES.find((t) => t.name === name)?.id ?? "";
23
- var KERNEL_FILE_TABLE = kernelId("File");
24
- var KERNEL_PERSON_TABLE = kernelId("Person");
25
- Object.fromEntries(
26
- records.PARITY_FIELD_TYPES.map((p) => [p.parity_type, p.made_of])
27
- );
28
- var KERNEL = { file: KERNEL_FILE_TABLE, person: KERNEL_PERSON_TABLE };
29
- function editorKindFor(field2) {
30
- return records.fieldKindFor(field2, KERNEL);
31
- }
32
-
33
- // src/gridLook.ts
34
- function defaultSortOf(table, fields) {
35
- const raw = table?.default_sort ?? null;
36
- const first = Array.isArray(raw) ? raw[0] : raw;
37
- let name = null;
38
- let direction = "asc";
39
- if (typeof first === "string") {
40
- const trimmed = first.trim();
41
- if (trimmed === "") return null;
42
- if (trimmed.startsWith("-")) {
43
- name = trimmed.slice(1).trim();
44
- direction = "desc";
45
- } else {
46
- const [head, tail] = trimmed.split(/\s+/);
47
- name = head ?? null;
48
- if (tail && tail.toLowerCase() === "desc") direction = "desc";
49
- }
50
- } else if (first && typeof first === "object") {
51
- const entry = first;
52
- const named = entry["field"] ?? entry["key"] ?? entry["id"];
53
- name = typeof named === "string" ? named : null;
54
- if (String(entry["direction"] ?? "").toLowerCase() === "desc") direction = "desc";
55
- }
56
- if (!name) return null;
57
- const field2 = fields.find((f) => f.key === name) ?? fields.find((f) => f.id === name);
58
- return field2 ? { id: field2.key, direction } : null;
59
- }
60
- var MEASURE_LABEL = {
61
- count: "Count",
62
- sum: "Sum",
63
- avg: "Average",
64
- min: "Smallest",
65
- max: "Largest",
66
- median: "Median",
67
- filled: "Filled",
68
- empty: "Empty",
69
- unique: "Unique",
70
- percent_empty: "Percent empty",
71
- percent_filled: "Percent filled",
72
- range: "Range"
73
- };
74
-
75
- // src/gridPage.ts
76
- function filterRefusal(f) {
77
- if (!computedOnRead(f)) return null;
78
- return `${fieldName(f)} is worked out each time it is read, so the store keeps no value to filter the whole table by. Filter by a column it is worked out from.`;
79
- }
80
- function computedOnRead(f) {
81
- const kind = String(editorKindFor(f));
82
- return (f.type === "formula" || kind === "formula" || kind === "lookup" || kind === "rollup") && String(f.compute_on ?? "read") === "read";
83
- }
84
- function holdsNumbers(field2) {
85
- const kind = String(editorKindFor(field2));
86
- if (kind === "number" || kind === "currency" || kind === "percent") return true;
87
- return String((field2.config ?? {})["system"] ?? "") === "autonumber";
88
- }
89
- function sortAsFor(field2) {
90
- const kind = String(editorKindFor(field2));
91
- if (holdsNumbers(field2)) return "number";
92
- if (kind === "datetime") return "date";
93
- return "text";
94
- }
95
- function pageSortFor(fields, sort) {
96
- if (!sort) return [];
97
- const field2 = fields.find((f) => f.key === sort.id);
98
- if (!field2) return [];
99
- return [{ field: field2.key, direction: sort.direction === "desc" ? "desc" : "asc", as: sortAsFor(field2) }];
100
- }
101
- function containsPattern(text) {
102
- return `(?i)${text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`;
103
- }
104
- var BLANK_VALUE = "__empty__";
105
- var field = (f) => ({ field: f.id });
106
- var constant = (value) => ({ const: value });
107
- var withinWindow = (f, window) => ({ op: "within", args: [field(f), constant(window)] });
108
- var op = (name, ...args) => ({ op: name, args });
109
- function clauseFor(f, value, now = /* @__PURE__ */ new Date()) {
110
- const name = fieldName(f);
111
- const refused = filterRefusal(f);
112
- if (refused) return refused;
113
- const not = (rule) => op("not", rule);
114
- switch (value.kind) {
115
- case "text": {
116
- const mode = value.mode ?? "contains";
117
- if (mode === "empty" || mode === "null") return value.negated ? { rule: op("present", field(f)) } : { rule: not(op("present", field(f))) };
118
- if (mode === "not_empty" || mode === "not_null") return value.negated ? { rule: not(op("present", field(f))) } : { rule: op("present", field(f)) };
119
- const text = value.value.trim();
120
- if (text === "") return null;
121
- const kind = String(editorKindFor(f));
122
- if (kind === "number" || kind === "currency" || kind === "percent" || kind === "checkbox") {
123
- return `${name} holds numbers, so it is filtered by a range, not by words.`;
124
- }
125
- const matches = op("matches", field(f), constant(containsPattern(text)));
126
- return { rule: value.negated ? not(matches) : matches };
127
- }
128
- case "select": {
129
- const ticked = value.values ?? (value.value === "" ? [] : [value.value]);
130
- const blank = ticked.includes(BLANK_VALUE);
131
- const words = ticked.filter((w) => w !== BLANK_VALUE);
132
- if (!blank && words.length === 0) return value.negated ? null : { rule: constant(false) };
133
- const present = op("present", field(f));
134
- const kind = String(editorKindFor(f));
135
- if (kind === "datetime" || kind === "date") {
136
- if (words.length === 0) return { rule: value.negated ? present : not(present) };
137
- const holdsDays = String((f.config ?? {})["kind"] ?? "") === "date";
138
- if (words.length === 1 && !blank && !value.negated) return { flat: { [f.key]: dayWindow(words[0], holdsDays) } };
139
- const leaves = words.map((day) => withinWindow(f, dayWindow(day, holdsDays)));
140
- const anyDay = leaves.length === 1 ? leaves[0] : op("or", ...leaves);
141
- if (!value.negated) return { rule: blank ? op("or", not(present), anyDay) : anyDay };
142
- return { rule: blank ? op("and", present, not(anyDay)) : not(anyDay) };
143
- }
144
- const asStored = (w) => holdsNumbers(f) || kind === "rating" ? Number.isFinite(Number(w)) ? Number(w) : w : kind === "checkbox" && (w === "true" || w === "false") ? w === "true" : w;
145
- const stored = words.map(asStored);
146
- const anyWord = stored.length === 0 ? null : stored.length === 1 ? op("eq", field(f), constant(stored[0])) : op("or", ...stored.map((w) => op("eq", field(f), constant(w))));
147
- if (!value.negated) {
148
- if (!blank && stored.length === 1) return { flat: { [f.key]: stored[0] } };
149
- if (!blank) return { rule: anyWord };
150
- return { rule: anyWord ? op("or", not(present), anyWord) : not(present) };
10
+ function _interopNamespace(e) {
11
+ if (e && e.__esModule) return e;
12
+ var n = Object.create(null);
13
+ if (e) {
14
+ Object.keys(e).forEach(function (k) {
15
+ if (k !== 'default') {
16
+ var d = Object.getOwnPropertyDescriptor(e, k);
17
+ Object.defineProperty(n, k, d.get ? d : {
18
+ enumerable: true,
19
+ get: function () { return e[k]; }
20
+ });
151
21
  }
152
- if (blank) return { rule: anyWord ? op("and", present, not(anyWord)) : present };
153
- return { rule: op("or", not(present), not(anyWord)) };
154
- }
155
- case "boolean":
156
- return value.negated ? { rule: op("ne", field(f), constant(value.value)) } : { flat: { [f.key]: value.value } };
157
- case "number": {
158
- const turned = (rule) => ({ rule: value.negated ? not(rule) : rule });
159
- if (value.op === "empty") return turned(not(op("present", field(f))));
160
- if (value.op === "not_empty") return turned(op("present", field(f)));
161
- if (value.op === "eq" || value.op === "ne") {
162
- if (typeof value.min !== "number") return null;
163
- return turned(op(value.op, field(f), constant(value.min)));
164
- }
165
- if (value.op === "lt") return typeof value.max === "number" ? turned(op("lt", field(f), constant(value.max))) : null;
166
- if (value.op === "gt") return typeof value.min === "number" ? turned(op("gt", field(f), constant(value.min))) : null;
167
- const parts = [];
168
- if (typeof value.min === "number") parts.push(op("gte", field(f), constant(value.min)));
169
- if (typeof value.max === "number") parts.push(op("lte", field(f), constant(value.max)));
170
- if (parts.length === 0) return null;
171
- const range = parts.length === 1 ? parts[0] : op("and", ...parts);
172
- return { rule: value.negated ? not(range) : range };
173
- }
174
- case "date": {
175
- const zone2 = void 0;
176
- const moments = dataTable.dateFilterBounds(value.preset ? { ...value, anchor: now.toISOString() } : value, now, zone2);
177
- const holdsDays = String((f.config ?? {})["kind"] ?? "") === "date";
178
- const bounds = holdsDays ? dataTable.dateFilterDayBounds(moments, zone2) : moments;
179
- if (bounds.since === void 0 && bounds.until === void 0) return null;
180
- return {
181
- flat: {
182
- [f.key]: {
183
- ...bounds.since === void 0 ? {} : { from: bounds.since },
184
- ...bounds.until === void 0 ? {} : { to: bounds.until }
185
- }
186
- }
187
- };
188
- }
189
- default:
190
- return `${name} cannot be filtered that way by the store.`;
191
- }
192
- }
193
- function dayWindow(day, holdsDays) {
194
- if (!holdsDays) return dataTable.dayInstantWindow(day, void 0);
195
- const [y, m, d] = day.split("-").map(Number);
196
- const ymd = (t) => `${t.getUTCFullYear()}-${String(t.getUTCMonth() + 1).padStart(2, "0")}-${String(t.getUTCDate()).padStart(2, "0")}`;
197
- return { from: ymd(new Date(Date.UTC(y, (m ?? 1) - 1, d ?? 1))), to: ymd(new Date(Date.UTC(y, (m ?? 1) - 1, (d ?? 1) + 1))) };
198
- }
199
- function storeQuestion(fields, base, columnFilters, now = /* @__PURE__ */ new Date()) {
200
- const refused = [];
201
- const flat = {};
202
- const rules = [];
203
- if (base && records.isRuleFilter(base)) rules.push(base);
204
- else if (base) Object.assign(flat, base);
205
- for (const [key, value] of Object.entries(columnFilters)) {
206
- if (!value) continue;
207
- const f = fields.find((candidate) => candidate.key === key);
208
- if (!f) continue;
209
- const clause = clauseFor(f, value, now);
210
- if (clause === null) continue;
211
- if (typeof clause === "string") {
212
- refused.push(clause);
213
- continue;
214
- }
215
- if ("flat" in clause) Object.assign(flat, clause.flat);
216
- else rules.push(clause.rule);
22
+ });
217
23
  }
218
- const flatKeys = Object.keys(flat);
219
- if (rules.length === 0) return { filter: flatKeys.length > 0 ? flat : void 0, refused };
220
- for (const key of flatKeys) {
221
- const f = fields.find((candidate) => candidate.key === key);
222
- const value = flat[key];
223
- if (!f) continue;
224
- if (value !== null && typeof value === "object") {
225
- rules.push(withinWindow(f, value));
226
- continue;
227
- }
228
- rules.push(value === null ? op("not", op("present", field(f))) : op("eq", field(f), constant(value)));
229
- }
230
- return { filter: rules.length === 1 ? rules[0] : op("and", ...rules), refused };
24
+ n.default = e;
25
+ return Object.freeze(n);
231
26
  }
232
27
 
233
- // src/rowVersion.ts
234
- function ownVersion(row) {
235
- const v = row.version;
236
- return typeof v === "number" ? v : null;
237
- }
28
+ var base__namespace = /*#__PURE__*/_interopNamespace(base);
238
29
 
239
- // src/groupReads.ts
240
- function isPlainGrouping(grouping) {
241
- return Boolean(grouping) && !(grouping.then && grouping.then.length > 0) && !grouping.across && !(grouping.trail && grouping.trail.length > 0);
242
- }
243
- function groupedPageSort(fields, groupKey, sort) {
244
- if (!groupKey) return sort;
245
- const field2 = fields.find((f) => f.key === groupKey);
246
- if (!field2) return sort;
247
- return [{ field: groupKey, direction: "asc", as: sortAsFor(field2) }, ...sort.filter((s) => s.field !== groupKey)];
248
- }
249
- function chosenEntries(chosen) {
250
- return JSON.parse(JSON.stringify(Object.entries(chosen).sort())).filter(([, op2]) => op2 in MEASURE_LABEL);
251
- }
252
- function groupFactMeasures(chosen) {
253
- return [{ op: "count" }, ...chosenEntries(chosen).filter(([, op2]) => op2 !== "count").map(([key, op2]) => ({ op: op2, key }))];
254
- }
255
- function summaryBarMeasures(chosen) {
256
- return chosenEntries(chosen).map(([key, op2]) => op2 === "count" ? { op: "count" } : { op: op2, key });
257
- }
258
- function choiceFieldKeys(fields) {
259
- return fields.filter((f) => {
260
- const kind = String(editorKindFor(f));
261
- return kind === "select" || kind === "multi_select";
262
- }).map((f) => f.key);
263
- }
264
- var REVERSE_CELL_CHIPS = 3;
30
+ // src/firstPage.ts
265
31
  var MIN_ROW_HEIGHT = 24;
266
32
  var MAX_ROW_HEIGHT = 96;
267
33
  var AGGREGATE_KINDS = [
@@ -360,8 +126,8 @@ function parseGridPresentation(raw) {
360
126
  if (footer === "sticky" || footer === "inline") out.footer = footer;
361
127
  if (isRecord(value["summaries"])) {
362
128
  const summaries = {};
363
- for (const [key, op2] of Object.entries(value["summaries"])) {
364
- if (typeof op2 === "string" && op2.trim() !== "") summaries[key] = op2;
129
+ for (const [key, op] of Object.entries(value["summaries"])) {
130
+ if (typeof op === "string" && op.trim() !== "") summaries[key] = op;
365
131
  }
366
132
  if (Object.keys(summaries).length > 0) out.summaries = summaries;
367
133
  }
@@ -369,9 +135,9 @@ function parseGridPresentation(raw) {
369
135
  }
370
136
  function parseGrouping(raw) {
371
137
  if (!isRecord(raw)) return void 0;
372
- const field2 = raw["field"];
373
- if (typeof field2 !== "string" || field2.trim() === "") return void 0;
374
- const out = { field: field2 };
138
+ const field = raw["field"];
139
+ if (typeof field !== "string" || field.trim() === "") return void 0;
140
+ const out = { field };
375
141
  if (isRecord(raw["aggregates"])) {
376
142
  const aggregates = {};
377
143
  for (const [key, spec] of Object.entries(raw["aggregates"])) {
@@ -429,338 +195,60 @@ function parseGrouping(raw) {
429
195
  }
430
196
  return out;
431
197
  }
432
- var STORE_KEPT_LAYOUTS = ["grid", "kanban", "calendar", "gallery", ...["timeline"] , "list"];
433
- var KINDS = STORE_KEPT_LAYOUTS;
434
- function viewSettings(definition, rowFilters) {
435
- const data = definition ?? {};
436
- const text = (key) => {
437
- const v = data[key];
438
- return typeof v === "string" && v !== "" ? v : null;
439
- };
440
- const layout = String(data["layout"] ?? "grid");
441
- const flat = rowFilters ?? (isObject(data["filters"]) ? data["filters"] : null);
442
- const moved = data["moved_from"];
443
- return {
444
- layout: KINDS.includes(layout) ? layout : "grid",
445
- filters: flat && Object.keys(flat).length > 0 ? flat : null,
446
- where: isRule(data["where"]) ? data["where"] : null,
447
- groupField: text("group_field"),
448
- swimlaneField: text("swimlane_field"),
449
- collapsedColumns: Array.isArray(data["collapsed_columns"]) ? data["collapsed_columns"].filter((v) => ["string", "number", "boolean"].includes(typeof v)).map(String) : [],
450
- measure: text("measure"),
451
- dateField: text("date_field"),
452
- startField: text("start_field"),
453
- endField: text("end_field"),
454
- imageField: text("image_field"),
455
- sorts: parseSorts(data["sorts"]),
456
- ruleId: text("rule_id"),
457
- isDefault: data["is_default"] === true || data["is_default"] === "true",
458
- presentation: parseGridPresentation(data["presentation"]),
459
- movedFrom: isObject(moved) ? moved : null
460
- };
198
+ function presentationIsEmpty(p) {
199
+ return (p.style === void 0 || tableStyle.tableStyleIsEmpty(p.style)) && Object.keys(p.formats ?? {}).length === 0 && (p.frozen?.length ?? 0) === 0 && p.grouping === void 0 && Object.keys(p.widths ?? {}).length === 0 && p.rowHeight === void 0 && (p.hiddenFields?.length ?? 0) === 0 && p.cardHidden === void 0 && (p.columnOrder?.length ?? 0) === 0 && p.gallerySize === void 0 && p.wrap === void 0 && p.fit === void 0 && p.freezeFirst === void 0 && p.footer === void 0 && Object.keys(p.summaries ?? {}).length === 0;
461
200
  }
462
- function isObject(raw) {
463
- return Boolean(raw) && typeof raw === "object" && !Array.isArray(raw);
464
- }
465
- function isRule(raw) {
466
- if (!isObject(raw)) return false;
467
- const node = raw;
468
- return typeof node.op === "string" && Array.isArray(node.args);
469
- }
470
- function parseSorts(raw) {
471
- let list = raw;
472
- if (typeof raw === "string") {
473
- try {
474
- list = raw.trim() === "" ? [] : JSON.parse(raw);
475
- } catch {
476
- return [];
477
- }
478
- }
479
- if (!Array.isArray(list)) return [];
480
- return list.filter((s) => isObject(s) && typeof s.field === "string").map((s) => ({ field: s.field, direction: s.direction === "desc" ? "desc" : "asc" }));
481
- }
482
-
483
- // src/views.ts
484
- var VIEW_LAYOUTS = ["grid", "kanban", "calendar", "gallery", "timeline", "list"];
485
- function viewOrderOf(definition) {
486
- const raw = definition?.["order"];
487
- return raw === "manual" ? "manual" : raw === "sorted" ? "sorted" : null;
488
- }
489
- function defaultViewOf(views) {
490
- return views.find((v) => v.isDefault);
491
- }
492
- function viewFromRow(row) {
493
- const data = row.definition ?? {};
494
- const k = viewSettings(data, row.filters && Object.keys(row.filters).length > 0 ? row.filters : null);
495
- const tableFromDefinition = typeof data["table_id"] === "string" && data["table_id"] !== "" ? data["table_id"] : null;
496
- return {
497
- id: row.view_id,
498
- name: row.name || "Untitled view",
499
- subject: row.table_id ?? tableFromDefinition ?? "",
500
- layout: k.layout,
501
- groupField: k.groupField,
502
- swimlaneField: k.swimlaneField,
503
- collapsedColumns: k.collapsedColumns,
504
- measure: k.measure,
505
- dateField: k.dateField,
506
- startField: k.startField,
507
- endField: k.endField,
508
- imageField: k.imageField,
509
- sorts: k.sorts,
510
- order: viewOrderOf(data),
511
- ruleId: k.ruleId,
512
- ...k.filters ? { filters: k.filters } : {},
513
- where: k.where,
514
- // The older table's own default view, carried in by the mover, IS this table's default —
515
- // the mover wrote the row's column, which `custom.views` does not return. Read as anything
516
- // else, the page would seed a second "All records" beside it and open on that.
517
- isDefault: k.isDefault || k.movedFrom?.["kind"] === "default_view",
518
- presentation: k.presentation,
519
- movedFrom: k.movedFrom
520
- };
521
- }
522
-
523
- // src/viewLook.ts
524
- function lookFromDocument(doc) {
525
- const data = doc ?? {};
526
- const read = viewSettings(data);
527
- const out = {};
528
- const has = (key) => Object.prototype.hasOwnProperty.call(data, key);
529
- if (has("layout") && VIEW_LAYOUTS.includes(String(data["layout"]))) {
530
- out.layout = data["layout"];
531
- }
532
- if (has("group_field")) out.groupField = read.groupField;
533
- if (has("swimlane_field")) out.swimlaneField = read.swimlaneField;
534
- if (has("collapsed_columns")) out.collapsedColumns = read.collapsedColumns;
535
- if (has("measure")) out.measure = read.measure;
536
- if (has("date_field")) out.dateField = read.dateField;
537
- if (has("start_field")) out.startField = read.startField;
538
- if (has("end_field")) out.endField = read.endField;
539
- if (has("image_field")) out.imageField = read.imageField;
540
- if (has("sorts")) out.sorts = read.sorts;
541
- if (has("where")) out.where = read.where;
542
- if (has("presentation")) out.presentation = parseGridPresentation(data["presentation"]);
543
- return out;
544
- }
545
- function applyLook(view, look) {
546
- if (!look) return view;
547
- return { ...view, ...look };
548
- }
549
- async function readLooks(client, tableId) {
550
- const answered = await client.viewLookRead({ table_id: tableId });
551
- if (!answered.ok) return answered;
552
- const out = {};
553
- for (const [viewId, row] of Object.entries(answered.data ?? {})) {
554
- out[viewId] = lookFromDocument(row?.look ?? null);
555
- }
556
- return { ok: true, data: out };
557
- }
558
-
559
- // src/entityQuery.ts
560
- function entityTableQuery(options = {}) {
561
- const search = (options.search ?? "").trim();
562
- return { ...options.pageSize ? { pageSize: options.pageSize } : {}, ...search ? { search } : {} };
563
- }
564
- function entityChartQuestion(input) {
565
- const m = input.measure ?? { op: "count" };
566
- return {
567
- ...input.by ? { by: [input.by] } : {},
568
- show: [m.op === "count" ? "count" : { op: m.op, of: m.of }],
569
- ...input.where ? { where: input.where } : {},
570
- ...input.organization ? { organization: input.organization } : {}
571
- };
572
- }
573
-
574
- // src/firstPageEntity.ts
575
- function recordedClient(input) {
576
- const recording = core.recordingDataSource(core.asRecordsDataSource(input.dataSource));
577
- const client = core.createRecordsClient({ dataSource: recording.source, organizationId: input.organizationId, actor: input.actor, onError: () => {
578
- } });
579
- return { recording, client };
580
- }
581
- function mergeSeeds(...seeds) {
582
- const held = seeds.filter((s) => Boolean(s));
583
- const answers = /* @__PURE__ */ new Map();
584
- for (const seed of held) for (const a of seed.answers) answers.set(`${a.door}|${JSON.stringify(a.args)}`, a);
585
- return { at: held.length ? Math.min(...held.map((s) => s.at)) : Date.now(), answers: [...answers.values()] };
586
- }
587
- async function askEntityBlockSeed(input) {
588
- const recording = core.recordingDataSource(core.asRecordsDataSource(input.dataSource));
589
- const port$1 = port.createSeedPort(recording.source);
590
- try {
591
- await Promise.all([port$1.describe(input.token), port$1.list(input.token, entityTableQuery(input.question ?? {}))]);
592
- } catch {
593
- }
594
- return recording.seed();
595
- }
596
- async function askChartSeed(input) {
597
- const { recording, client } = recordedClient(input);
598
- try {
599
- await client.drillAsk({ source: input.source, question: entityChartQuestion(input.question ?? {}) });
600
- } catch {
601
- }
602
- return recording.seed();
603
- }
604
- async function askTileSeed(input) {
605
- const { recording, client } = recordedClient(input);
606
- const specs = Array.isArray(input.spec) ? input.spec : [input.spec];
607
- await Promise.all(specs.map((spec) => client.recordAggregate({ table_id: input.tableId, ...spec }).catch(() => null)));
608
- return recording.seed();
201
+ function presentationDocument(p) {
202
+ return presentationIsEmpty(p) ? "" : JSON.stringify(p);
609
203
  }
204
+ var gridPresentationCodec = {
205
+ parse: parseGridPresentation,
206
+ isEmpty: presentationIsEmpty,
207
+ toDocument: (presentation) => JSON.parse(presentationDocument(presentation))
208
+ };
209
+ var boundViews = base__namespace.bindViewCodec(gridPresentationCodec);
210
+ var { viewSettings, viewSettingsPatch } = boundViews;
610
211
 
611
212
  // src/firstPage.ts
612
- var TABLE_PAGE_SIZE = 100;
613
- var EMBEDDED_PAGE_SIZE = 50;
614
- function viewFilterOf(shown, fields) {
615
- if (!shown) return void 0;
616
- const base = shown.where ?? (shown.filters && Object.keys(shown.filters).length > 0 ? shown.filters : void 0);
617
- return storeQuestion(fields, base, {}).filter;
618
- }
619
- function firstGridPageArgs(input) {
620
- const { shown, fields } = input;
621
- if (!shown) return null;
622
- if ((shown.layout ?? "grid") !== "grid") return null;
623
- if (shown.ruleId) return null;
624
- if (shown.order === "manual") return null;
625
- const grouping = shown.presentation?.grouping;
626
- if (grouping && !(input.merged && isPlainGrouping(grouping))) return null;
627
- const first = (shown.sorts ?? [])[0];
628
- const viewSort = first && fields.some((f) => f.key === first.field) ? { id: first.field, direction: first.direction } : null;
629
- const opening = viewSort ?? defaultSortOf(input.table, fields);
630
- return {
631
- p_table_id: input.tableId,
632
- p_filter: viewFilterOf(shown, fields) ?? {},
633
- p_search: null,
634
- p_sort: groupedPageSort(fields, grouping?.field ?? null, pageSortFor(fields, opening)),
635
- p_view_id: null,
636
- p_limit: input.pageSize ?? TABLE_PAGE_SIZE,
637
- p_offset: 0
638
- };
639
- }
640
- async function firstGridPageRequest(client, tableId, options = {}) {
641
- return (await firstGridOpening(client, tableId, options))?.args ?? null;
642
- }
643
- function defaultSpec(tableId) {
644
- return { name: "All", subject: tableId, layout: "grid", isDefault: true };
645
- }
646
- function shownFromSpec(spec, tableId) {
647
- return { ...spec, subject: spec.subject ?? tableId, id: "", movedFrom: null };
648
- }
649
- async function firstGridOpening(client, tableId, options) {
650
- const explicit = options.view;
651
- const [table, fields, views, looks] = await Promise.all([
652
- client.tableRead({ table_id: tableId }),
653
- client.fields({ table_id: tableId }),
654
- explicit ? Promise.resolve(null) : client.views({ table_id: tableId }),
655
- explicit ? Promise.resolve(null) : readLooks(client, tableId)
656
- ]);
657
- if (!table.ok || !fields.ok) return null;
658
- let shown;
659
- if (explicit) {
660
- shown = shownFromSpec(explicit, tableId);
661
- } else {
662
- if (!views?.ok || !looks?.ok) return null;
663
- const mine = views.data.map(viewFromRow).filter((v) => v.subject === tableId);
664
- const view = defaultViewOf(mine) ?? mine[0] ?? null;
665
- shown = view ? applyLook(view, looks.data[view.id]) : shownFromSpec(defaultSpec(tableId), tableId);
666
- }
667
- const args = firstGridPageArgs({
668
- tableId,
669
- table: table.data,
670
- fields: fields.data,
671
- shown,
672
- ...options.pageSize ? { pageSize: options.pageSize } : {},
673
- ...options.merged ? { merged: true } : {}
674
- });
675
- return args ? { args, shown, fields: fields.data } : null;
676
- }
677
- function serverRowsOf(seed) {
678
- const found = seed?.answers.find((a) => a.door === "server_rows");
679
- const data = found?.data;
680
- if (!data || typeof data !== "object") return null;
681
- return { on: data.on === true, capMs: typeof data.cap_ms === "number" && data.cap_ms > 0 ? data.cap_ms : null };
682
- }
683
- async function askTablePageSeed(input) {
684
- const recording = core.recordingDataSource(core.asRecordsDataSource(input.dataSource));
685
- const client = core.createRecordsClient({
686
- dataSource: recording.source,
687
- organizationId: input.organizationId,
688
- actor: input.actor,
689
- onError: () => {
690
- }
691
- });
692
- const record = input.recordId ? Promise.resolve(
693
- recording.source.rpc("record_page_bundle", { p_organization_id: input.organizationId, p_record_id: input.recordId }, { schema: "custom" })
694
- ).catch(() => null) : null;
695
- try {
696
- const pageSize = input.pageSize ?? (input.embedded ? EMBEDDED_PAGE_SIZE : TABLE_PAGE_SIZE);
697
- const opening = await firstGridOpening(client, input.tableId, { pageSize, ...input.merged ? { merged: true } : {}, ...input.view ? { view: input.view } : {} });
698
- const wantRows = typeof input.rows === "function" ? input.rows(recording.seed()) : input.rows !== false;
699
- if (opening && wantRows) {
700
- const { args, shown, fields } = opening;
701
- const page = await client.listPage({
702
- table_id: args.p_table_id,
703
- filter: args.p_filter,
704
- search: args.p_search,
705
- sort: args.p_sort,
706
- view_id: args.p_view_id,
707
- limit: args.p_limit,
708
- offset: args.p_offset
709
- });
710
- if (page.ok) {
711
- const chosen = shown?.presentation?.summaries ?? {};
712
- const groupKey = shown?.presentation?.grouping?.field ?? null;
713
- const reads = [];
714
- const filter = args.p_filter && Object.keys(args.p_filter).length > 0 ? args.p_filter : void 0;
715
- if (groupKey) {
716
- reads.push(client.recordAggregate({ table_id: input.tableId, groupBy: [groupKey], measures: groupFactMeasures(chosen), limit: 1e3, ...filter ? { filter } : {} }));
717
- }
718
- const bar = summaryBarMeasures(chosen);
719
- if (bar.length > 0) reads.push(client.recordAggregate({ table_id: input.tableId, measures: bar, ...filter ? { filter } : {} }));
720
- for (const field2 of fields) {
721
- if (field2.type !== "list" && field2.type !== "relation") continue;
722
- const ids = /* @__PURE__ */ new Set();
723
- for (const row of page.data.rows) {
724
- const value = row.document?.[field2.key];
725
- for (const id of Array.isArray(value) ? value.map(String) : typeof value === "string" ? [value] : []) if (uuid.isUuidShape(id)) ids.add(id);
726
- }
727
- if (ids.size > 0) reads.push(client.relationWordsMany({ field_id: field2.id, record_ids: [...ids] }));
728
- }
729
- if (input.merged) {
730
- for (const key of choiceFieldKeys(fields)) {
731
- reads.push(client.recordAggregate({ table_id: input.tableId, groupBy: [key], measures: [{ op: "count" }], limit: 500, ...filter ? { filter } : {} }));
732
- }
733
- }
734
- const unversioned = page.data.rows.filter((row) => ownVersion(row) === null).map((row) => row.id);
735
- if (unversioned.length > 0) reads.push(client.recordHeaders({ ids: unversioned }));
736
- reads.push(
737
- client.reverseColumns({ table_id: input.tableId }).then(async (columns) => {
738
- if (!columns.ok || columns.data.length === 0) return null;
739
- const record_ids = page.data.rows.map((row) => row.id);
740
- const all = await client.reverseLinksFields({ table_id: input.tableId, source_field_ids: columns.data.map((c) => c.source_field_id), record_ids, limit: REVERSE_CELL_CHIPS });
741
- if (all.ok || all.error.code !== "door_absent") return null;
742
- return Promise.all(columns.data.map((c) => client.reverseLinksMany({ table_id: input.tableId, source_field_id: c.source_field_id, record_ids, limit: REVERSE_CELL_CHIPS })));
743
- })
744
- );
745
- await Promise.all(reads.map((read) => read.catch(() => null)));
746
- }
747
- }
748
- } catch {
749
- }
750
- if (record) await record;
751
- return recording.seed();
752
- }
213
+ var { firstGridPageRequest, askTablePageSeed } = firstPage.bindFirstPageCodec(gridPresentationCodec);
753
214
 
754
- exports.EMBEDDED_PAGE_SIZE = EMBEDDED_PAGE_SIZE;
755
- exports.TABLE_PAGE_SIZE = TABLE_PAGE_SIZE;
756
- exports.askChartSeed = askChartSeed;
757
- exports.askEntityBlockSeed = askEntityBlockSeed;
215
+ Object.defineProperty(exports, "EMBEDDED_PAGE_SIZE", {
216
+ enumerable: true,
217
+ get: function () { return firstPage.EMBEDDED_PAGE_SIZE; }
218
+ });
219
+ Object.defineProperty(exports, "TABLE_PAGE_SIZE", {
220
+ enumerable: true,
221
+ get: function () { return firstPage.TABLE_PAGE_SIZE; }
222
+ });
223
+ Object.defineProperty(exports, "askChartSeed", {
224
+ enumerable: true,
225
+ get: function () { return firstPage.askChartSeed; }
226
+ });
227
+ Object.defineProperty(exports, "askEntityBlockSeed", {
228
+ enumerable: true,
229
+ get: function () { return firstPage.askEntityBlockSeed; }
230
+ });
231
+ Object.defineProperty(exports, "askTileSeed", {
232
+ enumerable: true,
233
+ get: function () { return firstPage.askTileSeed; }
234
+ });
235
+ Object.defineProperty(exports, "firstGridPageArgs", {
236
+ enumerable: true,
237
+ get: function () { return firstPage.firstGridPageArgs; }
238
+ });
239
+ Object.defineProperty(exports, "mergeSeeds", {
240
+ enumerable: true,
241
+ get: function () { return firstPage.mergeSeeds; }
242
+ });
243
+ Object.defineProperty(exports, "serverRowsOf", {
244
+ enumerable: true,
245
+ get: function () { return firstPage.serverRowsOf; }
246
+ });
247
+ Object.defineProperty(exports, "viewFilterOf", {
248
+ enumerable: true,
249
+ get: function () { return firstPage.viewFilterOf; }
250
+ });
758
251
  exports.askTablePageSeed = askTablePageSeed;
759
- exports.askTileSeed = askTileSeed;
760
- exports.firstGridPageArgs = firstGridPageArgs;
761
252
  exports.firstGridPageRequest = firstGridPageRequest;
762
- exports.mergeSeeds = mergeSeeds;
763
- exports.serverRowsOf = serverRowsOf;
764
- exports.viewFilterOf = viewFilterOf;
765
253
  //# sourceMappingURL=first-page.cjs.map
766
254
  //# sourceMappingURL=first-page.cjs.map