@ai-matrx/records-ui 0.66.0 → 0.68.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -2134,9 +2134,15 @@ interface PortalCardViewProps {
2134
2134
  onPreview: (person: PortalPrincipal, tableId: Uuid) => Promise<PortalAnswer<PortalPreviewRow[]>>;
2135
2135
  /** The invite control, which needs a client of its own. Absent means none is offered. */
2136
2136
  invite?: ReactNode;
2137
+ /**
2138
+ * Where this app is served from, so a person's own invitation link can be copied whole.
2139
+ * Omit it and the view falls back to the browser's origin, which keeps this component
2140
+ * mountable BARE against a recorded answer with no host and no network.
2141
+ */
2142
+ origin?: string | undefined;
2137
2143
  className?: string | undefined;
2138
2144
  }
2139
- declare function PortalCardView({ card, tableId, onRevoke, onPreview, invite, className, }: PortalCardViewProps): react.JSX.Element;
2145
+ declare function PortalCardView({ card, tableId, onRevoke, onPreview, invite, origin, className, }: PortalCardViewProps): react.JSX.Element;
2140
2146
 
2141
2147
  interface DigestSchedulerProps {
2142
2148
  /** The Table the digest is about. A saved view is a view OF something. */
package/dist/index.d.ts CHANGED
@@ -2134,9 +2134,15 @@ interface PortalCardViewProps {
2134
2134
  onPreview: (person: PortalPrincipal, tableId: Uuid) => Promise<PortalAnswer<PortalPreviewRow[]>>;
2135
2135
  /** The invite control, which needs a client of its own. Absent means none is offered. */
2136
2136
  invite?: ReactNode;
2137
+ /**
2138
+ * Where this app is served from, so a person's own invitation link can be copied whole.
2139
+ * Omit it and the view falls back to the browser's origin, which keeps this component
2140
+ * mountable BARE against a recorded answer with no host and no network.
2141
+ */
2142
+ origin?: string | undefined;
2137
2143
  className?: string | undefined;
2138
2144
  }
2139
- declare function PortalCardView({ card, tableId, onRevoke, onPreview, invite, className, }: PortalCardViewProps): react.JSX.Element;
2145
+ declare function PortalCardView({ card, tableId, onRevoke, onPreview, invite, origin, className, }: PortalCardViewProps): react.JSX.Element;
2140
2146
 
2141
2147
  interface DigestSchedulerProps {
2142
2148
  /** The Table the digest is about. A saved view is a view OF something. */
package/dist/index.js CHANGED
@@ -608,6 +608,9 @@ function isRelationFieldType(id) {
608
608
  function parityTypesWithNoExplanation() {
609
609
  return PARITY_FIELD_TYPES.map((row) => row.parity_type).filter((type) => !BY_ID.has(type));
610
610
  }
611
+ var ADD_FIELD_OPEN_LABEL = "Add field";
612
+ var ADD_FIELD_SAVE_LABEL = "Create field";
613
+ var EDIT_FIELD_SAVE_LABEL = "Save field";
611
614
 
612
615
  // src/parity.ts
613
616
  var kernelId = (name) => KERNEL_TABLES.find((t) => t.name === name)?.id ?? "";
@@ -1237,7 +1240,16 @@ function RefusalNotice({
1237
1240
  /* @__PURE__ */ jsxs5(AlertDescription, { className: "space-y-1 text-xs", children: [
1238
1241
  plain.sentence.replace(/\.$/, "") === plain.title ? null : /* @__PURE__ */ jsx6("p", { children: plain.sentence }),
1239
1242
  /* @__PURE__ */ jsx6("p", { className: "opacity-80", children: plain.remedy }),
1240
- plain.forEngineers ? /* @__PURE__ */ jsx6("p", { className: "sr-only", ...error.sqlstate ? { "data-sqlstate": error.sqlstate } : {}, children: plain.forEngineers }) : null,
1243
+ plain.forEngineers ? /* @__PURE__ */ jsx6(
1244
+ "p",
1245
+ {
1246
+ className: "sr-only",
1247
+ "aria-hidden": "true",
1248
+ "data-for-engineers": "",
1249
+ ...error.sqlstate ? { "data-sqlstate": error.sqlstate } : {},
1250
+ children: plain.forEngineers
1251
+ }
1252
+ ) : null,
1241
1253
  actions
1242
1254
  ] })
1243
1255
  ]
@@ -4818,7 +4830,7 @@ function FieldEditor({ tableId, field, onSaved, onCancel, onRemoved, className }
4818
4830
  size: "sm",
4819
4831
  disabled: mutation.saving || missing !== null,
4820
4832
  onClick: () => void save(),
4821
- children: mutation.saving ? "Saving\u2026" : field ? "Save field" : "Add field"
4833
+ children: mutation.saving ? "Saving\u2026" : field ? EDIT_FIELD_SAVE_LABEL : ADD_FIELD_SAVE_LABEL
4822
4834
  }
4823
4835
  ),
4824
4836
  onCancel ? /* @__PURE__ */ jsx17(Button12, { size: "sm", variant: "ghost", onClick: onCancel, children: "Cancel" }) : null,
@@ -7236,7 +7248,9 @@ function FieldPicker({
7236
7248
  }) {
7237
7249
  const want = LAYOUT_FIELD_KIND[layout];
7238
7250
  const offerable = want ? offerableFields(all, want) : [];
7239
- if (offerable.length === 0) {
7251
+ const chosenField = chosen ? all.find((field) => field.key === chosen) : void 0;
7252
+ const unusual = chosenField && !offerable.some((field) => field.key === chosenField.key) ? chosenField : void 0;
7253
+ if (offerable.length === 0 && !unusual) {
7240
7254
  return /* @__PURE__ */ jsx26("p", { className: "text-xs text-muted-foreground", children: LAYOUT_NO_FIELD[layout] });
7241
7255
  }
7242
7256
  return /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-1.5 text-xs", children: [
@@ -7251,7 +7265,11 @@ function FieldPicker({
7251
7265
  onChange: (event) => onPick(event.target.value === "" ? null : event.target.value),
7252
7266
  children: [
7253
7267
  /* @__PURE__ */ jsx26("option", { value: "", children: "Choose a field" }),
7254
- offerable.map((field) => /* @__PURE__ */ jsx26("option", { value: field.key, children: fieldName(field) }, field.key))
7268
+ offerable.map((field) => /* @__PURE__ */ jsx26("option", { value: field.key, children: fieldName(field) }, field.key)),
7269
+ unusual ? /* @__PURE__ */ jsxs22("option", { value: unusual.key, children: [
7270
+ fieldName(unusual),
7271
+ " \u2014 an unusual column to use here"
7272
+ ] }, unusual.key) : null
7255
7273
  ]
7256
7274
  }
7257
7275
  ),
@@ -9797,6 +9815,7 @@ function PortalsPanel({ tableId, className }) {
9797
9815
  {
9798
9816
  portalId: portal.portal_id,
9799
9817
  ...tableId ? { tableId } : {},
9818
+ origin,
9800
9819
  onChanged: () => void load()
9801
9820
  }
9802
9821
  ) : null
@@ -9804,7 +9823,7 @@ function PortalsPanel({ tableId, className }) {
9804
9823
  }) })
9805
9824
  ] });
