@arbidocs/blocks 0.5.119 → 0.5.120

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.
Files changed (115) hide show
  1. package/dist/{ConnectedNativeDocxComparison-546ILGLW.cjs → ConnectedNativeDocxComparison-SGE4R3M4.cjs} +6 -6
  2. package/dist/{ConnectedNativeDocxComparison-546ILGLW.cjs.map → ConnectedNativeDocxComparison-SGE4R3M4.cjs.map} +1 -1
  3. package/dist/{ConnectedStreamedWordArtifact-S2ZFZLZQ.cjs → ConnectedStreamedWordArtifact-6MCLJRIT.cjs} +6 -6
  4. package/dist/{ConnectedStreamedWordArtifact-S2ZFZLZQ.cjs.map → ConnectedStreamedWordArtifact-6MCLJRIT.cjs.map} +1 -1
  5. package/dist/{DocumentReviewCard-ZSBZBGFK.cjs → DocumentReviewCard-BPIAJJED.cjs} +14 -14
  6. package/dist/{DocumentReviewCard-ZSBZBGFK.cjs.map → DocumentReviewCard-BPIAJJED.cjs.map} +1 -1
  7. package/dist/{FilesViewerDialog-6UKR5WEF.cjs → FilesViewerDialog-67WK3TZC.cjs} +11 -11
  8. package/dist/{FilesViewerDialog-6UKR5WEF.cjs.map → FilesViewerDialog-67WK3TZC.cjs.map} +1 -1
  9. package/dist/agents/index.cjs +185 -185
  10. package/dist/agents/tasks/ConversationListView.js +10 -2
  11. package/dist/agents/tasks/ConversationListView.js.map +2 -2
  12. package/dist/agents/tasks/TaskTable.js +5 -4
  13. package/dist/agents/tasks/TaskTable.js.map +2 -2
  14. package/dist/agents/tasks/WorkflowsTable.js +4 -5
  15. package/dist/agents/tasks/WorkflowsTable.js.map +2 -2
  16. package/dist/agents/tasks/taskColumns.js +1 -1
  17. package/dist/agents/tasks/taskColumns.js.map +1 -1
  18. package/dist/agents/tasks/taskTableLabels.js +1 -1
  19. package/dist/agents/tasks/taskTableLabels.js.map +1 -1
  20. package/dist/agents/tasks/workflowTableLabels.js +1 -1
  21. package/dist/agents/tasks/workflowTableLabels.js.map +1 -1
  22. package/dist/{chunk-P77YTTJ3.cjs → chunk-3GWWOYGS.cjs} +4 -4
  23. package/dist/{chunk-P77YTTJ3.cjs.map → chunk-3GWWOYGS.cjs.map} +1 -1
  24. package/dist/{chunk-HB2O4THB.cjs → chunk-5IZFSAEZ.cjs} +4 -4
  25. package/dist/{chunk-HB2O4THB.cjs.map → chunk-5IZFSAEZ.cjs.map} +1 -1
  26. package/dist/{chunk-DDIW4HLU.cjs → chunk-775S43W7.cjs} +19 -10
  27. package/dist/chunk-775S43W7.cjs.map +1 -0
  28. package/dist/{chunk-Y24V6HPR.cjs → chunk-BP3IJ34D.cjs} +4 -4
  29. package/dist/{chunk-Y24V6HPR.cjs.map → chunk-BP3IJ34D.cjs.map} +1 -1
  30. package/dist/{chunk-TT4IF52H.cjs → chunk-BUVIBHFU.cjs} +37 -38
  31. package/dist/chunk-BUVIBHFU.cjs.map +1 -0
  32. package/dist/{chunk-OEREKAAP.cjs → chunk-CKCG4NDB.cjs} +8 -8
  33. package/dist/{chunk-OEREKAAP.cjs.map → chunk-CKCG4NDB.cjs.map} +1 -1
  34. package/dist/{chunk-YGXOKB5Z.cjs → chunk-DFBDQKGE.cjs} +4 -4
  35. package/dist/{chunk-YGXOKB5Z.cjs.map → chunk-DFBDQKGE.cjs.map} +1 -1
  36. package/dist/{chunk-VGCTYTEW.cjs → chunk-ECLUFKYR.cjs} +4 -4
  37. package/dist/{chunk-VGCTYTEW.cjs.map → chunk-ECLUFKYR.cjs.map} +1 -1
  38. package/dist/{chunk-CPG7II4E.cjs → chunk-HA66DHW6.cjs} +28 -28
  39. package/dist/{chunk-CPG7II4E.cjs.map → chunk-HA66DHW6.cjs.map} +1 -1
  40. package/dist/{chunk-57NHXEU2.cjs → chunk-MXBXZXXQ.cjs} +5 -5
  41. package/dist/{chunk-57NHXEU2.cjs.map → chunk-MXBXZXXQ.cjs.map} +1 -1
  42. package/dist/{chunk-NNUK5ZM7.cjs → chunk-NLSWDP42.cjs} +9 -17
  43. package/dist/chunk-NLSWDP42.cjs.map +1 -0
  44. package/dist/{chunk-B2HNNG25.cjs → chunk-Q6CLWOP2.cjs} +29 -29
  45. package/dist/{chunk-B2HNNG25.cjs.map → chunk-Q6CLWOP2.cjs.map} +1 -1
  46. package/dist/{chunk-R7CJEIA5.cjs → chunk-QQWHG3KF.cjs} +5 -6
  47. package/dist/chunk-QQWHG3KF.cjs.map +1 -0
  48. package/dist/{chunk-VLCY46K6.cjs → chunk-TG2GM7WJ.cjs} +4 -3
  49. package/dist/chunk-TG2GM7WJ.cjs.map +1 -0
  50. package/dist/{chunk-QHOHDNBU.cjs → chunk-VZCPMXWC.cjs} +4 -4
  51. package/dist/{chunk-QHOHDNBU.cjs.map → chunk-VZCPMXWC.cjs.map} +1 -1
  52. package/dist/{chunk-NIE3N6OM.cjs → chunk-W6INT5GS.cjs} +5 -5
  53. package/dist/{chunk-NIE3N6OM.cjs.map → chunk-W6INT5GS.cjs.map} +1 -1
  54. package/dist/{chunk-ZPPMAL5P.cjs → chunk-WQMR3O2D.cjs} +6 -10
  55. package/dist/chunk-WQMR3O2D.cjs.map +1 -0
  56. package/dist/{chunk-SB4M3ITT.cjs → chunk-X36UR4A7.cjs} +173 -56
  57. package/dist/chunk-X36UR4A7.cjs.map +1 -0
  58. package/dist/{chunk-XKVPSOKP.cjs → chunk-YYSBWMDJ.cjs} +4 -4
  59. package/dist/{chunk-XKVPSOKP.cjs.map → chunk-YYSBWMDJ.cjs.map} +1 -1
  60. package/dist/collaboration/index.cjs +3 -3
  61. package/dist/collaboration/sharing/ShareControl.js +10 -2
  62. package/dist/collaboration/sharing/ShareControl.js.map +2 -2
  63. package/dist/components/SharedCell.d.ts +2 -4
  64. package/dist/components/SharedCell.js +4 -8
  65. package/dist/components/SharedCell.js.map +2 -2
  66. package/dist/connect/docx.cjs +9 -9
  67. package/dist/connect/index.cjs +595 -567
  68. package/dist/connect/index.cjs.map +1 -1
  69. package/dist/connect/viewer.cjs +9 -9
  70. package/dist/connection/facts/factPageColumns.js +3 -9
  71. package/dist/connection/facts/factPageColumns.js.map +2 -2
  72. package/dist/connection/files/grid/cells.js +1 -3
  73. package/dist/connection/files/grid/cells.js.map +2 -2
  74. package/dist/connection/files/grid/documentColumns.js +3 -2
  75. package/dist/connection/files/grid/documentColumns.js.map +2 -2
  76. package/dist/connection/sharing/WorkspaceMembersList.d.ts +4 -0
  77. package/dist/connection/sharing/WorkspaceMembersList.js +34 -0
  78. package/dist/connection/sharing/WorkspaceMembersList.js.map +7 -0
  79. package/dist/connection/shell/ConnectedAppShell.js +4 -0
  80. package/dist/connection/shell/ConnectedAppShell.js.map +2 -2
  81. package/dist/connection/viewer/ConnectedDocumentViewer.js +3 -2
  82. package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
  83. package/dist/connection/viewer/ViewerPdfPane.js +20 -2
  84. package/dist/connection/viewer/ViewerPdfPane.js.map +2 -2
  85. package/dist/connection/viewer/pdf/PdfPassageHighlights.d.ts +12 -0
  86. package/dist/connection/viewer/pdf/PdfPassageHighlights.js +36 -0
  87. package/dist/connection/viewer/pdf/PdfPassageHighlights.js.map +7 -0
  88. package/dist/connection/viewer/pdf/passageHighlights.d.ts +26 -0
  89. package/dist/connection/viewer/pdf/passageHighlights.js +40 -0
  90. package/dist/connection/viewer/pdf/passageHighlights.js.map +7 -0
  91. package/dist/connection/viewer/pdf/usePdfPassageHighlights.d.ts +9 -0
  92. package/dist/connection/viewer/pdf/usePdfPassageHighlights.js +47 -0
  93. package/dist/connection/viewer/pdf/usePdfPassageHighlights.js.map +7 -0
  94. package/dist/connection/workflows/workflowsPageLabels.js +1 -1
  95. package/dist/connection/workflows/workflowsPageLabels.js.map +1 -1
  96. package/dist/embed/index.cjs +13 -13
  97. package/dist/facts/factColumns.js +3 -3
  98. package/dist/facts/factColumns.js.map +1 -1
  99. package/dist/facts/index.cjs +42 -42
  100. package/dist/files/HtmlViewerParts.js +7 -15
  101. package/dist/files/HtmlViewerParts.js.map +2 -2
  102. package/dist/files/index.cjs +223 -223
  103. package/dist/index.cjs +238 -238
  104. package/dist/styles.css +1 -1
  105. package/dist/workflow-canvas/index.cjs +24 -24
  106. package/dist/workflow-canvas/index.cjs.map +1 -1
  107. package/node_modules/@arbidocs/coedit/package.json +1 -1
  108. package/package.json +5 -5
  109. package/dist/chunk-DDIW4HLU.cjs.map +0 -1
  110. package/dist/chunk-NNUK5ZM7.cjs.map +0 -1
  111. package/dist/chunk-R7CJEIA5.cjs.map +0 -1
  112. package/dist/chunk-SB4M3ITT.cjs.map +0 -1
  113. package/dist/chunk-TT4IF52H.cjs.map +0 -1
  114. package/dist/chunk-VLCY46K6.cjs.map +0 -1
  115. package/dist/chunk-ZPPMAL5P.cjs.map +0 -1
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/connection/viewer/pdf/PdfPassageHighlights.tsx"],
4
+ "sourcesContent": ["/**\n * The lit passages of one PDF page, drawn over it. The boxes are fractions of the page, so the layer\n * fills the page area and scales with it; it takes no pointer events, so the PDF stays selectable.\n */\n\nimport { cn } from '@arbidocs/react/ui'\nimport type { PdfPassageBox } from './passageHighlights'\n\nexport interface PdfPassageHighlightsProps {\n boxes: readonly PdfPassageBox[]\n /** The passage being read: its box is told to the host once it is drawn, to bring it into view. */\n activeId: string | null\n onActiveDrawn: (element: HTMLElement) => void\n}\n\nexport function PdfPassageHighlights({\n boxes,\n activeId,\n onActiveDrawn,\n}: PdfPassageHighlightsProps) {\n return (\n <div className=\"pointer-events-none absolute inset-0\" data-testid=\"pdf-passage-highlights\">\n {boxes.map(({ chunkId, box: [x0, y0, x1, y1], highlight }) => (\n <div\n key={chunkId}\n ref={\n chunkId === activeId\n ? (element) => {\n if (element) onActiveDrawn(element)\n }\n : undefined\n }\n data-testid=\"pdf-passage-highlight\"\n data-chunk-id={chunkId}\n data-highlight={highlight}\n className={cn(\n // multiplied, so the page's text stays as dark as it was under the wash\n 'absolute rounded-sm mix-blend-multiply',\n highlight === 'strong' ? 'bg-ai-soft ring-1 ring-ai-accent/50' : 'bg-ai-soft/60'\n )}\n style={{\n left: `${x0 * 100}%`,\n top: `${y0 * 100}%`,\n width: `${(x1 - x0) * 100}%`,\n height: `${(y1 - y0) * 100}%`,\n }}\n />\n ))}\n </div>\n )\n}\n"],
5
+ "mappings": ";AAuBQ;AAlBR,SAAS,UAAU;AAUZ,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AACF,GAA8B;AAC5B,SACE,oBAAC,SAAI,WAAU,wCAAuC,eAAY,0BAC/D,gBAAM,IAAI,CAAC,EAAE,SAAS,KAAK,CAAC,IAAI,IAAI,IAAI,EAAE,GAAG,UAAU,MACtD;AAAA,IAAC;AAAA;AAAA,MAEC,KACE,YAAY,WACR,CAAC,YAAY;AACX,YAAI,QAAS,eAAc,OAAO;AAAA,MACpC,IACA;AAAA,MAEN,eAAY;AAAA,MACZ,iBAAe;AAAA,MACf,kBAAgB;AAAA,MAChB,WAAW;AAAA;AAAA,QAET;AAAA,QACA,cAAc,WAAW,wCAAwC;AAAA,MACnE;AAAA,MACA,OAAO;AAAA,QACL,MAAM,GAAG,KAAK,GAAG;AAAA,QACjB,KAAK,GAAG,KAAK,GAAG;AAAA,QAChB,OAAO,IAAI,KAAK,MAAM,GAAG;AAAA,QACzB,QAAQ,IAAI,KAAK,MAAM,GAAG;AAAA,MAC5B;AAAA;AAAA,IArBK;AAAA,EAsBP,CACD,GACH;AAEJ;",
6
+ "names": []
7
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Which passages light up on the PDF, and where. The rules are the parsed view's (`ParsedPassage`):
3
+ * while a fact's Citation popover is open its cited passages are light and the one being read is
4
+ * strong; otherwise the passage a citation opened the document at is the one lit. A passage's box
5
+ * is the parser's (`page_bbox`: fractions of its page, top-left origin), so it lands on the page
6
+ * at any zoom.
7
+ */
8
+ import type { ProcessedPage } from '@arbidocs/react/viewers';
9
+ import type { PassageHighlight } from '../../../files';
10
+ /** [x0, y0, x1, y1] as fractions of the page. */
11
+ export type PageBox = readonly [number, number, number, number];
12
+ export interface PdfPassageBox {
13
+ chunkId: string;
14
+ box: PageBox;
15
+ highlight: PassageHighlight;
16
+ }
17
+ export interface PassageHighlightState {
18
+ /** A fact's cited passages (its Citation popover is open); empty when none is. */
19
+ cited: ReadonlySet<string>;
20
+ /** The passage being read: the one a citation opened the document at. */
21
+ active: string | null;
22
+ }
23
+ /** How a passage is lit, or null when it is not. */
24
+ export declare function passageHighlight(chunkId: string, { cited, active }: PassageHighlightState): PassageHighlight | null;
25
+ /** The lit passages' boxes, by page number. Passages without a usable box are left out. */
26
+ export declare function passageBoxesByPage(pages: readonly ProcessedPage[], state: PassageHighlightState): Map<number, PdfPassageBox[]>;
@@ -0,0 +1,40 @@
1
+ "use client";
2
+ function passageHighlight(chunkId, { cited, active }) {
3
+ if (cited.size > 0) {
4
+ if (!cited.has(chunkId)) return null;
5
+ return chunkId === active ? "strong" : "light";
6
+ }
7
+ return chunkId === active ? "light" : null;
8
+ }
9
+ function asBox(bbox) {
10
+ if (!bbox || bbox.length !== 4 || !bbox.every(Number.isFinite)) return null;
11
+ const [x0, y0, x1, y1] = bbox;
12
+ if (x1 <= x0 || y1 <= y0) return null;
13
+ return [x0, y0, x1, y1];
14
+ }
15
+ function isWholePage([x0, y0, x1, y1]) {
16
+ return x0 <= 0 && y0 <= 0 && x1 >= 1 && y1 >= 1;
17
+ }
18
+ function passageBoxesByPage(pages, state) {
19
+ const byPage = /* @__PURE__ */ new Map();
20
+ if (state.cited.size === 0 && !state.active) return byPage;
21
+ for (const page of pages) {
22
+ if (page.pageNumber === null) continue;
23
+ for (const chunk of page.chunks) {
24
+ const chunkId = chunk.chunkExtId;
25
+ if (!chunkId) continue;
26
+ const highlight = passageHighlight(chunkId, state);
27
+ const box = highlight && asBox(chunk.pageBbox);
28
+ if (!highlight || !box || isWholePage(box)) continue;
29
+ const boxes = byPage.get(page.pageNumber) ?? [];
30
+ boxes.push({ chunkId, box, highlight });
31
+ byPage.set(page.pageNumber, boxes);
32
+ }
33
+ }
34
+ return byPage;
35
+ }
36
+ export {
37
+ passageBoxesByPage,
38
+ passageHighlight
39
+ };
40
+ //# sourceMappingURL=passageHighlights.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/connection/viewer/pdf/passageHighlights.ts"],
4
+ "sourcesContent": ["/**\n * Which passages light up on the PDF, and where. The rules are the parsed view's (`ParsedPassage`):\n * while a fact's Citation popover is open its cited passages are light and the one being read is\n * strong; otherwise the passage a citation opened the document at is the one lit. A passage's box\n * is the parser's (`page_bbox`: fractions of its page, top-left origin), so it lands on the page\n * at any zoom.\n */\n\nimport type { ProcessedPage } from '@arbidocs/react/viewers'\nimport type { PassageHighlight } from '../../../files'\n\n/** [x0, y0, x1, y1] as fractions of the page. */\nexport type PageBox = readonly [number, number, number, number]\n\nexport interface PdfPassageBox {\n chunkId: string\n box: PageBox\n highlight: PassageHighlight\n}\n\nexport interface PassageHighlightState {\n /** A fact's cited passages (its Citation popover is open); empty when none is. */\n cited: ReadonlySet<string>\n /** The passage being read: the one a citation opened the document at. */\n active: string | null\n}\n\n/** How a passage is lit, or null when it is not. */\nexport function passageHighlight(\n chunkId: string,\n { cited, active }: PassageHighlightState\n): PassageHighlight | null {\n if (cited.size > 0) {\n if (!cited.has(chunkId)) return null\n return chunkId === active ? 'strong' : 'light'\n }\n return chunkId === active ? 'light' : null\n}\n\n/** A drawable box: four finite fractions with area. */\nfunction asBox(bbox: readonly number[] | undefined): PageBox | null {\n if (!bbox || bbox.length !== 4 || !bbox.every(Number.isFinite)) return null\n const [x0, y0, x1, y1] = bbox\n if (x1 <= x0 || y1 <= y0) return null\n return [x0, y0, x1, y1]\n}\n\n/**\n * The page's whole area: what the parser gives a chunk on a page where it recognized no block to\n * place it by. It says \"this page\", and a rectangle over the whole page would say nothing more.\n */\nfunction isWholePage([x0, y0, x1, y1]: PageBox): boolean {\n return x0 <= 0 && y0 <= 0 && x1 >= 1 && y1 >= 1\n}\n\n/** The lit passages' boxes, by page number. Passages without a usable box are left out. */\nexport function passageBoxesByPage(\n pages: readonly ProcessedPage[],\n state: PassageHighlightState\n): Map<number, PdfPassageBox[]> {\n const byPage = new Map<number, PdfPassageBox[]>()\n if (state.cited.size === 0 && !state.active) return byPage\n for (const page of pages) {\n if (page.pageNumber === null) continue\n for (const chunk of page.chunks) {\n const chunkId = chunk.chunkExtId\n if (!chunkId) continue\n const highlight = passageHighlight(chunkId, state)\n const box = highlight && asBox(chunk.pageBbox)\n if (!highlight || !box || isWholePage(box)) continue\n const boxes = byPage.get(page.pageNumber) ?? []\n boxes.push({ chunkId, box, highlight })\n byPage.set(page.pageNumber, boxes)\n }\n }\n return byPage\n}\n"],
5
+ "mappings": ";AA4BO,SAAS,iBACd,SACA,EAAE,OAAO,OAAO,GACS;AACzB,MAAI,MAAM,OAAO,GAAG;AAClB,QAAI,CAAC,MAAM,IAAI,OAAO,EAAG,QAAO;AAChC,WAAO,YAAY,SAAS,WAAW;AAAA,EACzC;AACA,SAAO,YAAY,SAAS,UAAU;AACxC;AAGA,SAAS,MAAM,MAAqD;AAClE,MAAI,CAAC,QAAQ,KAAK,WAAW,KAAK,CAAC,KAAK,MAAM,OAAO,QAAQ,EAAG,QAAO;AACvE,QAAM,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI;AACzB,MAAI,MAAM,MAAM,MAAM,GAAI,QAAO;AACjC,SAAO,CAAC,IAAI,IAAI,IAAI,EAAE;AACxB;AAMA,SAAS,YAAY,CAAC,IAAI,IAAI,IAAI,EAAE,GAAqB;AACvD,SAAO,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM;AAChD;AAGO,SAAS,mBACd,OACA,OAC8B;AAC9B,QAAM,SAAS,oBAAI,IAA6B;AAChD,MAAI,MAAM,MAAM,SAAS,KAAK,CAAC,MAAM,OAAQ,QAAO;AACpD,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,eAAe,KAAM;AAC9B,eAAW,SAAS,KAAK,QAAQ;AAC/B,YAAM,UAAU,MAAM;AACtB,UAAI,CAAC,QAAS;AACd,YAAM,YAAY,iBAAiB,SAAS,KAAK;AACjD,YAAM,MAAM,aAAa,MAAM,MAAM,QAAQ;AAC7C,UAAI,CAAC,aAAa,CAAC,OAAO,YAAY,GAAG,EAAG;AAC5C,YAAM,QAAQ,OAAO,IAAI,KAAK,UAAU,KAAK,CAAC;AAC9C,YAAM,KAAK,EAAE,SAAS,KAAK,UAAU,CAAC;AACtC,aAAO,IAAI,KAAK,YAAY,KAAK;AAAA,IACnC;AAAA,EACF;AACA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The passages a citation lights, drawn over the PDF page by page: a fact's cited passages (its
3
+ * Citation popover is open) and the passage a citation opened the document at, as the parsed view
4
+ * lights them. Nothing is fetched until one is lit; the parsed chunks are the parsed view's own
5
+ * query, so opening that tab afterwards costs nothing more.
6
+ */
7
+ import { type ReactNode } from 'react';
8
+ /** A PDF viewer's page overlay for the document being viewed: `(page) => highlights | null`. */
9
+ export declare function usePdfPassageHighlights(documentId: string | undefined): (pageNumber: number) => ReactNode;
@@ -0,0 +1,47 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useCallback, useEffect, useMemo, useRef } from "react";
4
+ import { useArbiSessionState, useParsedDocument } from "@arbidocs/react";
5
+ import { useProcessedChunks } from "@arbidocs/react/viewers";
6
+ import { useViewerPassageCitation } from "../support.js";
7
+ import { PdfPassageHighlights } from "./PdfPassageHighlights.js";
8
+ import { passageBoxesByPage } from "./passageHighlights.js";
9
+ const NONE = [];
10
+ const NO_FOOTNOTES = {};
11
+ function usePdfPassageHighlights(documentId) {
12
+ const citedIds = useViewerPassageCitation()?.highlighted ?? NONE;
13
+ const cited = useMemo(() => new Set(citedIds), [citedIds]);
14
+ const active = useArbiSessionState((s) => s.viewingDocument?.passageId ?? null);
15
+ const { data: parsed } = useParsedDocument(documentId, "final", {
16
+ enabled: cited.size > 0 || !!active
17
+ });
18
+ const { processedChunks } = useProcessedChunks(parsed?.chunks, NO_FOOTNOTES);
19
+ const boxesByPage = useMemo(
20
+ () => passageBoxesByPage(processedChunks, { cited, active }),
21
+ [processedChunks, cited, active]
22
+ );
23
+ const centredFor = useRef(null);
24
+ const activeKey = active ? `${documentId}:${active}` : null;
25
+ useEffect(() => {
26
+ if (!activeKey) centredFor.current = null;
27
+ }, [activeKey]);
28
+ const centre = useCallback(
29
+ (element) => {
30
+ if (!activeKey || centredFor.current === activeKey) return;
31
+ centredFor.current = activeKey;
32
+ element.scrollIntoView?.({ block: "center", behavior: "smooth" });
33
+ },
34
+ [activeKey]
35
+ );
36
+ return useCallback(
37
+ (pageNumber) => {
38
+ const boxes = boxesByPage.get(pageNumber);
39
+ return boxes ? /* @__PURE__ */ jsx(PdfPassageHighlights, { boxes, activeId: active, onActiveDrawn: centre }) : null;
40
+ },
41
+ [boxesByPage, active, centre]
42
+ );
43
+ }
44
+ export {
45
+ usePdfPassageHighlights
46
+ };
47
+ //# sourceMappingURL=usePdfPassageHighlights.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/connection/viewer/pdf/usePdfPassageHighlights.tsx"],
4
+ "sourcesContent": ["/**\n * The passages a citation lights, drawn over the PDF page by page: a fact's cited passages (its\n * Citation popover is open) and the passage a citation opened the document at, as the parsed view\n * lights them. Nothing is fetched until one is lit; the parsed chunks are the parsed view's own\n * query, so opening that tab afterwards costs nothing more.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, type ReactNode } from 'react'\nimport { useArbiSessionState, useParsedDocument } from '@arbidocs/react'\nimport { useProcessedChunks } from '@arbidocs/react/viewers'\nimport { useViewerPassageCitation } from '../support'\nimport { PdfPassageHighlights } from './PdfPassageHighlights'\nimport { passageBoxesByPage } from './passageHighlights'\n\nconst NONE: readonly string[] = []\nconst NO_FOOTNOTES: Record<string, string> = {}\n\n/** A PDF viewer's page overlay for the document being viewed: `(page) => highlights | null`. */\nexport function usePdfPassageHighlights(\n documentId: string | undefined\n): (pageNumber: number) => ReactNode {\n const citedIds = useViewerPassageCitation()?.highlighted ?? NONE\n const cited = useMemo(() => new Set(citedIds), [citedIds])\n const active = useArbiSessionState((s) => s.viewingDocument?.passageId ?? null)\n\n const { data: parsed } = useParsedDocument(documentId, 'final', {\n enabled: cited.size > 0 || !!active,\n })\n const { processedChunks } = useProcessedChunks(parsed?.chunks, NO_FOOTNOTES)\n const boxesByPage = useMemo(\n () => passageBoxesByPage(processedChunks, { cited, active }),\n [processedChunks, cited, active]\n )\n\n // The passage being read is brought into view once, when its page first draws it: the viewer\n // opens the page, this centres the passage on it, and scrolling away is then left alone.\n const centredFor = useRef<string | null>(null)\n const activeKey = active ? `${documentId}:${active}` : null\n useEffect(() => {\n if (!activeKey) centredFor.current = null\n }, [activeKey])\n const centre = useCallback(\n (element: HTMLElement) => {\n if (!activeKey || centredFor.current === activeKey) return\n centredFor.current = activeKey\n element.scrollIntoView?.({ block: 'center', behavior: 'smooth' })\n },\n [activeKey]\n )\n\n return useCallback(\n (pageNumber: number) => {\n const boxes = boxesByPage.get(pageNumber)\n return boxes ? (\n <PdfPassageHighlights boxes={boxes} activeId={active} onActiveDrawn={centre} />\n ) : null\n },\n [boxesByPage, active, centre]\n )\n}\n"],
5
+ "mappings": ";AAsDQ;AA/CR,SAAS,aAAa,WAAW,SAAS,cAA8B;AACxE,SAAS,qBAAqB,yBAAyB;AACvD,SAAS,0BAA0B;AACnC,SAAS,gCAAgC;AACzC,SAAS,4BAA4B;AACrC,SAAS,0BAA0B;AAEnC,MAAM,OAA0B,CAAC;AACjC,MAAM,eAAuC,CAAC;AAGvC,SAAS,wBACd,YACmC;AACnC,QAAM,WAAW,yBAAyB,GAAG,eAAe;AAC5D,QAAM,QAAQ,QAAQ,MAAM,IAAI,IAAI,QAAQ,GAAG,CAAC,QAAQ,CAAC;AACzD,QAAM,SAAS,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,aAAa,IAAI;AAE9E,QAAM,EAAE,MAAM,OAAO,IAAI,kBAAkB,YAAY,SAAS;AAAA,IAC9D,SAAS,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,EAC/B,CAAC;AACD,QAAM,EAAE,gBAAgB,IAAI,mBAAmB,QAAQ,QAAQ,YAAY;AAC3E,QAAM,cAAc;AAAA,IAClB,MAAM,mBAAmB,iBAAiB,EAAE,OAAO,OAAO,CAAC;AAAA,IAC3D,CAAC,iBAAiB,OAAO,MAAM;AAAA,EACjC;AAIA,QAAM,aAAa,OAAsB,IAAI;AAC7C,QAAM,YAAY,SAAS,GAAG,UAAU,IAAI,MAAM,KAAK;AACvD,YAAU,MAAM;AACd,QAAI,CAAC,UAAW,YAAW,UAAU;AAAA,EACvC,GAAG,CAAC,SAAS,CAAC;AACd,QAAM,SAAS;AAAA,IACb,CAAC,YAAyB;AACxB,UAAI,CAAC,aAAa,WAAW,YAAY,UAAW;AACpD,iBAAW,UAAU;AACrB,cAAQ,iBAAiB,EAAE,OAAO,UAAU,UAAU,SAAS,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,SAAO;AAAA,IACL,CAAC,eAAuB;AACtB,YAAM,QAAQ,YAAY,IAAI,UAAU;AACxC,aAAO,QACL,oBAAC,wBAAqB,OAAc,UAAU,QAAQ,eAAe,QAAQ,IAC3E;AAAA,IACN;AAAA,IACA,CAAC,aAAa,QAAQ,MAAM;AAAA,EAC9B;AACF;",
6
+ "names": []
7
+ }
@@ -9,7 +9,7 @@ const DEFAULT_CONNECTED_WORKFLOWS_PAGE_LABELS = {
9
9
  };
