@hub-kit/core 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. package/README.md +125 -0
  2. package/cli/hub-kit.mjs +112 -0
  3. package/dist/adapters/bank-reconciliation.d.ts +100 -0
  4. package/dist/adapters/bank-reconciliation.js +1 -0
  5. package/dist/adapters/bank-sync-log.d.ts +46 -0
  6. package/dist/adapters/bank-sync-log.js +1 -0
  7. package/dist/adapters/category-rules.d.ts +94 -0
  8. package/dist/adapters/category-rules.js +1 -0
  9. package/dist/adapters/companies.d.ts +85 -0
  10. package/dist/adapters/companies.js +3 -0
  11. package/dist/adapters/customers.d.ts +71 -0
  12. package/dist/adapters/customers.js +1 -0
  13. package/dist/adapters/exclusion-rules.d.ts +34 -0
  14. package/dist/adapters/exclusion-rules.js +15 -0
  15. package/dist/adapters/file-naming.d.ts +36 -0
  16. package/dist/adapters/file-naming.js +1 -0
  17. package/dist/adapters/index.d.ts +24 -0
  18. package/dist/adapters/index.js +1 -0
  19. package/dist/adapters/invoice-detail.d.ts +126 -0
  20. package/dist/adapters/invoice-detail.js +1 -0
  21. package/dist/adapters/invoice-list.d.ts +63 -0
  22. package/dist/adapters/invoice-list.js +1 -0
  23. package/dist/adapters/invoice-upload.d.ts +26 -0
  24. package/dist/adapters/invoice-upload.js +1 -0
  25. package/dist/adapters/manual-bookings.d.ts +56 -0
  26. package/dist/adapters/manual-bookings.js +1 -0
  27. package/dist/adapters/notifications.d.ts +31 -0
  28. package/dist/adapters/notifications.js +1 -0
  29. package/dist/adapters/open-items.d.ts +42 -0
  30. package/dist/adapters/open-items.js +1 -0
  31. package/dist/adapters/opos-whitelist.d.ts +38 -0
  32. package/dist/adapters/opos-whitelist.js +1 -0
  33. package/dist/adapters/outgoing-invoices.d.ts +32 -0
  34. package/dist/adapters/outgoing-invoices.js +1 -0
  35. package/dist/adapters/overview.d.ts +68 -0
  36. package/dist/adapters/overview.js +1 -0
  37. package/dist/adapters/processing-log.d.ts +48 -0
  38. package/dist/adapters/processing-log.js +1 -0
  39. package/dist/adapters/properties.d.ts +87 -0
  40. package/dist/adapters/properties.js +1 -0
  41. package/dist/adapters/supplier-detail.d.ts +64 -0
  42. package/dist/adapters/supplier-detail.js +1 -0
  43. package/dist/adapters/supplier-list.d.ts +21 -0
  44. package/dist/adapters/supplier-list.js +1 -0
  45. package/dist/adapters/team.d.ts +79 -0
  46. package/dist/adapters/team.js +1 -0
  47. package/dist/adapters/trash.d.ts +26 -0
  48. package/dist/adapters/trash.js +1 -0
  49. package/dist/adapters/vat-rules.d.ts +83 -0
  50. package/dist/adapters/vat-rules.js +1 -0
  51. package/dist/components/access/index.d.ts +3 -0
  52. package/dist/components/access/index.js +3 -0
  53. package/dist/components/access/permission-checklist.d.ts +13 -0
  54. package/dist/components/access/permission-checklist.js +19 -0
  55. package/dist/components/access/permission-matrix.d.ts +12 -0
  56. package/dist/components/access/permission-matrix.js +18 -0
  57. package/dist/components/access/types.d.ts +15 -0
  58. package/dist/components/access/types.js +1 -0
  59. package/dist/components/dashboard/date-range-calendar.d.ts +19 -0
  60. package/dist/components/dashboard/date-range-calendar.js +97 -0
  61. package/dist/components/dashboard/index.d.ts +23 -0
  62. package/dist/components/dashboard/index.js +14 -0
  63. package/dist/components/dashboard/kpi-card.d.ts +13 -0
  64. package/dist/components/dashboard/kpi-card.js +7 -0
  65. package/dist/components/dashboard/money-cards-row.d.ts +29 -0
  66. package/dist/components/dashboard/money-cards-row.js +28 -0
  67. package/dist/components/dashboard/money-trend-chart.d.ts +13 -0
  68. package/dist/components/dashboard/money-trend-chart.js +16 -0
  69. package/dist/components/dashboard/panel.d.ts +9 -0
  70. package/dist/components/dashboard/panel.js +5 -0
  71. package/dist/components/dashboard/period-picker.d.ts +25 -0
  72. package/dist/components/dashboard/period-picker.js +82 -0
  73. package/dist/components/dashboard/periods.d.ts +13 -0
  74. package/dist/components/dashboard/periods.js +63 -0
  75. package/dist/components/dashboard/pipeline-stages-panel.d.ts +14 -0
  76. package/dist/components/dashboard/pipeline-stages-panel.js +12 -0
  77. package/dist/components/dashboard/processing-summary-panel.d.ts +34 -0
  78. package/dist/components/dashboard/processing-summary-panel.js +11 -0
  79. package/dist/components/dashboard/ranked-bars.d.ts +15 -0
  80. package/dist/components/dashboard/ranked-bars.js +16 -0
  81. package/dist/components/dashboard/ranked-list-panel.d.ts +14 -0
  82. package/dist/components/dashboard/ranked-list-panel.js +9 -0
  83. package/dist/components/dashboard/stage-tiles.d.ts +15 -0
  84. package/dist/components/dashboard/stage-tiles.js +6 -0
  85. package/dist/components/dashboard/stat-rows-panel.d.ts +25 -0
  86. package/dist/components/dashboard/stat-rows-panel.js +7 -0
  87. package/dist/components/dashboard/stat-tile.d.ts +20 -0
  88. package/dist/components/dashboard/stat-tile.js +9 -0
  89. package/dist/components/feedback/index.d.ts +4 -0
  90. package/dist/components/feedback/index.js +2 -0
  91. package/dist/components/feedback/query-states.d.ts +27 -0
  92. package/dist/components/feedback/query-states.js +38 -0
  93. package/dist/components/feedback/table-pagination.d.ts +20 -0
  94. package/dist/components/feedback/table-pagination.js +15 -0
  95. package/dist/components/invoice-queue/index.d.ts +5 -0
  96. package/dist/components/invoice-queue/index.js +3 -0
  97. package/dist/components/invoice-queue/next-action-cell.d.ts +5 -0
  98. package/dist/components/invoice-queue/next-action-cell.js +9 -0
  99. package/dist/components/invoice-queue/queue-kpi-card.d.ts +19 -0
  100. package/dist/components/invoice-queue/queue-kpi-card.js +31 -0
  101. package/dist/components/invoice-queue/queue-kpi-row.d.ts +22 -0
  102. package/dist/components/invoice-queue/queue-kpi-row.js +12 -0
  103. package/dist/components/notifications/alerts.d.ts +25 -0
  104. package/dist/components/notifications/alerts.js +66 -0
  105. package/dist/components/notifications/bell.d.ts +14 -0
  106. package/dist/components/notifications/bell.js +17 -0
  107. package/dist/components/notifications/highlight.d.ts +4 -0
  108. package/dist/components/notifications/highlight.js +7 -0
  109. package/dist/components/notifications/index.d.ts +7 -0
  110. package/dist/components/notifications/index.js +6 -0
  111. package/dist/components/notifications/reminder-dialog.d.ts +24 -0
  112. package/dist/components/notifications/reminder-dialog.js +54 -0
  113. package/dist/components/notifications/types.d.ts +27 -0
  114. package/dist/components/notifications/types.js +1 -0
  115. package/dist/components/notifications/use-notification-acks.d.ts +7 -0
  116. package/dist/components/notifications/use-notification-acks.js +37 -0
  117. package/dist/components/shell/breadcrumbs.d.ts +7 -0
  118. package/dist/components/shell/breadcrumbs.js +38 -0
  119. package/dist/components/shell/index.d.ts +3 -0
  120. package/dist/components/shell/index.js +3 -0
  121. package/dist/components/shell/shell.d.ts +30 -0
  122. package/dist/components/shell/shell.js +110 -0
  123. package/dist/components/shell/types.d.ts +23 -0
  124. package/dist/components/shell/types.js +3 -0
  125. package/dist/components/tour/find-target.d.ts +1 -0
  126. package/dist/components/tour/find-target.js +3 -0
  127. package/dist/components/tour/index.d.ts +14 -0
  128. package/dist/components/tour/index.js +8 -0
  129. package/dist/components/tour/labels.d.ts +10 -0
  130. package/dist/components/tour/labels.js +9 -0
  131. package/dist/components/tour/seen-store.d.ts +3 -0
  132. package/dist/components/tour/seen-store.js +34 -0
  133. package/dist/components/tour/tour-blocks.d.ts +4 -0
  134. package/dist/components/tour/tour-blocks.js +27 -0
  135. package/dist/components/tour/tour-button.d.ts +4 -0
  136. package/dist/components/tour/tour-button.js +12 -0
  137. package/dist/components/tour/tour-card.d.ts +11 -0
  138. package/dist/components/tour/tour-card.js +7 -0
  139. package/dist/components/tour/tour-context.d.ts +16 -0
  140. package/dist/components/tour/tour-context.js +2 -0
  141. package/dist/components/tour/tour-overlay.d.ts +1 -0
  142. package/dist/components/tour/tour-overlay.js +165 -0
  143. package/dist/components/tour/tour-provider.d.ts +9 -0
  144. package/dist/components/tour/tour-provider.js +80 -0
  145. package/dist/components/tour/types.d.ts +44 -0
  146. package/dist/components/tour/types.js +1 -0
  147. package/dist/components/tour/use-tour.d.ts +3 -0
  148. package/dist/components/tour/use-tour.js +9 -0
  149. package/dist/hooks/use-mobile.d.ts +1 -0
  150. package/dist/hooks/use-mobile.js +15 -0
  151. package/dist/i18n/index.d.ts +15 -0
  152. package/dist/i18n/index.js +15 -0
  153. package/dist/lib/bank-import/classify.d.ts +8 -0
  154. package/dist/lib/bank-import/classify.js +89 -0
  155. package/dist/lib/bank-import/column-guess.d.ts +2 -0
  156. package/dist/lib/bank-import/column-guess.js +40 -0
  157. package/dist/lib/bank-import/csv.d.ts +3 -0
  158. package/dist/lib/bank-import/csv.js +20 -0
  159. package/dist/lib/bank-import/duplicates.d.ts +2 -0
  160. package/dist/lib/bank-import/duplicates.js +21 -0
  161. package/dist/lib/bank-import/index.d.ts +12 -0
  162. package/dist/lib/bank-import/index.js +9 -0
  163. package/dist/lib/bank-import/mapping-storage.d.ts +3 -0
  164. package/dist/lib/bank-import/mapping-storage.js +29 -0
  165. package/dist/lib/bank-import/normalize.d.ts +4 -0
  166. package/dist/lib/bank-import/normalize.js +82 -0
  167. package/dist/lib/bank-import/parse-file.d.ts +7 -0
  168. package/dist/lib/bank-import/parse-file.js +23 -0
  169. package/dist/lib/bank-import/types.d.ts +31 -0
  170. package/dist/lib/bank-import/types.js +1 -0
  171. package/dist/lib/bank-import/xlsx.d.ts +2 -0
  172. package/dist/lib/bank-import/xlsx.js +25 -0
  173. package/dist/lib/class-names.d.ts +2 -0
  174. package/dist/lib/class-names.js +5 -0
  175. package/dist/lib/download.d.ts +2 -0
  176. package/dist/lib/download.js +14 -0
  177. package/dist/lib/formatters.d.ts +6 -0
  178. package/dist/lib/formatters.js +24 -0
  179. package/dist/lib/index.d.ts +9 -0
  180. package/dist/lib/index.js +6 -0
  181. package/dist/lib/opos-whitelist/index.d.ts +2 -0
  182. package/dist/lib/opos-whitelist/index.js +1 -0
  183. package/dist/lib/opos-whitelist/opos.d.ts +14 -0
  184. package/dist/lib/opos-whitelist/opos.js +49 -0
  185. package/dist/lib/query-result.d.ts +12 -0
  186. package/dist/lib/query-result.js +1 -0
  187. package/dist/lib/tour-placeholders/index.d.ts +2 -0
  188. package/dist/lib/tour-placeholders/index.js +1 -0
  189. package/dist/lib/tour-placeholders/overview.d.ts +12 -0
  190. package/dist/lib/tour-placeholders/overview.js +139 -0
  191. package/dist/pages/bank-accounts/BankAccountsPage.d.ts +7 -0
  192. package/dist/pages/bank-accounts/BankAccountsPage.js +21 -0
  193. package/dist/pages/bank-accounts/index.d.ts +4 -0
  194. package/dist/pages/bank-accounts/index.js +2 -0
  195. package/dist/pages/bank-accounts/labels.d.ts +15 -0
  196. package/dist/pages/bank-accounts/labels.js +14 -0
  197. package/dist/pages/bank-import/BankImportWizard.d.ts +9 -0
  198. package/dist/pages/bank-import/BankImportWizard.js +158 -0
  199. package/dist/pages/bank-import/index.d.ts +4 -0
  200. package/dist/pages/bank-import/index.js +2 -0
  201. package/dist/pages/bank-import/labels.d.ts +44 -0
  202. package/dist/pages/bank-import/labels.js +43 -0
  203. package/dist/pages/bank-sync-log/BankSyncLogPage.d.ts +7 -0
  204. package/dist/pages/bank-sync-log/BankSyncLogPage.js +77 -0
  205. package/dist/pages/bank-sync-log/index.d.ts +4 -0
  206. package/dist/pages/bank-sync-log/index.js +2 -0
  207. package/dist/pages/bank-sync-log/labels.d.ts +21 -0
  208. package/dist/pages/bank-sync-log/labels.js +20 -0
  209. package/dist/pages/bank-transactions/BankMatchPanel.d.ts +8 -0
  210. package/dist/pages/bank-transactions/BankMatchPanel.js +75 -0
  211. package/dist/pages/bank-transactions/BankTransactionsPage.d.ts +7 -0
  212. package/dist/pages/bank-transactions/BankTransactionsPage.js +59 -0
  213. package/dist/pages/bank-transactions/badges.d.ts +8 -0
  214. package/dist/pages/bank-transactions/badges.js +24 -0
  215. package/dist/pages/bank-transactions/index.d.ts +6 -0
  216. package/dist/pages/bank-transactions/index.js +4 -0
  217. package/dist/pages/bank-transactions/labels.d.ts +41 -0
  218. package/dist/pages/bank-transactions/labels.js +40 -0
  219. package/dist/pages/bank-transactions/sort-control.d.ts +17 -0
  220. package/dist/pages/bank-transactions/sort-control.js +8 -0
  221. package/dist/pages/bank-transactions/use-table-view.d.ts +23 -0
  222. package/dist/pages/bank-transactions/use-table-view.js +54 -0
  223. package/dist/pages/category-rules/CategoryRulesPage.d.ts +7 -0
  224. package/dist/pages/category-rules/CategoryRulesPage.js +160 -0
  225. package/dist/pages/category-rules/index.d.ts +4 -0
  226. package/dist/pages/category-rules/index.js +2 -0
  227. package/dist/pages/category-rules/labels.d.ts +66 -0
  228. package/dist/pages/category-rules/labels.js +72 -0
  229. package/dist/pages/companies/company-detail-page.d.ts +10 -0
  230. package/dist/pages/companies/company-detail-page.js +184 -0
  231. package/dist/pages/companies/company-form.d.ts +20 -0
  232. package/dist/pages/companies/company-form.js +23 -0
  233. package/dist/pages/companies/company-list-page.d.ts +9 -0
  234. package/dist/pages/companies/company-list-page.js +109 -0
  235. package/dist/pages/companies/known-spellings-card.d.ts +8 -0
  236. package/dist/pages/companies/known-spellings-card.js +65 -0
  237. package/dist/pages/companies/labels.d.ts +105 -0
  238. package/dist/pages/companies/labels.js +104 -0
  239. package/dist/pages/companies/sort-control.d.ts +17 -0
  240. package/dist/pages/companies/sort-control.js +8 -0
  241. package/dist/pages/companies/use-infinite-rows.d.ts +6 -0
  242. package/dist/pages/companies/use-infinite-rows.js +24 -0
  243. package/dist/pages/companies/use-table-view.d.ts +23 -0
  244. package/dist/pages/companies/use-table-view.js +56 -0
  245. package/dist/pages/customers/company-chip.d.ts +6 -0
  246. package/dist/pages/customers/company-chip.js +9 -0
  247. package/dist/pages/customers/copy-button.d.ts +6 -0
  248. package/dist/pages/customers/copy-button.js +31 -0
  249. package/dist/pages/customers/customer-detail-page.d.ts +10 -0
  250. package/dist/pages/customers/customer-detail-page.js +83 -0
  251. package/dist/pages/customers/customer-list-page.d.ts +9 -0
  252. package/dist/pages/customers/customer-list-page.js +65 -0
  253. package/dist/pages/customers/edit-customer-dialog.d.ts +9 -0
  254. package/dist/pages/customers/edit-customer-dialog.js +72 -0
  255. package/dist/pages/customers/form-hints.d.ts +6 -0
  256. package/dist/pages/customers/form-hints.js +9 -0
  257. package/dist/pages/customers/invoice-status-badge.d.ts +10 -0
  258. package/dist/pages/customers/invoice-status-badge.js +22 -0
  259. package/dist/pages/customers/labels.d.ts +116 -0
  260. package/dist/pages/customers/labels.js +117 -0
  261. package/dist/pages/customers/new-customer-dialog.d.ts +6 -0
  262. package/dist/pages/customers/new-customer-dialog.js +93 -0
  263. package/dist/pages/customers/sort-control.d.ts +14 -0
  264. package/dist/pages/customers/sort-control.js +9 -0
  265. package/dist/pages/customers/use-table-view.d.ts +23 -0
  266. package/dist/pages/customers/use-table-view.js +56 -0
  267. package/dist/pages/exclusion-rules/exclusion-rules-page.d.ts +7 -0
  268. package/dist/pages/exclusion-rules/exclusion-rules-page.js +114 -0
  269. package/dist/pages/exclusion-rules/labels.d.ts +53 -0
  270. package/dist/pages/exclusion-rules/labels.js +61 -0
  271. package/dist/pages/file-naming/build-filename.d.ts +3 -0
  272. package/dist/pages/file-naming/build-filename.js +82 -0
  273. package/dist/pages/file-naming/file-naming-page.d.ts +10 -0
  274. package/dist/pages/file-naming/file-naming-page.js +120 -0
  275. package/dist/pages/file-naming/labels.d.ts +44 -0
  276. package/dist/pages/file-naming/labels.js +44 -0
  277. package/dist/pages/index.d.ts +63 -0
  278. package/dist/pages/index.js +48 -0
  279. package/dist/pages/invoice-detail/InvoiceDetailPage.d.ts +11 -0
  280. package/dist/pages/invoice-detail/InvoiceDetailPage.js +292 -0
  281. package/dist/pages/invoice-detail/OutgoingInvoiceFlag.d.ts +26 -0
  282. package/dist/pages/invoice-detail/OutgoingInvoiceFlag.js +16 -0
  283. package/dist/pages/invoice-detail/ReviewBadge.d.ts +15 -0
  284. package/dist/pages/invoice-detail/ReviewBadge.js +23 -0
  285. package/dist/pages/invoice-detail/ReviewCard.d.ts +17 -0
  286. package/dist/pages/invoice-detail/ReviewCard.js +12 -0
  287. package/dist/pages/invoice-detail/SideBySide.d.ts +5 -0
  288. package/dist/pages/invoice-detail/SideBySide.js +5 -0
  289. package/dist/pages/invoice-detail/WorkflowHistoryList.d.ts +23 -0
  290. package/dist/pages/invoice-detail/WorkflowHistoryList.js +32 -0
  291. package/dist/pages/invoice-detail/WorkflowLadder.d.ts +20 -0
  292. package/dist/pages/invoice-detail/WorkflowLadder.js +16 -0
  293. package/dist/pages/invoice-detail/history.d.ts +23 -0
  294. package/dist/pages/invoice-detail/history.js +76 -0
  295. package/dist/pages/invoice-detail/index.d.ts +21 -0
  296. package/dist/pages/invoice-detail/index.js +11 -0
  297. package/dist/pages/invoice-detail/labels.d.ts +79 -0
  298. package/dist/pages/invoice-detail/labels.js +139 -0
  299. package/dist/pages/invoice-detail/pipeline-types.d.ts +58 -0
  300. package/dist/pages/invoice-detail/pipeline-types.js +1 -0
  301. package/dist/pages/invoice-detail/review-recheck.d.ts +8 -0
  302. package/dist/pages/invoice-detail/review-recheck.js +103 -0
  303. package/dist/pages/invoice-detail/review.d.ts +91 -0
  304. package/dist/pages/invoice-detail/review.js +310 -0
  305. package/dist/pages/invoice-list/badges.d.ts +23 -0
  306. package/dist/pages/invoice-list/badges.js +26 -0
  307. package/dist/pages/invoice-list/index.d.ts +5 -0
  308. package/dist/pages/invoice-list/index.js +3 -0
  309. package/dist/pages/invoice-list/invoice-list-page.d.ts +13 -0
  310. package/dist/pages/invoice-list/invoice-list-page.js +114 -0
  311. package/dist/pages/invoice-list/labels.d.ts +36 -0
  312. package/dist/pages/invoice-list/labels.js +29 -0
  313. package/dist/pages/invoice-list/sort-control.d.ts +17 -0
  314. package/dist/pages/invoice-list/sort-control.js +8 -0
  315. package/dist/pages/invoice-list/use-table-view.d.ts +23 -0
  316. package/dist/pages/invoice-list/use-table-view.js +54 -0
  317. package/dist/pages/invoice-upload/InvoiceUploadPage.d.ts +7 -0
  318. package/dist/pages/invoice-upload/InvoiceUploadPage.js +115 -0
  319. package/dist/pages/invoice-upload/index.d.ts +4 -0
  320. package/dist/pages/invoice-upload/index.js +2 -0
  321. package/dist/pages/invoice-upload/labels.d.ts +29 -0
  322. package/dist/pages/invoice-upload/labels.js +28 -0
  323. package/dist/pages/manual-bookings/ManualBookingsPage.d.ts +7 -0
  324. package/dist/pages/manual-bookings/ManualBookingsPage.js +161 -0
  325. package/dist/pages/manual-bookings/index.d.ts +4 -0
  326. package/dist/pages/manual-bookings/index.js +2 -0
  327. package/dist/pages/manual-bookings/labels.d.ts +53 -0
  328. package/dist/pages/manual-bookings/labels.js +52 -0
  329. package/dist/pages/notifications/labels.d.ts +22 -0
  330. package/dist/pages/notifications/labels.js +21 -0
  331. package/dist/pages/notifications/notifications-page.d.ts +14 -0
  332. package/dist/pages/notifications/notifications-page.js +81 -0
  333. package/dist/pages/open-items/OpenItemsPage.d.ts +11 -0
  334. package/dist/pages/open-items/OpenItemsPage.js +110 -0
  335. package/dist/pages/open-items/index.d.ts +6 -0
  336. package/dist/pages/open-items/index.js +3 -0
  337. package/dist/pages/open-items/labels.d.ts +37 -0
  338. package/dist/pages/open-items/labels.js +36 -0
  339. package/dist/pages/open-items/urgency.d.ts +8 -0
  340. package/dist/pages/open-items/urgency.js +27 -0
  341. package/dist/pages/opos-whitelist/OposWhitelistPage.d.ts +7 -0
  342. package/dist/pages/opos-whitelist/OposWhitelistPage.js +165 -0
  343. package/dist/pages/opos-whitelist/index.d.ts +4 -0
  344. package/dist/pages/opos-whitelist/index.js +2 -0
  345. package/dist/pages/opos-whitelist/labels.d.ts +56 -0
  346. package/dist/pages/opos-whitelist/labels.js +70 -0
  347. package/dist/pages/outgoing-invoices/OutgoingInvoicesPage.d.ts +7 -0
  348. package/dist/pages/outgoing-invoices/OutgoingInvoicesPage.js +169 -0
  349. package/dist/pages/outgoing-invoices/index.d.ts +4 -0
  350. package/dist/pages/outgoing-invoices/index.js +2 -0
  351. package/dist/pages/outgoing-invoices/labels.d.ts +43 -0
  352. package/dist/pages/outgoing-invoices/labels.js +42 -0
  353. package/dist/pages/outgoing-invoices/sort-control.d.ts +17 -0
  354. package/dist/pages/outgoing-invoices/sort-control.js +8 -0
  355. package/dist/pages/outgoing-invoices/use-table-view.d.ts +23 -0
  356. package/dist/pages/outgoing-invoices/use-table-view.js +54 -0
  357. package/dist/pages/overview/labels.d.ts +35 -0
  358. package/dist/pages/overview/labels.js +34 -0
  359. package/dist/pages/overview/overview-page.d.ts +22 -0
  360. package/dist/pages/overview/overview-page.js +127 -0
  361. package/dist/pages/processing-log/labels.d.ts +54 -0
  362. package/dist/pages/processing-log/labels.js +53 -0
  363. package/dist/pages/processing-log/mail-parsing.d.ts +21 -0
  364. package/dist/pages/processing-log/mail-parsing.js +52 -0
  365. package/dist/pages/processing-log/processing-log-page.d.ts +9 -0
  366. package/dist/pages/processing-log/processing-log-page.js +206 -0
  367. package/dist/pages/properties/badges.d.ts +20 -0
  368. package/dist/pages/properties/badges.js +45 -0
  369. package/dist/pages/properties/company-assignment-field.d.ts +11 -0
  370. package/dist/pages/properties/company-assignment-field.js +13 -0
  371. package/dist/pages/properties/form-field.d.ts +6 -0
  372. package/dist/pages/properties/form-field.js +9 -0
  373. package/dist/pages/properties/labels.d.ts +124 -0
  374. package/dist/pages/properties/labels.js +128 -0
  375. package/dist/pages/properties/name-variants-card.d.ts +7 -0
  376. package/dist/pages/properties/name-variants-card.js +60 -0
  377. package/dist/pages/properties/property-detail-page.d.ts +10 -0
  378. package/dist/pages/properties/property-detail-page.js +150 -0
  379. package/dist/pages/properties/property-list-page.d.ts +13 -0
  380. package/dist/pages/properties/property-list-page.js +201 -0
  381. package/dist/pages/properties/sort-control.d.ts +14 -0
  382. package/dist/pages/properties/sort-control.js +9 -0
  383. package/dist/pages/properties/use-infinite-rows.d.ts +6 -0
  384. package/dist/pages/properties/use-infinite-rows.js +26 -0
  385. package/dist/pages/properties/use-table-view.d.ts +23 -0
  386. package/dist/pages/properties/use-table-view.js +56 -0
  387. package/dist/pages/supplier-detail/SupplierDetailPage.d.ts +10 -0
  388. package/dist/pages/supplier-detail/SupplierDetailPage.js +157 -0
  389. package/dist/pages/supplier-detail/index.d.ts +4 -0
  390. package/dist/pages/supplier-detail/index.js +2 -0
  391. package/dist/pages/supplier-detail/labels.d.ts +46 -0
  392. package/dist/pages/supplier-detail/labels.js +45 -0
  393. package/dist/pages/supplier-list/SupplierListPage.d.ts +9 -0
  394. package/dist/pages/supplier-list/SupplierListPage.js +102 -0
  395. package/dist/pages/supplier-list/index.d.ts +4 -0
  396. package/dist/pages/supplier-list/index.js +2 -0
  397. package/dist/pages/supplier-list/labels.d.ts +33 -0
  398. package/dist/pages/supplier-list/labels.js +32 -0
  399. package/dist/pages/supplier-list/sort-control.d.ts +17 -0
  400. package/dist/pages/supplier-list/sort-control.js +8 -0
  401. package/dist/pages/supplier-list/use-table-view.d.ts +23 -0
  402. package/dist/pages/supplier-list/use-table-view.js +54 -0
  403. package/dist/pages/team/account-dialogs.d.ts +12 -0
  404. package/dist/pages/team/account-dialogs.js +49 -0
  405. package/dist/pages/team/employee-editor.d.ts +19 -0
  406. package/dist/pages/team/employee-editor.js +124 -0
  407. package/dist/pages/team/labels.d.ts +99 -0
  408. package/dist/pages/team/labels.js +98 -0
  409. package/dist/pages/team/new-employee.d.ts +8 -0
  410. package/dist/pages/team/new-employee.js +103 -0
  411. package/dist/pages/team/roles-tab.d.ts +6 -0
  412. package/dist/pages/team/roles-tab.js +46 -0
  413. package/dist/pages/team/team-page.d.ts +7 -0
  414. package/dist/pages/team/team-page.js +81 -0
  415. package/dist/pages/team/temp-password-dialog.d.ts +11 -0
  416. package/dist/pages/team/temp-password-dialog.js +23 -0
  417. package/dist/pages/trash/labels.d.ts +68 -0
  418. package/dist/pages/trash/labels.js +69 -0
  419. package/dist/pages/trash/trash-page.d.ts +9 -0
  420. package/dist/pages/trash/trash-page.js +259 -0
  421. package/dist/pages/vat-rules/labels.d.ts +110 -0
  422. package/dist/pages/vat-rules/labels.js +109 -0
  423. package/dist/pages/vat-rules/new-rule-dialog.d.ts +7 -0
  424. package/dist/pages/vat-rules/new-rule-dialog.js +134 -0
  425. package/dist/pages/vat-rules/rule-row.d.ts +20 -0
  426. package/dist/pages/vat-rules/rule-row.js +120 -0
  427. package/dist/pages/vat-rules/vat-rules-page.d.ts +9 -0
  428. package/dist/pages/vat-rules/vat-rules-page.js +61 -0
  429. package/dist/ui/alert-dialog.d.ts +20 -0
  430. package/dist/ui/alert-dialog.js +41 -0
  431. package/dist/ui/badge.d.ts +9 -0
  432. package/dist/ui/badge.js +20 -0
  433. package/dist/ui/breadcrumb.d.ts +19 -0
  434. package/dist/ui/breadcrumb.js +23 -0
  435. package/dist/ui/button.d.ts +11 -0
  436. package/dist/ui/button.js +33 -0
  437. package/dist/ui/calendar.d.ts +8 -0
  438. package/dist/ui/calendar.js +75 -0
  439. package/dist/ui/card.d.ts +8 -0
  440. package/dist/ui/card.js +16 -0
  441. package/dist/ui/chart.d.ts +62 -0
  442. package/dist/ui/chart.js +118 -0
  443. package/dist/ui/checkbox.d.ts +4 -0
  444. package/dist/ui/checkbox.js +11 -0
  445. package/dist/ui/collapsible.d.ts +5 -0
  446. package/dist/ui/collapsible.js +5 -0
  447. package/dist/ui/combobox.d.ts +24 -0
  448. package/dist/ui/combobox.js +55 -0
  449. package/dist/ui/command.d.ts +80 -0
  450. package/dist/ui/command.js +29 -0
  451. package/dist/ui/dialog.d.ts +19 -0
  452. package/dist/ui/dialog.js +58 -0
  453. package/dist/ui/dropdown-menu.d.ts +27 -0
  454. package/dist/ui/dropdown-menu.js +33 -0
  455. package/dist/ui/field-context.d.ts +4 -0
  456. package/dist/ui/field-context.js +6 -0
  457. package/dist/ui/field.d.ts +3 -0
  458. package/dist/ui/field.js +8 -0
  459. package/dist/ui/icon-action.d.ts +3 -0
  460. package/dist/ui/icon-action.js +8 -0
  461. package/dist/ui/index.d.ts +32 -0
  462. package/dist/ui/index.js +32 -0
  463. package/dist/ui/input.d.ts +3 -0
  464. package/dist/ui/input.js +11 -0
  465. package/dist/ui/label.d.ts +5 -0
  466. package/dist/ui/label.js +15 -0
  467. package/dist/ui/multi-combobox.d.ts +18 -0
  468. package/dist/ui/multi-combobox.js +40 -0
  469. package/dist/ui/popover.d.ts +9 -0
  470. package/dist/ui/popover.js +12 -0
  471. package/dist/ui/scroll-area.d.ts +5 -0
  472. package/dist/ui/scroll-area.js +9 -0
  473. package/dist/ui/scroll-shadow.d.ts +8 -0
  474. package/dist/ui/scroll-shadow.js +57 -0
  475. package/dist/ui/select.d.ts +13 -0
  476. package/dist/ui/select.js +31 -0
  477. package/dist/ui/separator.d.ts +4 -0
  478. package/dist/ui/separator.js +7 -0
  479. package/dist/ui/sheet.d.ts +25 -0
  480. package/dist/ui/sheet.js +40 -0
  481. package/dist/ui/sidebar.d.ts +65 -0
  482. package/dist/ui/sidebar.js +207 -0
  483. package/dist/ui/skeleton.d.ts +2 -0
  484. package/dist/ui/skeleton.js +6 -0
  485. package/dist/ui/sonner.d.ts +5 -0
  486. package/dist/ui/sonner.js +13 -0
  487. package/dist/ui/switch.d.ts +4 -0
  488. package/dist/ui/switch.js +7 -0
  489. package/dist/ui/table.d.ts +12 -0
  490. package/dist/ui/table.js +24 -0
  491. package/dist/ui/tabs.d.ts +7 -0
  492. package/dist/ui/tabs.js +12 -0
  493. package/dist/ui/textarea.d.ts +3 -0
  494. package/dist/ui/textarea.js +11 -0
  495. package/dist/ui/tooltip.d.ts +7 -0
  496. package/dist/ui/tooltip.js +11 -0
  497. package/package.json +80 -0
  498. package/themes/TOKENS.md +57 -0
  499. package/themes/default.css +60 -0
