@strapi/upload 5.51.2 → 5.52.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/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/components/TruncatedText.js +76 -0
- package/dist/admin/future/components/TruncatedText.js.map +1 -0
- package/dist/admin/future/components/TruncatedText.mjs +74 -0
- package/dist/admin/future/components/TruncatedText.mjs.map +1 -0
- 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/hooks/useTracking.js +57 -0
- package/dist/admin/future/hooks/useTracking.js.map +1 -0
- package/dist/admin/future/hooks/useTracking.mjs +53 -0
- package/dist/admin/future/hooks/useTracking.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/AssetsPage.js +328 -139
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +332 -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 +328 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +326 -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 +74 -53
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +74 -54
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js +92 -28
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +94 -30
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +26 -4
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +27 -5
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.js +172 -60
- package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +175 -63
- 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 +259 -63
- package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +262 -66
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +146 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +144 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.js → FolderFormDialog.js} +62 -16
- package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.mjs → FolderFormDialog.mjs} +64 -18
- package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +132 -229
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +135 -232
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/SortMenu.js +14 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/SortMenu.mjs +14 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +5 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +6 -1
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.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/pages/Assets/utils/selection.js +17 -0
- package/dist/admin/future/pages/Assets/utils/selection.js.map +1 -1
- package/dist/admin/future/pages/Assets/utils/selection.mjs +17 -1
- package/dist/admin/future/pages/Assets/utils/selection.mjs.map +1 -1
- package/dist/admin/future/services/api.js +31 -8
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +31 -8
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/services/assets.js +22 -23
- package/dist/admin/future/services/assets.js.map +1 -1
- package/dist/admin/future/services/assets.mjs +22 -23
- 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/hooks/useAIMetadataJob.js +1 -1
- package/dist/admin/hooks/useAIMetadataJob.js.map +1 -1
- package/dist/admin/hooks/useAIMetadataJob.mjs +1 -1
- package/dist/admin/hooks/useAIMetadataJob.mjs.map +1 -1
- 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/pages/SettingsPage/SettingsPage.js +2 -2
- package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs +2 -2
- package/dist/admin/pages/SettingsPage/SettingsPage.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/components/TruncatedText.d.ts +32 -0
- package/dist/admin/src/future/hooks/useAIMetadataEnabled.d.ts +26 -0
- package/dist/admin/src/future/hooks/useTracking.d.ts +29 -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 +26 -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 +21 -0
- package/dist/admin/src/future/pages/Assets/components/FolderFormDialog.d.ts +16 -0
- package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +2 -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/pages/Assets/utils/selection.d.ts +10 -0
- package/dist/admin/src/future/services/api.d.ts +6 -7
- 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/controllers/admin-file.js +27 -9
- package/dist/server/controllers/admin-file.js.map +1 -1
- package/dist/server/controllers/admin-file.mjs +27 -9
- package/dist/server/controllers/admin-file.mjs.map +1 -1
- package/dist/server/controllers/admin-upload.js +24 -8
- package/dist/server/controllers/admin-upload.js.map +1 -1
- package/dist/server/controllers/admin-upload.mjs +24 -8
- package/dist/server/controllers/admin-upload.mjs.map +1 -1
- package/dist/server/routes/admin.js +41 -21
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/admin.mjs +41 -21
- package/dist/server/routes/admin.mjs.map +1 -1
- package/dist/server/services/ai-metadata.js.map +1 -1
- package/dist/server/services/ai-metadata.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/controllers/admin-file.d.ts +29 -8
- package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-upload.d.ts +20 -4
- package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +4 -4
- package/dist/server/src/index.d.ts +4 -4
- package/dist/server/src/routes/admin.d.ts.map +1 -1
- package/dist/server/src/services/ai-metadata.d.ts +2 -2
- package/dist/server/src/services/ai-metadata.d.ts.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/dist/shared/contracts/ai-metadata-jobs.d.ts +10 -32
- package/dist/shared/contracts/ai-metadata-jobs.d.ts.map +1 -1
- package/dist/shared/contracts/files.d.ts +10 -10
- package/dist/shared/contracts/files.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
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
|
+
import { Tooltip, Typography } from '@strapi/design-system';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Text that ellipsizes, with a tooltip carrying the full value once it actually
|
|
7
|
+
* does. Used for folder and asset names, which are user-supplied and routinely
|
|
8
|
+
* longer than the column, card or rail holding them.
|
|
9
|
+
*
|
|
10
|
+
* The tooltip is conditional rather than always-on: a permanent tooltip would
|
|
11
|
+
* make every short name hoverable for no reason, and would announce a
|
|
12
|
+
* description that merely repeats the visible text.
|
|
13
|
+
*
|
|
14
|
+
* Whether the text is truncated can't be derived from the string — it depends on
|
|
15
|
+
* the rendered width — so it has to be measured. That measurement happens when
|
|
16
|
+
* the pointer or focus arrives, not at mount.
|
|
17
|
+
*
|
|
18
|
+
* Measuring at mount is the obvious approach and it does not work here. The
|
|
19
|
+
* reading is only correct once the row's width constraint has reached this span,
|
|
20
|
+
* and the tree remounts its rows during first render: the instance that survives
|
|
21
|
+
* can take its one measurement while still unconstrained, conclude it fits, and
|
|
22
|
+
* be stuck there. Nothing corrects it afterwards, because a ResizeObserver on
|
|
23
|
+
* this span never fires again — an ancestor clamps the row, so the text
|
|
24
|
+
* overflows inside a box whose own size stops changing.
|
|
25
|
+
*
|
|
26
|
+
* Reading on hover sidesteps all of that. It is the only moment the answer is
|
|
27
|
+
* needed, the layout is settled by then, and nothing is cached across remounts
|
|
28
|
+
* or resizes that could go stale.
|
|
29
|
+
*/ const TruncatedText = ({ children, ...props })=>{
|
|
30
|
+
const textRef = useRef(null);
|
|
31
|
+
const [isTruncated, setIsTruncated] = useState(false);
|
|
32
|
+
const checkTruncation = ()=>{
|
|
33
|
+
const el = textRef.current;
|
|
34
|
+
if (el) {
|
|
35
|
+
setIsTruncated(el.scrollWidth > el.clientWidth);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
// A ref callback rather than useRef alone, so the first measurement happens
|
|
39
|
+
// when the node attaches and again whenever it is replaced. The tree remounts
|
|
40
|
+
// its rows during first render, and a value measured against the discarded
|
|
41
|
+
// node would never be revisited — this re-runs against the node that survives.
|
|
42
|
+
const attachRef = (el)=>{
|
|
43
|
+
textRef.current = el;
|
|
44
|
+
if (el) {
|
|
45
|
+
checkTruncation();
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
// The Tooltip stays mounted and the *label* is what's conditional, rather than
|
|
49
|
+
// swapping between a wrapped and unwrapped span. Swapping loses the first
|
|
50
|
+
// hover: the measurement that decides to show a tooltip is itself triggered by
|
|
51
|
+
// the pointer arriving, so the trigger would mount underneath a pointer that
|
|
52
|
+
// has already entered, and Radix — which starts watching at mount — sees no
|
|
53
|
+
// enter event and stays closed until the pointer leaves and returns.
|
|
54
|
+
//
|
|
55
|
+
// With `label` empty the DS Tooltip renders its child as-is and attaches
|
|
56
|
+
// nothing, so untruncated text still costs no DOM node and announces no
|
|
57
|
+
// description duplicating what is already on screen.
|
|
58
|
+
return /*#__PURE__*/ jsx(Tooltip, {
|
|
59
|
+
label: isTruncated ? children : undefined,
|
|
60
|
+
children: /*#__PURE__*/ jsx(Typography, {
|
|
61
|
+
ref: attachRef,
|
|
62
|
+
ellipsis: true,
|
|
63
|
+
// Focus is covered as well as hover: the tooltip has to be reachable by
|
|
64
|
+
// keyboard, and these rows are buttons.
|
|
65
|
+
onPointerEnter: checkTruncation,
|
|
66
|
+
onFocus: checkTruncation,
|
|
67
|
+
...props,
|
|
68
|
+
children: children
|
|
69
|
+
})
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export { TruncatedText };
|
|
74
|
+
//# sourceMappingURL=TruncatedText.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TruncatedText.mjs","sources":["../../../../admin/src/future/components/TruncatedText.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\n\nimport { Tooltip, Typography, type TypographyProps } from '@strapi/design-system';\n\ninterface TruncatedTextProps extends Omit<TypographyProps, 'children' | 'ellipsis'> {\n /** The full text. Doubles as the tooltip content once it no longer fits. */\n children: string;\n}\n\n/**\n * Text that ellipsizes, with a tooltip carrying the full value once it actually\n * does. Used for folder and asset names, which are user-supplied and routinely\n * longer than the column, card or rail holding them.\n *\n * The tooltip is conditional rather than always-on: a permanent tooltip would\n * make every short name hoverable for no reason, and would announce a\n * description that merely repeats the visible text.\n *\n * Whether the text is truncated can't be derived from the string — it depends on\n * the rendered width — so it has to be measured. That measurement happens when\n * the pointer or focus arrives, not at mount.\n *\n * Measuring at mount is the obvious approach and it does not work here. The\n * reading is only correct once the row's width constraint has reached this span,\n * and the tree remounts its rows during first render: the instance that survives\n * can take its one measurement while still unconstrained, conclude it fits, and\n * be stuck there. Nothing corrects it afterwards, because a ResizeObserver on\n * this span never fires again — an ancestor clamps the row, so the text\n * overflows inside a box whose own size stops changing.\n *\n * Reading on hover sidesteps all of that. It is the only moment the answer is\n * needed, the layout is settled by then, and nothing is cached across remounts\n * or resizes that could go stale.\n */\nexport const TruncatedText = ({ children, ...props }: TruncatedTextProps) => {\n const textRef = useRef<HTMLSpanElement | null>(null);\n const [isTruncated, setIsTruncated] = useState(false);\n\n const checkTruncation = () => {\n const el = textRef.current;\n\n if (el) {\n setIsTruncated(el.scrollWidth > el.clientWidth);\n }\n };\n\n // A ref callback rather than useRef alone, so the first measurement happens\n // when the node attaches and again whenever it is replaced. The tree remounts\n // its rows during first render, and a value measured against the discarded\n // node would never be revisited — this re-runs against the node that survives.\n const attachRef = (el: HTMLSpanElement | null) => {\n textRef.current = el;\n\n if (el) {\n checkTruncation();\n }\n };\n\n // The Tooltip stays mounted and the *label* is what's conditional, rather than\n // swapping between a wrapped and unwrapped span. Swapping loses the first\n // hover: the measurement that decides to show a tooltip is itself triggered by\n // the pointer arriving, so the trigger would mount underneath a pointer that\n // has already entered, and Radix — which starts watching at mount — sees no\n // enter event and stays closed until the pointer leaves and returns.\n //\n // With `label` empty the DS Tooltip renders its child as-is and attaches\n // nothing, so untruncated text still costs no DOM node and announces no\n // description duplicating what is already on screen.\n return (\n <Tooltip label={isTruncated ? children : undefined}>\n <Typography\n ref={attachRef}\n ellipsis\n // Focus is covered as well as hover: the tooltip has to be reachable by\n // keyboard, and these rows are buttons.\n onPointerEnter={checkTruncation}\n onFocus={checkTruncation}\n {...props}\n >\n {children}\n </Typography>\n </Tooltip>\n );\n};\n"],"names":["TruncatedText","children","props","textRef","useRef","isTruncated","setIsTruncated","useState","checkTruncation","el","current","scrollWidth","clientWidth","attachRef","_jsx","Tooltip","label","undefined","Typography","ref","ellipsis","onPointerEnter","onFocus"],"mappings":";;;;AASA;;;;;;;;;;;;;;;;;;;;;;;;UAyBaA,aAAAA,GAAgB,CAAC,EAAEC,QAAQ,EAAE,GAAGC,KAAAA,EAA2B,GAAA;AACtE,IAAA,MAAMC,UAAUC,MAAAA,CAA+B,IAAA,CAAA;AAC/C,IAAA,MAAM,CAACC,WAAAA,EAAaC,cAAAA,CAAe,GAAGC,QAAAA,CAAS,KAAA,CAAA;AAE/C,IAAA,MAAMC,eAAAA,GAAkB,IAAA;QACtB,MAAMC,EAAAA,GAAKN,QAAQO,OAAO;AAE1B,QAAA,IAAID,EAAAA,EAAI;AACNH,YAAAA,cAAAA,CAAeG,EAAAA,CAAGE,WAAW,GAAGF,EAAAA,CAAGG,WAAW,CAAA;AAChD,QAAA;AACF,IAAA,CAAA;;;;;AAMA,IAAA,MAAMC,YAAY,CAACJ,EAAAA,GAAAA;AACjBN,QAAAA,OAAAA,CAAQO,OAAO,GAAGD,EAAAA;AAElB,QAAA,IAAIA,EAAAA,EAAI;AACND,YAAAA,eAAAA,EAAAA;AACF,QAAA;AACF,IAAA,CAAA;;;;;;;;;;;AAYA,IAAA,qBACEM,GAAA,CAACC,OAAAA,EAAAA;AAAQC,QAAAA,KAAAA,EAAOX,cAAcJ,QAAAA,GAAWgB,SAAAA;AACvC,QAAA,QAAA,gBAAAH,GAAA,CAACI,UAAAA,EAAAA;YACCC,GAAAA,EAAKN,SAAAA;YACLO,QAAQ,EAAA,IAAA;;;YAGRC,cAAAA,EAAgBb,eAAAA;YAChBc,OAAAA,EAASd,eAAAA;AACR,YAAA,GAAGN,KAAK;AAERD,YAAAA,QAAAA,EAAAA;;;AAIT;;;;"}
|
|
@@ -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;;;;"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var strapiAdmin = require('@strapi/admin/strapi-admin');
|
|
5
|
+
var ee = require('@strapi/admin/strapi-admin/ee');
|
|
6
|
+
var settings = require('../services/settings.js');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Media Library version tag stamped on every event fired from the new
|
|
10
|
+
* (`src/future`) Media Library. Legacy events omit it, so analytics can filter
|
|
11
|
+
* new usage from the old plan while both trees emit the SAME event names (see
|
|
12
|
+
* CMS-246). Bump this if a future revamp ever needs its own bucket.
|
|
13
|
+
*/ const MEDIA_LIBRARY_VERSION = 'v2';
|
|
14
|
+
/**
|
|
15
|
+
* `location` value for every new Media Library event. The new tree is the
|
|
16
|
+
* standalone Media Library page, which the legacy plan tags `'upload'` (as
|
|
17
|
+
* opposed to `'content-manager'` for the asset-picker modal). Kept identical so
|
|
18
|
+
* migrated events line up with the legacy ones on the `location` axis.
|
|
19
|
+
*/ const MEDIA_LIBRARY_LOCATION = 'upload';
|
|
20
|
+
/**
|
|
21
|
+
* Tracking wrapper scoped to the new Media Library. Mirrors the legacy
|
|
22
|
+
* `admin/src/hooks/useTracking` — it forwards to the admin `trackUsage` and
|
|
23
|
+
* injects `isAiMediaLibraryConfigured` when AI is available — and additionally
|
|
24
|
+
* stamps `mediaLibraryVersion` on every event so the migrated plan stays
|
|
25
|
+
* distinguishable from the legacy one.
|
|
26
|
+
*
|
|
27
|
+
* The cast mirrors the legacy wrapper: these two properties are cross-cutting
|
|
28
|
+
* media-tracking metadata that the admin `TrackingEvent` type does not (and
|
|
29
|
+
* should not) enumerate per event.
|
|
30
|
+
*/ const useTracking = ()=>{
|
|
31
|
+
const { trackUsage: trackStrapiUsage } = strapiAdmin.useTracking();
|
|
32
|
+
const { data } = settings.useGetUploadSettingsQuery();
|
|
33
|
+
const isAiAvailable = ee.useAIAvailability();
|
|
34
|
+
// Memoised so consumers can safely list `trackUsage` in effect deps (the
|
|
35
|
+
// search-input debounce commit does) without re-firing every render.
|
|
36
|
+
const trackUsage = React.useCallback((event, properties)=>{
|
|
37
|
+
return trackStrapiUsage(event, {
|
|
38
|
+
...properties,
|
|
39
|
+
...isAiAvailable ? {
|
|
40
|
+
isAiMediaLibraryConfigured: Boolean(data?.data?.aiMetadata)
|
|
41
|
+
} : {},
|
|
42
|
+
mediaLibraryVersion: MEDIA_LIBRARY_VERSION
|
|
43
|
+
});
|
|
44
|
+
}, [
|
|
45
|
+
trackStrapiUsage,
|
|
46
|
+
isAiAvailable,
|
|
47
|
+
data
|
|
48
|
+
]);
|
|
49
|
+
return {
|
|
50
|
+
trackUsage
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
exports.MEDIA_LIBRARY_LOCATION = MEDIA_LIBRARY_LOCATION;
|
|
55
|
+
exports.MEDIA_LIBRARY_VERSION = MEDIA_LIBRARY_VERSION;
|
|
56
|
+
exports.useTracking = useTracking;
|
|
57
|
+
//# sourceMappingURL=useTracking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTracking.js","sources":["../../../../admin/src/future/hooks/useTracking.ts"],"sourcesContent":["import { useCallback } from 'react';\n\nimport { useTracking as useStrapiTracking, type TrackingEvent } from '@strapi/admin/strapi-admin';\nimport { useAIAvailability } from '@strapi/admin/strapi-admin/ee';\n\nimport { useGetUploadSettingsQuery } from '../services/settings';\n\n/**\n * Media Library version tag stamped on every event fired from the new\n * (`src/future`) Media Library. Legacy events omit it, so analytics can filter\n * new usage from the old plan while both trees emit the SAME event names (see\n * CMS-246). Bump this if a future revamp ever needs its own bucket.\n */\nexport const MEDIA_LIBRARY_VERSION = 'v2';\n\n/**\n * `location` value for every new Media Library event. The new tree is the\n * standalone Media Library page, which the legacy plan tags `'upload'` (as\n * opposed to `'content-manager'` for the asset-picker modal). Kept identical so\n * migrated events line up with the legacy ones on the `location` axis.\n */\nexport const MEDIA_LIBRARY_LOCATION = 'upload';\n\n/**\n * Tracking wrapper scoped to the new Media Library. Mirrors the legacy\n * `admin/src/hooks/useTracking` — it forwards to the admin `trackUsage` and\n * injects `isAiMediaLibraryConfigured` when AI is available — and additionally\n * stamps `mediaLibraryVersion` on every event so the migrated plan stays\n * distinguishable from the legacy one.\n *\n * The cast mirrors the legacy wrapper: these two properties are cross-cutting\n * media-tracking metadata that the admin `TrackingEvent` type does not (and\n * should not) enumerate per event.\n */\nexport const useTracking = () => {\n const { trackUsage: trackStrapiUsage } = useStrapiTracking();\n const { data } = useGetUploadSettingsQuery();\n const isAiAvailable = useAIAvailability();\n\n // Memoised so consumers can safely list `trackUsage` in effect deps (the\n // search-input debounce commit does) without re-firing every render.\n const trackUsage = useCallback(\n <TEvent extends TrackingEvent>(event: TEvent['name'], properties?: TEvent['properties']) => {\n return trackStrapiUsage(event, {\n ...properties,\n ...(isAiAvailable ? { isAiMediaLibraryConfigured: Boolean(data?.data?.aiMetadata) } : {}),\n mediaLibraryVersion: MEDIA_LIBRARY_VERSION,\n } as TEvent['properties']);\n },\n [trackStrapiUsage, isAiAvailable, data]\n );\n\n return { trackUsage };\n};\n"],"names":["MEDIA_LIBRARY_VERSION","MEDIA_LIBRARY_LOCATION","useTracking","trackUsage","trackStrapiUsage","useStrapiTracking","data","useGetUploadSettingsQuery","isAiAvailable","useAIAvailability","useCallback","event","properties","isAiMediaLibraryConfigured","Boolean","aiMetadata","mediaLibraryVersion"],"mappings":";;;;;;;AAOA;;;;;IAMO,MAAMA,qBAAAA,GAAwB;AAErC;;;;;IAMO,MAAMC,sBAAAA,GAAyB;AAEtC;;;;;;;;;;UAWaC,WAAAA,GAAc,IAAA;AACzB,IAAA,MAAM,EAAEC,UAAAA,EAAYC,gBAAgB,EAAE,GAAGC,uBAAAA,EAAAA;IACzC,MAAM,EAAEC,IAAI,EAAE,GAAGC,kCAAAA,EAAAA;AACjB,IAAA,MAAMC,aAAAA,GAAgBC,oBAAAA,EAAAA;;;IAItB,MAAMN,UAAAA,GAAaO,iBAAAA,CACjB,CAA+BC,KAAAA,EAAuBC,UAAAA,GAAAA;AACpD,QAAA,OAAOR,iBAAiBO,KAAAA,EAAO;AAC7B,YAAA,GAAGC,UAAU;AACb,YAAA,GAAIJ,aAAAA,GAAgB;gBAAEK,0BAAAA,EAA4BC,OAAAA,CAAQR,MAAMA,IAAAA,EAAMS,UAAAA;AAAY,aAAA,GAAI,EAAE;YACxFC,mBAAAA,EAAqBhB;AACvB,SAAA,CAAA;IACF,CAAA,EACA;AAACI,QAAAA,gBAAAA;AAAkBI,QAAAA,aAAAA;AAAeF,QAAAA;AAAK,KAAA,CAAA;IAGzC,OAAO;AAAEH,QAAAA;AAAW,KAAA;AACtB;;;;;;"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { useTracking as useTracking$1 } from '@strapi/admin/strapi-admin';
|
|
3
|
+
import { useAIAvailability } from '@strapi/admin/strapi-admin/ee';
|
|
4
|
+
import { useGetUploadSettingsQuery } from '../services/settings.mjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Media Library version tag stamped on every event fired from the new
|
|
8
|
+
* (`src/future`) Media Library. Legacy events omit it, so analytics can filter
|
|
9
|
+
* new usage from the old plan while both trees emit the SAME event names (see
|
|
10
|
+
* CMS-246). Bump this if a future revamp ever needs its own bucket.
|
|
11
|
+
*/ const MEDIA_LIBRARY_VERSION = 'v2';
|
|
12
|
+
/**
|
|
13
|
+
* `location` value for every new Media Library event. The new tree is the
|
|
14
|
+
* standalone Media Library page, which the legacy plan tags `'upload'` (as
|
|
15
|
+
* opposed to `'content-manager'` for the asset-picker modal). Kept identical so
|
|
16
|
+
* migrated events line up with the legacy ones on the `location` axis.
|
|
17
|
+
*/ const MEDIA_LIBRARY_LOCATION = 'upload';
|
|
18
|
+
/**
|
|
19
|
+
* Tracking wrapper scoped to the new Media Library. Mirrors the legacy
|
|
20
|
+
* `admin/src/hooks/useTracking` — it forwards to the admin `trackUsage` and
|
|
21
|
+
* injects `isAiMediaLibraryConfigured` when AI is available — and additionally
|
|
22
|
+
* stamps `mediaLibraryVersion` on every event so the migrated plan stays
|
|
23
|
+
* distinguishable from the legacy one.
|
|
24
|
+
*
|
|
25
|
+
* The cast mirrors the legacy wrapper: these two properties are cross-cutting
|
|
26
|
+
* media-tracking metadata that the admin `TrackingEvent` type does not (and
|
|
27
|
+
* should not) enumerate per event.
|
|
28
|
+
*/ const useTracking = ()=>{
|
|
29
|
+
const { trackUsage: trackStrapiUsage } = useTracking$1();
|
|
30
|
+
const { data } = useGetUploadSettingsQuery();
|
|
31
|
+
const isAiAvailable = useAIAvailability();
|
|
32
|
+
// Memoised so consumers can safely list `trackUsage` in effect deps (the
|
|
33
|
+
// search-input debounce commit does) without re-firing every render.
|
|
34
|
+
const trackUsage = useCallback((event, properties)=>{
|
|
35
|
+
return trackStrapiUsage(event, {
|
|
36
|
+
...properties,
|
|
37
|
+
...isAiAvailable ? {
|
|
38
|
+
isAiMediaLibraryConfigured: Boolean(data?.data?.aiMetadata)
|
|
39
|
+
} : {},
|
|
40
|
+
mediaLibraryVersion: MEDIA_LIBRARY_VERSION
|
|
41
|
+
});
|
|
42
|
+
}, [
|
|
43
|
+
trackStrapiUsage,
|
|
44
|
+
isAiAvailable,
|
|
45
|
+
data
|
|
46
|
+
]);
|
|
47
|
+
return {
|
|
48
|
+
trackUsage
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export { MEDIA_LIBRARY_LOCATION, MEDIA_LIBRARY_VERSION, useTracking };
|
|
53
|
+
//# sourceMappingURL=useTracking.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTracking.mjs","sources":["../../../../admin/src/future/hooks/useTracking.ts"],"sourcesContent":["import { useCallback } from 'react';\n\nimport { useTracking as useStrapiTracking, type TrackingEvent } from '@strapi/admin/strapi-admin';\nimport { useAIAvailability } from '@strapi/admin/strapi-admin/ee';\n\nimport { useGetUploadSettingsQuery } from '../services/settings';\n\n/**\n * Media Library version tag stamped on every event fired from the new\n * (`src/future`) Media Library. Legacy events omit it, so analytics can filter\n * new usage from the old plan while both trees emit the SAME event names (see\n * CMS-246). Bump this if a future revamp ever needs its own bucket.\n */\nexport const MEDIA_LIBRARY_VERSION = 'v2';\n\n/**\n * `location` value for every new Media Library event. The new tree is the\n * standalone Media Library page, which the legacy plan tags `'upload'` (as\n * opposed to `'content-manager'` for the asset-picker modal). Kept identical so\n * migrated events line up with the legacy ones on the `location` axis.\n */\nexport const MEDIA_LIBRARY_LOCATION = 'upload';\n\n/**\n * Tracking wrapper scoped to the new Media Library. Mirrors the legacy\n * `admin/src/hooks/useTracking` — it forwards to the admin `trackUsage` and\n * injects `isAiMediaLibraryConfigured` when AI is available — and additionally\n * stamps `mediaLibraryVersion` on every event so the migrated plan stays\n * distinguishable from the legacy one.\n *\n * The cast mirrors the legacy wrapper: these two properties are cross-cutting\n * media-tracking metadata that the admin `TrackingEvent` type does not (and\n * should not) enumerate per event.\n */\nexport const useTracking = () => {\n const { trackUsage: trackStrapiUsage } = useStrapiTracking();\n const { data } = useGetUploadSettingsQuery();\n const isAiAvailable = useAIAvailability();\n\n // Memoised so consumers can safely list `trackUsage` in effect deps (the\n // search-input debounce commit does) without re-firing every render.\n const trackUsage = useCallback(\n <TEvent extends TrackingEvent>(event: TEvent['name'], properties?: TEvent['properties']) => {\n return trackStrapiUsage(event, {\n ...properties,\n ...(isAiAvailable ? { isAiMediaLibraryConfigured: Boolean(data?.data?.aiMetadata) } : {}),\n mediaLibraryVersion: MEDIA_LIBRARY_VERSION,\n } as TEvent['properties']);\n },\n [trackStrapiUsage, isAiAvailable, data]\n );\n\n return { trackUsage };\n};\n"],"names":["MEDIA_LIBRARY_VERSION","MEDIA_LIBRARY_LOCATION","useTracking","trackUsage","trackStrapiUsage","useStrapiTracking","data","useGetUploadSettingsQuery","isAiAvailable","useAIAvailability","useCallback","event","properties","isAiMediaLibraryConfigured","Boolean","aiMetadata","mediaLibraryVersion"],"mappings":";;;;;AAOA;;;;;IAMO,MAAMA,qBAAAA,GAAwB;AAErC;;;;;IAMO,MAAMC,sBAAAA,GAAyB;AAEtC;;;;;;;;;;UAWaC,WAAAA,GAAc,IAAA;AACzB,IAAA,MAAM,EAAEC,UAAAA,EAAYC,gBAAgB,EAAE,GAAGC,aAAAA,EAAAA;IACzC,MAAM,EAAEC,IAAI,EAAE,GAAGC,yBAAAA,EAAAA;AACjB,IAAA,MAAMC,aAAAA,GAAgBC,iBAAAA,EAAAA;;;IAItB,MAAMN,UAAAA,GAAaO,WAAAA,CACjB,CAA+BC,KAAAA,EAAuBC,UAAAA,GAAAA;AACpD,QAAA,OAAOR,iBAAiBO,KAAAA,EAAO;AAC7B,YAAA,GAAGC,UAAU;AACb,YAAA,GAAIJ,aAAAA,GAAgB;gBAAEK,0BAAAA,EAA4BC,OAAAA,CAAQR,MAAMA,IAAAA,EAAMS,UAAAA;AAAY,aAAA,GAAI,EAAE;YACxFC,mBAAAA,EAAqBhB;AACvB,SAAA,CAAA;IACF,CAAA,EACA;AAACI,QAAAA,gBAAAA;AAAkBI,QAAAA,aAAAA;AAAeF,QAAAA;AAAK,KAAA,CAAA;IAGzC,OAAO;AAAEH,QAAAA;AAAW,KAAA;AACtB;;;;"}
|