@ai-matrx/records-ui 0.113.36 → 0.113.37
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 +6 -0
- package/dist/first-page.cjs +2 -1
- package/dist/first-page.cjs.map +1 -1
- package/dist/first-page.d.cts +5 -0
- package/dist/first-page.d.ts +5 -0
- package/dist/first-page.js +2 -1
- package/dist/first-page.js.map +1 -1
- package/dist/index.cjs +284 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +296 -40
- package/dist/index.js.map +1 -1
- package/dist/object-actions.cjs.map +1 -1
- package/dist/object-actions.d.cts +1 -1
- package/dist/object-actions.d.ts +1 -1
- package/dist/object-actions.js.map +1 -1
- package/dist/{objectActions-B7AUBkcl.d.cts → objectActions-CV8VEz58.d.cts} +1 -1
- package/dist/{objectActions-B7AUBkcl.d.ts → objectActions-CV8VEz58.d.ts} +1 -1
- package/dist/pickers.cjs +169 -75
- package/dist/pickers.cjs.map +1 -1
- package/dist/pickers.js +130 -36
- package/dist/pickers.js.map +1 -1
- package/package.json +3 -3
package/dist/pickers.js
CHANGED
|
@@ -1036,13 +1036,20 @@ var NOT_ANSWERED_YET = whatYouMayDo(null, false);
|
|
|
1036
1036
|
var KERNEL_REASON = "This is one of the tables the platform ships, so its columns are not changed from a screen. Make your own table to change columns.";
|
|
1037
1037
|
function whatYouMayDoWithTable(table, level, known) {
|
|
1038
1038
|
const base = whatYouMayDo(level, known);
|
|
1039
|
-
if (!table?.is_kernel) return base;
|
|
1039
|
+
if (!table?.is_kernel) return table && tableIsLocked(table) ? lockedStructure(base) : base;
|
|
1040
1040
|
return {
|
|
1041
1041
|
...base,
|
|
1042
1042
|
structure: false,
|
|
1043
1043
|
why: (what) => what === "structure" ? KERNEL_REASON : base.why(what)
|
|
1044
1044
|
};
|
|
1045
1045
|
}
|
|
1046
|
+
function tableIsLocked(table) {
|
|
1047
|
+
return table?.metadata?.["locked"] === true;
|
|
1048
|
+
}
|
|
1049
|
+
var DATABASE_LOCKED_REASON = "This database is locked, so its columns and settings are read-only. Unlock it to change them.";
|
|
1050
|
+
function lockedStructure(base) {
|
|
1051
|
+
return { ...base, structure: false, why: (what) => what === "structure" ? DATABASE_LOCKED_REASON : base.why(what) };
|
|
1052
|
+
}
|
|
1046
1053
|
|
|
1047
1054
|
// src/host.tsx
|
|
1048
1055
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
@@ -4282,10 +4289,46 @@ function SourceArchivedNotice({ fieldId, tableId }) {
|
|
|
4282
4289
|
}
|
|
4283
4290
|
|
|
4284
4291
|
// src/Condition.tsx
|
|
4285
|
-
import { useEffect as useEffect12, useState as useState17 } from "react";
|
|
4292
|
+
import { createContext as createContext4, useContext as useContext4, useEffect as useEffect12, useState as useState17 } from "react";
|
|
4286
4293
|
import { BasicInput as BasicInput6, Button as Button10 } from "@ai-matrx/design-system";
|
|
4287
4294
|
import { optionKey as optionKey2, optionLabel, rankTypedMatches as rankTypedMatches2 } from "@ai-matrx/records";
|
|
4288
4295
|
import { useOptionalRecordsClient as useOptionalRecordsClient5 } from "@ai-matrx/records/react";
|
|
4296
|
+
|
|
4297
|
+
// src/personTime.ts
|
|
4298
|
+
import { useSyncExternalStore } from "react";
|
|
4299
|
+
import { setColorRuleTimeZone } from "@ai-matrx/design-system/data-table/table-style";
|
|
4300
|
+
var zone = null;
|
|
4301
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
4302
|
+
function getPersonTimeZone() {
|
|
4303
|
+
return zone;
|
|
4304
|
+
}
|
|
4305
|
+
function usePersonTimeZone() {
|
|
4306
|
+
return useSyncExternalStore(
|
|
4307
|
+
(cb) => {
|
|
4308
|
+
listeners.add(cb);
|
|
4309
|
+
return () => listeners.delete(cb);
|
|
4310
|
+
},
|
|
4311
|
+
() => zone,
|
|
4312
|
+
() => null
|
|
4313
|
+
);
|
|
4314
|
+
}
|
|
4315
|
+
function personWallNow(at = /* @__PURE__ */ new Date()) {
|
|
4316
|
+
if (!zone) return at;
|
|
4317
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
4318
|
+
timeZone: zone,
|
|
4319
|
+
year: "numeric",
|
|
4320
|
+
month: "2-digit",
|
|
4321
|
+
day: "2-digit",
|
|
4322
|
+
hour: "2-digit",
|
|
4323
|
+
minute: "2-digit",
|
|
4324
|
+
second: "2-digit",
|
|
4325
|
+
hourCycle: "h23"
|
|
4326
|
+
}).formatToParts(at);
|
|
4327
|
+
const n = (t) => Number(parts.find((p) => p.type === t)?.value ?? 0);
|
|
4328
|
+
return new Date(n("year"), n("month") - 1, n("day"), n("hour"), n("minute"), n("second"));
|
|
4329
|
+
}
|
|
4330
|
+
|
|
4331
|
+
// src/Condition.tsx
|
|
4289
4332
|
import { Fragment as Fragment7, jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4290
4333
|
var CONDITION_OPS = [
|
|
4291
4334
|
{ op: "eq", label: "is" },
|
|
@@ -4296,6 +4339,48 @@ var CONDITION_OPS = [
|
|
|
4296
4339
|
{ op: "gte", label: "is at least" },
|
|
4297
4340
|
{ op: "lte", label: "is at most" }
|
|
4298
4341
|
];
|
|
4342
|
+
var FilterTermsContext = createContext4(false);
|
|
4343
|
+
var RELATIVE_DAY_TERMS = [
|
|
4344
|
+
{ kind: "today", label: "is today" },
|
|
4345
|
+
{ kind: "tomorrow", label: "is tomorrow" },
|
|
4346
|
+
{ kind: "yesterday", label: "is yesterday" },
|
|
4347
|
+
{ kind: "this_week", label: "is this week" },
|
|
4348
|
+
{ kind: "next_week", label: "is next week" },
|
|
4349
|
+
{ kind: "last_week", label: "is last week" },
|
|
4350
|
+
{ kind: "this_month", label: "is this month" },
|
|
4351
|
+
{ kind: "next_month", label: "is next month" },
|
|
4352
|
+
{ kind: "last_month", label: "is last month" },
|
|
4353
|
+
{ kind: "before_today", label: "is before today" },
|
|
4354
|
+
{ kind: "next_days", label: "is in the next \u2026 days", takesDays: true },
|
|
4355
|
+
{ kind: "past_days", label: "is in the past \u2026 days", takesDays: true }
|
|
4356
|
+
];
|
|
4357
|
+
function relativeDayNode(fieldId, kind, days) {
|
|
4358
|
+
const zone2 = getPersonTimeZone();
|
|
4359
|
+
const window2 = { relative: kind };
|
|
4360
|
+
if (RELATIVE_DAY_TERMS.find((t) => t.kind === kind)?.takesDays) window2["n"] = days ?? 7;
|
|
4361
|
+
if (zone2) window2["tz"] = zone2;
|
|
4362
|
+
return { op: "within", args: [{ field: fieldId }, { const: window2 }] };
|
|
4363
|
+
}
|
|
4364
|
+
function relativeDayOf(expr) {
|
|
4365
|
+
const node = asNode(expr);
|
|
4366
|
+
if (!node || node["op"] !== "within") return null;
|
|
4367
|
+
const [a, b] = argsOf(node);
|
|
4368
|
+
const window2 = asNode(b?.["const"]);
|
|
4369
|
+
if (!a || typeof a["field"] !== "string" || !window2 || typeof window2["relative"] !== "string") return null;
|
|
4370
|
+
const days = typeof window2["n"] === "number" ? window2["n"] : null;
|
|
4371
|
+
return { kind: window2["relative"], days, field: a["field"] };
|
|
4372
|
+
}
|
|
4373
|
+
function meNode(fieldId, negate) {
|
|
4374
|
+
return { op: negate ? "ne" : "eq", args: [{ field: fieldId }, { const: { me: true } }] };
|
|
4375
|
+
}
|
|
4376
|
+
function meOf(expr) {
|
|
4377
|
+
const node = asNode(expr);
|
|
4378
|
+
if (!node || node["op"] !== "eq" && node["op"] !== "ne") return null;
|
|
4379
|
+
const [a, b] = argsOf(node);
|
|
4380
|
+
const value = asNode(b?.["const"]);
|
|
4381
|
+
if (!a || typeof a["field"] !== "string" || !value || value["me"] !== true) return null;
|
|
4382
|
+
return { which: node["op"] === "eq" ? "me" : "not_me", field: a["field"] };
|
|
4383
|
+
}
|
|
4299
4384
|
function pointsAtARecord(f) {
|
|
4300
4385
|
return !!f?.field && f.field.type === "relation" && !!f.field.relation_target;
|
|
4301
4386
|
}
|
|
@@ -4366,6 +4451,7 @@ function ChoiceValue({ field, value, onChange }) {
|
|
|
4366
4451
|
}
|
|
4367
4452
|
function conditionIsSimple(expr) {
|
|
4368
4453
|
if (expr === null || expr === void 0) return true;
|
|
4454
|
+
if (relativeDayOf(expr) !== null || meOf(expr) !== null) return true;
|
|
4369
4455
|
const node = expr;
|
|
4370
4456
|
if (typeof node.op !== "string" || !CONDITION_OPS.some((c) => c.op === node.op)) return false;
|
|
4371
4457
|
if (!Array.isArray(node.args)) return false;
|
|
@@ -4410,6 +4496,14 @@ function conditionInWords(expr, fields) {
|
|
|
4410
4496
|
const args = Array.isArray(n["args"]) ? n["args"] : [];
|
|
4411
4497
|
if (op === "not") return `not ${walk(args[0])}`;
|
|
4412
4498
|
if (op === "present") return `${walk(args[0])} has been answered`;
|
|
4499
|
+
const dayRange = relativeDayOf(n);
|
|
4500
|
+
if (dayRange) {
|
|
4501
|
+
const term = RELATIVE_DAY_TERMS.find((t) => t.kind === dayRange.kind);
|
|
4502
|
+
const said3 = term ? term.label.replace("\u2026", String(dayRange.days ?? 7)) : "is in a day range";
|
|
4503
|
+
return `${name(dayRange.field)} ${said3}`;
|
|
4504
|
+
}
|
|
4505
|
+
const reader = meOf(n);
|
|
4506
|
+
if (reader) return `${name(reader.field)} ${reader.which === "me" ? "is me" : "is not me"}`;
|
|
4413
4507
|
const word = said2[op] ?? op;
|
|
4414
4508
|
if (op === "and" || op === "or") return args.map(walk).join(` ${word} `);
|
|
4415
4509
|
if (args.length === 2) return `${walk(args[0])} ${word} ${walk(args[1])}`;
|
|
@@ -4431,11 +4525,31 @@ function conditionValue(typed) {
|
|
|
4431
4525
|
}
|
|
4432
4526
|
function ConditionRow({ lead, expr, fields, onChange, emptyLabel = "always", className }) {
|
|
4433
4527
|
const node = expr ?? null;
|
|
4434
|
-
const
|
|
4528
|
+
const filterTerms = useContext4(FilterTermsContext);
|
|
4529
|
+
const relative = relativeDayOf(expr);
|
|
4530
|
+
const reader = meOf(expr);
|
|
4531
|
+
const op = relative ? `rel:${relative.kind}` : reader ? reader.which : node?.op ?? "";
|
|
4435
4532
|
const onField = node?.args?.[0]?.field ?? "";
|
|
4436
|
-
const value = node?.args?.[1]?.const ?? "";
|
|
4533
|
+
const value = relative || reader ? "" : node?.args?.[1]?.const ?? "";
|
|
4437
4534
|
const chosen = fields.find((f) => f.id === onField);
|
|
4535
|
+
const chosenKind = chosen?.field ? String(editorKindFor(chosen.field)) : "";
|
|
4536
|
+
const extraTerms = !filterTerms ? [] : chosenKind === "datetime" ? RELATIVE_DAY_TERMS.map((t) => ({ op: `rel:${t.kind}`, label: t.label })) : chosenKind === "member" ? [{ op: "me", label: "is me" }, { op: "not_me", label: "is not me" }] : [];
|
|
4537
|
+
const relativeTerm = relative ? RELATIVE_DAY_TERMS.find((t) => t.kind === relative.kind) : void 0;
|
|
4438
4538
|
function write(next) {
|
|
4539
|
+
const picked = next.op;
|
|
4540
|
+
const fieldNow = next.field ?? onField;
|
|
4541
|
+
if (fieldNow && picked !== void 0 && (picked.startsWith("rel:") || picked === "me" || picked === "not_me")) {
|
|
4542
|
+
onChange(picked === "me" || picked === "not_me" ? meNode(fieldNow, picked === "not_me") : relativeDayNode(fieldNow, picked.slice(4), relative?.days ?? void 0));
|
|
4543
|
+
return;
|
|
4544
|
+
}
|
|
4545
|
+
if (fieldNow && next.days !== void 0 && relative) {
|
|
4546
|
+
onChange(relativeDayNode(fieldNow, relative.kind, next.days));
|
|
4547
|
+
return;
|
|
4548
|
+
}
|
|
4549
|
+
if (next.field !== void 0 && (relative || reader)) {
|
|
4550
|
+
onChange(next.field ? { op: CONDITION_OPS[0].op, args: [{ field: next.field }, { const: "" }] } : null);
|
|
4551
|
+
return;
|
|
4552
|
+
}
|
|
4439
4553
|
const chosenOp = next.op ?? (op || (next.field ? CONDITION_OPS[0].op : ""));
|
|
4440
4554
|
const chosenField = next.field ?? onField;
|
|
4441
4555
|
const chosenValue = next.value ?? value;
|
|
@@ -4477,11 +4591,21 @@ function ConditionRow({ lead, expr, fields, onChange, emptyLabel = "always", cla
|
|
|
4477
4591
|
className: "h-8 w-auto min-w-[6rem] text-xs",
|
|
4478
4592
|
value: op,
|
|
4479
4593
|
onChange: (next) => write({ op: next }),
|
|
4480
|
-
options: CONDITION_OPS.map((c) => ({ value: c.op, label: c.label })),
|
|
4594
|
+
options: [...CONDITION_OPS, ...extraTerms].map((c) => ({ value: c.op, label: c.label })),
|
|
4481
4595
|
attrs: { "data-condition": "comparison" }
|
|
4482
4596
|
}
|
|
4483
4597
|
),
|
|
4484
|
-
|
|
4598
|
+
relative ? relativeTerm?.takesDays ? /* @__PURE__ */ jsx23(
|
|
4599
|
+
BasicInput6,
|
|
4600
|
+
{
|
|
4601
|
+
className: "h-8 w-16 text-xs",
|
|
4602
|
+
type: "number",
|
|
4603
|
+
min: 0,
|
|
4604
|
+
"aria-label": "Number of days",
|
|
4605
|
+
value: String(relative.days ?? 7),
|
|
4606
|
+
onChange: (e) => write({ days: Math.max(0, Math.floor(Number(e.target.value) || 0)) })
|
|
4607
|
+
}
|
|
4608
|
+
) : null : reader || op === "present" ? null : pointsAtARecord(chosen) ? (
|
|
4485
4609
|
// A RECORD IS PICKED BY ITS WORDS, NEVER TYPED AS AN ID. The same picker the
|
|
4486
4610
|
// cell uses, on the same `relation_words_many` the cell reads, so a filter and
|
|
4487
4611
|
// the column it filters can never disagree about what a record is called. It
|
|
@@ -5674,36 +5798,6 @@ function readersSentence(count, tableName2) {
|
|
|
5674
5798
|
return `${rollups} on ${tableName2 ?? "this table"} read through this.`;
|
|
5675
5799
|
}
|
|
5676
5800
|
|
|
5677
|
-
// src/personTime.ts
|
|
5678
|
-
import { useSyncExternalStore } from "react";
|
|
5679
|
-
var zone = null;
|
|
5680
|
-
var listeners = /* @__PURE__ */ new Set();
|
|
5681
|
-
function usePersonTimeZone() {
|
|
5682
|
-
return useSyncExternalStore(
|
|
5683
|
-
(cb) => {
|
|
5684
|
-
listeners.add(cb);
|
|
5685
|
-
return () => listeners.delete(cb);
|
|
5686
|
-
},
|
|
5687
|
-
() => zone,
|
|
5688
|
-
() => null
|
|
5689
|
-
);
|
|
5690
|
-
}
|
|
5691
|
-
function personWallNow(at = /* @__PURE__ */ new Date()) {
|
|
5692
|
-
if (!zone) return at;
|
|
5693
|
-
const parts = new Intl.DateTimeFormat("en-US", {
|
|
5694
|
-
timeZone: zone,
|
|
5695
|
-
year: "numeric",
|
|
5696
|
-
month: "2-digit",
|
|
5697
|
-
day: "2-digit",
|
|
5698
|
-
hour: "2-digit",
|
|
5699
|
-
minute: "2-digit",
|
|
5700
|
-
second: "2-digit",
|
|
5701
|
-
hourCycle: "h23"
|
|
5702
|
-
}).formatToParts(at);
|
|
5703
|
-
const n = (t) => Number(parts.find((p) => p.type === t)?.value ?? 0);
|
|
5704
|
-
return new Date(n("year"), n("month") - 1, n("day"), n("hour"), n("minute"), n("second"));
|
|
5705
|
-
}
|
|
5706
|
-
|
|
5707
5801
|
// src/gridMenus.ts
|
|
5708
5802
|
function nextFieldSort(fields) {
|
|
5709
5803
|
let last = 0;
|