@multiplatform.one/frappe-ui 6.7.0 → 7.0.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 (516) hide show
  1. package/dist/cjs/FrappeAssignment.cjs +2 -0
  2. package/dist/cjs/FrappeAssignment.native.js +2 -0
  3. package/dist/cjs/FrappeAssignment.native.js.map +1 -1
  4. package/dist/cjs/FrappeCalendar.cjs +5 -7
  5. package/dist/cjs/FrappeCalendar.native.js +5 -9
  6. package/dist/cjs/FrappeCalendar.native.js.map +1 -1
  7. package/dist/cjs/FrappeChartCard.cjs +2 -0
  8. package/dist/cjs/FrappeChartCard.native.js +2 -0
  9. package/dist/cjs/FrappeChartCard.native.js.map +1 -1
  10. package/dist/cjs/FrappeDashboard.cjs +11 -22
  11. package/dist/cjs/FrappeDashboard.native.js +20 -22
  12. package/dist/cjs/FrappeDashboard.native.js.map +1 -1
  13. package/dist/cjs/FrappeForm.cjs +3 -1
  14. package/dist/cjs/FrappeForm.native.js +3 -1
  15. package/dist/cjs/FrappeForm.native.js.map +1 -1
  16. package/dist/cjs/FrappeGantt.cjs +5 -7
  17. package/dist/cjs/FrappeGantt.native.js +5 -9
  18. package/dist/cjs/FrappeGantt.native.js.map +1 -1
  19. package/dist/cjs/FrappeImageView.cjs +3 -1
  20. package/dist/cjs/FrappeImageView.native.js +3 -1
  21. package/dist/cjs/FrappeImageView.native.js.map +1 -1
  22. package/dist/cjs/FrappeKPICard.cjs +2 -0
  23. package/dist/cjs/FrappeKPICard.native.js +2 -0
  24. package/dist/cjs/FrappeKPICard.native.js.map +1 -1
  25. package/dist/cjs/FrappeKanban.cjs +3 -1
  26. package/dist/cjs/FrappeKanban.native.js +3 -1
  27. package/dist/cjs/FrappeKanban.native.js.map +1 -1
  28. package/dist/cjs/FrappeLikedBy.cjs +2 -0
  29. package/dist/cjs/FrappeLikedBy.native.js +2 -0
  30. package/dist/cjs/FrappeLikedBy.native.js.map +1 -1
  31. package/dist/cjs/FrappeList.cjs +3 -1
  32. package/dist/cjs/FrappeList.native.js +3 -1
  33. package/dist/cjs/FrappeList.native.js.map +1 -1
  34. package/dist/cjs/FrappeListView.cjs +6 -12
  35. package/dist/cjs/FrappeListView.native.js +13 -12
  36. package/dist/cjs/FrappeListView.native.js.map +1 -1
  37. package/dist/cjs/FrappeProvider.cjs +5 -1
  38. package/dist/cjs/FrappeProvider.native.js +5 -1
  39. package/dist/cjs/FrappeProvider.native.js.map +1 -1
  40. package/dist/cjs/FrappeReportBuilder.cjs +2 -0
  41. package/dist/cjs/FrappeReportBuilder.native.js +2 -0
  42. package/dist/cjs/FrappeReportBuilder.native.js.map +1 -1
  43. package/dist/cjs/FrappeReportView.cjs +23 -45
  44. package/dist/cjs/FrappeReportView.native.js +35 -50
  45. package/dist/cjs/FrappeReportView.native.js.map +1 -1
  46. package/dist/cjs/FrappeTable.cjs +105 -31
  47. package/dist/cjs/FrappeTable.native.js +140 -42
  48. package/dist/cjs/FrappeTable.native.js.map +1 -1
  49. package/dist/cjs/FrappeTreeView.cjs +3 -1
  50. package/dist/cjs/FrappeTreeView.native.js +3 -1
  51. package/dist/cjs/FrappeTreeView.native.js.map +1 -1
  52. package/dist/cjs/SyncErrorNotice.cjs +76 -0
  53. package/dist/cjs/SyncErrorNotice.native.js +92 -0
  54. package/dist/cjs/SyncErrorNotice.native.js.map +1 -0
  55. package/dist/cjs/commentActions.cjs +120 -0
  56. package/dist/cjs/commentActions.native.js +129 -0
  57. package/dist/cjs/commentActions.native.js.map +1 -0
  58. package/dist/cjs/components/attachments.cjs +2 -0
  59. package/dist/cjs/components/attachments.native.js +2 -0
  60. package/dist/cjs/components/attachments.native.js.map +1 -1
  61. package/dist/cjs/components/tags.cjs +5 -0
  62. package/dist/cjs/components/tags.native.js +5 -0
  63. package/dist/cjs/components/tags.native.js.map +1 -1
  64. package/dist/cjs/components/timeline.cjs +29 -2
  65. package/dist/cjs/components/timeline.native.js +33 -2
  66. package/dist/cjs/components/timeline.native.js.map +1 -1
  67. package/dist/cjs/desk/DeskFormSidebar.cjs +2 -0
  68. package/dist/cjs/desk/DeskFormSidebar.native.js +2 -0
  69. package/dist/cjs/desk/DeskFormSidebar.native.js.map +1 -1
  70. package/dist/cjs/fieldRegistry.cjs +2 -0
  71. package/dist/cjs/fieldRegistry.native.js +2 -0
  72. package/dist/cjs/fieldRegistry.native.js.map +1 -1
  73. package/dist/cjs/fields/Date/index.cjs +71 -7
  74. package/dist/cjs/fields/Date/index.native.js +325 -37
  75. package/dist/cjs/fields/Date/index.native.js.map +1 -1
  76. package/dist/cjs/fields/Date/types.cjs +18 -0
  77. package/dist/cjs/fields/Date/types.native.js +21 -0
  78. package/dist/cjs/fields/Date/types.native.js.map +1 -0
  79. package/dist/cjs/fields/Date/wire.cjs +4 -8
  80. package/dist/cjs/fields/Date/wire.native.js +4 -11
  81. package/dist/cjs/fields/Date/wire.native.js.map +1 -1
  82. package/dist/cjs/fields/DynamicLink.cjs +2 -0
  83. package/dist/cjs/fields/DynamicLink.native.js +2 -0
  84. package/dist/cjs/fields/DynamicLink.native.js.map +1 -1
  85. package/dist/cjs/fields/FileUpload.cjs +2 -0
  86. package/dist/cjs/fields/FileUpload.native.js +2 -0
  87. package/dist/cjs/fields/FileUpload.native.js.map +1 -1
  88. package/dist/cjs/fields/TableMultiSelect.cjs +6 -1
  89. package/dist/cjs/fields/TableMultiSelect.native.js +6 -1
  90. package/dist/cjs/fields/TableMultiSelect.native.js.map +1 -1
  91. package/dist/cjs/frappeStoryTarget.cjs +88 -0
  92. package/dist/cjs/frappeStoryTarget.native.js +100 -0
  93. package/dist/cjs/frappeStoryTarget.native.js.map +1 -1
  94. package/dist/cjs/frappeUsers.cjs +2 -0
  95. package/dist/cjs/frappeUsers.native.js +2 -0
  96. package/dist/cjs/frappeUsers.native.js.map +1 -1
  97. package/dist/cjs/index.cjs +17 -4
  98. package/dist/cjs/index.native.js +17 -4
  99. package/dist/cjs/index.native.js.map +1 -1
  100. package/dist/cjs/liveErrors.cjs +5 -1
  101. package/dist/cjs/liveErrors.native.js +5 -1
  102. package/dist/cjs/liveErrors.native.js.map +1 -1
  103. package/dist/cjs/useFrappeAggregate.cjs +13 -1
  104. package/dist/cjs/useFrappeAggregate.native.js +14 -1
  105. package/dist/cjs/useFrappeAggregate.native.js.map +1 -1
  106. package/dist/cjs/useFrappeFacets.cjs +329 -0
  107. package/dist/cjs/useFrappeFacets.native.js +632 -0
  108. package/dist/cjs/useFrappeFacets.native.js.map +1 -0
  109. package/dist/esm/FrappeAssignment.mjs +2 -0
  110. package/dist/esm/FrappeAssignment.mjs.map +1 -1
  111. package/dist/esm/FrappeAssignment.native.js +2 -0
  112. package/dist/esm/FrappeAssignment.native.js.map +1 -1
  113. package/dist/esm/FrappeCalendar.mjs +6 -8
  114. package/dist/esm/FrappeCalendar.mjs.map +1 -1
  115. package/dist/esm/FrappeCalendar.native.js +6 -10
  116. package/dist/esm/FrappeCalendar.native.js.map +1 -1
  117. package/dist/esm/FrappeChartCard.mjs +2 -0
  118. package/dist/esm/FrappeChartCard.mjs.map +1 -1
  119. package/dist/esm/FrappeChartCard.native.js +2 -0
  120. package/dist/esm/FrappeChartCard.native.js.map +1 -1
  121. package/dist/esm/FrappeDashboard.mjs +12 -19
  122. package/dist/esm/FrappeDashboard.mjs.map +1 -1
  123. package/dist/esm/FrappeDashboard.native.js +23 -21
  124. package/dist/esm/FrappeDashboard.native.js.map +1 -1
  125. package/dist/esm/FrappeForm.mjs +3 -1
  126. package/dist/esm/FrappeForm.mjs.map +1 -1
  127. package/dist/esm/FrappeForm.native.js +3 -1
  128. package/dist/esm/FrappeForm.native.js.map +1 -1
  129. package/dist/esm/FrappeGantt.mjs +6 -8
  130. package/dist/esm/FrappeGantt.mjs.map +1 -1
  131. package/dist/esm/FrappeGantt.native.js +6 -10
  132. package/dist/esm/FrappeGantt.native.js.map +1 -1
  133. package/dist/esm/FrappeImageView.mjs +3 -1
  134. package/dist/esm/FrappeImageView.mjs.map +1 -1
  135. package/dist/esm/FrappeImageView.native.js +3 -1
  136. package/dist/esm/FrappeImageView.native.js.map +1 -1
  137. package/dist/esm/FrappeKPICard.mjs +2 -0
  138. package/dist/esm/FrappeKPICard.mjs.map +1 -1
  139. package/dist/esm/FrappeKPICard.native.js +2 -0
  140. package/dist/esm/FrappeKPICard.native.js.map +1 -1
  141. package/dist/esm/FrappeKanban.mjs +3 -1
  142. package/dist/esm/FrappeKanban.mjs.map +1 -1
  143. package/dist/esm/FrappeKanban.native.js +3 -1
  144. package/dist/esm/FrappeKanban.native.js.map +1 -1
  145. package/dist/esm/FrappeLikedBy.mjs +2 -0
  146. package/dist/esm/FrappeLikedBy.mjs.map +1 -1
  147. package/dist/esm/FrappeLikedBy.native.js +2 -0
  148. package/dist/esm/FrappeLikedBy.native.js.map +1 -1
  149. package/dist/esm/FrappeList.mjs +3 -1
  150. package/dist/esm/FrappeList.mjs.map +1 -1
  151. package/dist/esm/FrappeList.native.js +3 -1
  152. package/dist/esm/FrappeList.native.js.map +1 -1
  153. package/dist/esm/FrappeListView.mjs +7 -13
  154. package/dist/esm/FrappeListView.mjs.map +1 -1
  155. package/dist/esm/FrappeListView.native.js +15 -14
  156. package/dist/esm/FrappeListView.native.js.map +1 -1
  157. package/dist/esm/FrappeProvider.mjs +5 -1
  158. package/dist/esm/FrappeProvider.mjs.map +1 -1
  159. package/dist/esm/FrappeProvider.native.js +5 -1
  160. package/dist/esm/FrappeProvider.native.js.map +1 -1
  161. package/dist/esm/FrappeReportBuilder.mjs +2 -0
  162. package/dist/esm/FrappeReportBuilder.mjs.map +1 -1
  163. package/dist/esm/FrappeReportBuilder.native.js +2 -0
  164. package/dist/esm/FrappeReportBuilder.native.js.map +1 -1
  165. package/dist/esm/FrappeReportView.mjs +26 -49
  166. package/dist/esm/FrappeReportView.mjs.map +1 -1
  167. package/dist/esm/FrappeReportView.native.js +38 -54
  168. package/dist/esm/FrappeReportView.native.js.map +1 -1
  169. package/dist/esm/FrappeTable.mjs +107 -33
  170. package/dist/esm/FrappeTable.mjs.map +1 -1
  171. package/dist/esm/FrappeTable.native.js +142 -44
  172. package/dist/esm/FrappeTable.native.js.map +1 -1
  173. package/dist/esm/FrappeTreeView.mjs +3 -1
  174. package/dist/esm/FrappeTreeView.mjs.map +1 -1
  175. package/dist/esm/FrappeTreeView.native.js +3 -1
  176. package/dist/esm/FrappeTreeView.native.js.map +1 -1
  177. package/dist/esm/SyncErrorNotice.mjs +51 -0
  178. package/dist/esm/SyncErrorNotice.mjs.map +1 -0
  179. package/dist/esm/SyncErrorNotice.native.js +53 -0
  180. package/dist/esm/SyncErrorNotice.native.js.map +1 -0
  181. package/dist/esm/commentActions.mjs +95 -0
  182. package/dist/esm/commentActions.mjs.map +1 -0
  183. package/dist/esm/commentActions.native.js +101 -0
  184. package/dist/esm/commentActions.native.js.map +1 -0
  185. package/dist/esm/components/attachments.mjs +2 -0
  186. package/dist/esm/components/attachments.mjs.map +1 -1
  187. package/dist/esm/components/attachments.native.js +2 -0
  188. package/dist/esm/components/attachments.native.js.map +1 -1
  189. package/dist/esm/components/tags.mjs +5 -0
  190. package/dist/esm/components/tags.mjs.map +1 -1
  191. package/dist/esm/components/tags.native.js +5 -0
  192. package/dist/esm/components/tags.native.js.map +1 -1
  193. package/dist/esm/components/timeline.mjs +31 -4
  194. package/dist/esm/components/timeline.mjs.map +1 -1
  195. package/dist/esm/components/timeline.native.js +35 -4
  196. package/dist/esm/components/timeline.native.js.map +1 -1
  197. package/dist/esm/desk/DeskFormSidebar.mjs +2 -0
  198. package/dist/esm/desk/DeskFormSidebar.mjs.map +1 -1
  199. package/dist/esm/desk/DeskFormSidebar.native.js +2 -0
  200. package/dist/esm/desk/DeskFormSidebar.native.js.map +1 -1
  201. package/dist/esm/fieldRegistry.mjs +2 -0
  202. package/dist/esm/fieldRegistry.mjs.map +1 -1
  203. package/dist/esm/fieldRegistry.native.js +2 -0
  204. package/dist/esm/fieldRegistry.native.js.map +1 -1
  205. package/dist/esm/fields/Date/index.mjs +73 -9
  206. package/dist/esm/fields/Date/index.mjs.map +1 -1
  207. package/dist/esm/fields/Date/index.native.js +315 -38
  208. package/dist/esm/fields/Date/index.native.js.map +1 -1
  209. package/dist/esm/fields/Date/types.mjs +2 -0
  210. package/dist/esm/fields/Date/types.mjs.map +1 -0
  211. package/dist/esm/fields/Date/types.native.js +2 -0
  212. package/dist/esm/fields/Date/types.native.js.map +1 -0
  213. package/dist/esm/fields/Date/wire.mjs +4 -8
  214. package/dist/esm/fields/Date/wire.mjs.map +1 -1
  215. package/dist/esm/fields/Date/wire.native.js +4 -11
  216. package/dist/esm/fields/Date/wire.native.js.map +1 -1
  217. package/dist/esm/fields/DynamicLink.mjs +2 -0
  218. package/dist/esm/fields/DynamicLink.mjs.map +1 -1
  219. package/dist/esm/fields/DynamicLink.native.js +2 -0
  220. package/dist/esm/fields/DynamicLink.native.js.map +1 -1
  221. package/dist/esm/fields/FileUpload.mjs +2 -0
  222. package/dist/esm/fields/FileUpload.mjs.map +1 -1
  223. package/dist/esm/fields/FileUpload.native.js +2 -0
  224. package/dist/esm/fields/FileUpload.native.js.map +1 -1
  225. package/dist/esm/fields/TableMultiSelect.mjs +7 -2
  226. package/dist/esm/fields/TableMultiSelect.mjs.map +1 -1
  227. package/dist/esm/fields/TableMultiSelect.native.js +7 -2
  228. package/dist/esm/fields/TableMultiSelect.native.js.map +1 -1
  229. package/dist/esm/frappeStoryTarget.mjs +88 -2
  230. package/dist/esm/frappeStoryTarget.mjs.map +1 -1
  231. package/dist/esm/frappeStoryTarget.native.js +100 -2
  232. package/dist/esm/frappeStoryTarget.native.js.map +1 -1
  233. package/dist/esm/frappeUsers.mjs +2 -0
  234. package/dist/esm/frappeUsers.mjs.map +1 -1
  235. package/dist/esm/frappeUsers.native.js +2 -0
  236. package/dist/esm/frappeUsers.native.js.map +1 -1
  237. package/dist/esm/index.mjs +7 -3
  238. package/dist/esm/index.mjs.map +1 -1
  239. package/dist/esm/index.native.js +7 -3
  240. package/dist/esm/index.native.js.map +1 -1
  241. package/dist/esm/liveErrors.mjs +5 -1
  242. package/dist/esm/liveErrors.mjs.map +1 -1
  243. package/dist/esm/liveErrors.native.js +5 -1
  244. package/dist/esm/liveErrors.native.js.map +1 -1
  245. package/dist/esm/useFrappeAggregate.mjs +13 -1
  246. package/dist/esm/useFrappeAggregate.mjs.map +1 -1
  247. package/dist/esm/useFrappeAggregate.native.js +14 -1
  248. package/dist/esm/useFrappeAggregate.native.js.map +1 -1
  249. package/dist/esm/useFrappeFacets.mjs +299 -0
  250. package/dist/esm/useFrappeFacets.mjs.map +1 -0
  251. package/dist/esm/useFrappeFacets.native.js +599 -0
  252. package/dist/esm/useFrappeFacets.native.js.map +1 -0
  253. package/dist/jsx/FrappeAssignment.mjs +2 -0
  254. package/dist/jsx/FrappeAssignment.mjs.map +1 -1
  255. package/dist/jsx/FrappeAssignment.native.js +2 -0
  256. package/dist/jsx/FrappeAssignment.native.js.map +1 -1
  257. package/dist/jsx/FrappeCalendar.mjs +6 -8
  258. package/dist/jsx/FrappeCalendar.mjs.map +1 -1
  259. package/dist/jsx/FrappeCalendar.native.js +5 -9
  260. package/dist/jsx/FrappeCalendar.native.js.map +1 -1
  261. package/dist/jsx/FrappeChartCard.mjs +2 -0
  262. package/dist/jsx/FrappeChartCard.mjs.map +1 -1
  263. package/dist/jsx/FrappeChartCard.native.js +2 -0
  264. package/dist/jsx/FrappeChartCard.native.js.map +1 -1
  265. package/dist/jsx/FrappeDashboard.mjs +12 -19
  266. package/dist/jsx/FrappeDashboard.mjs.map +1 -1
  267. package/dist/jsx/FrappeDashboard.native.js +20 -22
  268. package/dist/jsx/FrappeDashboard.native.js.map +1 -1
  269. package/dist/jsx/FrappeForm.mjs +3 -1
  270. package/dist/jsx/FrappeForm.mjs.map +1 -1
  271. package/dist/jsx/FrappeForm.native.js +3 -1
  272. package/dist/jsx/FrappeForm.native.js.map +1 -1
  273. package/dist/jsx/FrappeGantt.mjs +6 -8
  274. package/dist/jsx/FrappeGantt.mjs.map +1 -1
  275. package/dist/jsx/FrappeGantt.native.js +5 -9
  276. package/dist/jsx/FrappeGantt.native.js.map +1 -1
  277. package/dist/jsx/FrappeImageView.mjs +3 -1
  278. package/dist/jsx/FrappeImageView.mjs.map +1 -1
  279. package/dist/jsx/FrappeImageView.native.js +3 -1
  280. package/dist/jsx/FrappeImageView.native.js.map +1 -1
  281. package/dist/jsx/FrappeKPICard.mjs +2 -0
  282. package/dist/jsx/FrappeKPICard.mjs.map +1 -1
  283. package/dist/jsx/FrappeKPICard.native.js +2 -0
  284. package/dist/jsx/FrappeKPICard.native.js.map +1 -1
  285. package/dist/jsx/FrappeKanban.mjs +3 -1
  286. package/dist/jsx/FrappeKanban.mjs.map +1 -1
  287. package/dist/jsx/FrappeKanban.native.js +3 -1
  288. package/dist/jsx/FrappeKanban.native.js.map +1 -1
  289. package/dist/jsx/FrappeLikedBy.mjs +2 -0
  290. package/dist/jsx/FrappeLikedBy.mjs.map +1 -1
  291. package/dist/jsx/FrappeLikedBy.native.js +2 -0
  292. package/dist/jsx/FrappeLikedBy.native.js.map +1 -1
  293. package/dist/jsx/FrappeList.mjs +3 -1
  294. package/dist/jsx/FrappeList.mjs.map +1 -1
  295. package/dist/jsx/FrappeList.native.js +3 -1
  296. package/dist/jsx/FrappeList.native.js.map +1 -1
  297. package/dist/jsx/FrappeListView.mjs +7 -13
  298. package/dist/jsx/FrappeListView.mjs.map +1 -1
  299. package/dist/jsx/FrappeListView.native.js +13 -12
  300. package/dist/jsx/FrappeListView.native.js.map +1 -1
  301. package/dist/jsx/FrappeProvider.mjs +5 -1
  302. package/dist/jsx/FrappeProvider.mjs.map +1 -1
  303. package/dist/jsx/FrappeProvider.native.js +5 -1
  304. package/dist/jsx/FrappeProvider.native.js.map +1 -1
  305. package/dist/jsx/FrappeReportBuilder.mjs +2 -0
  306. package/dist/jsx/FrappeReportBuilder.mjs.map +1 -1
  307. package/dist/jsx/FrappeReportBuilder.native.js +2 -0
  308. package/dist/jsx/FrappeReportBuilder.native.js.map +1 -1
  309. package/dist/jsx/FrappeReportView.mjs +26 -49
  310. package/dist/jsx/FrappeReportView.mjs.map +1 -1
  311. package/dist/jsx/FrappeReportView.native.js +35 -50
  312. package/dist/jsx/FrappeReportView.native.js.map +1 -1
  313. package/dist/jsx/FrappeTable.mjs +107 -33
  314. package/dist/jsx/FrappeTable.mjs.map +1 -1
  315. package/dist/jsx/FrappeTable.native.js +140 -42
  316. package/dist/jsx/FrappeTable.native.js.map +1 -1
  317. package/dist/jsx/FrappeTreeView.mjs +3 -1
  318. package/dist/jsx/FrappeTreeView.mjs.map +1 -1
  319. package/dist/jsx/FrappeTreeView.native.js +3 -1
  320. package/dist/jsx/FrappeTreeView.native.js.map +1 -1
  321. package/dist/jsx/SyncErrorNotice.mjs +51 -0
  322. package/dist/jsx/SyncErrorNotice.mjs.map +1 -0
  323. package/dist/jsx/SyncErrorNotice.native.js +92 -0
  324. package/dist/jsx/SyncErrorNotice.native.js.map +1 -0
  325. package/dist/jsx/commentActions.mjs +95 -0
  326. package/dist/jsx/commentActions.mjs.map +1 -0
  327. package/dist/jsx/commentActions.native.js +129 -0
  328. package/dist/jsx/commentActions.native.js.map +1 -0
  329. package/dist/jsx/components/attachments.mjs +2 -0
  330. package/dist/jsx/components/attachments.mjs.map +1 -1
  331. package/dist/jsx/components/attachments.native.js +2 -0
  332. package/dist/jsx/components/attachments.native.js.map +1 -1
  333. package/dist/jsx/components/tags.mjs +5 -0
  334. package/dist/jsx/components/tags.mjs.map +1 -1
  335. package/dist/jsx/components/tags.native.js +5 -0
  336. package/dist/jsx/components/tags.native.js.map +1 -1
  337. package/dist/jsx/components/timeline.mjs +31 -4
  338. package/dist/jsx/components/timeline.mjs.map +1 -1
  339. package/dist/jsx/components/timeline.native.js +33 -2
  340. package/dist/jsx/components/timeline.native.js.map +1 -1
  341. package/dist/jsx/desk/DeskFormSidebar.mjs +2 -0
  342. package/dist/jsx/desk/DeskFormSidebar.mjs.map +1 -1
  343. package/dist/jsx/desk/DeskFormSidebar.native.js +2 -0
  344. package/dist/jsx/desk/DeskFormSidebar.native.js.map +1 -1
  345. package/dist/jsx/fieldRegistry.mjs +2 -0
  346. package/dist/jsx/fieldRegistry.mjs.map +1 -1
  347. package/dist/jsx/fieldRegistry.native.js +2 -0
  348. package/dist/jsx/fieldRegistry.native.js.map +1 -1
  349. package/dist/jsx/fields/Date/index.mjs +73 -9
  350. package/dist/jsx/fields/Date/index.mjs.map +1 -1
  351. package/dist/jsx/fields/Date/index.native.js +325 -37
  352. package/dist/jsx/fields/Date/index.native.js.map +1 -1
  353. package/dist/jsx/fields/Date/types.mjs +2 -0
  354. package/dist/jsx/fields/Date/types.mjs.map +1 -0
  355. package/dist/jsx/fields/Date/types.native.js +21 -0
  356. package/dist/jsx/fields/Date/types.native.js.map +1 -0
  357. package/dist/jsx/fields/Date/wire.mjs +4 -8
  358. package/dist/jsx/fields/Date/wire.mjs.map +1 -1
  359. package/dist/jsx/fields/Date/wire.native.js +4 -11
  360. package/dist/jsx/fields/Date/wire.native.js.map +1 -1
  361. package/dist/jsx/fields/DynamicLink.mjs +2 -0
  362. package/dist/jsx/fields/DynamicLink.mjs.map +1 -1
  363. package/dist/jsx/fields/DynamicLink.native.js +2 -0
  364. package/dist/jsx/fields/DynamicLink.native.js.map +1 -1
  365. package/dist/jsx/fields/FileUpload.mjs +2 -0
  366. package/dist/jsx/fields/FileUpload.mjs.map +1 -1
  367. package/dist/jsx/fields/FileUpload.native.js +2 -0
  368. package/dist/jsx/fields/FileUpload.native.js.map +1 -1
  369. package/dist/jsx/fields/TableMultiSelect.mjs +7 -2
  370. package/dist/jsx/fields/TableMultiSelect.mjs.map +1 -1
  371. package/dist/jsx/fields/TableMultiSelect.native.js +6 -1
  372. package/dist/jsx/fields/TableMultiSelect.native.js.map +1 -1
  373. package/dist/jsx/frappeStoryTarget.mjs +88 -2
  374. package/dist/jsx/frappeStoryTarget.mjs.map +1 -1
  375. package/dist/jsx/frappeStoryTarget.native.js +100 -0
  376. package/dist/jsx/frappeStoryTarget.native.js.map +1 -1
  377. package/dist/jsx/frappeUsers.mjs +2 -0
  378. package/dist/jsx/frappeUsers.mjs.map +1 -1
  379. package/dist/jsx/frappeUsers.native.js +2 -0
  380. package/dist/jsx/frappeUsers.native.js.map +1 -1
  381. package/dist/jsx/index.js +7 -3
  382. package/dist/jsx/index.js.map +1 -1
  383. package/dist/jsx/index.mjs +7 -3
  384. package/dist/jsx/index.mjs.map +1 -1
  385. package/dist/jsx/index.native.js +17 -4
  386. package/dist/jsx/index.native.js.map +1 -1
  387. package/dist/jsx/liveErrors.mjs +5 -1
  388. package/dist/jsx/liveErrors.mjs.map +1 -1
  389. package/dist/jsx/liveErrors.native.js +5 -1
  390. package/dist/jsx/liveErrors.native.js.map +1 -1
  391. package/dist/jsx/useFrappeAggregate.mjs +13 -1
  392. package/dist/jsx/useFrappeAggregate.mjs.map +1 -1
  393. package/dist/jsx/useFrappeAggregate.native.js +14 -1
  394. package/dist/jsx/useFrappeAggregate.native.js.map +1 -1
  395. package/dist/jsx/useFrappeFacets.mjs +299 -0
  396. package/dist/jsx/useFrappeFacets.mjs.map +1 -0
  397. package/dist/jsx/useFrappeFacets.native.js +632 -0
  398. package/dist/jsx/useFrappeFacets.native.js.map +1 -0
  399. package/package.json +20 -20
  400. package/src/FormSidebar.stories.tsx +88 -10
  401. package/src/FrappeAssignment.tsx +2 -0
  402. package/src/FrappeCalendar.tsx +12 -7
  403. package/src/FrappeChartCard.tsx +9 -2
  404. package/src/FrappeDashboard.spec.tsx +95 -0
  405. package/src/FrappeDashboard.tsx +20 -41
  406. package/src/FrappeForm.stories.tsx +53 -46
  407. package/src/FrappeForm.tsx +11 -1
  408. package/src/FrappeGantt.tsx +12 -7
  409. package/src/FrappeImageView.tsx +11 -1
  410. package/src/FrappeKPICard.stories.tsx +4 -1
  411. package/src/FrappeKPICard.tsx +2 -0
  412. package/src/FrappeKanban.tsx +4 -0
  413. package/src/FrappeLikedBy.stories.tsx +26 -10
  414. package/src/FrappeLikedBy.tsx +2 -0
  415. package/src/FrappeList.tsx +11 -1
  416. package/src/FrappeListView.spec.tsx +144 -0
  417. package/src/FrappeListView.tsx +11 -23
  418. package/src/FrappeProvider.tsx +30 -2
  419. package/src/FrappeReportBuilder.tsx +2 -0
  420. package/src/FrappeReportView.spec.tsx +140 -16
  421. package/src/FrappeReportView.stories.tsx +12 -6
  422. package/src/FrappeReportView.tsx +62 -61
  423. package/src/FrappeTable.keepRows.spec.tsx +200 -0
  424. package/src/FrappeTable.retryStorm.spec.tsx +140 -0
  425. package/src/FrappeTable.spec.tsx +222 -0
  426. package/src/FrappeTable.tsx +211 -54
  427. package/src/FrappeTreeView.tsx +11 -1
  428. package/src/SyncErrorNotice.spec.tsx +60 -0
  429. package/src/SyncErrorNotice.tsx +81 -0
  430. package/src/commentActions.ts +157 -0
  431. package/src/components/attachments.tsx +2 -0
  432. package/src/components/tags.tsx +14 -1
  433. package/src/components/timeline.optimistic.spec.tsx +106 -0
  434. package/src/components/timeline.tsx +36 -4
  435. package/src/desk/DeskFormSidebar.tsx +2 -0
  436. package/src/fieldRegistry.ts +2 -0
  437. package/src/fields/Date/index.native.tsx +410 -0
  438. package/src/fields/Date/index.tsx +138 -57
  439. package/src/fields/Date/nativePresentation.spec.tsx +251 -0
  440. package/src/fields/Date/typeParity.spec.tsx +480 -0
  441. package/src/fields/Date/types.ts +53 -0
  442. package/src/fields/Date/wire.spec.ts +63 -1
  443. package/src/fields/Date/wire.ts +17 -17
  444. package/src/fields/DynamicLink.tsx +2 -0
  445. package/src/fields/FileUpload.tsx +2 -0
  446. package/src/fields/TableMultiSelect.tsx +6 -3
  447. package/src/frappeStoryTarget.tsx +104 -1
  448. package/src/frappeUsers.ts +2 -0
  449. package/src/index.spec.ts +62 -0
  450. package/src/index.ts +36 -2
  451. package/src/liveErrors.spec.ts +50 -0
  452. package/src/liveErrors.ts +11 -1
  453. package/src/useFrappeAggregate.ts +20 -1
  454. package/src/useFrappeFacets.spec.tsx +436 -0
  455. package/src/useFrappeFacets.ts +568 -0
  456. package/types/FrappeAssignment.d.ts.map +1 -1
  457. package/types/FrappeCalendar.d.ts.map +1 -1
  458. package/types/FrappeChartCard.d.ts +1 -2
  459. package/types/FrappeChartCard.d.ts.map +1 -1
  460. package/types/FrappeDashboard.d.ts +0 -1
  461. package/types/FrappeDashboard.d.ts.map +1 -1
  462. package/types/FrappeForm.d.ts.map +1 -1
  463. package/types/FrappeGantt.d.ts.map +1 -1
  464. package/types/FrappeKPICard.d.ts.map +1 -1
  465. package/types/FrappeKanban.d.ts.map +1 -1
  466. package/types/FrappeLikedBy.d.ts.map +1 -1
  467. package/types/FrappeList.d.ts.map +1 -1
  468. package/types/FrappeListView.d.ts.map +1 -1
  469. package/types/FrappeProvider.d.ts +18 -1
  470. package/types/FrappeProvider.d.ts.map +1 -1
  471. package/types/FrappeReportBuilder.d.ts.map +1 -1
  472. package/types/FrappeReportView.d.ts +22 -15
  473. package/types/FrappeReportView.d.ts.map +1 -1
  474. package/types/FrappeTable.d.ts +21 -2
  475. package/types/FrappeTable.d.ts.map +1 -1
  476. package/types/FrappeTreeView.d.ts.map +1 -1
  477. package/types/SyncErrorNotice.d.ts +38 -0
  478. package/types/SyncErrorNotice.d.ts.map +1 -0
  479. package/types/commentActions.d.ts +46 -0
  480. package/types/commentActions.d.ts.map +1 -0
  481. package/types/components/attachments.d.ts.map +1 -1
  482. package/types/components/tags.d.ts.map +1 -1
  483. package/types/components/timeline.d.ts.map +1 -1
  484. package/types/desk/DeskFormSidebar.d.ts.map +1 -1
  485. package/types/fieldRegistry.d.ts.map +1 -1
  486. package/types/fields/Date/index.d.ts +22 -12
  487. package/types/fields/Date/index.d.ts.map +1 -1
  488. package/types/fields/Date/index.native.d.ts +14 -0
  489. package/types/fields/Date/index.native.d.ts.map +1 -0
  490. package/types/fields/Date/types.d.ts +27 -0
  491. package/types/fields/Date/types.d.ts.map +1 -0
  492. package/types/fields/Date/wire.d.ts +13 -9
  493. package/types/fields/Date/wire.d.ts.map +1 -1
  494. package/types/fields/DynamicLink.d.ts.map +1 -1
  495. package/types/fields/FileUpload.d.ts.map +1 -1
  496. package/types/fields/TableMultiSelect.d.ts.map +1 -1
  497. package/types/frappeStoryTarget.d.ts +19 -1
  498. package/types/frappeStoryTarget.d.ts.map +1 -1
  499. package/types/frappeUsers.d.ts.map +1 -1
  500. package/types/index.d.ts +6 -2
  501. package/types/index.d.ts.map +1 -1
  502. package/types/liveErrors.d.ts +4 -0
  503. package/types/liveErrors.d.ts.map +1 -1
  504. package/types/useFrappeAggregate.d.ts +4 -0
  505. package/types/useFrappeAggregate.d.ts.map +1 -1
  506. package/types/useFrappeFacets.d.ts +143 -0
  507. package/types/useFrappeFacets.d.ts.map +1 -0
  508. package/dist/cjs/fields/Date/date.native.js +0 -277
  509. package/dist/cjs/fields/Date/date.native.js.map +0 -1
  510. package/dist/esm/fields/Date/date.native.js +0 -238
  511. package/dist/esm/fields/Date/date.native.js.map +0 -1
  512. package/dist/jsx/fields/Date/date.native.js +0 -277
  513. package/dist/jsx/fields/Date/date.native.js.map +0 -1
  514. package/src/fields/Date/date.native.tsx +0 -299
  515. package/types/fields/Date/date.native.d.ts +0 -19
  516. package/types/fields/Date/date.native.d.ts.map +0 -1