10
10
  const DEFAULT_WORKFLOWS_PAGE_TABLE_LABELS = {
11
11
  colName: "Workflow",
12
- colShared: "Visibility",
12
+ colShared: "Sharing",
13
13
  searchLabel: "Filter workflows",
14
14
  searchPlaceholder: "Filter\u2026",
15
15
  emptyTitle: "No workflows yet",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/connection/workflows/workflowsPageLabels.ts"],
4
- "sourcesContent": ["/** The Workflows page's words (`ConnectedWorkflowsPage`), and its table's. */\nimport type { TaskTriggerChipLabels } from '../../agents/tasks/TaskTriggerChip'\nimport type { WorkflowListLabels } from '../../agents/tasks/workflowTableLabels'\n\nexport interface ConnectedWorkflowsPageLabels {\n newWorkflow: string\n /** Opens the workflow whose history is shown. */\n edit: string\n editAria: string\n /** The builder's way back to the list. */\n back: string\n /** Runs the catalogue entry open in the builder. */\n runTemplate: string\n /** When a workflow with no trigger of its own starts. */\n manualTrigger: string\n}\n\nexport const DEFAULT_CONNECTED_WORKFLOWS_PAGE_LABELS: ConnectedWorkflowsPageLabels = {\n newWorkflow: 'New workflow',\n edit: 'Edit',\n editAria: 'Edit workflow',\n back: 'Workflows',\n runTemplate: 'Run',\n manualTrigger: 'When started manually',\n}\n\n/** The table's words on this page. */\nexport const DEFAULT_WORKFLOWS_PAGE_TABLE_LABELS: Partial<WorkflowListLabels> = {\n colName: 'Workflow',\n colShared: 'Visibility',\n searchLabel: 'Filter workflows',\n searchPlaceholder: 'Filter\u2026',\n emptyTitle: 'No workflows yet',\n emptyMessage:\n 'Build a workflow of steps for people and agents. Start it by hand, on a schedule, when something happens, or after a thread is marked done.',\n openLastRun: 'Open the latest thread',\n runs: 'History',\n run: 'Start now',\n moreActions: 'Workflow options',\n filterWorkflows: 'Workflows',\n}\n\n/** How the trigger chips say an \"after\" or a manual start on this page. */\nexport const WORKFLOWS_PAGE_TRIGGER_CHIP_LABELS: Partial<TaskTriggerChipLabels> = {\n after: (name) => `After \u201C${name}\u201D is marked done`,\n afterUnknown: 'After a thread is marked done',\n onDemand: 'Manual',\n}\n"],
4
+ "sourcesContent": ["/** The Workflows page's words (`ConnectedWorkflowsPage`), and its table's. */\nimport type { TaskTriggerChipLabels } from '../../agents/tasks/TaskTriggerChip'\nimport type { WorkflowListLabels } from '../../agents/tasks/workflowTableLabels'\n\nexport interface ConnectedWorkflowsPageLabels {\n newWorkflow: string\n /** Opens the workflow whose history is shown. */\n edit: string\n editAria: string\n /** The builder's way back to the list. */\n back: string\n /** Runs the catalogue entry open in the builder. */\n runTemplate: string\n /** When a workflow with no trigger of its own starts. */\n manualTrigger: string\n}\n\nexport const DEFAULT_CONNECTED_WORKFLOWS_PAGE_LABELS: ConnectedWorkflowsPageLabels = {\n newWorkflow: 'New workflow',\n edit: 'Edit',\n editAria: 'Edit workflow',\n back: 'Workflows',\n runTemplate: 'Run',\n manualTrigger: 'When started manually',\n}\n\n/** The table's words on this page. */\nexport const DEFAULT_WORKFLOWS_PAGE_TABLE_LABELS: Partial<WorkflowListLabels> = {\n colName: 'Workflow',\n colShared: 'Sharing',\n searchLabel: 'Filter workflows',\n searchPlaceholder: 'Filter\u2026',\n emptyTitle: 'No workflows yet',\n emptyMessage:\n 'Build a workflow of steps for people and agents. Start it by hand, on a schedule, when something happens, or after a thread is marked done.',\n openLastRun: 'Open the latest thread',\n runs: 'History',\n run: 'Start now',\n moreActions: 'Workflow options',\n filterWorkflows: 'Workflows',\n}\n\n/** How the trigger chips say an \"after\" or a manual start on this page. */\nexport const WORKFLOWS_PAGE_TRIGGER_CHIP_LABELS: Partial<TaskTriggerChipLabels> = {\n after: (name) => `After \u201C${name}\u201D is marked done`,\n afterUnknown: 'After a thread is marked done',\n onDemand: 'Manual',\n}\n"],
5
5
  "mappings": ";AAiBO,MAAM,0CAAwE;AAAA,EACnF,aAAa;AAAA,EACb,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,aAAa;AAAA,EACb,eAAe;AACjB;AAGO,MAAM,sCAAmE;AAAA,EAC9E,SAAS;AAAA,EACT,WAAW;AAAA,EACX,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,cACE;AAAA,EACF,aAAa;AAAA,EACb,MAAM;AAAA,EACN,KAAK;AAAA,EACL,aAAa;AAAA,EACb,iBAAiB;AACnB;AAGO,MAAM,qCAAqE;AAAA,EAChF,OAAO,CAAC,SAAS,eAAU,IAAI;AAAA,EAC/B,cAAc;AAAA,EACd,UAAU;AACZ;",
6
6
  "names": []
7
7
  }
