@ai-matrx/records-ui 0.110.0 → 0.110.2

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/dist/index.js CHANGED
@@ -6879,7 +6879,7 @@ import { Badge as Badge5, cn as cn18 } from "@ai-matrx/design-system";
6879
6879
  import { createContext as createContext5, useContext as useContext5 } from "react";
6880
6880
 
6881
6881
  // src/firstPage.ts
6882
- import { asRecordsDataSource, createRecordsClient, recordingDataSource } from "@ai-matrx/records/core";
6882
+ import { asRecordsDataSource as asRecordsDataSource2, createRecordsClient, recordingDataSource } from "@ai-matrx/records/core";
6883
6883
 
6884
6884
  // src/viewKeys.ts
6885
6885
  var STORE_KEEPS_TIMELINE = true;
@@ -7340,6 +7340,689 @@ var LOOK_WORDS = {
7340
7340
  newName: "Name for the new view"
7341
7341
  };
7342
7342
 
7343
+ // ../entity-data/src/port/port.ts
7344
+ import { isUuidShape as isUuidShape3 } from "@ai-matrx/kit/uuid";
7345
+ import { mintOpId } from "@ai-matrx/records";
7346
+
7347
+ // ../entity-data/src/core/client.ts
7348
+ import { asRecordsDataSource } from "@ai-matrx/records/core";
7349
+
7350
+ // ../entity-data/src/core/errors.ts
7351
+ import { mapPgError } from "@ai-matrx/records/core";
7352
+ var ENTITY_REFUSALS = {
7353
+ /** conflict_version: somebody else's write won. */
7354
+ MX001: "stale_write",
7355
+ /** organization_required: the call needs an organization and carried none. */
7356
+ MX002: "organization_required",
7357
+ /** forbidden. */
7358
+ MX003: "door",
7359
+ /** not_found (also: not visible to this person). */
7360
+ MX004: "not_found",
7361
+ /** validation_refused (detail.reason required / bad_value / ambiguous_word / constraint; `not_supported` is read apart below). */
7362
+ MX005: "invalid_argument",
7363
+ /** system_column: a write named a column the store owns. */
7364
+ MX008: "invalid_argument",
7365
+ /** unknown_identifier: a column that is not there or not usable here. */
7366
+ MX012: "invalid_argument",
7367
+ /** cursor_invalid: the page cursor belongs to another list; the engine restarts the page. */
7368
+ MX013: "invalid_argument",
7369
+ /** view_not_offered. */
7370
+ MX015: "invalid_argument",
7371
+ /** invalid_argument: a parameter the door refuses by name. */
7372
+ MX016: "invalid_argument"
7373
+ };
7374
+ function mapEntityError(error, where) {
7375
+ const mapped = mapPgError(error, where);
7376
+ const state = mapped.sqlstate;
7377
+ if (state && /^MX\d{3}$/.test(state)) {
7378
+ const code = ENTITY_REFUSALS[state];
7379
+ if (code) {
7380
+ const reason = mapped.detail?.reason;
7381
+ const known = { ...mapped, code: state === "MX005" && reason === "not_supported" ? "not_supported" : code };
7382
+ delete known.unmapped;
7383
+ delete known.diagnostic;
7384
+ return known;
7385
+ }
7386
+ }
7387
+ return mapped;
7388
+ }
7389
+ function refusal2(code, message, hint) {
7390
+ return { ok: false, error: { code, message, ...hint ? { hint } : {} } };
7391
+ }
7392
+
7393
+ // ../entity-data/src/core/client.ts
7394
+ var OP_ID_HEADER = "x-matrx-op-id";
7395
+ var ENTITY_DOOR_SCHEMA = "platform";
7396
+ function createEntityClient(options) {
7397
+ const source = asRecordsDataSource(options.dataSource ?? options.supabase);
7398
+ let warnedHeaderless = false;
7399
+ function withHeaders(pending, headers) {
7400
+ if (!headers) return;
7401
+ const builder = pending;
7402
+ if (typeof builder.setHeader === "function") {
7403
+ for (const [name, value] of Object.entries(headers)) builder.setHeader(name, value);
7404
+ return;
7405
+ }
7406
+ if (!warnedHeaderless) {
7407
+ warnedHeaderless = true;
7408
+ console.warn(
7409
+ `[@ai-matrx/entity-data] This data source cannot carry a per-call header (${Object.keys(headers).join(", ")}), so this browser re-reads the notice of its own writes once.`
7410
+ );
7411
+ }
7412
+ }
7413
+ async function call(fn, args, schema = ENTITY_DOOR_SCHEMA, headers) {
7414
+ try {
7415
+ const pending = source.rpc(fn, args, { schema });
7416
+ withHeaders(pending, headers);
7417
+ const answer = await pending;
7418
+ if (answer.error) return { ok: false, error: mapEntityError(answer.error, `${schema}.${fn}`) };
7419
+ return { ok: true, data: answer.data };
7420
+ } catch (thrown) {
7421
+ return {
7422
+ ok: false,
7423
+ error: mapEntityError({ code: "", message: thrown instanceof Error ? thrown.message : String(thrown) }, `${schema}.${fn}`)
7424
+ };
7425
+ }
7426
+ }
7427
+ return {
7428
+ list(request) {
7429
+ const args = {
7430
+ p_entity_type: request.token,
7431
+ p_scope: request.scope ?? null,
7432
+ p_filter: request.filter ?? {},
7433
+ p_search: request.search ?? null,
7434
+ p_sort: request.sort ?? null,
7435
+ p_archived: request.archived ?? "active",
7436
+ p_page_size: request.pageSize ?? null,
7437
+ p_after: request.after ?? null,
7438
+ p_with_total: request.withTotal ?? true
7439
+ };
7440
+ return call("entity_list_scoped", args);
7441
+ },
7442
+ get(request) {
7443
+ return call("entity_get", { p_entity_type: request.token, p_ids: [...request.ids] });
7444
+ },
7445
+ columns(request) {
7446
+ return call("entity_columns", { p_organization_id: request.organizationId ?? null, p_token: request.token });
7447
+ },
7448
+ insert(request) {
7449
+ return call(
7450
+ "entity_insert",
7451
+ { p_entity_type: request.token, p_organization_id: request.organizationId, p_rows: request.rows.map((r) => ({ ...r })) },
7452
+ ENTITY_DOOR_SCHEMA,
7453
+ opHeader(request.opId)
7454
+ );
7455
+ },
7456
+ update(request) {
7457
+ return call(
7458
+ "entity_update",
7459
+ { p_entity_type: request.token, p_id: request.id, p_base_version: request.baseVersion, p_patch: request.patch },
7460
+ ENTITY_DOOR_SCHEMA,
7461
+ opHeader(request.opId)
7462
+ );
7463
+ },
7464
+ archive(request) {
7465
+ return call("entity_archive", { p_entity_type: request.token, p_ids: [...request.ids] }, ENTITY_DOOR_SCHEMA, opHeader(request.opId));
7466
+ },
7467
+ unarchive(request) {
7468
+ return call("entity_unarchive", { p_entity_type: request.token, p_ids: [...request.ids] }, ENTITY_DOOR_SCHEMA, opHeader(request.opId));
7469
+ },
7470
+ knob(request) {
7471
+ return call("knob_resolve", { p_feature: "entity_data", p_key: request.key, p_organization_id: request.organizationId ?? null });
7472
+ },
7473
+ async memberOrganizations() {
7474
+ const answer = await call("my_orgs", {}, "iam");
7475
+ if (!answer.ok) return answer;
7476
+ const rows = Array.isArray(answer.data) ? answer.data : [];
7477
+ const ids = rows.map((row) => typeof row === "string" ? row : row && typeof row === "object" ? Object.values(row)[0] : null).filter((id) => typeof id === "string");
7478
+ return { ok: true, data: ids };
7479
+ }
7480
+ };
7481
+ }
7482
+ function opHeader(opId) {
7483
+ return opId ? { [OP_ID_HEADER]: opId } : void 0;
7484
+ }
7485
+
7486
+ // ../entity-data/src/core/realtime.ts
7487
+ import {
7488
+ defineChannelNamespace,
7489
+ subscribeToRealtimeManager
7490
+ } from "@ai-matrx/realtime";
7491
+ import { isOwnOp } from "@ai-matrx/records";
7492
+ var entityOrgChannel = defineChannelNamespace({
7493
+ namespace: "entity-org",
7494
+ foreignTopic: "mx:entity-org",
7495
+ parts: ["organizationId", "token"],
7496
+ description: "One organization's changes to one platform type (contacts, deals, projects, tasks, employees). Carries NOTICES written by platform.entity_org_notice_stmt \u2014 which ids moved, never a value. Admitted by the one RLS policy on realtime.messages to members of that organization."
7497
+ });
7498
+ var ENTITY_NOTICE_EVENT = "entity_bump";
7499
+ var DEFAULT_BATCH_MS = 150;
7500
+ var DEFAULT_MAX_WAIT_MS = 1e3;
7501
+ var DEFAULT_MAX_ORG_TOPICS = 20;
7502
+ function entityNoticeKey(notice) {
7503
+ return notice.id ?? (notice.at ? `${notice.organization_id ?? ""}:${notice.entity_type ?? ""}:${notice.at}` : void 0);
7504
+ }
7505
+ function entityOrgTopic(organizationId, token2) {
7506
+ return entityOrgChannel.topic({ organizationId, token: token2 });
7507
+ }
7508
+ function entityOrgChannelSpec(organizationId, token2, onNotice, onBackfill) {
7509
+ return {
7510
+ topic: entityOrgTopic(organizationId, token2),
7511
+ // Database Broadcast is authorized by RLS on realtime.messages; the manager awaits setAuth() first.
7512
+ private: true,
7513
+ // The sender is Postgres: no Matrx envelope. Our own write is known by the op id it carried.
7514
+ wire: { mode: "raw", isOwnMessage: (payload) => isOwnOp(payload?.op_id) },
7515
+ eventKey: (_source, payload) => entityNoticeKey(payload ?? {}),
7516
+ broadcast: [
7517
+ {
7518
+ event: ENTITY_NOTICE_EVENT,
7519
+ onMessage: (message) => {
7520
+ const notice = message.data ?? {};
7521
+ if (isOwnOp(notice.op_id)) return;
7522
+ onNotice(notice);
7523
+ }
7524
+ }
7525
+ ],
7526
+ // Realtime has no replay: a channel back from a gap re-reads.
7527
+ onBackfill: () => onBackfill()
7528
+ };
7529
+ }
7530
+ function orderOrganizationTopics(input) {
7531
+ const members = input.members ? new Set(input.members) : null;
7532
+ const out = [];
7533
+ const push = (org) => {
7534
+ if (!org || out.includes(org)) return;
7535
+ if (members && !members.has(org)) return;
7536
+ out.push(org);
7537
+ };
7538
+ push(input.active);
7539
+ push(input.filter);
7540
+ const held = [...(input.held ?? /* @__PURE__ */ new Map()).entries()].sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));
7541
+ for (const [org] of held) push(org);
7542
+ for (const org of [...input.members ?? []].sort()) push(org);
7543
+ return out.slice(0, Math.max(0, input.max));
7544
+ }
7545
+ function createEntityRealtime(options = {}) {
7546
+ const batchMs = options.batchMs ?? DEFAULT_BATCH_MS;
7547
+ const maxWaitMs = options.maxWaitMs ?? DEFAULT_MAX_WAIT_MS;
7548
+ const channels = /* @__PURE__ */ new Map();
7549
+ const open = (organizationId, token2) => {
7550
+ const channel = { listeners: /* @__PURE__ */ new Set(), stop: null };
7551
+ const spec = entityOrgChannelSpec(
7552
+ organizationId,
7553
+ token2,
7554
+ (notice) => {
7555
+ for (const listener of channel.listeners) listener.notice(notice);
7556
+ },
7557
+ () => {
7558
+ for (const listener of channel.listeners) listener.backfill();
7559
+ }
7560
+ );
7561
+ if (options.manager) {
7562
+ const handle = options.manager.open(spec);
7563
+ channel.stop = () => handle.close();
7564
+ } else {
7565
+ channel.stop = subscribeToRealtimeManager(() => spec);
7566
+ }
7567
+ return channel;
7568
+ };
7569
+ return {
7570
+ subscribe({ token: token2, organizationIds }, sink) {
7571
+ let timer = null;
7572
+ let firstAt = 0;
7573
+ let pending = /* @__PURE__ */ new Set();
7574
+ let wholeList = false;
7575
+ const flush = () => {
7576
+ if (timer !== null) clearTimeout(timer);
7577
+ timer = null;
7578
+ const ids = [...pending];
7579
+ const all = wholeList;
7580
+ pending = /* @__PURE__ */ new Set();
7581
+ wholeList = false;
7582
+ if (all) sink.rows(null);
7583
+ else if (ids.length > 0) sink.rows(ids);
7584
+ };
7585
+ const nudge = () => {
7586
+ const now = Date.now();
7587
+ if (timer === null) firstAt = now;
7588
+ else clearTimeout(timer);
7589
+ const wait = Math.max(0, Math.min(batchMs, firstAt + maxWaitMs - now));
7590
+ timer = setTimeout(flush, wait);
7591
+ };
7592
+ const listener = {
7593
+ notice(notice) {
7594
+ if (notice.entity_type && notice.entity_type !== token2) return;
7595
+ if (notice.ids == null) wholeList = true;
7596
+ else for (const id of notice.ids) pending.add(id);
7597
+ nudge();
7598
+ },
7599
+ backfill() {
7600
+ wholeList = true;
7601
+ flush();
7602
+ }
7603
+ };
7604
+ const keys = [...new Set(organizationIds)].map((org) => {
7605
+ const key = entityOrgTopic(org, token2);
7606
+ const channel = channels.get(key) ?? open(org, token2);
7607
+ channels.set(key, channel);
7608
+ channel.listeners.add(listener);
7609
+ return key;
7610
+ });
7611
+ return () => {
7612
+ if (timer !== null) clearTimeout(timer);
7613
+ for (const key of keys) {
7614
+ const channel = channels.get(key);
7615
+ if (!channel) continue;
7616
+ channel.listeners.delete(listener);
7617
+ if (channel.listeners.size > 0) continue;
7618
+ channel.stop?.();
7619
+ channels.delete(key);
7620
+ }
7621
+ };
7622
+ }
7623
+ };
7624
+ }
7625
+
7626
+ // ../entity-data/src/core/wire.ts
7627
+ var IDENTITY = {
7628
+ _id: "id",
7629
+ _version: "version",
7630
+ _organization_id: "organization_id"
7631
+ };
7632
+ var CUSTOM_PREFIX = "_custom.";
7633
+ function wireColumn(column, customKeys) {
7634
+ const identity = IDENTITY[column];
7635
+ if (identity) return identity;
7636
+ if (column.startsWith(CUSTOM_PREFIX)) return column;
7637
+ return customKeys.has(column) ? `${CUSTOM_PREFIX}${column}` : column;
7638
+ }
7639
+ function predicate(clause, customKeys) {
7640
+ const column = wireColumn(clause.column, customKeys);
7641
+ const v = clause.value;
7642
+ switch (clause.op) {
7643
+ case "eq":
7644
+ return v === null || v === void 0 ? { column, op: "empty" } : { column, op: "eq", value: v };
7645
+ case "neq":
7646
+ return v === null || v === void 0 ? { column, op: "empty", negated: true } : { column, op: "neq", value: v };
7647
+ case "lt":
7648
+ case "lte":
7649
+ case "gt":
7650
+ case "gte":
7651
+ return { column, op: clause.op, value: v };
7652
+ case "in":
7653
+ return { column, op: "in", values: Array.isArray(v) ? v : [] };
7654
+ case "empty":
7655
+ return v === false ? { column, op: "empty", negated: true } : { column, op: "empty" };
7656
+ case "contains":
7657
+ return { column, op: "contains", value: v };
7658
+ default:
7659
+ return { column, op: String(clause.op), value: v };
7660
+ }
7661
+ }
7662
+ function toWire(query, customKeys = /* @__PURE__ */ new Set()) {
7663
+ const q = query ?? {};
7664
+ const out = {};
7665
+ const scope = {};
7666
+ if (q.lane) scope.kind = q.lane;
7667
+ if (q.org && q.org !== "all") scope.organization_id = q.org;
7668
+ if (scope.kind || scope.organization_id) out.scope = scope;
7669
+ if (q.where && q.where.length > 0) out.filter = { all: q.where.map((c) => predicate(c, customKeys)) };
7670
+ const search = q.search?.trim();
7671
+ if (search) out.search = search;
7672
+ if (q.sort && q.sort.length > 0) {
7673
+ out.sort = q.sort.map((s) => ({
7674
+ column: wireColumn(s.column, customKeys),
7675
+ dir: s.direction === "desc" ? "desc" : "asc",
7676
+ nulls: "last"
7677
+ }));
7678
+ }
7679
+ if (typeof q.pageSize === "number" && Number.isFinite(q.pageSize)) out.pageSize = Math.max(1, Math.floor(q.pageSize));
7680
+ return out;
7681
+ }
7682
+
7683
+ // ../entity-data/src/port/rows.ts
7684
+ var IDENTITY_COLUMNS = /* @__PURE__ */ new Set(["id", "version", "organization_id"]);
7685
+ var PRESENTATION_KEYS = /* @__PURE__ */ new Set(["_state", "_k"]);
7686
+ function isRefList(value) {
7687
+ return Array.isArray(value) && value.length > 0 && value.every((item) => item !== null && typeof item === "object" && typeof item.token === "string" && typeof item.id === "string");
7688
+ }
7689
+ function toRefs(value) {
7690
+ if (!isRefList(value)) return [];
7691
+ return value.map((item) => ({ token: item.token, id: item.id, label: typeof item.label === "string" ? item.label : null }));
7692
+ }
7693
+ function toRow(wire) {
7694
+ const row = {
7695
+ _id: wire.id,
7696
+ _version: wire.version,
7697
+ _organization_id: wire.organization_id,
7698
+ _custom: wire._custom && typeof wire._custom === "object" ? { ...wire._custom } : {}
7699
+ };
7700
+ for (const [key, value] of Object.entries(wire)) {
7701
+ if (IDENTITY_COLUMNS.has(key) || PRESENTATION_KEYS.has(key) || key === "_custom") continue;
7702
+ row[key] = isRefList(value) ? toRefs(value) : value === void 0 ? null : value;
7703
+ }
7704
+ return row;
7705
+ }
7706
+ function toColumn(wire) {
7707
+ const column = {
7708
+ key: wire.key,
7709
+ label: wire.label || wire.key,
7710
+ type: wire.type,
7711
+ origin: wire.origin === "custom" ? "custom" : "platform",
7712
+ required: Boolean(wire.required),
7713
+ readOnly: Boolean(wire.readOnly)
7714
+ };
7715
+ if (wire.choices && wire.choices.length > 0) column.choices = [...wire.choices];
7716
+ if (wire.linksTo && wire.linksTo.length > 0) column.linksTo = [...wire.linksTo];
7717
+ return column;
7718
+ }
7719
+ function toColumns(wire) {
7720
+ return wire.filter((c) => !IDENTITY_COLUMNS.has(c.key)).map(toColumn);
7721
+ }
7722
+
7723
+ // ../entity-data/src/port/port.ts
7724
+ function toWireValue(value) {
7725
+ if (isRef(value)) return value.id;
7726
+ if (Array.isArray(value) && value.length > 0 && value.every(isRef)) {
7727
+ return value.length === 1 ? value[0].id : value.map((ref) => ref.id);
7728
+ }
7729
+ return value;
7730
+ }
7731
+ function isRef(value) {
7732
+ return value !== null && typeof value === "object" && !Array.isArray(value) && typeof value.token === "string" && typeof value.id === "string";
7733
+ }
7734
+ function toWireValues(values) {
7735
+ const out = {};
7736
+ for (const [key, value] of Object.entries(values)) {
7737
+ if (value === void 0) continue;
7738
+ if (key === "_custom" && value && typeof value === "object" && !Array.isArray(value)) {
7739
+ out._custom = Object.fromEntries(Object.entries(value).filter(([, v]) => v !== void 0).map(([k, v]) => [k, toWireValue(v)]));
7740
+ continue;
7741
+ }
7742
+ out[key] = Array.isArray(value) && value.length === 0 && key !== "_custom" ? null : toWireValue(value);
7743
+ }
7744
+ return out;
7745
+ }
7746
+ function createEntityDataPort(options) {
7747
+ const client = options.client ?? createEntityClient({ dataSource: options.dataSource });
7748
+ const activeOrganization = () => (options.activeOrganizationId ? options.activeOrganizationId() : options.organization) ?? null;
7749
+ const gets = /* @__PURE__ */ new Map();
7750
+ const aliases = options.aliases;
7751
+ const shapes = /* @__PURE__ */ new Map();
7752
+ let warnedNotLive = false;
7753
+ const held = /* @__PURE__ */ new Map();
7754
+ const replans = /* @__PURE__ */ new Map();
7755
+ let memberships = null;
7756
+ let maxOrgTopics = null;
7757
+ function hold(alias, rows) {
7758
+ const byId = held.get(alias) ?? /* @__PURE__ */ new Map();
7759
+ held.set(alias, byId);
7760
+ const before = new Set(byId.values());
7761
+ for (const r of rows) {
7762
+ if (typeof r.id === "string" && typeof r.organization_id === "string") byId.set(r.id, r.organization_id);
7763
+ }
7764
+ if ([...byId.values()].some((org) => !before.has(org))) for (const replan of replans.get(alias) ?? []) replan();
7765
+ }
7766
+ function heldCounts(alias) {
7767
+ const counts = /* @__PURE__ */ new Map();
7768
+ for (const org of held.get(alias)?.values() ?? []) counts.set(org, (counts.get(org) ?? 0) + 1);
7769
+ return counts;
7770
+ }
7771
+ function membershipsOnce() {
7772
+ memberships ??= client.memberOrganizations().then((answer) => {
7773
+ if (answer.ok) return answer.data;
7774
+ memberships = null;
7775
+ console.warn(`[@ai-matrx/entity-data] Could not read your organizations for live updates: ${answer.error.message}`);
7776
+ return null;
7777
+ });
7778
+ return memberships;
7779
+ }
7780
+ function maxOrgTopicsOnce() {
7781
+ maxOrgTopics ??= client.knob({ key: "realtime_max_org_topics", organizationId: activeOrganization() }).then((answer) => {
7782
+ const value = answer.ok ? Number(answer.data) : Number.NaN;
7783
+ if (Number.isFinite(value) && value >= 0) return value;
7784
+ console.warn(`[@ai-matrx/entity-data] knob entity_data.realtime_max_org_topics did not resolve; joining at most ${DEFAULT_MAX_ORG_TOPICS} organizations.`);
7785
+ return DEFAULT_MAX_ORG_TOPICS;
7786
+ });
7787
+ return maxOrgTopics;
7788
+ }
7789
+ const tokenBindings = /* @__PURE__ */ new Map();
7790
+ function bindingOf(alias) {
7791
+ if (Object.prototype.hasOwnProperty.call(aliases, alias)) return aliases[alias];
7792
+ if (!options.tokensAreAliases || !/^[a-z][a-z0-9_]*$/.test(alias)) return null;
7793
+ let bound2 = tokenBindings.get(alias);
7794
+ if (!bound2) {
7795
+ bound2 = { kind: "entity", token: alias };
7796
+ tokenBindings.set(alias, bound2);
7797
+ }
7798
+ return bound2;
7799
+ }
7800
+ function noSuchAlias(alias) {
7801
+ return refusal2("not_found", `This Applet has no data source called "${alias}".`, "Use one of the aliases sources() lists.");
7802
+ }
7803
+ function shapeOf(alias, binding) {
7804
+ let held2 = shapes.get(alias);
7805
+ if (!held2) {
7806
+ held2 = client.columns({ token: binding.token, organizationId: binding.organizationId ?? null }).then((answer) => {
7807
+ if (!answer.ok) shapes.delete(alias);
7808
+ return answer;
7809
+ });
7810
+ shapes.set(alias, held2);
7811
+ }
7812
+ return held2;
7813
+ }
7814
+ function getCoalesced(alias, token2, id) {
7815
+ return new Promise((resolve) => {
7816
+ let batch = gets.get(alias);
7817
+ if (!batch) {
7818
+ batch = /* @__PURE__ */ new Map();
7819
+ gets.set(alias, batch);
7820
+ const asked3 = batch;
7821
+ queueMicrotask(() => {
7822
+ gets.delete(alias);
7823
+ void flushGets(alias, token2, asked3);
7824
+ });
7825
+ }
7826
+ const waiting = batch.get(id) ?? [];
7827
+ waiting.push(resolve);
7828
+ batch.set(id, waiting);
7829
+ });
7830
+ }
7831
+ async function flushGets(alias, token2, asked3) {
7832
+ const answer = await client.get({ token: token2, ids: [...asked3.keys()] });
7833
+ if (answer.ok) hold(alias, answer.data.rows);
7834
+ const byId = new Map(answer.ok ? answer.data.rows.map((r) => [r.id, r]) : []);
7835
+ for (const [id, waiting] of asked3) {
7836
+ const found = byId.get(id);
7837
+ const wire = found && found["_state"]?.archived === true ? void 0 : found;
7838
+ const result = answer.ok ? { ok: true, data: wire ? toRow(wire) : null } : answer;
7839
+ for (const resolve of waiting) resolve(result);
7840
+ }
7841
+ }
7842
+ function readBack(alias, answer, what) {
7843
+ if (!answer.ok) return answer;
7844
+ hold(alias, answer.data.rows);
7845
+ const wire = answer.data.rows[0];
7846
+ if (!wire) {
7847
+ return refusal2(
7848
+ "not_found",
7849
+ `${what} was saved, but you cannot open it now, so it is not shown here.`,
7850
+ "The row is in the store; who may open it decides whether it appears in this list."
7851
+ );
7852
+ }
7853
+ return { ok: true, data: toRow(wire) };
7854
+ }
7855
+ function done(answer) {
7856
+ return answer.ok ? { ok: true, data: void 0 } : answer;
7857
+ }
7858
+ return {
7859
+ async sources() {
7860
+ const out = [];
7861
+ for (const [alias, binding] of Object.entries(aliases)) {
7862
+ const shape = await shapeOf(alias, binding);
7863
+ if (!shape.ok) return shape;
7864
+ out.push({
7865
+ alias,
7866
+ label: binding.label ?? shape.data.label ?? alias,
7867
+ kind: "entity",
7868
+ canCreate: Boolean(shape.data.can_create),
7869
+ canUpdate: Boolean(shape.data.can_update)
7870
+ });
7871
+ }
7872
+ return { ok: true, data: out };
7873
+ },
7874
+ async describe(alias) {
7875
+ const binding = bindingOf(alias);
7876
+ if (!binding) return noSuchAlias(alias);
7877
+ const shape = await shapeOf(alias, binding);
7878
+ if (!shape.ok) return shape;
7879
+ return {
7880
+ ok: true,
7881
+ data: {
7882
+ token: binding.token,
7883
+ label: binding.label ?? shape.data.label ?? binding.token,
7884
+ canCreate: Boolean(shape.data.can_create),
7885
+ canUpdate: Boolean(shape.data.can_update)
7886
+ }
7887
+ };
7888
+ },
7889
+ async columns(alias) {
7890
+ const binding = bindingOf(alias);
7891
+ if (!binding) return noSuchAlias(alias);
7892
+ const shape = await shapeOf(alias, binding);
7893
+ return shape.ok ? { ok: true, data: toColumns(shape.data.columns) } : shape;
7894
+ },
7895
+ async list(alias, q = {}, cursor) {
7896
+ const binding = bindingOf(alias);
7897
+ if (!binding) return noSuchAlias(alias);
7898
+ let customKeys = /* @__PURE__ */ new Set();
7899
+ if (q.where && q.where.length > 0 || q.sort && q.sort.length > 0) {
7900
+ const shape = await shapeOf(alias, binding);
7901
+ if (!shape.ok) return shape;
7902
+ customKeys = new Set(shape.data.columns.filter((c) => c.origin === "custom").map((c) => c.key));
7903
+ }
7904
+ const wire = toWire(q, customKeys);
7905
+ if (binding.organizationId) wire.scope = { ...wire.scope, organization_id: binding.organizationId };
7906
+ const answer = await client.list({ token: binding.token, ...wire, after: cursor ?? null });
7907
+ if (!answer.ok) return answer;
7908
+ const { data } = answer;
7909
+ if (data.sort_ignored.length > 0) {
7910
+ console.warn(`[@ai-matrx/entity-data] "${alias}" sorts by one column for now; ignored: ${data.sort_ignored.join(", ")}.`);
7911
+ }
7912
+ hold(alias, data.rows);
7913
+ const page = {
7914
+ rows: data.rows.map(toRow),
7915
+ // A count that stopped at the store's cap is a floor, not a count: unknown beats a wrong number.
7916
+ total: data.total === null || data.total === void 0 || data.total_is_capped ? null : data.total,
7917
+ cursor: data.has_more ? data.next_after : null
7918
+ };
7919
+ return { ok: true, data: page };
7920
+ },
7921
+ async get(alias, id) {
7922
+ const binding = bindingOf(alias);
7923
+ if (!binding) return noSuchAlias(alias);
7924
+ if (!isUuidShape3(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
7925
+ return getCoalesced(alias, binding.token, id);
7926
+ },
7927
+ async create(alias, values) {
7928
+ const binding = bindingOf(alias);
7929
+ if (!binding) return noSuchAlias(alias);
7930
+ const organizationId = binding.organizationId ?? activeOrganization();
7931
+ if (!organizationId) {
7932
+ return refusal2(
7933
+ "organization_required",
7934
+ "Choose the organization this new record belongs to.",
7935
+ "Pick an organization, then add the row again. Nothing was saved."
7936
+ );
7937
+ }
7938
+ const answer = await client.insert({ token: binding.token, organizationId, rows: [toWireValues(values)], opId: mintOpId() });
7939
+ return readBack(alias, answer, "The new row");
7940
+ },
7941
+ async update(alias, id, patch, baseVersion) {
7942
+ const binding = bindingOf(alias);
7943
+ if (!binding) return noSuchAlias(alias);
7944
+ if (!isUuidShape3(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
7945
+ const answer = await client.update({ token: binding.token, id, baseVersion, patch: toWireValues(patch), opId: mintOpId() });
7946
+ return readBack(alias, answer, "The change");
7947
+ },
7948
+ async archive(alias, id) {
7949
+ const binding = bindingOf(alias);
7950
+ if (!binding) return noSuchAlias(alias);
7951
+ if (!isUuidShape3(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
7952
+ return done(await client.archive({ token: binding.token, ids: [id], opId: mintOpId() }));
7953
+ },
7954
+ async restore(alias, id) {
7955
+ const binding = bindingOf(alias);
7956
+ if (!binding) return noSuchAlias(alias);
7957
+ if (!isUuidShape3(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
7958
+ return done(await client.unarchive({ token: binding.token, ids: [id], opId: mintOpId() }));
7959
+ },
7960
+ subscribe(event, listener) {
7961
+ const alias = event.startsWith("rows:") ? event.slice(5) : null;
7962
+ const binding = alias ? bindingOf(alias) : null;
7963
+ if (!alias || !binding) {
7964
+ throw new Error(`DataPort.subscribe: "${event}" is not an event this Applet's port carries. Use rows:<alias>.`);
7965
+ }
7966
+ const realtime = options.realtime;
7967
+ if (!realtime) {
7968
+ if (!warnedNotLive) {
7969
+ warnedNotLive = true;
7970
+ console.warn("[@ai-matrx/entity-data] This host bound no realtime layer, so other people's changes appear on the next read.");
7971
+ }
7972
+ return () => {
7973
+ };
7974
+ }
7975
+ let stopped = false;
7976
+ let joined = [];
7977
+ let stopLive = null;
7978
+ const sink = { rows: (ids) => listener({ ids: ids === null ? null : [...ids] }) };
7979
+ const plan = async () => {
7980
+ const organizationIds = binding.organizationId ? [binding.organizationId] : orderOrganizationTopics({
7981
+ active: activeOrganization(),
7982
+ held: heldCounts(alias),
7983
+ members: await membershipsOnce(),
7984
+ max: await maxOrgTopicsOnce()
7985
+ });
7986
+ if (stopped) return;
7987
+ if (organizationIds.length === joined.length && organizationIds.every((org, i) => org === joined[i])) return;
7988
+ const previous = stopLive;
7989
+ joined = organizationIds;
7990
+ stopLive = realtime.subscribe({ token: binding.token, organizationIds }, sink);
7991
+ previous?.();
7992
+ };
7993
+ const replan = () => void plan();
7994
+ const set = replans.get(alias) ?? /* @__PURE__ */ new Set();
7995
+ replans.set(alias, set);
7996
+ set.add(replan);
7997
+ replan();
7998
+ return () => {
7999
+ stopped = true;
8000
+ set.delete(replan);
8001
+ stopLive?.();
8002
+ stopLive = null;
8003
+ };
8004
+ }
8005
+ };
8006
+ }
8007
+ function createSeedPort(dataSource) {
8008
+ return createEntityDataPort({ client: createEntityClient({ dataSource }), aliases: {}, tokensAreAliases: true, activeOrganizationId: () => null });
8009
+ }
8010
+
8011
+ // src/entityQuery.ts
8012
+ function entityTableQuery(options = {}) {
8013
+ const search = (options.search ?? "").trim();
8014
+ return { ...options.pageSize ? { pageSize: options.pageSize } : {}, ...search ? { search } : {} };
8015
+ }
8016
+ function entityChartQuestion(input) {
8017
+ const m = input.measure ?? { op: "count" };
8018
+ return {
8019
+ ...input.by ? { by: [input.by] } : {},
8020
+ show: [m.op === "count" ? "count" : { op: m.op, of: m.of }],
8021
+ ...input.where ? { where: input.where } : {},
8022
+ ...input.organization ? { organization: input.organization } : {}
8023
+ };
8024
+ }
8025
+
7343
8026
  // src/firstPage.ts
7344
8027
  var EMBEDDED_PAGE_SIZE = 50;
7345
8028
 
@@ -16068,7 +16751,7 @@ import {
16068
16751
  useRecordsClient as useRecordsClient26
16069
16752
  } from "@ai-matrx/records/react";
16070
16753
  import { Button as Button30, Separator as Separator2, cn as cn29 } from "@ai-matrx/design-system";
16071
- import { mapPgError } from "@ai-matrx/records/core";
16754
+ import { mapPgError as mapPgError2 } from "@ai-matrx/records/core";
16072
16755
  import { jsx as jsx55, jsxs as jsxs50 } from "react/jsx-runtime";
16073
16756
  function isEmptyValue(value) {
16074
16757
  return value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
@@ -16140,7 +16823,7 @@ async function writeStandardRowValues(client, args) {
16140
16823
  { schema: config.schema ?? "custom" }
16141
16824
  );
16142
16825
  if (!old.error) return { ok: true };
16143
- const error = mapPgError(old.error, "entityValueWrite");
16826
+ const error = mapPgError2(old.error, "entityValueWrite");
16144
16827
  return { ok: false, error: doorIsAbsent(error) && first && first.error.code !== "door_absent" ? first.error : error };
16145
16828
  }
16146
16829
  function doorIsAbsent(error) {
@@ -24946,771 +25629,105 @@ function GridBody({
24946
25629
  }
24947
25630
  ) });
24948
25631
  }
24949
- function askWhenAColumnMenuIsReached(target, ask) {
24950
- if (target?.closest?.('[role="columnheader"], thead, [data-matrx-canonical-signature="column-menu"]')) ask();
24951
- }
24952
- var DETAIL_OFF = { enabled: false };
24953
- var WINDOW_OFF = { enabled: false };
24954
- var VIRTUALIZE_FILLED = { threshold: 40 };
24955
- function menuFace(items) {
24956
- return JSON.stringify(items, (_key, value) => typeof value === "function" ? "\u0192" : value);
24957
- }
24958
- function menuThroughLatest(items, at, latest) {
24959
- return items.map((item) => {
24960
- const path = `${at}/${item.id}`;
24961
- return {
24962
- ...item,
24963
- ...item.onSelect ? { onSelect: () => latest.get(path)?.() } : {},
24964
- ...item.submenu ? { submenu: menuThroughLatest(item.submenu, path, latest) } : {}
24965
- };
24966
- });
24967
- }
24968
- function bindLatest(items, at, latest) {
24969
- for (const item of items) {
24970
- const path = `${at}/${item.id}`;
24971
- if (item.onSelect) latest.set(path, item.onSelect);
24972
- if (item.submenu) bindLatest(item.submenu, path, latest);
24973
- }
24974
- }
24975
- function holdHeaderMenu(held, latest, key, items) {
24976
- if (!items) return items;
24977
- const at = `menu:${key}`;
24978
- bindLatest(items, at, latest);
24979
- const sig = menuFace(items);
24980
- const was = held.get(at);
24981
- if (was && was.sig === sig) return was.value;
24982
- const value = menuThroughLatest(items, at, latest);
24983
- held.set(at, { sig, value });
24984
- return value;
24985
- }
24986
- function holdByContent(held, at, value) {
24987
- if (value === void 0) return value;
24988
- const sig = JSON.stringify(value);
24989
- const was = held.get(at);
24990
- if (was && was.sig === sig) return was.value;
24991
- held.set(at, { sig, value });
24992
- return value;
24993
- }
24994
- function sameColumns(a, b) {
24995
- if (a === b) return true;
24996
- if (a.length !== b.length) return false;
24997
- return a.every((column, i) => {
24998
- const other = b[i];
24999
- if (column === other) return true;
25000
- const keys = Object.keys(column);
25001
- return keys.length === Object.keys(other).length && keys.every((key) => Object.is(column[key], other[key]));
25002
- });
25003
- }
25004
- function withHeaderMenus(columns, menuFor, filterFor) {
25005
- return columns.map((column) => {
25006
- const items = menuFor(String(column.id));
25007
- const filter = filterFor?.(String(column.id));
25008
- const withMenu = items && items.length > 0 ? { ...column, headerMenu: items } : column;
25009
- return filter ? { ...withMenu, ...filter } : withMenu;
25010
- });
25011
- }
25012
- function withoutGoneColumns(query, liveKeys, openingSort) {
25013
- const sortGone = Boolean(query.sort && !liveKeys.has(query.sort.id));
25014
- const goneFilters = Object.keys(query.columnFilters ?? {}).filter((key) => !liveKeys.has(key));
25015
- if (!sortGone && goneFilters.length === 0) return query;
25016
- const columnFilters = { ...query.columnFilters };
25017
- for (const key of goneFilters) delete columnFilters[key];
25018
- const fallback = openingSort && liveKeys.has(openingSort.id) ? openingSort : null;
25019
- return { ...query, sort: sortGone ? fallback : query.sort, columnFilters, page: 1 };
25020
- }
25021
- function sortIgnoredOf(answer) {
25022
- return Array.isArray(answer?.sortIgnored) ? answer.sortIgnored : [];
25023
- }
25024
-
25025
- // src/RecordsTableCard.tsx
25026
- import { MatrxTableCard, MatrxTableCardEmpty, MatrxTableCardShowMore as MatrxTableCardShowMore2, TABLE_CARD_DEFAULT_INITIAL_ROWS } from "@ai-matrx/design-system/data-table";
25027
- import { Button as Button43 } from "@ai-matrx/design-system";
25028
- import { useFields as useFields9, useOptionalRecordsClient as useOptionalRecordsClient9, useTable as useTable7 } from "@ai-matrx/records/react";
25029
-
25030
- // src/entityTable.tsx
25031
- import { useId as useId2, useMemo as useMemo38 } from "react";
25032
- import { MatrxDataTable as MatrxDataTable3 } from "@ai-matrx/design-system/data-table";
25033
- import { useRecordsClient as useRecordsClient40 } from "@ai-matrx/records/react";
25034
-
25035
- // ../entity-data/src/react/index.tsx
25036
- import { createContext as createContext8, createElement, useContext as useContext8, useMemo as useMemo37, useRef as useRef38 } from "react";
25037
- import { useQuery } from "@tanstack/react-query";
25038
- import {
25039
- dataKeys,
25040
- hostEvents,
25041
- useRecordsQueryClient,
25042
- useDataColumns,
25043
- useDataMutations,
25044
- useDataRow,
25045
- useDataRows
25046
- } from "@ai-matrx/records/data/react";
25047
-
25048
- // ../entity-data/src/core/client.ts
25049
- import { asRecordsDataSource as asRecordsDataSource2 } from "@ai-matrx/records/core";
25050
-
25051
- // ../entity-data/src/core/errors.ts
25052
- import { mapPgError as mapPgError2 } from "@ai-matrx/records/core";
25053
- var ENTITY_REFUSALS = {
25054
- /** conflict_version: somebody else's write won. */
25055
- MX001: "stale_write",
25056
- /** organization_required: the call needs an organization and carried none. */
25057
- MX002: "organization_required",
25058
- /** forbidden. */
25059
- MX003: "door",
25060
- /** not_found (also: not visible to this person). */
25061
- MX004: "not_found",
25062
- /** validation_refused (detail.reason required / bad_value / ambiguous_word / constraint; `not_supported` is read apart below). */
25063
- MX005: "invalid_argument",
25064
- /** system_column: a write named a column the store owns. */
25065
- MX008: "invalid_argument",
25066
- /** unknown_identifier: a column that is not there or not usable here. */
25067
- MX012: "invalid_argument",
25068
- /** cursor_invalid: the page cursor belongs to another list; the engine restarts the page. */
25069
- MX013: "invalid_argument",
25070
- /** view_not_offered. */
25071
- MX015: "invalid_argument",
25072
- /** invalid_argument: a parameter the door refuses by name. */
25073
- MX016: "invalid_argument"
25074
- };
25075
- function mapEntityError(error, where) {
25076
- const mapped = mapPgError2(error, where);
25077
- const state = mapped.sqlstate;
25078
- if (state && /^MX\d{3}$/.test(state)) {
25079
- const code = ENTITY_REFUSALS[state];
25080
- if (code) {
25081
- const reason = mapped.detail?.reason;
25082
- const known = { ...mapped, code: state === "MX005" && reason === "not_supported" ? "not_supported" : code };
25083
- delete known.unmapped;
25084
- delete known.diagnostic;
25085
- return known;
25086
- }
25087
- }
25088
- return mapped;
25089
- }
25090
- function refusal2(code, message, hint) {
25091
- return { ok: false, error: { code, message, ...hint ? { hint } : {} } };
25092
- }
25093
-
25094
- // ../entity-data/src/core/client.ts
25095
- var OP_ID_HEADER = "x-matrx-op-id";
25096
- var ENTITY_DOOR_SCHEMA = "platform";
25097
- function createEntityClient(options) {
25098
- const source = asRecordsDataSource2(options.dataSource ?? options.supabase);
25099
- let warnedHeaderless = false;
25100
- function withHeaders(pending, headers) {
25101
- if (!headers) return;
25102
- const builder = pending;
25103
- if (typeof builder.setHeader === "function") {
25104
- for (const [name, value] of Object.entries(headers)) builder.setHeader(name, value);
25105
- return;
25106
- }
25107
- if (!warnedHeaderless) {
25108
- warnedHeaderless = true;
25109
- console.warn(
25110
- `[@ai-matrx/entity-data] This data source cannot carry a per-call header (${Object.keys(headers).join(", ")}), so this browser re-reads the notice of its own writes once.`
25111
- );
25112
- }
25113
- }
25114
- async function call(fn, args, schema = ENTITY_DOOR_SCHEMA, headers) {
25115
- try {
25116
- const pending = source.rpc(fn, args, { schema });
25117
- withHeaders(pending, headers);
25118
- const answer = await pending;
25119
- if (answer.error) return { ok: false, error: mapEntityError(answer.error, `${schema}.${fn}`) };
25120
- return { ok: true, data: answer.data };
25121
- } catch (thrown) {
25122
- return {
25123
- ok: false,
25124
- error: mapEntityError({ code: "", message: thrown instanceof Error ? thrown.message : String(thrown) }, `${schema}.${fn}`)
25125
- };
25126
- }
25127
- }
25128
- return {
25129
- list(request) {
25130
- const args = {
25131
- p_entity_type: request.token,
25132
- p_scope: request.scope ?? null,
25133
- p_filter: request.filter ?? {},
25134
- p_search: request.search ?? null,
25135
- p_sort: request.sort ?? null,
25136
- p_archived: request.archived ?? "active",
25137
- p_page_size: request.pageSize ?? null,
25138
- p_after: request.after ?? null,
25139
- p_with_total: request.withTotal ?? true
25140
- };
25141
- return call("entity_list_scoped", args);
25142
- },
25143
- get(request) {
25144
- return call("entity_get", { p_entity_type: request.token, p_ids: [...request.ids] });
25145
- },
25146
- columns(request) {
25147
- return call("entity_columns", { p_organization_id: request.organizationId ?? null, p_token: request.token });
25148
- },
25149
- insert(request) {
25150
- return call(
25151
- "entity_insert",
25152
- { p_entity_type: request.token, p_organization_id: request.organizationId, p_rows: request.rows.map((r) => ({ ...r })) },
25153
- ENTITY_DOOR_SCHEMA,
25154
- opHeader(request.opId)
25155
- );
25156
- },
25157
- update(request) {
25158
- return call(
25159
- "entity_update",
25160
- { p_entity_type: request.token, p_id: request.id, p_base_version: request.baseVersion, p_patch: request.patch },
25161
- ENTITY_DOOR_SCHEMA,
25162
- opHeader(request.opId)
25163
- );
25164
- },
25165
- archive(request) {
25166
- return call("entity_archive", { p_entity_type: request.token, p_ids: [...request.ids] }, ENTITY_DOOR_SCHEMA, opHeader(request.opId));
25167
- },
25168
- unarchive(request) {
25169
- return call("entity_unarchive", { p_entity_type: request.token, p_ids: [...request.ids] }, ENTITY_DOOR_SCHEMA, opHeader(request.opId));
25170
- },
25171
- knob(request) {
25172
- return call("knob_resolve", { p_feature: "entity_data", p_key: request.key, p_organization_id: request.organizationId ?? null });
25173
- },
25174
- async memberOrganizations() {
25175
- const answer = await call("my_orgs", {}, "iam");
25176
- if (!answer.ok) return answer;
25177
- const rows = Array.isArray(answer.data) ? answer.data : [];
25178
- const ids = rows.map((row) => typeof row === "string" ? row : row && typeof row === "object" ? Object.values(row)[0] : null).filter((id) => typeof id === "string");
25179
- return { ok: true, data: ids };
25180
- }
25181
- };
25182
- }
25183
- function opHeader(opId) {
25184
- return opId ? { [OP_ID_HEADER]: opId } : void 0;
25185
- }
25186
-
25187
- // ../entity-data/src/core/realtime.ts
25188
- import {
25189
- defineChannelNamespace,
25190
- subscribeToRealtimeManager
25191
- } from "@ai-matrx/realtime";
25192
- import { isOwnOp } from "@ai-matrx/records";
25193
- var entityOrgChannel = defineChannelNamespace({
25194
- namespace: "entity-org",
25195
- foreignTopic: "mx:entity-org",
25196
- parts: ["organizationId", "token"],
25197
- description: "One organization's changes to one platform type (contacts, deals, projects, tasks, employees). Carries NOTICES written by platform.entity_org_notice_stmt \u2014 which ids moved, never a value. Admitted by the one RLS policy on realtime.messages to members of that organization."
25198
- });
25199
- var ENTITY_NOTICE_EVENT = "entity_bump";
25200
- var DEFAULT_BATCH_MS = 150;
25201
- var DEFAULT_MAX_WAIT_MS = 1e3;
25202
- var DEFAULT_MAX_ORG_TOPICS = 20;
25203
- function entityNoticeKey(notice) {
25204
- return notice.id ?? (notice.at ? `${notice.organization_id ?? ""}:${notice.entity_type ?? ""}:${notice.at}` : void 0);
25205
- }
25206
- function entityOrgTopic(organizationId, token2) {
25207
- return entityOrgChannel.topic({ organizationId, token: token2 });
25208
- }
25209
- function entityOrgChannelSpec(organizationId, token2, onNotice, onBackfill) {
25210
- return {
25211
- topic: entityOrgTopic(organizationId, token2),
25212
- // Database Broadcast is authorized by RLS on realtime.messages; the manager awaits setAuth() first.
25213
- private: true,
25214
- // The sender is Postgres: no Matrx envelope. Our own write is known by the op id it carried.
25215
- wire: { mode: "raw", isOwnMessage: (payload) => isOwnOp(payload?.op_id) },
25216
- eventKey: (_source, payload) => entityNoticeKey(payload ?? {}),
25217
- broadcast: [
25218
- {
25219
- event: ENTITY_NOTICE_EVENT,
25220
- onMessage: (message) => {
25221
- const notice = message.data ?? {};
25222
- if (isOwnOp(notice.op_id)) return;
25223
- onNotice(notice);
25224
- }
25225
- }
25226
- ],
25227
- // Realtime has no replay: a channel back from a gap re-reads.
25228
- onBackfill: () => onBackfill()
25229
- };
25230
- }
25231
- function orderOrganizationTopics(input) {
25232
- const members = input.members ? new Set(input.members) : null;
25233
- const out = [];
25234
- const push = (org) => {
25235
- if (!org || out.includes(org)) return;
25236
- if (members && !members.has(org)) return;
25237
- out.push(org);
25238
- };
25239
- push(input.active);
25240
- push(input.filter);
25241
- const held = [...(input.held ?? /* @__PURE__ */ new Map()).entries()].sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));
25242
- for (const [org] of held) push(org);
25243
- for (const org of [...input.members ?? []].sort()) push(org);
25244
- return out.slice(0, Math.max(0, input.max));
25245
- }
25246
- function createEntityRealtime(options = {}) {
25247
- const batchMs = options.batchMs ?? DEFAULT_BATCH_MS;
25248
- const maxWaitMs = options.maxWaitMs ?? DEFAULT_MAX_WAIT_MS;
25249
- const channels = /* @__PURE__ */ new Map();
25250
- const open = (organizationId, token2) => {
25251
- const channel = { listeners: /* @__PURE__ */ new Set(), stop: null };
25252
- const spec = entityOrgChannelSpec(
25253
- organizationId,
25254
- token2,
25255
- (notice) => {
25256
- for (const listener of channel.listeners) listener.notice(notice);
25257
- },
25258
- () => {
25259
- for (const listener of channel.listeners) listener.backfill();
25260
- }
25261
- );
25262
- if (options.manager) {
25263
- const handle = options.manager.open(spec);
25264
- channel.stop = () => handle.close();
25265
- } else {
25266
- channel.stop = subscribeToRealtimeManager(() => spec);
25267
- }
25268
- return channel;
25269
- };
25270
- return {
25271
- subscribe({ token: token2, organizationIds }, sink) {
25272
- let timer = null;
25273
- let firstAt = 0;
25274
- let pending = /* @__PURE__ */ new Set();
25275
- let wholeList = false;
25276
- const flush = () => {
25277
- if (timer !== null) clearTimeout(timer);
25278
- timer = null;
25279
- const ids = [...pending];
25280
- const all = wholeList;
25281
- pending = /* @__PURE__ */ new Set();
25282
- wholeList = false;
25283
- if (all) sink.rows(null);
25284
- else if (ids.length > 0) sink.rows(ids);
25285
- };
25286
- const nudge = () => {
25287
- const now = Date.now();
25288
- if (timer === null) firstAt = now;
25289
- else clearTimeout(timer);
25290
- const wait = Math.max(0, Math.min(batchMs, firstAt + maxWaitMs - now));
25291
- timer = setTimeout(flush, wait);
25292
- };
25293
- const listener = {
25294
- notice(notice) {
25295
- if (notice.entity_type && notice.entity_type !== token2) return;
25296
- if (notice.ids == null) wholeList = true;
25297
- else for (const id of notice.ids) pending.add(id);
25298
- nudge();
25299
- },
25300
- backfill() {
25301
- wholeList = true;
25302
- flush();
25303
- }
25304
- };
25305
- const keys = [...new Set(organizationIds)].map((org) => {
25306
- const key = entityOrgTopic(org, token2);
25307
- const channel = channels.get(key) ?? open(org, token2);
25308
- channels.set(key, channel);
25309
- channel.listeners.add(listener);
25310
- return key;
25311
- });
25312
- return () => {
25313
- if (timer !== null) clearTimeout(timer);
25314
- for (const key of keys) {
25315
- const channel = channels.get(key);
25316
- if (!channel) continue;
25317
- channel.listeners.delete(listener);
25318
- if (channel.listeners.size > 0) continue;
25319
- channel.stop?.();
25320
- channels.delete(key);
25321
- }
25322
- };
25323
- }
25324
- };
25325
- }
25326
-
25327
- // ../entity-data/src/port/port.ts
25328
- import { isUuidShape as isUuidShape3 } from "@ai-matrx/kit/uuid";
25329
- import { mintOpId } from "@ai-matrx/records";
25330
-
25331
- // ../entity-data/src/core/wire.ts
25332
- var IDENTITY = {
25333
- _id: "id",
25334
- _version: "version",
25335
- _organization_id: "organization_id"
25336
- };
25337
- var CUSTOM_PREFIX = "_custom.";
25338
- function wireColumn(column, customKeys) {
25339
- const identity = IDENTITY[column];
25340
- if (identity) return identity;
25341
- if (column.startsWith(CUSTOM_PREFIX)) return column;
25342
- return customKeys.has(column) ? `${CUSTOM_PREFIX}${column}` : column;
25343
- }
25344
- function predicate(clause, customKeys) {
25345
- const column = wireColumn(clause.column, customKeys);
25346
- const v = clause.value;
25347
- switch (clause.op) {
25348
- case "eq":
25349
- return v === null || v === void 0 ? { column, op: "empty" } : { column, op: "eq", value: v };
25350
- case "neq":
25351
- return v === null || v === void 0 ? { column, op: "empty", negated: true } : { column, op: "neq", value: v };
25352
- case "lt":
25353
- case "lte":
25354
- case "gt":
25355
- case "gte":
25356
- return { column, op: clause.op, value: v };
25357
- case "in":
25358
- return { column, op: "in", values: Array.isArray(v) ? v : [] };
25359
- case "empty":
25360
- return v === false ? { column, op: "empty", negated: true } : { column, op: "empty" };
25361
- case "contains":
25362
- return { column, op: "contains", value: v };
25363
- default:
25364
- return { column, op: String(clause.op), value: v };
25365
- }
25366
- }
25367
- function toWire(query, customKeys = /* @__PURE__ */ new Set()) {
25368
- const q = query ?? {};
25369
- const out = {};
25370
- const scope = {};
25371
- if (q.lane) scope.kind = q.lane;
25372
- if (q.org && q.org !== "all") scope.organization_id = q.org;
25373
- if (scope.kind || scope.organization_id) out.scope = scope;
25374
- if (q.where && q.where.length > 0) out.filter = { all: q.where.map((c) => predicate(c, customKeys)) };
25375
- const search = q.search?.trim();
25376
- if (search) out.search = search;
25377
- if (q.sort && q.sort.length > 0) {
25378
- out.sort = q.sort.map((s) => ({
25379
- column: wireColumn(s.column, customKeys),
25380
- dir: s.direction === "desc" ? "desc" : "asc",
25381
- nulls: "last"
25382
- }));
25383
- }
25384
- if (typeof q.pageSize === "number" && Number.isFinite(q.pageSize)) out.pageSize = Math.max(1, Math.floor(q.pageSize));
25385
- return out;
25386
- }
25387
-
25388
- // ../entity-data/src/port/rows.ts
25389
- var IDENTITY_COLUMNS = /* @__PURE__ */ new Set(["id", "version", "organization_id"]);
25390
- var PRESENTATION_KEYS = /* @__PURE__ */ new Set(["_state", "_k"]);
25391
- function isRefList(value) {
25392
- return Array.isArray(value) && value.length > 0 && value.every((item) => item !== null && typeof item === "object" && typeof item.token === "string" && typeof item.id === "string");
25393
- }
25394
- function toRefs(value) {
25395
- if (!isRefList(value)) return [];
25396
- return value.map((item) => ({ token: item.token, id: item.id, label: typeof item.label === "string" ? item.label : null }));
25397
- }
25398
- function toRow(wire) {
25399
- const row = {
25400
- _id: wire.id,
25401
- _version: wire.version,
25402
- _organization_id: wire.organization_id,
25403
- _custom: wire._custom && typeof wire._custom === "object" ? { ...wire._custom } : {}
25404
- };
25405
- for (const [key, value] of Object.entries(wire)) {
25406
- if (IDENTITY_COLUMNS.has(key) || PRESENTATION_KEYS.has(key) || key === "_custom") continue;
25407
- row[key] = isRefList(value) ? toRefs(value) : value === void 0 ? null : value;
25408
- }
25409
- return row;
25632
+ function askWhenAColumnMenuIsReached(target, ask) {
25633
+ if (target?.closest?.('[role="columnheader"], thead, [data-matrx-canonical-signature="column-menu"]')) ask();
25410
25634
  }
25411
- function toColumn(wire) {
25412
- const column = {
25413
- key: wire.key,
25414
- label: wire.label || wire.key,
25415
- type: wire.type,
25416
- origin: wire.origin === "custom" ? "custom" : "platform",
25417
- required: Boolean(wire.required),
25418
- readOnly: Boolean(wire.readOnly)
25419
- };
25420
- if (wire.choices && wire.choices.length > 0) column.choices = [...wire.choices];
25421
- if (wire.linksTo && wire.linksTo.length > 0) column.linksTo = [...wire.linksTo];
25422
- return column;
25635
+ var DETAIL_OFF = { enabled: false };
25636
+ var WINDOW_OFF = { enabled: false };
25637
+ var VIRTUALIZE_FILLED = { threshold: 40 };
25638
+ function menuFace(items) {
25639
+ return JSON.stringify(items, (_key, value) => typeof value === "function" ? "\u0192" : value);
25423
25640
  }
25424
- function toColumns(wire) {
25425
- return wire.filter((c) => !IDENTITY_COLUMNS.has(c.key)).map(toColumn);
25641
+ function menuThroughLatest(items, at, latest) {
25642
+ return items.map((item) => {
25643
+ const path = `${at}/${item.id}`;
25644
+ return {
25645
+ ...item,
25646
+ ...item.onSelect ? { onSelect: () => latest.get(path)?.() } : {},
25647
+ ...item.submenu ? { submenu: menuThroughLatest(item.submenu, path, latest) } : {}
25648
+ };
25649
+ });
25426
25650
  }
25427
-
25428
- // ../entity-data/src/port/port.ts
25429
- function toWireValue(value) {
25430
- if (isRef(value)) return value.id;
25431
- if (Array.isArray(value) && value.length > 0 && value.every(isRef)) {
25432
- return value.length === 1 ? value[0].id : value.map((ref) => ref.id);
25651
+ function bindLatest(items, at, latest) {
25652
+ for (const item of items) {
25653
+ const path = `${at}/${item.id}`;
25654
+ if (item.onSelect) latest.set(path, item.onSelect);
25655
+ if (item.submenu) bindLatest(item.submenu, path, latest);
25433
25656
  }
25657
+ }
25658
+ function holdHeaderMenu(held, latest, key, items) {
25659
+ if (!items) return items;
25660
+ const at = `menu:${key}`;
25661
+ bindLatest(items, at, latest);
25662
+ const sig = menuFace(items);
25663
+ const was = held.get(at);
25664
+ if (was && was.sig === sig) return was.value;
25665
+ const value = menuThroughLatest(items, at, latest);
25666
+ held.set(at, { sig, value });
25434
25667
  return value;
25435
25668
  }
25436
- function isRef(value) {
25437
- return value !== null && typeof value === "object" && !Array.isArray(value) && typeof value.token === "string" && typeof value.id === "string";
25669
+ function holdByContent(held, at, value) {
25670
+ if (value === void 0) return value;
25671
+ const sig = JSON.stringify(value);
25672
+ const was = held.get(at);
25673
+ if (was && was.sig === sig) return was.value;
25674
+ held.set(at, { sig, value });
25675
+ return value;
25438
25676
  }
25439
- function toWireValues(values) {
25440
- const out = {};
25441
- for (const [key, value] of Object.entries(values)) {
25442
- if (value === void 0) continue;
25443
- if (key === "_custom" && value && typeof value === "object" && !Array.isArray(value)) {
25444
- out._custom = Object.fromEntries(Object.entries(value).filter(([, v]) => v !== void 0).map(([k, v]) => [k, toWireValue(v)]));
25445
- continue;
25446
- }
25447
- out[key] = Array.isArray(value) && value.length === 0 && key !== "_custom" ? null : toWireValue(value);
25448
- }
25449
- return out;
25677
+ function sameColumns(a, b) {
25678
+ if (a === b) return true;
25679
+ if (a.length !== b.length) return false;
25680
+ return a.every((column, i) => {
25681
+ const other = b[i];
25682
+ if (column === other) return true;
25683
+ const keys = Object.keys(column);
25684
+ return keys.length === Object.keys(other).length && keys.every((key) => Object.is(column[key], other[key]));
25685
+ });
25450
25686
  }
25451
- function createEntityDataPort(options) {
25452
- const client = options.client ?? createEntityClient({ dataSource: options.dataSource });
25453
- const activeOrganization = () => (options.activeOrganizationId ? options.activeOrganizationId() : options.organization) ?? null;
25454
- const gets = /* @__PURE__ */ new Map();
25455
- const aliases = options.aliases;
25456
- const shapes = /* @__PURE__ */ new Map();
25457
- let warnedNotLive = false;
25458
- const held = /* @__PURE__ */ new Map();
25459
- const replans = /* @__PURE__ */ new Map();
25460
- let memberships = null;
25461
- let maxOrgTopics = null;
25462
- function hold(alias, rows) {
25463
- const byId = held.get(alias) ?? /* @__PURE__ */ new Map();
25464
- held.set(alias, byId);
25465
- const before = new Set(byId.values());
25466
- for (const r of rows) {
25467
- if (typeof r.id === "string" && typeof r.organization_id === "string") byId.set(r.id, r.organization_id);
25468
- }
25469
- if ([...byId.values()].some((org) => !before.has(org))) for (const replan of replans.get(alias) ?? []) replan();
25470
- }
25471
- function heldCounts(alias) {
25472
- const counts = /* @__PURE__ */ new Map();
25473
- for (const org of held.get(alias)?.values() ?? []) counts.set(org, (counts.get(org) ?? 0) + 1);
25474
- return counts;
25475
- }
25476
- function membershipsOnce() {
25477
- memberships ??= client.memberOrganizations().then((answer) => {
25478
- if (answer.ok) return answer.data;
25479
- memberships = null;
25480
- console.warn(`[@ai-matrx/entity-data] Could not read your organizations for live updates: ${answer.error.message}`);
25481
- return null;
25482
- });
25483
- return memberships;
25484
- }
25485
- function maxOrgTopicsOnce() {
25486
- maxOrgTopics ??= client.knob({ key: "realtime_max_org_topics", organizationId: activeOrganization() }).then((answer) => {
25487
- const value = answer.ok ? Number(answer.data) : Number.NaN;
25488
- if (Number.isFinite(value) && value >= 0) return value;
25489
- console.warn(`[@ai-matrx/entity-data] knob entity_data.realtime_max_org_topics did not resolve; joining at most ${DEFAULT_MAX_ORG_TOPICS} organizations.`);
25490
- return DEFAULT_MAX_ORG_TOPICS;
25491
- });
25492
- return maxOrgTopics;
25493
- }
25494
- const tokenBindings = /* @__PURE__ */ new Map();
25495
- function bindingOf(alias) {
25496
- if (Object.prototype.hasOwnProperty.call(aliases, alias)) return aliases[alias];
25497
- if (!options.tokensAreAliases || !/^[a-z][a-z0-9_]*$/.test(alias)) return null;
25498
- let bound2 = tokenBindings.get(alias);
25499
- if (!bound2) {
25500
- bound2 = { kind: "entity", token: alias };
25501
- tokenBindings.set(alias, bound2);
25502
- }
25503
- return bound2;
25504
- }
25505
- function noSuchAlias(alias) {
25506
- return refusal2("not_found", `This Applet has no data source called "${alias}".`, "Use one of the aliases sources() lists.");
25507
- }
25508
- function shapeOf(alias, binding) {
25509
- let held2 = shapes.get(alias);
25510
- if (!held2) {
25511
- held2 = client.columns({ token: binding.token, organizationId: binding.organizationId ?? null }).then((answer) => {
25512
- if (!answer.ok) shapes.delete(alias);
25513
- return answer;
25514
- });
25515
- shapes.set(alias, held2);
25516
- }
25517
- return held2;
25518
- }
25519
- function getCoalesced(alias, token2, id) {
25520
- return new Promise((resolve) => {
25521
- let batch = gets.get(alias);
25522
- if (!batch) {
25523
- batch = /* @__PURE__ */ new Map();
25524
- gets.set(alias, batch);
25525
- const asked3 = batch;
25526
- queueMicrotask(() => {
25527
- gets.delete(alias);
25528
- void flushGets(alias, token2, asked3);
25529
- });
25530
- }
25531
- const waiting = batch.get(id) ?? [];
25532
- waiting.push(resolve);
25533
- batch.set(id, waiting);
25534
- });
25535
- }
25536
- async function flushGets(alias, token2, asked3) {
25537
- const answer = await client.get({ token: token2, ids: [...asked3.keys()] });
25538
- if (answer.ok) hold(alias, answer.data.rows);
25539
- const byId = new Map(answer.ok ? answer.data.rows.map((r) => [r.id, r]) : []);
25540
- for (const [id, waiting] of asked3) {
25541
- const found = byId.get(id);
25542
- const wire = found && found["_state"]?.archived === true ? void 0 : found;
25543
- const result = answer.ok ? { ok: true, data: wire ? toRow(wire) : null } : answer;
25544
- for (const resolve of waiting) resolve(result);
25545
- }
25546
- }
25547
- function readBack(alias, answer, what) {
25548
- if (!answer.ok) return answer;
25549
- hold(alias, answer.data.rows);
25550
- const wire = answer.data.rows[0];
25551
- if (!wire) {
25552
- return refusal2(
25553
- "not_found",
25554
- `${what} was saved, but you cannot open it now, so it is not shown here.`,
25555
- "The row is in the store; who may open it decides whether it appears in this list."
25556
- );
25557
- }
25558
- return { ok: true, data: toRow(wire) };
25559
- }
25560
- function done(answer) {
25561
- return answer.ok ? { ok: true, data: void 0 } : answer;
25562
- }
25563
- return {
25564
- async sources() {
25565
- const out = [];
25566
- for (const [alias, binding] of Object.entries(aliases)) {
25567
- const shape = await shapeOf(alias, binding);
25568
- if (!shape.ok) return shape;
25569
- out.push({
25570
- alias,
25571
- label: binding.label ?? shape.data.label ?? alias,
25572
- kind: "entity",
25573
- canCreate: Boolean(shape.data.can_create),
25574
- canUpdate: Boolean(shape.data.can_update)
25575
- });
25576
- }
25577
- return { ok: true, data: out };
25578
- },
25579
- async describe(alias) {
25580
- const binding = bindingOf(alias);
25581
- if (!binding) return noSuchAlias(alias);
25582
- const shape = await shapeOf(alias, binding);
25583
- if (!shape.ok) return shape;
25584
- return {
25585
- ok: true,
25586
- data: {
25587
- token: binding.token,
25588
- label: binding.label ?? shape.data.label ?? binding.token,
25589
- canCreate: Boolean(shape.data.can_create),
25590
- canUpdate: Boolean(shape.data.can_update)
25591
- }
25592
- };
25593
- },
25594
- async columns(alias) {
25595
- const binding = bindingOf(alias);
25596
- if (!binding) return noSuchAlias(alias);
25597
- const shape = await shapeOf(alias, binding);
25598
- return shape.ok ? { ok: true, data: toColumns(shape.data.columns) } : shape;
25599
- },
25600
- async list(alias, q = {}, cursor) {
25601
- const binding = bindingOf(alias);
25602
- if (!binding) return noSuchAlias(alias);
25603
- let customKeys = /* @__PURE__ */ new Set();
25604
- if (q.where && q.where.length > 0 || q.sort && q.sort.length > 0) {
25605
- const shape = await shapeOf(alias, binding);
25606
- if (!shape.ok) return shape;
25607
- customKeys = new Set(shape.data.columns.filter((c) => c.origin === "custom").map((c) => c.key));
25608
- }
25609
- const wire = toWire(q, customKeys);
25610
- if (binding.organizationId) wire.scope = { ...wire.scope, organization_id: binding.organizationId };
25611
- const answer = await client.list({ token: binding.token, ...wire, after: cursor ?? null });
25612
- if (!answer.ok) return answer;
25613
- const { data } = answer;
25614
- if (data.sort_ignored.length > 0) {
25615
- console.warn(`[@ai-matrx/entity-data] "${alias}" sorts by one column for now; ignored: ${data.sort_ignored.join(", ")}.`);
25616
- }
25617
- hold(alias, data.rows);
25618
- const page = {
25619
- rows: data.rows.map(toRow),
25620
- // A count that stopped at the store's cap is a floor, not a count: unknown beats a wrong number.
25621
- total: data.total === null || data.total === void 0 || data.total_is_capped ? null : data.total,
25622
- cursor: data.has_more ? data.next_after : null
25623
- };
25624
- return { ok: true, data: page };
25625
- },
25626
- async get(alias, id) {
25627
- const binding = bindingOf(alias);
25628
- if (!binding) return noSuchAlias(alias);
25629
- if (!isUuidShape3(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
25630
- return getCoalesced(alias, binding.token, id);
25631
- },
25632
- async create(alias, values) {
25633
- const binding = bindingOf(alias);
25634
- if (!binding) return noSuchAlias(alias);
25635
- const organizationId = binding.organizationId ?? activeOrganization();
25636
- if (!organizationId) {
25637
- return refusal2(
25638
- "organization_required",
25639
- "Choose the organization this new record belongs to.",
25640
- "Pick an organization, then add the row again. Nothing was saved."
25641
- );
25642
- }
25643
- const answer = await client.insert({ token: binding.token, organizationId, rows: [toWireValues(values)], opId: mintOpId() });
25644
- return readBack(alias, answer, "The new row");
25645
- },
25646
- async update(alias, id, patch, baseVersion) {
25647
- const binding = bindingOf(alias);
25648
- if (!binding) return noSuchAlias(alias);
25649
- if (!isUuidShape3(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
25650
- const answer = await client.update({ token: binding.token, id, baseVersion, patch: toWireValues(patch), opId: mintOpId() });
25651
- return readBack(alias, answer, "The change");
25652
- },
25653
- async archive(alias, id) {
25654
- const binding = bindingOf(alias);
25655
- if (!binding) return noSuchAlias(alias);
25656
- if (!isUuidShape3(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
25657
- return done(await client.archive({ token: binding.token, ids: [id], opId: mintOpId() }));
25658
- },
25659
- async restore(alias, id) {
25660
- const binding = bindingOf(alias);
25661
- if (!binding) return noSuchAlias(alias);
25662
- if (!isUuidShape3(id)) return refusal2("invalid_argument", `"${String(id)}" is not a row id.`);
25663
- return done(await client.unarchive({ token: binding.token, ids: [id], opId: mintOpId() }));
25664
- },
25665
- subscribe(event, listener) {
25666
- const alias = event.startsWith("rows:") ? event.slice(5) : null;
25667
- const binding = alias ? bindingOf(alias) : null;
25668
- if (!alias || !binding) {
25669
- throw new Error(`DataPort.subscribe: "${event}" is not an event this Applet's port carries. Use rows:<alias>.`);
25670
- }
25671
- const realtime = options.realtime;
25672
- if (!realtime) {
25673
- if (!warnedNotLive) {
25674
- warnedNotLive = true;
25675
- console.warn("[@ai-matrx/entity-data] This host bound no realtime layer, so other people's changes appear on the next read.");
25676
- }
25677
- return () => {
25678
- };
25679
- }
25680
- let stopped = false;
25681
- let joined = [];
25682
- let stopLive = null;
25683
- const sink = { rows: (ids) => listener({ ids: ids === null ? null : [...ids] }) };
25684
- const plan = async () => {
25685
- const organizationIds = binding.organizationId ? [binding.organizationId] : orderOrganizationTopics({
25686
- active: activeOrganization(),
25687
- held: heldCounts(alias),
25688
- members: await membershipsOnce(),
25689
- max: await maxOrgTopicsOnce()
25690
- });
25691
- if (stopped) return;
25692
- if (organizationIds.length === joined.length && organizationIds.every((org, i) => org === joined[i])) return;
25693
- const previous = stopLive;
25694
- joined = organizationIds;
25695
- stopLive = realtime.subscribe({ token: binding.token, organizationIds }, sink);
25696
- previous?.();
25697
- };
25698
- const replan = () => void plan();
25699
- const set = replans.get(alias) ?? /* @__PURE__ */ new Set();
25700
- replans.set(alias, set);
25701
- set.add(replan);
25702
- replan();
25703
- return () => {
25704
- stopped = true;
25705
- set.delete(replan);
25706
- stopLive?.();
25707
- stopLive = null;
25708
- };
25709
- }
25710
- };
25687
+ function withHeaderMenus(columns, menuFor, filterFor) {
25688
+ return columns.map((column) => {
25689
+ const items = menuFor(String(column.id));
25690
+ const filter = filterFor?.(String(column.id));
25691
+ const withMenu = items && items.length > 0 ? { ...column, headerMenu: items } : column;
25692
+ return filter ? { ...withMenu, ...filter } : withMenu;
25693
+ });
25694
+ }
25695
+ function withoutGoneColumns(query, liveKeys, openingSort) {
25696
+ const sortGone = Boolean(query.sort && !liveKeys.has(query.sort.id));
25697
+ const goneFilters = Object.keys(query.columnFilters ?? {}).filter((key) => !liveKeys.has(key));
25698
+ if (!sortGone && goneFilters.length === 0) return query;
25699
+ const columnFilters = { ...query.columnFilters };
25700
+ for (const key of goneFilters) delete columnFilters[key];
25701
+ const fallback = openingSort && liveKeys.has(openingSort.id) ? openingSort : null;
25702
+ return { ...query, sort: sortGone ? fallback : query.sort, columnFilters, page: 1 };
25711
25703
  }
25704
+ function sortIgnoredOf(answer) {
25705
+ return Array.isArray(answer?.sortIgnored) ? answer.sortIgnored : [];
25706
+ }
25707
+
25708
+ // src/RecordsTableCard.tsx
25709
+ import { MatrxTableCard, MatrxTableCardEmpty, MatrxTableCardShowMore as MatrxTableCardShowMore2, TABLE_CARD_DEFAULT_INITIAL_ROWS } from "@ai-matrx/design-system/data-table";
25710
+ import { Button as Button43 } from "@ai-matrx/design-system";
25711
+ import { useFields as useFields9, useOptionalRecordsClient as useOptionalRecordsClient9, useTable as useTable7 } from "@ai-matrx/records/react";
25712
+
25713
+ // src/entityTable.tsx
25714
+ import { useId as useId2, useMemo as useMemo38 } from "react";
25715
+ import { MatrxDataTable as MatrxDataTable3 } from "@ai-matrx/design-system/data-table";
25716
+ import { useRecordsClient as useRecordsClient40 } from "@ai-matrx/records/react";
25712
25717
 
25713
25718
  // ../entity-data/src/react/index.tsx
25719
+ import { createContext as createContext8, createElement, useContext as useContext8, useMemo as useMemo37, useRef as useRef38, useState as useState62 } from "react";
25720
+ import { QueryClient, QueryClientContext, QueryClientProvider, useQuery } from "@tanstack/react-query";
25721
+ import { useSeededSource } from "@ai-matrx/records/react";
25722
+ import {
25723
+ dataKeys,
25724
+ hostEvents,
25725
+ useRecordsQueryClient,
25726
+ useDataColumns,
25727
+ useDataMutations,
25728
+ useDataRow,
25729
+ useDataRows
25730
+ } from "@ai-matrx/records/data/react";
25714
25731
  var ENTITY_PORT_KEY = "entity-data";
25715
25732
  var EntityScopeContext = createContext8(null);
25716
25733
  function EntityDataProvider({ dataSource, client, activeOrganizationId, realtime, portKey = ENTITY_PORT_KEY, children }) {
@@ -25728,7 +25745,10 @@ function EntityDataProvider({ dataSource, client, activeOrganizationId, realtime
25728
25745
  });
25729
25746
  return { port, portKey, events: hostEvents(port) };
25730
25747
  }, [client, dataSource, realtime, portKey]);
25731
- return createElement(EntityScopeContext.Provider, { value: scope }, children);
25748
+ const above = useContext8(QueryClientContext);
25749
+ const [serverClient] = useState62(() => typeof window === "undefined" && !above ? new QueryClient() : null);
25750
+ const inner2 = createElement(EntityScopeContext.Provider, { value: scope }, children);
25751
+ return serverClient ? createElement(QueryClientProvider, { client: serverClient }, inner2) : inner2;
25732
25752
  }
25733
25753
  function useOptionalEntityScope() {
25734
25754
  return useContext8(EntityScopeContext);
@@ -25743,16 +25763,20 @@ function useEntityScope() {
25743
25763
  return scope;
25744
25764
  }
25745
25765
  function useEntityList(token2, query = {}) {
25746
- return useDataRows(token2, query, useEntityScope());
25766
+ const seeded = useSeededSource(`entity:${token2}:rows:${JSON.stringify(query)}`, (source) => createSeedPort(source).list(token2, query));
25767
+ return useDataRows(token2, query, useEntityScope(), seeded);
25747
25768
  }
25748
25769
  function useEntityColumns(token2) {
25749
- return useDataColumns(token2, useEntityScope());
25770
+ const seeded = useSeededSource(`entity:${token2}:columns`, (source) => createSeedPort(source).columns(token2));
25771
+ return useDataColumns(token2, useEntityScope(), seeded);
25750
25772
  }
25751
25773
  function useEntityType(token2) {
25752
25774
  const scope = useEntityScope();
25753
25775
  const qc = useRecordsQueryClient();
25776
+ const seeded = useSeededSource(`entity:${token2}:type`, (source) => createSeedPort(source).describe(token2));
25754
25777
  const q = useQuery(
25755
25778
  {
25779
+ ...seeded ? { initialData: seeded.data, initialDataUpdatedAt: seeded.at } : {},
25756
25780
  queryKey: [...dataKeys.alias(scope.portKey, token2), "type"],
25757
25781
  queryFn: async () => {
25758
25782
  const answer = await scope.port.describe(token2);
@@ -25820,10 +25844,9 @@ function editTypeOf(column) {
25820
25844
  return false;
25821
25845
  }
25822
25846
  function useEntityTable(token2, options = {}) {
25823
- const search = (options.search ?? "").trim();
25824
25847
  const type = useEntityType(token2);
25825
25848
  const columns = useEntityColumns(token2);
25826
- const list = useEntityList(token2, { ...options.pageSize ? { pageSize: options.pageSize } : {}, ...search ? { search } : {} });
25849
+ const list = useEntityList(token2, entityTableQuery(options));
25827
25850
  const write = useEntityWrite(token2);
25828
25851
  const shown4 = useMemo38(() => entityShownColumns(columns.data ?? []), [columns.data]);
25829
25852
  const refused = list.error ?? columns.error ?? type.error;
@@ -26020,7 +26043,7 @@ function ConnectedRecordsTableCard({
26020
26043
 
26021
26044
  // src/ExportMenu.tsx
26022
26045
  import { downloadFile as downloadFile2 } from "@ai-matrx/kit/download";
26023
- import { useEffect as useEffect53, useState as useState62 } from "react";
26046
+ import { useEffect as useEffect53, useState as useState63 } from "react";
26024
26047
  import { useFields as useFields10, useRecords as useRecords6, useRecordsClient as useRecordsClient41, useTable as useTable8 } from "@ai-matrx/records/react";
26025
26048
  import { exportCsv, exportXlsx, wholeValueOf as wholeValueOf5, withWholeValues } from "@ai-matrx/records/core";
26026
26049
 
@@ -26128,7 +26151,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
26128
26151
  const fields = useFields10(tableId);
26129
26152
  const page = useRecords6(view ? null : tableId, { pageSize: 500 });
26130
26153
  const viewKey = view ? JSON.stringify([view.filter ?? null, view.sorts ?? [], view.viewId ?? null]) : "";
26131
- const [viewRead, setViewRead] = useState62(null);
26154
+ const [viewRead, setViewRead] = useState63(null);
26132
26155
  useEffect53(() => {
26133
26156
  if (!view || !fields.data) return;
26134
26157
  let live = true;
@@ -26140,7 +26163,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
26140
26163
  };
26141
26164
  }, [client, tableId, fields.data, viewKey]);
26142
26165
  const viewHeld = viewRead && viewRead.key === viewKey ? viewRead : null;
26143
- const [failure, setFailure] = useState62(null);
26166
+ const [failure, setFailure] = useState63(null);
26144
26167
  const labels = useRecordLabels(fields.data ?? void 0);
26145
26168
  const records = rows ?? (view ? viewHeld && "rows" in viewHeld ? viewHeld.rows : [] : page.data?.rows ?? []);
26146
26169
  const columns = view && fields.data ? viewColumns(fields.data, view.presentation) : fields.data ?? [];
@@ -26210,7 +26233,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
26210
26233
  }
26211
26234
 
26212
26235
  // src/ImportNotice.tsx
26213
- import { useCallback as useCallback29, useEffect as useEffect54, useMemo as useMemo39, useState as useState63 } from "react";
26236
+ import { useCallback as useCallback29, useEffect as useEffect54, useMemo as useMemo39, useState as useState64 } from "react";
26214
26237
  import { useRecordsClient as useRecordsClient42 } from "@ai-matrx/records/react";
26215
26238
  import { Button as Button45, cn as cn38 } from "@ai-matrx/design-system";
26216
26239
  import { jsx as jsx76, jsxs as jsxs68 } from "react/jsx-runtime";
@@ -26237,10 +26260,10 @@ function runToNotice(runs) {
26237
26260
  }
26238
26261
  function ImportNotice({ tableId, onOpenImport, epoch = 0, className }) {
26239
26262
  const client = useRecordsClient42();
26240
- const [runs, setRuns] = useState63(null);
26241
- const [problem, setProblem] = useState63(null);
26242
- const [report, setReport] = useState63(null);
26243
- const [dismissed, setDismissed] = useState63(null);
26263
+ const [runs, setRuns] = useState64(null);
26264
+ const [problem, setProblem] = useState64(null);
26265
+ const [report, setReport] = useState64(null);
26266
+ const [dismissed, setDismissed] = useState64(null);
26244
26267
  useEffect54(() => {
26245
26268
  let live = true;
26246
26269
  void client.imports({ table_id: tableId, limit: 5 }).then((answered) => {
@@ -26314,7 +26337,7 @@ function ImportNotice({ tableId, onOpenImport, epoch = 0, className }) {
26314
26337
  }
26315
26338
 
26316
26339
  // src/SaveToTable.tsx
26317
- import { useMemo as useMemo42, useState as useState69 } from "react";
26340
+ import { useMemo as useMemo42, useState as useState70 } from "react";
26318
26341
  import { useRecordsClient as useRecordsClient48, useMyLevels as useMyLevels3, useTables as useTables3 } from "@ai-matrx/records/react";
26319
26342
  import {
26320
26343
  Button as Button52,
@@ -26330,7 +26353,7 @@ import {
26330
26353
  } from "@ai-matrx/design-system";
26331
26354
 
26332
26355
  // src/TablesHome.tsx
26333
- import { useCallback as useCallback33, useEffect as useEffect59, useState as useState68 } from "react";
26356
+ import { useCallback as useCallback33, useEffect as useEffect59, useState as useState69 } from "react";
26334
26357
  import { useRecordsClient as useRecordsClient47, useTables as useTables2 } from "@ai-matrx/records/react";
26335
26358
  import { withTableFacts } from "@ai-matrx/records/core";
26336
26359
  import { withTablePlacement as withTablePlacement2 } from "@ai-matrx/records";
@@ -26515,7 +26538,7 @@ function fieldsForNewColumns(columns) {
26515
26538
 
26516
26539
  // src/BookingSlots.tsx
26517
26540
  import { copyText as copyText3 } from "@ai-matrx/kit/clipboard";
26518
- import { useCallback as useCallback32, useEffect as useEffect57, useMemo as useMemo41, useState as useState66 } from "react";
26541
+ import { useCallback as useCallback32, useEffect as useEffect57, useMemo as useMemo41, useState as useState67 } from "react";
26519
26542
  import { useRecordsClient as useRecordsClient45, useMyLevels as useMyLevels2 } from "@ai-matrx/records/react";
26520
26543
  import { bookingPath as bookingPath2 } from "@ai-matrx/records";
26521
26544
  import { Badge as Badge11, Button as Button49, Skeleton as Skeleton7, cn as cn41 } from "@ai-matrx/design-system";
@@ -26523,7 +26546,7 @@ import { Badge as Badge11, Button as Button49, Skeleton as Skeleton7, cn as cn41
26523
26546
  // src/BookingBuilder.tsx
26524
26547
  import { copyText as copyText2 } from "@ai-matrx/kit/clipboard";
26525
26548
  import { ErrorBox as ErrorBox3 } from "@ai-matrx/design-system";
26526
- import { useCallback as useCallback30, useEffect as useEffect55, useMemo as useMemo40, useRef as useRef39, useState as useState64 } from "react";
26549
+ import { useCallback as useCallback30, useEffect as useEffect55, useMemo as useMemo40, useRef as useRef39, useState as useState65 } from "react";
26527
26550
  import { useFields as useFields11, useRecordsClient as useRecordsClient43, useTable as useTable9 } from "@ai-matrx/records/react";
26528
26551
  import { formatDurationMinutes } from "@ai-matrx/kit/format";
26529
26552
  import {
@@ -26642,24 +26665,24 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
26642
26665
  const table = useTable9(tableId);
26643
26666
  const rights = useTableRights(table.data);
26644
26667
  const fields = useFields11(tableId);
26645
- const [existing, setExisting] = useState64(null);
26646
- const [loaded, setLoaded] = useState64(false);
26647
- const [error, setError] = useState64(null);
26648
- const [saving, setSaving] = useState64(false);
26649
- const [publishing, setPublishing] = useState64(false);
26650
- const [copied, setCopied] = useState64(false);
26651
- const [title, setTitle] = useState64("");
26652
- const [minutes, setMinutes] = useState64(30);
26653
- const [buffer, setBuffer] = useState64(0);
26654
- const [lead, setLead] = useState64(120);
26655
- const [perDay, setPerDay] = useState64(8);
26656
- const [days, setDays] = useState64(30);
26657
- const [timezone, setTimezone] = useState64(() => ownTimeZone());
26658
- const [windows, setWindows] = useState64(() => draftWindows(null));
26659
- const [asked3, setAsked] = useState64([]);
26660
- const [confirmation, setConfirmation] = useState64("");
26661
- const [offer, setOffer] = useState64(null);
26662
- const [formId, setFormId] = useState64(bookingId ?? null);
26668
+ const [existing, setExisting] = useState65(null);
26669
+ const [loaded, setLoaded] = useState65(false);
26670
+ const [error, setError] = useState65(null);
26671
+ const [saving, setSaving] = useState65(false);
26672
+ const [publishing, setPublishing] = useState65(false);
26673
+ const [copied, setCopied] = useState65(false);
26674
+ const [title, setTitle] = useState65("");
26675
+ const [minutes, setMinutes] = useState65(30);
26676
+ const [buffer, setBuffer] = useState65(0);
26677
+ const [lead, setLead] = useState65(120);
26678
+ const [perDay, setPerDay] = useState65(8);
26679
+ const [days, setDays] = useState65(30);
26680
+ const [timezone, setTimezone] = useState65(() => ownTimeZone());
26681
+ const [windows, setWindows] = useState65(() => draftWindows(null));
26682
+ const [asked3, setAsked] = useState65([]);
26683
+ const [confirmation, setConfirmation] = useState65("");
26684
+ const [offer, setOffer] = useState65(null);
26685
+ const [formId, setFormId] = useState65(bookingId ?? null);
26663
26686
  const madeRef = useRef39(null);
26664
26687
  const publicOrigin = host.publicOrigin ?? (typeof window === "undefined" ? "" : window.location.origin);
26665
26688
  const askable = useMemo40(
@@ -26739,7 +26762,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
26739
26762
  const first = askable[0]?.key;
26740
26763
  setAsked(keys.length > 0 ? keys : first ? [first] : []);
26741
26764
  }, [loaded, existing, formId, fields.data, askable]);
26742
- const [addingWho, setAddingWho] = useState64(false);
26765
+ const [addingWho, setAddingWho] = useState65(false);
26743
26766
  async function addWho() {
26744
26767
  setAddingWho(true);
26745
26768
  setError(null);
@@ -26758,7 +26781,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
26758
26781
  setAddingWho(false);
26759
26782
  setWhoAdded(true);
26760
26783
  }
26761
- const [whoAdded, setWhoAdded] = useState64(false);
26784
+ const [whoAdded, setWhoAdded] = useState65(false);
26762
26785
  useEffect55(() => {
26763
26786
  if (!whoAdded) return;
26764
26787
  const who = askable.filter((f) => isWhoField(f)).map((f) => f.key);
@@ -27068,7 +27091,7 @@ function BuildOrAsk({
27068
27091
  }
27069
27092
 
27070
27093
  // src/BuiltOnArchive.tsx
27071
- import { useCallback as useCallback31, useEffect as useEffect56, useState as useState65 } from "react";
27094
+ import { useCallback as useCallback31, useEffect as useEffect56, useState as useState66 } from "react";
27072
27095
  import {
27073
27096
  archivedWhen,
27074
27097
  BUILT_KIND_WORD
@@ -27473,11 +27496,11 @@ function archivedThings(forms, checklists) {
27473
27496
  }
27474
27497
  function ArchivedBuiltOn({ tableId, onRestored }) {
27475
27498
  const client = useRecordsClient44();
27476
- const [things, setThings] = useState65(null);
27477
- const [error, setError] = useState65(null);
27478
- const [restoring, setRestoring] = useState65(null);
27479
- const [refusal4, setRefusal] = useState65(null);
27480
- const [said2, setSaid] = useState65(null);
27499
+ const [things, setThings] = useState66(null);
27500
+ const [error, setError] = useState66(null);
27501
+ const [restoring, setRestoring] = useState66(null);
27502
+ const [refusal4, setRefusal] = useState66(null);
27503
+ const [said2, setSaid] = useState66(null);
27481
27504
  const read = useCallback31(async () => {
27482
27505
  const [forms, checklists] = await Promise.all([
27483
27506
  client.formsArchived({ table_id: tableId }),
@@ -27562,14 +27585,14 @@ var STATE_WORDS = BOOKING_PAGE_STATE_LABEL;
27562
27585
  function BookingSlots({ tableId, activeBookingId, className }) {
27563
27586
  const client = useRecordsClient45();
27564
27587
  const host = useRecordsUi();
27565
- const [pages, setPages] = useState66(null);
27566
- const [error, setError] = useState66(null);
27567
- const [busy, setBusy] = useState66(null);
27568
- const [copied, setCopied] = useState66(null);
27569
- const [shown4, setShown] = useState66(null);
27570
- const [building, setBuilding] = useState66(false);
27571
- const [archivedSaid, setArchivedSaid] = useState66(null);
27572
- const [changing, setChanging] = useState66(null);
27588
+ const [pages, setPages] = useState67(null);
27589
+ const [error, setError] = useState67(null);
27590
+ const [busy, setBusy] = useState67(null);
27591
+ const [copied, setCopied] = useState67(null);
27592
+ const [shown4, setShown] = useState67(null);
27593
+ const [building, setBuilding] = useState67(false);
27594
+ const [archivedSaid, setArchivedSaid] = useState67(null);
27595
+ const [changing, setChanging] = useState67(null);
27573
27596
  const load = useCallback32(async () => {
27574
27597
  const answered = await client.bookings(tableId ? { table_id: tableId } : {});
27575
27598
  if (!answered.ok) {
@@ -27797,7 +27820,7 @@ function nextInWords(page) {
27797
27820
  }
27798
27821
 
27799
27822
  // src/WhereItLives.tsx
27800
- import { useEffect as useEffect58, useState as useState67 } from "react";
27823
+ import { useEffect as useEffect58, useState as useState68 } from "react";
27801
27824
  import { moveConsequence } from "@ai-matrx/records";
27802
27825
  import { useRecordsClient as useRecordsClient46 } from "@ai-matrx/records/react";
27803
27826
  import { Button as Button50, ErrorBox as ErrorBox4, Popover as Popover8, PopoverContent as PopoverContent8, PopoverTrigger as PopoverTrigger8 } from "@ai-matrx/design-system";
@@ -27805,18 +27828,18 @@ import { jsx as jsx84, jsxs as jsxs75 } from "react/jsx-runtime";
27805
27828
  function WhereItLives({ tableId, knownOrganizationName, onMoved, variant = "header", openAsked = 0 }) {
27806
27829
  const client = useRecordsClient46();
27807
27830
  const host = useRecordsUi();
27808
- const [answer, setAnswer] = useState67(null);
27809
- const [attempt, setAttempt] = useState67(0);
27810
- const [open, setOpen] = useState67(false);
27811
- const [armed, setArmed] = useState67(variant === "anchor" ? false : variant !== "row" || !knownOrganizationName);
27831
+ const [answer, setAnswer] = useState68(null);
27832
+ const [attempt, setAttempt] = useState68(0);
27833
+ const [open, setOpen] = useState68(false);
27834
+ const [armed, setArmed] = useState68(variant === "anchor" ? false : variant !== "row" || !knownOrganizationName);
27812
27835
  useEffect58(() => {
27813
27836
  if (openAsked <= 0) return;
27814
27837
  setArmed(true);
27815
27838
  setOpen(true);
27816
27839
  }, [openAsked]);
27817
- const [choosing, setChoosing] = useState67(null);
27818
- const [moving, setMoving] = useState67(false);
27819
- const [said2, setSaid] = useState67(null);
27840
+ const [choosing, setChoosing] = useState68(null);
27841
+ const [moving, setMoving] = useState68(false);
27842
+ const [said2, setSaid] = useState68(null);
27820
27843
  useEffect58(() => {
27821
27844
  if (!armed) return;
27822
27845
  let alive = true;
@@ -28073,7 +28096,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
28073
28096
  const client = useRecordsClient47();
28074
28097
  const tables = useTables2();
28075
28098
  const me = client.config.actor.user_id ?? null;
28076
- const [facts, setFacts] = useState68({ phase: "reading" });
28099
+ const [facts, setFacts] = useState69({ phase: "reading" });
28077
28100
  useEffect59(() => {
28078
28101
  let alive = true;
28079
28102
  void client.tableFacts().then((answered) => {
@@ -28088,9 +28111,9 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
28088
28111
  withTableFacts(tables.data ?? [], facts.rows, me),
28089
28112
  facts.rows
28090
28113
  ) : tables.data ?? [];
28091
- const [showEverything, setShowEverything] = useState68(false);
28114
+ const [showEverything, setShowEverything] = useState69(false);
28092
28115
  const keptCount = listed.filter((t) => laneFor(t) === "app").length;
28093
- const [askedName, setAskedName] = useState68(null);
28116
+ const [askedName, setAskedName] = useState69(null);
28094
28117
  const firstTableId = listed[0]?.id ?? null;
28095
28118
  useEffect59(() => {
28096
28119
  if (organizationName || !firstTableId) return;
@@ -28105,19 +28128,19 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
28105
28128
  const livesIn = organizationName || askedName;
28106
28129
  const isMine = (t) => Boolean(me) && laneFor(t) !== "system" && laneFor(t) !== "app" && t.created_by === me;
28107
28130
  const sectionsKnown = facts.phase !== "failed";
28108
- const [creating, setCreating] = useState68(false);
28109
- const [name, setName] = useState68("");
28110
- const [columnWords2, setColumnWords] = useState68("");
28111
- const [columns, setColumns] = useState68([]);
28112
- const [busy, setBusy] = useState68(false);
28113
- const [error, setError] = useState68(null);
28114
- const [importInto, setImportInto] = useState68(null);
28131
+ const [creating, setCreating] = useState69(false);
28132
+ const [name, setName] = useState69("");
28133
+ const [columnWords2, setColumnWords] = useState69("");
28134
+ const [columns, setColumns] = useState69([]);
28135
+ const [busy, setBusy] = useState69(false);
28136
+ const [error, setError] = useState69(null);
28137
+ const [importInto, setImportInto] = useState69(null);
28115
28138
  const createAsked = askedBy?.create ?? 0;
28116
28139
  useEffect59(() => {
28117
28140
  if (createAsked > 0) setCreating(true);
28118
28141
  }, [createAsked]);
28119
28142
  const hostButtons = askedBy !== void 0;
28120
- const [boards, setBoards] = useState68(null);
28143
+ const [boards, setBoards] = useState69(null);
28121
28144
  useEffect59(() => {
28122
28145
  if (makingOnly) return;
28123
28146
  let cancelled = false;
@@ -28399,13 +28422,13 @@ function typeWord2(t) {
28399
28422
  function SaveToTable({ source, shapeIndex = 0, onOpenTable, onSaved, onClose, className }) {
28400
28423
  const client = useRecordsClient48();
28401
28424
  const shapes = useMemo42(() => shapesOfSource(source), [source]);
28402
- const [which, setWhich] = useState69(() => Math.min(Math.max(0, shapeIndex), Math.max(0, shapes.length - 1)));
28425
+ const [which, setWhich] = useState70(() => Math.min(Math.max(0, shapeIndex), Math.max(0, shapes.length - 1)));
28403
28426
  const shape = shapes[which] ?? null;
28404
- const [split, setSplit] = useState69("");
28427
+ const [split, setSplit] = useState70("");
28405
28428
  const reading = shape?.splits.find((s) => s.delimiter === split) ?? null;
28406
28429
  const headers = reading?.headers ?? shape?.headers ?? [];
28407
28430
  const rows = reading?.rows ?? shape?.rows ?? [];
28408
- const [target, setTarget] = useState69("new");
28431
+ const [target, setTarget] = useState70("new");
28409
28432
  const tables = useTables3();
28410
28433
  const own3 = tablePickerEntries(tables.data ?? []).entries.map((e) => e.table).filter((t) => laneFor(t) !== "system");
28411
28434
  const levels = useMyLevels3(own3.map((t) => t.id));
@@ -28413,18 +28436,18 @@ function SaveToTable({ source, shapeIndex = 0, onOpenTable, onSaved, onClose, cl
28413
28436
  const level = levels.data?.[t.id];
28414
28437
  return level === "edit_content" || level === "editor" || level === "admin";
28415
28438
  }).sort((a, b) => a.name.localeCompare(b.name));
28416
- const [tableId, setTableId] = useState69("");
28439
+ const [tableId, setTableId] = useState70("");
28417
28440
  const proposedName = shape?.name ?? source.title ?? "Saved table";
28418
- const [name, setName] = useState69(null);
28419
- const [description, setDescription] = useState69("");
28420
- const [replaceAsked, setReplaceAsked] = useState69(false);
28421
- const [replacing, setReplacing] = useState69(false);
28422
- const [replaced, setReplaced] = useState69(null);
28423
- const [drafts, setDrafts] = useState69(null);
28441
+ const [name, setName] = useState70(null);
28442
+ const [description, setDescription] = useState70("");
28443
+ const [replaceAsked, setReplaceAsked] = useState70(false);
28444
+ const [replacing, setReplacing] = useState70(false);
28445
+ const [replaced, setReplaced] = useState70(null);
28446
+ const [drafts, setDrafts] = useState70(null);
28424
28447
  const columns = drafts ?? draftsFor(headers, rows);
28425
- const [problem, setProblem] = useState69(null);
28426
- const [phase, setPhase] = useState69("ready");
28427
- const [made, setMade] = useState69(null);
28448
+ const [problem, setProblem] = useState70(null);
28449
+ const [phase, setPhase] = useState70("ready");
28450
+ const [made, setMade] = useState70(null);
28428
28451
  const sourceName = source.title?.trim() || shape?.name || "the rows above";
28429
28452
  const sourceText = useMemo42(() => JSON.stringify({ headers, rows }), [headers, rows]);
28430
28453
  const wizardSource = useMemo42(
@@ -28781,7 +28804,7 @@ function SaveToTable({ source, shapeIndex = 0, onOpenTable, onSaved, onClose, cl
28781
28804
  }
28782
28805
 
28783
28806
  // src/StageRules.tsx
28784
- import { useCallback as useCallback34, useEffect as useEffect60, useMemo as useMemo43, useState as useState70 } from "react";
28807
+ import { useCallback as useCallback34, useEffect as useEffect60, useMemo as useMemo43, useState as useState71 } from "react";
28785
28808
  import { useFields as useFields12, useRecordsClient as useRecordsClient49, useTable as useTable10 } from "@ai-matrx/records/react";
28786
28809
  import { BasicInput as BasicInput17, BasicTextarea as BasicTextarea8, Button as Button53, Separator as Separator7, Skeleton as Skeleton9, cn as cn44 } from "@ai-matrx/design-system";
28787
28810
  import { jsx as jsx87, jsxs as jsxs78 } from "react/jsx-runtime";
@@ -28820,15 +28843,15 @@ function StageRulesSection({ tableId, stage, className }) {
28820
28843
  const table = useTable10(tableId);
28821
28844
  const rights = useTableRights(table.data);
28822
28845
  const fields = useFields12(tableId);
28823
- const [pipeline, setPipeline] = useState70(null);
28824
- const [enforcement, setEnforcement] = useState70(null);
28825
- const [asked3, setAsked] = useState70(false);
28826
- const [error, setError] = useState70(null);
28827
- const [chosen, setChosen] = useState70(stage ?? null);
28828
- const [draft, setDraft] = useState70(null);
28829
- const [preview, setPreview] = useState70(null);
28830
- const [previewError, setPreviewError] = useState70(null);
28831
- const [saving, setSaving] = useState70(false);
28846
+ const [pipeline, setPipeline] = useState71(null);
28847
+ const [enforcement, setEnforcement] = useState71(null);
28848
+ const [asked3, setAsked] = useState71(false);
28849
+ const [error, setError] = useState71(null);
28850
+ const [chosen, setChosen] = useState71(stage ?? null);
28851
+ const [draft, setDraft] = useState71(null);
28852
+ const [preview, setPreview] = useState71(null);
28853
+ const [previewError, setPreviewError] = useState71(null);
28854
+ const [saving, setSaving] = useState71(false);
28832
28855
  const load = useCallback34(async () => {
28833
28856
  const [read, mode] = await Promise.all([client.pipelineRead({ table_id: tableId }), client.stageRuleEnforcement()]);
28834
28857
  if (!read.ok) setError(read.error);
@@ -29030,7 +29053,7 @@ function Clause({
29030
29053
  fields,
29031
29054
  onChange
29032
29055
  }) {
29033
- const [replacing, setReplacing] = useState70(false);
29056
+ const [replacing, setReplacing] = useState71(false);
29034
29057
  const drawable = conditionIsDrawable(expr) || replacing;
29035
29058
  if (drawable) {
29036
29059
  return /* @__PURE__ */ jsx87(
@@ -29069,7 +29092,7 @@ function Clause({
29069
29092
  }
29070
29093
 
29071
29094
  // src/TableRename.tsx
29072
- import { useCallback as useCallback35, useEffect as useEffect61, useRef as useRef40, useState as useState71 } from "react";
29095
+ import { useCallback as useCallback35, useEffect as useEffect61, useRef as useRef40, useState as useState72 } from "react";
29073
29096
  import { tableShapeChanged as tableShapeChanged7, useRecordsClient as useRecordsClient50 } from "@ai-matrx/records/react";
29074
29097
  import {
29075
29098
  Button as Button54,
@@ -29090,7 +29113,7 @@ function tableNameProblem(typed2) {
29090
29113
  return null;
29091
29114
  }
29092
29115
  function useRenameFromMenu() {
29093
- const [open, setOpen] = useState71(false);
29116
+ const [open, setOpen] = useState72(false);
29094
29117
  const asked3 = useRef40(false);
29095
29118
  const ask = useCallback35(() => {
29096
29119
  asked3.current = true;
@@ -29114,9 +29137,9 @@ function TableRenameDialog({
29114
29137
  onRenamed
29115
29138
  }) {
29116
29139
  const client = useRecordsClient50();
29117
- const [typed2, setTyped] = useState71(name);
29118
- const [busy, setBusy] = useState71(false);
29119
- const [refused, setRefused] = useState71(null);
29140
+ const [typed2, setTyped] = useState72(name);
29141
+ const [busy, setBusy] = useState72(false);
29142
+ const [refused, setRefused] = useState72(null);
29120
29143
  const box = useRef40(null);
29121
29144
  const openedAt = useRef40(null);
29122
29145
  useEffect61(() => {
@@ -29210,10 +29233,10 @@ function TableRenameDialog({
29210
29233
  }
29211
29234
 
29212
29235
  // src/TableSettings.tsx
29213
- import { useEffect as useEffect65, useMemo as useMemo45, useRef as useRef41, useState as useState76 } from "react";
29236
+ import { useEffect as useEffect65, useMemo as useMemo45, useRef as useRef41, useState as useState77 } from "react";
29214
29237
 
29215
29238
  // src/ArchiveDeliberately.tsx
29216
- import { useState as useState72 } from "react";
29239
+ import { useState as useState73 } from "react";
29217
29240
  import { useRecordsClient as useRecordsClient51 } from "@ai-matrx/records/react";
29218
29241
  import { Button as Button55, Dialog as Dialog13, DialogContent as DialogContent13, DialogFooter as DialogFooter10, DialogHeader as DialogHeader13, DialogTitle as DialogTitle13, ErrorBox as ErrorBox6, Input as Input5, Textarea as Textarea4 } from "@ai-matrx/design-system";
29219
29242
  import { jsx as jsx89, jsxs as jsxs80 } from "react/jsx-runtime";
@@ -29228,11 +29251,11 @@ function codeDependsRefusal(error) {
29228
29251
  var MOST_PASSES = 500;
29229
29252
  function ArchiveDeliberatelyDialog({ tableId, name, slug, declaredIn, open, onOpenChange, onArchived }) {
29230
29253
  const client = useRecordsClient51();
29231
- const [step2, setStep] = useState72(1);
29232
- const [typed2, setTyped] = useState72("");
29233
- const [reason, setReason] = useState72("");
29234
- const [busy, setBusy] = useState72(false);
29235
- const [refused, setRefused] = useState72(null);
29254
+ const [step2, setStep] = useState73(1);
29255
+ const [typed2, setTyped] = useState73("");
29256
+ const [reason, setReason] = useState73("");
29257
+ const [busy, setBusy] = useState73(false);
29258
+ const [refused, setRefused] = useState73(null);
29236
29259
  const ready = typed2.trim() === slug && reason.trim() !== "";
29237
29260
  const close = (next) => {
29238
29261
  if (busy) return;
@@ -29335,7 +29358,7 @@ function announceTableArchived({ notify, client, tableId, name, onRestored }) {
29335
29358
  }
29336
29359
 
29337
29360
  // src/TableFoundation.tsx
29338
- import { useEffect as useEffect62, useState as useState73 } from "react";
29361
+ import { useEffect as useEffect62, useState as useState74 } from "react";
29339
29362
  import { tableShapeChanged as tableShapeChanged8, useRecordsClient as useRecordsClient52 } from "@ai-matrx/records/react";
29340
29363
  import { Switch as Switch2 } from "@ai-matrx/design-system";
29341
29364
  import { jsx as jsx90, jsxs as jsxs81 } from "react/jsx-runtime";
@@ -29345,8 +29368,8 @@ function isFoundationTable(table) {
29345
29368
  function TableFoundationSwitch({ tableId, table }) {
29346
29369
  const client = useRecordsClient52();
29347
29370
  const stored = isFoundationTable(table);
29348
- const [pending, setPending] = useState73(null);
29349
- const [refused, setRefused] = useState73(null);
29371
+ const [pending, setPending] = useState74(null);
29372
+ const [refused, setRefused] = useState74(null);
29350
29373
  const on = pending ?? stored;
29351
29374
  useEffect62(() => {
29352
29375
  if (pending !== null && stored === pending) setPending(null);
@@ -29386,7 +29409,7 @@ function TableFoundationSwitch({ tableId, table }) {
29386
29409
  }
29387
29410
 
29388
29411
  // src/RowControls.tsx
29389
- import { useCallback as useCallback36, useEffect as useEffect63, useState as useState74 } from "react";
29412
+ import { useCallback as useCallback36, useEffect as useEffect63, useState as useState75 } from "react";
29390
29413
  import {
29391
29414
  isShownTo,
29392
29415
  SHOWN_TO_LABEL
@@ -29433,10 +29456,10 @@ function ShownToSelect({
29433
29456
  }
29434
29457
  function NewRowsDefaults({ tableId }) {
29435
29458
  const client = useRecordsClient53();
29436
- const [d, setD] = useState74(null);
29437
- const [error, setError] = useState74(null);
29438
- const [busy, setBusy] = useState74(false);
29439
- const [applied, setApplied] = useState74(null);
29459
+ const [d, setD] = useState75(null);
29460
+ const [error, setError] = useState75(null);
29461
+ const [busy, setBusy] = useState75(false);
29462
+ const [applied, setApplied] = useState75(null);
29440
29463
  const read = useCallback36(async () => {
29441
29464
  const answer = await client.tableRowDefaults({ table_id: tableId });
29442
29465
  if (answer.ok) {
@@ -29516,8 +29539,8 @@ function NewRowsDefaults({ tableId }) {
29516
29539
  }
29517
29540
  function RowShownTo({ recordId }) {
29518
29541
  const client = useRecordsClient53();
29519
- const [c, setC] = useState74(null);
29520
- const [error, setError] = useState74(null);
29542
+ const [c, setC] = useState75(null);
29543
+ const [error, setError] = useState75(null);
29521
29544
  const read = useCallback36(async () => {
29522
29545
  const answer = await client.recordRowControls({ record_id: recordId });
29523
29546
  if (answer.ok) {
@@ -29559,7 +29582,7 @@ function RowShownTo({ recordId }) {
29559
29582
  }
29560
29583
 
29561
29584
  // src/ColumnsAtOnce.tsx
29562
- import { useEffect as useEffect64, useMemo as useMemo44, useState as useState75 } from "react";
29585
+ import { useEffect as useEffect64, useMemo as useMemo44, useState as useState76 } from "react";
29563
29586
  import { useFieldMutation as useFieldMutation3 } from "@ai-matrx/records/react";
29564
29587
  import { Badge as Badge12, BasicInput as BasicInput18, Button as Button57, Checkbox as Checkbox10, cn as cn45 } from "@ai-matrx/design-system";
29565
29588
  import { jsx as jsx92, jsxs as jsxs83 } from "react/jsx-runtime";
@@ -29592,13 +29615,13 @@ function ColumnsAtOnce({
29592
29615
  }) {
29593
29616
  const shape = useFieldMutation3();
29594
29617
  const savedSignature = JSON.stringify(rows.map((f) => [f.id, f.label, f.sort]));
29595
- const [draft, setDraft] = useState75(() => draftOf3(rows));
29618
+ const [draft, setDraft] = useState76(() => draftOf3(rows));
29596
29619
  useEffect64(() => setDraft(draftOf3(rows)), [savedSignature]);
29597
29620
  const hiddenSignature = JSON.stringify(look?.hidden ?? []);
29598
- const [hidden, setHidden] = useState75(() => [...look?.hidden ?? []]);
29621
+ const [hidden, setHidden] = useState76(() => [...look?.hidden ?? []]);
29599
29622
  useEffect64(() => setHidden([...look?.hidden ?? []]), [hiddenSignature]);
29600
- const [dragging, setDragging] = useState75(null);
29601
- const [saving, setSaving] = useState75(false);
29623
+ const [dragging, setDragging] = useState76(null);
29624
+ const [saving, setSaving] = useState76(false);
29602
29625
  const byId = useMemo44(() => new Map(rows.map((f) => [f.id, f])), [rows]);
29603
29626
  const batch = columnsBatch(rows, draft);
29604
29627
  const orderMoved = rows.some((f, i) => f.id !== draft[i]?.id);
@@ -29790,11 +29813,11 @@ function TableSettingsPanel({
29790
29813
  archiveAskedSeen.current = archiveAsked;
29791
29814
  void ask();
29792
29815
  }, [archiveAsked, panelReady]);
29793
- const [editing, setEditing] = useState76(null);
29794
- const [askingToDelete, setAskingToDelete] = useState76(false);
29795
- const [deliberate, setDeliberate] = useState76(null);
29796
- const [askingToRemove, setAskingToRemove] = useState76(null);
29797
- const [enriching, setEnriching] = useState76(null);
29816
+ const [editing, setEditing] = useState77(null);
29817
+ const [askingToDelete, setAskingToDelete] = useState77(false);
29818
+ const [deliberate, setDeliberate] = useState77(null);
29819
+ const [askingToRemove, setAskingToRemove] = useState77(null);
29820
+ const [enriching, setEnriching] = useState77(null);
29798
29821
  if (table.error) return /* @__PURE__ */ jsx93(RefusalNotice, { error: table.error, className });
29799
29822
  if (fields.error) return /* @__PURE__ */ jsx93(RefusalNotice, { error: fields.error, className });
29800
29823
  if (!rights.structure) return /* @__PURE__ */ jsx93("p", { className: cn46("text-xs text-muted-foreground", className), children: rights.why("structure") });
@@ -29968,12 +29991,12 @@ function TableSettingsPanel({
29968
29991
  }
29969
29992
 
29970
29993
  // src/Peek.tsx
29971
- import { useEffect as useEffect69, useState as useState80 } from "react";
29994
+ import { useEffect as useEffect69, useState as useState81 } from "react";
29972
29995
  import { useFields as useFields15, useRecord as useRecord3, useRecordsClient as useRecordsClient58, useTable as useTable14 } from "@ai-matrx/records/react";
29973
29996
  import { AlchemyMenu as AlchemyMenu2 } from "@ai-matrx/alchemy/react";
29974
29997
 
29975
29998
  // src/RecordChat.tsx
29976
- import { useEffect as useEffect66, useMemo as useMemo46, useState as useState77 } from "react";
29999
+ import { useEffect as useEffect66, useMemo as useMemo46, useState as useState78 } from "react";
29977
30000
  import { useRecordsClient as useRecordsClient55 } from "@ai-matrx/records/react";
29978
30001
  import { Skeleton as Skeleton10, cn as cn47 } from "@ai-matrx/design-system";
29979
30002
  import { jsx as jsx94, jsxs as jsxs85 } from "react/jsx-runtime";
@@ -29981,8 +30004,8 @@ var NO_CHAT_REASON = "Chatting about this record is not switched on here yet, so
29981
30004
  function RecordChat({ tableId, recordId, className }) {
29982
30005
  const client = useRecordsClient55();
29983
30006
  const host = useRecordsUi();
29984
- const [scope, setScope] = useState77(null);
29985
- const [error, setError] = useState77(null);
30007
+ const [scope, setScope] = useState78(null);
30008
+ const [error, setError] = useState78(null);
29986
30009
  useEffect66(() => {
29987
30010
  let cancelled = false;
29988
30011
  setScope(null);
@@ -30197,7 +30220,7 @@ function RecordFieldsInPlace({
30197
30220
 
30198
30221
  // src/ShareControl.tsx
30199
30222
  import { copyText as copyText4 } from "@ai-matrx/kit/clipboard";
30200
- import { useEffect as useEffect67, useState as useState78 } from "react";
30223
+ import { useEffect as useEffect67, useState as useState79 } from "react";
30201
30224
  import { Button as Button59, Popover as Popover9, PopoverContent as PopoverContent9, PopoverTrigger as PopoverTrigger9 } from "@ai-matrx/design-system";
30202
30225
  import { Fragment as Fragment35, jsx as jsx96, jsxs as jsxs87 } from "react/jsx-runtime";
30203
30226
  function useCanShare() {
@@ -30219,7 +30242,7 @@ function ShareControl({
30219
30242
  className
30220
30243
  }) {
30221
30244
  const host = useRecordsUi();
30222
- const [open, setOpen] = useState78(initiallyOpen);
30245
+ const [open, setOpen] = useState79(initiallyOpen);
30223
30246
  useEffect67(() => {
30224
30247
  if (initiallyOpen) setOpen(true);
30225
30248
  }, [initiallyOpen]);
@@ -30257,7 +30280,7 @@ function ShareForSomebodyElse({
30257
30280
  variant,
30258
30281
  className
30259
30282
  }) {
30260
- const [copied, setCopied] = useState78(null);
30283
+ const [copied, setCopied] = useState79(null);
30261
30284
  const copy = async () => {
30262
30285
  if (await copyText4(window.location.href)) {
30263
30286
  setCopied("yes");
@@ -30284,7 +30307,7 @@ function ShareForSomebodyElse({
30284
30307
  }
30285
30308
 
30286
30309
  // src/RecordBody.tsx
30287
- import { useEffect as useEffect68, useRef as useRef43, useState as useState79 } from "react";
30310
+ import { useEffect as useEffect68, useRef as useRef43, useState as useState80 } from "react";
30288
30311
  import { Button as Button60, cn as cn48 } from "@ai-matrx/design-system";
30289
30312
  import { newerKindOf as newerKindOf5 } from "@ai-matrx/records";
30290
30313
  import { tableShapeChanged as tableShapeChanged10, useFieldMutation as useFieldMutation5, useFields as useFields14, useRecord as useRecord2, useRecordsClient as useRecordsClient57, useTable as useTable13 } from "@ai-matrx/records/react";
@@ -30320,7 +30343,7 @@ function BodyEditor({ tableId, recordId, field: field2 }) {
30320
30343
  const may = useRecordRights(recordId);
30321
30344
  const raw = record.data?.document?.[field2.key];
30322
30345
  const stored = typeof raw === "string" ? raw : "";
30323
- const [saving, setSaving] = useState79({ phase: "idle" });
30346
+ const [saving, setSaving] = useState80({ phase: "idle" });
30324
30347
  const lastSaved = useRef43(null);
30325
30348
  const waiting = useRef43(null);
30326
30349
  const timer = useRef43(null);
@@ -30403,7 +30426,7 @@ function Peek({ tableId, recordId, onClose, className, onPage = false }) {
30403
30426
  const may = useRecordRights(recordId);
30404
30427
  const host = useRecordsUi();
30405
30428
  const organizationId = useRecordsClient58().config.organizationId;
30406
- const [talking, setTalking] = useState80(false);
30429
+ const [talking, setTalking] = useState81(false);
30407
30430
  const peekMemoryKey = `peek:${tableId}:${onPage ? "page" : "panel"}`;
30408
30431
  const peekRowsWhileReading = rememberedRowCount(peekMemoryKey, 40, 8);
30409
30432
  const shownFieldCount = (fields.data ?? []).filter(
@@ -30538,7 +30561,7 @@ function computedInPlainWords(row, field2) {
30538
30561
  }
30539
30562
 
30540
30563
  // src/systemTable.ts
30541
- import { useEffect as useEffect70, useMemo as useMemo48, useState as useState81 } from "react";
30564
+ import { useEffect as useEffect70, useMemo as useMemo48, useState as useState82 } from "react";
30542
30565
  import { useRecordsClient as useRecordsClient59 } from "@ai-matrx/records/react";
30543
30566
  var inFlight = /* @__PURE__ */ new Map();
30544
30567
  async function ensureSystemTable(client, spec) {
@@ -30668,7 +30691,7 @@ async function declare(client, spec) {
30668
30691
  }
30669
30692
  function useSystemTable(spec) {
30670
30693
  const client = useRecordsClient59();
30671
- const [state, setState] = useState81({ tableId: null, loading: true, error: null });
30694
+ const [state, setState] = useState82({ tableId: null, loading: true, error: null });
30672
30695
  const slug = spec.slug;
30673
30696
  const stable = useMemo48(() => spec, [slug]);
30674
30697
  useEffect70(() => {
@@ -30688,7 +30711,7 @@ function useSystemTable(spec) {
30688
30711
  }
30689
30712
 
30690
30713
  // src/ViewSwitcher.tsx
30691
- import { useEffect as useEffect77, useMemo as useMemo56, useState as useState89 } from "react";
30714
+ import { useEffect as useEffect77, useMemo as useMemo56, useState as useState90 } from "react";
30692
30715
  import { mayDrag as mayDrag4, useFields as useFields18, useRecordPage as useRecordPage2, useRecordsClient as useRecordsClient64, useTable as useTable17 } from "@ai-matrx/records/react";
30693
30716
  import { newerKindOf as newerKindOf6, stableFilterKey as stableFilterKey4 } from "@ai-matrx/records";
30694
30717
  import { Button as Button67, Select as Select16, SelectContent as SelectContent16, SelectItem as SelectItem16, SelectTrigger as SelectTrigger16, SelectValue as SelectValue16, cn as cn55 } from "@ai-matrx/design-system";
@@ -30702,7 +30725,7 @@ import {
30702
30725
  import { formatCount as formatCount4 } from "@ai-matrx/kit/format";
30703
30726
 
30704
30727
  // src/recordMoves.tsx
30705
- import { useCallback as useCallback37, useEffect as useEffect71, useMemo as useMemo49, useRef as useRef44, useState as useState82 } from "react";
30728
+ import { useCallback as useCallback37, useEffect as useEffect71, useMemo as useMemo49, useRef as useRef44, useState as useState83 } from "react";
30706
30729
  import { useRecordsClient as useRecordsClient60 } from "@ai-matrx/records/react";
30707
30730
  import { Button as Button62 } from "@ai-matrx/design-system";
30708
30731
  import { Fragment as Fragment38, jsx as jsx99, jsxs as jsxs90 } from "react/jsx-runtime";
@@ -30716,9 +30739,9 @@ function useRecordMoves({
30716
30739
  onMoved
30717
30740
  }) {
30718
30741
  const client = useRecordsClient60();
30719
- const [refused, setRefused] = useState82(null);
30742
+ const [refused, setRefused] = useState83(null);
30720
30743
  const versions = useRecordVersions(client, rows);
30721
- const [stale, setStale] = useState82(null);
30744
+ const [stale, setStale] = useState83(null);
30722
30745
  const reload = useCallback37(() => onMoved?.(), [onMoved]);
30723
30746
  const forget = useCallback37(() => void 0, []);
30724
30747
  const undo = useGridUndo({
@@ -30849,7 +30872,7 @@ function MoveRefusedBadge({ refused }) {
30849
30872
  }
30850
30873
 
30851
30874
  // src/Pipeline.tsx
30852
- import { useCallback as useCallback39, useEffect as useEffect72, useMemo as useMemo51, useRef as useRef45, useState as useState84 } from "react";
30875
+ import { useCallback as useCallback39, useEffect as useEffect72, useMemo as useMemo51, useRef as useRef45, useState as useState85 } from "react";
30853
30876
  import {
30854
30877
  mayDrag,
30855
30878
  useFields as useFields17,
@@ -30911,7 +30934,7 @@ function CardDates({ record, fields }) {
30911
30934
 
30912
30935
  // src/RecordActionMenu.tsx
30913
30936
  import { copyText as copyText5 } from "@ai-matrx/kit/clipboard";
30914
- import { useCallback as useCallback38, useMemo as useMemo50, useState as useState83 } from "react";
30937
+ import { useCallback as useCallback38, useMemo as useMemo50, useState as useState84 } from "react";
30915
30938
  import { useFields as useFields16, useRecordsClient as useRecordsClient61, useTable as useTable15 } from "@ai-matrx/records/react";
30916
30939
  import {
30917
30940
  ContextMenu,
@@ -31104,7 +31127,7 @@ function ObjectActionContextMenuItems({ actions }) {
31104
31127
  }) });
31105
31128
  }
31106
31129
  function RecordActionMenu({ tableId, row, name, onOpenRecord, onChanged, children, className }) {
31107
- const [merging, setMerging] = useState83(false);
31130
+ const [merging, setMerging] = useState84(false);
31108
31131
  const openMerge = useCallback38(() => setMerging(true), []);
31109
31132
  const actionHost = useRecordActionHost({ tableId, row, onOpenRecord, onChanged, onMerge: openMerge });
31110
31133
  const rights = useMemo50(() => whatYouMayDo(row.level || null, true), [row.level]);
@@ -31193,21 +31216,21 @@ function PipelineBoard({
31193
31216
  () => style ?? resolveTableStyle(ownDecorations.data, fields.data ?? [], void 0),
31194
31217
  [style, ownDecorations.data, fields.data]
31195
31218
  );
31196
- const [definition, setDefinition] = useState84(null);
31197
- const [columns, setColumns] = useState84([]);
31198
- const [error, setError] = useState84(null);
31199
- const [loading, setLoading] = useState84(true);
31200
- const [pending, setPending] = useState84({ kind: "none" });
31201
- const [waiting, setWaiting] = useState84(/* @__PURE__ */ new Map());
31202
- const [dragging, setDragging] = useState84(null);
31203
- const [over, setOver] = useState84(null);
31219
+ const [definition, setDefinition] = useState85(null);
31220
+ const [columns, setColumns] = useState85([]);
31221
+ const [error, setError] = useState85(null);
31222
+ const [loading, setLoading] = useState85(true);
31223
+ const [pending, setPending] = useState85({ kind: "none" });
31224
+ const [waiting, setWaiting] = useState85(/* @__PURE__ */ new Map());
31225
+ const [dragging, setDragging] = useState85(null);
31226
+ const [over, setOver] = useState85(null);
31204
31227
  const alive = useRef45(true);
31205
- const [selected, setSelected] = useState84(/* @__PURE__ */ new Set());
31228
+ const [selected, setSelected] = useState85(/* @__PURE__ */ new Set());
31206
31229
  const anchor = useRef45(null);
31207
- const [batch, setBatch] = useState84(/* @__PURE__ */ new Map());
31208
- const [batchSaid, setBatchSaid] = useState84(null);
31209
- const [batchError, setBatchError] = useState84(null);
31210
- const [moving, setMoving] = useState84(false);
31230
+ const [batch, setBatch] = useState85(/* @__PURE__ */ new Map());
31231
+ const [batchSaid, setBatchSaid] = useState85(null);
31232
+ const [batchError, setBatchError] = useState85(null);
31233
+ const [moving, setMoving] = useState85(false);
31211
31234
  useEffect72(() => {
31212
31235
  alive.current = true;
31213
31236
  return () => {
@@ -31606,7 +31629,7 @@ function Held({
31606
31629
  onFill,
31607
31630
  onAsk
31608
31631
  }) {
31609
- const [draft, setDraft] = useState84({});
31632
+ const [draft, setDraft] = useState85({});
31610
31633
  if (pending.kind === "asking") {
31611
31634
  return /* @__PURE__ */ jsx102("p", { className: "px-2 py-1 text-xs text-muted-foreground", children: "Asking\u2026" });
31612
31635
  }
@@ -31893,7 +31916,7 @@ function CardFieldsInline({ row, fields }) {
31893
31916
  }
31894
31917
 
31895
31918
  // src/CalendarView.tsx
31896
- import { useEffect as useEffect73, useMemo as useMemo53, useRef as useRef46, useState as useState85 } from "react";
31919
+ import { useEffect as useEffect73, useMemo as useMemo53, useRef as useRef46, useState as useState86 } from "react";
31897
31920
  import { mayDrag as mayDrag2 } from "@ai-matrx/records/react";
31898
31921
  import { Button as Button64, Select as Select13, SelectContent as SelectContent13, SelectItem as SelectItem13, SelectTrigger as SelectTrigger13, SelectValue as SelectValue13, cn as cn52 } from "@ai-matrx/design-system";
31899
31922
  import { CHOICE_CHIP_CLASS as CHOICE_CHIP_CLASS2 } from "@ai-matrx/design-system/data-table";
@@ -32173,7 +32196,7 @@ function packOverlaps(blocks) {
32173
32196
  function useNarrow() {
32174
32197
  const query = "(max-width: 639px)";
32175
32198
  const read = () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(query).matches;
32176
- const [narrow, setNarrow] = useState85(read);
32199
+ const [narrow, setNarrow] = useState86(read);
32177
32200
  useEffect73(() => {
32178
32201
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
32179
32202
  const list = window.matchMedia(query);
@@ -32218,10 +32241,10 @@ function CalendarView({
32218
32241
  }) {
32219
32242
  const moves = useRecordMoves({ tableId, rows, onMoved });
32220
32243
  const narrow = useNarrow();
32221
- const [mode, setMode] = useState85(initialMode ?? (narrow ? "list" : "month"));
32244
+ const [mode, setMode] = useState86(initialMode ?? (narrow ? "list" : "month"));
32222
32245
  usePersonTimeZone();
32223
- const [anchor, setAnchor] = useState85(initialDate ?? dayKey(personWallNow()));
32224
- const [openDay, setOpenDay] = useState85(null);
32246
+ const [anchor, setAnchor] = useState86(initialDate ?? dayKey(personWallNow()));
32247
+ const [openDay, setOpenDay] = useState86(null);
32225
32248
  const titleFields = useMemo53(() => titleField ? [titleField] : [], [titleField]);
32226
32249
  const labels = useRecordLabels(titleFields);
32227
32250
  const all = fields ?? [];
@@ -32231,7 +32254,7 @@ function CalendarView({
32231
32254
  () => eligibleFieldFor("date", all, null, { far: farFields }).eligible.filter((f) => f.key !== dateField.key),
32232
32255
  [all, farFields, dateField.key]
32233
32256
  );
32234
- const [endPick, setEndPick] = useState85(void 0);
32257
+ const [endPick, setEndPick] = useState86(void 0);
32235
32258
  const endChosen = endPick !== void 0 ? endPick : endKey ?? void 0;
32236
32259
  const endUnusual = endChosen && !otherDates.some((f) => f.key === endChosen) ? all.find((f) => f.key === endChosen && f.key !== dateField.key) : void 0;
32237
32260
  const endField = endChosen === void 0 ? otherDates.length === 1 ? otherDates[0] : void 0 : otherDates.find((f) => f.key === endChosen) ?? endUnusual ?? void 0;
@@ -32240,10 +32263,10 @@ function CalendarView({
32240
32263
  const canMove = (row) => mayDrag2(row.level) && !startWorkedOut;
32241
32264
  const creates = canCreate && !startWorkedOut;
32242
32265
  const choiceFields = useMemo53(() => eligibleFieldFor("choice", all).eligible.filter(isChoiceField), [all]);
32243
- const [colorPick, setColorPick] = useState85(void 0);
32266
+ const [colorPick, setColorPick] = useState86(void 0);
32244
32267
  const colorKey = colorPick !== void 0 ? colorPick : style?.colorBy?.field ?? choiceFields[0]?.key ?? null;
32245
32268
  const colorOf = useRowColorBy(all, colorKey, style);
32246
- const [placedOver, setPlacedOver] = useState85(() => /* @__PURE__ */ new Map());
32269
+ const [placedOver, setPlacedOver] = useState86(() => /* @__PURE__ */ new Map());
32247
32270
  useEffect73(() => setPlacedOver(/* @__PURE__ */ new Map()), [rows]);
32248
32271
  const undoneCount = moves.undo.depth.forward;
32249
32272
  useEffect73(() => {
@@ -32274,7 +32297,7 @@ function CalendarView({
32274
32297
  const titleOf = (row) => cardWords(row, titleField, labels).text;
32275
32298
  const rowById = (id) => rows.find((r) => r.id === id);
32276
32299
  const frame = useRef46(null);
32277
- const [focusOn, setFocusOn] = useState85(null);
32300
+ const [focusOn, setFocusOn] = useState86(null);
32278
32301
  useEffect73(() => {
32279
32302
  if (!focusOn) return;
32280
32303
  const button = frame.current?.querySelector(`[data-calendar-card="${focusOn}"] button`);
@@ -32323,8 +32346,8 @@ function CalendarView({
32323
32346
  if (made) onOpenRecord?.(made);
32324
32347
  };
32325
32348
  const grabOffset = useRef46(0);
32326
- const [resizing, setResizing] = useState85(null);
32327
- const [ghost, setGhost] = useState85(null);
32349
+ const [resizing, setResizing] = useState86(null);
32350
+ const [ghost, setGhost] = useState86(null);
32328
32351
  useEffect73(() => {
32329
32352
  if (!ghost || typeof document === "undefined") return;
32330
32353
  const clear = () => setGhost(null);
@@ -32464,7 +32487,7 @@ function CalendarView({
32464
32487
  window.addEventListener("pointermove", onMove);
32465
32488
  window.addEventListener("pointerup", onUp);
32466
32489
  };
32467
- const [selecting, setSelecting] = useState85(null);
32490
+ const [selecting, setSelecting] = useState86(null);
32468
32491
  const beginSelect = (day) => (e) => {
32469
32492
  if (!creates || e.button !== 0) return;
32470
32493
  const slot = e.target.closest?.("[data-calendar-slot]");
@@ -32877,7 +32900,7 @@ function WeekHours({
32877
32900
  if (frame.current) frame.current.scrollTop = 7 * HOUR_PX;
32878
32901
  }, []);
32879
32902
  usePersonTimeZone();
32880
- const [now, setNow] = useState85(() => personWallNow());
32903
+ const [now, setNow] = useState86(() => personWallNow());
32881
32904
  useEffect73(() => {
32882
32905
  const timer = setInterval(() => setNow(personWallNow()), 6e4);
32883
32906
  return () => clearInterval(timer);
@@ -32920,7 +32943,7 @@ function weekHeading(first) {
32920
32943
  }
32921
32944
 
32922
32945
  // src/TimelineView.tsx
32923
- import { useEffect as useEffect74, useMemo as useMemo54, useRef as useRef47, useState as useState86 } from "react";
32946
+ import { useEffect as useEffect74, useMemo as useMemo54, useRef as useRef47, useState as useState87 } from "react";
32924
32947
  import { mayDrag as mayDrag3 } from "@ai-matrx/records/react";
32925
32948
  import { Button as Button65, Select as Select14, SelectContent as SelectContent14, SelectItem as SelectItem14, SelectTrigger as SelectTrigger14, SelectValue as SelectValue14, cn as cn53 } from "@ai-matrx/design-system";
32926
32949
  import { CHOICE_CHIP_CLASS as CHOICE_CHIP_CLASS3 } from "@ai-matrx/design-system/data-table";
@@ -33038,13 +33061,13 @@ function TimelineView({
33038
33061
  className
33039
33062
  }) {
33040
33063
  const moves = useRecordMoves({ tableId, rows, onMoved });
33041
- const [zoom, setZoom] = useState86(initialZoom);
33064
+ const [zoom, setZoom] = useState87(initialZoom);
33042
33065
  usePersonTimeZone();
33043
33066
  const today = dayKeyOf(personWallNow());
33044
- const [anchor, setAnchor] = useState86(initialDate ?? today);
33067
+ const [anchor, setAnchor] = useState87(initialDate ?? today);
33045
33068
  const dates = useMemo54(() => offerableFields(fields, "date", { far: farFields }), [fields, farFields]);
33046
33069
  const has = (list, key) => key && list.some((f) => f.key === key) ? key : null;
33047
- const [picked, setPicked] = useState86({});
33070
+ const [picked, setPicked] = useState87({});
33048
33071
  useEffect74(() => setPicked({}), [startKey, endKey, groupKey, colorKey]);
33049
33072
  const named = (key) => key && fields.some((f) => f.key === key) ? key : null;
33050
33073
  const startChosen = "startKey" in picked ? picked.startKey ?? null : has(dates, startKey) ?? named(startKey) ?? onlyCandidate(dates);
@@ -33073,7 +33096,7 @@ function TimelineView({
33073
33096
  const labels = useRecordLabels(labelFields);
33074
33097
  const titleOf = (row) => cardWords(row, titleField, labels).text;
33075
33098
  const groupOptions = useChoiceOptions(fields, groupField && isChoiceField(groupField) ? [groupField.key] : []).get(groupField?.key ?? "");
33076
- const [placedOver, setPlacedOver] = useState86(() => /* @__PURE__ */ new Map());
33099
+ const [placedOver, setPlacedOver] = useState87(() => /* @__PURE__ */ new Map());
33077
33100
  useEffect74(() => setPlacedOver(/* @__PURE__ */ new Map()), [rows]);
33078
33101
  const undoneCount = moves.undo.depth.forward;
33079
33102
  useEffect74(() => {
@@ -33081,7 +33104,7 @@ function TimelineView({
33081
33104
  }, [undoneCount]);
33082
33105
  const startOf = (row) => placedOver.has(row.id) ? placedOver.get(row.id).start : startField ? (row.document ?? {})[startField.key] : null;
33083
33106
  const endOf = (row) => !endField ? null : placedOver.has(row.id) ? placedOver.get(row.id).end : (row.document ?? {})[endField.key];
33084
- const [dragging, setDragging] = useState86(null);
33107
+ const [dragging, setDragging] = useState87(null);
33085
33108
  const { placed, unscheduled } = useMemo54(() => {
33086
33109
  const out = [];
33087
33110
  const without = [];
@@ -33177,7 +33200,7 @@ function TimelineView({
33177
33200
  const xOf = (day) => daysBetween(from, day) * px;
33178
33201
  const scroller = useRef47(null);
33179
33202
  const grouped = Boolean(groupField);
33180
- const [scrollX, setScrollX] = useState86(0);
33203
+ const [scrollX, setScrollX] = useState87(0);
33181
33204
  const frame = useRef47(null);
33182
33205
  const onScroll = () => {
33183
33206
  if (frame.current !== null) return;
@@ -33573,7 +33596,7 @@ function TimelineView({
33573
33596
  }
33574
33597
 
33575
33598
  // src/ViewNeeds.tsx
33576
- import { useEffect as useEffect75, useState as useState87 } from "react";
33599
+ import { useEffect as useEffect75, useState as useState88 } from "react";
33577
33600
  import { useFieldMutation as useFieldMutation6, useRecordsClient as useRecordsClient63, useTable as useTable16 } from "@ai-matrx/records/react";
33578
33601
  import { BasicInput as BasicInput19, Button as Button66, Label as Label17 } from "@ai-matrx/design-system";
33579
33602
  import { jsx as jsx106, jsxs as jsxs97 } from "react/jsx-runtime";
@@ -33609,10 +33632,10 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
33609
33632
  const mutation = useFieldMutation6();
33610
33633
  const client = useRecordsClient63();
33611
33634
  const taken = fields.map((f) => fieldName(f));
33612
- const [label, setLabel] = useState87(() => freeColumnName(need?.starter.label ?? "", taken));
33613
- const [options, setOptions] = useState87(() => [...need?.starter.options ?? []]);
33614
- const [refused, setRefused] = useState87(null);
33615
- const [pendingId, setPendingId] = useState87(null);
33635
+ const [label, setLabel] = useState88(() => freeColumnName(need?.starter.label ?? "", taken));
33636
+ const [options, setOptions] = useState88(() => [...need?.starter.options ?? []]);
33637
+ const [refused, setRefused] = useState88(null);
33638
+ const [pendingId, setPendingId] = useState88(null);
33616
33639
  if (!need) return null;
33617
33640
  const name = label.trim() === "" ? need.starter.label : label.trim();
33618
33641
  const choices = options.map((o) => o.trim()).filter((o) => o !== "");
@@ -33706,7 +33729,7 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
33706
33729
  }
33707
33730
 
33708
33731
  // src/GalleryCover.tsx
33709
- import { useEffect as useEffect76, useState as useState88 } from "react";
33732
+ import { useEffect as useEffect76, useState as useState89 } from "react";
33710
33733
  import { useOptionalRecordsClient as useOptionalRecordsClient10 } from "@ai-matrx/records/react";
33711
33734
  import { Fragment as Fragment43, jsx as jsx107 } from "react/jsx-runtime";
33712
33735
  function isImageAddress(value) {
@@ -33727,7 +33750,7 @@ function GalleryCover({ field: field2, value }) {
33727
33750
  function FileCover({ recordId }) {
33728
33751
  const client = useOptionalRecordsClient10();
33729
33752
  const host = useRecordsUi();
33730
- const [read, setRead] = useState88(null);
33753
+ const [read, setRead] = useState89(null);
33731
33754
  useEffect76(() => {
33732
33755
  let cancelled = false;
33733
33756
  if (!client) {
@@ -33943,7 +33966,7 @@ import { Fragment as Fragment44, jsx as jsx109, jsxs as jsxs99 } from "react/jsx
33943
33966
  var NO_FIELDS2 = [];
33944
33967
  function useViewRecords(view, pageSize = 200, filter, viewId) {
33945
33968
  const client = useRecordsClient64();
33946
- const [limit, setLimit] = useState89(pageSize);
33969
+ const [limit, setLimit] = useState90(pageSize);
33947
33970
  const questionKey = `${view.subject}|${stableFilterKey4(filter ?? null)}|${JSON.stringify(view.sorts ?? [])}`;
33948
33971
  useEffect77(() => {
33949
33972
  setLimit(pageSize);
@@ -33957,7 +33980,7 @@ function useViewRecords(view, pageSize = 200, filter, viewId) {
33957
33980
  ...filter ? { filter } : {},
33958
33981
  ...storeSort.length > 0 ? { sort: storeSort } : {}
33959
33982
  });
33960
- const [ruled, setRuled] = useState89({
33983
+ const [ruled, setRuled] = useState90({
33961
33984
  rows: [],
33962
33985
  loading: Boolean(view.ruleId),
33963
33986
  error: null
@@ -34074,8 +34097,8 @@ function ViewSwitcher({
34074
34097
  className
34075
34098
  }) {
34076
34099
  const pageSize = pageSizeAsked ?? (embedded ? EMBEDDED_PAGE_SIZE : 200);
34077
- const [layout, setLayout] = useState89(view.layout);
34078
- const [local, setLocal] = useState89({});
34100
+ const [layout, setLayout] = useState90(view.layout);
34101
+ const [local, setLocal] = useState90({});
34079
34102
  useEffect77(() => {
34080
34103
  setLayout(view.layout);
34081
34104
  setLocal({});
@@ -34171,7 +34194,7 @@ var UNUSUAL_FIELD_NOTE = "an unusual column to use here";
34171
34194
  function useFarFields(all) {
34172
34195
  const client = useRecordsClient64();
34173
34196
  const targets = lookupTargets(all).sort().join(",");
34174
- const [far, setFar] = useState89(() => /* @__PURE__ */ new Map());
34197
+ const [far, setFar] = useState90(() => /* @__PURE__ */ new Map());
34175
34198
  useEffect77(() => {
34176
34199
  let cancelled = false;
34177
34200
  const ids = targets ? targets.split(",") : [];
@@ -34207,7 +34230,7 @@ function eligibleFieldFor(want, all, chosenKey, placing) {
34207
34230
  }
34208
34231
  function useStageField(tableId) {
34209
34232
  const client = useRecordsClient64();
34210
- const [stage, setStage] = useState89({
34233
+ const [stage, setStage] = useState90({
34211
34234
  asked: false,
34212
34235
  key: null
34213
34236
  });
@@ -35011,7 +35034,7 @@ function boardDefaultGroupField(eligible) {
35011
35034
  }
35012
35035
 
35013
35036
  // src/ArchivedView.tsx
35014
- import { useCallback as useCallback40, useEffect as useEffect78, useState as useState90 } from "react";
35037
+ import { useCallback as useCallback40, useEffect as useEffect78, useState as useState91 } from "react";
35015
35038
  import {
35016
35039
  ARCHIVE_LANES,
35017
35040
  ARCHIVE_LANE_LABEL,
@@ -35043,12 +35066,12 @@ function ArchivedView({
35043
35066
  const table = useTable18(tableId);
35044
35067
  const rights = useTableRights(table.data);
35045
35068
  const fields = useFields19(tableId);
35046
- const [lane, setLane] = useState90(laneFromHost ?? DEFAULT_ARCHIVE_LANE);
35047
- const [rows, setRows] = useState90([]);
35048
- const [loading, setLoading] = useState90(true);
35049
- const [error, setError] = useState90(null);
35050
- const [restoring, setRestoring] = useState90(null);
35051
- const [refusal4, setRefusal] = useState90(null);
35069
+ const [lane, setLane] = useState91(laneFromHost ?? DEFAULT_ARCHIVE_LANE);
35070
+ const [rows, setRows] = useState91([]);
35071
+ const [loading, setLoading] = useState91(true);
35072
+ const [error, setError] = useState91(null);
35073
+ const [restoring, setRestoring] = useState91(null);
35074
+ const [refusal4, setRefusal] = useState91(null);
35052
35075
  useEffect78(() => {
35053
35076
  if (laneFromHost) setLane(laneFromHost);
35054
35077
  }, [laneFromHost]);
@@ -35151,10 +35174,10 @@ function retiredColumnLine(row) {
35151
35174
  }
35152
35175
  function RetiredColumns({ tableId, mayRestore, whyNot }) {
35153
35176
  const client = useRecordsClient65();
35154
- const [rows, setRows] = useState90(null);
35155
- const [error, setError] = useState90(null);
35156
- const [restoring, setRestoring] = useState90(null);
35157
- const [refusal4, setRefusal] = useState90(null);
35177
+ const [rows, setRows] = useState91(null);
35178
+ const [error, setError] = useState91(null);
35179
+ const [restoring, setRestoring] = useState91(null);
35180
+ const [refusal4, setRefusal] = useState91(null);
35158
35181
  const read = useCallback40(async () => {
35159
35182
  const answer = await client.fieldsRetired({ table_id: tableId });
35160
35183
  if (answer.ok) {
@@ -35210,7 +35233,7 @@ function RetiredColumns({ tableId, mayRestore, whyNot }) {
35210
35233
  }
35211
35234
 
35212
35235
  // src/ArchivedDisclosure.tsx
35213
- import { useCallback as useCallback41, useEffect as useEffect79, useState as useState91 } from "react";
35236
+ import { useCallback as useCallback41, useEffect as useEffect79, useState as useState92 } from "react";
35214
35237
  import {
35215
35238
  emptyPortalArchiveLine,
35216
35239
  portalConfirmLine,
@@ -35228,7 +35251,7 @@ function ArchivedDisclosure({
35228
35251
  children,
35229
35252
  className
35230
35253
  }) {
35231
- const [open, setOpen] = useState91(defaultOpen);
35254
+ const [open, setOpen] = useState92(defaultOpen);
35232
35255
  const toggle = () => {
35233
35256
  const next = !open;
35234
35257
  setOpen(next);
@@ -35262,13 +35285,13 @@ function ArchivedPortals({
35262
35285
  className
35263
35286
  }) {
35264
35287
  const client = useRecordsClient66();
35265
- const [rows, setRows] = useState91(null);
35266
- const [error, setError] = useState91(null);
35267
- const [confirming, setConfirming] = useState91(null);
35268
- const [typed2, setTyped] = useState91("");
35269
- const [restoring, setRestoring] = useState91(null);
35270
- const [refusal4, setRefusal] = useState91(null);
35271
- const [said2, setSaid] = useState91(null);
35288
+ const [rows, setRows] = useState92(null);
35289
+ const [error, setError] = useState92(null);
35290
+ const [confirming, setConfirming] = useState92(null);
35291
+ const [typed2, setTyped] = useState92("");
35292
+ const [restoring, setRestoring] = useState92(null);
35293
+ const [refusal4, setRefusal] = useState92(null);
35294
+ const [said2, setSaid] = useState92(null);
35272
35295
  const read = useCallback41(async () => {
35273
35296
  const answered = await client.listPortals({ archived: "archived" });
35274
35297
  if (answered.ok) {
@@ -35395,7 +35418,7 @@ function ArchivedPortals({
35395
35418
  }
35396
35419
 
35397
35420
  // src/ViewBar.tsx
35398
- import { useCallback as useCallback43, useEffect as useEffect80, useRef as useRef49, useState as useState92 } from "react";
35421
+ import { useCallback as useCallback43, useEffect as useEffect80, useRef as useRef49, useState as useState93 } from "react";
35399
35422
  import { useRecordsClient as useRecordsClient67 } from "@ai-matrx/records/react";
35400
35423
  import { Badge as Badge14, Button as Button70, Input as Input6, Popover as Popover10, PopoverContent as PopoverContent10, PopoverTrigger as PopoverTrigger10, Skeleton as Skeleton15, cn as cn58 } from "@ai-matrx/design-system";
35401
35424
 
@@ -35453,18 +35476,18 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
35453
35476
  const table = useTable19(tableId);
35454
35477
  const rights = useTableRights(table.data);
35455
35478
  const notify = useRecordsUi().notify;
35456
- const [views, setViews] = useState92(() => initialViews ?? null);
35457
- const [error, setError] = useState92(null);
35458
- const [unavailable, setUnavailable] = useState92(false);
35459
- const [active, setActive] = useState92(() => {
35479
+ const [views, setViews] = useState93(() => initialViews ?? null);
35480
+ const [error, setError] = useState93(null);
35481
+ const [unavailable, setUnavailable] = useState93(false);
35482
+ const [active, setActive] = useState93(() => {
35460
35483
  if (!initialViews || initialViews.length === 0) return activeViewId ?? null;
35461
35484
  return (initialViews.find((v) => v.id === activeViewId) ?? defaultViewOf(initialViews) ?? initialViews[0]).id;
35462
35485
  });
35463
35486
  const readOnMount = useRef49(initialViews === void 0);
35464
- const [naming, setNaming] = useState92(false);
35465
- const [draftName, setDraftName] = useState92("");
35466
- const [open, setOpen] = useState92(false);
35467
- const [renaming, setRenaming] = useState92(null);
35487
+ const [naming, setNaming] = useState93(false);
35488
+ const [draftName, setDraftName] = useState93("");
35489
+ const [open, setOpen] = useState93(false);
35490
+ const [renaming, setRenaming] = useState93(null);
35468
35491
  const seedKey = JSON.stringify(seed ?? []);
35469
35492
  const readViews = useCallback43(async () => {
35470
35493
  const result = await client.views({ table_id: tableId });
@@ -35728,7 +35751,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
35728
35751
  }
35729
35752
 
35730
35753
  // src/ProposalRow.tsx
35731
- import { useEffect as useEffect81, useRef as useRef50, useState as useState93 } from "react";
35754
+ import { useEffect as useEffect81, useRef as useRef50, useState as useState94 } from "react";
35732
35755
  import { useRecordsClient as useRecordsClient68 } from "@ai-matrx/records/react";
35733
35756
  import { Badge as Badge15, Button as Button71, cn as cn59 } from "@ai-matrx/design-system";
35734
35757
  import { jsx as jsx113, jsxs as jsxs103 } from "react/jsx-runtime";
@@ -35743,9 +35766,9 @@ function ProposalRow({
35743
35766
  className
35744
35767
  }) {
35745
35768
  const client = useRecordsClient68();
35746
- const [settled, setSettled] = useState93(outcome ?? null);
35747
- const [busy, setBusy] = useState93(false);
35748
- const [confirming, setConfirming] = useState93(false);
35769
+ const [settled, setSettled] = useState94(outcome ?? null);
35770
+ const [busy, setBusy] = useState94(false);
35771
+ const [confirming, setConfirming] = useState94(false);
35749
35772
  const drawnVersion = useRef50(null);
35750
35773
  const needsVersion = change.act === "update" && Boolean(change.record) && change.version === void 0 && !onApply && !settled;
35751
35774
  useEffect81(() => {
@@ -35836,14 +35859,14 @@ function ProposalRow({
35836
35859
  }
35837
35860
 
35838
35861
  // src/ActionInbox.tsx
35839
- import { useCallback as useCallback45, useEffect as useEffect83, useMemo as useMemo58, useRef as useRef51, useState as useState95 } from "react";
35862
+ import { useCallback as useCallback45, useEffect as useEffect83, useMemo as useMemo58, useRef as useRef51, useState as useState96 } from "react";
35840
35863
  import { useRecordsClient as useRecordsClient70 } from "@ai-matrx/records/react";
35841
35864
  import { Badge as Badge17, Button as Button73, Checkbox as Checkbox11, Skeleton as Skeleton17, cn as cn61 } from "@ai-matrx/design-system";
35842
35865
  import { toggleSelection as toggleSelection2 } from "@ai-matrx/design-system/data-table";
35843
35866
  import { formatAbsoluteDate, formatDurationMs } from "@ai-matrx/kit/format";
35844
35867
 
35845
35868
  // src/ChecklistRunner.tsx
35846
- import { useCallback as useCallback44, useEffect as useEffect82, useMemo as useMemo57, useState as useState94 } from "react";
35869
+ import { useCallback as useCallback44, useEffect as useEffect82, useMemo as useMemo57, useState as useState95 } from "react";
35847
35870
  import { useRecordsClient as useRecordsClient69, useTable as useTable20 } from "@ai-matrx/records/react";
35848
35871
  import { Badge as Badge16, BasicInput as BasicInput21, BasicTextarea as BasicTextarea9, Button as Button72, Skeleton as Skeleton16, cn as cn60 } from "@ai-matrx/design-system";
35849
35872
  import { humanizeIdentifier as humanizeIdentifier13 } from "@ai-matrx/kit/text-case";
@@ -35863,13 +35886,13 @@ function ChecklistRunner({
35863
35886
  const client = useRecordsClient69();
35864
35887
  const table = useTable20(tableId ?? null);
35865
35888
  const rights = useTableRights(table.data);
35866
- const [runs, setRuns] = useState94(null);
35867
- const [activeId, setActiveId] = useState94(runId ?? null);
35868
- const [steps, setSteps] = useState94(null);
35869
- const [templates, setTemplates] = useState94(null);
35870
- const [error, setError] = useState94(null);
35871
- const [busy, setBusy] = useState94(null);
35872
- const [said2, setSaid] = useState94(null);
35889
+ const [runs, setRuns] = useState95(null);
35890
+ const [activeId, setActiveId] = useState95(runId ?? null);
35891
+ const [steps, setSteps] = useState95(null);
35892
+ const [templates, setTemplates] = useState95(null);
35893
+ const [error, setError] = useState95(null);
35894
+ const [busy, setBusy] = useState95(null);
35895
+ const [said2, setSaid] = useState95(null);
35873
35896
  const mayStart = offerToStart ?? Boolean(recordId);
35874
35897
  const loadRuns = useCallback44(async () => {
35875
35898
  if (runId) {
@@ -36048,7 +36071,7 @@ function StepRow({
36048
36071
  className
36049
36072
  }) {
36050
36073
  const host = useRecordsUi();
36051
- const [members, setMembers] = useState94(null);
36074
+ const [members, setMembers] = useState95(null);
36052
36075
  const unassigned = !step2.finished && !step2.assignee_user_id && Boolean(step2.role);
36053
36076
  useEffect82(() => {
36054
36077
  if (!unassigned || !onAssign || !host.members || members !== null) return;
@@ -36060,7 +36083,7 @@ function StepRow({
36060
36083
  alive = false;
36061
36084
  };
36062
36085
  }, [unassigned, onAssign, host, members]);
36063
- const [answer, setAnswer] = useState94("");
36086
+ const [answer, setAnswer] = useState95("");
36064
36087
  const key = step2.requires_key ?? (step2.requires === "note" ? "note" : null);
36065
36088
  const asksHere = step2.requires === "note" || step2.requires === "answer";
36066
36089
  const needsAnswer = asksHere && answer.trim().length === 0;
@@ -36154,9 +36177,9 @@ function StepRow({
36154
36177
  function useMyChecklistSteps(limit = 25) {
36155
36178
  const client = useRecordsClient69();
36156
36179
  const me = client.config.actor.user_id ?? null;
36157
- const [steps, setSteps] = useState94([]);
36158
- const [loading, setLoading] = useState94(true);
36159
- const [error, setError] = useState94(null);
36180
+ const [steps, setSteps] = useState95([]);
36181
+ const [loading, setLoading] = useState95(true);
36182
+ const [error, setError] = useState95(null);
36160
36183
  const refresh = useCallback44(async () => {
36161
36184
  if (!me) {
36162
36185
  setSteps([]);
@@ -36202,8 +36225,8 @@ function MyChecklistSteps({
36202
36225
  onSteps?.(held.map((s) => s.step_id));
36203
36226
  }, [held, onSteps]);
36204
36227
  const steps = onlyIds ? held.filter((s) => onlyIds.has(s.step_id)) : held;
36205
- const [busy, setBusy] = useState94(null);
36206
- const [refusal4, setRefusal] = useState94(null);
36228
+ const [busy, setBusy] = useState95(null);
36229
+ const [refusal4, setRefusal] = useState95(null);
36207
36230
  const complete = useCallback44(
36208
36231
  async (step2, evidence) => {
36209
36232
  setBusy(step2.step_id);
@@ -36247,12 +36270,12 @@ function ChecklistsPanel({ tableId, onOpenRecord, className }) {
36247
36270
  const client = useRecordsClient69();
36248
36271
  const table = useTable20(tableId);
36249
36272
  const rights = useTableRights(table.data);
36250
- const [templates, setTemplates] = useState94(null);
36251
- const [runs, setRuns] = useState94(null);
36252
- const [error, setError] = useState94(null);
36253
- const [editing, setEditing] = useState94(null);
36254
- const [openRun, setOpenRun] = useState94(null);
36255
- const [archivedSaid, setArchivedSaid] = useState94(null);
36273
+ const [templates, setTemplates] = useState95(null);
36274
+ const [runs, setRuns] = useState95(null);
36275
+ const [error, setError] = useState95(null);
36276
+ const [editing, setEditing] = useState95(null);
36277
+ const [openRun, setOpenRun] = useState95(null);
36278
+ const [archivedSaid, setArchivedSaid] = useState95(null);
36256
36279
  const load = useCallback44(async () => {
36257
36280
  const [t, r] = await Promise.all([
36258
36281
  client.checklistTemplates({ about_table_id: tableId, limit: 100 }),
@@ -36422,14 +36445,14 @@ function ChecklistTemplateEditor({
36422
36445
  className
36423
36446
  }) {
36424
36447
  const client = useRecordsClient69();
36425
- const [savedId, setSavedId] = useState94(templateId ?? null);
36426
- const [saved, setSaved] = useState94(false);
36427
- const [name, setName] = useState94("");
36428
- const [rows, setRows] = useState94([{ ...EMPTY_ROW }]);
36429
- const [refusal4, setRefusal] = useState94(null);
36430
- const [error, setError] = useState94(null);
36431
- const [busy, setBusy] = useState94(false);
36432
- const [loading, setLoading] = useState94(Boolean(templateId));
36448
+ const [savedId, setSavedId] = useState95(templateId ?? null);
36449
+ const [saved, setSaved] = useState95(false);
36450
+ const [name, setName] = useState95("");
36451
+ const [rows, setRows] = useState95([{ ...EMPTY_ROW }]);
36452
+ const [refusal4, setRefusal] = useState95(null);
36453
+ const [error, setError] = useState95(null);
36454
+ const [busy, setBusy] = useState95(false);
36455
+ const [loading, setLoading] = useState95(Boolean(templateId));
36433
36456
  useEffect82(() => {
36434
36457
  if (!templateId) return;
36435
36458
  let cancelled = false;
@@ -36730,25 +36753,25 @@ function ActionInbox({
36730
36753
  className
36731
36754
  }) {
36732
36755
  const client = useRecordsClient70();
36733
- const [showDecided, setShowDecided] = useState95(includeSettled);
36734
- const [groupBy, setGroupBy] = useState95(defaultGroupBy);
36735
- const [everyTable, setEveryTable] = useState95(false);
36736
- const [items, setItems] = useState95(null);
36737
- const [error, setError] = useState95(null);
36738
- const [outcome, setOutcome] = useState95({});
36739
- const [busy, setBusy] = useState95(null);
36740
- const [cursor, setCursor] = useState95(0);
36756
+ const [showDecided, setShowDecided] = useState96(includeSettled);
36757
+ const [groupBy, setGroupBy] = useState96(defaultGroupBy);
36758
+ const [everyTable, setEveryTable] = useState96(false);
36759
+ const [items, setItems] = useState96(null);
36760
+ const [error, setError] = useState96(null);
36761
+ const [outcome, setOutcome] = useState96({});
36762
+ const [busy, setBusy] = useState96(null);
36763
+ const [cursor, setCursor] = useState96(0);
36741
36764
  const listRef = useRef51(null);
36742
- const [selected, setSelected] = useState95(/* @__PURE__ */ new Set());
36765
+ const [selected, setSelected] = useState96(/* @__PURE__ */ new Set());
36743
36766
  const anchor = useRef51(null);
36744
- const [deciding, setDeciding] = useState95(false);
36745
- const [batchSaid, setBatchSaid] = useState95(null);
36746
- const [view, setView] = useState95("inbox");
36747
- const [counts, setCounts] = useState95(null);
36748
- const [snoozing, setSnoozing] = useState95(null);
36749
- const [pickAt, setPickAt] = useState95("");
36750
- const [said2, setSaid] = useState95(null);
36751
- const [stepIds, setStepIds] = useState95(/* @__PURE__ */ new Set());
36767
+ const [deciding, setDeciding] = useState96(false);
36768
+ const [batchSaid, setBatchSaid] = useState96(null);
36769
+ const [view, setView] = useState96("inbox");
36770
+ const [counts, setCounts] = useState96(null);
36771
+ const [snoozing, setSnoozing] = useState96(null);
36772
+ const [pickAt, setPickAt] = useState96("");
36773
+ const [said2, setSaid] = useState96(null);
36774
+ const [stepIds, setStepIds] = useState96(/* @__PURE__ */ new Set());
36752
36775
  const onSteps = useCallback45((ids) => setStepIds(new Set(ids)), []);
36753
36776
  const load = useCallback45(async () => {
36754
36777
  const [result, counted] = await Promise.all([
@@ -36803,11 +36826,11 @@ function ActionInbox({
36803
36826
  },
36804
36827
  [client, load]
36805
36828
  );
36806
- const [held, setHeld] = useState95({});
36829
+ const [held, setHeld] = useState96({});
36807
36830
  const holds2 = useRef51(/* @__PURE__ */ new Map());
36808
36831
  const lastHold = useRef51(null);
36809
36832
  const holdSeq = useRef51(0);
36810
- const [, tick] = useState95(0);
36833
+ const [, tick] = useState96(0);
36811
36834
  useEffect83(() => {
36812
36835
  if (Object.keys(held).length === 0) return;
36813
36836
  const t = setInterval(() => tick((n) => n + 1), 250);
@@ -37484,7 +37507,7 @@ function ActionInbox({
37484
37507
  }
37485
37508
 
37486
37509
  // src/HistoryPanel.tsx
37487
- import { useCallback as useCallback46, useEffect as useEffect84, useRef as useRef52, useState as useState96 } from "react";
37510
+ import { useCallback as useCallback46, useEffect as useEffect84, useRef as useRef52, useState as useState97 } from "react";
37488
37511
  import {
37489
37512
  useFields as useFields20,
37490
37513
  useRecordChangeRevision,
@@ -37500,12 +37523,12 @@ function HistoryPanel({ tableId, recordId, onAskAboutField, className }) {
37500
37523
  const table = useTable21(tableId);
37501
37524
  const fields = useFields20(tableId);
37502
37525
  const rights = useTableRights(table.data);
37503
- const [entries, setEntries] = useState96(null);
37504
- const [error, setError] = useState96(null);
37505
- const [open, setOpen] = useState96(null);
37506
- const [pending, setPending] = useState96({ phase: "idle" });
37526
+ const [entries, setEntries] = useState97(null);
37527
+ const [error, setError] = useState97(null);
37528
+ const [open, setOpen] = useState97(null);
37529
+ const [pending, setPending] = useState97({ phase: "idle" });
37507
37530
  const seenAtPreview = useRef52(null);
37508
- const [said2, setSaid] = useState96(null);
37531
+ const [said2, setSaid] = useState97(null);
37509
37532
  const listRef = useRef52(null);
37510
37533
  const changed = useRecordChangeRevision(recordId);
37511
37534
  const load = useCallback46(async () => {
@@ -37800,7 +37823,7 @@ function say(value, field2) {
37800
37823
  }
37801
37824
 
37802
37825
  // src/CommentThread.tsx
37803
- import { useCallback as useCallback47, useEffect as useEffect85, useMemo as useMemo59, useRef as useRef53, useState as useState97 } from "react";
37826
+ import { useCallback as useCallback47, useEffect as useEffect85, useMemo as useMemo59, useRef as useRef53, useState as useState98 } from "react";
37804
37827
  import {
37805
37828
  useFields as useFields21,
37806
37829
  useRecordsClient as useRecordsClient72,
@@ -37814,16 +37837,16 @@ function CommentThread({ tableId, recordId, fieldKey, className }) {
37814
37837
  const table = useTable22(tableId);
37815
37838
  const fields = useFields21(tableId);
37816
37839
  const host = useRecordsUi();
37817
- const [thread, setThread] = useState97(null);
37818
- const [error, setError] = useState97(null);
37819
- const [draft, setDraft] = useState97("");
37820
- const [replyTo, setReplyTo] = useState97(null);
37821
- const [busy, setBusy] = useState97(false);
37822
- const [said2, setSaid] = useState97(null);
37823
- const [showResolved, setShowResolved] = useState97(false);
37824
- const [people, setPeople] = useState97([]);
37825
- const [mentionQuery, setMentionQuery] = useState97(null);
37826
- const [picked, setPicked] = useState97([]);
37840
+ const [thread, setThread] = useState98(null);
37841
+ const [error, setError] = useState98(null);
37842
+ const [draft, setDraft] = useState98("");
37843
+ const [replyTo, setReplyTo] = useState98(null);
37844
+ const [busy, setBusy] = useState98(false);
37845
+ const [said2, setSaid] = useState98(null);
37846
+ const [showResolved, setShowResolved] = useState98(false);
37847
+ const [people, setPeople] = useState98([]);
37848
+ const [mentionQuery, setMentionQuery] = useState98(null);
37849
+ const [picked, setPicked] = useState98([]);
37827
37850
  const box = useRef53(null);
37828
37851
  const load = useCallback47(async () => {
37829
37852
  const answered = await client.commentThread({ record_id: recordId, include_resolved: showResolved });
@@ -38044,7 +38067,7 @@ function Line({
38044
38067
  }
38045
38068
 
38046
38069
  // src/FieldHistoryPanel.tsx
38047
- import { useCallback as useCallback48, useEffect as useEffect86, useRef as useRef54, useState as useState98 } from "react";
38070
+ import { useCallback as useCallback48, useEffect as useEffect86, useRef as useRef54, useState as useState99 } from "react";
38048
38071
  import {
38049
38072
  useFields as useFields22,
38050
38073
  useRecordsClient as useRecordsClient73,
@@ -38065,11 +38088,11 @@ function FieldHistoryPanel({
38065
38088
  const table = useTable23(tableId);
38066
38089
  const fields = useFields22(tableId);
38067
38090
  const rights = useTableRights(table.data);
38068
- const [rows, setRows] = useState98(null);
38069
- const [error, setError] = useState98(null);
38070
- const [pending, setPending] = useState98({ phase: "idle" });
38091
+ const [rows, setRows] = useState99(null);
38092
+ const [error, setError] = useState99(null);
38093
+ const [pending, setPending] = useState99({ phase: "idle" });
38071
38094
  const seenAtPreview = useRef54(null);
38072
- const [said2, setSaid] = useState98(null);
38095
+ const [said2, setSaid] = useState99(null);
38073
38096
  const load = useCallback48(async () => {
38074
38097
  const answered = await client.fieldHistory(
38075
38098
  recordId ? { table_id: tableId, field_key: fieldKey, record_id: recordId } : { table_id: tableId, field_key: fieldKey }
@@ -38476,7 +38499,7 @@ function submissionStamp(args) {
38476
38499
  }
38477
38500
 
38478
38501
  // src/FormResultsPanel.tsx
38479
- import { useEffect as useEffect90, useMemo as useMemo62, useState as useState102 } from "react";
38502
+ import { useEffect as useEffect90, useMemo as useMemo62, useState as useState103 } from "react";
38480
38503
  import { useFields as useFields23, useOptionalRecordsClient as useOptionalRecordsClient13 } from "@ai-matrx/records/react";
38481
38504
  import { Button as Button77, Skeleton as Skeleton21, cn as cn67 } from "@ai-matrx/design-system";
38482
38505
 
@@ -38505,7 +38528,7 @@ import { cn as cn66 } from "@ai-matrx/design-system";
38505
38528
  import { formatCount as formatCount5 } from "@ai-matrx/kit/format";
38506
38529
 
38507
38530
  // src/linkWords.ts
38508
- import { useEffect as useEffect87, useMemo as useMemo60, useState as useState99 } from "react";
38531
+ import { useEffect as useEffect87, useMemo as useMemo60, useState as useState100 } from "react";
38509
38532
  import { useOptionalRecordsClient as useOptionalRecordsClient11 } from "@ai-matrx/records/react";
38510
38533
 
38511
38534
  // src/charts.ts
@@ -38720,8 +38743,8 @@ function useLinkGroupNamer(block, tableId) {
38720
38743
  const groupBy = block.kind === "stuck" ? [] : block.group_by ?? [];
38721
38744
  const rows = block.kind === "stuck" ? [] : block.rows ?? [];
38722
38745
  const ask = JSON.stringify([tableId, groupBy, rows.map((r) => r.groups ?? null)]);
38723
- const [named, setNamed] = useState99({});
38724
- const [choices, setChoices] = useState99([]);
38746
+ const [named, setNamed] = useState100({});
38747
+ const [choices, setChoices] = useState100([]);
38725
38748
  const labels = useRecordLabels(choices);
38726
38749
  useEffect87(() => {
38727
38750
  if (!client || groupBy.length === 0 || rows.length === 0) return;
@@ -38766,7 +38789,7 @@ function useLinkGroupNamer(block, tableId) {
38766
38789
  }
38767
38790
 
38768
38791
  // src/measureWords.ts
38769
- import { useEffect as useEffect88, useState as useState100 } from "react";
38792
+ import { useEffect as useEffect88, useState as useState101 } from "react";
38770
38793
  import { useOptionalRecordsClient as useOptionalRecordsClient12 } from "@ai-matrx/records/react";
38771
38794
  import { humanizeIdentifier as humanizeIdentifier17 } from "@ai-matrx/kit/text-case";
38772
38795
  var OP_WORD = { sum: "Total", avg: "Average", min: "Lowest", max: "Highest" };
@@ -38783,7 +38806,7 @@ function measureWords(key, fields) {
38783
38806
  }
38784
38807
  function useMeasureWords(key, tableId) {
38785
38808
  const client = useOptionalRecordsClient12();
38786
- const [fields, setFields] = useState100(null);
38809
+ const [fields, setFields] = useState101(null);
38787
38810
  const needs = key !== "count";
38788
38811
  useEffect88(() => {
38789
38812
  if (!client || !tableId || !needs) return;
@@ -38803,13 +38826,13 @@ import {
38803
38826
  useEffect as useEffect89,
38804
38827
  useId as useId4,
38805
38828
  useRef as useRef55,
38806
- useState as useState101
38829
+ useState as useState102
38807
38830
  } from "react";
38808
38831
  import { cn as cn65 } from "@ai-matrx/design-system";
38809
38832
  import { jsx as jsx119, jsxs as jsxs109 } from "react/jsx-runtime";
38810
38833
  function useMeasuredWidth(fallback = 480) {
38811
38834
  const ref = useRef55(null);
38812
- const [width, setWidth] = useState101(fallback);
38835
+ const [width, setWidth] = useState102(fallback);
38813
38836
  useEffect89(() => {
38814
38837
  const node = ref.current;
38815
38838
  if (!node) return;
@@ -39439,9 +39462,9 @@ function answersBlock(question, title) {
39439
39462
  function FormResultsPanel({ form, className }) {
39440
39463
  const client = useOptionalRecordsClient13();
39441
39464
  const fields = useFields23(form.subject);
39442
- const [results, setResults] = useState102(null);
39443
- const [error, setError] = useState102(null);
39444
- const [round, setRound] = useState102(0);
39465
+ const [results, setResults] = useState103(null);
39466
+ const [error, setError] = useState103(null);
39467
+ const [round, setRound] = useState103(0);
39445
39468
  useEffect90(() => {
39446
39469
  if (!client) {
39447
39470
  setError(refusal("not_supported", "Results are read from the record store, and this screen has none.", "Open the form inside the app."));
@@ -39540,7 +39563,7 @@ function FormResultsPanel({ form, className }) {
39540
39563
  }
39541
39564
 
39542
39565
  // src/PortalBuilder.tsx
39543
- import { useCallback as useCallback49, useEffect as useEffect91, useMemo as useMemo63, useRef as useRef56, useState as useState103 } from "react";
39566
+ import { useCallback as useCallback49, useEffect as useEffect91, useMemo as useMemo63, useRef as useRef56, useState as useState104 } from "react";
39544
39567
  import { useRecordsClient as useRecordsClient74, useTables as useTables4 } from "@ai-matrx/records/react";
39545
39568
  import { BasicInput as BasicInput22, Button as Button78, Checkbox as Checkbox12, Label as Label18, Separator as Separator10, Skeleton as Skeleton22, cn as cn68 } from "@ai-matrx/design-system";
39546
39569
  import { Fragment as Fragment49, jsx as jsx122, jsxs as jsxs112 } from "react/jsx-runtime";
@@ -39548,19 +39571,19 @@ var RESTATING_REPLACES = "Saving replaces what this portal shows: a table you un
39548
39571
  function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
39549
39572
  const client = useRecordsClient74();
39550
39573
  const tables = useTables4();
39551
- const [title, setTitle] = useState103("");
39552
- const [clientTableId, setClientTableId] = useState103(null);
39553
- const [exposures, setExposures] = useState103({});
39554
- const [fieldsByTable, setFieldsByTable] = useState103({});
39555
- const [error, setError] = useState103(null);
39556
- const [saving, setSaving] = useState103(false);
39557
- const [savedId, setSavedId] = useState103(portalId ?? null);
39558
- const [existing, setExisting] = useState103(null);
39559
- const [loading, setLoading] = useState103(Boolean(portalId));
39560
- const [inviteEmail, setInviteEmail] = useState103("");
39561
- const [inviteRecordId, setInviteRecordId] = useState103("");
39562
- const [inviting, setInviting] = useState103(false);
39563
- const [invitationSaid, setInvitationSaid] = useState103(null);
39574
+ const [title, setTitle] = useState104("");
39575
+ const [clientTableId, setClientTableId] = useState104(null);
39576
+ const [exposures, setExposures] = useState104({});
39577
+ const [fieldsByTable, setFieldsByTable] = useState104({});
39578
+ const [error, setError] = useState104(null);
39579
+ const [saving, setSaving] = useState104(false);
39580
+ const [savedId, setSavedId] = useState104(portalId ?? null);
39581
+ const [existing, setExisting] = useState104(null);
39582
+ const [loading, setLoading] = useState104(Boolean(portalId));
39583
+ const [inviteEmail, setInviteEmail] = useState104("");
39584
+ const [inviteRecordId, setInviteRecordId] = useState104("");
39585
+ const [inviting, setInviting] = useState104(false);
39586
+ const [invitationSaid, setInvitationSaid] = useState104(null);
39564
39587
  const loadFields = useCallback49(
39565
39588
  async (id, fresh = false) => {
39566
39589
  if (fieldsByTable[id] && !fresh) return;
@@ -39629,7 +39652,7 @@ function PortalBuilder({ tableId, portalId, onSaved, onClose, className }) {
39629
39652
  }));
39630
39653
  if (on) void loadFields(t.id);
39631
39654
  }
39632
- const [linking, setLinking] = useState103(null);
39655
+ const [linking, setLinking] = useState104(null);
39633
39656
  const linkingNow = useRef56(null);
39634
39657
  async function addLinkBack(id) {
39635
39658
  const clients = (tables.data ?? []).find((t) => t.id === clientTableId);
@@ -39932,7 +39955,7 @@ function clientNoun(table) {
39932
39955
 
39933
39956
  // src/PortalsPanel.tsx
39934
39957
  import { copyText as copyText6 } from "@ai-matrx/kit/clipboard";
39935
- import { useCallback as useCallback50, useEffect as useEffect93, useMemo as useMemo65, useState as useState105 } from "react";
39958
+ import { useCallback as useCallback50, useEffect as useEffect93, useMemo as useMemo65, useState as useState106 } from "react";
39936
39959
  import { useRecordsClient as useRecordsClient76 } from "@ai-matrx/records/react";
39937
39960
  import {
39938
39961
  portalArchiveConsequence,
@@ -39943,7 +39966,7 @@ import {
39943
39966
  import { Badge as Badge21, BasicInput as BasicInput24, Button as Button80, Separator as Separator11, Skeleton as Skeleton23, cn as cn72 } from "@ai-matrx/design-system";
39944
39967
 
39945
39968
  // src/PortalLookEditor.tsx
39946
- import { useEffect as useEffect92, useMemo as useMemo64, useState as useState104 } from "react";
39969
+ import { useEffect as useEffect92, useMemo as useMemo64, useState as useState105 } from "react";
39947
39970
  import { useRecordsClient as useRecordsClient75 } from "@ai-matrx/records/react";
39948
39971
  import { BasicInput as BasicInput23, Button as Button79, cn as cn71 } from "@ai-matrx/design-system";
39949
39972
 
@@ -40057,17 +40080,17 @@ function candidateRows(card, available) {
40057
40080
  function PortalLookEditor({ card, onSaved, className }) {
40058
40081
  const client = useRecordsClient75();
40059
40082
  const stored = card.config?.style ?? {};
40060
- const [name, setName] = useState104(stored.display_name ?? "");
40061
- const [welcome, setWelcome] = useState104(stored.welcome ?? "");
40062
- const [logo, setLogo] = useState104(stored.logo_file_id ?? "");
40063
- const [accent, setAccent] = useState104(stored.accent ?? "");
40064
- const [links, setLinks] = useState104(stored.footer_links ?? []);
40065
- const [forms, setForms] = useState104(null);
40066
- const [busy, setBusy] = useState104(false);
40067
- const [error, setError] = useState104(null);
40068
- const [said2, setSaid] = useState104(null);
40069
- const [formsError, setFormsError] = useState104(null);
40070
- const [formsUnread, setFormsUnread] = useState104(false);
40083
+ const [name, setName] = useState105(stored.display_name ?? "");
40084
+ const [welcome, setWelcome] = useState105(stored.welcome ?? "");
40085
+ const [logo, setLogo] = useState105(stored.logo_file_id ?? "");
40086
+ const [accent, setAccent] = useState105(stored.accent ?? "");
40087
+ const [links, setLinks] = useState105(stored.footer_links ?? []);
40088
+ const [forms, setForms] = useState105(null);
40089
+ const [busy, setBusy] = useState105(false);
40090
+ const [error, setError] = useState105(null);
40091
+ const [said2, setSaid] = useState105(null);
40092
+ const [formsError, setFormsError] = useState105(null);
40093
+ const [formsUnread, setFormsUnread] = useState105(false);
40071
40094
  useEffect92(() => {
40072
40095
  let cancelled = false;
40073
40096
  void (async () => {
@@ -40314,16 +40337,16 @@ var PORTAL_SUGGESTION = "Let each of my customers sign in and see their own jobs
40314
40337
  function PortalsPanel({ tableId, activePortalId, className }) {
40315
40338
  const client = useRecordsClient76();
40316
40339
  const host = useRecordsUi();
40317
- const [portals, setPortals] = useState105(null);
40318
- const [exposures, setExposures] = useState105([]);
40319
- const [listError, setListError] = useState105(null);
40320
- const [openId, setOpenId] = useState105(activePortalId ?? null);
40340
+ const [portals, setPortals] = useState106(null);
40341
+ const [exposures, setExposures] = useState106([]);
40342
+ const [listError, setListError] = useState106(null);
40343
+ const [openId, setOpenId] = useState106(activePortalId ?? null);
40321
40344
  useEffect93(() => {
40322
40345
  if (activePortalId) setOpenId(activePortalId);
40323
40346
  }, [activePortalId]);
40324
- const [building, setBuilding] = useState105(false);
40325
- const [adding, setAdding] = useState105(null);
40326
- const [archiveToken, setArchiveToken] = useState105(0);
40347
+ const [building, setBuilding] = useState106(false);
40348
+ const [adding, setAdding] = useState106(null);
40349
+ const [archiveToken, setArchiveToken] = useState106(0);
40327
40350
  const load = useCallback50(async () => {
40328
40351
  const [answered, mapped] = await Promise.all([client.portals(), client.portalTables()]);
40329
40352
  if (!answered.ok) {
@@ -40493,11 +40516,11 @@ function ArchivePortalControl({
40493
40516
  onArchived
40494
40517
  }) {
40495
40518
  const client = useRecordsClient76();
40496
- const [asking, setAsking] = useState105(false);
40497
- const [typed2, setTyped] = useState105("");
40498
- const [busy, setBusy] = useState105(false);
40499
- const [error, setError] = useState105(null);
40500
- const [said2, setSaid] = useState105(null);
40519
+ const [asking, setAsking] = useState106(false);
40520
+ const [typed2, setTyped] = useState106("");
40521
+ const [busy, setBusy] = useState106(false);
40522
+ const [error, setError] = useState106(null);
40523
+ const [said2, setSaid] = useState106(null);
40501
40524
  const go = async () => {
40502
40525
  setBusy(true);
40503
40526
  setError(null);
@@ -40564,8 +40587,8 @@ function ArchivePortalControl({
40564
40587
  ] });
40565
40588
  }
40566
40589
  function CopyLink({ url, what }) {
40567
- const [copied, setCopied] = useState105(false);
40568
- const [shown4, setShown] = useState105(false);
40590
+ const [copied, setCopied] = useState106(false);
40591
+ const [shown4, setShown] = useState106(false);
40569
40592
  return /* @__PURE__ */ jsxs116(Fragment50, { children: [
40570
40593
  /* @__PURE__ */ jsx126(
40571
40594
  Button80,
@@ -40599,8 +40622,8 @@ function PortalDetail({
40599
40622
  onChanged
40600
40623
  }) {
40601
40624
  const client = useRecordsClient76();
40602
- const [card, setCard] = useState105(null);
40603
- const [error, setError] = useState105(null);
40625
+ const [card, setCard] = useState106(null);
40626
+ const [error, setError] = useState106(null);
40604
40627
  const load = useCallback50(async () => {
40605
40628
  const answered = await client.portalCard({ portal_id: portalId });
40606
40629
  if (!answered.ok) {
@@ -40728,11 +40751,11 @@ function People({
40728
40751
  origin
40729
40752
  }) {
40730
40753
  const here = origin ?? (typeof window === "undefined" ? "" : window.location.origin);
40731
- const [askingToRevoke, setAskingToRevoke] = useState105(null);
40732
- const [busy, setBusy] = useState105(false);
40733
- const [said2, setSaid] = useState105(null);
40734
- const [error, setError] = useState105(null);
40735
- const [previewing, setPreviewing] = useState105(null);
40754
+ const [askingToRevoke, setAskingToRevoke] = useState106(null);
40755
+ const [busy, setBusy] = useState106(false);
40756
+ const [said2, setSaid] = useState106(null);
40757
+ const [error, setError] = useState106(null);
40758
+ const [previewing, setPreviewing] = useState106(null);
40736
40759
  const revoke = useCallback50(
40737
40760
  async (person) => {
40738
40761
  setBusy(true);
@@ -40816,9 +40839,9 @@ function Preview({
40816
40839
  onPreview
40817
40840
  }) {
40818
40841
  const first = card.tables[0];
40819
- const [which, setWhich] = useState105(first?.table_id ?? null);
40820
- const [rows, setRows] = useState105(null);
40821
- const [error, setError] = useState105(null);
40842
+ const [which, setWhich] = useState106(first?.table_id ?? null);
40843
+ const [rows, setRows] = useState106(null);
40844
+ const [error, setError] = useState106(null);
40822
40845
  useEffect93(() => {
40823
40846
  if (!which) return;
40824
40847
  let cancelled = false;
@@ -40857,14 +40880,14 @@ function Preview({
40857
40880
  }
40858
40881
  function Invite({ card, onInvited }) {
40859
40882
  const client = useRecordsClient76();
40860
- const [rows, setRows] = useState105(null);
40861
- const [clientTable, setClientTable] = useState105(null);
40862
- const [search, setSearch] = useState105("");
40863
- const [picked, setPicked] = useState105(null);
40864
- const [email, setEmail] = useState105("");
40865
- const [busy, setBusy] = useState105(false);
40866
- const [said2, setSaid] = useState105(null);
40867
- const [error, setError] = useState105(null);
40883
+ const [rows, setRows] = useState106(null);
40884
+ const [clientTable, setClientTable] = useState106(null);
40885
+ const [search, setSearch] = useState106("");
40886
+ const [picked, setPicked] = useState106(null);
40887
+ const [email, setEmail] = useState106("");
40888
+ const [busy, setBusy] = useState106(false);
40889
+ const [said2, setSaid] = useState106(null);
40890
+ const [error, setError] = useState106(null);
40868
40891
  useEffect93(() => {
40869
40892
  let cancelled = false;
40870
40893
  void client.list({ table_id: card.client_table_id, limit: 200 }).then((answered) => {
@@ -41076,7 +41099,7 @@ function FormLookFrame({ look, title, children, contained = false, showOwnerHead
41076
41099
  }
41077
41100
 
41078
41101
  // src/DigestScheduler.tsx
41079
- import { useCallback as useCallback51, useEffect as useEffect94, useMemo as useMemo66, useState as useState106 } from "react";
41102
+ import { useCallback as useCallback51, useEffect as useEffect94, useMemo as useMemo66, useState as useState107 } from "react";
41080
41103
  import { useRecordsClient as useRecordsClient77, useTable as useTable24 } from "@ai-matrx/records/react";
41081
41104
  import { hasQuietHours } from "@ai-matrx/records";
41082
41105
  import { BasicInput as BasicInput25, Button as Button81, Checkbox as Checkbox13, Label as Label19, Separator as Separator12, Skeleton as Skeleton24, cn as cn74 } from "@ai-matrx/design-system";
@@ -41139,41 +41162,41 @@ function DigestScheduler({
41139
41162
  }) {
41140
41163
  const client = useRecordsClient77();
41141
41164
  const host = useRecordsUi();
41142
- const [views, setViews] = useState106(null);
41143
- const [cadences, setCadences] = useState106([]);
41144
- const [members, setMembers] = useState106(null);
41145
- const [error, setError] = useState106(null);
41165
+ const [views, setViews] = useState107(null);
41166
+ const [cadences, setCadences] = useState107([]);
41167
+ const [members, setMembers] = useState107(null);
41168
+ const [error, setError] = useState107(null);
41146
41169
  const was = scheduleParts(existing?.schedule);
41147
- const [viewId, setViewId] = useState106(
41170
+ const [viewId, setViewId] = useState107(
41148
41171
  existing?.saved_view_id ?? savedViewId ?? ""
41149
41172
  );
41150
- const [name, setName] = useState106(
41173
+ const [name, setName] = useState107(
41151
41174
  existing?.name ?? (subjectName?.trim() ? `${subjectName.trim()} summary` : "")
41152
41175
  );
41153
- const [cadence, setCadence] = useState106(
41176
+ const [cadence, setCadence] = useState107(
41154
41177
  ["hourly", "daily", "weekly"].includes(existing?.cadence ?? "") ? existing.cadence : "weekly"
41155
41178
  );
41156
- const [weekday, setWeekday] = useState106(was.day ?? "monday");
41157
- const [time, setTime] = useState106(was.time ?? "08:00");
41158
- const [timezone, setTimezone] = useState106(() => {
41179
+ const [weekday, setWeekday] = useState107(was.day ?? "monday");
41180
+ const [time, setTime] = useState107(was.time ?? "08:00");
41181
+ const [timezone, setTimezone] = useState107(() => {
41159
41182
  const kept = existing?.quiet_hours?.tz?.trim();
41160
41183
  return kept && kept.toUpperCase() !== "UTC" ? kept : ownTimeZone();
41161
41184
  });
41162
41185
  const table = useTable24(tableId);
41163
41186
  const tableName2 = table.data?.name?.trim() || null;
41164
- const [channel, setChannel] = useState106(
41187
+ const [channel, setChannel] = useState107(
41165
41188
  existing?.channel === "email" || existing?.channel === "sms" ? existing.channel : "in_app"
41166
41189
  );
41167
- const [quiet2, setQuiet] = useState106(hasQuietHours(existing?.quiet_hours));
41168
- const [quietFrom, setQuietFrom] = useState106(existing?.quiet_hours?.start ?? "22:00");
41169
- const [quietTo, setQuietTo] = useState106(existing?.quiet_hours?.end ?? "07:00");
41170
- const [recipients, setRecipients] = useState106(
41190
+ const [quiet2, setQuiet] = useState107(hasQuietHours(existing?.quiet_hours));
41191
+ const [quietFrom, setQuietFrom] = useState107(existing?.quiet_hours?.start ?? "22:00");
41192
+ const [quietTo, setQuietTo] = useState107(existing?.quiet_hours?.end ?? "07:00");
41193
+ const [recipients, setRecipients] = useState107(
41171
41194
  existing?.recipient_user_id ? [existing.recipient_user_id] : []
41172
41195
  );
41173
- const [saving, setSaving] = useState106(false);
41174
- const [outcomes, setOutcomes] = useState106(null);
41175
- const [preview, setPreview] = useState106(null);
41176
- const [previewing, setPreviewing] = useState106(false);
41196
+ const [saving, setSaving] = useState107(false);
41197
+ const [outcomes, setOutcomes] = useState107(null);
41198
+ const [preview, setPreview] = useState107(null);
41199
+ const [previewing, setPreviewing] = useState107(false);
41177
41200
  const load = useCallback51(async () => {
41178
41201
  const [saved, offered] = await Promise.all([
41179
41202
  // The store's own door onto `platform.saved_view`, narrowed in SQL to
@@ -41448,13 +41471,13 @@ function DigestScheduler({
41448
41471
  }
41449
41472
 
41450
41473
  // src/SubscriptionsPanel.tsx
41451
- import { useCallback as useCallback53, useEffect as useEffect96, useState as useState108 } from "react";
41474
+ import { useCallback as useCallback53, useEffect as useEffect96, useState as useState109 } from "react";
41452
41475
  import { useRecordsClient as useRecordsClient79 } from "@ai-matrx/records/react";
41453
41476
  import { hasQuietHours as hasQuietHours2 } from "@ai-matrx/records";
41454
41477
  import { Badge as Badge22, Button as Button83, Skeleton as Skeleton26, Switch as Switch4, cn as cn76 } from "@ai-matrx/design-system";
41455
41478
 
41456
41479
  // src/WebhooksPanel.tsx
41457
- import { useCallback as useCallback52, useEffect as useEffect95, useState as useState107 } from "react";
41480
+ import { useCallback as useCallback52, useEffect as useEffect95, useState as useState108 } from "react";
41458
41481
  import { useRecordsClient as useRecordsClient78, useTable as useTable25 } from "@ai-matrx/records/react";
41459
41482
  import { BasicInput as BasicInput26, Button as Button82, Checkbox as Checkbox14, ConfirmDialog as ConfirmDialog7, Label as Label20, Skeleton as Skeleton25, cn as cn75 } from "@ai-matrx/design-system";
41460
41483
  import { jsx as jsx129, jsxs as jsxs119 } from "react/jsx-runtime";
@@ -41478,16 +41501,16 @@ function WebhooksPanel({ tableId, className }) {
41478
41501
  const client = useRecordsClient78();
41479
41502
  const table = useTable25(tableId);
41480
41503
  const rights = useTableRights(table.data);
41481
- const [hooks, setHooks] = useState107(null);
41482
- const [error, setError] = useState107(null);
41483
- const [adding, setAdding] = useState107(false);
41484
- const [url, setUrl] = useState107("");
41485
- const [description, setDescription] = useState107("");
41486
- const [events, setEvents] = useState107(DEFAULT_EVENTS);
41487
- const [busy, setBusy] = useState107(false);
41488
- const [declared2, setDeclared] = useState107(null);
41489
- const [stopping, setStopping] = useState107(null);
41490
- const [readRefused, setReadRefused] = useState107(null);
41504
+ const [hooks, setHooks] = useState108(null);
41505
+ const [error, setError] = useState108(null);
41506
+ const [adding, setAdding] = useState108(false);
41507
+ const [url, setUrl] = useState108("");
41508
+ const [description, setDescription] = useState108("");
41509
+ const [events, setEvents] = useState108(DEFAULT_EVENTS);
41510
+ const [busy, setBusy] = useState108(false);
41511
+ const [declared2, setDeclared] = useState108(null);
41512
+ const [stopping, setStopping] = useState108(null);
41513
+ const [readRefused, setReadRefused] = useState108(null);
41491
41514
  const load = useCallback52(async () => {
41492
41515
  const answered = await client.tableWebhooks({ table_id: tableId });
41493
41516
  if (!answered.ok) {
@@ -41671,12 +41694,12 @@ var CHANNEL_WORDS2 = SUBSCRIPTION_CHANNEL_LABEL;
41671
41694
  var DIGEST_SUGGESTION = "Email me a summary of this every Monday at 8 in the morning.";
41672
41695
  function SubscriptionsPanel({ tableId, activeRuleId, className }) {
41673
41696
  const client = useRecordsClient79();
41674
- const [rows, setRows] = useState108(null);
41675
- const [error, setError] = useState108(null);
41676
- const [busy, setBusy] = useState108(null);
41677
- const [preview, setPreview] = useState108(null);
41678
- const [scheduling, setScheduling] = useState108(false);
41679
- const [changing, setChanging] = useState108(null);
41697
+ const [rows, setRows] = useState109(null);
41698
+ const [error, setError] = useState109(null);
41699
+ const [busy, setBusy] = useState109(null);
41700
+ const [preview, setPreview] = useState109(null);
41701
+ const [scheduling, setScheduling] = useState109(false);
41702
+ const [changing, setChanging] = useState109(null);
41680
41703
  const host = useRecordsUi();
41681
41704
  const load = useCallback53(async () => {
41682
41705
  const answered = await client.subscriptions({ table_id: tableId });
@@ -41879,7 +41902,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
41879
41902
  // src/FormBuilder.tsx
41880
41903
  import { copyText as copyText7 } from "@ai-matrx/kit/clipboard";
41881
41904
  import { ErrorBox as ErrorBox7 } from "@ai-matrx/design-system";
41882
- import { useCallback as useCallback55, useEffect as useEffect98, useMemo as useMemo68, useRef as useRef58, useState as useState111 } from "react";
41905
+ import { useCallback as useCallback55, useEffect as useEffect98, useMemo as useMemo68, useRef as useRef58, useState as useState112 } from "react";
41883
41906
  import { DndContext, KeyboardSensor, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
41884
41907
  import { SortableContext, arrayMove, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
41885
41908
  import { CSS as CSS2 } from "@dnd-kit/utilities";
@@ -41896,7 +41919,7 @@ import {
41896
41919
  } from "@ai-matrx/design-system";
41897
41920
 
41898
41921
  // src/FormFlowEditor.tsx
41899
- import { useState as useState109 } from "react";
41922
+ import { useState as useState110 } from "react";
41900
41923
  import {
41901
41924
  BasicInput as BasicInput27,
41902
41925
  BasicTextarea as BasicTextarea10,
@@ -42001,7 +42024,7 @@ function QuestionLogic({
42001
42024
  const choiceFields = field2 && isChoiceField(field2) ? [field2] : [];
42002
42025
  const options = useChoiceOptions(choiceFields, choiceFields.map((f) => f.key));
42003
42026
  const choices = field2 ? (options.get(field2.key) ?? []).map((o) => ({ key: o.key, label: o.label })) : [];
42004
- const [answer, setAnswer] = useState109("");
42027
+ const [answer, setAnswer] = useState110("");
42005
42028
  const setJump = (i, part) => onChange({ jumps: jumps.map((j, k) => k === i ? { ...j, ...part } : j) });
42006
42029
  return /* @__PURE__ */ jsxs121("div", { className: "col-span-2 flex flex-col gap-1.5 text-xs", "data-records-form-logic": question.field, children: [
42007
42030
  jumps.map((jump, i) => /* @__PURE__ */ jsxs121("div", { className: "flex flex-col gap-1 rounded border border-dashed p-1.5", "data-records-form-jump": "", children: [
@@ -42071,7 +42094,7 @@ function parseHiddenFields(line) {
42071
42094
  return out;
42072
42095
  }
42073
42096
  function HiddenFieldsEditor({ value, onChange }) {
42074
- const [line, setLine] = useState109(value.join(", "));
42097
+ const [line, setLine] = useState110(value.join(", "));
42075
42098
  return /* @__PURE__ */ jsxs121("label", { className: "flex flex-col gap-1", "data-records-form-hidden-editor": "", children: [
42076
42099
  /* @__PURE__ */ jsx131(Label21, { className: "text-xs font-medium", children: "Hidden fields" }),
42077
42100
  /* @__PURE__ */ jsx131(
@@ -42122,8 +42145,8 @@ function ThemeEditor({
42122
42145
  var EMBED_LABELS = { inline: "Inline", popup: "Popup", slider: "Slider" };
42123
42146
  function EmbedSnippets({ url, label }) {
42124
42147
  const { copyText: copyText13 } = useClipboard();
42125
- const [kind, setKind] = useState109("inline");
42126
- const [copied, setCopied] = useState109(false);
42148
+ const [kind, setKind] = useState110("inline");
42149
+ const [copied, setCopied] = useState110(false);
42127
42150
  const snippet = formEmbedSnippet(kind, url, { label });
42128
42151
  return /* @__PURE__ */ jsxs121("section", { className: "flex flex-col gap-1.5 rounded border px-2.5 py-2", "aria-label": "Embed", "data-records-form-embed": "", children: [
42129
42152
  /* @__PURE__ */ jsxs121("div", { className: "flex items-center gap-2", children: [
@@ -42148,7 +42171,7 @@ function EmbedSnippets({ url, label }) {
42148
42171
  }
42149
42172
 
42150
42173
  // src/FormRunner.tsx
42151
- import { useCallback as useCallback54, useEffect as useEffect97, useMemo as useMemo67, useRef as useRef57, useState as useState110 } from "react";
42174
+ import { useCallback as useCallback54, useEffect as useEffect97, useMemo as useMemo67, useRef as useRef57, useState as useState111 } from "react";
42152
42175
  import { useFields as useFields24, useOptionalRecordsClient as useOptionalRecordsClient14 } from "@ai-matrx/records/react";
42153
42176
  import { Button as Button85, Label as Label22, Progress, Skeleton as Skeleton27, cn as cn77, formThemeClasses } from "@ai-matrx/design-system";
42154
42177
  import { humanizeIdentifier as humanizeIdentifier18 } from "@ai-matrx/kit/text-case";
@@ -42253,18 +42276,18 @@ function FormStage({
42253
42276
  autoAdvance
42254
42277
  }) {
42255
42278
  const host = useRecordsUi();
42256
- const [answers, setAnswers] = useState110(() => ({ ...initialAnswers ?? {} }));
42257
- const [at, setAt] = useState110(0);
42258
- const [error, setError] = useState110(null);
42259
- const [refusal4, setRefusal] = useState110(null);
42260
- const [writing, setWriting] = useState110(false);
42261
- const [done, setDone] = useState110(null);
42262
- const [hidden, setHidden] = useState110({});
42263
- const [ending, setEnding] = useState110(null);
42264
- const [started, setStarted] = useState110(() => !form.welcome || resumed);
42279
+ const [answers, setAnswers] = useState111(() => ({ ...initialAnswers ?? {} }));
42280
+ const [at, setAt] = useState111(0);
42281
+ const [error, setError] = useState111(null);
42282
+ const [refusal4, setRefusal] = useState111(null);
42283
+ const [writing, setWriting] = useState111(false);
42284
+ const [done, setDone] = useState111(null);
42285
+ const [hidden, setHidden] = useState111({});
42286
+ const [ending, setEnding] = useState111(null);
42287
+ const [started, setStarted] = useState111(() => !form.welcome || resumed);
42265
42288
  const routes = formRoutes(form);
42266
- const [routeKnown, setRouteKnown] = useState110(() => !routes || !whichAsked);
42267
- const [stopped, setStopped] = useState110(null);
42289
+ const [routeKnown, setRouteKnown] = useState111(() => !routes || !whichAsked);
42290
+ const [stopped, setStopped] = useState111(null);
42268
42291
  const answersRef = useRef57(answers);
42269
42292
  answersRef.current = answers;
42270
42293
  const choose = autoAdvance ?? form.autoAdvance ?? true;
@@ -42453,7 +42476,7 @@ function FormStage({
42453
42476
  else void submit();
42454
42477
  }
42455
42478
  const routing = useRef57(false);
42456
- const [routingNow, setRoutingNow] = useState110(false);
42479
+ const [routingNow, setRoutingNow] = useState111(false);
42457
42480
  const typedAhead = useRef57("");
42458
42481
  useEffect97(() => {
42459
42482
  if (!routingNow) return;
@@ -42760,7 +42783,7 @@ function Question({
42760
42783
  upload
42761
42784
  }) {
42762
42785
  const host = useRecordsUi();
42763
- const [uploadError, setUploadError] = useState110(null);
42786
+ const [uploadError, setUploadError] = useState111(null);
42764
42787
  const field2 = question.field;
42765
42788
  if (!field2) return null;
42766
42789
  const id = `form-${field2.key}`;
@@ -42887,24 +42910,24 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42887
42910
  const table = useTable26(tableId);
42888
42911
  const rights = useTableRights(table.data);
42889
42912
  const fields = useFields25(tableId);
42890
- const [forms, setForms] = useState111(null);
42891
- const [error, setError] = useState111(null);
42892
- const [refused, setRefused] = useState111(null);
42893
- const [activeId, setActiveId] = useState111(activeFormId ?? null);
42894
- const [draft, setDraft] = useState111(null);
42895
- const [saving, setSaving] = useState111(false);
42896
- const [saved, setSaved] = useState111(null);
42897
- const [publishing, setPublishing] = useState111(false);
42898
- const [copied, setCopied] = useState111(false);
42899
- const [shownUrl, setShownUrl] = useState111(null);
42900
- const [lookOptions, setLookOptions] = useState111(null);
42901
- const [lookUnread, setLookUnread] = useState111(null);
42902
- const [orgKnobs, setOrgKnobs] = useState111(null);
42903
- const [restoredAt, setRestoredAt] = useState111(null);
42904
- const [showResults, setShowResults] = useState111(false);
42905
- const [adding, setAdding] = useState111(false);
42913
+ const [forms, setForms] = useState112(null);
42914
+ const [error, setError] = useState112(null);
42915
+ const [refused, setRefused] = useState112(null);
42916
+ const [activeId, setActiveId] = useState112(activeFormId ?? null);
42917
+ const [draft, setDraft] = useState112(null);
42918
+ const [saving, setSaving] = useState112(false);
42919
+ const [saved, setSaved] = useState112(null);
42920
+ const [publishing, setPublishing] = useState112(false);
42921
+ const [copied, setCopied] = useState112(false);
42922
+ const [shownUrl, setShownUrl] = useState112(null);
42923
+ const [lookOptions, setLookOptions] = useState112(null);
42924
+ const [lookUnread, setLookUnread] = useState112(null);
42925
+ const [orgKnobs, setOrgKnobs] = useState112(null);
42926
+ const [restoredAt, setRestoredAt] = useState112(null);
42927
+ const [showResults, setShowResults] = useState112(false);
42928
+ const [adding, setAdding] = useState112(false);
42906
42929
  const keysBeforeAdd = useRef58(null);
42907
- const [makeOnMount, setMakeOnMount] = useState111("waiting");
42930
+ const [makeOnMount, setMakeOnMount] = useState112("waiting");
42908
42931
  const publicOrigin = host.publicOrigin ?? (typeof window === "undefined" ? "" : window.location.origin);
42909
42932
  const load = useCallback55(async () => {
42910
42933
  const answered = await client.forms({ table_id: tableId });
@@ -43105,7 +43128,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
43105
43128
  await load();
43106
43129
  return true;
43107
43130
  }
43108
- const [started, setStarted] = useState111(false);
43131
+ const [started, setStarted] = useState112(false);
43109
43132
  useEffect98(() => {
43110
43133
  if (!startWithOne || started || forms === null || forms.length > 0) return;
43111
43134
  if (askableFields(fields.data ?? []).length === 0) return;
@@ -43605,7 +43628,7 @@ function QuestionRow({
43605
43628
  onRemove
43606
43629
  }) {
43607
43630
  const sortable = useSortable({ id: question.field });
43608
- const [open, setOpen] = useState111(true);
43631
+ const [open, setOpen] = useState112(true);
43609
43632
  const name = field2 ? fieldName(field2) : question.field;
43610
43633
  return /* @__PURE__ */ jsxs123(
43611
43634
  "div",
@@ -43699,11 +43722,11 @@ function NotifyOnAnswer({
43699
43722
  onNotify
43700
43723
  }) {
43701
43724
  const client = useRecordsClient80();
43702
- const [subs, setSubs] = useState111(null);
43703
- const [busy, setBusy] = useState111(false);
43704
- const [error, setError] = useState111(null);
43705
- const [said2, setSaid] = useState111(null);
43706
- const [url, setUrl] = useState111(notify?.webhookUrl ?? "");
43725
+ const [subs, setSubs] = useState112(null);
43726
+ const [busy, setBusy] = useState112(false);
43727
+ const [error, setError] = useState112(null);
43728
+ const [said2, setSaid] = useState112(null);
43729
+ const [url, setUrl] = useState112(notify?.webhookUrl ?? "");
43707
43730
  useEffect98(() => setUrl(notify?.webhookUrl ?? ""), [notify?.webhookUrl]);
43708
43731
  useEffect98(() => {
43709
43732
  let cancelled = false;
@@ -43836,7 +43859,7 @@ function NotifyOnAnswer({
43836
43859
  }
43837
43860
 
43838
43861
  // src/DocTemplate.tsx
43839
- import { useCallback as useCallback56, useEffect as useEffect99, useState as useState112 } from "react";
43862
+ import { useCallback as useCallback56, useEffect as useEffect99, useState as useState113 } from "react";
43840
43863
  import { useFields as useFields26, useRecordsClient as useRecordsClient81, useTable as useTable27 } from "@ai-matrx/records/react";
43841
43864
  import { BasicInput as BasicInput29, BasicTextarea as BasicTextarea12, Button as Button87, Label as Label24, Skeleton as Skeleton29, cn as cn79 } from "@ai-matrx/design-system";
43842
43865
  import { jsx as jsx134, jsxs as jsxs124 } from "react/jsx-runtime";
@@ -43846,13 +43869,13 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
43846
43869
  const table = useTable27(tableId);
43847
43870
  const rights = useTableRights(table.data);
43848
43871
  const fields = useFields26(tableId);
43849
- const [templates, setTemplates] = useState112(null);
43850
- const [error, setError] = useState112(null);
43851
- const [activeId, setActiveId] = useState112(activeTemplateId ?? null);
43852
- const [draftName, setDraftName] = useState112("");
43853
- const [draftBody, setDraftBody] = useState112("");
43854
- const [unresolved, setUnresolved] = useState112([]);
43855
- const [saving, setSaving] = useState112(false);
43872
+ const [templates, setTemplates] = useState113(null);
43873
+ const [error, setError] = useState113(null);
43874
+ const [activeId, setActiveId] = useState113(activeTemplateId ?? null);
43875
+ const [draftName, setDraftName] = useState113("");
43876
+ const [draftBody, setDraftBody] = useState113("");
43877
+ const [unresolved, setUnresolved] = useState113([]);
43878
+ const [saving, setSaving] = useState113(false);
43856
43879
  const load = useCallback56(async () => {
43857
43880
  const held = await client.docTemplates({ table_id: tableId });
43858
43881
  if (!held.ok) {
@@ -44020,17 +44043,17 @@ function DocTemplate({ tableId, seed, activeTemplateId, onActiveTemplate, classN
44020
44043
  }
44021
44044
 
44022
44045
  // src/DocRender.tsx
44023
- import { useCallback as useCallback57, useEffect as useEffect100, useRef as useRef59, useState as useState113 } from "react";
44046
+ import { useCallback as useCallback57, useEffect as useEffect100, useRef as useRef59, useState as useState114 } from "react";
44024
44047
  import { useRecordsClient as useRecordsClient82 } from "@ai-matrx/records/react";
44025
44048
  import { Button as Button88, Skeleton as Skeleton30, cn as cn80 } from "@ai-matrx/design-system";
44026
44049
  import { jsx as jsx135, jsxs as jsxs125 } from "react/jsx-runtime";
44027
44050
  function DocRender({ templateId, recordId, filename, onRendered, className }) {
44028
44051
  const client = useRecordsClient82();
44029
- const [preview, setPreview] = useState113(null);
44030
- const [renders, setRenders] = useState113(null);
44031
- const [showing, setShowing] = useState113(null);
44032
- const [error, setError] = useState113(null);
44033
- const [busy, setBusy] = useState113(null);
44052
+ const [preview, setPreview] = useState114(null);
44053
+ const [renders, setRenders] = useState114(null);
44054
+ const [showing, setShowing] = useState114(null);
44055
+ const [error, setError] = useState114(null);
44056
+ const [busy, setBusy] = useState114(null);
44034
44057
  const paper = useRef59(null);
44035
44058
  const load = useCallback57(async () => {
44036
44059
  const [body, held] = await Promise.all([
@@ -44136,7 +44159,7 @@ function DocRender({ templateId, recordId, filename, onRendered, className }) {
44136
44159
  }
44137
44160
 
44138
44161
  // src/SignBlock.tsx
44139
- import { useCallback as useCallback58, useEffect as useEffect101, useState as useState114 } from "react";
44162
+ import { useCallback as useCallback58, useEffect as useEffect101, useState as useState115 } from "react";
44140
44163
  import { useFields as useFields27, useRecordsClient as useRecordsClient83 } from "@ai-matrx/records/react";
44141
44164
  import { BasicInput as BasicInput30, Button as Button89, Skeleton as Skeleton31, cn as cn81 } from "@ai-matrx/design-system";
44142
44165
  import { useTable as useTable28 } from "@ai-matrx/records/react";
@@ -44146,11 +44169,11 @@ function SignBlock({ tableId, recordId, render, className }) {
44146
44169
  const table = useTable28(tableId);
44147
44170
  const rights = useTableRights(table.data);
44148
44171
  const fields = useFields27(tableId);
44149
- const [signatures, setSignatures] = useState114(null);
44150
- const [verdicts, setVerdicts] = useState114({});
44151
- const [error, setError] = useState114(null);
44152
- const [name, setName] = useState114("");
44153
- const [busy, setBusy] = useState114(false);
44172
+ const [signatures, setSignatures] = useState115(null);
44173
+ const [verdicts, setVerdicts] = useState115({});
44174
+ const [error, setError] = useState115(null);
44175
+ const [name, setName] = useState115("");
44176
+ const [busy, setBusy] = useState115(false);
44154
44177
  const load = useCallback58(async () => {
44155
44178
  const held = await client.docSignatures({ record_id: recordId });
44156
44179
  if (!held.ok) {
@@ -44287,7 +44310,7 @@ function SignBlock({ tableId, recordId, render, className }) {
44287
44310
  }
44288
44311
 
44289
44312
  // src/NotifyRuleEditor.tsx
44290
- import { useCallback as useCallback59, useEffect as useEffect102, useState as useState115 } from "react";
44313
+ import { useCallback as useCallback59, useEffect as useEffect102, useState as useState116 } from "react";
44291
44314
  import { useRecordsClient as useRecordsClient84, useTable as useTable29 } from "@ai-matrx/records/react";
44292
44315
  import { hasQuietHours as hasQuietHours3 } from "@ai-matrx/records";
44293
44316
  import { Button as Button90, Skeleton as Skeleton32, cn as cn82 } from "@ai-matrx/design-system";
@@ -44299,12 +44322,12 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
44299
44322
  const host = useRecordsUi();
44300
44323
  const table = useTable29(tableId);
44301
44324
  const rights = useTableRights(table.data);
44302
- const [subscriptions, setSubscriptions] = useState115(null);
44303
- const [cadences, setCadences] = useState115([]);
44304
- const [views, setViews] = useState115(null);
44305
- const [error, setError] = useState115(null);
44306
- const [busy, setBusy] = useState115(false);
44307
- const [stopping, setStopping] = useState115(null);
44325
+ const [subscriptions, setSubscriptions] = useState116(null);
44326
+ const [cadences, setCadences] = useState116([]);
44327
+ const [views, setViews] = useState116(null);
44328
+ const [error, setError] = useState116(null);
44329
+ const [busy, setBusy] = useState116(false);
44330
+ const [stopping, setStopping] = useState116(null);
44308
44331
  const load = useCallback59(async () => {
44309
44332
  const [held, offered] = await Promise.all([
44310
44333
  // THE PERSON'S OWN DOOR, not the notifier's. It answers what is addressed
@@ -44542,7 +44565,7 @@ function NotifyRuleEditor({ tableId, seed, chosenRuleId, onChoose, className })
44542
44565
  }
44543
44566
 
44544
44567
  // src/DashboardCanvas.tsx
44545
- import { useCallback as useCallback60, useEffect as useEffect104, useMemo as useMemo71, useState as useState118 } from "react";
44568
+ import { useCallback as useCallback60, useEffect as useEffect104, useMemo as useMemo71, useState as useState119 } from "react";
44546
44569
  import { useFields as useFields30, useRecordsClient as useRecordsClient86, useTable as useTable31 } from "@ai-matrx/records/react";
44547
44570
  import {
44548
44571
  BasicInput as BasicInput31,
@@ -44710,7 +44733,7 @@ function GridCell2({
44710
44733
  }
44711
44734
 
44712
44735
  // src/AddChart.tsx
44713
- import { useMemo as useMemo70, useState as useState117 } from "react";
44736
+ import { useMemo as useMemo70, useState as useState118 } from "react";
44714
44737
  import { useFields as useFields29, useRecordsClient as useRecordsClient85 } from "@ai-matrx/records/react";
44715
44738
  import {
44716
44739
  Button as Button92,
@@ -44722,7 +44745,7 @@ import {
44722
44745
  } from "@ai-matrx/design-system";
44723
44746
 
44724
44747
  // src/TablePickers.tsx
44725
- import { useEffect as useEffect103, useMemo as useMemo69, useState as useState116 } from "react";
44748
+ import { useEffect as useEffect103, useMemo as useMemo69, useState as useState117 } from "react";
44726
44749
  import { RecordsProvider as RecordsProvider2, useFields as useFields28, useRecords as useRecords7, useTable as useTable30 } from "@ai-matrx/records/react";
44727
44750
  import { Button as Button91, CreatablePicker as CreatablePicker2 } from "@ai-matrx/design-system";
44728
44751
 
@@ -44842,7 +44865,7 @@ function readTablesAnywhere(dataSource) {
44842
44865
  return read;
44843
44866
  }
44844
44867
  function useTablesAnywhere(dataSource) {
44845
- const [state, setState] = useState116({ loading: true, error: null, rows: [] });
44868
+ const [state, setState] = useState117({ loading: true, error: null, rows: [] });
44846
44869
  useEffect103(() => {
44847
44870
  let live = true;
44848
44871
  void readTablesAnywhere(dataSource).then((result) => {
@@ -44920,7 +44943,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
44920
44943
  const all = useMemo69(() => fields.data ?? [], [fields.data]);
44921
44944
  const byKey = useMemo69(() => new Map(all.map((f) => [f.key, f])), [all]);
44922
44945
  const keys = Object.keys(value);
44923
- const [adding, setAdding] = useState116(false);
44946
+ const [adding, setAdding] = useState117(false);
44924
44947
  const optionsFor = (current) => all.filter((f) => f.key === current || !(f.key in value)).map((f) => ({ value: f.key, label: fieldName(f) }));
44925
44948
  const rename = (from, to) => {
44926
44949
  if (from === to) return;
@@ -45076,7 +45099,7 @@ function chartSpecFrom(args) {
45076
45099
  }
45077
45100
  function AddChart({ subject, onAdd, onClose }) {
45078
45101
  const client = useRecordsClient85();
45079
- const [tableId, setTableId] = useState117(subject);
45102
+ const [tableId, setTableId] = useState118(subject);
45080
45103
  const fields = useFields29(tableId);
45081
45104
  const all = useMemo70(() => onePerKey(fields.data ?? []), [fields.data]);
45082
45105
  const labels = useRecordLabels(all);
@@ -45084,11 +45107,11 @@ function AddChart({ subject, onAdd, onClose }) {
45084
45107
  const field2 = all.find((f) => f.key === key);
45085
45108
  return field2 ? scalarText(field2, value, labels) : String(value);
45086
45109
  };
45087
- const [measureKey5, setMeasureKey] = useState117("count");
45088
- const [splitKey, setSplitKey] = useState117("none");
45089
- const [kind, setKind] = useState117("auto");
45090
- const [filter, setFilter] = useState117({});
45091
- const [saving, setSaving] = useState117(false);
45110
+ const [measureKey5, setMeasureKey] = useState118("count");
45111
+ const [splitKey, setSplitKey] = useState118("none");
45112
+ const [kind, setKind] = useState118("auto");
45113
+ const [filter, setFilter] = useState118({});
45114
+ const [saving, setSaving] = useState118(false);
45092
45115
  const numbers = numberColumns(all);
45093
45116
  const choices = offerableFields(all, "choice");
45094
45117
  const dates = offerableFields(all, "date");
@@ -45235,20 +45258,20 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
45235
45258
  const table = useTable31(tableId);
45236
45259
  const rights = useTableRights(table.data);
45237
45260
  const fields = useFields30(tableId);
45238
- const [boards, setBoards] = useState118(null);
45239
- const [pages, setPages] = useState118([]);
45240
- const [error, setError] = useState118(null);
45241
- const [activeId, setActiveId] = useState118(activeDashboardId ?? null);
45242
- const [madeOnMount, setMadeOnMount] = useState118("waiting");
45243
- const [askingToRemove, setAskingToRemove] = useState118(null);
45244
- const [run, setRun] = useState118(null);
45245
- const [running, setRunning] = useState118(false);
45246
- const [question, setQuestion] = useState118("");
45247
- const [asking, setAsking] = useState118(false);
45248
- const [scheduling, setScheduling] = useState118(false);
45249
- const [arranging, setArranging] = useState118(false);
45250
- const [adding, setAdding] = useState118(false);
45251
- const [grain, setGrain] = useState118(null);
45261
+ const [boards, setBoards] = useState119(null);
45262
+ const [pages, setPages] = useState119([]);
45263
+ const [error, setError] = useState119(null);
45264
+ const [activeId, setActiveId] = useState119(activeDashboardId ?? null);
45265
+ const [madeOnMount, setMadeOnMount] = useState119("waiting");
45266
+ const [askingToRemove, setAskingToRemove] = useState119(null);
45267
+ const [run, setRun] = useState119(null);
45268
+ const [running, setRunning] = useState119(false);
45269
+ const [question, setQuestion] = useState119("");
45270
+ const [asking, setAsking] = useState119(false);
45271
+ const [scheduling, setScheduling] = useState119(false);
45272
+ const [arranging, setArranging] = useState119(false);
45273
+ const [adding, setAdding] = useState119(false);
45274
+ const [grain, setGrain] = useState119(null);
45252
45275
  const runArgs = (dashboard_id) => ({
45253
45276
  dashboard_id,
45254
45277
  ...filter ? { filter } : {},
@@ -45266,7 +45289,7 @@ function DashboardCanvas({ tableId, activeDashboardId, filter, createOnMount, on
45266
45289
  setBoards(read);
45267
45290
  return read;
45268
45291
  }, [client, tableId]);
45269
- const [notKept, setNotKept] = useState118(null);
45292
+ const [notKept, setNotKept] = useState119(null);
45270
45293
  useEffect104(() => {
45271
45294
  void load();
45272
45295
  }, [load]);
@@ -45793,9 +45816,9 @@ function TargetControl({
45793
45816
  onChange
45794
45817
  }) {
45795
45818
  const saved = !block.target ? "none" : "field" in block.target && block.target.field ? "field" : "value";
45796
- const [mode, setMode] = useState118(saved);
45819
+ const [mode, setMode] = useState119(saved);
45797
45820
  const savedValue = block.target && "value" in block.target && typeof block.target.value === "number" ? block.target.value : null;
45798
- const [draft, setDraft] = useState118(savedValue === null ? "" : String(savedValue));
45821
+ const [draft, setDraft] = useState119(savedValue === null ? "" : String(savedValue));
45799
45822
  useEffect104(() => {
45800
45823
  setMode(saved);
45801
45824
  setDraft(savedValue === null ? "" : String(savedValue));
@@ -45864,7 +45887,7 @@ function TargetControl({
45864
45887
 
45865
45888
  // src/QuestionPanel.tsx
45866
45889
  import { copyText as copyText8 } from "@ai-matrx/kit/clipboard";
45867
- import { useEffect as useEffect105, useMemo as useMemo72, useRef as useRef61, useState as useState119 } from "react";
45890
+ import { useEffect as useEffect105, useMemo as useMemo72, useRef as useRef61, useState as useState120 } from "react";
45868
45891
  import { Badge as Badge23, BasicInput as BasicInput32, Button as Button94, Checkbox as Checkbox16, Label as Label25, Skeleton as Skeleton34, cn as cn85 } from "@ai-matrx/design-system";
45869
45892
  import { useFields as useFields31, useRecordsClient as useRecordsClient87 } from "@ai-matrx/records/react";
45870
45893
 
@@ -46281,8 +46304,8 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46281
46304
  const fields = useFields31(tableId);
46282
46305
  const all = useMemo72(() => fields.data ?? [], [fields.data]);
46283
46306
  const me = client.config.actor?.user_id ?? null;
46284
- const [hidden, setHidden] = useState119(null);
46285
- const [related, setRelated] = useState119({});
46307
+ const [hidden, setHidden] = useState120(null);
46308
+ const [related, setRelated] = useState120({});
46286
46309
  useEffect105(() => {
46287
46310
  if (all.length === 0) {
46288
46311
  if (!fields.loading) setHidden(/* @__PURE__ */ new Set());
@@ -46307,15 +46330,15 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46307
46330
  };
46308
46331
  }, [client, tableId, all, fields.loading]);
46309
46332
  const offered = useMemo72(() => hidden ? all.filter((f) => !hidden.has(f.key)) : [], [all, hidden]);
46310
- const [saved, setSaved] = useState119(null);
46311
- const [savedEpoch, setSavedEpoch] = useState119(0);
46312
- const [current, setCurrent] = useState119(null);
46313
- const [spec, setSpec] = useState119(newQuestion);
46314
- const [name, setName] = useState119("");
46315
- const [shared, setShared] = useState119(true);
46316
- const [saveError, setSaveError] = useState119(null);
46317
- const [saving, setSaving] = useState119(false);
46318
- const [linkMissed, setLinkMissed] = useState119(false);
46333
+ const [saved, setSaved] = useState120(null);
46334
+ const [savedEpoch, setSavedEpoch] = useState120(0);
46335
+ const [current, setCurrent] = useState120(null);
46336
+ const [spec, setSpec] = useState120(newQuestion);
46337
+ const [name, setName] = useState120("");
46338
+ const [shared, setShared] = useState120(true);
46339
+ const [saveError, setSaveError] = useState120(null);
46340
+ const [saving, setSaving] = useState120(false);
46341
+ const [linkMissed, setLinkMissed] = useState120(false);
46319
46342
  const openedFromLink = useRef61(false);
46320
46343
  useEffect105(() => {
46321
46344
  let live = true;
@@ -46346,8 +46369,8 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46346
46369
  setSpec(draft);
46347
46370
  }, [draft]);
46348
46371
  const mine = !current || me !== null && current.createdBy === me;
46349
- const [answer, setAnswer] = useState119(null);
46350
- const [asking, setAsking] = useState119(false);
46372
+ const [answer, setAnswer] = useState120(null);
46373
+ const [asking, setAsking] = useState120(false);
46351
46374
  const specKey = JSON.stringify(spec);
46352
46375
  useEffect105(() => {
46353
46376
  if (all.length === 0) return;
@@ -46791,7 +46814,7 @@ function QuestionAnswerView({ tableId, spec, answer, fields, related = NO_RELATE
46791
46814
  }
46792
46815
 
46793
46816
  // src/TableAsk.tsx
46794
- import { useState as useState120 } from "react";
46817
+ import { useState as useState121 } from "react";
46795
46818
  import { BasicInput as BasicInput33, Button as Button95, Popover as Popover12, PopoverContent as PopoverContent12, PopoverTrigger as PopoverTrigger12, Skeleton as Skeleton35 } from "@ai-matrx/design-system";
46796
46819
  import { optionLabel as optionLabel4 } from "@ai-matrx/records";
46797
46820
  import { useFields as useFields32, useRecordsClient as useRecordsClient88 } from "@ai-matrx/records/react";
@@ -47014,9 +47037,9 @@ function TableAsk({ tableId, onOpenInQuestions }) {
47014
47037
  const client = useRecordsClient88();
47015
47038
  const fields = useFields32(tableId);
47016
47039
  const all = fields.data ?? [];
47017
- const [open, setOpen] = useState120(false);
47018
- const [words2, setWords] = useState120("");
47019
- const [said2, setSaid] = useState120({ kind: "idle" });
47040
+ const [open, setOpen] = useState121(false);
47041
+ const [words2, setWords] = useState121("");
47042
+ const [said2, setSaid] = useState121({ kind: "idle" });
47020
47043
  const ask = async () => {
47021
47044
  if (words2.trim() === "" || all.length === 0) return;
47022
47045
  const choices = {};
@@ -47089,7 +47112,7 @@ function TableAsk({ tableId, onOpenInQuestions }) {
47089
47112
  }
47090
47113
 
47091
47114
  // src/PageScreen.tsx
47092
- import { useCallback as useCallback61, useEffect as useEffect106, useMemo as useMemo73, useState as useState121 } from "react";
47115
+ import { useCallback as useCallback61, useEffect as useEffect106, useMemo as useMemo73, useState as useState122 } from "react";
47093
47116
  import {
47094
47117
  useFields as useFields33,
47095
47118
  useRecordPage as useRecordPage3,
@@ -47114,18 +47137,18 @@ function PageScreen({
47114
47137
  const client = useRecordsClient89();
47115
47138
  const host = useRecordsUi();
47116
47139
  const organizationId = client.config.organizationId;
47117
- const [page, setPage] = useState121(null);
47118
- const [missing, setMissing] = useState121(false);
47119
- const [error, setError] = useState121(null);
47120
- const [level, setLevel] = useState121(null);
47121
- const [editing, setEditing] = useState121(startEditing);
47122
- const [run, setRun] = useState121(null);
47123
- const [saveError, setSaveError] = useState121(null);
47124
- const [askingToArchive, setAskingToArchive] = useState121(false);
47125
- const [selected, setSelected] = useState121({});
47126
- const [filterValues, setFilterValues] = useState121({});
47127
- const [mine, setMine] = useState121({});
47128
- const [making, setMaking] = useState121("waiting");
47140
+ const [page, setPage] = useState122(null);
47141
+ const [missing, setMissing] = useState122(false);
47142
+ const [error, setError] = useState122(null);
47143
+ const [level, setLevel] = useState122(null);
47144
+ const [editing, setEditing] = useState122(startEditing);
47145
+ const [run, setRun] = useState122(null);
47146
+ const [saveError, setSaveError] = useState122(null);
47147
+ const [askingToArchive, setAskingToArchive] = useState122(false);
47148
+ const [selected, setSelected] = useState122({});
47149
+ const [filterValues, setFilterValues] = useState122({});
47150
+ const [mine, setMine] = useState122({});
47151
+ const [making, setMaking] = useState122("waiting");
47129
47152
  const id = page?.id ?? pageId ?? null;
47130
47153
  const load = useCallback61(
47131
47154
  async (want) => {
@@ -47427,7 +47450,7 @@ function AppletBlockView({ block }) {
47427
47450
  }
47428
47451
  function AppletPick({ value, onChange }) {
47429
47452
  const host = useRecordsUi();
47430
- const [options, setOptions] = useState121(null);
47453
+ const [options, setOptions] = useState122(null);
47431
47454
  useEffect106(() => {
47432
47455
  let live = true;
47433
47456
  host.applets?.list().then((apps) => live && setOptions(apps.map((a) => ({ value: a.id, label: a.name })))).catch(() => live && setOptions([]));
@@ -47464,7 +47487,7 @@ function ListBlockView({
47464
47487
  const table = useTable32(block.table_id);
47465
47488
  const fields = useFields33(block.table_id);
47466
47489
  const all = useMemo73(() => onePerKey3(fields.data ?? []), [fields.data]);
47467
- const [view, setView] = useState121(block.view_id ? "reading" : null);
47490
+ const [view, setView] = useState122(block.view_id ? "reading" : null);
47468
47491
  useEffect106(() => {
47469
47492
  if (!block.view_id) {
47470
47493
  setView(null);
@@ -47482,7 +47505,7 @@ function ListBlockView({
47482
47505
  };
47483
47506
  }, [client, block.table_id, block.view_id]);
47484
47507
  const meField = block.me_field ? all.find((f) => f.key === block.me_field) : void 0;
47485
- const [me, setMe] = useState121(null);
47508
+ const [me, setMe] = useState122(null);
47486
47509
  useEffect106(() => {
47487
47510
  if (!mine || !meField?.relation_target || !viewerUserId) {
47488
47511
  setMe(null);
@@ -47581,10 +47604,10 @@ function ActionButton2({ block, recordId }) {
47581
47604
  const client = useRecordsClient89();
47582
47605
  const actionsRead = useRowActions2(block.action_id ? block.table_id : null);
47583
47606
  const action3 = !block.action_id ? null : actionsRead.data ? actionsRead.data.actions.find((a) => a.id === block.action_id) ?? null : actionsRead.loading ? "reading" : null;
47584
- const [asking, setAsking] = useState121(false);
47585
- const [running, setRunning] = useState121(false);
47586
- const [done, setDone] = useState121(null);
47587
- const [error, setError] = useState121(null);
47607
+ const [asking, setAsking] = useState122(false);
47608
+ const [running, setRunning] = useState122(false);
47609
+ const [done, setDone] = useState122(null);
47610
+ const [error, setError] = useState122(null);
47588
47611
  useEffect106(() => {
47589
47612
  setDone(null);
47590
47613
  setError(null);
@@ -47624,8 +47647,8 @@ function ActionButton2({ block, recordId }) {
47624
47647
  }
47625
47648
  function FormBlockView({ block }) {
47626
47649
  const client = useRecordsClient89();
47627
- const [form, setForm] = useState121("reading");
47628
- const [sent, setSent] = useState121(0);
47650
+ const [form, setForm] = useState122("reading");
47651
+ const [sent, setSent] = useState122(0);
47629
47652
  useEffect106(() => {
47630
47653
  if (!block.form_id) {
47631
47654
  setForm(null);
@@ -47751,7 +47774,7 @@ function FieldPick({
47751
47774
  }
47752
47775
  function ListSettings({ block, onChange }) {
47753
47776
  const client = useRecordsClient89();
47754
- const [views, setViews] = useState121([]);
47777
+ const [views, setViews] = useState122([]);
47755
47778
  const fields = useFields33(block.table_id);
47756
47779
  const all = onePerKey3(fields.data ?? []);
47757
47780
  useEffect106(() => {
@@ -47830,7 +47853,7 @@ function ActionPicker({ tableId, value, onChange }) {
47830
47853
  }
47831
47854
  function FormPicker({ tableId, value, onChange }) {
47832
47855
  const client = useRecordsClient89();
47833
- const [forms, setForms] = useState121([]);
47856
+ const [forms, setForms] = useState122([]);
47834
47857
  useEffect106(() => {
47835
47858
  let live = true;
47836
47859
  void client.forms({ table_id: tableId }).then((answered) => {
@@ -47877,7 +47900,7 @@ function onePerKey3(all) {
47877
47900
 
47878
47901
  // src/FormsPanel.tsx
47879
47902
  import { copyText as copyText9 } from "@ai-matrx/kit/clipboard";
47880
- import { useCallback as useCallback62, useEffect as useEffect107, useState as useState122 } from "react";
47903
+ import { useCallback as useCallback62, useEffect as useEffect107, useState as useState123 } from "react";
47881
47904
  import { useRecordsClient as useRecordsClient90, useTable as useTable33 } from "@ai-matrx/records/react";
47882
47905
  import { publicFormPath as publicFormPath2 } from "@ai-matrx/records";
47883
47906
  import { Badge as Badge24, Button as Button97, Skeleton as Skeleton37, cn as cn87 } from "@ai-matrx/design-system";
@@ -47894,12 +47917,12 @@ function FormsPanel({ tableId, activeFormId, className }) {
47894
47917
  const host = useRecordsUi();
47895
47918
  const table = useTable33(tableId);
47896
47919
  const rights = useTableRights(table.data);
47897
- const [forms, setForms] = useState122(null);
47898
- const [error, setError] = useState122(null);
47899
- const [busy, setBusy] = useState122(null);
47900
- const [copied, setCopied] = useState122(null);
47901
- const [building, setBuilding] = useState122(false);
47902
- const [archivedSaid, setArchivedSaid] = useState122(null);
47920
+ const [forms, setForms] = useState123(null);
47921
+ const [error, setError] = useState123(null);
47922
+ const [busy, setBusy] = useState123(null);
47923
+ const [copied, setCopied] = useState123(null);
47924
+ const [building, setBuilding] = useState123(false);
47925
+ const [archivedSaid, setArchivedSaid] = useState123(null);
47903
47926
  const linked = activeFormId && forms !== null ? forms.find((f) => f.form_id === activeFormId) ?? null : null;
47904
47927
  const linkedMissing = Boolean(activeFormId) && forms !== null && linked === null;
47905
47928
  useEffect107(() => {
@@ -47932,7 +47955,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
47932
47955
  },
47933
47956
  [client, load]
47934
47957
  );
47935
- const [shown4, setShown] = useState122(null);
47958
+ const [shown4, setShown] = useState123(null);
47936
47959
  const copy = useCallback62(async (url, formId) => {
47937
47960
  if (await copyText9(url)) {
47938
47961
  setCopied(formId);
@@ -48060,12 +48083,12 @@ function FormsPanel({ tableId, activeFormId, className }) {
48060
48083
  }
48061
48084
 
48062
48085
  // src/CaptureSheet.tsx
48063
- import { useCallback as useCallback64, useEffect as useEffect109, useRef as useRef63, useState as useState124 } from "react";
48086
+ import { useCallback as useCallback64, useEffect as useEffect109, useRef as useRef63, useState as useState125 } from "react";
48064
48087
  import { useFields as useFields34, useRecordsClient as useRecordsClient92, useTable as useTable34 } from "@ai-matrx/records/react";
48065
48088
  import { Button as Button99, Input as Input8, Skeleton as Skeleton39, Textarea as Textarea7, cn as cn89 } from "@ai-matrx/design-system";
48066
48089
 
48067
48090
  // src/CaptureRun.tsx
48068
- import { useCallback as useCallback63, useEffect as useEffect108, useMemo as useMemo74, useRef as useRef62, useState as useState123 } from "react";
48091
+ import { useCallback as useCallback63, useEffect as useEffect108, useMemo as useMemo74, useRef as useRef62, useState as useState124 } from "react";
48069
48092
  import {
48070
48093
  coerceTypedAnswer as coerceTypedAnswer3,
48071
48094
  coercionLabel,
@@ -48112,17 +48135,17 @@ function whereWeAre(timeoutMs = 4e3) {
48112
48135
  function CaptureRun({ sheetId, face: given, className }) {
48113
48136
  const client = useRecordsClient91();
48114
48137
  const host = useRecordsUi();
48115
- const [face, setFace] = useState123(given);
48116
- const [loadFailed, setLoadFailed] = useState123(null);
48117
- const [at, setAt] = useState123(0);
48118
- const [answers, setAnswers] = useState123({});
48119
- const [files, setFiles] = useState123({});
48120
- const [missing, setMissing] = useState123(null);
48121
- const [done, setDone] = useState123(null);
48122
- const [counts, setCounts] = useState123({ waiting: 0, sending: 0, refused: 0, landed: 0 });
48123
- const [items, setItems] = useState123([]);
48124
- const [lastSynced, setLastSynced] = useState123(null);
48125
- const [sending, setSending] = useState123(false);
48138
+ const [face, setFace] = useState124(given);
48139
+ const [loadFailed, setLoadFailed] = useState124(null);
48140
+ const [at, setAt] = useState124(0);
48141
+ const [answers, setAnswers] = useState124({});
48142
+ const [files, setFiles] = useState124({});
48143
+ const [missing, setMissing] = useState124(null);
48144
+ const [done, setDone] = useState124(null);
48145
+ const [counts, setCounts] = useState124({ waiting: 0, sending: 0, refused: 0, landed: 0 });
48146
+ const [items, setItems] = useState124([]);
48147
+ const [lastSynced, setLastSynced] = useState124(null);
48148
+ const [sending, setSending] = useState124(false);
48126
48149
  const queueRef = useRef62(null);
48127
48150
  useEffect108(() => {
48128
48151
  const q2 = openCaptureQueue({
@@ -48494,15 +48517,15 @@ function AdHocCaptureSheet({
48494
48517
  const host = useRecordsUi();
48495
48518
  const table = useTable34(tableId);
48496
48519
  const fields = useFields34(tableId);
48497
- const [mode, setMode] = useState124("reading");
48498
- const [reading, setReading] = useState124("");
48499
- const [note, setNote] = useState124("");
48500
- const [fileId, setFileId] = useState124(null);
48501
- const [pending, setPending] = useState124(null);
48502
- const [saved, setSaved] = useState124([]);
48503
- const [error, setError] = useState124(null);
48504
- const [uploadError, setUploadError] = useState124(null);
48505
- const [flushing, setFlushing] = useState124(false);
48520
+ const [mode, setMode] = useState125("reading");
48521
+ const [reading, setReading] = useState125("");
48522
+ const [note, setNote] = useState125("");
48523
+ const [fileId, setFileId] = useState125(null);
48524
+ const [pending, setPending] = useState125(null);
48525
+ const [saved, setSaved] = useState125([]);
48526
+ const [error, setError] = useState125(null);
48527
+ const [uploadError, setUploadError] = useState125(null);
48528
+ const [flushing, setFlushing] = useState125(false);
48506
48529
  const queue = useRef63([]);
48507
48530
  const keep = useCallback64(
48508
48531
  async (next) => {
@@ -48691,17 +48714,17 @@ function AdHocCaptureSheet({
48691
48714
  }
48692
48715
 
48693
48716
  // src/PortalShell.tsx
48694
- import { useCallback as useCallback65, useEffect as useEffect110, useState as useState125 } from "react";
48717
+ import { useCallback as useCallback65, useEffect as useEffect110, useState as useState126 } from "react";
48695
48718
  import { useRecordsClient as useRecordsClient93 } from "@ai-matrx/records/react";
48696
48719
  import { Button as Button100, Skeleton as Skeleton40, cn as cn90 } from "@ai-matrx/design-system";
48697
48720
  import { jsx as jsx149, jsxs as jsxs138 } from "react/jsx-runtime";
48698
48721
  function PortalShell({ tableId, form, resourceType = "record", className }) {
48699
48722
  const client = useRecordsClient93();
48700
- const [card, setCard] = useState125(null);
48701
- const [reach, setReach] = useState125(null);
48702
- const [error, setError] = useState125(null);
48703
- const [open, setOpen] = useState125(null);
48704
- const [sending, setSending] = useState125(false);
48723
+ const [card, setCard] = useState126(null);
48724
+ const [reach, setReach] = useState126(null);
48725
+ const [error, setError] = useState126(null);
48726
+ const [open, setOpen] = useState126(null);
48727
+ const [sending, setSending] = useState126(false);
48705
48728
  const load = useCallback65(async () => {
48706
48729
  const who = await client.externalPrincipalCard();
48707
48730
  if (!who.ok) {
@@ -48776,7 +48799,7 @@ function PortalShell({ tableId, form, resourceType = "record", className }) {
48776
48799
  }
48777
48800
  function PortalRow({ tableId, recordId }) {
48778
48801
  const client = useRecordsClient93();
48779
- const [title, setTitle] = useState125(null);
48802
+ const [title, setTitle] = useState126(null);
48780
48803
  useEffect110(() => {
48781
48804
  let cancelled = false;
48782
48805
  void client.recordRead({ record_id: recordId }).then((answered) => {
@@ -48797,7 +48820,7 @@ function PortalRow({ tableId, recordId }) {
48797
48820
  }
48798
48821
 
48799
48822
  // src/PublicViewPage.tsx
48800
- import { useCallback as useCallback66, useEffect as useEffect111, useState as useState126 } from "react";
48823
+ import { useCallback as useCallback66, useEffect as useEffect111, useState as useState127 } from "react";
48801
48824
  import { useRecordsClient as useRecordsClient94 } from "@ai-matrx/records/react";
48802
48825
  import { Skeleton as Skeleton41, cn as cn91 } from "@ai-matrx/design-system";
48803
48826
 
@@ -48815,12 +48838,12 @@ function publicReadOf(binding) {
48815
48838
  import { jsx as jsx150, jsxs as jsxs139 } from "react/jsx-runtime";
48816
48839
  function PublicViewPage({ slug, className }) {
48817
48840
  const client = useRecordsClient94();
48818
- const [binding, setBinding] = useState126(null);
48819
- const [rows, setRows] = useState126(null);
48820
- const [fields, setFields] = useState126(null);
48821
- const [error, setError] = useState126(null);
48822
- const [plan, setPlan] = useState126(null);
48823
- const [gap, setGap] = useState126(null);
48841
+ const [binding, setBinding] = useState127(null);
48842
+ const [rows, setRows] = useState127(null);
48843
+ const [fields, setFields] = useState127(null);
48844
+ const [error, setError] = useState127(null);
48845
+ const [plan, setPlan] = useState127(null);
48846
+ const [gap, setGap] = useState127(null);
48824
48847
  const load = useCallback66(async () => {
48825
48848
  const notice = await client.worldPublishGapNotice();
48826
48849
  if (notice.ok) setGap(notice.data);
@@ -48909,7 +48932,7 @@ function PublicRow({ row, fields }) {
48909
48932
 
48910
48933
  // src/EmbedFrame.tsx
48911
48934
  import { copyText as copyText10 } from "@ai-matrx/kit/clipboard";
48912
- import { useCallback as useCallback67, useEffect as useEffect112, useState as useState127 } from "react";
48935
+ import { useCallback as useCallback67, useEffect as useEffect112, useState as useState128 } from "react";
48913
48936
  import { useRecordsClient as useRecordsClient95 } from "@ai-matrx/records/react";
48914
48937
  import { Button as Button101, Input as Input9, Skeleton as Skeleton42, Textarea as Textarea8, cn as cn92 } from "@ai-matrx/design-system";
48915
48938
  import { useTable as useTable35 } from "@ai-matrx/records/react";
@@ -48926,11 +48949,11 @@ function EmbedFrame({
48926
48949
  const host = useRecordsUi();
48927
48950
  const table = useTable35(tableId);
48928
48951
  const rights = useTableRights(table.data);
48929
- const [origins, setOrigins] = useState127("");
48930
- const [secret, setSecret] = useState127(null);
48931
- const [tokenId, setTokenId] = useState127(null);
48932
- const [error, setError] = useState127(null);
48933
- const [busy, setBusy] = useState127(false);
48952
+ const [origins, setOrigins] = useState128("");
48953
+ const [secret, setSecret] = useState128(null);
48954
+ const [tokenId, setTokenId] = useState128(null);
48955
+ const [error, setError] = useState128(null);
48956
+ const [busy, setBusy] = useState128(false);
48934
48957
  const mode = formId ? "write" : "read";
48935
48958
  const parsed = origins.split(/[\s,]+/).map((o) => o.trim()).filter((o) => o.length > 0);
48936
48959
  const issue = useCallback67(async () => {
@@ -49017,9 +49040,9 @@ function EmbedFrame({
49017
49040
  }
49018
49041
  function useEmbedHandshake(args) {
49019
49042
  const client = useRecordsClient95();
49020
- const [binding, setBinding] = useState127(null);
49021
- const [error, setError] = useState127(null);
49022
- const [loading, setLoading] = useState127(true);
49043
+ const [binding, setBinding] = useState128(null);
49044
+ const [error, setError] = useState128(null);
49045
+ const [loading, setLoading] = useState128(true);
49023
49046
  const origin = args.origin ?? (typeof location === "undefined" ? "" : location.origin);
49024
49047
  const { secret, requiredMode } = args;
49025
49048
  useEffect112(() => {
@@ -49045,7 +49068,7 @@ function useEmbedHandshake(args) {
49045
49068
 
49046
49069
  // src/TablePage.tsx
49047
49070
  import { copyText as copyText12 } from "@ai-matrx/kit/clipboard";
49048
- import { useCallback as useCallback69, useEffect as useEffect115, useMemo as useMemo78, useRef as useRef64, useState as useState134 } from "react";
49071
+ import { useCallback as useCallback69, useEffect as useEffect115, useMemo as useMemo78, useRef as useRef64, useState as useState135 } from "react";
49049
49072
  import { archivedByLine as archivedByLine2 } from "@ai-matrx/records";
49050
49073
  import { useFields as useFields37, useRecordsClient as useRecordsClient97, useSeededAnswer, useTable as useTable36 } from "@ai-matrx/records/react";
49051
49074
  import {
@@ -49109,13 +49132,13 @@ async function downloadViewCsv(args) {
49109
49132
  }
49110
49133
 
49111
49134
  // src/RecordPanel.tsx
49112
- import { Fragment as Fragment63, useState as useState128 } from "react";
49135
+ import { Fragment as Fragment63, useState as useState129 } from "react";
49113
49136
  import { Button as Button102, Separator as Separator13 } from "@ai-matrx/design-system";
49114
49137
  import { useFields as useFields35, useRecord as useRecord4 } from "@ai-matrx/records/react";
49115
49138
  import { Fragment as Fragment64, jsx as jsx152, jsxs as jsxs141 } from "react/jsx-runtime";
49116
49139
  function RecordPanel({ tableId, recordId, onClose, onAskAboutField, onPage = false }) {
49117
49140
  const host = useRecordsUi();
49118
- const [asking, setAsking] = useState128(null);
49141
+ const [asking, setAsking] = useState129(null);
49119
49142
  return /* @__PURE__ */ jsxs141("div", { className: "space-y-3", "data-record-panel": recordId, children: [
49120
49143
  /* @__PURE__ */ jsx152(Peek, { tableId, recordId, onPage, ...onClose ? { onClose } : {} }),
49121
49144
  onPage ? /* @__PURE__ */ jsxs141(Fragment64, { children: [
@@ -49193,7 +49216,7 @@ function LinkedLists({ tableId, recordId }) {
49193
49216
  }
49194
49217
  function RecordAsk({ tableId, recordId }) {
49195
49218
  const host = useRecordsUi();
49196
- const [open, setOpen] = useState128(false);
49219
+ const [open, setOpen] = useState129(false);
49197
49220
  if (!host.chat) return null;
49198
49221
  return /* @__PURE__ */ jsxs141("section", { className: "flex min-w-0 flex-col gap-1.5", "data-record-ask": open ? "open" : "", children: [
49199
49222
  /* @__PURE__ */ jsx152(Separator13, {}),
@@ -49202,7 +49225,7 @@ function RecordAsk({ tableId, recordId }) {
49202
49225
  }
49203
49226
 
49204
49227
  // src/breakDown.tsx
49205
- import { useMemo as useMemo75, useState as useState129 } from "react";
49228
+ import { useMemo as useMemo75, useState as useState130 } from "react";
49206
49229
  import {
49207
49230
  Button as Button103,
49208
49231
  Dialog as Dialog14,
@@ -49242,7 +49265,7 @@ function BreakDownDialog({
49242
49265
  const source = useMemo75(() => ({ kind: "table", id: tableId }), [tableId]);
49243
49266
  const { def } = useDrillDefinition(open ? source : null);
49244
49267
  const dimensions = useMemo75(() => drillDimensionsOf(def, NO_LABELS), [def]);
49245
- const [picked, setPicked] = useState129(null);
49268
+ const [picked, setPicked] = useState130(null);
49246
49269
  const key = picked ?? held?.field ?? dimensions[0]?.key ?? "";
49247
49270
  return /* @__PURE__ */ jsx153(Dialog14, { open, onOpenChange, children: /* @__PURE__ */ jsxs142(DialogContent14, { "data-break-down": "", className: "max-w-sm", children: [
49248
49271
  /* @__PURE__ */ jsx153(DialogHeader14, { children: /* @__PURE__ */ jsx153(DialogTitle14, { children: "Break down by" }) }),
@@ -49269,7 +49292,7 @@ function BreakDownDialog({
49269
49292
 
49270
49293
  // src/TableReference.tsx
49271
49294
  import { copyText as copyText11 } from "@ai-matrx/kit/clipboard";
49272
- import { useCallback as useCallback68, useMemo as useMemo76, useState as useState130 } from "react";
49295
+ import { useCallback as useCallback68, useMemo as useMemo76, useState as useState131 } from "react";
49273
49296
  import { useContentTransferCapabilities as useContentTransferCapabilities2 } from "@ai-matrx/alchemy/react/workspace";
49274
49297
  import { Button as Button104, Dialog as Dialog15, DialogContent as DialogContent15, DialogHeader as DialogHeader15, DialogTitle as DialogTitle15 } from "@ai-matrx/design-system";
49275
49298
  import { jsx as jsx154, jsxs as jsxs143 } from "react/jsx-runtime";
@@ -49297,7 +49320,7 @@ function TableReferenceDialog({
49297
49320
  }) {
49298
49321
  const port = useContentTransferCapabilities2().reference;
49299
49322
  const notify = useRecordsUi().notify;
49300
- const [copied, setCopied] = useState130(null);
49323
+ const [copied, setCopied] = useState131(null);
49301
49324
  const choices = useMemo76(
49302
49325
  () => tableReferenceChoices(table.id, tableName(table)).filter((c) => port?.supports(c.reference)),
49303
49326
  [table, port]
@@ -49326,7 +49349,7 @@ function TableReferenceDialog({
49326
49349
 
49327
49350
  // src/TableDuplicate.tsx
49328
49351
  import { formatCount as formatCount6 } from "@ai-matrx/kit/format";
49329
- import { useState as useState131 } from "react";
49352
+ import { useState as useState132 } from "react";
49330
49353
  import { tableShapeChanged as tableShapeChanged12, useRecordsClient as useRecordsClient96 } from "@ai-matrx/records/react";
49331
49354
  import { Button as Button105, Dialog as Dialog16, DialogContent as DialogContent16, DialogFooter as DialogFooter11, DialogHeader as DialogHeader16, DialogTitle as DialogTitle16, ErrorBox as ErrorBox8, Input as Input10, Switch as Switch5 } from "@ai-matrx/design-system";
49332
49355
  import { Fragment as Fragment65, jsx as jsx155, jsxs as jsxs144 } from "react/jsx-runtime";
@@ -49341,9 +49364,9 @@ function duplicateProgressWords(p) {
49341
49364
  function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated }) {
49342
49365
  const client = useRecordsClient96();
49343
49366
  const host = useRecordsUi();
49344
- const [typed2, setTyped] = useState131(() => copyNameFor(name));
49345
- const [withRecords, setWithRecords] = useState131(true);
49346
- const [phase, setPhase] = useState131({ kind: "asking" });
49367
+ const [typed2, setTyped] = useState132(() => copyNameFor(name));
49368
+ const [withRecords, setWithRecords] = useState132(true);
49369
+ const [phase, setPhase] = useState132({ kind: "asking" });
49347
49370
  const problem = tableNameProblem(typed2);
49348
49371
  const copying = phase.kind === "copying";
49349
49372
  const close = (next) => {
@@ -49428,7 +49451,7 @@ function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated
49428
49451
  }
49429
49452
 
49430
49453
  // src/ViewFilter.tsx
49431
- import { useEffect as useEffect113, useMemo as useMemo77, useState as useState132 } from "react";
49454
+ import { useEffect as useEffect113, useMemo as useMemo77, useState as useState133 } from "react";
49432
49455
  import { Button as Button106, Popover as Popover13, PopoverContent as PopoverContent13, PopoverTrigger as PopoverTrigger13 } from "@ai-matrx/design-system";
49433
49456
  import { useFields as useFields36 } from "@ai-matrx/records/react";
49434
49457
  import { jsx as jsx156, jsxs as jsxs145 } from "react/jsx-runtime";
@@ -49442,9 +49465,9 @@ function conditionCount(expr) {
49442
49465
  }
49443
49466
  function ViewFilter({ tableId, view, onApply, className }) {
49444
49467
  const fields = useFields36(tableId);
49445
- const [open, setOpen] = useState132(false);
49468
+ const [open, setOpen] = useState133(false);
49446
49469
  const saved = view?.where ?? null;
49447
- const [draft, setDraft] = useState132(saved);
49470
+ const [draft, setDraft] = useState133(saved);
49448
49471
  const savedKey = JSON.stringify(saved);
49449
49472
  useEffect113(() => {
49450
49473
  setDraft(saved);
@@ -49621,7 +49644,7 @@ function phoneTableActions(actions) {
49621
49644
  }
49622
49645
 
49623
49646
  // src/toolbarFit.ts
49624
- import { useEffect as useEffect114, useState as useState133 } from "react";
49647
+ import { useEffect as useEffect114, useState as useState134 } from "react";
49625
49648
  var FOLDED_GUESS = { look: 104, chooser: 96, tools: 120 };
49626
49649
  var SLOT_MIN = 36;
49627
49650
  function toolbarFold(input) {
@@ -49678,7 +49701,7 @@ function rowNeeds(row) {
49678
49701
  return { needs: needs + gap * Math.max(0, pieces.length - 1), gap };
49679
49702
  }
49680
49703
  function useToolbarFit(row) {
49681
- const [fold, setFold] = useState133(0);
49704
+ const [fold, setFold] = useState134(0);
49682
49705
  useEffect114(() => {
49683
49706
  if (!row) return;
49684
49707
  const widths = {
@@ -49763,7 +49786,7 @@ function clippedEnds(scrollLeft, clientWidth, scrollWidth) {
49763
49786
  return start && end ? "both" : start ? "start" : end ? "end" : "none";
49764
49787
  }
49765
49788
  function useSlotScroll(slot) {
49766
- const [ends, setEnds] = useState133("none");
49789
+ const [ends, setEnds] = useState134("none");
49767
49790
  useEffect114(() => {
49768
49791
  if (!slot) return;
49769
49792
  let pending = 0;
@@ -49889,9 +49912,9 @@ function TableNotHere({
49889
49912
  className
49890
49913
  }) {
49891
49914
  const client = useRecordsClient97();
49892
- const [archived, setArchived] = useState134({ phase: "asking" });
49893
- const [restoring, setRestoring] = useState134(false);
49894
- const [refusal4, setRefusal] = useState134(null);
49915
+ const [archived, setArchived] = useState135({ phase: "asking" });
49916
+ const [restoring, setRestoring] = useState135(false);
49917
+ const [refusal4, setRefusal] = useState135(null);
49895
49918
  useEffect115(() => {
49896
49919
  let alive = true;
49897
49920
  void client.tableArchived({ table_id: tableId }).then((answered) => {
@@ -50106,12 +50129,12 @@ function TablePage({
50106
50129
  }
50107
50130
  );
50108
50131
  const seededViews = seededOpening && (seedViews ?? [defaultView(tableId)]).every((spec) => seedIsSatisfied(spec, seededOpening.views)) ? seededOpening.views : void 0;
50109
- const [view, setView] = useState134(() => {
50132
+ const [view, setView] = useState135(() => {
50110
50133
  if (!seededViews || seededViews.length === 0) return null;
50111
50134
  const asked3 = savedViewFromParam(activeView);
50112
50135
  return seededViews.find((v) => v.id === asked3) ?? defaultViewOf(seededViews) ?? seededViews[0];
50113
50136
  });
50114
- const [looks, setLooks] = useState134(() => seededViews ? seededOpening?.looks : void 0);
50137
+ const [looks, setLooks] = useState135(() => seededViews ? seededOpening?.looks : void 0);
50115
50138
  const looksSeededFor = useRef64(seededViews && seededOpening ? tableId : null);
50116
50139
  useEffect115(() => {
50117
50140
  if (looksSeededFor.current === tableId) {
@@ -50130,44 +50153,44 @@ function TablePage({
50130
50153
  }, [client, tableId]);
50131
50154
  const look = view && looks ? looks[view.id] : void 0;
50132
50155
  const shown4 = view ? applyLook(view, look) : null;
50133
- const [viewsEpoch, setViewsEpoch] = useState134(0);
50156
+ const [viewsEpoch, setViewsEpoch] = useState135(0);
50134
50157
  const opening = openingRail(activeRecordId, activeRail);
50135
50158
  const recordsUi = useRecordsUi();
50136
50159
  const savedFromLink = savedViewFromParam(activeView);
50137
50160
  const questionsFromLink = questionsFromParam(activeView);
50138
50161
  const openedByPackage = openingView(savedFromLink || questionsFromLink ? null : activeView, activeDashboardId);
50139
50162
  const opened = questionsFromLink ? { ...openedByPackage, main: "questions" } : openedByPackage;
50140
- const [views, setViews] = useState134(() => seededViews);
50141
- const [pickedViewId, setPickedViewId] = useState134(savedFromLink);
50163
+ const [views, setViews] = useState135(() => seededViews);
50164
+ const [pickedViewId, setPickedViewId] = useState135(savedFromLink);
50142
50165
  const viewSeen = useRef64(null);
50143
- const [viewLinkMissed, setViewLinkMissed] = useState134(false);
50166
+ const [viewLinkMissed, setViewLinkMissed] = useState135(false);
50144
50167
  const railAsked = typeof activeRail === "string" ? activeRail.trim() : "";
50145
50168
  const railUnknown = railAsked !== "" && railFromParam(railAsked) === null ? railAsked : null;
50146
50169
  const shareFromLink = railFromParam(activeRail) === "share";
50147
50170
  const canShare = useCanShare();
50148
50171
  const itemFor = (which) => railFromParam(activeRail) === which ? activeItemId ?? null : null;
50149
- const [asking, setAsking] = useState134(null);
50150
- const [layoutFromLink, setLayoutFromLink] = useState134(opened.layout);
50151
- const [surface, setSurface] = useState134({
50172
+ const [asking, setAsking] = useState135(null);
50173
+ const [layoutFromLink, setLayoutFromLink] = useState135(opened.layout);
50174
+ const [surface, setSurface] = useState135({
50152
50175
  main: opened.main,
50153
50176
  rail: opening.rail
50154
50177
  });
50155
50178
  const { main, rail } = surface;
50156
- const [questionDraft, setQuestionDraft] = useState134(null);
50179
+ const [questionDraft, setQuestionDraft] = useState135(null);
50157
50180
  const setRail = (next) => setSurface((now) => ({ ...now, rail: next }));
50158
- const [importEpoch, setImportEpoch] = useState134(0);
50159
- const [openRecord, setOpenRecord] = useState134(opening.record);
50181
+ const [importEpoch, setImportEpoch] = useState135(0);
50182
+ const [openRecord, setOpenRecord] = useState135(opening.record);
50160
50183
  const phone = useIsMobile2();
50161
- const [shareAsked, setShareAsked] = useState134(0);
50184
+ const [shareAsked, setShareAsked] = useState135(0);
50162
50185
  const { open: renameOpen, setOpen: setRenameOpen, ask: askRename, menuContentProps: renameMenuProps } = useRenameFromMenu();
50163
- const [archiveAsked, setArchiveAsked] = useState134(0);
50164
- const [moveAsked, setMoveAsked] = useState134(0);
50165
- const [duplicateOpen, setDuplicateOpen] = useState134(false);
50166
- const [referenceOpen, setReferenceOpen] = useState134(false);
50167
- const [breakDownOpen, setBreakDownOpen] = useState134(false);
50186
+ const [archiveAsked, setArchiveAsked] = useState135(0);
50187
+ const [moveAsked, setMoveAsked] = useState135(0);
50188
+ const [duplicateOpen, setDuplicateOpen] = useState135(false);
50189
+ const [referenceOpen, setReferenceOpen] = useState135(false);
50190
+ const [breakDownOpen, setBreakDownOpen] = useState135(false);
50168
50191
  const canGetReference = useCanGetReference();
50169
- const [toolbarSlot, setToolbarSlot] = useState134(null);
50170
- const [toolbarRow, setToolbarRow] = useState134(null);
50192
+ const [toolbarSlot, setToolbarSlot] = useState135(null);
50193
+ const [toolbarRow, setToolbarRow] = useState135(null);
50171
50194
  const toolbarFold2 = useToolbarFit(toolbarRow);
50172
50195
  const slotClipped = useSlotScroll(toolbarSlot);
50173
50196
  const embedded = pagePresentation2 === "embedded";
@@ -50239,7 +50262,7 @@ function TablePage({
50239
50262
  setLayoutFromLink(isLayout ? named : null);
50240
50263
  setSurface((now) => ({ ...now, main: isLayout ? "records" : named }));
50241
50264
  }, [activeView]);
50242
- const [viewSaveRefused, setViewSaveRefused] = useState134(null);
50265
+ const [viewSaveRefused, setViewSaveRefused] = useState135(null);
50243
50266
  const patchView = useCallback69(
50244
50267
  async (asked3) => {
50245
50268
  const current = view;
@@ -50257,8 +50280,8 @@ function TablePage({
50257
50280
  [client, tableId, view, looks]
50258
50281
  );
50259
50282
  const arrival = useRef64(viewAddress ?? null);
50260
- const [gridQuery, setGridQuery] = useState134(null);
50261
- const [addressResetEpoch, setAddressResetEpoch] = useState134(0);
50283
+ const [gridQuery, setGridQuery] = useState135(null);
50284
+ const [addressResetEpoch, setAddressResetEpoch] = useState135(0);
50262
50285
  const reportGrid = useCallback69((q) => {
50263
50286
  const next = { sort: q.sort, filters: q.filters, search: q.search, page: q.page };
50264
50287
  setGridQuery((held) => sameViewAddress(held, next) ? held : next);
@@ -50303,9 +50326,9 @@ function TablePage({
50303
50326
  }, [addressReady, addressSignature]);
50304
50327
  const queryShowing = !isViewAddressEmpty({ ...gridQuery ?? {}, hidden: [] });
50305
50328
  const lookShowing = Boolean(view && looks && (lookDiffers(view, looks[view.id]) || queryShowing));
50306
- const [lookRefused, setLookRefused] = useState134(null);
50307
- const [namingLook, setNamingLook] = useState134(false);
50308
- const [lookName, setLookName] = useState134("");
50329
+ const [lookRefused, setLookRefused] = useState135(null);
50330
+ const [namingLook, setNamingLook] = useState135(false);
50331
+ const [lookName, setLookName] = useState135("");
50309
50332
  const resetLook = async () => {
50310
50333
  const current = view;
50311
50334
  setAddressResetEpoch((n) => n + 1);
@@ -50364,7 +50387,7 @@ function TablePage({
50364
50387
  setPickedViewId(written.data);
50365
50388
  setViewsEpoch((n) => n + 1);
50366
50389
  };
50367
- const [designateRefused, setDesignateRefused] = useState134(null);
50390
+ const [designateRefused, setDesignateRefused] = useState135(null);
50368
50391
  const opensAs = view?.isDefault ? view.layout : null;
50369
50392
  const canDesignate = Boolean(
50370
50393
  rights.organise && view && layoutShowing && layoutShowing !== opensAs && storeKeepsLayout(layoutShowing)
@@ -51052,7 +51075,7 @@ var PUBLIC_READ_ONLY = "Public \xB7 read only";
51052
51075
  function usePublicReadOnly(client, organizationId, tableId, table, rights) {
51053
51076
  const readOnly = rights.known && rights.read && !rights.write;
51054
51077
  const marked = table?.published_to_web;
51055
- const [isPublic, setIsPublic] = useState134(false);
51078
+ const [isPublic, setIsPublic] = useState135(false);
51056
51079
  useEffect115(() => {
51057
51080
  if (!readOnly || !table) {
51058
51081
  setIsPublic(false);
@@ -51079,9 +51102,9 @@ function usePublicReadOnly(client, organizationId, tableId, table, rights) {
51079
51102
  import { formatCount as formatCount7 } from "@ai-matrx/kit/format";
51080
51103
  import { TapTargetSearchGroup as TapTargetSearchGroup2, TooltipProvider } from "@ai-matrx/design-system";
51081
51104
  import { MatrxTableCardShowMore as MatrxTableCardShowMore3 } from "@ai-matrx/design-system/data-table";
51082
- import { useEffect as useEffect116, useMemo as useMemo79, useState as useState135 } from "react";
51105
+ import { useEffect as useEffect116, useMemo as useMemo79, useRef as useRef65, useState as useState136 } from "react";
51083
51106
  import { Button as Button108, ErrorBox as ErrorBox9, Input as Input12, cn as cn95 } from "@ai-matrx/design-system";
51084
- import { useRecordsClient as useRecordsClient98 } from "@ai-matrx/records/react";
51107
+ import { useRecordsClient as useRecordsClient98, useSeededAnswer as useSeededAnswer2 } from "@ai-matrx/records/react";
51085
51108
  import { Fragment as Fragment67, jsx as jsx159, jsxs as jsxs148 } from "react/jsx-runtime";
51086
51109
  var entityTitleColumn = entityNameColumn;
51087
51110
  function shown3(v) {
@@ -51096,8 +51119,8 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
51096
51119
  () => cardFields ? entity.columns.filter((c) => cardFields.includes(c.key)) : entity.columns.filter((c) => c !== title && c !== column && c.type !== "choice").slice(0, 2),
51097
51120
  [cardFields, entity.columns, title, column]
51098
51121
  );
51099
- const [refused, setRefused] = useState135(null);
51100
- const [over, setOver] = useState135(null);
51122
+ const [refused, setRefused] = useState136(null);
51123
+ const [over, setOver] = useState136(null);
51101
51124
  if (entity.error) return /* @__PURE__ */ jsx159("p", { className: "px-1 py-3 text-xs text-muted-foreground", children: `This board could not be read: ${entity.error}` });
51102
51125
  if (!entity.loading && !column) {
51103
51126
  return /* @__PURE__ */ jsx159("p", { className: "px-1 py-3 text-xs text-muted-foreground", children: `${entity.label ?? "This table"} has no choice column to make a board of.` });
@@ -51161,38 +51184,42 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
51161
51184
  );
51162
51185
  }) });
51163
51186
  }
51187
+ function blockOfAnswer(answer, base, by) {
51188
+ if (!answer.ok) {
51189
+ return { ...base, refused: refusalSentence(answer.error) || "This chart could not be read.", ...answer.error.code ? { sqlstate: answer.error.code } : {} };
51190
+ }
51191
+ const rows = answer.data.rows.filter((r) => by ? r.kind !== "total" : r.kind === "total").map((r) => {
51192
+ const groups = {};
51193
+ if (by) {
51194
+ const v = r.kind === "other" ? "Other" : r.labels?.[by] ?? r.groups?.[by] ?? null;
51195
+ groups[by] = v === null || v === void 0 ? null : String(v);
51196
+ }
51197
+ const measuresOut = {};
51198
+ for (const [k, v] of Object.entries(r.measures ?? {})) measuresOut[k] = typeof v === "number" ? v : v === null ? null : Number(v);
51199
+ return { groups, measures: measuresOut, row_count: Number(r.row_count) };
51200
+ });
51201
+ return { ...base, rows };
51202
+ }
51164
51203
  function EntityChartBlock({ source, kind, by, measure, title, where, organization, centerValue, variant, className }) {
51165
51204
  const client = useRecordsClient98();
51166
51205
  const m = measure ?? { op: "count" };
51167
51206
  const ask = JSON.stringify([source.token, by ?? null, m, where ?? null, organization ?? null]);
51168
- const [block, setBlock] = useState135(null);
51207
+ const question = entityChartQuestion({ by, measure, where, organization });
51208
+ const measures = [m.op === "count" ? { op: "count" } : { op: m.op, key: m.of }];
51209
+ const base = { title: title ?? "", kind, measures, group_by: by ? [by] : [] };
51210
+ const seeded = useSeededAnswer2(`entity-chart:${ask}`, (c) => c.drillAsk({ source, question }));
51211
+ const [block, setBlock] = useState136(() => seeded ? blockOfAnswer({ ok: true, data: seeded }, base, by) : null);
51212
+ const firstRead = useRef65(true);
51169
51213
  useEffect116(() => {
51214
+ if (firstRead.current && seeded) {
51215
+ firstRead.current = false;
51216
+ return;
51217
+ }
51218
+ firstRead.current = false;
51170
51219
  let cancelled = false;
51171
- const question = {
51172
- ...by ? { by: [by] } : {},
51173
- show: [m.op === "count" ? "count" : { op: m.op, of: m.of }],
51174
- ...where ? { where } : {},
51175
- ...organization ? { organization } : {}
51176
- };
51177
- const measures = [m.op === "count" ? { op: "count" } : { op: m.op, key: m.of }];
51178
- const base = { title: title ?? "", kind, measures, group_by: by ? [by] : [] };
51179
51220
  void client.drillAsk({ source, question }).then((answer) => {
51180
51221
  if (cancelled) return;
51181
- if (!answer.ok) {
51182
- setBlock({ ...base, refused: refusalSentence(answer.error) || "This chart could not be read.", ...answer.error.code ? { sqlstate: answer.error.code } : {} });
51183
- return;
51184
- }
51185
- const rows = answer.data.rows.filter((r) => by ? r.kind !== "total" : r.kind === "total").map((r) => {
51186
- const groups = {};
51187
- if (by) {
51188
- const v = r.kind === "other" ? "Other" : r.labels?.[by] ?? r.groups?.[by] ?? null;
51189
- groups[by] = v === null || v === void 0 ? null : String(v);
51190
- }
51191
- const measuresOut = {};
51192
- for (const [k, v] of Object.entries(r.measures ?? {})) measuresOut[k] = typeof v === "number" ? v : v === null ? null : Number(v);
51193
- return { groups, measures: measuresOut, row_count: Number(r.row_count) };
51194
- });
51195
- setBlock({ ...base, rows });
51222
+ setBlock(blockOfAnswer(answer, base, by));
51196
51223
  });
51197
51224
  return () => {
51198
51225
  cancelled = true;
@@ -51230,10 +51257,10 @@ function EntityTablePageBody({
51230
51257
  actions,
51231
51258
  className
51232
51259
  }) {
51233
- const [typed2, setTyped] = useState135("");
51260
+ const [typed2, setTyped] = useState136("");
51234
51261
  const term = searchOverride ?? typed2;
51235
51262
  const entity = useEntityTable(source.token, { pageSize, search: term });
51236
- const [layout, setLayout] = useState135(opened);
51263
+ const [layout, setLayout] = useState136(opened);
51237
51264
  useEffect116(() => setLayout(opened), [opened]);
51238
51265
  const choose = (next) => {
51239
51266
  setLayout(next);
@@ -51241,9 +51268,9 @@ function EntityTablePageBody({
51241
51268
  };
51242
51269
  const boardable = entityChoiceColumns(entity.columns).length > 0;
51243
51270
  const nameColumn = entityNameColumn(entity.columns);
51244
- const [naming, setNaming] = useState135(null);
51245
- const [adding, setAdding] = useState135(false);
51246
- const [addRefused, setAddRefused] = useState135(null);
51271
+ const [naming, setNaming] = useState136(null);
51272
+ const [adding, setAdding] = useState136(false);
51273
+ const [addRefused, setAddRefused] = useState136(null);
51247
51274
  const add = async () => {
51248
51275
  const name = (naming ?? "").trim();
51249
51276
  if (!name || !nameColumn || adding) return;
@@ -51255,7 +51282,7 @@ function EntityTablePageBody({
51255
51282
  setNaming(null);
51256
51283
  onOpenRecord?.(made.id);
51257
51284
  };
51258
- const [question, setQuestion] = useState135(() => questionFromGrouping(void 0));
51285
+ const [question, setQuestion] = useState136(() => questionFromGrouping(void 0));
51259
51286
  const { config: drill } = useDrill({
51260
51287
  source,
51261
51288
  question,
@@ -51678,7 +51705,7 @@ function RecordNameWords({ tableId, recordId }) {
51678
51705
  }
51679
51706
 
51680
51707
  // src/HeldChangeDecision.tsx
51681
- import { useEffect as useEffect118, useState as useState136 } from "react";
51708
+ import { useEffect as useEffect118, useState as useState137 } from "react";
51682
51709
  import { RecordsProvider as RecordsProvider3, useRecordsClient as useRecordsClient99 } from "@ai-matrx/records/react";
51683
51710
  import { Button as Button110 } from "@ai-matrx/design-system";
51684
51711
  import { jsx as jsx163, jsxs as jsxs151 } from "react/jsx-runtime";
@@ -51687,9 +51714,9 @@ function HeldChangeDecision({ dataSource, userId, organizationId, approvalId, on
51687
51714
  }
51688
51715
  function Decision({ approvalId, onDecided }) {
51689
51716
  const client = useRecordsClient99();
51690
- const [may, setMay] = useState136(null);
51691
- const [busy, setBusy] = useState136(null);
51692
- const [error, setError] = useState136(null);
51717
+ const [may, setMay] = useState137(null);
51718
+ const [busy, setBusy] = useState137(null);
51719
+ const [error, setError] = useState137(null);
51693
51720
  useEffect118(() => {
51694
51721
  let live = true;
51695
51722
  void client.workApprovalMayDecide({ approval_id: approvalId }).then((res) => {
@@ -51723,7 +51750,7 @@ function Decision({ approvalId, onDecided }) {
51723
51750
  }
51724
51751
 
51725
51752
  // src/TemplatePreview.tsx
51726
- import { useEffect as useEffect119, useMemo as useMemo81, useState as useState137 } from "react";
51753
+ import { useEffect as useEffect119, useMemo as useMemo81, useState as useState138 } from "react";
51727
51754
  import { templatePreview } from "@ai-matrx/records/memory";
51728
51755
  import { useRecordsClient as useRecordsClient100 } from "@ai-matrx/records/react";
51729
51756
  import { jsx as jsx164, jsxs as jsxs152 } from "react/jsx-runtime";
@@ -51734,7 +51761,7 @@ function TemplatePreview({ spec, today, initialTable, host, aside, booking, clas
51734
51761
  const preview = useTemplatePreview(spec, today);
51735
51762
  const bound2 = useMemo81(() => ({ ...host, sayLevelNeeded: false }), [host]);
51736
51763
  const first = preview.tables.find((t) => t.token === initialTable) ?? preview.tables[0];
51737
- const [active, setActive] = useState137(first?.id ?? null);
51764
+ const [active, setActive] = useState138(first?.id ?? null);
51738
51765
  const table = preview.tables.find((t) => t.id === active) ?? first;
51739
51766
  if (!table) return null;
51740
51767
  return /* @__PURE__ */ jsxs152("div", { className: ["flex min-w-0 flex-col gap-3", className].filter(Boolean).join(" "), "data-template-preview": preview.tables.length, children: [
@@ -51772,8 +51799,8 @@ function TemplatePreview({ spec, today, initialTable, host, aside, booking, clas
51772
51799
  }
51773
51800
  function PreviewForms({ preview, booking }) {
51774
51801
  const client = useRecordsClient100();
51775
- const [forms, setForms] = useState137(null);
51776
- const [pages, setPages] = useState137([]);
51802
+ const [forms, setForms] = useState138(null);
51803
+ const [pages, setPages] = useState138([]);
51777
51804
  useEffect119(() => {
51778
51805
  let gone = false;
51779
51806
  void client.forms().then((answered) => {
@@ -52156,11 +52183,13 @@ export {
52156
52183
  endingsFromDocument,
52157
52184
  ensureSystemTable,
52158
52185
  entityCellValue,
52186
+ entityChartQuestion,
52159
52187
  entityChoiceColumns,
52160
52188
  entityNameColumn,
52161
52189
  entityReferenceSpec,
52162
52190
  entityShownColumns,
52163
52191
  entityTableColumns,
52192
+ entityTableQuery,
52164
52193
  entityTitleColumn,
52165
52194
  entityValueText,
52166
52195
  envelopeFor,