9806
9825
  }
9807
- function CopyLink({ url }) {
9826
+ function CopyLink({ url, what }) {
9808
9827
  const [copied, setCopied] = useState33(false);
9809
9828
  const [shown, setShown] = useState33(false);
9810
9829
  return /* @__PURE__ */ jsxs32(Fragment16, { children: [
@@ -9825,7 +9844,7 @@ function CopyLink({ url }) {
9825
9844
  }
9826
9845
  })();
9827
9846
  },
9828
- children: copied ? "Copied" : "Copy link"
9847
+ children: copied ? "Copied" : what ? `Copy ${what}` : "Copy link"
9829
9848
  }
9830
9849
  ),
9831
9850
  shown ? /* @__PURE__ */ jsxs32("p", { className: "mt-1.5 w-full break-all rounded border border-dashed border-border px-2 py-1 text-xs", children: [
@@ -9837,6 +9856,7 @@ function CopyLink({ url }) {
9837
9856
  function PortalDetail({
9838
9857
  portalId,
9839
9858
  tableId,
9859
+ origin,
9840
9860
  onChanged
9841
9861
  }) {
9842
9862
  const client = useRecordsClient25();
@@ -9886,6 +9906,7 @@ function PortalDetail({
9886
9906
  PortalCardView,
9887
9907
  {
9888
9908
  card,
9909
+ origin,
9889
9910
  ...tableId ? { tableId } : {},
9890
9911
  onRevoke: revoke,
9891
9912
  onPreview: preview,
@@ -9908,6 +9929,7 @@ function PortalCardView({
9908
9929
  onRevoke,
9909
9930
  onPreview,
9910
9931
  invite,
9932
+ origin,
9911
9933
  className
9912
9934
  }) {
9913
9935
  return /* @__PURE__ */ jsxs32("div", { className: cn30("mt-2.5 flex flex-col gap-2.5 border-t border-border pt-2.5", className), children: [
@@ -9938,7 +9960,7 @@ function PortalCardView({
9938
9960
  ] }, exposed.table_id))
9939
9961
  ] }),
9940
9962
  /* @__PURE__ */ jsx36(Separator10, {}),
9941
- /* @__PURE__ */ jsx36(People, { card, onRevoke, onPreview }),
9963
+ /* @__PURE__ */ jsx36(People, { card, onRevoke, onPreview, origin }),
9942
9964
  invite ? /* @__PURE__ */ jsxs32(Fragment16, { children: [
9943
9965
  /* @__PURE__ */ jsx36(Separator10, {}),
9944
9966
  invite
@@ -9948,8 +9970,10 @@ function PortalCardView({
9948
9970
  function People({
9949
9971
  card,
9950
9972
  onRevoke,
9951
- onPreview
9973
+ onPreview,
9974
+ origin
9952
9975
  }) {
9976
+ const here = origin ?? (typeof window === "undefined" ? "" : window.location.origin);
9953
9977
  const [askingToRevoke, setAskingToRevoke] = useState33(null);
9954
9978
  const [busy, setBusy] = useState33(false);
9955
9979
  const [said, setSaid] = useState33(null);
@@ -9991,6 +10015,7 @@ function People({
9991
10015
  /* @__PURE__ */ jsx36("p", { className: "mt-0.5 break-all text-muted-foreground", children: person.email }),
9992
10016
  /* @__PURE__ */ jsx36("p", { className: "mt-0.5 text-muted-foreground", children: state.why }),
9993
10017
  person.is_active ? /* @__PURE__ */ jsxs32("div", { className: "mt-1.5 flex flex-wrap gap-1.5", children: [
10018
+ person.accept_path ? /* @__PURE__ */ jsx36(CopyLink, { url: `${here}${person.accept_path}`, what: "their link" }) : null,
9994
10019
  /* @__PURE__ */ jsx36(
9995
10020
  Button30,
9996
10021
  {
@@ -10002,6 +10027,11 @@ function People({
10002
10027
  ),
10003
10028
  /* @__PURE__ */ jsx36(Button30, { size: "sm", variant: "ghost", onClick: () => setAskingToRevoke(person), children: "Remove their access" })
10004
10029
  ] }) : null,
10030
+ person.is_active && !person.signed_in && !person.accept_path ? /* @__PURE__ */ jsxs32("p", { className: "mt-1.5 text-muted-foreground", children: [
10031
+ "There is no link to copy for ",
10032
+ person.client || person.email,
10033
+ ": they were asked some other way, or the link they were sent has expired. Invite them again and a fresh one is made."
10034
+ ] }) : null,
10005
10035
  asking ? /* @__PURE__ */ jsxs32("div", { className: "mt-1.5 flex flex-col gap-1.5 rounded border border-destructive/40 px-2 py-1.5", children: [
10006
10036
  /* @__PURE__ */ jsx36("span", { className: "text-destructive", children: revokeConsequence(person, card.title) }),
10007
10037
  /* @__PURE__ */ jsxs32("div", { className: "flex flex-wrap gap-1.5", children: [
@@ -14857,7 +14887,7 @@ function TablePage({
14857
14887
  variant: surfaceChosen(surface, { rail: "field" }) ? "secondary" : "outline",
14858
14888
  "aria-pressed": surfaceChosen(surface, { rail: "field" }),
14859
14889
  onClick: () => press({ rail: "field" }),
14860
- children: "Add field"
14890
+ children: ADD_FIELD_OPEN_LABEL
14861
14891
  }
14862
14892
  ),
14863
14893
  /* @__PURE__ */ jsx58(