@@ -1,17 +1,17 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkOEREKAAP_cjs = require('../chunk-OEREKAAP.cjs');
4
+ var chunkCKCG4NDB_cjs = require('../chunk-CKCG4NDB.cjs');
5
5
  require('../chunk-557MJ4IH.cjs');
6
- require('../chunk-Y24V6HPR.cjs');
7
- require('../chunk-P77YTTJ3.cjs');
6
+ require('../chunk-BP3IJ34D.cjs');
7
+ require('../chunk-3GWWOYGS.cjs');
8
8
  require('../chunk-6UTKM5AB.cjs');
9
9
  require('../chunk-TJY7XPDE.cjs');
10
10
  require('../chunk-XNW62J54.cjs');
11
11
  require('../chunk-KXIRVKCJ.cjs');
12
- require('../chunk-TT4IF52H.cjs');
12
+ require('../chunk-BUVIBHFU.cjs');
13
13
  require('../chunk-NJCK6V6U.cjs');
14
- require('../chunk-NNUK5ZM7.cjs');
14
+ require('../chunk-NLSWDP42.cjs');
15
15
  require('../chunk-223D4727.cjs');
16
16
  require('../chunk-SNUBQMIS.cjs');
17
17
  require('../chunk-P5AQYC4D.cjs');
