@modern-admin/web 0.3.3 → 0.3.5

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 (236) hide show
  1. package/dist/standalone/assets/action-component-host-CXIbN-8V.js +2 -0
  2. package/dist/standalone/assets/action-component-host-CXIbN-8V.js.br +0 -0
  3. package/dist/standalone/assets/action-component-host-CXIbN-8V.js.gz +0 -0
  4. package/dist/standalone/assets/action-component-host-CXIbN-8V.js.map +1 -0
  5. package/dist/standalone/assets/action-page-OsWfKQ6C.js +2 -0
  6. package/dist/standalone/assets/action-page-OsWfKQ6C.js.br +0 -0
  7. package/dist/standalone/assets/action-page-OsWfKQ6C.js.gz +0 -0
  8. package/dist/standalone/assets/action-page-OsWfKQ6C.js.map +1 -0
  9. package/dist/standalone/assets/{ai-assistant-widget-Dk-VvXD0.js → ai-assistant-widget-Bt4Z7Fmr.js} +2 -2
  10. package/dist/standalone/assets/ai-assistant-widget-Bt4Z7Fmr.js.br +0 -0
  11. package/dist/standalone/assets/ai-assistant-widget-Bt4Z7Fmr.js.gz +0 -0
  12. package/dist/standalone/assets/{ai-assistant-widget-Dk-VvXD0.js.map → ai-assistant-widget-Bt4Z7Fmr.js.map} +1 -1
  13. package/dist/standalone/assets/arrow-left-CI9hUPwJ.js +2 -0
  14. package/dist/standalone/assets/arrow-left-CI9hUPwJ.js.map +1 -0
  15. package/dist/standalone/assets/audit-log-page-2wuGiWg-.js +2 -0
  16. package/dist/standalone/assets/audit-log-page-2wuGiWg-.js.br +0 -0
  17. package/dist/standalone/assets/audit-log-page-2wuGiWg-.js.gz +0 -0
  18. package/dist/standalone/assets/{audit-log-page-BEC79lKy.js.map → audit-log-page-2wuGiWg-.js.map} +1 -1
  19. package/dist/standalone/assets/{calendar-Pq7dP9RH.js → calendar-BZVUWakC.js} +2 -2
  20. package/dist/standalone/assets/calendar-BZVUWakC.js.br +0 -0
  21. package/dist/standalone/assets/calendar-BZVUWakC.js.gz +0 -0
  22. package/dist/standalone/assets/{calendar-Pq7dP9RH.js.map → calendar-BZVUWakC.js.map} +1 -1
  23. package/dist/standalone/assets/chart-widget-BtJb6YXV.js +2 -0
  24. package/dist/standalone/assets/chart-widget-BtJb6YXV.js.br +0 -0
  25. package/dist/standalone/assets/chart-widget-BtJb6YXV.js.gz +0 -0
  26. package/dist/standalone/assets/{chart-widget-B7pIeDCP.js.map → chart-widget-BtJb6YXV.js.map} +1 -1
  27. package/dist/standalone/assets/circle-alert-0EyKeic4.js +2 -0
  28. package/dist/standalone/assets/circle-alert-0EyKeic4.js.map +1 -0
  29. package/dist/standalone/assets/{command-B6-wRF2R.js → command-BNF_evMy.js} +2 -2
  30. package/dist/standalone/assets/command-BNF_evMy.js.br +0 -0
  31. package/dist/standalone/assets/command-BNF_evMy.js.gz +0 -0
  32. package/dist/standalone/assets/{command-B6-wRF2R.js.map → command-BNF_evMy.js.map} +1 -1
  33. package/dist/standalone/assets/{date-picker-BAp85mMa.js → date-picker-LfbUehd1.js} +2 -2
  34. package/dist/standalone/assets/date-picker-LfbUehd1.js.br +0 -0
  35. package/dist/standalone/assets/date-picker-LfbUehd1.js.gz +0 -0
  36. package/dist/standalone/assets/{date-picker-BAp85mMa.js.map → date-picker-LfbUehd1.js.map} +1 -1
  37. package/dist/standalone/assets/{dist-CvKz-wgE.js → dist-BSbFjTlr.js} +2 -2
  38. package/dist/standalone/assets/dist-BSbFjTlr.js.br +0 -0
  39. package/dist/standalone/assets/dist-BSbFjTlr.js.gz +0 -0
  40. package/dist/standalone/assets/dist-BSbFjTlr.js.map +1 -0
  41. package/dist/standalone/assets/{dist-Dkym1-ts.js → dist-BcL2U6dT.js} +2 -2
  42. package/dist/standalone/assets/dist-BcL2U6dT.js.br +0 -0
  43. package/dist/standalone/assets/dist-BcL2U6dT.js.gz +0 -0
  44. package/dist/standalone/assets/{dist-Dkym1-ts.js.map → dist-BcL2U6dT.js.map} +1 -1
  45. package/dist/standalone/assets/edit-page-DCRB9Y_q.js +2 -0
  46. package/dist/standalone/assets/edit-page-DCRB9Y_q.js.br +0 -0
  47. package/dist/standalone/assets/edit-page-DCRB9Y_q.js.gz +0 -0
  48. package/dist/standalone/assets/{edit-page-BVwML9yD.js.map → edit-page-DCRB9Y_q.js.map} +1 -1
  49. package/dist/standalone/assets/ellipsis-lEjcTxo0.js +2 -0
  50. package/dist/standalone/assets/ellipsis-lEjcTxo0.js.map +1 -0
  51. package/dist/standalone/assets/{empty-BmE-qyE9.js → empty-DAEAjFd3.js} +2 -2
  52. package/dist/standalone/assets/empty-DAEAjFd3.js.br +0 -0
  53. package/dist/standalone/assets/empty-DAEAjFd3.js.gz +0 -0
  54. package/dist/standalone/assets/{empty-BmE-qyE9.js.map → empty-DAEAjFd3.js.map} +1 -1
  55. package/dist/standalone/assets/global-search-dialog-HMLztOho.js +2 -0
  56. package/dist/standalone/assets/global-search-dialog-HMLztOho.js.br +0 -0
  57. package/dist/standalone/assets/global-search-dialog-HMLztOho.js.gz +0 -0
  58. package/dist/standalone/assets/{global-search-dialog-C3Ri2VRv.js.map → global-search-dialog-HMLztOho.js.map} +1 -1
  59. package/dist/standalone/assets/{heavy-fields-aI_gOI6-.js → heavy-fields-ZuqfOFMv.js} +2 -2
  60. package/dist/standalone/assets/heavy-fields-ZuqfOFMv.js.br +0 -0
  61. package/dist/standalone/assets/heavy-fields-ZuqfOFMv.js.gz +0 -0
  62. package/dist/standalone/assets/{heavy-fields-aI_gOI6-.js.map → heavy-fields-ZuqfOFMv.js.map} +1 -1
  63. package/dist/standalone/assets/home-page-HmheewiP.js +3 -0
  64. package/dist/standalone/assets/home-page-HmheewiP.js.br +0 -0
  65. package/dist/standalone/assets/home-page-HmheewiP.js.gz +0 -0
  66. package/dist/standalone/assets/{home-page-Xc7HK72H.js.map → home-page-HmheewiP.js.map} +1 -1
  67. package/dist/standalone/assets/icon-registry-BV44--RL.js +2 -0
  68. package/dist/standalone/assets/icon-registry-BV44--RL.js.br +0 -0
  69. package/dist/standalone/assets/icon-registry-BV44--RL.js.gz +0 -0
  70. package/dist/standalone/assets/icon-registry-BV44--RL.js.map +1 -0
  71. package/dist/standalone/assets/{index-OvloY2cG.css → index-95cwJ2RY.css} +1 -1
  72. package/dist/standalone/assets/index-95cwJ2RY.css.br +0 -0
  73. package/dist/standalone/assets/index-95cwJ2RY.css.gz +0 -0
  74. package/dist/standalone/assets/index-t4woXGa-.js +15 -0
  75. package/dist/standalone/assets/index-t4woXGa-.js.br +0 -0
  76. package/dist/standalone/assets/index-t4woXGa-.js.gz +0 -0
  77. package/dist/standalone/assets/index-t4woXGa-.js.map +1 -0
  78. package/dist/standalone/assets/json-editor-sGw4fDoj.js +2 -0
  79. package/dist/standalone/assets/json-editor-sGw4fDoj.js.br +0 -0
  80. package/dist/standalone/assets/json-editor-sGw4fDoj.js.gz +0 -0
  81. package/dist/standalone/assets/{json-editor-DuYj4QGx.js.map → json-editor-sGw4fDoj.js.map} +1 -1
  82. package/dist/standalone/assets/property-renderer-DyCwdVkh.js +7 -0
  83. package/dist/standalone/assets/property-renderer-DyCwdVkh.js.br +0 -0
  84. package/dist/standalone/assets/property-renderer-DyCwdVkh.js.gz +0 -0
  85. package/dist/standalone/assets/property-renderer-DyCwdVkh.js.map +1 -0
  86. package/dist/standalone/assets/reference-Dfd804y3.js +2 -0
  87. package/dist/standalone/assets/reference-Dfd804y3.js.br +0 -0
  88. package/dist/standalone/assets/reference-Dfd804y3.js.gz +0 -0
  89. package/dist/standalone/assets/{reference-CbtDQb7U.js.map → reference-Dfd804y3.js.map} +1 -1
  90. package/dist/standalone/assets/refresh-cw-DHvUQTMb.js +2 -0
  91. package/dist/standalone/assets/refresh-cw-DHvUQTMb.js.map +1 -0
  92. package/dist/standalone/assets/revisions-button-DXZAh2Lu.js +2 -0
  93. package/dist/standalone/assets/revisions-button-DXZAh2Lu.js.br +0 -0
  94. package/dist/standalone/assets/revisions-button-DXZAh2Lu.js.gz +0 -0
  95. package/dist/standalone/assets/{revisions-button-hLRZGkwM.js.map → revisions-button-DXZAh2Lu.js.map} +1 -1
  96. package/dist/standalone/assets/router-wFvtgo77.js +186 -0
  97. package/dist/standalone/assets/router-wFvtgo77.js.br +0 -0
  98. package/dist/standalone/assets/router-wFvtgo77.js.gz +0 -0
  99. package/dist/standalone/assets/router-wFvtgo77.js.map +1 -0
  100. package/dist/standalone/assets/select-BWf6walM.js +2 -0
  101. package/dist/standalone/assets/select-BWf6walM.js.br +0 -0
  102. package/dist/standalone/assets/select-BWf6walM.js.gz +0 -0
  103. package/dist/standalone/assets/{select-BxTIWCco.js.map → select-BWf6walM.js.map} +1 -1
  104. package/dist/standalone/assets/settings-page-Co7sWbbL.js +2 -0
  105. package/dist/standalone/assets/settings-page-Co7sWbbL.js.br +0 -0
  106. package/dist/standalone/assets/settings-page-Co7sWbbL.js.gz +0 -0
  107. package/dist/standalone/assets/{settings-page-FHzVUo4t.js.map → settings-page-Co7sWbbL.js.map} +1 -1
  108. package/dist/standalone/assets/show-page-D-_vldWV.js +2 -0
  109. package/dist/standalone/assets/show-page-D-_vldWV.js.br +0 -0
  110. package/dist/standalone/assets/show-page-D-_vldWV.js.gz +0 -0
  111. package/dist/standalone/assets/show-page-D-_vldWV.js.map +1 -0
  112. package/dist/standalone/assets/{tabs-BrnwAET7.js → tabs-khcHka8W.js} +2 -2
  113. package/dist/standalone/assets/tabs-khcHka8W.js.br +0 -0
  114. package/dist/standalone/assets/tabs-khcHka8W.js.gz +0 -0
  115. package/dist/standalone/assets/{tabs-BrnwAET7.js.map → tabs-khcHka8W.js.map} +1 -1
  116. package/dist/standalone/assets/{zap-Be2c7_cs.js → upload-BVhXhZgn.js} +2 -2
  117. package/dist/standalone/assets/upload-BVhXhZgn.js.br +0 -0
  118. package/dist/standalone/assets/upload-BVhXhZgn.js.gz +0 -0
  119. package/dist/standalone/assets/upload-BVhXhZgn.js.map +1 -0
  120. package/dist/standalone/assets/{useQueries-CX5Gh6HV.js → useQueries-BCUhWYX4.js} +2 -2
  121. package/dist/standalone/assets/useQueries-BCUhWYX4.js.br +0 -0
  122. package/dist/standalone/assets/useQueries-BCUhWYX4.js.gz +0 -0
  123. package/dist/standalone/assets/{useQueries-CX5Gh6HV.js.map → useQueries-BCUhWYX4.js.map} +1 -1
  124. package/dist/standalone/assets/{user-directory-ZxAjN_q9.js → user-directory-9COoW6AO.js} +2 -2
  125. package/dist/standalone/assets/user-directory-9COoW6AO.js.br +0 -0
  126. package/dist/standalone/assets/user-directory-9COoW6AO.js.gz +0 -0
  127. package/dist/standalone/assets/{user-directory-ZxAjN_q9.js.map → user-directory-9COoW6AO.js.map} +1 -1
  128. package/dist/standalone/assets/{value-format-DmXCSwLn.js → value-format-CPnbnlE6.js} +2 -2
  129. package/dist/standalone/assets/value-format-CPnbnlE6.js.br +0 -0
  130. package/dist/standalone/assets/value-format-CPnbnlE6.js.gz +0 -0
  131. package/dist/standalone/assets/{value-format-DmXCSwLn.js.map → value-format-CPnbnlE6.js.map} +1 -1
  132. package/dist/standalone/assets/wand-sparkles-DWaFQeYS.js +2 -0
  133. package/dist/standalone/assets/wand-sparkles-DWaFQeYS.js.map +1 -0
  134. package/dist/standalone/assets/wizard-create-page-CFwMs8E3.js +2 -0
  135. package/dist/standalone/assets/wizard-create-page-CFwMs8E3.js.br +0 -0
  136. package/dist/standalone/assets/wizard-create-page-CFwMs8E3.js.gz +0 -0
  137. package/dist/standalone/assets/{wizard-create-page-Rh4uWxUR.js.map → wizard-create-page-CFwMs8E3.js.map} +1 -1
  138. package/dist/standalone/assets/zap-b3saQVKc.js +2 -0
  139. package/dist/standalone/assets/zap-b3saQVKc.js.map +1 -0
  140. package/dist/standalone/assets/{zod-bSPpBhsj.js → zod-BbfEBA4A.js} +2 -2
  141. package/dist/standalone/assets/zod-BbfEBA4A.js.br +0 -0
  142. package/dist/standalone/assets/zod-BbfEBA4A.js.gz +0 -0
  143. package/dist/standalone/assets/{zod-bSPpBhsj.js.map → zod-BbfEBA4A.js.map} +1 -1
  144. package/dist/standalone/index.html +8 -8
  145. package/dist/standalone/index.html.br +0 -0
  146. package/dist/standalone/index.html.gz +0 -0
  147. package/package.json +5 -5
  148. package/dist/standalone/assets/ai-assistant-widget-Dk-VvXD0.js.br +0 -0
  149. package/dist/standalone/assets/ai-assistant-widget-Dk-VvXD0.js.gz +0 -0
  150. package/dist/standalone/assets/audit-log-page-BEC79lKy.js +0 -2
  151. package/dist/standalone/assets/audit-log-page-BEC79lKy.js.br +0 -0
  152. package/dist/standalone/assets/audit-log-page-BEC79lKy.js.gz +0 -0
  153. package/dist/standalone/assets/calendar-Pq7dP9RH.js.br +0 -0
  154. package/dist/standalone/assets/calendar-Pq7dP9RH.js.gz +0 -0
  155. package/dist/standalone/assets/chart-widget-B7pIeDCP.js +0 -2
  156. package/dist/standalone/assets/chart-widget-B7pIeDCP.js.br +0 -0
  157. package/dist/standalone/assets/chart-widget-B7pIeDCP.js.gz +0 -0
  158. package/dist/standalone/assets/command-B6-wRF2R.js.br +0 -0
  159. package/dist/standalone/assets/command-B6-wRF2R.js.gz +0 -0
  160. package/dist/standalone/assets/date-picker-BAp85mMa.js.br +0 -0
  161. package/dist/standalone/assets/date-picker-BAp85mMa.js.gz +0 -0
  162. package/dist/standalone/assets/dist-CvKz-wgE.js.br +0 -0
  163. package/dist/standalone/assets/dist-CvKz-wgE.js.gz +0 -0
  164. package/dist/standalone/assets/dist-CvKz-wgE.js.map +0 -1
  165. package/dist/standalone/assets/dist-Dkym1-ts.js.br +0 -0
  166. package/dist/standalone/assets/dist-Dkym1-ts.js.gz +0 -0
  167. package/dist/standalone/assets/edit-page-BVwML9yD.js +0 -2
  168. package/dist/standalone/assets/edit-page-BVwML9yD.js.br +0 -0
  169. package/dist/standalone/assets/edit-page-BVwML9yD.js.gz +0 -0
  170. package/dist/standalone/assets/empty-BmE-qyE9.js.br +0 -0
  171. package/dist/standalone/assets/empty-BmE-qyE9.js.gz +0 -0
  172. package/dist/standalone/assets/global-search-dialog-C3Ri2VRv.js +0 -2
  173. package/dist/standalone/assets/global-search-dialog-C3Ri2VRv.js.br +0 -0
  174. package/dist/standalone/assets/global-search-dialog-C3Ri2VRv.js.gz +0 -0
  175. package/dist/standalone/assets/heavy-fields-aI_gOI6-.js.br +0 -0
  176. package/dist/standalone/assets/heavy-fields-aI_gOI6-.js.gz +0 -0
  177. package/dist/standalone/assets/home-page-Xc7HK72H.js +0 -3
  178. package/dist/standalone/assets/home-page-Xc7HK72H.js.br +0 -0
  179. package/dist/standalone/assets/home-page-Xc7HK72H.js.gz +0 -0
  180. package/dist/standalone/assets/icon-registry-AlRIE8PQ.js +0 -2
  181. package/dist/standalone/assets/icon-registry-AlRIE8PQ.js.br +0 -0
  182. package/dist/standalone/assets/icon-registry-AlRIE8PQ.js.gz +0 -0
  183. package/dist/standalone/assets/icon-registry-AlRIE8PQ.js.map +0 -1
  184. package/dist/standalone/assets/index-OvloY2cG.css.br +0 -0
  185. package/dist/standalone/assets/index-OvloY2cG.css.gz +0 -0
  186. package/dist/standalone/assets/index-R1VJOHqq.js +0 -15
  187. package/dist/standalone/assets/index-R1VJOHqq.js.br +0 -0
  188. package/dist/standalone/assets/index-R1VJOHqq.js.gz +0 -0
  189. package/dist/standalone/assets/index-R1VJOHqq.js.map +0 -1
  190. package/dist/standalone/assets/json-editor-DuYj4QGx.js +0 -2
  191. package/dist/standalone/assets/json-editor-DuYj4QGx.js.br +0 -0
  192. package/dist/standalone/assets/json-editor-DuYj4QGx.js.gz +0 -0
  193. package/dist/standalone/assets/property-renderer-U2F_u1LG.js +0 -7
  194. package/dist/standalone/assets/property-renderer-U2F_u1LG.js.br +0 -0
  195. package/dist/standalone/assets/property-renderer-U2F_u1LG.js.gz +0 -0
  196. package/dist/standalone/assets/property-renderer-U2F_u1LG.js.map +0 -1
  197. package/dist/standalone/assets/reference-CbtDQb7U.js +0 -2
  198. package/dist/standalone/assets/reference-CbtDQb7U.js.br +0 -0
  199. package/dist/standalone/assets/reference-CbtDQb7U.js.gz +0 -0
  200. package/dist/standalone/assets/refresh-cw-B2G7AzZh.js +0 -2
  201. package/dist/standalone/assets/refresh-cw-B2G7AzZh.js.map +0 -1
  202. package/dist/standalone/assets/revisions-button-hLRZGkwM.js +0 -2
  203. package/dist/standalone/assets/revisions-button-hLRZGkwM.js.br +0 -0
  204. package/dist/standalone/assets/revisions-button-hLRZGkwM.js.gz +0 -0
  205. package/dist/standalone/assets/router-DmBe_NWn.js +0 -186
  206. package/dist/standalone/assets/router-DmBe_NWn.js.br +0 -0
  207. package/dist/standalone/assets/router-DmBe_NWn.js.gz +0 -0
  208. package/dist/standalone/assets/router-DmBe_NWn.js.map +0 -1
  209. package/dist/standalone/assets/select-BxTIWCco.js +0 -2
  210. package/dist/standalone/assets/select-BxTIWCco.js.br +0 -0
  211. package/dist/standalone/assets/select-BxTIWCco.js.gz +0 -0
  212. package/dist/standalone/assets/settings-page-FHzVUo4t.js +0 -2
  213. package/dist/standalone/assets/settings-page-FHzVUo4t.js.br +0 -0
  214. package/dist/standalone/assets/settings-page-FHzVUo4t.js.gz +0 -0
  215. package/dist/standalone/assets/show-page-Jotfue76.js +0 -2
  216. package/dist/standalone/assets/show-page-Jotfue76.js.br +0 -0
  217. package/dist/standalone/assets/show-page-Jotfue76.js.gz +0 -0
  218. package/dist/standalone/assets/show-page-Jotfue76.js.map +0 -1
  219. package/dist/standalone/assets/tabs-BrnwAET7.js.br +0 -0
  220. package/dist/standalone/assets/tabs-BrnwAET7.js.gz +0 -0
  221. package/dist/standalone/assets/useQueries-CX5Gh6HV.js.br +0 -0
  222. package/dist/standalone/assets/useQueries-CX5Gh6HV.js.gz +0 -0
  223. package/dist/standalone/assets/user-directory-ZxAjN_q9.js.br +0 -0
  224. package/dist/standalone/assets/user-directory-ZxAjN_q9.js.gz +0 -0
  225. package/dist/standalone/assets/value-format-DmXCSwLn.js.br +0 -0
  226. package/dist/standalone/assets/value-format-DmXCSwLn.js.gz +0 -0
  227. package/dist/standalone/assets/wand-sparkles-BDM69Lk9.js +0 -2
  228. package/dist/standalone/assets/wand-sparkles-BDM69Lk9.js.map +0 -1
  229. package/dist/standalone/assets/wizard-create-page-Rh4uWxUR.js +0 -2
  230. package/dist/standalone/assets/wizard-create-page-Rh4uWxUR.js.br +0 -0
  231. package/dist/standalone/assets/wizard-create-page-Rh4uWxUR.js.gz +0 -0
  232. package/dist/standalone/assets/zap-Be2c7_cs.js.br +0 -0
  233. package/dist/standalone/assets/zap-Be2c7_cs.js.gz +0 -0
  234. package/dist/standalone/assets/zap-Be2c7_cs.js.map +0 -1
  235. package/dist/standalone/assets/zod-bSPpBhsj.js.br +0 -0
  236. package/dist/standalone/assets/zod-bSPpBhsj.js.gz +0 -0
