@freighttech/ui 0.13.18

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 (1477) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +31 -0
  3. package/dist/backend/AppShell.js +1289 -0
  4. package/dist/backend/AppShell.js.map +7 -0
  5. package/dist/backend/BackendChromeProvider.js +83 -0
  6. package/dist/backend/BackendChromeProvider.js.map +7 -0
  7. package/dist/backend/BackendPageSurface.js +19 -0
  8. package/dist/backend/BackendPageSurface.js.map +7 -0
  9. package/dist/backend/CollapsibleNavSection.js +149 -0
  10. package/dist/backend/CollapsibleNavSection.js.map +7 -0
  11. package/dist/backend/ContextHelp.js +33 -0
  12. package/dist/backend/ContextHelp.js.map +7 -0
  13. package/dist/backend/CrudForm.js +3163 -0
  14. package/dist/backend/CrudForm.js.map +7 -0
  15. package/dist/backend/DataTable.js +2091 -0
  16. package/dist/backend/DataTable.js.map +7 -0
  17. package/dist/backend/EmptyState.js +52 -0
  18. package/dist/backend/EmptyState.js.map +7 -0
  19. package/dist/backend/FilterBar.js +147 -0
  20. package/dist/backend/FilterBar.js.map +7 -0
  21. package/dist/backend/FilterOverlay.js +337 -0
  22. package/dist/backend/FilterOverlay.js.map +7 -0
  23. package/dist/backend/FlashMessages.js +158 -0
  24. package/dist/backend/FlashMessages.js.map +7 -0
  25. package/dist/backend/HtmlRichTextEditor.js +129 -0
  26. package/dist/backend/HtmlRichTextEditor.js.map +7 -0
  27. package/dist/backend/IntegrationsButton.js +25 -0
  28. package/dist/backend/IntegrationsButton.js.map +7 -0
  29. package/dist/backend/JsonBuilder.js +323 -0
  30. package/dist/backend/JsonBuilder.js.map +7 -0
  31. package/dist/backend/JsonDisplay.js +207 -0
  32. package/dist/backend/JsonDisplay.js.map +7 -0
  33. package/dist/backend/NextStepCallout.js +79 -0
  34. package/dist/backend/NextStepCallout.js.map +7 -0
  35. package/dist/backend/Page.js +27 -0
  36. package/dist/backend/Page.js.map +7 -0
  37. package/dist/backend/PerspectiveSidebar.js +456 -0
  38. package/dist/backend/PerspectiveSidebar.js.map +7 -0
  39. package/dist/backend/ProfileDropdown.js +341 -0
  40. package/dist/backend/ProfileDropdown.js.map +7 -0
  41. package/dist/backend/RowActions.js +155 -0
  42. package/dist/backend/RowActions.js.map +7 -0
  43. package/dist/backend/SectionHeader.js +74 -0
  44. package/dist/backend/SectionHeader.js.map +7 -0
  45. package/dist/backend/SettingsButton.js +25 -0
  46. package/dist/backend/SettingsButton.js.map +7 -0
  47. package/dist/backend/Sidebar.js +510 -0
  48. package/dist/backend/Sidebar.js.map +7 -0
  49. package/dist/backend/Sidebar.stories.js +166 -0
  50. package/dist/backend/Sidebar.stories.js.map +7 -0
  51. package/dist/backend/TruncatedCell.js +92 -0
  52. package/dist/backend/TruncatedCell.js.map +7 -0
  53. package/dist/backend/UserMenu.js +146 -0
  54. package/dist/backend/UserMenu.js.map +7 -0
  55. package/dist/backend/ValueIcons.js +34 -0
  56. package/dist/backend/ValueIcons.js.map +7 -0
  57. package/dist/backend/WebhookSetupGuide.js +79 -0
  58. package/dist/backend/WebhookSetupGuide.js.map +7 -0
  59. package/dist/backend/charts/BarChart.js +154 -0
  60. package/dist/backend/charts/BarChart.js.map +7 -0
  61. package/dist/backend/charts/ChartUtils.js +141 -0
  62. package/dist/backend/charts/ChartUtils.js.map +7 -0
  63. package/dist/backend/charts/ComboChart.js +261 -0
  64. package/dist/backend/charts/ComboChart.js.map +7 -0
  65. package/dist/backend/charts/ComboChart.stories.js +88 -0
  66. package/dist/backend/charts/ComboChart.stories.js.map +7 -0
  67. package/dist/backend/charts/KpiCard.js +96 -0
  68. package/dist/backend/charts/KpiCard.js.map +7 -0
  69. package/dist/backend/charts/LineChart.js +165 -0
  70. package/dist/backend/charts/LineChart.js.map +7 -0
  71. package/dist/backend/charts/PieChart.js +121 -0
  72. package/dist/backend/charts/PieChart.js.map +7 -0
  73. package/dist/backend/charts/ScatterChart.js +320 -0
  74. package/dist/backend/charts/ScatterChart.js.map +7 -0
  75. package/dist/backend/charts/TopNTable.js +91 -0
  76. package/dist/backend/charts/TopNTable.js.map +7 -0
  77. package/dist/backend/charts/WaterfallChart.js +136 -0
  78. package/dist/backend/charts/WaterfallChart.js.map +7 -0
  79. package/dist/backend/charts/index.js +30 -0
  80. package/dist/backend/charts/index.js.map +7 -0
  81. package/dist/backend/columns/ColumnChooserPanel.js +244 -0
  82. package/dist/backend/columns/ColumnChooserPanel.js.map +7 -0
  83. package/dist/backend/confirm-dialog/ConfirmDialog.js +214 -0
  84. package/dist/backend/confirm-dialog/ConfirmDialog.js.map +7 -0
  85. package/dist/backend/confirm-dialog/index.js +7 -0
  86. package/dist/backend/confirm-dialog/index.js.map +7 -0
  87. package/dist/backend/confirm-dialog/useConfirmDialog.js +113 -0
  88. package/dist/backend/confirm-dialog/useConfirmDialog.js.map +7 -0
  89. package/dist/backend/custom-fields/FieldDefinitionsEditor.js +1352 -0
  90. package/dist/backend/custom-fields/FieldDefinitionsEditor.js.map +7 -0
  91. package/dist/backend/custom-fields/FieldDefinitionsManager.js +332 -0
  92. package/dist/backend/custom-fields/FieldDefinitionsManager.js.map +7 -0
  93. package/dist/backend/dashboard/DashboardScreen.js +598 -0
  94. package/dist/backend/dashboard/DashboardScreen.js.map +7 -0
  95. package/dist/backend/dashboard/index.js +5 -0
  96. package/dist/backend/dashboard/index.js.map +7 -0
  97. package/dist/backend/dashboard/widgetRegistry.js +55 -0
  98. package/dist/backend/dashboard/widgetRegistry.js.map +7 -0
  99. package/dist/backend/date-range/DateRangeSelect.js +39 -0
  100. package/dist/backend/date-range/DateRangeSelect.js.map +7 -0
  101. package/dist/backend/date-range/InlineDateRangeSelect.js +42 -0
  102. package/dist/backend/date-range/InlineDateRangeSelect.js.map +7 -0
  103. package/dist/backend/date-range/InlineGranularitySelect.js +40 -0
  104. package/dist/backend/date-range/InlineGranularitySelect.js.map +7 -0
  105. package/dist/backend/date-range/dateRanges.js +176 -0
  106. package/dist/backend/date-range/dateRanges.js.map +7 -0
  107. package/dist/backend/date-range/index.js +25 -0
  108. package/dist/backend/date-range/index.js.map +7 -0
  109. package/dist/backend/detail/AccessDeniedMessage.js +28 -0
  110. package/dist/backend/detail/AccessDeniedMessage.js.map +7 -0
  111. package/dist/backend/detail/ActivitiesSection.js +947 -0
  112. package/dist/backend/detail/ActivitiesSection.js.map +7 -0
  113. package/dist/backend/detail/AddressEditor.js +417 -0
  114. package/dist/backend/detail/AddressEditor.js.map +7 -0
  115. package/dist/backend/detail/AddressTiles.js +441 -0
  116. package/dist/backend/detail/AddressTiles.js.map +7 -0
  117. package/dist/backend/detail/AddressesSection.js +274 -0
  118. package/dist/backend/detail/AddressesSection.js.map +7 -0
  119. package/dist/backend/detail/AttachmentDeleteDialog.js +41 -0
  120. package/dist/backend/detail/AttachmentDeleteDialog.js.map +7 -0
  121. package/dist/backend/detail/AttachmentMetadataDialog.js +519 -0
  122. package/dist/backend/detail/AttachmentMetadataDialog.js.map +7 -0
  123. package/dist/backend/detail/AttachmentVisualPreview.js +132 -0
  124. package/dist/backend/detail/AttachmentVisualPreview.js.map +7 -0
  125. package/dist/backend/detail/AttachmentsSection.js +281 -0
  126. package/dist/backend/detail/AttachmentsSection.js.map +7 -0
  127. package/dist/backend/detail/CustomDataSection.js +575 -0
  128. package/dist/backend/detail/CustomDataSection.js.map +7 -0
  129. package/dist/backend/detail/DetailFieldsSection.js +85 -0
  130. package/dist/backend/detail/DetailFieldsSection.js.map +7 -0
  131. package/dist/backend/detail/ErrorMessage.js +28 -0
  132. package/dist/backend/detail/ErrorMessage.js.map +7 -0
  133. package/dist/backend/detail/InlineEditors.js +697 -0
  134. package/dist/backend/detail/InlineEditors.js.map +7 -0
  135. package/dist/backend/detail/LoadingMessage.js +14 -0
  136. package/dist/backend/detail/LoadingMessage.js.map +7 -0
  137. package/dist/backend/detail/NotesSection.js +1022 -0
  138. package/dist/backend/detail/NotesSection.js.map +7 -0
  139. package/dist/backend/detail/TabEmptyState.js +25 -0
  140. package/dist/backend/detail/TabEmptyState.js.map +7 -0
  141. package/dist/backend/detail/TagsSection.js +375 -0
  142. package/dist/backend/detail/TagsSection.js.map +7 -0
  143. package/dist/backend/detail/addressFormat.js +77 -0
  144. package/dist/backend/detail/addressFormat.js.map +7 -0
  145. package/dist/backend/detail/index.js +36 -0
  146. package/dist/backend/detail/index.js.map +7 -0
  147. package/dist/backend/devtools/UmesDevToolsPanel.js +109 -0
  148. package/dist/backend/devtools/UmesDevToolsPanel.js.map +7 -0
  149. package/dist/backend/devtools/components/ConflictWarnings.js +32 -0
  150. package/dist/backend/devtools/components/ConflictWarnings.js.map +7 -0
  151. package/dist/backend/devtools/components/EnricherTiming.js +46 -0
  152. package/dist/backend/devtools/components/EnricherTiming.js.map +7 -0
  153. package/dist/backend/devtools/components/EventFlow.js +34 -0
  154. package/dist/backend/devtools/components/EventFlow.js.map +7 -0
  155. package/dist/backend/devtools/components/ExtensionPointList.js +58 -0
  156. package/dist/backend/devtools/components/ExtensionPointList.js.map +7 -0
  157. package/dist/backend/devtools/components/InterceptorActivity.js +36 -0
  158. package/dist/backend/devtools/components/InterceptorActivity.js.map +7 -0
  159. package/dist/backend/devtools/index.js +7 -0
  160. package/dist/backend/devtools/index.js.map +7 -0
  161. package/dist/backend/devtools/useUmesDevTools.js +125 -0
  162. package/dist/backend/devtools/useUmesDevTools.js.map +7 -0
  163. package/dist/backend/document-viewer/RegionOverlay.js +92 -0
  164. package/dist/backend/document-viewer/RegionOverlay.js.map +7 -0
  165. package/dist/backend/document-viewer/index.js +6 -0
  166. package/dist/backend/document-viewer/index.js.map +7 -0
  167. package/dist/backend/dynamic-grid/DynamicGrid.js +130 -0
  168. package/dist/backend/dynamic-grid/DynamicGrid.js.map +7 -0
  169. package/dist/backend/dynamic-grid/adapters.js +34 -0
  170. package/dist/backend/dynamic-grid/adapters.js.map +7 -0
  171. package/dist/backend/dynamic-grid/components/GridCell.js +149 -0
  172. package/dist/backend/dynamic-grid/components/GridCell.js.map +7 -0
  173. package/dist/backend/dynamic-grid/components/GridRow.js +32 -0
  174. package/dist/backend/dynamic-grid/components/GridRow.js.map +7 -0
  175. package/dist/backend/dynamic-grid/hooks/useGridKeyboardNav.js +115 -0
  176. package/dist/backend/dynamic-grid/hooks/useGridKeyboardNav.js.map +7 -0
  177. package/dist/backend/dynamic-grid/index.js +9 -0
  178. package/dist/backend/dynamic-grid/index.js.map +7 -0
  179. package/dist/backend/dynamic-grid/types.js +1 -0
  180. package/dist/backend/dynamic-grid/types.js.map +7 -0
  181. package/dist/backend/dynamic-table/DynamicTable.js +2607 -0
  182. package/dist/backend/dynamic-table/DynamicTable.js.map +7 -0
  183. package/dist/backend/dynamic-table/DynamicTable.stories.js +233 -0
  184. package/dist/backend/dynamic-table/DynamicTable.stories.js.map +7 -0
  185. package/dist/backend/dynamic-table/components/ActiveFilterChips.js +60 -0
  186. package/dist/backend/dynamic-table/components/ActiveFilterChips.js.map +7 -0
  187. package/dist/backend/dynamic-table/components/BulkActionsBar.js +58 -0
  188. package/dist/backend/dynamic-table/components/BulkActionsBar.js.map +7 -0
  189. package/dist/backend/dynamic-table/components/Cell.js +155 -0
  190. package/dist/backend/dynamic-table/components/Cell.js.map +7 -0
  191. package/dist/backend/dynamic-table/components/CellCommentDialog.js +726 -0
  192. package/dist/backend/dynamic-table/components/CellCommentDialog.js.map +7 -0
  193. package/dist/backend/dynamic-table/components/CellCommentHoverPopup.js +77 -0
  194. package/dist/backend/dynamic-table/components/CellCommentHoverPopup.js.map +7 -0
  195. package/dist/backend/dynamic-table/components/ColumnFilterPopover.js +485 -0
  196. package/dist/backend/dynamic-table/components/ColumnFilterPopover.js.map +7 -0
  197. package/dist/backend/dynamic-table/components/ColumnHeaderMenu.js +173 -0
  198. package/dist/backend/dynamic-table/components/ColumnHeaderMenu.js.map +7 -0
  199. package/dist/backend/dynamic-table/components/ColumnHeaders.js +528 -0
  200. package/dist/backend/dynamic-table/components/ColumnHeaders.js.map +7 -0
  201. package/dist/backend/dynamic-table/components/CompactLabelCell.js +64 -0
  202. package/dist/backend/dynamic-table/components/CompactLabelCell.js.map +7 -0
  203. package/dist/backend/dynamic-table/components/ConfigureViewFields.js +139 -0
  204. package/dist/backend/dynamic-table/components/ConfigureViewFields.js.map +7 -0
  205. package/dist/backend/dynamic-table/components/ConfigureViewFilters.js +305 -0
  206. package/dist/backend/dynamic-table/components/ConfigureViewFilters.js.map +7 -0
  207. package/dist/backend/dynamic-table/components/ConfigureViewFormatting.js +169 -0
  208. package/dist/backend/dynamic-table/components/ConfigureViewFormatting.js.map +7 -0
  209. package/dist/backend/dynamic-table/components/ConfigureViewFormulas.js +298 -0
  210. package/dist/backend/dynamic-table/components/ConfigureViewFormulas.js.map +7 -0
  211. package/dist/backend/dynamic-table/components/ConfigureViewGrouping.js +224 -0
  212. package/dist/backend/dynamic-table/components/ConfigureViewGrouping.js.map +7 -0
  213. package/dist/backend/dynamic-table/components/ConfigureViewLinkedColumns.js +167 -0
  214. package/dist/backend/dynamic-table/components/ConfigureViewLinkedColumns.js.map +7 -0
  215. package/dist/backend/dynamic-table/components/ConfigureViewPanel.js +592 -0
  216. package/dist/backend/dynamic-table/components/ConfigureViewPanel.js.map +7 -0
  217. package/dist/backend/dynamic-table/components/ConfigureViewRollups.js +269 -0
  218. package/dist/backend/dynamic-table/components/ConfigureViewRollups.js.map +7 -0
  219. package/dist/backend/dynamic-table/components/ConfigureViewSorting.js +107 -0
  220. package/dist/backend/dynamic-table/components/ConfigureViewSorting.js.map +7 -0
  221. package/dist/backend/dynamic-table/components/ContextMenu.js +91 -0
  222. package/dist/backend/dynamic-table/components/ContextMenu.js.map +7 -0
  223. package/dist/backend/dynamic-table/components/DateCell.js +80 -0
  224. package/dist/backend/dynamic-table/components/DateCell.js.map +7 -0
  225. package/dist/backend/dynamic-table/components/Debugger.js +311 -0
  226. package/dist/backend/dynamic-table/components/Debugger.js.map +7 -0
  227. package/dist/backend/dynamic-table/components/DensityControl.js +289 -0
  228. package/dist/backend/dynamic-table/components/DensityControl.js.map +7 -0
  229. package/dist/backend/dynamic-table/components/EmptyState.js +42 -0
  230. package/dist/backend/dynamic-table/components/EmptyState.js.map +7 -0
  231. package/dist/backend/dynamic-table/components/EntitySearchEditor.js +369 -0
  232. package/dist/backend/dynamic-table/components/EntitySearchEditor.js.map +7 -0
  233. package/dist/backend/dynamic-table/components/ExportMenu.js +63 -0
  234. package/dist/backend/dynamic-table/components/ExportMenu.js.map +7 -0
  235. package/dist/backend/dynamic-table/components/FilterDatePicker.js +165 -0
  236. package/dist/backend/dynamic-table/components/FilterDatePicker.js.map +7 -0
  237. package/dist/backend/dynamic-table/components/FilterValueInput.js +200 -0
  238. package/dist/backend/dynamic-table/components/FilterValueInput.js.map +7 -0
  239. package/dist/backend/dynamic-table/components/FooterTotalsRow.js +165 -0
  240. package/dist/backend/dynamic-table/components/FooterTotalsRow.js.map +7 -0
  241. package/dist/backend/dynamic-table/components/FullscreenOverlay.js +51 -0
  242. package/dist/backend/dynamic-table/components/FullscreenOverlay.js.map +7 -0
  243. package/dist/backend/dynamic-table/components/GroupHeaderRow.js +108 -0
  244. package/dist/backend/dynamic-table/components/GroupHeaderRow.js.map +7 -0
  245. package/dist/backend/dynamic-table/components/GroupSummaryRow.js +134 -0
  246. package/dist/backend/dynamic-table/components/GroupSummaryRow.js.map +7 -0
  247. package/dist/backend/dynamic-table/components/ImportPanel.js +341 -0
  248. package/dist/backend/dynamic-table/components/ImportPanel.js.map +7 -0
  249. package/dist/backend/dynamic-table/components/ImportPreviewGrid.js +114 -0
  250. package/dist/backend/dynamic-table/components/ImportPreviewGrid.js.map +7 -0
  251. package/dist/backend/dynamic-table/components/LoadErrorState.js +23 -0
  252. package/dist/backend/dynamic-table/components/LoadErrorState.js.map +7 -0
  253. package/dist/backend/dynamic-table/components/MentionPopup.js +149 -0
  254. package/dist/backend/dynamic-table/components/MentionPopup.js.map +7 -0
  255. package/dist/backend/dynamic-table/components/PerspectiveDeleteDialog.js +57 -0
  256. package/dist/backend/dynamic-table/components/PerspectiveDeleteDialog.js.map +7 -0
  257. package/dist/backend/dynamic-table/components/PerspectivePublishDialog.js +100 -0
  258. package/dist/backend/dynamic-table/components/PerspectivePublishDialog.js.map +7 -0
  259. package/dist/backend/dynamic-table/components/PerspectiveTabMenu.js +159 -0
  260. package/dist/backend/dynamic-table/components/PerspectiveTabMenu.js.map +7 -0
  261. package/dist/backend/dynamic-table/components/PerspectiveTabs.js +319 -0
  262. package/dist/backend/dynamic-table/components/PerspectiveTabs.js.map +7 -0
  263. package/dist/backend/dynamic-table/components/PerspectiveTemplateMenu.js +90 -0
  264. package/dist/backend/dynamic-table/components/PerspectiveTemplateMenu.js.map +7 -0
  265. package/dist/backend/dynamic-table/components/RowHeaderCell.js +58 -0
  266. package/dist/backend/dynamic-table/components/RowHeaderCell.js.map +7 -0
  267. package/dist/backend/dynamic-table/components/SearchBar.js +221 -0
  268. package/dist/backend/dynamic-table/components/SearchBar.js.map +7 -0
  269. package/dist/backend/dynamic-table/components/SelectMenu.js +186 -0
  270. package/dist/backend/dynamic-table/components/SelectMenu.js.map +7 -0
  271. package/dist/backend/dynamic-table/components/StaleDataBar.js +26 -0
  272. package/dist/backend/dynamic-table/components/StaleDataBar.js.map +7 -0
  273. package/dist/backend/dynamic-table/components/TableDeleteDialog.js +48 -0
  274. package/dist/backend/dynamic-table/components/TableDeleteDialog.js.map +7 -0
  275. package/dist/backend/dynamic-table/components/TablePagination.js +69 -0
  276. package/dist/backend/dynamic-table/components/TablePagination.js.map +7 -0
  277. package/dist/backend/dynamic-table/components/TableSkeleton.js +43 -0
  278. package/dist/backend/dynamic-table/components/TableSkeleton.js.map +7 -0
  279. package/dist/backend/dynamic-table/components/ToolbarOverflow.js +204 -0
  280. package/dist/backend/dynamic-table/components/ToolbarOverflow.js.map +7 -0
  281. package/dist/backend/dynamic-table/components/ViewModeSwitch.js +50 -0
  282. package/dist/backend/dynamic-table/components/ViewModeSwitch.js.map +7 -0
  283. package/dist/backend/dynamic-table/components/VirtualRow.js +214 -0
  284. package/dist/backend/dynamic-table/components/VirtualRow.js.map +7 -0
  285. package/dist/backend/dynamic-table/components/editors.js +1483 -0
  286. package/dist/backend/dynamic-table/components/editors.js.map +7 -0
  287. package/dist/backend/dynamic-table/components/renderers.js +131 -0
  288. package/dist/backend/dynamic-table/components/renderers.js.map +7 -0
  289. package/dist/backend/dynamic-table/events/events.js +73 -0
  290. package/dist/backend/dynamic-table/events/events.js.map +7 -0
  291. package/dist/backend/dynamic-table/formula/check.js +243 -0
  292. package/dist/backend/dynamic-table/formula/check.js.map +7 -0
  293. package/dist/backend/dynamic-table/formula/evaluate.js +302 -0
  294. package/dist/backend/dynamic-table/formula/evaluate.js.map +7 -0
  295. package/dist/backend/dynamic-table/formula/functions.js +602 -0
  296. package/dist/backend/dynamic-table/formula/functions.js.map +7 -0
  297. package/dist/backend/dynamic-table/formula/index.js +47 -0
  298. package/dist/backend/dynamic-table/formula/index.js.map +7 -0
  299. package/dist/backend/dynamic-table/formula/parse.js +293 -0
  300. package/dist/backend/dynamic-table/formula/parse.js.map +7 -0
  301. package/dist/backend/dynamic-table/formula/types.js +24 -0
  302. package/dist/backend/dynamic-table/formula/types.js.map +7 -0
  303. package/dist/backend/dynamic-table/handlers/cellWrites.js +143 -0
  304. package/dist/backend/dynamic-table/handlers/cellWrites.js.map +7 -0
  305. package/dist/backend/dynamic-table/handlers/index.js +504 -0
  306. package/dist/backend/dynamic-table/handlers/index.js.map +7 -0
  307. package/dist/backend/dynamic-table/handlers/perspectiveHandlers.js +377 -0
  308. package/dist/backend/dynamic-table/handlers/perspectiveHandlers.js.map +7 -0
  309. package/dist/backend/dynamic-table/hooks/index.js +524 -0
  310. package/dist/backend/dynamic-table/hooks/index.js.map +7 -0
  311. package/dist/backend/dynamic-table/hooks/useAbbreviations.js +19 -0
  312. package/dist/backend/dynamic-table/hooks/useAbbreviations.js.map +7 -0
  313. package/dist/backend/dynamic-table/hooks/useAnnotations.js +115 -0
  314. package/dist/backend/dynamic-table/hooks/useAnnotations.js.map +7 -0
  315. package/dist/backend/dynamic-table/hooks/useColumnVirtualizer.js +155 -0
  316. package/dist/backend/dynamic-table/hooks/useColumnVirtualizer.js.map +7 -0
  317. package/dist/backend/dynamic-table/hooks/useColumnWidthPersistence.js +135 -0
  318. package/dist/backend/dynamic-table/hooks/useColumnWidthPersistence.js.map +7 -0
  319. package/dist/backend/dynamic-table/hooks/useDensityPreference.js +203 -0
  320. package/dist/backend/dynamic-table/hooks/useDensityPreference.js.map +7 -0
  321. package/dist/backend/dynamic-table/hooks/useDynamicTablePage.js +1005 -0
  322. package/dist/backend/dynamic-table/hooks/useDynamicTablePage.js.map +7 -0
  323. package/dist/backend/dynamic-table/hooks/useEscapeLayer.js +32 -0
  324. package/dist/backend/dynamic-table/hooks/useEscapeLayer.js.map +7 -0
  325. package/dist/backend/dynamic-table/hooks/useGrouping.js +256 -0
  326. package/dist/backend/dynamic-table/hooks/useGrouping.js.map +7 -0
  327. package/dist/backend/dynamic-table/hooks/useSuggestionFetch.js +63 -0
  328. package/dist/backend/dynamic-table/hooks/useSuggestionFetch.js.map +7 -0
  329. package/dist/backend/dynamic-table/hooks/useTableDateFormat.js +11 -0
  330. package/dist/backend/dynamic-table/hooks/useTableDateFormat.js.map +7 -0
  331. package/dist/backend/dynamic-table/index.js +476 -0
  332. package/dist/backend/dynamic-table/index.js.map +7 -0
  333. package/dist/backend/dynamic-table/registry/ContentRegistryContext.js +126 -0
  334. package/dist/backend/dynamic-table/registry/ContentRegistryContext.js.map +7 -0
  335. package/dist/backend/dynamic-table/registry/TableRegistryContext.js +43 -0
  336. package/dist/backend/dynamic-table/registry/TableRegistryContext.js.map +7 -0
  337. package/dist/backend/dynamic-table/registry/filterAccessibleTables.js +13 -0
  338. package/dist/backend/dynamic-table/registry/filterAccessibleTables.js.map +7 -0
  339. package/dist/backend/dynamic-table/registry/index.js +44 -0
  340. package/dist/backend/dynamic-table/registry/index.js.map +7 -0
  341. package/dist/backend/dynamic-table/registry/lazyTable.js +55 -0
  342. package/dist/backend/dynamic-table/registry/lazyTable.js.map +7 -0
  343. package/dist/backend/dynamic-table/registry/types.js +1 -0
  344. package/dist/backend/dynamic-table/registry/types.js.map +7 -0
  345. package/dist/backend/dynamic-table/registry/widgetCatalog.js +96 -0
  346. package/dist/backend/dynamic-table/registry/widgetCatalog.js.map +7 -0
  347. package/dist/backend/dynamic-table/server/aggregate.js +261 -0
  348. package/dist/backend/dynamic-table/server/aggregate.js.map +7 -0
  349. package/dist/backend/dynamic-table/server/dateWindows.js +105 -0
  350. package/dist/backend/dynamic-table/server/dateWindows.js.map +7 -0
  351. package/dist/backend/dynamic-table/server/filterParser.js +97 -0
  352. package/dist/backend/dynamic-table/server/filterParser.js.map +7 -0
  353. package/dist/backend/dynamic-table/server/filterSuggestions.js +70 -0
  354. package/dist/backend/dynamic-table/server/filterSuggestions.js.map +7 -0
  355. package/dist/backend/dynamic-table/server/index.js +47 -0
  356. package/dist/backend/dynamic-table/server/index.js.map +7 -0
  357. package/dist/backend/dynamic-table/server/makeDynamicTableRoute.js +270 -0
  358. package/dist/backend/dynamic-table/server/makeDynamicTableRoute.js.map +7 -0
  359. package/dist/backend/dynamic-table/split-view/ContentPicker.js +171 -0
  360. package/dist/backend/dynamic-table/split-view/ContentPicker.js.map +7 -0
  361. package/dist/backend/dynamic-table/split-view/EmptySlot.js +47 -0
  362. package/dist/backend/dynamic-table/split-view/EmptySlot.js.map +7 -0
  363. package/dist/backend/dynamic-table/split-view/SplitViewHost.js +863 -0
  364. package/dist/backend/dynamic-table/split-view/SplitViewHost.js.map +7 -0
  365. package/dist/backend/dynamic-table/split-view/WidgetPane.js +280 -0
  366. package/dist/backend/dynamic-table/split-view/WidgetPane.js.map +7 -0
  367. package/dist/backend/dynamic-table/split-view/WorkspaceFilterBar.js +524 -0
  368. package/dist/backend/dynamic-table/split-view/WorkspaceFilterBar.js.map +7 -0
  369. package/dist/backend/dynamic-table/split-view/index.js +61 -0
  370. package/dist/backend/dynamic-table/split-view/index.js.map +7 -0
  371. package/dist/backend/dynamic-table/split-view/layoutPersistence.js +91 -0
  372. package/dist/backend/dynamic-table/split-view/layoutPersistence.js.map +7 -0
  373. package/dist/backend/dynamic-table/split-view/sharedCriteria.js +62 -0
  374. package/dist/backend/dynamic-table/split-view/sharedCriteria.js.map +7 -0
  375. package/dist/backend/dynamic-table/split-view/types.js +426 -0
  376. package/dist/backend/dynamic-table/split-view/types.js.map +7 -0
  377. package/dist/backend/dynamic-table/split-view/useSplitViewLayouts.js +79 -0
  378. package/dist/backend/dynamic-table/split-view/useSplitViewLayouts.js.map +7 -0
  379. package/dist/backend/dynamic-table/store/index.js +611 -0
  380. package/dist/backend/dynamic-table/store/index.js.map +7 -0
  381. package/dist/backend/dynamic-table/styles/ContextMenu.css.js +2 -0
  382. package/dist/backend/dynamic-table/styles/DynamicTable.css.js +2 -0
  383. package/dist/backend/dynamic-table/styles/DynamicTable.v2.css.js +2 -0
  384. package/dist/backend/dynamic-table/styles/SearchBar.css.js +2 -0
  385. package/dist/backend/dynamic-table/styles/dateCell.css.js +2 -0
  386. package/dist/backend/dynamic-table/styles/density.css.js +2 -0
  387. package/dist/backend/dynamic-table/types/density.js +29 -0
  388. package/dist/backend/dynamic-table/types/density.js.map +7 -0
  389. package/dist/backend/dynamic-table/types/filters.js +124 -0
  390. package/dist/backend/dynamic-table/types/filters.js.map +7 -0
  391. package/dist/backend/dynamic-table/types/grouping.js +34 -0
  392. package/dist/backend/dynamic-table/types/grouping.js.map +7 -0
  393. package/dist/backend/dynamic-table/types/import.js +7 -0
  394. package/dist/backend/dynamic-table/types/import.js.map +7 -0
  395. package/dist/backend/dynamic-table/types/index.js +46 -0
  396. package/dist/backend/dynamic-table/types/index.js.map +7 -0
  397. package/dist/backend/dynamic-table/types/perspective.js +79 -0
  398. package/dist/backend/dynamic-table/types/perspective.js.map +7 -0
  399. package/dist/backend/dynamic-table/types/rollup.js +13 -0
  400. package/dist/backend/dynamic-table/types/rollup.js.map +7 -0
  401. package/dist/backend/dynamic-table/utils/abbreviations.js +228 -0
  402. package/dist/backend/dynamic-table/utils/abbreviations.js.map +7 -0
  403. package/dist/backend/dynamic-table/utils/anchoredPosition.js +21 -0
  404. package/dist/backend/dynamic-table/utils/anchoredPosition.js.map +7 -0
  405. package/dist/backend/dynamic-table/utils/badgeAutoFit.js +35 -0
  406. package/dist/backend/dynamic-table/utils/badgeAutoFit.js.map +7 -0
  407. package/dist/backend/dynamic-table/utils/clipboard.js +172 -0
  408. package/dist/backend/dynamic-table/utils/clipboard.js.map +7 -0
  409. package/dist/backend/dynamic-table/utils/coerceCellValue.js +52 -0
  410. package/dist/backend/dynamic-table/utils/coerceCellValue.js.map +7 -0
  411. package/dist/backend/dynamic-table/utils/colorAdjacency.js +27 -0
  412. package/dist/backend/dynamic-table/utils/colorAdjacency.js.map +7 -0
  413. package/dist/backend/dynamic-table/utils/columnFill.js +36 -0
  414. package/dist/backend/dynamic-table/utils/columnFill.js.map +7 -0
  415. package/dist/backend/dynamic-table/utils/columnSpacerStyle.js +21 -0
  416. package/dist/backend/dynamic-table/utils/columnSpacerStyle.js.map +7 -0
  417. package/dist/backend/dynamic-table/utils/columnWindow.js +293 -0
  418. package/dist/backend/dynamic-table/utils/columnWindow.js.map +7 -0
  419. package/dist/backend/dynamic-table/utils/conditionalFormat.js +188 -0
  420. package/dist/backend/dynamic-table/utils/conditionalFormat.js.map +7 -0
  421. package/dist/backend/dynamic-table/utils/exportTable.js +82 -0
  422. package/dist/backend/dynamic-table/utils/exportTable.js.map +7 -0
  423. package/dist/backend/dynamic-table/utils/fillGeometry.js +92 -0
  424. package/dist/backend/dynamic-table/utils/fillGeometry.js.map +7 -0
  425. package/dist/backend/dynamic-table/utils/fillPatterns.js +241 -0
  426. package/dist/backend/dynamic-table/utils/fillPatterns.js.map +7 -0
  427. package/dist/backend/dynamic-table/utils/formatAggregate.js +82 -0
  428. package/dist/backend/dynamic-table/utils/formatAggregate.js.map +7 -0
  429. package/dist/backend/dynamic-table/utils/formatDateCompact.js +508 -0
  430. package/dist/backend/dynamic-table/utils/formatDateCompact.js.map +7 -0
  431. package/dist/backend/dynamic-table/utils/formatLabelCompact.js +312 -0
  432. package/dist/backend/dynamic-table/utils/formatLabelCompact.js.map +7 -0
  433. package/dist/backend/dynamic-table/utils/formulaColumns.js +158 -0
  434. package/dist/backend/dynamic-table/utils/formulaColumns.js.map +7 -0
  435. package/dist/backend/dynamic-table/utils/importMapping.js +118 -0
  436. package/dist/backend/dynamic-table/utils/importMapping.js.map +7 -0
  437. package/dist/backend/dynamic-table/utils/importParse.js +121 -0
  438. package/dist/backend/dynamic-table/utils/importParse.js.map +7 -0
  439. package/dist/backend/dynamic-table/utils/lookupColumns.js +28 -0
  440. package/dist/backend/dynamic-table/utils/lookupColumns.js.map +7 -0
  441. package/dist/backend/dynamic-table/utils/perspectiveTransforms.js +191 -0
  442. package/dist/backend/dynamic-table/utils/perspectiveTransforms.js.map +7 -0
  443. package/dist/backend/dynamic-table/utils/rollupColumns.js +81 -0
  444. package/dist/backend/dynamic-table/utils/rollupColumns.js.map +7 -0
  445. package/dist/backend/dynamic-table/validators/index.js +36 -0
  446. package/dist/backend/dynamic-table/validators/index.js.map +7 -0
  447. package/dist/backend/fields/registry.generated.js +8 -0
  448. package/dist/backend/fields/registry.generated.js.map +7 -0
  449. package/dist/backend/fields/registry.js +29 -0
  450. package/dist/backend/fields/registry.js.map +7 -0
  451. package/dist/backend/filters/AdvancedFilterBuilder.js +280 -0
  452. package/dist/backend/filters/AdvancedFilterBuilder.js.map +7 -0
  453. package/dist/backend/forms/ActionsDropdown.js +160 -0
  454. package/dist/backend/forms/ActionsDropdown.js.map +7 -0
  455. package/dist/backend/forms/FormActionButtons.js +59 -0
  456. package/dist/backend/forms/FormActionButtons.js.map +7 -0
  457. package/dist/backend/forms/FormFooter.js +18 -0
  458. package/dist/backend/forms/FormFooter.js.map +7 -0
  459. package/dist/backend/forms/FormHeader.js +125 -0
  460. package/dist/backend/forms/FormHeader.js.map +7 -0
  461. package/dist/backend/forms/index.js +11 -0
  462. package/dist/backend/forms/index.js.map +7 -0
  463. package/dist/backend/hooks/useAdvancedFilter.js +64 -0
  464. package/dist/backend/hooks/useAdvancedFilter.js.map +7 -0
  465. package/dist/backend/indexes/PartialIndexBanner.js +74 -0
  466. package/dist/backend/indexes/PartialIndexBanner.js.map +7 -0
  467. package/dist/backend/indexes/store.js +62 -0
  468. package/dist/backend/indexes/store.js.map +7 -0
  469. package/dist/backend/injection/ComponentOverrideProvider.js +55 -0
  470. package/dist/backend/injection/ComponentOverrideProvider.js.map +7 -0
  471. package/dist/backend/injection/InjectedField.js +166 -0
  472. package/dist/backend/injection/InjectedField.js.map +7 -0
  473. package/dist/backend/injection/InjectionSpot.js +323 -0
  474. package/dist/backend/injection/InjectionSpot.js.map +7 -0
  475. package/dist/backend/injection/InjectionWizard.js +256 -0
  476. package/dist/backend/injection/InjectionWizard.js.map +7 -0
  477. package/dist/backend/injection/PageInjectionBoundary.js +26 -0
  478. package/dist/backend/injection/PageInjectionBoundary.js.map +7 -0
  479. package/dist/backend/injection/SseEventIndicator.js +8 -0
  480. package/dist/backend/injection/SseEventIndicator.js.map +7 -0
  481. package/dist/backend/injection/StatusBadgeInjectionSpot.js +34 -0
  482. package/dist/backend/injection/StatusBadgeInjectionSpot.js.map +7 -0
  483. package/dist/backend/injection/StatusBadgeRenderer.js +58 -0
  484. package/dist/backend/injection/StatusBadgeRenderer.js.map +7 -0
  485. package/dist/backend/injection/WidgetSharedState.js +49 -0
  486. package/dist/backend/injection/WidgetSharedState.js.map +7 -0
  487. package/dist/backend/injection/WizardInjectionSpot.js +30 -0
  488. package/dist/backend/injection/WizardInjectionSpot.js.map +7 -0
  489. package/dist/backend/injection/eventBridge.js +129 -0
  490. package/dist/backend/injection/eventBridge.js.map +7 -0
  491. package/dist/backend/injection/helpers.js +26 -0
  492. package/dist/backend/injection/helpers.js.map +7 -0
  493. package/dist/backend/injection/mergeMenuItems.js +49 -0
  494. package/dist/backend/injection/mergeMenuItems.js.map +7 -0
  495. package/dist/backend/injection/mutationEvents.js +20 -0
  496. package/dist/backend/injection/mutationEvents.js.map +7 -0
  497. package/dist/backend/injection/resolveInjectedIcon.js +23 -0
  498. package/dist/backend/injection/resolveInjectedIcon.js.map +7 -0
  499. package/dist/backend/injection/spotIds.js +72 -0
  500. package/dist/backend/injection/spotIds.js.map +7 -0
  501. package/dist/backend/injection/useAppEvent.js +35 -0
  502. package/dist/backend/injection/useAppEvent.js.map +7 -0
  503. package/dist/backend/injection/useGuardedMutation.js +71 -0
  504. package/dist/backend/injection/useGuardedMutation.js.map +7 -0
  505. package/dist/backend/injection/useInjectedMenuItems.js +49 -0
  506. package/dist/backend/injection/useInjectedMenuItems.js.map +7 -0
  507. package/dist/backend/injection/useInjectionDataWidgets.js +36 -0
  508. package/dist/backend/injection/useInjectionDataWidgets.js.map +7 -0
  509. package/dist/backend/injection/useOperationProgress.js +64 -0
  510. package/dist/backend/injection/useOperationProgress.js.map +7 -0
  511. package/dist/backend/injection/useRegisteredComponent.js +89 -0
  512. package/dist/backend/injection/useRegisteredComponent.js.map +7 -0
  513. package/dist/backend/injection/useWidgetSharedState.js +26 -0
  514. package/dist/backend/injection/useWidgetSharedState.js.map +7 -0
  515. package/dist/backend/injection/visibility-utils.js +29 -0
  516. package/dist/backend/injection/visibility-utils.js.map +7 -0
  517. package/dist/backend/injection/widgetRegistry.js +55 -0
  518. package/dist/backend/injection/widgetRegistry.js.map +7 -0
  519. package/dist/backend/inputs/ComboboxInput.js +228 -0
  520. package/dist/backend/inputs/ComboboxInput.js.map +7 -0
  521. package/dist/backend/inputs/DatePicker.js +148 -0
  522. package/dist/backend/inputs/DatePicker.js.map +7 -0
  523. package/dist/backend/inputs/DateTimePicker.js +188 -0
  524. package/dist/backend/inputs/DateTimePicker.js.map +7 -0
  525. package/dist/backend/inputs/EventPatternInput.js +38 -0
  526. package/dist/backend/inputs/EventPatternInput.js.map +7 -0
  527. package/dist/backend/inputs/EventSelect.js +115 -0
  528. package/dist/backend/inputs/EventSelect.js.map +7 -0
  529. package/dist/backend/inputs/LookupSelect.js +197 -0
  530. package/dist/backend/inputs/LookupSelect.js.map +7 -0
  531. package/dist/backend/inputs/PhoneNumberField.js +133 -0
  532. package/dist/backend/inputs/PhoneNumberField.js.map +7 -0
  533. package/dist/backend/inputs/SwitchableMarkdownInput.js +73 -0
  534. package/dist/backend/inputs/SwitchableMarkdownInput.js.map +7 -0
  535. package/dist/backend/inputs/TagsInput.js +258 -0
  536. package/dist/backend/inputs/TagsInput.js.map +7 -0
  537. package/dist/backend/inputs/TimeInput.js +132 -0
  538. package/dist/backend/inputs/TimeInput.js.map +7 -0
  539. package/dist/backend/inputs/TimePicker.js +105 -0
  540. package/dist/backend/inputs/TimePicker.js.map +7 -0
  541. package/dist/backend/inputs/index.js +12 -0
  542. package/dist/backend/inputs/index.js.map +7 -0
  543. package/dist/backend/markdown/MarkdownContent.js +20 -0
  544. package/dist/backend/markdown/MarkdownContent.js.map +7 -0
  545. package/dist/backend/markdown/index.js +3 -0
  546. package/dist/backend/markdown/index.js.map +7 -0
  547. package/dist/backend/markdown/useMarkdownRemarkPlugins.js +33 -0
  548. package/dist/backend/markdown/useMarkdownRemarkPlugins.js.map +7 -0
  549. package/dist/backend/messages/MessageComposer.js +158 -0
  550. package/dist/backend/messages/MessageComposer.js.map +7 -0
  551. package/dist/backend/messages/MessageObjectDetail.js +81 -0
  552. package/dist/backend/messages/MessageObjectDetail.js.map +7 -0
  553. package/dist/backend/messages/MessageObjectPreview.js +48 -0
  554. package/dist/backend/messages/MessageObjectPreview.js.map +7 -0
  555. package/dist/backend/messages/MessageObjectRecordPicker.js +89 -0
  556. package/dist/backend/messages/MessageObjectRecordPicker.js.map +7 -0
  557. package/dist/backend/messages/MessagePrioritySelector.js +74 -0
  558. package/dist/backend/messages/MessagePrioritySelector.js.map +7 -0
  559. package/dist/backend/messages/MessagesIcon.js +22 -0
  560. package/dist/backend/messages/MessagesIcon.js.map +7 -0
  561. package/dist/backend/messages/SendObjectMessageDialog.js +65 -0
  562. package/dist/backend/messages/SendObjectMessageDialog.js.map +7 -0
  563. package/dist/backend/messages/index.js +17 -0
  564. package/dist/backend/messages/index.js.map +7 -0
  565. package/dist/backend/messages/message-compose-form-groups.js +333 -0
  566. package/dist/backend/messages/message-compose-form-groups.js.map +7 -0
  567. package/dist/backend/messages/message-composer.types.js +1 -0
  568. package/dist/backend/messages/message-composer.types.js.map +7 -0
  569. package/dist/backend/messages/message-priority.js +40 -0
  570. package/dist/backend/messages/message-priority.js.map +7 -0
  571. package/dist/backend/messages/useMessageCompose.js +488 -0
  572. package/dist/backend/messages/useMessageCompose.js.map +7 -0
  573. package/dist/backend/messages/useMessageComposeOperations.js +163 -0
  574. package/dist/backend/messages/useMessageComposeOperations.js.map +7 -0
  575. package/dist/backend/messages/useMessagesPoll.js +79 -0
  576. package/dist/backend/messages/useMessagesPoll.js.map +7 -0
  577. package/dist/backend/notifications/NotificationBell.js +83 -0
  578. package/dist/backend/notifications/NotificationBell.js.map +7 -0
  579. package/dist/backend/notifications/NotificationCountBadge.js +9 -0
  580. package/dist/backend/notifications/NotificationCountBadge.js.map +7 -0
  581. package/dist/backend/notifications/NotificationDispatcher.js +165 -0
  582. package/dist/backend/notifications/NotificationDispatcher.js.map +7 -0
  583. package/dist/backend/notifications/NotificationItem.js +187 -0
  584. package/dist/backend/notifications/NotificationItem.js.map +7 -0
  585. package/dist/backend/notifications/NotificationPanel.js +146 -0
  586. package/dist/backend/notifications/NotificationPanel.js.map +7 -0
  587. package/dist/backend/notifications/index.js +19 -0
  588. package/dist/backend/notifications/index.js.map +7 -0
  589. package/dist/backend/notifications/useNotificationActions.js +124 -0
  590. package/dist/backend/notifications/useNotificationActions.js.map +7 -0
  591. package/dist/backend/notifications/useNotificationEffect.js +13 -0
  592. package/dist/backend/notifications/useNotificationEffect.js.map +7 -0
  593. package/dist/backend/notifications/useNotifications.js +11 -0
  594. package/dist/backend/notifications/useNotifications.js.map +7 -0
  595. package/dist/backend/notifications/useNotificationsPoll.js +135 -0
  596. package/dist/backend/notifications/useNotificationsPoll.js.map +7 -0
  597. package/dist/backend/notifications/useNotificationsSse.js +173 -0
  598. package/dist/backend/notifications/useNotificationsSse.js.map +7 -0
  599. package/dist/backend/operations/LastOperationBanner.js +80 -0
  600. package/dist/backend/operations/LastOperationBanner.js.map +7 -0
  601. package/dist/backend/operations/store.js +183 -0
  602. package/dist/backend/operations/store.js.map +7 -0
  603. package/dist/backend/progress/ProgressTopBar.js +129 -0
  604. package/dist/backend/progress/ProgressTopBar.js.map +7 -0
  605. package/dist/backend/progress/useProgress.js +11 -0
  606. package/dist/backend/progress/useProgress.js.map +7 -0
  607. package/dist/backend/progress/useProgressPoll.js +69 -0
  608. package/dist/backend/progress/useProgressPoll.js.map +7 -0
  609. package/dist/backend/progress/useProgressSse.js +104 -0
  610. package/dist/backend/progress/useProgressSse.js.map +7 -0
  611. package/dist/backend/schedule/ScheduleAgenda.js +107 -0
  612. package/dist/backend/schedule/ScheduleAgenda.js.map +7 -0
  613. package/dist/backend/schedule/ScheduleGrid.js +107 -0
  614. package/dist/backend/schedule/ScheduleGrid.js.map +7 -0
  615. package/dist/backend/schedule/ScheduleToolbar.js +166 -0
  616. package/dist/backend/schedule/ScheduleToolbar.js.map +7 -0
  617. package/dist/backend/schedule/ScheduleView.js +168 -0
  618. package/dist/backend/schedule/ScheduleView.js.map +7 -0
  619. package/dist/backend/schedule/index.js +6 -0
  620. package/dist/backend/schedule/index.js.map +7 -0
  621. package/dist/backend/schedule/recurrence.js +83 -0
  622. package/dist/backend/schedule/recurrence.js.map +7 -0
  623. package/dist/backend/schedule/types.js +1 -0
  624. package/dist/backend/schedule/types.js.map +7 -0
  625. package/dist/backend/section-page/SectionNav.js +104 -0
  626. package/dist/backend/section-page/SectionNav.js.map +7 -0
  627. package/dist/backend/section-page/SectionPage.js +33 -0
  628. package/dist/backend/section-page/SectionPage.js.map +7 -0
  629. package/dist/backend/section-page/index.js +7 -0
  630. package/dist/backend/section-page/index.js.map +7 -0
  631. package/dist/backend/section-page/types.js +1 -0
  632. package/dist/backend/section-page/types.js.map +7 -0
  633. package/dist/backend/settings/SettingsNavigation.js +43 -0
  634. package/dist/backend/settings/SettingsNavigation.js.map +7 -0
  635. package/dist/backend/settings/SettingsPageWrapper.js +66 -0
  636. package/dist/backend/settings/SettingsPageWrapper.js.map +7 -0
  637. package/dist/backend/settings/index.js +6 -0
  638. package/dist/backend/settings/index.js.map +7 -0
  639. package/dist/backend/upgrades/UpgradeActionBanner.js +91 -0
  640. package/dist/backend/upgrades/UpgradeActionBanner.js.map +7 -0
  641. package/dist/backend/utils/api.js +178 -0
  642. package/dist/backend/utils/api.js.map +7 -0
  643. package/dist/backend/utils/apiCall.js +68 -0
  644. package/dist/backend/utils/apiCall.js.map +7 -0
  645. package/dist/backend/utils/crud.js +126 -0
  646. package/dist/backend/utils/crud.js.map +7 -0
  647. package/dist/backend/utils/customFieldColumns.js +100 -0
  648. package/dist/backend/utils/customFieldColumns.js.map +7 -0
  649. package/dist/backend/utils/customFieldDefs.js +143 -0
  650. package/dist/backend/utils/customFieldDefs.js.map +7 -0
  651. package/dist/backend/utils/customFieldFilters.js +151 -0
  652. package/dist/backend/utils/customFieldFilters.js.map +7 -0
  653. package/dist/backend/utils/customFieldForms.js +169 -0
  654. package/dist/backend/utils/customFieldForms.js.map +7 -0
  655. package/dist/backend/utils/customFieldRelationDisplay.js +239 -0
  656. package/dist/backend/utils/customFieldRelationDisplay.js.map +7 -0
  657. package/dist/backend/utils/customFieldValues.js +26 -0
  658. package/dist/backend/utils/customFieldValues.js.map +7 -0
  659. package/dist/backend/utils/flash.js +16 -0
  660. package/dist/backend/utils/flash.js.map +7 -0
  661. package/dist/backend/utils/nav.js +280 -0
  662. package/dist/backend/utils/nav.js.map +7 -0
  663. package/dist/backend/utils/richTextSanitizer.js +11 -0
  664. package/dist/backend/utils/richTextSanitizer.js.map +7 -0
  665. package/dist/backend/utils/scopedHeaderStack.js +44 -0
  666. package/dist/backend/utils/scopedHeaderStack.js.map +7 -0
  667. package/dist/backend/utils/serverErrors.js +237 -0
  668. package/dist/backend/utils/serverErrors.js.map +7 -0
  669. package/dist/backend/utils/useAutoDiscoveredFields.js +96 -0
  670. package/dist/backend/utils/useAutoDiscoveredFields.js.map +7 -0
  671. package/dist/backend/version-history/VersionHistoryAction.js +67 -0
  672. package/dist/backend/version-history/VersionHistoryAction.js.map +7 -0
  673. package/dist/backend/version-history/VersionHistoryDetail.js +57 -0
  674. package/dist/backend/version-history/VersionHistoryDetail.js.map +7 -0
  675. package/dist/backend/version-history/VersionHistoryPanel.js +270 -0
  676. package/dist/backend/version-history/VersionHistoryPanel.js.map +7 -0
  677. package/dist/backend/version-history/index.js +13 -0
  678. package/dist/backend/version-history/index.js.map +7 -0
  679. package/dist/backend/version-history/labels.js +52 -0
  680. package/dist/backend/version-history/labels.js.map +7 -0
  681. package/dist/backend/version-history/types.js +1 -0
  682. package/dist/backend/version-history/types.js.map +7 -0
  683. package/dist/backend/version-history/useAuditPermissions.js +72 -0
  684. package/dist/backend/version-history/useAuditPermissions.js.map +7 -0
  685. package/dist/backend/version-history/useVersionHistory.js +141 -0
  686. package/dist/backend/version-history/useVersionHistory.js.map +7 -0
  687. package/dist/backend/views/NewViewForm.js +56 -0
  688. package/dist/backend/views/NewViewForm.js.map +7 -0
  689. package/dist/backend/views/ShareForm.js +49 -0
  690. package/dist/backend/views/ShareForm.js.map +7 -0
  691. package/dist/backend/views/ViewChip.js +112 -0
  692. package/dist/backend/views/ViewChip.js.map +7 -0
  693. package/dist/backend/views/ViewChipMenu.js +89 -0
  694. package/dist/backend/views/ViewChipMenu.js.map +7 -0
  695. package/dist/backend/views/types.js +1 -0
  696. package/dist/backend/views/types.js.map +7 -0
  697. package/dist/frontend/AuthFooter.js +23 -0
  698. package/dist/frontend/AuthFooter.js.map +7 -0
  699. package/dist/frontend/LanguageSwitcher.js +57 -0
  700. package/dist/frontend/LanguageSwitcher.js.map +7 -0
  701. package/dist/frontend/Layout.js +14 -0
  702. package/dist/frontend/Layout.js.map +7 -0
  703. package/dist/hooks/useIsMobile.js +21 -0
  704. package/dist/hooks/useIsMobile.js.map +7 -0
  705. package/dist/index.js +40 -0
  706. package/dist/index.js.map +7 -0
  707. package/dist/portal/PortalContext.js +113 -0
  708. package/dist/portal/PortalContext.js.map +7 -0
  709. package/dist/portal/PortalLayoutProvider.js +5 -0
  710. package/dist/portal/PortalLayoutProvider.js.map +7 -0
  711. package/dist/portal/PortalLayoutShell.js +44 -0
  712. package/dist/portal/PortalLayoutShell.js.map +7 -0
  713. package/dist/portal/PortalShell.js +229 -0
  714. package/dist/portal/PortalShell.js.map +7 -0
  715. package/dist/portal/components/PortalCard.js +31 -0
  716. package/dist/portal/components/PortalCard.js.map +7 -0
  717. package/dist/portal/components/PortalEmptyState.js +16 -0
  718. package/dist/portal/components/PortalEmptyState.js.map +7 -0
  719. package/dist/portal/components/PortalFeatureCard.js +21 -0
  720. package/dist/portal/components/PortalFeatureCard.js.map +7 -0
  721. package/dist/portal/components/PortalNotificationBell.js +67 -0
  722. package/dist/portal/components/PortalNotificationBell.js.map +7 -0
  723. package/dist/portal/components/PortalNotificationPanel.js +158 -0
  724. package/dist/portal/components/PortalNotificationPanel.js.map +7 -0
  725. package/dist/portal/components/PortalPageHeader.js +16 -0
  726. package/dist/portal/components/PortalPageHeader.js.map +7 -0
  727. package/dist/portal/components/index.js +18 -0
  728. package/dist/portal/components/index.js.map +7 -0
  729. package/dist/portal/hooks/useCustomerAuth.js +69 -0
  730. package/dist/portal/hooks/useCustomerAuth.js.map +7 -0
  731. package/dist/portal/hooks/usePortalAppEvent.js +26 -0
  732. package/dist/portal/hooks/usePortalAppEvent.js.map +7 -0
  733. package/dist/portal/hooks/usePortalDashboardWidgets.js +37 -0
  734. package/dist/portal/hooks/usePortalDashboardWidgets.js.map +7 -0
  735. package/dist/portal/hooks/usePortalEventBridge.js +129 -0
  736. package/dist/portal/hooks/usePortalEventBridge.js.map +7 -0
  737. package/dist/portal/hooks/usePortalInjectedMenuItems.js +88 -0
  738. package/dist/portal/hooks/usePortalInjectedMenuItems.js.map +7 -0
  739. package/dist/portal/hooks/usePortalNotifications.js +85 -0
  740. package/dist/portal/hooks/usePortalNotifications.js.map +7 -0
  741. package/dist/portal/hooks/useTenantContext.js +53 -0
  742. package/dist/portal/hooks/useTenantContext.js.map +7 -0
  743. package/dist/primitives/DataLoader.js +68 -0
  744. package/dist/primitives/DataLoader.js.map +7 -0
  745. package/dist/primitives/ErrorNotice.js +14 -0
  746. package/dist/primitives/ErrorNotice.js.map +7 -0
  747. package/dist/primitives/Notice.js +55 -0
  748. package/dist/primitives/Notice.js.map +7 -0
  749. package/dist/primitives/alert.js +38 -0
  750. package/dist/primitives/alert.js.map +7 -0
  751. package/dist/primitives/badge.js +33 -0
  752. package/dist/primitives/badge.js.map +7 -0
  753. package/dist/primitives/button.js +45 -0
  754. package/dist/primitives/button.js.map +7 -0
  755. package/dist/primitives/calendar.js +62 -0
  756. package/dist/primitives/calendar.js.map +7 -0
  757. package/dist/primitives/card.js +91 -0
  758. package/dist/primitives/card.js.map +7 -0
  759. package/dist/primitives/checkbox.js +28 -0
  760. package/dist/primitives/checkbox.js.map +7 -0
  761. package/dist/primitives/dialog.js +101 -0
  762. package/dist/primitives/dialog.js.map +7 -0
  763. package/dist/primitives/form-field.js +78 -0
  764. package/dist/primitives/form-field.js.map +7 -0
  765. package/dist/primitives/icon-button.js +40 -0
  766. package/dist/primitives/icon-button.js.map +7 -0
  767. package/dist/primitives/input.js +22 -0
  768. package/dist/primitives/input.js.map +7 -0
  769. package/dist/primitives/label.js +21 -0
  770. package/dist/primitives/label.js.map +7 -0
  771. package/dist/primitives/popover.js +36 -0
  772. package/dist/primitives/popover.js.map +7 -0
  773. package/dist/primitives/primitives.stories.js +187 -0
  774. package/dist/primitives/primitives.stories.js.map +7 -0
  775. package/dist/primitives/progress.js +28 -0
  776. package/dist/primitives/progress.js.map +7 -0
  777. package/dist/primitives/separator.js +9 -0
  778. package/dist/primitives/separator.js.map +7 -0
  779. package/dist/primitives/sheet.js +103 -0
  780. package/dist/primitives/sheet.js.map +7 -0
  781. package/dist/primitives/spinner.js +24 -0
  782. package/dist/primitives/spinner.js.map +7 -0
  783. package/dist/primitives/status-badge.js +38 -0
  784. package/dist/primitives/status-badge.js.map +7 -0
  785. package/dist/primitives/switch.js +80 -0
  786. package/dist/primitives/switch.js.map +7 -0
  787. package/dist/primitives/table.js +29 -0
  788. package/dist/primitives/table.js.map +7 -0
  789. package/dist/primitives/tabs.js +90 -0
  790. package/dist/primitives/tabs.js.map +7 -0
  791. package/dist/primitives/textarea.js +21 -0
  792. package/dist/primitives/textarea.js.map +7 -0
  793. package/dist/primitives/tooltip.js +60 -0
  794. package/dist/primitives/tooltip.js.map +7 -0
  795. package/dist/primitives-v2/Alert.js +69 -0
  796. package/dist/primitives-v2/Alert.js.map +7 -0
  797. package/dist/primitives-v2/Alert.stories.js +42 -0
  798. package/dist/primitives-v2/Alert.stories.js.map +7 -0
  799. package/dist/primitives-v2/Avatar.js +93 -0
  800. package/dist/primitives-v2/Avatar.js.map +7 -0
  801. package/dist/primitives-v2/Avatar.stories.js +57 -0
  802. package/dist/primitives-v2/Avatar.stories.js.map +7 -0
  803. package/dist/primitives-v2/Badge.js +50 -0
  804. package/dist/primitives-v2/Badge.js.map +7 -0
  805. package/dist/primitives-v2/Badge.stories.js +66 -0
  806. package/dist/primitives-v2/Badge.stories.js.map +7 -0
  807. package/dist/primitives-v2/Breadcrumb.js +53 -0
  808. package/dist/primitives-v2/Breadcrumb.js.map +7 -0
  809. package/dist/primitives-v2/Breadcrumb.stories.js +70 -0
  810. package/dist/primitives-v2/Breadcrumb.stories.js.map +7 -0
  811. package/dist/primitives-v2/Button.js +85 -0
  812. package/dist/primitives-v2/Button.js.map +7 -0
  813. package/dist/primitives-v2/Button.stories.js +48 -0
  814. package/dist/primitives-v2/Button.stories.js.map +7 -0
  815. package/dist/primitives-v2/Checkbox.js +65 -0
  816. package/dist/primitives-v2/Checkbox.js.map +7 -0
  817. package/dist/primitives-v2/Checkbox.stories.js +31 -0
  818. package/dist/primitives-v2/Checkbox.stories.js.map +7 -0
  819. package/dist/primitives-v2/IconButton.js +13 -0
  820. package/dist/primitives-v2/IconButton.js.map +7 -0
  821. package/dist/primitives-v2/IconButton.stories.js +37 -0
  822. package/dist/primitives-v2/IconButton.stories.js.map +7 -0
  823. package/dist/primitives-v2/Input.js +74 -0
  824. package/dist/primitives-v2/Input.js.map +7 -0
  825. package/dist/primitives-v2/Input.stories.js +56 -0
  826. package/dist/primitives-v2/Input.stories.js.map +7 -0
  827. package/dist/primitives-v2/NavGroup.js +54 -0
  828. package/dist/primitives-v2/NavGroup.js.map +7 -0
  829. package/dist/primitives-v2/NavGroup.stories.js +39 -0
  830. package/dist/primitives-v2/NavGroup.stories.js.map +7 -0
  831. package/dist/primitives-v2/NavItem.js +61 -0
  832. package/dist/primitives-v2/NavItem.js.map +7 -0
  833. package/dist/primitives-v2/NavItem.stories.js +56 -0
  834. package/dist/primitives-v2/NavItem.stories.js.map +7 -0
  835. package/dist/primitives-v2/SearchInput.js +93 -0
  836. package/dist/primitives-v2/SearchInput.js.map +7 -0
  837. package/dist/primitives-v2/SearchInput.stories.js +41 -0
  838. package/dist/primitives-v2/SearchInput.stories.js.map +7 -0
  839. package/dist/primitives-v2/Sidebar.js +48 -0
  840. package/dist/primitives-v2/Sidebar.js.map +7 -0
  841. package/dist/primitives-v2/Sidebar.stories.js +76 -0
  842. package/dist/primitives-v2/Sidebar.stories.js.map +7 -0
  843. package/dist/primitives-v2/Tab.js +78 -0
  844. package/dist/primitives-v2/Tab.js.map +7 -0
  845. package/dist/primitives-v2/Tab.stories.js +51 -0
  846. package/dist/primitives-v2/Tab.stories.js.map +7 -0
  847. package/dist/primitives-v2/Tag.js +61 -0
  848. package/dist/primitives-v2/Tag.js.map +7 -0
  849. package/dist/primitives-v2/Tag.stories.js +121 -0
  850. package/dist/primitives-v2/Tag.stories.js.map +7 -0
  851. package/dist/primitives-v2/Toggle.js +72 -0
  852. package/dist/primitives-v2/Toggle.js.map +7 -0
  853. package/dist/primitives-v2/Toggle.stories.js +34 -0
  854. package/dist/primitives-v2/Toggle.stories.js.map +7 -0
  855. package/dist/primitives-v2/Topbar.js +24 -0
  856. package/dist/primitives-v2/Topbar.js.map +7 -0
  857. package/dist/primitives-v2/Topbar.stories.js +58 -0
  858. package/dist/primitives-v2/Topbar.stories.js.map +7 -0
  859. package/dist/primitives-v2/index.js +41 -0
  860. package/dist/primitives-v2/index.js.map +7 -0
  861. package/dist/primitives-v2/utils.js +7 -0
  862. package/dist/primitives-v2/utils.js.map +7 -0
  863. package/dist/theme/BrandThemeProvider.js +49 -0
  864. package/dist/theme/BrandThemeProvider.js.map +7 -0
  865. package/dist/theme/QueryProvider.js +44 -0
  866. package/dist/theme/QueryProvider.js.map +7 -0
  867. package/dist/theme/ThemeProvider.js +96 -0
  868. package/dist/theme/ThemeProvider.js.map +7 -0
  869. package/dist/theme/ThemeToggle.js +88 -0
  870. package/dist/theme/ThemeToggle.js.map +7 -0
  871. package/dist/theme/index.js +12 -0
  872. package/dist/theme/index.js.map +7 -0
  873. package/dist/theme/m3.css.js +2 -0
  874. package/dist/theme/tokens.v2.css.js +2 -0
  875. package/dist/theme/typography.css.js +2 -0
  876. package/dist/theme/typography.stories.js +123 -0
  877. package/dist/theme/typography.stories.js.map +7 -0
  878. package/dist/theme/typography.tokens.js +281 -0
  879. package/dist/theme/typography.tokens.js.map +7 -0
  880. package/dist/types/react-big-calendar.d.js +1 -0
  881. package/dist/types/react-big-calendar.d.js.map +7 -0
  882. package/package.json +411 -0
  883. package/src/backend/AppShell.tsx +1606 -0
  884. package/src/backend/BackendChromeProvider.tsx +99 -0
  885. package/src/backend/BackendPageSurface.tsx +57 -0
  886. package/src/backend/CollapsibleNavSection.tsx +201 -0
  887. package/src/backend/ContextHelp.tsx +40 -0
  888. package/src/backend/CrudForm.tsx +3796 -0
  889. package/src/backend/DataTable.tsx +2584 -0
  890. package/src/backend/EmptyState.tsx +65 -0
  891. package/src/backend/FilterBar.tsx +171 -0
  892. package/src/backend/FilterOverlay.tsx +388 -0
  893. package/src/backend/FlashMessages.tsx +189 -0
  894. package/src/backend/HtmlRichTextEditor.tsx +124 -0
  895. package/src/backend/IntegrationsButton.tsx +29 -0
  896. package/src/backend/JsonBuilder.tsx +359 -0
  897. package/src/backend/JsonDisplay.tsx +258 -0
  898. package/src/backend/NextStepCallout.tsx +134 -0
  899. package/src/backend/Page.tsx +30 -0
  900. package/src/backend/PerspectiveSidebar.tsx +506 -0
  901. package/src/backend/ProfileDropdown.tsx +369 -0
  902. package/src/backend/RowActions.tsx +158 -0
  903. package/src/backend/SectionHeader.tsx +119 -0
  904. package/src/backend/SettingsButton.tsx +28 -0
  905. package/src/backend/Sidebar.stories.tsx +183 -0
  906. package/src/backend/Sidebar.tsx +737 -0
  907. package/src/backend/TruncatedCell.tsx +133 -0
  908. package/src/backend/UserMenu.tsx +153 -0
  909. package/src/backend/ValueIcons.tsx +48 -0
  910. package/src/backend/WebhookSetupGuide.tsx +127 -0
  911. package/src/backend/__tests__/AppShell.test.tsx +392 -0
  912. package/src/backend/__tests__/CrudForm.custom-fields.test.tsx +180 -0
  913. package/src/backend/__tests__/CrudForm.datetime.test.tsx +95 -0
  914. package/src/backend/__tests__/CrudForm.defaults.test.tsx +195 -0
  915. package/src/backend/__tests__/CrudForm.navigation.test.tsx +156 -0
  916. package/src/backend/__tests__/CrudForm.render.test.tsx +146 -0
  917. package/src/backend/__tests__/CrudForm.transformData.test.tsx +231 -0
  918. package/src/backend/__tests__/CrudForm.unsavedNavigation.test.tsx +145 -0
  919. package/src/backend/__tests__/CrudForm.validation.test.tsx +178 -0
  920. package/src/backend/__tests__/CustomDataSection.test.tsx +465 -0
  921. package/src/backend/__tests__/DataTable.extensions.test.tsx +339 -0
  922. package/src/backend/__tests__/DataTable.namespaces.test.ts +32 -0
  923. package/src/backend/__tests__/DataTable.render.test.tsx +48 -0
  924. package/src/backend/__tests__/FieldDefinitionsEditor.test.tsx +64 -0
  925. package/src/backend/__tests__/FlashMessages.test.tsx +105 -0
  926. package/src/backend/__tests__/FormHeader.test.tsx +81 -0
  927. package/src/backend/__tests__/NotificationDispatcher.test.ts +172 -0
  928. package/src/backend/__tests__/VersionHistoryPanel.test.tsx +109 -0
  929. package/src/backend/__tests__/component-replacement.test.tsx +270 -0
  930. package/src/backend/__tests__/custom-field-filters.test.ts +72 -0
  931. package/src/backend/__tests__/custom-field-forms.test.ts +54 -0
  932. package/src/backend/__tests__/nav-utils.test.ts +175 -0
  933. package/src/backend/__tests__/serverErrors.test.ts +83 -0
  934. package/src/backend/__tests__/useAuditPermissions.test.tsx +51 -0
  935. package/src/backend/__tests__/useNotifications.strategy.test.ts +58 -0
  936. package/src/backend/__tests__/useProgress.strategy.test.ts +62 -0
  937. package/src/backend/charts/BarChart.tsx +208 -0
  938. package/src/backend/charts/ChartUtils.tsx +196 -0
  939. package/src/backend/charts/ComboChart.stories.tsx +103 -0
  940. package/src/backend/charts/ComboChart.tsx +350 -0
  941. package/src/backend/charts/KpiCard.tsx +155 -0
  942. package/src/backend/charts/LineChart.tsx +207 -0
  943. package/src/backend/charts/PieChart.tsx +157 -0
  944. package/src/backend/charts/ScatterChart.tsx +498 -0
  945. package/src/backend/charts/TopNTable.tsx +141 -0
  946. package/src/backend/charts/WaterfallChart.tsx +213 -0
  947. package/src/backend/charts/index.ts +21 -0
  948. package/src/backend/columns/ColumnChooserPanel.tsx +293 -0
  949. package/src/backend/confirm-dialog/ConfirmDialog.tsx +275 -0
  950. package/src/backend/confirm-dialog/index.ts +7 -0
  951. package/src/backend/confirm-dialog/useConfirmDialog.tsx +146 -0
  952. package/src/backend/custom-fields/FieldDefinitionsEditor.tsx +1413 -0
  953. package/src/backend/custom-fields/FieldDefinitionsManager.tsx +381 -0
  954. package/src/backend/dashboard/DashboardScreen.tsx +706 -0
  955. package/src/backend/dashboard/__tests__/DashboardScreen.test.tsx +114 -0
  956. package/src/backend/dashboard/index.ts +1 -0
  957. package/src/backend/dashboard/widgetRegistry.ts +68 -0
  958. package/src/backend/date-range/DateRangeSelect.tsx +50 -0
  959. package/src/backend/date-range/InlineDateRangeSelect.tsx +52 -0
  960. package/src/backend/date-range/InlineGranularitySelect.tsx +63 -0
  961. package/src/backend/date-range/__tests__/dateRanges.test.ts +224 -0
  962. package/src/backend/date-range/dateRanges.ts +218 -0
  963. package/src/backend/date-range/index.ts +15 -0
  964. package/src/backend/detail/AccessDeniedMessage.tsx +32 -0
  965. package/src/backend/detail/ActivitiesSection.tsx +1261 -0
  966. package/src/backend/detail/AddressEditor.tsx +479 -0
  967. package/src/backend/detail/AddressTiles.tsx +591 -0
  968. package/src/backend/detail/AddressesSection.tsx +362 -0
  969. package/src/backend/detail/AttachmentDeleteDialog.tsx +56 -0
  970. package/src/backend/detail/AttachmentMetadataDialog.tsx +674 -0
  971. package/src/backend/detail/AttachmentVisualPreview.tsx +155 -0
  972. package/src/backend/detail/AttachmentsSection.tsx +327 -0
  973. package/src/backend/detail/CustomDataSection.tsx +700 -0
  974. package/src/backend/detail/DetailFieldsSection.tsx +163 -0
  975. package/src/backend/detail/ErrorMessage.tsx +32 -0
  976. package/src/backend/detail/InlineEditors.tsx +894 -0
  977. package/src/backend/detail/LoadingMessage.tsx +14 -0
  978. package/src/backend/detail/NotesSection.tsx +1266 -0
  979. package/src/backend/detail/TabEmptyState.tsx +48 -0
  980. package/src/backend/detail/TagsSection.tsx +470 -0
  981. package/src/backend/detail/__tests__/InlineEditors.test.tsx +59 -0
  982. package/src/backend/detail/addressFormat.tsx +121 -0
  983. package/src/backend/detail/index.ts +46 -0
  984. package/src/backend/devtools/UmesDevToolsPanel.tsx +122 -0
  985. package/src/backend/devtools/components/ConflictWarnings.tsx +36 -0
  986. package/src/backend/devtools/components/EnricherTiming.tsx +50 -0
  987. package/src/backend/devtools/components/EventFlow.tsx +45 -0
  988. package/src/backend/devtools/components/ExtensionPointList.tsx +59 -0
  989. package/src/backend/devtools/components/InterceptorActivity.tsx +48 -0
  990. package/src/backend/devtools/index.ts +2 -0
  991. package/src/backend/devtools/useUmesDevTools.ts +188 -0
  992. package/src/backend/document-viewer/RegionOverlay.tsx +150 -0
  993. package/src/backend/document-viewer/index.ts +2 -0
  994. package/src/backend/dynamic-grid/DynamicGrid.tsx +161 -0
  995. package/src/backend/dynamic-grid/adapters.ts +57 -0
  996. package/src/backend/dynamic-grid/components/GridCell.tsx +194 -0
  997. package/src/backend/dynamic-grid/components/GridRow.tsx +40 -0
  998. package/src/backend/dynamic-grid/hooks/useGridKeyboardNav.ts +134 -0
  999. package/src/backend/dynamic-grid/index.ts +4 -0
  1000. package/src/backend/dynamic-grid/types.ts +55 -0
  1001. package/src/backend/dynamic-table/DynamicTable.stories.tsx +274 -0
  1002. package/src/backend/dynamic-table/DynamicTable.tsx +4419 -0
  1003. package/src/backend/dynamic-table/README.md +1199 -0
  1004. package/src/backend/dynamic-table/URL_FILTERING.md +217 -0
  1005. package/src/backend/dynamic-table/__e2e__/GridHarness.ts +1155 -0
  1006. package/src/backend/dynamic-table/__e2e__/SplitViewHarness.ts +366 -0
  1007. package/src/backend/dynamic-table/__tests__/BulkActionsBar.test.tsx +143 -0
  1008. package/src/backend/dynamic-table/__tests__/ColumnQuickFilter.test.tsx +607 -0
  1009. package/src/backend/dynamic-table/__tests__/ConfigureViewFilters.suggestions.test.tsx +177 -0
  1010. package/src/backend/dynamic-table/__tests__/ConfigureViewFormatting.test.tsx +125 -0
  1011. package/src/backend/dynamic-table/__tests__/ConfigureViewFormulas.test.tsx +228 -0
  1012. package/src/backend/dynamic-table/__tests__/ConfigureViewGrouping.aggregations.test.tsx +131 -0
  1013. package/src/backend/dynamic-table/__tests__/ConfigureViewPanel.baseView.test.tsx +162 -0
  1014. package/src/backend/dynamic-table/__tests__/ConfigureViewPanel.focus.test.tsx +54 -0
  1015. package/src/backend/dynamic-table/__tests__/ConfigureViewPanel.sections.test.tsx +142 -0
  1016. package/src/backend/dynamic-table/__tests__/ConfigureViewRollups.test.tsx +228 -0
  1017. package/src/backend/dynamic-table/__tests__/ContextMenu.test.tsx +89 -0
  1018. package/src/backend/dynamic-table/__tests__/DynamicTable.density.test.tsx +299 -0
  1019. package/src/backend/dynamic-table/__tests__/DynamicTable.exportTruncation.test.tsx +145 -0
  1020. package/src/backend/dynamic-table/__tests__/DynamicTable.loadError.test.tsx +173 -0
  1021. package/src/backend/dynamic-table/__tests__/DynamicTable.wiring.test.tsx +357 -0
  1022. package/src/backend/dynamic-table/__tests__/EmptyState.test.tsx +70 -0
  1023. package/src/backend/dynamic-table/__tests__/ExportMenu.test.tsx +82 -0
  1024. package/src/backend/dynamic-table/__tests__/FooterTotalsRow.test.tsx +154 -0
  1025. package/src/backend/dynamic-table/__tests__/GroupSummaryRow.render.test.tsx +131 -0
  1026. package/src/backend/dynamic-table/__tests__/LoadErrorState.test.tsx +74 -0
  1027. package/src/backend/dynamic-table/__tests__/MentionPopup.search.test.tsx +127 -0
  1028. package/src/backend/dynamic-table/__tests__/PerspectiveTabs.test.tsx +170 -0
  1029. package/src/backend/dynamic-table/__tests__/RowHeaderCell.selection.test.tsx +80 -0
  1030. package/src/backend/dynamic-table/__tests__/abbreviationsSubscription.test.ts +171 -0
  1031. package/src/backend/dynamic-table/__tests__/aggregate.spec.test.ts +224 -0
  1032. package/src/backend/dynamic-table/__tests__/aggregateDimension.test.tsx +191 -0
  1033. package/src/backend/dynamic-table/__tests__/anchoredPosition.test.ts +88 -0
  1034. package/src/backend/dynamic-table/__tests__/badgeAutoFit.test.ts +121 -0
  1035. package/src/backend/dynamic-table/__tests__/cellHandlers.save.test.ts +282 -0
  1036. package/src/backend/dynamic-table/__tests__/cellWrites.test.ts +274 -0
  1037. package/src/backend/dynamic-table/__tests__/clipboard.test.ts +230 -0
  1038. package/src/backend/dynamic-table/__tests__/coerceCellValue.test.ts +117 -0
  1039. package/src/backend/dynamic-table/__tests__/colorAdjacency.test.ts +151 -0
  1040. package/src/backend/dynamic-table/__tests__/columnFill.test.ts +66 -0
  1041. package/src/backend/dynamic-table/__tests__/columnHeaderHandlers.sort.test.ts +100 -0
  1042. package/src/backend/dynamic-table/__tests__/columnHeaderReorder.test.tsx +209 -0
  1043. package/src/backend/dynamic-table/__tests__/columnReorderPersistence.test.tsx +127 -0
  1044. package/src/backend/dynamic-table/__tests__/columnVirtualization.render.test.tsx +420 -0
  1045. package/src/backend/dynamic-table/__tests__/columnVisibilityPersistence.test.tsx +136 -0
  1046. package/src/backend/dynamic-table/__tests__/columnWindow.test.ts +643 -0
  1047. package/src/backend/dynamic-table/__tests__/commentAudience.test.tsx +137 -0
  1048. package/src/backend/dynamic-table/__tests__/commentScope.test.tsx +214 -0
  1049. package/src/backend/dynamic-table/__tests__/conditionalFormat.test.ts +175 -0
  1050. package/src/backend/dynamic-table/__tests__/contentRegistry.test.ts +267 -0
  1051. package/src/backend/dynamic-table/__tests__/dateWindows.test.ts +149 -0
  1052. package/src/backend/dynamic-table/__tests__/density.test.ts +204 -0
  1053. package/src/backend/dynamic-table/__tests__/exportTable.test.ts +146 -0
  1054. package/src/backend/dynamic-table/__tests__/fillGeometry.test.ts +201 -0
  1055. package/src/backend/dynamic-table/__tests__/fillPatterns.test.ts +272 -0
  1056. package/src/backend/dynamic-table/__tests__/filterParser.presets.test.ts +64 -0
  1057. package/src/backend/dynamic-table/__tests__/filterParser.relative.test.ts +109 -0
  1058. package/src/backend/dynamic-table/__tests__/filterSuggestions.test.ts +152 -0
  1059. package/src/backend/dynamic-table/__tests__/formatAggregate.test.ts +99 -0
  1060. package/src/backend/dynamic-table/__tests__/formatDateCompact.test.ts +489 -0
  1061. package/src/backend/dynamic-table/__tests__/formatLabelCompact.test.ts +717 -0
  1062. package/src/backend/dynamic-table/__tests__/formula.check.test.ts +257 -0
  1063. package/src/backend/dynamic-table/__tests__/formula.evaluate.test.ts +274 -0
  1064. package/src/backend/dynamic-table/__tests__/formula.functions.test.ts +226 -0
  1065. package/src/backend/dynamic-table/__tests__/formula.noEval.test.ts +92 -0
  1066. package/src/backend/dynamic-table/__tests__/formula.parse.test.ts +233 -0
  1067. package/src/backend/dynamic-table/__tests__/formulaColumns.test.tsx +213 -0
  1068. package/src/backend/dynamic-table/__tests__/handlerIdentity.test.ts +77 -0
  1069. package/src/backend/dynamic-table/__tests__/importMapping.test.ts +174 -0
  1070. package/src/backend/dynamic-table/__tests__/importParse.test.ts +130 -0
  1071. package/src/backend/dynamic-table/__tests__/importServerOnly.test.ts +37 -0
  1072. package/src/backend/dynamic-table/__tests__/layoutPersistence.test.ts +372 -0
  1073. package/src/backend/dynamic-table/__tests__/mouseHandlers.doubleClick.test.ts +155 -0
  1074. package/src/backend/dynamic-table/__tests__/perspectivePersonalization.test.ts +188 -0
  1075. package/src/backend/dynamic-table/__tests__/perspectiveResolver.test.ts +133 -0
  1076. package/src/backend/dynamic-table/__tests__/perspectiveState.defaultGrouping.test.ts +306 -0
  1077. package/src/backend/dynamic-table/__tests__/perspectiveState.defaults.test.ts +107 -0
  1078. package/src/backend/dynamic-table/__tests__/perspectiveTemplates.test.tsx +269 -0
  1079. package/src/backend/dynamic-table/__tests__/perspectiveTransforms.aggregations.test.ts +105 -0
  1080. package/src/backend/dynamic-table/__tests__/perspectiveTransforms.conditionalFormats.test.ts +107 -0
  1081. package/src/backend/dynamic-table/__tests__/perspectiveTransforms.dateFormat.test.ts +61 -0
  1082. package/src/backend/dynamic-table/__tests__/perspectiveTransforms.formulas.test.ts +85 -0
  1083. package/src/backend/dynamic-table/__tests__/perspectiveTransforms.frozenColumns.test.ts +124 -0
  1084. package/src/backend/dynamic-table/__tests__/rollupColumns.test.ts +149 -0
  1085. package/src/backend/dynamic-table/__tests__/sharedCriteria.test.ts +255 -0
  1086. package/src/backend/dynamic-table/__tests__/splitViewTree.test.ts +324 -0
  1087. package/src/backend/dynamic-table/__tests__/store.clipboardMarker.test.ts +143 -0
  1088. package/src/backend/dynamic-table/__tests__/store.fillPreview.test.ts +168 -0
  1089. package/src/backend/dynamic-table/__tests__/store.mutations.test.ts +345 -0
  1090. package/src/backend/dynamic-table/__tests__/store.selection.test.ts +157 -0
  1091. package/src/backend/dynamic-table/__tests__/store.undo.test.ts +225 -0
  1092. package/src/backend/dynamic-table/__tests__/store.valueSource.test.tsx +204 -0
  1093. package/src/backend/dynamic-table/__tests__/useAnnotations.legacyOptions.test.tsx +58 -0
  1094. package/src/backend/dynamic-table/__tests__/useColumnVirtualizer.test.ts +290 -0
  1095. package/src/backend/dynamic-table/__tests__/useDensityPreference.test.ts +435 -0
  1096. package/src/backend/dynamic-table/__tests__/useDynamicTablePage.duplicate.test.tsx +99 -0
  1097. package/src/backend/dynamic-table/__tests__/useDynamicTablePage.export.test.tsx +281 -0
  1098. package/src/backend/dynamic-table/__tests__/useDynamicTablePage.personalization.test.tsx +313 -0
  1099. package/src/backend/dynamic-table/__tests__/useDynamicTablePage.perspectiveRestore.test.tsx +126 -0
  1100. package/src/backend/dynamic-table/__tests__/useGrouping.aggregations.test.ts +158 -0
  1101. package/src/backend/dynamic-table/__tests__/useGrouping.groupKey.test.ts +58 -0
  1102. package/src/backend/dynamic-table/__tests__/useKeyboardNavigation.test.ts +594 -0
  1103. package/src/backend/dynamic-table/__tests__/useStickyOffsets.memo.test.tsx +75 -0
  1104. package/src/backend/dynamic-table/__tests__/useStickyOffsets.test.ts +106 -0
  1105. package/src/backend/dynamic-table/__tests__/widgetPane.test.tsx +338 -0
  1106. package/src/backend/dynamic-table/components/ActiveFilterChips.tsx +109 -0
  1107. package/src/backend/dynamic-table/components/BulkActionsBar.tsx +89 -0
  1108. package/src/backend/dynamic-table/components/Cell.tsx +292 -0
  1109. package/src/backend/dynamic-table/components/CellCommentDialog.tsx +887 -0
  1110. package/src/backend/dynamic-table/components/CellCommentHoverPopup.tsx +94 -0
  1111. package/src/backend/dynamic-table/components/ColumnFilterPopover.tsx +775 -0
  1112. package/src/backend/dynamic-table/components/ColumnHeaderMenu.tsx +189 -0
  1113. package/src/backend/dynamic-table/components/ColumnHeaders.tsx +867 -0
  1114. package/src/backend/dynamic-table/components/CompactLabelCell.tsx +293 -0
  1115. package/src/backend/dynamic-table/components/ConfigureViewFields.tsx +173 -0
  1116. package/src/backend/dynamic-table/components/ConfigureViewFilters.tsx +346 -0
  1117. package/src/backend/dynamic-table/components/ConfigureViewFormatting.tsx +205 -0
  1118. package/src/backend/dynamic-table/components/ConfigureViewFormulas.tsx +423 -0
  1119. package/src/backend/dynamic-table/components/ConfigureViewGrouping.tsx +264 -0
  1120. package/src/backend/dynamic-table/components/ConfigureViewLinkedColumns.tsx +249 -0
  1121. package/src/backend/dynamic-table/components/ConfigureViewPanel.tsx +857 -0
  1122. package/src/backend/dynamic-table/components/ConfigureViewRollups.tsx +364 -0
  1123. package/src/backend/dynamic-table/components/ConfigureViewSorting.tsx +121 -0
  1124. package/src/backend/dynamic-table/components/ContextMenu.tsx +140 -0
  1125. package/src/backend/dynamic-table/components/DateCell.tsx +205 -0
  1126. package/src/backend/dynamic-table/components/Debugger.tsx +340 -0
  1127. package/src/backend/dynamic-table/components/DensityControl.tsx +441 -0
  1128. package/src/backend/dynamic-table/components/EmptyState.tsx +103 -0
  1129. package/src/backend/dynamic-table/components/EntitySearchEditor.tsx +528 -0
  1130. package/src/backend/dynamic-table/components/ExportMenu.tsx +90 -0
  1131. package/src/backend/dynamic-table/components/FilterDatePicker.tsx +194 -0
  1132. package/src/backend/dynamic-table/components/FilterValueInput.tsx +294 -0
  1133. package/src/backend/dynamic-table/components/FooterTotalsRow.tsx +291 -0
  1134. package/src/backend/dynamic-table/components/FullscreenOverlay.tsx +66 -0
  1135. package/src/backend/dynamic-table/components/GroupHeaderRow.tsx +136 -0
  1136. package/src/backend/dynamic-table/components/GroupSummaryRow.tsx +184 -0
  1137. package/src/backend/dynamic-table/components/ImportPanel.tsx +445 -0
  1138. package/src/backend/dynamic-table/components/ImportPreviewGrid.tsx +155 -0
  1139. package/src/backend/dynamic-table/components/LoadErrorState.tsx +70 -0
  1140. package/src/backend/dynamic-table/components/MentionPopup.tsx +224 -0
  1141. package/src/backend/dynamic-table/components/PerspectiveDeleteDialog.tsx +96 -0
  1142. package/src/backend/dynamic-table/components/PerspectivePublishDialog.tsx +152 -0
  1143. package/src/backend/dynamic-table/components/PerspectiveTabMenu.tsx +215 -0
  1144. package/src/backend/dynamic-table/components/PerspectiveTabs.tsx +426 -0
  1145. package/src/backend/dynamic-table/components/PerspectiveTemplateMenu.tsx +135 -0
  1146. package/src/backend/dynamic-table/components/RowHeaderCell.tsx +73 -0
  1147. package/src/backend/dynamic-table/components/SearchBar.tsx +309 -0
  1148. package/src/backend/dynamic-table/components/SelectMenu.tsx +237 -0
  1149. package/src/backend/dynamic-table/components/StaleDataBar.tsx +74 -0
  1150. package/src/backend/dynamic-table/components/TableDeleteDialog.tsx +74 -0
  1151. package/src/backend/dynamic-table/components/TablePagination.tsx +96 -0
  1152. package/src/backend/dynamic-table/components/TableSkeleton.tsx +123 -0
  1153. package/src/backend/dynamic-table/components/ToolbarOverflow.tsx +284 -0
  1154. package/src/backend/dynamic-table/components/ViewModeSwitch.tsx +92 -0
  1155. package/src/backend/dynamic-table/components/VirtualRow.tsx +346 -0
  1156. package/src/backend/dynamic-table/components/editors.tsx +1727 -0
  1157. package/src/backend/dynamic-table/components/renderers.tsx +162 -0
  1158. package/src/backend/dynamic-table/events/events.ts +107 -0
  1159. package/src/backend/dynamic-table/formula/check.ts +359 -0
  1160. package/src/backend/dynamic-table/formula/evaluate.ts +473 -0
  1161. package/src/backend/dynamic-table/formula/functions.ts +737 -0
  1162. package/src/backend/dynamic-table/formula/index.ts +57 -0
  1163. package/src/backend/dynamic-table/formula/parse.ts +414 -0
  1164. package/src/backend/dynamic-table/formula/types.ts +151 -0
  1165. package/src/backend/dynamic-table/handlers/cellWrites.ts +362 -0
  1166. package/src/backend/dynamic-table/handlers/index.ts +789 -0
  1167. package/src/backend/dynamic-table/handlers/perspectiveHandlers.ts +684 -0
  1168. package/src/backend/dynamic-table/hooks/index.ts +888 -0
  1169. package/src/backend/dynamic-table/hooks/useAbbreviations.ts +67 -0
  1170. package/src/backend/dynamic-table/hooks/useAnnotations.ts +215 -0
  1171. package/src/backend/dynamic-table/hooks/useColumnVirtualizer.ts +303 -0
  1172. package/src/backend/dynamic-table/hooks/useColumnWidthPersistence.ts +214 -0
  1173. package/src/backend/dynamic-table/hooks/useDensityPreference.ts +451 -0
  1174. package/src/backend/dynamic-table/hooks/useDynamicTablePage.tsx +1681 -0
  1175. package/src/backend/dynamic-table/hooks/useEscapeLayer.ts +72 -0
  1176. package/src/backend/dynamic-table/hooks/useGrouping.ts +428 -0
  1177. package/src/backend/dynamic-table/hooks/useSuggestionFetch.ts +109 -0
  1178. package/src/backend/dynamic-table/hooks/useTableDateFormat.tsx +19 -0
  1179. package/src/backend/dynamic-table/index.ts +497 -0
  1180. package/src/backend/dynamic-table/registry/ContentRegistryContext.tsx +244 -0
  1181. package/src/backend/dynamic-table/registry/TableRegistryContext.tsx +84 -0
  1182. package/src/backend/dynamic-table/registry/filterAccessibleTables.ts +36 -0
  1183. package/src/backend/dynamic-table/registry/index.ts +38 -0
  1184. package/src/backend/dynamic-table/registry/lazyTable.tsx +80 -0
  1185. package/src/backend/dynamic-table/registry/types.ts +181 -0
  1186. package/src/backend/dynamic-table/registry/widgetCatalog.ts +226 -0
  1187. package/src/backend/dynamic-table/server/aggregate.ts +474 -0
  1188. package/src/backend/dynamic-table/server/dateWindows.ts +201 -0
  1189. package/src/backend/dynamic-table/server/filterParser.ts +132 -0
  1190. package/src/backend/dynamic-table/server/filterSuggestions.ts +150 -0
  1191. package/src/backend/dynamic-table/server/index.ts +47 -0
  1192. package/src/backend/dynamic-table/server/makeDynamicTableRoute.ts +426 -0
  1193. package/src/backend/dynamic-table/split-view/ContentPicker.tsx +251 -0
  1194. package/src/backend/dynamic-table/split-view/EmptySlot.tsx +69 -0
  1195. package/src/backend/dynamic-table/split-view/SplitViewHost.tsx +1336 -0
  1196. package/src/backend/dynamic-table/split-view/WidgetPane.tsx +390 -0
  1197. package/src/backend/dynamic-table/split-view/WorkspaceFilterBar.tsx +728 -0
  1198. package/src/backend/dynamic-table/split-view/index.ts +48 -0
  1199. package/src/backend/dynamic-table/split-view/layoutPersistence.ts +185 -0
  1200. package/src/backend/dynamic-table/split-view/sharedCriteria.ts +196 -0
  1201. package/src/backend/dynamic-table/split-view/types.ts +778 -0
  1202. package/src/backend/dynamic-table/split-view/useSplitViewLayouts.ts +97 -0
  1203. package/src/backend/dynamic-table/store/index.ts +1011 -0
  1204. package/src/backend/dynamic-table/styles/ContextMenu.css +387 -0
  1205. package/src/backend/dynamic-table/styles/DynamicTable.css +3659 -0
  1206. package/src/backend/dynamic-table/styles/DynamicTable.v2.css +2651 -0
  1207. package/src/backend/dynamic-table/styles/SearchBar.css +426 -0
  1208. package/src/backend/dynamic-table/styles/dateCell.css +146 -0
  1209. package/src/backend/dynamic-table/styles/density.css +690 -0
  1210. package/src/backend/dynamic-table/types/density.ts +179 -0
  1211. package/src/backend/dynamic-table/types/filters.ts +156 -0
  1212. package/src/backend/dynamic-table/types/grouping.ts +189 -0
  1213. package/src/backend/dynamic-table/types/import.ts +132 -0
  1214. package/src/backend/dynamic-table/types/index.ts +1198 -0
  1215. package/src/backend/dynamic-table/types/perspective.ts +436 -0
  1216. package/src/backend/dynamic-table/types/rollup.ts +111 -0
  1217. package/src/backend/dynamic-table/utils/abbreviations.ts +556 -0
  1218. package/src/backend/dynamic-table/utils/anchoredPosition.ts +106 -0
  1219. package/src/backend/dynamic-table/utils/badgeAutoFit.ts +108 -0
  1220. package/src/backend/dynamic-table/utils/clipboard.ts +294 -0
  1221. package/src/backend/dynamic-table/utils/coerceCellValue.ts +96 -0
  1222. package/src/backend/dynamic-table/utils/colorAdjacency.ts +87 -0
  1223. package/src/backend/dynamic-table/utils/columnFill.ts +93 -0
  1224. package/src/backend/dynamic-table/utils/columnSpacerStyle.ts +53 -0
  1225. package/src/backend/dynamic-table/utils/columnWindow.ts +668 -0
  1226. package/src/backend/dynamic-table/utils/conditionalFormat.ts +300 -0
  1227. package/src/backend/dynamic-table/utils/exportTable.ts +140 -0
  1228. package/src/backend/dynamic-table/utils/fillGeometry.ts +187 -0
  1229. package/src/backend/dynamic-table/utils/fillPatterns.ts +422 -0
  1230. package/src/backend/dynamic-table/utils/formatAggregate.ts +145 -0
  1231. package/src/backend/dynamic-table/utils/formatDateCompact.ts +879 -0
  1232. package/src/backend/dynamic-table/utils/formatLabelCompact.ts +640 -0
  1233. package/src/backend/dynamic-table/utils/formulaColumns.tsx +237 -0
  1234. package/src/backend/dynamic-table/utils/importMapping.ts +202 -0
  1235. package/src/backend/dynamic-table/utils/importParse.ts +220 -0
  1236. package/src/backend/dynamic-table/utils/lookupColumns.tsx +47 -0
  1237. package/src/backend/dynamic-table/utils/perspectiveTransforms.ts +368 -0
  1238. package/src/backend/dynamic-table/utils/rollupColumns.ts +162 -0
  1239. package/src/backend/dynamic-table/validators/index.ts +40 -0
  1240. package/src/backend/fields/registry.generated.ts +8 -0
  1241. package/src/backend/fields/registry.ts +38 -0
  1242. package/src/backend/filters/AdvancedFilterBuilder.tsx +339 -0
  1243. package/src/backend/forms/ActionsDropdown.tsx +198 -0
  1244. package/src/backend/forms/FormActionButtons.tsx +98 -0
  1245. package/src/backend/forms/FormFooter.tsx +27 -0
  1246. package/src/backend/forms/FormHeader.tsx +204 -0
  1247. package/src/backend/forms/index.ts +4 -0
  1248. package/src/backend/hooks/useAdvancedFilter.ts +77 -0
  1249. package/src/backend/indexes/PartialIndexBanner.tsx +86 -0
  1250. package/src/backend/indexes/store.ts +88 -0
  1251. package/src/backend/injection/ComponentOverrideProvider.tsx +66 -0
  1252. package/src/backend/injection/InjectedField.tsx +196 -0
  1253. package/src/backend/injection/InjectionSpot.tsx +457 -0
  1254. package/src/backend/injection/InjectionWizard.tsx +335 -0
  1255. package/src/backend/injection/PageInjectionBoundary.tsx +31 -0
  1256. package/src/backend/injection/SseEventIndicator.tsx +11 -0
  1257. package/src/backend/injection/StatusBadgeInjectionSpot.tsx +50 -0
  1258. package/src/backend/injection/StatusBadgeRenderer.tsx +100 -0
  1259. package/src/backend/injection/WidgetSharedState.ts +58 -0
  1260. package/src/backend/injection/WizardInjectionSpot.tsx +46 -0
  1261. package/src/backend/injection/eventBridge.ts +158 -0
  1262. package/src/backend/injection/helpers.ts +35 -0
  1263. package/src/backend/injection/mergeMenuItems.ts +80 -0
  1264. package/src/backend/injection/mutationEvents.ts +22 -0
  1265. package/src/backend/injection/resolveInjectedIcon.tsx +30 -0
  1266. package/src/backend/injection/spotIds.ts +64 -0
  1267. package/src/backend/injection/useAppEvent.ts +76 -0
  1268. package/src/backend/injection/useGuardedMutation.ts +101 -0
  1269. package/src/backend/injection/useInjectedMenuItems.ts +67 -0
  1270. package/src/backend/injection/useInjectionDataWidgets.ts +41 -0
  1271. package/src/backend/injection/useOperationProgress.ts +105 -0
  1272. package/src/backend/injection/useRegisteredComponent.tsx +106 -0
  1273. package/src/backend/injection/useWidgetSharedState.ts +28 -0
  1274. package/src/backend/injection/visibility-utils.ts +31 -0
  1275. package/src/backend/injection/widgetRegistry.ts +68 -0
  1276. package/src/backend/inputs/ComboboxInput.tsx +272 -0
  1277. package/src/backend/inputs/DatePicker.tsx +162 -0
  1278. package/src/backend/inputs/DateTimePicker.tsx +199 -0
  1279. package/src/backend/inputs/EventPatternInput.tsx +46 -0
  1280. package/src/backend/inputs/EventSelect.tsx +183 -0
  1281. package/src/backend/inputs/LookupSelect.tsx +253 -0
  1282. package/src/backend/inputs/PhoneNumberField.tsx +166 -0
  1283. package/src/backend/inputs/SwitchableMarkdownInput.tsx +106 -0
  1284. package/src/backend/inputs/TagsInput.tsx +297 -0
  1285. package/src/backend/inputs/TimeInput.tsx +146 -0
  1286. package/src/backend/inputs/TimePicker.tsx +120 -0
  1287. package/src/backend/inputs/__tests__/DatePicker.test.tsx +76 -0
  1288. package/src/backend/inputs/__tests__/DateTimePicker.logic.test.ts +126 -0
  1289. package/src/backend/inputs/__tests__/PhoneNumberField.test.tsx +73 -0
  1290. package/src/backend/inputs/__tests__/TagsInput.test.tsx +78 -0
  1291. package/src/backend/inputs/__tests__/TimeInput.test.tsx +134 -0
  1292. package/src/backend/inputs/__tests__/TimePicker.test.tsx +50 -0
  1293. package/src/backend/inputs/index.ts +11 -0
  1294. package/src/backend/markdown/MarkdownContent.tsx +33 -0
  1295. package/src/backend/markdown/index.ts +2 -0
  1296. package/src/backend/markdown/useMarkdownRemarkPlugins.ts +39 -0
  1297. package/src/backend/messages/MessageComposer.tsx +197 -0
  1298. package/src/backend/messages/MessageObjectDetail.tsx +95 -0
  1299. package/src/backend/messages/MessageObjectPreview.tsx +64 -0
  1300. package/src/backend/messages/MessageObjectRecordPicker.tsx +149 -0
  1301. package/src/backend/messages/MessagePrioritySelector.tsx +78 -0
  1302. package/src/backend/messages/MessagesIcon.tsx +32 -0
  1303. package/src/backend/messages/SendObjectMessageDialog.tsx +74 -0
  1304. package/src/backend/messages/__tests__/MessageComposer.test.tsx +350 -0
  1305. package/src/backend/messages/__tests__/SendObjectMessageDialog.test.tsx +77 -0
  1306. package/src/backend/messages/index.ts +22 -0
  1307. package/src/backend/messages/message-compose-form-groups.tsx +383 -0
  1308. package/src/backend/messages/message-composer.types.ts +82 -0
  1309. package/src/backend/messages/message-priority.ts +53 -0
  1310. package/src/backend/messages/useMessageCompose.ts +666 -0
  1311. package/src/backend/messages/useMessageComposeOperations.ts +259 -0
  1312. package/src/backend/messages/useMessagesPoll.ts +118 -0
  1313. package/src/backend/notifications/NotificationBell.tsx +91 -0
  1314. package/src/backend/notifications/NotificationCountBadge.tsx +14 -0
  1315. package/src/backend/notifications/NotificationDispatcher.ts +213 -0
  1316. package/src/backend/notifications/NotificationItem.tsx +262 -0
  1317. package/src/backend/notifications/NotificationPanel.tsx +225 -0
  1318. package/src/backend/notifications/__tests__/NotificationCountBadge.test.tsx +34 -0
  1319. package/src/backend/notifications/index.ts +20 -0
  1320. package/src/backend/notifications/useNotificationActions.ts +161 -0
  1321. package/src/backend/notifications/useNotificationEffect.ts +17 -0
  1322. package/src/backend/notifications/useNotifications.ts +12 -0
  1323. package/src/backend/notifications/useNotificationsPoll.ts +167 -0
  1324. package/src/backend/notifications/useNotificationsSse.ts +220 -0
  1325. package/src/backend/operations/LastOperationBanner.tsx +85 -0
  1326. package/src/backend/operations/__tests__/LastOperationBanner.test.tsx +101 -0
  1327. package/src/backend/operations/store.ts +230 -0
  1328. package/src/backend/progress/ProgressTopBar.tsx +189 -0
  1329. package/src/backend/progress/useProgress.ts +12 -0
  1330. package/src/backend/progress/useProgressPoll.ts +100 -0
  1331. package/src/backend/progress/useProgressSse.ts +118 -0
  1332. package/src/backend/schedule/ScheduleAgenda.tsx +136 -0
  1333. package/src/backend/schedule/ScheduleGrid.tsx +136 -0
  1334. package/src/backend/schedule/ScheduleToolbar.tsx +178 -0
  1335. package/src/backend/schedule/ScheduleView.tsx +201 -0
  1336. package/src/backend/schedule/index.ts +5 -0
  1337. package/src/backend/schedule/recurrence.ts +99 -0
  1338. package/src/backend/schedule/types.ts +26 -0
  1339. package/src/backend/section-page/SectionNav.tsx +140 -0
  1340. package/src/backend/section-page/SectionPage.tsx +34 -0
  1341. package/src/backend/section-page/index.ts +3 -0
  1342. package/src/backend/section-page/types.ts +30 -0
  1343. package/src/backend/settings/SettingsNavigation.tsx +74 -0
  1344. package/src/backend/settings/SettingsPageWrapper.tsx +78 -0
  1345. package/src/backend/settings/index.ts +3 -0
  1346. package/src/backend/upgrades/UpgradeActionBanner.tsx +128 -0
  1347. package/src/backend/utils/__tests__/api.scoped-headers.test.ts +58 -0
  1348. package/src/backend/utils/__tests__/api.test.ts +148 -0
  1349. package/src/backend/utils/__tests__/apiCall.scoped-request-headers.test.ts +58 -0
  1350. package/src/backend/utils/__tests__/apiCall.test.ts +109 -0
  1351. package/src/backend/utils/__tests__/crud.test.ts +87 -0
  1352. package/src/backend/utils/__tests__/customFieldDefs.test.ts +25 -0
  1353. package/src/backend/utils/__tests__/customFieldValues.test.ts +35 -0
  1354. package/src/backend/utils/__tests__/richTextSanitizer.test.ts +57 -0
  1355. package/src/backend/utils/api.ts +214 -0
  1356. package/src/backend/utils/apiCall.ts +123 -0
  1357. package/src/backend/utils/crud.ts +174 -0
  1358. package/src/backend/utils/customFieldColumns.ts +118 -0
  1359. package/src/backend/utils/customFieldDefs.ts +247 -0
  1360. package/src/backend/utils/customFieldFilters.ts +174 -0
  1361. package/src/backend/utils/customFieldForms.ts +203 -0
  1362. package/src/backend/utils/customFieldRelationDisplay.ts +302 -0
  1363. package/src/backend/utils/customFieldValues.ts +41 -0
  1364. package/src/backend/utils/flash.ts +17 -0
  1365. package/src/backend/utils/nav.ts +402 -0
  1366. package/src/backend/utils/richTextSanitizer.ts +7 -0
  1367. package/src/backend/utils/scopedHeaderStack.ts +49 -0
  1368. package/src/backend/utils/serverErrors.ts +313 -0
  1369. package/src/backend/utils/useAutoDiscoveredFields.ts +138 -0
  1370. package/src/backend/version-history/VersionHistoryAction.tsx +76 -0
  1371. package/src/backend/version-history/VersionHistoryDetail.tsx +87 -0
  1372. package/src/backend/version-history/VersionHistoryPanel.tsx +331 -0
  1373. package/src/backend/version-history/index.ts +9 -0
  1374. package/src/backend/version-history/labels.ts +56 -0
  1375. package/src/backend/version-history/types.ts +27 -0
  1376. package/src/backend/version-history/useAuditPermissions.ts +94 -0
  1377. package/src/backend/version-history/useVersionHistory.ts +173 -0
  1378. package/src/backend/views/NewViewForm.tsx +54 -0
  1379. package/src/backend/views/ShareForm.tsx +62 -0
  1380. package/src/backend/views/ViewChip.tsx +123 -0
  1381. package/src/backend/views/ViewChipMenu.tsx +94 -0
  1382. package/src/backend/views/types.ts +4 -0
  1383. package/src/frontend/AuthFooter.tsx +29 -0
  1384. package/src/frontend/LanguageSwitcher.tsx +66 -0
  1385. package/src/frontend/Layout.tsx +13 -0
  1386. package/src/hooks/useIsMobile.ts +27 -0
  1387. package/src/index.ts +40 -0
  1388. package/src/portal/PortalContext.tsx +180 -0
  1389. package/src/portal/PortalLayoutProvider.tsx +5 -0
  1390. package/src/portal/PortalLayoutShell.tsx +64 -0
  1391. package/src/portal/PortalShell.tsx +370 -0
  1392. package/src/portal/components/PortalCard.tsx +77 -0
  1393. package/src/portal/components/PortalEmptyState.tsx +32 -0
  1394. package/src/portal/components/PortalFeatureCard.tsx +41 -0
  1395. package/src/portal/components/PortalNotificationBell.tsx +81 -0
  1396. package/src/portal/components/PortalNotificationPanel.tsx +230 -0
  1397. package/src/portal/components/PortalPageHeader.tsx +33 -0
  1398. package/src/portal/components/index.ts +6 -0
  1399. package/src/portal/hooks/useCustomerAuth.ts +97 -0
  1400. package/src/portal/hooks/usePortalAppEvent.ts +56 -0
  1401. package/src/portal/hooks/usePortalDashboardWidgets.ts +50 -0
  1402. package/src/portal/hooks/usePortalEventBridge.ts +162 -0
  1403. package/src/portal/hooks/usePortalInjectedMenuItems.ts +130 -0
  1404. package/src/portal/hooks/usePortalNotifications.ts +116 -0
  1405. package/src/portal/hooks/useTenantContext.ts +83 -0
  1406. package/src/primitives/DataLoader.tsx +93 -0
  1407. package/src/primitives/ErrorNotice.tsx +17 -0
  1408. package/src/primitives/Notice.tsx +83 -0
  1409. package/src/primitives/alert.tsx +59 -0
  1410. package/src/primitives/badge.tsx +43 -0
  1411. package/src/primitives/button.tsx +60 -0
  1412. package/src/primitives/calendar.tsx +69 -0
  1413. package/src/primitives/card.tsx +92 -0
  1414. package/src/primitives/checkbox.tsx +34 -0
  1415. package/src/primitives/dialog.tsx +122 -0
  1416. package/src/primitives/form-field.tsx +106 -0
  1417. package/src/primitives/icon-button.tsx +48 -0
  1418. package/src/primitives/input.tsx +26 -0
  1419. package/src/primitives/label.tsx +18 -0
  1420. package/src/primitives/popover.tsx +37 -0
  1421. package/src/primitives/primitives.stories.tsx +223 -0
  1422. package/src/primitives/progress.tsx +28 -0
  1423. package/src/primitives/separator.tsx +7 -0
  1424. package/src/primitives/sheet.tsx +137 -0
  1425. package/src/primitives/spinner.tsx +27 -0
  1426. package/src/primitives/status-badge.tsx +62 -0
  1427. package/src/primitives/switch.tsx +92 -0
  1428. package/src/primitives/table.tsx +27 -0
  1429. package/src/primitives/tabs.tsx +131 -0
  1430. package/src/primitives/textarea.tsx +20 -0
  1431. package/src/primitives/tooltip.tsx +85 -0
  1432. package/src/primitives-v2/AGENTS.md +66 -0
  1433. package/src/primitives-v2/Alert.stories.tsx +56 -0
  1434. package/src/primitives-v2/Alert.tsx +108 -0
  1435. package/src/primitives-v2/Avatar.stories.tsx +60 -0
  1436. package/src/primitives-v2/Avatar.tsx +139 -0
  1437. package/src/primitives-v2/Badge.stories.tsx +80 -0
  1438. package/src/primitives-v2/Badge.tsx +99 -0
  1439. package/src/primitives-v2/Breadcrumb.stories.tsx +61 -0
  1440. package/src/primitives-v2/Breadcrumb.tsx +96 -0
  1441. package/src/primitives-v2/Button.stories.tsx +72 -0
  1442. package/src/primitives-v2/Button.tsx +178 -0
  1443. package/src/primitives-v2/Checkbox.stories.tsx +34 -0
  1444. package/src/primitives-v2/Checkbox.tsx +103 -0
  1445. package/src/primitives-v2/IconButton.stories.tsx +40 -0
  1446. package/src/primitives-v2/IconButton.tsx +40 -0
  1447. package/src/primitives-v2/Input.stories.tsx +60 -0
  1448. package/src/primitives-v2/Input.tsx +113 -0
  1449. package/src/primitives-v2/NavGroup.stories.tsx +50 -0
  1450. package/src/primitives-v2/NavGroup.tsx +76 -0
  1451. package/src/primitives-v2/NavItem.stories.tsx +68 -0
  1452. package/src/primitives-v2/NavItem.tsx +105 -0
  1453. package/src/primitives-v2/SearchInput.stories.tsx +44 -0
  1454. package/src/primitives-v2/SearchInput.tsx +123 -0
  1455. package/src/primitives-v2/Sidebar.stories.tsx +91 -0
  1456. package/src/primitives-v2/Sidebar.tsx +92 -0
  1457. package/src/primitives-v2/Tab.stories.tsx +62 -0
  1458. package/src/primitives-v2/Tab.tsx +148 -0
  1459. package/src/primitives-v2/Tag.stories.tsx +123 -0
  1460. package/src/primitives-v2/Tag.tsx +115 -0
  1461. package/src/primitives-v2/Toggle.stories.tsx +37 -0
  1462. package/src/primitives-v2/Toggle.tsx +93 -0
  1463. package/src/primitives-v2/Topbar.stories.tsx +65 -0
  1464. package/src/primitives-v2/Topbar.tsx +37 -0
  1465. package/src/primitives-v2/index.ts +31 -0
  1466. package/src/primitives-v2/utils.ts +9 -0
  1467. package/src/theme/BrandThemeProvider.tsx +122 -0
  1468. package/src/theme/QueryProvider.tsx +46 -0
  1469. package/src/theme/ThemeProvider.tsx +120 -0
  1470. package/src/theme/ThemeToggle.tsx +88 -0
  1471. package/src/theme/index.ts +4 -0
  1472. package/src/theme/m3.css +622 -0
  1473. package/src/theme/tokens.v2.css +559 -0
  1474. package/src/theme/typography.css +163 -0
  1475. package/src/theme/typography.stories.tsx +157 -0
  1476. package/src/theme/typography.tokens.ts +326 -0
  1477. package/src/types/react-big-calendar.d.ts +16 -0
