@ai-matrx/records-ui 0.113.39 → 0.114.1

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
@@ -15527,7 +15527,7 @@ function useMergedGridControls(args) {
15527
15527
  },
15528
15528
  [enabled, fieldOf2, choiceOptions, rows, choiceCounts]
15529
15529
  );
15530
- const copyText14 = useCallback17(
15530
+ const copyText16 = useCallback17(
15531
15531
  (text, what) => {
15532
15532
  void writeClipboardText(text).then(
15533
15533
  (landed) => landed ? notify?.success(`${what} ${what.endsWith("cells") ? "are" : "is"} copied.`) : notify?.error("The clipboard refused the copy. Select the cells and press Cmd-C.")
@@ -15647,7 +15647,7 @@ function useMergedGridControls(args) {
15647
15647
  },
15648
15648
  sortedBy: query.sort ? { id: query.sort.id, direction: query.sort.direction } : null,
15649
15649
  actions: {
15650
- copyText: copyText14,
15650
+ copyText: copyText16,
15651
15651
  pasteInto: (rowId, columnId2) => {
15652
15652
  const field2 = fields.find((f) => f.key === columnId2);
15653
15653
  if (!field2) return;
@@ -15716,7 +15716,7 @@ function useMergedGridControls(args) {
15716
15716
  ...hrefForRecord && table ? {
15717
15717
  copyRecordLink: (rowId) => {
15718
15718
  const href = hrefForRecord({ table, recordId: rowId });
15719
- if (href) copyText14(new URL(href, window.location.origin).toString(), "The link");
15719
+ if (href) copyText16(new URL(href, window.location.origin).toString(), "The link");
15720
15720
  }
15721
15721
  } : {},
15722
15722
  ...editable && rights.structure ? {
@@ -15816,7 +15816,7 @@ function useMergedGridControls(args) {
15816
15816
  fieldKeys,
15817
15817
  canWrite,
15818
15818
  client,
15819
- copyText14,
15819
+ copyText16,
15820
15820
  editable,
15821
15821
  editing,
15822
15822
  fields,
@@ -25696,10 +25696,11 @@ function ConnectedRecordsTableCard({
25696
25696
  }
25697
25697
 
25698
25698
  // src/ExportMenu.tsx
25699
+ import { copyText as copyText2 } from "@ai-matrx/kit/clipboard";
25699
25700
  import { downloadFile as downloadFile2 } from "@ai-matrx/kit/download";
25700
25701
  import { useEffect as useEffect54, useState as useState65 } from "react";
25701
25702
  import { useFields as useFields10, useRecords as useRecords6, useRecordsClient as useRecordsClient41, useTable as useTable8 } from "@ai-matrx/records/react";
25702
- import { exportCsv, exportXlsx, wholeValueOf as wholeValueOf5, withWholeValues } from "@ai-matrx/records/core";
25703
+ import { exportCsv, exportMarkdown, exportXlsx, wholeValueOf as wholeValueOf5, withWholeValues } from "@ai-matrx/records/core";
25703
25704
 
25704
25705
  // src/viewExport.ts
25705
25706
  import { formatCount as formatCount4 } from "@ai-matrx/kit/format";
@@ -25877,6 +25878,31 @@ function ExportMenu({ tableId, rows, label, className, view }) {
25877
25878
  children: "XLSX"
25878
25879
  }
25879
25880
  ),
25881
+ /* @__PURE__ */ jsx80(
25882
+ Button46,
25883
+ {
25884
+ size: "sm",
25885
+ variant: "outline",
25886
+ onClick: () => void exported().then((rows2) => download(`${name}.md`, "text/markdown;charset=utf-8", exportMarkdown(columns, rows2))).catch(
25887
+ (thrown) => setFailure((0, refusals_exports.refusalFromThrown)(thrown, "The Markdown could not be written.", "The CSV beside this button carries the same rows."))
25888
+ ),
25889
+ children: "Markdown"
25890
+ }
25891
+ ),
25892
+ /* @__PURE__ */ jsx80(
25893
+ Button46,
25894
+ {
25895
+ size: "sm",
25896
+ variant: "outline",
25897
+ onClick: () => void exported().then(async (rows2) => {
25898
+ if (await copyText2(exportMarkdown(columns, rows2))) host.notify?.success("Markdown copied");
25899
+ else host.notify?.error("Couldn\u2019t copy the Markdown");
25900
+ }).catch(
25901
+ (thrown) => setFailure((0, refusals_exports.refusalFromThrown)(thrown, "The Markdown could not be written.", "The CSV beside this button carries the same rows."))
25902
+ ),
25903
+ children: "Copy Markdown"
25904
+ }
25905
+ ),
25880
25906
  /* @__PURE__ */ jsx80(
25881
25907
  AlchemyMenu,
25882
25908
  {
@@ -26197,14 +26223,14 @@ function fieldsForNewColumns(columns) {
26197
26223
  }
26198
26224
 
26199
26225
  // src/BookingSlots.tsx
26200
- import { copyText as copyText3 } from "@ai-matrx/kit/clipboard";
26226
+ import { copyText as copyText4 } from "@ai-matrx/kit/clipboard";
26201
26227
  import { useCallback as useCallback31, useEffect as useEffect58, useMemo as useMemo39, useState as useState69 } from "react";
26202
26228
  import { useRecordsClient as useRecordsClient45, useMyLevels as useMyLevels2 } from "@ai-matrx/records/react";
26203
26229
  import { bookingPath as bookingPath2 } from "@ai-matrx/records";
26204
26230
  import { Badge as Badge11, Button as Button51, Skeleton as Skeleton7, cn as cn44 } from "@ai-matrx/design-system";
26205
26231
 
26206
26232
  // src/BookingBuilder.tsx
26207
- import { copyText as copyText2 } from "@ai-matrx/kit/clipboard";
26233
+ import { copyText as copyText3 } from "@ai-matrx/kit/clipboard";
26208
26234
  import { ErrorBox as ErrorBox3 } from "@ai-matrx/design-system";
26209
26235
  import { useCallback as useCallback29, useEffect as useEffect56, useMemo as useMemo38, useRef as useRef37, useState as useState67 } from "react";
26210
26236
  import { useFields as useFields11, useRecordsClient as useRecordsClient43, useTable as useTable9 } from "@ai-matrx/records/react";
@@ -26683,7 +26709,7 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, startNew, classN
26683
26709
  size: "sm",
26684
26710
  variant: "outline",
26685
26711
  onClick: () => {
26686
- void copyText2(url).then((landed) => {
26712
+ void copyText3(url).then((landed) => {
26687
26713
  setCopied(landed);
26688
26714
  if (landed) window.setTimeout(() => setCopied(false), 1600);
26689
26715
  });
@@ -26875,7 +26901,7 @@ function tableActions(input) {
26875
26901
  const url = tableLink(table.id, host.origin);
26876
26902
  const favorite = host.isFavorite === true;
26877
26903
  const openInNewTab = host.openInNewTab;
26878
- const copyText14 = host.copyText;
26904
+ const copyText16 = host.copyText;
26879
26905
  const openBuiltOn = host.openBuiltOn;
26880
26906
  const built = [
26881
26907
  action({ id: "open", label: "Open", icon: "folder-open", group: "open", verb: "open" }, "read", input, bind(host.open, table)),
@@ -26889,7 +26915,7 @@ function tableActions(input) {
26889
26915
  { id: "copy-link", label: "Copy link", icon: "link", group: "open", verb: "copy-link" },
26890
26916
  "read",
26891
26917
  input,
26892
- copyText14 ? () => copyText14(url, table) : void 0
26918
+ copyText16 ? () => copyText16(url, table) : void 0
26893
26919
  ),
26894
26920
  action({ id: "rename", label: "Rename\u2026", icon: "pencil", group: "organize", verb: "rename" }, "structure", input, bind(host.rename, table)),
26895
26921
  action({ id: "duplicate", label: "Duplicate", icon: "copy", group: "organize", verb: "duplicate" }, "read", input, bind(host.duplicate, table)),
@@ -27299,7 +27325,7 @@ function BookingSlots({ tableId, activeBookingId, className }) {
27299
27325
  [client, load]
27300
27326
  );
27301
27327
  const copy = useCallback31(async (url, formId) => {
27302
- if (await copyText3(url)) {
27328
+ if (await copyText4(url)) {
27303
27329
  setCopied(formId);
27304
27330
  setShown(null);
27305
27331
  window.setTimeout(() => setCopied(null), 1600);
@@ -30036,7 +30062,7 @@ function RecordFieldsInPlace({
30036
30062
  }
30037
30063
 
30038
30064
  // src/ShareControl.tsx
30039
- import { copyText as copyText4 } from "@ai-matrx/kit/clipboard";
30065
+ import { copyText as copyText5 } from "@ai-matrx/kit/clipboard";
30040
30066
  import { useEffect as useEffect69, useState as useState82 } from "react";
30041
30067
  import { Button as Button62, Popover as Popover11, PopoverContent as PopoverContent11, PopoverTrigger as PopoverTrigger11 } from "@ai-matrx/design-system";
30042
30068
  import { Fragment as Fragment37, jsx as jsx102, jsxs as jsxs93 } from "react/jsx-runtime";
@@ -30099,7 +30125,7 @@ function ShareForSomebodyElse({
30099
30125
  }) {
30100
30126
  const [copied, setCopied] = useState82(null);
30101
30127
  const copy = async () => {
30102
- if (await copyText4(window.location.href)) {
30128
+ if (await copyText5(window.location.href)) {
30103
30129
  setCopied("yes");
30104
30130
  } else {
30105
30131
  setCopied("no");
@@ -30820,7 +30846,7 @@ function CardDates({ record, fields }) {
30820
30846
  }
30821
30847
 
30822
30848
  // src/RecordActionMenu.tsx
30823
- import { copyText as copyText5 } from "@ai-matrx/kit/clipboard";
30849
+ import { copyText as copyText6 } from "@ai-matrx/kit/clipboard";
30824
30850
  import { useCallback as useCallback38, useMemo as useMemo49, useState as useState87 } from "react";
30825
30851
  import { useFields as useFields16, useRecordsClient as useRecordsClient62, useTable as useTable16 } from "@ai-matrx/records/react";
30826
30852
  import {
@@ -30861,7 +30887,7 @@ function recordActions(input) {
30861
30887
  const origin = (host.origin ?? DEFAULT_ACTION_ORIGIN).replace(/\/+$/, "");
30862
30888
  const url = host.href ? /^https?:/.test(host.href) ? host.href : `${origin}${host.href}` : recordLink(record.tableId, record.id, host.origin);
30863
30889
  const openInNewTab = host.openInNewTab;
30864
- const copyText14 = host.copyText;
30890
+ const copyText16 = host.copyText;
30865
30891
  const built = [
30866
30892
  action2({ id: "open", label: "Open", icon: "folder-open", group: "open", verb: "open" }, "read", input, bind2(host.open, record)),
30867
30893
  action2(
@@ -30874,7 +30900,7 @@ function recordActions(input) {
30874
30900
  { id: "copy-link", label: "Copy link", icon: "link", group: "open", verb: "copy-link" },
30875
30901
  "read",
30876
30902
  input,
30877
- copyText14 ? () => copyText14(url, record) : void 0
30903
+ copyText16 ? () => copyText16(url, record) : void 0
30878
30904
  ),
30879
30905
  action2({ id: "duplicate", label: "Duplicate", icon: "copy", group: "organize", verb: "duplicate" }, "organise", input, bind2(host.duplicate, record)),
30880
30906
  action2(
@@ -30927,7 +30953,7 @@ function useRecordActionHost({ tableId, row, onOpenRecord, onChanged, onMerge })
30927
30953
  window.open(url, "_blank", "noopener,noreferrer");
30928
30954
  },
30929
30955
  copyText: async (url) => {
30930
- if (await copyText5(url)) {
30956
+ if (await copyText6(url)) {
30931
30957
  said2("Link copied");
30932
30958
  } else {
30933
30959
  notify?.error("Couldn\u2019t copy the link");
@@ -40079,7 +40105,7 @@ function clientNoun(table) {
40079
40105
  }
40080
40106
 
40081
40107
  // src/PortalsPanel.tsx
40082
- import { copyText as copyText6 } from "@ai-matrx/kit/clipboard";
40108
+ import { copyText as copyText7 } from "@ai-matrx/kit/clipboard";
40083
40109
  import { useCallback as useCallback50, useEffect as useEffect96, useMemo as useMemo65, useState as useState110 } from "react";
40084
40110
  import { useRecordsClient as useRecordsClient78 } from "@ai-matrx/records/react";
40085
40111
  import {
@@ -40685,7 +40711,7 @@ function CopyLink({ url, what }) {
40685
40711
  variant: "outline",
40686
40712
  onClick: () => {
40687
40713
  void (async () => {
40688
- if (await copyText6(url)) {
40714
+ if (await copyText7(url)) {
40689
40715
  setCopied(true);
40690
40716
  setShown(false);
40691
40717
  window.setTimeout(() => setCopied(false), 1600);
@@ -41988,7 +42014,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
41988
42014
  }
41989
42015
 
41990
42016
  // src/FormBuilder.tsx
41991
- import { copyText as copyText7 } from "@ai-matrx/kit/clipboard";
42017
+ import { copyText as copyText8 } from "@ai-matrx/kit/clipboard";
41992
42018
  import { ErrorBox as ErrorBox7 } from "@ai-matrx/design-system";
41993
42019
  import { useCallback as useCallback55, useEffect as useEffect101, useMemo as useMemo68, useRef as useRef56, useState as useState116 } from "react";
41994
42020
  import { DndContext, KeyboardSensor, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
@@ -42236,7 +42262,7 @@ function ThemeEditor({
42236
42262
  }
42237
42263
  var EMBED_LABELS = { inline: "Inline", popup: "Popup", slider: "Slider" };
42238
42264
  function EmbedSnippets({ url, label }) {
42239
- const { copyText: copyText14 } = useClipboard();
42265
+ const { copyText: copyText16 } = useClipboard();
42240
42266
  const [kind, setKind] = useState114("inline");
42241
42267
  const [copied, setCopied] = useState114(false);
42242
42268
  const snippet = formEmbedSnippet(kind, url, { label });
@@ -42250,7 +42276,7 @@ function EmbedSnippets({ url, label }) {
42250
42276
  size: "sm",
42251
42277
  variant: "outline",
42252
42278
  className: "ml-auto",
42253
- onClick: () => void copyText14(snippet).then((ok) => {
42279
+ onClick: () => void copyText16(snippet).then((ok) => {
42254
42280
  setCopied(Boolean(ok));
42255
42281
  window.setTimeout(() => setCopied(false), 1500);
42256
42282
  }),
@@ -43176,7 +43202,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
43176
43202
  await load();
43177
43203
  }
43178
43204
  async function copyLink(url) {
43179
- if (await copyText7(url)) {
43205
+ if (await copyText8(url)) {
43180
43206
  setCopied(true);
43181
43207
  setShownUrl(null);
43182
43208
  window.setTimeout(() => setCopied(false), 1600);
@@ -45986,7 +46012,7 @@ function TargetControl({
45986
46012
  }
45987
46013
 
45988
46014
  // src/QuestionPanel.tsx
45989
- import { copyText as copyText8 } from "@ai-matrx/kit/clipboard";
46015
+ import { copyText as copyText9 } from "@ai-matrx/kit/clipboard";
45990
46016
  import { useEffect as useEffect108, useMemo as useMemo72, useRef as useRef59, useState as useState124 } from "react";
45991
46017
  import { Badge as Badge24, BasicInput as BasicInput33, Button as Button97, Checkbox as Checkbox16, Label as Label26, Skeleton as Skeleton34, cn as cn88 } from "@ai-matrx/design-system";
45992
46018
  import { useFields as useFields31, useRecordsClient as useRecordsClient89 } from "@ai-matrx/records/react";
@@ -46158,7 +46184,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46158
46184
  const url = new URL(window.location.href);
46159
46185
  url.searchParams.set("view", "questions");
46160
46186
  url.searchParams.set("item", current.id);
46161
- void copyText8(url.toString());
46187
+ void copyText9(url.toString());
46162
46188
  };
46163
46189
  if (fields.loading || hidden === null) {
46164
46190
  return /* @__PURE__ */ jsxs139("div", { className: cn88("flex flex-col gap-2 p-3", className), "data-testid": "question-panel", children: [
@@ -47637,7 +47663,7 @@ function onePerKey3(all) {
47637
47663
  }
47638
47664
 
47639
47665
  // src/FormsPanel.tsx
47640
- import { copyText as copyText9 } from "@ai-matrx/kit/clipboard";
47666
+ import { copyText as copyText10 } from "@ai-matrx/kit/clipboard";
47641
47667
  import { useCallback as useCallback62, useEffect as useEffect110, useState as useState127 } from "react";
47642
47668
  import { useRecordsClient as useRecordsClient92, useTable as useTable34 } from "@ai-matrx/records/react";
47643
47669
  import { publicFormPath as publicFormPath2 } from "@ai-matrx/records";
@@ -47696,7 +47722,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
47696
47722
  );
47697
47723
  const [shown4, setShown] = useState127(null);
47698
47724
  const copy = useCallback62(async (url, formId) => {
47699
- if (await copyText9(url)) {
47725
+ if (await copyText10(url)) {
47700
47726
  setCopied(formId);
47701
47727
  setShown(null);
47702
47728
  window.setTimeout(() => setCopied(null), 1600);
@@ -48659,7 +48685,7 @@ function PublicRow({ row, fields }) {
48659
48685
  }
48660
48686
 
48661
48687
  // src/EmbedFrame.tsx
48662
- import { copyText as copyText10 } from "@ai-matrx/kit/clipboard";
48688
+ import { copyText as copyText11 } from "@ai-matrx/kit/clipboard";
48663
48689
  import { useCallback as useCallback67, useEffect as useEffect115, useState as useState132 } from "react";
48664
48690
  import { useRecordsClient as useRecordsClient97 } from "@ai-matrx/records/react";
48665
48691
  import { Button as Button104, Input as Input9, Skeleton as Skeleton42, Textarea as Textarea9, cn as cn95 } from "@ai-matrx/design-system";
@@ -48757,7 +48783,7 @@ function EmbedFrame({
48757
48783
  {
48758
48784
  size: "sm",
48759
48785
  variant: "outline",
48760
- onClick: () => void copyText10(snippet ?? ""),
48786
+ onClick: () => void copyText11(snippet ?? ""),
48761
48787
  children: "Copy"
48762
48788
  }
48763
48789
  ),
@@ -48795,7 +48821,7 @@ function useEmbedHandshake(args) {
48795
48821
  }
48796
48822
 
48797
48823
  // src/TablePage.tsx
48798
- import { copyText as copyText13 } from "@ai-matrx/kit/clipboard";
48824
+ import { copyText as copyText15 } from "@ai-matrx/kit/clipboard";
48799
48825
  import { useCallback as useCallback69, useEffect as useEffect118, useMemo as useMemo78, useRef as useRef62, useState as useState140 } from "react";
48800
48826
  import { archivedByLine as archivedByLine2 } from "@ai-matrx/records";
48801
48827
  import { tableShapeChanged as tableShapeChanged14, useFields as useFields37, useRecordsClient as useRecordsClient99, useSeededAnswer, useTable as useTable37, useTableArchive as useTableArchive2 } from "@ai-matrx/records/react";
@@ -48838,15 +48864,23 @@ function subscribeCalendarAction(args) {
48838
48864
  }
48839
48865
 
48840
48866
  // src/CalendarSubscribe.tsx
48841
- import { copyText as copyText11 } from "@ai-matrx/kit/clipboard";
48867
+ import { copyText as copyText12 } from "@ai-matrx/kit/clipboard";
48842
48868
  import { useState as useState133 } from "react";
48843
- import { Button as Button105, Dialog as Dialog15, DialogContent as DialogContent15, DialogHeader as DialogHeader15, DialogTitle as DialogTitle15, ErrorBox as ErrorBox8 } from "@ai-matrx/design-system";
48869
+
48870
+ // src/asRefusal.ts
48871
+ function asRefusal3(e, fallback) {
48872
+ if (e instanceof Error && e.message.trim() !== "") return e;
48873
+ return { message: fallback };
48874
+ }
48875
+
48876
+ // src/CalendarSubscribe.tsx
48877
+ import { Button as Button105, Dialog as Dialog15, DialogContent as DialogContent15, DialogHeader as DialogHeader15, DialogTitle as DialogTitle15 } from "@ai-matrx/design-system";
48844
48878
  import { jsx as jsx159, jsxs as jsxs148 } from "react/jsx-runtime";
48845
48879
  function CalendarLinkOnce({ url }) {
48846
48880
  const notify = useRecordsUi().notify;
48847
48881
  const [copied, setCopied] = useState133(false);
48848
48882
  const copy = async () => {
48849
- if (await copyText11(url)) {
48883
+ if (await copyText12(url)) {
48850
48884
  setCopied(true);
48851
48885
  notify?.success("Link copied");
48852
48886
  } else notify?.error("Couldn\u2019t copy the link");
@@ -48898,7 +48932,7 @@ function CalendarSubscribeDialog({
48898
48932
  });
48899
48933
  setUrl(port.urlFor(made.token));
48900
48934
  } catch (e) {
48901
- setError(e instanceof Error ? e.message : "The link could not be made");
48935
+ setError(asRefusal3(e, "The link could not be made"));
48902
48936
  } finally {
48903
48937
  setBusy(false);
48904
48938
  }
@@ -48908,22 +48942,14 @@ function CalendarSubscribeDialog({
48908
48942
  /* @__PURE__ */ jsx159("p", { className: "text-sm text-muted-foreground", children: "Shows the rows this view shows, read as you." }),
48909
48943
  url ? /* @__PURE__ */ jsx159(CalendarLinkOnce, { url }) : /* @__PURE__ */ jsxs148("div", { className: "flex flex-col gap-2", children: [
48910
48944
  /* @__PURE__ */ jsx159(Button105, { size: "sm", onClick: () => void make(), disabled: busy, "data-calendar-make": "", children: busy ? "Making\u2026" : "Make link" }),
48911
- error ? /* @__PURE__ */ jsx159(
48912
- ErrorBox8,
48913
- {
48914
- className: "text-sm text-destructive",
48915
- "data-calendar-error": "",
48916
- message: error,
48917
- operation: "Create a calendar link",
48918
- origin: "records-ui/CalendarSubscribe"
48919
- }
48920
- ) : null
48945
+ error ? /* @__PURE__ */ jsx159(RefusalNotice, { error }) : null
48921
48946
  ] })
48922
48947
  ] }) });
48923
48948
  }
48924
48949
 
48925
48950
  // src/viewShare.ts
48926
- import { exportCsv as exportCsv2 } from "@ai-matrx/records/core";
48951
+ import { copyText as copyText13 } from "@ai-matrx/kit/clipboard";
48952
+ import { exportCsv as exportCsv2, exportMarkdown as exportMarkdown2 } from "@ai-matrx/records/core";
48927
48953
  var NO_VIEW_REASON = "No saved view yet";
48928
48954
  function viewLink(tableId, viewId, origin) {
48929
48955
  return `${tableLink(tableId, origin)}?view=${encodeURIComponent(viewId)}`;
@@ -48962,6 +48988,56 @@ async function downloadViewCsv(args) {
48962
48988
  download(`${name}.csv`, "text/csv;charset=utf-8", exportCsv2(columns, rows));
48963
48989
  host.notify?.success(read.cut ? cutWords(read.rows.length) : "CSV downloaded");
48964
48990
  }
48991
+ function downloadMarkdownAction(args) {
48992
+ return {
48993
+ id: "download-markdown",
48994
+ label: "Download Markdown",
48995
+ icon: "file-text",
48996
+ group: "share",
48997
+ ...args.disabledReason ? { disabledReason: args.disabledReason } : {},
48998
+ run: args.run
48999
+ };
49000
+ }
49001
+ function copyMarkdownAction(args) {
49002
+ return {
49003
+ id: "copy-markdown",
49004
+ label: "Copy as Markdown",
49005
+ icon: "copy",
49006
+ group: "share",
49007
+ ...args.disabledReason ? { disabledReason: args.disabledReason } : {},
49008
+ run: args.run
49009
+ };
49010
+ }
49011
+ async function readViewMarkdown(args) {
49012
+ const { client, host, tableId, fields, view, labels } = args;
49013
+ const read = await readViewRows(client, tableId, fields, view, args.ceiling);
49014
+ if ("error" in read) return null;
49015
+ const columns = viewColumns(fields, view.presentation);
49016
+ const rows = await rowsForFile({ client, host, fields: columns, records: read.rows, labels });
49017
+ return { markdown: exportMarkdown2(columns, rows), cut: read.cut, count: read.rows.length };
49018
+ }
49019
+ async function downloadViewMarkdown(args) {
49020
+ const table = await readViewMarkdown(args);
49021
+ if (!table) {
49022
+ args.host.notify?.error("The Markdown could not be written");
49023
+ return;
49024
+ }
49025
+ const name = fileNameOf(args.tableName) || "records";
49026
+ download(`${name}.md`, "text/markdown;charset=utf-8", table.markdown);
49027
+ args.host.notify?.success(table.cut ? cutWords(table.count) : "Markdown downloaded");
49028
+ }
49029
+ async function copyViewMarkdown(args) {
49030
+ const table = await readViewMarkdown(args);
49031
+ if (!table) {
49032
+ args.host.notify?.error("The Markdown could not be written");
49033
+ return;
49034
+ }
49035
+ if (await copyText13(table.markdown)) {
49036
+ args.host.notify?.success(table.cut ? cutWords(table.count) : "Markdown copied");
49037
+ } else {
49038
+ args.host.notify?.error("Couldn\u2019t copy the Markdown");
49039
+ }
49040
+ }
48965
49041
 
48966
49042
  // src/RecordPanel.tsx
48967
49043
  import { Fragment as Fragment65, useState as useState134 } from "react";
@@ -49123,7 +49199,7 @@ function BreakDownDialog({
49123
49199
  }
49124
49200
 
49125
49201
  // src/TableReference.tsx
49126
- import { copyText as copyText12 } from "@ai-matrx/kit/clipboard";
49202
+ import { copyText as copyText14 } from "@ai-matrx/kit/clipboard";
49127
49203
  import { useCallback as useCallback68, useMemo as useMemo76, useState as useState136 } from "react";
49128
49204
  import { useContentTransferCapabilities as useContentTransferCapabilities2 } from "@ai-matrx/alchemy/react/workspace";
49129
49205
  import { Button as Button108, Dialog as Dialog17, DialogContent as DialogContent17, DialogHeader as DialogHeader17, DialogTitle as DialogTitle17 } from "@ai-matrx/design-system";
@@ -49161,7 +49237,7 @@ function TableReferenceDialog({
49161
49237
  async (choice) => {
49162
49238
  if (!port) return;
49163
49239
  try {
49164
- if (!await copyText12(await port.build(choice.reference))) throw new Error("clipboard refused");
49240
+ if (!await copyText14(await port.build(choice.reference))) throw new Error("clipboard refused");
49165
49241
  setCopied(choice.id);
49166
49242
  notify?.success("Reference copied");
49167
49243
  } catch {
@@ -49183,7 +49259,7 @@ function TableReferenceDialog({
49183
49259
  import { formatCount as formatCount7 } from "@ai-matrx/kit/format";
49184
49260
  import { useState as useState137 } from "react";
49185
49261
  import { tableShapeChanged as tableShapeChanged13, useRecordsClient as useRecordsClient98 } from "@ai-matrx/records/react";
49186
- import { Button as Button109, Dialog as Dialog18, DialogContent as DialogContent18, DialogFooter as DialogFooter11, DialogHeader as DialogHeader18, DialogTitle as DialogTitle18, ErrorBox as ErrorBox9, Input as Input10, Switch as Switch5 } from "@ai-matrx/design-system";
49262
+ import { Button as Button109, Dialog as Dialog18, DialogContent as DialogContent18, DialogFooter as DialogFooter11, DialogHeader as DialogHeader18, DialogTitle as DialogTitle18, ErrorBox as ErrorBox8, Input as Input10, Switch as Switch5 } from "@ai-matrx/design-system";
49187
49263
  import { Fragment as Fragment67, jsx as jsx163, jsxs as jsxs152 } from "react/jsx-runtime";
49188
49264
  function copyNameFor(name) {
49189
49265
  return `${name.trim() || "Table"} (copy)`;
@@ -49272,7 +49348,7 @@ function TableDuplicateDialog({ tableId, name, open, onOpenChange, onDuplicated
49272
49348
  /* @__PURE__ */ jsx163(Switch5, { checked: withRecords, disabled: copying, onCheckedChange: setWithRecords, "aria-label": "Copy its records" })
49273
49349
  ] }),
49274
49350
  phase.kind === "copying" ? /* @__PURE__ */ jsx163("p", { className: "text-xs text-muted-foreground", "data-table-duplicate-progress": "", children: phase.progress ? duplicateProgressWords(phase.progress) : "Starting the copy\u2026" }) : null,
49275
- phase.kind === "refused" ? /* @__PURE__ */ jsx163(ErrorBox9, { children: phase.sentence }) : null,
49351
+ phase.kind === "refused" ? /* @__PURE__ */ jsx163(ErrorBox8, { children: phase.sentence }) : null,
49276
49352
  problem && typed2 !== "" ? /* @__PURE__ */ jsx163("p", { className: "text-xs text-muted-foreground", children: problem }) : null
49277
49353
  ] }),
49278
49354
  /* @__PURE__ */ jsx163(DialogFooter11, { children: phase.kind === "done" ? /* @__PURE__ */ jsx163(Button109, { onClick: () => openCopy(phase.copy), "data-table-duplicate-open": "", children: "Open the copy" }) : /* @__PURE__ */ jsxs152(Fragment67, { children: [
@@ -50400,7 +50476,7 @@ function TablePage({
50400
50476
  viewId: view?.id ?? null,
50401
50477
  origin: actionOrigin,
50402
50478
  copy: async (text) => {
50403
- if (await copyText13(text)) {
50479
+ if (await copyText15(text)) {
50404
50480
  recordsUi.notify?.success("Link copied");
50405
50481
  } else {
50406
50482
  recordsUi.notify?.error("Couldn\u2019t copy the link");
@@ -50420,6 +50496,30 @@ function TablePage({
50420
50496
  labels: viewLabels
50421
50497
  })
50422
50498
  }),
50499
+ downloadMarkdownAction({
50500
+ ...mayDo.known && !mayDo.read ? { disabledReason: "Needs Viewer access" } : !allFields.data ? { disabledReason: "Reading this table\u2026" } : {},
50501
+ run: () => downloadViewMarkdown({
50502
+ client,
50503
+ host: recordsUi,
50504
+ tableId,
50505
+ tableName: table.data?.name ?? "",
50506
+ fields: allFields.data ?? [],
50507
+ view: viewReading,
50508
+ labels: viewLabels
50509
+ })
50510
+ }),
50511
+ copyMarkdownAction({
50512
+ ...mayDo.known && !mayDo.read ? { disabledReason: "Needs Viewer access" } : !allFields.data ? { disabledReason: "Reading this table\u2026" } : {},
50513
+ run: () => copyViewMarkdown({
50514
+ client,
50515
+ host: recordsUi,
50516
+ tableId,
50517
+ tableName: table.data?.name ?? "",
50518
+ fields: allFields.data ?? [],
50519
+ view: viewReading,
50520
+ labels: viewLabels
50521
+ })
50522
+ }),
50423
50523
  // THE PRIVATE CALENDAR LINK (CAL-FEED-UI): only where the host bound the doors.
50424
50524
  ...recordsUi.calendarFeed && organizationId ? [
50425
50525
  subscribeCalendarAction({
@@ -50433,7 +50533,7 @@ function TablePage({
50433
50533
  window.open(url, "_blank", "noopener,noreferrer");
50434
50534
  },
50435
50535
  copyText: async (url) => {
50436
- if (await copyText13(url)) {
50536
+ if (await copyText15(url)) {
50437
50537
  recordsUi.notify?.success("Link copied");
50438
50538
  } else {
50439
50539
  recordsUi.notify?.error("Couldn\u2019t copy the link");
@@ -51036,7 +51136,7 @@ import { formatCount as formatCount8 } from "@ai-matrx/kit/format";
51036
51136
  import { TapTargetSearchGroup as TapTargetSearchGroup2, TooltipProvider } from "@ai-matrx/design-system";
51037
51137
  import { MatrxTableCardShowMore as MatrxTableCardShowMore3 } from "@ai-matrx/design-system/data-table";
51038
51138
  import { useEffect as useEffect119, useMemo as useMemo79, useRef as useRef63, useState as useState141 } from "react";
51039
- import { Button as Button112, ErrorBox as ErrorBox10, Input as Input12, cn as cn98 } from "@ai-matrx/design-system";
51139
+ import { Button as Button112, ErrorBox as ErrorBox9, Input as Input12, cn as cn98 } from "@ai-matrx/design-system";
51040
51140
  import { SEED_FRESH_MS, useRecordsClient as useRecordsClient100, useSeededAnswerAt } from "@ai-matrx/records/react";
51041
51141
  import { Fragment as Fragment69, jsx as jsx167, jsxs as jsxs156 } from "react/jsx-runtime";
51042
51142
  var entityTitleColumn = entityNameColumn;
@@ -51093,7 +51193,7 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
51093
51193
  /* @__PURE__ */ jsx167("span", { className: "truncate font-medium", children: lane.label }),
51094
51194
  /* @__PURE__ */ jsx167("span", { className: "tabular-nums text-muted-foreground", children: cards.length })
51095
51195
  ] }),
51096
- refused && refused.to === lane.key ? /* @__PURE__ */ jsx167(ErrorBox10, { className: "rounded border border-destructive/40 px-1.5 py-1 text-xs text-destructive", message: refused.says, operation: "Move a card", origin: "records-ui/entityViews" }) : null,
51196
+ refused && refused.to === lane.key ? /* @__PURE__ */ jsx167(ErrorBox9, { className: "rounded border border-destructive/40 px-1.5 py-1 text-xs text-destructive", message: refused.says, operation: "Move a card", origin: "records-ui/entityViews" }) : null,
51097
51197
  cards.map((row) => /* @__PURE__ */ jsxs156(
51098
51198
  "article",
51099
51199
  {
@@ -51265,7 +51365,7 @@ function EntityTablePageBody({
51265
51365
  actions
51266
51366
  ] })
51267
51367
  ] }) : null,
51268
- addRefused ? /* @__PURE__ */ jsx167(ErrorBox10, { className: "rounded border border-destructive/40 px-1.5 py-1 text-xs text-destructive", message: addRefused, operation: "Add a row", origin: "records-ui/entityViews" }) : null,
51368
+ addRefused ? /* @__PURE__ */ jsx167(ErrorBox9, { className: "rounded border border-destructive/40 px-1.5 py-1 text-xs text-destructive", message: addRefused, operation: "Add a row", origin: "records-ui/entityViews" }) : null,
51269
51369
  entity.error ? /* @__PURE__ */ jsx167("p", { className: "px-1 py-3 text-xs text-muted-foreground", children: `This table could not be read: ${entity.error}` }) : layout === "board" && boardable ? /* @__PURE__ */ jsx167(EntityBoard, { entity, groupBy, onOpenRecord }) : /* @__PURE__ */ jsxs156(Fragment69, { children: [
51270
51370
  presentation === "embedded" && searchBox ? /* @__PURE__ */ jsx167("div", { className: "flex min-w-0 items-center justify-end", "data-records-entity-search": "", children: /* @__PURE__ */ jsx167(TooltipProvider, { children: /* @__PURE__ */ jsx167(
51271
51371
  TapTargetSearchGroup2,
@@ -51686,7 +51786,7 @@ function Decision({
51686
51786
 
51687
51787
  // src/CalendarLinks.tsx
51688
51788
  import { useCallback as useCallback70, useEffect as useEffect122, useState as useState143 } from "react";
51689
- import { Button as Button115, ErrorBox as ErrorBox11 } from "@ai-matrx/design-system";
51789
+ import { Button as Button115 } from "@ai-matrx/design-system";
51690
51790
  import { jsx as jsx172, jsxs as jsxs160 } from "react/jsx-runtime";
51691
51791
  var day = (iso) => iso ? new Date(iso).toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" }) : null;
51692
51792
  function CalendarLinks({ port }) {
@@ -51698,7 +51798,7 @@ function CalendarLinks({ port }) {
51698
51798
  setRows(await port.list());
51699
51799
  setError(null);
51700
51800
  } catch (e) {
51701
- setError(e instanceof Error ? e.message : "The links could not be read");
51801
+ setError(asRefusal3(e, "The links could not be read"));
51702
51802
  }
51703
51803
  }, [port]);
51704
51804
  useEffect122(() => {
@@ -51709,21 +51809,12 @@ function CalendarLinks({ port }) {
51709
51809
  await run();
51710
51810
  setError(null);
51711
51811
  } catch (e) {
51712
- setError(e instanceof Error ? e.message : "That didn\u2019t work");
51812
+ setError(asRefusal3(e, "That didn\u2019t work"));
51713
51813
  }
51714
51814
  };
51715
51815
  if (rows === null && !error) return /* @__PURE__ */ jsx172("p", { className: "text-sm text-muted-foreground", "data-calendar-links-loading": "", children: "Reading your links\u2026" });
51716
51816
  return /* @__PURE__ */ jsxs160("div", { className: "flex flex-col gap-2", "data-calendar-links": "", children: [
51717
- error ? /* @__PURE__ */ jsx172(
51718
- ErrorBox11,
51719
- {
51720
- className: "text-sm text-destructive",
51721
- "data-calendar-error": "",
51722
- message: error,
51723
- operation: "Manage calendar links",
51724
- origin: "records-ui/CalendarLinks"
51725
- }
51726
- ) : null,
51817
+ error ? /* @__PURE__ */ jsx172(RefusalNotice, { error }) : null,
51727
51818
  rows && rows.length === 0 ? /* @__PURE__ */ jsx172("p", { className: "text-sm text-muted-foreground", children: "No calendar links yet." }) : null,
51728
51819
  rows?.map((row) => /* @__PURE__ */ jsxs160("div", { className: "flex flex-col gap-2 rounded-md border px-3 py-2", "data-calendar-link-row": row.id, children: [
51729
51820
  /* @__PURE__ */ jsxs160("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [