@modern-admin/web 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/vite.js +20 -0
- package/dist/lib/index.js +6 -5
- package/dist/lib/index.js.map +1 -1
- package/dist/standalone/assets/action-component-host-8DE4kuUJ.js +2 -0
- package/dist/standalone/assets/action-component-host-8DE4kuUJ.js.br +0 -0
- package/dist/standalone/assets/action-component-host-8DE4kuUJ.js.gz +0 -0
- package/dist/standalone/assets/{action-component-host-P6HcuKj3.js.map → action-component-host-8DE4kuUJ.js.map} +1 -1
- package/dist/standalone/assets/action-page-D6BbXzUo.js +2 -0
- package/dist/standalone/assets/action-page-D6BbXzUo.js.br +0 -0
- package/dist/standalone/assets/action-page-D6BbXzUo.js.gz +0 -0
- package/dist/standalone/assets/{action-page-kyqtK3oq.js.map → action-page-D6BbXzUo.js.map} +1 -1
- package/dist/standalone/assets/ai-assistant-widget-BORa8_hT.js +2 -0
- package/dist/standalone/assets/ai-assistant-widget-BORa8_hT.js.br +0 -0
- package/dist/standalone/assets/ai-assistant-widget-BORa8_hT.js.gz +0 -0
- package/dist/standalone/assets/{ai-assistant-widget-DGanix6u.js.map → ai-assistant-widget-BORa8_hT.js.map} +1 -1
- package/dist/standalone/assets/arrow-left-yVCaEJJu.js +2 -0
- package/dist/standalone/assets/{arrow-left-CI9hUPwJ.js.map → arrow-left-yVCaEJJu.js.map} +1 -1
- package/dist/standalone/assets/audit-log-page-uHj9GWfi.js +2 -0
- package/dist/standalone/assets/audit-log-page-uHj9GWfi.js.br +0 -0
- package/dist/standalone/assets/audit-log-page-uHj9GWfi.js.gz +0 -0
- package/dist/standalone/assets/{audit-log-page-DozriTiA.js.map → audit-log-page-uHj9GWfi.js.map} +1 -1
- package/dist/standalone/assets/badge-CdW_Z0lB.js +2 -0
- package/dist/standalone/assets/{badge-lb2Nqx1b.js.map → badge-CdW_Z0lB.js.map} +1 -1
- package/dist/standalone/assets/{bot-DFDgGfNj.js → bot-CuDPD_ZU.js} +2 -2
- package/dist/standalone/assets/{bot-DFDgGfNj.js.map → bot-CuDPD_ZU.js.map} +1 -1
- package/dist/standalone/assets/cache-page-CBKj7WFq.js +2 -0
- package/dist/standalone/assets/cache-page-CBKj7WFq.js.br +0 -0
- package/dist/standalone/assets/cache-page-CBKj7WFq.js.gz +0 -0
- package/dist/standalone/assets/cache-page-CBKj7WFq.js.map +1 -0
- package/dist/standalone/assets/calendar-BuLRvNBg.js +2 -0
- package/dist/standalone/assets/calendar-BuLRvNBg.js.br +0 -0
- package/dist/standalone/assets/calendar-BuLRvNBg.js.gz +0 -0
- package/dist/standalone/assets/calendar-BuLRvNBg.js.map +1 -0
- package/dist/standalone/assets/card-BYbadRar.js +2 -0
- package/dist/standalone/assets/card-BYbadRar.js.br +0 -0
- package/dist/standalone/assets/card-BYbadRar.js.gz +0 -0
- package/dist/standalone/assets/{card-Dh44j2Nb.js.map → card-BYbadRar.js.map} +1 -1
- package/dist/standalone/assets/chart-widget-Bfk_mvm2.js +2 -0
- package/dist/standalone/assets/chart-widget-Bfk_mvm2.js.br +0 -0
- package/dist/standalone/assets/chart-widget-Bfk_mvm2.js.gz +0 -0
- package/dist/standalone/assets/{chart-widget-B819aHsE.js.map → chart-widget-Bfk_mvm2.js.map} +1 -1
- package/dist/standalone/assets/chevrons-up-down-y29_Sm-3.js +2 -0
- package/dist/standalone/assets/{chevrons-up-down-BHCs46XQ.js.map → chevrons-up-down-y29_Sm-3.js.map} +1 -1
- package/dist/standalone/assets/{circle-alert-0EyKeic4.js → circle-alert-D1sKnXtO.js} +2 -2
- package/dist/standalone/assets/{circle-alert-0EyKeic4.js.map → circle-alert-D1sKnXtO.js.map} +1 -1
- package/dist/standalone/assets/{clock-OCmX6DtA.js → clock-B9qbSr_k.js} +2 -2
- package/dist/standalone/assets/{clock-OCmX6DtA.js.map → clock-B9qbSr_k.js.map} +1 -1
- package/dist/standalone/assets/command-BAXXxf0P.js +2 -0
- package/dist/standalone/assets/command-BAXXxf0P.js.br +0 -0
- package/dist/standalone/assets/command-BAXXxf0P.js.gz +0 -0
- package/dist/standalone/assets/command-BAXXxf0P.js.map +1 -0
- package/dist/standalone/assets/{copy-BexCWf4U.js → copy-5fb4qj-_.js} +2 -2
- package/dist/standalone/assets/{copy-BexCWf4U.js.map → copy-5fb4qj-_.js.map} +1 -1
- package/dist/standalone/assets/createLucideIcon-QE2kj6ru.js +2 -0
- package/dist/standalone/assets/createLucideIcon-QE2kj6ru.js.br +0 -0
- package/dist/standalone/assets/createLucideIcon-QE2kj6ru.js.gz +0 -0
- package/dist/standalone/assets/createLucideIcon-QE2kj6ru.js.map +1 -0
- package/dist/standalone/assets/date-picker-Bxv-yrWf.js +2 -0
- package/dist/standalone/assets/date-picker-Bxv-yrWf.js.br +0 -0
- package/dist/standalone/assets/date-picker-Bxv-yrWf.js.gz +0 -0
- package/dist/standalone/assets/{date-picker-D0dWQEox.js.map → date-picker-Bxv-yrWf.js.map} +1 -1
- package/dist/standalone/assets/dist-COXu-_Zv.js +2 -0
- package/dist/standalone/assets/dist-COXu-_Zv.js.br +0 -0
- package/dist/standalone/assets/dist-COXu-_Zv.js.gz +0 -0
- package/dist/standalone/assets/dist-COXu-_Zv.js.map +1 -0
- package/dist/standalone/assets/dist-CiXwD0ML.js +2 -0
- package/dist/standalone/assets/dist-CiXwD0ML.js.br +0 -0
- package/dist/standalone/assets/dist-CiXwD0ML.js.gz +0 -0
- package/dist/standalone/assets/dist-CiXwD0ML.js.map +1 -0
- package/dist/standalone/assets/dist-DPxQeZn3.js +2 -0
- package/dist/standalone/assets/dist-DPxQeZn3.js.br +0 -0
- package/dist/standalone/assets/dist-DPxQeZn3.js.gz +0 -0
- package/dist/standalone/assets/dist-DPxQeZn3.js.map +1 -0
- package/dist/standalone/assets/edit-page-Dm638D2J.js +2 -0
- package/dist/standalone/assets/edit-page-Dm638D2J.js.br +0 -0
- package/dist/standalone/assets/edit-page-Dm638D2J.js.gz +0 -0
- package/dist/standalone/assets/{edit-page-CFPwq1_5.js.map → edit-page-Dm638D2J.js.map} +1 -1
- package/dist/standalone/assets/{ellipsis-lEjcTxo0.js → ellipsis-BRmOlhsy.js} +2 -2
- package/dist/standalone/assets/{ellipsis-lEjcTxo0.js.map → ellipsis-BRmOlhsy.js.map} +1 -1
- package/dist/standalone/assets/empty-DMs98grx.js +2 -0
- package/dist/standalone/assets/empty-DMs98grx.js.br +0 -0
- package/dist/standalone/assets/empty-DMs98grx.js.gz +0 -0
- package/dist/standalone/assets/empty-DMs98grx.js.map +1 -0
- package/dist/standalone/assets/{file-text-CcLZq8HA.js → file-text-MQF--yeB.js} +2 -2
- package/dist/standalone/assets/{file-text-CcLZq8HA.js.map → file-text-MQF--yeB.js.map} +1 -1
- package/dist/standalone/assets/floating-layer-BcTp2AMB.js +2 -0
- package/dist/standalone/assets/floating-layer-BcTp2AMB.js.br +0 -0
- package/dist/standalone/assets/floating-layer-BcTp2AMB.js.gz +0 -0
- package/dist/standalone/assets/floating-layer-BcTp2AMB.js.map +1 -0
- package/dist/standalone/assets/global-search-dialog-DxwxFDO5.js +2 -0
- package/dist/standalone/assets/global-search-dialog-DxwxFDO5.js.br +0 -0
- package/dist/standalone/assets/global-search-dialog-DxwxFDO5.js.gz +0 -0
- package/dist/standalone/assets/{global-search-dialog-AfQmJSE7.js.map → global-search-dialog-DxwxFDO5.js.map} +1 -1
- package/dist/standalone/assets/heavy-fields-LnhreUPp.js +174 -0
- package/dist/standalone/assets/heavy-fields-LnhreUPp.js.br +0 -0
- package/dist/standalone/assets/heavy-fields-LnhreUPp.js.gz +0 -0
- package/dist/standalone/assets/heavy-fields-LnhreUPp.js.map +1 -0
- package/dist/standalone/assets/home-page-DiDOzuic.js +61 -0
- package/dist/standalone/assets/home-page-DiDOzuic.js.br +0 -0
- package/dist/standalone/assets/home-page-DiDOzuic.js.gz +0 -0
- package/dist/standalone/assets/home-page-DiDOzuic.js.map +1 -0
- package/dist/standalone/assets/hooks-BiOfAnEq.js +186 -0
- package/dist/standalone/assets/hooks-BiOfAnEq.js.br +0 -0
- package/dist/standalone/assets/hooks-BiOfAnEq.js.gz +0 -0
- package/dist/standalone/assets/hooks-BiOfAnEq.js.map +1 -0
- package/dist/standalone/assets/icon-registry-s31CNk7M.js +2 -0
- package/dist/standalone/assets/icon-registry-s31CNk7M.js.br +0 -0
- package/dist/standalone/assets/icon-registry-s31CNk7M.js.gz +0 -0
- package/dist/standalone/assets/icon-registry-s31CNk7M.js.map +1 -0
- package/dist/standalone/assets/index-CASCzvYu.js +15 -0
- package/dist/standalone/assets/index-CASCzvYu.js.br +0 -0
- package/dist/standalone/assets/index-CASCzvYu.js.gz +0 -0
- package/dist/standalone/assets/index-CASCzvYu.js.map +1 -0
- package/dist/standalone/assets/index-Cz5ntgJ_.css +2 -0
- package/dist/standalone/assets/index-Cz5ntgJ_.css.br +0 -0
- package/dist/standalone/assets/index-Cz5ntgJ_.css.gz +0 -0
- package/dist/standalone/assets/{info-CGVdWTj1.js → info-ChwYoM77.js} +2 -2
- package/dist/standalone/assets/{info-CGVdWTj1.js.map → info-ChwYoM77.js.map} +1 -1
- package/dist/standalone/assets/json-editor-BD0UhGOT.js +2 -0
- package/dist/standalone/assets/json-editor-BD0UhGOT.js.br +0 -0
- package/dist/standalone/assets/json-editor-BD0UhGOT.js.gz +0 -0
- package/dist/standalone/assets/json-editor-BD0UhGOT.js.map +1 -0
- package/dist/standalone/assets/key-BzJFbNbz.js +2 -0
- package/dist/standalone/assets/key-BzJFbNbz.js.map +1 -0
- package/dist/standalone/assets/{key-round-CQLp1Ua9.js → key-round-oSqmVdkQ.js} +2 -2
- package/dist/standalone/assets/{key-round-CQLp1Ua9.js.map → key-round-oSqmVdkQ.js.map} +1 -1
- package/dist/standalone/assets/{minimize-2-Bx2cH_WS.js → minimize-2-iWv98HjE.js} +2 -2
- package/dist/standalone/assets/{minimize-2-Bx2cH_WS.js.map → minimize-2-iWv98HjE.js.map} +1 -1
- package/dist/standalone/assets/{palette-DVP_4RAn.js → palette-jgTV28yN.js} +2 -2
- package/dist/standalone/assets/{palette-DVP_4RAn.js.map → palette-jgTV28yN.js.map} +1 -1
- package/dist/standalone/assets/{pencil-BO-k3yTG.js → pencil-kFOObGrY.js} +2 -2
- package/dist/standalone/assets/{pencil-BO-k3yTG.js.map → pencil-kFOObGrY.js.map} +1 -1
- package/dist/standalone/assets/{pipette-CqHYfQnn.js → pipette-roLBCmPv.js} +2 -2
- package/dist/standalone/assets/pipette-roLBCmPv.js.br +0 -0
- package/dist/standalone/assets/pipette-roLBCmPv.js.gz +0 -0
- package/dist/standalone/assets/{pipette-CqHYfQnn.js.map → pipette-roLBCmPv.js.map} +1 -1
- package/dist/standalone/assets/plus-D7PHzena.js +2 -0
- package/dist/standalone/assets/{plus-Dk-FzitW.js.map → plus-D7PHzena.js.map} +1 -1
- package/dist/standalone/assets/property-renderer-ClrVnSny.js +4 -0
- package/dist/standalone/assets/property-renderer-ClrVnSny.js.br +0 -0
- package/dist/standalone/assets/property-renderer-ClrVnSny.js.gz +0 -0
- package/dist/standalone/assets/property-renderer-ClrVnSny.js.map +1 -0
- package/dist/standalone/assets/reference-BMbhUBHD.js +2 -0
- package/dist/standalone/assets/reference-BMbhUBHD.js.br +0 -0
- package/dist/standalone/assets/reference-BMbhUBHD.js.gz +0 -0
- package/dist/standalone/assets/{reference-DWJEoGIf.js.map → reference-BMbhUBHD.js.map} +1 -1
- package/dist/standalone/assets/refresh-cw-Cm9YiHGV.js +2 -0
- package/dist/standalone/assets/refresh-cw-Cm9YiHGV.js.map +1 -0
- package/dist/standalone/assets/revisions-button-Csueldv_.js +2 -0
- package/dist/standalone/assets/revisions-button-Csueldv_.js.br +0 -0
- package/dist/standalone/assets/revisions-button-Csueldv_.js.gz +0 -0
- package/dist/standalone/assets/{revisions-button-DR0oW2wX.js.map → revisions-button-Csueldv_.js.map} +1 -1
- package/dist/standalone/assets/richtext-render-DaiNQPjZ.js +68 -0
- package/dist/standalone/assets/richtext-render-DaiNQPjZ.js.br +0 -0
- package/dist/standalone/assets/richtext-render-DaiNQPjZ.js.gz +0 -0
- package/dist/standalone/assets/richtext-render-DaiNQPjZ.js.map +1 -0
- package/dist/standalone/assets/{rotate-ccw-BLr0QLAg.js → rotate-ccw-AB1VcvbK.js} +2 -2
- package/dist/standalone/assets/{rotate-ccw-BLr0QLAg.js.map → rotate-ccw-AB1VcvbK.js.map} +1 -1
- package/dist/standalone/assets/{save-Cd3oR3Sj.js → save-BkkrgP5Q.js} +2 -2
- package/dist/standalone/assets/{save-Cd3oR3Sj.js.map → save-BkkrgP5Q.js.map} +1 -1
- package/dist/standalone/assets/schemas-ByMQmMCS.js +65 -0
- package/dist/standalone/assets/schemas-ByMQmMCS.js.br +0 -0
- package/dist/standalone/assets/schemas-ByMQmMCS.js.gz +0 -0
- package/dist/standalone/assets/schemas-ByMQmMCS.js.map +1 -0
- package/dist/standalone/assets/select-BOe2daO9.js +2 -0
- package/dist/standalone/assets/select-BOe2daO9.js.br +0 -0
- package/dist/standalone/assets/select-BOe2daO9.js.gz +0 -0
- package/dist/standalone/assets/select-BOe2daO9.js.map +1 -0
- package/dist/standalone/assets/{send-D4KHQGYj.js → send-Bzb_4uMT.js} +2 -2
- package/dist/standalone/assets/{send-D4KHQGYj.js.map → send-Bzb_4uMT.js.map} +1 -1
- package/dist/standalone/assets/settings-page-BmphreWj.js +2 -0
- package/dist/standalone/assets/settings-page-BmphreWj.js.br +0 -0
- package/dist/standalone/assets/settings-page-BmphreWj.js.gz +0 -0
- package/dist/standalone/assets/{settings-page-DSWp2N6T.js.map → settings-page-BmphreWj.js.map} +1 -1
- package/dist/standalone/assets/show-page-CDgUXhsx.js +2 -0
- package/dist/standalone/assets/show-page-CDgUXhsx.js.br +0 -0
- package/dist/standalone/assets/show-page-CDgUXhsx.js.gz +0 -0
- package/dist/standalone/assets/{show-page-CGzUAZoO.js.map → show-page-CDgUXhsx.js.map} +1 -1
- package/dist/standalone/assets/{sparkles-CqF0zjrF.js → sparkles-1tT0H4n4.js} +2 -2
- package/dist/standalone/assets/{sparkles-CqF0zjrF.js.map → sparkles-1tT0H4n4.js.map} +1 -1
- package/dist/standalone/assets/{square-pen-DGT7ekeJ.js → square-pen-ZvVEwkzw.js} +2 -2
- package/dist/standalone/assets/{square-pen-DGT7ekeJ.js.map → square-pen-ZvVEwkzw.js.map} +1 -1
- package/dist/standalone/assets/table-RI-lM4fw.js +2 -0
- package/dist/standalone/assets/table-RI-lM4fw.js.br +1 -0
- package/dist/standalone/assets/table-RI-lM4fw.js.gz +0 -0
- package/dist/standalone/assets/table-RI-lM4fw.js.map +1 -0
- package/dist/standalone/assets/tabs-Bj4gQaH2.js +2 -0
- package/dist/standalone/assets/tabs-Bj4gQaH2.js.br +0 -0
- package/dist/standalone/assets/tabs-Bj4gQaH2.js.gz +0 -0
- package/dist/standalone/assets/tabs-Bj4gQaH2.js.map +1 -0
- package/dist/standalone/assets/textarea-C2w7TG3h.js +2 -0
- package/dist/standalone/assets/{textarea-DBVf3GGt.js.map → textarea-C2w7TG3h.js.map} +1 -1
- package/dist/standalone/assets/{trash-2-DhyKQCKv.js → trash-2-BIJVpWxv.js} +2 -2
- package/dist/standalone/assets/{trash-2-DhyKQCKv.js.map → trash-2-BIJVpWxv.js.map} +1 -1
- package/dist/standalone/assets/{triangle-alert-CyaaNWN8.js → triangle-alert-yljVpQCM.js} +2 -2
- package/dist/standalone/assets/{triangle-alert-CyaaNWN8.js.map → triangle-alert-yljVpQCM.js.map} +1 -1
- package/dist/standalone/assets/{undo-2-DlSB-5DM.js → undo-2-CnH3ScKE.js} +2 -2
- package/dist/standalone/assets/undo-2-CnH3ScKE.js.br +0 -0
- package/dist/standalone/assets/undo-2-CnH3ScKE.js.gz +0 -0
- package/dist/standalone/assets/{undo-2-DlSB-5DM.js.map → undo-2-CnH3ScKE.js.map} +1 -1
- package/dist/standalone/assets/{upload-BVhXhZgn.js → upload-DrfB-4bU.js} +2 -2
- package/dist/standalone/assets/upload-DrfB-4bU.js.br +0 -0
- package/dist/standalone/assets/upload-DrfB-4bU.js.gz +0 -0
- package/dist/standalone/assets/{upload-BVhXhZgn.js.map → upload-DrfB-4bU.js.map} +1 -1
- package/dist/standalone/assets/use-dashboard-charts-D7-ctwCE.js +2 -0
- package/dist/standalone/assets/use-dashboard-charts-D7-ctwCE.js.br +0 -0
- package/dist/standalone/assets/use-dashboard-charts-D7-ctwCE.js.gz +0 -0
- package/dist/standalone/assets/{use-dashboard-charts-Cr3OUSL5.js.map → use-dashboard-charts-D7-ctwCE.js.map} +1 -1
- package/dist/standalone/assets/useQueries-DNUnShBb.js +2 -0
- package/dist/standalone/assets/useQueries-DNUnShBb.js.br +0 -0
- package/dist/standalone/assets/useQueries-DNUnShBb.js.gz +0 -0
- package/dist/standalone/assets/useQueries-DNUnShBb.js.map +1 -0
- package/dist/standalone/assets/{user-directory-Df5X8VOe.js → user-directory-BvmDzxsG.js} +2 -2
- package/dist/standalone/assets/user-directory-BvmDzxsG.js.br +0 -0
- package/dist/standalone/assets/user-directory-BvmDzxsG.js.gz +0 -0
- package/dist/standalone/assets/{user-directory-Df5X8VOe.js.map → user-directory-BvmDzxsG.js.map} +1 -1
- package/dist/standalone/assets/{wand-sparkles-DWaFQeYS.js → wand-sparkles-DwseTI5T.js} +2 -2
- package/dist/standalone/assets/{wand-sparkles-DWaFQeYS.js.map → wand-sparkles-DwseTI5T.js.map} +1 -1
- package/dist/standalone/assets/wizard-create-page-D4a8FnmI.js +2 -0
- package/dist/standalone/assets/wizard-create-page-D4a8FnmI.js.br +0 -0
- package/dist/standalone/assets/wizard-create-page-D4a8FnmI.js.gz +0 -0
- package/dist/standalone/assets/{wizard-create-page-B8IcszRF.js.map → wizard-create-page-D4a8FnmI.js.map} +1 -1
- package/dist/standalone/assets/x-c-gfVPJa.js +2 -0
- package/dist/standalone/assets/{x-C3kLunD6.js.map → x-c-gfVPJa.js.map} +1 -1
- package/dist/standalone/assets/zap-BxPAEPtJ.js +2 -0
- package/dist/standalone/assets/zap-BxPAEPtJ.js.map +1 -0
- package/dist/standalone/assets/zod-2-ubQvxh.js +2 -0
- package/dist/standalone/assets/zod-2-ubQvxh.js.br +0 -0
- package/dist/standalone/assets/zod-2-ubQvxh.js.gz +0 -0
- package/dist/standalone/assets/zod-2-ubQvxh.js.map +1 -0
- package/dist/standalone/index.html +12 -12
- package/dist/standalone/index.html.br +0 -0
- package/dist/standalone/index.html.gz +0 -0
- package/package.json +21 -21
- package/src/vite.ts +21 -0
- package/dist/standalone/assets/action-component-host-P6HcuKj3.js +0 -2
- package/dist/standalone/assets/action-component-host-P6HcuKj3.js.br +0 -0
- package/dist/standalone/assets/action-component-host-P6HcuKj3.js.gz +0 -0
- package/dist/standalone/assets/action-page-kyqtK3oq.js +0 -2
- package/dist/standalone/assets/action-page-kyqtK3oq.js.br +0 -0
- package/dist/standalone/assets/action-page-kyqtK3oq.js.gz +0 -0
- package/dist/standalone/assets/ai-assistant-widget-DGanix6u.js +0 -2
- package/dist/standalone/assets/ai-assistant-widget-DGanix6u.js.br +0 -0
- package/dist/standalone/assets/ai-assistant-widget-DGanix6u.js.gz +0 -0
- package/dist/standalone/assets/arrow-left-CI9hUPwJ.js +0 -2
- package/dist/standalone/assets/audit-log-page-DozriTiA.js +0 -2
- package/dist/standalone/assets/audit-log-page-DozriTiA.js.br +0 -0
- package/dist/standalone/assets/audit-log-page-DozriTiA.js.gz +0 -0
- package/dist/standalone/assets/badge-lb2Nqx1b.js +0 -2
- package/dist/standalone/assets/calendar-crtd4PEn.js +0 -2
- package/dist/standalone/assets/calendar-crtd4PEn.js.br +0 -0
- package/dist/standalone/assets/calendar-crtd4PEn.js.gz +0 -0
- package/dist/standalone/assets/calendar-crtd4PEn.js.map +0 -1
- package/dist/standalone/assets/card-Dh44j2Nb.js +0 -2
- package/dist/standalone/assets/card-Dh44j2Nb.js.br +0 -0
- package/dist/standalone/assets/card-Dh44j2Nb.js.gz +0 -0
- package/dist/standalone/assets/chart-widget-B819aHsE.js +0 -2
- package/dist/standalone/assets/chart-widget-B819aHsE.js.br +0 -0
- package/dist/standalone/assets/chart-widget-B819aHsE.js.gz +0 -0
- package/dist/standalone/assets/chevrons-up-down-BHCs46XQ.js +0 -2
- package/dist/standalone/assets/command-xJ-6Grpv.js +0 -2
- package/dist/standalone/assets/command-xJ-6Grpv.js.br +0 -0
- package/dist/standalone/assets/command-xJ-6Grpv.js.gz +0 -0
- package/dist/standalone/assets/command-xJ-6Grpv.js.map +0 -1
- package/dist/standalone/assets/createLucideIcon-CUopU_LC.js +0 -2
- package/dist/standalone/assets/createLucideIcon-CUopU_LC.js.br +0 -0
- package/dist/standalone/assets/createLucideIcon-CUopU_LC.js.gz +0 -0
- package/dist/standalone/assets/createLucideIcon-CUopU_LC.js.map +0 -1
- package/dist/standalone/assets/date-picker-D0dWQEox.js +0 -2
- package/dist/standalone/assets/date-picker-D0dWQEox.js.br +0 -0
- package/dist/standalone/assets/date-picker-D0dWQEox.js.gz +0 -0
- package/dist/standalone/assets/dist-CWGgVQiS.js +0 -2
- package/dist/standalone/assets/dist-CWGgVQiS.js.br +0 -0
- package/dist/standalone/assets/dist-CWGgVQiS.js.gz +0 -0
- package/dist/standalone/assets/dist-CWGgVQiS.js.map +0 -1
- package/dist/standalone/assets/dist-UsTgBPww.js +0 -2
- package/dist/standalone/assets/dist-UsTgBPww.js.br +0 -0
- package/dist/standalone/assets/dist-UsTgBPww.js.gz +0 -0
- package/dist/standalone/assets/dist-UsTgBPww.js.map +0 -1
- package/dist/standalone/assets/dist-qlnAsTo_.js +0 -2
- package/dist/standalone/assets/dist-qlnAsTo_.js.br +0 -0
- package/dist/standalone/assets/dist-qlnAsTo_.js.gz +0 -0
- package/dist/standalone/assets/dist-qlnAsTo_.js.map +0 -1
- package/dist/standalone/assets/edit-page-CFPwq1_5.js +0 -2
- package/dist/standalone/assets/edit-page-CFPwq1_5.js.br +0 -0
- package/dist/standalone/assets/edit-page-CFPwq1_5.js.gz +0 -0
- package/dist/standalone/assets/empty-D9sUunOr.js +0 -2
- package/dist/standalone/assets/empty-D9sUunOr.js.br +0 -0
- package/dist/standalone/assets/empty-D9sUunOr.js.gz +0 -0
- package/dist/standalone/assets/empty-D9sUunOr.js.map +0 -1
- package/dist/standalone/assets/global-search-dialog-AfQmJSE7.js +0 -2
- package/dist/standalone/assets/global-search-dialog-AfQmJSE7.js.br +0 -0
- package/dist/standalone/assets/global-search-dialog-AfQmJSE7.js.gz +0 -0
- package/dist/standalone/assets/heavy-fields-_zVIBnm1.js +0 -181
- package/dist/standalone/assets/heavy-fields-_zVIBnm1.js.br +0 -0
- package/dist/standalone/assets/heavy-fields-_zVIBnm1.js.gz +0 -0
- package/dist/standalone/assets/heavy-fields-_zVIBnm1.js.map +0 -1
- package/dist/standalone/assets/home-page-BdTrAXqk.js +0 -3
- package/dist/standalone/assets/home-page-BdTrAXqk.js.br +0 -0
- package/dist/standalone/assets/home-page-BdTrAXqk.js.gz +0 -0
- package/dist/standalone/assets/home-page-BdTrAXqk.js.map +0 -1
- package/dist/standalone/assets/icon-registry-CcMm2Zh3.js +0 -2
- package/dist/standalone/assets/icon-registry-CcMm2Zh3.js.br +0 -0
- package/dist/standalone/assets/icon-registry-CcMm2Zh3.js.gz +0 -0
- package/dist/standalone/assets/icon-registry-CcMm2Zh3.js.map +0 -1
- package/dist/standalone/assets/index-DHZwffoP.css +0 -2
- package/dist/standalone/assets/index-DHZwffoP.css.br +0 -0
- package/dist/standalone/assets/index-DHZwffoP.css.gz +0 -0
- package/dist/standalone/assets/index-uYpCUVT4.js +0 -15
- package/dist/standalone/assets/index-uYpCUVT4.js.br +0 -0
- package/dist/standalone/assets/index-uYpCUVT4.js.gz +0 -0
- package/dist/standalone/assets/index-uYpCUVT4.js.map +0 -1
- package/dist/standalone/assets/json-editor-yfO4TUB_.js +0 -2
- package/dist/standalone/assets/json-editor-yfO4TUB_.js.br +0 -0
- package/dist/standalone/assets/json-editor-yfO4TUB_.js.gz +0 -0
- package/dist/standalone/assets/json-editor-yfO4TUB_.js.map +0 -1
- package/dist/standalone/assets/key-lbuX0yk_.js +0 -2
- package/dist/standalone/assets/key-lbuX0yk_.js.map +0 -1
- package/dist/standalone/assets/pipette-CqHYfQnn.js.br +0 -0
- package/dist/standalone/assets/pipette-CqHYfQnn.js.gz +0 -0
- package/dist/standalone/assets/plus-Dk-FzitW.js +0 -2
- package/dist/standalone/assets/property-renderer-CDKsa2KQ.js +0 -7
- package/dist/standalone/assets/property-renderer-CDKsa2KQ.js.br +0 -0
- package/dist/standalone/assets/property-renderer-CDKsa2KQ.js.gz +0 -0
- package/dist/standalone/assets/property-renderer-CDKsa2KQ.js.map +0 -1
- package/dist/standalone/assets/reference-DWJEoGIf.js +0 -2
- package/dist/standalone/assets/reference-DWJEoGIf.js.br +0 -0
- package/dist/standalone/assets/reference-DWJEoGIf.js.gz +0 -0
- package/dist/standalone/assets/refresh-cw-DHvUQTMb.js +0 -2
- package/dist/standalone/assets/refresh-cw-DHvUQTMb.js.map +0 -1
- package/dist/standalone/assets/revisions-button-DR0oW2wX.js +0 -2
- package/dist/standalone/assets/revisions-button-DR0oW2wX.js.br +0 -0
- package/dist/standalone/assets/revisions-button-DR0oW2wX.js.gz +0 -0
- package/dist/standalone/assets/richtext-render-VFCKGulc.js +0 -67
- package/dist/standalone/assets/richtext-render-VFCKGulc.js.br +0 -0
- package/dist/standalone/assets/richtext-render-VFCKGulc.js.gz +0 -0
- package/dist/standalone/assets/richtext-render-VFCKGulc.js.map +0 -1
- package/dist/standalone/assets/router-BcZgB5cZ.js +0 -186
- package/dist/standalone/assets/router-BcZgB5cZ.js.br +0 -0
- package/dist/standalone/assets/router-BcZgB5cZ.js.gz +0 -0
- package/dist/standalone/assets/router-BcZgB5cZ.js.map +0 -1
- package/dist/standalone/assets/schemas-twnCb1uT.js +0 -65
- package/dist/standalone/assets/schemas-twnCb1uT.js.br +0 -0
- package/dist/standalone/assets/schemas-twnCb1uT.js.gz +0 -0
- package/dist/standalone/assets/schemas-twnCb1uT.js.map +0 -1
- package/dist/standalone/assets/select-BiV9bunJ.js +0 -2
- package/dist/standalone/assets/select-BiV9bunJ.js.br +0 -0
- package/dist/standalone/assets/select-BiV9bunJ.js.gz +0 -0
- package/dist/standalone/assets/select-BiV9bunJ.js.map +0 -1
- package/dist/standalone/assets/settings-page-DSWp2N6T.js +0 -2
- package/dist/standalone/assets/settings-page-DSWp2N6T.js.br +0 -0
- package/dist/standalone/assets/settings-page-DSWp2N6T.js.gz +0 -0
- package/dist/standalone/assets/show-page-CGzUAZoO.js +0 -2
- package/dist/standalone/assets/show-page-CGzUAZoO.js.br +0 -0
- package/dist/standalone/assets/show-page-CGzUAZoO.js.gz +0 -0
- package/dist/standalone/assets/tabs-smdw70rV.js +0 -2
- package/dist/standalone/assets/tabs-smdw70rV.js.br +0 -0
- package/dist/standalone/assets/tabs-smdw70rV.js.gz +0 -0
- package/dist/standalone/assets/tabs-smdw70rV.js.map +0 -1
- package/dist/standalone/assets/textarea-DBVf3GGt.js +0 -2
- package/dist/standalone/assets/undo-2-DlSB-5DM.js.br +0 -0
- package/dist/standalone/assets/undo-2-DlSB-5DM.js.gz +0 -0
- package/dist/standalone/assets/upload-BVhXhZgn.js.br +0 -0
- package/dist/standalone/assets/upload-BVhXhZgn.js.gz +0 -0
- package/dist/standalone/assets/use-dashboard-charts-Cr3OUSL5.js +0 -2
- package/dist/standalone/assets/use-dashboard-charts-Cr3OUSL5.js.br +0 -0
- package/dist/standalone/assets/use-dashboard-charts-Cr3OUSL5.js.gz +0 -0
- package/dist/standalone/assets/useQueries-Ba2PuYhZ.js +0 -2
- package/dist/standalone/assets/useQueries-Ba2PuYhZ.js.br +0 -0
- package/dist/standalone/assets/useQueries-Ba2PuYhZ.js.gz +0 -0
- package/dist/standalone/assets/useQueries-Ba2PuYhZ.js.map +0 -1
- package/dist/standalone/assets/user-directory-Df5X8VOe.js.br +0 -0
- package/dist/standalone/assets/user-directory-Df5X8VOe.js.gz +0 -0
- package/dist/standalone/assets/value-format-BUeGtfH4.js +0 -60
- package/dist/standalone/assets/value-format-BUeGtfH4.js.br +0 -0
- package/dist/standalone/assets/value-format-BUeGtfH4.js.gz +0 -0
- package/dist/standalone/assets/value-format-BUeGtfH4.js.map +0 -1
- package/dist/standalone/assets/with-selector-id7qGzTH.js +0 -2
- package/dist/standalone/assets/with-selector-id7qGzTH.js.br +0 -0
- package/dist/standalone/assets/with-selector-id7qGzTH.js.gz +0 -0
- package/dist/standalone/assets/with-selector-id7qGzTH.js.map +0 -1
- package/dist/standalone/assets/wizard-create-page-B8IcszRF.js +0 -2
- package/dist/standalone/assets/wizard-create-page-B8IcszRF.js.br +0 -0
- package/dist/standalone/assets/wizard-create-page-B8IcszRF.js.gz +0 -0
- package/dist/standalone/assets/x-C3kLunD6.js +0 -2
- package/dist/standalone/assets/zap-b3saQVKc.js +0 -2
- package/dist/standalone/assets/zap-b3saQVKc.js.map +0 -1
- package/dist/standalone/assets/zod-mi61gVha.js +0 -2
- package/dist/standalone/assets/zod-mi61gVha.js.br +0 -0
- package/dist/standalone/assets/zod-mi61gVha.js.gz +0 -0
- package/dist/standalone/assets/zod-mi61gVha.js.map +0 -1
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./chart-widget-B819aHsE.js","./createLucideIcon-CUopU_LC.js","./with-selector-id7qGzTH.js","./refresh-cw-DHvUQTMb.js","./trash-2-DhyKQCKv.js","./minimize-2-Bx2cH_WS.js","./copy-BexCWf4U.js","./ellipsis-lEjcTxo0.js","./pencil-BO-k3yTG.js","./palette-DVP_4RAn.js","./triangle-alert-CyaaNWN8.js","./dist-UsTgBPww.js","./select-BiV9bunJ.js","./dist-CWGgVQiS.js","./router-BcZgB5cZ.js","./index-uYpCUVT4.js","./x-C3kLunD6.js","./dist-qlnAsTo_.js","./index-DHZwffoP.css","./date-picker-D0dWQEox.js","./calendar-crtd4PEn.js","./calendar-Chw94eNX.css","./useQueries-Ba2PuYhZ.js","./card-Dh44j2Nb.js","./value-format-BUeGtfH4.js","./pipette-CqHYfQnn.js","./use-dashboard-charts-Cr3OUSL5.js","./schemas-twnCb1uT.js","./uuid-DLSnbsz2.js","./reference-DWJEoGIf.js","./chevrons-up-down-BHCs46XQ.js","./badge-lb2Nqx1b.js","./command-xJ-6Grpv.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{a as e,n as t}from"./createLucideIcon-CUopU_LC.js";import{E as n}from"./with-selector-id7qGzTH.js";import{a as r,i,n as a,o,r as s}from"./pipette-CqHYfQnn.js";import{t as c}from"./trash-2-DhyKQCKv.js";import{t as l}from"./pencil-BO-k3yTG.js";import{t as u}from"./plus-Dk-FzitW.js";import{t as d}from"./x-C3kLunD6.js";import{s as f}from"./dist-UsTgBPww.js";import{a as p,i as m,n as h,r as g,t as _}from"./select-BiV9bunJ.js";import{a as v,c as y,i as ee,o as b,r as x,s as S,t as C}from"./empty-D9sUunOr.js";import{M as te,et as w,n as T,q as ne,rt as re}from"./router-BcZgB5cZ.js";import{a as E,i as D,n as O,t as k}from"./card-Dh44j2Nb.js";import{i as A,n as j,r as ie,t as ae}from"./tabs-smdw70rV.js";import{a as oe,o as se,r as ce,t as le}from"./value-format-BUeGtfH4.js";import{t as M}from"./uuid-DLSnbsz2.js";import{a as N,i as ue,t as de}from"./use-dashboard-charts-Cr3OUSL5.js";import{t as P}from"./reference-DWJEoGIf.js";import{H as F,I,L,N as R,P as z,R as B,Y as V,mt as fe,q as H,r as pe,t as U}from"./index-uYpCUVT4.js";var W=e(t(),1),G=n(),me=[{value:`kpi`,icon:(0,G.jsx)(o,{className:`size-4`}),labelKey:`dashboard:visKpi`},{value:`line`,icon:(0,G.jsx)(i,{className:`size-4`}),labelKey:`dashboard:visLine`},{value:`area`,icon:(0,G.jsx)(r,{className:`size-4`}),labelKey:`dashboard:visArea`},{value:`bar`,icon:(0,G.jsx)(s,{className:`size-4`}),labelKey:`dashboard:visBar`}],K=`__none__`,he=[`count`,`sum`,`avg`,`min`,`max`],ge=[`divide`,`multiply`,`add`,`subtract`],_e=[`number`,`currency`,`percent`],ve=[`7d`,`30d`,`90d`,`1y`,`all`];function ye(e){if(e.type===`date`||e.type===`datetime`)return!0;let t=e.path.toLowerCase();return t.endsWith(`at`)||t.endsWith(`_at`)||t.endsWith(`date`)}function be(e){if(ye(e))return!1;if(e.type===`reference`&&!e.isArray){let t=e.path;return t.endsWith(`Id`)||t.endsWith(`_id`)}return!(e.type===`json`||e.type===`mixed`||e.type===`richtext`||e.type===`markdown`||e.type===`textarea`||e.type===`previewMedia`||e.type===`file`)}function q({initial:e,onSave:t,onClose:n}){let{t:r,locale:i}=w(),a=ne(),[o,s]=W.useState(e?.title??``),[c,l]=W.useState(e?.visualisation??`area`),[v,ee]=W.useState(e?.resource??a[0]?.id??``),[b,x]=W.useState(e?.dateField??``),[C,te]=W.useState(e?.metric??`count`),[T,re]=W.useState(e?.field??``),[E,D]=W.useState(e?.groupBy??``),[O,k]=W.useState(e?.groupByLabelResource??``),[ue,de]=W.useState(e?.topN??10),[P,F]=W.useState(e&&e.timeRange.preset!==`custom`?e.timeRange.preset:`30d`),[fe,pe]=W.useState(e?.filters??{}),[U,q]=W.useState(e?.quickFilters??[]),[Te,Ee]=W.useState(e?.order??0),[De,Oe]=W.useState(e?.comparePrevious??!1),[J,Y]=W.useState(()=>e?.transform?.map(e=>({...e}))??[]),[X,ke]=W.useState(e?.format?.style??`number`),[Ae,je]=W.useState(e?.format?.currency??``),[Me,Ne]=W.useState(e?.format?.decimals==null?``:String(e.format.decimals)),[Pe,Fe]=W.useState(e?.format?.compact??!1),[Ie,Le]=W.useState(e?.format?.prefix??``),[Re,ze]=W.useState(e?.format?.suffix??``),[Be,Ve]=W.useState(e?.series?.__total__?.color),[Z,He]=W.useState({}),[Ue,We]=W.useState(`data`),Ge=a.find(e=>e.id===v),Q=Ge?.properties??[],Ke=Q.filter(ye),qe=Q.filter(e=>e.type===`number`||e.type===`float`||e.type===`currency`);W.useEffect(()=>{e?.resource!==v&&(x(Ke[0]?.path??``),re(``),D(``),k(``),pe({}),q([]))},[v]),W.useEffect(()=>{O||!E||Q.length===0||k(we(E,Q))},[E,Q]);let $=c===`kpi`,Je=()=>({preset:P}),Ye=()=>{let e=Me===``?void 0:Math.max(0,Math.min(6,Math.trunc(Number(Me)))),t={style:X,...X===`currency`&&Ae.trim().length===3?{currency:Ae.trim().toUpperCase()}:{},...e!=null&&Number.isFinite(e)?{decimals:e}:{},...Ie?{prefix:Ie.slice(0,8)}:{},...Re?{suffix:Re.slice(0,8)}:{},...Pe?{compact:!0}:{}};return t.style===`number`&&Object.keys(t).length===1?void 0:t},Xe=()=>{let t={...e?.series};return!$&&!E&&(Be?t.__total__={color:Be}:delete t.__total__),Object.keys(t).length?t:void 0},Ze=W.useMemo(()=>ce(Ye(),i),[X,Ae,Me,Pe,Ie,Re,i]),Qe=1234,$e=`${Qe} → ${Ze(le(Qe,J))}`,et=(e,t)=>{pe(n=>{let r={...n};return t===``?delete r[e]:r[e]=t,r})},tt=e=>{q(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])};return(0,G.jsx)(R,{open:!0,onOpenChange:e=>{e||n()},children:(0,G.jsxs)(z,{className:`w-full max-w-2xl max-h-[90vh] overflow-y-auto`,children:[(0,G.jsx)(L,{children:(0,G.jsx)(B,{children:r(e?`chart:editChart`:`chart:newChart`)})}),(0,G.jsxs)(ae,{value:Ue,onValueChange:e=>We(e),className:`py-1`,children:[(0,G.jsxs)(ie,{children:[(0,G.jsx)(A,{value:`data`,children:r(`dashboard:builder.tabData`)}),(0,G.jsx)(A,{value:`display`,children:r(`dashboard:builder.tabDisplay`)}),(0,G.jsx)(A,{value:`filters`,children:r(`dashboard:builder.tabFilters`)})]}),(0,G.jsxs)(j,{value:`data`,className:`space-y-4`,children:[(0,G.jsxs)(`div`,{className:`grid grid-cols-1 gap-3 sm:grid-cols-[1fr_8rem]`,children:[(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{htmlFor:`chart-title`,children:r(`chart:title`)}),(0,G.jsx)(V,{id:`chart-title`,placeholder:r(`chart:titlePlaceholder`),value:o,onChange:e=>s(e.target.value)})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,G.jsx)(H,{htmlFor:`chart-order`,children:r(`chart:order`)}),(0,G.jsx)(S,{content:r(`chart:orderHint`)})]}),(0,G.jsx)(V,{id:`chart-order`,type:`number`,step:1,value:Te,onChange:e=>Ee(Number.isFinite(Number(e.target.value))?Math.trunc(Number(e.target.value)):0)})]})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{children:r(`dashboard:vis`)}),(0,G.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:me.map(({value:e,icon:t,labelKey:n})=>(0,G.jsxs)(f,{type:`button`,variant:c===e?`default`:`outline`,size:`sm`,className:`flex-1 min-w-[5rem] gap-1.5 capitalize`,onClick:()=>l(e),children:[t,(0,G.jsx)(`span`,{className:`hidden sm:inline`,children:r(n)})]},e))})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{htmlFor:`chart-resource`,children:r(`chart:resource`)}),(0,G.jsxs)(_,{value:v,onValueChange:e=>ee(e),children:[(0,G.jsx)(m,{id:`chart-resource`,children:(0,G.jsx)(p,{})}),(0,G.jsx)(h,{children:a.map(e=>(0,G.jsxs)(g,{value:e.id,children:[e.name,e.name!==e.id&&(0,G.jsxs)(`span`,{className:`ml-1.5 text-xs text-muted-foreground`,children:[`(`,e.id,`)`]})]},e.id))})]}),Z.resource&&(0,G.jsx)(`p`,{className:`text-xs text-destructive`,children:Z.resource})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{htmlFor:`chart-datefield`,children:r(`dashboard:builder.dateField`)}),(0,G.jsxs)(_,{value:b||K,onValueChange:e=>x(e===K?``:e),children:[(0,G.jsx)(m,{id:`chart-datefield`,children:(0,G.jsx)(p,{placeholder:r(`chart:selectField`)})}),(0,G.jsxs)(h,{children:[(0,G.jsx)(g,{value:K,children:r(`chart:selectField`)}),(Ke.length>0?Ke:Q).map(e=>(0,G.jsx)(g,{value:e.path,children:e.label},e.path))]})]}),(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r(`dashboard:builder.dateFieldHint`)}),Z.dateField&&(0,G.jsx)(`p`,{className:`text-xs text-destructive`,children:Z.dateField})]}),(0,G.jsxs)(`div`,{className:`grid grid-cols-1 gap-3 sm:grid-cols-2`,children:[(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{htmlFor:`chart-metric`,children:r(`chart:metric`)}),(0,G.jsxs)(_,{value:C,onValueChange:e=>te(e),children:[(0,G.jsx)(m,{id:`chart-metric`,children:(0,G.jsx)(p,{})}),(0,G.jsx)(h,{children:he.map(e=>(0,G.jsx)(g,{value:e,children:r(`dashboard:metric${xe(e)}`)},e))})]})]}),C!==`count`&&(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{htmlFor:`chart-field`,children:r(`chart:aggregateField`)}),(0,G.jsxs)(_,{value:T||K,onValueChange:e=>re(e===K?``:e),children:[(0,G.jsx)(m,{id:`chart-field`,children:(0,G.jsx)(p,{placeholder:r(`chart:selectField`)})}),(0,G.jsxs)(h,{children:[(0,G.jsx)(g,{value:K,children:r(`chart:selectField`)}),qe.map(e=>(0,G.jsx)(g,{value:e.path,children:e.label},e.path))]})]}),Z.field&&(0,G.jsx)(`p`,{className:`text-xs text-destructive`,children:Z.field})]})]}),!$&&(0,G.jsxs)(`div`,{className:`grid grid-cols-1 gap-3 sm:grid-cols-2`,children:[(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{htmlFor:`chart-groupby`,children:r(`dashboard:builder.secondaryGroupBy`)}),(0,G.jsxs)(_,{value:E||K,onValueChange:e=>{let t=e===K?``:e;D(t),k(we(t,Q))},children:[(0,G.jsx)(m,{id:`chart-groupby`,children:(0,G.jsx)(p,{})}),(0,G.jsxs)(h,{children:[(0,G.jsx)(g,{value:K,children:r(`dashboard:builder.noBreakdown`)}),Q.filter(e=>be(e)&&e.path!==b).map(e=>(0,G.jsx)(g,{value:e.path,children:e.label},e.path))]})]})]}),E&&(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{htmlFor:`chart-topn`,children:r(`dashboard:builder.topN`)}),(0,G.jsx)(V,{id:`chart-topn`,type:`number`,min:1,max:50,value:ue,onChange:e=>de(Math.max(1,Math.min(50,Number(e.target.value)||10)))})]})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{children:r(`dashboard:builder.range`)}),(0,G.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:ve.map(e=>(0,G.jsx)(f,{type:`button`,variant:P===e?`default`:`outline`,size:`sm`,className:`flex-1 min-w-[4rem]`,onClick:()=>F(e),children:r(`dashboard:range.${e}`)},e))})]})]}),(0,G.jsxs)(j,{value:`display`,className:`space-y-4`,children:[!$&&(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,G.jsx)(H,{htmlFor:`chart-compare`,children:r(`dashboard:builder.comparePrevious`)}),(0,G.jsx)(S,{content:r(`dashboard:builder.comparePreviousHint`)})]}),(0,G.jsx)(y,{id:`chart-compare`,checked:!E&&De,disabled:!!E,onCheckedChange:Oe,"aria-label":r(`dashboard:builder.comparePrevious`)})]}),!!E&&(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r(`dashboard:builder.comparePreviousDisabled`)})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,G.jsx)(H,{children:r(`dashboard:builder.transform`)}),(0,G.jsx)(S,{content:r(`dashboard:builder.transformHint`)})]}),J.map((e,t)=>(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsxs)(_,{value:e.op,onValueChange:e=>Y(n=>n.map((n,r)=>r===t?{...n,op:e}:n)),children:[(0,G.jsx)(m,{className:`w-40`,"aria-label":r(`dashboard:builder.transform`),children:(0,G.jsx)(p,{})}),(0,G.jsx)(h,{children:ge.map(e=>(0,G.jsx)(g,{value:e,children:r(`dashboard:builder.op${xe(e)}`)},e))})]}),(0,G.jsx)(V,{type:`number`,className:`w-28`,value:Number.isFinite(e.value)?e.value:``,onChange:e=>Y(n=>n.map((n,r)=>r===t?{...n,value:Number(e.target.value)}:n))}),(0,G.jsx)(f,{type:`button`,variant:`ghost`,size:`icon`,className:`size-8`,onClick:()=>Y(e=>e.filter((e,n)=>n!==t)),"aria-label":r(`dashboard:builder.transformRemove`),children:(0,G.jsx)(d,{className:`size-4`})})]},t)),J.length<8&&(0,G.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>Y(e=>[...e,{op:`divide`,value:100}]),children:[(0,G.jsx)(u,{className:`size-4 mr-1`}),r(`dashboard:builder.transformAdd`)]})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{children:r(`dashboard:builder.format`)}),(0,G.jsxs)(`div`,{className:`grid grid-cols-1 gap-3 sm:grid-cols-2`,children:[(0,G.jsxs)(`div`,{className:`space-y-1`,children:[(0,G.jsx)(H,{htmlFor:`chart-format-style`,className:`text-xs text-muted-foreground`,children:r(`dashboard:builder.formatStyle`)}),(0,G.jsxs)(_,{value:X,onValueChange:e=>ke(e),children:[(0,G.jsx)(m,{id:`chart-format-style`,children:(0,G.jsx)(p,{})}),(0,G.jsx)(h,{children:_e.map(e=>(0,G.jsx)(g,{value:e,children:r(`dashboard:builder.format${xe(e)}`)},e))})]})]}),X===`currency`&&(0,G.jsxs)(`div`,{className:`space-y-1`,children:[(0,G.jsx)(H,{htmlFor:`chart-format-currency`,className:`text-xs text-muted-foreground`,children:r(`dashboard:builder.formatCurrencyCode`)}),(0,G.jsx)(V,{id:`chart-format-currency`,placeholder:`USD`,maxLength:3,value:Ae,onChange:e=>je(e.target.value.toUpperCase())})]}),(0,G.jsxs)(`div`,{className:`space-y-1`,children:[(0,G.jsx)(H,{htmlFor:`chart-format-decimals`,className:`text-xs text-muted-foreground`,children:r(`dashboard:builder.formatDecimals`)}),(0,G.jsx)(V,{id:`chart-format-decimals`,type:`number`,min:0,max:6,value:Me,onChange:e=>Ne(e.target.value)})]}),(0,G.jsxs)(`div`,{className:`space-y-1`,children:[(0,G.jsxs)(H,{htmlFor:`chart-format-prefix`,className:`text-xs text-muted-foreground`,children:[r(`dashboard:builder.formatPrefix`),` / `,r(`dashboard:builder.formatSuffix`)]}),(0,G.jsxs)(`div`,{className:`flex gap-2`,children:[(0,G.jsx)(V,{id:`chart-format-prefix`,maxLength:8,placeholder:r(`dashboard:builder.formatPrefix`),value:Ie,onChange:e=>Le(e.target.value)}),(0,G.jsx)(V,{maxLength:8,placeholder:r(`dashboard:builder.formatSuffix`),value:Re,onChange:e=>ze(e.target.value),"aria-label":r(`dashboard:builder.formatSuffix`)})]})]}),(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-2 sm:col-span-2`,children:[(0,G.jsx)(H,{htmlFor:`chart-format-compact`,children:r(`dashboard:builder.formatCompact`)}),(0,G.jsx)(y,{id:`chart-format-compact`,checked:Pe,onCheckedChange:Fe})]})]}),(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground tabular-nums`,children:$e})]}),!$&&!E&&(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{children:r(`dashboard:builder.color`)}),(0,G.jsx)(oe,{value:Be,onChange:Ve,presets:se,labels:{custom:r(`dashboard:widget.colorCustom`),pick:r(`dashboard:widget.colorPick`),auto:r(`dashboard:widget.colorAuto`)}})]})]}),(0,G.jsx)(j,{value:`filters`,className:`space-y-4`,children:Q.length>0?(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{children:r(`dashboard:builder.filters`)}),(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r(`dashboard:builder.filtersHint`)}),(0,G.jsx)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-3`,children:Q.filter(Se).map(e=>{let t=U.includes(e.path);return(0,G.jsxs)(`div`,{className:`space-y-1`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,G.jsx)(H,{htmlFor:`flt-${e.path}`,className:`text-xs text-muted-foreground`,children:e.label}),(0,G.jsx)(y,{checked:t,onCheckedChange:()=>tt(e.path),"aria-label":r(`dashboard:builder.quickFilterToggle`).replace(`{field}`,e.label),title:r(`dashboard:builder.quickFilterHint`)})]}),(0,G.jsx)(Ce,{property:e,value:fe[e.path]??``,onChange:t=>et(e.path,t)})]},e.path)})})]}):(0,G.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:r(`dashboard:builder.filtersEmpty`)})})]}),(0,G.jsxs)(I,{children:[(0,G.jsx)(f,{variant:`outline`,onClick:n,children:r(`common:cancel`)}),(0,G.jsx)(f,{onClick:()=>{let n=new Date().toISOString(),r=$?`all`:e&&e.step!==`all`?e.step:`day`,i={id:e?.id??M(),title:o.trim()||Ge?.name||v,resource:v,visualisation:c,dateField:b,step:r,metric:C,width:e?.width??`half`,topN:ue,filters:fe,quickFilters:U.filter(e=>Q.some(t=>t.path===e)),timeRange:Je(),order:Te,...e?.groupId?{groupId:e.groupId}:{},createdAt:e?.createdAt??n,updatedAt:n,...C!==`count`&&T?{field:T}:{},...!$&&E?{groupBy:E}:{},...!$&&E&&O?{groupByLabelResource:O}:{},transform:J,comparePrevious:!$&&!E&&De,...Ye()?{format:Ye()}:{},...Xe()?{series:Xe()}:{}},a=N.safeParse(i);if(!a.success){let e={};for(let t of a.error.issues){let n=t.path[0];typeof n==`string`&&!e[n]&&(e[n]=t.message)}He(e),We(`data`);return}He({}),t(i)},disabled:!v||!b,children:r(`chart:saveChart`)})]})]})})}var xe=e=>e.charAt(0).toUpperCase()+e.slice(1);function Se(e){if(e.isId||e.isArray||e.type===`json`||e.type===`mixed`||e.type===`richtext`||e.type===`markdown`||e.type===`textarea`||e.type===`previewMedia`||e.type===`file`)return!1;if(e.type===`reference`&&!e.isArray){let t=e.path;if(!(t.endsWith(`Id`)||t.endsWith(`_id`)))return!1}return!0}function Ce({property:e,value:t,onChange:n}){if(e.reference)return(0,G.jsx)(P,{referenceResourceId:e.reference,value:t||null,onChange:e=>n(e==null?``:String(e))});if(e.availableValues&&e.availableValues.length>0)return(0,G.jsxs)(_,{value:t||K,onValueChange:e=>n(e===K?``:e),children:[(0,G.jsx)(m,{id:`flt-${e.path}`,children:(0,G.jsx)(p,{})}),(0,G.jsxs)(h,{children:[(0,G.jsx)(g,{value:K,children:`—`}),e.availableValues.map(e=>(0,G.jsx)(g,{value:e.value,children:e.label},e.value))]})]});if(e.type===`boolean`)return(0,G.jsxs)(_,{value:t||K,onValueChange:e=>n(e===K?``:e),children:[(0,G.jsx)(m,{id:`flt-${e.path}`,children:(0,G.jsx)(p,{})}),(0,G.jsxs)(h,{children:[(0,G.jsx)(g,{value:K,children:`—`}),(0,G.jsx)(g,{value:`true`,children:`true`}),(0,G.jsx)(g,{value:`false`,children:`false`})]})]});let r=e.type===`number`||e.type===`float`||e.type===`currency`;return(0,G.jsx)(V,{id:`flt-${e.path}`,type:r?`number`:`text`,value:t,onChange:e=>n(e.target.value)})}function we(e,t){if(!e)return``;let n=t.find(t=>t.path===e);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}return``}function Te({initial:e,onSave:t,onClose:n}){let{t:r}=w(),[i,a]=W.useState(e?.name??``),[o,s]=W.useState(e?.order??0),[c,l]=W.useState(``);return(0,G.jsx)(R,{open:!0,onOpenChange:e=>{e||n()},children:(0,G.jsxs)(z,{className:`w-full max-w-md`,children:[(0,G.jsx)(L,{children:(0,G.jsx)(B,{children:r(e?`chart:editGroup`:`chart:newGroup`)})}),(0,G.jsxs)(`div`,{className:`space-y-4 py-1`,children:[(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{htmlFor:`group-name`,children:r(`chart:groupName`)}),(0,G.jsx)(V,{id:`group-name`,placeholder:r(`chart:groupNamePlaceholder`),value:i,onChange:e=>a(e.target.value),autoFocus:!0}),c&&(0,G.jsx)(`p`,{className:`text-xs text-destructive`,children:c})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,G.jsx)(H,{htmlFor:`group-order`,children:r(`chart:groupOrder`)}),(0,G.jsx)(S,{content:r(`chart:orderHint`)})]}),(0,G.jsx)(V,{id:`group-order`,type:`number`,step:1,value:o,onChange:e=>s(Number.isFinite(Number(e.target.value))?Math.trunc(Number(e.target.value)):0)})]})]}),(0,G.jsxs)(I,{children:[(0,G.jsx)(f,{variant:`outline`,onClick:n,children:r(`common:cancel`)}),(0,G.jsx)(f,{onClick:()=>{let e=i.trim();if(!e){l(r(`chart:groupNameRequired`));return}l(``),t({name:e,order:Number.isFinite(o)?Math.trunc(o):0})},children:r(`chart:saveGroup`)})]})]})})}function Ee({groups:e,initialGroupId:t,initialOrder:n,onSave:r,onClose:i,onCreateGroup:o}){let{t:s}=w(),c=W.useMemo(()=>[...e].sort((e,t)=>e.order-t.order),[e]),l=t??c[0]?.id??``,[u,d]=W.useState(l),[v,y]=W.useState(n??0);return(0,G.jsx)(R,{open:!0,onOpenChange:e=>{e||i()},children:(0,G.jsxs)(z,{className:`w-full max-w-md`,children:[(0,G.jsx)(L,{children:(0,G.jsx)(B,{children:s(`chart:moveChart`)})}),c.length===0?(0,G.jsxs)(`div`,{className:`space-y-3 py-2`,children:[(0,G.jsx)(`p`,{className:`text-sm font-medium`,children:s(`chart:moveNoGroups`)}),(0,G.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:s(`chart:moveNoGroupsHint`)}),(0,G.jsxs)(f,{variant:`outline`,className:`w-full`,onClick:()=>{i(),o()},children:[(0,G.jsx)(a,{className:`size-4 mr-2`}),s(`chart:addGroup`)]})]}):(0,G.jsxs)(`div`,{className:`space-y-4 py-1`,children:[(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(H,{htmlFor:`move-group`,children:s(`chart:moveGroup`)}),(0,G.jsxs)(_,{value:u,onValueChange:d,children:[(0,G.jsx)(m,{id:`move-group`,className:`w-full`,children:(0,G.jsx)(p,{})}),(0,G.jsx)(h,{children:c.map(e=>(0,G.jsx)(g,{value:e.id,children:e.name},e.id))})]})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,G.jsx)(H,{htmlFor:`move-order`,children:s(`chart:order`)}),(0,G.jsx)(S,{content:s(`chart:orderHint`)})]}),(0,G.jsx)(V,{id:`move-order`,type:`number`,step:1,value:v,onChange:e=>y(Number.isFinite(Number(e.target.value))?Math.trunc(Number(e.target.value)):0)})]})]}),(0,G.jsxs)(I,{children:[(0,G.jsx)(f,{variant:`outline`,onClick:i,children:s(`common:cancel`)}),c.length>0&&(0,G.jsx)(f,{onClick:()=>{u&&r({groupId:u,order:Number.isFinite(v)?Math.trunc(v):0})},disabled:!u,children:s(`chart:moveToGroup`)})]})]})})}var De=W.lazy(()=>U(()=>import(`./chart-widget-B819aHsE.js`).then(e=>({default:e.ChartWidget})),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32]),import.meta.url));function Oe(e){return(0,G.jsx)(W.Suspense,{fallback:(0,G.jsx)(F,{className:`h-[320px] w-full rounded-md`}),children:(0,G.jsx)(De,{...e})})}function J(){let{t:e}=w(),t=ne(),{user:n}=te(),r=re(),i=pe(),o=W.useMemo(()=>new de(r),[r]),{charts:d,groups:p,addChart:m,updateChart:h,removeChart:g,addGroup:_,updateGroup:y,removeGroup:S}=ue({userId:n?.id??null,store:o}),j=W.useMemo(()=>t.filter(e=>e.navigation!==null),[t]),[oe,se]=W.useState(!1),[ce,le]=W.useState(null),[M,N]=W.useState(null),[P,F]=W.useState(null),[I,L]=W.useState(null);W.useEffect(()=>{if(p.length===0){F(null);return}(!P||!p.some(e=>e.id===P))&&F(p[0].id)},[p,P]);let R=ce?d.find(e=>e.id===ce):void 0,z=p[0]?.id??null,B=W.useMemo(()=>p.length===0?[...d].sort(Y):P?d.filter(e=>e.groupId?e.groupId===P:P===z).sort(Y):[],[d,p.length,P,z]),V=P?p.find(e=>e.id===P)??null:null,H=async t=>{await i.confirm({title:e(`chart:deleteChartConfirm`),description:e(`chart:deleteChartConfirmHint`),confirmLabel:e(`common:delete`),destructive:!0})&&g(t.id)},U=async t=>{let n=d.filter(e=>e.groupId?e.groupId===t.id:t.id===z).length;await i.confirm({title:e(`chart:deleteGroupConfirm`),description:e(`chart:deleteGroupConfirmHint`).replace(`{count}`,String(n)),confirmLabel:e(`common:delete`),destructive:!0})&&S(t.id)};return(0,G.jsxs)(`div`,{className:`space-y-3 sm:space-y-6`,children:[(0,G.jsxs)(k,{children:[(0,G.jsxs)(D,{className:`flex flex-row items-center justify-between p-3 pb-2 space-y-0 gap-2 sm:p-6 sm:pb-2`,children:[(0,G.jsx)(E,{children:e(`chart:dashboard`)}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsxs)(f,{size:`sm`,variant:`outline`,onClick:()=>N(`new`),children:[(0,G.jsx)(a,{className:`size-4`}),(0,G.jsx)(`span`,{className:`hidden sm:inline ml-1.5`,children:e(`chart:addGroup`)})]}),(0,G.jsxs)(f,{size:`sm`,onClick:()=>se(!0),disabled:j.length===0,children:[(0,G.jsx)(u,{className:`size-4`}),(0,G.jsx)(`span`,{className:`hidden sm:inline ml-1.5`,children:e(`chart:addChart`)})]})]})]}),(0,G.jsxs)(O,{className:`p-3 pt-0 sm:p-6 sm:pt-0`,children:[p.length>0&&P&&(0,G.jsx)(ae,{value:P,onValueChange:e=>F(e),className:`mb-4`,children:(0,G.jsxs)(`div`,{className:`flex items-end justify-between gap-2`,children:[(0,G.jsx)(ie,{className:`flex-1`,children:p.map(e=>(0,G.jsx)(A,{value:e.id,children:e.name},e.id))}),V&&(0,G.jsxs)(`div`,{className:`mb-1 flex shrink-0 items-center gap-1`,children:[(0,G.jsxs)(f,{size:`sm`,variant:`ghost`,onClick:()=>N(V),"aria-label":e(`chart:editGroup`),children:[(0,G.jsx)(l,{className:`size-3.5`}),(0,G.jsx)(`span`,{className:`hidden sm:inline ml-1.5`,children:e(`chart:editGroup`)})]}),(0,G.jsxs)(f,{size:`sm`,variant:`ghost`,onClick:()=>void U(V),"aria-label":e(`chart:deleteGroup`),children:[(0,G.jsx)(c,{className:`size-3.5`}),(0,G.jsx)(`span`,{className:`hidden sm:inline ml-1.5`,children:e(`chart:deleteGroup`)})]})]})]})}),B.length===0?(0,G.jsx)(C,{className:`border-0 py-4`,children:(0,G.jsxs)(ee,{children:[(0,G.jsx)(v,{children:(0,G.jsx)(s,{})}),(0,G.jsx)(b,{children:e(`chart:noCharts`)}),(0,G.jsx)(x,{children:e(`chart:noChartsHint`)})]})}):(0,G.jsx)(`div`,{className:`grid gap-3 grid-cols-1 sm:gap-4 md:grid-cols-2`,children:B.map(e=>(0,G.jsx)(`div`,{className:e.width===`full`?`md:col-span-2`:void 0,children:(0,G.jsx)(Oe,{config:e,onEdit:()=>le(e.id),onDelete:()=>void H(e),onMove:()=>L(e),onUpdate:t=>h(e.id,t)})},e.id))})]})]}),(0,G.jsxs)(k,{children:[(0,G.jsx)(D,{children:(0,G.jsx)(E,{children:e(`common:resources`)})}),(0,G.jsx)(O,{children:j.length===0?(0,G.jsx)(C,{className:`border-0`,children:(0,G.jsxs)(ee,{children:[(0,G.jsx)(v,{children:(0,G.jsx)(fe,{})}),(0,G.jsx)(b,{children:e(`common:noRecords`)}),(0,G.jsx)(x,{children:e(`common:noRecordsHint`,{resource:`resource`})})]})}):(0,G.jsx)(`ul`,{className:`grid gap-2 sm:grid-cols-2 md:grid-cols-3`,children:j.map(e=>(0,G.jsx)(`li`,{children:(0,G.jsxs)(T,{to:{name:`list`,resourceId:e.id},className:`block rounded-md border border-border bg-card p-4 hover:border-primary/40 hover:shadow-sm transition-shadow`,children:[(0,G.jsx)(`div`,{className:`font-semibold`,children:e.name}),e.name!==e.id&&(0,G.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:e.id})]})},e.id))})})]}),oe&&(0,G.jsx)(q,{onSave:e=>{m(P?{...e,groupId:P}:e),se(!1)},onClose:()=>se(!1)}),R&&(0,G.jsx)(q,{initial:R,onSave:e=>{h(R.id,e),le(null)},onClose:()=>le(null)}),I&&(0,G.jsx)(Ee,{groups:p,initialGroupId:I.groupId,initialOrder:I.order,onSave:({groupId:e,order:t})=>{h(I.id,{...I,groupId:e,order:t}),L(null)},onClose:()=>L(null),onCreateGroup:()=>{L(null),N(`new`)}}),M&&(0,G.jsx)(Te,{initial:M===`new`?void 0:M,onSave:e=>{if(M===`new`){let t=_(e);F(t)}else y(M.id,e);N(null)},onClose:()=>N(null)})]})}function Y(e,t){return e.order===t.order?e.createdAt.localeCompare(t.createdAt):e.order-t.order}export{J as HomePage};
|
|
3
|
-
//# sourceMappingURL=home-page-BdTrAXqk.js.map
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"mappings":"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","names":[],"ignoreList":[],"sources":["../../../../react/src/components/chart-builder-dialog.tsx","../../../../react/src/components/group-settings-dialog.tsx","../../../../react/src/components/move-chart-dialog.tsx","../../../../react/src/pages/home-page.tsx"],"sourcesContent":["// Phase 10: time-series-first chart builder.\n//\n// X-axis is ALWAYS a date — the user picks `dateField` (required). `groupBy`\n// becomes an optional *secondary* breakdown that produces multiple series\n// (Metabase-style: pick \"status\" → one line per status value). Pie removed.\n// `width` lets the chart take half or full row on the dashboard grid.\n\nimport * as React from 'react'\nimport {\n BarChart2,\n LineChart,\n AreaChart,\n Activity,\n Plus,\n X,\n} from 'lucide-react'\nimport {\n Button,\n CHART_COLOR_PRESETS,\n ColorSwatchPicker,\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n InfoTooltip,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Switch,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@modern-admin/ui'\nimport {\n chartDefZ,\n uuidv7,\n type AggregationOpName,\n type ChartDef,\n type ChartDefInput,\n type ChartFormat,\n type ChartTransformStep,\n type ChartVisualisation,\n type TimeRange,\n type TimeRangePreset,\n} from '@modern-admin/core'\nimport { applyTransform, makeValueFormatter } from '../dashboard/value-format.js'\nimport { useI18n } from '../i18n.js'\nimport { useResources } from '../hooks.js'\nimport { ReferenceCombobox } from '../reference.js'\nimport type { PropertyJSON } from '../types.js'\n\nexport interface ChartBuilderDialogProps {\n /** Pre-populate for editing an existing chart. */\n initial?: ChartDef\n onSave(input: ChartDefInput): void\n onClose(): void\n}\n\nconst VIS_OPTIONS: { value: ChartVisualisation; icon: React.ReactElement; labelKey: string }[] = [\n { value: 'kpi', icon: <Activity className=\"size-4\" />, labelKey: 'dashboard:visKpi' },\n { value: 'line', icon: <LineChart className=\"size-4\" />, labelKey: 'dashboard:visLine' },\n { value: 'area', icon: <AreaChart className=\"size-4\" />, labelKey: 'dashboard:visArea' },\n { value: 'bar', icon: <BarChart2 className=\"size-4\" />, labelKey: 'dashboard:visBar' },\n]\n\nconst NONE = '__none__'\nconst METRICS: AggregationOpName[] = ['count', 'sum', 'avg', 'min', 'max']\nconst TRANSFORM_OPS: ChartTransformStep['op'][] = ['divide', 'multiply', 'add', 'subtract']\nconst FORMAT_STYLES: NonNullable<ChartFormat['style']>[] = ['number', 'currency', 'percent']\n// `custom` is intentionally excluded from the builder — the builder sets a\n// default interval; ad-hoc custom ranges are picked on the widget toolbar.\nconst PRESETS: Exclude<TimeRangePreset, 'custom'>[] = ['7d', '30d', '90d', '1y', 'all']\n\n/** Date-ish heuristic for the dateField selector when adapter metadata is sparse. */\nfunction isDateProperty(p: { type?: string; path: string }): boolean {\n if (p.type === 'date' || p.type === 'datetime') return true\n const lower = p.path.toLowerCase()\n return lower.endsWith('at') || lower.endsWith('_at') || lower.endsWith('date')\n}\n\n/**\n * Properties that make sense as a `groupBy` axis: anything that resolves to\n * a discrete column value the adapter can group on. Virtual relation columns\n * (`type: 'reference'` with `isArray: false` and no FK suffix) carry full\n * record objects in their values and would serialise to `[object Object]` —\n * exclude them so the user picks the underlying FK column instead.\n */\nfunction isGroupable(p: { path: string; type?: string; isArray?: boolean }): boolean {\n if (isDateProperty(p)) return false\n if (p.type === 'reference' && !p.isArray) {\n // Allow scalar FK columns (named `*Id`/`*_id` with type 'reference' set\n // via adapter override) — they group cleanly to id strings. Reject virtual\n // relation fields whose values are objects.\n const path = p.path\n return path.endsWith('Id') || path.endsWith('_id')\n }\n if (p.type === 'json' || p.type === 'mixed') return false\n if (p.type === 'richtext' || p.type === 'markdown' || p.type === 'textarea') return false\n if (p.type === 'previewMedia' || p.type === 'file') return false\n return true\n}\n\nexport function ChartBuilderDialog({\n initial,\n onSave,\n onClose,\n}: ChartBuilderDialogProps): React.ReactElement {\n const { t, locale } = useI18n()\n const resources = useResources()\n\n const [title, setTitle] = React.useState(initial?.title ?? '')\n const [visualisation, setVisualisation] = React.useState<ChartVisualisation>(\n initial?.visualisation ?? 'area',\n )\n const [resourceId, setResourceId] = React.useState(\n initial?.resource ?? resources[0]?.id ?? '',\n )\n const [dateField, setDateField] = React.useState(initial?.dateField ?? '')\n const [metric, setMetric] = React.useState<AggregationOpName>(initial?.metric ?? 'count')\n const [field, setField] = React.useState(initial?.field ?? '')\n const [groupBy, setGroupBy] = React.useState(initial?.groupBy ?? '')\n const [groupByLabelResource, setGroupByLabelResource] = React.useState(\n initial?.groupByLabelResource ?? '',\n )\n const [topN, setTopN] = React.useState(initial?.topN ?? 10)\n // The builder only sets a default time-range preset; custom ranges are\n // picked on the widget toolbar. If the saved chart is on 'custom', fall\n // back to the most useful preset for the builder UI.\n const [preset, setPreset] = React.useState<Exclude<TimeRangePreset, 'custom'>>(\n initial && initial.timeRange.preset !== 'custom' ? initial.timeRange.preset : '30d',\n )\n const [filters, setFilters] = React.useState<Record<string, string>>(\n initial?.filters ?? {},\n )\n const [quickFilters, setQuickFilters] = React.useState<string[]>(\n initial?.quickFilters ?? [],\n )\n const [order, setOrder] = React.useState<number>(initial?.order ?? 0)\n const [comparePrevious, setComparePrevious] = React.useState(\n initial?.comparePrevious ?? false,\n )\n const [transform, setTransform] = React.useState<ChartTransformStep[]>(\n () => initial?.transform?.map((s) => ({ ...s })) ?? [],\n )\n const [formatStyle, setFormatStyle] = React.useState<NonNullable<ChartFormat['style']>>(\n initial?.format?.style ?? 'number',\n )\n const [currency, setCurrency] = React.useState(initial?.format?.currency ?? '')\n const [decimals, setDecimals] = React.useState<string>(\n initial?.format?.decimals != null ? String(initial.format.decimals) : '',\n )\n const [compact, setCompact] = React.useState(initial?.format?.compact ?? false)\n const [prefix, setPrefix] = React.useState(initial?.format?.prefix ?? '')\n const [suffix, setSuffix] = React.useState(initial?.format?.suffix ?? '')\n const [totalColor, setTotalColor] = React.useState<string | undefined>(\n initial?.series?.['__total__']?.color,\n )\n const [errors, setErrors] = React.useState<Record<string, string>>({})\n const [tab, setTab] = React.useState<'data' | 'display' | 'filters'>('data')\n\n const resource = resources.find((r) => r.id === resourceId)\n const properties = resource?.properties ?? []\n const dateProps = properties.filter(isDateProperty)\n const numericProps = properties.filter(\n (p) => p.type === 'number' || p.type === 'float' || p.type === 'currency',\n )\n\n // Auto-select dateField when resource changes (skip the very first\n // render of edit-mode so we keep the saved value).\n React.useEffect(() => {\n if (initial?.resource === resourceId) return\n setDateField(dateProps[0]?.path ?? '')\n setField('')\n setGroupBy('')\n setGroupByLabelResource('')\n setFilters({})\n setQuickFilters([])\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [resourceId])\n\n // When opening an existing chart that predates the groupByLabelResource\n // feature (groupByLabelResource is empty but groupBy is set): auto-derive\n // the label resource so the user gets resolved labels without re-saving.\n React.useEffect(() => {\n if (groupByLabelResource || !groupBy || properties.length === 0) return\n setGroupByLabelResource(resolveGroupByLabelResource(groupBy, properties))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [groupBy, properties])\n\n const isKpi = visualisation === 'kpi'\n\n const buildTimeRange = (): TimeRange => ({ preset })\n\n // Omit `format` entirely while everything is at its default so old charts\n // don't accumulate noise on re-save.\n const buildFormat = (): ChartFormat | undefined => {\n const dec = decimals === '' ? undefined : Math.max(0, Math.min(6, Math.trunc(Number(decimals))))\n const fmt = {\n style: formatStyle,\n ...(formatStyle === 'currency' && currency.trim().length === 3\n ? { currency: currency.trim().toUpperCase() }\n : {}),\n ...(dec != null && Number.isFinite(dec) ? { decimals: dec } : {}),\n ...(prefix ? { prefix: prefix.slice(0, 8) } : {}),\n ...(suffix ? { suffix: suffix.slice(0, 8) } : {}),\n ...(compact ? { compact: true } : {}),\n }\n const isDefault = fmt.style === 'number' && Object.keys(fmt).length === 1\n return isDefault ? undefined : fmt\n }\n\n // Preserve per-series overrides saved from the widget colors dialog; the\n // builder itself only edits the single-series (__total__) color.\n const buildSeries = (): Record<string, { color?: string }> | undefined => {\n const next: Record<string, { color?: string }> = { ...initial?.series }\n if (!isKpi && !groupBy) {\n if (totalColor) next.__total__ = { color: totalColor }\n else delete next.__total__\n }\n return Object.keys(next).length ? next : undefined\n }\n\n // Live preview for the transform/format sections — pure helpers, cheap.\n const previewFormat = React.useMemo(\n () => makeValueFormatter(buildFormat(), locale),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [formatStyle, currency, decimals, compact, prefix, suffix, locale],\n )\n const PREVIEW_SAMPLE = 1234\n const previewText = `${PREVIEW_SAMPLE} → ${previewFormat(applyTransform(PREVIEW_SAMPLE, transform))}`\n\n const handleFilterChange = (path: string, value: string): void => {\n setFilters((prev) => {\n const next = { ...prev }\n if (value === '') delete next[path]\n else next[path] = value\n return next\n })\n }\n\n const toggleQuickFilter = (path: string): void => {\n setQuickFilters((prev) =>\n prev.includes(path) ? prev.filter((p) => p !== path) : [...prev, path],\n )\n }\n\n const handleSave = (): void => {\n const now = new Date().toISOString()\n // step is not user-editable in the builder; keep the previous value (or\n // pick a sane default) so chartDefZ stays valid. The widget toolbar\n // remains the place to tweak step on the fly.\n const savedStep = isKpi\n ? 'all'\n : initial && initial.step !== 'all'\n ? initial.step\n : 'day'\n const candidate: ChartDefInput = {\n id: initial?.id ?? uuidv7(),\n title: title.trim() || resource?.name || resourceId,\n resource: resourceId,\n visualisation,\n dateField,\n step: savedStep,\n metric,\n width: initial?.width ?? 'half',\n topN,\n filters,\n quickFilters: quickFilters.filter((p) => properties.some((q) => q.path === p)),\n timeRange: buildTimeRange(),\n order,\n // Preserve groupId on edit — the builder does not (yet) change group\n // membership directly; groups are managed from the dashboard tab strip.\n ...(initial?.groupId ? { groupId: initial.groupId } : {}),\n createdAt: initial?.createdAt ?? now,\n updatedAt: now,\n ...(metric !== 'count' && field ? { field } : {}),\n ...(!isKpi && groupBy ? { groupBy } : {}),\n ...(!isKpi && groupBy && groupByLabelResource ? { groupByLabelResource } : {}),\n transform,\n // Compare is only meaningful for time-series without a breakdown.\n comparePrevious: !isKpi && !groupBy ? comparePrevious : false,\n ...(buildFormat() ? { format: buildFormat() } : {}),\n ...(buildSeries() ? { series: buildSeries() } : {}),\n }\n const result = chartDefZ.safeParse(candidate)\n if (!result.success) {\n const fieldErrs: Record<string, string> = {}\n for (const issue of result.error.issues) {\n const key = issue.path[0]\n if (typeof key === 'string' && !fieldErrs[key]) fieldErrs[key] = issue.message\n }\n setErrors(fieldErrs)\n // Every schema-validated field lives on the Data tab — surface it so\n // the inline error isn't hidden behind another tab.\n setTab('data')\n return\n }\n setErrors({})\n onSave(candidate)\n }\n\n return (\n <Dialog open onOpenChange={(open) => { if (!open) onClose() }}>\n <DialogContent className=\"w-full max-w-2xl max-h-[90vh] overflow-y-auto\">\n <DialogHeader>\n <DialogTitle>\n {initial ? t('chart:editChart') : t('chart:newChart')}\n </DialogTitle>\n </DialogHeader>\n\n <Tabs\n value={tab}\n onValueChange={(v) => setTab(v as 'data' | 'display' | 'filters')}\n className=\"py-1\"\n >\n <TabsList>\n <TabsTrigger value=\"data\">{t('dashboard:builder.tabData')}</TabsTrigger>\n <TabsTrigger value=\"display\">{t('dashboard:builder.tabDisplay')}</TabsTrigger>\n <TabsTrigger value=\"filters\">{t('dashboard:builder.tabFilters')}</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"data\" className=\"space-y-4\">\n {/* Title + order */}\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-[1fr_8rem]\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"chart-title\">{t('chart:title')}</Label>\n <Input\n id=\"chart-title\"\n placeholder={t('chart:titlePlaceholder')}\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n />\n </div>\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <Label htmlFor=\"chart-order\">{t('chart:order')}</Label>\n <InfoTooltip content={t('chart:orderHint')} />\n </div>\n <Input\n id=\"chart-order\"\n type=\"number\"\n step={1}\n value={order}\n onChange={(e) => setOrder(Number.isFinite(Number(e.target.value)) ? Math.trunc(Number(e.target.value)) : 0)}\n />\n </div>\n </div>\n\n {/* Visualisation (incl. KPI) */}\n <div className=\"space-y-1.5\">\n <Label>{t('dashboard:vis')}</Label>\n <div className=\"flex flex-wrap gap-2\">\n {VIS_OPTIONS.map(({ value, icon, labelKey }) => (\n <Button\n key={value}\n type=\"button\"\n variant={visualisation === value ? 'default' : 'outline'}\n size=\"sm\"\n className=\"flex-1 min-w-[5rem] gap-1.5 capitalize\"\n onClick={() => setVisualisation(value)}\n >\n {icon}\n <span className=\"hidden sm:inline\">{t(labelKey)}</span>\n </Button>\n ))}\n </div>\n </div>\n\n {/* Resource */}\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"chart-resource\">{t('chart:resource')}</Label>\n <Select value={resourceId} onValueChange={(v) => setResourceId(v)}>\n <SelectTrigger id=\"chart-resource\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {resources.map((r) => (\n <SelectItem key={r.id} value={r.id}>\n {r.name}\n {r.name !== r.id && (\n <span className=\"ml-1.5 text-xs text-muted-foreground\">({r.id})</span>\n )}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {errors.resource && (\n <p className=\"text-xs text-destructive\">{errors.resource}</p>\n )}\n </div>\n\n {/* Date field — required, drives the X-axis bucketing */}\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"chart-datefield\">{t('dashboard:builder.dateField')}</Label>\n <Select\n value={dateField || NONE}\n onValueChange={(v) => setDateField(v === NONE ? '' : v)}\n >\n <SelectTrigger id=\"chart-datefield\">\n <SelectValue placeholder={t('chart:selectField')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>{t('chart:selectField')}</SelectItem>\n {(dateProps.length > 0 ? dateProps : properties).map((p) => (\n <SelectItem key={p.path} value={p.path}>{p.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-xs text-muted-foreground\">\n {t('dashboard:builder.dateFieldHint')}\n </p>\n {errors.dateField && (\n <p className=\"text-xs text-destructive\">{errors.dateField}</p>\n )}\n </div>\n\n {/* Metric + field */}\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"chart-metric\">{t('chart:metric')}</Label>\n <Select value={metric} onValueChange={(v) => setMetric(v as AggregationOpName)}>\n <SelectTrigger id=\"chart-metric\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {METRICS.map((m) => (\n <SelectItem key={m} value={m}>{t(`dashboard:metric${cap(m)}`)}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {metric !== 'count' && (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"chart-field\">{t('chart:aggregateField')}</Label>\n <Select\n value={field || NONE}\n onValueChange={(v) => setField(v === NONE ? '' : v)}\n >\n <SelectTrigger id=\"chart-field\">\n <SelectValue placeholder={t('chart:selectField')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>{t('chart:selectField')}</SelectItem>\n {numericProps.map((p) => (\n <SelectItem key={p.path} value={p.path}>{p.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n {errors.field && (\n <p className=\"text-xs text-destructive\">{errors.field}</p>\n )}\n </div>\n )}\n </div>\n\n {/* Secondary groupBy + topN — non-KPI only */}\n {!isKpi && (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"chart-groupby\">\n {t('dashboard:builder.secondaryGroupBy')}\n </Label>\n <Select\n value={groupBy || NONE}\n onValueChange={(v) => {\n const path = v === NONE ? '' : v\n setGroupBy(path)\n setGroupByLabelResource(resolveGroupByLabelResource(path, properties))\n }}\n >\n <SelectTrigger id=\"chart-groupby\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>{t('dashboard:builder.noBreakdown')}</SelectItem>\n {properties\n .filter((p) => isGroupable(p) && p.path !== dateField)\n .map((p) => (\n <SelectItem key={p.path} value={p.path}>{p.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {groupBy && (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"chart-topn\">{t('dashboard:builder.topN')}</Label>\n <Input\n id=\"chart-topn\"\n type=\"number\"\n min={1}\n max={50}\n value={topN}\n onChange={(e) =>\n setTopN(Math.max(1, Math.min(50, Number(e.target.value) || 10)))\n }\n />\n </div>\n )}\n </div>\n )}\n\n {/* Default time-range preset. Custom ranges are picked on the\n widget toolbar — not in the builder. */}\n <div className=\"space-y-1.5\">\n <Label>{t('dashboard:builder.range')}</Label>\n <div className=\"flex flex-wrap gap-2\">\n {PRESETS.map((p) => (\n <Button\n key={p}\n type=\"button\"\n variant={preset === p ? 'default' : 'outline'}\n size=\"sm\"\n className=\"flex-1 min-w-[4rem]\"\n onClick={() => setPreset(p)}\n >\n {t(`dashboard:range.${p}`)}\n </Button>\n ))}\n </div>\n </div>\n </TabsContent>\n\n <TabsContent value=\"display\" className=\"space-y-4\">\n {/* Previous-period compare — time-series without breakdown only. */}\n {!isKpi && (\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex items-center gap-1.5\">\n <Label htmlFor=\"chart-compare\">\n {t('dashboard:builder.comparePrevious')}\n </Label>\n <InfoTooltip content={t('dashboard:builder.comparePreviousHint')} />\n </div>\n <Switch\n id=\"chart-compare\"\n checked={!groupBy && comparePrevious}\n disabled={!!groupBy}\n onCheckedChange={setComparePrevious}\n aria-label={t('dashboard:builder.comparePrevious')}\n />\n </div>\n {!!groupBy && (\n <p className=\"text-xs text-muted-foreground\">\n {t('dashboard:builder.comparePreviousDisabled')}\n </p>\n )}\n </div>\n )}\n\n {/* Value transform — ordered scalar pipeline (e.g. cents → dollars). */}\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <Label>{t('dashboard:builder.transform')}</Label>\n <InfoTooltip content={t('dashboard:builder.transformHint')} />\n </div>\n {transform.map((step, i) => (\n <div key={i} className=\"flex items-center gap-2\">\n <Select\n value={step.op}\n onValueChange={(v) =>\n setTransform((prev) =>\n prev.map((s, j) =>\n j === i ? { ...s, op: v as ChartTransformStep['op'] } : s,\n ),\n )\n }\n >\n <SelectTrigger className=\"w-40\" aria-label={t('dashboard:builder.transform')}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {TRANSFORM_OPS.map((op) => (\n <SelectItem key={op} value={op}>\n {t(`dashboard:builder.op${cap(op)}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Input\n type=\"number\"\n className=\"w-28\"\n value={Number.isFinite(step.value) ? step.value : ''}\n onChange={(e) =>\n setTransform((prev) =>\n prev.map((s, j) =>\n j === i ? { ...s, value: Number(e.target.value) } : s,\n ),\n )\n }\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-8\"\n onClick={() =>\n setTransform((prev) => prev.filter((_, j) => j !== i))\n }\n aria-label={t('dashboard:builder.transformRemove')}\n >\n <X className=\"size-4\" />\n </Button>\n </div>\n ))}\n {transform.length < 8 && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() =>\n setTransform((prev) => [...prev, { op: 'divide', value: 100 }])\n }\n >\n <Plus className=\"size-4 mr-1\" />\n {t('dashboard:builder.transformAdd')}\n </Button>\n )}\n </div>\n\n {/* Value format */}\n <div className=\"space-y-1.5\">\n <Label>{t('dashboard:builder.format')}</Label>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <div className=\"space-y-1\">\n <Label\n htmlFor=\"chart-format-style\"\n className=\"text-xs text-muted-foreground\"\n >\n {t('dashboard:builder.formatStyle')}\n </Label>\n <Select\n value={formatStyle}\n onValueChange={(v) => setFormatStyle(v as NonNullable<ChartFormat['style']>)}\n >\n <SelectTrigger id=\"chart-format-style\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {FORMAT_STYLES.map((s) => (\n <SelectItem key={s} value={s}>\n {t(`dashboard:builder.format${cap(s)}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {formatStyle === 'currency' && (\n <div className=\"space-y-1\">\n <Label\n htmlFor=\"chart-format-currency\"\n className=\"text-xs text-muted-foreground\"\n >\n {t('dashboard:builder.formatCurrencyCode')}\n </Label>\n <Input\n id=\"chart-format-currency\"\n placeholder=\"USD\"\n maxLength={3}\n value={currency}\n onChange={(e) => setCurrency(e.target.value.toUpperCase())}\n />\n </div>\n )}\n <div className=\"space-y-1\">\n <Label\n htmlFor=\"chart-format-decimals\"\n className=\"text-xs text-muted-foreground\"\n >\n {t('dashboard:builder.formatDecimals')}\n </Label>\n <Input\n id=\"chart-format-decimals\"\n type=\"number\"\n min={0}\n max={6}\n value={decimals}\n onChange={(e) => setDecimals(e.target.value)}\n />\n </div>\n <div className=\"space-y-1\">\n <Label\n htmlFor=\"chart-format-prefix\"\n className=\"text-xs text-muted-foreground\"\n >\n {t('dashboard:builder.formatPrefix')} / {t('dashboard:builder.formatSuffix')}\n </Label>\n <div className=\"flex gap-2\">\n <Input\n id=\"chart-format-prefix\"\n maxLength={8}\n placeholder={t('dashboard:builder.formatPrefix')}\n value={prefix}\n onChange={(e) => setPrefix(e.target.value)}\n />\n <Input\n maxLength={8}\n placeholder={t('dashboard:builder.formatSuffix')}\n value={suffix}\n onChange={(e) => setSuffix(e.target.value)}\n aria-label={t('dashboard:builder.formatSuffix')}\n />\n </div>\n </div>\n <div className=\"flex items-center justify-between gap-2 sm:col-span-2\">\n <Label htmlFor=\"chart-format-compact\">\n {t('dashboard:builder.formatCompact')}\n </Label>\n <Switch\n id=\"chart-format-compact\"\n checked={compact}\n onCheckedChange={setCompact}\n />\n </div>\n </div>\n <p className=\"text-xs text-muted-foreground tabular-nums\">{previewText}</p>\n </div>\n\n {/* Series color — single-series charts; breakdown colors are edited\n from the widget menu once the series are known. */}\n {!isKpi && !groupBy && (\n <div className=\"space-y-1.5\">\n <Label>{t('dashboard:builder.color')}</Label>\n <ColorSwatchPicker\n value={totalColor}\n onChange={setTotalColor}\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 </TabsContent>\n\n <TabsContent value=\"filters\" className=\"space-y-4\">\n {/* Filters — one row per property, with a checkbox to mark the\n filter as a \"quick filter\" (exposed above the chart for inline\n tweaking on the dashboard). Reference fields use a combobox. */}\n {properties.length > 0 ? (\n <div className=\"space-y-1.5\">\n <Label>{t('dashboard:builder.filters')}</Label>\n <p className=\"text-xs text-muted-foreground\">\n {t('dashboard:builder.filtersHint')}\n </p>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-3\">\n {properties.filter(isFilterable).map((p) => {\n const exposed = quickFilters.includes(p.path)\n return (\n <div key={p.path} className=\"space-y-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <Label\n htmlFor={`flt-${p.path}`}\n className=\"text-xs text-muted-foreground\"\n >\n {p.label}\n </Label>\n <Switch\n checked={exposed}\n onCheckedChange={() => toggleQuickFilter(p.path)}\n aria-label={t('dashboard:builder.quickFilterToggle').replace(\n '{field}',\n p.label,\n )}\n title={t('dashboard:builder.quickFilterHint')}\n />\n </div>\n <FilterInput\n property={p}\n value={filters[p.path] ?? ''}\n onChange={(v) => handleFilterChange(p.path, v)}\n />\n </div>\n )\n })}\n </div>\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('dashboard:builder.filtersEmpty')}\n </p>\n )}\n </TabsContent>\n </Tabs>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={onClose}>{t('common:cancel')}</Button>\n <Button onClick={handleSave} disabled={!resourceId || !dateField}>\n {t('chart:saveChart')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n\nconst cap = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1)\n\n/**\n * Property is exposable as a filter. Excludes ids, array fields, free-form\n * blobs (json/mixed/richtext), media fields, and virtual relation columns\n * (we keep the underlying FK column so we don't list `authorId` and `author`\n * twice).\n */\nfunction isFilterable(p: PropertyJSON): boolean {\n if (p.isId) return false\n if (p.isArray) return false\n if (p.type === 'json' || p.type === 'mixed') return false\n if (p.type === 'richtext' || p.type === 'markdown' || p.type === 'textarea') return false\n if (p.type === 'previewMedia' || p.type === 'file') return false\n // Drop virtual relation columns (full objects) — keep FK siblings instead.\n if (p.type === 'reference' && !p.isArray) {\n const path = p.path\n if (!(path.endsWith('Id') || path.endsWith('_id'))) return false\n }\n return true\n}\n\n/**\n * Renders an inline input for one filter row in the builder. Reference\n * properties get the same combobox the resource forms use; enums/booleans\n * get a Select; numerics get a number input; everything else falls back to\n * a plain text input.\n */\nfunction FilterInput({\n property,\n value,\n onChange,\n}: {\n property: PropertyJSON\n value: string\n onChange(next: string): void\n}): React.ReactElement {\n if (property.reference) {\n return (\n <ReferenceCombobox\n referenceResourceId={property.reference}\n value={value || null}\n onChange={(next) => onChange(next == null ? '' : String(next))}\n />\n )\n }\n if (property.availableValues && property.availableValues.length > 0) {\n return (\n <Select\n value={value || NONE}\n onValueChange={(v) => onChange(v === NONE ? '' : v)}\n >\n <SelectTrigger id={`flt-${property.path}`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>—</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 || NONE}\n onValueChange={(v) => onChange(v === NONE ? '' : v)}\n >\n <SelectTrigger id={`flt-${property.path}`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>—</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 id={`flt-${property.path}`}\n type={isNumeric ? 'number' : 'text'}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n />\n )\n}\n\n/**\n * Resolve which resource to use for groupBy label resolution.\n *\n * 1. If the property itself is `type: 'reference'` (virtual relation field),\n * use its `reference` resource id directly — same mechanism as the record\n * title display in resource forms.\n * 2. If it is a raw FK column (e.g. `authorId`), look for a sibling property\n * whose path is the FK name without the trailing `Id`/`_id` suffix AND\n * has `reference` set. Covers the Prisma/Drizzle naming convention.\n */\nfunction resolveGroupByLabelResource(\n path: string,\n properties: ReadonlyArray<{ path: string; type: string; reference: string | null }>,\n): string {\n if (!path) return ''\n const prop = properties.find((p) => p.path === path)\n if (!prop) return ''\n // Direct reference property (virtual relation).\n if (prop.reference) return prop.reference\n // FK column heuristic: strip Id / _id suffix and look for sibling.\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 = properties.find((p) => p.path === base && p.reference)\n if (sibling?.reference) return sibling.reference\n }\n return ''\n}\n","// Create / edit dialog for a dashboard chart group. Lives in the react\n// package because it is i18n-aware; the actual primitives come from\n// @modern-admin/ui.\n\nimport * as React from 'react'\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n InfoTooltip,\n Input,\n Label,\n} from '@modern-admin/ui'\nimport type { ChartGroup } from '@modern-admin/core'\nimport { useI18n } from '../i18n.js'\n\nexport interface GroupSettingsDialogProps {\n /** When set, the dialog is in edit mode and pre-populates from this group. */\n initial?: ChartGroup\n onSave(input: { name: string; order: number }): void\n onClose(): void\n}\n\nexport function GroupSettingsDialog({\n initial,\n onSave,\n onClose,\n}: GroupSettingsDialogProps): React.ReactElement {\n const { t } = useI18n()\n const [name, setName] = React.useState(initial?.name ?? '')\n const [order, setOrder] = React.useState<number>(initial?.order ?? 0)\n const [error, setError] = React.useState<string>('')\n\n const handleSave = (): void => {\n const trimmed = name.trim()\n if (!trimmed) {\n setError(t('chart:groupNameRequired'))\n return\n }\n setError('')\n onSave({ name: trimmed, order: Number.isFinite(order) ? Math.trunc(order) : 0 })\n }\n\n return (\n <Dialog open onOpenChange={(open) => { if (!open) onClose() }}>\n <DialogContent className=\"w-full max-w-md\">\n <DialogHeader>\n <DialogTitle>\n {initial ? t('chart:editGroup') : t('chart:newGroup')}\n </DialogTitle>\n </DialogHeader>\n\n <div className=\"space-y-4 py-1\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"group-name\">{t('chart:groupName')}</Label>\n <Input\n id=\"group-name\"\n placeholder={t('chart:groupNamePlaceholder')}\n value={name}\n onChange={(e) => setName(e.target.value)}\n autoFocus\n />\n {error && <p className=\"text-xs text-destructive\">{error}</p>}\n </div>\n\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <Label htmlFor=\"group-order\">{t('chart:groupOrder')}</Label>\n <InfoTooltip content={t('chart:orderHint')} />\n </div>\n <Input\n id=\"group-order\"\n type=\"number\"\n step={1}\n value={order}\n onChange={(e) =>\n setOrder(Number.isFinite(Number(e.target.value)) ? Math.trunc(Number(e.target.value)) : 0)\n }\n />\n </div>\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={onClose}>{t('common:cancel')}</Button>\n <Button onClick={handleSave}>{t('chart:saveGroup')}</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","// Dialog for moving a chart to a different group and adjusting its order.\n// Opened from the chart widget's \"…\" dropdown menu.\n\nimport * as React from 'react'\nimport { FolderPlus } from 'lucide-react'\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n InfoTooltip,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@modern-admin/ui'\nimport type { ChartGroup } from '@modern-admin/core'\nimport { useI18n } from '../i18n.js'\n\nexport interface MoveChartDialogProps {\n groups: ChartGroup[]\n /** Current group id of the chart being moved. */\n initialGroupId?: string\n /** Current order value of the chart being moved. */\n initialOrder?: number\n onSave(input: { groupId: string; order: number }): void\n onClose(): void\n /** Called when the user wants to create a group first (no groups exist). */\n onCreateGroup(): void\n}\n\nexport function MoveChartDialog({\n groups,\n initialGroupId,\n initialOrder,\n onSave,\n onClose,\n onCreateGroup,\n}: MoveChartDialogProps): React.ReactElement {\n const { t } = useI18n()\n\n const sorted = React.useMemo(\n () => [...groups].sort((a, b) => a.order - b.order),\n [groups],\n )\n\n // Seed from the chart's current group, or the first group if unset.\n const defaultGroupId = initialGroupId ?? sorted[0]?.id ?? ''\n const [groupId, setGroupId] = React.useState(defaultGroupId)\n const [order, setOrder] = React.useState<number>(initialOrder ?? 0)\n\n const handleSave = (): void => {\n if (!groupId) return\n onSave({ groupId, order: Number.isFinite(order) ? Math.trunc(order) : 0 })\n }\n\n return (\n <Dialog open onOpenChange={(open) => { if (!open) onClose() }}>\n <DialogContent className=\"w-full max-w-md\">\n <DialogHeader>\n <DialogTitle>{t('chart:moveChart')}</DialogTitle>\n </DialogHeader>\n\n {sorted.length === 0 ? (\n // No groups yet — prompt to create one.\n <div className=\"space-y-3 py-2\">\n <p className=\"text-sm font-medium\">{t('chart:moveNoGroups')}</p>\n <p className=\"text-sm text-muted-foreground\">{t('chart:moveNoGroupsHint')}</p>\n <Button\n variant=\"outline\"\n className=\"w-full\"\n onClick={() => { onClose(); onCreateGroup() }}\n >\n <FolderPlus className=\"size-4 mr-2\" />\n {t('chart:addGroup')}\n </Button>\n </div>\n ) : (\n <div className=\"space-y-4 py-1\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"move-group\">{t('chart:moveGroup')}</Label>\n <Select value={groupId} onValueChange={setGroupId}>\n <SelectTrigger id=\"move-group\" className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {sorted.map((g) => (\n <SelectItem key={g.id} value={g.id}>\n {g.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <Label htmlFor=\"move-order\">{t('chart:order')}</Label>\n <InfoTooltip content={t('chart:orderHint')} />\n </div>\n <Input\n id=\"move-order\"\n type=\"number\"\n step={1}\n value={order}\n onChange={(e) =>\n setOrder(Number.isFinite(Number(e.target.value)) ? Math.trunc(Number(e.target.value)) : 0)\n }\n />\n </div>\n </div>\n )}\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={onClose}>{t('common:cancel')}</Button>\n {sorted.length > 0 && (\n <Button onClick={handleSave} disabled={!groupId}>\n {t('chart:moveToGroup')}\n </Button>\n )}\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","import * as React from 'react'\nimport { Plus, Database, BarChart2, FolderPlus, Pencil, Trash2 } from 'lucide-react'\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Empty,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n Skeleton,\n Tabs,\n TabsList,\n TabsTrigger,\n} from '@modern-admin/ui'\nimport { useResources, useCurrentUser } from '../hooks.js'\nimport { useI18n } from '../i18n.js'\nimport { Link } from '../router.js'\nimport { useDashboardCharts, ServerDashboardStore } from '../use-dashboard-charts.js'\nimport { useAdminClient } from '../provider.js'\nimport { useDialogs } from '../dialogs.js'\nimport type { ChartWidgetProps } from '../components/chart-widget.js'\nimport { ChartBuilderDialog } from '../components/chart-builder-dialog.js'\nimport { GroupSettingsDialog } from '../components/group-settings-dialog.js'\nimport { MoveChartDialog } from '../components/move-chart-dialog.js'\nimport type { ChartDef, ChartGroup } from '@modern-admin/core'\n\n// ChartWidget statically pulls in Recharts (via ui's TimeSeriesChart/KpiCard).\n// Split it into its own async chunk so the dashboard's charting library never\n// loads until a chart is actually rendered — dashboards with no charts (and\n// the initial home-page paint) skip the Recharts payload entirely.\nconst ChartWidgetImpl = React.lazy(() =>\n import('../components/chart-widget.js').then((m) => ({ default: m.ChartWidget })),\n)\n\nfunction LazyChartWidget(props: ChartWidgetProps): React.ReactElement {\n return (\n <React.Suspense fallback={<Skeleton className=\"h-[320px] w-full rounded-md\" />}>\n <ChartWidgetImpl {...props} />\n </React.Suspense>\n )\n}\n\nexport function HomePage(): React.ReactElement {\n const { t } = useI18n()\n const resources = useResources()\n const { user } = useCurrentUser()\n const adminClient = useAdminClient()\n const dialogs = useDialogs()\n // Use server-backed store so charts persist across devices/browsers.\n // Falls back gracefully when configStore is not configured server-side.\n const serverStore = React.useMemo(() => new ServerDashboardStore(adminClient), [adminClient])\n const {\n charts,\n groups,\n addChart,\n updateChart,\n removeChart,\n addGroup,\n updateGroup,\n removeGroup,\n } = useDashboardCharts({\n userId: user?.id ?? null,\n store: serverStore,\n })\n\n // Only show resources explicitly visible in navigation (same rule as sidebar).\n const navResources = React.useMemo(\n () => resources.filter((r) => r.navigation !== null),\n [resources],\n )\n\n const [building, setBuilding] = React.useState(false)\n const [editingId, setEditingId] = React.useState<string | null>(null)\n // null = no dialog; 'new' = create; ChartGroup = edit-existing.\n const [groupDialog, setGroupDialog] = React.useState<ChartGroup | 'new' | null>(null)\n const [activeGroupId, setActiveGroupId] = React.useState<string | null>(null)\n // Chart being moved — null when dialog is closed.\n const [movingChart, setMovingChart] = React.useState<ChartDef | null>(null)\n\n // Keep `activeGroupId` valid when groups change (group removed, list reloaded\n // from store, etc.). When at least one group exists we always render charts\n // bucketed by group, so we need a definite active id.\n React.useEffect(() => {\n if (groups.length === 0) {\n setActiveGroupId(null)\n return\n }\n if (!activeGroupId || !groups.some((g) => g.id === activeGroupId)) {\n setActiveGroupId(groups[0]!.id)\n }\n }, [groups, activeGroupId])\n\n const editingChart = editingId ? charts.find((c) => c.id === editingId) : undefined\n\n // Build the chart bucket for the active group: charts whose `groupId`\n // matches OR (fallback) ungrouped charts when the active group is the\n // first one. Sorted by `order` then `createdAt`.\n const firstGroupId = groups[0]?.id ?? null\n const visibleCharts = React.useMemo(() => {\n if (groups.length === 0) return [...charts].sort(byChartOrder)\n if (!activeGroupId) return []\n const filtered = charts.filter((c) => {\n if (c.groupId) return c.groupId === activeGroupId\n // Ungrouped charts default into the first group so they remain visible.\n return activeGroupId === firstGroupId\n })\n return filtered.sort(byChartOrder)\n }, [charts, groups.length, activeGroupId, firstGroupId])\n\n const activeGroup = activeGroupId ? groups.find((g) => g.id === activeGroupId) ?? null : null\n\n const handleDeleteChart = async (chart: ChartDef): Promise<void> => {\n const ok = await dialogs.confirm({\n title: t('chart:deleteChartConfirm'),\n description: t('chart:deleteChartConfirmHint'),\n confirmLabel: t('common:delete'),\n destructive: true,\n })\n if (ok) removeChart(chart.id)\n }\n\n const handleDeleteGroup = async (group: ChartGroup): Promise<void> => {\n const count = charts.filter((c) => {\n if (c.groupId) return c.groupId === group.id\n // Ungrouped charts also belong to the first group at display time.\n return group.id === firstGroupId\n }).length\n const ok = await dialogs.confirm({\n title: t('chart:deleteGroupConfirm'),\n description: t('chart:deleteGroupConfirmHint').replace('{count}', String(count)),\n confirmLabel: t('common:delete'),\n destructive: true,\n })\n if (ok) removeGroup(group.id)\n }\n\n return (\n <div className=\"space-y-3 sm:space-y-6\">\n {/* ── Dashboard charts ──────────────────────────────────────── */}\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between p-3 pb-2 space-y-0 gap-2 sm:p-6 sm:pb-2\">\n <CardTitle>{t('chart:dashboard')}</CardTitle>\n <div className=\"flex items-center gap-2\">\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setGroupDialog('new')}\n >\n <FolderPlus className=\"size-4\" />\n <span className=\"hidden sm:inline ml-1.5\">{t('chart:addGroup')}</span>\n </Button>\n <Button size=\"sm\" onClick={() => setBuilding(true)} disabled={navResources.length === 0}>\n <Plus className=\"size-4\" />\n <span className=\"hidden sm:inline ml-1.5\">{t('chart:addChart')}</span>\n </Button>\n </div>\n </CardHeader>\n <CardContent className=\"p-3 pt-0 sm:p-6 sm:pt-0\">\n {groups.length > 0 && activeGroupId && (\n <Tabs\n value={activeGroupId}\n onValueChange={(v) => setActiveGroupId(v)}\n className=\"mb-4\"\n >\n <div className=\"flex items-end justify-between gap-2\">\n <TabsList className=\"flex-1\">\n {groups.map((g) => (\n <TabsTrigger key={g.id} value={g.id}>\n {g.name}\n </TabsTrigger>\n ))}\n </TabsList>\n {activeGroup && (\n <div className=\"mb-1 flex shrink-0 items-center gap-1\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => setGroupDialog(activeGroup)}\n aria-label={t('chart:editGroup')}\n >\n <Pencil className=\"size-3.5\" />\n <span className=\"hidden sm:inline ml-1.5\">{t('chart:editGroup')}</span>\n </Button>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => void handleDeleteGroup(activeGroup)}\n aria-label={t('chart:deleteGroup')}\n >\n <Trash2 className=\"size-3.5\" />\n <span className=\"hidden sm:inline ml-1.5\">{t('chart:deleteGroup')}</span>\n </Button>\n </div>\n )}\n </div>\n </Tabs>\n )}\n\n {visibleCharts.length === 0 ? (\n <Empty className=\"border-0 py-4\">\n <EmptyHeader>\n <EmptyMedia>\n <BarChart2 />\n </EmptyMedia>\n <EmptyTitle>{t('chart:noCharts')}</EmptyTitle>\n <EmptyDescription>{t('chart:noChartsHint')}</EmptyDescription>\n </EmptyHeader>\n </Empty>\n ) : (\n <div className=\"grid gap-3 grid-cols-1 sm:gap-4 md:grid-cols-2\">\n {visibleCharts.map((c) => (\n <div\n key={c.id}\n className={c.width === 'full' ? 'md:col-span-2' : undefined}\n >\n <LazyChartWidget\n config={c}\n onEdit={() => setEditingId(c.id)}\n onDelete={() => void handleDeleteChart(c)}\n onMove={() => setMovingChart(c)}\n onUpdate={(input) => updateChart(c.id, input)}\n />\n </div>\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n\n {/* ── Resources list ────────────────────────────────────────── */}\n <Card>\n <CardHeader>\n <CardTitle>{t('common:resources')}</CardTitle>\n </CardHeader>\n <CardContent>\n {navResources.length === 0 ? (\n <Empty className=\"border-0\">\n <EmptyHeader>\n <EmptyMedia>\n <Database />\n </EmptyMedia>\n <EmptyTitle>{t('common:noRecords')}</EmptyTitle>\n <EmptyDescription>\n {t('common:noRecordsHint', { resource: 'resource' })}\n </EmptyDescription>\n </EmptyHeader>\n </Empty>\n ) : (\n <ul className=\"grid gap-2 sm:grid-cols-2 md:grid-cols-3\">\n {navResources.map((r) => (\n <li key={r.id}>\n <Link\n to={{ name: 'list', resourceId: r.id }}\n className=\"block rounded-md border border-border bg-card p-4 hover:border-primary/40 hover:shadow-sm transition-shadow\"\n >\n <div className=\"font-semibold\">{r.name}</div>\n {r.name !== r.id && (\n <div className=\"text-xs text-muted-foreground\">{r.id}</div>\n )}\n </Link>\n </li>\n ))}\n </ul>\n )}\n </CardContent>\n </Card>\n\n {/* ── Chart builder dialog ──────────────────────────────────── */}\n {building && (\n <ChartBuilderDialog\n onSave={(input) => {\n // New charts inherit the active group so the user sees them in\n // the tab they were on. The hook also auto-falls back to the\n // first group if `groupId` is undefined.\n addChart(activeGroupId ? { ...input, groupId: activeGroupId } : input)\n setBuilding(false)\n }}\n onClose={() => setBuilding(false)}\n />\n )}\n {editingChart && (\n <ChartBuilderDialog\n initial={editingChart}\n onSave={(input) => { updateChart(editingChart.id, input); setEditingId(null) }}\n onClose={() => setEditingId(null)}\n />\n )}\n\n {/* ── Move chart dialog ─────────────────────────────────────── */}\n {movingChart && (\n <MoveChartDialog\n groups={groups}\n initialGroupId={movingChart.groupId}\n initialOrder={movingChart.order}\n onSave={({ groupId, order }) => {\n updateChart(movingChart.id, { ...movingChart, groupId, order })\n setMovingChart(null)\n }}\n onClose={() => setMovingChart(null)}\n onCreateGroup={() => {\n setMovingChart(null)\n setGroupDialog('new')\n }}\n />\n )}\n\n {/* ── Group settings dialog ─────────────────────────────────── */}\n {groupDialog && (\n <GroupSettingsDialog\n initial={groupDialog === 'new' ? undefined : groupDialog}\n onSave={(input) => {\n if (groupDialog === 'new') {\n const newId = addGroup(input)\n setActiveGroupId(newId)\n } else {\n updateGroup(groupDialog.id, input)\n }\n setGroupDialog(null)\n }}\n onClose={() => setGroupDialog(null)}\n />\n )}\n </div>\n )\n}\n\n/** Sort charts within a group: by `order` asc, ties broken by `createdAt`. */\nfunction byChartOrder(a: ChartDef, b: ChartDef): number {\n if (a.order !== b.order) return a.order - b.order\n return a.createdAt.localeCompare(b.createdAt)\n}\n"],"file":"home-page-BdTrAXqk.js"}
|