@@ -22,12 +22,12 @@ require('../chunk-4B6HYQTW.cjs');
22
22
  require('../chunk-MZZ3SBQL.cjs');
23
23
  require('../chunk-NY3YUCOW.cjs');
24
24
  require('../chunk-325GVZE6.cjs');
25
- require('../chunk-ZPPMAL5P.cjs');
25
+ require('../chunk-WQMR3O2D.cjs');
26
26
  require('../chunk-ORELHENJ.cjs');
27
27
  require('../chunk-NWNVWO6L.cjs');
28
28
  require('../chunk-SK6HQ46Q.cjs');
29
29
  require('../chunk-E3Y7RI3J.cjs');
30
- require('../chunk-VLCY46K6.cjs');
30
+ require('../chunk-TG2GM7WJ.cjs');
31
31
  require('../chunk-OEJQFPWO.cjs');
32
32
  require('../chunk-TP5PGWIO.cjs');
33
33
  require('../chunk-I4IS6ST6.cjs');
@@ -84,27 +84,27 @@ require('../chunk-PLIF5CUV.cjs');
84
84
 
85
85
  Object.defineProperty(exports, "ArbiChat", {
86
86
  enumerable: true,
87
- get: function () { return chunkOEREKAAP_cjs.ArbiChat; }
87
+ get: function () { return chunkCKCG4NDB_cjs.ArbiChat; }
88
88
  });
89
89
  Object.defineProperty(exports, "ConnectedCompactLogin", {
90
90
  enumerable: true,
91
- get: function () { return chunkOEREKAAP_cjs.ConnectedCompactLogin; }
91
+ get: function () { return chunkCKCG4NDB_cjs.ConnectedCompactLogin; }
92
92
  });
93
93
  Object.defineProperty(exports, "ConnectedEmbeddedChat", {
94
94
  enumerable: true,
95
- get: function () { return chunkOEREKAAP_cjs.ConnectedEmbeddedChat; }
95
+ get: function () { return chunkCKCG4NDB_cjs.ConnectedEmbeddedChat; }
96
96
  });
97
97
  Object.defineProperty(exports, "ConnectedLoginPage", {
98
98
  enumerable: true,
99
- get: function () { return chunkOEREKAAP_cjs.ConnectedLoginPage; }
99
+ get: function () { return chunkCKCG4NDB_cjs.ConnectedLoginPage; }
100
100
  });
101
101
  Object.defineProperty(exports, "EmbeddedChatPanel", {
102
102
  enumerable: true,
103
- get: function () { return chunkOEREKAAP_cjs.EmbeddedChatPanel; }
103
+ get: function () { return chunkCKCG4NDB_cjs.EmbeddedChatPanel; }
104
104
  });
105
105
  Object.defineProperty(exports, "defaultHost", {
106
106
  enumerable: true,
107
- get: function () { return chunkOEREKAAP_cjs.defaultHost; }
107
+ get: function () { return chunkCKCG4NDB_cjs.defaultHost; }
108
108
  });
109
109
  Object.defineProperty(exports, "useConnection", {
110
110
  enumerable: true,
@@ -17,7 +17,7 @@ const DEFAULT_FACT_COLUMN_LABELS = {
17
17
  labels: "Labels",
18
18
  verified: "Verified",
19
19
  verifiedTooltip: "Verified by a human",
20
- shared: "Shared",
20
+ shared: "Sharing",
21
21
  sharedTooltip: "Shared with the workspace, or private to you & your agents",
22
22
  createdBy: "Created by",
23
23
  sources: "Sources",
@@ -240,8 +240,8 @@ function createFactColumns(slots) {
240
240
  headerTooltip: l.sharedTooltip,
241
241
  field: fieldOf("shared"),
242
242
  // minWidth (not just width) is raised too: AG Grid clamps any persisted width up to it.
243
- width: 110,
244
- minWidth: 110,
243
+ width: 124,
244
+ minWidth: 124,
245
245
  sortable: true,
246
246
  headerClass: "header-hcenter",
247
247
  cellDataType: "boolean",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/facts/factColumns.tsx"],
4
- "sourcesContent": ["/**\n * Column definitions for the Facts grid. Every column has an explicit `colId` (AG Grid persists\n * column state by id: see CLAUDE.md). The app supplies behaviour and app-specific cells through\n * slots; the structure, widths, sorting, filters and presentational cells live here.\n */\nimport type { CSSProperties, ReactNode } from 'react'\nimport type {\n ColDef,\n ICellRendererParams,\n IHeaderParams,\n ValueGetterParams,\n} from 'ag-grid-community'\nimport { CalendarDays, Paperclip, Quote } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { formatSpan } from '../timeline/span'\nimport { decodeWhitespaceEntities } from './fact-text'\nimport { testIdOr } from '../chat/test-id'\n\nexport interface FactColumnLabels {\n inChatHeaderTooltip: string\n inChatTitle: string\n notInChatTitle: string\n removeFromChat: string\n addToChat: string\n fact: string\n dates: string\n dateTitle: string\n labels: string\n verified: string\n verifiedTooltip: string\n shared: string\n sharedTooltip: string\n createdBy: string\n sources: string\n /** Tooltip of the Sources cell for `count` cited documents. */\n sourcedFrom: (count: number) => string\n createdAt: string\n updated: string\n id: string\n}\n\nexport const DEFAULT_FACT_COLUMN_LABELS: FactColumnLabels = {\n inChatHeaderTooltip: 'Facts added to this chat are always in context for this chat',\n inChatTitle: 'In this chat \u2014 always in context for it. Click to remove from chat.',\n notInChatTitle: 'Add to chat \u2014 always in context for this chat',\n removeFromChat: 'Remove from chat',\n addToChat: 'Add to chat',\n fact: 'Fact',\n dates: 'Dates',\n dateTitle: 'Date of the fact itself, not when this was saved',\n labels: 'Labels',\n verified: 'Verified',\n verifiedTooltip: 'Verified by a human',\n shared: 'Shared',\n sharedTooltip: 'Shared with the workspace, or private to you & your agents',\n createdBy: 'Created by',\n sources: 'Sources',\n sourcedFrom: (n) => `Sourced from ${n} document${n === 1 ? '' : 's'} \u2014 open the fact to see them`,\n createdAt: 'Created at',\n updated: 'Updated',\n id: 'ID',\n}\n\nexport interface FactColumnTestIds {\n inChat: (factId: string) => string\n text: (factId: string) => string\n date: (factId: string) => string\n}\n\n/** The fields of a fact the grid reads. Callers' richer types are accepted as-is. */\nexport interface FactRowView {\n external_id: string\n text: string\n confirmed: boolean\n shared: boolean\n date_start?: string | null\n date_end?: string | null\n timezone?: string | null\n tags?: Array<{ name: string }> | null\n citations?: unknown[] | null\n created_by_ext_id?: string | null\n created_at?: string | null\n updated_at?: string | null\n}\n\nexport interface FactColumnSlots<T extends FactRowView> {\n /** Whether the fact is in the host's current chat. With `onToggleInChat`, adds the In chat\n * column; a host without chats leaves both out. Read at render time: the host refreshes the\n * column when its chat changes. */\n isInChat?: (fact: T) => boolean\n /** Add the fact to the current chat, or take it out. */\n onToggleInChat?: (fact: T) => void\n /** Custom header (persistent filter button) for the columns that use one. */\n renderHeader: (params: IHeaderParams, colId: string) => ReactNode\n /** Row action menu, shown at the right edge of the Fact cell. */\n renderRowActions: (fact: T, params: ICellRendererParams<T>) => ReactNode\n /** Inline label picker for the Labels cell. */\n renderLabels: (fact: T, params: ICellRendererParams<T>) => ReactNode\n /** The Verified switch. */\n renderVerified: (fact: T) => ReactNode\n /** The Shared switch. */\n renderShared: (fact: T, params: ICellRendererParams<T>) => ReactNode\n /** The creator avatar. */\n renderCreator: (fact: T, params: ICellRendererParams<T>) => ReactNode\n /** Sort/filter value for the Created by column (the creator's display name). */\n getCreatorName: (params: ValueGetterParams<T>) => string\n /** Friendly display of an ISO timestamp (Created at / Updated). */\n formatDate: (iso: string) => string\n labels?: Partial<FactColumnLabels>\n testIds?: Partial<FactColumnTestIds>\n}\n\n/**\n * Date-filter params for a column whose value is an ISO string. AG Grid hands the comparator a JS\n * `Date` from the picker and the raw cell value; this compares UTC day components so a filter\n * never shifts a date by a day for viewers west of UTC.\n */\nexport const ISO_DATE_FILTER_PARAMS = {\n browserDatePicker: true,\n comparator: (filterDate: Date, cellValue: unknown): number => {\n if (!cellValue || typeof cellValue !== 'string') return -1\n const cell = new Date(cellValue)\n if (Number.isNaN(cell.getTime())) return -1\n const cellDay = Date.UTC(cell.getUTCFullYear(), cell.getUTCMonth(), cell.getUTCDate())\n const filterDay = Date.UTC(\n filterDate.getFullYear(),\n filterDate.getMonth(),\n filterDate.getDate()\n )\n return cellDay < filterDay ? -1 : cellDay > filterDay ? 1 : 0\n },\n}\n\n/** How many source documents a fact cites (the Sources column counts documents, not passages). */\nexport function sourceDocCount(fact: Pick<FactRowView, 'citations'> | undefined): number {\n return fact?.citations?.length ?? 0\n}\n\n/** Default left-to-right order; default-hidden columns trail. Every colId must be listed. */\nexport const DEFAULT_FACT_COLUMN_ORDER = [\n 'in_chat',\n 'text',\n 'sources',\n 'tags',\n 'date',\n 'confirmed',\n 'shared',\n 'created_by',\n 'created_at',\n 'updated_at',\n 'note_id',\n] as const\n\nexport function createFactColumns<T extends FactRowView>(slots: FactColumnSlots<T>): ColDef<T>[] {\n // AG Grid's `field` is a path type over the row; for a generic row we assert the known keys.\n const fieldOf = (name: keyof FactRowView) => name as ColDef<T>['field']\n const l = { ...DEFAULT_FACT_COLUMN_LABELS, ...slots.labels }\n const ids = slots.testIds\n\n const { isInChat, onToggleInChat } = slots\n const inChatColumn: ColDef<T>[] =\n isInChat && onToggleInChat\n ? [\n {\n colId: 'in_chat',\n headerName: '',\n headerComponent: () => (\n <span className=\"flex size-full items-center justify-center\">\n <Paperclip className=\"size-3.5 text-muted-foreground\" />\n </span>\n ),\n valueGetter: (params: ValueGetterParams<T>) =>\n params.data ? isInChat(params.data) : false,\n width: 44,\n minWidth: 44,\n maxWidth: 44,\n sortable: true,\n resizable: false,\n headerTooltip: l.inChatHeaderTooltip,\n cellClass: 'cell-hcenter',\n // A toggle, not a readout: a fact in the chat rides every message of it, so it flips\n // in place.\n cellRenderer: (params: ICellRendererParams<T>) => {\n if (!params.data) return null\n const fact = params.data\n const inChat = isInChat(fact)\n return (\n <button\n type=\"button\"\n onClick={() => onToggleInChat(fact)}\n title={inChat ? l.inChatTitle : l.notInChatTitle}\n aria-label={inChat ? l.removeFromChat : l.addToChat}\n aria-pressed={inChat}\n data-testid={testIdOr(ids?.inChat?.(fact.external_id), {\n testId: `facts-grid-in-chat-${fact.external_id}`,\n })}\n className=\"flex h-full items-center\"\n >\n <Paperclip\n className={cn(\n 'size-3.5',\n inChat\n ? 'text-primary'\n : 'text-muted-foreground/30 transition-colors hover:text-muted-foreground'\n )}\n />\n </button>\n )\n },\n },\n ]\n : []\n\n const columns: ColDef<T>[] = [\n ...inChatColumn,\n {\n colId: 'text',\n suppressHeaderFilterButton: true,\n headerComponent: (p: IHeaderParams) => slots.renderHeader(p, 'text'),\n headerName: l.fact,\n field: fieldOf('text'),\n flex: 3,\n minWidth: 280,\n sortable: true,\n filter: 'agTextColumnFilter',\n // Decode the editor's whitespace entities (`&#x20;` for a trailing space) so the tooltip\n // reads as typed, not as raw markdown references.\n tooltipValueGetter: (p) => decodeWhitespaceEntities(p.data?.text),\n // Editable only via the grid api (Rename in the row's menu); clicks never open the editor\n // (suppressClickEdit on the grid).\n editable: true,\n cellEditor: 'agLargeTextCellEditor',\n cellEditorPopup: true,\n cellEditorParams: { rows: 8, cols: 60 },\n valueSetter: (params) => {\n if (!params.data) return false\n params.data.text = params.newValue\n return true\n },\n // NOT `cell-multiline`: this cell has its OWN clamp (the `.fact-clamp` span below, sized\n // from the row height). A second clamp cut the text in half at the minimum row height.\n cellClass: 'relative',\n cellRenderer: (params: ICellRendererParams<T>) => {\n if (!params.data) return null\n const fact = params.data\n // Clamp to however many WHOLE lines fit the row height (leading-snug ~ 20px/line),\n // top-aligned so the BEGINNING of the fact is always shown. No overflow clip here: the\n // wrapper is the cell's content box, shorter than a line at the density floor.\n const rowH = params.node.rowHeight ?? 52\n const clampLines = Math.max(1, Math.floor(rowH / 20))\n return (\n <div className=\"relative flex size-full items-start pr-6\">\n <span\n className=\"fact-clamp whitespace-normal break-words text-sm leading-snug text-foreground\"\n style={{ ['--fact-clamp-lines' as string]: clampLines } as CSSProperties}\n data-testid={testIdOr(ids?.text?.(fact.external_id), {\n testId: `facts-grid-text-${fact.external_id}`,\n })}\n >\n {decodeWhitespaceEntities(fact.text)}\n </span>\n {/* `facts-row-kebab` (app CSS) keeps the menu always visible: touch has no hover. */}\n <div className=\"facts-row-kebab absolute right-0.5 top-1/2 -translate-y-1/2\">\n {slots.renderRowActions(fact, params)}\n </div>\n </div>\n )\n },\n },\n {\n colId: 'date',\n // AG Grid's DEFAULT header, so the sort arrow and filter button are the native ones,\n // identical to the Files table's Date columns.\n headerName: l.dates,\n // Sort on the raw bound rather than the rendered string (\"Oct 2019\" sorts April first).\n field: fieldOf('date_start'),\n flex: 0.8,\n minWidth: 132,\n sortable: true,\n filter: 'agDateColumnFilter',\n filterParams: ISO_DATE_FILTER_PARAMS,\n // The edit value is the date-only slice: a lexical sort matches a chronological one, and\n // the inline editor shows \"2024-03-12\" rather than a full ISO timestamp. Inline typing\n // accepts YYYY, YYYY-MM or YYYY-MM-DD; clearing the cell undates the fact.\n editable: true,\n singleClickEdit: true,\n valueGetter: (params: ValueGetterParams<T>) =>\n params.data?.date_start ? params.data.date_start.slice(0, 10) : null,\n valueSetter: (params) => {\n if (!params.data) return false\n params.data.date_start = params.newValue\n return true\n },\n cellClass: 'relative cell-tnum',\n cellRenderer: (params: ICellRendererParams<T>) => {\n const when = formatSpan(\n params.data?.date_start,\n params.data?.date_end,\n params.data?.timezone\n )\n if (!when) return <span className=\"text-muted-foreground/50\">\u2014</span>\n return (\n <span\n className=\"inline-flex items-center gap-1\"\n data-testid={testIdOr(ids?.date?.(params.data?.external_id ?? ''), {\n testId: `facts-grid-date-${params.data?.external_id}`,\n })}\n title={l.dateTitle}\n >\n <CalendarDays className=\"size-3 opacity-70\" />\n {when}\n </span>\n )\n },\n },\n {\n colId: 'tags',\n suppressHeaderFilterButton: true,\n headerComponent: (p: IHeaderParams) => slots.renderHeader(p, 'tags'),\n headerName: l.labels,\n flex: 0.9,\n // Never narrower than its own header, even with the filter button and sort indicator.\n minWidth: 160,\n sortable: true,\n filter: 'agTextColumnFilter',\n cellClass: 'overflow-visible',\n valueGetter: (params: ValueGetterParams<T>) =>\n (params.data?.tags ?? []).map((t) => t.name).join(', '),\n // Editable in place: toggling a label persists immediately, no dialog round-trip.\n cellRenderer: (params: ICellRendererParams<T>) =>\n params.data ? slots.renderLabels(params.data, params) : null,\n },\n {\n colId: 'confirmed',\n headerName: l.verified,\n headerTooltip: l.verifiedTooltip,\n field: fieldOf('confirmed'),\n // minWidth matches width so the header can't be clamped narrow enough to ellipsize.\n width: 116,\n minWidth: 116,\n sortable: true,\n cellDataType: 'boolean',\n valueGetter: (params) => params.data?.confirmed ?? false,\n cellClass: 'cell-hcenter',\n headerClass: 'header-hcenter',\n cellRenderer: (params: ICellRendererParams<T>) =>\n params.data ? (\n <div className=\"flex h-full items-center justify-center\">\n {slots.renderVerified(params.data)}\n </div>\n ) : null,\n },\n {\n colId: 'shared',\n headerName: l.shared,\n headerTooltip: l.sharedTooltip,\n field: fieldOf('shared'),\n // minWidth (not just width) is raised too: AG Grid clamps any persisted width up to it.\n width: 110,\n minWidth: 110,\n sortable: true,\n headerClass: 'header-hcenter',\n cellDataType: 'boolean',\n valueGetter: (params) => params.data?.shared ?? false,\n cellRenderer: (params: ICellRendererParams<T>) =>\n params.data ? (\n <div className=\"flex h-full items-center justify-center\">\n {slots.renderShared(params.data, params)}\n </div>\n ) : null,\n },\n {\n colId: 'created_by',\n headerName: l.createdBy,\n headerTooltip: l.createdBy,\n width: 138,\n minWidth: 138,\n sortable: true,\n valueGetter: (params) => slots.getCreatorName(params),\n cellRenderer: (params: ICellRendererParams<T>) =>\n params.data ? (\n <div className=\"flex h-full items-center justify-center\">\n {slots.renderCreator(params.data, params)}\n </div>\n ) : null,\n },\n {\n colId: 'sources',\n headerName: l.sources,\n width: 112,\n minWidth: 104,\n sortable: true,\n // A hand-written fact has no sources, which is information rather than a gap: it reads as\n // an em dash instead of a zero.\n valueGetter: (params) => sourceDocCount(params.data),\n cellRenderer: (params: ICellRendererParams<T>) => {\n const n = sourceDocCount(params.data)\n if (n === 0) return <span className=\"text-muted-foreground/40\">\u2014</span>\n return (\n <span\n className=\"inline-flex items-center gap-1 text-xs text-muted-foreground\"\n title={l.sourcedFrom(n)}\n >\n <Quote className=\"size-3 opacity-70\" />\n {n}\n </span>\n )\n },\n },\n {\n colId: 'created_at',\n suppressHeaderFilterButton: true,\n headerComponent: (p: IHeaderParams) => slots.renderHeader(p, 'created_at'),\n headerName: l.createdAt,\n field: fieldOf('created_at'),\n width: 162,\n minWidth: 154,\n sortable: true,\n filter: 'agDateColumnFilter',\n filterParams: ISO_DATE_FILTER_PARAMS,\n // Display-only: a valueFormatter avoids mounting a React component per row.\n cellClass: 'text-muted-foreground',\n valueFormatter: (params) => (params.value ? slots.formatDate(params.value) : ''),\n },\n {\n colId: 'updated_at',\n suppressHeaderFilterButton: true,\n headerComponent: (p: IHeaderParams) => slots.renderHeader(p, 'updated_at'),\n headerName: l.updated,\n field: fieldOf('updated_at'),\n width: 140,\n minWidth: 140,\n // Hidden by default: a column-menu opt-in like the documents grid's long tail.\n hide: true,\n sortable: true,\n filter: 'agDateColumnFilter',\n filterParams: ISO_DATE_FILTER_PARAMS,\n valueFormatter: (params) => (params.value ? slots.formatDate(params.value) : ''),\n },\n {\n colId: 'note_id',\n headerName: l.id,\n field: fieldOf('external_id'),\n width: 120,\n minWidth: 100,\n sortable: true,\n filter: 'agTextColumnFilter',\n // Hidden by default like the documents ID column: needed when quoting a fact to support.\n hide: true,\n cellClass: 'font-mono text-xs text-muted-foreground',\n },\n ]\n\n // Persisted per-user column order still wins once set; bump the grid id to apply a new default.\n return DEFAULT_FACT_COLUMN_ORDER.map((id) => columns.find((c) => c.colId === id)).filter(\n (c): c is ColDef<T> => c !== undefined\n )\n}\n"],
4
+ "sourcesContent": ["/**\n * Column definitions for the Facts grid. Every column has an explicit `colId` (AG Grid persists\n * column state by id: see CLAUDE.md). The app supplies behaviour and app-specific cells through\n * slots; the structure, widths, sorting, filters and presentational cells live here.\n */\nimport type { CSSProperties, ReactNode } from 'react'\nimport type {\n ColDef,\n ICellRendererParams,\n IHeaderParams,\n ValueGetterParams,\n} from 'ag-grid-community'\nimport { CalendarDays, Paperclip, Quote } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { formatSpan } from '../timeline/span'\nimport { decodeWhitespaceEntities } from './fact-text'\nimport { testIdOr } from '../chat/test-id'\n\nexport interface FactColumnLabels {\n inChatHeaderTooltip: string\n inChatTitle: string\n notInChatTitle: string\n removeFromChat: string\n addToChat: string\n fact: string\n dates: string\n dateTitle: string\n labels: string\n verified: string\n verifiedTooltip: string\n shared: string\n sharedTooltip: string\n createdBy: string\n sources: string\n /** Tooltip of the Sources cell for `count` cited documents. */\n sourcedFrom: (count: number) => string\n createdAt: string\n updated: string\n id: string\n}\n\nexport const DEFAULT_FACT_COLUMN_LABELS: FactColumnLabels = {\n inChatHeaderTooltip: 'Facts added to this chat are always in context for this chat',\n inChatTitle: 'In this chat \u2014 always in context for it. Click to remove from chat.',\n notInChatTitle: 'Add to chat \u2014 always in context for this chat',\n removeFromChat: 'Remove from chat',\n addToChat: 'Add to chat',\n fact: 'Fact',\n dates: 'Dates',\n dateTitle: 'Date of the fact itself, not when this was saved',\n labels: 'Labels',\n verified: 'Verified',\n verifiedTooltip: 'Verified by a human',\n shared: 'Sharing',\n sharedTooltip: 'Shared with the workspace, or private to you & your agents',\n createdBy: 'Created by',\n sources: 'Sources',\n sourcedFrom: (n) => `Sourced from ${n} document${n === 1 ? '' : 's'} \u2014 open the fact to see them`,\n createdAt: 'Created at',\n updated: 'Updated',\n id: 'ID',\n}\n\nexport interface FactColumnTestIds {\n inChat: (factId: string) => string\n text: (factId: string) => string\n date: (factId: string) => string\n}\n\n/** The fields of a fact the grid reads. Callers' richer types are accepted as-is. */\nexport interface FactRowView {\n external_id: string\n text: string\n confirmed: boolean\n shared: boolean\n date_start?: string | null\n date_end?: string | null\n timezone?: string | null\n tags?: Array<{ name: string }> | null\n citations?: unknown[] | null\n created_by_ext_id?: string | null\n created_at?: string | null\n updated_at?: string | null\n}\n\nexport interface FactColumnSlots<T extends FactRowView> {\n /** Whether the fact is in the host's current chat. With `onToggleInChat`, adds the In chat\n * column; a host without chats leaves both out. Read at render time: the host refreshes the\n * column when its chat changes. */\n isInChat?: (fact: T) => boolean\n /** Add the fact to the current chat, or take it out. */\n onToggleInChat?: (fact: T) => void\n /** Custom header (persistent filter button) for the columns that use one. */\n renderHeader: (params: IHeaderParams, colId: string) => ReactNode\n /** Row action menu, shown at the right edge of the Fact cell. */\n renderRowActions: (fact: T, params: ICellRendererParams<T>) => ReactNode\n /** Inline label picker for the Labels cell. */\n renderLabels: (fact: T, params: ICellRendererParams<T>) => ReactNode\n /** The Verified switch. */\n renderVerified: (fact: T) => ReactNode\n /** The Shared switch. */\n renderShared: (fact: T, params: ICellRendererParams<T>) => ReactNode\n /** The creator avatar. */\n renderCreator: (fact: T, params: ICellRendererParams<T>) => ReactNode\n /** Sort/filter value for the Created by column (the creator's display name). */\n getCreatorName: (params: ValueGetterParams<T>) => string\n /** Friendly display of an ISO timestamp (Created at / Updated). */\n formatDate: (iso: string) => string\n labels?: Partial<FactColumnLabels>\n testIds?: Partial<FactColumnTestIds>\n}\n\n/**\n * Date-filter params for a column whose value is an ISO string. AG Grid hands the comparator a JS\n * `Date` from the picker and the raw cell value; this compares UTC day components so a filter\n * never shifts a date by a day for viewers west of UTC.\n */\nexport const ISO_DATE_FILTER_PARAMS = {\n browserDatePicker: true,\n comparator: (filterDate: Date, cellValue: unknown): number => {\n if (!cellValue || typeof cellValue !== 'string') return -1\n const cell = new Date(cellValue)\n if (Number.isNaN(cell.getTime())) return -1\n const cellDay = Date.UTC(cell.getUTCFullYear(), cell.getUTCMonth(), cell.getUTCDate())\n const filterDay = Date.UTC(\n filterDate.getFullYear(),\n filterDate.getMonth(),\n filterDate.getDate()\n )\n return cellDay < filterDay ? -1 : cellDay > filterDay ? 1 : 0\n },\n}\n\n/** How many source documents a fact cites (the Sources column counts documents, not passages). */\nexport function sourceDocCount(fact: Pick<FactRowView, 'citations'> | undefined): number {\n return fact?.citations?.length ?? 0\n}\n\n/** Default left-to-right order; default-hidden columns trail. Every colId must be listed. */\nexport const DEFAULT_FACT_COLUMN_ORDER = [\n 'in_chat',\n 'text',\n 'sources',\n 'tags',\n 'date',\n 'confirmed',\n 'shared',\n 'created_by',\n 'created_at',\n 'updated_at',\n 'note_id',\n] as const\n\nexport function createFactColumns<T extends FactRowView>(slots: FactColumnSlots<T>): ColDef<T>[] {\n // AG Grid's `field` is a path type over the row; for a generic row we assert the known keys.\n const fieldOf = (name: keyof FactRowView) => name as ColDef<T>['field']\n const l = { ...DEFAULT_FACT_COLUMN_LABELS, ...slots.labels }\n const ids = slots.testIds\n\n const { isInChat, onToggleInChat } = slots\n const inChatColumn: ColDef<T>[] =\n isInChat && onToggleInChat\n ? [\n {\n colId: 'in_chat',\n headerName: '',\n headerComponent: () => (\n <span className=\"flex size-full items-center justify-center\">\n <Paperclip className=\"size-3.5 text-muted-foreground\" />\n </span>\n ),\n valueGetter: (params: ValueGetterParams<T>) =>\n params.data ? isInChat(params.data) : false,\n width: 44,\n minWidth: 44,\n maxWidth: 44,\n sortable: true,\n resizable: false,\n headerTooltip: l.inChatHeaderTooltip,\n cellClass: 'cell-hcenter',\n // A toggle, not a readout: a fact in the chat rides every message of it, so it flips\n // in place.\n cellRenderer: (params: ICellRendererParams<T>) => {\n if (!params.data) return null\n const fact = params.data\n const inChat = isInChat(fact)\n return (\n <button\n type=\"button\"\n onClick={() => onToggleInChat(fact)}\n title={inChat ? l.inChatTitle : l.notInChatTitle}\n aria-label={inChat ? l.removeFromChat : l.addToChat}\n aria-pressed={inChat}\n data-testid={testIdOr(ids?.inChat?.(fact.external_id), {\n testId: `facts-grid-in-chat-${fact.external_id}`,\n })}\n className=\"flex h-full items-center\"\n >\n <Paperclip\n className={cn(\n 'size-3.5',\n inChat\n ? 'text-primary'\n : 'text-muted-foreground/30 transition-colors hover:text-muted-foreground'\n )}\n />\n </button>\n )\n },\n },\n ]\n : []\n\n const columns: ColDef<T>[] = [\n ...inChatColumn,\n {\n colId: 'text',\n suppressHeaderFilterButton: true,\n headerComponent: (p: IHeaderParams) => slots.renderHeader(p, 'text'),\n headerName: l.fact,\n field: fieldOf('text'),\n flex: 3,\n minWidth: 280,\n sortable: true,\n filter: 'agTextColumnFilter',\n // Decode the editor's whitespace entities (`&#x20;` for a trailing space) so the tooltip\n // reads as typed, not as raw markdown references.\n tooltipValueGetter: (p) => decodeWhitespaceEntities(p.data?.text),\n // Editable only via the grid api (Rename in the row's menu); clicks never open the editor\n // (suppressClickEdit on the grid).\n editable: true,\n cellEditor: 'agLargeTextCellEditor',\n cellEditorPopup: true,\n cellEditorParams: { rows: 8, cols: 60 },\n valueSetter: (params) => {\n if (!params.data) return false\n params.data.text = params.newValue\n return true\n },\n // NOT `cell-multiline`: this cell has its OWN clamp (the `.fact-clamp` span below, sized\n // from the row height). A second clamp cut the text in half at the minimum row height.\n cellClass: 'relative',\n cellRenderer: (params: ICellRendererParams<T>) => {\n if (!params.data) return null\n const fact = params.data\n // Clamp to however many WHOLE lines fit the row height (leading-snug ~ 20px/line),\n // top-aligned so the BEGINNING of the fact is always shown. No overflow clip here: the\n // wrapper is the cell's content box, shorter than a line at the density floor.\n const rowH = params.node.rowHeight ?? 52\n const clampLines = Math.max(1, Math.floor(rowH / 20))\n return (\n <div className=\"relative flex size-full items-start pr-6\">\n <span\n className=\"fact-clamp whitespace-normal break-words text-sm leading-snug text-foreground\"\n style={{ ['--fact-clamp-lines' as string]: clampLines } as CSSProperties}\n data-testid={testIdOr(ids?.text?.(fact.external_id), {\n testId: `facts-grid-text-${fact.external_id}`,\n })}\n >\n {decodeWhitespaceEntities(fact.text)}\n </span>\n {/* `facts-row-kebab` (app CSS) keeps the menu always visible: touch has no hover. */}\n <div className=\"facts-row-kebab absolute right-0.5 top-1/2 -translate-y-1/2\">\n {slots.renderRowActions(fact, params)}\n </div>\n </div>\n )\n },\n },\n {\n colId: 'date',\n // AG Grid's DEFAULT header, so the sort arrow and filter button are the native ones,\n // identical to the Files table's Date columns.\n headerName: l.dates,\n // Sort on the raw bound rather than the rendered string (\"Oct 2019\" sorts April first).\n field: fieldOf('date_start'),\n flex: 0.8,\n minWidth: 132,\n sortable: true,\n filter: 'agDateColumnFilter',\n filterParams: ISO_DATE_FILTER_PARAMS,\n // The edit value is the date-only slice: a lexical sort matches a chronological one, and\n // the inline editor shows \"2024-03-12\" rather than a full ISO timestamp. Inline typing\n // accepts YYYY, YYYY-MM or YYYY-MM-DD; clearing the cell undates the fact.\n editable: true,\n singleClickEdit: true,\n valueGetter: (params: ValueGetterParams<T>) =>\n params.data?.date_start ? params.data.date_start.slice(0, 10) : null,\n valueSetter: (params) => {\n if (!params.data) return false\n params.data.date_start = params.newValue\n return true\n },\n cellClass: 'relative cell-tnum',\n cellRenderer: (params: ICellRendererParams<T>) => {\n const when = formatSpan(\n params.data?.date_start,\n params.data?.date_end,\n params.data?.timezone\n )\n if (!when) return <span className=\"text-muted-foreground/50\">\u2014</span>\n return (\n <span\n className=\"inline-flex items-center gap-1\"\n data-testid={testIdOr(ids?.date?.(params.data?.external_id ?? ''), {\n testId: `facts-grid-date-${params.data?.external_id}`,\n })}\n title={l.dateTitle}\n >\n <CalendarDays className=\"size-3 opacity-70\" />\n {when}\n </span>\n )\n },\n },\n {\n colId: 'tags',\n suppressHeaderFilterButton: true,\n headerComponent: (p: IHeaderParams) => slots.renderHeader(p, 'tags'),\n headerName: l.labels,\n flex: 0.9,\n // Never narrower than its own header, even with the filter button and sort indicator.\n minWidth: 160,\n sortable: true,\n filter: 'agTextColumnFilter',\n cellClass: 'overflow-visible',\n valueGetter: (params: ValueGetterParams<T>) =>\n (params.data?.tags ?? []).map((t) => t.name).join(', '),\n // Editable in place: toggling a label persists immediately, no dialog round-trip.\n cellRenderer: (params: ICellRendererParams<T>) =>\n params.data ? slots.renderLabels(params.data, params) : null,\n },\n {\n colId: 'confirmed',\n headerName: l.verified,\n headerTooltip: l.verifiedTooltip,\n field: fieldOf('confirmed'),\n // minWidth matches width so the header can't be clamped narrow enough to ellipsize.\n width: 116,\n minWidth: 116,\n sortable: true,\n cellDataType: 'boolean',\n valueGetter: (params) => params.data?.confirmed ?? false,\n cellClass: 'cell-hcenter',\n headerClass: 'header-hcenter',\n cellRenderer: (params: ICellRendererParams<T>) =>\n params.data ? (\n <div className=\"flex h-full items-center justify-center\">\n {slots.renderVerified(params.data)}\n </div>\n ) : null,\n },\n {\n colId: 'shared',\n headerName: l.shared,\n headerTooltip: l.sharedTooltip,\n field: fieldOf('shared'),\n // minWidth (not just width) is raised too: AG Grid clamps any persisted width up to it.\n width: 124,\n minWidth: 124,\n sortable: true,\n headerClass: 'header-hcenter',\n cellDataType: 'boolean',\n valueGetter: (params) => params.data?.shared ?? false,\n cellRenderer: (params: ICellRendererParams<T>) =>\n params.data ? (\n <div className=\"flex h-full items-center justify-center\">\n {slots.renderShared(params.data, params)}\n </div>\n ) : null,\n },\n {\n colId: 'created_by',\n headerName: l.createdBy,\n headerTooltip: l.createdBy,\n width: 138,\n minWidth: 138,\n sortable: true,\n valueGetter: (params) => slots.getCreatorName(params),\n cellRenderer: (params: ICellRendererParams<T>) =>\n params.data ? (\n <div className=\"flex h-full items-center justify-center\">\n {slots.renderCreator(params.data, params)}\n </div>\n ) : null,\n },\n {\n colId: 'sources',\n headerName: l.sources,\n width: 112,\n minWidth: 104,\n sortable: true,\n // A hand-written fact has no sources, which is information rather than a gap: it reads as\n // an em dash instead of a zero.\n valueGetter: (params) => sourceDocCount(params.data),\n cellRenderer: (params: ICellRendererParams<T>) => {\n const n = sourceDocCount(params.data)\n if (n === 0) return <span className=\"text-muted-foreground/40\">\u2014</span>\n return (\n <span\n className=\"inline-flex items-center gap-1 text-xs text-muted-foreground\"\n title={l.sourcedFrom(n)}\n >\n <Quote className=\"size-3 opacity-70\" />\n {n}\n </span>\n )\n },\n },\n {\n colId: 'created_at',\n suppressHeaderFilterButton: true,\n headerComponent: (p: IHeaderParams) => slots.renderHeader(p, 'created_at'),\n headerName: l.createdAt,\n field: fieldOf('created_at'),\n width: 162,\n minWidth: 154,\n sortable: true,\n filter: 'agDateColumnFilter',\n filterParams: ISO_DATE_FILTER_PARAMS,\n // Display-only: a valueFormatter avoids mounting a React component per row.\n cellClass: 'text-muted-foreground',\n valueFormatter: (params) => (params.value ? slots.formatDate(params.value) : ''),\n },\n {\n colId: 'updated_at',\n suppressHeaderFilterButton: true,\n headerComponent: (p: IHeaderParams) => slots.renderHeader(p, 'updated_at'),\n headerName: l.updated,\n field: fieldOf('updated_at'),\n width: 140,\n minWidth: 140,\n // Hidden by default: a column-menu opt-in like the documents grid's long tail.\n hide: true,\n sortable: true,\n filter: 'agDateColumnFilter',\n filterParams: ISO_DATE_FILTER_PARAMS,\n valueFormatter: (params) => (params.value ? slots.formatDate(params.value) : ''),\n },\n {\n colId: 'note_id',\n headerName: l.id,\n field: fieldOf('external_id'),\n width: 120,\n minWidth: 100,\n sortable: true,\n filter: 'agTextColumnFilter',\n // Hidden by default like the documents ID column: needed when quoting a fact to support.\n hide: true,\n cellClass: 'font-mono text-xs text-muted-foreground',\n },\n ]\n\n // Persisted per-user column order still wins once set; bump the grid id to apply a new default.\n return DEFAULT_FACT_COLUMN_ORDER.map((id) => columns.find((c) => c.colId === id)).filter(\n (c): c is ColDef<T> => c !== undefined\n )\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunk57NHXEU2_cjs = require('../chunk-57NHXEU2.cjs');
4
+ var chunkMXBXZXXQ_cjs = require('../chunk-MXBXZXXQ.cjs');
5
5
  var chunkTJY7XPDE_cjs = require('../chunk-TJY7XPDE.cjs');
6
6
  var chunkDDWLMYRO_cjs = require('../chunk-DDWLMYRO.cjs');
7
7
  require('../chunk-SNUBQMIS.cjs');
@@ -42,167 +42,167 @@ function toFactRows(records) {
42
42
 
43
43
  Object.defineProperty(exports, "DEFAULT_FACTS_BULK_BAR_LABELS", {
44
44
  enumerable: true,
45
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACTS_BULK_BAR_LABELS; }
45
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACTS_BULK_BAR_LABELS; }
46
46
  });
47
47
  Object.defineProperty(exports, "DEFAULT_FACTS_EMPTY_STATE_LABELS", {
48
48
  enumerable: true,
49
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACTS_EMPTY_STATE_LABELS; }
49
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACTS_EMPTY_STATE_LABELS; }
50
50
  });
51
51
  Object.defineProperty(exports, "DEFAULT_FACTS_FIELDS_BUTTON_LABELS", {
52
52
  enumerable: true,
53
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACTS_FIELDS_BUTTON_LABELS; }
53
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACTS_FIELDS_BUTTON_LABELS; }
54
54
  });
