@strapi/upload 5.51.2 → 5.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/future/App.js +3 -3
- package/dist/admin/future/App.js.map +1 -1
- package/dist/admin/future/App.mjs +4 -4
- package/dist/admin/future/App.mjs.map +1 -1
- package/dist/admin/future/components/BetaNotice.js +72 -0
- package/dist/admin/future/components/BetaNotice.js.map +1 -0
- package/dist/admin/future/components/BetaNotice.mjs +70 -0
- package/dist/admin/future/components/BetaNotice.mjs.map +1 -0
- package/dist/admin/future/components/Drawer.js +16 -3
- package/dist/admin/future/components/Drawer.js.map +1 -1
- package/dist/admin/future/components/Drawer.mjs +16 -3
- package/dist/admin/future/components/Drawer.mjs.map +1 -1
- package/dist/admin/future/hooks/useAIMetadataEnabled.js +39 -0
- package/dist/admin/future/hooks/useAIMetadataEnabled.js.map +1 -0
- package/dist/admin/future/hooks/useAIMetadataEnabled.mjs +37 -0
- package/dist/admin/future/hooks/useAIMetadataEnabled.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/AssetsPage.js +297 -139
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +301 -143
- package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js +46 -0
- package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs +44 -0
- package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +325 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +323 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +35 -14
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +35 -14
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +54 -53
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +54 -54
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js +89 -24
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +91 -26
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +15 -3
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +16 -4
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.js +168 -58
- package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +171 -61
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +64 -132
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +64 -132
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +123 -76
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +126 -79
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/BusyOverlay.js +36 -0
- package/dist/admin/future/pages/Assets/components/BusyOverlay.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs +34 -0
- package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js +131 -0
- package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs +129 -0
- package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +27 -17
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +28 -18
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js +28 -31
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs +28 -31
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +10 -15
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs +10 -15
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterBadges.js +13 -4
- package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +13 -4
- package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterMenu.js +241 -61
- package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +244 -64
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +144 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +142 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.js → FolderFormDialog.js} +50 -16
- package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.mjs → FolderFormDialog.mjs} +52 -18
- package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +111 -191
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +114 -194
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js +47 -0
- package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs +44 -0
- package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +203 -62
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +204 -63
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js +75 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs +73 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs.map +1 -0
- package/dist/admin/future/services/api.js +24 -0
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +24 -0
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/services/assets.js +11 -0
- package/dist/admin/future/services/assets.js.map +1 -1
- package/dist/admin/future/services/assets.mjs +11 -0
- package/dist/admin/future/services/assets.mjs.map +1 -1
- package/dist/admin/future/services/folders.js +37 -2
- package/dist/admin/future/services/folders.js.map +1 -1
- package/dist/admin/future/services/folders.mjs +37 -3
- package/dist/admin/future/services/folders.mjs.map +1 -1
- package/dist/admin/future/utils/buildDragSetFromSelection.js +7 -5
- package/dist/admin/future/utils/buildDragSetFromSelection.js.map +1 -1
- package/dist/admin/future/utils/buildDragSetFromSelection.mjs +7 -5
- package/dist/admin/future/utils/buildDragSetFromSelection.mjs.map +1 -1
- package/dist/admin/future/utils/formatMoveSuccessMessage.js +12 -1
- package/dist/admin/future/utils/formatMoveSuccessMessage.js.map +1 -1
- package/dist/admin/future/utils/formatMoveSuccessMessage.mjs +12 -1
- package/dist/admin/future/utils/formatMoveSuccessMessage.mjs.map +1 -1
- package/dist/admin/future/utils/getRelationId.js +24 -0
- package/dist/admin/future/utils/getRelationId.js.map +1 -0
- package/dist/admin/future/utils/getRelationId.mjs +22 -0
- package/dist/admin/future/utils/getRelationId.mjs.map +1 -0
- package/dist/admin/future/utils/isEventFromWithin.js +14 -0
- package/dist/admin/future/utils/isEventFromWithin.js.map +1 -0
- package/dist/admin/future/utils/isEventFromWithin.mjs +12 -0
- package/dist/admin/future/utils/isEventFromWithin.mjs.map +1 -0
- package/dist/admin/future/utils/itemLocations.js +40 -0
- package/dist/admin/future/utils/itemLocations.js.map +1 -0
- package/dist/admin/future/utils/itemLocations.mjs +36 -0
- package/dist/admin/future/utils/itemLocations.mjs.map +1 -0
- package/dist/admin/future/utils/itemSource.js +36 -0
- package/dist/admin/future/utils/itemSource.js.map +1 -0
- package/dist/admin/future/utils/itemSource.mjs +32 -0
- package/dist/admin/future/utils/itemSource.mjs.map +1 -0
- package/dist/admin/index.js +11 -17
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +12 -18
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/src/future/App.d.ts +1 -1
- package/dist/admin/src/future/components/BetaNotice.d.ts +11 -0
- package/dist/admin/src/future/components/Drawer.d.ts +5 -1
- package/dist/admin/src/future/hooks/useAIMetadataEnabled.d.ts +26 -0
- package/dist/admin/src/future/pages/Assets/components/ActionsMenuContent.d.ts +33 -0
- package/dist/admin/src/future/pages/Assets/components/AssetActionsMenu.d.ts +24 -0
- package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +16 -0
- package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +8 -1
- package/dist/admin/src/future/pages/Assets/components/BulkMoveDialog.d.ts +17 -6
- package/dist/admin/src/future/pages/Assets/components/BusyOverlay.d.ts +9 -0
- package/dist/admin/src/future/pages/Assets/components/DeleteItemsDialog.d.ts +27 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +8 -1
- package/dist/admin/src/future/pages/Assets/components/Dnd/buildDragSet.d.ts +18 -3
- package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +2 -1
- package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +3 -1
- package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +4 -0
- package/dist/admin/src/future/pages/Assets/components/FolderActionsMenu.d.ts +20 -0
- package/dist/admin/src/future/pages/Assets/components/FolderFormDialog.d.ts +16 -0
- package/dist/admin/src/future/pages/Assets/hooks/useBusyAssets.d.ts +38 -0
- package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +20 -6
- package/dist/admin/src/future/pages/Assets/hooks/useInfiniteScrollSentinel.d.ts +41 -0
- package/dist/admin/src/future/services/folders.d.ts +6 -1
- package/dist/admin/src/future/utils/buildDragSetFromSelection.d.ts +4 -3
- package/dist/admin/src/future/utils/formatMoveSuccessMessage.d.ts +7 -1
- package/dist/admin/src/future/utils/getRelationId.d.ts +11 -0
- package/dist/admin/src/future/utils/isEventFromWithin.d.ts +11 -0
- package/dist/admin/src/future/utils/itemLocations.d.ts +31 -0
- package/dist/admin/src/future/utils/itemSource.d.ts +22 -0
- package/dist/admin/translations/en.json.js +25 -4
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +25 -4
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/server/services/image-manipulation.js.map +1 -1
- package/dist/server/services/image-manipulation.mjs.map +1 -1
- package/dist/server/src/services/image-manipulation.d.ts +0 -5
- package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
- package/package.json +9 -9
- package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js.map +0 -1
- package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs.map +0 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js +0 -33
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js.map +0 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs +0 -31
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs.map +0 -1
- package/dist/admin/src/future/pages/Assets/components/CreateFolderDialog.d.ts +0 -8
- package/dist/admin/src/future/pages/Assets/components/FolderTree/filterFolderTree.d.ts +0 -16
package/dist/admin/future/App.js
CHANGED
|
@@ -8,13 +8,13 @@ var reactRouterDom = require('react-router-dom');
|
|
|
8
8
|
var AssetsPage = require('./pages/Assets/AssetsPage.js');
|
|
9
9
|
var translations = require('./utils/translations.js');
|
|
10
10
|
|
|
11
|
-
const
|
|
11
|
+
const BetaMediaLibrary = ()=>{
|
|
12
12
|
const { formatMessage } = reactIntl.useIntl();
|
|
13
13
|
const title = formatMessage({
|
|
14
14
|
id: translations.getTranslationKey('plugin.name'),
|
|
15
15
|
defaultMessage: 'Media Library'
|
|
16
16
|
});
|
|
17
|
-
return /*#__PURE__*/ jsxRuntime.jsxs(
|
|
17
|
+
return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
18
18
|
children: [
|
|
19
19
|
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Page.Title, {
|
|
20
20
|
children: title
|
|
@@ -29,5 +29,5 @@ const UnstableMediaLibrary = ()=>{
|
|
|
29
29
|
});
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
exports.
|
|
32
|
+
exports.BetaMediaLibrary = BetaMediaLibrary;
|
|
33
33
|
//# sourceMappingURL=App.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.js","sources":["../../../admin/src/future/App.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Page } from '@strapi/admin/strapi-admin';\nimport { useIntl } from 'react-intl';\nimport { Route, Routes } from 'react-router-dom';\n\nimport { AssetsPage } from './pages/Assets/AssetsPage';\nimport { getTranslationKey } from './utils/translations';\n\nexport const
|
|
1
|
+
{"version":3,"file":"App.js","sources":["../../../admin/src/future/App.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Page } from '@strapi/admin/strapi-admin';\nimport { useIntl } from 'react-intl';\nimport { Route, Routes } from 'react-router-dom';\n\nimport { AssetsPage } from './pages/Assets/AssetsPage';\nimport { getTranslationKey } from './utils/translations';\n\nexport const BetaMediaLibrary = () => {\n const { formatMessage } = useIntl();\n\n const title = formatMessage({\n id: getTranslationKey('plugin.name'),\n defaultMessage: 'Media Library',\n });\n\n return (\n <>\n <Page.Title>{title}</Page.Title>\n\n <Routes>\n <Route index element={<AssetsPage />} />\n </Routes>\n </>\n );\n};\n"],"names":["BetaMediaLibrary","formatMessage","useIntl","title","id","getTranslationKey","defaultMessage","_jsxs","_Fragment","_jsx","Page","Title","Routes","Route","index","element","AssetsPage"],"mappings":";;;;;;;;;;MASaA,gBAAAA,GAAmB,IAAA;IAC9B,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAE1B,IAAA,MAAMC,QAAQF,aAAAA,CAAc;AAC1BG,QAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,aAAA,CAAA;QACtBC,cAAAA,EAAgB;AAClB,KAAA,CAAA;IAEA,qBACEC,eAAA,CAAAC,mBAAA,EAAA;;AACE,0BAAAC,cAAA,CAACC,iBAAKC,KAAK,EAAA;AAAER,gBAAAA,QAAAA,EAAAA;;0BAEbM,cAAA,CAACG,qBAAAA,EAAAA;AACC,gBAAA,QAAA,gBAAAH,cAAA,CAACI,oBAAAA,EAAAA;oBAAMC,KAAK,EAAA,IAAA;AAACC,oBAAAA,OAAAA,gBAASN,cAAA,CAACO,qBAAAA,EAAAA,EAAAA;;;;;AAI/B;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import 'react';
|
|
3
3
|
import { Page } from '@strapi/admin/strapi-admin';
|
|
4
4
|
import { useIntl } from 'react-intl';
|
|
@@ -6,13 +6,13 @@ import { Routes, Route } from 'react-router-dom';
|
|
|
6
6
|
import { AssetsPage } from './pages/Assets/AssetsPage.mjs';
|
|
7
7
|
import { getTranslationKey } from './utils/translations.mjs';
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
const BetaMediaLibrary = ()=>{
|
|
10
10
|
const { formatMessage } = useIntl();
|
|
11
11
|
const title = formatMessage({
|
|
12
12
|
id: getTranslationKey('plugin.name'),
|
|
13
13
|
defaultMessage: 'Media Library'
|
|
14
14
|
});
|
|
15
|
-
return /*#__PURE__*/ jsxs(
|
|
15
|
+
return /*#__PURE__*/ jsxs(Fragment, {
|
|
16
16
|
children: [
|
|
17
17
|
/*#__PURE__*/ jsx(Page.Title, {
|
|
18
18
|
children: title
|
|
@@ -27,5 +27,5 @@ const UnstableMediaLibrary = ()=>{
|
|
|
27
27
|
});
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
export {
|
|
30
|
+
export { BetaMediaLibrary };
|
|
31
31
|
//# sourceMappingURL=App.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.mjs","sources":["../../../admin/src/future/App.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Page } from '@strapi/admin/strapi-admin';\nimport { useIntl } from 'react-intl';\nimport { Route, Routes } from 'react-router-dom';\n\nimport { AssetsPage } from './pages/Assets/AssetsPage';\nimport { getTranslationKey } from './utils/translations';\n\nexport const
|
|
1
|
+
{"version":3,"file":"App.mjs","sources":["../../../admin/src/future/App.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Page } from '@strapi/admin/strapi-admin';\nimport { useIntl } from 'react-intl';\nimport { Route, Routes } from 'react-router-dom';\n\nimport { AssetsPage } from './pages/Assets/AssetsPage';\nimport { getTranslationKey } from './utils/translations';\n\nexport const BetaMediaLibrary = () => {\n const { formatMessage } = useIntl();\n\n const title = formatMessage({\n id: getTranslationKey('plugin.name'),\n defaultMessage: 'Media Library',\n });\n\n return (\n <>\n <Page.Title>{title}</Page.Title>\n\n <Routes>\n <Route index element={<AssetsPage />} />\n </Routes>\n </>\n );\n};\n"],"names":["BetaMediaLibrary","formatMessage","useIntl","title","id","getTranslationKey","defaultMessage","_jsxs","_Fragment","_jsx","Page","Title","Routes","Route","index","element","AssetsPage"],"mappings":";;;;;;;;MASaA,gBAAAA,GAAmB,IAAA;IAC9B,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAE1B,IAAA,MAAMC,QAAQF,aAAAA,CAAc;AAC1BG,QAAAA,EAAAA,EAAIC,iBAAAA,CAAkB,aAAA,CAAA;QACtBC,cAAAA,EAAgB;AAClB,KAAA,CAAA;IAEA,qBACEC,IAAA,CAAAC,QAAA,EAAA;;AACE,0BAAAC,GAAA,CAACC,KAAKC,KAAK,EAAA;AAAER,gBAAAA,QAAAA,EAAAA;;0BAEbM,GAAA,CAACG,MAAAA,EAAAA;AACC,gBAAA,QAAA,gBAAAH,GAAA,CAACI,KAAAA,EAAAA;oBAAMC,KAAK,EAAA,IAAA;AAACC,oBAAAA,OAAAA,gBAASN,GAAA,CAACO,UAAAA,EAAAA,EAAAA;;;;;AAI/B;;;;"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var strapiAdmin = require('@strapi/admin/strapi-admin');
|
|
5
|
+
var designSystem = require('@strapi/design-system');
|
|
6
|
+
var reactIntl = require('react-intl');
|
|
7
|
+
var translations = require('../utils/translations.js');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The beta indicator is a notice rather than a badge on the page header: that
|
|
11
|
+
* header's title follows the folder you are in, so a badge attached to it would
|
|
12
|
+
* read as "this folder is beta". This notice covers the whole Media Library, and
|
|
13
|
+
* stays dismissed once a tester has read it.
|
|
14
|
+
*
|
|
15
|
+
* It renders inside `Layouts.Content` so it picks up the content column's gutter.
|
|
16
|
+
* Rendered above the layout instead, it would span the full viewport width and
|
|
17
|
+
* sit over the folder sidebar.
|
|
18
|
+
*/ const BetaNotice = ()=>{
|
|
19
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
20
|
+
const [isBetaNoticeDismissed, setIsBetaNoticeDismissed] = strapiAdmin.usePersistentState('STRAPI_UPLOAD_LIBRARY_BETA_NOTICE_DISMISSED', false);
|
|
21
|
+
if (isBetaNoticeDismissed) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
|
|
25
|
+
paddingBottom: 4,
|
|
26
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Alert, {
|
|
27
|
+
variant: "default",
|
|
28
|
+
onClose: ()=>setIsBetaNoticeDismissed(true),
|
|
29
|
+
closeLabel: formatMessage({
|
|
30
|
+
id: translations.getTranslationKey('beta.notice.close'),
|
|
31
|
+
defaultMessage: 'Close'
|
|
32
|
+
}),
|
|
33
|
+
title: formatMessage({
|
|
34
|
+
id: translations.getTranslationKey('plugin.name'),
|
|
35
|
+
defaultMessage: 'Media Library'
|
|
36
|
+
}),
|
|
37
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
|
|
38
|
+
tag: "span",
|
|
39
|
+
gap: 2,
|
|
40
|
+
alignItems: "center",
|
|
41
|
+
children: [
|
|
42
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
|
|
43
|
+
tag: "span",
|
|
44
|
+
background: "neutral150",
|
|
45
|
+
hasRadius: true,
|
|
46
|
+
paddingLeft: 2,
|
|
47
|
+
paddingRight: 2,
|
|
48
|
+
shrink: 0,
|
|
49
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
50
|
+
variant: "sigma",
|
|
51
|
+
textColor: "neutral600",
|
|
52
|
+
children: formatMessage({
|
|
53
|
+
id: translations.getTranslationKey('beta.badge'),
|
|
54
|
+
defaultMessage: 'Beta'
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
}),
|
|
58
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
59
|
+
tag: "span",
|
|
60
|
+
children: formatMessage({
|
|
61
|
+
id: translations.getTranslationKey('beta.notice.content'),
|
|
62
|
+
defaultMessage: 'This is a beta version of the Media Library. Some features are still in progress — please report any issue you run into.'
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
]
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
exports.BetaNotice = BetaNotice;
|
|
72
|
+
//# sourceMappingURL=BetaNotice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BetaNotice.js","sources":["../../../../admin/src/future/components/BetaNotice.tsx"],"sourcesContent":["import { usePersistentState } from '@strapi/admin/strapi-admin';\nimport { Alert, Box, Flex, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { getTranslationKey } from '../utils/translations';\n\n/**\n * The beta indicator is a notice rather than a badge on the page header: that\n * header's title follows the folder you are in, so a badge attached to it would\n * read as \"this folder is beta\". This notice covers the whole Media Library, and\n * stays dismissed once a tester has read it.\n *\n * It renders inside `Layouts.Content` so it picks up the content column's gutter.\n * Rendered above the layout instead, it would span the full viewport width and\n * sit over the folder sidebar.\n */\nexport const BetaNotice = () => {\n const { formatMessage } = useIntl();\n const [isBetaNoticeDismissed, setIsBetaNoticeDismissed] = usePersistentState(\n 'STRAPI_UPLOAD_LIBRARY_BETA_NOTICE_DISMISSED',\n false\n );\n\n if (isBetaNoticeDismissed) {\n return null;\n }\n\n return (\n <Box paddingBottom={4}>\n <Alert\n variant=\"default\"\n onClose={() => setIsBetaNoticeDismissed(true)}\n closeLabel={formatMessage({\n id: getTranslationKey('beta.notice.close'),\n defaultMessage: 'Close',\n })}\n title={formatMessage({\n id: getTranslationKey('plugin.name'),\n defaultMessage: 'Media Library',\n })}\n >\n {/* `Alert` renders its children inside a `<p>`, so everything here stays\n inline to keep the markup valid. That rules out `Badge`, which always\n renders a `<div>` — the badge below reproduces its look on a `<span>`. */}\n <Flex tag=\"span\" gap={2} alignItems=\"center\">\n <Box\n tag=\"span\"\n background=\"neutral150\"\n hasRadius\n paddingLeft={2}\n paddingRight={2}\n shrink={0}\n >\n <Typography variant=\"sigma\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('beta.badge'),\n defaultMessage: 'Beta',\n })}\n </Typography>\n </Box>\n <Typography tag=\"span\">\n {formatMessage({\n id: getTranslationKey('beta.notice.content'),\n defaultMessage:\n 'This is a beta version of the Media Library. Some features are still in progress — please report any issue you run into.',\n })}\n </Typography>\n </Flex>\n </Alert>\n </Box>\n );\n};\n"],"names":["BetaNotice","formatMessage","useIntl","isBetaNoticeDismissed","setIsBetaNoticeDismissed","usePersistentState","_jsx","Box","paddingBottom","Alert","variant","onClose","closeLabel","id","getTranslationKey","defaultMessage","title","_jsxs","Flex","tag","gap","alignItems","background","hasRadius","paddingLeft","paddingRight","shrink","Typography","textColor"],"mappings":";;;;;;;;AAMA;;;;;;;;;UAUaA,UAAAA,GAAa,IAAA;IACxB,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAM,CAACC,qBAAAA,EAAuBC,wBAAAA,CAAyB,GAAGC,+BACxD,6CAAA,EACA,KAAA,CAAA;AAGF,IAAA,IAAIF,qBAAAA,EAAuB;QACzB,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,qBACEG,cAAA,CAACC,gBAAAA,EAAAA;QAAIC,aAAAA,EAAe,CAAA;AAClB,QAAA,QAAA,gBAAAF,cAAA,CAACG,kBAAAA,EAAAA;YACCC,OAAAA,EAAQ,SAAA;AACRC,YAAAA,OAAAA,EAAS,IAAMP,wBAAAA,CAAyB,IAAA,CAAA;AACxCQ,YAAAA,UAAAA,EAAYX,aAAAA,CAAc;AACxBY,gBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,mBAAA,CAAA;gBACtBC,cAAAA,EAAgB;AAClB,aAAA,CAAA;AACAC,YAAAA,KAAAA,EAAOf,aAAAA,CAAc;AACnBY,gBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,aAAA,CAAA;gBACtBC,cAAAA,EAAgB;AAClB,aAAA,CAAA;AAKA,YAAA,QAAA,gBAAAE,eAAA,CAACC,iBAAAA,EAAAA;gBAAKC,GAAAA,EAAI,MAAA;gBAAOC,GAAAA,EAAK,CAAA;gBAAGC,UAAAA,EAAW,QAAA;;kCAClCf,cAAA,CAACC,gBAAAA,EAAAA;wBACCY,GAAAA,EAAI,MAAA;wBACJG,UAAAA,EAAW,YAAA;wBACXC,SAAS,EAAA,IAAA;wBACTC,WAAAA,EAAa,CAAA;wBACbC,YAAAA,EAAc,CAAA;wBACdC,MAAAA,EAAQ,CAAA;AAER,wBAAA,QAAA,gBAAApB,cAAA,CAACqB,uBAAAA,EAAAA;4BAAWjB,OAAAA,EAAQ,OAAA;4BAAQkB,SAAAA,EAAU,YAAA;sCACnC3B,aAAAA,CAAc;AACbY,gCAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,YAAA,CAAA;gCACtBC,cAAAA,EAAgB;AAClB,6BAAA;;;kCAGJT,cAAA,CAACqB,uBAAAA,EAAAA;wBAAWR,GAAAA,EAAI,MAAA;kCACblB,aAAAA,CAAc;AACbY,4BAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,qBAAA,CAAA;4BACtBC,cAAAA,EACE;AACJ,yBAAA;;;;;;AAMZ;;;;"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { usePersistentState } from '@strapi/admin/strapi-admin';
|
|
3
|
+
import { Box, Alert, Flex, Typography } from '@strapi/design-system';
|
|
4
|
+
import { useIntl } from 'react-intl';
|
|
5
|
+
import { getTranslationKey } from '../utils/translations.mjs';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The beta indicator is a notice rather than a badge on the page header: that
|
|
9
|
+
* header's title follows the folder you are in, so a badge attached to it would
|
|
10
|
+
* read as "this folder is beta". This notice covers the whole Media Library, and
|
|
11
|
+
* stays dismissed once a tester has read it.
|
|
12
|
+
*
|
|
13
|
+
* It renders inside `Layouts.Content` so it picks up the content column's gutter.
|
|
14
|
+
* Rendered above the layout instead, it would span the full viewport width and
|
|
15
|
+
* sit over the folder sidebar.
|
|
16
|
+
*/ const BetaNotice = ()=>{
|
|
17
|
+
const { formatMessage } = useIntl();
|
|
18
|
+
const [isBetaNoticeDismissed, setIsBetaNoticeDismissed] = usePersistentState('STRAPI_UPLOAD_LIBRARY_BETA_NOTICE_DISMISSED', false);
|
|
19
|
+
if (isBetaNoticeDismissed) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return /*#__PURE__*/ jsx(Box, {
|
|
23
|
+
paddingBottom: 4,
|
|
24
|
+
children: /*#__PURE__*/ jsx(Alert, {
|
|
25
|
+
variant: "default",
|
|
26
|
+
onClose: ()=>setIsBetaNoticeDismissed(true),
|
|
27
|
+
closeLabel: formatMessage({
|
|
28
|
+
id: getTranslationKey('beta.notice.close'),
|
|
29
|
+
defaultMessage: 'Close'
|
|
30
|
+
}),
|
|
31
|
+
title: formatMessage({
|
|
32
|
+
id: getTranslationKey('plugin.name'),
|
|
33
|
+
defaultMessage: 'Media Library'
|
|
34
|
+
}),
|
|
35
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
|
36
|
+
tag: "span",
|
|
37
|
+
gap: 2,
|
|
38
|
+
alignItems: "center",
|
|
39
|
+
children: [
|
|
40
|
+
/*#__PURE__*/ jsx(Box, {
|
|
41
|
+
tag: "span",
|
|
42
|
+
background: "neutral150",
|
|
43
|
+
hasRadius: true,
|
|
44
|
+
paddingLeft: 2,
|
|
45
|
+
paddingRight: 2,
|
|
46
|
+
shrink: 0,
|
|
47
|
+
children: /*#__PURE__*/ jsx(Typography, {
|
|
48
|
+
variant: "sigma",
|
|
49
|
+
textColor: "neutral600",
|
|
50
|
+
children: formatMessage({
|
|
51
|
+
id: getTranslationKey('beta.badge'),
|
|
52
|
+
defaultMessage: 'Beta'
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
}),
|
|
56
|
+
/*#__PURE__*/ jsx(Typography, {
|
|
57
|
+
tag: "span",
|
|
58
|
+
children: formatMessage({
|
|
59
|
+
id: getTranslationKey('beta.notice.content'),
|
|
60
|
+
defaultMessage: 'This is a beta version of the Media Library. Some features are still in progress — please report any issue you run into.'
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
]
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export { BetaNotice };
|
|
70
|
+
//# sourceMappingURL=BetaNotice.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BetaNotice.mjs","sources":["../../../../admin/src/future/components/BetaNotice.tsx"],"sourcesContent":["import { usePersistentState } from '@strapi/admin/strapi-admin';\nimport { Alert, Box, Flex, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { getTranslationKey } from '../utils/translations';\n\n/**\n * The beta indicator is a notice rather than a badge on the page header: that\n * header's title follows the folder you are in, so a badge attached to it would\n * read as \"this folder is beta\". This notice covers the whole Media Library, and\n * stays dismissed once a tester has read it.\n *\n * It renders inside `Layouts.Content` so it picks up the content column's gutter.\n * Rendered above the layout instead, it would span the full viewport width and\n * sit over the folder sidebar.\n */\nexport const BetaNotice = () => {\n const { formatMessage } = useIntl();\n const [isBetaNoticeDismissed, setIsBetaNoticeDismissed] = usePersistentState(\n 'STRAPI_UPLOAD_LIBRARY_BETA_NOTICE_DISMISSED',\n false\n );\n\n if (isBetaNoticeDismissed) {\n return null;\n }\n\n return (\n <Box paddingBottom={4}>\n <Alert\n variant=\"default\"\n onClose={() => setIsBetaNoticeDismissed(true)}\n closeLabel={formatMessage({\n id: getTranslationKey('beta.notice.close'),\n defaultMessage: 'Close',\n })}\n title={formatMessage({\n id: getTranslationKey('plugin.name'),\n defaultMessage: 'Media Library',\n })}\n >\n {/* `Alert` renders its children inside a `<p>`, so everything here stays\n inline to keep the markup valid. That rules out `Badge`, which always\n renders a `<div>` — the badge below reproduces its look on a `<span>`. */}\n <Flex tag=\"span\" gap={2} alignItems=\"center\">\n <Box\n tag=\"span\"\n background=\"neutral150\"\n hasRadius\n paddingLeft={2}\n paddingRight={2}\n shrink={0}\n >\n <Typography variant=\"sigma\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('beta.badge'),\n defaultMessage: 'Beta',\n })}\n </Typography>\n </Box>\n <Typography tag=\"span\">\n {formatMessage({\n id: getTranslationKey('beta.notice.content'),\n defaultMessage:\n 'This is a beta version of the Media Library. Some features are still in progress — please report any issue you run into.',\n })}\n </Typography>\n </Flex>\n </Alert>\n </Box>\n );\n};\n"],"names":["BetaNotice","formatMessage","useIntl","isBetaNoticeDismissed","setIsBetaNoticeDismissed","usePersistentState","_jsx","Box","paddingBottom","Alert","variant","onClose","closeLabel","id","getTranslationKey","defaultMessage","title","_jsxs","Flex","tag","gap","alignItems","background","hasRadius","paddingLeft","paddingRight","shrink","Typography","textColor"],"mappings":";;;;;;AAMA;;;;;;;;;UAUaA,UAAAA,GAAa,IAAA;IACxB,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAM,CAACC,qBAAAA,EAAuBC,wBAAAA,CAAyB,GAAGC,mBACxD,6CAAA,EACA,KAAA,CAAA;AAGF,IAAA,IAAIF,qBAAAA,EAAuB;QACzB,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,qBACEG,GAAA,CAACC,GAAAA,EAAAA;QAAIC,aAAAA,EAAe,CAAA;AAClB,QAAA,QAAA,gBAAAF,GAAA,CAACG,KAAAA,EAAAA;YACCC,OAAAA,EAAQ,SAAA;AACRC,YAAAA,OAAAA,EAAS,IAAMP,wBAAAA,CAAyB,IAAA,CAAA;AACxCQ,YAAAA,UAAAA,EAAYX,aAAAA,CAAc;AACxBY,gBAAAA,EAAAA,EAAIC,iBAAAA,CAAkB,mBAAA,CAAA;gBACtBC,cAAAA,EAAgB;AAClB,aAAA,CAAA;AACAC,YAAAA,KAAAA,EAAOf,aAAAA,CAAc;AACnBY,gBAAAA,EAAAA,EAAIC,iBAAAA,CAAkB,aAAA,CAAA;gBACtBC,cAAAA,EAAgB;AAClB,aAAA,CAAA;AAKA,YAAA,QAAA,gBAAAE,IAAA,CAACC,IAAAA,EAAAA;gBAAKC,GAAAA,EAAI,MAAA;gBAAOC,GAAAA,EAAK,CAAA;gBAAGC,UAAAA,EAAW,QAAA;;kCAClCf,GAAA,CAACC,GAAAA,EAAAA;wBACCY,GAAAA,EAAI,MAAA;wBACJG,UAAAA,EAAW,YAAA;wBACXC,SAAS,EAAA,IAAA;wBACTC,WAAAA,EAAa,CAAA;wBACbC,YAAAA,EAAc,CAAA;wBACdC,MAAAA,EAAQ,CAAA;AAER,wBAAA,QAAA,gBAAApB,GAAA,CAACqB,UAAAA,EAAAA;4BAAWjB,OAAAA,EAAQ,OAAA;4BAAQkB,SAAAA,EAAU,YAAA;sCACnC3B,aAAAA,CAAc;AACbY,gCAAAA,EAAAA,EAAIC,iBAAAA,CAAkB,YAAA,CAAA;gCACtBC,cAAAA,EAAgB;AAClB,6BAAA;;;kCAGJT,GAAA,CAACqB,UAAAA,EAAAA;wBAAWR,GAAAA,EAAI,MAAA;kCACblB,aAAAA,CAAc;AACbY,4BAAAA,EAAAA,EAAIC,iBAAAA,CAAkB,qBAAA,CAAA;4BACtBC,cAAAA,EACE;AACJ,yBAAA;;;;;;AAMZ;;;;"}
|
|
@@ -78,7 +78,14 @@ const DrawerContainer = styledComponents.styled(designSystem.Flex)`
|
|
|
78
78
|
flex-direction: column;
|
|
79
79
|
position: fixed;
|
|
80
80
|
bottom: 0;
|
|
81
|
+
/* Mobile: full-bleed sheet. Anchoring to the right at a fixed width left a
|
|
82
|
+
dead gutter on every phone wider than the panel, and the panel only filled
|
|
83
|
+
the screen once the viewport happened to be narrower than it. Below the
|
|
84
|
+
medium breakpoint the panel is the screen; medium+ restores the
|
|
85
|
+
right-anchored rail. */
|
|
86
|
+
left: 0;
|
|
81
87
|
right: 0;
|
|
88
|
+
width: 100%;
|
|
82
89
|
padding: ${({ theme })=>theme.spaces[2]};
|
|
83
90
|
max-width: 100%;
|
|
84
91
|
/* Sit just below the overlay token (300) so that:
|
|
@@ -88,10 +95,14 @@ const DrawerContainer = styledComponents.styled(designSystem.Flex)`
|
|
|
88
95
|
drawer (e.g. the asset details "delete" confirm) cover the drawer. */
|
|
89
96
|
z-index: 200;
|
|
90
97
|
overflow: hidden;
|
|
91
|
-
width: ${({ width })=>width ?? '400px'};
|
|
92
98
|
/* dvh, not vh: anchored to the bottom, a 100vh cap on mobile (visual
|
|
93
99
|
viewport < 100vh under the URL bar) would push the drawer top off-screen. */
|
|
94
|
-
max-height: ${({ maxHeight })
|
|
100
|
+
max-height: ${({ $maxHeight })=>$maxHeight ?? '100dvh'};
|
|
101
|
+
|
|
102
|
+
${({ theme })=>theme.breakpoints.medium} {
|
|
103
|
+
left: auto;
|
|
104
|
+
width: ${({ $width })=>$width ?? '400px'};
|
|
105
|
+
}
|
|
95
106
|
|
|
96
107
|
&:focus {
|
|
97
108
|
outline: none;
|
|
@@ -139,7 +150,7 @@ const CloseIconButton = styledComponents.styled(designSystem.IconButton)`
|
|
|
139
150
|
background: transparent;
|
|
140
151
|
}
|
|
141
152
|
`;
|
|
142
|
-
const DrawerBody = /*#__PURE__*/ React__namespace.forwardRef(({ animationDirection, children, ...props }, ref)=>/*#__PURE__*/ jsxRuntime.jsx(Dialog__namespace.Content, {
|
|
153
|
+
const DrawerBody = /*#__PURE__*/ React__namespace.forwardRef(({ animationDirection, width, maxHeight, children, ...props }, ref)=>/*#__PURE__*/ jsxRuntime.jsx(Dialog__namespace.Content, {
|
|
143
154
|
ref: ref,
|
|
144
155
|
forceMount: true,
|
|
145
156
|
asChild: true,
|
|
@@ -148,6 +159,8 @@ const DrawerBody = /*#__PURE__*/ React__namespace.forwardRef(({ animationDirecti
|
|
|
148
159
|
"data-animation-direction": animationDirection,
|
|
149
160
|
children: /*#__PURE__*/ jsxRuntime.jsx(DrawerContainer, {
|
|
150
161
|
$animationDirection: animationDirection,
|
|
162
|
+
$width: width,
|
|
163
|
+
$maxHeight: maxHeight,
|
|
151
164
|
...props,
|
|
152
165
|
children: /*#__PURE__*/ jsxRuntime.jsx(DrawerContent, {
|
|
153
166
|
children: children
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer.js","sources":["../../../../admin/src/future/components/Drawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as Dialog from '@radix-ui/react-dialog';\nimport { Box, ScrollArea, IconButton, Flex, FlexProps } from '@strapi/design-system';\nimport { Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { keyframes, styled } from 'styled-components';\n\n/** Duration of the close animation in ms. Use for timing cleanup (e.g. removing URL params). */\nexport const DRAWER_CLOSE_ANIMATION_MS = 300;\n\n/* -------------------------------------------------------------------------------------------------\n * Animations\n * -----------------------------------------------------------------------------------------------*/\n\n// Direction: up\nconst slideUpFromBottomIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\n\nconst slideUpFromBottomOut = keyframes`\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(100%);\n }\n`;\n\n// Direction: left\nconst slideLeftFromRightIn = keyframes`\n from {\n opacity: 0;\n transform: translateX(100%);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n`;\n\nconst slideLeftFromRightOut = keyframes`\n from {\n opacity: 1;\n transform: translateX(0);\n }\n to {\n opacity: 0;\n transform: translateX(100%);\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Styled components\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerContainerProps {\n $animationDirection?: DrawerBodyProps['animationDirection'];\n}\n\nconst DrawerContainer = styled(Flex)<DrawerContainerProps>`\n flex-direction: column;\n position: fixed;\n bottom: 0;\n right: 0;\n padding: ${({ theme }) => theme.spaces[2]};\n max-width: 100%;\n /* Sit just below the overlay token (300) so that:\n - popovers (500) and tooltips (1000) rendered from descendant components\n surface above the drawer panel,\n - AlertDialog overlays (300) and contents (310) opened from inside the\n drawer (e.g. the asset details \"delete\" confirm) cover the drawer. */\n z-index: 200;\n overflow: hidden;\n width: ${({ width }) => width ?? '400px'};\n /* dvh, not vh: anchored to the bottom, a 100vh cap on mobile (visual\n viewport < 100vh under the URL bar) would push the drawer top off-screen. */\n max-height: ${({ maxHeight }) => maxHeight ?? '100dvh'};\n\n &:focus {\n outline: none;\n }\n\n @media (prefers-reduced-motion: no-preference) {\n &[data-state='open'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomIn : slideLeftFromRightIn}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n }\n\n &[data-state='closed'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomOut : slideLeftFromRightOut}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n pointer-events: none;\n }\n }\n`;\n\nconst DrawerContent = styled(Box)`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n background-color: ${({ theme }) => theme.colors.neutral0};\n border-radius: ${({ theme }) => theme.borderRadius};\n box-shadow: ${({ theme }) => theme.shadows.popupShadow};\n overflow: hidden;\n border: 1px solid ${({ theme }) => theme.colors.neutral150};\n`;\n\ninterface CollapsibleContentProps {\n $isVisible: boolean;\n}\n\nconst CollapsibleContent = styled(Box)<CollapsibleContentProps>`\n display: grid;\n flex: 1;\n min-height: 0;\n grid-template-rows: ${({ $isVisible }) => ($isVisible ? '1fr' : '0fr')};\n transition: grid-template-rows 0.3s ease-in-out;\n\n > div {\n overflow: hidden;\n min-height: 0;\n }\n`;\n\nconst CloseIconButton = styled(IconButton)`\n &:hover {\n background: transparent;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Body\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerBodyProps extends FlexProps {\n animationDirection?: 'up' | 'left';\n children: React.ReactNode;\n}\n\nconst DrawerBody = React.forwardRef<HTMLDivElement, DrawerBodyProps>(\n ({ animationDirection, children, ...props }, ref) => (\n <Dialog.Content\n ref={ref}\n forceMount\n asChild\n onPointerDownOutside={(e) => e.preventDefault()}\n onInteractOutside={(e) => e.preventDefault()}\n data-animation-direction={animationDirection}\n >\n <DrawerContainer $animationDirection={animationDirection} {...props}>\n <DrawerContent>{children}</DrawerContent>\n </DrawerContainer>\n </Dialog.Content>\n )\n);\nDrawerBody.displayName = 'DrawerBody';\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerRootProps {\n isVisible?: boolean;\n onClose?: () => void;\n children: React.ReactNode;\n}\n\nconst DrawerRoot = ({ isVisible, onClose, children }: DrawerRootProps): React.ReactElement => (\n <Dialog.Root\n open={isVisible}\n onOpenChange={(nextVisible) => !nextVisible && onClose?.()}\n modal={false}\n >\n <Dialog.Portal>{children}</Dialog.Portal>\n </Dialog.Root>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Content - composable content slot (collapsible when isContentExpanded is used)\n * Contains a scrollable area\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerScrollableContentProps {\n children: React.ReactNode;\n /** When provided, content can collapse/expand (e.g. for minimize). Omit to always show. */\n isContentExpanded?: boolean;\n}\n\nconst DrawerScrollableContent = ({\n children,\n isContentExpanded = true,\n}: DrawerScrollableContentProps) => (\n <CollapsibleContent $isVisible={isContentExpanded} data-collapsed={!isContentExpanded}>\n <ScrollArea>{children}</ScrollArea>\n </CollapsibleContent>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.CloseButton - composable close icon button (Cross icon by default)\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerCloseButtonProps extends React.PropsWithChildren {\n onClose: () => void;\n label?: string;\n}\n\nconst DrawerCloseButton = ({ onClose, label, children }: DrawerCloseButtonProps) => {\n const { formatMessage } = useIntl();\n const labelMessage = label ?? formatMessage({ id: 'global.close', defaultMessage: 'Close' });\n return (\n <CloseIconButton onClick={onClose} label={labelMessage} variant=\"ghost\">\n {children ?? <Cross />}\n </CloseIconButton>\n );\n};\n\nconst Drawer = {\n Root: DrawerRoot,\n Body: DrawerBody,\n ScrollableContent: DrawerScrollableContent,\n CloseButton: DrawerCloseButton,\n Title: Dialog.Title,\n Description: Dialog.Description,\n};\n\nexport { Drawer };\n"],"names":["DRAWER_CLOSE_ANIMATION_MS","slideUpFromBottomIn","keyframes","slideUpFromBottomOut","slideLeftFromRightIn","slideLeftFromRightOut","DrawerContainer","styled","Flex","theme","spaces","width","maxHeight","$animationDirection","DrawerContent","Box","colors","neutral0","borderRadius","shadows","popupShadow","neutral150","CollapsibleContent","$isVisible","CloseIconButton","IconButton","DrawerBody","React","forwardRef","animationDirection","children","props","ref","_jsx","Dialog","Content","forceMount","asChild","onPointerDownOutside","e","preventDefault","onInteractOutside","data-animation-direction","displayName","DrawerRoot","isVisible","onClose","Root","open","onOpenChange","nextVisible","modal","Portal","DrawerScrollableContent","isContentExpanded","data-collapsed","ScrollArea","DrawerCloseButton","label","formatMessage","useIntl","labelMessage","id","defaultMessage","onClick","variant","Cross","Drawer","Body","ScrollableContent","CloseButton","Title","Description"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Drawer.js","sources":["../../../../admin/src/future/components/Drawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as Dialog from '@radix-ui/react-dialog';\nimport { Box, ScrollArea, IconButton, Flex, FlexProps } from '@strapi/design-system';\nimport { Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { keyframes, styled } from 'styled-components';\n\n/** Duration of the close animation in ms. Use for timing cleanup (e.g. removing URL params). */\nexport const DRAWER_CLOSE_ANIMATION_MS = 300;\n\n/* -------------------------------------------------------------------------------------------------\n * Animations\n * -----------------------------------------------------------------------------------------------*/\n\n// Direction: up\nconst slideUpFromBottomIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\n\nconst slideUpFromBottomOut = keyframes`\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(100%);\n }\n`;\n\n// Direction: left\nconst slideLeftFromRightIn = keyframes`\n from {\n opacity: 0;\n transform: translateX(100%);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n`;\n\nconst slideLeftFromRightOut = keyframes`\n from {\n opacity: 1;\n transform: translateX(0);\n }\n to {\n opacity: 0;\n transform: translateX(100%);\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Styled components\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerContainerProps {\n $animationDirection?: DrawerBodyProps['animationDirection'];\n $width?: string;\n $maxHeight?: string;\n}\n\nconst DrawerContainer = styled(Flex)<DrawerContainerProps>`\n flex-direction: column;\n position: fixed;\n bottom: 0;\n /* Mobile: full-bleed sheet. Anchoring to the right at a fixed width left a\n dead gutter on every phone wider than the panel, and the panel only filled\n the screen once the viewport happened to be narrower than it. Below the\n medium breakpoint the panel is the screen; medium+ restores the\n right-anchored rail. */\n left: 0;\n right: 0;\n width: 100%;\n padding: ${({ theme }) => theme.spaces[2]};\n max-width: 100%;\n /* Sit just below the overlay token (300) so that:\n - popovers (500) and tooltips (1000) rendered from descendant components\n surface above the drawer panel,\n - AlertDialog overlays (300) and contents (310) opened from inside the\n drawer (e.g. the asset details \"delete\" confirm) cover the drawer. */\n z-index: 200;\n overflow: hidden;\n /* dvh, not vh: anchored to the bottom, a 100vh cap on mobile (visual\n viewport < 100vh under the URL bar) would push the drawer top off-screen. */\n max-height: ${({ $maxHeight }) => $maxHeight ?? '100dvh'};\n\n ${({ theme }) => theme.breakpoints.medium} {\n left: auto;\n width: ${({ $width }) => $width ?? '400px'};\n }\n\n &:focus {\n outline: none;\n }\n\n @media (prefers-reduced-motion: no-preference) {\n &[data-state='open'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomIn : slideLeftFromRightIn}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n }\n\n &[data-state='closed'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomOut : slideLeftFromRightOut}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n pointer-events: none;\n }\n }\n`;\n\nconst DrawerContent = styled(Box)`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n background-color: ${({ theme }) => theme.colors.neutral0};\n border-radius: ${({ theme }) => theme.borderRadius};\n box-shadow: ${({ theme }) => theme.shadows.popupShadow};\n overflow: hidden;\n border: 1px solid ${({ theme }) => theme.colors.neutral150};\n`;\n\ninterface CollapsibleContentProps {\n $isVisible: boolean;\n}\n\nconst CollapsibleContent = styled(Box)<CollapsibleContentProps>`\n display: grid;\n flex: 1;\n min-height: 0;\n grid-template-rows: ${({ $isVisible }) => ($isVisible ? '1fr' : '0fr')};\n transition: grid-template-rows 0.3s ease-in-out;\n\n > div {\n overflow: hidden;\n min-height: 0;\n }\n`;\n\nconst CloseIconButton = styled(IconButton)`\n &:hover {\n background: transparent;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Body\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerBodyProps extends Omit<FlexProps, 'width' | 'maxHeight'> {\n animationDirection?: 'up' | 'left';\n /** Width of the panel from the medium breakpoint up. Mobile is always full-bleed. */\n width?: string;\n /** Cap on the panel height. Defaults to the dynamic viewport height. */\n maxHeight?: string;\n children: React.ReactNode;\n}\n\nconst DrawerBody = React.forwardRef<HTMLDivElement, DrawerBodyProps>(\n ({ animationDirection, width, maxHeight, children, ...props }, ref) => (\n <Dialog.Content\n ref={ref}\n forceMount\n asChild\n onPointerDownOutside={(e) => e.preventDefault()}\n onInteractOutside={(e) => e.preventDefault()}\n data-animation-direction={animationDirection}\n >\n {/* width/maxHeight go through transient props so the DS Flex never emits a\n competing `width` rule that would outrank the mobile full-bleed one. */}\n <DrawerContainer\n $animationDirection={animationDirection}\n $width={width}\n $maxHeight={maxHeight}\n {...props}\n >\n <DrawerContent>{children}</DrawerContent>\n </DrawerContainer>\n </Dialog.Content>\n )\n);\nDrawerBody.displayName = 'DrawerBody';\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerRootProps {\n isVisible?: boolean;\n onClose?: () => void;\n children: React.ReactNode;\n}\n\nconst DrawerRoot = ({ isVisible, onClose, children }: DrawerRootProps): React.ReactElement => (\n <Dialog.Root\n open={isVisible}\n onOpenChange={(nextVisible) => !nextVisible && onClose?.()}\n modal={false}\n >\n <Dialog.Portal>{children}</Dialog.Portal>\n </Dialog.Root>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Content - composable content slot (collapsible when isContentExpanded is used)\n * Contains a scrollable area\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerScrollableContentProps {\n children: React.ReactNode;\n /** When provided, content can collapse/expand (e.g. for minimize). Omit to always show. */\n isContentExpanded?: boolean;\n}\n\nconst DrawerScrollableContent = ({\n children,\n isContentExpanded = true,\n}: DrawerScrollableContentProps) => (\n <CollapsibleContent $isVisible={isContentExpanded} data-collapsed={!isContentExpanded}>\n <ScrollArea>{children}</ScrollArea>\n </CollapsibleContent>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.CloseButton - composable close icon button (Cross icon by default)\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerCloseButtonProps extends React.PropsWithChildren {\n onClose: () => void;\n label?: string;\n}\n\nconst DrawerCloseButton = ({ onClose, label, children }: DrawerCloseButtonProps) => {\n const { formatMessage } = useIntl();\n const labelMessage = label ?? formatMessage({ id: 'global.close', defaultMessage: 'Close' });\n return (\n <CloseIconButton onClick={onClose} label={labelMessage} variant=\"ghost\">\n {children ?? <Cross />}\n </CloseIconButton>\n );\n};\n\nconst Drawer = {\n Root: DrawerRoot,\n Body: DrawerBody,\n ScrollableContent: DrawerScrollableContent,\n CloseButton: DrawerCloseButton,\n Title: Dialog.Title,\n Description: Dialog.Description,\n};\n\nexport { Drawer };\n"],"names":["DRAWER_CLOSE_ANIMATION_MS","slideUpFromBottomIn","keyframes","slideUpFromBottomOut","slideLeftFromRightIn","slideLeftFromRightOut","DrawerContainer","styled","Flex","theme","spaces","$maxHeight","breakpoints","medium","$width","$animationDirection","DrawerContent","Box","colors","neutral0","borderRadius","shadows","popupShadow","neutral150","CollapsibleContent","$isVisible","CloseIconButton","IconButton","DrawerBody","React","forwardRef","animationDirection","width","maxHeight","children","props","ref","_jsx","Dialog","Content","forceMount","asChild","onPointerDownOutside","e","preventDefault","onInteractOutside","data-animation-direction","displayName","DrawerRoot","isVisible","onClose","Root","open","onOpenChange","nextVisible","modal","Portal","DrawerScrollableContent","isContentExpanded","data-collapsed","ScrollArea","DrawerCloseButton","label","formatMessage","useIntl","labelMessage","id","defaultMessage","onClick","variant","Cross","Drawer","Body","ScrollableContent","CloseButton","Title","Description"],"mappings":"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"}
|
|
@@ -55,7 +55,14 @@ const DrawerContainer = styled(Flex)`
|
|
|
55
55
|
flex-direction: column;
|
|
56
56
|
position: fixed;
|
|
57
57
|
bottom: 0;
|
|
58
|
+
/* Mobile: full-bleed sheet. Anchoring to the right at a fixed width left a
|
|
59
|
+
dead gutter on every phone wider than the panel, and the panel only filled
|
|
60
|
+
the screen once the viewport happened to be narrower than it. Below the
|
|
61
|
+
medium breakpoint the panel is the screen; medium+ restores the
|
|
62
|
+
right-anchored rail. */
|
|
63
|
+
left: 0;
|
|
58
64
|
right: 0;
|
|
65
|
+
width: 100%;
|
|
59
66
|
padding: ${({ theme })=>theme.spaces[2]};
|
|
60
67
|
max-width: 100%;
|
|
61
68
|
/* Sit just below the overlay token (300) so that:
|
|
@@ -65,10 +72,14 @@ const DrawerContainer = styled(Flex)`
|
|
|
65
72
|
drawer (e.g. the asset details "delete" confirm) cover the drawer. */
|
|
66
73
|
z-index: 200;
|
|
67
74
|
overflow: hidden;
|
|
68
|
-
width: ${({ width })=>width ?? '400px'};
|
|
69
75
|
/* dvh, not vh: anchored to the bottom, a 100vh cap on mobile (visual
|
|
70
76
|
viewport < 100vh under the URL bar) would push the drawer top off-screen. */
|
|
71
|
-
max-height: ${({ maxHeight })
|
|
77
|
+
max-height: ${({ $maxHeight })=>$maxHeight ?? '100dvh'};
|
|
78
|
+
|
|
79
|
+
${({ theme })=>theme.breakpoints.medium} {
|
|
80
|
+
left: auto;
|
|
81
|
+
width: ${({ $width })=>$width ?? '400px'};
|
|
82
|
+
}
|
|
72
83
|
|
|
73
84
|
&:focus {
|
|
74
85
|
outline: none;
|
|
@@ -116,7 +127,7 @@ const CloseIconButton = styled(IconButton)`
|
|
|
116
127
|
background: transparent;
|
|
117
128
|
}
|
|
118
129
|
`;
|
|
119
|
-
const DrawerBody = /*#__PURE__*/ React.forwardRef(({ animationDirection, children, ...props }, ref)=>/*#__PURE__*/ jsx(Dialog.Content, {
|
|
130
|
+
const DrawerBody = /*#__PURE__*/ React.forwardRef(({ animationDirection, width, maxHeight, children, ...props }, ref)=>/*#__PURE__*/ jsx(Dialog.Content, {
|
|
120
131
|
ref: ref,
|
|
121
132
|
forceMount: true,
|
|
122
133
|
asChild: true,
|
|
@@ -125,6 +136,8 @@ const DrawerBody = /*#__PURE__*/ React.forwardRef(({ animationDirection, childre
|
|
|
125
136
|
"data-animation-direction": animationDirection,
|
|
126
137
|
children: /*#__PURE__*/ jsx(DrawerContainer, {
|
|
127
138
|
$animationDirection: animationDirection,
|
|
139
|
+
$width: width,
|
|
140
|
+
$maxHeight: maxHeight,
|
|
128
141
|
...props,
|
|
129
142
|
children: /*#__PURE__*/ jsx(DrawerContent, {
|
|
130
143
|
children: children
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer.mjs","sources":["../../../../admin/src/future/components/Drawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as Dialog from '@radix-ui/react-dialog';\nimport { Box, ScrollArea, IconButton, Flex, FlexProps } from '@strapi/design-system';\nimport { Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { keyframes, styled } from 'styled-components';\n\n/** Duration of the close animation in ms. Use for timing cleanup (e.g. removing URL params). */\nexport const DRAWER_CLOSE_ANIMATION_MS = 300;\n\n/* -------------------------------------------------------------------------------------------------\n * Animations\n * -----------------------------------------------------------------------------------------------*/\n\n// Direction: up\nconst slideUpFromBottomIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\n\nconst slideUpFromBottomOut = keyframes`\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(100%);\n }\n`;\n\n// Direction: left\nconst slideLeftFromRightIn = keyframes`\n from {\n opacity: 0;\n transform: translateX(100%);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n`;\n\nconst slideLeftFromRightOut = keyframes`\n from {\n opacity: 1;\n transform: translateX(0);\n }\n to {\n opacity: 0;\n transform: translateX(100%);\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Styled components\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerContainerProps {\n $animationDirection?: DrawerBodyProps['animationDirection'];\n}\n\nconst DrawerContainer = styled(Flex)<DrawerContainerProps>`\n flex-direction: column;\n position: fixed;\n bottom: 0;\n right: 0;\n padding: ${({ theme }) => theme.spaces[2]};\n max-width: 100%;\n /* Sit just below the overlay token (300) so that:\n - popovers (500) and tooltips (1000) rendered from descendant components\n surface above the drawer panel,\n - AlertDialog overlays (300) and contents (310) opened from inside the\n drawer (e.g. the asset details \"delete\" confirm) cover the drawer. */\n z-index: 200;\n overflow: hidden;\n width: ${({ width }) => width ?? '400px'};\n /* dvh, not vh: anchored to the bottom, a 100vh cap on mobile (visual\n viewport < 100vh under the URL bar) would push the drawer top off-screen. */\n max-height: ${({ maxHeight }) => maxHeight ?? '100dvh'};\n\n &:focus {\n outline: none;\n }\n\n @media (prefers-reduced-motion: no-preference) {\n &[data-state='open'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomIn : slideLeftFromRightIn}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n }\n\n &[data-state='closed'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomOut : slideLeftFromRightOut}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n pointer-events: none;\n }\n }\n`;\n\nconst DrawerContent = styled(Box)`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n background-color: ${({ theme }) => theme.colors.neutral0};\n border-radius: ${({ theme }) => theme.borderRadius};\n box-shadow: ${({ theme }) => theme.shadows.popupShadow};\n overflow: hidden;\n border: 1px solid ${({ theme }) => theme.colors.neutral150};\n`;\n\ninterface CollapsibleContentProps {\n $isVisible: boolean;\n}\n\nconst CollapsibleContent = styled(Box)<CollapsibleContentProps>`\n display: grid;\n flex: 1;\n min-height: 0;\n grid-template-rows: ${({ $isVisible }) => ($isVisible ? '1fr' : '0fr')};\n transition: grid-template-rows 0.3s ease-in-out;\n\n > div {\n overflow: hidden;\n min-height: 0;\n }\n`;\n\nconst CloseIconButton = styled(IconButton)`\n &:hover {\n background: transparent;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Body\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerBodyProps extends FlexProps {\n animationDirection?: 'up' | 'left';\n children: React.ReactNode;\n}\n\nconst DrawerBody = React.forwardRef<HTMLDivElement, DrawerBodyProps>(\n ({ animationDirection, children, ...props }, ref) => (\n <Dialog.Content\n ref={ref}\n forceMount\n asChild\n onPointerDownOutside={(e) => e.preventDefault()}\n onInteractOutside={(e) => e.preventDefault()}\n data-animation-direction={animationDirection}\n >\n <DrawerContainer $animationDirection={animationDirection} {...props}>\n <DrawerContent>{children}</DrawerContent>\n </DrawerContainer>\n </Dialog.Content>\n )\n);\nDrawerBody.displayName = 'DrawerBody';\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerRootProps {\n isVisible?: boolean;\n onClose?: () => void;\n children: React.ReactNode;\n}\n\nconst DrawerRoot = ({ isVisible, onClose, children }: DrawerRootProps): React.ReactElement => (\n <Dialog.Root\n open={isVisible}\n onOpenChange={(nextVisible) => !nextVisible && onClose?.()}\n modal={false}\n >\n <Dialog.Portal>{children}</Dialog.Portal>\n </Dialog.Root>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Content - composable content slot (collapsible when isContentExpanded is used)\n * Contains a scrollable area\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerScrollableContentProps {\n children: React.ReactNode;\n /** When provided, content can collapse/expand (e.g. for minimize). Omit to always show. */\n isContentExpanded?: boolean;\n}\n\nconst DrawerScrollableContent = ({\n children,\n isContentExpanded = true,\n}: DrawerScrollableContentProps) => (\n <CollapsibleContent $isVisible={isContentExpanded} data-collapsed={!isContentExpanded}>\n <ScrollArea>{children}</ScrollArea>\n </CollapsibleContent>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.CloseButton - composable close icon button (Cross icon by default)\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerCloseButtonProps extends React.PropsWithChildren {\n onClose: () => void;\n label?: string;\n}\n\nconst DrawerCloseButton = ({ onClose, label, children }: DrawerCloseButtonProps) => {\n const { formatMessage } = useIntl();\n const labelMessage = label ?? formatMessage({ id: 'global.close', defaultMessage: 'Close' });\n return (\n <CloseIconButton onClick={onClose} label={labelMessage} variant=\"ghost\">\n {children ?? <Cross />}\n </CloseIconButton>\n );\n};\n\nconst Drawer = {\n Root: DrawerRoot,\n Body: DrawerBody,\n ScrollableContent: DrawerScrollableContent,\n CloseButton: DrawerCloseButton,\n Title: Dialog.Title,\n Description: Dialog.Description,\n};\n\nexport { Drawer };\n"],"names":["DRAWER_CLOSE_ANIMATION_MS","slideUpFromBottomIn","keyframes","slideUpFromBottomOut","slideLeftFromRightIn","slideLeftFromRightOut","DrawerContainer","styled","Flex","theme","spaces","width","maxHeight","$animationDirection","DrawerContent","Box","colors","neutral0","borderRadius","shadows","popupShadow","neutral150","CollapsibleContent","$isVisible","CloseIconButton","IconButton","DrawerBody","React","forwardRef","animationDirection","children","props","ref","_jsx","Dialog","Content","forceMount","asChild","onPointerDownOutside","e","preventDefault","onInteractOutside","data-animation-direction","displayName","DrawerRoot","isVisible","onClose","Root","open","onOpenChange","nextVisible","modal","Portal","DrawerScrollableContent","isContentExpanded","data-collapsed","ScrollArea","DrawerCloseButton","label","formatMessage","useIntl","labelMessage","id","defaultMessage","onClick","variant","Cross","Drawer","Body","ScrollableContent","CloseButton","Title","Description"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Drawer.mjs","sources":["../../../../admin/src/future/components/Drawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as Dialog from '@radix-ui/react-dialog';\nimport { Box, ScrollArea, IconButton, Flex, FlexProps } from '@strapi/design-system';\nimport { Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { keyframes, styled } from 'styled-components';\n\n/** Duration of the close animation in ms. Use for timing cleanup (e.g. removing URL params). */\nexport const DRAWER_CLOSE_ANIMATION_MS = 300;\n\n/* -------------------------------------------------------------------------------------------------\n * Animations\n * -----------------------------------------------------------------------------------------------*/\n\n// Direction: up\nconst slideUpFromBottomIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\n\nconst slideUpFromBottomOut = keyframes`\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(100%);\n }\n`;\n\n// Direction: left\nconst slideLeftFromRightIn = keyframes`\n from {\n opacity: 0;\n transform: translateX(100%);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n`;\n\nconst slideLeftFromRightOut = keyframes`\n from {\n opacity: 1;\n transform: translateX(0);\n }\n to {\n opacity: 0;\n transform: translateX(100%);\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Styled components\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerContainerProps {\n $animationDirection?: DrawerBodyProps['animationDirection'];\n $width?: string;\n $maxHeight?: string;\n}\n\nconst DrawerContainer = styled(Flex)<DrawerContainerProps>`\n flex-direction: column;\n position: fixed;\n bottom: 0;\n /* Mobile: full-bleed sheet. Anchoring to the right at a fixed width left a\n dead gutter on every phone wider than the panel, and the panel only filled\n the screen once the viewport happened to be narrower than it. Below the\n medium breakpoint the panel is the screen; medium+ restores the\n right-anchored rail. */\n left: 0;\n right: 0;\n width: 100%;\n padding: ${({ theme }) => theme.spaces[2]};\n max-width: 100%;\n /* Sit just below the overlay token (300) so that:\n - popovers (500) and tooltips (1000) rendered from descendant components\n surface above the drawer panel,\n - AlertDialog overlays (300) and contents (310) opened from inside the\n drawer (e.g. the asset details \"delete\" confirm) cover the drawer. */\n z-index: 200;\n overflow: hidden;\n /* dvh, not vh: anchored to the bottom, a 100vh cap on mobile (visual\n viewport < 100vh under the URL bar) would push the drawer top off-screen. */\n max-height: ${({ $maxHeight }) => $maxHeight ?? '100dvh'};\n\n ${({ theme }) => theme.breakpoints.medium} {\n left: auto;\n width: ${({ $width }) => $width ?? '400px'};\n }\n\n &:focus {\n outline: none;\n }\n\n @media (prefers-reduced-motion: no-preference) {\n &[data-state='open'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomIn : slideLeftFromRightIn}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n }\n\n &[data-state='closed'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomOut : slideLeftFromRightOut}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n pointer-events: none;\n }\n }\n`;\n\nconst DrawerContent = styled(Box)`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n background-color: ${({ theme }) => theme.colors.neutral0};\n border-radius: ${({ theme }) => theme.borderRadius};\n box-shadow: ${({ theme }) => theme.shadows.popupShadow};\n overflow: hidden;\n border: 1px solid ${({ theme }) => theme.colors.neutral150};\n`;\n\ninterface CollapsibleContentProps {\n $isVisible: boolean;\n}\n\nconst CollapsibleContent = styled(Box)<CollapsibleContentProps>`\n display: grid;\n flex: 1;\n min-height: 0;\n grid-template-rows: ${({ $isVisible }) => ($isVisible ? '1fr' : '0fr')};\n transition: grid-template-rows 0.3s ease-in-out;\n\n > div {\n overflow: hidden;\n min-height: 0;\n }\n`;\n\nconst CloseIconButton = styled(IconButton)`\n &:hover {\n background: transparent;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Body\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerBodyProps extends Omit<FlexProps, 'width' | 'maxHeight'> {\n animationDirection?: 'up' | 'left';\n /** Width of the panel from the medium breakpoint up. Mobile is always full-bleed. */\n width?: string;\n /** Cap on the panel height. Defaults to the dynamic viewport height. */\n maxHeight?: string;\n children: React.ReactNode;\n}\n\nconst DrawerBody = React.forwardRef<HTMLDivElement, DrawerBodyProps>(\n ({ animationDirection, width, maxHeight, children, ...props }, ref) => (\n <Dialog.Content\n ref={ref}\n forceMount\n asChild\n onPointerDownOutside={(e) => e.preventDefault()}\n onInteractOutside={(e) => e.preventDefault()}\n data-animation-direction={animationDirection}\n >\n {/* width/maxHeight go through transient props so the DS Flex never emits a\n competing `width` rule that would outrank the mobile full-bleed one. */}\n <DrawerContainer\n $animationDirection={animationDirection}\n $width={width}\n $maxHeight={maxHeight}\n {...props}\n >\n <DrawerContent>{children}</DrawerContent>\n </DrawerContainer>\n </Dialog.Content>\n )\n);\nDrawerBody.displayName = 'DrawerBody';\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerRootProps {\n isVisible?: boolean;\n onClose?: () => void;\n children: React.ReactNode;\n}\n\nconst DrawerRoot = ({ isVisible, onClose, children }: DrawerRootProps): React.ReactElement => (\n <Dialog.Root\n open={isVisible}\n onOpenChange={(nextVisible) => !nextVisible && onClose?.()}\n modal={false}\n >\n <Dialog.Portal>{children}</Dialog.Portal>\n </Dialog.Root>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Content - composable content slot (collapsible when isContentExpanded is used)\n * Contains a scrollable area\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerScrollableContentProps {\n children: React.ReactNode;\n /** When provided, content can collapse/expand (e.g. for minimize). Omit to always show. */\n isContentExpanded?: boolean;\n}\n\nconst DrawerScrollableContent = ({\n children,\n isContentExpanded = true,\n}: DrawerScrollableContentProps) => (\n <CollapsibleContent $isVisible={isContentExpanded} data-collapsed={!isContentExpanded}>\n <ScrollArea>{children}</ScrollArea>\n </CollapsibleContent>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.CloseButton - composable close icon button (Cross icon by default)\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerCloseButtonProps extends React.PropsWithChildren {\n onClose: () => void;\n label?: string;\n}\n\nconst DrawerCloseButton = ({ onClose, label, children }: DrawerCloseButtonProps) => {\n const { formatMessage } = useIntl();\n const labelMessage = label ?? formatMessage({ id: 'global.close', defaultMessage: 'Close' });\n return (\n <CloseIconButton onClick={onClose} label={labelMessage} variant=\"ghost\">\n {children ?? <Cross />}\n </CloseIconButton>\n );\n};\n\nconst Drawer = {\n Root: DrawerRoot,\n Body: DrawerBody,\n ScrollableContent: DrawerScrollableContent,\n CloseButton: DrawerCloseButton,\n Title: Dialog.Title,\n Description: Dialog.Description,\n};\n\nexport { Drawer };\n"],"names":["DRAWER_CLOSE_ANIMATION_MS","slideUpFromBottomIn","keyframes","slideUpFromBottomOut","slideLeftFromRightIn","slideLeftFromRightOut","DrawerContainer","styled","Flex","theme","spaces","$maxHeight","breakpoints","medium","$width","$animationDirection","DrawerContent","Box","colors","neutral0","borderRadius","shadows","popupShadow","neutral150","CollapsibleContent","$isVisible","CloseIconButton","IconButton","DrawerBody","React","forwardRef","animationDirection","width","maxHeight","children","props","ref","_jsx","Dialog","Content","forceMount","asChild","onPointerDownOutside","e","preventDefault","onInteractOutside","data-animation-direction","displayName","DrawerRoot","isVisible","onClose","Root","open","onOpenChange","nextVisible","modal","Portal","DrawerScrollableContent","isContentExpanded","data-collapsed","ScrollArea","DrawerCloseButton","label","formatMessage","useIntl","labelMessage","id","defaultMessage","onClick","variant","Cross","Drawer","Body","ScrollableContent","CloseButton","Title","Description"],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var ee = require('@strapi/admin/strapi-admin/ee');
|
|
4
|
+
var constants = require('../../shared/constants.js');
|
|
5
|
+
var settings = require('../services/settings.js');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Whether the replace flow will actually regenerate AI metadata, so the UI only
|
|
9
|
+
* promises it when it happens.
|
|
10
|
+
*
|
|
11
|
+
* Two independent gates, both required — `GET /upload/settings` returns the
|
|
12
|
+
* stored `aiMetadata` toggle on its own, which stays `true` (its default) on
|
|
13
|
+
* licenses without AI, so the setting alone over-promises. The server's own
|
|
14
|
+
* check (`aiMetadata.isEnabled()`) ANDs the same two conditions.
|
|
15
|
+
*
|
|
16
|
+
* Pass `{ mime }` to add the third gate the replace flow applies: it only
|
|
17
|
+
* regenerates metadata for images the AI provider can read
|
|
18
|
+
* (`admin-upload.replaceFile` → `aiMetadata.processFiles`, which filters on this
|
|
19
|
+
* same allowlist). Promising it for a PDF — or for a GIF, which clears the
|
|
20
|
+
* server's looser `image/*` gate but is skipped by the provider — would describe
|
|
21
|
+
* something that never happens.
|
|
22
|
+
*
|
|
23
|
+
* The argument is an object rather than a bare `mime` so the two intents stay
|
|
24
|
+
* distinguishable: `File.mime` is optional on the contract, so a positional
|
|
25
|
+
* parameter let `useAIMetadataEnabled(asset.mime)` collapse into the ungated
|
|
26
|
+
* call whenever the mime was missing — silently taking the permissive path this
|
|
27
|
+
* hook exists to close. `useAIMetadataEnabled({ mime: undefined })` still gates
|
|
28
|
+
* (and fails closed); only an omitted `options` skips the mime check.
|
|
29
|
+
*/ const useAIMetadataEnabled = (options)=>{
|
|
30
|
+
const isAIAvailable = ee.useAIAvailability();
|
|
31
|
+
const { data: settings$1 } = settings.useGetUploadSettingsQuery();
|
|
32
|
+
if (!isAIAvailable || !(settings$1?.data?.aiMetadata ?? false)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
return options === undefined ? true : constants.isAIMetadataSupportedMime(options.mime);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
exports.useAIMetadataEnabled = useAIMetadataEnabled;
|
|
39
|
+
//# sourceMappingURL=useAIMetadataEnabled.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAIMetadataEnabled.js","sources":["../../../../admin/src/future/hooks/useAIMetadataEnabled.ts"],"sourcesContent":["import { useAIAvailability } from '@strapi/admin/strapi-admin/ee';\n\nimport { isAIMetadataSupportedMime } from '../../../../shared/constants';\nimport { useGetUploadSettingsQuery } from '../services/settings';\n\n/**\n * Whether the replace flow will actually regenerate AI metadata, so the UI only\n * promises it when it happens.\n *\n * Two independent gates, both required — `GET /upload/settings` returns the\n * stored `aiMetadata` toggle on its own, which stays `true` (its default) on\n * licenses without AI, so the setting alone over-promises. The server's own\n * check (`aiMetadata.isEnabled()`) ANDs the same two conditions.\n *\n * Pass `{ mime }` to add the third gate the replace flow applies: it only\n * regenerates metadata for images the AI provider can read\n * (`admin-upload.replaceFile` → `aiMetadata.processFiles`, which filters on this\n * same allowlist). Promising it for a PDF — or for a GIF, which clears the\n * server's looser `image/*` gate but is skipped by the provider — would describe\n * something that never happens.\n *\n * The argument is an object rather than a bare `mime` so the two intents stay\n * distinguishable: `File.mime` is optional on the contract, so a positional\n * parameter let `useAIMetadataEnabled(asset.mime)` collapse into the ungated\n * call whenever the mime was missing — silently taking the permissive path this\n * hook exists to close. `useAIMetadataEnabled({ mime: undefined })` still gates\n * (and fails closed); only an omitted `options` skips the mime check.\n */\nexport const useAIMetadataEnabled = (options?: { mime?: string | null }): boolean => {\n const isAIAvailable = useAIAvailability();\n const { data: settings } = useGetUploadSettingsQuery();\n\n if (!isAIAvailable || !(settings?.data?.aiMetadata ?? false)) {\n return false;\n }\n\n return options === undefined ? true : isAIMetadataSupportedMime(options.mime);\n};\n"],"names":["useAIMetadataEnabled","options","isAIAvailable","useAIAvailability","data","settings","useGetUploadSettingsQuery","aiMetadata","undefined","isAIMetadataSupportedMime","mime"],"mappings":";;;;;;AAKA;;;;;;;;;;;;;;;;;;;;;;IAuBO,MAAMA,oBAAAA,GAAuB,CAACC,OAAAA,GAAAA;AACnC,IAAA,MAAMC,aAAAA,GAAgBC,oBAAAA,EAAAA;AACtB,IAAA,MAAM,EAAEC,IAAAA,EAAMC,UAAQ,EAAE,GAAGC,kCAAAA,EAAAA;IAE3B,IAAI,CAACJ,iBAAiB,EAAEG,YAAUD,IAAAA,EAAMG,UAAAA,IAAc,KAAI,CAAA,EAAI;QAC5D,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,OAAON,OAAAA,KAAYO,SAAAA,GAAY,IAAA,GAAOC,mCAAAA,CAA0BR,QAAQS,IAAI,CAAA;AAC9E;;;;"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useAIAvailability } from '@strapi/admin/strapi-admin/ee';
|
|
2
|
+
import { isAIMetadataSupportedMime } from '../../shared/constants.mjs';
|
|
3
|
+
import { useGetUploadSettingsQuery } from '../services/settings.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Whether the replace flow will actually regenerate AI metadata, so the UI only
|
|
7
|
+
* promises it when it happens.
|
|
8
|
+
*
|
|
9
|
+
* Two independent gates, both required — `GET /upload/settings` returns the
|
|
10
|
+
* stored `aiMetadata` toggle on its own, which stays `true` (its default) on
|
|
11
|
+
* licenses without AI, so the setting alone over-promises. The server's own
|
|
12
|
+
* check (`aiMetadata.isEnabled()`) ANDs the same two conditions.
|
|
13
|
+
*
|
|
14
|
+
* Pass `{ mime }` to add the third gate the replace flow applies: it only
|
|
15
|
+
* regenerates metadata for images the AI provider can read
|
|
16
|
+
* (`admin-upload.replaceFile` → `aiMetadata.processFiles`, which filters on this
|
|
17
|
+
* same allowlist). Promising it for a PDF — or for a GIF, which clears the
|
|
18
|
+
* server's looser `image/*` gate but is skipped by the provider — would describe
|
|
19
|
+
* something that never happens.
|
|
20
|
+
*
|
|
21
|
+
* The argument is an object rather than a bare `mime` so the two intents stay
|
|
22
|
+
* distinguishable: `File.mime` is optional on the contract, so a positional
|
|
23
|
+
* parameter let `useAIMetadataEnabled(asset.mime)` collapse into the ungated
|
|
24
|
+
* call whenever the mime was missing — silently taking the permissive path this
|
|
25
|
+
* hook exists to close. `useAIMetadataEnabled({ mime: undefined })` still gates
|
|
26
|
+
* (and fails closed); only an omitted `options` skips the mime check.
|
|
27
|
+
*/ const useAIMetadataEnabled = (options)=>{
|
|
28
|
+
const isAIAvailable = useAIAvailability();
|
|
29
|
+
const { data: settings } = useGetUploadSettingsQuery();
|
|
30
|
+
if (!isAIAvailable || !(settings?.data?.aiMetadata ?? false)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return options === undefined ? true : isAIMetadataSupportedMime(options.mime);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export { useAIMetadataEnabled };
|
|
37
|
+
//# sourceMappingURL=useAIMetadataEnabled.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAIMetadataEnabled.mjs","sources":["../../../../admin/src/future/hooks/useAIMetadataEnabled.ts"],"sourcesContent":["import { useAIAvailability } from '@strapi/admin/strapi-admin/ee';\n\nimport { isAIMetadataSupportedMime } from '../../../../shared/constants';\nimport { useGetUploadSettingsQuery } from '../services/settings';\n\n/**\n * Whether the replace flow will actually regenerate AI metadata, so the UI only\n * promises it when it happens.\n *\n * Two independent gates, both required — `GET /upload/settings` returns the\n * stored `aiMetadata` toggle on its own, which stays `true` (its default) on\n * licenses without AI, so the setting alone over-promises. The server's own\n * check (`aiMetadata.isEnabled()`) ANDs the same two conditions.\n *\n * Pass `{ mime }` to add the third gate the replace flow applies: it only\n * regenerates metadata for images the AI provider can read\n * (`admin-upload.replaceFile` → `aiMetadata.processFiles`, which filters on this\n * same allowlist). Promising it for a PDF — or for a GIF, which clears the\n * server's looser `image/*` gate but is skipped by the provider — would describe\n * something that never happens.\n *\n * The argument is an object rather than a bare `mime` so the two intents stay\n * distinguishable: `File.mime` is optional on the contract, so a positional\n * parameter let `useAIMetadataEnabled(asset.mime)` collapse into the ungated\n * call whenever the mime was missing — silently taking the permissive path this\n * hook exists to close. `useAIMetadataEnabled({ mime: undefined })` still gates\n * (and fails closed); only an omitted `options` skips the mime check.\n */\nexport const useAIMetadataEnabled = (options?: { mime?: string | null }): boolean => {\n const isAIAvailable = useAIAvailability();\n const { data: settings } = useGetUploadSettingsQuery();\n\n if (!isAIAvailable || !(settings?.data?.aiMetadata ?? false)) {\n return false;\n }\n\n return options === undefined ? true : isAIMetadataSupportedMime(options.mime);\n};\n"],"names":["useAIMetadataEnabled","options","isAIAvailable","useAIAvailability","data","settings","useGetUploadSettingsQuery","aiMetadata","undefined","isAIMetadataSupportedMime","mime"],"mappings":";;;;AAKA;;;;;;;;;;;;;;;;;;;;;;IAuBO,MAAMA,oBAAAA,GAAuB,CAACC,OAAAA,GAAAA;AACnC,IAAA,MAAMC,aAAAA,GAAgBC,iBAAAA,EAAAA;AACtB,IAAA,MAAM,EAAEC,IAAAA,EAAMC,QAAQ,EAAE,GAAGC,yBAAAA,EAAAA;IAE3B,IAAI,CAACJ,iBAAiB,EAAEG,UAAUD,IAAAA,EAAMG,UAAAA,IAAc,KAAI,CAAA,EAAI;QAC5D,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,OAAON,OAAAA,KAAYO,SAAAA,GAAY,IAAA,GAAOC,yBAAAA,CAA0BR,QAAQS,IAAI,CAAA;AAC9E;;;;"}
|