@@ -57,6 +57,8 @@ export function FileUpload({
57
57
  ? {
58
58
  baseURL: finalBaseURL,
59
59
  socketPort: config?.socketPort,
60
+ siteName: config?.siteName,
61
+ socketBaseURL: config?.socketBaseURL,
60
62
  auth: auth ?? config?.auth,
61
63
  syncOptions: config?.syncOptions,
62
64
  fixtures: config?.fixtures,
@@ -2,7 +2,7 @@ import { PopoverContent } from "@multiplatform.one/components";
2
2
  import { useFrappeCollection, useLiveQuery } from "@multiplatform.one/frappe";
3
3
  import { Button, Skeleton } from "@multiplatform.one/forms";
4
4
  import { CaretDownIcon, CheckIcon, XIcon } from "@phosphor-icons/react";
5
- import { useResolvedKnobs } from "@multiplatform.one/theme";
5
+ import { menuRowFrame, useResolvedKnobs } from "@multiplatform.one/theme";
6
6
  import { useMemo, useState } from "react";
7
7
  import { useTranslation } from "react-i18next";
8
8
  import { Checkbox, Label, ListItem, Popover, ScrollView, Text, XStack, YStack } from "tamagui";
@@ -61,6 +61,8 @@ export function TableMultiSelect({
61
61
  ? {
62
62
  baseURL: finalBaseURL,
63
63
  socketPort: config?.socketPort,
64
+ siteName: config?.siteName,
65
+ socketBaseURL: config?.socketBaseURL,
64
66
  auth: auth ?? config?.auth,
65
67
  syncOptions: config?.syncOptions,
66
68
  fixtures: config?.fixtures,
@@ -132,7 +134,7 @@ export function TableMultiSelect({
132
134
  </Button>
133
135
  </Popover.Trigger>
134
136
 
135
- <PopoverContent>
137
+ <PopoverContent overflow="hidden">
136
138
  <Popover.Arrow borderWidth={1} borderColor="$borderColor" />
137
139
 
138
140
  <YStack minWidth={250} maxHeight={300}>
@@ -150,6 +152,7 @@ export function TableMultiSelect({
150
152
  return (
151
153
  <ListItem
152
154
  key={option.name}
155
+ {...menuRowFrame}
153
156
  title={displayLabel}
154
157
  size={knobProps.sizeToken}
155
158
  icon={
@@ -166,7 +169,7 @@ export function TableMultiSelect({
166
169
  </Checkbox.Indicator>
167
170
  </Checkbox>
168
171
  }
169
- hoverStyle={{ backgroundColor: "$color2" }}
172
+ hoverStyle={{ backgroundColor: "$color2", borderRadius: 0 }}
170
173
  cursor={isOptionDisabled ? "not-allowed" : "pointer"}
171
174
  opacity={isOptionDisabled ? 0.5 : 1}
172
175
  onPress={() => !isOptionDisabled && handleToggle(option.name || "")}
@@ -14,7 +14,7 @@
14
14
  * Storybook never hard-fails when the bench is down.
15
15
  */
16
16
  import type { FixtureProvider } from "@multiplatform.one/frappe";
17
- import type { ReactNode } from "react";
17
+ import { useEffect, useState, type ReactNode } from "react";
18
18
  import { FrappeProvider } from "./FrappeProvider";
19
19
 
20
20
  interface StorybookFrappeEnv {
@@ -93,3 +93,106 @@ export function FrappeStoryProvider({ children, fixtures }: FrappeStoryProviderP
93
93
  </FrappeProvider>
94
94
  );
95
95
  }
96
+
97
+ /**
98
+ * Preferred name for the live-story ToDo. Fixture stories ship a document
99
+ * under this name; the live bench usually cannot (ToDo autonames by hash and
100
+ * rejects rename), so {@link LiveToDoGate} resolves a real row when live.
101
+ */
102
+ export const LIVE_TODO_NAME = "TODO-LIVE-001";
103
+
104
+ let liveToDoPromise: Promise<string> | undefined;
105
+
106
+ async function lookupOrSeedLiveToDo(): Promise<string> {
107
+ const base = frappeStoryBaseUrl.replace(/\/$/, "");
108
+ const preferred = await fetch(`${base}/api/resource/ToDo/${encodeURIComponent(LIVE_TODO_NAME)}`);
109
+ if (preferred.ok) return LIVE_TODO_NAME;
110
+
111
+ const list = await fetch(
112
+ `${base}/api/resource/ToDo?limit_page_length=1&fields=${encodeURIComponent('["name"]')}`,
113
+ );
114
+ if (list.ok) {
115
+ const row = (await list.json())?.data?.[0]?.name;
116
+ if (typeof row === "string" && row) return row;
117
+ }
118
+
119
+ const whoRes = await fetch(`${base}/api/method/frappe.auth.get_logged_user`);
120
+ const me = whoRes.ok ? ((await whoRes.json())?.message as string | undefined) : undefined;
121
+ const created = await fetch(`${base}/api/resource/ToDo`, {
122
+ method: "POST",
123
+ headers: { "Content-Type": "application/json" },
124
+ body: JSON.stringify({
125
+ description: "MPO live-story fixture ToDo",
126
+ status: "Open",
127
+ priority: "Medium",
128
+ ...(typeof me === "string" && me && me !== "Guest" ? { allocated_to: me } : {}),
129
+ }),
130
+ });
131
+ if (!created.ok) {
132
+ throw new Error(`Could not seed a ToDo on this bench (HTTP ${created.status})`);
133
+ }
134
+ const hashName = (await created.json())?.data?.name as string | undefined;
135
+ if (!hashName) throw new Error("Bench created a ToDo without a name");
136
+ const renamed = await fetch(`${base}/api/method/frappe.client.rename_doc`, {
137
+ method: "POST",
138
+ headers: { "Content-Type": "application/json" },
139
+ body: JSON.stringify({
140
+ doctype: "ToDo",
141
+ old_name: hashName,
142
+ new_name: LIVE_TODO_NAME,
143
+ }),
144
+ });
145
+ return renamed.ok ? LIVE_TODO_NAME : hashName;
146
+ }
147
+
148
+ /**
149
+ * Resolves the ToDo the live form / sidebar / liked-by stories open.
150
+ *
151
+ * Offline (fixtures) → {@link LIVE_TODO_NAME}. Live + explicit `name` arg →
152
+ * that name (harnesses pass a real doc). Live with no arg → GET the preferred
153
+ * name, else the first readable ToDo, else create one (rename to the preferred
154
+ * name is best-effort: ToDo often forbids rename).
155
+ */
156
+ export function LiveToDoGate({
157
+ name,
158
+ children,
159
+ }: {
160
+ name?: string;
161
+ children: (resolvedName: string) => ReactNode;
162
+ }) {
163
+ const requested = name?.trim() || undefined;
164
+ const [resolved, setResolved] = useState<string | null>(
165
+ requested ?? (frappeStoriesLive ? null : LIVE_TODO_NAME),
166
+ );
167
+ const [error, setError] = useState<string | null>(null);
168
+
169
+ useEffect(() => {
170
+ if (requested) {
171
+ setResolved(requested);
172
+ setError(null);
173
+ return;
174
+ }
175
+ if (!frappeStoriesLive) {
176
+ setResolved(LIVE_TODO_NAME);
177
+ setError(null);
178
+ return;
179
+ }
180
+ let cancelled = false;
181
+ liveToDoPromise ??= lookupOrSeedLiveToDo();
182
+ liveToDoPromise
183
+ .then((value) => {
184
+ if (!cancelled) setResolved(value);
185
+ })
186
+ .catch((err: unknown) => {
187
+ liveToDoPromise = undefined;
188
+ if (!cancelled) setError(err instanceof Error ? err.message : String(err));
189
+ });
190
+ return () => {
191
+ cancelled = true;
192
+ };
193
+ }, [requested]);
194
+
195
+ if (error) return <div>{error}</div>;
196
+ if (!resolved) return <div>Resolving live ToDo…</div>;
197
+ return <>{children(resolved)}</>;
198
+ }
@@ -61,6 +61,8 @@ export function useFrappeUsers(
61
61
  ? {
62
62
  baseURL: config.baseURL,
63
63
  socketPort: config.socketPort,
64
+ siteName: config.siteName,
65
+ socketBaseURL: config.socketBaseURL,
64
66
  auth: config.auth,
65
67
  syncOptions: config.syncOptions,
66
68
  fixtures: config.fixtures,
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Guardrail for the dashboard-catalog re-export seam.
3
+ *
4
+ * The barrel used to re-export KPICard / calculateTrend /
5
+ * calculatePercentageChange / aggregateData (and the widget/chart types)
6
+ * from ./FrappeDashboard, which does not define them — it bounced them
7
+ * from @multiplatform.one/components. In the built package that bounce
8
+ * put the catalog behind FrappeDashboard.native's own components import,
9
+ * and a native-conditions consumer that narrows components (the GNOME
10
+ * shim aliases; metro with exact resolution) failed the WHOLE barrel on
11
+ * that seam before anything rendered — measured downstream 2026-08-13.
12
+ * This spec locks the fix both ways:
13
+ *
14
+ * 1. ./FrappeDashboard exports only what it defines (FrappeDashboard and
15
+ * the sanitizing ChartCard bridge) — no catalog names.
16
+ * 2. The barrel still ships the catalog, and each name IS the components
17
+ * export, not a copy and not a bounce.
18
+ */
19
+ import * as components from "@multiplatform.one/components";
20
+ import { describe, expect, it } from "vitest";
21
+ import * as dashboard from "./FrappeDashboard";
22
+ import * as barrel from "./index";
23
+
24
+ const CATALOG_VALUE_NAMES = [
25
+ "KPICard",
26
+ "calculateTrend",
27
+ "calculatePercentageChange",
28
+ "aggregateData",
29
+ ] as const;
30
+
31
+ describe("dashboard catalog seam", () => {
32
+ it("keeps ./FrappeDashboard to the names it defines", () => {
33
+ for (const name of CATALOG_VALUE_NAMES) {
34
+ expect(
35
+ (dashboard as Record<string, unknown>)[name],
36
+ `FrappeDashboard must not re-export catalog "${name}"`,
37
+ ).toBeUndefined();
38
+ }
39
+ expect(dashboard.FrappeDashboard).toBeDefined();
40
+ expect(dashboard.ChartCard, "the sanitizing ChartCard bridge is its own export").toBeDefined();
41
+ expect(
42
+ dashboard.ChartCard,
43
+ "ChartCard must be the sanitizing bridge, not the raw catalog card",
44
+ ).not.toBe(components.ChartCard);
45
+ });
46
+
47
+ it("re-exports the catalog from components directly, identically", () => {
48
+ for (const name of CATALOG_VALUE_NAMES) {
49
+ expect(
50
+ (barrel as Record<string, unknown>)[name],
51
+ `barrel must export "${name}"`,
52
+ ).toBeDefined();
53
+ expect(
54
+ (barrel as Record<string, unknown>)[name],
55
+ `barrel "${name}" must be the components export`,
56
+ ).toBe((components as Record<string, unknown>)[name]);
57
+ }
58
+ expect(barrel.ChartCard, "barrel ChartCard stays the sanitizing bridge").toBe(
59
+ dashboard.ChartCard,
60
+ );
61
+ });
62
+ });
package/src/index.ts CHANGED
@@ -81,10 +81,20 @@ export {
81
81
 
82
82
  export {
83
83
  FrappeDashboard,
84
+ ChartCard,
84
85
  type FrappeDashboardProps,
85
86
  type DashboardDataSource,
87
+ } from "./FrappeDashboard";
88
+
89
+ // The KPI/trend catalog is the components package's — re-export it from
90
+ // there, NOT through ./FrappeDashboard. The old bounce made the built
91
+ // FrappeDashboard.native module re-export names it does not define, and a
92
+ // native-conditions consumer that narrows @multiplatform.one/components
93
+ // (the GNOME shim aliases; metro with exact resolution) failed the whole
94
+ // barrel on that seam before anything rendered — measured 2026-08-13.
95
+ // One seam (components' own barrel) instead of two.
96
+ export {
86
97
  KPICard,
87
- ChartCard,
88
98
  calculateTrend,
89
99
  calculatePercentageChange,
90
100
  aggregateData,
@@ -96,7 +106,7 @@ export {
96
106
  type ChartDataPoint,
97
107
  type ChartType,
98
108
  type TrendDirection,
99
- } from "./FrappeDashboard";
109
+ } from "@multiplatform.one/components";
100
110
 
101
111
  export { FrappeKPICard, type FrappeKPICardProps, type FrappeKPIDataSource } from "./FrappeKPICard";
102
112
 
@@ -115,6 +125,22 @@ export {
115
125
  type UseFrappeAggregateResult,
116
126
  } from "./useFrappeAggregate";
117
127
 
128
+ export {
129
+ useFrappeFacets,
130
+ filtersExcludingField,
131
+ isFacetFilterActive,
132
+ toggleFacetFilter,
133
+ scrubUserFacetRows,
134
+ NO_TAGS_LABEL,
135
+ type FrappeFacetFilter,
136
+ type FrappeFacetFilters,
137
+ type FrappeFacetOption,
138
+ type FrappeFacetState,
139
+ type FrappeFacetsConnection,
140
+ type UseFrappeFacetsOptions,
141
+ type UseFrappeFacetsResult,
142
+ } from "./useFrappeFacets";
143
+
118
144
  export { FrappeImageView, type FrappeImageViewProps } from "./FrappeImageView";
119
145
  export { FrappeTreeView, type FrappeTreeViewProps } from "./FrappeTreeView";
120
146
  export {
@@ -122,6 +148,8 @@ export {
122
148
  type FrappeConnectionIndicatorProps,
123
149
  } from "./FrappeConnectionIndicator";
124
150
 
151
+ export { SyncErrorNotice, type SyncErrorNoticeProps } from "./SyncErrorNotice";
152
+
125
153
  // ---------------------------------------------------------------------------
126
154
  // Schema Form & Field Registry
127
155
  // ---------------------------------------------------------------------------
@@ -288,6 +316,11 @@ export {
288
316
  type FrappeComment,
289
317
  type FrappeVersion,
290
318
  } from "./components/timeline";
319
+ export {
320
+ useFrappeCommentActions,
321
+ type FrappeCommentActions,
322
+ type AddCommentInput,
323
+ } from "./commentActions";
291
324
 
292
325
  // ---------------------------------------------------------------------------
293
326
  // Pagination Bridge
@@ -322,6 +355,7 @@ export {
322
355
  normalizeReportRows,
323
356
  reportColumnToDataTableColumn,
324
357
  reportFieldtypeToTableField,
358
+ reportRowLabel,
325
359
  scrubFieldname,
326
360
  type FrappeReportColumn,
327
361
  type FrappeReportConnection,
@@ -0,0 +1,50 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { isPermissionError, toLiveLoadError } from "./liveErrors";
3
+
4
+ describe("isPermissionError", () => {
5
+ it("treats HTTP 403 / 401 as permission", () => {
6
+ expect(isPermissionError(Object.assign(new Error("nope"), { status: 403 }))).toBe(true);
7
+ expect(isPermissionError(Object.assign(new Error("nope"), { status: 401 }))).toBe(true);
8
+ expect(isPermissionError(Object.assign(new Error("nope"), { status: 500 }))).toBe(false);
9
+ });
10
+
11
+ it("treats a PermissionError-shaped message as permission", () => {
12
+ expect(isPermissionError(new Error("PermissionError"))).toBe(true);
13
+ expect(isPermissionError(new Error("You don't have access to Report: ToDo"))).toBe(false);
14
+ });
15
+ });
16
+
17
+ describe("toLiveLoadError", () => {
18
+ const labels = {
19
+ permissionMessage: "You do not have permission to run ToDo",
20
+ genericMessage: "Error running ToDo",
21
+ };
22
+
23
+ it("keeps a readable server sentence as detail", () => {
24
+ const err = Object.assign(new Error("You don't have access to Report: ToDo"), { status: 403 });
25
+ expect(toLiveLoadError(err, labels).message).toBe(
26
+ "You do not have permission to run ToDo: You don't have access to Report: ToDo",
27
+ );
28
+ });
29
+
30
+ it("does not append a developer-mode python traceback to permission chrome", () => {
31
+ const err = Object.assign(
32
+ new Error(
33
+ '["Traceback (most recent call last):\\n File "apps/frappe/frappe/app.py", line 120, in application',
34
+ ),
35
+ { status: 403 },
36
+ );
37
+ const normalized = toLiveLoadError(err, labels);
38
+ expect(normalized.message).toBe("You do not have permission to run ToDo");
39
+ expect(normalized.message).not.toMatch(/Traceback/);
40
+ });
41
+
42
+ it("does not append a traceback to a generic load failure either", () => {
43
+ const err = new Error(
44
+ '["Traceback (most recent call last):\\n File "apps/frappe/frappe/app.py"',
45
+ );
46
+ const normalized = toLiveLoadError(err, labels);
47
+ expect(normalized.message).toBe("Error running ToDo");
48
+ expect(normalized.message).not.toMatch(/Traceback/);
49
+ });
50
+ });
package/src/liveErrors.ts CHANGED
@@ -17,10 +17,19 @@ export function isPermissionError(error: unknown): boolean {
17
17
  return /permission|not permitted|forbidden/i.test(message);
18
18
  }
19
19
 
20
+ /** True when `detail` is a developer-mode python traceback, not a sentence. */
21
+ function isTracebackDetail(detail: string): boolean {
22
+ return /Traceback \(most recent call last\)/i.test(detail);
23
+ }
24
+
20
25
  /**
21
26
  * Normalizes an initial-sync failure into an Error with an honest,
22
27
  * user-facing message. `permissionMessage` / `genericMessage` come from the
23
28
  * caller so components keep i18n ownership.
29
+ *
30
+ * A leaked `exc` traceback (the sentence `HttpClient` used to prefer) is
31
+ * dropped rather than appended — report / list chrome must never render a
32
+ * python stack at the user. A readable server sentence is kept as detail.
24
33
  */
25
34
  export function toLiveLoadError(
26
35
  error: unknown,
@@ -28,7 +37,8 @@ export function toLiveLoadError(
28
37
  ): Error {
29
38
  const detail = error instanceof Error ? error.message : String(error ?? "");
30
39
  const lead = isPermissionError(error) ? permissionMessage : genericMessage;
31
- const message = detail && detail !== lead ? `${lead}: ${detail}` : lead;
40
+ const usable = detail && detail !== lead && !isTracebackDetail(detail) ? detail : "";
41
+ const message = usable ? `${lead}: ${usable}` : lead;
32
42
  const normalized = new Error(message);
33
43
  if (error instanceof Error && error.stack) normalized.stack = error.stack;
34
44
  return normalized;
@@ -43,6 +43,10 @@ export type FrappeAggregateOperation = "count" | "sum" | "avg" | "min" | "max";
43
43
  export interface FrappeAggregateConnection {
44
44
  baseURL: string;
45
45
  socketPort?: number;
46
+ /** Same-origin socket override (see FrappeConfig.socketBaseURL). */
47
+ socketBaseURL?: string;
48
+ /** Frappe site name — the realtime Socket.IO namespace. */
49
+ siteName?: string;
46
50
  auth?: { useToken?: boolean; token?: string | (() => string | Promise<string>); type?: string };
47
51
  syncOptions?: unknown;
48
52
  fixtures?: FixtureProvider;
@@ -256,6 +260,8 @@ export function useFrappeAggregate(
256
260
  specRef.current = spec;
257
261
  const connectionRef = useRef(connection);
258
262
  connectionRef.current = connection;
263
+ const hasSettledRef = useRef(false);
264
+ const identityRef = useRef(`${connection?.baseURL}:${spec.doctype}`);
259
265
 
260
266
  const runFetch = useCallback(async () => {
261
267
  const conn = connectionRef.current;
@@ -270,6 +276,7 @@ export function useFrappeAggregate(
270
276
  setData(result);
271
277
  setError(undefined);
272
278
  setLastUpdated(new Date());
279
+ hasSettledRef.current = true;
273
280
  } catch (err) {
274
281
  if (seq !== fetchSeq.current) return;
275
282
  setError(err instanceof Error ? err : new Error(String(err)));
@@ -294,9 +301,21 @@ export function useFrappeAggregate(
294
301
  }, []);
295
302
 
296
303
  // Initial load + reload when the query identity changes.
304
+ // After the first settle, a filter/spec change is a refetch (isStale),
305
+ // not a first load (isLoading) — the shown number stays so the list
306
+ // chrome cannot jump when the user toggles a filter.
297
307
  useEffect(() => {
298
308
  if (!enabled) return;
299
- setIsLoading(true);
309
+ const identity = `${connectionRef.current?.baseURL}:${specRef.current.doctype}`;
310
+ if (identityRef.current !== identity) {
311
+ identityRef.current = identity;
312
+ hasSettledRef.current = false;
313
+ }
314
+ if (hasSettledRef.current) {
315
+ setIsStale(true);
316
+ } else {
317
+ setIsLoading(true);
318
+ }
300
319
  setError(undefined);
301
320
  void runFetch();
302
321
  // eslint-disable-next-line react-hooks/exhaustive-deps