55
55
  Object.defineProperty(exports, "DEFAULT_FACTS_TOOLBAR_LABELS", {
56
56
  enumerable: true,
57
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACTS_TOOLBAR_LABELS; }
57
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACTS_TOOLBAR_LABELS; }
58
58
  });
59
59
  Object.defineProperty(exports, "DEFAULT_FACTS_VIEW_TOGGLE_LABELS", {
60
60
  enumerable: true,
61
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACTS_VIEW_TOGGLE_LABELS; }
61
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACTS_VIEW_TOGGLE_LABELS; }
62
62
  });
63
63
  Object.defineProperty(exports, "DEFAULT_FACT_COLUMN_LABELS", {
64
64
  enumerable: true,
65
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACT_COLUMN_LABELS; }
65
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACT_COLUMN_LABELS; }
66
66
  });
67
67
  Object.defineProperty(exports, "DEFAULT_FACT_COLUMN_ORDER", {
68
68
  enumerable: true,
69
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACT_COLUMN_ORDER; }
69
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACT_COLUMN_ORDER; }
70
70
  });
71
71
  Object.defineProperty(exports, "DEFAULT_FACT_COMPOSER_LABELS", {
72
72
  enumerable: true,
73
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACT_COMPOSER_LABELS; }
73
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACT_COMPOSER_LABELS; }
74
74
  });
