@modern-admin/web 0.4.1 → 0.4.2
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/standalone/assets/{action-component-host-BrEZDHZt.js → action-component-host-P6HcuKj3.js} +2 -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-component-host-BrEZDHZt.js.map → action-component-host-P6HcuKj3.js.map} +1 -1
- package/dist/standalone/assets/{action-page-Bx7kzeK7.js → action-page-kyqtK3oq.js} +2 -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/{action-page-Bx7kzeK7.js.map → action-page-kyqtK3oq.js.map} +1 -1
- package/dist/standalone/assets/{ai-assistant-widget-BbIXVrSu.js → ai-assistant-widget-DGanix6u.js} +2 -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/{ai-assistant-widget-BbIXVrSu.js.map → ai-assistant-widget-DGanix6u.js.map} +1 -1
- package/dist/standalone/assets/{audit-log-page-BoZh23oQ.js → audit-log-page-DozriTiA.js} +2 -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/{audit-log-page-BoZh23oQ.js.map → audit-log-page-DozriTiA.js.map} +1 -1
- package/dist/standalone/assets/{badge-6nyM5Jft.js → badge-lb2Nqx1b.js} +2 -2
- package/dist/standalone/assets/{badge-6nyM5Jft.js.map → badge-lb2Nqx1b.js.map} +1 -1
- package/dist/standalone/assets/{calendar-nvD_z7KQ.js → calendar-crtd4PEn.js} +2 -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-nvD_z7KQ.js.map → calendar-crtd4PEn.js.map} +1 -1
- package/dist/standalone/assets/{card-4cS4uWCP.js → card-Dh44j2Nb.js} +2 -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/{card-4cS4uWCP.js.map → card-Dh44j2Nb.js.map} +1 -1
- package/dist/standalone/assets/chart-widget-B819aHsE.js +2 -0
- 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/chart-widget-B819aHsE.js.map +1 -0
- package/dist/standalone/assets/{command-Sb0xL-se.js → command-xJ-6Grpv.js} +2 -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 +1 -0
- package/dist/standalone/assets/{date-picker-C4HcgidQ.js → date-picker-D0dWQEox.js} +2 -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/{date-picker-C4HcgidQ.js.map → date-picker-D0dWQEox.js.map} +1 -1
- package/dist/standalone/assets/{dist-BSbFjTlr.js → dist-CWGgVQiS.js} +2 -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-BSbFjTlr.js.map → dist-CWGgVQiS.js.map} +1 -1
- package/dist/standalone/assets/{dist-Dpg8xy_r.js → dist-UsTgBPww.js} +2 -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-Dpg8xy_r.js.map → dist-UsTgBPww.js.map} +1 -1
- package/dist/standalone/assets/dist-qlnAsTo_.js +2 -0
- 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-BcL2U6dT.js.map → dist-qlnAsTo_.js.map} +1 -1
- package/dist/standalone/assets/{edit-page-CW7-FAPC.js → edit-page-CFPwq1_5.js} +2 -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/{edit-page-CW7-FAPC.js.map → edit-page-CFPwq1_5.js.map} +1 -1
- package/dist/standalone/assets/empty-D9sUunOr.js +2 -0
- 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-Cposcczv.js.map → empty-D9sUunOr.js.map} +1 -1
- package/dist/standalone/assets/{global-search-dialog-DLv_nIvM.js → global-search-dialog-AfQmJSE7.js} +2 -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/{global-search-dialog-DLv_nIvM.js.map → global-search-dialog-AfQmJSE7.js.map} +1 -1
- package/dist/standalone/assets/{heavy-fields-BiCEgD2L.js → heavy-fields-_zVIBnm1.js} +4 -4
- 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-BiCEgD2L.js.map → heavy-fields-_zVIBnm1.js.map} +1 -1
- package/dist/standalone/assets/{home-page-BSz1wGk0.js → home-page-BdTrAXqk.js} +3 -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-BSz1wGk0.js.map → home-page-BdTrAXqk.js.map} +1 -1
- package/dist/standalone/assets/{icon-registry-BQU4fIc4.js → icon-registry-CcMm2Zh3.js} +2 -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-BQU4fIc4.js.map → icon-registry-CcMm2Zh3.js.map} +1 -1
- package/dist/standalone/assets/index-DHZwffoP.css +2 -0
- package/dist/standalone/assets/index-DHZwffoP.css.br +0 -0
- package/dist/standalone/assets/{index-95cwJ2RY.css.gz → index-DHZwffoP.css.gz} +0 -0
- package/dist/standalone/assets/index-uYpCUVT4.js +15 -0
- 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 +1 -0
- package/dist/standalone/assets/json-editor-yfO4TUB_.js +2 -0
- 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-CAIgxYb3.js.map → json-editor-yfO4TUB_.js.map} +1 -1
- package/dist/standalone/assets/{property-renderer-B8Md-EqW.js → property-renderer-CDKsa2KQ.js} +4 -4
- 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 +1 -0
- package/dist/standalone/assets/reference-DWJEoGIf.js +2 -0
- package/dist/standalone/assets/reference-DWJEoGIf.js.br +0 -0
- package/dist/standalone/assets/reference-DWJEoGIf.js.gz +0 -0
- package/dist/standalone/assets/reference-DWJEoGIf.js.map +1 -0
- package/dist/standalone/assets/{revisions-button-0WtL6bsZ.js → revisions-button-DR0oW2wX.js} +2 -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/{revisions-button-0WtL6bsZ.js.map → revisions-button-DR0oW2wX.js.map} +1 -1
- package/dist/standalone/assets/{richtext-render-DnVcQ34I.js → richtext-render-VFCKGulc.js} +2 -2
- 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-DnVcQ34I.js.map → richtext-render-VFCKGulc.js.map} +1 -1
- package/dist/standalone/assets/{router-wFvtgo77.js → router-BcZgB5cZ.js} +12 -12
- 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 +1 -0
- package/dist/standalone/assets/select-BiV9bunJ.js +2 -0
- 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-CR4acjX0.js.map → select-BiV9bunJ.js.map} +1 -1
- package/dist/standalone/assets/{settings-page-DtguXLAP.js → settings-page-DSWp2N6T.js} +2 -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/{settings-page-DtguXLAP.js.map → settings-page-DSWp2N6T.js.map} +1 -1
- package/dist/standalone/assets/{show-page-Dnox2NwO.js → show-page-CGzUAZoO.js} +2 -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/{show-page-Dnox2NwO.js.map → show-page-CGzUAZoO.js.map} +1 -1
- package/dist/standalone/assets/tabs-smdw70rV.js +2 -0
- 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-DUS8e6dR.js.map → tabs-smdw70rV.js.map} +1 -1
- package/dist/standalone/assets/{textarea-CX_0QVSz.js → textarea-DBVf3GGt.js} +2 -2
- package/dist/standalone/assets/{textarea-CX_0QVSz.js.map → textarea-DBVf3GGt.js.map} +1 -1
- package/dist/standalone/assets/useQueries-Ba2PuYhZ.js +2 -0
- 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 +1 -0
- package/dist/standalone/assets/{user-directory-9COoW6AO.js → user-directory-Df5X8VOe.js} +2 -2
- 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/{user-directory-9COoW6AO.js.map → user-directory-Df5X8VOe.js.map} +1 -1
- package/dist/standalone/assets/{value-format-Cgau0meh.js → value-format-BUeGtfH4.js} +16 -16
- 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-Cgau0meh.js.map → value-format-BUeGtfH4.js.map} +1 -1
- package/dist/standalone/assets/with-selector-id7qGzTH.js +2 -0
- 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 +1 -0
- package/dist/standalone/assets/{wizard-create-page-v2-Aw8Oj.js → wizard-create-page-B8IcszRF.js} +2 -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/{wizard-create-page-v2-Aw8Oj.js.map → wizard-create-page-B8IcszRF.js.map} +1 -1
- package/dist/standalone/assets/{zod-BrelKLfy.js → zod-mi61gVha.js} +2 -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-BrelKLfy.js.map → zod-mi61gVha.js.map} +1 -1
- package/dist/standalone/index.html +10 -10
- package/dist/standalone/index.html.br +0 -0
- package/dist/standalone/index.html.gz +0 -0
- package/package.json +4 -4
- package/dist/standalone/assets/action-component-host-BrEZDHZt.js.br +0 -0
- package/dist/standalone/assets/action-component-host-BrEZDHZt.js.gz +0 -0
- package/dist/standalone/assets/action-page-Bx7kzeK7.js.br +0 -0
- package/dist/standalone/assets/action-page-Bx7kzeK7.js.gz +0 -0
- package/dist/standalone/assets/ai-assistant-widget-BbIXVrSu.js.br +0 -0
- package/dist/standalone/assets/ai-assistant-widget-BbIXVrSu.js.gz +0 -0
- package/dist/standalone/assets/audit-log-page-BoZh23oQ.js.br +0 -0
- package/dist/standalone/assets/audit-log-page-BoZh23oQ.js.gz +0 -0
- package/dist/standalone/assets/calendar-nvD_z7KQ.js.br +0 -0
- package/dist/standalone/assets/calendar-nvD_z7KQ.js.gz +0 -0
- package/dist/standalone/assets/card-4cS4uWCP.js.br +0 -0
- package/dist/standalone/assets/card-4cS4uWCP.js.gz +0 -0
- package/dist/standalone/assets/chart-widget-YeCL7jdB.js +0 -2
- package/dist/standalone/assets/chart-widget-YeCL7jdB.js.br +0 -0
- package/dist/standalone/assets/chart-widget-YeCL7jdB.js.gz +0 -0
- package/dist/standalone/assets/chart-widget-YeCL7jdB.js.map +0 -1
- package/dist/standalone/assets/command-Sb0xL-se.js.br +0 -0
- package/dist/standalone/assets/command-Sb0xL-se.js.gz +0 -0
- package/dist/standalone/assets/command-Sb0xL-se.js.map +0 -1
- package/dist/standalone/assets/date-picker-C4HcgidQ.js.br +0 -0
- package/dist/standalone/assets/date-picker-C4HcgidQ.js.gz +0 -0
- package/dist/standalone/assets/dist-BSbFjTlr.js.br +0 -0
- package/dist/standalone/assets/dist-BSbFjTlr.js.gz +0 -0
- package/dist/standalone/assets/dist-BcL2U6dT.js +0 -2
- package/dist/standalone/assets/dist-BcL2U6dT.js.br +0 -0
- package/dist/standalone/assets/dist-BcL2U6dT.js.gz +0 -0
- package/dist/standalone/assets/dist-Dpg8xy_r.js.br +0 -0
- package/dist/standalone/assets/dist-Dpg8xy_r.js.gz +0 -0
- package/dist/standalone/assets/edit-page-CW7-FAPC.js.br +0 -0
- package/dist/standalone/assets/edit-page-CW7-FAPC.js.gz +0 -0
- package/dist/standalone/assets/empty-Cposcczv.js +0 -2
- package/dist/standalone/assets/empty-Cposcczv.js.br +0 -0
- package/dist/standalone/assets/empty-Cposcczv.js.gz +0 -0
- package/dist/standalone/assets/global-search-dialog-DLv_nIvM.js.br +0 -0
- package/dist/standalone/assets/global-search-dialog-DLv_nIvM.js.gz +0 -0
- package/dist/standalone/assets/heavy-fields-BiCEgD2L.js.br +0 -0
- package/dist/standalone/assets/heavy-fields-BiCEgD2L.js.gz +0 -0
- package/dist/standalone/assets/home-page-BSz1wGk0.js.br +0 -0
- package/dist/standalone/assets/home-page-BSz1wGk0.js.gz +0 -0
- package/dist/standalone/assets/icon-registry-BQU4fIc4.js.br +0 -0
- package/dist/standalone/assets/icon-registry-BQU4fIc4.js.gz +0 -0
- package/dist/standalone/assets/index-95cwJ2RY.css +0 -2
- package/dist/standalone/assets/index-95cwJ2RY.css.br +0 -0
- package/dist/standalone/assets/index-BL8keDxQ.js +0 -15
- package/dist/standalone/assets/index-BL8keDxQ.js.br +0 -0
- package/dist/standalone/assets/index-BL8keDxQ.js.gz +0 -0
- package/dist/standalone/assets/index-BL8keDxQ.js.map +0 -1
- package/dist/standalone/assets/json-editor-CAIgxYb3.js +0 -2
- package/dist/standalone/assets/json-editor-CAIgxYb3.js.br +0 -0
- package/dist/standalone/assets/json-editor-CAIgxYb3.js.gz +0 -0
- package/dist/standalone/assets/property-renderer-B8Md-EqW.js.br +0 -0
- package/dist/standalone/assets/property-renderer-B8Md-EqW.js.gz +0 -0
- package/dist/standalone/assets/property-renderer-B8Md-EqW.js.map +0 -1
- package/dist/standalone/assets/reference-WPaf6IdD.js +0 -2
- package/dist/standalone/assets/reference-WPaf6IdD.js.br +0 -0
- package/dist/standalone/assets/reference-WPaf6IdD.js.gz +0 -0
- package/dist/standalone/assets/reference-WPaf6IdD.js.map +0 -1
- package/dist/standalone/assets/revisions-button-0WtL6bsZ.js.br +0 -0
- package/dist/standalone/assets/revisions-button-0WtL6bsZ.js.gz +0 -0
- package/dist/standalone/assets/richtext-render-DnVcQ34I.js.br +0 -0
- package/dist/standalone/assets/richtext-render-DnVcQ34I.js.gz +0 -0
- package/dist/standalone/assets/router-wFvtgo77.js.br +0 -0
- package/dist/standalone/assets/router-wFvtgo77.js.gz +0 -0
- package/dist/standalone/assets/router-wFvtgo77.js.map +0 -1
- package/dist/standalone/assets/select-CR4acjX0.js +0 -2
- package/dist/standalone/assets/select-CR4acjX0.js.br +0 -0
- package/dist/standalone/assets/select-CR4acjX0.js.gz +0 -0
- package/dist/standalone/assets/settings-page-DtguXLAP.js.br +0 -0
- package/dist/standalone/assets/settings-page-DtguXLAP.js.gz +0 -0
- package/dist/standalone/assets/show-page-Dnox2NwO.js.br +0 -0
- package/dist/standalone/assets/show-page-Dnox2NwO.js.gz +0 -0
- package/dist/standalone/assets/tabs-DUS8e6dR.js +0 -2
- package/dist/standalone/assets/tabs-DUS8e6dR.js.br +0 -0
- package/dist/standalone/assets/tabs-DUS8e6dR.js.gz +0 -0
- package/dist/standalone/assets/useQueries-BCUhWYX4.js +0 -2
- package/dist/standalone/assets/useQueries-BCUhWYX4.js.br +0 -0
- package/dist/standalone/assets/useQueries-BCUhWYX4.js.gz +0 -0
- package/dist/standalone/assets/useQueries-BCUhWYX4.js.map +0 -1
- package/dist/standalone/assets/user-directory-9COoW6AO.js.br +0 -0
- package/dist/standalone/assets/user-directory-9COoW6AO.js.gz +0 -0
- package/dist/standalone/assets/value-format-Cgau0meh.js.br +0 -0
- package/dist/standalone/assets/value-format-Cgau0meh.js.gz +0 -0
- package/dist/standalone/assets/with-selector-NDLhu4dT.js +0 -2
- package/dist/standalone/assets/with-selector-NDLhu4dT.js.br +0 -0
- package/dist/standalone/assets/with-selector-NDLhu4dT.js.gz +0 -0
- package/dist/standalone/assets/with-selector-NDLhu4dT.js.map +0 -1
- package/dist/standalone/assets/wizard-create-page-v2-Aw8Oj.js.br +0 -0
- package/dist/standalone/assets/wizard-create-page-v2-Aw8Oj.js.gz +0 -0
- package/dist/standalone/assets/zod-BrelKLfy.js.br +0 -0
- package/dist/standalone/assets/zod-BrelKLfy.js.gz +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-search-dialog-DLv_nIvM.js","names":[],"sources":["../../../../react/src/components/global-search-dialog.tsx"],"sourcesContent":["// Cross-resource command palette. Backed by `useGlobalSearch`, which fans\n// the query out to every registered resource's `search` action server-side.\n// Results are grouped by resource; selecting an entry navigates to the\n// record's show page and closes the palette.\n//\n// Designed as a controlled component — the parent (typically the header)\n// holds the `open` state so it can pair the trigger button with the\n// `mod+k` hotkey.\n\nimport * as React from 'react'\nimport {\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n DialogDescription,\n DialogTitle,\n} from '@modern-admin/ui'\nimport { AlertTriangle, ArrowRight, Clock, Loader2, X } from 'lucide-react'\nimport { useGlobalSearch } from '../hooks.js'\nimport { useI18n } from '../i18n.js'\nimport { useNavigate } from '../router.js'\n\nconst DEBOUNCE_MS = 300\nconst RECENT_STORAGE_KEY = 'modern-admin:global-search:recent:v1'\nconst RECENT_MAX = 6\n\nexport interface GlobalSearchDialogProps {\n open: boolean\n\n onOpenChange(open: boolean): void\n}\n\nconst readRecent = (): string[] => {\n if (typeof window === 'undefined') return []\n try {\n const raw = window.localStorage.getItem(RECENT_STORAGE_KEY)\n if (!raw) return []\n const parsed = JSON.parse(raw) as unknown\n if (!Array.isArray(parsed)) return []\n return parsed.filter((v): v is string => typeof v === 'string').slice(0, RECENT_MAX)\n } catch {\n return []\n }\n}\n\nconst writeRecent = (entries: string[]): void => {\n if (typeof window === 'undefined') return\n try {\n window.localStorage.setItem(RECENT_STORAGE_KEY, JSON.stringify(entries.slice(0, RECENT_MAX)))\n } catch {\n /* quota exceeded — recent list is best-effort */\n }\n}\n\n/**\n * Highlight every case-insensitive occurrence of `needle` in `text` with\n * `<mark>`. Returns an array of React nodes ready to render inside any\n * inline container. Empty `needle` falls back to the raw string.\n */\nconst highlightMatch = (text: string, needle: string): React.ReactNode => {\n if (!needle) return text\n const lower = text.toLowerCase()\n const target = needle.toLowerCase()\n const nodes: React.ReactNode[] = []\n let cursor = 0\n let key = 0\n while (cursor < text.length) {\n const idx = lower.indexOf(target, cursor)\n if (idx === -1) {\n nodes.push(text.slice(cursor))\n break\n }\n if (idx > cursor) nodes.push(text.slice(cursor, idx))\n nodes.push(\n <mark\n key={key++}\n className=\"rounded-sm bg-primary/20 px-0.5 text-foreground\"\n >\n {text.slice(idx, idx + target.length)}\n </mark>,\n )\n cursor = idx + target.length\n }\n return nodes\n}\n\nexport function GlobalSearchDialog({\n open,\n onOpenChange,\n}: GlobalSearchDialogProps): React.ReactElement {\n const { t } = useI18n()\n const navigate = useNavigate()\n const [query, setQuery] = React.useState('')\n const [debounced, setDebounced] = React.useState('')\n const [recent, setRecent] = React.useState<string[]>(() => readRecent())\n\n // Reset query each time the dialog opens so it starts empty, and rehydrate\n // the recent list (other tabs may have appended entries while we were idle).\n React.useEffect(() => {\n if (open) {\n setQuery('')\n setDebounced('')\n setRecent(readRecent())\n }\n }, [open])\n\n React.useEffect(() => {\n const timer = window.setTimeout(() => setDebounced(query.trim()), DEBOUNCE_MS)\n return () => window.clearTimeout(timer)\n }, [query])\n\n const { data, isFetching, isError } = useGlobalSearch(debounced, open)\n\n // Capture the most recent successful query so it's available for the\n // \"recent\" list. We only persist on user-driven navigation (not every\n // keystroke) to keep the list signal-to-noise high.\n const persistRecent = React.useCallback((value: string): void => {\n if (!value) return\n setRecent((prev) => {\n const next = [value, ...prev.filter((q) => q !== value)].slice(0, RECENT_MAX)\n writeRecent(next)\n return next\n })\n }, [])\n\n const groups = data?.groups ?? []\n const hasQuery = debounced.length > 0\n const showEmpty = hasQuery && !isFetching && !isError && groups.length === 0\n\n const handleSelect = React.useCallback(\n (resourceId: string, recordId: string): void => {\n persistRecent(debounced)\n onOpenChange(false)\n navigate({ name: 'show', resourceId, recordId })\n },\n [debounced, navigate, onOpenChange, persistRecent],\n )\n\n const handleShowAll = React.useCallback(\n (resourceId: string): void => {\n persistRecent(debounced)\n onOpenChange(false)\n navigate({ name: 'list', resourceId })\n },\n [debounced, navigate, onOpenChange, persistRecent],\n )\n\n const handlePickRecent = React.useCallback((value: string): void => {\n setQuery(value)\n setDebounced(value)\n }, [])\n\n const handleClearRecent = React.useCallback((): void => {\n setRecent([])\n writeRecent([])\n }, [])\n\n return (\n <CommandDialog open={open} onOpenChange={onOpenChange}>\n {/* Visually-hidden title + description keep Radix Dialog accessibility\n warnings quiet and provide a label for screen readers. */}\n <DialogTitle className=\"sr-only\">{t('globalSearch:title')}</DialogTitle>\n <DialogDescription className=\"sr-only\">\n {t('globalSearch:description')}\n </DialogDescription>\n <CommandInput\n placeholder={t('globalSearch:placeholder')}\n value={query}\n onValueChange={setQuery}\n />\n {/* cmdk dedupes by item value — prefix each value with `resourceId:recordId`\n so identical record ids across resources keep distinct entries.\n shouldFilter is left on (default) so cmdk re-orders by relevance against\n the typed query — server already narrowed the set down. */}\n <CommandList>\n {!hasQuery && recent.length === 0 && (\n <div className=\"py-6 text-center text-sm text-muted-foreground\">\n {t('globalSearch:hint')}\n </div>\n )}\n {!hasQuery && recent.length > 0 && (\n <CommandGroup\n heading={\n <span className=\"flex items-center justify-between gap-2\">\n <span>{t('globalSearch:recent')}</span>\n <button\n type=\"button\"\n className=\"text-xs text-muted-foreground hover:text-foreground\"\n onClick={handleClearRecent}\n >\n <X className=\"mr-1 inline size-3\" aria-hidden=\"true\" />\n {t('globalSearch:clearRecent')}\n </button>\n </span>\n }\n >\n {recent.map((entry) => (\n <CommandItem\n key={`recent:${entry}`}\n value={`recent:${entry}`}\n onSelect={() => handlePickRecent(entry)}\n >\n <Clock className=\"mr-2 size-4 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"flex-1 truncate\">{entry}</span>\n </CommandItem>\n ))}\n </CommandGroup>\n )}\n {hasQuery && isError && (\n <div\n className=\"flex items-center justify-center gap-2 py-6 text-sm text-destructive\"\n role=\"alert\"\n >\n <AlertTriangle className=\"size-4\" aria-hidden=\"true\" />\n <span>{t('globalSearch:error')}</span>\n </div>\n )}\n {showEmpty && <CommandEmpty>{t('globalSearch:noResults')}</CommandEmpty>}\n {hasQuery && !isError && isFetching && groups.length === 0 && (\n <div\n className=\"flex items-center justify-center gap-2 py-6 text-sm text-muted-foreground\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\"/>\n <span>{t('common:loading')}</span>\n </div>\n )}\n {groups.map((group, idx) => (\n <React.Fragment key={group.resourceId}>\n {idx > 0 && <CommandSeparator/>}\n <CommandGroup heading={group.resourceName}>\n {group.records.map((hit) => (\n <CommandItem\n key={`${hit.resourceId}:${hit.recordId}`}\n value={`${hit.resourceId}:${hit.recordId} ${hit.title} ${hit.snippet ?? ''}`}\n onSelect={() => handleSelect(hit.resourceId, hit.recordId)}\n className=\"flex-col items-start gap-0.5\"\n >\n <div className=\"flex w-full items-baseline gap-2\">\n <span className=\"flex-1 truncate font-medium\">\n {highlightMatch(hit.title, debounced)}\n </span>\n {hit.matchedField && (\n <span className=\"shrink-0 text-xs text-muted-foreground\">\n {t('globalSearch:matchedIn').replace('{field}', hit.matchedField)}\n </span>\n )}\n </div>\n {hit.snippet && (\n <div className=\"line-clamp-1 text-xs text-muted-foreground\">\n {highlightMatch(hit.snippet, debounced)}\n </div>\n )}\n </CommandItem>\n ))}\n {/* `forceMount` keeps this row visible regardless of the current\n query — cmdk's default fuzzy filter would otherwise drop it\n because the value `${id}:show-all` rarely contains the typed\n needle. */}\n <CommandItem\n key={`${group.resourceId}:show-all`}\n value={`${group.resourceId}:show-all`}\n forceMount\n onSelect={() => handleShowAll(group.resourceId)}\n className=\"text-xs text-muted-foreground\"\n >\n <ArrowRight className=\"mr-2 size-3.5\" aria-hidden=\"true\" />\n {t('globalSearch:showAllIn').replace('{resource}', group.resourceName)}\n </CommandItem>\n </CommandGroup>\n </React.Fragment>\n ))}\n </CommandList>\n </CommandDialog>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"global-search-dialog-AfQmJSE7.js","names":[],"sources":["../../../../react/src/components/global-search-dialog.tsx"],"sourcesContent":["// Cross-resource command palette. Backed by `useGlobalSearch`, which fans\n// the query out to every registered resource's `search` action server-side.\n// Results are grouped by resource; selecting an entry navigates to the\n// record's show page and closes the palette.\n//\n// Designed as a controlled component — the parent (typically the header)\n// holds the `open` state so it can pair the trigger button with the\n// `mod+k` hotkey.\n\nimport * as React from 'react'\nimport {\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n DialogDescription,\n DialogTitle,\n} from '@modern-admin/ui'\nimport { AlertTriangle, ArrowRight, Clock, Loader2, X } from 'lucide-react'\nimport { useGlobalSearch } from '../hooks.js'\nimport { useI18n } from '../i18n.js'\nimport { useNavigate } from '../router.js'\n\nconst DEBOUNCE_MS = 300\nconst RECENT_STORAGE_KEY = 'modern-admin:global-search:recent:v1'\nconst RECENT_MAX = 6\n\nexport interface GlobalSearchDialogProps {\n open: boolean\n\n onOpenChange(open: boolean): void\n}\n\nconst readRecent = (): string[] => {\n if (typeof window === 'undefined') return []\n try {\n const raw = window.localStorage.getItem(RECENT_STORAGE_KEY)\n if (!raw) return []\n const parsed = JSON.parse(raw) as unknown\n if (!Array.isArray(parsed)) return []\n return parsed.filter((v): v is string => typeof v === 'string').slice(0, RECENT_MAX)\n } catch {\n return []\n }\n}\n\nconst writeRecent = (entries: string[]): void => {\n if (typeof window === 'undefined') return\n try {\n window.localStorage.setItem(RECENT_STORAGE_KEY, JSON.stringify(entries.slice(0, RECENT_MAX)))\n } catch {\n /* quota exceeded — recent list is best-effort */\n }\n}\n\n/**\n * Highlight every case-insensitive occurrence of `needle` in `text` with\n * `<mark>`. Returns an array of React nodes ready to render inside any\n * inline container. Empty `needle` falls back to the raw string.\n */\nconst highlightMatch = (text: string, needle: string): React.ReactNode => {\n if (!needle) return text\n const lower = text.toLowerCase()\n const target = needle.toLowerCase()\n const nodes: React.ReactNode[] = []\n let cursor = 0\n let key = 0\n while (cursor < text.length) {\n const idx = lower.indexOf(target, cursor)\n if (idx === -1) {\n nodes.push(text.slice(cursor))\n break\n }\n if (idx > cursor) nodes.push(text.slice(cursor, idx))\n nodes.push(\n <mark\n key={key++}\n className=\"rounded-sm bg-primary/20 px-0.5 text-foreground\"\n >\n {text.slice(idx, idx + target.length)}\n </mark>,\n )\n cursor = idx + target.length\n }\n return nodes\n}\n\nexport function GlobalSearchDialog({\n open,\n onOpenChange,\n}: GlobalSearchDialogProps): React.ReactElement {\n const { t } = useI18n()\n const navigate = useNavigate()\n const [query, setQuery] = React.useState('')\n const [debounced, setDebounced] = React.useState('')\n const [recent, setRecent] = React.useState<string[]>(() => readRecent())\n\n // Reset query each time the dialog opens so it starts empty, and rehydrate\n // the recent list (other tabs may have appended entries while we were idle).\n React.useEffect(() => {\n if (open) {\n setQuery('')\n setDebounced('')\n setRecent(readRecent())\n }\n }, [open])\n\n React.useEffect(() => {\n const timer = window.setTimeout(() => setDebounced(query.trim()), DEBOUNCE_MS)\n return () => window.clearTimeout(timer)\n }, [query])\n\n const { data, isFetching, isError } = useGlobalSearch(debounced, open)\n\n // Capture the most recent successful query so it's available for the\n // \"recent\" list. We only persist on user-driven navigation (not every\n // keystroke) to keep the list signal-to-noise high.\n const persistRecent = React.useCallback((value: string): void => {\n if (!value) return\n setRecent((prev) => {\n const next = [value, ...prev.filter((q) => q !== value)].slice(0, RECENT_MAX)\n writeRecent(next)\n return next\n })\n }, [])\n\n const groups = data?.groups ?? []\n const hasQuery = debounced.length > 0\n const showEmpty = hasQuery && !isFetching && !isError && groups.length === 0\n\n const handleSelect = React.useCallback(\n (resourceId: string, recordId: string): void => {\n persistRecent(debounced)\n onOpenChange(false)\n navigate({ name: 'show', resourceId, recordId })\n },\n [debounced, navigate, onOpenChange, persistRecent],\n )\n\n const handleShowAll = React.useCallback(\n (resourceId: string): void => {\n persistRecent(debounced)\n onOpenChange(false)\n navigate({ name: 'list', resourceId })\n },\n [debounced, navigate, onOpenChange, persistRecent],\n )\n\n const handlePickRecent = React.useCallback((value: string): void => {\n setQuery(value)\n setDebounced(value)\n }, [])\n\n const handleClearRecent = React.useCallback((): void => {\n setRecent([])\n writeRecent([])\n }, [])\n\n return (\n <CommandDialog open={open} onOpenChange={onOpenChange}>\n {/* Visually-hidden title + description keep Radix Dialog accessibility\n warnings quiet and provide a label for screen readers. */}\n <DialogTitle className=\"sr-only\">{t('globalSearch:title')}</DialogTitle>\n <DialogDescription className=\"sr-only\">\n {t('globalSearch:description')}\n </DialogDescription>\n <CommandInput\n placeholder={t('globalSearch:placeholder')}\n value={query}\n onValueChange={setQuery}\n />\n {/* cmdk dedupes by item value — prefix each value with `resourceId:recordId`\n so identical record ids across resources keep distinct entries.\n shouldFilter is left on (default) so cmdk re-orders by relevance against\n the typed query — server already narrowed the set down. */}\n <CommandList>\n {!hasQuery && recent.length === 0 && (\n <div className=\"py-6 text-center text-sm text-muted-foreground\">\n {t('globalSearch:hint')}\n </div>\n )}\n {!hasQuery && recent.length > 0 && (\n <CommandGroup\n heading={\n <span className=\"flex items-center justify-between gap-2\">\n <span>{t('globalSearch:recent')}</span>\n <button\n type=\"button\"\n className=\"text-xs text-muted-foreground hover:text-foreground\"\n onClick={handleClearRecent}\n >\n <X className=\"mr-1 inline size-3\" aria-hidden=\"true\" />\n {t('globalSearch:clearRecent')}\n </button>\n </span>\n }\n >\n {recent.map((entry) => (\n <CommandItem\n key={`recent:${entry}`}\n value={`recent:${entry}`}\n onSelect={() => handlePickRecent(entry)}\n >\n <Clock className=\"mr-2 size-4 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"flex-1 truncate\">{entry}</span>\n </CommandItem>\n ))}\n </CommandGroup>\n )}\n {hasQuery && isError && (\n <div\n className=\"flex items-center justify-center gap-2 py-6 text-sm text-destructive\"\n role=\"alert\"\n >\n <AlertTriangle className=\"size-4\" aria-hidden=\"true\" />\n <span>{t('globalSearch:error')}</span>\n </div>\n )}\n {showEmpty && <CommandEmpty>{t('globalSearch:noResults')}</CommandEmpty>}\n {hasQuery && !isError && isFetching && groups.length === 0 && (\n <div\n className=\"flex items-center justify-center gap-2 py-6 text-sm text-muted-foreground\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\"/>\n <span>{t('common:loading')}</span>\n </div>\n )}\n {groups.map((group, idx) => (\n <React.Fragment key={group.resourceId}>\n {idx > 0 && <CommandSeparator/>}\n <CommandGroup heading={group.resourceName}>\n {group.records.map((hit) => (\n <CommandItem\n key={`${hit.resourceId}:${hit.recordId}`}\n value={`${hit.resourceId}:${hit.recordId} ${hit.title} ${hit.snippet ?? ''}`}\n onSelect={() => handleSelect(hit.resourceId, hit.recordId)}\n className=\"flex-col items-start gap-0.5\"\n >\n <div className=\"flex w-full items-baseline gap-2\">\n <span className=\"flex-1 truncate font-medium\">\n {highlightMatch(hit.title, debounced)}\n </span>\n {hit.matchedField && (\n <span className=\"shrink-0 text-xs text-muted-foreground\">\n {t('globalSearch:matchedIn').replace('{field}', hit.matchedField)}\n </span>\n )}\n </div>\n {hit.snippet && (\n <div className=\"line-clamp-1 text-xs text-muted-foreground\">\n {highlightMatch(hit.snippet, debounced)}\n </div>\n )}\n </CommandItem>\n ))}\n {/* `forceMount` keeps this row visible regardless of the current\n query — cmdk's default fuzzy filter would otherwise drop it\n because the value `${id}:show-all` rarely contains the typed\n needle. */}\n <CommandItem\n key={`${group.resourceId}:show-all`}\n value={`${group.resourceId}:show-all`}\n forceMount\n onSelect={() => handleShowAll(group.resourceId)}\n className=\"text-xs text-muted-foreground\"\n >\n <ArrowRight className=\"mr-2 size-3.5\" aria-hidden=\"true\" />\n {t('globalSearch:showAllIn').replace('{resource}', group.resourceName)}\n </CommandItem>\n </CommandGroup>\n </React.Fragment>\n ))}\n </CommandList>\n </CommandDialog>\n )\n}\n"],"mappings":"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"}
|