@shapio/cms 0.0.0-stage → 0.2.1
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/README.md +27 -2
- package/dist/admin/apple-touch-icon.png +0 -0
- package/dist/admin/assets/AssistError-hVUWpP3F.js +2 -0
- package/dist/admin/assets/AssistError-hVUWpP3F.js.map +1 -0
- package/dist/admin/assets/BlockMenuItems-B0g93m6M.js +6 -0
- package/dist/admin/assets/BlockMenuItems-B0g93m6M.js.map +1 -0
- package/dist/admin/assets/Body-CFQKONK4.js +2 -0
- package/dist/admin/assets/Body-CFQKONK4.js.map +1 -0
- package/dist/admin/assets/Builder-Do5KVHV9.js +2 -0
- package/dist/admin/assets/Builder-Do5KVHV9.js.map +1 -0
- package/dist/admin/assets/ConfirmDialog-D6rs75TP.js +2 -0
- package/dist/admin/assets/ConfirmDialog-D6rs75TP.js.map +1 -0
- package/dist/admin/assets/CopyButton-Bc7crFDE.js +2 -0
- package/dist/admin/assets/CopyButton-Bc7crFDE.js.map +1 -0
- package/dist/admin/assets/CursorPager-BFPD_adV.js +2 -0
- package/dist/admin/assets/CursorPager-BFPD_adV.js.map +1 -0
- package/dist/admin/assets/ExternalLink-Cdfcyyed.js +2 -0
- package/dist/admin/assets/ExternalLink-Cdfcyyed.js.map +1 -0
- package/dist/admin/assets/FormCheckboxGroup-Bicl1CBP.js +2 -0
- package/dist/admin/assets/FormCheckboxGroup-Bicl1CBP.js.map +1 -0
- package/dist/admin/assets/FormRadioGroup-34iVSV4L.js +2 -0
- package/dist/admin/assets/FormRadioGroup-34iVSV4L.js.map +1 -0
- package/dist/admin/assets/FormSelectField-Ba4fIu-8.js +2 -0
- package/dist/admin/assets/FormSelectField-Ba4fIu-8.js.map +1 -0
- package/dist/admin/assets/FormSwitchField-DN6bfPC0.js +2 -0
- package/dist/admin/assets/FormSwitchField-DN6bfPC0.js.map +1 -0
- package/dist/admin/assets/FormTextareaField-WsNjLm32.js +2 -0
- package/dist/admin/assets/FormTextareaField-WsNjLm32.js.map +1 -0
- package/dist/admin/assets/HintedLabel-jKLM0ETt.js +2 -0
- package/dist/admin/assets/HintedLabel-jKLM0ETt.js.map +1 -0
- package/dist/admin/assets/InfoHint-DBqcrmZ3.js +2 -0
- package/dist/admin/assets/InfoHint-DBqcrmZ3.js.map +1 -0
- package/dist/admin/assets/InsertMenuItem-CRKXblK5.js +2 -0
- package/dist/admin/assets/InsertMenuItem-CRKXblK5.js.map +1 -0
- package/dist/admin/assets/LinkTabs-Bn2JVqOL.js +2 -0
- package/dist/admin/assets/LinkTabs-Bn2JVqOL.js.map +1 -0
- package/dist/admin/assets/Match-DaYgKrk7.js +2 -0
- package/dist/admin/assets/Match-DaYgKrk7.js.map +1 -0
- package/dist/admin/assets/Panel-6wFe96Gr.js +2 -0
- package/dist/admin/assets/Panel-6wFe96Gr.js.map +1 -0
- package/dist/admin/assets/QueryView-DFZtm0fn.js +2 -0
- package/dist/admin/assets/QueryView-DFZtm0fn.js.map +1 -0
- package/dist/admin/assets/RadioTile-DsTyz7ml.js +2 -0
- package/dist/admin/assets/RadioTile-DsTyz7ml.js.map +1 -0
- package/dist/admin/assets/RichTextField-BGkH403g.js +144 -0
- package/dist/admin/assets/RichTextField-BGkH403g.js.map +1 -0
- package/dist/admin/assets/RowTitle-sFt6NjO4.js +2 -0
- package/dist/admin/assets/RowTitle-sFt6NjO4.js.map +1 -0
- package/dist/admin/assets/SecretReveal-Z6MOFdcL.js +2 -0
- package/dist/admin/assets/SecretReveal-Z6MOFdcL.js.map +1 -0
- package/dist/admin/assets/StepList-BTP_EMzx.js +2 -0
- package/dist/admin/assets/StepList-BTP_EMzx.js.map +1 -0
- package/dist/admin/assets/Structure-D5-hCUuF.js +2 -0
- package/dist/admin/assets/Structure-D5-hCUuF.js.map +1 -0
- package/dist/admin/assets/SubNavLink-C5oN5mzB.js +2 -0
- package/dist/admin/assets/SubNavLink-C5oN5mzB.js.map +1 -0
- package/dist/admin/assets/SuggestAltButton-BuN35BBL.js +2 -0
- package/dist/admin/assets/SuggestAltButton-BuN35BBL.js.map +1 -0
- package/dist/admin/assets/TextLink-B4a6j3r6.js +2 -0
- package/dist/admin/assets/TextLink-B4a6j3r6.js.map +1 -0
- package/dist/admin/assets/Thumbnail-u8NE5NhQ.js +2 -0
- package/dist/admin/assets/Thumbnail-u8NE5NhQ.js.map +1 -0
- package/dist/admin/assets/UnsavedChangesGuard-BYwMTDsE.js +2 -0
- package/dist/admin/assets/UnsavedChangesGuard-BYwMTDsE.js.map +1 -0
- package/dist/admin/assets/UserAvatar-D-yX0ozh.js +2 -0
- package/dist/admin/assets/UserAvatar-D-yX0ozh.js.map +1 -0
- package/dist/admin/assets/View-BLsQYPow.js +11 -0
- package/dist/admin/assets/View-BLsQYPow.js.map +1 -0
- package/dist/admin/assets/arrow-up-Ws7W9KsZ.js +2 -0
- package/dist/admin/assets/arrow-up-Ws7W9KsZ.js.map +1 -0
- package/dist/admin/assets/auth-b3_9QbtL.js +2 -0
- package/dist/admin/assets/auth-b3_9QbtL.js.map +1 -0
- package/dist/admin/assets/badge-CMox6-v3.js +2 -0
- package/dist/admin/assets/badge-CMox6-v3.js.map +1 -0
- package/dist/admin/assets/calendar-clock-9W0Lkt89.js +2 -0
- package/dist/admin/assets/calendar-clock-9W0Lkt89.js.map +1 -0
- package/dist/admin/assets/changeSets-CO7JdILW.js +2 -0
- package/dist/admin/assets/changeSets-CO7JdILW.js.map +1 -0
- package/dist/admin/assets/chevron-left-DyqYjcMB.js +2 -0
- package/dist/admin/assets/chevron-left-DyqYjcMB.js.map +1 -0
- package/dist/admin/assets/circle-check-aJ2DW5t4.js +2 -0
- package/dist/admin/assets/circle-check-aJ2DW5t4.js.map +1 -0
- package/dist/admin/assets/circle-x-BnRBht9z.js +2 -0
- package/dist/admin/assets/circle-x-BnRBht9z.js.map +1 -0
- package/dist/admin/assets/client-C8vMCv-p.js +10 -0
- package/dist/admin/assets/client-C8vMCv-p.js.map +1 -0
- package/dist/admin/assets/clock-DRtFQbTs.js +2 -0
- package/dist/admin/assets/clock-DRtFQbTs.js.map +1 -0
- package/dist/admin/assets/cn-DnXL75B0.js +2 -0
- package/dist/admin/assets/cn-DnXL75B0.js.map +1 -0
- package/dist/admin/assets/coerce-COM3rk1i.js +2 -0
- package/dist/admin/assets/coerce-COM3rk1i.js.map +1 -0
- package/dist/admin/assets/constants-CS1ziZO0.js +2 -0
- package/dist/admin/assets/constants-CS1ziZO0.js.map +1 -0
- package/dist/admin/assets/constants-DCtq_UOe.js +2 -0
- package/dist/admin/assets/constants-DCtq_UOe.js.map +1 -0
- package/dist/admin/assets/constants-DUBUgzpU.js +2 -0
- package/dist/admin/assets/constants-DUBUgzpU.js.map +1 -0
- package/dist/admin/assets/content-Dic2fof_.js +3 -0
- package/dist/admin/assets/content-Dic2fof_.js.map +1 -0
- package/dist/admin/assets/contentCounts-Ct0tYgHD.js +2 -0
- package/dist/admin/assets/contentCounts-Ct0tYgHD.js.map +1 -0
- package/dist/admin/assets/contentTypes-D4_Ax9rb.js +2 -0
- package/dist/admin/assets/contentTypes-D4_Ax9rb.js.map +1 -0
- package/dist/admin/assets/copy-B5B8RjV0.js +2 -0
- package/dist/admin/assets/copy-B5B8RjV0.js.map +1 -0
- package/dist/admin/assets/dateTimeLocal-BuBv3it2.js +2 -0
- package/dist/admin/assets/dateTimeLocal-BuBv3it2.js.map +1 -0
- package/dist/admin/assets/defineEditor-CiJc766Y.js +2 -0
- package/dist/admin/assets/defineEditor-CiJc766Y.js.map +1 -0
- package/dist/admin/assets/develop-Brnb5YPC.js +11 -0
- package/dist/admin/assets/develop-Brnb5YPC.js.map +1 -0
- package/dist/admin/assets/dropdown-menu-CW3fabv5.js +2 -0
- package/dist/admin/assets/dropdown-menu-CW3fabv5.js.map +1 -0
- package/dist/admin/assets/ellipsis-DNdmromA.js +2 -0
- package/dist/admin/assets/ellipsis-DNdmromA.js.map +1 -0
- package/dist/admin/assets/errors-DfoXUVDI.js +2 -0
- package/dist/admin/assets/errors-DfoXUVDI.js.map +1 -0
- package/dist/admin/assets/external-link-YnuWXDBk.js +2 -0
- package/dist/admin/assets/external-link-YnuWXDBk.js.map +1 -0
- package/dist/admin/assets/file-text-CB7Bc0GA.js +2 -0
- package/dist/admin/assets/file-text-CB7Bc0GA.js.map +1 -0
- package/dist/admin/assets/fileRoute-BYwireXG.js +2 -0
- package/dist/admin/assets/fileRoute-BYwireXG.js.map +1 -0
- package/dist/admin/assets/globe-Bvs3UC3V.js +2 -0
- package/dist/admin/assets/globe-Bvs3UC3V.js.map +1 -0
- package/dist/admin/assets/image-CeoxwJeM.js +2 -0
- package/dist/admin/assets/image-CeoxwJeM.js.map +1 -0
- package/dist/admin/assets/image-off-iVqYw2Zc.js +2 -0
- package/dist/admin/assets/image-off-iVqYw2Zc.js.map +1 -0
- package/dist/admin/assets/inbox-DYbEOpaQ.js +2 -0
- package/dist/admin/assets/inbox-DYbEOpaQ.js.map +1 -0
- package/dist/admin/assets/inbox-wDoqym--.js +2 -0
- package/dist/admin/assets/inbox-wDoqym--.js.map +1 -0
- package/dist/admin/assets/index-57Mn6XLO.js +4 -0
- package/dist/admin/assets/index-57Mn6XLO.js.map +1 -0
- package/dist/admin/assets/index-BLYOgCKc.css +2 -0
- package/dist/admin/assets/jsx-runtime-DREnUpxT.js +2 -0
- package/dist/admin/assets/jsx-runtime-DREnUpxT.js.map +1 -0
- package/dist/admin/assets/key-round-Bcw6qqcb.js +2 -0
- package/dist/admin/assets/key-round-Bcw6qqcb.js.map +1 -0
- package/dist/admin/assets/link-2-DhM2vi4v.js +2 -0
- package/dist/admin/assets/link-2-DhM2vi4v.js.map +1 -0
- package/dist/admin/assets/link-2-off-DpDOMsa-.js +2 -0
- package/dist/admin/assets/link-2-off-DpDOMsa-.js.map +1 -0
- package/dist/admin/assets/link-CKr_uUfb.js +2 -0
- package/dist/admin/assets/link-CKr_uUfb.js.map +1 -0
- package/dist/admin/assets/list-BElvKZw_.js +2 -0
- package/dist/admin/assets/list-BElvKZw_.js.map +1 -0
- package/dist/admin/assets/locales-Bnv3qcdZ.js +2 -0
- package/dist/admin/assets/locales-Bnv3qcdZ.js.map +1 -0
- package/dist/admin/assets/media-BfDqe_2P.js +2 -0
- package/dist/admin/assets/media-BfDqe_2P.js.map +1 -0
- package/dist/admin/assets/media-DjK3xGFN.js +2 -0
- package/dist/admin/assets/media-DjK3xGFN.js.map +1 -0
- package/dist/admin/assets/modelPermissions-DZ1lWfQZ.js +2 -0
- package/dist/admin/assets/modelPermissions-DZ1lWfQZ.js.map +1 -0
- package/dist/admin/assets/network-CAJ76ILr.js +2 -0
- package/dist/admin/assets/network-CAJ76ILr.js.map +1 -0
- package/dist/admin/assets/pencil-Zd05MDs2.js +2 -0
- package/dist/admin/assets/pencil-Zd05MDs2.js.map +1 -0
- package/dist/admin/assets/plus-B0gd63Da.js +2 -0
- package/dist/admin/assets/plus-B0gd63Da.js.map +1 -0
- package/dist/admin/assets/preload-helper-CJKHb_rG.js +2 -0
- package/dist/admin/assets/preload-helper-CJKHb_rG.js.map +1 -0
- package/dist/admin/assets/publishing-B7zv1e7j.js +2 -0
- package/dist/admin/assets/publishing-B7zv1e7j.js.map +1 -0
- package/dist/admin/assets/publishing-vCVjaSGF.js +2 -0
- package/dist/admin/assets/publishing-vCVjaSGF.js.map +1 -0
- package/dist/admin/assets/radio-group-DVR0mTpo.js +2 -0
- package/dist/admin/assets/radio-group-DVR0mTpo.js.map +1 -0
- package/dist/admin/assets/react-CQOZoUwg.js +2 -0
- package/dist/admin/assets/react-CQOZoUwg.js.map +1 -0
- package/dist/admin/assets/react-dom-pEVw9mjF.js +2 -0
- package/dist/admin/assets/react-dom-pEVw9mjF.js.map +1 -0
- package/dist/admin/assets/rolldown-runtime-Dd_uD5pT.js +1 -0
- package/dist/admin/assets/root-CDpNo7ef.js +2 -0
- package/dist/admin/assets/root-CDpNo7ef.js.map +1 -0
- package/dist/admin/assets/rotate-ccw-BOTDOdHf.js +2 -0
- package/dist/admin/assets/rotate-ccw-BOTDOdHf.js.map +1 -0
- package/dist/admin/assets/schedules-CG-ZphRK.js +2 -0
- package/dist/admin/assets/schedules-CG-ZphRK.js.map +1 -0
- package/dist/admin/assets/schema-KXXSPVJn.js +2 -0
- package/dist/admin/assets/schema-KXXSPVJn.js.map +1 -0
- package/dist/admin/assets/scroll-text-D-gHqYwR.js +2 -0
- package/dist/admin/assets/scroll-text-D-gHqYwR.js.map +1 -0
- package/dist/admin/assets/search-BcPL1qyc.js +2 -0
- package/dist/admin/assets/search-BcPL1qyc.js.map +1 -0
- package/dist/admin/assets/searchSchema-BGrRDBL_.js +2 -0
- package/dist/admin/assets/searchSchema-BGrRDBL_.js.map +1 -0
- package/dist/admin/assets/searchSchemas-ChN9hhuQ.js +2 -0
- package/dist/admin/assets/searchSchemas-ChN9hhuQ.js.map +1 -0
- package/dist/admin/assets/sections-BrGcWOnw.js +2 -0
- package/dist/admin/assets/sections-BrGcWOnw.js.map +1 -0
- package/dist/admin/assets/sections-i9TeeK-h.js +2 -0
- package/dist/admin/assets/sections-i9TeeK-h.js.map +1 -0
- package/dist/admin/assets/select--nGB4WjU.js +2 -0
- package/dist/admin/assets/select--nGB4WjU.js.map +1 -0
- package/dist/admin/assets/send-Bu3RRfdI.js +2 -0
- package/dist/admin/assets/send-Bu3RRfdI.js.map +1 -0
- package/dist/admin/assets/settings-68BAxrPM.js +2 -0
- package/dist/admin/assets/settings-68BAxrPM.js.map +1 -0
- package/dist/admin/assets/settle-LRKtTN_e.js +2 -0
- package/dist/admin/assets/settle-LRKtTN_e.js.map +1 -0
- package/dist/admin/assets/shared-react-KADNSNpb.js +1 -0
- package/dist/admin/assets/shared-react-dom-BpneAejY.js +1 -0
- package/dist/admin/assets/shared-react-dom-client-CnpZTXxo.js +1 -0
- package/dist/admin/assets/shared-react-jsx-runtime-CU_Fm1m8.js +1 -0
- package/dist/admin/assets/shared-shapio-editor-sdk-9ANIbEN0.js +1 -0
- package/dist/admin/assets/sites-C6_THCVK.js +2 -0
- package/dist/admin/assets/sites-C6_THCVK.js.map +1 -0
- package/dist/admin/assets/skeleton-DUvclBAr.js +42 -0
- package/dist/admin/assets/skeleton-DUvclBAr.js.map +1 -0
- package/dist/admin/assets/snapshots-CKjK-vkL.js +2 -0
- package/dist/admin/assets/snapshots-CKjK-vkL.js.map +1 -0
- package/dist/admin/assets/sparkles-B_NX7PAY.js +2 -0
- package/dist/admin/assets/sparkles-B_NX7PAY.js.map +1 -0
- package/dist/admin/assets/src-D6DABe5J.js +4 -0
- package/dist/admin/assets/src-D6DABe5J.js.map +1 -0
- package/dist/admin/assets/stableId-Dmr2Afn_.js +2 -0
- package/dist/admin/assets/stableId-Dmr2Afn_.js.map +1 -0
- package/dist/admin/assets/store-B5xrQ1Ex.js +2 -0
- package/dist/admin/assets/store-B5xrQ1Ex.js.map +1 -0
- package/dist/admin/assets/switch-B-FbT-l8.js +2 -0
- package/dist/admin/assets/switch-B-FbT-l8.js.map +1 -0
- package/dist/admin/assets/table-DQzCPm7J.js +56 -0
- package/dist/admin/assets/table-DQzCPm7J.js.map +1 -0
- package/dist/admin/assets/tabs-YThoOiE3.js +5 -0
- package/dist/admin/assets/tabs-YThoOiE3.js.map +1 -0
- package/dist/admin/assets/textarea-_wcx8Mn1.js +2 -0
- package/dist/admin/assets/textarea-_wcx8Mn1.js.map +1 -0
- package/dist/admin/assets/titles-DyCBLXue.js +2 -0
- package/dist/admin/assets/titles-DyCBLXue.js.map +1 -0
- package/dist/admin/assets/tokens-CqsxrApC.js +2 -0
- package/dist/admin/assets/tokens-CqsxrApC.js.map +1 -0
- package/dist/admin/assets/tooltip-BMe4HylJ.js +2 -0
- package/dist/admin/assets/tooltip-BMe4HylJ.js.map +1 -0
- package/dist/admin/assets/undo-2-DMOHOH6w.js +2 -0
- package/dist/admin/assets/undo-2-DMOHOH6w.js.map +1 -0
- package/dist/admin/assets/useAuditLabels-CSw_kwLs.js +2 -0
- package/dist/admin/assets/useAuditLabels-CSw_kwLs.js.map +1 -0
- package/dist/admin/assets/useConfirmTarget-9JmfiY2X.js +2 -0
- package/dist/admin/assets/useConfirmTarget-9JmfiY2X.js.map +1 -0
- package/dist/admin/assets/useContentSchema-CS5QQcRk.js +2 -0
- package/dist/admin/assets/useContentSchema-CS5QQcRk.js.map +1 -0
- package/dist/admin/assets/useCursorPager-Dt_axwd1.js +2 -0
- package/dist/admin/assets/useCursorPager-Dt_axwd1.js.map +1 -0
- package/dist/admin/assets/useDebouncedValue-Dqs3wwhn.js +2 -0
- package/dist/admin/assets/useDebouncedValue-Dqs3wwhn.js.map +1 -0
- package/dist/admin/assets/useDiscardGuard-7rRGpd4q.js +2 -0
- package/dist/admin/assets/useDiscardGuard-7rRGpd4q.js.map +1 -0
- package/dist/admin/assets/useMediaUploader-CBUcNW6d.js +2 -0
- package/dist/admin/assets/useMediaUploader-CBUcNW6d.js.map +1 -0
- package/dist/admin/assets/usePaletteItems-bbTIqpPu.js +2 -0
- package/dist/admin/assets/usePaletteItems-bbTIqpPu.js.map +1 -0
- package/dist/admin/assets/usePlaces-D1raoQ2s.js +2 -0
- package/dist/admin/assets/usePlaces-D1raoQ2s.js.map +1 -0
- package/dist/admin/assets/useQueries-DKGIdq6A.js +2 -0
- package/dist/admin/assets/useQueries-DKGIdq6A.js.map +1 -0
- package/dist/admin/assets/useSaveShortcut-rKtp1qK7.js +2 -0
- package/dist/admin/assets/useSaveShortcut-rKtp1qK7.js.map +1 -0
- package/dist/admin/assets/useSearchInput-1fDoEtXe.js +2 -0
- package/dist/admin/assets/useSearchInput-1fDoEtXe.js.map +1 -0
- package/dist/admin/assets/users-C1ZSee3N.js +2 -0
- package/dist/admin/assets/users-C1ZSee3N.js.map +1 -0
- package/dist/admin/assets/users-DMfQL0s4.js +2 -0
- package/dist/admin/assets/users-DMfQL0s4.js.map +1 -0
- package/dist/admin/assets/w3c-keyname-BOAvb0qz.js +2 -0
- package/dist/admin/assets/w3c-keyname-BOAvb0qz.js.map +1 -0
- package/dist/admin/assets/zod-Pf5A-ax4.js +2 -0
- package/dist/admin/assets/zod-Pf5A-ax4.js.map +1 -0
- package/dist/admin/favicon-32.png +0 -0
- package/dist/admin/favicon.svg +5 -0
- package/dist/admin/fonts/OFL-SourceSerif4.txt +93 -0
- package/dist/admin/fonts/OFL.txt +93 -0
- package/dist/admin/fonts/manrope-latin-ext-wght-normal.woff2 +0 -0
- package/dist/admin/fonts/manrope-latin-wght-normal.woff2 +0 -0
- package/dist/admin/fonts/source-serif-4-latin-ext-wght-italic.woff2 +0 -0
- package/dist/admin/fonts/source-serif-4-latin-ext-wght-normal.woff2 +0 -0
- package/dist/admin/fonts/source-serif-4-latin-wght-italic.woff2 +0 -0
- package/dist/admin/fonts/source-serif-4-latin-wght-normal.woff2 +0 -0
- package/dist/admin/index.html +89 -0
- package/dist/admin/theme-init.js +18 -0
- package/dist/cli.js +5163 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +39 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +1051 -0
- package/dist/index.js +3 -0
- package/dist/public-CKU0Gkfq.d.ts +1177 -0
- package/dist/worker-C-MSYr4l.js +46445 -0
- package/dist/worker-C-MSYr4l.js.map +1 -0
- package/package.json +98 -3
- package/vendor/graphiql/LICENSE.graphiql +21 -0
- package/vendor/graphiql/LICENSE.react +21 -0
- package/vendor/graphiql/LICENSE.react-dom +21 -0
- package/vendor/graphiql/graphiql.min.css +1 -0
- package/vendor/graphiql/graphiql.min.js +46 -0
- package/vendor/graphiql/react-dom.production.min.js +267 -0
- package/vendor/graphiql/react.production.min.js +31 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-DjK3xGFN.js","names":["__iconData","__iconData","z.object","z.string","z.number","zodResolver","i18next","useState","i18next","_Fragment","Trash2","useState","_Fragment","AlertTriangle","useState","useRef","z.object","zodResolver","i18next","useId","Loader2","useRef","MoreHorizontal","_Fragment","Trash2","useMemo","useState","useCallback","useState","i18next","useState","i18next","Loader2","useId","useState","useMemo","_Fragment","__toESM","require_jsx_runtime","ShapioApiError","useTranslation","LoaderCircle","cn","useMediaAsset","useUpdateMediaAsset","useDeleteMediaAsset","useMediaFolders","useDeleteMediaFolder","useMediaUsage","useCreateMediaFolder","useUpdateMediaFolder","useNavigate","hasErrorCode","Lock","X","SubmitButton","Page","Sheet","SheetDescription","SheetFooter","PageHeader","TriangleAlert","SheetBody","SheetTitle","StatusChip","SheetHeader","ErrorState","Badge","SheetContent","LoadingState","useSearch","createLazyRoute","toast","Trash","PopoverTrigger","FieldDescription","FieldLabel","PopoverContent","Popover","Field","FieldContent","FieldGroup","instance","Check","Button","describeError","Input","Skeleton","Alert","FormError","AlertDescription","InlineConfirm","ConfirmDialog","Library","Toolbar","Images","UploadQueue","FocalPoint","UploadButton","Upload","useMediaUploader","Ellipsis","ExternalLink","Variants","useMediaPermissions","FileIcon","FolderPlus","fileKindLabel","MEDIA_STATUS_DISPLAY","isImage","formatBytes","Globe","Inbox","Pencil","DropdownMenuItem","DropdownMenuSeparator","DropdownMenuTrigger","DropdownMenuContent","DropdownMenu","Switch","useController","FormTextField","requiredText","FormFieldError","u","useForm","settle","string","object","number","useDiscardGuard","ROOT_FOLDER","MIME_FILTER_BY_TYPE","SuggestAltButton","Panel","CopyButton","FormTextareaField","__iconData$2","FolderInput","createLucideIcon","__iconData$1","FolderOpen","__iconData","Folder","import_react","require_react","detailsSchema","valuesFor","asset","changesFrom","values","useAssetDetailsForm","update","form","reset","result","usageCountOf","details","error","useDeleteAssetFlow","remove","blocked","setBlocked","forceOpen","setForceOpen","forceUsageCount","setForceUsageCount","deleted","target","onDeleted","usageCount","isOwner","import_jsx_runtime","DeleteAction","deletion","t","MetadataForm","focal","image","event","onSubmit","readOnly","alt","value","previewImageUrl","variant","Preview","Section","title","children","Usage","usage","assetId","item","Visibility","confirming","setConfirming","isPrivate","next","consequence","canManage","Details","query","open","onClose","status","requestOpenChange","canWrite","file","onReplace","discardPrompt","hasFiles","Dropzone","dragging","setDragging","depth","enabled","className","files","onFiles","buildFolderTree","byParent","folders","folder","candidate","build","parentId","a","b","flattenFolderTree","nodes","node","folderSchema","useFolderForm","createFolder","updateFolder","initialName","edit","trimmed","name","onDone","mutation","EditRow","errorId","setFocus","message","creating","pending","FOLDER_ROW_CLASSES","Menu","handingOff","handOff","action","actions","Item","current","currentId","Icon","renameEdit","editing","childEdit","onEditDone","onSelect","child","ScopeButton","icon","label","FolderTree","tree","topLevelEdit","useAssetSelection","selected","setSelected","checked","id","openerOf","selector","useFolderActions","setEditing","deletingId","setDeletingId","deleteFolder","returnFocus","useMediaSearch","search","navigate","previous","changes","moveFocusWithArrows","buttons","index","button","last","useMoveToFolder","move","useMoveMediaAssets","setTarget","folderId","assetIds","onMoved","Choice","MovePopover","titleId","setOpen","choices","SelectionBar","onClear","mediaLazyRoute","uploader","selection","folderActions","setSearch","uploadFolder","upload","assetQuery"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/folder-input.mjs","../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/folder-open.mjs","../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/folder.mjs","../../src/features/Media/hooks/useAssetDetailsForm.ts","../../src/features/Media/hooks/useDeleteAssetFlow.ts","../../src/features/Media/Details/DeleteAction/index.tsx","../../src/features/Media/Details/MetadataForm/index.tsx","../../src/features/Media/Details/Preview/index.tsx","../../src/features/Media/Details/Section/index.tsx","../../src/features/Media/Details/Usage/index.tsx","../../src/features/Media/Details/Visibility/index.tsx","../../src/features/Media/Details/index.tsx","../../src/features/Media/Dropzone/index.tsx","../../src/features/Media/helpers/folderTree.ts","../../src/features/Media/hooks/useFolderForm.ts","../../src/features/Media/FolderTree/EditRow/index.tsx","../../src/features/Media/FolderTree/constants.ts","../../src/features/Media/FolderTree/Menu/index.tsx","../../src/features/Media/FolderTree/Item/index.tsx","../../src/features/Media/FolderTree/ScopeButton/index.tsx","../../src/features/Media/FolderTree/index.tsx","../../src/features/Media/hooks/useAssetSelection.ts","../../src/features/Media/hooks/useFolderActions.ts","../../src/features/Media/hooks/useMediaSearch.ts","../../src/features/Media/helpers/arrowFocus.ts","../../src/features/Media/hooks/useMoveToFolder.ts","../../src/features/Media/MovePopover/Choice/index.tsx","../../src/features/Media/MovePopover/index.tsx","../../src/features/Media/SelectionBar/index.tsx","../../src/features/Media/index.tsx","../../src/app/lazyRoutes/media.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.49.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"folder-input\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M2 9V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-1\",\n key: \"fm4g5t\"\n }\n ],\n [\"path\", { d: \"M2 13h10\", key: \"pgb2dq\" }],\n [\"path\", { d: \"m9 16 3-3-3-3\", key: \"6m91ic\" }]\n ]\n};\n__iconData.node;\nconst FolderInput = createLucideIcon(__iconData);\n\nexport { __iconData, FolderInput as default };\n//# sourceMappingURL=folder-input.mjs.map\n","/**\n * @license lucide-react v1.49.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"folder-open\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2\",\n key: \"usdka0\"\n }\n ]\n ]\n};\n__iconData.node;\nconst FolderOpen = createLucideIcon(__iconData);\n\nexport { __iconData, FolderOpen as default };\n//# sourceMappingURL=folder-open.mjs.map\n","/**\n * @license lucide-react v1.49.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"folder\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z\",\n key: \"1kt360\"\n }\n ]\n ]\n};\n__iconData.node;\nconst Folder = createLucideIcon(__iconData);\n\nexport { __iconData, Folder as default };\n//# sourceMappingURL=folder.mjs.map\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport type { MediaAsset, UpdateMediaAssetInput } from '@shapio/client';\nimport { useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useUpdateMediaAsset } from '@/api/media';\nimport { i18next } from '@/app/i18n';\nimport { settle } from '@/helpers/settle';\nimport { requiredText } from '@/helpers/validation';\n\nconst MAX_FILENAME = 255;\nconst MAX_ALT = 1000;\nconst MAX_CAPTION = 4000;\n\nconst detailsSchema = z.object({\n filename: requiredText().max(MAX_FILENAME, 'validation.tooLong'),\n alt: z.string().max(MAX_ALT, 'validation.tooLong'),\n caption: z.string().max(MAX_CAPTION, 'validation.tooLong'),\n focalPoint: z.object({ x: z.number().min(0).max(1), y: z.number().min(0).max(1) }).nullable(),\n});\n\nexport type AssetDetailsValues = z.infer<typeof detailsSchema>;\n\nconst valuesFor = (asset: MediaAsset | undefined): AssetDetailsValues => ({\n filename: asset?.filename ?? '',\n alt: asset?.alt ?? '',\n caption: asset?.caption ?? '',\n focalPoint: asset?.focalPoint ?? null,\n});\n\n/** Only what changed is sent, with the version the editor saw (409 VERSION_CONFLICT if it moved). */\nconst changesFrom = (asset: MediaAsset, values: AssetDetailsValues): UpdateMediaAssetInput => ({\n expectedVersion: asset.version,\n ...(values.filename !== asset.filename ? { filename: values.filename.trim() } : {}),\n ...(values.alt !== asset.alt ? { alt: values.alt } : {}),\n ...(values.caption !== asset.caption ? { caption: values.caption } : {}),\n ...(JSON.stringify(values.focalPoint) !== JSON.stringify(asset.focalPoint)\n ? { focalPoint: values.focalPoint }\n : {}),\n});\n\n/** File name, alt text, caption and focal point of one asset. */\nexport const useAssetDetailsForm = (asset: MediaAsset | undefined) => {\n const update = useUpdateMediaAsset();\n const form = useForm<AssetDetailsValues>({\n resolver: zodResolver(detailsSchema),\n defaultValues: valuesFor(asset),\n });\n const { reset } = form;\n // A different asset (or a fresh load of this one) starts from what the server has.\n useEffect(() => {\n reset(valuesFor(asset));\n update.reset();\n // The mutation object changes identity on every render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [asset?.id, reset]);\n const onSubmit = form.handleSubmit(async (values) => {\n if (!asset) {\n return;\n }\n const result = await settle(update.mutateAsync({ id: asset.id, input: changesFrom(asset, values) }));\n if (result.ok) {\n reset(valuesFor(result.value));\n toast.success(i18next.t('media.details.saved'));\n }\n });\n return { form, onSubmit, pending: update.isPending, error: update.error };\n};\n","import { ShapioApiError, type MediaAsset } from '@shapio/client';\nimport { useState } from 'react';\nimport { toast } from 'sonner';\nimport { hasErrorCode } from '@/api/errors';\nimport { useDeleteMediaAsset } from '@/api/media';\nimport { i18next } from '@/app/i18n';\n\nconst usageCountOf = (error: unknown): number => {\n const details =\n error instanceof ShapioApiError ? (error.details as { usageCount?: unknown } | undefined) : undefined;\n return typeof details?.usageCount === 'number' ? details.usageCount : 0;\n};\n\n/**\n * Delete, with the server's protection surfaced: a referenced asset answers 409 MEDIA_IN_USE. For an owner\n * the inline confirmation then hands over to a blocking \"Delete anyway\" dialog (which sends `force`); for\n * anyone else the inline confirmation stays open and explains why it can't be deleted.\n */\nexport const useDeleteAssetFlow = (\n asset: MediaAsset | undefined,\n isOwner: boolean,\n onDeleted: () => void,\n) => {\n const remove = useDeleteMediaAsset();\n const [blocked, setBlocked] = useState<{ assetId: string; usageCount: number } | undefined>(undefined);\n const [forceOpen, setForceOpen] = useState(false);\n // Kept while the dialog animates out, so its text doesn't change.\n const [forceUsageCount, setForceUsageCount] = useState(0);\n const deleted = (target: MediaAsset) => {\n toast.success(i18next.t('media.delete.done', { name: target.filename }));\n onDeleted();\n };\n return {\n /** Set once a non-owner's delete was refused because content uses the file. */\n blockedUsageCount: blocked && blocked.assetId === asset?.id ? blocked.usageCount : undefined,\n /** The inline confirmation's action: rejects (and the popover shows why) unless it was handed over. */\n confirm: async () => {\n if (!asset) {\n return;\n }\n try {\n await remove.mutateAsync({ id: asset.id, force: false });\n } catch (error) {\n if (!hasErrorCode(error, 'MEDIA_IN_USE')) {\n throw error;\n }\n const usageCount = usageCountOf(error);\n if (!isOwner) {\n setBlocked({ assetId: asset.id, usageCount });\n throw error;\n }\n remove.reset();\n setForceUsageCount(usageCount);\n setForceOpen(true);\n return;\n }\n deleted(asset);\n },\n force: {\n open: forceOpen,\n usageCount: forceUsageCount,\n pending: remove.isPending,\n error: remove.error,\n onOpenChange: setForceOpen,\n confirm: () => {\n if (asset) {\n remove.mutate(\n { id: asset.id, force: true },\n {\n onSuccess: () => {\n setForceOpen(false);\n deleted(asset);\n },\n },\n );\n }\n },\n },\n };\n};\n","import type { MediaAsset } from '@shapio/client';\nimport { Trash2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { ConfirmDialog } from '@/components/ConfirmDialog';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { Button } from '@/components/ui/button';\nimport { useMediaPermissions } from '@/hooks/useMediaPermissions';\nimport { useDeleteAssetFlow } from '../../hooks/useDeleteAssetFlow';\n\ntype DeleteActionProps = { asset: MediaAsset; onDeleted: () => void };\n\n/**\n * \"Delete file\", confirmed inline. If content still uses the file, the confirmation says so; only an owner\n * can then delete it anyway, through a blocking dialog (it leaves that content pointing at a missing file).\n */\nexport const DeleteAction = ({ asset, onDeleted }: DeleteActionProps) => {\n const { t } = useTranslation();\n const { isOwner } = useMediaPermissions();\n const deletion = useDeleteAssetFlow(asset, isOwner, onDeleted);\n const blocked = deletion.blockedUsageCount;\n return (\n <>\n <InlineConfirm\n tone=\"danger\"\n align=\"start\"\n side=\"top\"\n title={t('media.delete.title', { name: asset.filename })}\n description={\n blocked === undefined\n ? t('media.delete.description')\n : `${t('media.delete.inUseDescription', { count: blocked })} ${t('media.delete.onlyOwners')}`\n }\n confirmLabel={t('common.delete')}\n onConfirm={deletion.confirm}\n trigger={\n <Button variant=\"destructive-ghost\">\n <Trash2 aria-hidden=\"true\" />\n {t('media.delete.action')}\n </Button>\n }\n />\n <ConfirmDialog\n open={deletion.force.open}\n onOpenChange={deletion.force.onOpenChange}\n title={t('media.delete.inUseTitle')}\n description={`${t('media.delete.inUseDescription', { count: deletion.force.usageCount })} ${t(\n 'media.delete.ownerMayForce',\n )}`}\n confirmLabel={t('media.delete.force')}\n destructive\n pending={deletion.force.pending}\n error={deletion.force.error}\n onConfirm={deletion.force.confirm}\n />\n </>\n );\n};\n","import type { MediaAsset } from '@shapio/client';\nimport { useController, type UseFormReturn } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { FocalPoint } from '@/components/FocalPoint';\nimport { FormError } from '@/components/FormError';\nimport { FormTextareaField } from '@/components/FormTextareaField';\nimport { FormTextField } from '@/components/FormTextField';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { SuggestAltButton } from '@/components/SuggestAltButton';\nimport { FieldGroup } from '@/components/ui/field';\nimport { isImage } from '../../helpers/fileKind';\nimport type { AssetDetailsValues } from '../../hooks/useAssetDetailsForm';\n\ntype MetadataFormProps = {\n asset: MediaAsset;\n form: UseFormReturn<AssetDetailsValues>;\n onSubmit: () => void;\n pending: boolean;\n error: unknown;\n readOnly: boolean;\n};\n\n/** File name, alt text, caption and (images) focal point; saved together. */\nexport const MetadataForm = ({ asset, form, onSubmit, pending, error, readOnly }: MetadataFormProps) => {\n const { t } = useTranslation();\n const focal = useController({ control: form.control, name: 'focalPoint' });\n const image = isImage(asset.mimeType);\n return (\n <form\n noValidate\n aria-label={t('media.details.formLabel')}\n onSubmit={(event) => {\n event.preventDefault();\n onSubmit();\n }}\n >\n <fieldset disabled={readOnly} className=\"contents\">\n <FieldGroup>\n <FormTextField\n control={form.control}\n name=\"filename\"\n label={t('media.fields.filename')}\n autoComplete=\"off\"\n />\n {image ? (\n <FormTextareaField\n control={form.control}\n name=\"alt\"\n label={t('media.fields.alt')}\n rows={2}\n placeholder={t('media.details.altHint')}\n />\n ) : null}\n {image && !readOnly ? (\n <SuggestAltButton\n assetId={asset.id}\n mimeType={asset.mimeType}\n onSuggest={(alt) => form.setValue('alt', alt, { shouldDirty: true, shouldValidate: true })}\n />\n ) : null}\n <FormTextareaField\n control={form.control}\n name=\"caption\"\n label={t('media.fields.caption')}\n rows={2}\n />\n {image && !readOnly ? (\n <FocalPoint\n imageUrl={asset.url}\n value={focal.field.value}\n onChange={(value) => focal.field.onChange(value)}\n />\n ) : null}\n <FormError error={error} />\n {readOnly ? null : (\n <div className=\"flex justify-end\">\n <SubmitButton\n pending={pending}\n pendingLabel={t('common.saving')}\n disabled={!form.formState.isDirty}\n >\n {t('common.saveChanges')}\n </SubmitButton>\n </div>\n )}\n </FieldGroup>\n </fieldset>\n </form>\n );\n};\n","import type { MediaAsset } from '@shapio/client';\nimport { ExternalLink } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { FileIcon } from '../../FileIcon';\nimport { isImage } from '../../helpers/fileKind';\n\ntype PreviewProps = { asset: MediaAsset };\n\n/** The widest ready variant up to 1280 px, else the original. */\nconst previewImageUrl = (asset: MediaAsset): string =>\n asset.variants.find((variant) => variant.name === 'w1280' && variant.url)?.url ??\n asset.variants.find((variant) => variant.name === 'w640' && variant.url)?.url ??\n asset.url;\n\n/** Images, video and audio play inline; other files show their type and an Open link. */\nexport const Preview = ({ asset }: PreviewProps) => {\n const { t } = useTranslation();\n if (isImage(asset.mimeType)) {\n return (\n <img\n src={previewImageUrl(asset)}\n alt={asset.alt || t('media.details.previewOf', { name: asset.filename })}\n className=\"max-h-72 w-full rounded-lg border bg-muted object-contain\"\n />\n );\n }\n if (asset.mimeType.startsWith('video/')) {\n return (\n <video\n src={asset.url}\n controls\n preload=\"metadata\"\n className=\"max-h-72 w-full rounded-lg border bg-muted\"\n />\n );\n }\n if (asset.mimeType.startsWith('audio/')) {\n return <audio src={asset.url} controls preload=\"metadata\" className=\"w-full\" />;\n }\n return (\n <div className=\"flex flex-col items-center gap-3 rounded-lg border bg-muted px-4 py-8\">\n <FileIcon mimeType={asset.mimeType} className=\"size-10 text-muted-foreground\" />\n <Button asChild variant=\"outline\" size=\"sm\">\n <a href={asset.url} target=\"_blank\" rel=\"noopener noreferrer\">\n <ExternalLink aria-hidden=\"true\" />\n {t('media.details.openFile')}\n </a>\n </Button>\n </div>\n );\n};\n","import type { ReactNode } from 'react';\n\ntype SectionProps = { title: string; children: ReactNode };\n\n/** A titled block of the details sheet. */\nexport const Section = ({ title, children }: SectionProps) => (\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold\">{title}</h3>\n {children}\n </section>\n);\n","import { useTranslation } from 'react-i18next';\nimport { useMediaUsage } from '@/api/media';\nimport { ErrorState } from '@/components/ErrorState';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Badge } from '@/components/ui/badge';\nimport { Skeleton } from '@/components/ui/skeleton';\n\ntype UsageProps = { assetId: string };\n\n/** \"Used in\": the entries whose draft or published version references the asset. */\nexport const Usage = ({ assetId }: UsageProps) => {\n const { t } = useTranslation();\n const usage = useMediaUsage(assetId);\n if (usage.isPending) {\n return <Skeleton className=\"h-8 w-full\" />;\n }\n if (usage.isError) {\n return <ErrorState error={usage.error} onRetry={() => void usage.refetch()} />;\n }\n if (usage.data.total === 0) {\n return <p className=\"text-sm text-muted-foreground\">{t('media.usage.none')}</p>;\n }\n return (\n <div className=\"space-y-2\">\n <p className=\"text-sm\">{t('media.usage.count', { count: usage.data.total })}</p>\n <ul className=\"divide-y rounded-lg border\">\n {usage.data.items.map((item) => (\n <li\n key={`${item.entryId}:${item.fieldId}:${item.locale}:${item.state}`}\n className=\"flex min-w-0 items-center gap-2 px-3 py-2\"\n >\n <span className=\"min-w-0 flex-1 truncate font-mono text-xs\" title={item.entryId}>\n {t('media.usage.entry', { id: item.entryId })}\n </span>\n <Badge variant=\"outline\" className=\"font-mono\">\n {item.locale}\n </Badge>\n <StatusChip\n size=\"sm\"\n tone={item.state === 'published' ? 'success' : 'neutral'}\n label={item.state === 'published' ? t('media.usage.published') : t('media.usage.draft')}\n />\n </li>\n ))}\n </ul>\n </div>\n );\n};\n","import type { MediaAsset } from '@shapio/client';\nimport { Globe, Lock } from 'lucide-react';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useUpdateMediaAsset } from '@/api/media';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { Field, FieldContent, FieldDescription, FieldLabel } from '@/components/ui/field';\nimport { Switch } from '@/components/ui/switch';\n\ntype VisibilityProps = { asset: MediaAsset; canManage: boolean };\n\n/**\n * Public files have a stable URL anyone can open; private files only open through signed links that\n * expire. One line says what the current setting means. Changing it needs `media.manage` and is confirmed\n * beside the switch, because it changes who can see the file.\n */\nexport const Visibility = ({ asset, canManage }: VisibilityProps) => {\n const { t } = useTranslation();\n const update = useUpdateMediaAsset();\n const [confirming, setConfirming] = useState(false);\n const isPrivate = asset.visibility === 'private';\n const next = isPrivate ? 'public' : 'private';\n const consequence = isPrivate\n ? t('media.visibility.privateExplanation')\n : t('media.visibility.publicExplanation');\n return (\n <Field orientation=\"horizontal\">\n <FieldContent>\n <div className=\"flex items-center gap-1.5\">\n {isPrivate ? (\n <Lock aria-hidden=\"true\" className=\"size-4 text-muted-foreground\" />\n ) : (\n <Globe aria-hidden=\"true\" className=\"size-4 text-muted-foreground\" />\n )}\n <FieldLabel htmlFor=\"asset-private\">{t('media.visibility.privateLabel')}</FieldLabel>\n </div>\n <FieldDescription id=\"asset-private-description\">\n {canManage ? consequence : `${consequence} ${t('media.visibility.needsManage')}`}\n </FieldDescription>\n </FieldContent>\n <InlineConfirm\n tone={next === 'public' ? 'danger' : 'default'}\n open={confirming}\n onOpenChange={setConfirming}\n title={\n next === 'private' ? t('media.visibility.makePrivateTitle') : t('media.visibility.makePublicTitle')\n }\n description={\n next === 'private'\n ? t('media.visibility.makePrivateDescription')\n : t('media.visibility.makePublicDescription')\n }\n confirmLabel={\n next === 'private' ? t('media.visibility.makePrivate') : t('media.visibility.makePublic')\n }\n onConfirm={() =>\n update\n .mutateAsync({ id: asset.id, input: { expectedVersion: asset.version, visibility: next } })\n .then(() => toast.success(t('media.visibility.changed')))\n }\n >\n <Switch\n id=\"asset-private\"\n checked={isPrivate}\n disabled={!canManage || update.isPending}\n aria-describedby=\"asset-private-description\"\n onCheckedChange={() => setConfirming(true)}\n />\n </InlineConfirm>\n </Field>\n );\n};\n","import { AlertTriangle } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useMediaAsset } from '@/api/media';\nimport { CopyButton } from '@/components/CopyButton';\nimport { ErrorState } from '@/components/ErrorState';\nimport { LoadingState } from '@/components/LoadingState';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Alert, AlertDescription } from '@/components/ui/alert';\nimport {\n Sheet,\n SheetBody,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n} from '@/components/ui/sheet';\nimport { useDiscardGuard } from '@/hooks/useDiscardGuard';\nimport { useMediaPermissions } from '@/hooks/useMediaPermissions';\nimport { fileKindLabel } from '../helpers/fileKind';\nimport { formatBytes } from '../helpers/formatBytes';\nimport { MEDIA_STATUS_DISPLAY } from '../helpers/statusDisplay';\nimport { useAssetDetailsForm } from '../hooks/useAssetDetailsForm';\nimport { UploadButton } from '../UploadButton';\nimport { DeleteAction } from './DeleteAction';\nimport { MetadataForm } from './MetadataForm';\nimport { Preview } from './Preview';\nimport { Section } from './Section';\nimport { Usage } from './Usage';\nimport { Variants } from './Variants';\nimport { Visibility } from './Visibility';\n\ntype DetailsProps = {\n assetId: string | undefined;\n onClose: () => void;\n onReplace: (assetId: string, file: File) => void;\n};\n\n/** One asset: preview, metadata, focal point, visibility, variants, \"used in\", replace and delete. */\nexport const Details = ({ assetId, onClose, onReplace }: DetailsProps) => {\n const { t } = useTranslation();\n const query = useMediaAsset(assetId);\n const asset = query.data;\n const { canWrite, canManage } = useMediaPermissions();\n const details = useAssetDetailsForm(asset);\n const { requestOpenChange, discardPrompt } = useDiscardGuard({\n dirty: details.form.formState.isDirty,\n pending: details.pending,\n onOpenChange: (open) => {\n if (!open) {\n details.form.reset();\n onClose();\n }\n },\n });\n const status = asset ? MEDIA_STATUS_DISPLAY[asset.status] : undefined;\n return (\n <>\n <Sheet open={assetId !== undefined} onOpenChange={requestOpenChange}>\n <SheetContent size=\"sm\">\n <SheetHeader>\n <SheetTitle className=\"pr-8 break-all\">{asset?.filename ?? t('media.details.title')}</SheetTitle>\n <SheetDescription className=\"text-meta\">\n {asset\n ? [\n fileKindLabel(asset.filename, asset.mimeType),\n formatBytes(asset.sizeBytes),\n asset.width && asset.height\n ? t('media.dimensions', { width: asset.width, height: asset.height })\n : '',\n ]\n .filter(Boolean)\n .join(' · ')\n : t('common.loading')}\n </SheetDescription>\n {asset && status ? (\n // In the fixed header, not the scrolling body: the focus trap wraps here without scrolling.\n <div className=\"flex flex-wrap items-center gap-2 pt-1\">\n <StatusChip tone={status.tone} label={t(status.labelKey)} />\n {asset.visibility === 'private' ? (\n <StatusChip tone=\"muted\" label={t('media.visibility.private')} />\n ) : null}\n <span className=\"ml-auto\">\n <CopyButton value={asset.url} />\n </span>\n </div>\n ) : null}\n </SheetHeader>\n <SheetBody className=\"space-y-6\">\n {query.isPending ? <LoadingState rows={3} /> : null}\n {query.isError ? <ErrorState error={query.error} onRetry={() => void query.refetch()} /> : null}\n {asset && status ? (\n <>\n <div className=\"space-y-3\">\n <Preview asset={asset} />\n {asset.urlExpiresAt ? (\n <p className=\"text-meta text-muted-foreground\">{t('media.details.signedLinkNote')}</p>\n ) : null}\n {asset.processingError ? (\n <Alert variant=\"destructive\">\n <AlertTriangle aria-hidden=\"true\" />\n <AlertDescription>{asset.processingError}</AlertDescription>\n </Alert>\n ) : null}\n </div>\n <Section title={t('media.details.metadata')}>\n <MetadataForm\n asset={asset}\n form={details.form}\n onSubmit={() => void details.onSubmit()}\n pending={details.pending}\n error={details.error}\n readOnly={!canWrite}\n />\n </Section>\n <Section title={t('media.usage.title')}>\n <Usage assetId={asset.id} />\n </Section>\n <Section title={t('media.visibility.title')}>\n <Visibility asset={asset} canManage={canManage} />\n </Section>\n <Section title={t('media.variants.title')}>\n <Variants asset={asset} />\n </Section>\n </>\n ) : null}\n </SheetBody>\n {asset && (canWrite || canManage) ? (\n <SheetFooter className=\"flex-row flex-wrap justify-between\">\n {canManage ? <DeleteAction asset={asset} onDeleted={onClose} /> : null}\n {canWrite ? (\n <UploadButton\n variant=\"outline\"\n multiple={false}\n label={t('media.details.replace')}\n onFiles={([file]) => (file ? onReplace(asset.id, file) : undefined)}\n className=\"ml-auto\"\n />\n ) : null}\n </SheetFooter>\n ) : null}\n </SheetContent>\n </Sheet>\n {discardPrompt}\n </>\n );\n};\n","import { Upload } from 'lucide-react';\nimport { useRef, useState, type DragEvent, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { cn } from '@/helpers/cn';\n\ntype DropzoneProps = {\n enabled: boolean;\n onFiles: (files: File[]) => void;\n children: ReactNode;\n className?: string;\n};\n\nconst hasFiles = (event: DragEvent) => event.dataTransfer.types.includes('Files');\n\n/**\n * Drop files anywhere over the library to upload them. A pointer shortcut only: the Upload button is the\n * keyboard and screen-reader path, so the overlay is hidden from assistive technology.\n */\nexport const Dropzone = ({ enabled, onFiles, children, className }: DropzoneProps) => {\n const { t } = useTranslation();\n const [dragging, setDragging] = useState(false);\n const depth = useRef(0);\n if (!enabled) {\n return <div className={className}>{children}</div>;\n }\n return (\n <div\n className={cn('relative', className)}\n onDragEnter={(event) => {\n if (hasFiles(event)) {\n depth.current += 1;\n setDragging(true);\n }\n }}\n onDragLeave={() => {\n depth.current = Math.max(0, depth.current - 1);\n if (depth.current === 0) {\n setDragging(false);\n }\n }}\n onDragOver={(event) => {\n if (hasFiles(event)) {\n event.preventDefault();\n event.dataTransfer.dropEffect = 'copy';\n }\n }}\n onDrop={(event) => {\n event.preventDefault();\n depth.current = 0;\n setDragging(false);\n const files = [...event.dataTransfer.files];\n if (files.length > 0) {\n onFiles(files);\n }\n }}\n >\n {children}\n {dragging ? (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 z-20 flex flex-col items-center justify-center gap-2 rounded-xl border-2 border-dashed border-primary bg-background/90 text-primary\"\n >\n <Upload className=\"size-8\" />\n <p className=\"font-semibold\">{t('media.upload.dropHere')}</p>\n </div>\n ) : null}\n </div>\n );\n};\n","import type { MediaFolder } from '@shapio/client';\n\nexport type FolderNode = MediaFolder & { children: FolderNode[]; depth: number };\n\n/** Builds the folder tree from the flat list, siblings sorted by name. Orphans (parent missing) go to the root. */\nexport const buildFolderTree = (folders: readonly MediaFolder[]): FolderNode[] => {\n const byParent = Map.groupBy(folders, (folder) =>\n folder.parentId && folders.some((candidate) => candidate.id === folder.parentId) ? folder.parentId : null,\n );\n const build = (parentId: string | null, depth: number): FolderNode[] =>\n [...(byParent.get(parentId) ?? [])]\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((folder) => ({ ...folder, depth, children: build(folder.id, depth + 1) }));\n return build(null, 0);\n};\n\n/** Depth-first: every folder with its depth, for pickers that show the tree as an indented list. */\nexport const flattenFolderTree = (nodes: readonly FolderNode[]): FolderNode[] =>\n nodes.flatMap((node) => [node, ...flattenFolderTree(node.children)]);\n\n/** The folder and everything under it (a folder cannot move into these). */\nexport const descendantIds = (folders: readonly MediaFolder[], id: string): Set<string> => {\n const result = new Set([id]);\n let grew = true;\n while (grew) {\n grew = false;\n for (const folder of folders) {\n if (folder.parentId && result.has(folder.parentId) && !result.has(folder.id)) {\n result.add(folder.id);\n grew = true;\n }\n }\n }\n return result;\n};\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport type { MediaFolder } from '@shapio/client';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useCreateMediaFolder, useUpdateMediaFolder } from '@/api/media';\nimport { i18next } from '@/app/i18n';\nimport { settle } from '@/helpers/settle';\nimport { requiredText } from '@/helpers/validation';\n\nconst MAX_NAME_LENGTH = 255;\n\nconst folderSchema = z.object({ name: requiredText().max(MAX_NAME_LENGTH, 'validation.tooLong') });\n\nexport type FolderValues = z.infer<typeof folderSchema>;\n\n/** What the inline folder row edits: a new folder (under `parentId`) or the name of `folder`. */\nexport type FolderEdit =\n { mode: 'create'; parentId: string | null } | { mode: 'rename'; folder: MediaFolder };\n\n/** The inline folder row's form: creates a folder or renames one, then calls `onDone`. */\nexport const useFolderForm = (edit: FolderEdit, onDone: () => void) => {\n const createFolder = useCreateMediaFolder();\n const updateFolder = useUpdateMediaFolder();\n const initialName = edit.mode === 'rename' ? edit.folder.name : '';\n const form = useForm<FolderValues>({\n resolver: zodResolver(folderSchema),\n defaultValues: { name: initialName },\n });\n const onSubmit = form.handleSubmit(async ({ name }) => {\n const trimmed = name.trim();\n if (edit.mode === 'rename' && trimmed === edit.folder.name) {\n onDone();\n return;\n }\n const result = await settle(\n edit.mode === 'rename'\n ? updateFolder.mutateAsync({\n id: edit.folder.id,\n input: { expectedVersion: edit.folder.version, name: trimmed },\n })\n : createFolder.mutateAsync({ name: trimmed, parentId: edit.parentId }),\n );\n if (result.ok) {\n toast.success(\n i18next.t(edit.mode === 'rename' ? 'media.folders.renamed' : 'media.folders.created', {\n name: trimmed,\n }),\n );\n onDone();\n }\n });\n const mutation = edit.mode === 'rename' ? updateFolder : createFolder;\n return { form, onSubmit, initialName, pending: mutation.isPending, error: mutation.error };\n};\n","import { Check, FolderPlus, Loader2, Pencil, X } from 'lucide-react';\nimport { useEffect, useId, type FocusEvent, type KeyboardEvent } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { FormFieldError } from '@/components/FormFieldError';\nimport { Button } from '@/components/ui/button';\nimport { Input } from '@/components/ui/input';\nimport { describeError } from '@/helpers/describeError';\nimport { useFolderForm, type FolderEdit } from '../../hooks/useFolderForm';\n\ntype EditRowProps = {\n edit: FolderEdit;\n /** `returnFocus`: false when focus already left the row (a click elsewhere), so it isn't pulled back. */\n onDone: (returnFocus: boolean) => void;\n};\n\n/**\n * A folder name being typed in place, in the tree (the caller's list item): a new folder or a rename. Enter saves, Escape cancels;\n * leaving the row without changing anything cancels too.\n */\nexport const EditRow = ({ edit, onDone }: EditRowProps) => {\n const { t } = useTranslation();\n const errorId = useId();\n const { form, onSubmit, initialName, pending, error } = useFolderForm(edit, () => onDone(true));\n const { setFocus } = form;\n useEffect(() => {\n setFocus('name', { shouldSelect: true });\n }, [setFocus]);\n const fieldError = form.formState.errors.name?.message;\n const message = fieldError ?? (error ? describeError(error) : undefined);\n const creating = edit.mode === 'create';\n const cancelOnEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && !pending) {\n event.preventDefault();\n event.stopPropagation();\n onDone(true);\n }\n };\n const cancelWhenLeftUnchanged = (event: FocusEvent<HTMLFormElement>) => {\n const next = event.relatedTarget;\n if (next instanceof Node && event.currentTarget.contains(next)) {\n return;\n }\n if (!pending && form.getValues('name').trim() === initialName) {\n onDone(false);\n }\n };\n return (\n <div>\n <form\n noValidate\n onSubmit={(event) => void onSubmit(event)}\n onKeyDown={cancelOnEscape}\n onBlur={cancelWhenLeftUnchanged}\n className=\"flex items-center gap-1 py-0.5 pl-1\"\n >\n {creating ? (\n <FolderPlus aria-hidden=\"true\" className=\"size-4 shrink-0 text-muted-foreground\" />\n ) : (\n <Pencil aria-hidden=\"true\" className=\"size-4 shrink-0 text-muted-foreground\" />\n )}\n <Input\n {...form.register('name')}\n inputSize=\"sm\"\n autoComplete=\"off\"\n spellCheck={false}\n readOnly={pending}\n aria-label={\n creating ? t('media.folders.newName') : t('media.folders.renameLabel', { name: edit.folder.name })\n }\n aria-invalid={message ? true : undefined}\n aria-describedby={message ? errorId : undefined}\n className=\"h-8 px-2\"\n />\n <Button\n type=\"submit\"\n variant=\"ghost\"\n size=\"icon-xs\"\n disabled={pending}\n aria-label={creating ? t('media.folders.create') : t('media.folders.saveName')}\n >\n {pending ? <Loader2 aria-hidden=\"true\" className=\"animate-spin\" /> : <Check aria-hidden=\"true\" />}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n disabled={pending}\n aria-label={t('common.cancel')}\n onClick={() => onDone(true)}\n >\n <X aria-hidden=\"true\" />\n </Button>\n </form>\n <div className=\"pl-6\">\n <FormFieldError id={errorId} message={message} />\n </div>\n </div>\n );\n};\n","/** A 36px folder-rail row: muted until hovered, accent pill while it is the current scope. */\nexport const FOLDER_ROW_CLASSES =\n 'flex h-9 min-w-0 items-center gap-2.5 rounded-lg text-left text-sm font-medium text-muted-foreground outline-none hover:bg-muted hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-[current=true]:bg-accent aria-[current=true]:font-semibold aria-[current=true]:text-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0';\n","import type { MediaFolder } from '@shapio/client';\nimport { FolderPlus, MoreHorizontal, Pencil, Trash2 } from 'lucide-react';\nimport { useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\n\nexport type FolderActions = {\n onCreate: (parentId: string | null) => void;\n onRename: (folder: MediaFolder) => void;\n /** The folder whose delete confirmation is open. */\n deletingId: string | undefined;\n onDeleteOpenChange: (folder: MediaFolder, open: boolean) => void;\n onDelete: (folder: MediaFolder) => Promise<unknown>;\n};\n\ntype MenuProps = { folder: MediaFolder; canManage: boolean; actions: FolderActions };\n\n/**\n * A folder's \"…\" menu: new subfolder and rename (an inline row takes focus), delete (confirmed in a popover\n * anchored to this button).\n */\nexport const Menu = ({ folder, canManage, actions }: MenuProps) => {\n const { t } = useTranslation();\n // A menu item hands focus to the inline row or the delete confirmation instead of the menu button.\n const handingOff = useRef(false);\n const handOff = (action: () => void) => () => {\n handingOff.current = true;\n action();\n };\n return (\n <DropdownMenu>\n <InlineConfirm\n tone=\"danger\"\n open={actions.deletingId === folder.id}\n onOpenChange={(open) => actions.onDeleteOpenChange(folder, open)}\n title={t('media.folders.deleteTitle', { name: folder.name })}\n description={t('media.folders.deleteDescription')}\n confirmLabel={t('common.delete')}\n onConfirm={() => actions.onDelete(folder)}\n >\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={t('media.folders.actions', { name: folder.name })}\n className=\"absolute right-1.5\"\n data-folder-menu={folder.id}\n >\n <MoreHorizontal aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n </InlineConfirm>\n <DropdownMenuContent\n align=\"end\"\n onCloseAutoFocus={(event) => {\n if (handingOff.current) {\n handingOff.current = false;\n event.preventDefault();\n }\n }}\n >\n <DropdownMenuItem onSelect={handOff(() => actions.onCreate(folder.id))}>\n <FolderPlus aria-hidden=\"true\" />\n {t('media.folders.newSubfolder')}\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={handOff(() => actions.onRename(folder))}>\n <Pencil aria-hidden=\"true\" />\n {t('media.folders.rename')}\n </DropdownMenuItem>\n {canManage ? (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n variant=\"destructive\"\n onSelect={handOff(() => actions.onDeleteOpenChange(folder, true))}\n >\n <Trash2 aria-hidden=\"true\" />\n {t('common.delete')}\n </DropdownMenuItem>\n </>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n};\n","import { Folder, FolderOpen } from 'lucide-react';\nimport { cn } from '@/helpers/cn';\nimport type { FolderNode } from '../../helpers/folderTree';\nimport type { FolderEdit } from '../../hooks/useFolderForm';\nimport { FOLDER_ROW_CLASSES } from '../constants';\nimport { EditRow } from '../EditRow';\nimport { Menu, type FolderActions } from '../Menu';\n\ntype ItemProps = {\n node: FolderNode;\n currentId: string | undefined;\n canWrite: boolean;\n canManage: boolean;\n actions: FolderActions;\n /** The inline row being edited anywhere in the tree. */\n editing: FolderEdit | undefined;\n onEditDone: (returnFocus: boolean) => void;\n onSelect: (id: string) => void;\n};\n\n/** A folder (button + actions menu, or its name being edited) and its subfolders, as a nested list. */\nexport const Item = ({\n node,\n currentId,\n canWrite,\n canManage,\n actions,\n editing,\n onEditDone,\n onSelect,\n}: ItemProps) => {\n const current = node.id === currentId;\n const Icon = current ? FolderOpen : Folder;\n const renameEdit = editing?.mode === 'rename' && editing.folder.id === node.id ? editing : undefined;\n const childEdit = editing?.mode === 'create' && editing.parentId === node.id ? editing : undefined;\n return (\n <li>\n {renameEdit ? (\n <EditRow edit={renameEdit} onDone={onEditDone} />\n ) : (\n <div className=\"relative flex items-center\">\n <button\n type=\"button\"\n aria-current={current ? 'true' : undefined}\n onClick={() => onSelect(node.id)}\n className={cn(FOLDER_ROW_CLASSES, 'flex-1 pl-2.5', canWrite ? 'pr-9' : 'pr-2.5')}\n >\n <Icon aria-hidden=\"true\" />\n <span className=\"truncate\">{node.name}</span>\n <span className=\"ml-auto text-xs font-medium text-muted-foreground tabular-nums\">\n {node.assetCount}\n </span>\n </button>\n {canWrite ? <Menu folder={node} canManage={canManage} actions={actions} /> : null}\n </div>\n )}\n {node.children.length > 0 || childEdit ? (\n <ul className=\"mt-0.5 ml-4 space-y-0.5 border-l pl-1.5\">\n {childEdit ? (\n <li>\n <EditRow edit={childEdit} onDone={onEditDone} />\n </li>\n ) : null}\n {node.children.map((child) => (\n <Item\n key={child.id}\n node={child}\n currentId={currentId}\n canWrite={canWrite}\n canManage={canManage}\n actions={actions}\n editing={editing}\n onEditDone={onEditDone}\n onSelect={onSelect}\n />\n ))}\n </ul>\n ) : null}\n </li>\n );\n};\n","import type { ReactNode } from 'react';\nimport { cn } from '@/helpers/cn';\nimport { FOLDER_ROW_CLASSES } from '../constants';\n\ntype ScopeButtonProps = { current: boolean; icon: ReactNode; label: string; onClick: () => void };\n\n/** \"All media\" and \"Not in a folder\": scopes above the folder list. */\nexport const ScopeButton = ({ current, icon, label, onClick }: ScopeButtonProps) => (\n <button\n type=\"button\"\n aria-current={current ? 'true' : undefined}\n onClick={onClick}\n className={cn(FOLDER_ROW_CLASSES, 'w-full px-2.5')}\n >\n {icon}\n <span className=\"truncate\">{label}</span>\n </button>\n);\n","import type { MediaFolder } from '@shapio/client';\nimport { Images, Inbox } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Panel } from '@/components/Panel';\nimport { Skeleton } from '@/components/ui/skeleton';\nimport { ROOT_FOLDER } from '../constants';\nimport { buildFolderTree } from '../helpers/folderTree';\nimport type { FolderEdit } from '../hooks/useFolderForm';\nimport { EditRow } from './EditRow';\nimport { Item } from './Item';\nimport type { FolderActions } from './Menu';\nimport { ScopeButton } from './ScopeButton';\n\ntype FolderTreeProps = {\n folders: readonly MediaFolder[] | undefined;\n /** A folder ID, `root`, or undefined for every folder. */\n current: string | undefined;\n canWrite: boolean;\n canManage: boolean;\n actions: FolderActions;\n /** The folder name being typed in place (a new folder or a rename), if any. */\n editing: FolderEdit | undefined;\n onEditDone: (returnFocus: boolean) => void;\n onSelect: (folder: string | undefined) => void;\n className?: string;\n};\n\n/**\n * The folder rail: \"All media\", \"Not in a folder\", then every folder with rename / new subfolder / delete.\n * New top-level folders come from the page header; new and renamed folders are named in place.\n */\nexport const FolderTree = ({\n folders,\n current,\n canWrite,\n canManage,\n actions,\n editing,\n onEditDone,\n onSelect,\n className,\n}: FolderTreeProps) => {\n const { t } = useTranslation();\n const tree = useMemo(() => buildFolderTree(folders ?? []), [folders]);\n const topLevelEdit = editing?.mode === 'create' && editing.parentId === null ? editing : undefined;\n return (\n <Panel title={t('media.folders.title')} flush className={className} bodyClassName=\"p-2\">\n <nav aria-label={t('media.folders.title')} className=\"space-y-1\">\n <ul className=\"space-y-0.5\">\n <li>\n <ScopeButton\n current={current === undefined}\n icon={<Images aria-hidden=\"true\" />}\n label={t('media.folders.all')}\n onClick={() => onSelect(undefined)}\n />\n </li>\n <li>\n <ScopeButton\n current={current === ROOT_FOLDER}\n icon={<Inbox aria-hidden=\"true\" />}\n label={t('media.folders.unfiled')}\n onClick={() => onSelect(ROOT_FOLDER)}\n />\n </li>\n </ul>\n {folders === undefined ? (\n <Skeleton className=\"h-8 w-full\" />\n ) : tree.length > 0 || topLevelEdit ? (\n <ul className=\"space-y-0.5 border-t pt-1\">\n {topLevelEdit ? (\n <li>\n <EditRow edit={topLevelEdit} onDone={onEditDone} />\n </li>\n ) : null}\n {tree.map((node) => (\n <Item\n key={node.id}\n node={node}\n currentId={current}\n canWrite={canWrite}\n canManage={canManage}\n actions={actions}\n editing={editing}\n onEditDone={onEditDone}\n onSelect={onSelect}\n />\n ))}\n </ul>\n ) : null}\n </nav>\n </Panel>\n );\n};\n","import { useCallback, useState } from 'react';\n\n/** The assets ticked for bulk actions. */\nexport const useAssetSelection = () => {\n const [selected, setSelected] = useState<ReadonlySet<string>>(new Set());\n const toggle = useCallback(\n (id: string, checked: boolean) =>\n setSelected((current) => {\n const next = new Set(current);\n if (checked) {\n next.add(id);\n } else {\n next.delete(id);\n }\n return next;\n }),\n [],\n );\n const clear = useCallback(() => setSelected(new Set()), []);\n return { selected, toggle, clear };\n};\n","import type { MediaFolder } from '@shapio/client';\nimport { useState } from 'react';\nimport { toast } from 'sonner';\nimport { useDeleteMediaFolder } from '@/api/media';\nimport { i18next } from '@/app/i18n';\nimport type { FolderActions } from '../FolderTree/Menu';\nimport type { FolderEdit } from './useFolderForm';\n\n/**\n * Where focus returns after an inline folder row: the page header's \"New folder\" button (`data-new-folder`)\n * for a top-level folder, otherwise the folder's actions button (`data-folder-menu` = its ID).\n */\nconst openerOf = (edit: FolderEdit): HTMLElement | null => {\n const id = edit.mode === 'rename' ? edit.folder.id : edit.parentId;\n const selector = id === null ? '[data-new-folder]' : `[data-folder-menu=\"${CSS.escape(id)}\"]`;\n return document.querySelector<HTMLElement>(selector);\n};\n\n/**\n * Create, rename and delete folders: the inline row being edited (create/rename happen in the tree, not a\n * dialog) and the folder whose delete confirmation is open.\n */\nexport const useFolderActions = (onDeleted: (folder: MediaFolder) => void) => {\n const [editing, setEditing] = useState<FolderEdit | undefined>(undefined);\n const [deletingId, setDeletingId] = useState<string | undefined>(undefined);\n const deleteFolder = useDeleteMediaFolder();\n const actions: FolderActions = {\n onCreate: (parentId) => setEditing({ mode: 'create', parentId }),\n onRename: (folder) => setEditing({ mode: 'rename', folder }),\n deletingId,\n onDeleteOpenChange: (folder, open) => setDeletingId(open ? folder.id : undefined),\n onDelete: (folder) =>\n deleteFolder.mutateAsync(folder.id).then(() => {\n toast.success(i18next.t('media.folders.deleted', { name: folder.name }));\n onDeleted(folder);\n }),\n };\n return {\n actions,\n editing,\n /**\n * Closes the inline row. With `returnFocus`, focus goes back to what opened it (the header button or\n * the folder's actions button) once the tree has re-rendered; not when focus already moved elsewhere.\n */\n stopEditing: (returnFocus: boolean) => {\n const edit = editing;\n setEditing(undefined);\n if (edit && returnFocus) {\n requestAnimationFrame(() => openerOf(edit)?.focus());\n }\n },\n };\n};\n","import { useNavigate, useSearch } from '@tanstack/react-router';\nimport type { MediaSearch } from '@/app/searchSchemas';\nimport { MIME_FILTER_BY_TYPE } from '../constants';\n\n/** Folder, filters, view and the open asset live in the URL (bookmarkable, back-button friendly). */\nexport const useMediaSearch = () => {\n const search = useSearch({ from: '/app/media' });\n const navigate = useNavigate({ from: '/media' });\n const setSearch = (changes: Partial<MediaSearch>, replace = false) =>\n void navigate({ search: (previous) => ({ ...previous, ...changes }), replace });\n return {\n search,\n setSearch,\n /** The API query for the current folder and filters. */\n assetQuery: {\n ...(search.folder ? { folder: search.folder } : {}),\n ...(search.q ? { search: search.q } : {}),\n ...(search.type ? { mimeType: MIME_FILTER_BY_TYPE[search.type] } : {}),\n },\n };\n};\n","import type { KeyboardEvent } from 'react';\n\n/**\n * Up/Down (and Home/End) move focus between the enabled buttons inside `event.currentTarget`, for short\n * pick lists where Tab alone would be slow.\n */\nexport const moveFocusWithArrows = (event: KeyboardEvent<HTMLElement>) => {\n const keys = ['ArrowDown', 'ArrowUp', 'Home', 'End'];\n if (!keys.includes(event.key)) {\n return;\n }\n const buttons = [...event.currentTarget.querySelectorAll<HTMLButtonElement>('button:not(:disabled)')];\n if (buttons.length === 0) {\n return;\n }\n event.preventDefault();\n const index = buttons.findIndex((button) => button === document.activeElement);\n const last = buttons.length - 1;\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? last\n : event.key === 'ArrowDown'\n ? Math.min(index + 1, last)\n : Math.max(index - 1, 0);\n buttons[next]?.focus();\n};\n","import { useState } from 'react';\nimport { toast } from 'sonner';\nimport { useMoveMediaAssets } from '@/api/media';\nimport { i18next } from '@/app/i18n';\nimport { settle } from '@/helpers/settle';\n\n/** The move target while a move runs: a folder ID, or null for \"no folder\". */\ntype MoveTarget = string | null;\n\n/** Moves assets into a folder (or out of every folder) and reports it; `onMoved` runs on success. */\nexport const useMoveToFolder = (assetIds: readonly string[], onMoved: () => void) => {\n const move = useMoveMediaAssets();\n const [target, setTarget] = useState<MoveTarget | undefined>(undefined);\n return {\n /** The folder being moved into while the request runs. */\n target: move.isPending ? target : undefined,\n pending: move.isPending,\n error: move.error,\n reset: move.reset,\n moveTo: async (folderId: MoveTarget) => {\n setTarget(folderId);\n const result = await settle(move.mutateAsync({ assetIds: [...assetIds], folderId }));\n if (result.ok) {\n toast.success(i18next.t('media.move.done', { count: result.value.moved.length }));\n onMoved();\n }\n },\n };\n};\n","import { Loader2 } from 'lucide-react';\nimport type { CSSProperties, ReactNode } from 'react';\nimport { cn } from '@/helpers/cn';\nimport { FOLDER_ROW_CLASSES } from '../../FolderTree/constants';\n\ntype ChoiceProps = {\n icon: ReactNode;\n label: string;\n /** Nesting level, indents the row (a runtime value, passed as a CSS variable). */\n depth: number;\n pending: boolean;\n disabled: boolean;\n onClick: () => void;\n};\n\n/** One folder in the move popover, indented by its depth; a spinner while the move into it runs. */\nexport const Choice = ({ icon, label, depth, pending, disabled, onClick }: ChoiceProps) => (\n <li>\n <button\n type=\"button\"\n disabled={disabled}\n aria-busy={pending || undefined}\n onClick={onClick}\n style={{ '--depth': depth } as CSSProperties}\n className={cn(\n FOLDER_ROW_CLASSES,\n 'w-full pr-2.5 pl-[calc(0.625rem+var(--depth)*1rem)] disabled:opacity-50',\n )}\n >\n {pending ? <Loader2 aria-hidden=\"true\" className=\"animate-spin\" /> : icon}\n <span className=\"truncate\">{label}</span>\n </button>\n </li>\n);\n","import { Folder, FolderInput, Inbox } from 'lucide-react';\nimport { useId, useMemo, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useMediaFolders } from '@/api/media';\nimport { FormError } from '@/components/FormError';\nimport { Button } from '@/components/ui/button';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\nimport { Skeleton } from '@/components/ui/skeleton';\nimport { moveFocusWithArrows } from '../helpers/arrowFocus';\nimport { buildFolderTree, flattenFolderTree } from '../helpers/folderTree';\nimport { useMoveToFolder } from '../hooks/useMoveToFolder';\nimport { Choice } from './Choice';\n\ntype MovePopoverProps = { assetIds: readonly string[]; onMoved: () => void };\n\n/**\n * \"Move to…\" for the selected files: a popover with the folder tree; choosing a folder moves them at once.\n * Up and Down move through the folders.\n */\nexport const MovePopover = ({ assetIds, onMoved }: MovePopoverProps) => {\n const { t } = useTranslation();\n const titleId = useId();\n const [open, setOpen] = useState(false);\n const folders = useMediaFolders();\n const choices = useMemo(() => flattenFolderTree(buildFolderTree(folders.data ?? [])), [folders.data]);\n const move = useMoveToFolder(assetIds, () => {\n setOpen(false);\n onMoved();\n });\n const changeOpen = (next: boolean) => {\n if (move.pending) {\n return;\n }\n if (next) {\n move.reset();\n }\n setOpen(next);\n };\n return (\n <Popover open={open} onOpenChange={changeOpen} modal>\n <PopoverTrigger asChild>\n <Button size=\"sm\" variant=\"outline\">\n <FolderInput aria-hidden=\"true\" />\n {t('media.move.action')}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" aria-labelledby={titleId} className=\"w-72 space-y-2 p-2\">\n <p id={titleId} className=\"px-2.5 pt-1 text-sm font-semibold\">\n {t('media.move.title', { count: assetIds.length })}\n </p>\n <ul className=\"max-h-72 space-y-0.5 overflow-y-auto\" onKeyDown={moveFocusWithArrows}>\n <Choice\n icon={<Inbox aria-hidden=\"true\" />}\n label={t('media.folders.none')}\n depth={0}\n pending={move.target === null}\n disabled={move.pending}\n onClick={() => void move.moveTo(null)}\n />\n {choices.map((folder) => (\n <Choice\n key={folder.id}\n icon={<Folder aria-hidden=\"true\" />}\n label={folder.name}\n depth={folder.depth}\n pending={move.target === folder.id}\n disabled={move.pending}\n onClick={() => void move.moveTo(folder.id)}\n />\n ))}\n </ul>\n {folders.isPending ? <Skeleton className=\"h-8 w-full\" /> : null}\n <FormError error={move.error} />\n </PopoverContent>\n </Popover>\n );\n};\n","import { X } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { MovePopover } from '../MovePopover';\n\ntype SelectionBarProps = { selected: ReadonlySet<string>; onClear: () => void };\n\n/** Bulk actions for the ticked assets. Announced when the selection changes. */\nexport const SelectionBar = ({ selected, onClear }: SelectionBarProps) => {\n const { t } = useTranslation();\n return (\n <div className=\"flex flex-wrap items-center gap-2 rounded-xl border bg-accent py-1.5 pr-1.5 pl-4 text-accent-foreground\">\n <span role=\"status\" aria-live=\"polite\" className=\"mr-auto text-sm font-medium\">\n {t('media.selectedCount', { count: selected.size })}\n </span>\n <MovePopover assetIds={[...selected]} onMoved={onClear} />\n <Button size=\"sm\" variant=\"ghost\" onClick={onClear}>\n <X aria-hidden=\"true\" />\n {t('media.clearSelection')}\n </Button>\n </div>\n );\n};\n","import { FolderPlus } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useMediaFolders } from '@/api/media';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { Button } from '@/components/ui/button';\nimport { useMediaPermissions } from '@/hooks/useMediaPermissions';\nimport { useMediaUploader } from '@/hooks/useMediaUploader';\nimport { ROOT_FOLDER } from './constants';\nimport { Details } from './Details';\nimport { Dropzone } from './Dropzone';\nimport { FolderTree } from './FolderTree';\nimport { useAssetSelection } from './hooks/useAssetSelection';\nimport { useFolderActions } from './hooks/useFolderActions';\nimport { useMediaSearch } from './hooks/useMediaSearch';\nimport { Library } from './Library';\nimport { SelectionBar } from './SelectionBar';\nimport { Toolbar } from './Toolbar';\nimport { UploadButton } from './UploadButton';\nimport { UploadQueue } from './UploadQueue';\n\n/** The media library: folders, search and filters, uploads (drop or pick), bulk move and asset details. Folders are created and renamed in place. */\nexport const Media = () => {\n const { t } = useTranslation();\n const { search, setSearch, assetQuery } = useMediaSearch();\n const folders = useMediaFolders();\n const { canWrite, canManage } = useMediaPermissions();\n const uploader = useMediaUploader();\n const selection = useAssetSelection();\n const folderActions = useFolderActions((folder) => {\n if (search.folder === folder.id) {\n setSearch({ folder: undefined });\n }\n });\n const uploadFolder = search.folder && search.folder !== ROOT_FOLDER ? search.folder : null;\n const upload = (files: File[]) => uploader.enqueue(files, { folderId: uploadFolder, visibility: 'public' });\n return (\n <Page width=\"full\">\n <PageHeader\n title={t('media.title')}\n actions={\n canWrite ? (\n <>\n <Button variant=\"outline\" data-new-folder onClick={() => folderActions.actions.onCreate(null)}>\n <FolderPlus aria-hidden=\"true\" />\n {t('media.folders.new')}\n </Button>\n <UploadButton label={t('media.upload.action')} onFiles={upload} />\n </>\n ) : null\n }\n />\n <div className=\"grid gap-6 lg:grid-cols-[13.75rem_minmax(0,1fr)]\">\n <FolderTree\n folders={folders.data}\n current={search.folder}\n canWrite={canWrite}\n canManage={canManage}\n actions={folderActions.actions}\n editing={folderActions.editing}\n onEditDone={folderActions.stopEditing}\n onSelect={(folder) => {\n selection.clear();\n setSearch({ folder });\n }}\n className=\"lg:self-start\"\n />\n <Dropzone enabled={canWrite} onFiles={upload} className=\"min-h-96 min-w-0 space-y-4\">\n <UploadQueue onRetry={uploader.retry} onDismiss={uploader.dismiss} />\n <Toolbar\n query={search.q}\n type={search.type}\n view={search.view ?? 'grid'}\n onQueryChange={(q) => setSearch({ q }, true)}\n onTypeChange={(type) => setSearch({ type })}\n onViewChange={(view) => setSearch({ view })}\n />\n {selection.selected.size > 0 ? (\n <SelectionBar selected={selection.selected} onClear={selection.clear} />\n ) : null}\n <Library\n query={assetQuery}\n filtered={Boolean(search.q || search.type)}\n view={search.view ?? 'grid'}\n selected={selection.selected}\n selectable={canWrite}\n activeId={search.asset}\n onSelectChange={selection.toggle}\n onOpen={(asset) => setSearch({ asset: asset.id })}\n />\n </Dropzone>\n </div>\n <Details\n assetId={search.asset}\n onClose={() => setSearch({ asset: undefined })}\n onReplace={(assetId, file) =>\n uploader.enqueue([file], { folderId: null, visibility: 'public', replaceAssetId: assetId })\n }\n />\n </Page>\n );\n};\n","import { createLazyRoute } from '@tanstack/react-router';\nimport { Media } from '@/features/Media';\n\n/** The media library, loaded on first visit. */\nexport const mediaLazyRoute = createLazyRoute('/app/media')({ component: Media });\n"],"ignoreList":[0,1,2],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=(e,t,n)=>e?e.modelPermissions[t]?.includes(n)??!1:!1,t=e=>e?e.globalPermissions.includes(`schema.create`)?!0:Object.values(e.modelPermissions).some(e=>e.includes(`schemaManage`)):!1,n=[`tokens.manage`,`webhooks.manage`],r=e=>!!e&&(n.some(t=>e?.globalPermissions.includes(t))||t(e));export{r as n,t as r,e as t};
|
|
2
|
+
//# sourceMappingURL=modelPermissions-DZ1lWfQZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modelPermissions-DZ1lWfQZ.js","names":["canOnModel","me","modelId","action","hasSchemaPermission","actions","DEVELOP_PERMISSIONS","canSeeDevelop"],"sources":["../../src/helpers/modelPermissions.ts"],"sourcesContent":["import type { ContentAction, GlobalAction, MeResponse } from '@shapio/client';\n\ntype Me = Pick<MeResponse, 'globalPermissions' | 'modelPermissions'>;\n\n/**\n * Whether the admin may perform a content action on a model, from `me.modelPermissions`. The server\n * enforces every action anyway; this only decides what the navigation and the palette offer.\n */\nexport const canOnModel = (me: Me | null | undefined, modelId: string, action: ContentAction): boolean => {\n if (!me) {\n return false;\n }\n return me.modelPermissions[modelId]?.includes(action) ?? false;\n};\n\n/** Any schema permission: creating models, or managing the structure of at least one. */\nexport const hasSchemaPermission = (me: Me | null | undefined): boolean => {\n if (!me) {\n return false;\n }\n if (me.globalPermissions.includes('schema.create')) {\n return true;\n }\n return Object.values(me.modelPermissions).some((actions) => actions.includes('schemaManage'));\n};\n\n/** Developer areas show with tokens or webhooks management, or any schema permission (plan §9). */\nconst DEVELOP_PERMISSIONS: readonly GlobalAction[] = ['tokens.manage', 'webhooks.manage'];\n\nexport const canSeeDevelop = (me: Me | null | undefined): boolean =>\n Boolean(me) &&\n (DEVELOP_PERMISSIONS.some((action) => me?.globalPermissions.includes(action)) || hasSchemaPermission(me));\n"],"mappings":"AAQA,IAAaA,GAAc,EAA2B,EAAiB,IAChEC,EAGEA,EAAG,iBAAiBC,EAAQ,EAAE,SAASC,CAAM,GAAK,GAFhD,GAMEC,EAAuB,GAC7BH,EAGDA,EAAG,kBAAkB,SAAS,eAAe,EACxC,GAEF,OAAO,OAAOA,EAAG,gBAAgB,CAAC,CAAC,KAAM,GAAYI,EAAQ,SAAS,cAAc,CAAC,EALnF,GASLC,EAA+C,CAAC,gBAAiB,iBAAiB,EAE3EC,EAAiB,GAC5B,EAAQN,IACPK,EAAoB,KAAM,GAAWL,GAAI,kBAAkB,SAASE,CAAM,CAAC,GAAKC,EAAoBH,CAAE"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./react-CQOZoUwg.js";import{t as n}from"./jsx-runtime-DREnUpxT.js";import{H as r,P as i,V as a,_ as o,bt as s,i as c,j as l,l as u,s as d,t as f,v as p,y as ee}from"./cn-DnXL75B0.js";import{d as m,l as te,s as ne}from"./errors-DfoXUVDI.js";import{O as re,_ as ie,a as h,i as g,j as ae,n as oe,o as _,r as se,t as v}from"./badge-CMox6-v3.js";import{i as y,n as b,o as ce,t as x}from"./RowTitle-sFt6NjO4.js";import{t as S}from"./fileRoute-BYwireXG.js";import{t as le}from"./UnsavedChangesGuard-BYwMTDsE.js";import{t as C}from"./FormCheckboxGroup-Bicl1CBP.js";import{B as ue,G as w,R as de,d as T,f as fe,o as E,p as pe,u as me}from"./InfoHint-DBqcrmZ3.js";import{N as D,i as O,k as he,n as ge,r as _e}from"./skeleton-DUvclBAr.js";import{u as k}from"./auth-b3_9QbtL.js";import{a as ve,i as ye,n as be,r as xe,s as Se,t as Ce}from"./select--nGB4WjU.js";import{t as we}from"./CursorPager-BFPD_adV.js";import{a as Te,i as A,n as Ee,o as De,r as j,t as Oe}from"./ConfirmDialog-D6rs75TP.js";import{S as ke,_ as Ae,b as je,d as Me,f as Ne,g as Pe,h as Fe,p as Ie,v as Le,x as Re,y as ze}from"./searchSchemas-ChN9hhuQ.js";import{t as Be}from"./ellipsis-DNdmromA.js";import{t as Ve}from"./link-CKr_uUfb.js";import{t as He}from"./pencil-Zd05MDs2.js";import{t as M}from"./plus-B0gd63Da.js";import{t as Ue}from"./scroll-text-D-gHqYwR.js";import{t as We}from"./search-BcPL1qyc.js";import{i as Ge,n as Ke,r as qe,t as Je}from"./useAuditLabels-CSw_kwLs.js";import{t as Ye}from"./users-C1ZSee3N.js";import{t as Xe}from"./UserAvatar-D-yX0ozh.js";import{a as N,l as Ze,p as Qe,r as $e,t as et}from"./dropdown-menu-CW3fabv5.js";import{n as tt,t as nt}from"./radio-group-DVR0mTpo.js";import{t as rt}from"./switch-B-FbT-l8.js";import{d as it,f as at,i as ot,l as st,n as P,o as F,r as ct,t as I,u as L}from"./zod-Pf5A-ax4.js";import{t as R}from"./settle-LRKtTN_e.js";import{_ as z,a as B,f as lt,g as V,i as H,l as ut,n as U,o as W,r as G,s as K,t as q,u as dt}from"./table-DQzCPm7J.js";import{t as ft}from"./HintedLabel-jKLM0ETt.js";import{o as pt}from"./schema-KXXSPVJn.js";import{t as J}from"./QueryView-DFZtm0fn.js";import{t as mt}from"./FormRadioGroup-34iVSV4L.js";import{H as ht}from"./src-D6DABe5J.js";import{t as Y}from"./Panel-6wFe96Gr.js";import{t as gt}from"./FormTextareaField-WsNjLm32.js";import{n as X,t as _t}from"./FormSelectField-Ba4fIu-8.js";import{a as vt,c as yt,i as bt,n as xt,o as St,r as Ct,s as wt,t as Tt}from"./users-DMfQL0s4.js";import{a as Et,i as Dt,n as Ot,o as kt,r as At,t as jt}from"./SecretReveal-Z6MOFdcL.js";import{t as Mt}from"./useConfirmTarget-9JmfiY2X.js";import{t as Nt}from"./LinkTabs-Bn2JVqOL.js";var Pt=[`read`,`create`,`update`,`delete`,`publish`,`schemaManage`],Ft=[`schema.create`,`users.manage`,`roles.manage`,`tokens.manage`,`audit.read`,`sites.manage`,`media.read`,`media.write`,`media.manage`,`publishing.manage`,`webhooks.manage`,`deployments.manage`,`deployments.trigger`,`changes.manage`,`changes.ship`],Z=[`read`,`create`,`update`,`delete`,`publish`],It={name:`book-open`,size:24,node:[[`path`,{d:`M12 5v16`,key:`1f6ucr`}],[`path`,{d:`M20.001 19A2 2 0 0022 17V5a2 2 0 00-1.999-2L16 3.002A5 5 0 0012 5a5 5 0 00-4-2H4a2 2 0 00-2 2v12a2 2 0 001.999 2H8a5 5 0 014 2 5 5 0 014-2z`,key:`1fyvmf`}]]};It.node;var Lt=c(It),Rt={name:`sliders-horizontal`,size:24,node:[[`path`,{d:`M10 5H3`,key:`1qgfaw`}],[`path`,{d:`M12 19H3`,key:`yhmn1j`}],[`path`,{d:`M14 3v4`,key:`1sua03`}],[`path`,{d:`M16 17v4`,key:`1q0r14`}],[`path`,{d:`M21 12h-9`,key:`1o4lsq`}],[`path`,{d:`M21 19h-5`,key:`1rlt1p`}],[`path`,{d:`M21 5h-7`,key:`1oszz2`}],[`path`,{d:`M8 10v4`,key:`tgpxqk`}],[`path`,{d:`M8 12H3`,key:`a7s4jb`}]]};Rt.node;var zt=c(Rt),Q=e(t(),1),Bt=e=>Promise.all([e.invalidateQueries({queryKey:i.sites.all}),e.invalidateQueries({queryKey:i.me})]),Vt=()=>r({queryKey:i.sites.all,queryFn:()=>u.sites.list(),meta:{silent:!0}}),Ht=e=>r({queryKey:i.sites.site(e),queryFn:()=>u.sites.get(e),meta:{silent:!0}}),Ut=()=>{let e=Vt();return{names:(0,Q.useMemo)(()=>new Map((e.data??[]).map(e=>[e.id,e.name])),[e.data]),error:e.error}},Wt=()=>{let e=s();return a({mutationKey:[`sites`,`create`],meta:{silent:!0},mutationFn:e=>d(()=>u.sites.create(e)),onSuccess:()=>Bt(e)})},Gt=()=>{let e=s();return a({mutationKey:[`sites`,`update`],meta:{silent:!0},mutationFn:({id:e,input:t})=>d(()=>u.sites.update(e,t)),onSettled:()=>Bt(e)})},Kt=()=>{let e=s();return a({mutationKey:[`sites`,`delete`],meta:{silent:!0},mutationFn:e=>d(()=>u.sites.remove(e.id)),onSuccess:(t,n)=>{if(n.key===o().key){ee();return}return e.removeQueries({queryKey:i.sites.site(n.id)}),Bt(e)}})},qt=e=>r({queryKey:i.sites.appRoles(e),queryFn:()=>u.sites.appRoles.get(e),meta:{silent:!0}}),Jt=()=>{let e=s();return a({mutationKey:[`sites`,`appRoles`,`set`],meta:{silent:!0},mutationFn:({id:e,input:t})=>d(()=>u.sites.appRoles.set(e,t)),onSuccess:t=>e.setQueryData(i.sites.appRoles(t.siteId),t)})},Yt=e=>k().data?.networkPermissions.includes(e)??!1,Xt=e=>{let t=Jt(),n=L({defaultValues:{public:e.public,authenticated:e.authenticated}}),{reset:r,formState:i}=n;return(0,Q.useEffect)(()=>{i.isDirty||r({public:e.public,authenticated:e.authenticated})},[e,r,i.isDirty]),{form:n,onSubmit:n.handleSubmit(async n=>{let i=await R(t.mutateAsync({id:e.siteId,input:n}));i.ok&&(r({public:i.value.public,authenticated:i.value.authenticated}),w.success(D.t(`sites.appRoles.saved`)))}),setBindings:t}},$=e(n(),1),Zt=({bindings:e,roles:t,canManage:n})=>{let{t:r}=l(),{form:i,onSubmit:a,setBindings:o}=Xt(e),s=t.map(e=>({value:e.id,label:e.name})),{isDirty:c}=i.formState;return(0,$.jsxs)(`form`,{noValidate:!0,onSubmit:e=>void a(e),children:[(0,$.jsxs)(me,{children:[(0,$.jsx)(C,{control:i.control,name:`public`,legend:r(`sites.appRoles.public`),options:s,disabled:!n}),(0,$.jsx)(C,{control:i.control,name:`authenticated`,legend:r(`sites.appRoles.authenticated`),options:s,disabled:!n}),(0,$.jsx)(A,{error:o.error}),n?(0,$.jsx)(`div`,{children:(0,$.jsx)(ie,{pending:o.isPending,pendingLabel:r(`common.saving`),disabled:!c,children:r(`common.saveChanges`)})}):null]}),(0,$.jsx)(le,{when:c})]})},Qt=({siteId:e,canManage:t})=>{let{t:n}=l(),r=qt(e),i=Fe();return(0,$.jsx)(Y,{title:n(`sites.appRoles.title`),description:n(`sites.appRoles.description`),children:(0,$.jsx)(J,{query:r,children:e=>(0,$.jsx)(J,{query:i,children:n=>(0,$.jsx)(Zt,{bindings:e,roles:n,canManage:t})})})})},$t=({site:e})=>{let{t}=l(),n=m(),r=Kt();return(0,$.jsx)(Y,{title:t(`sites.danger`),description:t(`sites.deleteDescription`),children:(0,$.jsx)(j,{tone:`danger`,title:t(`sites.deleteTitle`,{name:e.name}),description:t(`sites.deleteConsequence`),confirmLabel:t(`common.delete`),onConfirm:async()=>{await r.mutateAsync(e),e.key!==o().key&&(w.success(t(`sites.deleted`,{name:e.name})),n({to:`/network/sites`}))},trigger:(0,$.jsx)(O,{variant:`destructive-ghost`,children:t(`sites.delete`)})})})},en=V({name:F().max(200,`validation.tooLong`)}),tn=e=>{let t=Gt(),n=L({resolver:I(en),defaultValues:{name:e.name}}),{reset:r,formState:i}=n;return(0,Q.useEffect)(()=>{i.isDirty||r({name:e.name})},[e.name,r,i.isDirty]),{form:n,onSubmit:n.handleSubmit(async({name:n})=>{let i=await R(t.mutateAsync({id:e.id,input:{expectedVersion:e.version,name:n}}));i.ok&&(r({name:i.value.name}),w.success(D.t(`sites.renamed`)))}),updateSite:t}},nn=`site-key`,rn=`site-key-hint`,an=({site:e,canManage:t})=>{let{t:n}=l(),{form:r,onSubmit:i,updateSite:a}=tn(e),{isDirty:o}=r.formState;return(0,$.jsxs)(Y,{title:n(`sites.details`),children:[(0,$.jsx)(`form`,{noValidate:!0,onSubmit:e=>void i(e),className:`max-w-md`,children:(0,$.jsxs)(me,{children:[(0,$.jsx)(P,{control:r.control,name:`name`,label:n(`sites.name`),autoComplete:`off`,readOnly:!t}),(0,$.jsxs)(E,{children:[(0,$.jsx)(ft,{htmlFor:nn,label:n(`sites.key`),hint:n(`sites.keyHint`),hintId:rn}),(0,$.jsx)(ge,{id:nn,value:e.key,readOnly:!0,className:`font-mono`,"aria-describedby":rn})]}),(0,$.jsx)(A,{error:a.error}),t?(0,$.jsx)(`div`,{children:(0,$.jsx)(ie,{pending:a.isPending,pendingLabel:n(`common.saving`),disabled:!o,children:n(`common.saveChanges`)})}):null]})}),(0,$.jsx)(le,{when:o})]})},on=()=>{let{t:e}=l(),{siteId:t}=ae({from:`/app/network/sites/$siteId`}),n=Ht(t),r=Yt(`sites.manage`),i=Yt(`roles.manage`);return(0,$.jsx)(h,{width:`narrow`,children:(0,$.jsx)(J,{query:n,children:t=>(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(g,{breadcrumb:[{label:e(`sites.title`),link:te({to:`/network/sites`})}],title:t.name,badge:t.isPrimary?(0,$.jsx)(v,{variant:`secondary`,children:e(`sites.primary`)}):null,meta:t.key,actions:(0,$.jsx)(O,{variant:`outline`,onClick:()=>p(t.key),children:e(`sites.open`)})}),(0,$.jsx)(an,{site:t,canManage:r},t.id),(0,$.jsx)(Qt,{siteId:t.id,canManage:i}),r&&!t.isPrimary?(0,$.jsx)($t,{site:t}):null]})})})},sn=V({name:F().max(200,`validation.tooLong`),key:z().trim().regex(/^[a-z][a-z0-9-]{0,62}$/,`validation.siteKey`)}),cn={name:``,key:``},ln=(e,t)=>{let n=Wt(),r=L({resolver:I(sn),defaultValues:cn}),{reset:i}=r;return(0,Q.useEffect)(()=>{e&&i(cn)},[e,i]),{form:r,onSubmit:r.handleSubmit(async e=>{let r=await R(n.mutateAsync(e));r.ok&&(i(cn),t(r.value))}),createSite:n}},un=({open:e,onOpenChange:t,onCreated:n})=>{let{t:r}=l(),{form:i,onSubmit:a,createSite:o}=ln(e,n);return(0,$.jsxs)(X,{open:e,onOpenChange:t,size:`md`,title:r(`sites.createTitle`),dirty:i.formState.isDirty,pending:o.isPending,submitLabel:r(`common.create`),pendingLabel:r(`common.saving`),onSubmit:e=>void a(e),children:[(0,$.jsx)(P,{control:i.control,name:`name`,label:r(`sites.name`),autoComplete:`off`}),(0,$.jsx)(P,{control:i.control,name:`key`,label:r(`sites.key`),autoComplete:`off`,spellCheck:!1,hint:r(`sites.keyHint`),description:r(`sites.keyFixed`)}),(0,$.jsx)(A,{error:o.error})]})},dn=({sites:e})=>{let{t}=l();return(0,$.jsx)(K,{children:(0,$.jsxs)(q,{children:[(0,$.jsx)(B,{children:(0,$.jsxs)(W,{children:[(0,$.jsx)(H,{children:t(`sites.name`)}),(0,$.jsx)(H,{children:t(`sites.key`)}),(0,$.jsx)(H,{children:t(`sites.createdAt`)}),(0,$.jsx)(H,{children:(0,$.jsx)(`span`,{className:`sr-only`,children:t(`common.actions`)})})]})}),(0,$.jsx)(U,{children:e.map(e=>(0,$.jsxs)(W,{children:[(0,$.jsx)(G,{children:(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(x,{asChild:!0,children:(0,$.jsx)(ne,{to:`/network/sites/$siteId`,params:{siteId:e.id},children:e.name})}),e.isPrimary?(0,$.jsx)(v,{variant:`secondary`,children:t(`sites.primary`)}):null]})}),(0,$.jsx)(G,{className:`font-mono text-xs`,children:e.key}),(0,$.jsx)(G,{title:b(e.createdAt),children:y(e.createdAt)}),(0,$.jsx)(G,{className:`text-right`,children:(0,$.jsx)(O,{variant:`outline`,size:`sm`,"aria-label":t(`sites.openNamed`,{name:e.name}),onClick:()=>p(e.key),children:t(`sites.open`)})})]},e.id))})]})})},fn=()=>{let{t:e}=l(),t=m(),n=Vt(),r=Yt(`sites.manage`),[i,a]=(0,Q.useState)(!1);return(0,$.jsxs)(h,{children:[(0,$.jsx)(g,{title:e(`sites.title`),meta:n.data?e(`sites.count`,{count:n.data.length}):void 0,actions:r?(0,$.jsxs)(O,{onClick:()=>a(!0),children:[(0,$.jsx)(M,{"aria-hidden":`true`}),e(`sites.create`)]}):null}),(0,$.jsx)(J,{query:n,isEmpty:e=>e.length===0,empty:(0,$.jsx)(_,{icon:ke,title:e(`sites.empty`)}),children:e=>(0,$.jsx)(dn,{sites:e})}),r?(0,$.jsx)(un,{open:i,onOpenChange:a,onCreated:n=>{a(!1),w.success(e(`sites.created`,{name:n.name})),t({to:`/network/sites/$siteId`,params:{siteId:n.id}})}}):null]})},pn=`all`,mn=e=>Me.includes(e),hn=({action:e,actorType:t,onChange:n})=>{let{t:r}=l(),[i,a]=(0,Q.useState)(e??``),o=!!e||!!t;return(0,$.jsxs)(`form`,{role:`search`,className:`flex w-full flex-wrap items-center gap-2`,onSubmit:e=>{e.preventDefault(),n({action:i.trim()||void 0,actorType:t})},children:[(0,$.jsx)(_e,{htmlFor:`audit-action`,className:`sr-only`,children:r(`audit.filterAction`)}),(0,$.jsxs)(`div`,{className:`relative w-full sm:w-80`,children:[(0,$.jsx)(We,{"aria-hidden":`true`,className:`absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground`}),(0,$.jsx)(ge,{id:`audit-action`,inputSize:`sm`,value:i,placeholder:r(`audit.filterActionPlaceholder`),onChange:e=>a(e.target.value),onBlur:()=>n({action:i.trim()||void 0,actorType:t}),className:`pl-8`})]}),(0,$.jsx)(_e,{htmlFor:`audit-actor-type`,className:`sr-only`,children:r(`audit.filterActor`)}),(0,$.jsxs)(Ce,{value:t??pn,onValueChange:t=>n({action:e,actorType:mn(t)?t:void 0}),children:[(0,$.jsx)(ye,{id:`audit-actor-type`,size:`sm`,className:`w-44`,children:(0,$.jsx)(ve,{})}),(0,$.jsxs)(be,{children:[(0,$.jsx)(xe,{value:pn,children:r(`audit.allActors`)}),Me.map(e=>(0,$.jsx)(xe,{value:e,children:r(`audit.actorTypes.${e}`)},e))]})]}),o?(0,$.jsx)(O,{type:`button`,variant:`ghost`,size:`sm`,onClick:()=>{a(``),n({action:void 0,actorType:void 0})},children:r(`audit.clearFilters`)}):null]})},gn=()=>{let e=ce({from:`/app/network/audit-log`}),t=m({from:`/network/audit-log`}),[n,r]=(0,Q.useState)([]),i=e=>void t({search:t=>({...t,...e})});return{search:e,goFirst:e.cursor===void 0?void 0:()=>{r([]),i({cursor:void 0})},goPrevious:n.length===0?void 0:()=>{i({cursor:n.at(-1)}),r(e=>e.slice(0,-1))},goNext:t=>{r(t=>[...t,e.cursor]),i({cursor:t})},setFilters:e=>{r([]),i({...e,cursor:void 0})}}},_n=e=>e.targetType?`${e.targetType}:${e.targetId??``}`:void 0,vn=({events:e})=>{let{t}=l(),{actionLabel:n,targetLabel:r}=Je();return(0,$.jsxs)(q,{children:[(0,$.jsx)(B,{children:(0,$.jsxs)(W,{children:[(0,$.jsx)(H,{children:t(`audit.actor`)}),(0,$.jsx)(H,{children:t(`audit.action`)}),(0,$.jsx)(H,{children:t(`audit.target`)}),(0,$.jsx)(H,{children:t(`audit.outcome`)}),(0,$.jsx)(H,{children:t(`audit.ipAddress`)}),(0,$.jsx)(H,{children:t(`audit.when`)})]})}),(0,$.jsx)(U,{children:e.map(e=>{let i=t(`audit.actorTypes.${e.actorType}`),a=e.actorName??e.actorEmail??i,o=e.actorName&&e.actorEmail?e.actorEmail:e.actorName||e.actorEmail?i:e.actorId??void 0,s=n(e.action),c=_n(e),l=Ke(e.metadata);return(0,$.jsxs)(W,{children:[(0,$.jsx)(G,{children:(0,$.jsxs)(`span`,{className:`flex items-center gap-2.5`,children:[(0,$.jsx)(Xe,{name:a,size:`sm`}),(0,$.jsxs)(`span`,{className:`min-w-0`,children:[(0,$.jsx)(`span`,{className:`block max-w-48 truncate text-sm font-semibold`,children:a}),o?(0,$.jsx)(`span`,{className:`block max-w-48 truncate text-xs text-muted-foreground`,title:o,children:o}):null]})]})}),(0,$.jsx)(G,{title:e.action,children:s?(0,$.jsx)(v,{variant:`secondary`,children:s}):(0,$.jsx)(v,{variant:`secondary`,className:`font-mono`,children:e.action})}),(0,$.jsx)(G,{className:`max-w-64`,title:c,children:e.targetType?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`span`,{className:`block truncate text-sm`,children:r(e.targetType)??(0,$.jsx)(`span`,{className:`font-mono text-xs`,children:e.targetType})}),(0,$.jsx)(`span`,{className:`block truncate text-xs text-muted-foreground`,children:l??(0,$.jsx)(`span`,{className:`font-mono`,children:e.targetId})})]}):(0,$.jsx)(`span`,{className:`text-muted-foreground`,children:t(`common.none`)})}),(0,$.jsx)(G,{children:(0,$.jsx)(oe,{tone:e.outcome===`success`?`success`:`danger`,label:e.outcome===`success`?t(`audit.success`):t(`audit.failure`)})}),(0,$.jsx)(G,{className:`font-mono text-xs`,children:e.ip??t(`common.unknown`)}),(0,$.jsx)(G,{className:`whitespace-nowrap`,title:b(e.occurredAt),children:y(e.occurredAt)})]},e.id)})})]})},yn=()=>{let{t:e}=l(),{search:t,goFirst:n,goPrevious:r,goNext:i,setFilters:a}=gn(),o=qe({cursor:t.cursor,limit:50,action:t.action,actorType:t.actorType}),s=o.data?.nextCursor;return(0,$.jsxs)(h,{width:`full`,children:[(0,$.jsx)(g,{title:e(`audit.title`)}),(0,$.jsx)(K,{toolbar:(0,$.jsx)(hn,{action:t.action,actorType:t.actorType,onChange:a},`${t.action??``}|${t.actorType??``}`),footer:(0,$.jsx)(we,{onFirst:n,onPrevious:r,onNext:s?()=>i(s):void 0}),children:(0,$.jsx)(J,{query:o,loadingRows:8,isEmpty:e=>e.items.length===0&&t.cursor===void 0,empty:(0,$.jsx)(_,{size:`panel`,icon:Ue,title:e(`audit.empty`)}),children:e=>(0,$.jsx)(vn,{events:e.items})})})]})},bn=[...Pt,...Ft],xn={read:`roles.actions.read`,create:`roles.actions.create`,update:`roles.actions.update`,delete:`roles.actions.delete`,publish:`roles.actions.publish`,schemaManage:`roles.actions.schemaManage`,"schema.create":`roles.actions.schemaCreate`,"users.manage":`roles.actions.usersManage`,"roles.manage":`roles.actions.rolesManage`,"tokens.manage":`roles.actions.tokensManage`,"audit.read":`roles.actions.auditRead`,"sites.manage":`roles.actions.sitesManage`,"media.read":`roles.actions.mediaRead`,"media.write":`roles.actions.mediaWrite`,"media.manage":`roles.actions.mediaManage`,"publishing.manage":`roles.actions.publishingManage`,"webhooks.manage":`roles.actions.webhooksManage`,"deployments.manage":`roles.actions.deploymentsManage`,"deployments.trigger":`roles.actions.deploymentsTrigger`,"changes.manage":`roles.actions.changesManage`,"changes.ship":`roles.actions.changesShip`},Sn=[`admin`,`delivery`],Cn=/^[a-z][a-z0-9-]{0,62}$/,wn=V({key:z().trim().regex(Cn,`validation.roleKey`),name:F(),description:z().trim(),kind:ut([`admin`,`delivery`]),actions:dt(lt(e=>bn.includes(e)))}),Tn=e=>e.modelId===null&&e.condition===null&&e.fieldIds===null,En=e=>({key:e?.key??``,name:e?.name??``,description:e?.description??``,kind:e?.kind??`admin`,actions:(e?.permissions??[]).filter(Tn).map(e=>e.action)}),Dn=e=>({action:e,modelId:null,condition:null,fieldIds:null}),On=(e,t,n)=>{let r=Ot(),i=kt(),a=L({resolver:I(wn),defaultValues:En(t)}),{reset:o}=a;(0,Q.useEffect)(()=>{e&&o(En(t))},[e,t,o]);let s=a.handleSubmit(async({key:e,name:a,description:o,kind:s,actions:c})=>{if(t){let e=t.permissions.filter(e=>!Tn(e));if(!(await R(i.mutateAsync({id:t.id,input:{expectedVersion:t.version,name:a,description:o,permissions:[...e,...c.map(Dn)]}}))).ok)return;w.success(D.t(`roles.saved`))}else{if(!(await R(r.mutateAsync({key:e,name:a,description:o,kind:s,permissions:c.map(Dn)}))).ok)return;w.success(D.t(`roles.created`))}n()}),c=t?i:r;return{form:a,onSubmit:s,pending:c.isPending,error:c.error}},kn={admin:`roles.kindAdmin`,delivery:`roles.kindDelivery`},An=({open:e,onOpenChange:t,role:n})=>{let{t:r}=l(),{form:i,onSubmit:a,pending:o,error:s}=On(e,n,()=>t(!1)),c=n!==void 0,u=i.watch(`kind`);return(0,$.jsxs)(X,{open:e,onOpenChange:t,size:`md`,title:r(c?`roles.editTitle`:`roles.createTitle`),dirty:i.formState.isDirty,pending:o,submitLabel:r(c?`common.saveChanges`:`common.create`),pendingLabel:r(`common.saving`),onSubmit:e=>void a(e),children:[(0,$.jsx)(P,{control:i.control,name:`name`,label:r(`roles.name`),autoComplete:`off`}),(0,$.jsx)(P,{control:i.control,name:`key`,label:r(`roles.key`),hint:r(`roles.keyHint`),autoComplete:`off`,spellCheck:!1,className:`font-mono`,disabled:c}),(0,$.jsx)(gt,{control:i.control,name:`description`,label:r(`roles.roleDescription`),rows:2}),(0,$.jsx)(_t,{control:i.control,name:`kind`,label:r(`roles.kind`),hint:r(`roles.kindHint`),options:Sn.map(e=>({value:e,label:r(kn[e])})),disabled:c}),(0,$.jsx)(C,{control:i.control,name:`actions`,legend:r(`roles.contentPermissions`),options:Pt.map(e=>({value:e,label:r(xn[e])}))}),u===`admin`?(0,$.jsx)(C,{control:i.control,name:`actions`,legend:r(`roles.instancePermissions`),options:Ft.map(e=>({value:e,label:r(xn[e])}))}):null,(0,$.jsx)(A,{error:s})]})},jn=({roles:e,onEdit:t,onDelete:n})=>{let{t:r}=l();return(0,$.jsx)(K,{children:(0,$.jsxs)(q,{children:[(0,$.jsx)(B,{children:(0,$.jsxs)(W,{children:[(0,$.jsx)(H,{children:r(`roles.name`)}),(0,$.jsx)(H,{children:r(`roles.key`)}),(0,$.jsx)(H,{children:r(`roles.kind`)}),(0,$.jsx)(H,{children:r(`roles.permissions`)}),(0,$.jsx)(H,{children:(0,$.jsx)(`span`,{className:`sr-only`,children:r(`common.actions`)})})]})}),(0,$.jsx)(U,{children:e.map(e=>(0,$.jsxs)(W,{children:[(0,$.jsxs)(G,{className:`max-w-xs`,children:[(0,$.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(x,{children:e.name}),(0,$.jsx)(v,{variant:e.isSystem?`secondary`:`outline`,children:e.isSystem?r(`roles.builtIn`):r(`roles.custom`)})]}),e.description?(0,$.jsx)(`span`,{className:`block truncate text-meta whitespace-normal text-muted-foreground`,children:e.description}):null]}),(0,$.jsx)(G,{className:`font-mono text-xs`,children:e.key}),(0,$.jsx)(G,{children:e.kind===`admin`?r(`roles.kindAdmin`):r(`roles.kindDelivery`)}),(0,$.jsx)(G,{children:r(`roles.permissionsCount`,{count:e.permissions.length})}),(0,$.jsx)(G,{className:`text-right`,children:e.isSystem?null:(0,$.jsxs)(et,{children:[(0,$.jsx)(Qe,{asChild:!0,children:(0,$.jsx)(O,{variant:`ghost`,size:`icon-sm`,"aria-label":`${r(`common.actions`)}: ${e.name}`,children:(0,$.jsx)(Be,{"aria-hidden":`true`})})}),(0,$.jsxs)($e,{align:`end`,children:[(0,$.jsxs)(N,{onSelect:()=>t(e),children:[(0,$.jsx)(He,{"aria-hidden":`true`}),r(`common.edit`)]}),(0,$.jsxs)(N,{variant:`destructive`,onSelect:()=>n(e),children:[(0,$.jsx)(de,{"aria-hidden":`true`}),r(`common.delete`)]})]})]})})]},e.id))})]})})},Mn=()=>{let{t:e}=l();return(0,$.jsx)(Nt,{label:e(`roles.sections`),tabs:[{to:`/network/roles`,label:e(`roles.tabAdmin`)},{to:`/network/roles/app`,label:e(`roles.tabApp`)}]})},Nn=()=>{let{t:e}=l(),t=Et(),n=At(),r=Mt(),[i,a]=(0,Q.useState)({open:!1,role:void 0});return(0,$.jsxs)(h,{width:`full`,children:[(0,$.jsx)(g,{title:e(`roles.title`),tabs:(0,$.jsx)(Mn,{}),actions:(0,$.jsxs)(O,{onClick:()=>a({open:!0,role:void 0}),children:[(0,$.jsx)(M,{"aria-hidden":`true`}),e(`roles.create`)]})}),(0,$.jsx)(J,{query:t,isEmpty:e=>e.length===0,empty:(0,$.jsx)(_,{icon:Re,title:e(`roles.empty`)}),children:e=>(0,$.jsx)(jn,{roles:e,onEdit:e=>a({open:!0,role:e}),onDelete:e=>r.ask(e)})}),(0,$.jsx)(An,{open:i.open,onOpenChange:e=>a(t=>({...t,open:e})),role:i.role}),(0,$.jsx)(Oe,{open:r.open,onOpenChange:r.onOpenChange,title:e(`roles.deleteTitle`,{name:r.target?.name??``}),description:e(`roles.deleteDescription`),confirmLabel:e(`common.delete`),destructive:!0,onConfirm:()=>{r.target&&n.mutate(r.target.id,{onSuccess:()=>w.success(e(`roles.deleted`))})}})]})},Pn=V({key:z().trim().regex(Cn,`validation.roleKey`),name:F(),description:z().trim()}),Fn={key:``,name:``,description:``},In=(e,t)=>{let n=Pe(),r=L({resolver:I(Pn),defaultValues:Fn}),{reset:i}=r;return(0,Q.useEffect)(()=>{e&&i(Fn)},[e,i]),{form:r,onSubmit:r.handleSubmit(async e=>{let r=await R(n.mutateAsync({...e,permissions:[]}));r.ok&&(w.success(D.t(`appRoles.created`)),t(r.value))}),createAppRole:n}},Ln=({open:e,onOpenChange:t,onCreated:n})=>{let{t:r}=l(),{form:i,onSubmit:a,createAppRole:o}=In(e,n);return(0,$.jsxs)(X,{open:e,onOpenChange:t,size:`md`,title:r(`appRoles.createTitle`),dirty:i.formState.isDirty,pending:o.isPending,submitLabel:r(`common.create`),pendingLabel:r(`common.saving`),onSubmit:e=>void a(e),children:[(0,$.jsx)(P,{control:i.control,name:`name`,label:r(`roles.name`),autoComplete:`off`}),(0,$.jsx)(P,{control:i.control,name:`key`,label:r(`roles.key`),hint:r(`roles.keyHint`),autoComplete:`off`,spellCheck:!1,className:`font-mono`}),(0,$.jsx)(gt,{control:i.control,name:`description`,label:r(`roles.roleDescription`),rows:2}),(0,$.jsx)(A,{error:o.error})]})},Rn=e=>e.permissions.some(e=>e.action===`read`&&e.modelId===null&&e.condition===null),zn=()=>{let e=Le();return{grantReadAll:t=>e.mutate({id:t.id,input:{expectedVersion:t.version,permissions:[...t.permissions.filter(e=>e.action!==`read`||e.modelId!==null),{action:`read`,modelId:null,condition:null,fieldIds:null}]}},{onSuccess:()=>w.success(D.t(`appRoles.readAllGranted`,{name:t.name})),onError:e=>w.error(he(e))}),pendingRoleId:e.isPending?e.variables?.id:void 0}},Bn=({role:e,onDelete:t})=>{let{t:n}=l(),[r,i]=(0,Q.useState)(!1);return(0,$.jsxs)(et,{children:[(0,$.jsx)(j,{tone:`danger`,open:r,onOpenChange:i,title:n(`roles.deleteTitle`,{name:e.name}),description:n(`appRoles.deleteDescription`),confirmLabel:n(`common.delete`),onConfirm:()=>t(e),children:(0,$.jsx)(Qe,{asChild:!0,children:(0,$.jsx)(O,{variant:`ghost`,size:`icon-sm`,"aria-label":`${n(`common.actions`)}: ${e.name}`,children:(0,$.jsx)(Be,{"aria-hidden":`true`})})})}),(0,$.jsxs)($e,{align:`end`,onCloseAutoFocus:e=>r&&e.preventDefault(),children:[(0,$.jsx)(N,{asChild:!0,children:(0,$.jsxs)(ne,{to:`/network/roles/app/$roleId`,params:{roleId:e.id},children:[(0,$.jsx)(zt,{"aria-hidden":`true`}),n(`appRoles.editPermissions`)]})}),e.isSystem?null:(0,$.jsxs)(N,{variant:`destructive`,onSelect:()=>i(!0),children:[(0,$.jsx)(de,{"aria-hidden":`true`}),n(`common.delete`)]})]})]})},Vn={public:`appRoles.holdersPublic`,authenticated:`appRoles.holdersAuthenticated`},Hn=e=>Object.hasOwn(Vn,e)?Vn[e]:void 0,Un=({roles:e,onDelete:t,onGrantReadAll:n,pendingRoleId:r})=>{let{t:i}=l();return(0,$.jsx)(K,{children:(0,$.jsxs)(q,{children:[(0,$.jsx)(B,{children:(0,$.jsxs)(W,{children:[(0,$.jsx)(H,{children:i(`roles.name`)}),(0,$.jsx)(H,{children:i(`roles.key`)}),(0,$.jsx)(H,{children:i(`appRoles.heldBy`)}),(0,$.jsx)(H,{children:i(`roles.permissions`)}),(0,$.jsx)(H,{children:(0,$.jsx)(`span`,{className:`sr-only`,children:i(`common.actions`)})})]})}),(0,$.jsx)(U,{children:e.map(e=>{let a=e.isSystem?Hn(e.key):void 0;return(0,$.jsxs)(W,{children:[(0,$.jsxs)(G,{className:`max-w-xs`,children:[(0,$.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(x,{asChild:!0,children:(0,$.jsx)(ne,{to:`/network/roles/app/$roleId`,params:{roleId:e.id},children:e.name})}),(0,$.jsx)(v,{variant:e.isSystem?`secondary`:`outline`,children:e.isSystem?i(`roles.builtIn`):i(`roles.custom`)})]}),e.description?(0,$.jsx)(`span`,{className:`block text-meta whitespace-normal text-muted-foreground`,children:e.description}):null]}),(0,$.jsx)(G,{className:`font-mono text-xs`,children:e.key}),(0,$.jsx)(G,{children:a?i(a):i(`appRoles.userCount`,{count:e.userCount})}),(0,$.jsx)(G,{children:(0,$.jsxs)(`span`,{className:`flex flex-wrap items-center gap-2`,children:[i(`roles.permissionsCount`,{count:e.permissions.length}),e.isSystem&&!Rn(e)?(0,$.jsxs)(O,{variant:`outline`,size:`sm`,disabled:r===e.id,"aria-label":`${i(`appRoles.grantReadAll`)}: ${e.name}`,onClick:()=>n(e),children:[(0,$.jsx)(Lt,{"aria-hidden":`true`}),i(`appRoles.grantReadAll`)]}):null]})}),(0,$.jsx)(G,{className:`text-right`,children:(0,$.jsx)(Bn,{role:e,onDelete:t})})]},e.id)})})]})})},Wn=()=>{let{t:e}=l(),t=m(),n=Fe(),r=Ae(),[i,a]=(0,Q.useState)(!1),{grantReadAll:o,pendingRoleId:s}=zn(),c=async t=>{await r.mutateAsync(t.id),w.success(e(`roles.deleted`))};return(0,$.jsxs)(h,{width:`full`,children:[(0,$.jsx)(g,{title:e(`appRoles.title`),tabs:(0,$.jsx)(Mn,{}),actions:(0,$.jsxs)(O,{onClick:()=>a(!0),children:[(0,$.jsx)(M,{"aria-hidden":`true`}),e(`appRoles.create`)]})}),(0,$.jsx)(J,{query:n,isEmpty:e=>e.length===0,empty:(0,$.jsx)(_,{icon:Re,title:e(`roles.empty`)}),children:t=>(0,$.jsxs)(`div`,{className:`space-y-4`,children:[t.some(e=>e.isSystem&&!Rn(e))?(0,$.jsxs)(Te,{variant:`info`,role:`note`,children:[(0,$.jsx)(ue,{"aria-hidden":`true`}),(0,$.jsx)(De,{children:e(`appRoles.denyByDefault`)})]}):null,(0,$.jsx)(Un,{roles:t,onDelete:c,onGrantReadAll:o,pendingRoleId:s})]})}),(0,$.jsx)(Ln,{open:i,onOpenChange:a,onCreated:e=>{a(!1),t({to:`/network/roles/app/$roleId`,params:{roleId:e.id}})}})]})},Gn=new Set([`read`,`update`,`delete`,`publish`]),Kn=new Set([`read`,`create`,`update`]),qn={read:`appRoles.actions.read`,create:`appRoles.actions.create`,update:`appRoles.actions.update`,delete:`appRoles.actions.delete`,publish:`appRoles.actions.publish`},Jn=e=>{let t={};for(let n of e){let e=n.modelId??`*`;t[e]={...t[e],[n.action]:{ownOnly:n.condition===`ownedByPrincipal`,fieldIds:n.fieldIds===null?null:[...n.fieldIds].sort()}}}return t},Yn=e=>Object.keys(e).sort((e,t)=>e===`*`?-1:t===`*`?1:e.localeCompare(t)).flatMap(t=>Z.flatMap(n=>{let r=e[t]?.[n];return r?[{action:n,modelId:t===`*`?null:t,condition:r.ownOnly&&Gn.has(n)?`ownedByPrincipal`:null,fieldIds:Kn.has(n)?r.fieldIds:null}]:[]})),Xn=(e,t,n,r)=>{let i={...e[t]};return r?i[n]=r:delete i[n],{...e,[t]:i}},Zn=(e,t,n,r)=>Xn(e,t,n,r?e[t]?.[n]??{ownOnly:!1,fieldIds:null}:void 0),Qn=(e,t,n,r)=>{let i=e[t]?.[n];return i?Xn(e,t,n,{...i,...r}):e},$n=(e,t)=>Z.some(n=>t?.[n]!==void 0&&(Gn.has(n)||e!==`*`&&Kn.has(n))),er=(e,t,n,r)=>t.reduce((e,t)=>Zn(e,t,n,r),e),tr=(e,t,n)=>{let r=t.filter(t=>e[t]?.[n]!==void 0).length;return r===0?!1:r===t.length||`indeterminate`},nr=V({name:F(),description:z().trim()}),rr=e=>{let t=Le(),n=L({resolver:I(nr),defaultValues:{name:e.name,description:e.description}}),[r,i]=(0,Q.useState)(()=>Jn(e.permissions)),a=(0,Q.useMemo)(()=>JSON.stringify(Yn(Jn(e.permissions))),[e.permissions]),o=(0,Q.useMemo)(()=>Yn(r),[r]),s=JSON.stringify(o)!==a,c=!e.isSystem&&n.formState.isDirty,l=n.handleSubmit(async n=>{(await R(t.mutateAsync({id:e.id,input:{expectedVersion:e.version,...c?n:{},...s?{permissions:o}:{}}}))).ok&&w.success(D.t(`roles.saved`))});return{form:n,matrix:r,setMatrix:i,dirty:s||c,onSubmit:l,pending:t.isPending,error:t.error}},ir=`all`,ar=`selected`,or=({id:e,rowKey:t,fields:n,grants:r,onChange:i})=>{let{t:a}=l(),o=(n??[]).filter(e=>!e.deprecated);return(0,$.jsx)(`div`,{id:e,className:`grid gap-6 border-t bg-muted/40 px-5 py-4 md:grid-cols-2`,children:Z.map(n=>{let s=r[n],c=Gn.has(n),l=t!==`*`&&Kn.has(n);if(!s||!c&&!l)return null;let u=`${e}-${n}`;return(0,$.jsxs)(pe,{className:`gap-3`,children:[(0,$.jsx)(fe,{variant:`label`,children:a(qn[n])}),c?(0,$.jsxs)(E,{orientation:`horizontal`,children:[(0,$.jsx)(T,{htmlFor:`${u}-own`,children:a(`appRoles.ownOnly`)}),(0,$.jsx)(rt,{id:`${u}-own`,checked:s.ownOnly,onCheckedChange:e=>i(n,{ownOnly:e})})]}):null,l?(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(nt,{"aria-label":a(`appRoles.fieldScope`),value:s.fieldIds===null?ir:ar,onValueChange:e=>i(n,{fieldIds:e===ir?null:o.filter(e=>e.public).map(e=>e.id)}),children:[(0,$.jsxs)(E,{orientation:`horizontal`,children:[(0,$.jsx)(tt,{id:`${u}-all`,value:ir}),(0,$.jsx)(T,{htmlFor:`${u}-all`,className:`font-normal`,children:a(`appRoles.allPublicFields`)})]}),(0,$.jsxs)(E,{orientation:`horizontal`,children:[(0,$.jsx)(tt,{id:`${u}-selected`,value:ar}),(0,$.jsx)(T,{htmlFor:`${u}-selected`,className:`font-normal`,children:a(`appRoles.selectedFields`)})]})]}),s.fieldIds===null?null:(0,$.jsx)(`div`,{className:`grid gap-2 pl-6 sm:grid-cols-2`,children:o.map(e=>{let t=s.fieldIds??[],r=`${u}-field-${e.id}`;return(0,$.jsxs)(E,{orientation:`horizontal`,children:[(0,$.jsx)(Ee,{id:r,checked:t.includes(e.id),onCheckedChange:r=>i(n,{fieldIds:r===!0?[...t,e.id].sort():t.filter(t=>t!==e.id)})}),(0,$.jsxs)(T,{htmlFor:r,className:`font-normal`,children:[e.label,e.public?null:(0,$.jsx)(v,{variant:`secondary`,children:a(`appRoles.notPublic`)})]})]},e.id)})})]}):null]},n)})})},sr=({label:e,detail:t,grants:n,optionsId:r,expanded:i,canExpand:a,onToggle:o,onToggleExpanded:s})=>{let{t:c}=l();return(0,$.jsxs)(W,{className:`hover:bg-transparent has-aria-expanded:bg-transparent`,children:[(0,$.jsx)(G,{className:`sticky left-0 z-10 h-9 bg-card py-0`,children:(0,$.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,$.jsx)(`span`,{className:`font-semibold`,children:e}),(0,$.jsx)(`span`,{className:`truncate text-xs text-muted-foreground`,children:t})]})}),Z.map(t=>(0,$.jsx)(G,{className:`h-9 py-0 text-center`,children:(0,$.jsx)(Ee,{checked:n[t]!==void 0,onCheckedChange:e=>o(t,e===!0),"aria-label":`${c(qn[t])}: ${e}`,className:`align-middle`})},t)),(0,$.jsx)(G,{className:`h-9 py-0 text-right`,children:(0,$.jsxs)(O,{type:`button`,variant:`ghost`,size:`xs`,disabled:!a,"aria-expanded":i,"aria-controls":i?r:void 0,"aria-label":`${c(`appRoles.options`)}: ${e}`,onClick:s,children:[c(`appRoles.options`),(0,$.jsx)(Se,{"aria-hidden":`true`,className:f(`transition-transform`,i&&`rotate-180`)})]})})]})},cr=({matrix:e,models:t,onChange:n})=>{let{t:r}=l(),[i,a]=(0,Q.useState)(new Set),o=e=>a(t=>{let n=new Set(t);return n.delete(e)||n.add(e),n}),s=[{key:`*`,label:r(`appRoles.allModels`),detail:r(`appRoles.allModelsHint`),fields:void 0},...t.map(e=>e.definition).filter(ht).map(e=>({key:e.id,label:e.label,detail:e.apiKey,fields:e.fields}))],c=s.map(e=>e.key);return(0,$.jsxs)(q,{children:[(0,$.jsx)(B,{children:(0,$.jsxs)(W,{children:[(0,$.jsx)(H,{className:`sticky left-0 z-10 min-w-60 bg-muted`,children:r(`appRoles.model`)}),Z.map(t=>{let i=r(qn[t]);return(0,$.jsx)(H,{className:`w-24 bg-muted`,children:(0,$.jsxs)(`span`,{className:`flex items-center justify-center gap-2`,children:[(0,$.jsx)(Ee,{checked:tr(e,c,t),onCheckedChange:r=>n(er(e,c,t,r===!0)),"aria-label":r(`appRoles.everyRow`,{action:i})}),i]})},t)}),(0,$.jsx)(H,{className:`bg-muted`,children:(0,$.jsx)(`span`,{className:`sr-only`,children:r(`appRoles.options`)})})]})}),(0,$.jsx)(U,{children:s.map(t=>{let r=e[t.key]??{},a=$n(t.key,r),s=a&&i.has(t.key),c=`app-role-options-${t.key===`*`?`all`:t.key}`;return(0,$.jsxs)(Q.Fragment,{children:[(0,$.jsx)(sr,{label:t.label,detail:t.detail,grants:r,optionsId:c,expanded:s,canExpand:a,onToggle:(r,i)=>n(Zn(e,t.key,r,i)),onToggleExpanded:()=>o(t.key)}),s?(0,$.jsx)(W,{className:`hover:bg-transparent`,children:(0,$.jsx)(G,{colSpan:Z.length+2,className:`h-auto p-0 whitespace-normal`,children:(0,$.jsx)(or,{id:c,rowKey:t.key,fields:t.fields,grants:r,onChange:(r,i)=>n(Qn(e,t.key,r,i))})})}):null]},t.key)})})]})},lr={public:`appRoles.publicExplained`,authenticated:`appRoles.authenticatedExplained`},ur=e=>Object.hasOwn(lr,e)?lr[e]:void 0,dr=({role:e,models:t})=>{let{t:n}=l(),r=rr(e),i=e.isSystem?ur(e.key):void 0,a=[{label:n(`roles.title`),link:te({to:`/network/roles`})},{label:n(`appRoles.title`),link:te({to:`/network/roles/app`})}];return(0,$.jsxs)(`form`,{noValidate:!0,className:`space-y-6`,onSubmit:e=>void r.onSubmit(e),children:[(0,$.jsx)(g,{sticky:!0,breadcrumb:a,title:e.name,badge:e.isSystem?(0,$.jsx)(v,{variant:`secondary`,children:n(`roles.builtIn`)}):null,meta:i?n(i):e.description||void 0,actions:(0,$.jsx)(ie,{pending:r.pending,pendingLabel:n(`common.saving`),disabled:!r.dirty,children:n(`common.saveChanges`)})}),e.isSystem?null:(0,$.jsx)(Y,{title:n(`appRoles.details`),children:(0,$.jsxs)(me,{className:`max-w-xl`,children:[(0,$.jsx)(P,{control:r.form.control,name:`name`,label:n(`roles.name`),autoComplete:`off`}),(0,$.jsx)(gt,{control:r.form.control,name:`description`,label:n(`roles.roleDescription`),rows:2})]})}),(0,$.jsx)(Y,{title:n(`roles.permissions`),description:n(`appRoles.permissionsHint`),flush:!0,children:(0,$.jsx)(cr,{matrix:r.matrix,models:t,onChange:r.setMatrix})}),(0,$.jsx)(A,{error:r.error}),(0,$.jsx)(le,{when:r.dirty&&!r.pending})]})},fr=()=>{let{roleId:e}=ae({from:`/app/network/roles/app/$roleId`}),t=Ie(e),n=pt(`model`);return(0,$.jsx)(h,{width:`full`,children:(0,$.jsx)(J,{query:t,loadingRows:6,children:e=>(0,$.jsx)(J,{query:n,loadingRows:6,children:t=>(0,$.jsx)(dr,{role:e,models:t},`${e.id}:${e.version}`)})})})},pr=()=>{let{t:e}=l(),t=k().data?.emailDelivery,n=Ct(),[r,i]=(0,Q.useState)(void 0),a=async({id:e,email:t})=>{let r=await n.mutateAsync(e);i({...r,email:t})};return{revealed:r,emailDelivery:t,reveal:a,announceInvitation:async n=>{if(t===`console`){await a(n);return}w.success(e(`users.invited`,{email:n.email}),{action:{label:e(`users.copyLink`),onClick:()=>void R(a(n))}})},dismiss:()=>i(void 0),keepFocusOnReveal:e=>{r&&e.preventDefault()}}},mr=({link:e,emailDelivery:t,onDismiss:n})=>{let{t:r}=l(),i=b(e.expiresAt);return(0,$.jsx)(jt,{title:r(`users.invitationLink.title`,{email:e.email}),description:r(t===`console`?`users.invitationLink.noEmailDescription`:`users.invitationLink.description`,{date:i}),label:r(`users.invitationLink.label`),secret:e.acceptUrl,dismissLabel:r(`users.invitationLink.done`),onDismiss:n})},hr=({assignments:e,roleNames:t,siteNames:n})=>{let{t:r}=l(),i=n.size>1;return e.map(({roleId:e,siteId:a})=>{let o=t.get(e)??r(`common.unknown`),s=a===null?r(`sites.switcher.allSites`):n.get(a)??r(`common.unknown`);return(0,$.jsx)(v,{variant:`outline`,children:i?r(`users.access.badge`,{role:o,site:s}):o},`${e}:${a??``}`)})},gr=({siteNames:e,onCopyLink:t,onCloseAutoFocus:n})=>{let{t:r}=l(),i=Tt(),{names:a}=Dt(),o=vt();return i.isError?(0,$.jsx)(se,{error:i.error,onRetry:()=>void i.refetch()}):!i.data||i.data.length===0?null:(0,$.jsx)(Y,{title:r(`users.invitationsTitle`),flush:!0,children:(0,$.jsxs)(q,{children:[(0,$.jsx)(B,{children:(0,$.jsxs)(W,{children:[(0,$.jsx)(H,{children:r(`users.email`)}),(0,$.jsx)(H,{children:r(`users.roles`)}),(0,$.jsx)(H,{children:r(`users.invitationExpires`)}),(0,$.jsx)(H,{children:(0,$.jsx)(`span`,{className:`sr-only`,children:r(`common.actions`)})})]})}),(0,$.jsx)(U,{children:i.data.map(i=>(0,$.jsxs)(W,{children:[(0,$.jsx)(G,{children:(0,$.jsx)(x,{children:i.email})}),(0,$.jsx)(G,{children:(0,$.jsx)(`span`,{className:`flex flex-wrap gap-1`,children:(0,$.jsx)(hr,{assignments:i.assignments,roleNames:a,siteNames:e})})}),(0,$.jsx)(G,{title:b(i.expiresAt),children:y(i.expiresAt)}),(0,$.jsx)(G,{children:(0,$.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,$.jsx)(j,{tone:`default`,title:r(`users.invitationLink.confirmTitle`,{email:i.email}),description:r(`users.invitationLink.confirmDescription`),confirmLabel:r(`users.invitationLink.create`),onConfirm:()=>t(i),onCloseAutoFocus:n,trigger:(0,$.jsxs)(O,{variant:`outline`,size:`sm`,"aria-label":`${r(`users.copyLink`)}: ${i.email}`,children:[(0,$.jsx)(Ve,{"aria-hidden":`true`}),r(`users.copyLink`)]})}),(0,$.jsx)(j,{tone:`danger`,title:r(`users.revokeInvitationTitle`,{email:i.email}),description:r(`users.revokeInvitationDescription`),confirmLabel:r(`common.revoke`),onConfirm:async()=>{await o.mutateAsync(i.id),w.success(r(`users.invitationRevoked`))},trigger:(0,$.jsx)(O,{variant:`outline`,size:`sm`,"aria-label":`${r(`common.revoke`)}: ${i.email}`,children:r(`common.revoke`)})})]})})]},i.id))})]})})},_r=e=>e??`all`,vr=(e,t)=>{let n=new Map;for(let{roleId:r,siteId:i}of e){let e=_r(i);(!n.has(e)||r===t)&&n.set(e,r)}return[...n].map(([e,t])=>({site:e,roleId:t}))},yr=e=>e.map(({site:e,roleId:t})=>({roleId:t,siteId:e===`all`?null:e})),br=e=>dt(V({site:z().min(1),roleId:z().min(1,`validation.selectRole`)})).min(1).superRefine((t,n)=>{let r=new Set;t.forEach((t,i)=>{r.has(t.site)&&n.addIssue({code:`custom`,path:[i,`site`],message:`validation.siteTwice`}),r.add(t.site),e!==void 0&&t.roleId===e&&t.site!==`all`&&n.addIssue({code:`custom`,path:[i,`roleId`],message:`validation.ownerAllSites`})})}),xr=(e,t,n)=>{let r=new Set(e.map(e=>e.site)),i=[`all`,...t].find(e=>!r.has(e));return i===void 0?void 0:{site:i,roleId:n}},Sr=({control:e,roleOptions:t,siteOptions:n,siteIds:r,multiSite:i,defaultRoleId:a})=>{let{t:o}=l(),{fields:s,append:c,remove:u}=st({control:e,name:`rows`}),{errors:d}=it({control:e,name:`rows`}),f=at({control:e,name:`rows`}),p=(e,t)=>`rows.${e}.${t}`;if(!i)return(0,$.jsx)(mt,{control:e,name:p(0,`roleId`),legend:o(`users.role`),options:t});let ee=xr(f??[],r,a??``),m=d.rows;return(0,$.jsxs)(pe,{children:[(0,$.jsx)(fe,{variant:`label`,children:o(`users.access.title`)}),(0,$.jsx)(`div`,{className:`space-y-3`,children:s.map((r,i)=>(0,$.jsxs)(`fieldset`,{"aria-label":o(`users.access.row`,{n:i+1}),className:`grid grid-cols-[1fr_1fr_auto] items-start gap-3`,children:[(0,$.jsx)(_t,{control:e,name:p(i,`site`),label:o(`users.access.site`),options:n}),(0,$.jsx)(_t,{control:e,name:p(i,`roleId`),label:o(`users.role`),options:t}),(0,$.jsx)(O,{type:`button`,variant:`ghost`,size:`icon`,className:`mt-7`,disabled:s.length===1,"aria-label":o(`users.access.remove`,{n:i+1}),onClick:()=>u(i),children:(0,$.jsx)(re,{"aria-hidden":`true`})})]},r.id))}),(0,$.jsx)(ct,{message:m?.root?.message??m?.message}),(0,$.jsx)(`div`,{children:(0,$.jsxs)(O,{type:`button`,variant:`outline`,size:`sm`,disabled:!ee,onClick:()=>ee&&c(ee),children:[(0,$.jsx)(M,{"aria-hidden":`true`}),o(`users.access.add`)]})})]})},Cr={owner:`owner`,editor:`editor`},wr=({includeOwner:e,heldRoleIds:t=[]})=>{let n=Et(),r=(n.data??[]).filter(e=>e.kind===`admin`),i=e=>e===Cr.owner;return{options:r.filter(n=>!i(n.key)||e||t.includes(n.id)).map(e=>({value:e.id,label:e.name,...e.description?{description:e.description}:{}})),editorRoleId:r.find(e=>e.key===Cr.editor)?.id,ownerRoleId:r.find(e=>i(e.key))?.id,isPending:n.isPending,error:n.error}},Tr=({includeOwner:e,heldRoleIds:t})=>{let{t:n}=l(),r=wr({includeOwner:e,...t?{heldRoleIds:t}:{}}),i=Vt(),a=(0,Q.useMemo)(()=>[{value:`all`,label:n(`sites.switcher.allSites`)},...(i.data??[]).map(e=>({value:e.id,label:e.name}))],[i.data,n]),o=(0,Q.useMemo)(()=>(i.data??[]).map(e=>e.id),[i.data]);return{roleOptions:r.options,siteOptions:a,siteIds:o,multiSite:o.length>1,editorRoleId:r.editorRoleId,ownerRoleId:r.ownerRoleId,error:r.error??i.error}},Er=e=>({email:``,rows:[{site:`all`,roleId:e}]}),Dr=({open:e,defaultRoleId:t,ownerRoleId:n,onInvited:r,onDone:i})=>{let a=xt(),o=(0,Q.useMemo)(()=>V({email:ot(),rows:br(n)}),[n]),s=L({resolver:I(o),defaultValues:Er(``)}),{reset:c}=s;return(0,Q.useEffect)(()=>{e&&c(Er(t??``))},[e,t,c]),{form:s,onSubmit:s.handleSubmit(async({email:e,rows:n})=>{let o=await R(a.mutateAsync({email:e,assignments:yr(n)}));o.ok&&(await R(r(o.value)),c(Er(t??``)),i())}),invite:a}},Or=({open:e,onOpenChange:t,onInvited:n,onCloseAutoFocus:r})=>{let{t:i}=l(),a=Tr({includeOwner:!1}),{form:o,onSubmit:s,invite:c}=Dr({open:e,defaultRoleId:a.editorRoleId,ownerRoleId:a.ownerRoleId,onInvited:n,onDone:()=>t(!1)});return(0,$.jsxs)(X,{open:e,onOpenChange:t,size:`md`,title:i(`users.inviteTitle`),dirty:o.formState.isDirty,pending:o.formState.isSubmitting,submitLabel:i(`users.invite`),pendingLabel:i(`common.saving`),onSubmit:e=>void s(e),onCloseAutoFocus:r,children:[(0,$.jsx)(P,{control:o.control,name:`email`,label:i(`users.email`),type:`email`,autoComplete:`off`}),(0,$.jsx)(Sr,{control:o.control,roleOptions:a.roleOptions,siteOptions:a.siteOptions,siteIds:a.siteIds,multiSite:a.multiSite,defaultRoleId:a.editorRoleId}),(0,$.jsx)(A,{error:c.error??a.error})]})},kr=(e,t,n,r)=>{let i=wt(),a=(0,Q.useMemo)(()=>V({rows:br(n)}),[n]),o=L({resolver:I(a),defaultValues:{rows:[]}}),{reset:s}=o;return(0,Q.useEffect)(()=>{e&&s({rows:vr(t.assignments,n)})},[e,t.assignments,n,s]),{form:o,onSubmit:o.handleSubmit(async({rows:e})=>{(await R(i.mutateAsync({id:t.id,input:{assignments:yr(e)}}))).ok&&(w.success(D.t(`users.rolesSaved`)),r())}),updateUser:i}},Ar=()=>k().data?.roles.some(e=>e.key===Cr.owner)??!1,jr=({open:e,onOpenChange:t,user:n})=>{let{t:r}=l(),i=Tr({includeOwner:Ar(),heldRoleIds:n.assignments.map(e=>e.roleId)}),{form:a,onSubmit:o,updateUser:s}=kr(e,n,i.ownerRoleId,()=>t(!1));return(0,$.jsxs)(X,{open:e,onOpenChange:t,size:`md`,title:r(`users.accessTitle`,{name:n.name||n.email}),dirty:a.formState.isDirty,pending:s.isPending,submitLabel:r(`common.saveChanges`),pendingLabel:r(`common.saving`),onSubmit:e=>void o(e),children:[(0,$.jsx)(Sr,{control:a.control,roleOptions:i.roleOptions,siteOptions:i.siteOptions,siteIds:i.siteIds,multiSite:i.multiSite,defaultRoleId:i.editorRoleId}),(0,$.jsx)(A,{error:s.error??i.error})]})},Mr=({user:e,roleNames:t,siteNames:n,isSelf:r,onToggleStatus:i,onRemove:a})=>{let{t:o}=l(),[s,c]=(0,Q.useState)(void 0),[u,d]=(0,Q.useState)(!1),f=e.name||e.email;return(0,$.jsxs)(W,{children:[(0,$.jsx)(G,{children:(0,$.jsx)(Ne,{name:f,email:e.email,badge:r?(0,$.jsx)(v,{variant:`secondary`,children:o(`users.you`)}):null})}),(0,$.jsxs)(G,{children:[(0,$.jsx)(`span`,{className:`flex flex-wrap gap-1`,children:(0,$.jsx)(hr,{assignments:e.assignments,roleNames:t,siteNames:n})}),s===void 0?null:(0,$.jsx)(jr,{open:s,onOpenChange:c,user:e})]}),(0,$.jsx)(G,{children:e.status===`active`?(0,$.jsx)(oe,{tone:`success`,label:o(`users.active`)}):(0,$.jsx)(oe,{tone:`muted`,label:o(`users.disabled`)})}),(0,$.jsx)(G,{title:b(e.lastLoginAt)||void 0,children:e.lastLoginAt?y(e.lastLoginAt):o(`common.never`)}),(0,$.jsx)(G,{className:`text-right`,children:r?null:(0,$.jsxs)(et,{children:[(0,$.jsx)(j,{tone:`danger`,open:u,onOpenChange:d,title:o(`users.removeTitle`,{name:f}),description:o(`users.removeDescription`),confirmLabel:o(`common.remove`),onConfirm:()=>a(e),children:(0,$.jsx)(Qe,{asChild:!0,children:(0,$.jsx)(O,{variant:`ghost`,size:`icon-sm`,"aria-label":`${o(`common.actions`)}: ${f}`,children:(0,$.jsx)(Be,{"aria-hidden":`true`})})})}),(0,$.jsxs)($e,{align:`end`,onCloseAutoFocus:e=>(u||s)&&e.preventDefault(),children:[(0,$.jsxs)(N,{onSelect:()=>c(!0),children:[(0,$.jsx)(Re,{"aria-hidden":`true`}),o(`users.editAccess`)]}),(0,$.jsxs)(N,{onSelect:()=>i(e),children:[e.status===`active`?(0,$.jsx)(ze,{"aria-hidden":`true`}):(0,$.jsx)(je,{"aria-hidden":`true`}),e.status===`active`?o(`users.disable`):o(`users.enable`)]}),(0,$.jsx)(Ze,{}),(0,$.jsxs)(N,{variant:`destructive`,onSelect:()=>d(!0),children:[(0,$.jsx)(de,{"aria-hidden":`true`}),o(`common.remove`)]})]})]})})]})},Nr=({users:e,roleNames:t,siteNames:n,currentUserId:r,onToggleStatus:i,onRemove:a})=>{let{t:o}=l();return(0,$.jsx)(K,{children:(0,$.jsxs)(q,{children:[(0,$.jsx)(B,{children:(0,$.jsxs)(W,{children:[(0,$.jsx)(H,{children:o(`users.name`)}),(0,$.jsx)(H,{children:o(`users.roles`)}),(0,$.jsx)(H,{children:o(`users.status`)}),(0,$.jsx)(H,{children:o(`users.lastLogin`)}),(0,$.jsx)(H,{children:(0,$.jsx)(`span`,{className:`sr-only`,children:o(`common.actions`)})})]})}),(0,$.jsx)(U,{children:e.map(e=>(0,$.jsx)(Mr,{user:e,roleNames:t,siteNames:n,isSelf:e.id===r,onToggleStatus:i,onRemove:a},e.id))})]})})},Pr={sites:S(`/app/network/sites`)({component:fn}),site:S(`/app/network/sites/$siteId`)({component:on}),users:S(`/app/network/users`)({component:()=>{let{t:e}=l(),{data:t}=k(),n=yt(),{names:r}=Dt(),{names:i}=Ut(),a=St(),o=bt(),[s,c]=(0,Q.useState)(!1),u=pr(),d=async t=>{await o.mutateAsync(t.id),w.success(e(`users.removed`))};return(0,$.jsxs)(h,{children:[(0,$.jsx)(g,{title:e(`users.title`),actions:(0,$.jsxs)(O,{onClick:()=>c(!0),children:[(0,$.jsx)(Ge,{"aria-hidden":`true`}),e(`users.invite`)]})}),(0,$.jsx)(J,{query:n,isEmpty:e=>e.length===0,empty:(0,$.jsx)(_,{icon:Ye,title:e(`users.empty`)}),children:n=>(0,$.jsx)(Nr,{users:n,roleNames:r,siteNames:i,currentUserId:t?.user.id,onToggleStatus:t=>a.mutate({id:t.id,status:t.status===`active`?`disabled`:`active`},{onSuccess:()=>w.success(e(`users.statusChanged`))}),onRemove:d})}),u.revealed?(0,$.jsx)(mr,{link:u.revealed,emailDelivery:u.emailDelivery,onDismiss:u.dismiss},u.revealed.acceptUrl):null,(0,$.jsx)(gr,{siteNames:i,onCopyLink:u.reveal,onCloseAutoFocus:u.keepFocusOnReveal}),(0,$.jsx)(Or,{open:s,onOpenChange:c,onInvited:u.announceInvitation,onCloseAutoFocus:u.keepFocusOnReveal})]})}}),roles:S(`/app/network/roles`)({component:Nn}),appRoles:S(`/app/network/roles/app`)({component:Wn}),appRole:S(`/app/network/roles/app/$roleId`)({component:fr}),auditLog:S(`/app/network/audit-log`)({component:yn})};export{Pr as networkLazyRoutes};
|
|
2
|
+
//# sourceMappingURL=network-CAJ76ILr.js.map
|