75
75
  Object.defineProperty(exports, "DEFAULT_FACT_DATE_INPUT_LABELS", {
76
76
  enumerable: true,
77
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACT_DATE_INPUT_LABELS; }
77
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACT_DATE_INPUT_LABELS; }
78
78
  });
79
79
  Object.defineProperty(exports, "DEFAULT_FACT_LABELS_CELL_LABELS", {
80
80
  enumerable: true,
81
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACT_LABELS_CELL_LABELS; }
81
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACT_LABELS_CELL_LABELS; }
82
82
  });
83
83
  Object.defineProperty(exports, "DEFAULT_FACT_ROW_ACTIONS_LABELS", {
84
84
  enumerable: true,
85
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACT_ROW_ACTIONS_LABELS; }
85
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACT_ROW_ACTIONS_LABELS; }
86
86
  });
87
87
  Object.defineProperty(exports, "DEFAULT_FACT_SEARCH_BAR_LABELS", {
88
88
  enumerable: true,
89
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACT_SEARCH_BAR_LABELS; }
89
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACT_SEARCH_BAR_LABELS; }
90
90
  });
91
91
  Object.defineProperty(exports, "DEFAULT_FACT_SEARCH_RESULT_LABELS", {
92
92
  enumerable: true,
93
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACT_SEARCH_RESULT_LABELS; }
93
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACT_SEARCH_RESULT_LABELS; }
94
94
  });