@@ -0,0 +1,20 @@
1
+ export declare const PAGE_SIZES: readonly [10, 25, 50, 100];
2
+ export interface PaginationLabels {
3
+ perPage: string;
4
+ showing: (from: number, to: number, total: number) => string;
5
+ pageOf: (page: number, pages: number) => string;
6
+ previous: string;
7
+ next: string;
8
+ }
9
+ export declare const englishPaginationLabels: PaginationLabels;
10
+ export declare function TablePagination({ page, totalPages, pageSize, total, from, to, onPage, onPageSize, labels, }: {
11
+ page: number;
12
+ totalPages: number;
13
+ pageSize: number;
14
+ total: number;
15
+ from: number;
16
+ to: number;
17
+ onPage: (page: number) => void;
18
+ onPageSize: (size: number) => void;
19
+ labels?: PaginationLabels;
20
+ }): import("react").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ChevronLeft, ChevronRight } from "lucide-react";
3
+ import { Button } from "../../ui/button.js";
4
+ import { Combobox } from "../../ui/combobox.js";
5
+ export const PAGE_SIZES = [10, 25, 50, 100];
6
+ export const englishPaginationLabels = {
7
+ perPage: "Per page",
8
+ showing: (from, to, total) => `Showing ${from}–${to} of ${total}`,
9
+ pageOf: (page, pages) => `Page ${page} of ${pages}`,
10
+ previous: "Previous",
11
+ next: "Next",
12
+ };
13
+ export function TablePagination({ page, totalPages, pageSize, total, from, to, onPage, onPageSize, labels = englishPaginationLabels, }) {
14
+ return (_jsxs("div", { className: "mt-4 flex flex-col gap-3 border-t border-border pt-4 sm:flex-row sm:items-center sm:justify-between", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2 text-sm text-foreground", children: [_jsx("span", { className: "font-medium", children: labels.perPage }), _jsx(Combobox, { value: String(pageSize), onValueChange: (value) => onPageSize(Number(value)), ariaLabel: labels.perPage, className: "h-8 w-[80px]", options: PAGE_SIZES.map((size) => ({ value: String(size), label: String(size) })) }), _jsx("span", { className: "hidden text-muted-foreground sm:inline", children: labels.showing(from, to, total) })] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: labels.pageOf(page, totalPages) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", className: "gap-1 rounded-md", disabled: page <= 1, onClick: () => onPage(page - 1), children: [_jsx(ChevronLeft, { className: "size-4" }), " ", labels.previous] }), _jsxs(Button, { variant: "default", size: "sm", className: "gap-1 rounded-md", disabled: page >= totalPages, onClick: () => onPage(page + 1), children: [labels.next, " ", _jsx(ChevronRight, { className: "size-4" })] })] })] })] }));
15
+ }
@@ -0,0 +1,5 @@
1
+ export { QueueKpiCard } from "./queue-kpi-card";
2
+ export type { QueueTone } from "./queue-kpi-card";
3
+ export { QueueKpiRow } from "./queue-kpi-row";
4
+ export type { QueueCard } from "./queue-kpi-row";
5
+ export { NextActionCell } from "./next-action-cell";
@@ -0,0 +1,3 @@
1
+ export { QueueKpiCard } from "./queue-kpi-card.js";
2
+ export { QueueKpiRow } from "./queue-kpi-row.js";
3
+ export { NextActionCell } from "./next-action-cell.js";
@@ -0,0 +1,5 @@
1
+ export declare function NextActionCell({ label, muted, className, }: {
2
+ label: string;
3
+ muted?: boolean;
4
+ className?: string;
5
+ }): import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ArrowRight } from "lucide-react";
3
+ import { cn } from "../../lib/class-names.js";
4
+ export function NextActionCell({ label, muted, className, }) {
5
+ if (muted) {
6
+ return (_jsx("span", { className: cn("text-xs whitespace-nowrap text-muted-foreground", className), children: label }));
7
+ }
8
+ return (_jsxs("span", { className: cn("inline-flex items-center gap-1 text-xs font-medium whitespace-nowrap text-brand-dark", className), children: [label, _jsx(ArrowRight, { className: "size-3.5 shrink-0", "aria-hidden": true })] }));
9
+ }
@@ -0,0 +1,19 @@
1
+ import type { ComponentType } from "react";
2
+ export type QueueTone = "warning" | "success" | "danger" | "neutral";
3
+ export declare function QueueKpiCard({ label, description, count, amount, tone, icon: Icon, to, search, onSelect, active, }: {
4
+ label: string;
5
+ description: string;
6
+ /** Already formatted by the host, so the core stays free of locale helpers. */
7
+ count: string;
8
+ amount: string;
9
+ tone: QueueTone;
10
+ icon: ComponentType<{
11
+ className?: string;
12
+ }>;
13
+ /** Link target, for a page that keeps its filter in the URL. */
14
+ to?: string;
15
+ search?: Record<string, unknown>;
16
+ /** Used instead of `to` where the filter is local component state. */
17
+ onSelect?: () => void;
18
+ active?: boolean;
19
+ }): import("react").JSX.Element;
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Link } from "@tanstack/react-router";
3
+ import { cn } from "../../lib/class-names.js";
4
+ const TONE_NUMBER = {
5
+ warning: "text-warning",
6
+ success: "text-success",
7
+ danger: "text-danger",
8
+ neutral: "text-foreground",
9
+ };
10
+ const TONE_ICON = {
11
+ warning: "bg-warning-soft text-warning",
12
+ success: "bg-success-soft text-success",
13
+ danger: "bg-danger-soft text-danger",
14
+ neutral: "bg-muted text-muted-foreground",
15
+ };
16
+ const TONE_RULE = {
17
+ warning: "bg-warning",
18
+ success: "bg-success",
19
+ danger: "bg-danger",
20
+ neutral: "bg-border",
21
+ };
22
+ export function QueueKpiCard({ label, description, count, amount, tone, icon: Icon, to, search, onSelect, active, }) {
23
+ const content = (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: cn("grid size-7 shrink-0 place-items-center rounded-lg", TONE_ICON[tone]), children: _jsx(Icon, { className: "size-3.5" }) }), _jsx("span", { className: "min-w-0 truncate text-xs font-semibold text-foreground", children: label })] }), _jsxs("div", { className: "mt-1.5 flex items-baseline gap-2", children: [_jsx("span", { className: cn("text-2xl font-bold tabular-nums", TONE_NUMBER[tone]), children: count }), _jsx("span", { className: "min-w-0 truncate text-xs text-muted-foreground", children: amount })] }), _jsx("p", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: description }), !active && (_jsx("span", { className: cn("absolute inset-x-0 bottom-0 h-0.5", TONE_RULE[tone]), "aria-hidden": true }))] }));
24
+ const cardClassName = cn("relative flex min-w-0 flex-col overflow-hidden rounded-xl border px-3 pt-2.5 pb-2 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", active
25
+ ? "border-brand-dark bg-brand-tint ring-1 ring-brand-dark"
26
+ : "border-border bg-card hover:border-brand-dark/30 hover:bg-brand-tint/40");
27
+ if (onSelect) {
28
+ return (_jsx("button", { type: "button", onClick: onSelect, "aria-pressed": active, className: cardClassName, children: content }));
29
+ }
30
+ return (_jsx(Link, { to: to ?? "", search: search, "aria-pressed": active, className: cardClassName, children: content }));
31
+ }
@@ -0,0 +1,22 @@
1
+ import type { ComponentType } from "react";
2
+ import { type QueueTone } from "./queue-kpi-card";
3
+ export interface QueueCard {
4
+ key: string;
5
+ label: string;
6
+ description: string;
7
+ count: string;
8
+ amount: string;
9
+ tone: QueueTone;
10
+ icon: ComponentType<{
11
+ className?: string;
12
+ }>;
13
+ to?: string;
14
+ search?: Record<string, unknown>;
15
+ onSelect?: () => void;
16
+ active?: boolean;
17
+ }
18
+ export declare function QueueKpiRow({ cards, loading, className, }: {
19
+ cards: QueueCard[];
20
+ loading?: boolean;
21
+ className?: string;
22
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Skeleton } from "../../ui/skeleton.js";
3
+ import { cn } from "../../lib/class-names.js";
4
+ import { QueueKpiCard } from "./queue-kpi-card.js";
5
+ export function QueueKpiRow({ cards, loading, className, }) {
6
+ if (loading) {
7
+ return (_jsx("div", { className: cn("grid gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5", className), children: Array.from({ length: 5 }, (_, i) => (_jsx(Skeleton, { className: "h-44 w-full rounded-xl" }, i))) }));
8
+ }
9
+ if (cards.length === 0)
10
+ return null;
11
+ return (_jsx("div", { className: cn("grid gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5", className), children: cards.map(({ key, ...card }) => (_jsx(QueueKpiCard, { ...card }, key))) }));
12
+ }
@@ -0,0 +1,25 @@
1
+ import type { NotificationItem } from "./types";
2
+ export declare function sortBySeverity(items: NotificationItem[]): NotificationItem[];
3
+ /** One row of compact alert chips, worst first, capped at `max`; the rest hide behind "see all". */
4
+ export declare function AlertStrip({ items, max, seeAllLabel, seeAllTo, onItemClick, onDismiss, dismissLabel, className, }: {
5
+ items: NotificationItem[];
6
+ max?: number;
7
+ /** Omitted where the strip can never overflow, e.g. a fixed pair of configuration warnings. */
8
+ seeAllLabel?: string;
9
+ seeAllTo?: string;
10
+ /** Fired when a chip is followed: the host acknowledges that item at its current count. */
11
+ onItemClick?: (item: NotificationItem) => void;
12
+ /** Renders a small close button per chip: discard without visiting the screen. */
13
+ onDismiss?: (item: NotificationItem) => void;
14
+ dismissLabel?: string;
15
+ className?: string;
16
+ }): import("react").JSX.Element | null;
17
+ export declare function AlertList({ items, emptyText, onItemClick, isRead, readLabel, className, }: {
18
+ items: NotificationItem[];
19
+ emptyText: string;
20
+ onItemClick?: (item: NotificationItem) => void;
21
+ /** Whether an item was already acknowledged; read rows are dimmed and labelled. */
22
+ isRead?: (item: NotificationItem) => boolean;
23
+ readLabel?: string;
24
+ className?: string;
25
+ }): import("react").JSX.Element;
@@ -0,0 +1,66 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment } from "react";
3
+ import { Link } from "@tanstack/react-router";
4
+ import { ArrowRight, ChevronRight, CircleAlert, Info, TriangleAlert, X } from "lucide-react";
5
+ import { cn } from "../../lib/class-names.js";
6
+ import { HighlightedText } from "./highlight.js";
7
+ const TONE_CHIP = {
8
+ default: "border-brand-soft bg-brand-wash text-brand-dark hover:border-brand",
9
+ warn: "border-amber-200 bg-amber-50 text-amber-900 hover:border-amber-300",
10
+ danger: "border-red-200 bg-red-50 text-red-800 hover:border-red-300",
11
+ };
12
+ /** Count pill per tone, same palette the bell rows use. */
13
+ const TONE_BADGE = {
14
+ default: "bg-brand-wash text-brand-dark",
15
+ warn: "bg-amber-100 text-amber-800",
16
+ danger: "bg-red-100 text-red-700",
17
+ };
18
+ const TONE_ORDER = { danger: 0, warn: 1, default: 2 };
19
+ export function sortBySeverity(items) {
20
+ return [...items].sort((a, b) => TONE_ORDER[a.tone ?? "default"] - TONE_ORDER[b.tone ?? "default"]);
21
+ }
22
+ const TONE_ICON = {
23
+ default: Info,
24
+ warn: TriangleAlert,
25
+ danger: CircleAlert,
26
+ };
27
+ const TONE_ICON_CLS = {
28
+ default: "text-brand",
29
+ warn: "text-amber-600",
30
+ danger: "text-red-600",
31
+ };
32
+ function ToneIcon({ tone, icon, }) {
33
+ const Icon = icon ?? TONE_ICON[tone];
34
+ return _jsx(Icon, { className: cn("size-4 shrink-0", TONE_ICON_CLS[tone]), "aria-hidden": true });
35
+ }
36
+ /** One row of compact alert chips, worst first, capped at `max`; the rest hide behind "see all". */
37
+ export function AlertStrip({ items, max = 3, seeAllLabel, seeAllTo, onItemClick, onDismiss, dismissLabel, className, }) {
38
+ if (items.length === 0)
39
+ return null;
40
+ const sorted = sortBySeverity(items);
41
+ const shown = sorted.slice(0, max);
42
+ const rest = sorted.length - shown.length;
43
+ return (
44
+ // ONE ALERT PER LINE, ALL THE SAME WIDTH. Side by side the chips competed for the same glance
45
+ // and each was cut to a fragment. Stacked, each gets a line of its own. w-fit sizes the column
46
+ // to its WIDEST row and the rows then stretch to fill it, so the block reads as one set of
47
+ // cards with a straight right edge rather than a ragged staircase of different widths.
48
+ _jsxs("div", { className: cn("flex w-fit max-w-full flex-col items-stretch gap-1.5", className), children: [shown.map((item) => {
49
+ const tone = item.tone ?? "default";
50
+ return (_jsxs("div", { className: cn("flex min-w-0 items-center rounded-lg border transition-colors", TONE_CHIP[tone]), children: [_jsxs(Link, { to: item.link.to, search: item.link.search, hash: item.link.hash, onClick: () => onItemClick?.(item), className: cn("flex min-w-0 flex-1 items-center gap-2 rounded-lg py-2 pl-3 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onDismiss ? "pr-1" : "pr-3"), children: [_jsx(ToneIcon, { tone: tone, icon: item.icon }), _jsx("span", { className: "min-w-0 text-[13px] leading-snug font-medium", children: _jsx(HighlightedText, { text: item.message ?? item.label, highlight: item.highlight }) }), _jsx(ChevronRight, { className: "size-4 shrink-0 opacity-50", "aria-hidden": true })] }), onDismiss && (_jsx("button", { type: "button", "aria-label": dismissLabel, title: dismissLabel, onClick: () => onDismiss(item), className: "mr-1.5 cursor-pointer rounded-md p-1 opacity-50 transition-opacity hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(X, { className: "size-3.5", "aria-hidden": true }) }))] }, item.key));
51
+ }), rest > 0 && seeAllTo && (_jsxs(Link, { to: seeAllTo, className: "flex items-center gap-1 self-start rounded-lg px-1 py-0.5 text-[13px] font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: [seeAllLabel, " (+", rest, ")", _jsx(ArrowRight, { className: "size-3.5", "aria-hidden": true })] }))] }));
52
+ }
53
+ export function AlertList({ items, emptyText, onItemClick, isRead, readLabel, className, }) {
54
+ if (items.length === 0) {
55
+ return _jsx("div", { className: cn("py-6 text-sm text-muted-foreground", className), children: emptyText });
56
+ }
57
+ const sorted = sortBySeverity(items);
58
+ const unread = sorted.filter((item) => !(isRead?.(item) ?? false));
59
+ const read = sorted.filter((item) => isRead?.(item) ?? false);
60
+ const ordered = [...unread, ...read];
61
+ return (_jsx("div", { className: cn("divide-y divide-border overflow-hidden rounded-xl border border-border bg-card", className), children: ordered.map((item, index) => {
62
+ const tone = item.tone ?? "default";
63
+ const isReadRow = index >= unread.length;
64
+ return (_jsxs(Fragment, { children: [index === unread.length && unread.length > 0 && readLabel && (_jsx("div", { className: "bg-muted/40 px-4 py-1.5 text-[11px] font-medium tracking-wide text-muted-foreground uppercase", children: readLabel })), _jsxs(Link, { to: item.link.to, search: item.link.search, hash: item.link.hash, onClick: () => onItemClick?.(item), className: "flex items-start gap-3 px-4 py-3 transition-colors hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset", children: [_jsx("span", { className: cn("mt-0.5 shrink-0", isReadRow && "opacity-40"), children: _jsx(ToneIcon, { tone: tone, icon: item.icon }) }), _jsx("span", { className: cn("min-w-0 flex-1 text-sm leading-snug", isReadRow ? "text-muted-foreground" : "font-medium text-foreground"), children: _jsx(HighlightedText, { text: item.message ?? item.label, highlight: item.highlight }) }), (item.atLabel || item.dateLabel) && (_jsxs("span", { className: "shrink-0 text-right text-xs leading-tight text-muted-foreground", children: [item.atLabel && _jsx("span", { className: "block", children: item.atLabel }), item.dateLabel && (_jsx("span", { className: "block text-muted-foreground/70 tabular-nums", children: item.dateLabel }))] })), !item.message && (_jsx("span", { className: cn("inline-flex h-5 min-w-5 shrink-0 items-center justify-center rounded-full px-1.5 text-xs font-semibold tabular-nums", isReadRow ? "bg-muted text-muted-foreground" : TONE_BADGE[tone]), children: item.count }))] })] }, item.key));
65
+ }) }));
66
+ }
@@ -0,0 +1,14 @@
1
+ import type { NotificationItem } from "./types";
2
+ export declare function NotificationBell({ items, unseenCount, onOpened, onItemClick, title, emptyText, ariaLabel, seeAllLabel, seeAllTo, }: {
3
+ items: NotificationItem[];
4
+ unseenCount: number;
5
+ onOpened: () => void;
6
+ /** Fired when a row is followed: the host acknowledges that item at its current count. */
7
+ onItemClick?: (item: NotificationItem) => void;
8
+ title: string;
9
+ emptyText: string;
10
+ ariaLabel: string;
11
+ /** Way out of the dropdown into the full list. Both required to render the footer link. */
12
+ seeAllLabel?: string;
13
+ seeAllTo?: string;
14
+ }): import("react").JSX.Element;
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Link } from "@tanstack/react-router";
3
+ import { ArrowRight, Bell } from "lucide-react";
4
+ import { Button } from "../../ui/button.js";
5
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "../../ui/dropdown-menu.js";
6
+ import { cn } from "../../lib/class-names.js";
7
+ const TONE_CLS = {
8
+ default: "bg-brand-wash text-brand-dark",
9
+ warn: "bg-amber-100 text-amber-800",
10
+ danger: "bg-red-100 text-red-700",
11
+ };
12
+ export function NotificationBell({ items, unseenCount, onOpened, onItemClick, title, emptyText, ariaLabel, seeAllLabel, seeAllTo, }) {
13
+ return (_jsxs(DropdownMenu, { modal: false, onOpenChange: (open) => {
14
+ if (open)
15
+ onOpened();
16
+ }, children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": ariaLabel, className: "relative text-muted-foreground hover:text-foreground", children: [_jsx(Bell, { className: "size-4.5" }), unseenCount > 0 && (_jsx("span", { className: "absolute -top-0.5 -right-0.5 flex h-4 min-w-4 items-center justify-center rounded-full bg-destructive px-1 text-[0.62rem] font-semibold tabular-nums text-white", children: unseenCount > 99 ? "99+" : unseenCount }))] }) }), _jsxs(DropdownMenuContent, { align: "end", sideOffset: 10, collisionPadding: 12, className: cn("min-w-72 max-w-[calc(100vw-2rem)] overflow-visible border-t-4 border-t-primary shadow-xl", "relative before:absolute before:right-5 before:h-0 before:w-0 before:content-['']", "data-[side=bottom]:before:-top-2 data-[side=bottom]:before:border-x-8 data-[side=bottom]:before:border-b-8 data-[side=bottom]:before:border-x-transparent data-[side=bottom]:before:border-b-primary", "data-[side=top]:before:-bottom-2 data-[side=top]:before:border-x-8 data-[side=top]:before:border-t-8 data-[side=top]:before:border-x-transparent data-[side=top]:before:border-t-primary"), children: [_jsx(DropdownMenuLabel, { children: title }), _jsx(DropdownMenuSeparator, {}), items.length === 0 ? (_jsx("div", { className: "px-2 py-3 text-sm text-muted-foreground", children: emptyText })) : (items.map((item) => (_jsx(DropdownMenuItem, { asChild: true, className: "cursor-pointer", children: _jsxs(Link, { to: item.link.to, search: item.link.search, onClick: () => onItemClick?.(item), children: [_jsx("span", { className: "min-w-0 flex-1 truncate text-sm", title: item.label, children: item.label }), _jsx("span", { className: cn("ml-2 inline-flex h-5 min-w-5 shrink-0 items-center justify-center rounded-full px-1.5 text-xs font-medium tabular-nums", TONE_CLS[item.tone ?? "default"]), children: item.count })] }) }, item.key)))), seeAllLabel && seeAllTo && (_jsxs(_Fragment, { children: [_jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuItem, { asChild: true, className: "cursor-pointer", children: _jsxs(Link, { to: seeAllTo, className: "justify-between text-sm font-medium", children: [seeAllLabel, _jsx(ArrowRight, { className: "size-3.5 opacity-60", "aria-hidden": true })] }) })] }))] })] }));
17
+ }
@@ -0,0 +1,4 @@
1
+ export declare function HighlightedText({ text, highlight }: {
2
+ text: string;
3
+ highlight?: string;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export function HighlightedText({ text, highlight }) {
3
+ const at = highlight ? text.indexOf(highlight) : -1;
4
+ if (!highlight || at < 0)
5
+ return _jsx(_Fragment, { children: text });
6
+ return (_jsxs(_Fragment, { children: [text.slice(0, at), _jsx("strong", { className: "font-semibold", children: highlight }), text.slice(at + highlight.length)] }));
7
+ }
@@ -0,0 +1,7 @@
1
+ export * from "./types";
2
+ export { HighlightedText } from "./highlight";
3
+ export { NotificationBell } from "./bell";
4
+ export { AlertStrip, AlertList, sortBySeverity } from "./alerts";
5
+ export { useNotificationAcks } from "./use-notification-acks";
6
+ export { ReminderDialog, englishReminderDialogLabels } from "./reminder-dialog";
7
+ export type { ReminderDialogLabels } from "./reminder-dialog";
@@ -0,0 +1,6 @@
1
+ export * from "./types.js";
2
+ export { HighlightedText } from "./highlight.js";
3
+ export { NotificationBell } from "./bell.js";
4
+ export { AlertStrip, AlertList, sortBySeverity } from "./alerts.js";
5
+ export { useNotificationAcks } from "./use-notification-acks.js";
6
+ export { ReminderDialog, englishReminderDialogLabels } from "./reminder-dialog.js";
@@ -0,0 +1,24 @@
1
+ import type { ReminderRecipient } from "../../adapters/notifications";
2
+ export interface ReminderDialogLabels {
3
+ title: string;
4
+ description: string;
5
+ recipient: string;
6
+ recipientPlaceholder: string;
7
+ note: string;
8
+ notePlaceholder: string;
9
+ send: string;
10
+ sending: string;
11
+ sent: (recipientName: string) => string;
12
+ failed: string;
13
+ }
14
+ export declare const englishReminderDialogLabels: ReminderDialogLabels;
15
+ export declare function ReminderDialog({ recipients, sendReminder, open, onOpenChange, labels, }: {
16
+ recipients: ReminderRecipient[];
17
+ sendReminder: (input: {
18
+ recipientUserId: string;
19
+ note?: string;
20
+ }) => Promise<void>;
21
+ open: boolean;
22
+ onOpenChange: (open: boolean) => void;
23
+ labels?: ReminderDialogLabels;
24
+ }): import("react").JSX.Element;
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Loader2 } from "lucide-react";
4
+ import { toast } from "sonner";
5
+ import { Button } from "../../ui/button.js";
6
+ import { Combobox } from "../../ui/combobox.js";
7
+ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "../../ui/dialog.js";
8
+ import { Label } from "../../ui/label.js";
9
+ import { Textarea } from "../../ui/textarea.js";
10
+ import { readableErrorMessage } from "../feedback/query-states.js";
11
+ export const englishReminderDialogLabels = {
12
+ title: "Remind a person",
13
+ description: "Sends the person a direct reminder into their notifications.",
14
+ recipient: "Recipient",
15
+ recipientPlaceholder: "Choose a person",
16
+ note: "Note (optional)",
17
+ notePlaceholder: "e.g. Please approve today.",
18
+ send: "Send reminder",
19
+ sending: "Sending …",
20
+ sent: (recipientName) => `Reminder sent to ${recipientName}.`,
21
+ failed: "The reminder could not be sent.",
22
+ };
23
+ export function ReminderDialog({ recipients, sendReminder, open, onOpenChange, labels = englishReminderDialogLabels, }) {
24
+ const [recipientId, setRecipientId] = useState("");
25
+ const [note, setNote] = useState("");
26
+ const [isSending, setIsSending] = useState(false);
27
+ const recipientName = recipients.find((r) => r.value === recipientId)?.label ?? "";
28
+ function reset() {
29
+ setRecipientId("");
30
+ setNote("");
31
+ }
32
+ async function send() {
33
+ setIsSending(true);
34
+ try {
35
+ await sendReminder({ recipientUserId: recipientId, note: note.trim() || undefined });
36
+ toast.success(labels.sent(recipientName));
37
+ onOpenChange(false);
38
+ reset();
39
+ }
40
+ catch (error) {
41
+ toast.error(labels.failed, { description: readableErrorMessage(error, "") });
42
+ }
43
+ finally {
44
+ setIsSending(false);
45
+ }
46
+ }
47
+ return (_jsx(Dialog, { open: open, onOpenChange: (nextOpen) => {
48
+ if (isSending)
49
+ return;
50
+ onOpenChange(nextOpen);
51
+ if (!nextOpen)
52
+ reset();
53
+ }, children: _jsxs(DialogContent, { className: "sm:max-w-md", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: labels.title }), _jsx(DialogDescription, { children: labels.description })] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { children: labels.recipient }), _jsx(Combobox, { value: recipientId, onValueChange: setRecipientId, options: recipients, placeholder: labels.recipientPlaceholder })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "reminder-note", children: labels.note }), _jsx(Textarea, { id: "reminder-note", value: note, onChange: (event) => setNote(event.target.value), placeholder: labels.notePlaceholder, rows: 3 })] })] }), _jsx(DialogFooter, { children: _jsxs(Button, { disabled: !recipientId || isSending, onClick: send, children: [isSending && _jsx(Loader2, { className: "size-4 animate-spin" }), isSending ? labels.sending : labels.send] }) })] }) }));
54
+ }
@@ -0,0 +1,27 @@
1
+ import type { ComponentType } from "react";
2
+ export type NotificationTone = "default" | "warn" | "danger";
3
+ export interface NotificationItem {
4
+ key: string;
5
+ /** Short name of the thing ("Overdue invoices"). Used where a count pill sits beside it. */
6
+ label: string;
7
+ message?: string;
8
+ count: number;
9
+ tone?: NotificationTone;
10
+ ack?: {
11
+ key: string;
12
+ value: number;
13
+ };
14
+ passive?: boolean;
15
+ highlight?: string;
16
+ at?: string;
17
+ atLabel?: string;
18
+ dateLabel?: string;
19
+ icon?: ComponentType<{
20
+ className?: string;
21
+ }>;
22
+ link: {
23
+ to: string;
24
+ search?: Record<string, unknown>;
25
+ hash?: string;
26
+ };
27
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { NotificationItem } from "./types";
2
+ import type { AckStore } from "../../adapters/notifications";
3
+ export declare function useNotificationAcks(items: NotificationItem[], store: AckStore): {
4
+ visible: NotificationItem[];
5
+ isAcknowledged: (item: NotificationItem) => boolean;
6
+ acknowledge: (item: NotificationItem) => void;
7
+ };
@@ -0,0 +1,37 @@
1
+ import { useEffect, useState } from "react";
2
+ // Hides an item once acknowledged, until its count grows past the acknowledged value.
3
+ // Items with an `ack` marker use that key and value instead of their own key and count.
4
+ export function useNotificationAcks(items, store) {
5
+ const [localAcked, setLocalAcked] = useState(null);
6
+ const acked = localAcked ?? store.acked;
7
+ useEffect(() => {
8
+ const lowered = {};
9
+ for (const item of items) {
10
+ if (item.ack)
11
+ continue;
12
+ const ackedCount = acked[item.key];
13
+ if (ackedCount !== undefined && item.count < ackedCount)
14
+ lowered[item.key] = item.count;
15
+ }
16
+ if (Object.keys(lowered).length > 0)
17
+ setLocalAcked({ ...acked, ...lowered });
18
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19
+ }, [items]);
20
+ const ackKey = (item) => item.ack?.key ?? item.key;
21
+ const ackValue = (item) => item.ack?.value ?? item.count;
22
+ const isAcknowledged = (item) => {
23
+ if (item.passive)
24
+ return true;
25
+ const ackedValue = acked[ackKey(item)];
26
+ return ackedValue !== undefined && ackValue(item) <= ackedValue;
27
+ };
28
+ return {
29
+ visible: items.filter((item) => !isAcknowledged(item)),
30
+ isAcknowledged,
31
+ acknowledge: (item) => {
32
+ const next = { ...acked, [ackKey(item)]: ackValue(item) };
33
+ setLocalAcked(next);
34
+ store.save(next);
35
+ },
36
+ };
37
+ }
@@ -0,0 +1,7 @@
1
+ import { type Crumb, type ShellNavEntry } from "./types";
2
+ export declare function buildCrumbs({ nav, pathname, homeLabel, staticLeafLabels, }: {
3
+ nav: ShellNavEntry[];
4
+ pathname: string;
5
+ homeLabel: string;
6
+ staticLeafLabels?: Record<string, string>;
7
+ }): Crumb[];
@@ -0,0 +1,38 @@
1
+ import { isShellGroup } from "./types.js";
2
+ export function buildCrumbs({ nav, pathname, homeLabel, staticLeafLabels = {}, }) {
3
+ if (pathname === "/")
4
+ return [{ label: homeLabel }];
5
+ const segments = pathname.split("/").filter(Boolean);
6
+ const base = `/${segments[0]}`;
7
+ const crumbs = [{ label: homeLabel, to: "/" }];
8
+ let page;
9
+ for (const entry of nav) {
10
+ if (isShellGroup(entry)) {
11
+ const child = entry.items.find((c) => c.to === base);
12
+ if (child) {
13
+ crumbs.push({ label: entry.label, to: entry.items[0]?.to });
14
+ page = child;
15
+ break;
16
+ }
17
+ }
18
+ else if (entry.to === base && entry.to !== "/") {
19
+ page = entry;
20
+ break;
21
+ }
22
+ }
23
+ const isLeafPage = segments.length === 1;
24
+ if (page) {
25
+ crumbs.push({ label: page.label, to: isLeafPage ? undefined : page.to });
26
+ }
27
+ else {
28
+ crumbs.push({
29
+ label: staticLeafLabels[segments[0]] ?? segments[0],
30
+ to: isLeafPage ? undefined : base,
31
+ });
32
+ }
33
+ if (!isLeafPage) {
34
+ const leaf = segments[segments.length - 1];
35
+ crumbs.push({ label: staticLeafLabels[leaf] ?? decodeURIComponent(leaf) });
36
+ }
37
+ return crumbs;
38
+ }
@@ -0,0 +1,3 @@
1
+ export { Shell, ShellFooterGroup, ShellRailMenu, useShellLeafLabel, type ShellProps } from "./shell";
2
+ export { buildCrumbs } from "./breadcrumbs";
3
+ export { isShellGroup, type Crumb, type ShellBadge, type ShellNavEntry, type ShellNavGroup, type ShellNavLink, } from "./types";
@@ -0,0 +1,3 @@
1
+ export { Shell, ShellFooterGroup, ShellRailMenu, useShellLeafLabel } from "./shell.js";
2
+ export { buildCrumbs } from "./breadcrumbs.js";
3
+ export { isShellGroup, } from "./types.js";
@@ -0,0 +1,30 @@
1
+ import { type ReactNode } from "react";
2
+ import { type LucideIcon } from "lucide-react";
3
+ import { type ShellBadge, type ShellNavEntry, type ShellNavLink } from "./types";
4
+ export declare function useShellLeafLabel(label: string | null): void;
5
+ export interface ShellProps {
6
+ nav: ShellNavEntry[];
7
+ logo: ReactNode;
8
+ footer?: ReactNode;
9
+ headerActions?: ReactNode;
10
+ badges?: Record<string, ShellBadge>;
11
+ homeLabel: string;
12
+ staticLeafLabels?: Record<string, string>;
13
+ breadcrumbAriaLabel?: string;
14
+ closeLabel?: string;
15
+ children: ReactNode;
16
+ }
17
+ export declare function ShellFooterGroup({ label, icon: Icon, items, active, }: {
18
+ label: string;
19
+ icon: LucideIcon;
20
+ items: ShellNavLink[];
21
+ active: boolean;
22
+ }): import("react").JSX.Element;
23
+ export declare function ShellRailMenu({ label, icon: Icon, items, active, align, }: {
24
+ label: string;
25
+ icon: LucideIcon;
26
+ items: ShellNavLink[];
27
+ active: boolean;
28
+ align?: "start" | "end";
29
+ }): import("react").JSX.Element;
30
+ export declare function Shell({ nav, logo, footer, headerActions, badges, homeLabel, staticLeafLabels, breadcrumbAriaLabel, closeLabel, children, }: ShellProps): import("react").JSX.Element;