@@ -0,0 +1,2 @@
1
+ import{a as e,n as t}from"./createLucideIcon-CUopU_LC.js";import{S as n}from"./with-selector-NDLhu4dT.js";import{i as r,r as i,t as a}from"./refresh-cw-DHvUQTMb.js";import{t as o}from"./trash-2-DhyKQCKv.js";import{n as ee,r as te,t as ne}from"./minimize-2-Bx2cH_WS.js";import{t as re}from"./copy-BexCWf4U.js";import{t as ie}from"./ellipsis-lEjcTxo0.js";import{t as ae}from"./pencil-BO-k3yTG.js";import{n as oe,t as se}from"./palette-DVP_4RAn.js";import{t as ce}from"./triangle-alert-CyaaNWN8.js";import{s}from"./dist-Dpg8xy_r.js";import{a as c,i as l,n as u,r as d,t as f}from"./select-BWf6walM.js";import{K as le,Z as ue,et as p}from"./router-wFvtgo77.js";import{t as m}from"./date-picker-LfbUehd1.js";import{a as de,i as fe,n as pe,t as me}from"./card-4cS4uWCP.js";import{a as h,c as he,i as g,l as ge,n as _e,o as _,r as ve,s as v,t as y}from"./value-format-CPnbnlE6.js";import{r as ye}from"./use-dashboard-charts-Cr3OUSL5.js";import{t as b}from"./reference-Dfd804y3.js";import{H as be,I as x,L as S,M as xe,N as C,O as Se,P as w,R as T,S as Ce,T as E,Y as D,w as we,yt as O}from"./index-t4woXGa-.js";var k=e(t(),1);function A(e,t,n){if(n===`all`)return[e.slice(0,10)];let r=[],i=N(new Date(e),n),a=N(new Date(t),n);for(;i.getTime()<=a.getTime();)r.push(M(i)),P(i,n);return r}function j(e,t,n,r){let i=A(t,n,r);return e.map(e=>{let t=new Map(e.points.map(e=>[e.date,e.value])),n=i.map(e=>({date:e,value:t.get(e)??0}));return{key:e.key,points:n}})}function Te(e,t=`en-US`){let n=new Intl.DateTimeFormat(t,{day:`2-digit`,month:`2-digit`}),r=new Intl.DateTimeFormat(t,{month:`2-digit`,year:`numeric`}),i=new Intl.DateTimeFormat(t,{year:`numeric`});return t=>{let a=new Date(t);return e===`year`?i.format(a):e===`month`?r.format(a):n.format(a)}}function Ee(e,t=`en-US`){let n=new Intl.DateTimeFormat(t,{day:`2-digit`,month:`long`,year:`numeric`}),r=new Intl.DateTimeFormat(t,{month:`long`,year:`numeric`}),i=new Intl.DateTimeFormat(t,{year:`numeric`}),a=new Intl.DateTimeFormat(t,{day:`2-digit`,month:`short`});return t=>{let o=new Date(t);if(e===`year`)return i.format(o);if(e===`month`)return r.format(o);if(e===`week`){let e=new Date(o);return e.setDate(e.getDate()+6),`${a.format(o)} – ${a.format(e)}`}return n.format(o)}}function M(e){return e.toISOString().slice(0,10)}function N(e,t){let n=new Date(Date.UTC(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()));if(t===`week`){let e=(n.getUTCDay()+6)%7;n.setUTCDate(n.getUTCDate()-e)}else t===`month`?n.setUTCDate(1):t===`year`&&n.setUTCMonth(0,1);return n}function P(e,t){t===`day`?e.setUTCDate(e.getUTCDate()+1):t===`week`?e.setUTCDate(e.getUTCDate()+7):t===`month`?e.setUTCMonth(e.getUTCMonth()+1):t===`year`&&e.setUTCFullYear(e.getUTCFullYear()+1)}var F=`__prev__:`;function De(e){let t=Date.parse(`${e.from}T00:00:00.000Z`),n=Date.parse(`${e.to}T00:00:00.000Z`);if(Number.isNaN(t)||Number.isNaN(n)||n<t)return null;let r=Math.round((n-t)/864e5)+1;return{from:L(new Date(t-r*864e5)),to:L(new Date(t-864e5))}}function Oe(e,t,n,r){if(n.length===0)return[];let i=A(t.from,t.to,r),a=n.length-i.length;return e.map(e=>{let t=new Map(e.points.map(e=>[e.date,e.value])),r=n.map((e,n)=>{let r=i[n-a];return r===void 0?{date:e,value:0}:{date:e,value:t.get(r)??0,sourceDate:r}});return{key:`${F}${e.key}`,sourceKey:e.key,points:r}})}function I(e){if(!e||e.length===0)return null;let t=0;for(let n of e)for(let e of n.points)t+=e.value;return t}function ke(e,t){if(e==null||t==null||t===0)return null;let n=Math.round((e-t)/Math.abs(t)*1e3)/10;return{percent:n,direction:n>0?`up`:n<0?`down`:`flat`}}var L=e=>e.toISOString().slice(0,10),R=n();function Ae({items:e,onSave:t,onClose:n}){let{t:r}=p(),[i,a]=k.useState(()=>Object.fromEntries(e.map(e=>[e.key,e.override])));return(0,R.jsx)(C,{open:!0,onOpenChange:e=>{e||n()},children:(0,R.jsxs)(w,{className:`w-full max-w-lg`,children:[(0,R.jsx)(S,{children:(0,R.jsx)(T,{children:r(`dashboard:widget.colorsTitle`)})}),(0,R.jsx)(`div`,{className:`max-h-[60vh] space-y-4 overflow-y-auto py-1`,children:e.map(e=>(0,R.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-2 text-sm`,children:[(0,R.jsx)(`span`,{className:`size-3 shrink-0 rounded-full`,style:{backgroundColor:i[e.key]??e.auto}}),(0,R.jsx)(`span`,{className:`truncate font-medium`,children:e.label})]}),(0,R.jsx)(h,{value:i[e.key],onChange:t=>a(n=>({...n,[e.key]:t})),presets:_,labels:{custom:r(`dashboard:widget.colorCustom`),pick:r(`dashboard:widget.colorPick`),auto:r(`dashboard:widget.colorAuto`)}})]},e.key))}),(0,R.jsxs)(x,{children:[(0,R.jsx)(s,{variant:`outline`,onClick:n,children:r(`common:cancel`)}),(0,R.jsx)(s,{onClick:()=>{let e={};for(let[t,n]of Object.entries(i))n&&(e[t]=n);t(e)},children:r(`common:save`)})]})]})})}var je=[`7d`,`30d`,`90d`,`1y`,`all`,`custom`],Me=[`day`,`week`,`month`,`year`];function z({config:e,onEdit:t,onDelete:n,onMove:h,onUpdate:_}){let{t:v,locale:y}=p(),b=e.visualisation===`kpi`,x=b?`all`:e.timeRange.preset===`all`&&(e.step===`day`||e.step===`week`)?`month`:e.timeRange.preset===`1y`&&e.step===`day`?`week`:e.step,S=k.useMemo(()=>ye(e.timeRange),[e.timeRange]),C=!b&&e.comparePrevious===!0&&!e.groupBy,w=le(e.resource),T=k.useMemo(()=>{if(e.groupByLabelResource)return e.groupByLabelResource;if(!e.groupBy||!w)return;let t=w.properties,n=t.find(t=>t.path===e.groupBy);if(!n)return;if(n.reference)return n.reference;let r=n.path.endsWith(`_id`)?n.path.slice(0,-3):n.path.endsWith(`Id`)?n.path.slice(0,-2):``;if(r){let e=t.find(e=>e.path===r&&e.reference);if(e?.reference)return e.reference}},[e.groupBy,e.groupByLabelResource,w]),{data:D,isLoading:j,isError:M,refetch:N,isFetching:P}=ue(k.useMemo(()=>({resource:e.resource,dateField:e.dateField,step:x,metric:e.metric,from:S.from,to:S.to,...e.field?{field:e.field}:{},...!b&&e.groupBy?{groupBy:e.groupBy}:{},...!b&&e.groupBy?{topN:e.topN}:{},...!b&&e.groupBy&&T?{groupByLabelResource:T}:{},...Object.keys(e.filters).length?{filters:e.filters}:{},...b||C?{comparePrevious:!0}:{}}),[e,S,b,C,x,T])),[F,L]=k.useState(!1),[z,B]=k.useState(!1),[H,U]=k.useState(S.from),[W,Re]=k.useState(S.to),G=e.quickFilters??[],[K,ze]=k.useState(()=>V(G,e.filters)),Be=G.join(`|`),Ve=k.useMemo(()=>Object.entries(e.filters).map(([e,t])=>`${e}=${t}`).sort().join(`|`),[e.filters]);k.useEffect(()=>{ze(V(G,e.filters))},[Be,Ve]);let He=()=>{let t={...e.filters};for(let e of G){let n=K[e]??``;n===``?delete t[e]:t[e]=n}q({filters:t})},Ue=G.some(t=>(K[t]??``)!==(e.filters[t]??``)),q=t=>{_({...e,...t,updatedAt:new Date().toISOString()})},We=e=>{e===`custom`?(U(S.from),Re(S.to),q({timeRange:{preset:`custom`,from:S.from,to:S.to}})):q({timeRange:{preset:e}})},Ge=()=>{H&&W&&q({timeRange:{preset:`custom`,from:H,to:W}})},Ke=e=>{e!==`all`&&q({step:e})},qe=()=>{q({width:e.width===`full`?`half`:`full`})},J=b?`h-32`:`h-[320px]`,Je=D?.resolvedLabels,Y=k.useCallback(e=>e===`__total__`?v(`dashboard:seriesTotal`):e===`__other__`?v(`dashboard:seriesOther`):e===`__null__`?v(`dashboard:seriesNull`):Je?.[e]??e,[Je,v]),Ye=k.useMemo(()=>ve(e.format,y),[e.format,y]),Xe=k.useMemo(()=>_e(e.format,y),[e.format,y]),X=k.useMemo(()=>{let t=g(Fe(D?.series??[],S,x,Y),e.transform).map(t=>{let n=e.series?.[t.key]?.color;return n?{...t,color:n}:t});if(!C||!D?.previous?.length)return t;let n=De(S);if(!n)return t;let r=A(S.from,S.to,x),i=g(Oe(D.previous,n,r,x),e.transform).map(e=>({key:e.key,label:v(`dashboard:widget.previousSeries`).replace(`{label}`,Y(e.sourceKey)),points:e.points,dashed:!0,hiddenWith:e.sourceKey}));return[...t,...i]},[D?.series,D?.previous,S.from,S.to,x,Y,C,e.transform,e.series,v]),Z=k.useMemo(()=>C&&D?ke(I(D.series),I(D.previous)):null,[C,D]),[Ze,Q]=k.useState(!1),Qe=k.useMemo(()=>{let t=X.filter(e=>!(`dashed`in e)||!e.dashed),n=ge(t.length);return t.map((t,r)=>({key:t.key,label:t.label,override:e.series?.[t.key]?.color,auto:n[r]}))},[X,e.series]),$e=t=>{let n={...e.series};for(let e of Qe)delete n[e.key];for(let[e,r]of Object.entries(t))n[e]={color:r};q({series:n}),Q(!1)},$=D&&D.supported===!1;return(0,R.jsxs)(me,{className:`flex flex-col`,children:[(0,R.jsxs)(fe,{className:`flex flex-row items-center justify-between gap-2 p-3 pb-2 space-y-0 sm:p-6 sm:pb-2`,children:[(0,R.jsxs)(de,{className:`flex min-w-0 items-center gap-2 text-sm font-medium pr-2`,children:[(0,R.jsx)(`span`,{className:`truncate`,children:e.title||v(`chart:untitled`)}),Z&&(0,R.jsxs)(`span`,{title:v(`dashboard:widget.previousPeriod`),className:`inline-flex shrink-0 items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-medium tabular-nums ${Z.direction===`up`?`bg-emerald-500/10 text-emerald-600 dark:text-emerald-400`:Z.direction===`down`?`bg-rose-500/10 text-rose-600 dark:text-rose-400`:`bg-muted text-muted-foreground`}`,children:[Z.direction===`up`?(0,R.jsx)(i,{className:`size-3`}):Z.direction===`down`?(0,R.jsx)(r,{className:`size-3`}):null,Math.abs(Z.percent),`%`]})]}),(0,R.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[(0,R.jsx)(s,{variant:`ghost`,size:`icon`,className:`size-7`,onClick:qe,"aria-label":e.width===`full`?v(`dashboard:widget.shrink`):v(`dashboard:widget.expand`),children:e.width===`full`?(0,R.jsx)(ne,{className:`size-3.5`}):(0,R.jsx)(ee,{className:`size-3.5`})}),D?.sql&&(0,R.jsx)(s,{variant:F?`secondary`:`ghost`,size:`icon`,className:`size-7`,onClick:()=>L(e=>!e),"aria-label":v(`dashboard:widget.toggleSql`),children:(0,R.jsx)(te,{className:`size-3.5`})}),(0,R.jsx)(s,{variant:`ghost`,size:`icon`,className:`size-7`,onClick:()=>N(),disabled:P,"aria-label":v(`common:refresh`),children:(0,R.jsx)(a,{className:`size-3.5 ${P?`animate-spin`:``}`})}),(0,R.jsxs)(Ce,{children:[(0,R.jsx)(xe,{asChild:!0,children:(0,R.jsx)(s,{variant:`ghost`,size:`icon`,className:`size-7`,"aria-label":v(`common:openMenu`),children:(0,R.jsx)(ie,{className:`size-3.5`})})}),(0,R.jsxs)(we,{align:`end`,children:[(0,R.jsxs)(E,{onClick:t,children:[(0,R.jsx)(ae,{className:`size-4 mr-2`}),v(`chart:editChart`)]}),!b&&(0,R.jsxs)(E,{onClick:()=>Q(!0),children:[(0,R.jsx)(se,{className:`size-4 mr-2`}),v(`dashboard:widget.editColors`)]}),h&&(0,R.jsxs)(E,{onClick:h,children:[(0,R.jsx)(oe,{className:`size-4 mr-2`}),v(`chart:moveToGroup`)]}),(0,R.jsx)(Se,{}),(0,R.jsxs)(E,{onClick:n,className:`text-destructive focus:text-destructive`,children:[(0,R.jsx)(o,{className:`size-4 mr-2`}),v(`chart:deleteChart`)]})]})]})]})]}),(0,R.jsxs)(pe,{className:`flex-1 p-3 pt-0 space-y-3 sm:p-6 sm:pt-0`,children:[!$&&G.length>0&&w&&(0,R.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[G.map(e=>{let t=w.properties.find(t=>t.path===e);return t?(0,R.jsx)(Pe,{property:t,placeholder:t.label,value:K[e]??``,onChange:t=>ze(n=>({...n,[e]:t}))},e):null}),(0,R.jsxs)(s,{size:`sm`,className:`h-8 px-3 text-xs shrink-0`,onClick:He,disabled:!Ue,children:[(0,R.jsx)(O,{className:`size-3.5 mr-1`}),v(`common:apply`)]})]}),!$&&(0,R.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 text-xs text-muted-foreground`,children:[!b&&(0,R.jsxs)(f,{value:e.step===`all`?`day`:e.step,onValueChange:e=>Ke(e),children:[(0,R.jsx)(l,{className:`h-8 px-2 text-xs w-auto`,"aria-label":v(`chart:step`),children:(0,R.jsx)(c,{})}),(0,R.jsx)(u,{children:Me.map(e=>(0,R.jsx)(d,{value:e,children:v(`chart:step${Ne(e)}`)},e))})]}),(0,R.jsxs)(f,{value:e.timeRange.preset,onValueChange:e=>We(e),children:[(0,R.jsx)(l,{className:`h-8 px-2 text-xs w-auto`,"aria-label":v(`dashboard:builder.range`),children:(0,R.jsx)(c,{})}),(0,R.jsx)(u,{children:je.map(e=>(0,R.jsx)(d,{value:e,children:v(`dashboard:range.${e}`)},e))})]}),e.timeRange.preset===`custom`?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(m,{value:H,onChange:U,ariaLabel:v(`common:from`),openCalendarLabel:v(`common:openCalendar`),className:`w-[130px]`,inputClassName:`h-8 text-xs`}),(0,R.jsx)(`span`,{className:`text-muted-foreground`,children:`—`}),(0,R.jsx)(m,{value:W,onChange:Re,ariaLabel:v(`common:to`),openCalendarLabel:v(`common:openCalendar`),className:`w-[130px]`,inputClassName:`h-8 text-xs`}),(0,R.jsxs)(s,{size:`sm`,className:`h-8 px-3 shrink-0`,onClick:Ge,disabled:!H||!W,"aria-label":v(`common:apply`),children:[(0,R.jsx)(O,{className:`size-3.5 mr-1`}),v(`common:apply`)]})]}):(0,R.jsxs)(`span`,{className:`ml-auto tabular-nums`,children:[S.from,` — `,S.to]})]}),!$&&!M&&D?.truncated&&(0,R.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2 text-xs text-amber-700 dark:text-amber-400`,children:[(0,R.jsx)(ce,{className:`size-3.5 mt-0.5 shrink-0`}),(0,R.jsx)(`span`,{children:v(`dashboard:widget.truncatedWarning`)})]}),j?(0,R.jsx)(be,{className:`${J} w-full rounded-md`}):M?(0,R.jsx)(`div`,{className:`flex items-center justify-center text-sm text-muted-foreground ${J}`,children:v(`chart:loadError`)}):$?(0,R.jsx)(`div`,{className:`flex items-center justify-center text-center text-sm text-muted-foreground px-4 ${J}`,children:v(`dashboard:widget.unsupported`)}):b?(0,R.jsx)(Ie,{data:D,transform:e.transform,formatNumber:Ye,labels:Le(v)}):(0,R.jsx)(he,{series:X,height:320,visualisation:e.visualisation===`kpi`?void 0:e.visualisation,tickFormatter:Te(x,y),labelFormatter:Ee(x,y),valueFormatter:Ye,axisValueFormatter:Xe,labels:{noData:v(`chart:noData`),showAll:v(`dashboard:widget.showAll`),hideAll:v(`dashboard:widget.hideAll`)}}),D?.sql&&F&&(0,R.jsxs)(`div`,{className:`relative`,children:[(0,R.jsx)(s,{variant:`ghost`,size:`icon`,className:`absolute top-1 right-1 size-6`,onClick:()=>{navigator.clipboard.writeText(D.sql??``),B(!0),setTimeout(()=>B(!1),2e3)},"aria-label":v(z?`common:copied`:`common:copy`),children:z?(0,R.jsx)(O,{className:`size-3 text-green-500`}):(0,R.jsx)(re,{className:`size-3`})}),(0,R.jsx)(`pre`,{className:`text-[11px] leading-snug bg-muted/50 border border-border rounded-md p-2 pr-8 overflow-x-auto whitespace-pre`,children:D.sql})]})]}),Ze&&(0,R.jsx)(Ae,{items:Qe,onSave:$e,onClose:()=>Q(!1)})]})}var Ne=e=>e.charAt(0).toUpperCase()+e.slice(1),B=`__none__`;function V(e,t){let n={};for(let r of e)n[r]=t[r]??``;return n}function Pe({property:e,placeholder:t,value:n,onChange:r}){let i=t??e.label;return e.reference?(0,R.jsx)(`div`,{className:`w-36`,children:(0,R.jsx)(b,{referenceResourceId:e.reference,value:n||null,onChange:e=>r(e==null?``:String(e)),placeholder:i,className:`h-8 text-xs`})}):e.availableValues&&e.availableValues.length>0?(0,R.jsxs)(f,{value:n||B,onValueChange:e=>r(e===B?``:e),children:[(0,R.jsx)(l,{className:`h-8 px-2 text-xs w-36`,children:(0,R.jsx)(c,{placeholder:i})}),(0,R.jsxs)(u,{children:[(0,R.jsx)(d,{value:B,children:i}),e.availableValues.map(e=>(0,R.jsx)(d,{value:e.value,children:e.label},e.value))]})]}):e.type===`boolean`?(0,R.jsxs)(f,{value:n||B,onValueChange:e=>r(e===B?``:e),children:[(0,R.jsx)(l,{className:`h-8 px-2 text-xs w-36`,children:(0,R.jsx)(c,{placeholder:i})}),(0,R.jsxs)(u,{children:[(0,R.jsx)(d,{value:B,children:i}),(0,R.jsx)(d,{value:`true`,children:`true`}),(0,R.jsx)(d,{value:`false`,children:`false`})]})]}):(0,R.jsx)(D,{type:e.type===`number`||e.type===`float`||e.type===`currency`?`number`:`text`,className:`h-8 px-2 text-xs w-36`,value:n,placeholder:i,onChange:e=>r(e.target.value)})}function Fe(e,t,n,r){return j(e.map(e=>({key:e.key,points:e.points})),t.from,t.to,n).map(e=>({key:e.key,label:r(e.key),points:[...e.points]}))}function Ie({data:e,transform:t,formatNumber:n,labels:r}){let i=H(e?.series),a=H(e?.previous);return(0,R.jsx)(v,{value:i==null?i:y(i,t),previousValue:a==null?a:y(a,t),formatNumber:n,labels:r})}function H(e){if(!e||e.length===0)return null;let t=0;for(let n of e)for(let e of n.points)t+=e.value;return t}function Le(e){return{noData:e(`chart:noData`),deltaUp:e(`dashboard:widget.deltaUp`),deltaDown:e(`dashboard:widget.deltaDown`),deltaFlat:e(`dashboard:widget.deltaFlat`),previousPeriod:e(`dashboard:widget.previousPeriod`)}}export{z as ChartWidget};
2
+ //# sourceMappingURL=chart-widget-BtJb6YXV.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-widget-B7pIeDCP.js","names":[],"sources":["../../../../react/src/dashboard/time-series.ts","../../../../react/src/dashboard/compare.ts","../../../../react/src/components/chart-series-colors-dialog.tsx","../../../../react/src/components/chart-widget.tsx"],"sourcesContent":["// Time-series UI helpers — bucket fill, tick formatting, label formatting.\n// All zero-fill happens here on the client side (req: \"Заполнение нулями\n// должно быть только в ui, вне зависимости от адаптеров\"). Adapters return\n// only buckets that have data; the UI fabricates the rest at value 0 so\n// charts don't have visual gaps.\n\nimport type {\n TimeSeriesPoint,\n TimeSeriesSeries,\n TimeSeriesStep,\n} from '../client.js'\n\n/** Generate a continuous sequence of `YYYY-MM-DD` bucket keys spanning [from, to]. */\nexport function generateBuckets(\n fromIso: string,\n toIso: string,\n step: TimeSeriesStep,\n): string[] {\n if (step === 'all') return [fromIso.slice(0, 10)]\n const out: string[] = []\n const cur = startOf(new Date(fromIso), step)\n const end = startOf(new Date(toIso), step)\n while (cur.getTime() <= end.getTime()) {\n out.push(ymd(cur))\n advance(cur, step)\n }\n return out\n}\n\n/**\n * Zero-fill every series so each one has a value for every bucket in the\n * resolved date range. Missing buckets become `value: 0` rather than gaps,\n * which Recharts renders as flat segments instead of breaks.\n */\nexport function fillTimeSeries(\n series: TimeSeriesSeries[],\n fromIso: string,\n toIso: string,\n step: TimeSeriesStep,\n): TimeSeriesSeries[] {\n const buckets = generateBuckets(fromIso, toIso, step)\n return series.map((s) => {\n const map = new Map(s.points.map((p) => [p.date, p.value]))\n const points: TimeSeriesPoint[] = buckets.map((date) => ({\n date,\n value: map.get(date) ?? 0,\n }))\n return { key: s.key, points }\n })\n}\n\n/**\n * X-axis tick formatter — short label format depending on bucket size.\n * day/week → DD.MM, month → MM.YYYY, year → YYYY.\n */\nexport function makeTickFormatter(\n step: TimeSeriesStep,\n locale = 'en-US',\n): (iso: string) => string {\n const dayMonth = new Intl.DateTimeFormat(locale, { day: '2-digit', month: '2-digit' })\n const monthYear = new Intl.DateTimeFormat(locale, { month: '2-digit', year: 'numeric' })\n const year = new Intl.DateTimeFormat(locale, { year: 'numeric' })\n return (iso: string): string => {\n const d = new Date(iso)\n if (step === 'year') return year.format(d)\n if (step === 'month') return monthYear.format(d)\n return dayMonth.format(d)\n }\n}\n\n/**\n * Tooltip label formatter — long, human-friendly form. For week buckets\n * we render `Mon DD – Sun DD` (the bucket plus 6 days).\n */\nexport function makeLabelFormatter(\n step: TimeSeriesStep,\n locale = 'en-US',\n): (iso: string) => string {\n const fullDay = new Intl.DateTimeFormat(locale, {\n day: '2-digit',\n month: 'long',\n year: 'numeric',\n })\n const monthYear = new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric' })\n const year = new Intl.DateTimeFormat(locale, { year: 'numeric' })\n const shortDay = new Intl.DateTimeFormat(locale, { day: '2-digit', month: 'short' })\n return (iso: string): string => {\n const d = new Date(iso)\n if (step === 'year') return year.format(d)\n if (step === 'month') return monthYear.format(d)\n if (step === 'week') {\n const end = new Date(d)\n end.setDate(end.getDate() + 6)\n return `${shortDay.format(d)} – ${shortDay.format(end)}`\n }\n return fullDay.format(d)\n }\n}\n\n// ─── Internals ────────────────────────────────────────────────────────────\n\nfunction ymd(d: Date): string {\n return d.toISOString().slice(0, 10)\n}\n\nfunction startOf(d: Date, step: TimeSeriesStep): Date {\n const out = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()))\n if (step === 'week') {\n // Monday-anchored week.\n const dow = (out.getUTCDay() + 6) % 7\n out.setUTCDate(out.getUTCDate() - dow)\n } else if (step === 'month') {\n out.setUTCDate(1)\n } else if (step === 'year') {\n out.setUTCMonth(0, 1)\n }\n return out\n}\n\nfunction advance(d: Date, step: TimeSeriesStep): void {\n if (step === 'day') d.setUTCDate(d.getUTCDate() + 1)\n else if (step === 'week') d.setUTCDate(d.getUTCDate() + 7)\n else if (step === 'month') d.setUTCMonth(d.getUTCMonth() + 1)\n else if (step === 'year') d.setUTCFullYear(d.getUTCFullYear() + 1)\n}\n","// Previous-period comparison helpers for dashboard charts.\n//\n// The adapters compute the previous window as `prevTo = from`,\n// `prevFrom = from − (to − from)` where the wire `from`/`to` are\n// start-of-day / end-of-day instants. In whole-day terms that is the\n// N-day window ending the day before the current one starts — which is\n// what `serverPreviousRangeOf` reproduces so client-side zero-fill and\n// tooltips agree with the buckets the server actually returns. (The\n// degenerate 1 ms boundary bucket at `from` itself is dropped.)\n\nimport type { TimeSeriesSeries, TimeSeriesStep } from '../client.js'\nimport { generateBuckets } from './time-series.js'\n\n/** Prefix marking overlay series produced from the previous window. */\nexport const PREVIOUS_KEY_PREFIX = '__prev__:'\n\nexport interface AlignedPreviousPoint {\n /** Current-window bucket the point is plotted on. */\n date: string\n value: number\n /** Real previous-window bucket the value came from (for tooltips). */\n sourceDate?: string\n}\n\nexport interface AlignedPreviousSeries {\n key: string\n /** Key of the paired current-window series (`__total__`, …). */\n sourceKey: string\n points: AlignedPreviousPoint[]\n}\n\n/**\n * Whole-day previous window matching the adapters' formula: for a current\n * window of N days `[from, to]`, returns `[from − N, from − 1]`.\n */\nexport function serverPreviousRangeOf(range: {\n from: string\n to: string\n}): { from: string; to: string } | null {\n const f = Date.parse(`${range.from}T00:00:00.000Z`)\n const t = Date.parse(`${range.to}T00:00:00.000Z`)\n if (Number.isNaN(f) || Number.isNaN(t) || t < f) return null\n const days = Math.round((t - f) / 86_400_000) + 1\n return {\n from: ymd(new Date(f - days * 86_400_000)),\n to: ymd(new Date(f - 86_400_000)),\n }\n}\n\n/**\n * Zero-fill the previous window and re-plot each point onto the current\n * window's bucket axis (point *i* → `currentBuckets[i]`), keeping the real\n * date in `sourceDate`. When bucket counts differ (step-aligned month/week\n * windows drift by ±1) the series are aligned on their END — \"yesterday\n * lines up with yesterday\" — and leading gaps become zeros.\n */\nexport function alignPreviousSeries(\n previous: ReadonlyArray<TimeSeriesSeries>,\n prevRange: { from: string; to: string },\n currentBuckets: ReadonlyArray<string>,\n step: TimeSeriesStep,\n): AlignedPreviousSeries[] {\n if (currentBuckets.length === 0) return []\n const prevBuckets = generateBuckets(prevRange.from, prevRange.to, step)\n const offset = currentBuckets.length - prevBuckets.length\n return previous.map((s) => {\n const map = new Map(s.points.map((p) => [p.date, p.value]))\n const points: AlignedPreviousPoint[] = currentBuckets.map((date, i) => {\n const src = prevBuckets[i - offset]\n return src === undefined\n ? { date, value: 0 }\n : { date, value: map.get(src) ?? 0, sourceDate: src }\n })\n return { key: `${PREVIOUS_KEY_PREFIX}${s.key}`, sourceKey: s.key, points }\n })\n}\n\n/** Total across all points of all series (raw, pre-transform values). */\nexport function sumSeries(\n series: ReadonlyArray<TimeSeriesSeries> | undefined,\n): number | null {\n if (!series || series.length === 0) return null\n let total = 0\n for (const s of series) for (const p of s.points) total += p.value\n return total\n}\n\nexport interface PeriodDelta {\n /** Signed percentage, one decimal place (e.g. -81.7). */\n percent: number\n direction: 'up' | 'down' | 'flat'\n}\n\n/**\n * Period-over-period delta on raw totals: `(cur − prev) / prev`. Returns\n * null when the previous total is missing or 0 (undefined percentage).\n */\nexport function computeDelta(\n current: number | null,\n previous: number | null,\n): PeriodDelta | null {\n if (current == null || previous == null || previous === 0) return null\n const percent = Math.round(((current - previous) / Math.abs(previous)) * 1000) / 10\n return {\n percent,\n direction: percent > 0 ? 'up' : percent < 0 ? 'down' : 'flat',\n }\n}\n\nconst ymd = (d: Date): string => d.toISOString().slice(0, 10)\n","// Per-series color override dialog for a dashboard chart. Opened from the\n// widget \"…\" menu so it can list the series actually rendered (groupBy\n// values are only known once data is loaded). Lives in the react package\n// because it is i18n-aware; primitives come from @modern-admin/ui.\n\nimport * as React from 'react'\nimport {\n Button,\n ColorSwatchPicker,\n CHART_COLOR_PRESETS,\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@modern-admin/ui'\nimport { useI18n } from '../i18n.js'\n\nexport interface SeriesColorItem {\n /** Stable series key (`__total__`, groupBy value, …). */\n key: string\n /** Display label (legend text). */\n label: string\n /** Persisted override, if any. */\n override?: string\n /** Palette color used when no override is set — shown as the row swatch. */\n auto: string\n}\n\nexport interface ChartSeriesColorsDialogProps {\n items: ReadonlyArray<SeriesColorItem>\n /** Receives only the overrides (key → hex); auto rows are omitted. */\n onSave(overrides: Record<string, string>): void\n onClose(): void\n}\n\nexport function ChartSeriesColorsDialog({\n items,\n onSave,\n onClose,\n}: ChartSeriesColorsDialogProps): React.ReactElement {\n const { t } = useI18n()\n const [draft, setDraft] = React.useState<Record<string, string | undefined>>(\n () => Object.fromEntries(items.map((i) => [i.key, i.override])),\n )\n\n const handleSave = (): void => {\n const overrides: Record<string, string> = {}\n for (const [key, color] of Object.entries(draft)) {\n if (color) overrides[key] = color\n }\n onSave(overrides)\n }\n\n return (\n <Dialog open onOpenChange={(open) => { if (!open) onClose() }}>\n <DialogContent className=\"w-full max-w-lg\">\n <DialogHeader>\n <DialogTitle>{t('dashboard:widget.colorsTitle')}</DialogTitle>\n </DialogHeader>\n\n <div className=\"max-h-[60vh] space-y-4 overflow-y-auto py-1\">\n {items.map((item) => (\n <div key={item.key} className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2 text-sm\">\n <span\n className=\"size-3 shrink-0 rounded-full\"\n style={{ backgroundColor: draft[item.key] ?? item.auto }}\n />\n <span className=\"truncate font-medium\">{item.label}</span>\n </div>\n <ColorSwatchPicker\n value={draft[item.key]}\n onChange={(next) =>\n setDraft((prev) => ({ ...prev, [item.key]: next }))\n }\n presets={CHART_COLOR_PRESETS}\n labels={{\n custom: t('dashboard:widget.colorCustom'),\n pick: t('dashboard:widget.colorPick'),\n auto: t('dashboard:widget.colorAuto'),\n }}\n />\n </div>\n ))}\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={onClose}>{t('common:cancel')}</Button>\n <Button onClick={handleSave}>{t('common:save')}</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","// Dashboard tile rendering one ChartDef. Phase 10 brings:\n// • Per-widget toolbar (step / range / width / SQL toggle) — changes persist\n// via `onUpdate` so a tweak survives reload without re-opening the builder.\n// • Time-series chart (date X-axis, value Y-axis) with multi-series via\n// secondary `groupBy`. Zero-fill happens UI-side regardless of adapter.\n// • KPI mode = `step: 'all'` — sums the single bucket and shows period-over-\n// period delta.\n// • Graceful degradation when the adapter cannot do time-series aggregation\n// (e.g. non-relational DB) — shows a friendly message instead of erroring.\n\nimport * as React from 'react'\nimport {\n MoreHorizontal,\n Pencil,\n Trash2,\n RefreshCw,\n Maximize2,\n Minimize2,\n Code,\n Copy,\n Check,\n FolderSymlink,\n AlertTriangle,\n ArrowUp,\n ArrowDown,\n Palette,\n} from 'lucide-react'\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n TimeSeriesChart,\n KpiCard,\n DatePicker,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Button,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Skeleton,\n paletteFor,\n} from '@modern-admin/ui'\nimport { ReferenceCombobox } from '../reference.js'\nimport type { PropertyJSON } from '../types.js'\nimport type {\n ChartDef,\n ChartDefInput,\n AggregationStep,\n ChartWidth,\n TimeRange,\n TimeRangePreset,\n} from '@modern-admin/core'\nimport { useTimeSeries, useResource } from '../hooks.js'\nimport { useI18n } from '../i18n.js'\nimport { resolveRange } from '../use-dashboard-charts.js'\nimport {\n fillTimeSeries,\n generateBuckets,\n makeLabelFormatter,\n makeTickFormatter,\n} from '../dashboard/time-series.js'\nimport {\n applyTransform,\n transformSeries,\n makeValueFormatter,\n makeAxisFormatter,\n} from '../dashboard/value-format.js'\nimport {\n alignPreviousSeries,\n serverPreviousRangeOf,\n sumSeries,\n computeDelta,\n} from '../dashboard/compare.js'\nimport { ChartSeriesColorsDialog } from './chart-series-colors-dialog.js'\nimport type { TimeSeriesQuery, TimeSeriesSeries } from '../client.js'\nimport type { ChartTransformStep } from '@modern-admin/core'\n\nconst PRESETS: TimeRangePreset[] = ['7d', '30d', '90d', '1y', 'all', 'custom']\nconst STEPS: Exclude<AggregationStep, 'all'>[] = ['day', 'week', 'month', 'year']\n\nexport interface ChartWidgetProps {\n config: ChartDef\n onEdit(): void\n onDelete(): void\n onMove?(): void\n /** Called when the user tweaks step / range / width directly on the widget. */\n onUpdate(input: ChartDefInput): void\n}\n\nexport function ChartWidget({\n config,\n onEdit,\n onDelete,\n onMove,\n onUpdate,\n}: ChartWidgetProps): React.ReactElement {\n const { t, locale } = useI18n()\n\n const isKpi = config.visualisation === 'kpi'\n // KPI charts force `step: 'all'`; the schema enforces this at save time.\n // For very wide presets, automatically coarsen granularity so the point\n // count stays manageable — 3650 daily buckets for 'all' would render an\n // unreadable axis and cause significant memory pressure in Recharts.\n const renderStep: AggregationStep =\n isKpi ? 'all'\n : config.timeRange.preset === 'all' && (config.step === 'day' || config.step === 'week') ? 'month'\n : config.timeRange.preset === '1y' && config.step === 'day' ? 'week'\n : config.step\n\n // Resolve the time-range preset to concrete from/to per render so cards\n // automatically reflect \"now\" as days roll over without re-saving.\n const range = React.useMemo(() => resolveRange(config.timeRange), [config.timeRange])\n\n // Previous-period overlay is only meaningful without a breakdown: top-N is\n // computed independently per window, so grouped series keys aren't stable.\n const compareActive = !isKpi && config.comparePrevious === true && !config.groupBy\n\n // If the saved ChartDef pre-dates the groupByLabelResource feature (i.e.,\n // groupBy is set but groupByLabelResource is not), derive it from the\n // resource's property metadata so labels resolve without requiring a re-save.\n const resourceConfig = useResource(config.resource)\n const effectiveLabelResource = React.useMemo(() => {\n if (config.groupByLabelResource) return config.groupByLabelResource\n if (!config.groupBy || !resourceConfig) return undefined\n const props = resourceConfig.properties\n const prop = props.find((p) => p.path === config.groupBy)\n if (!prop) return undefined\n if (prop.reference) return prop.reference\n // FK heuristic: strip Id / _id suffix and look for a sibling reference prop.\n const base = prop.path.endsWith('_id')\n ? prop.path.slice(0, -3)\n : prop.path.endsWith('Id')\n ? prop.path.slice(0, -2)\n : ''\n if (base) {\n const sibling = props.find((p) => p.path === base && p.reference)\n if (sibling?.reference) return sibling.reference\n }\n return undefined\n }, [config.groupBy, config.groupByLabelResource, resourceConfig])\n\n const query = React.useMemo<TimeSeriesQuery>(\n () => ({\n resource: config.resource,\n dateField: config.dateField,\n step: renderStep as TimeSeriesQuery['step'],\n metric: config.metric,\n from: range.from,\n to: range.to,\n ...(config.field ? { field: config.field } : {}),\n ...(!isKpi && config.groupBy ? { groupBy: config.groupBy } : {}),\n ...(!isKpi && config.groupBy ? { topN: config.topN } : {}),\n ...(!isKpi && config.groupBy && effectiveLabelResource\n ? { groupByLabelResource: effectiveLabelResource }\n : {}),\n ...(Object.keys(config.filters).length ? { filters: config.filters } : {}),\n ...(isKpi || compareActive ? { comparePrevious: true as const } : {}),\n }),\n [config, range, isKpi, compareActive, renderStep, effectiveLabelResource],\n )\n\n const { data, isLoading, isError, refetch, isFetching } = useTimeSeries(query)\n\n const [showSql, setShowSql] = React.useState(false)\n const [sqlCopied, setSqlCopied] = React.useState(false)\n\n // Draft from/to — only committed when the user clicks Apply.\n // Seeded from `config.timeRange` when preset changes to 'custom'.\n const [draftFrom, setDraftFrom] = React.useState(range.from)\n const [draftTo, setDraftTo] = React.useState(range.to)\n\n // Draft state for quick filters exposed above the chart. The user tweaks\n // values inline and clicks Apply to refetch — mirroring the custom-range\n // pattern so widgets don't refetch on every keystroke.\n const quickFilterPaths = config.quickFilters ?? []\n const [draftFilters, setDraftFilters] = React.useState<Record<string, string>>(\n () => seedDraftFilters(quickFilterPaths, config.filters),\n )\n // Re-seed whenever the saved chart definition changes externally.\n const quickFiltersKey = quickFilterPaths.join('|')\n const savedFiltersKey = React.useMemo(\n () =>\n Object.entries(config.filters)\n .map(([k, v]) => `${k}=${v}`)\n .sort()\n .join('|'),\n [config.filters],\n )\n React.useEffect(() => {\n setDraftFilters(seedDraftFilters(quickFilterPaths, config.filters))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [quickFiltersKey, savedFiltersKey])\n\n const applyQuickFilters = (): void => {\n const next: Record<string, string> = { ...config.filters }\n for (const p of quickFilterPaths) {\n const v = draftFilters[p] ?? ''\n if (v === '') delete next[p]\n else next[p] = v\n }\n update({ filters: next })\n }\n\n const draftDirty = quickFilterPaths.some(\n (p) => (draftFilters[p] ?? '') !== (config.filters[p] ?? ''),\n )\n\n // Mutators — persisted by the parent via `onUpdate(updatedDef)`.\n const update = (patch: Partial<ChartDefInput>): void => {\n onUpdate({ ...config, ...patch, updatedAt: new Date().toISOString() })\n }\n\n const onPresetChange = (preset: TimeRangePreset): void => {\n if (preset === 'custom') {\n // Seed draft with the currently resolved window — user can then narrow\n // it and click Apply without triggering an immediate refetch.\n setDraftFrom(range.from)\n setDraftTo(range.to)\n update({\n timeRange: { preset: 'custom', from: range.from, to: range.to } as TimeRange,\n })\n } else {\n update({ timeRange: { preset } as TimeRange })\n }\n }\n\n const applyCustomRange = (): void => {\n if (draftFrom && draftTo) {\n update({\n timeRange: { preset: 'custom', from: draftFrom, to: draftTo } as TimeRange,\n })\n }\n }\n\n const onStepChange = (step: AggregationStep): void => {\n if (step === 'all') return // KPI is selected via the builder, not the toolbar\n update({ step })\n }\n\n const onWidthToggle = (): void => {\n update({ width: (config.width === 'full' ? 'half' : 'full') as ChartWidth })\n }\n\n // ── Render ────────────────────────────────────────────────────────────\n\n const heightClass = isKpi ? 'h-32' : 'h-[320px]'\n\n const resolvedLabels = data?.resolvedLabels\n const seriesLabel = React.useCallback(\n (key: string): string => {\n if (key === '__total__') return t('dashboard:seriesTotal')\n if (key === '__other__') return t('dashboard:seriesOther')\n if (key === '__null__') return t('dashboard:seriesNull')\n return resolvedLabels?.[key] ?? key\n },\n [resolvedLabels, t],\n )\n\n const valueFormatter = React.useMemo(\n () => makeValueFormatter(config.format, locale),\n [config.format, locale],\n )\n const axisValueFormatter = React.useMemo(\n () => makeAxisFormatter(config.format, locale),\n [config.format, locale],\n )\n\n const chartSeries = React.useMemo(() => {\n const primary = transformSeries(\n prepareSeries(data?.series ?? [], range, renderStep, seriesLabel),\n config.transform,\n ).map((s) => {\n const color = config.series?.[s.key]?.color\n return color ? { ...s, color } : s\n })\n if (!compareActive || !data?.previous?.length) return primary\n const prevRange = serverPreviousRangeOf(range)\n if (!prevRange) return primary\n const currentBuckets = generateBuckets(range.from, range.to, renderStep)\n const overlays = transformSeries(\n alignPreviousSeries(data.previous, prevRange, currentBuckets, renderStep),\n config.transform,\n ).map((s) => ({\n key: s.key,\n label: t('dashboard:widget.previousSeries').replace(\n '{label}',\n seriesLabel(s.sourceKey),\n ),\n points: s.points,\n dashed: true,\n hiddenWith: s.sourceKey,\n }))\n return [...primary, ...overlays]\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n data?.series,\n data?.previous,\n range.from,\n range.to,\n renderStep,\n seriesLabel,\n compareActive,\n config.transform,\n config.series,\n t,\n ])\n\n // Period-over-period delta on raw (pre-transform) totals.\n const delta = React.useMemo(\n () =>\n compareActive && data\n ? computeDelta(sumSeries(data.series), sumSeries(data.previous))\n : null,\n [compareActive, data],\n )\n\n const [colorsOpen, setColorsOpen] = React.useState(false)\n // Effective colors for the dialog rows: override or palette by index\n // among primary (non-dashed) series — matches TimeSeriesChart's slots.\n const colorItems = React.useMemo(() => {\n const primary = chartSeries.filter((s) => !('dashed' in s) || !s.dashed)\n const palette = paletteFor(primary.length)\n return primary.map((s, i) => ({\n key: s.key,\n label: s.label,\n override: config.series?.[s.key]?.color,\n auto: palette[i]!,\n }))\n }, [chartSeries, config.series])\n\n const saveSeriesColors = (overrides: Record<string, string>): void => {\n // Preserve overrides for series not currently rendered (other windows /\n // filters may surface different groupBy values).\n const next: Record<string, { color?: string }> = { ...config.series }\n for (const item of colorItems) delete next[item.key]\n for (const [key, color] of Object.entries(overrides)) next[key] = { color }\n update({ series: next })\n setColorsOpen(false)\n }\n\n // Adapter cannot do time-series — friendly message, no toolbar churn.\n const unsupported = data && data.supported === false\n\n return (\n <Card className=\"flex flex-col\">\n <CardHeader className=\"flex flex-row items-center justify-between gap-2 p-3 pb-2 space-y-0 sm:p-6 sm:pb-2\">\n <CardTitle className=\"flex min-w-0 items-center gap-2 text-sm font-medium pr-2\">\n <span className=\"truncate\">{config.title || t('chart:untitled')}</span>\n {delta && (\n <span\n title={t('dashboard:widget.previousPeriod')}\n className={`inline-flex shrink-0 items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-medium tabular-nums ${\n delta.direction === 'up'\n ? 'bg-emerald-500/10 text-emerald-600 dark:text-emerald-400'\n : delta.direction === 'down'\n ? 'bg-rose-500/10 text-rose-600 dark:text-rose-400'\n : 'bg-muted text-muted-foreground'\n }`}\n >\n {delta.direction === 'up' ? (\n <ArrowUp className=\"size-3\" />\n ) : delta.direction === 'down' ? (\n <ArrowDown className=\"size-3\" />\n ) : null}\n {Math.abs(delta.percent)}%\n </span>\n )}\n </CardTitle>\n <div className=\"flex items-center gap-1 shrink-0\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7\"\n onClick={onWidthToggle}\n aria-label={\n config.width === 'full'\n ? t('dashboard:widget.shrink')\n : t('dashboard:widget.expand')\n }\n >\n {config.width === 'full' ? (\n <Minimize2 className=\"size-3.5\" />\n ) : (\n <Maximize2 className=\"size-3.5\" />\n )}\n </Button>\n {data?.sql && (\n <Button\n variant={showSql ? 'secondary' : 'ghost'}\n size=\"icon\"\n className=\"size-7\"\n onClick={() => setShowSql((v) => !v)}\n aria-label={t('dashboard:widget.toggleSql')}\n >\n <Code className=\"size-3.5\" />\n </Button>\n )}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('common:refresh')}\n >\n <RefreshCw className={`size-3.5 ${isFetching ? 'animate-spin' : ''}`} />\n </Button>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7\"\n aria-label={t('common:openMenu')}\n >\n <MoreHorizontal className=\"size-3.5\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={onEdit}>\n <Pencil className=\"size-4 mr-2\" />\n {t('chart:editChart')}\n </DropdownMenuItem>\n {!isKpi && (\n <DropdownMenuItem onClick={() => setColorsOpen(true)}>\n <Palette className=\"size-4 mr-2\" />\n {t('dashboard:widget.editColors')}\n </DropdownMenuItem>\n )}\n {onMove && (\n <DropdownMenuItem onClick={onMove}>\n <FolderSymlink className=\"size-4 mr-2\" />\n {t('chart:moveToGroup')}\n </DropdownMenuItem>\n )}\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={onDelete}\n className=\"text-destructive focus:text-destructive\"\n >\n <Trash2 className=\"size-4 mr-2\" />\n {t('chart:deleteChart')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </CardHeader>\n\n <CardContent className=\"flex-1 p-3 pt-0 space-y-3 sm:p-6 sm:pt-0\">\n {/* Quick filters — compact inline row, label as placeholder, Apply on the right. */}\n {!unsupported && quickFilterPaths.length > 0 && resourceConfig && (\n <div className=\"flex flex-wrap items-center gap-2\">\n {quickFilterPaths.map((path) => {\n const prop = resourceConfig.properties.find((p) => p.path === path)\n if (!prop) return null\n return (\n <QuickFilterInput\n key={path}\n property={prop}\n placeholder={prop.label}\n value={draftFilters[path] ?? ''}\n onChange={(v) => setDraftFilters((prev) => ({ ...prev, [path]: v }))}\n />\n )\n })}\n <Button\n size=\"sm\"\n className=\"h-8 px-3 text-xs shrink-0\"\n onClick={applyQuickFilters}\n disabled={!draftDirty}\n >\n <Check className=\"size-3.5 mr-1\" />\n {t('common:apply')}\n </Button>\n </div>\n )}\n\n {/* Toolbar — step + range + window display. Hidden for unsupported\n adapters because changing knobs would have no effect. */}\n {!unsupported && (\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-muted-foreground\">\n {!isKpi && (\n <Select\n value={config.step === 'all' ? 'day' : config.step}\n onValueChange={(v) => onStepChange(v as AggregationStep)}\n >\n <SelectTrigger\n className=\"h-8 px-2 text-xs w-auto\"\n aria-label={t('chart:step')}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STEPS.map((s) => (\n <SelectItem key={s} value={s}>\n {t(`chart:step${cap(s)}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <Select\n value={config.timeRange.preset}\n onValueChange={(v) => onPresetChange(v as TimeRangePreset)}\n >\n <SelectTrigger\n className=\"h-8 px-2 text-xs w-auto\"\n aria-label={t('dashboard:builder.range')}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {PRESETS.map((p) => (\n <SelectItem key={p} value={p}>\n {t(`dashboard:range.${p}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {config.timeRange.preset === 'custom' ? (\n <>\n <DatePicker\n value={draftFrom}\n onChange={setDraftFrom}\n ariaLabel={t('common:from')}\n openCalendarLabel={t('common:openCalendar')}\n className=\"w-[130px]\"\n inputClassName=\"h-8 text-xs\"\n />\n <span className=\"text-muted-foreground\">—</span>\n <DatePicker\n value={draftTo}\n onChange={setDraftTo}\n ariaLabel={t('common:to')}\n openCalendarLabel={t('common:openCalendar')}\n className=\"w-[130px]\"\n inputClassName=\"h-8 text-xs\"\n />\n <Button\n size=\"sm\"\n className=\"h-8 px-3 shrink-0\"\n onClick={applyCustomRange}\n disabled={!draftFrom || !draftTo}\n aria-label={t('common:apply')}\n >\n <Check className=\"size-3.5 mr-1\" />\n {t('common:apply')}\n </Button>\n </>\n ) : (\n <span className=\"ml-auto tabular-nums\">\n {range.from} — {range.to}\n </span>\n )}\n </div>\n )}\n\n {/* Truncation warning — adapter capped the scan, so the chart reflects\n only a subset of the window. Hidden while loading / unsupported. */}\n {!unsupported && !isError && data?.truncated && (\n <div className=\"flex items-start gap-2 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2 text-xs text-amber-700 dark:text-amber-400\">\n <AlertTriangle className=\"size-3.5 mt-0.5 shrink-0\" />\n <span>{t('dashboard:widget.truncatedWarning')}</span>\n </div>\n )}\n\n {/* Body */}\n {isLoading ? (\n <Skeleton className={`${heightClass} w-full rounded-md`} />\n ) : isError ? (\n <div\n className={`flex items-center justify-center text-sm text-muted-foreground ${heightClass}`}\n >\n {t('chart:loadError')}\n </div>\n ) : unsupported ? (\n <div\n className={`flex items-center justify-center text-center text-sm text-muted-foreground px-4 ${heightClass}`}\n >\n {t('dashboard:widget.unsupported')}\n </div>\n ) : isKpi ? (\n <KpiBody\n data={data}\n transform={config.transform}\n formatNumber={valueFormatter}\n labels={kpiLabels(t)}\n />\n ) : (\n <TimeSeriesChart\n series={chartSeries}\n height={320}\n visualisation={config.visualisation === 'kpi' ? undefined : config.visualisation}\n tickFormatter={makeTickFormatter(renderStep, locale)}\n labelFormatter={makeLabelFormatter(renderStep, locale)}\n valueFormatter={valueFormatter}\n axisValueFormatter={axisValueFormatter}\n labels={{\n noData: t('chart:noData'),\n showAll: t('dashboard:widget.showAll'),\n hideAll: t('dashboard:widget.hideAll'),\n }}\n />\n )}\n\n {/* Captured SQL — only when the user toggled and server returned it. */}\n {data?.sql && showSql && (\n <div className=\"relative\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"absolute top-1 right-1 size-6\"\n onClick={() => {\n void navigator.clipboard.writeText(data.sql ?? '')\n setSqlCopied(true)\n setTimeout(() => setSqlCopied(false), 2000)\n }}\n aria-label={sqlCopied ? t('common:copied') : t('common:copy')}\n >\n {sqlCopied\n ? <Check className=\"size-3 text-green-500\" />\n : <Copy className=\"size-3\" />}\n </Button>\n <pre className=\"text-[11px] leading-snug bg-muted/50 border border-border rounded-md p-2 pr-8 overflow-x-auto whitespace-pre\">\n {data.sql}\n </pre>\n </div>\n )}\n </CardContent>\n\n {colorsOpen && (\n <ChartSeriesColorsDialog\n items={colorItems}\n onSave={saveSeriesColors}\n onClose={() => setColorsOpen(false)}\n />\n )}\n </Card>\n )\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────\n\nconst cap = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1)\n\nconst QF_NONE = '__none__'\n\nfunction seedDraftFilters(\n paths: ReadonlyArray<string>,\n filters: Record<string, string>,\n): Record<string, string> {\n const out: Record<string, string> = {}\n for (const p of paths) out[p] = filters[p] ?? ''\n return out\n}\n\n/** Compact inline filter input — label is passed as placeholder so no\n * extra row is needed. Matches the `h-7 text-xs` sizing of toolbar controls. */\nfunction QuickFilterInput({\n property,\n placeholder,\n value,\n onChange,\n}: {\n property: PropertyJSON\n placeholder?: string\n value: string\n onChange(next: string): void\n}): React.ReactElement {\n const ph = placeholder ?? property.label\n if (property.reference) {\n return (\n <div className=\"w-36\">\n <ReferenceCombobox\n referenceResourceId={property.reference}\n value={value || null}\n onChange={(next) => onChange(next == null ? '' : String(next))}\n placeholder={ph}\n className=\"h-8 text-xs\"\n />\n </div>\n )\n }\n if (property.availableValues && property.availableValues.length > 0) {\n return (\n <Select\n value={value || QF_NONE}\n onValueChange={(v) => onChange(v === QF_NONE ? '' : v)}\n >\n <SelectTrigger className=\"h-8 px-2 text-xs w-36\">\n <SelectValue placeholder={ph} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={QF_NONE}>{ph}</SelectItem>\n {property.availableValues.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n }\n if (property.type === 'boolean') {\n return (\n <Select\n value={value || QF_NONE}\n onValueChange={(v) => onChange(v === QF_NONE ? '' : v)}\n >\n <SelectTrigger className=\"h-8 px-2 text-xs w-36\">\n <SelectValue placeholder={ph} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={QF_NONE}>{ph}</SelectItem>\n <SelectItem value=\"true\">true</SelectItem>\n <SelectItem value=\"false\">false</SelectItem>\n </SelectContent>\n </Select>\n )\n }\n const isNumeric =\n property.type === 'number' || property.type === 'float' || property.type === 'currency'\n return (\n <Input\n type={isNumeric ? 'number' : 'text'}\n className=\"h-8 px-2 text-xs w-36\"\n value={value}\n placeholder={ph}\n onChange={(e) => onChange(e.target.value)}\n />\n )\n}\n\n/**\n * Zero-fill every series across the resolved date range and re-tag each\n * with its display label (so legend shows \"Total\" / \"Other\" / actual\n * groupBy values rather than the wire-format internal keys).\n */\nfunction prepareSeries(\n series: ReadonlyArray<TimeSeriesSeries>,\n range: { from: string; to: string },\n step: AggregationStep,\n labelFor: (key: string) => string,\n): { key: string; label: string; points: { date: string; value: number }[] }[] {\n const filled = fillTimeSeries(\n series.map((s) => ({ key: s.key, points: s.points })),\n range.from,\n range.to,\n step as Exclude<AggregationStep, 'all'> | 'all',\n )\n return filled.map((s) => ({\n key: s.key,\n label: labelFor(s.key),\n points: [...s.points],\n }))\n}\n\ninterface KpiBodyProps {\n data: { series: ReadonlyArray<TimeSeriesSeries>; previous?: ReadonlyArray<TimeSeriesSeries> } | undefined\n transform: ReadonlyArray<ChartTransformStep>\n formatNumber: (n: number) => string\n labels: {\n noData: string\n deltaUp: string\n deltaDown: string\n deltaFlat: string\n previousPeriod: string\n }\n}\n\n/** KPI mode summarises the single-bucket response to one scalar. The value\n * transform applies to both windows so the delta stays consistent. */\nfunction KpiBody({ data, transform, formatNumber, labels }: KpiBodyProps): React.ReactElement {\n const raw = sumAll(data?.series)\n const rawPrev = sumAll(data?.previous)\n const value = raw == null ? raw : applyTransform(raw, transform)\n const prev = rawPrev == null ? rawPrev : applyTransform(rawPrev, transform)\n return (\n <KpiCard\n value={value}\n previousValue={prev}\n formatNumber={formatNumber}\n labels={labels}\n />\n )\n}\n\nfunction sumAll(series: ReadonlyArray<TimeSeriesSeries> | undefined): number | null {\n if (!series || series.length === 0) return null\n let total = 0\n for (const s of series) for (const p of s.points) total += p.value\n return total\n}\n\nfunction kpiLabels(t: (key: string) => string): {\n noData: string\n deltaUp: string\n deltaDown: string\n deltaFlat: string\n previousPeriod: string\n} {\n return {\n noData: t('chart:noData'),\n deltaUp: t('dashboard:widget.deltaUp'),\n deltaDown: t('dashboard:widget.deltaDown'),\n deltaFlat: t('dashboard:widget.deltaFlat'),\n previousPeriod: t('dashboard:widget.previousPeriod'),\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"chart-widget-BtJb6YXV.js","names":[],"sources":["../../../../react/src/dashboard/time-series.ts","../../../../react/src/dashboard/compare.ts","../../../../react/src/components/chart-series-colors-dialog.tsx","../../../../react/src/components/chart-widget.tsx"],"sourcesContent":["// Time-series UI helpers — bucket fill, tick formatting, label formatting.\n// All zero-fill happens here on the client side (req: \"Заполнение нулями\n// должно быть только в ui, вне зависимости от адаптеров\"). Adapters return\n// only buckets that have data; the UI fabricates the rest at value 0 so\n// charts don't have visual gaps.\n\nimport type {\n TimeSeriesPoint,\n TimeSeriesSeries,\n TimeSeriesStep,\n} from '../client.js'\n\n/** Generate a continuous sequence of `YYYY-MM-DD` bucket keys spanning [from, to]. */\nexport function generateBuckets(\n fromIso: string,\n toIso: string,\n step: TimeSeriesStep,\n): string[] {\n if (step === 'all') return [fromIso.slice(0, 10)]\n const out: string[] = []\n const cur = startOf(new Date(fromIso), step)\n const end = startOf(new Date(toIso), step)\n while (cur.getTime() <= end.getTime()) {\n out.push(ymd(cur))\n advance(cur, step)\n }\n return out\n}\n\n/**\n * Zero-fill every series so each one has a value for every bucket in the\n * resolved date range. Missing buckets become `value: 0` rather than gaps,\n * which Recharts renders as flat segments instead of breaks.\n */\nexport function fillTimeSeries(\n series: TimeSeriesSeries[],\n fromIso: string,\n toIso: string,\n step: TimeSeriesStep,\n): TimeSeriesSeries[] {\n const buckets = generateBuckets(fromIso, toIso, step)\n return series.map((s) => {\n const map = new Map(s.points.map((p) => [p.date, p.value]))\n const points: TimeSeriesPoint[] = buckets.map((date) => ({\n date,\n value: map.get(date) ?? 0,\n }))\n return { key: s.key, points }\n })\n}\n\n/**\n * X-axis tick formatter — short label format depending on bucket size.\n * day/week → DD.MM, month → MM.YYYY, year → YYYY.\n */\nexport function makeTickFormatter(\n step: TimeSeriesStep,\n locale = 'en-US',\n): (iso: string) => string {\n const dayMonth = new Intl.DateTimeFormat(locale, { day: '2-digit', month: '2-digit' })\n const monthYear = new Intl.DateTimeFormat(locale, { month: '2-digit', year: 'numeric' })\n const year = new Intl.DateTimeFormat(locale, { year: 'numeric' })\n return (iso: string): string => {\n const d = new Date(iso)\n if (step === 'year') return year.format(d)\n if (step === 'month') return monthYear.format(d)\n return dayMonth.format(d)\n }\n}\n\n/**\n * Tooltip label formatter — long, human-friendly form. For week buckets\n * we render `Mon DD – Sun DD` (the bucket plus 6 days).\n */\nexport function makeLabelFormatter(\n step: TimeSeriesStep,\n locale = 'en-US',\n): (iso: string) => string {\n const fullDay = new Intl.DateTimeFormat(locale, {\n day: '2-digit',\n month: 'long',\n year: 'numeric',\n })\n const monthYear = new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric' })\n const year = new Intl.DateTimeFormat(locale, { year: 'numeric' })\n const shortDay = new Intl.DateTimeFormat(locale, { day: '2-digit', month: 'short' })\n return (iso: string): string => {\n const d = new Date(iso)\n if (step === 'year') return year.format(d)\n if (step === 'month') return monthYear.format(d)\n if (step === 'week') {\n const end = new Date(d)\n end.setDate(end.getDate() + 6)\n return `${shortDay.format(d)} – ${shortDay.format(end)}`\n }\n return fullDay.format(d)\n }\n}\n\n// ─── Internals ────────────────────────────────────────────────────────────\n\nfunction ymd(d: Date): string {\n return d.toISOString().slice(0, 10)\n}\n\nfunction startOf(d: Date, step: TimeSeriesStep): Date {\n const out = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()))\n if (step === 'week') {\n // Monday-anchored week.\n const dow = (out.getUTCDay() + 6) % 7\n out.setUTCDate(out.getUTCDate() - dow)\n } else if (step === 'month') {\n out.setUTCDate(1)\n } else if (step === 'year') {\n out.setUTCMonth(0, 1)\n }\n return out\n}\n\nfunction advance(d: Date, step: TimeSeriesStep): void {\n if (step === 'day') d.setUTCDate(d.getUTCDate() + 1)\n else if (step === 'week') d.setUTCDate(d.getUTCDate() + 7)\n else if (step === 'month') d.setUTCMonth(d.getUTCMonth() + 1)\n else if (step === 'year') d.setUTCFullYear(d.getUTCFullYear() + 1)\n}\n","// Previous-period comparison helpers for dashboard charts.\n//\n// The adapters compute the previous window as `prevTo = from`,\n// `prevFrom = from − (to − from)` where the wire `from`/`to` are\n// start-of-day / end-of-day instants. In whole-day terms that is the\n// N-day window ending the day before the current one starts — which is\n// what `serverPreviousRangeOf` reproduces so client-side zero-fill and\n// tooltips agree with the buckets the server actually returns. (The\n// degenerate 1 ms boundary bucket at `from` itself is dropped.)\n\nimport type { TimeSeriesSeries, TimeSeriesStep } from '../client.js'\nimport { generateBuckets } from './time-series.js'\n\n/** Prefix marking overlay series produced from the previous window. */\nexport const PREVIOUS_KEY_PREFIX = '__prev__:'\n\nexport interface AlignedPreviousPoint {\n /** Current-window bucket the point is plotted on. */\n date: string\n value: number\n /** Real previous-window bucket the value came from (for tooltips). */\n sourceDate?: string\n}\n\nexport interface AlignedPreviousSeries {\n key: string\n /** Key of the paired current-window series (`__total__`, …). */\n sourceKey: string\n points: AlignedPreviousPoint[]\n}\n\n/**\n * Whole-day previous window matching the adapters' formula: for a current\n * window of N days `[from, to]`, returns `[from − N, from − 1]`.\n */\nexport function serverPreviousRangeOf(range: {\n from: string\n to: string\n}): { from: string; to: string } | null {\n const f = Date.parse(`${range.from}T00:00:00.000Z`)\n const t = Date.parse(`${range.to}T00:00:00.000Z`)\n if (Number.isNaN(f) || Number.isNaN(t) || t < f) return null\n const days = Math.round((t - f) / 86_400_000) + 1\n return {\n from: ymd(new Date(f - days * 86_400_000)),\n to: ymd(new Date(f - 86_400_000)),\n }\n}\n\n/**\n * Zero-fill the previous window and re-plot each point onto the current\n * window's bucket axis (point *i* → `currentBuckets[i]`), keeping the real\n * date in `sourceDate`. When bucket counts differ (step-aligned month/week\n * windows drift by ±1) the series are aligned on their END — \"yesterday\n * lines up with yesterday\" — and leading gaps become zeros.\n */\nexport function alignPreviousSeries(\n previous: ReadonlyArray<TimeSeriesSeries>,\n prevRange: { from: string; to: string },\n currentBuckets: ReadonlyArray<string>,\n step: TimeSeriesStep,\n): AlignedPreviousSeries[] {\n if (currentBuckets.length === 0) return []\n const prevBuckets = generateBuckets(prevRange.from, prevRange.to, step)\n const offset = currentBuckets.length - prevBuckets.length\n return previous.map((s) => {\n const map = new Map(s.points.map((p) => [p.date, p.value]))\n const points: AlignedPreviousPoint[] = currentBuckets.map((date, i) => {\n const src = prevBuckets[i - offset]\n return src === undefined\n ? { date, value: 0 }\n : { date, value: map.get(src) ?? 0, sourceDate: src }\n })\n return { key: `${PREVIOUS_KEY_PREFIX}${s.key}`, sourceKey: s.key, points }\n })\n}\n\n/** Total across all points of all series (raw, pre-transform values). */\nexport function sumSeries(\n series: ReadonlyArray<TimeSeriesSeries> | undefined,\n): number | null {\n if (!series || series.length === 0) return null\n let total = 0\n for (const s of series) for (const p of s.points) total += p.value\n return total\n}\n\nexport interface PeriodDelta {\n /** Signed percentage, one decimal place (e.g. -81.7). */\n percent: number\n direction: 'up' | 'down' | 'flat'\n}\n\n/**\n * Period-over-period delta on raw totals: `(cur − prev) / prev`. Returns\n * null when the previous total is missing or 0 (undefined percentage).\n */\nexport function computeDelta(\n current: number | null,\n previous: number | null,\n): PeriodDelta | null {\n if (current == null || previous == null || previous === 0) return null\n const percent = Math.round(((current - previous) / Math.abs(previous)) * 1000) / 10\n return {\n percent,\n direction: percent > 0 ? 'up' : percent < 0 ? 'down' : 'flat',\n }\n}\n\nconst ymd = (d: Date): string => d.toISOString().slice(0, 10)\n","// Per-series color override dialog for a dashboard chart. Opened from the\n// widget \"…\" menu so it can list the series actually rendered (groupBy\n// values are only known once data is loaded). Lives in the react package\n// because it is i18n-aware; primitives come from @modern-admin/ui.\n\nimport * as React from 'react'\nimport {\n Button,\n ColorSwatchPicker,\n CHART_COLOR_PRESETS,\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@modern-admin/ui'\nimport { useI18n } from '../i18n.js'\n\nexport interface SeriesColorItem {\n /** Stable series key (`__total__`, groupBy value, …). */\n key: string\n /** Display label (legend text). */\n label: string\n /** Persisted override, if any. */\n override?: string\n /** Palette color used when no override is set — shown as the row swatch. */\n auto: string\n}\n\nexport interface ChartSeriesColorsDialogProps {\n items: ReadonlyArray<SeriesColorItem>\n /** Receives only the overrides (key → hex); auto rows are omitted. */\n onSave(overrides: Record<string, string>): void\n onClose(): void\n}\n\nexport function ChartSeriesColorsDialog({\n items,\n onSave,\n onClose,\n}: ChartSeriesColorsDialogProps): React.ReactElement {\n const { t } = useI18n()\n const [draft, setDraft] = React.useState<Record<string, string | undefined>>(\n () => Object.fromEntries(items.map((i) => [i.key, i.override])),\n )\n\n const handleSave = (): void => {\n const overrides: Record<string, string> = {}\n for (const [key, color] of Object.entries(draft)) {\n if (color) overrides[key] = color\n }\n onSave(overrides)\n }\n\n return (\n <Dialog open onOpenChange={(open) => { if (!open) onClose() }}>\n <DialogContent className=\"w-full max-w-lg\">\n <DialogHeader>\n <DialogTitle>{t('dashboard:widget.colorsTitle')}</DialogTitle>\n </DialogHeader>\n\n <div className=\"max-h-[60vh] space-y-4 overflow-y-auto py-1\">\n {items.map((item) => (\n <div key={item.key} className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2 text-sm\">\n <span\n className=\"size-3 shrink-0 rounded-full\"\n style={{ backgroundColor: draft[item.key] ?? item.auto }}\n />\n <span className=\"truncate font-medium\">{item.label}</span>\n </div>\n <ColorSwatchPicker\n value={draft[item.key]}\n onChange={(next) =>\n setDraft((prev) => ({ ...prev, [item.key]: next }))\n }\n presets={CHART_COLOR_PRESETS}\n labels={{\n custom: t('dashboard:widget.colorCustom'),\n pick: t('dashboard:widget.colorPick'),\n auto: t('dashboard:widget.colorAuto'),\n }}\n />\n </div>\n ))}\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={onClose}>{t('common:cancel')}</Button>\n <Button onClick={handleSave}>{t('common:save')}</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","// Dashboard tile rendering one ChartDef. Phase 10 brings:\n// • Per-widget toolbar (step / range / width / SQL toggle) — changes persist\n// via `onUpdate` so a tweak survives reload without re-opening the builder.\n// • Time-series chart (date X-axis, value Y-axis) with multi-series via\n// secondary `groupBy`. Zero-fill happens UI-side regardless of adapter.\n// • KPI mode = `step: 'all'` — sums the single bucket and shows period-over-\n// period delta.\n// • Graceful degradation when the adapter cannot do time-series aggregation\n// (e.g. non-relational DB) — shows a friendly message instead of erroring.\n\nimport * as React from 'react'\nimport {\n MoreHorizontal,\n Pencil,\n Trash2,\n RefreshCw,\n Maximize2,\n Minimize2,\n Code,\n Copy,\n Check,\n FolderSymlink,\n AlertTriangle,\n ArrowUp,\n ArrowDown,\n Palette,\n} from 'lucide-react'\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n TimeSeriesChart,\n KpiCard,\n DatePicker,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Button,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Skeleton,\n paletteFor,\n} from '@modern-admin/ui'\nimport { ReferenceCombobox } from '../reference.js'\nimport type { PropertyJSON } from '../types.js'\nimport type {\n ChartDef,\n ChartDefInput,\n AggregationStep,\n ChartWidth,\n TimeRange,\n TimeRangePreset,\n} from '@modern-admin/core'\nimport { useTimeSeries, useResource } from '../hooks.js'\nimport { useI18n } from '../i18n.js'\nimport { resolveRange } from '../use-dashboard-charts.js'\nimport {\n fillTimeSeries,\n generateBuckets,\n makeLabelFormatter,\n makeTickFormatter,\n} from '../dashboard/time-series.js'\nimport {\n applyTransform,\n transformSeries,\n makeValueFormatter,\n makeAxisFormatter,\n} from '../dashboard/value-format.js'\nimport {\n alignPreviousSeries,\n serverPreviousRangeOf,\n sumSeries,\n computeDelta,\n} from '../dashboard/compare.js'\nimport { ChartSeriesColorsDialog } from './chart-series-colors-dialog.js'\nimport type { TimeSeriesQuery, TimeSeriesSeries } from '../client.js'\nimport type { ChartTransformStep } from '@modern-admin/core'\n\nconst PRESETS: TimeRangePreset[] = ['7d', '30d', '90d', '1y', 'all', 'custom']\nconst STEPS: Exclude<AggregationStep, 'all'>[] = ['day', 'week', 'month', 'year']\n\nexport interface ChartWidgetProps {\n config: ChartDef\n onEdit(): void\n onDelete(): void\n onMove?(): void\n /** Called when the user tweaks step / range / width directly on the widget. */\n onUpdate(input: ChartDefInput): void\n}\n\nexport function ChartWidget({\n config,\n onEdit,\n onDelete,\n onMove,\n onUpdate,\n}: ChartWidgetProps): React.ReactElement {\n const { t, locale } = useI18n()\n\n const isKpi = config.visualisation === 'kpi'\n // KPI charts force `step: 'all'`; the schema enforces this at save time.\n // For very wide presets, automatically coarsen granularity so the point\n // count stays manageable — 3650 daily buckets for 'all' would render an\n // unreadable axis and cause significant memory pressure in Recharts.\n const renderStep: AggregationStep =\n isKpi ? 'all'\n : config.timeRange.preset === 'all' && (config.step === 'day' || config.step === 'week') ? 'month'\n : config.timeRange.preset === '1y' && config.step === 'day' ? 'week'\n : config.step\n\n // Resolve the time-range preset to concrete from/to per render so cards\n // automatically reflect \"now\" as days roll over without re-saving.\n const range = React.useMemo(() => resolveRange(config.timeRange), [config.timeRange])\n\n // Previous-period overlay is only meaningful without a breakdown: top-N is\n // computed independently per window, so grouped series keys aren't stable.\n const compareActive = !isKpi && config.comparePrevious === true && !config.groupBy\n\n // If the saved ChartDef pre-dates the groupByLabelResource feature (i.e.,\n // groupBy is set but groupByLabelResource is not), derive it from the\n // resource's property metadata so labels resolve without requiring a re-save.\n const resourceConfig = useResource(config.resource)\n const effectiveLabelResource = React.useMemo(() => {\n if (config.groupByLabelResource) return config.groupByLabelResource\n if (!config.groupBy || !resourceConfig) return undefined\n const props = resourceConfig.properties\n const prop = props.find((p) => p.path === config.groupBy)\n if (!prop) return undefined\n if (prop.reference) return prop.reference\n // FK heuristic: strip Id / _id suffix and look for a sibling reference prop.\n const base = prop.path.endsWith('_id')\n ? prop.path.slice(0, -3)\n : prop.path.endsWith('Id')\n ? prop.path.slice(0, -2)\n : ''\n if (base) {\n const sibling = props.find((p) => p.path === base && p.reference)\n if (sibling?.reference) return sibling.reference\n }\n return undefined\n }, [config.groupBy, config.groupByLabelResource, resourceConfig])\n\n const query = React.useMemo<TimeSeriesQuery>(\n () => ({\n resource: config.resource,\n dateField: config.dateField,\n step: renderStep as TimeSeriesQuery['step'],\n metric: config.metric,\n from: range.from,\n to: range.to,\n ...(config.field ? { field: config.field } : {}),\n ...(!isKpi && config.groupBy ? { groupBy: config.groupBy } : {}),\n ...(!isKpi && config.groupBy ? { topN: config.topN } : {}),\n ...(!isKpi && config.groupBy && effectiveLabelResource\n ? { groupByLabelResource: effectiveLabelResource }\n : {}),\n ...(Object.keys(config.filters).length ? { filters: config.filters } : {}),\n ...(isKpi || compareActive ? { comparePrevious: true as const } : {}),\n }),\n [config, range, isKpi, compareActive, renderStep, effectiveLabelResource],\n )\n\n const { data, isLoading, isError, refetch, isFetching } = useTimeSeries(query)\n\n const [showSql, setShowSql] = React.useState(false)\n const [sqlCopied, setSqlCopied] = React.useState(false)\n\n // Draft from/to — only committed when the user clicks Apply.\n // Seeded from `config.timeRange` when preset changes to 'custom'.\n const [draftFrom, setDraftFrom] = React.useState(range.from)\n const [draftTo, setDraftTo] = React.useState(range.to)\n\n // Draft state for quick filters exposed above the chart. The user tweaks\n // values inline and clicks Apply to refetch — mirroring the custom-range\n // pattern so widgets don't refetch on every keystroke.\n const quickFilterPaths = config.quickFilters ?? []\n const [draftFilters, setDraftFilters] = React.useState<Record<string, string>>(\n () => seedDraftFilters(quickFilterPaths, config.filters),\n )\n // Re-seed whenever the saved chart definition changes externally.\n const quickFiltersKey = quickFilterPaths.join('|')\n const savedFiltersKey = React.useMemo(\n () =>\n Object.entries(config.filters)\n .map(([k, v]) => `${k}=${v}`)\n .sort()\n .join('|'),\n [config.filters],\n )\n React.useEffect(() => {\n setDraftFilters(seedDraftFilters(quickFilterPaths, config.filters))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [quickFiltersKey, savedFiltersKey])\n\n const applyQuickFilters = (): void => {\n const next: Record<string, string> = { ...config.filters }\n for (const p of quickFilterPaths) {\n const v = draftFilters[p] ?? ''\n if (v === '') delete next[p]\n else next[p] = v\n }\n update({ filters: next })\n }\n\n const draftDirty = quickFilterPaths.some(\n (p) => (draftFilters[p] ?? '') !== (config.filters[p] ?? ''),\n )\n\n // Mutators — persisted by the parent via `onUpdate(updatedDef)`.\n const update = (patch: Partial<ChartDefInput>): void => {\n onUpdate({ ...config, ...patch, updatedAt: new Date().toISOString() })\n }\n\n const onPresetChange = (preset: TimeRangePreset): void => {\n if (preset === 'custom') {\n // Seed draft with the currently resolved window — user can then narrow\n // it and click Apply without triggering an immediate refetch.\n setDraftFrom(range.from)\n setDraftTo(range.to)\n update({\n timeRange: { preset: 'custom', from: range.from, to: range.to } as TimeRange,\n })\n } else {\n update({ timeRange: { preset } as TimeRange })\n }\n }\n\n const applyCustomRange = (): void => {\n if (draftFrom && draftTo) {\n update({\n timeRange: { preset: 'custom', from: draftFrom, to: draftTo } as TimeRange,\n })\n }\n }\n\n const onStepChange = (step: AggregationStep): void => {\n if (step === 'all') return // KPI is selected via the builder, not the toolbar\n update({ step })\n }\n\n const onWidthToggle = (): void => {\n update({ width: (config.width === 'full' ? 'half' : 'full') as ChartWidth })\n }\n\n // ── Render ────────────────────────────────────────────────────────────\n\n const heightClass = isKpi ? 'h-32' : 'h-[320px]'\n\n const resolvedLabels = data?.resolvedLabels\n const seriesLabel = React.useCallback(\n (key: string): string => {\n if (key === '__total__') return t('dashboard:seriesTotal')\n if (key === '__other__') return t('dashboard:seriesOther')\n if (key === '__null__') return t('dashboard:seriesNull')\n return resolvedLabels?.[key] ?? key\n },\n [resolvedLabels, t],\n )\n\n const valueFormatter = React.useMemo(\n () => makeValueFormatter(config.format, locale),\n [config.format, locale],\n )\n const axisValueFormatter = React.useMemo(\n () => makeAxisFormatter(config.format, locale),\n [config.format, locale],\n )\n\n const chartSeries = React.useMemo(() => {\n const primary = transformSeries(\n prepareSeries(data?.series ?? [], range, renderStep, seriesLabel),\n config.transform,\n ).map((s) => {\n const color = config.series?.[s.key]?.color\n return color ? { ...s, color } : s\n })\n if (!compareActive || !data?.previous?.length) return primary\n const prevRange = serverPreviousRangeOf(range)\n if (!prevRange) return primary\n const currentBuckets = generateBuckets(range.from, range.to, renderStep)\n const overlays = transformSeries(\n alignPreviousSeries(data.previous, prevRange, currentBuckets, renderStep),\n config.transform,\n ).map((s) => ({\n key: s.key,\n label: t('dashboard:widget.previousSeries').replace(\n '{label}',\n seriesLabel(s.sourceKey),\n ),\n points: s.points,\n dashed: true,\n hiddenWith: s.sourceKey,\n }))\n return [...primary, ...overlays]\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n data?.series,\n data?.previous,\n range.from,\n range.to,\n renderStep,\n seriesLabel,\n compareActive,\n config.transform,\n config.series,\n t,\n ])\n\n // Period-over-period delta on raw (pre-transform) totals.\n const delta = React.useMemo(\n () =>\n compareActive && data\n ? computeDelta(sumSeries(data.series), sumSeries(data.previous))\n : null,\n [compareActive, data],\n )\n\n const [colorsOpen, setColorsOpen] = React.useState(false)\n // Effective colors for the dialog rows: override or palette by index\n // among primary (non-dashed) series — matches TimeSeriesChart's slots.\n const colorItems = React.useMemo(() => {\n const primary = chartSeries.filter((s) => !('dashed' in s) || !s.dashed)\n const palette = paletteFor(primary.length)\n return primary.map((s, i) => ({\n key: s.key,\n label: s.label,\n override: config.series?.[s.key]?.color,\n auto: palette[i]!,\n }))\n }, [chartSeries, config.series])\n\n const saveSeriesColors = (overrides: Record<string, string>): void => {\n // Preserve overrides for series not currently rendered (other windows /\n // filters may surface different groupBy values).\n const next: Record<string, { color?: string }> = { ...config.series }\n for (const item of colorItems) delete next[item.key]\n for (const [key, color] of Object.entries(overrides)) next[key] = { color }\n update({ series: next })\n setColorsOpen(false)\n }\n\n // Adapter cannot do time-series — friendly message, no toolbar churn.\n const unsupported = data && data.supported === false\n\n return (\n <Card className=\"flex flex-col\">\n <CardHeader className=\"flex flex-row items-center justify-between gap-2 p-3 pb-2 space-y-0 sm:p-6 sm:pb-2\">\n <CardTitle className=\"flex min-w-0 items-center gap-2 text-sm font-medium pr-2\">\n <span className=\"truncate\">{config.title || t('chart:untitled')}</span>\n {delta && (\n <span\n title={t('dashboard:widget.previousPeriod')}\n className={`inline-flex shrink-0 items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-medium tabular-nums ${\n delta.direction === 'up'\n ? 'bg-emerald-500/10 text-emerald-600 dark:text-emerald-400'\n : delta.direction === 'down'\n ? 'bg-rose-500/10 text-rose-600 dark:text-rose-400'\n : 'bg-muted text-muted-foreground'\n }`}\n >\n {delta.direction === 'up' ? (\n <ArrowUp className=\"size-3\" />\n ) : delta.direction === 'down' ? (\n <ArrowDown className=\"size-3\" />\n ) : null}\n {Math.abs(delta.percent)}%\n </span>\n )}\n </CardTitle>\n <div className=\"flex items-center gap-1 shrink-0\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7\"\n onClick={onWidthToggle}\n aria-label={\n config.width === 'full'\n ? t('dashboard:widget.shrink')\n : t('dashboard:widget.expand')\n }\n >\n {config.width === 'full' ? (\n <Minimize2 className=\"size-3.5\" />\n ) : (\n <Maximize2 className=\"size-3.5\" />\n )}\n </Button>\n {data?.sql && (\n <Button\n variant={showSql ? 'secondary' : 'ghost'}\n size=\"icon\"\n className=\"size-7\"\n onClick={() => setShowSql((v) => !v)}\n aria-label={t('dashboard:widget.toggleSql')}\n >\n <Code className=\"size-3.5\" />\n </Button>\n )}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('common:refresh')}\n >\n <RefreshCw className={`size-3.5 ${isFetching ? 'animate-spin' : ''}`} />\n </Button>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7\"\n aria-label={t('common:openMenu')}\n >\n <MoreHorizontal className=\"size-3.5\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={onEdit}>\n <Pencil className=\"size-4 mr-2\" />\n {t('chart:editChart')}\n </DropdownMenuItem>\n {!isKpi && (\n <DropdownMenuItem onClick={() => setColorsOpen(true)}>\n <Palette className=\"size-4 mr-2\" />\n {t('dashboard:widget.editColors')}\n </DropdownMenuItem>\n )}\n {onMove && (\n <DropdownMenuItem onClick={onMove}>\n <FolderSymlink className=\"size-4 mr-2\" />\n {t('chart:moveToGroup')}\n </DropdownMenuItem>\n )}\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={onDelete}\n className=\"text-destructive focus:text-destructive\"\n >\n <Trash2 className=\"size-4 mr-2\" />\n {t('chart:deleteChart')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </CardHeader>\n\n <CardContent className=\"flex-1 p-3 pt-0 space-y-3 sm:p-6 sm:pt-0\">\n {/* Quick filters — compact inline row, label as placeholder, Apply on the right. */}\n {!unsupported && quickFilterPaths.length > 0 && resourceConfig && (\n <div className=\"flex flex-wrap items-center gap-2\">\n {quickFilterPaths.map((path) => {\n const prop = resourceConfig.properties.find((p) => p.path === path)\n if (!prop) return null\n return (\n <QuickFilterInput\n key={path}\n property={prop}\n placeholder={prop.label}\n value={draftFilters[path] ?? ''}\n onChange={(v) => setDraftFilters((prev) => ({ ...prev, [path]: v }))}\n />\n )\n })}\n <Button\n size=\"sm\"\n className=\"h-8 px-3 text-xs shrink-0\"\n onClick={applyQuickFilters}\n disabled={!draftDirty}\n >\n <Check className=\"size-3.5 mr-1\" />\n {t('common:apply')}\n </Button>\n </div>\n )}\n\n {/* Toolbar — step + range + window display. Hidden for unsupported\n adapters because changing knobs would have no effect. */}\n {!unsupported && (\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-muted-foreground\">\n {!isKpi && (\n <Select\n value={config.step === 'all' ? 'day' : config.step}\n onValueChange={(v) => onStepChange(v as AggregationStep)}\n >\n <SelectTrigger\n className=\"h-8 px-2 text-xs w-auto\"\n aria-label={t('chart:step')}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STEPS.map((s) => (\n <SelectItem key={s} value={s}>\n {t(`chart:step${cap(s)}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <Select\n value={config.timeRange.preset}\n onValueChange={(v) => onPresetChange(v as TimeRangePreset)}\n >\n <SelectTrigger\n className=\"h-8 px-2 text-xs w-auto\"\n aria-label={t('dashboard:builder.range')}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {PRESETS.map((p) => (\n <SelectItem key={p} value={p}>\n {t(`dashboard:range.${p}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {config.timeRange.preset === 'custom' ? (\n <>\n <DatePicker\n value={draftFrom}\n onChange={setDraftFrom}\n ariaLabel={t('common:from')}\n openCalendarLabel={t('common:openCalendar')}\n className=\"w-[130px]\"\n inputClassName=\"h-8 text-xs\"\n />\n <span className=\"text-muted-foreground\">—</span>\n <DatePicker\n value={draftTo}\n onChange={setDraftTo}\n ariaLabel={t('common:to')}\n openCalendarLabel={t('common:openCalendar')}\n className=\"w-[130px]\"\n inputClassName=\"h-8 text-xs\"\n />\n <Button\n size=\"sm\"\n className=\"h-8 px-3 shrink-0\"\n onClick={applyCustomRange}\n disabled={!draftFrom || !draftTo}\n aria-label={t('common:apply')}\n >\n <Check className=\"size-3.5 mr-1\" />\n {t('common:apply')}\n </Button>\n </>\n ) : (\n <span className=\"ml-auto tabular-nums\">\n {range.from} — {range.to}\n </span>\n )}\n </div>\n )}\n\n {/* Truncation warning — adapter capped the scan, so the chart reflects\n only a subset of the window. Hidden while loading / unsupported. */}\n {!unsupported && !isError && data?.truncated && (\n <div className=\"flex items-start gap-2 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2 text-xs text-amber-700 dark:text-amber-400\">\n <AlertTriangle className=\"size-3.5 mt-0.5 shrink-0\" />\n <span>{t('dashboard:widget.truncatedWarning')}</span>\n </div>\n )}\n\n {/* Body */}\n {isLoading ? (\n <Skeleton className={`${heightClass} w-full rounded-md`} />\n ) : isError ? (\n <div\n className={`flex items-center justify-center text-sm text-muted-foreground ${heightClass}`}\n >\n {t('chart:loadError')}\n </div>\n ) : unsupported ? (\n <div\n className={`flex items-center justify-center text-center text-sm text-muted-foreground px-4 ${heightClass}`}\n >\n {t('dashboard:widget.unsupported')}\n </div>\n ) : isKpi ? (\n <KpiBody\n data={data}\n transform={config.transform}\n formatNumber={valueFormatter}\n labels={kpiLabels(t)}\n />\n ) : (\n <TimeSeriesChart\n series={chartSeries}\n height={320}\n visualisation={config.visualisation === 'kpi' ? undefined : config.visualisation}\n tickFormatter={makeTickFormatter(renderStep, locale)}\n labelFormatter={makeLabelFormatter(renderStep, locale)}\n valueFormatter={valueFormatter}\n axisValueFormatter={axisValueFormatter}\n labels={{\n noData: t('chart:noData'),\n showAll: t('dashboard:widget.showAll'),\n hideAll: t('dashboard:widget.hideAll'),\n }}\n />\n )}\n\n {/* Captured SQL — only when the user toggled and server returned it. */}\n {data?.sql && showSql && (\n <div className=\"relative\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"absolute top-1 right-1 size-6\"\n onClick={() => {\n void navigator.clipboard.writeText(data.sql ?? '')\n setSqlCopied(true)\n setTimeout(() => setSqlCopied(false), 2000)\n }}\n aria-label={sqlCopied ? t('common:copied') : t('common:copy')}\n >\n {sqlCopied\n ? <Check className=\"size-3 text-green-500\" />\n : <Copy className=\"size-3\" />}\n </Button>\n <pre className=\"text-[11px] leading-snug bg-muted/50 border border-border rounded-md p-2 pr-8 overflow-x-auto whitespace-pre\">\n {data.sql}\n </pre>\n </div>\n )}\n </CardContent>\n\n {colorsOpen && (\n <ChartSeriesColorsDialog\n items={colorItems}\n onSave={saveSeriesColors}\n onClose={() => setColorsOpen(false)}\n />\n )}\n </Card>\n )\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────\n\nconst cap = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1)\n\nconst QF_NONE = '__none__'\n\nfunction seedDraftFilters(\n paths: ReadonlyArray<string>,\n filters: Record<string, string>,\n): Record<string, string> {\n const out: Record<string, string> = {}\n for (const p of paths) out[p] = filters[p] ?? ''\n return out\n}\n\n/** Compact inline filter input — label is passed as placeholder so no\n * extra row is needed. Matches the `h-7 text-xs` sizing of toolbar controls. */\nfunction QuickFilterInput({\n property,\n placeholder,\n value,\n onChange,\n}: {\n property: PropertyJSON\n placeholder?: string\n value: string\n onChange(next: string): void\n}): React.ReactElement {\n const ph = placeholder ?? property.label\n if (property.reference) {\n return (\n <div className=\"w-36\">\n <ReferenceCombobox\n referenceResourceId={property.reference}\n value={value || null}\n onChange={(next) => onChange(next == null ? '' : String(next))}\n placeholder={ph}\n className=\"h-8 text-xs\"\n />\n </div>\n )\n }\n if (property.availableValues && property.availableValues.length > 0) {\n return (\n <Select\n value={value || QF_NONE}\n onValueChange={(v) => onChange(v === QF_NONE ? '' : v)}\n >\n <SelectTrigger className=\"h-8 px-2 text-xs w-36\">\n <SelectValue placeholder={ph} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={QF_NONE}>{ph}</SelectItem>\n {property.availableValues.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n }\n if (property.type === 'boolean') {\n return (\n <Select\n value={value || QF_NONE}\n onValueChange={(v) => onChange(v === QF_NONE ? '' : v)}\n >\n <SelectTrigger className=\"h-8 px-2 text-xs w-36\">\n <SelectValue placeholder={ph} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={QF_NONE}>{ph}</SelectItem>\n <SelectItem value=\"true\">true</SelectItem>\n <SelectItem value=\"false\">false</SelectItem>\n </SelectContent>\n </Select>\n )\n }\n const isNumeric =\n property.type === 'number' || property.type === 'float' || property.type === 'currency'\n return (\n <Input\n type={isNumeric ? 'number' : 'text'}\n className=\"h-8 px-2 text-xs w-36\"\n value={value}\n placeholder={ph}\n onChange={(e) => onChange(e.target.value)}\n />\n )\n}\n\n/**\n * Zero-fill every series across the resolved date range and re-tag each\n * with its display label (so legend shows \"Total\" / \"Other\" / actual\n * groupBy values rather than the wire-format internal keys).\n */\nfunction prepareSeries(\n series: ReadonlyArray<TimeSeriesSeries>,\n range: { from: string; to: string },\n step: AggregationStep,\n labelFor: (key: string) => string,\n): { key: string; label: string; points: { date: string; value: number }[] }[] {\n const filled = fillTimeSeries(\n series.map((s) => ({ key: s.key, points: s.points })),\n range.from,\n range.to,\n step as Exclude<AggregationStep, 'all'> | 'all',\n )\n return filled.map((s) => ({\n key: s.key,\n label: labelFor(s.key),\n points: [...s.points],\n }))\n}\n\ninterface KpiBodyProps {\n data: { series: ReadonlyArray<TimeSeriesSeries>; previous?: ReadonlyArray<TimeSeriesSeries> } | undefined\n transform: ReadonlyArray<ChartTransformStep>\n formatNumber: (n: number) => string\n labels: {\n noData: string\n deltaUp: string\n deltaDown: string\n deltaFlat: string\n previousPeriod: string\n }\n}\n\n/** KPI mode summarises the single-bucket response to one scalar. The value\n * transform applies to both windows so the delta stays consistent. */\nfunction KpiBody({ data, transform, formatNumber, labels }: KpiBodyProps): React.ReactElement {\n const raw = sumAll(data?.series)\n const rawPrev = sumAll(data?.previous)\n const value = raw == null ? raw : applyTransform(raw, transform)\n const prev = rawPrev == null ? rawPrev : applyTransform(rawPrev, transform)\n return (\n <KpiCard\n value={value}\n previousValue={prev}\n formatNumber={formatNumber}\n labels={labels}\n />\n )\n}\n\nfunction sumAll(series: ReadonlyArray<TimeSeriesSeries> | undefined): number | null {\n if (!series || series.length === 0) return null\n let total = 0\n for (const s of series) for (const p of s.points) total += p.value\n return total\n}\n\nfunction kpiLabels(t: (key: string) => string): {\n noData: string\n deltaUp: string\n deltaDown: string\n deltaFlat: string\n previousPeriod: string\n} {\n return {\n noData: t('chart:noData'),\n deltaUp: t('dashboard:widget.deltaUp'),\n deltaDown: t('dashboard:widget.deltaDown'),\n deltaFlat: t('dashboard:widget.deltaFlat'),\n previousPeriod: t('dashboard:widget.previousPeriod'),\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./createLucideIcon-CUopU_LC.js";var t=e(`circle-alert`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`12`,x2:`12`,y1:`8`,y2:`12`,key:`1pkeuh`}],[`line`,{x1:`12`,x2:`12.01`,y1:`16`,y2:`16`,key:`4dfq90`}]]);export{t};
2
+ //# sourceMappingURL=circle-alert-0EyKeic4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circle-alert-0EyKeic4.js","names":[],"sources":["../../../../../node_modules/.bun/lucide-react@1.23.0+e14d3f224186685e/node_modules/lucide-react/dist/esm/icons/circle-alert.mjs"],"sourcesContent":["/**\n * @license lucide-react v1.23.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"8\", y2: \"12\", key: \"1pkeuh\" }],\n [\"line\", { x1: \"12\", x2: \"12.01\", y1: \"16\", y2: \"16\", key: \"4dfq90\" }]\n];\nconst CircleAlert = createLucideIcon(\"circle-alert\", __iconNode);\n\nexport { __iconNode, CircleAlert as default };\n//# sourceMappingURL=circle-alert.mjs.map\n"],"x_google_ignoreList":[0],"mappings":"mDAcA,IAAM,EAAc,EAAiB,eAAgB,CAJnD,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,KAAM,IAAK,QAAS,CAAC,EACzD,CAAC,OAAQ,CAAE,GAAI,KAAM,GAAI,KAAM,GAAI,IAAK,GAAI,KAAM,IAAK,QAAS,CAAC,EACjE,CAAC,OAAQ,CAAE,GAAI,KAAM,GAAI,QAAS,GAAI,KAAM,GAAI,KAAM,IAAK,QAAS,CAAC,CAElB,CAAU"}
@@ -1,2 +1,2 @@
1
- import{a as e,n as t}from"./createLucideIcon-CUopU_LC.js";import{S as n,d as r,l as i,s as a,y as o}from"./with-selector-NDLhu4dT.js";import{a as s,o as c,r as l,t as u}from"./dist-Dkym1-ts.js";import{N as d,P as f,Q as p}from"./index-R1VJOHqq.js";var m=e(t(),1),h=1,g=.9,_=.8,v=.17,y=.1,b=.999,x=.9999,ee=.99,S=/[\\\/_+.#"@\[\(\{&]/,C=/[\\\/_+.#"@\[\(\{&]/g,w=/[\s-]/,T=/[\s-]/g;function E(e,t,n,r,i,a,o){if(a===t.length)return i===e.length?h:ee;var s=`${i},${a}`;if(o[s]!==void 0)return o[s];for(var c=r.charAt(a),l=n.indexOf(c,i),u=0,d,f,p,m;l>=0;)d=E(e,t,n,r,l+1,a+1,o),d>u&&(l===i?d*=h:S.test(e.charAt(l-1))?(d*=_,p=e.slice(i,l-1).match(C),p&&i>0&&(d*=b**+p.length)):w.test(e.charAt(l-1))?(d*=g,m=e.slice(i,l-1).match(T),m&&i>0&&(d*=b**+m.length)):(d*=v,i>0&&(d*=b**+(l-i))),e.charAt(l)!==t.charAt(a)&&(d*=x)),(d<y&&n.charAt(l-1)===r.charAt(a+1)||r.charAt(a+1)===r.charAt(a)&&n.charAt(l-1)!==r.charAt(a))&&(f=E(e,t,n,r,l+1,a+2,o),f*y>d&&(d=f*y)),d>u&&(u=d),l=n.indexOf(c,l+1);return o[s]=u,u}function D(e){return e.toLowerCase().replace(T,` `)}function O(e,t,n){return e=n&&n.length>0?`${e+` `+n.join(` `)}`:e,E(e,t,D(e),D(t),0,0,{})}var k=`[cmdk-group=""]`,A=`[cmdk-group-items=""]`,te=`[cmdk-group-heading=""]`,ne=`[cmdk-item=""]`,j=`${ne}:not([aria-disabled="true"])`,M=`cmdk-item-select`,N=`data-value`,re=(e,t,n)=>O(e,t,n),P=m.createContext(void 0),F=()=>m.useContext(P),ie=m.createContext(void 0),I=()=>m.useContext(ie),L=m.createContext(void 0),R=m.forwardRef((e,t)=>{let n=Y(()=>({search:``,value:e.value??e.defaultValue??``,selectedItemId:void 0,filtered:{count:0,items:new Map,groups:new Set}})),a=Y(()=>new Set),o=Y(()=>new Map),s=Y(()=>new Map),c=Y(()=>new Set),l=q(e),{label:u,children:d,value:f,onValueChange:p,filter:h,shouldFilter:g,loop:_,disablePointerSelection:v=!1,vimBindings:y=!0,...b}=e,x=i(),ee=i(),S=i(),C=m.useRef(null),w=le();J(()=>{if(f!==void 0){let e=f.trim();n.current.value=e,T.emit()}},[f]),J(()=>{w(6,L)},[]);let T=m.useMemo(()=>({subscribe:e=>(c.current.add(e),()=>c.current.delete(e)),snapshot:()=>n.current,setState:(e,t,r)=>{var i,a,o;if(!Object.is(n.current[e],t)){if(n.current[e]=t,e===`search`)I(),O(),w(1,F);else if(e===`value`){if(document.activeElement.hasAttribute(`cmdk-input`)||document.activeElement.hasAttribute(`cmdk-root`)){let e=document.getElementById(S);e?e.focus():(i=document.getElementById(x))==null||i.focus()}if(w(7,()=>{n.current.selectedItemId=R()?.id,T.emit()}),r||w(5,L),l.current?.value!==void 0){let e=t??``;(o=(a=l.current).onValueChange)==null||o.call(a,e);return}}T.emit()}},emit:()=>{c.current.forEach(e=>e())}}),[]),E=m.useMemo(()=>({value:(e,t,r)=>{t!==s.current.get(e)?.value&&(s.current.set(e,{value:t,keywords:r}),n.current.filtered.items.set(e,D(t,r)),w(2,()=>{O(),T.emit()}))},item:(e,t)=>(a.current.add(e),t&&(o.current.has(t)?o.current.get(t).add(e):o.current.set(t,new Set([e]))),w(3,()=>{I(),O(),n.current.value||F(),T.emit()}),()=>{s.current.delete(e),a.current.delete(e),n.current.filtered.items.delete(e);let t=R();w(4,()=>{I(),t?.getAttribute(`id`)===e&&F(),T.emit()})}),group:e=>(o.current.has(e)||o.current.set(e,new Set),()=>{s.current.delete(e),o.current.delete(e)}),filter:()=>l.current.shouldFilter,label:u||e[`aria-label`],getDisablePointerSelection:()=>l.current.disablePointerSelection,listId:x,inputId:S,labelId:ee,listInnerRef:C}),[]);function D(e,t){let r=l.current?.filter??re;return e?r(e,n.current.search,t):0}function O(){if(!n.current.search||l.current.shouldFilter===!1)return;let e=n.current.filtered.items,t=[];n.current.filtered.groups.forEach(n=>{let r=o.current.get(n),i=0;r.forEach(t=>{let n=e.get(t);i=Math.max(n,i)}),t.push([n,i])});let r=C.current;z().sort((t,n)=>{let r=t.getAttribute(`id`),i=n.getAttribute(`id`);return(e.get(i)??0)-(e.get(r)??0)}).forEach(e=>{let t=e.closest(A);t?t.appendChild(e.parentElement===t?e:e.closest(`${A} > *`)):r.appendChild(e.parentElement===r?e:e.closest(`${A} > *`))}),t.sort((e,t)=>t[1]-e[1]).forEach(e=>{let t=C.current?.querySelector(`${k}[${N}="${encodeURIComponent(e[0])}"]`);t?.parentElement.appendChild(t)})}function F(){let e=z().find(e=>e.getAttribute(`aria-disabled`)!==`true`)?.getAttribute(N);T.setState(`value`,e||void 0)}function I(){if(!n.current.search||l.current.shouldFilter===!1){n.current.filtered.count=a.current.size;return}n.current.filtered.groups=new Set;let e=0;for(let t of a.current){let r=D(s.current.get(t)?.value??``,s.current.get(t)?.keywords??[]);n.current.filtered.items.set(t,r),r>0&&e++}for(let[e,t]of o.current)for(let r of t)if(n.current.filtered.items.get(r)>0){n.current.filtered.groups.add(e);break}n.current.filtered.count=e}function L(){var e;let t=R();t&&(t.parentElement?.firstChild===t&&((e=t.closest(k)?.querySelector(te))==null||e.scrollIntoView({block:`nearest`})),t.scrollIntoView({block:`nearest`}))}function R(){return C.current?.querySelector(`${ne}[aria-selected="true"]`)}function z(){return Array.from(C.current?.querySelectorAll(j)||[])}function B(e){let t=z()[e];t&&T.setState(`value`,t.getAttribute(N))}function V(e){var t;let n=R(),r=z(),i=r.findIndex(e=>e===n),a=r[i+e];(t=l.current)!=null&&t.loop&&(a=i+e<0?r[r.length-1]:i+e===r.length?r[0]:r[i+e]),a&&T.setState(`value`,a.getAttribute(N))}function H(e){let t=R()?.closest(k),n;for(;t&&!n;)t=e>0?oe(t,k):se(t,k),n=t?.querySelector(j);n?T.setState(`value`,n.getAttribute(N)):V(e)}let U=()=>B(z().length-1),W=e=>{e.preventDefault(),e.metaKey?U():e.altKey?H(1):V(1)},G=e=>{e.preventDefault(),e.metaKey?B(0):e.altKey?H(-1):V(-1)};return m.createElement(r.div,{ref:t,tabIndex:-1,...b,"cmdk-root":``,onKeyDown:e=>{var t;(t=b.onKeyDown)==null||t.call(b,e);let n=e.nativeEvent.isComposing||e.keyCode===229;if(!(e.defaultPrevented||n))switch(e.key){case`n`:case`j`:y&&e.ctrlKey&&W(e);break;case`ArrowDown`:W(e);break;case`p`:case`k`:y&&e.ctrlKey&&G(e);break;case`ArrowUp`:G(e);break;case`Home`:e.preventDefault(),B(0);break;case`End`:e.preventDefault(),U();break;case`Enter`:{e.preventDefault();let t=R();if(t){let e=new Event(M);t.dispatchEvent(e)}}}}},m.createElement(`label`,{"cmdk-label":``,htmlFor:E.inputId,id:E.labelId,style:de},u),Z(e,e=>m.createElement(ie.Provider,{value:T},m.createElement(P.Provider,{value:E},e))))}),z=m.forwardRef((e,t)=>{let n=i(),a=m.useRef(null),s=m.useContext(L),c=F(),l=q(e),u=l.current?.forceMount??s?.forceMount;J(()=>{if(!u)return c.item(n,s?.id)},[u]);let d=ce(n,a,[e.value,e.children,a],e.keywords),f=I(),p=X(e=>e.value&&e.value===d.current),h=X(e=>u||c.filter()===!1?!0:!e.search||e.filtered.items.get(n)>0);m.useEffect(()=>{let t=a.current;if(!(!t||e.disabled))return t.addEventListener(M,g),()=>t.removeEventListener(M,g)},[h,e.onSelect,e.disabled]);function g(){var e,t;_(),(t=(e=l.current).onSelect)==null||t.call(e,d.current)}function _(){f.setState(`value`,d.current,!0)}if(!h)return null;let{disabled:v,value:y,onSelect:b,forceMount:x,keywords:ee,...S}=e;return m.createElement(r.div,{ref:o(a,t),...S,id:n,"cmdk-item":``,role:`option`,"aria-disabled":!!v,"aria-selected":!!p,"data-disabled":!!v,"data-selected":!!p,onPointerMove:v||c.getDisablePointerSelection()?void 0:_,onClick:v?void 0:g},e.children)}),B=m.forwardRef((e,t)=>{let{heading:n,children:a,forceMount:s,...c}=e,l=i(),u=m.useRef(null),d=m.useRef(null),f=i(),p=F(),h=X(e=>s||p.filter()===!1?!0:!e.search||e.filtered.groups.has(l));J(()=>p.group(l),[]),ce(l,u,[e.value,e.heading,d]);let g=m.useMemo(()=>({id:l,forceMount:s}),[s]);return m.createElement(r.div,{ref:o(u,t),...c,"cmdk-group":``,role:`presentation`,hidden:!h||void 0},n&&m.createElement(`div`,{ref:d,"cmdk-group-heading":``,"aria-hidden":!0,id:f},n),Z(e,e=>m.createElement(`div`,{"cmdk-group-items":``,role:`group`,"aria-labelledby":n?f:void 0},m.createElement(L.Provider,{value:g},e))))}),V=m.forwardRef((e,t)=>{let{alwaysRender:n,...i}=e,a=m.useRef(null),s=X(e=>!e.search);return!n&&!s?null:m.createElement(r.div,{ref:o(a,t),...i,"cmdk-separator":``,role:`separator`})}),H=m.forwardRef((e,t)=>{let{onValueChange:n,...i}=e,a=e.value!=null,o=I(),s=X(e=>e.search),c=X(e=>e.selectedItemId),l=F();return m.useEffect(()=>{e.value!=null&&o.setState(`search`,e.value)},[e.value]),m.createElement(r.input,{ref:t,...i,"cmdk-input":``,autoComplete:`off`,autoCorrect:`off`,spellCheck:!1,"aria-autocomplete":`list`,role:`combobox`,"aria-expanded":!0,"aria-controls":l.listId,"aria-labelledby":l.labelId,"aria-activedescendant":c,id:l.inputId,type:`text`,value:a?e.value:s,onChange:e=>{a||o.setState(`search`,e.target.value),n?.(e.target.value)}})}),U=m.forwardRef((e,t)=>{let{children:n,label:i=`Suggestions`,...a}=e,s=m.useRef(null),c=m.useRef(null),l=X(e=>e.selectedItemId),u=F();return m.useEffect(()=>{if(c.current&&s.current){let e=c.current,t=s.current,n,r=new ResizeObserver(()=>{n=requestAnimationFrame(()=>{let n=e.offsetHeight;t.style.setProperty(`--cmdk-list-height`,n.toFixed(1)+`px`)})});return r.observe(e),()=>{cancelAnimationFrame(n),r.unobserve(e)}}},[]),m.createElement(r.div,{ref:o(s,t),...a,"cmdk-list":``,role:`listbox`,tabIndex:-1,"aria-activedescendant":l,"aria-label":i,id:u.listId},Z(e,e=>m.createElement(`div`,{ref:o(c,u.listInnerRef),"cmdk-list-sizer":``},e)))}),W=m.forwardRef((e,t)=>{let{open:n,onOpenChange:r,overlayClassName:i,contentClassName:a,container:o,...d}=e;return m.createElement(u,{open:n,onOpenChange:r},m.createElement(c,{container:o},m.createElement(s,{"cmdk-overlay":``,className:i}),m.createElement(l,{"aria-label":e.label,"cmdk-dialog":``,className:a},m.createElement(R,{ref:t,...d}))))}),G=m.forwardRef((e,t)=>X(e=>e.filtered.count===0)?m.createElement(r.div,{ref:t,...e,"cmdk-empty":``,role:`presentation`}):null),ae=m.forwardRef((e,t)=>{let{progress:n,children:i,label:a=`Loading...`,...o}=e;return m.createElement(r.div,{ref:t,...o,"cmdk-loading":``,role:`progressbar`,"aria-valuenow":n,"aria-valuemin":0,"aria-valuemax":100,"aria-label":a},Z(e,e=>m.createElement(`div`,{"aria-hidden":!0},e)))}),K=Object.assign(R,{List:U,Item:z,Input:H,Group:B,Separator:V,Dialog:W,Empty:G,Loading:ae});function oe(e,t){let n=e.nextElementSibling;for(;n;){if(n.matches(t))return n;n=n.nextElementSibling}}function se(e,t){let n=e.previousElementSibling;for(;n;){if(n.matches(t))return n;n=n.previousElementSibling}}function q(e){let t=m.useRef(e);return J(()=>{t.current=e}),t}var J=typeof window>`u`?m.useEffect:m.useLayoutEffect;function Y(e){let t=m.useRef();return t.current===void 0&&(t.current=e()),t}function X(e){let t=I(),n=()=>e(t.snapshot());return m.useSyncExternalStore(t.subscribe,n,n)}function ce(e,t,n,r=[]){let i=m.useRef(),a=F();return J(()=>{var o;let s=(()=>{for(let e of n){if(typeof e==`string`)return e.trim();if(typeof e==`object`&&`current`in e)return e.current?e.current.textContent?.trim():i.current}})(),c=r.map(e=>e.trim());a.value(e,s,c),(o=t.current)==null||o.setAttribute(N,s),i.current=s}),i}var le=()=>{let[e,t]=m.useState(),n=Y(()=>new Map);return J(()=>{n.current.forEach(e=>e()),n.current=new Map},[e]),(e,r)=>{n.current.set(e,r),t({})}};function ue(e){let t=e.type;return typeof t==`function`?t(e.props):`render`in t?t.render(e.props):e}function Z({asChild:e,children:t},n){return e&&m.isValidElement(t)?m.cloneElement(ue(t),{ref:t.ref},n(t.props.children)):n(t)}var de={position:`absolute`,width:`1px`,height:`1px`,padding:`0`,margin:`-1px`,overflow:`hidden`,clip:`rect(0, 0, 0, 0)`,whiteSpace:`nowrap`,borderWidth:`0`},Q=n(),$=m.forwardRef(({className:e,...t},n)=>(0,Q.jsx)(K,{ref:n,className:a(`flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground`,e),...t}));$.displayName=K.displayName;var fe=({children:e,...t})=>(0,Q.jsx)(d,{...t,children:(0,Q.jsx)(f,{className:`overflow-hidden p-0 shadow-lg`,children:(0,Q.jsx)($,{className:`[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5`,children:e})})}),pe=m.forwardRef(({className:e,...t},n)=>(0,Q.jsxs)(`div`,{className:`flex items-center border-b border-border px-3`,"cmdk-input-wrapper":``,children:[(0,Q.jsx)(p,{className:`mr-2 h-4 w-4 shrink-0 opacity-50`}),(0,Q.jsx)(K.Input,{ref:n,className:a(`flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50`,e),...t})]}));pe.displayName=K.Input.displayName;var me=m.forwardRef(({className:e,...t},n)=>(0,Q.jsx)(K.List,{ref:n,className:a(`max-h-[300px] overflow-y-auto overflow-x-hidden`,e),...t}));me.displayName=K.List.displayName;var he=m.forwardRef((e,t)=>(0,Q.jsx)(K.Empty,{ref:t,className:`py-6 text-center text-sm`,...e}));he.displayName=K.Empty.displayName;var ge=m.forwardRef(({className:e,...t},n)=>(0,Q.jsx)(K.Group,{ref:n,className:a(`overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground`,e),...t}));ge.displayName=K.Group.displayName;var _e=m.forwardRef(({className:e,...t},n)=>(0,Q.jsx)(K.Separator,{ref:n,className:a(`-mx-1 h-px bg-border/40`,e),...t}));_e.displayName=K.Separator.displayName;var ve=m.forwardRef(({className:e,...t},n)=>(0,Q.jsx)(K.Item,{ref:n,className:a(`relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0`,e),...t}));ve.displayName=K.Item.displayName;var ye=({className:e,...t})=>(0,Q.jsx)(`span`,{className:a(`ml-auto text-xs tracking-widest text-muted-foreground`,e),...t});ye.displayName=`CommandShortcut`;export{pe as a,_e as c,ge as i,fe as n,ve as o,he as r,me as s,$ as t};
2
- //# sourceMappingURL=command-B6-wRF2R.js.map
1
+ import{a as e,n as t}from"./createLucideIcon-CUopU_LC.js";import{S as n,d as r,l as i,s as a,y as o}from"./with-selector-NDLhu4dT.js";import{a as s,o as c,r as l,t as u}from"./dist-BcL2U6dT.js";import{$ as d,N as f,P as p}from"./index-t4woXGa-.js";var m=e(t(),1),h=1,g=.9,_=.8,v=.17,y=.1,b=.999,x=.9999,ee=.99,S=/[\\\/_+.#"@\[\(\{&]/,C=/[\\\/_+.#"@\[\(\{&]/g,w=/[\s-]/,T=/[\s-]/g;function E(e,t,n,r,i,a,o){if(a===t.length)return i===e.length?h:ee;var s=`${i},${a}`;if(o[s]!==void 0)return o[s];for(var c=r.charAt(a),l=n.indexOf(c,i),u=0,d,f,p,m;l>=0;)d=E(e,t,n,r,l+1,a+1,o),d>u&&(l===i?d*=h:S.test(e.charAt(l-1))?(d*=_,p=e.slice(i,l-1).match(C),p&&i>0&&(d*=b**+p.length)):w.test(e.charAt(l-1))?(d*=g,m=e.slice(i,l-1).match(T),m&&i>0&&(d*=b**+m.length)):(d*=v,i>0&&(d*=b**+(l-i))),e.charAt(l)!==t.charAt(a)&&(d*=x)),(d<y&&n.charAt(l-1)===r.charAt(a+1)||r.charAt(a+1)===r.charAt(a)&&n.charAt(l-1)!==r.charAt(a))&&(f=E(e,t,n,r,l+1,a+2,o),f*y>d&&(d=f*y)),d>u&&(u=d),l=n.indexOf(c,l+1);return o[s]=u,u}function D(e){return e.toLowerCase().replace(T,` `)}function O(e,t,n){return e=n&&n.length>0?`${e+` `+n.join(` `)}`:e,E(e,t,D(e),D(t),0,0,{})}var k=`[cmdk-group=""]`,A=`[cmdk-group-items=""]`,te=`[cmdk-group-heading=""]`,ne=`[cmdk-item=""]`,j=`${ne}:not([aria-disabled="true"])`,M=`cmdk-item-select`,N=`data-value`,re=(e,t,n)=>O(e,t,n),P=m.createContext(void 0),F=()=>m.useContext(P),ie=m.createContext(void 0),I=()=>m.useContext(ie),L=m.createContext(void 0),R=m.forwardRef((e,t)=>{let n=Y(()=>({search:``,value:e.value??e.defaultValue??``,selectedItemId:void 0,filtered:{count:0,items:new Map,groups:new Set}})),a=Y(()=>new Set),o=Y(()=>new Map),s=Y(()=>new Map),c=Y(()=>new Set),l=q(e),{label:u,children:d,value:f,onValueChange:p,filter:h,shouldFilter:g,loop:_,disablePointerSelection:v=!1,vimBindings:y=!0,...b}=e,x=i(),ee=i(),S=i(),C=m.useRef(null),w=le();J(()=>{if(f!==void 0){let e=f.trim();n.current.value=e,T.emit()}},[f]),J(()=>{w(6,L)},[]);let T=m.useMemo(()=>({subscribe:e=>(c.current.add(e),()=>c.current.delete(e)),snapshot:()=>n.current,setState:(e,t,r)=>{var i,a,o;if(!Object.is(n.current[e],t)){if(n.current[e]=t,e===`search`)I(),O(),w(1,F);else if(e===`value`){if(document.activeElement.hasAttribute(`cmdk-input`)||document.activeElement.hasAttribute(`cmdk-root`)){let e=document.getElementById(S);e?e.focus():(i=document.getElementById(x))==null||i.focus()}if(w(7,()=>{n.current.selectedItemId=R()?.id,T.emit()}),r||w(5,L),l.current?.value!==void 0){let e=t??``;(o=(a=l.current).onValueChange)==null||o.call(a,e);return}}T.emit()}},emit:()=>{c.current.forEach(e=>e())}}),[]),E=m.useMemo(()=>({value:(e,t,r)=>{t!==s.current.get(e)?.value&&(s.current.set(e,{value:t,keywords:r}),n.current.filtered.items.set(e,D(t,r)),w(2,()=>{O(),T.emit()}))},item:(e,t)=>(a.current.add(e),t&&(o.current.has(t)?o.current.get(t).add(e):o.current.set(t,new Set([e]))),w(3,()=>{I(),O(),n.current.value||F(),T.emit()}),()=>{s.current.delete(e),a.current.delete(e),n.current.filtered.items.delete(e);let t=R();w(4,()=>{I(),t?.getAttribute(`id`)===e&&F(),T.emit()})}),group:e=>(o.current.has(e)||o.current.set(e,new Set),()=>{s.current.delete(e),o.current.delete(e)}),filter:()=>l.current.shouldFilter,label:u||e[`aria-label`],getDisablePointerSelection:()=>l.current.disablePointerSelection,listId:x,inputId:S,labelId:ee,listInnerRef:C}),[]);function D(e,t){let r=l.current?.filter??re;return e?r(e,n.current.search,t):0}function O(){if(!n.current.search||l.current.shouldFilter===!1)return;let e=n.current.filtered.items,t=[];n.current.filtered.groups.forEach(n=>{let r=o.current.get(n),i=0;r.forEach(t=>{let n=e.get(t);i=Math.max(n,i)}),t.push([n,i])});let r=C.current;z().sort((t,n)=>{let r=t.getAttribute(`id`),i=n.getAttribute(`id`);return(e.get(i)??0)-(e.get(r)??0)}).forEach(e=>{let t=e.closest(A);t?t.appendChild(e.parentElement===t?e:e.closest(`${A} > *`)):r.appendChild(e.parentElement===r?e:e.closest(`${A} > *`))}),t.sort((e,t)=>t[1]-e[1]).forEach(e=>{let t=C.current?.querySelector(`${k}[${N}="${encodeURIComponent(e[0])}"]`);t?.parentElement.appendChild(t)})}function F(){let e=z().find(e=>e.getAttribute(`aria-disabled`)!==`true`)?.getAttribute(N);T.setState(`value`,e||void 0)}function I(){if(!n.current.search||l.current.shouldFilter===!1){n.current.filtered.count=a.current.size;return}n.current.filtered.groups=new Set;let e=0;for(let t of a.current){let r=D(s.current.get(t)?.value??``,s.current.get(t)?.keywords??[]);n.current.filtered.items.set(t,r),r>0&&e++}for(let[e,t]of o.current)for(let r of t)if(n.current.filtered.items.get(r)>0){n.current.filtered.groups.add(e);break}n.current.filtered.count=e}function L(){var e;let t=R();t&&(t.parentElement?.firstChild===t&&((e=t.closest(k)?.querySelector(te))==null||e.scrollIntoView({block:`nearest`})),t.scrollIntoView({block:`nearest`}))}function R(){return C.current?.querySelector(`${ne}[aria-selected="true"]`)}function z(){return Array.from(C.current?.querySelectorAll(j)||[])}function B(e){let t=z()[e];t&&T.setState(`value`,t.getAttribute(N))}function V(e){var t;let n=R(),r=z(),i=r.findIndex(e=>e===n),a=r[i+e];(t=l.current)!=null&&t.loop&&(a=i+e<0?r[r.length-1]:i+e===r.length?r[0]:r[i+e]),a&&T.setState(`value`,a.getAttribute(N))}function H(e){let t=R()?.closest(k),n;for(;t&&!n;)t=e>0?oe(t,k):se(t,k),n=t?.querySelector(j);n?T.setState(`value`,n.getAttribute(N)):V(e)}let U=()=>B(z().length-1),W=e=>{e.preventDefault(),e.metaKey?U():e.altKey?H(1):V(1)},G=e=>{e.preventDefault(),e.metaKey?B(0):e.altKey?H(-1):V(-1)};return m.createElement(r.div,{ref:t,tabIndex:-1,...b,"cmdk-root":``,onKeyDown:e=>{var t;(t=b.onKeyDown)==null||t.call(b,e);let n=e.nativeEvent.isComposing||e.keyCode===229;if(!(e.defaultPrevented||n))switch(e.key){case`n`:case`j`:y&&e.ctrlKey&&W(e);break;case`ArrowDown`:W(e);break;case`p`:case`k`:y&&e.ctrlKey&&G(e);break;case`ArrowUp`:G(e);break;case`Home`:e.preventDefault(),B(0);break;case`End`:e.preventDefault(),U();break;case`Enter`:{e.preventDefault();let t=R();if(t){let e=new Event(M);t.dispatchEvent(e)}}}}},m.createElement(`label`,{"cmdk-label":``,htmlFor:E.inputId,id:E.labelId,style:de},u),Z(e,e=>m.createElement(ie.Provider,{value:T},m.createElement(P.Provider,{value:E},e))))}),z=m.forwardRef((e,t)=>{let n=i(),a=m.useRef(null),s=m.useContext(L),c=F(),l=q(e),u=l.current?.forceMount??s?.forceMount;J(()=>{if(!u)return c.item(n,s?.id)},[u]);let d=ce(n,a,[e.value,e.children,a],e.keywords),f=I(),p=X(e=>e.value&&e.value===d.current),h=X(e=>u||c.filter()===!1?!0:!e.search||e.filtered.items.get(n)>0);m.useEffect(()=>{let t=a.current;if(!(!t||e.disabled))return t.addEventListener(M,g),()=>t.removeEventListener(M,g)},[h,e.onSelect,e.disabled]);function g(){var e,t;_(),(t=(e=l.current).onSelect)==null||t.call(e,d.current)}function _(){f.setState(`value`,d.current,!0)}if(!h)return null;let{disabled:v,value:y,onSelect:b,forceMount:x,keywords:ee,...S}=e;return m.createElement(r.div,{ref:o(a,t),...S,id:n,"cmdk-item":``,role:`option`,"aria-disabled":!!v,"aria-selected":!!p,"data-disabled":!!v,"data-selected":!!p,onPointerMove:v||c.getDisablePointerSelection()?void 0:_,onClick:v?void 0:g},e.children)}),B=m.forwardRef((e,t)=>{let{heading:n,children:a,forceMount:s,...c}=e,l=i(),u=m.useRef(null),d=m.useRef(null),f=i(),p=F(),h=X(e=>s||p.filter()===!1?!0:!e.search||e.filtered.groups.has(l));J(()=>p.group(l),[]),ce(l,u,[e.value,e.heading,d]);let g=m.useMemo(()=>({id:l,forceMount:s}),[s]);return m.createElement(r.div,{ref:o(u,t),...c,"cmdk-group":``,role:`presentation`,hidden:!h||void 0},n&&m.createElement(`div`,{ref:d,"cmdk-group-heading":``,"aria-hidden":!0,id:f},n),Z(e,e=>m.createElement(`div`,{"cmdk-group-items":``,role:`group`,"aria-labelledby":n?f:void 0},m.createElement(L.Provider,{value:g},e))))}),V=m.forwardRef((e,t)=>{let{alwaysRender:n,...i}=e,a=m.useRef(null),s=X(e=>!e.search);return!n&&!s?null:m.createElement(r.div,{ref:o(a,t),...i,"cmdk-separator":``,role:`separator`})}),H=m.forwardRef((e,t)=>{let{onValueChange:n,...i}=e,a=e.value!=null,o=I(),s=X(e=>e.search),c=X(e=>e.selectedItemId),l=F();return m.useEffect(()=>{e.value!=null&&o.setState(`search`,e.value)},[e.value]),m.createElement(r.input,{ref:t,...i,"cmdk-input":``,autoComplete:`off`,autoCorrect:`off`,spellCheck:!1,"aria-autocomplete":`list`,role:`combobox`,"aria-expanded":!0,"aria-controls":l.listId,"aria-labelledby":l.labelId,"aria-activedescendant":c,id:l.inputId,type:`text`,value:a?e.value:s,onChange:e=>{a||o.setState(`search`,e.target.value),n?.(e.target.value)}})}),U=m.forwardRef((e,t)=>{let{children:n,label:i=`Suggestions`,...a}=e,s=m.useRef(null),c=m.useRef(null),l=X(e=>e.selectedItemId),u=F();return m.useEffect(()=>{if(c.current&&s.current){let e=c.current,t=s.current,n,r=new ResizeObserver(()=>{n=requestAnimationFrame(()=>{let n=e.offsetHeight;t.style.setProperty(`--cmdk-list-height`,n.toFixed(1)+`px`)})});return r.observe(e),()=>{cancelAnimationFrame(n),r.unobserve(e)}}},[]),m.createElement(r.div,{ref:o(s,t),...a,"cmdk-list":``,role:`listbox`,tabIndex:-1,"aria-activedescendant":l,"aria-label":i,id:u.listId},Z(e,e=>m.createElement(`div`,{ref:o(c,u.listInnerRef),"cmdk-list-sizer":``},e)))}),W=m.forwardRef((e,t)=>{let{open:n,onOpenChange:r,overlayClassName:i,contentClassName:a,container:o,...d}=e;return m.createElement(u,{open:n,onOpenChange:r},m.createElement(c,{container:o},m.createElement(s,{"cmdk-overlay":``,className:i}),m.createElement(l,{"aria-label":e.label,"cmdk-dialog":``,className:a},m.createElement(R,{ref:t,...d}))))}),G=m.forwardRef((e,t)=>X(e=>e.filtered.count===0)?m.createElement(r.div,{ref:t,...e,"cmdk-empty":``,role:`presentation`}):null),ae=m.forwardRef((e,t)=>{let{progress:n,children:i,label:a=`Loading...`,...o}=e;return m.createElement(r.div,{ref:t,...o,"cmdk-loading":``,role:`progressbar`,"aria-valuenow":n,"aria-valuemin":0,"aria-valuemax":100,"aria-label":a},Z(e,e=>m.createElement(`div`,{"aria-hidden":!0},e)))}),K=Object.assign(R,{List:U,Item:z,Input:H,Group:B,Separator:V,Dialog:W,Empty:G,Loading:ae});function oe(e,t){let n=e.nextElementSibling;for(;n;){if(n.matches(t))return n;n=n.nextElementSibling}}function se(e,t){let n=e.previousElementSibling;for(;n;){if(n.matches(t))return n;n=n.previousElementSibling}}function q(e){let t=m.useRef(e);return J(()=>{t.current=e}),t}var J=typeof window>`u`?m.useEffect:m.useLayoutEffect;function Y(e){let t=m.useRef();return t.current===void 0&&(t.current=e()),t}function X(e){let t=I(),n=()=>e(t.snapshot());return m.useSyncExternalStore(t.subscribe,n,n)}function ce(e,t,n,r=[]){let i=m.useRef(),a=F();return J(()=>{var o;let s=(()=>{for(let e of n){if(typeof e==`string`)return e.trim();if(typeof e==`object`&&`current`in e)return e.current?e.current.textContent?.trim():i.current}})(),c=r.map(e=>e.trim());a.value(e,s,c),(o=t.current)==null||o.setAttribute(N,s),i.current=s}),i}var le=()=>{let[e,t]=m.useState(),n=Y(()=>new Map);return J(()=>{n.current.forEach(e=>e()),n.current=new Map},[e]),(e,r)=>{n.current.set(e,r),t({})}};function ue(e){let t=e.type;return typeof t==`function`?t(e.props):`render`in t?t.render(e.props):e}function Z({asChild:e,children:t},n){return e&&m.isValidElement(t)?m.cloneElement(ue(t),{ref:t.ref},n(t.props.children)):n(t)}var de={position:`absolute`,width:`1px`,height:`1px`,padding:`0`,margin:`-1px`,overflow:`hidden`,clip:`rect(0, 0, 0, 0)`,whiteSpace:`nowrap`,borderWidth:`0`},Q=n(),$=m.forwardRef(({className:e,...t},n)=>(0,Q.jsx)(K,{ref:n,className:a(`flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground`,e),...t}));$.displayName=K.displayName;var fe=({children:e,...t})=>(0,Q.jsx)(f,{...t,children:(0,Q.jsx)(p,{className:`overflow-hidden p-0 shadow-lg`,children:(0,Q.jsx)($,{className:`[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5`,children:e})})}),pe=m.forwardRef(({className:e,...t},n)=>(0,Q.jsxs)(`div`,{className:`flex items-center border-b border-border px-3`,"cmdk-input-wrapper":``,children:[(0,Q.jsx)(d,{className:`mr-2 h-4 w-4 shrink-0 opacity-50`}),(0,Q.jsx)(K.Input,{ref:n,className:a(`flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50`,e),...t})]}));pe.displayName=K.Input.displayName;var me=m.forwardRef(({className:e,...t},n)=>(0,Q.jsx)(K.List,{ref:n,className:a(`max-h-[300px] overflow-y-auto overflow-x-hidden`,e),...t}));me.displayName=K.List.displayName;var he=m.forwardRef((e,t)=>(0,Q.jsx)(K.Empty,{ref:t,className:`py-6 text-center text-sm`,...e}));he.displayName=K.Empty.displayName;var ge=m.forwardRef(({className:e,...t},n)=>(0,Q.jsx)(K.Group,{ref:n,className:a(`overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground`,e),...t}));ge.displayName=K.Group.displayName;var _e=m.forwardRef(({className:e,...t},n)=>(0,Q.jsx)(K.Separator,{ref:n,className:a(`-mx-1 h-px bg-border/40`,e),...t}));_e.displayName=K.Separator.displayName;var ve=m.forwardRef(({className:e,...t},n)=>(0,Q.jsx)(K.Item,{ref:n,className:a(`relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0`,e),...t}));ve.displayName=K.Item.displayName;var ye=({className:e,...t})=>(0,Q.jsx)(`span`,{className:a(`ml-auto text-xs tracking-widest text-muted-foreground`,e),...t});ye.displayName=`CommandShortcut`;export{pe as a,_e as c,ge as i,fe as n,ve as o,he as r,me as s,$ as t};
2
+ //# sourceMappingURL=command-BNF_evMy.js.map