95
95
  Object.defineProperty(exports, "DEFAULT_FACT_SOURCES_ROW_LABELS", {
96
96
  enumerable: true,
97
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACT_SOURCES_ROW_LABELS; }
97
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACT_SOURCES_ROW_LABELS; }
98
98
  });
99
99
  Object.defineProperty(exports, "DEFAULT_FACT_SOURCE_GROUP_LABELS", {
100
100
  enumerable: true,
101
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACT_SOURCE_GROUP_LABELS; }
101
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACT_SOURCE_GROUP_LABELS; }
102
102
  });
103
103
  Object.defineProperty(exports, "DEFAULT_FACT_TIMELINE_LABELS", {
104
104
  enumerable: true,
105
- get: function () { return chunk57NHXEU2_cjs.DEFAULT_FACT_TIMELINE_LABELS; }
105
+ get: function () { return chunkMXBXZXXQ_cjs.DEFAULT_FACT_TIMELINE_LABELS; }
106
106
  });
107
107
  Object.defineProperty(exports, "FactComposer", {
108
108
  enumerable: true,
109
- get: function () { return chunk57NHXEU2_cjs.FactComposer; }
109
+ get: function () { return chunkMXBXZXXQ_cjs.FactComposer; }
110
110
  });
111
111
  Object.defineProperty(exports, "FactDateInput", {
112
112
  enumerable: true,
113
- get: function () { return chunk57NHXEU2_cjs.FactDateInput; }
113
+ get: function () { return chunkMXBXZXXQ_cjs.FactDateInput; }
114
114
  });
115
115
  Object.defineProperty(exports, "FactFieldRow", {
116
116
  enumerable: true,
117
- get: function () { return chunk57NHXEU2_cjs.FactFieldRow; }
117
+ get: function () { return chunkMXBXZXXQ_cjs.FactFieldRow; }
118
118
  });
119
119
  Object.defineProperty(exports, "FactLabelsCell", {
120
120
  enumerable: true,
121
- get: function () { return chunk57NHXEU2_cjs.FactLabelsCell; }
121
+ get: function () { return chunkMXBXZXXQ_cjs.FactLabelsCell; }
122
122
  });
123
123
  Object.defineProperty(exports, "FactRowActions", {
124
124
  enumerable: true,
125
- get: function () { return chunk57NHXEU2_cjs.FactRowActions; }
125
+ get: function () { return chunkMXBXZXXQ_cjs.FactRowActions; }
126
126
  });
127
127
  Object.defineProperty(exports, "FactSearchBar", {
128
128
  enumerable: true,
129
- get: function () { return chunk57NHXEU2_cjs.FactSearchBar; }
129
+ get: function () { return chunkMXBXZXXQ_cjs.FactSearchBar; }
130
130
  });
131
131
  Object.defineProperty(exports, "FactSearchNoMatches", {
132
132
  enumerable: true,
133
- get: function () { return chunk57NHXEU2_cjs.FactSearchNoMatches; }
133
+ get: function () { return chunkMXBXZXXQ_cjs.FactSearchNoMatches; }
134
134
  });
135
135
  Object.defineProperty(exports, "FactSearchPending", {
136
136
  enumerable: true,
137
- get: function () { return chunk57NHXEU2_cjs.FactSearchPending; }
137
+ get: function () { return chunkMXBXZXXQ_cjs.FactSearchPending; }
138
138
  });
139
139
  Object.defineProperty(exports, "FactSearchResult", {
140
140
  enumerable: true,
141
- get: function () { return chunk57NHXEU2_cjs.FactSearchResult; }
141
+ get: function () { return chunkMXBXZXXQ_cjs.FactSearchResult; }
142
142
  });
143
143
  Object.defineProperty(exports, "FactSearchTotals", {
144
144
  enumerable: true,
145
- get: function () { return chunk57NHXEU2_cjs.FactSearchTotals; }
145
+ get: function () { return chunkMXBXZXXQ_cjs.FactSearchTotals; }
146
146
  });
147
147
  Object.defineProperty(exports, "FactSourceGroup", {
148
148
  enumerable: true,
149
- get: function () { return chunk57NHXEU2_cjs.FactSourceGroup; }
149
+ get: function () { return chunkMXBXZXXQ_cjs.FactSourceGroup; }
150
150
  });
151
151
  Object.defineProperty(exports, "FactSourcesRow", {
152
152
  enumerable: true,
153
- get: function () { return chunk57NHXEU2_cjs.FactSourcesRow; }
153
+ get: function () { return chunkMXBXZXXQ_cjs.FactSourcesRow; }
154
154
  });
155
155
  Object.defineProperty(exports, "FactsBulkBar", {
156
156
  enumerable: true,
157
- get: function () { return chunk57NHXEU2_cjs.FactsBulkBar; }
157
+ get: function () { return chunkMXBXZXXQ_cjs.FactsBulkBar; }
158
158
  });
159
159
  Object.defineProperty(exports, "FactsCalendar", {
160
160
  enumerable: true,
161
- get: function () { return chunk57NHXEU2_cjs.FactsCalendar; }
161
+ get: function () { return chunkMXBXZXXQ_cjs.FactsCalendar; }
162
162
  });
163
163
  Object.defineProperty(exports, "FactsEmptyState", {
164
164
  enumerable: true,
165
- get: function () { return chunk57NHXEU2_cjs.FactsEmptyState; }
165
+ get: function () { return chunkMXBXZXXQ_cjs.FactsEmptyState; }
166
166
  });
167
167
  Object.defineProperty(exports, "FactsFieldsButton", {
168
168
  enumerable: true,
169
- get: function () { return chunk57NHXEU2_cjs.FactsFieldsButton; }
169
+ get: function () { return chunkMXBXZXXQ_cjs.FactsFieldsButton; }
170
170
  });
171
171
  Object.defineProperty(exports, "FactsGanttPane", {
172
172
  enumerable: true,
173
- get: function () { return chunk57NHXEU2_cjs.FactsGanttPane; }
173
+ get: function () { return chunkMXBXZXXQ_cjs.FactsGanttPane; }
174
174
  });
175
175
  Object.defineProperty(exports, "FactsLoadError", {
176
176
  enumerable: true,
177
- get: function () { return chunk57NHXEU2_cjs.FactsLoadError; }
177
+ get: function () { return chunkMXBXZXXQ_cjs.FactsLoadError; }
178
178
  });
179
179
  Object.defineProperty(exports, "FactsLoading", {
180
180
  enumerable: true,
181
- get: function () { return chunk57NHXEU2_cjs.FactsLoading; }
181
+ get: function () { return chunkMXBXZXXQ_cjs.FactsLoading; }
182
182
  });
183
183
  Object.defineProperty(exports, "FactsToolbar", {
184
184
  enumerable: true,
185
- get: function () { return chunk57NHXEU2_cjs.FactsToolbar; }
185
+ get: function () { return chunkMXBXZXXQ_cjs.FactsToolbar; }
186
186
  });
187
187
  Object.defineProperty(exports, "FactsViewToggle", {
188
188
  enumerable: true,
189
- get: function () { return chunk57NHXEU2_cjs.FactsViewToggle; }
189
+ get: function () { return chunkMXBXZXXQ_cjs.FactsViewToggle; }
190
190
  });
191
191
  Object.defineProperty(exports, "ISO_DATE_FILTER_PARAMS", {
192
192
  enumerable: true,
193
- get: function () { return chunk57NHXEU2_cjs.ISO_DATE_FILTER_PARAMS; }
193
+ get: function () { return chunkMXBXZXXQ_cjs.ISO_DATE_FILTER_PARAMS; }
194
194
  });
195
195
  Object.defineProperty(exports, "createFactColumns", {
196
196
  enumerable: true,
197
- get: function () { return chunk57NHXEU2_cjs.createFactColumns; }
197
+ get: function () { return chunkMXBXZXXQ_cjs.createFactColumns; }
198
198
  });
199
199
  Object.defineProperty(exports, "enableFactTableColumnResize", {
200
200
  enumerable: true,
201
- get: function () { return chunk57NHXEU2_cjs.enableFactTableColumnResize; }
201
+ get: function () { return chunkMXBXZXXQ_cjs.enableFactTableColumnResize; }
202
202
  });
203
203
  Object.defineProperty(exports, "sourceDocCount", {
204
204
  enumerable: true,
205
- get: function () { return chunk57NHXEU2_cjs.sourceDocCount; }
205
+ get: function () { return chunkMXBXZXXQ_cjs.sourceDocCount; }
206
206
  });
207
207
  Object.defineProperty(exports, "EMPTY_FACT_DATE_FIELDS", {
208
208
  enumerable: true,