@@ -0,0 +1,261 @@
1
+ import { isAggregationFn } from "../types/grouping.js";
2
+ import { coerceAggregateValue } from "../utils/formatAggregate.js";
3
+ const MAX_AGGREGATE_ENTRIES = 12;
4
+ const MAX_AGGREGATE_PARAM_LENGTH = 500;
5
+ class AggregateSpecError extends Error {
6
+ constructor(message) {
7
+ super(message);
8
+ this.name = "AggregateSpecError";
9
+ }
10
+ }
11
+ class AggregateScopeError extends Error {
12
+ constructor(message) {
13
+ super(message);
14
+ this.name = "AggregateScopeError";
15
+ }
16
+ }
17
+ function aggregateKey(field, fn) {
18
+ return `${field}:${fn}`;
19
+ }
20
+ function parseAggregateSpec(raw, fieldMap) {
21
+ if (raw === null || raw === void 0) return [];
22
+ if (typeof raw !== "string") throw new AggregateSpecError("aggregate must be a string");
23
+ const trimmed = raw.trim();
24
+ if (!trimmed) return [];
25
+ if (trimmed.length > MAX_AGGREGATE_PARAM_LENGTH) {
26
+ throw new AggregateSpecError(`aggregate must be at most ${MAX_AGGREGATE_PARAM_LENGTH} characters`);
27
+ }
28
+ const parts = trimmed.split(",").map((p) => p.trim()).filter(Boolean);
29
+ if (parts.length > MAX_AGGREGATE_ENTRIES) {
30
+ throw new AggregateSpecError(`aggregate accepts at most ${MAX_AGGREGATE_ENTRIES} entries`);
31
+ }
32
+ const seen = /* @__PURE__ */ new Set();
33
+ const out = [];
34
+ for (const part of parts) {
35
+ const idx = part.indexOf(":");
36
+ if (idx <= 0 || idx === part.length - 1) {
37
+ throw new AggregateSpecError(`Malformed aggregate entry: "${part}" (expected field:fn)`);
38
+ }
39
+ const field = part.slice(0, idx).trim();
40
+ const rest = part.slice(idx + 1).trim();
41
+ const dimIdx = rest.indexOf(":");
42
+ const fn = (dimIdx < 0 ? rest : rest.slice(0, dimIdx)).trim();
43
+ const dimension = dimIdx < 0 ? "" : rest.slice(dimIdx + 1).trim();
44
+ if (!field) throw new AggregateSpecError(`Malformed aggregate entry: "${part}"`);
45
+ if (!isAggregationFn(fn)) throw new AggregateSpecError(`Unknown aggregate function: "${fn}"`);
46
+ const property = Object.prototype.hasOwnProperty.call(fieldMap, field) ? fieldMap[field] : void 0;
47
+ if (!property || typeof property !== "string") {
48
+ throw new AggregateSpecError(`Unknown aggregate field: "${field}"`);
49
+ }
50
+ let dimensionProperty;
51
+ if (dimIdx >= 0) {
52
+ if (!dimension) {
53
+ throw new AggregateSpecError(`Malformed aggregate entry: "${part}" (empty dimension)`);
54
+ }
55
+ const dimProp = Object.prototype.hasOwnProperty.call(fieldMap, dimension) ? fieldMap[dimension] : void 0;
56
+ if (!dimProp || typeof dimProp !== "string") {
57
+ throw new AggregateSpecError(`Unknown aggregate dimension: "${dimension}"`);
58
+ }
59
+ dimensionProperty = dimProp;
60
+ }
61
+ const key = aggregateKey(field, fn);
62
+ if (seen.has(key)) continue;
63
+ seen.add(key);
64
+ out.push(
65
+ dimensionProperty ? { field, fn, property, dimension, dimensionProperty } : { field, fn, property }
66
+ );
67
+ }
68
+ return out;
69
+ }
70
+ function buildAggregateWhere(where, tenancy) {
71
+ const orgField = tenancy.orgField === void 0 ? "organizationId" : tenancy.orgField;
72
+ const tenantField = tenancy.tenantField === void 0 ? "tenantId" : tenancy.tenantField;
73
+ const softDeleteField = tenancy.softDeleteField === void 0 ? "deletedAt" : tenancy.softDeleteField;
74
+ if (orgField) {
75
+ const ids = (tenancy.organizationIds ?? []).filter((id) => typeof id === "string" && id);
76
+ if (ids.length === 0) {
77
+ throw new AggregateScopeError(
78
+ "Refusing to aggregate without an organization scope \u2014 an unscoped aggregate leaks other tenants\u2019 totals."
79
+ );
80
+ }
81
+ }
82
+ if (tenantField && !tenancy.tenantId) {
83
+ throw new AggregateScopeError("Refusing to aggregate without a tenant id.");
84
+ }
85
+ const merged = { ...where };
86
+ if (softDeleteField) merged[softDeleteField] = null;
87
+ if (tenantField) merged[tenantField] = tenancy.tenantId;
88
+ if (orgField) merged[orgField] = { $in: [...new Set(tenancy.organizationIds)] };
89
+ return merged;
90
+ }
91
+ function tenancyFromRouteContext(ctx, orm = {}) {
92
+ return {
93
+ orgField: orm.orgField,
94
+ organizationIds: [...ctx.allowedOrgIds],
95
+ tenantField: orm.tenantField,
96
+ tenantId: ctx.tenantId,
97
+ softDeleteField: orm.softDeleteField
98
+ };
99
+ }
100
+ function sqlForFn(fn, column) {
101
+ switch (fn) {
102
+ case "sum":
103
+ return `sum(${column})`;
104
+ case "avg":
105
+ return `avg(${column})`;
106
+ case "min":
107
+ return `min(${column})`;
108
+ case "max":
109
+ return `max(${column})`;
110
+ case "count":
111
+ return `count(${column})`;
112
+ case "countDistinct":
113
+ return `count(distinct ${column})`;
114
+ }
115
+ }
116
+ const SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
117
+ function buildAggregateSelect(entries, columnOf, tableAlias) {
118
+ if (!SAFE_IDENTIFIER.test(tableAlias)) {
119
+ throw new AggregateSpecError(`Unsafe table alias: "${tableAlias}"`);
120
+ }
121
+ const expressions = [];
122
+ const aliasToKey = {};
123
+ entries.forEach((entry, i) => {
124
+ const column = columnOf(entry.property);
125
+ if (!column) throw new AggregateSpecError(`Unmapped aggregate field: "${entry.field}"`);
126
+ if (!SAFE_IDENTIFIER.test(column)) {
127
+ throw new AggregateSpecError(`Unsafe column name for field "${entry.field}"`);
128
+ }
129
+ const alias = `agg_${i}`;
130
+ expressions.push(`${sqlForFn(entry.fn, `"${tableAlias}"."${column}"`)} as "${alias}"`);
131
+ aliasToKey[alias] = aggregateKey(entry.field, entry.fn);
132
+ });
133
+ const totalAlias = "agg_total";
134
+ expressions.push(`count(*) as "${totalAlias}"`);
135
+ return { expressions, aliasToKey, totalAlias };
136
+ }
137
+ function mapAggregateRow(row, plan) {
138
+ const values = {};
139
+ for (const [alias, key] of Object.entries(plan.aliasToKey)) {
140
+ values[key] = coerceAggregateValue(row?.[alias]);
141
+ }
142
+ return {
143
+ scope: "dataset",
144
+ total: coerceAggregateValue(row?.[plan.totalAlias]) ?? 0,
145
+ values
146
+ };
147
+ }
148
+ function makeColumnResolver(em, entity) {
149
+ const anyEm = em;
150
+ let properties;
151
+ try {
152
+ const metadata = anyEm.getMetadata?.();
153
+ const meta = metadata?.find?.(entity) ?? metadata?.get?.(typeof entity === "string" ? entity : entity?.name);
154
+ properties = meta?.properties;
155
+ } catch {
156
+ properties = void 0;
157
+ }
158
+ return (property) => {
159
+ const prop = properties?.[property];
160
+ const fromMeta = prop?.fieldNames?.[0];
161
+ if (typeof fromMeta === "string" && fromMeta) return fromMeta;
162
+ if (properties) return void 0;
163
+ return property.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
164
+ };
165
+ }
166
+ let rawFragment = null;
167
+ async function getRawFragment() {
168
+ if (!rawFragment) {
169
+ const mod = await import("@mikro-orm/core");
170
+ if (typeof mod?.raw !== "function") {
171
+ throw new Error("@mikro-orm/core does not export raw(); cannot build an aggregate query");
172
+ }
173
+ rawFragment = (sql) => mod.raw(sql);
174
+ }
175
+ return rawFragment;
176
+ }
177
+ async function runAggregate(options) {
178
+ const { em, entity, where, tenancy, entries } = options;
179
+ const tableAlias = options.tableAlias ?? "dta";
180
+ const scopedWhere = buildAggregateWhere(where, tenancy);
181
+ if (entries.length === 0) {
182
+ const total = await em.count(entity, scopedWhere);
183
+ return { scope: "dataset", total, values: {} };
184
+ }
185
+ const columnOf = makeColumnResolver(em, entity);
186
+ const plan = buildAggregateSelect(entries, columnOf, tableAlias);
187
+ const raw = await getRawFragment();
188
+ const compileWith = (expressions, groupByColumn) => {
189
+ const qb = em.createQueryBuilder(entity, tableAlias);
190
+ qb.select("*");
191
+ qb.where(scopedWhere);
192
+ const native = qb.getNativeQuery();
193
+ native.clear("select");
194
+ native.select(expressions.map((expr) => raw(expr)));
195
+ if (groupByColumn) native.groupBy([raw(`"${tableAlias}"."${groupByColumn}"`)]);
196
+ return native.compile();
197
+ };
198
+ const { sql, params } = compileWith(plan.expressions);
199
+ const row = await em.getConnection().execute(sql, params, "get");
200
+ const result = mapAggregateRow(row, plan);
201
+ const dimensioned = entries.filter((e) => e.dimension && e.dimensionProperty);
202
+ if (dimensioned.length > 0) {
203
+ const breakdowns = {};
204
+ const byDimension = /* @__PURE__ */ new Map();
205
+ for (const entry of dimensioned) {
206
+ const list = byDimension.get(entry.dimensionProperty);
207
+ if (list) list.push(entry);
208
+ else byDimension.set(entry.dimensionProperty, [entry]);
209
+ }
210
+ for (const [dimensionProperty, group] of byDimension) {
211
+ const dimColumn = columnOf(dimensionProperty);
212
+ if (!dimColumn) throw new AggregateSpecError(`Unmapped aggregate dimension: "${group[0].dimension}"`);
213
+ if (!SAFE_IDENTIFIER.test(dimColumn)) {
214
+ throw new AggregateSpecError(`Unsafe column name for dimension "${group[0].dimension}"`);
215
+ }
216
+ const expressions = [`"${tableAlias}"."${dimColumn}" as "agg_dim"`];
217
+ const aliasToKey = {};
218
+ group.forEach((entry, i) => {
219
+ const column = columnOf(entry.property);
220
+ if (!column) throw new AggregateSpecError(`Unmapped aggregate field: "${entry.field}"`);
221
+ if (!SAFE_IDENTIFIER.test(column)) {
222
+ throw new AggregateSpecError(`Unsafe column name for field "${entry.field}"`);
223
+ }
224
+ const alias = `agg_d_${i}`;
225
+ expressions.push(`${sqlForFn(entry.fn, `"${tableAlias}"."${column}"`)} as "${alias}"`);
226
+ aliasToKey[alias] = aggregateKey(entry.field, entry.fn);
227
+ });
228
+ const compiled = compileWith(expressions, dimColumn);
229
+ const rows = await em.getConnection().execute(
230
+ compiled.sql,
231
+ compiled.params,
232
+ "all"
233
+ );
234
+ for (const key of Object.values(aliasToKey)) breakdowns[key] = [];
235
+ for (const r of rows ?? []) {
236
+ const dimValue = r?.["agg_dim"];
237
+ const dimKey = dimValue === null || dimValue === void 0 ? "" : String(dimValue);
238
+ for (const [alias, key] of Object.entries(aliasToKey)) {
239
+ breakdowns[key].push({ key: dimKey, value: coerceAggregateValue(r?.[alias]) });
240
+ }
241
+ }
242
+ }
243
+ result.breakdowns = breakdowns;
244
+ }
245
+ return result;
246
+ }
247
+ export {
248
+ AggregateScopeError,
249
+ AggregateSpecError,
250
+ MAX_AGGREGATE_ENTRIES,
251
+ MAX_AGGREGATE_PARAM_LENGTH,
252
+ aggregateKey,
253
+ buildAggregateSelect,
254
+ buildAggregateWhere,
255
+ makeColumnResolver,
256
+ mapAggregateRow,
257
+ parseAggregateSpec,
258
+ runAggregate,
259
+ tenancyFromRouteContext
260
+ };
261
+ //# sourceMappingURL=aggregate.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/backend/dynamic-table/server/aggregate.ts"],
4
+ "sourcesContent": ["// server/aggregate.ts\n//\n// Shared server-side aggregation helper for DynamicTable list routes.\n//\n// The whole point of this file is one structural rule:\n//\n// THE AGGREGATE RUNS OVER THE SAME `WHERE` CLAUSE AS THE ROW QUERY.\n//\n// A total computed from a separately-built filter object describes a different\n// set of rows than the ones on screen \u2014 and if that separate build forgets\n// `organization_id`, it describes every tenant's rows. So the caller hands over\n// the *same* filters object it passed to `findAndCount`, and this helper\n// re-asserts tenancy on top of it as defence in depth.\n\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { AggregationFn, AggregateResult, AggregateBreakdownEntry } from '../types/grouping'\nimport { isAggregationFn } from '../types/grouping'\nimport { coerceAggregateValue } from '../utils/formatAggregate'\n\n/** Hard cap on how many aggregates one request may ask for. */\nexport const MAX_AGGREGATE_ENTRIES = 12\n\n/** Hard cap on the raw `aggregate=` string length. */\nexport const MAX_AGGREGATE_PARAM_LENGTH = 500\n\nexport interface AggregateEntry {\n /** Client-facing column key (the `ColumnDef.data` value). */\n field: string\n fn: AggregationFn\n /** ORM property name the field resolves to, via the route's `fieldMap`. */\n property: string\n /** Client-facing key of the optional partition column. */\n dimension?: string\n /** ORM property the dimension resolves to, via the same `fieldMap`. */\n dimensionProperty?: string\n}\n\nexport class AggregateSpecError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'AggregateSpecError'\n }\n}\n\nexport class AggregateScopeError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'AggregateScopeError'\n }\n}\n\n/** `${field}:${fn}` \u2014 the key an `AggregateResult.values` entry is filed under. */\nexport function aggregateKey(field: string, fn: AggregationFn): string {\n return `${field}:${fn}`\n}\n\n// \u2500\u2500\u2500 Spec parsing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Parse `aggregate=grossAmount:sum,netAmount:avg,id:count`.\n *\n * An entry may carry an OPTIONAL third segment \u2014 `grossAmount:sum:currencyCode`\n * \u2014 naming a column to partition the aggregate by. That yields one figure per\n * distinct value instead of a single scalar, which is what stops a `sum` from\n * silently adding amounts in different currencies together (HEDGE-147). Two-part\n * entries are unchanged, so already-deployed clients and routes are unaffected.\n *\n * Every field \u2014 the aggregated one AND the dimension \u2014 is resolved through the\n * route's `fieldMap` allow-list, so an unknown or hostile field name never\n * becomes SQL; it is a 400. `fn` is a closed union. Throws `AggregateSpecError`;\n * callers map that to a 400.\n */\nexport function parseAggregateSpec(\n raw: string | null | undefined,\n fieldMap: Record<string, string>,\n): AggregateEntry[] {\n if (raw === null || raw === undefined) return []\n if (typeof raw !== 'string') throw new AggregateSpecError('aggregate must be a string')\n const trimmed = raw.trim()\n if (!trimmed) return []\n if (trimmed.length > MAX_AGGREGATE_PARAM_LENGTH) {\n throw new AggregateSpecError(`aggregate must be at most ${MAX_AGGREGATE_PARAM_LENGTH} characters`)\n }\n\n const parts = trimmed.split(',').map((p) => p.trim()).filter(Boolean)\n if (parts.length > MAX_AGGREGATE_ENTRIES) {\n throw new AggregateSpecError(`aggregate accepts at most ${MAX_AGGREGATE_ENTRIES} entries`)\n }\n\n const seen = new Set<string>()\n const out: AggregateEntry[] = []\n for (const part of parts) {\n const idx = part.indexOf(':')\n if (idx <= 0 || idx === part.length - 1) {\n throw new AggregateSpecError(`Malformed aggregate entry: \"${part}\" (expected field:fn)`)\n }\n const field = part.slice(0, idx).trim()\n const rest = part.slice(idx + 1).trim()\n const dimIdx = rest.indexOf(':')\n const fn = (dimIdx < 0 ? rest : rest.slice(0, dimIdx)).trim()\n const dimension = dimIdx < 0 ? '' : rest.slice(dimIdx + 1).trim()\n if (!field) throw new AggregateSpecError(`Malformed aggregate entry: \"${part}\"`)\n if (!isAggregationFn(fn)) throw new AggregateSpecError(`Unknown aggregate function: \"${fn}\"`)\n\n // Allow-list: the field must be a column this route publishes.\n const property = Object.prototype.hasOwnProperty.call(fieldMap, field) ? fieldMap[field] : undefined\n if (!property || typeof property !== 'string') {\n throw new AggregateSpecError(`Unknown aggregate field: \"${field}\"`)\n }\n\n // Same allow-list for the partition column \u2014 it reaches SQL as a GROUP BY\n // identifier, so it gets exactly the treatment the aggregated field gets.\n let dimensionProperty: string | undefined\n if (dimIdx >= 0) {\n if (!dimension) {\n throw new AggregateSpecError(`Malformed aggregate entry: \"${part}\" (empty dimension)`)\n }\n const dimProp = Object.prototype.hasOwnProperty.call(fieldMap, dimension)\n ? fieldMap[dimension]\n : undefined\n if (!dimProp || typeof dimProp !== 'string') {\n throw new AggregateSpecError(`Unknown aggregate dimension: \"${dimension}\"`)\n }\n dimensionProperty = dimProp\n }\n\n const key = aggregateKey(field, fn)\n if (seen.has(key)) continue\n seen.add(key)\n out.push(\n dimensionProperty\n ? { field, fn, property, dimension, dimensionProperty }\n : { field, fn, property },\n )\n }\n return out\n}\n\n// \u2500\u2500\u2500 Tenancy \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface AggregateTenancy {\n /** ORM property holding the organization id. `null` opts an unscoped entity out. */\n orgField?: string | null\n /**\n * The organization scope is a SET, not a single id \u2014 `buildScopeFilters`\n * emits `{ $in: [...] }` because a user may see several organizations.\n */\n organizationIds: string[]\n /** ORM property holding the tenant id. `null` opts out. */\n tenantField?: string | null\n tenantId?: string | null\n /** ORM property for soft deletion. `null` opts out. */\n softDeleteField?: string | null\n}\n\n/**\n * Merge the row query's `where` with the tenancy scope, and refuse to build an\n * aggregate that isn't scoped.\n *\n * The row query already carries these keys; re-applying identical values is a\n * no-op, and the throw is what turns \"someone forgot\" from a silent\n * cross-tenant total into a failed request.\n */\nexport function buildAggregateWhere(\n where: Record<string, unknown>,\n tenancy: AggregateTenancy,\n): Record<string, unknown> {\n const orgField = tenancy.orgField === undefined ? 'organizationId' : tenancy.orgField\n const tenantField = tenancy.tenantField === undefined ? 'tenantId' : tenancy.tenantField\n const softDeleteField =\n tenancy.softDeleteField === undefined ? 'deletedAt' : tenancy.softDeleteField\n\n if (orgField) {\n const ids = (tenancy.organizationIds ?? []).filter((id) => typeof id === 'string' && id)\n if (ids.length === 0) {\n throw new AggregateScopeError(\n 'Refusing to aggregate without an organization scope \u2014 an unscoped aggregate leaks other tenants\u2019 totals.',\n )\n }\n }\n if (tenantField && !tenancy.tenantId) {\n throw new AggregateScopeError('Refusing to aggregate without a tenant id.')\n }\n\n const merged: Record<string, unknown> = { ...where }\n if (softDeleteField) merged[softDeleteField] = null\n if (tenantField) merged[tenantField] = tenancy.tenantId\n if (orgField) merged[orgField] = { $in: [...new Set(tenancy.organizationIds)] }\n return merged\n}\n\n/**\n * Adapt a `makeDynamicTableRoute` context + ORM config into `AggregateTenancy`.\n *\n * Structurally typed so this file never has to import the route factory. Note\n * `allowedOrgIds` is a **Set** \u2014 the visible organization scope is a set of ids\n * (`buildScopeFilters` emits `{ $in: [...] }`), not one id, and collapsing it\n * to `ctx.organizationId` would silently narrow or widen the aggregate.\n */\nexport function tenancyFromRouteContext(\n ctx: { tenantId: string | null; allowedOrgIds: Set<string> },\n orm: { orgField?: string | null; tenantField?: string | null; softDeleteField?: string | null } = {},\n): AggregateTenancy {\n return {\n orgField: orm.orgField,\n organizationIds: [...ctx.allowedOrgIds],\n tenantField: orm.tenantField,\n tenantId: ctx.tenantId,\n softDeleteField: orm.softDeleteField,\n }\n}\n\n// \u2500\u2500\u2500 SQL construction \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** SQL template per function. `%s` is the (metadata-derived) qualified column. */\nfunction sqlForFn(fn: AggregationFn, column: string): string {\n switch (fn) {\n case 'sum':\n return `sum(${column})`\n case 'avg':\n return `avg(${column})`\n case 'min':\n return `min(${column})`\n case 'max':\n return `max(${column})`\n case 'count':\n return `count(${column})`\n case 'countDistinct':\n return `count(distinct ${column})`\n }\n}\n\nconst SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/\n\nexport interface AggregateSelectPlan {\n /** Raw `select` expressions, in entry order, plus the trailing row count. */\n expressions: string[]\n /** Generated alias -> the `AggregateResult.values` key it fills. */\n aliasToKey: Record<string, string>\n /** Alias of the `count(*)` expression. */\n totalAlias: string\n}\n\n/**\n * Build the select list.\n *\n * Injection safety, three layers deep: `field` was already resolved through the\n * route's `fieldMap` allow-list; `columnOf` maps the ORM property to a real\n * column name taken from ORM metadata (never from the request); and the result\n * is re-checked against `SAFE_IDENTIFIER` before it is concatenated. Aliases\n * are generated (`agg_0`, `agg_1`, \u2026), never derived from user input.\n */\nexport function buildAggregateSelect(\n entries: AggregateEntry[],\n columnOf: (property: string) => string | undefined,\n tableAlias: string,\n): AggregateSelectPlan {\n if (!SAFE_IDENTIFIER.test(tableAlias)) {\n throw new AggregateSpecError(`Unsafe table alias: \"${tableAlias}\"`)\n }\n\n const expressions: string[] = []\n const aliasToKey: Record<string, string> = {}\n\n entries.forEach((entry, i) => {\n const column = columnOf(entry.property)\n if (!column) throw new AggregateSpecError(`Unmapped aggregate field: \"${entry.field}\"`)\n if (!SAFE_IDENTIFIER.test(column)) {\n throw new AggregateSpecError(`Unsafe column name for field \"${entry.field}\"`)\n }\n const alias = `agg_${i}`\n expressions.push(`${sqlForFn(entry.fn, `\"${tableAlias}\".\"${column}\"`)} as \"${alias}\"`)\n aliasToKey[alias] = aggregateKey(entry.field, entry.fn)\n })\n\n const totalAlias = 'agg_total'\n expressions.push(`count(*) as \"${totalAlias}\"`)\n return { expressions, aliasToKey, totalAlias }\n}\n\n/**\n * Turn one raw aggregate row (all values arrive as STRINGS from pg: `int8` for\n * counts, `numeric` for sums) into the transport shape.\n */\nexport function mapAggregateRow(\n row: Record<string, unknown> | null | undefined,\n plan: AggregateSelectPlan,\n): AggregateResult {\n const values: Record<string, number | null> = {}\n for (const [alias, key] of Object.entries(plan.aliasToKey)) {\n values[key] = coerceAggregateValue(row?.[alias])\n }\n return {\n scope: 'dataset',\n total: coerceAggregateValue(row?.[plan.totalAlias]) ?? 0,\n values,\n }\n}\n\n// \u2500\u2500\u2500 Execution \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface RunAggregateOptions {\n em: EntityManager\n entity: any\n /**\n * The EXACT filters object handed to the row query. Passing a freshly built\n * one is the bug this helper exists to prevent.\n */\n where: Record<string, unknown>\n tenancy: AggregateTenancy\n entries: AggregateEntry[]\n /** SQL table alias. Generated, never user input. */\n tableAlias?: string\n}\n\n/**\n * Resolve an ORM property name to its physical column, from ENTITY METADATA.\n * Never from the request \u2014 that is what keeps the identifier trustworthy.\n * A property the metadata does not know is rejected rather than guessed.\n */\nexport function makeColumnResolver(\n em: EntityManager,\n entity: any,\n): (property: string) => string | undefined {\n const anyEm = em as any\n let properties: Record<string, any> | undefined\n try {\n const metadata = anyEm.getMetadata?.()\n const meta =\n metadata?.find?.(entity) ?? metadata?.get?.(typeof entity === 'string' ? entity : entity?.name)\n properties = meta?.properties\n } catch {\n properties = undefined\n }\n return (property: string) => {\n const prop = properties?.[property]\n const fromMeta = prop?.fieldNames?.[0]\n if (typeof fromMeta === 'string' && fromMeta) return fromMeta\n if (properties) return undefined\n // No metadata at all (unit tests, unusual driver): fall back to the\n // conventional camelCase \u2192 snake_case mapping. Still gated by\n // SAFE_IDENTIFIER in `buildAggregateSelect`.\n return property.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`)\n }\n}\n\n/**\n * `raw()` lives in `@mikro-orm/core`, which this package does not depend on\n * directly. It is imported lazily so that (a) the pure spec/SQL helpers above\n * stay importable in a jsdom unit test, and (b) nothing pulls the ORM into a\n * client bundle. Resolution happens inside the host app, which always has it.\n */\nlet rawFragment: ((sql: string) => unknown) | null = null\nasync function getRawFragment(): Promise<(sql: string) => unknown> {\n if (!rawFragment) {\n const mod: any = await import('@mikro-orm/core')\n if (typeof mod?.raw !== 'function') {\n throw new Error('@mikro-orm/core does not export raw(); cannot build an aggregate query')\n }\n rawFragment = (sql: string) => mod.raw(sql)\n }\n return rawFragment\n}\n\n/**\n * Run the aggregate. Returns `scope: 'dataset'` \u2014 it is computed over the whole\n * filtered set, which is the entire reason this exists.\n *\n * The query builder is seeded with the SAME `where` the row query used (plus a\n * re-assertion of tenancy), then its select list is swapped for the aggregate\n * expressions. Same builder, same clause, same rows.\n */\nexport async function runAggregate(options: RunAggregateOptions): Promise<AggregateResult> {\n const { em, entity, where, tenancy, entries } = options\n const tableAlias = options.tableAlias ?? 'dta'\n\n const scopedWhere = buildAggregateWhere(where, tenancy)\n\n if (entries.length === 0) {\n const total = await em.count(entity, scopedWhere as any)\n return { scope: 'dataset', total, values: {} }\n }\n\n const columnOf = makeColumnResolver(em, entity)\n const plan = buildAggregateSelect(entries, columnOf, tableAlias)\n const raw = await getRawFragment()\n\n const compileWith = (expressions: string[], groupByColumn?: string) => {\n const qb: any = em.createQueryBuilder(entity as any, tableAlias)\n qb.select('*')\n qb.where(scopedWhere as any)\n\n // Take the compiled row query and swap ONLY its select list. The FROM and the\n // WHERE (including tenancy) are whatever the row query produced \u2014 that is the\n // structural guarantee that the total describes the rows on screen.\n const native: any = qb.getNativeQuery()\n native.clear('select')\n native.select(expressions.map((expr) => raw(expr)))\n // MikroORM v7 dropped knex: `getNativeQuery()` returns the ORM's own\n // `NativeQueryBuilder`, whose signature is\n // `groupBy(groupBy: (string | RawQueryFragment)[])` \u2014 an ARRAY, and there\n // is no `groupByRaw`. Passing a bare fragment (or calling `groupByRaw`)\n // throws, and `runAggregate`'s caller swallows that into \"no total\", so the\n // footer silently degrades to page scope instead of erroring. Both parts of\n // the name are `SAFE_IDENTIFIER`-checked and metadata-derived above.\n if (groupByColumn) native.groupBy([raw(`\"${tableAlias}\".\"${groupByColumn}\"`)])\n return native.compile()\n }\n\n const { sql, params } = compileWith(plan.expressions)\n const row = (await (em.getConnection() as any).execute(sql, params, 'get')) as\n | Record<string, unknown>\n | null\n | undefined\n\n const result = mapAggregateRow(row, plan)\n\n // \u2500\u2500 Per-dimension breakdowns \u2500\u2500\n //\n // One extra grouped query per distinct partition column, reusing the SAME\n // `where`. Kept separate from the scalar query so that adding a dimension can\n // never change the ungrouped `total`, and so a route/driver that cannot do\n // this degrades to \"no breakdown\" rather than to a wrong grand total.\n const dimensioned = entries.filter((e) => e.dimension && e.dimensionProperty)\n if (dimensioned.length > 0) {\n const breakdowns: Record<string, AggregateBreakdownEntry[]> = {}\n const byDimension = new Map<string, AggregateEntry[]>()\n for (const entry of dimensioned) {\n const list = byDimension.get(entry.dimensionProperty!)\n if (list) list.push(entry)\n else byDimension.set(entry.dimensionProperty!, [entry])\n }\n\n for (const [dimensionProperty, group] of byDimension) {\n const dimColumn = columnOf(dimensionProperty)\n if (!dimColumn) throw new AggregateSpecError(`Unmapped aggregate dimension: \"${group[0].dimension}\"`)\n if (!SAFE_IDENTIFIER.test(dimColumn)) {\n throw new AggregateSpecError(`Unsafe column name for dimension \"${group[0].dimension}\"`)\n }\n\n const expressions: string[] = [`\"${tableAlias}\".\"${dimColumn}\" as \"agg_dim\"`]\n const aliasToKey: Record<string, string> = {}\n group.forEach((entry, i) => {\n const column = columnOf(entry.property)\n if (!column) throw new AggregateSpecError(`Unmapped aggregate field: \"${entry.field}\"`)\n if (!SAFE_IDENTIFIER.test(column)) {\n throw new AggregateSpecError(`Unsafe column name for field \"${entry.field}\"`)\n }\n const alias = `agg_d_${i}`\n expressions.push(`${sqlForFn(entry.fn, `\"${tableAlias}\".\"${column}\"`)} as \"${alias}\"`)\n aliasToKey[alias] = aggregateKey(entry.field, entry.fn)\n })\n\n const compiled = compileWith(expressions, dimColumn)\n const rows = (await (em.getConnection() as any).execute(\n compiled.sql,\n compiled.params,\n 'all',\n )) as Record<string, unknown>[] | null | undefined\n\n for (const key of Object.values(aliasToKey)) breakdowns[key] = []\n for (const r of rows ?? []) {\n const dimValue = r?.['agg_dim']\n const dimKey = dimValue === null || dimValue === undefined ? '' : String(dimValue)\n for (const [alias, key] of Object.entries(aliasToKey)) {\n breakdowns[key].push({ key: dimKey, value: coerceAggregateValue(r?.[alias]) })\n }\n }\n }\n result.breakdowns = breakdowns\n }\n\n return result\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,105 @@
1
+ const ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
2
+ function parseIsoDay(value) {
3
+ if (typeof value !== "string" || !ISO_DATE_RE.test(value)) return null;
4
+ const [y, m, d] = value.split("-").map(Number);
5
+ const date = new Date(y, m - 1, d, 0, 0, 0, 0);
6
+ return Number.isNaN(date.getTime()) ? null : date;
7
+ }
8
+ function startOfDay(date) {
9
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0);
10
+ }
11
+ function endOfDay(date) {
12
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999);
13
+ }
14
+ function addUnit(base, n, unit) {
15
+ if (unit === "weeks") {
16
+ return new Date(base.getFullYear(), base.getMonth(), base.getDate() + n * 7);
17
+ }
18
+ if (unit === "months") {
19
+ const targetFirst = new Date(base.getFullYear(), base.getMonth() + n, 1);
20
+ const daysInTarget = new Date(targetFirst.getFullYear(), targetFirst.getMonth() + 1, 0).getDate();
21
+ return new Date(targetFirst.getFullYear(), targetFirst.getMonth(), Math.min(base.getDate(), daysInTarget));
22
+ }
23
+ return new Date(base.getFullYear(), base.getMonth(), base.getDate() + n);
24
+ }
25
+ function parseUnit(value) {
26
+ return value === "weeks" || value === "months" ? value : "days";
27
+ }
28
+ function isoWeekday(date) {
29
+ const wd = date.getDay();
30
+ return wd === 0 ? 7 : wd;
31
+ }
32
+ function startOfWeek(date) {
33
+ return startOfDay(addUnit(date, 1 - isoWeekday(date), "days"));
34
+ }
35
+ function endOfWeek(date) {
36
+ return endOfDay(addUnit(date, 7 - isoWeekday(date), "days"));
37
+ }
38
+ function parsePositiveInt(value) {
39
+ const n = typeof value === "number" ? value : Number(String(value ?? "").trim());
40
+ return Number.isInteger(n) && n >= 1 ? n : null;
41
+ }
42
+ const DATE_WINDOW_OPERATORS = [
43
+ "is_between",
44
+ "is_in_next",
45
+ "is_in_last",
46
+ "is_overdue",
47
+ "is_today",
48
+ "is_tomorrow",
49
+ "is_this_week",
50
+ "is_next_week"
51
+ ];
52
+ const WINDOW_OPERATOR_SET = new Set(DATE_WINDOW_OPERATORS);
53
+ function isDateWindowOperator(operator) {
54
+ return WINDOW_OPERATOR_SET.has(operator);
55
+ }
56
+ function resolveDateWindow(operator, values, now = /* @__PURE__ */ new Date()) {
57
+ switch (operator) {
58
+ case "is_between": {
59
+ const from = parseIsoDay(values[0]);
60
+ const to = parseIsoDay(values[1]);
61
+ if (!from && !to) return null;
62
+ return { from: from ? startOfDay(from) : null, to: to ? endOfDay(to) : null };
63
+ }
64
+ case "is_in_next": {
65
+ const count = parsePositiveInt(values[0]);
66
+ if (count === null) return null;
67
+ return { from: startOfDay(now), to: endOfDay(addUnit(now, count, parseUnit(values[1]))) };
68
+ }
69
+ case "is_in_last": {
70
+ const count = parsePositiveInt(values[0]);
71
+ if (count === null) return null;
72
+ return { from: startOfDay(addUnit(now, -count, parseUnit(values[1]))), to: endOfDay(now) };
73
+ }
74
+ case "is_overdue":
75
+ return { from: null, to: startOfDay(now), toExclusive: true };
76
+ case "is_today":
77
+ return { from: startOfDay(now), to: endOfDay(now) };
78
+ case "is_tomorrow": {
79
+ const t = addUnit(now, 1, "days");
80
+ return { from: startOfDay(t), to: endOfDay(t) };
81
+ }
82
+ case "is_this_week":
83
+ return { from: startOfDay(now), to: endOfWeek(now) };
84
+ case "is_next_week": {
85
+ const nextWeek = addUnit(now, 7, "days");
86
+ return { from: startOfWeek(nextWeek), to: endOfWeek(nextWeek) };
87
+ }
88
+ default:
89
+ return null;
90
+ }
91
+ }
92
+ export {
93
+ DATE_WINDOW_OPERATORS,
94
+ addUnit,
95
+ endOfDay,
96
+ endOfWeek,
97
+ isDateWindowOperator,
98
+ parseIsoDay,
99
+ parsePositiveInt,
100
+ parseUnit,
101
+ resolveDateWindow,
102
+ startOfDay,
103
+ startOfWeek
104
+ };
105
+ //# sourceMappingURL=dateWindows.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/backend/dynamic-table/server/dateWindows.ts"],
4
+ "sourcesContent": ["/**\n * Date-window resolution for DynamicTable filter operators \u2014 ONE implementation,\n * shared by every list route regardless of how it applies filters.\n *\n * ## Why this file exists (workshop item A14)\n *\n * There are two kinds of list route in this repo:\n *\n * - **DB-backed** routes push filters into SQL through {@link parseFilterRow}\n * (`filterParser.ts`). Those understood the now-relative operators.\n * - **In-memory** routes (the folders Files list, the Transport list) denormalise\n * rows first and match with their own `applyColumnFilters`. Those did **not**.\n * Their parser dropped any rule whose right-hand side was empty, and every\n * preset (`is_today`, `is_tomorrow`, `is_this_week`, `is_next_week`,\n * `is_overdue`) is deliberately value-less \u2014 so picking \"tomorrow\" on ETD\n * silently returned the **entire unfiltered table**. `is_in_next` /\n * `is_in_last` survived the drop but fell through to a substring match, so\n * \"next 7 days\" matched every row whose ISO timestamp contained a \"7\".\n *\n * Both were invisible: a filter that changes nothing looks like \"no shipments\n * match today\", not like a bug. Resolving the operator to a concrete\n * `[from, to]` window here, once, means the preset and the explicit\n * `is_between` range are the *same mechanism* on every list \u2014 which is the\n * requirement: one operator whose window happens to be computed, the other\n * whose window is typed.\n *\n * All arithmetic is local-time (matching how operators read a calendar) and\n * day-bounded, so a row stored at `2026-06-12 14:30` matches `is_today` on\n * 2026-06-12.\n */\n\nexport type RelativeUnit = 'days' | 'weeks' | 'months'\n\n/**\n * A resolved filter window. `from` is always an inclusive lower bound.\n * `to` is inclusive unless {@link DateWindow.toExclusive} is set \u2014 `is_overdue`\n * is \"strictly before the start of today\", which is not expressible as an\n * inclusive end-of-day bound without an off-by-one-millisecond fudge.\n * Either side may be `null`, meaning unbounded.\n */\nexport type DateWindow = {\n from: Date | null\n to: Date | null\n toExclusive?: boolean\n}\n\nconst ISO_DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/\n\n/** Parse `YYYY-MM-DD` into a local Date at the start of that day. */\nexport function parseIsoDay(value: unknown): Date | null {\n if (typeof value !== 'string' || !ISO_DATE_RE.test(value)) return null\n const [y, m, d] = value.split('-').map(Number)\n const date = new Date(y, m - 1, d, 0, 0, 0, 0)\n return Number.isNaN(date.getTime()) ? null : date\n}\n\nexport function startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0)\n}\n\nexport function endOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999)\n}\n\n/**\n * Add `n` units to `base` (n may be negative). Days/weeks are plain day\n * arithmetic; months are calendar months with an end-of-month clamp so the\n * result is always a real date instead of a JS Date overflow:\n * May 31 minus 1 month -> Apr 30 (not May 1)\n * Jan 31 plus 1 month -> Feb 28/29 (not Mar 2/3)\n */\nexport function addUnit(base: Date, n: number, unit: RelativeUnit): Date {\n if (unit === 'weeks') {\n return new Date(base.getFullYear(), base.getMonth(), base.getDate() + n * 7)\n }\n if (unit === 'months') {\n const targetFirst = new Date(base.getFullYear(), base.getMonth() + n, 1)\n const daysInTarget = new Date(targetFirst.getFullYear(), targetFirst.getMonth() + 1, 0).getDate()\n return new Date(targetFirst.getFullYear(), targetFirst.getMonth(), Math.min(base.getDate(), daysInTarget))\n }\n return new Date(base.getFullYear(), base.getMonth(), base.getDate() + n)\n}\n\n/** Coerce a stored relative unit value, defaulting to days. */\nexport function parseUnit(value: unknown): RelativeUnit {\n return value === 'weeks' || value === 'months' ? value : 'days'\n}\n\n/** ISO weekday: Monday = 1 \u2026 Sunday = 7. */\nfunction isoWeekday(date: Date): number {\n const wd = date.getDay()\n return wd === 0 ? 7 : wd\n}\n\n/** Monday 00:00 of the ISO week containing `date`. */\nexport function startOfWeek(date: Date): Date {\n return startOfDay(addUnit(date, 1 - isoWeekday(date), 'days'))\n}\n\n/** Sunday 23:59 of the ISO week containing `date`. */\nexport function endOfWeek(date: Date): Date {\n return endOfDay(addUnit(date, 7 - isoWeekday(date), 'days'))\n}\n\n/**\n * Coerce a stored relative count to a positive integer, or null if invalid.\n * Uses `Number` (not `parseInt`) so fractional/garbage input like \"1.5\" or\n * \"5abc\" is rejected outright rather than silently truncated.\n */\nexport function parsePositiveInt(value: unknown): number | null {\n const n = typeof value === 'number' ? value : Number(String(value ?? '').trim())\n return Number.isInteger(n) && n >= 1 ? n : null\n}\n\n/**\n * Every operator that resolves to a `[from, to]` window.\n *\n * `is_between` is in this list ON PURPOSE. Agnieszka works date-first on an\n * explicit range (\"szybciej mi jest operowa\u0107 na zakresie dat\") and declined\n * more presets; Klaudiusz lives on \"tomorrow\". Both mechanisms must coexist in\n * the same operator list, and the cheapest way to guarantee they never diverge\n * is for them to produce the same shape.\n */\nexport const DATE_WINDOW_OPERATORS = [\n 'is_between',\n 'is_in_next',\n 'is_in_last',\n 'is_overdue',\n 'is_today',\n 'is_tomorrow',\n 'is_this_week',\n 'is_next_week',\n] as const\n\nexport type DateWindowOperator = (typeof DATE_WINDOW_OPERATORS)[number]\n\nconst WINDOW_OPERATOR_SET: ReadonlySet<string> = new Set<string>(DATE_WINDOW_OPERATORS)\n\nexport function isDateWindowOperator(operator: string): operator is DateWindowOperator {\n return WINDOW_OPERATOR_SET.has(operator)\n}\n\n/**\n * Resolve a window operator + its stored `values` into a concrete\n * `[from, to]` range, anchored to `now`.\n *\n * Returns `null` when the rule cannot produce a window \u2014 an unknown operator,\n * an `is_between` with neither end filled, or an `is_in_next` whose count is\n * missing or not a positive integer. A `null` return means \"drop this rule\",\n * never \"match nothing\".\n *\n * `now` is injected (and re-read per request by callers) so a saved\n * perspective holding `is_tomorrow` keeps meaning *tomorrow*, not the day\n * after it was saved.\n */\nexport function resolveDateWindow(\n operator: string,\n values: readonly unknown[],\n now: Date = new Date(),\n): DateWindow | null {\n switch (operator) {\n case 'is_between': {\n // Explicit range from the two FilterDatePickers \u2014 values = [from, to].\n // A half-open range (only one end filled) is still a useful filter, so\n // the missing side is left unbounded rather than dropping the rule.\n const from = parseIsoDay(values[0])\n const to = parseIsoDay(values[1])\n if (!from && !to) return null\n return { from: from ? startOfDay(from) : null, to: to ? endOfDay(to) : null }\n }\n case 'is_in_next': {\n // Moving window anchored to today: [start of today, end of today + N units].\n const count = parsePositiveInt(values[0])\n if (count === null) return null\n return { from: startOfDay(now), to: endOfDay(addUnit(now, count, parseUnit(values[1]))) }\n }\n case 'is_in_last': {\n const count = parsePositiveInt(values[0])\n if (count === null) return null\n return { from: startOfDay(addUnit(now, -count, parseUnit(values[1]))), to: endOfDay(now) }\n }\n case 'is_overdue':\n // Strictly before today \u2014 a date that has already passed.\n return { from: null, to: startOfDay(now), toExclusive: true }\n case 'is_today':\n return { from: startOfDay(now), to: endOfDay(now) }\n case 'is_tomorrow': {\n const t = addUnit(now, 1, 'days')\n return { from: startOfDay(t), to: endOfDay(t) }\n }\n case 'is_this_week':\n // Today through the end of the current ISO week (upcoming, not past days).\n return { from: startOfDay(now), to: endOfWeek(now) }\n case 'is_next_week': {\n const nextWeek = addUnit(now, 7, 'days')\n return { from: startOfWeek(nextWeek), to: endOfWeek(nextWeek) }\n }\n default:\n return null\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,97 @@
1
+ import { escapeLikePattern } from "@open-mercato/shared/lib/db/escapeLikePattern";
2
+ import {
3
+ endOfDay,
4
+ parseIsoDay,
5
+ resolveDateWindow,
6
+ startOfDay
7
+ } from "./dateWindows.js";
8
+ function parseFilterRow(row, fieldMap, now = /* @__PURE__ */ new Date()) {
9
+ const field = fieldMap[row.field];
10
+ if (!field) return null;
11
+ const val = row.values[0];
12
+ const hasValue = val !== void 0 && val !== null && val !== "";
13
+ const hasValues = Array.isArray(row.values) && row.values.length > 0;
14
+ switch (row.operator) {
15
+ case "is_any_of":
16
+ if (!hasValues) return null;
17
+ return { [field]: { $in: row.values } };
18
+ case "is_not_any_of":
19
+ if (!hasValues) return null;
20
+ return { [field]: { $nin: row.values } };
21
+ case "contains":
22
+ if (!hasValue) return null;
23
+ return { [field]: { $ilike: `%${escapeLikePattern(String(val))}%` } };
24
+ case "is_empty":
25
+ return { [field]: { $eq: null } };
26
+ case "is_not_empty":
27
+ return { [field]: { $ne: null } };
28
+ case "equals": {
29
+ if (!hasValue) return null;
30
+ const day = parseIsoDay(val);
31
+ if (day) return { [field]: { $gte: startOfDay(day), $lte: endOfDay(day) } };
32
+ return { [field]: { $eq: val } };
33
+ }
34
+ case "not_equals":
35
+ if (!hasValue) return null;
36
+ return { [field]: { $ne: val } };
37
+ case "is_true":
38
+ return { [field]: { $eq: true } };
39
+ case "is_false":
40
+ return { [field]: { $eq: false } };
41
+ case "greater_than":
42
+ if (!hasValue) return null;
43
+ return { [field]: { $gt: val } };
44
+ case "less_than":
45
+ if (!hasValue) return null;
46
+ return { [field]: { $lt: val } };
47
+ case "is_before": {
48
+ if (!hasValue) return null;
49
+ const day = parseIsoDay(val);
50
+ return { [field]: { $lt: day ?? val } };
51
+ }
52
+ case "is_after": {
53
+ if (!hasValue) return null;
54
+ const day = parseIsoDay(val);
55
+ return { [field]: { $gt: day ? endOfDay(day) : val } };
56
+ }
57
+ case "is_on_or_before": {
58
+ if (!hasValue) return null;
59
+ const day = parseIsoDay(val);
60
+ return { [field]: { $lte: day ? endOfDay(day) : val } };
61
+ }
62
+ case "is_on_or_after": {
63
+ if (!hasValue) return null;
64
+ const day = parseIsoDay(val);
65
+ return { [field]: { $gte: day ? startOfDay(day) : val } };
66
+ }
67
+ // ── Windowed date operators ───────────────────────────────────────────────
68
+ // `is_between` (explicit range) and every now-relative preset / moving
69
+ // window resolve through ONE shared resolver, so the DB-backed lists and
70
+ // the in-memory lists can never drift apart on what "tomorrow" means.
71
+ case "is_between":
72
+ case "is_in_next":
73
+ case "is_in_last":
74
+ case "is_overdue":
75
+ case "is_today":
76
+ case "is_tomorrow":
77
+ case "is_this_week":
78
+ case "is_next_week": {
79
+ const window = resolveDateWindow(row.operator, row.values, now);
80
+ if (!window) return null;
81
+ const range = {};
82
+ if (window.from) range.$gte = window.from;
83
+ if (window.to) range[window.toExclusive ? "$lt" : "$lte"] = window.to;
84
+ return { [field]: range };
85
+ }
86
+ default:
87
+ return null;
88
+ }
89
+ }
90
+ function parseDynamicTableFilters(filterRows, fieldMap, now = /* @__PURE__ */ new Date()) {
91
+ return filterRows.map((row) => parseFilterRow(row, fieldMap, now)).filter((f) => f !== null);
92
+ }
93
+ export {
94
+ parseDynamicTableFilters,
95
+ parseFilterRow
96
+ };
97
+ //# sourceMappingURL=filterParser.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/backend/dynamic-table/server/filterParser.ts"],
4
+ "sourcesContent": ["import { escapeLikePattern } from '@open-mercato/shared/lib/db/escapeLikePattern'\nimport {\n endOfDay,\n parseIsoDay,\n resolveDateWindow,\n startOfDay,\n} from './dateWindows'\n\nexport interface DynamicTableFilterRow {\n field: string\n operator: string\n values: unknown[]\n}\n\n/**\n * Parse a single DynamicTable FilterRow into a MikroORM Where clause.\n * Returns null if the row cannot be parsed (unknown field, missing value, etc.)\n *\n * Date semantics: when an operator is date-typed (`is_before` / `is_after` /\n * `is_on_or_before` / `is_on_or_after` / `is_between`) or when `equals` is\n * given an ISO `YYYY-MM-DD` value, the parser converts the right-hand side\n * into Date objects and uses day-bounded ranges so timestamp columns compare\n * correctly. The on/between/equals operators expand to a [start-of-day,\n * end-of-day] window so a row stored as `2026-05-11 14:30` matches a filter\n * for `equals 2026-05-11`.\n */\nexport function parseFilterRow(\n row: DynamicTableFilterRow,\n fieldMap: Record<string, string>,\n now: Date = new Date()\n): Record<string, unknown> | null {\n const field = fieldMap[row.field]\n if (!field) return null\n\n const val = row.values[0]\n const hasValue = val !== undefined && val !== null && val !== ''\n const hasValues = Array.isArray(row.values) && row.values.length > 0\n\n switch (row.operator) {\n case 'is_any_of':\n if (!hasValues) return null\n return { [field]: { $in: row.values } }\n case 'is_not_any_of':\n if (!hasValues) return null\n return { [field]: { $nin: row.values } }\n case 'contains':\n if (!hasValue) return null\n return { [field]: { $ilike: `%${escapeLikePattern(String(val))}%` } }\n case 'is_empty':\n return { [field]: { $eq: null } }\n case 'is_not_empty':\n return { [field]: { $ne: null } }\n case 'equals': {\n if (!hasValue) return null\n // Same-day equality for ISO date values; exact-match otherwise.\n const day = parseIsoDay(val)\n if (day) return { [field]: { $gte: startOfDay(day), $lte: endOfDay(day) } }\n return { [field]: { $eq: val } }\n }\n case 'not_equals':\n if (!hasValue) return null\n return { [field]: { $ne: val } }\n case 'is_true':\n return { [field]: { $eq: true } }\n case 'is_false':\n return { [field]: { $eq: false } }\n case 'greater_than':\n if (!hasValue) return null\n return { [field]: { $gt: val } }\n case 'less_than':\n if (!hasValue) return null\n return { [field]: { $lt: val } }\n case 'is_before': {\n if (!hasValue) return null\n const day = parseIsoDay(val)\n // Strictly before the picked day starts.\n return { [field]: { $lt: day ?? val } }\n }\n case 'is_after': {\n if (!hasValue) return null\n const day = parseIsoDay(val)\n // Strictly after the picked day ends.\n return { [field]: { $gt: day ? endOfDay(day) : val } }\n }\n case 'is_on_or_before': {\n if (!hasValue) return null\n const day = parseIsoDay(val)\n // Anywhere on the picked day or earlier.\n return { [field]: { $lte: day ? endOfDay(day) : val } }\n }\n case 'is_on_or_after': {\n if (!hasValue) return null\n const day = parseIsoDay(val)\n return { [field]: { $gte: day ? startOfDay(day) : val } }\n }\n // \u2500\u2500 Windowed date operators \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // `is_between` (explicit range) and every now-relative preset / moving\n // window resolve through ONE shared resolver, so the DB-backed lists and\n // the in-memory lists can never drift apart on what \"tomorrow\" means.\n case 'is_between':\n case 'is_in_next':\n case 'is_in_last':\n case 'is_overdue':\n case 'is_today':\n case 'is_tomorrow':\n case 'is_this_week':\n case 'is_next_week': {\n const window = resolveDateWindow(row.operator, row.values, now)\n if (!window) return null\n const range: Record<string, Date> = {}\n if (window.from) range.$gte = window.from\n if (window.to) range[window.toExclusive ? '$lt' : '$lte'] = window.to\n return { [field]: range }\n }\n default:\n return null\n }\n}\n\n/**\n * Convert an array of DynamicTable FilterRows into MikroORM Where clauses.\n * Filters out rows that cannot be parsed (unknown field, missing value, etc.)\n */\nexport function parseDynamicTableFilters(\n filterRows: DynamicTableFilterRow[],\n fieldMap: Record<string, string>,\n now: Date = new Date()\n): Record<string, unknown>[] {\n return filterRows\n .map((row) => parseFilterRow(row, fieldMap, now))\n .filter((f): f is Record<string, unknown> => f !== null)\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,70 @@
1
+ const IDENTIFIER = /^[a-z_][a-z0-9_]*$/i;
2
+ function assertIdentifier(kind, value) {
3
+ if (!IDENTIFIER.test(value)) {
4
+ throw new Error(`Unsafe ${kind} identifier for filter suggestions: ${JSON.stringify(value)}`);
5
+ }
6
+ return `"${value}"`;
7
+ }
8
+ async function distinctColumnValues(opts) {
9
+ const limit = Math.min(Math.max(opts.limit ?? 50, 1), 200);
10
+ const base = assertIdentifier("table", opts.table);
11
+ const columns = (Array.isArray(opts.column) ? opts.column : [opts.column]).map((c) => assertIdentifier("column", c));
12
+ if (columns.length === 0) return [];
13
+ const params = [];
14
+ const where = [];
15
+ let from = `${base} AS t`;
16
+ let prefix = "t";
17
+ if (opts.join) {
18
+ const jt = assertIdentifier("table", opts.join.table);
19
+ const on = assertIdentifier("column", opts.join.on);
20
+ const foreign = assertIdentifier("column", opts.join.foreign);
21
+ from = `${base} AS t INNER JOIN ${jt} AS j ON j.${foreign} = t.${on}`;
22
+ prefix = "j";
23
+ }
24
+ const target = columns.length === 1 ? `${prefix}.${columns[0]}` : `unnest(ARRAY[${columns.map((c) => `${prefix}.${c}::text`).join(", ")}])`;
25
+ for (const [rawColumn, value] of Object.entries(opts.scope ?? {})) {
26
+ if (value === void 0) continue;
27
+ const scoped = `t.${assertIdentifier("column", rawColumn)}`;
28
+ if (value === null) {
29
+ where.push(`${scoped} IS NULL`);
30
+ } else if (Array.isArray(value)) {
31
+ if (value.length === 0) return [];
32
+ const holes = value.map((entry) => {
33
+ params.push(entry);
34
+ return "?";
35
+ });
36
+ where.push(`${scoped} IN (${holes.join(", ")})`);
37
+ } else {
38
+ params.push(value);
39
+ where.push(`${scoped} = ?`);
40
+ }
41
+ }
42
+ const needle = (opts.query ?? "").trim();
43
+ const scopeWhere = where.length > 0 ? `WHERE ${where.join(" AND ")} ` : "";
44
+ const outer = ["value IS NOT NULL", "btrim(value) <> ''"];
45
+ let sql;
46
+ if (columns.length === 1) {
47
+ if (needle) params.push(`%${needle}%`);
48
+ const outerSql = [...outer, ...needle ? ["value ILIKE ?"] : []].join(" AND ");
49
+ sql = `SELECT DISTINCT value FROM (SELECT ${target}::text AS value FROM ${from} ${scopeWhere}) s WHERE ${outerSql} ORDER BY value ASC LIMIT ?`;
50
+ } else {
51
+ if (needle) params.push(`%${needle}%`);
52
+ const outerSql = [...outer, ...needle ? ["value ILIKE ?"] : []].join(" AND ");
53
+ sql = `SELECT DISTINCT value FROM (SELECT ${target} AS value FROM ${from} ${scopeWhere}) s WHERE ${outerSql} ORDER BY value ASC LIMIT ?`;
54
+ }
55
+ params.push(limit);
56
+ try {
57
+ const rows = await opts.em.getConnection().execute(sql, params);
58
+ return Array.isArray(rows) ? rows.map((r) => r.value).filter(Boolean) : [];
59
+ } catch (err) {
60
+ console.error(
61
+ `[filter-suggestions] query failed for ${opts.table}.${opts.column}:`,
62
+ err instanceof Error ? err.message : err
63
+ );
64
+ return [];
65
+ }
66
+ }
67
+ export {
68
+ distinctColumnValues
69
+ };
70
+ //# sourceMappingURL=filterSuggestions.js.map