@strapi/upload 5.52.0 → 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.
Files changed (111) hide show
  1. package/dist/admin/future/components/TruncatedText.js +76 -0
  2. package/dist/admin/future/components/TruncatedText.js.map +1 -0
  3. package/dist/admin/future/components/TruncatedText.mjs +74 -0
  4. package/dist/admin/future/components/TruncatedText.mjs.map +1 -0
  5. package/dist/admin/future/hooks/useTracking.js +57 -0
  6. package/dist/admin/future/hooks/useTracking.js.map +1 -0
  7. package/dist/admin/future/hooks/useTracking.mjs +53 -0
  8. package/dist/admin/future/hooks/useTracking.mjs.map +1 -0
  9. package/dist/admin/future/pages/Assets/AssetsPage.js +31 -0
  10. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  11. package/dist/admin/future/pages/Assets/AssetsPage.mjs +31 -0
  12. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  13. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +9 -6
  14. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -1
  15. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +9 -6
  16. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -1
  17. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +21 -1
  18. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  19. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +21 -1
  20. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  21. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +3 -4
  22. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  23. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +4 -5
  24. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  25. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +11 -1
  26. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -1
  27. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +11 -1
  28. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
  29. package/dist/admin/future/pages/Assets/components/AssetsTable.js +6 -4
  30. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  31. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +6 -4
  32. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  33. package/dist/admin/future/pages/Assets/components/FilterMenu.js +18 -2
  34. package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -1
  35. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +18 -2
  36. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -1
  37. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +9 -7
  38. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -1
  39. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +9 -7
  40. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -1
  41. package/dist/admin/future/pages/Assets/components/FolderFormDialog.js +12 -0
  42. package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -1
  43. package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs +12 -0
  44. package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -1
  45. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +21 -38
  46. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  47. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +23 -40
  48. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  49. package/dist/admin/future/pages/Assets/components/SortMenu.js +14 -0
  50. package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -1
  51. package/dist/admin/future/pages/Assets/components/SortMenu.mjs +14 -0
  52. package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -1
  53. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +5 -0
  54. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  55. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +6 -1
  56. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  57. package/dist/admin/future/pages/Assets/utils/selection.js +17 -0
  58. package/dist/admin/future/pages/Assets/utils/selection.js.map +1 -1
  59. package/dist/admin/future/pages/Assets/utils/selection.mjs +17 -1
  60. package/dist/admin/future/pages/Assets/utils/selection.mjs.map +1 -1
  61. package/dist/admin/future/services/api.js +7 -8
  62. package/dist/admin/future/services/api.js.map +1 -1
  63. package/dist/admin/future/services/api.mjs +7 -8
  64. package/dist/admin/future/services/api.mjs.map +1 -1
  65. package/dist/admin/future/services/assets.js +11 -23
  66. package/dist/admin/future/services/assets.js.map +1 -1
  67. package/dist/admin/future/services/assets.mjs +11 -23
  68. package/dist/admin/future/services/assets.mjs.map +1 -1
  69. package/dist/admin/hooks/useAIMetadataJob.js +1 -1
  70. package/dist/admin/hooks/useAIMetadataJob.js.map +1 -1
  71. package/dist/admin/hooks/useAIMetadataJob.mjs +1 -1
  72. package/dist/admin/hooks/useAIMetadataJob.mjs.map +1 -1
  73. package/dist/admin/pages/SettingsPage/SettingsPage.js +2 -2
  74. package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
  75. package/dist/admin/pages/SettingsPage/SettingsPage.mjs +2 -2
  76. package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
  77. package/dist/admin/src/future/components/TruncatedText.d.ts +32 -0
  78. package/dist/admin/src/future/hooks/useTracking.d.ts +29 -0
  79. package/dist/admin/src/future/pages/Assets/components/AssetActionsMenu.d.ts +5 -3
  80. package/dist/admin/src/future/pages/Assets/components/FolderActionsMenu.d.ts +5 -4
  81. package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +2 -0
  82. package/dist/admin/src/future/pages/Assets/utils/selection.d.ts +10 -0
  83. package/dist/admin/src/future/services/api.d.ts +6 -7
  84. package/dist/server/controllers/admin-file.js +27 -9
  85. package/dist/server/controllers/admin-file.js.map +1 -1
  86. package/dist/server/controllers/admin-file.mjs +27 -9
  87. package/dist/server/controllers/admin-file.mjs.map +1 -1
  88. package/dist/server/controllers/admin-upload.js +24 -8
  89. package/dist/server/controllers/admin-upload.js.map +1 -1
  90. package/dist/server/controllers/admin-upload.mjs +24 -8
  91. package/dist/server/controllers/admin-upload.mjs.map +1 -1
  92. package/dist/server/routes/admin.js +41 -21
  93. package/dist/server/routes/admin.js.map +1 -1
  94. package/dist/server/routes/admin.mjs +41 -21
  95. package/dist/server/routes/admin.mjs.map +1 -1
  96. package/dist/server/services/ai-metadata.js.map +1 -1
  97. package/dist/server/services/ai-metadata.mjs.map +1 -1
  98. package/dist/server/src/controllers/admin-file.d.ts +29 -8
  99. package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
  100. package/dist/server/src/controllers/admin-upload.d.ts +20 -4
  101. package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
  102. package/dist/server/src/controllers/index.d.ts +4 -4
  103. package/dist/server/src/index.d.ts +4 -4
  104. package/dist/server/src/routes/admin.d.ts.map +1 -1
  105. package/dist/server/src/services/ai-metadata.d.ts +2 -2
  106. package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
  107. package/dist/shared/contracts/ai-metadata-jobs.d.ts +10 -32
  108. package/dist/shared/contracts/ai-metadata-jobs.d.ts.map +1 -1
  109. package/dist/shared/contracts/files.d.ts +10 -10
  110. package/dist/shared/contracts/files.d.ts.map +1 -1
  111. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"AssetsGrid.js","sources":["../../../../../../admin/src/future/pages/Assets/components/AssetsGrid.tsx"],"sourcesContent":["import {\n Box,\n Card,\n CardBody,\n CardHeader,\n Checkbox,\n Flex,\n Grid,\n Typography,\n} from '@strapi/design-system';\nimport { Folder as FolderIcon } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, css } from 'styled-components';\n\nimport { ASSET_TYPES } from '../../../../enums';\nimport { useMediaLibraryPermissions } from '../../../hooks/useMediaLibraryPermissions';\nimport { prefixFileUrlWithBackendUrl } from '../../../utils/files';\nimport { getAssetIcon } from '../../../utils/getAssetIcon';\nimport { isEventFromWithin } from '../../../utils/isEventFromWithin';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSelection } from '../hooks/useAssetSelection';\nimport { useBusyAssetsOptional } from '../hooks/useBusyAssets';\nimport { useFolderNavigation } from '../hooks/useFolderNavigation';\nimport { assetKey, folderKey, type ItemKey } from '../utils/selection';\n\nimport { AssetActionsMenu } from './AssetActionsMenu';\nimport { BusyOverlay } from './BusyOverlay';\nimport { useAssetsDndOptional } from './Dnd/AssetsDndProvider';\nimport { useFileDraggable, useFolderDraggableDroppable } from './Dnd/useAssetDnd';\nimport { FolderActionsMenu } from './FolderActionsMenu';\n\nimport type { File } from '../../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../../shared/contracts/folders';\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\n// Cards own click, Enter and Space; the controls sitting on them (checkbox, \"...\"\n// menu) must not let those reach the card. Scoped to the wrapper's own DOM\n// subtree so the menu's portaled content — a React child of the wrapper, but\n// never a DOM descendant — still reaches `document`, where Radix listens in\n// order to dismiss its layers.\nconst stopCardEvent = (e: React.SyntheticEvent) => {\n if (isEventFromWithin(e)) {\n e.stopPropagation();\n }\n};\n\n// Top-left selection checkbox overlaid on the asset preview, always visible.\nconst CheckboxOverlay = styled(Flex)`\n position: absolute;\n top: ${({ theme }) => theme.spaces[3]};\n left: ${({ theme }) => theme.spaces[3]};\n z-index: 1;\n box-shadow: ${({ theme }) => theme.shadows.filterShadow};\n`;\n\nconst StyledCard = styled(Card)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isBusy?: boolean;\n $isSelected?: boolean;\n}>`\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: 8px;\n overflow: hidden;\n cursor: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'wait' : 'pointer')};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n /* No opacity change while busy — the overlay does the dimming, and stacking\n one on the other would wash the card out. */\n pointer-events: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'none' : 'auto')};\n background: ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary100 : undefined)};\n /* Shift+click range selection must not highlight card text. */\n user-select: none;\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * FolderCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst FoldersRow = styled(Box)`\n grid-column: 1 / -1;\n`;\n\nconst StyledFolderCard = styled(Flex)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isValidDropTarget?: boolean;\n $isInvalidDropTarget?: boolean;\n $isSelected?: boolean;\n}>`\n width: 100%;\n user-select: none;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`}; // 8px 12px\n align-items: center;\n gap: ${({ theme }) => theme.spaces[2]}; // 8px\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme, $isSelected }) =>\n $isSelected ? theme.colors.primary100 : theme.colors.neutral0};\n cursor: ${({ $isMovePending, $isInvalidDropTarget }) => {\n if ($isMovePending) {\n return 'wait';\n }\n\n return $isInvalidDropTarget ? 'not-allowed' : 'pointer';\n }};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n transition: background 0.2s;\n\n ${({ $isValidDropTarget, theme }) =>\n $isValidDropTarget &&\n css`\n background: ${theme.colors.primary100};\n border: 1px dashed ${theme.colors.primary600};\n `}\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\nconst FolderIconContainer = styled(Flex)`\n flex-shrink: 0;\n color: ${({ theme }) => theme.colors.neutral600};\n`;\n\nconst FolderName = styled(Typography)`\n flex: 1;\n min-width: 0;\n`;\n\ninterface FolderCardProps {\n folder: Folder;\n orderedItemKeys: ItemKey[];\n}\n\nconst FolderCard = ({ folder, orderedItemKeys }: FolderCardProps) => {\n const { formatMessage } = useIntl();\n const { navigateToFolder } = useFolderNavigation();\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const {\n dragData,\n draggable: { attributes, listeners, setNodeRef: setDragRef, isDragging },\n droppable: { setNodeRef: setDropRef },\n showValidDropHighlight,\n showInvalidDropCursor,\n } = useFolderDraggableDroppable(folder);\n\n const key = folderKey(folder.id);\n\n const setNodeRef = (node: HTMLElement | null) => {\n setDragRef(node);\n setDropRef(node);\n };\n\n // Folders share the selection mechanism with assets (toggle, range,\n // select-all). Only the plain-click semantic differs: it navigates into the\n // folder instead of selecting it.\n //\n // The containment guard on this and the handlers below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // navigating into the folder or starting a drag.\n const handleClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n navigateToFolder(folder);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n navigateToFolder(folder);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n // Checkbox is the pointer path to selection; Shift extends the range.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledFolderCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isValidDropTarget={showValidDropHighlight}\n $isInvalidDropTarget={showInvalidDropCursor}\n $isSelected={isSelected(key)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n role=\"listitem\"\n tabIndex={0}\n >\n {canUpdate && (\n <Flex onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={isSelected(key)}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: folder.name }\n )}\n />\n </Flex>\n )}\n <FolderIconContainer>\n <FolderIcon width={20} height={20} />\n </FolderIconContainer>\n <FolderName textColor=\"neutral800\" ellipsis>\n {folder.name}\n </FolderName>\n <Flex onClick={stopCardEvent} onKeyDown={stopCardEvent} onPointerDown={stopCardEvent}>\n <FolderActionsMenu folder={folder} dragData={dragData} />\n </Flex>\n </StyledFolderCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetPreview\n * -----------------------------------------------------------------------------------------------*/\n\nconst PreviewContainer = styled(Box)`\n position: relative;\n width: 100%;\n padding-bottom: 62.5%;\n height: 0;\n overflow: hidden;\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n transparent 0% 50%\n )\n 50% / 20px 20px;\n`;\n\nconst StyledImage = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n`;\n\nconst IconPreview = styled(Flex)`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n color: ${({ theme }) => theme.colors.neutral500};\n background: ${({ theme }) => theme.colors.neutral100};\n`;\n\ninterface AssetPreviewProps {\n asset: File;\n}\n\nconst AssetPreview = ({ asset }: AssetPreviewProps) => {\n const { alternativeText, ext, formats, mime, url, updatedAt, isLocal, isUrlSigned } = asset;\n\n if (mime?.includes(ASSET_TYPES.Image)) {\n // Replace keeps the same hash/URL, so without a cache-buster the browser\n // serves the stale thumbnail after a Replace Media. `updatedAt`\n // changes on replace, so it re-fetches exactly once per replacement.\n // Skipped for signed URLs — an extra query param invalidates the signature.\n const cacheKey = updatedAt && !isUrlSigned ? new Date(updatedAt).getTime() : undefined;\n const appendCacheBuster = (raw: string) => {\n if (cacheKey === undefined) {\n return raw;\n }\n return raw.includes('?') ? `${raw}&v=${cacheKey}` : `${raw}?v=${cacheKey}`;\n };\n\n const rawMediaURL =\n prefixFileUrlWithBackendUrl(formats?.thumbnail?.url) ?? prefixFileUrlWithBackendUrl(url);\n const mediaURL = rawMediaURL ? appendCacheBuster(rawMediaURL) : rawMediaURL;\n\n if (mediaURL) {\n return (\n <PreviewContainer>\n <StyledImage\n src={mediaURL}\n alt={alternativeText || ''}\n // Only signed remote URLs need crossOrigin (cache collision with\n // the preview). Public/unsigned remote thumbnails must render\n // without a bucket CORS rule. See #26581.\n crossOrigin={!isLocal && isUrlSigned ? 'anonymous' : undefined}\n draggable={false}\n onDragStart={(e) => e.preventDefault()}\n />\n </PreviewContainer>\n );\n }\n }\n\n const DocIcon = getAssetIcon(mime, ext);\n\n return (\n <PreviewContainer>\n <IconPreview justifyContent=\"center\" alignItems=\"center\">\n <DocIcon width={48} height={48} />\n </IconPreview>\n </PreviewContainer>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst StyledCardHeader = styled(CardHeader)`\n position: relative;\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};\n`;\n\nconst CardFooter = styled(Flex)`\n min-width: 0;\n width: 100%;\n`;\n\nconst FileTypeIcon = styled(Flex)`\n color: ${({ theme }) => theme.colors.neutral600};\n flex-shrink: 0;\n`;\n\nconst FileName = styled(Typography)`\n flex: 1;\n min-width: 0;\n`;\n\n// The asset filename is its own interactive element: clicking it opens the\n// details drawer instead of selecting the card (mirrors the table view).\nconst NameButton = styled.button`\n display: inline-flex;\n flex: 1;\n min-width: 0;\n border: none;\n background: transparent;\n padding: 0;\n margin: 0;\n cursor: pointer;\n text-align: left;\n color: inherit;\n font: inherit;\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n border-radius: 2px;\n }\n`;\n\ninterface AssetCardProps {\n asset: File;\n orderedItemKeys: ItemKey[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nconst AssetCard = ({ asset, orderedItemKeys, onAssetItemClick }: AssetCardProps) => {\n const { formatMessage } = useIntl();\n const TypeIcon = getAssetIcon(asset.mime, asset.ext);\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { attributes, listeners, setNodeRef, isDragging, dragData } = useFileDraggable(asset);\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const busyMessage = useBusyAssetsOptional()?.getBusyMessage(asset.id) ?? null;\n\n const key = assetKey(asset.id);\n const selected = isSelected(key);\n\n // Plain click opens the asset details; pointer selection lives on the\n // checkbox only. Modifier clicks keep the selection semantics: shift selects\n // a range, cmd/ctrl toggles.\n //\n // The containment guard on this and the handler below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // opening the details drawer or toggling the selection.\n const handleCardClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n onAssetItemClick(asset.id);\n }\n };\n\n // Space toggles selection (additive), Enter opens the details drawer.\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n onAssetItemClick(asset.id);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n const handleNameClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onAssetItemClick(asset.id);\n };\n\n // Same semantics as the table's row checkbox: Shift extends the range,\n // otherwise a plain additive toggle. Never bubbles into the card click.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isBusy={busyMessage !== null}\n $isSelected={selected}\n tabIndex={0}\n role=\"listitem\"\n onDragStart={(e) => e.preventDefault()}\n onClick={handleCardClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n >\n <StyledCardHeader>\n {canUpdate && (\n <CheckboxOverlay onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={selected}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: asset.name }\n )}\n />\n </CheckboxOverlay>\n )}\n <AssetPreview asset={asset} />\n {/* The header is the card's only positioned ancestor, and it's the part\n worth covering — the footer keeps the name legible while the preview\n is mid-replace. Below the checkbox overlay (z-index 1) would hide\n the spinner, so it sits above it. */}\n {busyMessage !== null ? <BusyOverlay zIndex={2}>{busyMessage}</BusyOverlay> : null}\n </StyledCardHeader>\n <CardBody>\n <CardFooter alignItems=\"center\" gap={2}>\n <FileTypeIcon>\n <TypeIcon width={20} height={20} />\n </FileTypeIcon>\n <NameButton type=\"button\" onClick={handleNameClick}>\n <FileName textColor=\"primary800\" ellipsis>\n {asset.name}\n </FileName>\n </NameButton>\n <Flex onClick={stopCardEvent} onKeyDown={stopCardEvent} onPointerDown={stopCardEvent}>\n <AssetActionsMenu asset={asset} dragData={dragData} />\n </Flex>\n </CardFooter>\n </CardBody>\n </StyledCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsGridProps {\n assets: File[];\n folders?: Folder[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nexport const AssetsGrid = ({ assets, folders = [], onAssetItemClick }: AssetsGridProps) => {\n const totalItems = folders.length + assets.length;\n\n // Render order: folders always on top in the grid (mixing is table-only) —\n // range selection follows it.\n const orderedItemKeys: ItemKey[] = [\n ...folders.map((folder) => folderKey(folder.id)),\n ...assets.map((asset) => assetKey(asset.id)),\n ];\n\n // The empty state is owned by the page (`AssetsView` renders `EmptyState`) — an\n // empty grid renders nothing at all.\n if (totalItems === 0) {\n return null;\n }\n\n return (\n <Grid.Root gap={4} role=\"list\" data-testid=\"assets-grid\">\n {folders.length > 0 && (\n <FoldersRow>\n <Grid.Root gap={4}>\n {folders.map((folder) => (\n <Grid.Item col={3} m={4} s={6} xs={12} key={`folder-${folder.id}`}>\n <FolderCard folder={folder} orderedItemKeys={orderedItemKeys} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </FoldersRow>\n )}\n {assets.map((asset) => (\n <Grid.Item\n col={3}\n m={4}\n s={6}\n xs={12}\n key={asset.id}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <AssetCard\n asset={asset}\n orderedItemKeys={orderedItemKeys}\n onAssetItemClick={onAssetItemClick}\n />\n </Grid.Item>\n ))}\n </Grid.Root>\n );\n};\n"],"names":["stopCardEvent","e","isEventFromWithin","stopPropagation","CheckboxOverlay","styled","Flex","theme","spaces","shadows","filterShadow","StyledCard","Card","$isSelected","colors","primary600","neutral200","$isMovePending","$isBusy","$isDragging","primary100","undefined","FoldersRow","Box","StyledFolderCard","borderRadius","neutral0","$isInvalidDropTarget","$isValidDropTarget","css","FolderIconContainer","neutral600","FolderName","Typography","FolderCard","folder","orderedItemKeys","formatMessage","useIntl","navigateToFolder","useFolderNavigation","isMovePending","useAssetsDndOptional","isSelected","toggle","selectRange","useAssetSelection","canUpdate","useMediaLibraryPermissions","dragData","draggable","attributes","listeners","setNodeRef","setDragRef","isDragging","droppable","setDropRef","showValidDropHighlight","showInvalidDropCursor","useFolderDraggableDroppable","key","folderKey","id","node","handleClick","shiftKey","metaKey","ctrlKey","handleKeyDown","preventDefault","handleCheckboxClick","_jsxs","ref","onClick","onKeyDown","onPointerDown","role","tabIndex","_jsx","Checkbox","checked","aria-label","getTranslationKey","defaultMessage","name","FolderIcon","width","height","textColor","ellipsis","FolderActionsMenu","PreviewContainer","neutral100","StyledImage","img","IconPreview","neutral500","AssetPreview","asset","alternativeText","ext","formats","mime","url","updatedAt","isLocal","isUrlSigned","includes","ASSET_TYPES","Image","cacheKey","Date","getTime","appendCacheBuster","raw","rawMediaURL","prefixFileUrlWithBackendUrl","thumbnail","mediaURL","src","alt","crossOrigin","onDragStart","DocIcon","getAssetIcon","justifyContent","alignItems","StyledCardHeader","CardHeader","CardFooter","FileTypeIcon","FileName","NameButton","button","AssetCard","onAssetItemClick","TypeIcon","useFileDraggable","busyMessage","useBusyAssetsOptional","getBusyMessage","assetKey","selected","handleCardClick","handleNameClick","BusyOverlay","zIndex","CardBody","gap","type","AssetActionsMenu","AssetsGrid","assets","folders","totalItems","length","map","Grid","Root","data-testid","Item","col","m","s","xs","direction"],"mappings":"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"}
1
+ {"version":3,"file":"AssetsGrid.js","sources":["../../../../../../admin/src/future/pages/Assets/components/AssetsGrid.tsx"],"sourcesContent":["import { Box, Card, CardBody, CardHeader, Checkbox, Flex, Grid } from '@strapi/design-system';\nimport { Folder as FolderIcon } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, css } from 'styled-components';\n\nimport { ASSET_TYPES } from '../../../../enums';\nimport { TruncatedText } from '../../../components/TruncatedText';\nimport { useMediaLibraryPermissions } from '../../../hooks/useMediaLibraryPermissions';\nimport { prefixFileUrlWithBackendUrl } from '../../../utils/files';\nimport { getAssetIcon } from '../../../utils/getAssetIcon';\nimport { isEventFromWithin } from '../../../utils/isEventFromWithin';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSelection } from '../hooks/useAssetSelection';\nimport { useBusyAssetsOptional } from '../hooks/useBusyAssets';\nimport { useFolderNavigation } from '../hooks/useFolderNavigation';\nimport { assetKey, folderKey, type ItemKey } from '../utils/selection';\n\nimport { AssetActionsMenu } from './AssetActionsMenu';\nimport { BusyOverlay } from './BusyOverlay';\nimport { useAssetsDndOptional } from './Dnd/AssetsDndProvider';\nimport { useFileDraggable, useFolderDraggableDroppable } from './Dnd/useAssetDnd';\nimport { FolderActionsMenu } from './FolderActionsMenu';\n\nimport type { File } from '../../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../../shared/contracts/folders';\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\n// Cards own click, Enter and Space; the controls sitting on them (checkbox, \"...\"\n// menu) must not let those reach the card. Scoped to the wrapper's own DOM\n// subtree so the menu's portaled content — a React child of the wrapper, but\n// never a DOM descendant — still reaches `document`, where Radix listens in\n// order to dismiss its layers.\nconst stopCardEvent = (e: React.SyntheticEvent) => {\n if (isEventFromWithin(e)) {\n e.stopPropagation();\n }\n};\n\n// Top-left selection checkbox overlaid on the asset preview, always visible.\nconst CheckboxOverlay = styled(Flex)`\n position: absolute;\n top: ${({ theme }) => theme.spaces[3]};\n left: ${({ theme }) => theme.spaces[3]};\n z-index: 1;\n box-shadow: ${({ theme }) => theme.shadows.filterShadow};\n`;\n\nconst StyledCard = styled(Card)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isBusy?: boolean;\n $isSelected?: boolean;\n}>`\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: 8px;\n overflow: hidden;\n cursor: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'wait' : 'pointer')};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n /* No opacity change while busy — the overlay does the dimming, and stacking\n one on the other would wash the card out. */\n pointer-events: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'none' : 'auto')};\n background: ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary100 : undefined)};\n /* Shift+click range selection must not highlight card text. */\n user-select: none;\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * FolderCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst FoldersRow = styled(Box)`\n grid-column: 1 / -1;\n`;\n\nconst StyledFolderCard = styled(Flex)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isValidDropTarget?: boolean;\n $isInvalidDropTarget?: boolean;\n $isSelected?: boolean;\n}>`\n width: 100%;\n user-select: none;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`}; // 8px 12px\n align-items: center;\n gap: ${({ theme }) => theme.spaces[2]}; // 8px\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme, $isSelected }) =>\n $isSelected ? theme.colors.primary100 : theme.colors.neutral0};\n cursor: ${({ $isMovePending, $isInvalidDropTarget }) => {\n if ($isMovePending) {\n return 'wait';\n }\n\n return $isInvalidDropTarget ? 'not-allowed' : 'pointer';\n }};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n transition: background 0.2s;\n\n ${({ $isValidDropTarget, theme }) =>\n $isValidDropTarget &&\n css`\n background: ${theme.colors.primary100};\n border: 1px dashed ${theme.colors.primary600};\n `}\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\nconst FolderIconContainer = styled(Flex)`\n flex-shrink: 0;\n color: ${({ theme }) => theme.colors.neutral600};\n`;\n\nconst FolderName = styled(TruncatedText)`\n flex: 1;\n min-width: 0;\n`;\n\ninterface FolderCardProps {\n folder: Folder;\n orderedItemKeys: ItemKey[];\n}\n\nconst FolderCard = ({ folder, orderedItemKeys }: FolderCardProps) => {\n const { formatMessage } = useIntl();\n const { navigateToFolder } = useFolderNavigation();\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const {\n dragData,\n draggable: { attributes, listeners, setNodeRef: setDragRef, isDragging },\n droppable: { setNodeRef: setDropRef },\n showValidDropHighlight,\n showInvalidDropCursor,\n } = useFolderDraggableDroppable(folder);\n\n const key = folderKey(folder.id);\n\n const setNodeRef = (node: HTMLElement | null) => {\n setDragRef(node);\n setDropRef(node);\n };\n\n // Folders share the selection mechanism with assets (toggle, range,\n // select-all). Only the plain-click semantic differs: it navigates into the\n // folder instead of selecting it.\n //\n // The containment guard on this and the handlers below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // navigating into the folder or starting a drag.\n const handleClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n navigateToFolder(folder);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n navigateToFolder(folder);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n // Checkbox is the pointer path to selection; Shift extends the range.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledFolderCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isValidDropTarget={showValidDropHighlight}\n $isInvalidDropTarget={showInvalidDropCursor}\n $isSelected={isSelected(key)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n role=\"listitem\"\n tabIndex={0}\n >\n {canUpdate && (\n <Flex onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={isSelected(key)}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: folder.name }\n )}\n />\n </Flex>\n )}\n <FolderIconContainer>\n <FolderIcon width={20} height={20} />\n </FolderIconContainer>\n <FolderName textColor=\"neutral800\">{folder.name}</FolderName>\n <Flex onClick={stopCardEvent} onKeyDown={stopCardEvent} onPointerDown={stopCardEvent}>\n <FolderActionsMenu folder={folder} dragData={dragData} />\n </Flex>\n </StyledFolderCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetPreview\n * -----------------------------------------------------------------------------------------------*/\n\nconst PreviewContainer = styled(Box)`\n position: relative;\n width: 100%;\n padding-bottom: 62.5%;\n height: 0;\n overflow: hidden;\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n transparent 0% 50%\n )\n 50% / 20px 20px;\n`;\n\nconst StyledImage = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n`;\n\nconst IconPreview = styled(Flex)`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n color: ${({ theme }) => theme.colors.neutral500};\n background: ${({ theme }) => theme.colors.neutral100};\n`;\n\ninterface AssetPreviewProps {\n asset: File;\n}\n\nconst AssetPreview = ({ asset }: AssetPreviewProps) => {\n const { alternativeText, ext, formats, mime, url, updatedAt, isLocal, isUrlSigned } = asset;\n\n if (mime?.includes(ASSET_TYPES.Image)) {\n // Replace keeps the same hash/URL, so without a cache-buster the browser\n // serves the stale thumbnail after a Replace Media. `updatedAt`\n // changes on replace, so it re-fetches exactly once per replacement.\n // Skipped for signed URLs — an extra query param invalidates the signature.\n const cacheKey = updatedAt && !isUrlSigned ? new Date(updatedAt).getTime() : undefined;\n const appendCacheBuster = (raw: string) => {\n if (cacheKey === undefined) {\n return raw;\n }\n return raw.includes('?') ? `${raw}&v=${cacheKey}` : `${raw}?v=${cacheKey}`;\n };\n\n const rawMediaURL =\n prefixFileUrlWithBackendUrl(formats?.thumbnail?.url) ?? prefixFileUrlWithBackendUrl(url);\n const mediaURL = rawMediaURL ? appendCacheBuster(rawMediaURL) : rawMediaURL;\n\n if (mediaURL) {\n return (\n <PreviewContainer>\n <StyledImage\n src={mediaURL}\n alt={alternativeText || ''}\n // Only signed remote URLs need crossOrigin (cache collision with\n // the preview). Public/unsigned remote thumbnails must render\n // without a bucket CORS rule. See #26581.\n crossOrigin={!isLocal && isUrlSigned ? 'anonymous' : undefined}\n draggable={false}\n onDragStart={(e) => e.preventDefault()}\n />\n </PreviewContainer>\n );\n }\n }\n\n const DocIcon = getAssetIcon(mime, ext);\n\n return (\n <PreviewContainer>\n <IconPreview justifyContent=\"center\" alignItems=\"center\">\n <DocIcon width={48} height={48} />\n </IconPreview>\n </PreviewContainer>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst StyledCardHeader = styled(CardHeader)`\n position: relative;\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};\n`;\n\nconst CardFooter = styled(Flex)`\n min-width: 0;\n width: 100%;\n`;\n\nconst FileTypeIcon = styled(Flex)`\n color: ${({ theme }) => theme.colors.neutral600};\n flex-shrink: 0;\n`;\n\nconst FileName = styled(TruncatedText)`\n flex: 1;\n min-width: 0;\n`;\n\n// The asset filename is its own interactive element: clicking it opens the\n// details drawer instead of selecting the card (mirrors the table view).\nconst NameButton = styled.button`\n display: inline-flex;\n flex: 1;\n min-width: 0;\n border: none;\n background: transparent;\n padding: 0;\n margin: 0;\n cursor: pointer;\n text-align: left;\n color: inherit;\n font: inherit;\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n border-radius: 2px;\n }\n`;\n\ninterface AssetCardProps {\n asset: File;\n orderedItemKeys: ItemKey[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nconst AssetCard = ({ asset, orderedItemKeys, onAssetItemClick }: AssetCardProps) => {\n const { formatMessage } = useIntl();\n const TypeIcon = getAssetIcon(asset.mime, asset.ext);\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { attributes, listeners, setNodeRef, isDragging, dragData } = useFileDraggable(asset);\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const busyMessage = useBusyAssetsOptional()?.getBusyMessage(asset.id) ?? null;\n\n const key = assetKey(asset.id);\n const selected = isSelected(key);\n\n // Plain click opens the asset details; pointer selection lives on the\n // checkbox only. Modifier clicks keep the selection semantics: shift selects\n // a range, cmd/ctrl toggles.\n //\n // The containment guard on this and the handler below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // opening the details drawer or toggling the selection.\n const handleCardClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n onAssetItemClick(asset.id);\n }\n };\n\n // Space toggles selection (additive), Enter opens the details drawer.\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n onAssetItemClick(asset.id);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n const handleNameClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onAssetItemClick(asset.id);\n };\n\n // Same semantics as the table's row checkbox: Shift extends the range,\n // otherwise a plain additive toggle. Never bubbles into the card click.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isBusy={busyMessage !== null}\n $isSelected={selected}\n tabIndex={0}\n role=\"listitem\"\n onDragStart={(e) => e.preventDefault()}\n onClick={handleCardClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n >\n <StyledCardHeader>\n {canUpdate && (\n <CheckboxOverlay onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={selected}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: asset.name }\n )}\n />\n </CheckboxOverlay>\n )}\n <AssetPreview asset={asset} />\n {/* The header is the card's only positioned ancestor, and it's the part\n worth covering — the footer keeps the name legible while the preview\n is mid-replace. Below the checkbox overlay (z-index 1) would hide\n the spinner, so it sits above it. */}\n {busyMessage !== null ? <BusyOverlay zIndex={2}>{busyMessage}</BusyOverlay> : null}\n </StyledCardHeader>\n <CardBody>\n <CardFooter alignItems=\"center\" gap={2}>\n <FileTypeIcon>\n <TypeIcon width={20} height={20} />\n </FileTypeIcon>\n <NameButton type=\"button\" onClick={handleNameClick}>\n <FileName textColor=\"primary800\">{asset.name}</FileName>\n </NameButton>\n <Flex onClick={stopCardEvent} onKeyDown={stopCardEvent} onPointerDown={stopCardEvent}>\n <AssetActionsMenu asset={asset} dragData={dragData} />\n </Flex>\n </CardFooter>\n </CardBody>\n </StyledCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsGridProps {\n assets: File[];\n folders?: Folder[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nexport const AssetsGrid = ({ assets, folders = [], onAssetItemClick }: AssetsGridProps) => {\n const totalItems = folders.length + assets.length;\n\n // Render order: folders always on top in the grid (mixing is table-only) —\n // range selection follows it.\n const orderedItemKeys: ItemKey[] = [\n ...folders.map((folder) => folderKey(folder.id)),\n ...assets.map((asset) => assetKey(asset.id)),\n ];\n\n // The empty state is owned by the page (`AssetsView` renders `EmptyState`) — an\n // empty grid renders nothing at all.\n if (totalItems === 0) {\n return null;\n }\n\n return (\n <Grid.Root gap={4} role=\"list\" data-testid=\"assets-grid\">\n {folders.length > 0 && (\n <FoldersRow>\n <Grid.Root gap={4}>\n {folders.map((folder) => (\n <Grid.Item col={3} m={4} s={6} xs={12} key={`folder-${folder.id}`}>\n <FolderCard folder={folder} orderedItemKeys={orderedItemKeys} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </FoldersRow>\n )}\n {assets.map((asset) => (\n <Grid.Item\n col={3}\n m={4}\n s={6}\n xs={12}\n key={asset.id}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <AssetCard\n asset={asset}\n orderedItemKeys={orderedItemKeys}\n onAssetItemClick={onAssetItemClick}\n />\n </Grid.Item>\n ))}\n </Grid.Root>\n );\n};\n"],"names":["stopCardEvent","e","isEventFromWithin","stopPropagation","CheckboxOverlay","styled","Flex","theme","spaces","shadows","filterShadow","StyledCard","Card","$isSelected","colors","primary600","neutral200","$isMovePending","$isBusy","$isDragging","primary100","undefined","FoldersRow","Box","StyledFolderCard","borderRadius","neutral0","$isInvalidDropTarget","$isValidDropTarget","css","FolderIconContainer","neutral600","FolderName","TruncatedText","FolderCard","folder","orderedItemKeys","formatMessage","useIntl","navigateToFolder","useFolderNavigation","isMovePending","useAssetsDndOptional","isSelected","toggle","selectRange","useAssetSelection","canUpdate","useMediaLibraryPermissions","dragData","draggable","attributes","listeners","setNodeRef","setDragRef","isDragging","droppable","setDropRef","showValidDropHighlight","showInvalidDropCursor","useFolderDraggableDroppable","key","folderKey","id","node","handleClick","shiftKey","metaKey","ctrlKey","handleKeyDown","preventDefault","handleCheckboxClick","_jsxs","ref","onClick","onKeyDown","onPointerDown","role","tabIndex","_jsx","Checkbox","checked","aria-label","getTranslationKey","defaultMessage","name","FolderIcon","width","height","textColor","FolderActionsMenu","PreviewContainer","neutral100","StyledImage","img","IconPreview","neutral500","AssetPreview","asset","alternativeText","ext","formats","mime","url","updatedAt","isLocal","isUrlSigned","includes","ASSET_TYPES","Image","cacheKey","Date","getTime","appendCacheBuster","raw","rawMediaURL","prefixFileUrlWithBackendUrl","thumbnail","mediaURL","src","alt","crossOrigin","onDragStart","DocIcon","getAssetIcon","justifyContent","alignItems","StyledCardHeader","CardHeader","CardFooter","FileTypeIcon","FileName","NameButton","button","AssetCard","onAssetItemClick","TypeIcon","useFileDraggable","busyMessage","useBusyAssetsOptional","getBusyMessage","assetKey","selected","handleCardClick","handleNameClick","BusyOverlay","zIndex","CardBody","gap","type","AssetActionsMenu","AssetsGrid","assets","folders","totalItems","length","map","Grid","Root","data-testid","Item","col","m","s","xs","direction"],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { Grid, Box, Flex, Checkbox, CardBody, Typography, Card, CardHeader } from '@strapi/design-system';
2
+ import { Grid, Box, Flex, Checkbox, CardBody, Card, CardHeader } from '@strapi/design-system';
3
3
  import { Folder } from '@strapi/icons';
4
4
  import { useIntl } from 'react-intl';
5
5
  import { styled, css } from 'styled-components';
6
6
  import { ASSET_TYPES } from '../../../../enums.mjs';
7
+ import { TruncatedText } from '../../../components/TruncatedText.mjs';
7
8
  import { useMediaLibraryPermissions } from '../../../hooks/useMediaLibraryPermissions.mjs';
8
9
  import { prefixFileUrlWithBackendUrl } from '../../../utils/files.mjs';
9
10
  import { getAssetIcon } from '../../../utils/getAssetIcon.mjs';
@@ -105,7 +106,7 @@ const FolderIconContainer = styled(Flex)`
105
106
  flex-shrink: 0;
106
107
  color: ${({ theme })=>theme.colors.neutral600};
107
108
  `;
108
- const FolderName = styled(Typography)`
109
+ const FolderName = styled(TruncatedText)`
109
110
  flex: 1;
110
111
  min-width: 0;
111
112
  `;
@@ -203,7 +204,6 @@ const FolderCard = ({ folder, orderedItemKeys })=>{
203
204
  }),
204
205
  /*#__PURE__*/ jsx(FolderName, {
205
206
  textColor: "neutral800",
206
- ellipsis: true,
207
207
  children: folder.name
208
208
  }),
209
209
  /*#__PURE__*/ jsx(Flex, {
@@ -306,7 +306,7 @@ const FileTypeIcon = styled(Flex)`
306
306
  color: ${({ theme })=>theme.colors.neutral600};
307
307
  flex-shrink: 0;
308
308
  `;
309
- const FileName = styled(Typography)`
309
+ const FileName = styled(TruncatedText)`
310
310
  flex: 1;
311
311
  min-width: 0;
312
312
  `;
@@ -448,7 +448,6 @@ const AssetCard = ({ asset, orderedItemKeys, onAssetItemClick })=>{
448
448
  onClick: handleNameClick,
449
449
  children: /*#__PURE__*/ jsx(FileName, {
450
450
  textColor: "primary800",
451
- ellipsis: true,
452
451
  children: asset.name
453
452
  })
454
453
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"AssetsGrid.mjs","sources":["../../../../../../admin/src/future/pages/Assets/components/AssetsGrid.tsx"],"sourcesContent":["import {\n Box,\n Card,\n CardBody,\n CardHeader,\n Checkbox,\n Flex,\n Grid,\n Typography,\n} from '@strapi/design-system';\nimport { Folder as FolderIcon } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, css } from 'styled-components';\n\nimport { ASSET_TYPES } from '../../../../enums';\nimport { useMediaLibraryPermissions } from '../../../hooks/useMediaLibraryPermissions';\nimport { prefixFileUrlWithBackendUrl } from '../../../utils/files';\nimport { getAssetIcon } from '../../../utils/getAssetIcon';\nimport { isEventFromWithin } from '../../../utils/isEventFromWithin';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSelection } from '../hooks/useAssetSelection';\nimport { useBusyAssetsOptional } from '../hooks/useBusyAssets';\nimport { useFolderNavigation } from '../hooks/useFolderNavigation';\nimport { assetKey, folderKey, type ItemKey } from '../utils/selection';\n\nimport { AssetActionsMenu } from './AssetActionsMenu';\nimport { BusyOverlay } from './BusyOverlay';\nimport { useAssetsDndOptional } from './Dnd/AssetsDndProvider';\nimport { useFileDraggable, useFolderDraggableDroppable } from './Dnd/useAssetDnd';\nimport { FolderActionsMenu } from './FolderActionsMenu';\n\nimport type { File } from '../../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../../shared/contracts/folders';\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\n// Cards own click, Enter and Space; the controls sitting on them (checkbox, \"...\"\n// menu) must not let those reach the card. Scoped to the wrapper's own DOM\n// subtree so the menu's portaled content — a React child of the wrapper, but\n// never a DOM descendant — still reaches `document`, where Radix listens in\n// order to dismiss its layers.\nconst stopCardEvent = (e: React.SyntheticEvent) => {\n if (isEventFromWithin(e)) {\n e.stopPropagation();\n }\n};\n\n// Top-left selection checkbox overlaid on the asset preview, always visible.\nconst CheckboxOverlay = styled(Flex)`\n position: absolute;\n top: ${({ theme }) => theme.spaces[3]};\n left: ${({ theme }) => theme.spaces[3]};\n z-index: 1;\n box-shadow: ${({ theme }) => theme.shadows.filterShadow};\n`;\n\nconst StyledCard = styled(Card)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isBusy?: boolean;\n $isSelected?: boolean;\n}>`\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: 8px;\n overflow: hidden;\n cursor: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'wait' : 'pointer')};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n /* No opacity change while busy — the overlay does the dimming, and stacking\n one on the other would wash the card out. */\n pointer-events: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'none' : 'auto')};\n background: ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary100 : undefined)};\n /* Shift+click range selection must not highlight card text. */\n user-select: none;\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * FolderCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst FoldersRow = styled(Box)`\n grid-column: 1 / -1;\n`;\n\nconst StyledFolderCard = styled(Flex)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isValidDropTarget?: boolean;\n $isInvalidDropTarget?: boolean;\n $isSelected?: boolean;\n}>`\n width: 100%;\n user-select: none;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`}; // 8px 12px\n align-items: center;\n gap: ${({ theme }) => theme.spaces[2]}; // 8px\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme, $isSelected }) =>\n $isSelected ? theme.colors.primary100 : theme.colors.neutral0};\n cursor: ${({ $isMovePending, $isInvalidDropTarget }) => {\n if ($isMovePending) {\n return 'wait';\n }\n\n return $isInvalidDropTarget ? 'not-allowed' : 'pointer';\n }};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n transition: background 0.2s;\n\n ${({ $isValidDropTarget, theme }) =>\n $isValidDropTarget &&\n css`\n background: ${theme.colors.primary100};\n border: 1px dashed ${theme.colors.primary600};\n `}\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\nconst FolderIconContainer = styled(Flex)`\n flex-shrink: 0;\n color: ${({ theme }) => theme.colors.neutral600};\n`;\n\nconst FolderName = styled(Typography)`\n flex: 1;\n min-width: 0;\n`;\n\ninterface FolderCardProps {\n folder: Folder;\n orderedItemKeys: ItemKey[];\n}\n\nconst FolderCard = ({ folder, orderedItemKeys }: FolderCardProps) => {\n const { formatMessage } = useIntl();\n const { navigateToFolder } = useFolderNavigation();\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const {\n dragData,\n draggable: { attributes, listeners, setNodeRef: setDragRef, isDragging },\n droppable: { setNodeRef: setDropRef },\n showValidDropHighlight,\n showInvalidDropCursor,\n } = useFolderDraggableDroppable(folder);\n\n const key = folderKey(folder.id);\n\n const setNodeRef = (node: HTMLElement | null) => {\n setDragRef(node);\n setDropRef(node);\n };\n\n // Folders share the selection mechanism with assets (toggle, range,\n // select-all). Only the plain-click semantic differs: it navigates into the\n // folder instead of selecting it.\n //\n // The containment guard on this and the handlers below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // navigating into the folder or starting a drag.\n const handleClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n navigateToFolder(folder);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n navigateToFolder(folder);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n // Checkbox is the pointer path to selection; Shift extends the range.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledFolderCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isValidDropTarget={showValidDropHighlight}\n $isInvalidDropTarget={showInvalidDropCursor}\n $isSelected={isSelected(key)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n role=\"listitem\"\n tabIndex={0}\n >\n {canUpdate && (\n <Flex onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={isSelected(key)}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: folder.name }\n )}\n />\n </Flex>\n )}\n <FolderIconContainer>\n <FolderIcon width={20} height={20} />\n </FolderIconContainer>\n <FolderName textColor=\"neutral800\" ellipsis>\n {folder.name}\n </FolderName>\n <Flex onClick={stopCardEvent} onKeyDown={stopCardEvent} onPointerDown={stopCardEvent}>\n <FolderActionsMenu folder={folder} dragData={dragData} />\n </Flex>\n </StyledFolderCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetPreview\n * -----------------------------------------------------------------------------------------------*/\n\nconst PreviewContainer = styled(Box)`\n position: relative;\n width: 100%;\n padding-bottom: 62.5%;\n height: 0;\n overflow: hidden;\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n transparent 0% 50%\n )\n 50% / 20px 20px;\n`;\n\nconst StyledImage = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n`;\n\nconst IconPreview = styled(Flex)`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n color: ${({ theme }) => theme.colors.neutral500};\n background: ${({ theme }) => theme.colors.neutral100};\n`;\n\ninterface AssetPreviewProps {\n asset: File;\n}\n\nconst AssetPreview = ({ asset }: AssetPreviewProps) => {\n const { alternativeText, ext, formats, mime, url, updatedAt, isLocal, isUrlSigned } = asset;\n\n if (mime?.includes(ASSET_TYPES.Image)) {\n // Replace keeps the same hash/URL, so without a cache-buster the browser\n // serves the stale thumbnail after a Replace Media. `updatedAt`\n // changes on replace, so it re-fetches exactly once per replacement.\n // Skipped for signed URLs — an extra query param invalidates the signature.\n const cacheKey = updatedAt && !isUrlSigned ? new Date(updatedAt).getTime() : undefined;\n const appendCacheBuster = (raw: string) => {\n if (cacheKey === undefined) {\n return raw;\n }\n return raw.includes('?') ? `${raw}&v=${cacheKey}` : `${raw}?v=${cacheKey}`;\n };\n\n const rawMediaURL =\n prefixFileUrlWithBackendUrl(formats?.thumbnail?.url) ?? prefixFileUrlWithBackendUrl(url);\n const mediaURL = rawMediaURL ? appendCacheBuster(rawMediaURL) : rawMediaURL;\n\n if (mediaURL) {\n return (\n <PreviewContainer>\n <StyledImage\n src={mediaURL}\n alt={alternativeText || ''}\n // Only signed remote URLs need crossOrigin (cache collision with\n // the preview). Public/unsigned remote thumbnails must render\n // without a bucket CORS rule. See #26581.\n crossOrigin={!isLocal && isUrlSigned ? 'anonymous' : undefined}\n draggable={false}\n onDragStart={(e) => e.preventDefault()}\n />\n </PreviewContainer>\n );\n }\n }\n\n const DocIcon = getAssetIcon(mime, ext);\n\n return (\n <PreviewContainer>\n <IconPreview justifyContent=\"center\" alignItems=\"center\">\n <DocIcon width={48} height={48} />\n </IconPreview>\n </PreviewContainer>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst StyledCardHeader = styled(CardHeader)`\n position: relative;\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};\n`;\n\nconst CardFooter = styled(Flex)`\n min-width: 0;\n width: 100%;\n`;\n\nconst FileTypeIcon = styled(Flex)`\n color: ${({ theme }) => theme.colors.neutral600};\n flex-shrink: 0;\n`;\n\nconst FileName = styled(Typography)`\n flex: 1;\n min-width: 0;\n`;\n\n// The asset filename is its own interactive element: clicking it opens the\n// details drawer instead of selecting the card (mirrors the table view).\nconst NameButton = styled.button`\n display: inline-flex;\n flex: 1;\n min-width: 0;\n border: none;\n background: transparent;\n padding: 0;\n margin: 0;\n cursor: pointer;\n text-align: left;\n color: inherit;\n font: inherit;\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n border-radius: 2px;\n }\n`;\n\ninterface AssetCardProps {\n asset: File;\n orderedItemKeys: ItemKey[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nconst AssetCard = ({ asset, orderedItemKeys, onAssetItemClick }: AssetCardProps) => {\n const { formatMessage } = useIntl();\n const TypeIcon = getAssetIcon(asset.mime, asset.ext);\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { attributes, listeners, setNodeRef, isDragging, dragData } = useFileDraggable(asset);\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const busyMessage = useBusyAssetsOptional()?.getBusyMessage(asset.id) ?? null;\n\n const key = assetKey(asset.id);\n const selected = isSelected(key);\n\n // Plain click opens the asset details; pointer selection lives on the\n // checkbox only. Modifier clicks keep the selection semantics: shift selects\n // a range, cmd/ctrl toggles.\n //\n // The containment guard on this and the handler below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // opening the details drawer or toggling the selection.\n const handleCardClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n onAssetItemClick(asset.id);\n }\n };\n\n // Space toggles selection (additive), Enter opens the details drawer.\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n onAssetItemClick(asset.id);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n const handleNameClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onAssetItemClick(asset.id);\n };\n\n // Same semantics as the table's row checkbox: Shift extends the range,\n // otherwise a plain additive toggle. Never bubbles into the card click.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isBusy={busyMessage !== null}\n $isSelected={selected}\n tabIndex={0}\n role=\"listitem\"\n onDragStart={(e) => e.preventDefault()}\n onClick={handleCardClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n >\n <StyledCardHeader>\n {canUpdate && (\n <CheckboxOverlay onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={selected}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: asset.name }\n )}\n />\n </CheckboxOverlay>\n )}\n <AssetPreview asset={asset} />\n {/* The header is the card's only positioned ancestor, and it's the part\n worth covering — the footer keeps the name legible while the preview\n is mid-replace. Below the checkbox overlay (z-index 1) would hide\n the spinner, so it sits above it. */}\n {busyMessage !== null ? <BusyOverlay zIndex={2}>{busyMessage}</BusyOverlay> : null}\n </StyledCardHeader>\n <CardBody>\n <CardFooter alignItems=\"center\" gap={2}>\n <FileTypeIcon>\n <TypeIcon width={20} height={20} />\n </FileTypeIcon>\n <NameButton type=\"button\" onClick={handleNameClick}>\n <FileName textColor=\"primary800\" ellipsis>\n {asset.name}\n </FileName>\n </NameButton>\n <Flex onClick={stopCardEvent} onKeyDown={stopCardEvent} onPointerDown={stopCardEvent}>\n <AssetActionsMenu asset={asset} dragData={dragData} />\n </Flex>\n </CardFooter>\n </CardBody>\n </StyledCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsGridProps {\n assets: File[];\n folders?: Folder[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nexport const AssetsGrid = ({ assets, folders = [], onAssetItemClick }: AssetsGridProps) => {\n const totalItems = folders.length + assets.length;\n\n // Render order: folders always on top in the grid (mixing is table-only) —\n // range selection follows it.\n const orderedItemKeys: ItemKey[] = [\n ...folders.map((folder) => folderKey(folder.id)),\n ...assets.map((asset) => assetKey(asset.id)),\n ];\n\n // The empty state is owned by the page (`AssetsView` renders `EmptyState`) — an\n // empty grid renders nothing at all.\n if (totalItems === 0) {\n return null;\n }\n\n return (\n <Grid.Root gap={4} role=\"list\" data-testid=\"assets-grid\">\n {folders.length > 0 && (\n <FoldersRow>\n <Grid.Root gap={4}>\n {folders.map((folder) => (\n <Grid.Item col={3} m={4} s={6} xs={12} key={`folder-${folder.id}`}>\n <FolderCard folder={folder} orderedItemKeys={orderedItemKeys} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </FoldersRow>\n )}\n {assets.map((asset) => (\n <Grid.Item\n col={3}\n m={4}\n s={6}\n xs={12}\n key={asset.id}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <AssetCard\n asset={asset}\n orderedItemKeys={orderedItemKeys}\n onAssetItemClick={onAssetItemClick}\n />\n </Grid.Item>\n ))}\n </Grid.Root>\n );\n};\n"],"names":["stopCardEvent","e","isEventFromWithin","stopPropagation","CheckboxOverlay","styled","Flex","theme","spaces","shadows","filterShadow","StyledCard","Card","$isSelected","colors","primary600","neutral200","$isMovePending","$isBusy","$isDragging","primary100","undefined","FoldersRow","Box","StyledFolderCard","borderRadius","neutral0","$isInvalidDropTarget","$isValidDropTarget","css","FolderIconContainer","neutral600","FolderName","Typography","FolderCard","folder","orderedItemKeys","formatMessage","useIntl","navigateToFolder","useFolderNavigation","isMovePending","useAssetsDndOptional","isSelected","toggle","selectRange","useAssetSelection","canUpdate","useMediaLibraryPermissions","dragData","draggable","attributes","listeners","setNodeRef","setDragRef","isDragging","droppable","setDropRef","showValidDropHighlight","showInvalidDropCursor","useFolderDraggableDroppable","key","folderKey","id","node","handleClick","shiftKey","metaKey","ctrlKey","handleKeyDown","preventDefault","handleCheckboxClick","_jsxs","ref","onClick","onKeyDown","onPointerDown","role","tabIndex","_jsx","Checkbox","checked","aria-label","getTranslationKey","defaultMessage","name","FolderIcon","width","height","textColor","ellipsis","FolderActionsMenu","PreviewContainer","neutral100","StyledImage","img","IconPreview","neutral500","AssetPreview","asset","alternativeText","ext","formats","mime","url","updatedAt","isLocal","isUrlSigned","includes","ASSET_TYPES","Image","cacheKey","Date","getTime","appendCacheBuster","raw","rawMediaURL","prefixFileUrlWithBackendUrl","thumbnail","mediaURL","src","alt","crossOrigin","onDragStart","DocIcon","getAssetIcon","justifyContent","alignItems","StyledCardHeader","CardHeader","CardFooter","FileTypeIcon","FileName","NameButton","button","AssetCard","onAssetItemClick","TypeIcon","useFileDraggable","busyMessage","useBusyAssetsOptional","getBusyMessage","assetKey","selected","handleCardClick","handleNameClick","BusyOverlay","zIndex","CardBody","gap","type","AssetActionsMenu","AssetsGrid","assets","folders","totalItems","length","map","Grid","Root","data-testid","Item","col","m","s","xs","direction"],"mappings":"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"}
1
+ {"version":3,"file":"AssetsGrid.mjs","sources":["../../../../../../admin/src/future/pages/Assets/components/AssetsGrid.tsx"],"sourcesContent":["import { Box, Card, CardBody, CardHeader, Checkbox, Flex, Grid } from '@strapi/design-system';\nimport { Folder as FolderIcon } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, css } from 'styled-components';\n\nimport { ASSET_TYPES } from '../../../../enums';\nimport { TruncatedText } from '../../../components/TruncatedText';\nimport { useMediaLibraryPermissions } from '../../../hooks/useMediaLibraryPermissions';\nimport { prefixFileUrlWithBackendUrl } from '../../../utils/files';\nimport { getAssetIcon } from '../../../utils/getAssetIcon';\nimport { isEventFromWithin } from '../../../utils/isEventFromWithin';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSelection } from '../hooks/useAssetSelection';\nimport { useBusyAssetsOptional } from '../hooks/useBusyAssets';\nimport { useFolderNavigation } from '../hooks/useFolderNavigation';\nimport { assetKey, folderKey, type ItemKey } from '../utils/selection';\n\nimport { AssetActionsMenu } from './AssetActionsMenu';\nimport { BusyOverlay } from './BusyOverlay';\nimport { useAssetsDndOptional } from './Dnd/AssetsDndProvider';\nimport { useFileDraggable, useFolderDraggableDroppable } from './Dnd/useAssetDnd';\nimport { FolderActionsMenu } from './FolderActionsMenu';\n\nimport type { File } from '../../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../../shared/contracts/folders';\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\n// Cards own click, Enter and Space; the controls sitting on them (checkbox, \"...\"\n// menu) must not let those reach the card. Scoped to the wrapper's own DOM\n// subtree so the menu's portaled content — a React child of the wrapper, but\n// never a DOM descendant — still reaches `document`, where Radix listens in\n// order to dismiss its layers.\nconst stopCardEvent = (e: React.SyntheticEvent) => {\n if (isEventFromWithin(e)) {\n e.stopPropagation();\n }\n};\n\n// Top-left selection checkbox overlaid on the asset preview, always visible.\nconst CheckboxOverlay = styled(Flex)`\n position: absolute;\n top: ${({ theme }) => theme.spaces[3]};\n left: ${({ theme }) => theme.spaces[3]};\n z-index: 1;\n box-shadow: ${({ theme }) => theme.shadows.filterShadow};\n`;\n\nconst StyledCard = styled(Card)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isBusy?: boolean;\n $isSelected?: boolean;\n}>`\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: 8px;\n overflow: hidden;\n cursor: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'wait' : 'pointer')};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n /* No opacity change while busy — the overlay does the dimming, and stacking\n one on the other would wash the card out. */\n pointer-events: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'none' : 'auto')};\n background: ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary100 : undefined)};\n /* Shift+click range selection must not highlight card text. */\n user-select: none;\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * FolderCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst FoldersRow = styled(Box)`\n grid-column: 1 / -1;\n`;\n\nconst StyledFolderCard = styled(Flex)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isValidDropTarget?: boolean;\n $isInvalidDropTarget?: boolean;\n $isSelected?: boolean;\n}>`\n width: 100%;\n user-select: none;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`}; // 8px 12px\n align-items: center;\n gap: ${({ theme }) => theme.spaces[2]}; // 8px\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme, $isSelected }) =>\n $isSelected ? theme.colors.primary100 : theme.colors.neutral0};\n cursor: ${({ $isMovePending, $isInvalidDropTarget }) => {\n if ($isMovePending) {\n return 'wait';\n }\n\n return $isInvalidDropTarget ? 'not-allowed' : 'pointer';\n }};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n transition: background 0.2s;\n\n ${({ $isValidDropTarget, theme }) =>\n $isValidDropTarget &&\n css`\n background: ${theme.colors.primary100};\n border: 1px dashed ${theme.colors.primary600};\n `}\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\nconst FolderIconContainer = styled(Flex)`\n flex-shrink: 0;\n color: ${({ theme }) => theme.colors.neutral600};\n`;\n\nconst FolderName = styled(TruncatedText)`\n flex: 1;\n min-width: 0;\n`;\n\ninterface FolderCardProps {\n folder: Folder;\n orderedItemKeys: ItemKey[];\n}\n\nconst FolderCard = ({ folder, orderedItemKeys }: FolderCardProps) => {\n const { formatMessage } = useIntl();\n const { navigateToFolder } = useFolderNavigation();\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const {\n dragData,\n draggable: { attributes, listeners, setNodeRef: setDragRef, isDragging },\n droppable: { setNodeRef: setDropRef },\n showValidDropHighlight,\n showInvalidDropCursor,\n } = useFolderDraggableDroppable(folder);\n\n const key = folderKey(folder.id);\n\n const setNodeRef = (node: HTMLElement | null) => {\n setDragRef(node);\n setDropRef(node);\n };\n\n // Folders share the selection mechanism with assets (toggle, range,\n // select-all). Only the plain-click semantic differs: it navigates into the\n // folder instead of selecting it.\n //\n // The containment guard on this and the handlers below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // navigating into the folder or starting a drag.\n const handleClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n navigateToFolder(folder);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n navigateToFolder(folder);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n // Checkbox is the pointer path to selection; Shift extends the range.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledFolderCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isValidDropTarget={showValidDropHighlight}\n $isInvalidDropTarget={showInvalidDropCursor}\n $isSelected={isSelected(key)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n role=\"listitem\"\n tabIndex={0}\n >\n {canUpdate && (\n <Flex onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={isSelected(key)}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: folder.name }\n )}\n />\n </Flex>\n )}\n <FolderIconContainer>\n <FolderIcon width={20} height={20} />\n </FolderIconContainer>\n <FolderName textColor=\"neutral800\">{folder.name}</FolderName>\n <Flex onClick={stopCardEvent} onKeyDown={stopCardEvent} onPointerDown={stopCardEvent}>\n <FolderActionsMenu folder={folder} dragData={dragData} />\n </Flex>\n </StyledFolderCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetPreview\n * -----------------------------------------------------------------------------------------------*/\n\nconst PreviewContainer = styled(Box)`\n position: relative;\n width: 100%;\n padding-bottom: 62.5%;\n height: 0;\n overflow: hidden;\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n transparent 0% 50%\n )\n 50% / 20px 20px;\n`;\n\nconst StyledImage = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n`;\n\nconst IconPreview = styled(Flex)`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n color: ${({ theme }) => theme.colors.neutral500};\n background: ${({ theme }) => theme.colors.neutral100};\n`;\n\ninterface AssetPreviewProps {\n asset: File;\n}\n\nconst AssetPreview = ({ asset }: AssetPreviewProps) => {\n const { alternativeText, ext, formats, mime, url, updatedAt, isLocal, isUrlSigned } = asset;\n\n if (mime?.includes(ASSET_TYPES.Image)) {\n // Replace keeps the same hash/URL, so without a cache-buster the browser\n // serves the stale thumbnail after a Replace Media. `updatedAt`\n // changes on replace, so it re-fetches exactly once per replacement.\n // Skipped for signed URLs — an extra query param invalidates the signature.\n const cacheKey = updatedAt && !isUrlSigned ? new Date(updatedAt).getTime() : undefined;\n const appendCacheBuster = (raw: string) => {\n if (cacheKey === undefined) {\n return raw;\n }\n return raw.includes('?') ? `${raw}&v=${cacheKey}` : `${raw}?v=${cacheKey}`;\n };\n\n const rawMediaURL =\n prefixFileUrlWithBackendUrl(formats?.thumbnail?.url) ?? prefixFileUrlWithBackendUrl(url);\n const mediaURL = rawMediaURL ? appendCacheBuster(rawMediaURL) : rawMediaURL;\n\n if (mediaURL) {\n return (\n <PreviewContainer>\n <StyledImage\n src={mediaURL}\n alt={alternativeText || ''}\n // Only signed remote URLs need crossOrigin (cache collision with\n // the preview). Public/unsigned remote thumbnails must render\n // without a bucket CORS rule. See #26581.\n crossOrigin={!isLocal && isUrlSigned ? 'anonymous' : undefined}\n draggable={false}\n onDragStart={(e) => e.preventDefault()}\n />\n </PreviewContainer>\n );\n }\n }\n\n const DocIcon = getAssetIcon(mime, ext);\n\n return (\n <PreviewContainer>\n <IconPreview justifyContent=\"center\" alignItems=\"center\">\n <DocIcon width={48} height={48} />\n </IconPreview>\n </PreviewContainer>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst StyledCardHeader = styled(CardHeader)`\n position: relative;\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};\n`;\n\nconst CardFooter = styled(Flex)`\n min-width: 0;\n width: 100%;\n`;\n\nconst FileTypeIcon = styled(Flex)`\n color: ${({ theme }) => theme.colors.neutral600};\n flex-shrink: 0;\n`;\n\nconst FileName = styled(TruncatedText)`\n flex: 1;\n min-width: 0;\n`;\n\n// The asset filename is its own interactive element: clicking it opens the\n// details drawer instead of selecting the card (mirrors the table view).\nconst NameButton = styled.button`\n display: inline-flex;\n flex: 1;\n min-width: 0;\n border: none;\n background: transparent;\n padding: 0;\n margin: 0;\n cursor: pointer;\n text-align: left;\n color: inherit;\n font: inherit;\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n border-radius: 2px;\n }\n`;\n\ninterface AssetCardProps {\n asset: File;\n orderedItemKeys: ItemKey[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nconst AssetCard = ({ asset, orderedItemKeys, onAssetItemClick }: AssetCardProps) => {\n const { formatMessage } = useIntl();\n const TypeIcon = getAssetIcon(asset.mime, asset.ext);\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { attributes, listeners, setNodeRef, isDragging, dragData } = useFileDraggable(asset);\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const busyMessage = useBusyAssetsOptional()?.getBusyMessage(asset.id) ?? null;\n\n const key = assetKey(asset.id);\n const selected = isSelected(key);\n\n // Plain click opens the asset details; pointer selection lives on the\n // checkbox only. Modifier clicks keep the selection semantics: shift selects\n // a range, cmd/ctrl toggles.\n //\n // The containment guard on this and the handler below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // opening the details drawer or toggling the selection.\n const handleCardClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n onAssetItemClick(asset.id);\n }\n };\n\n // Space toggles selection (additive), Enter opens the details drawer.\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n onAssetItemClick(asset.id);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n const handleNameClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onAssetItemClick(asset.id);\n };\n\n // Same semantics as the table's row checkbox: Shift extends the range,\n // otherwise a plain additive toggle. Never bubbles into the card click.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isBusy={busyMessage !== null}\n $isSelected={selected}\n tabIndex={0}\n role=\"listitem\"\n onDragStart={(e) => e.preventDefault()}\n onClick={handleCardClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n >\n <StyledCardHeader>\n {canUpdate && (\n <CheckboxOverlay onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={selected}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: asset.name }\n )}\n />\n </CheckboxOverlay>\n )}\n <AssetPreview asset={asset} />\n {/* The header is the card's only positioned ancestor, and it's the part\n worth covering — the footer keeps the name legible while the preview\n is mid-replace. Below the checkbox overlay (z-index 1) would hide\n the spinner, so it sits above it. */}\n {busyMessage !== null ? <BusyOverlay zIndex={2}>{busyMessage}</BusyOverlay> : null}\n </StyledCardHeader>\n <CardBody>\n <CardFooter alignItems=\"center\" gap={2}>\n <FileTypeIcon>\n <TypeIcon width={20} height={20} />\n </FileTypeIcon>\n <NameButton type=\"button\" onClick={handleNameClick}>\n <FileName textColor=\"primary800\">{asset.name}</FileName>\n </NameButton>\n <Flex onClick={stopCardEvent} onKeyDown={stopCardEvent} onPointerDown={stopCardEvent}>\n <AssetActionsMenu asset={asset} dragData={dragData} />\n </Flex>\n </CardFooter>\n </CardBody>\n </StyledCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsGridProps {\n assets: File[];\n folders?: Folder[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nexport const AssetsGrid = ({ assets, folders = [], onAssetItemClick }: AssetsGridProps) => {\n const totalItems = folders.length + assets.length;\n\n // Render order: folders always on top in the grid (mixing is table-only) —\n // range selection follows it.\n const orderedItemKeys: ItemKey[] = [\n ...folders.map((folder) => folderKey(folder.id)),\n ...assets.map((asset) => assetKey(asset.id)),\n ];\n\n // The empty state is owned by the page (`AssetsView` renders `EmptyState`) — an\n // empty grid renders nothing at all.\n if (totalItems === 0) {\n return null;\n }\n\n return (\n <Grid.Root gap={4} role=\"list\" data-testid=\"assets-grid\">\n {folders.length > 0 && (\n <FoldersRow>\n <Grid.Root gap={4}>\n {folders.map((folder) => (\n <Grid.Item col={3} m={4} s={6} xs={12} key={`folder-${folder.id}`}>\n <FolderCard folder={folder} orderedItemKeys={orderedItemKeys} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </FoldersRow>\n )}\n {assets.map((asset) => (\n <Grid.Item\n col={3}\n m={4}\n s={6}\n xs={12}\n key={asset.id}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <AssetCard\n asset={asset}\n orderedItemKeys={orderedItemKeys}\n onAssetItemClick={onAssetItemClick}\n />\n </Grid.Item>\n ))}\n </Grid.Root>\n );\n};\n"],"names":["stopCardEvent","e","isEventFromWithin","stopPropagation","CheckboxOverlay","styled","Flex","theme","spaces","shadows","filterShadow","StyledCard","Card","$isSelected","colors","primary600","neutral200","$isMovePending","$isBusy","$isDragging","primary100","undefined","FoldersRow","Box","StyledFolderCard","borderRadius","neutral0","$isInvalidDropTarget","$isValidDropTarget","css","FolderIconContainer","neutral600","FolderName","TruncatedText","FolderCard","folder","orderedItemKeys","formatMessage","useIntl","navigateToFolder","useFolderNavigation","isMovePending","useAssetsDndOptional","isSelected","toggle","selectRange","useAssetSelection","canUpdate","useMediaLibraryPermissions","dragData","draggable","attributes","listeners","setNodeRef","setDragRef","isDragging","droppable","setDropRef","showValidDropHighlight","showInvalidDropCursor","useFolderDraggableDroppable","key","folderKey","id","node","handleClick","shiftKey","metaKey","ctrlKey","handleKeyDown","preventDefault","handleCheckboxClick","_jsxs","ref","onClick","onKeyDown","onPointerDown","role","tabIndex","_jsx","Checkbox","checked","aria-label","getTranslationKey","defaultMessage","name","FolderIcon","width","height","textColor","FolderActionsMenu","PreviewContainer","neutral100","StyledImage","img","IconPreview","neutral500","AssetPreview","asset","alternativeText","ext","formats","mime","url","updatedAt","isLocal","isUrlSigned","includes","ASSET_TYPES","Image","cacheKey","Date","getTime","appendCacheBuster","raw","rawMediaURL","prefixFileUrlWithBackendUrl","thumbnail","mediaURL","src","alt","crossOrigin","onDragStart","DocIcon","getAssetIcon","justifyContent","alignItems","StyledCardHeader","CardHeader","CardFooter","FileTypeIcon","FileName","NameButton","button","AssetCard","onAssetItemClick","TypeIcon","useFileDraggable","busyMessage","useBusyAssetsOptional","getBusyMessage","assetKey","selected","handleCardClick","handleNameClick","BusyOverlay","zIndex","CardBody","gap","type","AssetActionsMenu","AssetsGrid","assets","folders","totalItems","length","map","Grid","Root","data-testid","Item","col","m","s","xs","direction"],"mappings":"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"}
@@ -6,6 +6,7 @@ var strapiAdmin = require('@strapi/admin/strapi-admin');
6
6
  var designSystem = require('@strapi/design-system');
7
7
  var reactIntl = require('react-intl');
8
8
  var styledComponents = require('styled-components');
9
+ var useTracking = require('../../../hooks/useTracking.js');
9
10
  var translations = require('../../../utils/translations.js');
10
11
  var useAssetSearch = require('../hooks/useAssetSearch.js');
11
12
 
@@ -27,6 +28,7 @@ const StyledSearchForm = styledComponents.styled(designSystem.SearchForm)`
27
28
  */ const AssetsSearchInput = ()=>{
28
29
  const { formatMessage } = reactIntl.useIntl();
29
30
  const { searchQuery, setSearchQuery } = useAssetSearch.useAssetSearch();
31
+ const { trackUsage } = useTracking.useTracking();
30
32
  const isMobile = strapiAdmin.useIsMobile();
31
33
  const [value, setValue] = React.useState(searchQuery);
32
34
  const debouncedValue = strapiAdmin.useDebounce(value, DEBOUNCE_MS);
@@ -45,10 +47,18 @@ const StyledSearchForm = styledComponents.styled(designSystem.SearchForm)`
45
47
  return;
46
48
  }
47
49
  lastCommittedRef.current = debouncedValue;
50
+ // Only a real query counts as a search — clearing the box (empty value) is
51
+ // a reset, not a `didSearch`.
52
+ if (debouncedValue) {
53
+ trackUsage('didSearchMediaLibraryElements', {
54
+ location: useTracking.MEDIA_LIBRARY_LOCATION
55
+ });
56
+ }
48
57
  setSearchQuery(debouncedValue);
49
58
  }, [
50
59
  debouncedValue,
51
- setSearchQuery
60
+ setSearchQuery,
61
+ trackUsage
52
62
  ]);
53
63
  // Re-sync on external changes — back/forward, or "Clear search" in the empty
54
64
  // state.
@@ -1 +1 @@
1
- {"version":3,"file":"AssetsSearchInput.js","sources":["../../../../../../admin/src/future/pages/Assets/components/AssetsSearchInput.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ChangeEvent, type FormEvent } from 'react';\n\nimport { useDebounce, useIsMobile, useQueryParams } from '@strapi/admin/strapi-admin';\nimport { Box, Searchbar, SearchForm } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSearch } from '../hooks/useAssetSearch';\n\nconst DEBOUNCE_MS = 300;\n\n// The DS Searchbar nests two bordered boxes: its own shell (neutral150) wrapping\n// the field (neutral200). Side by side they read as a single 2px, two-tone\n// border, which sits oddly next to the 1px neutral200 on the Filter button in the\n// same toolbar. Dropping the shell's border leaves the field's own — same width\n// and colour as the button — and costs nothing, since the focus ring lives on the\n// field too.\nconst StyledSearchForm = styled(SearchForm)`\n > div {\n border: none;\n }\n`;\n\n/**\n * Keyword search over the whole Media Library. Owns the typing state and the\n * debounce; `useAssetSearch` owns the `?_q=` URL param.\n */\nexport const AssetsSearchInput = () => {\n const { formatMessage } = useIntl();\n const { searchQuery, setSearchQuery } = useAssetSearch();\n const isMobile = useIsMobile();\n\n const [value, setValue] = useState(searchQuery);\n const debouncedValue = useDebounce(value, DEBOUNCE_MS);\n\n // Tracks the last value the URL and the input agreed on. Without it the two\n // effects below would ping-pong: each would see the other's write as a change\n // worth reacting to.\n const lastCommittedRef = useRef(searchQuery);\n\n // Read directly rather than through `useFolderNavigation`, which strips\n // malformed `?folder=` values as a side effect.\n const [{ query }] = useQueryParams<{ folder?: string }>();\n const folderParam = query?.folder ?? '';\n const lastFolderRef = useRef(folderParam);\n\n // Commit settled input to the URL.\n useEffect(() => {\n if (debouncedValue === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = debouncedValue;\n setSearchQuery(debouncedValue);\n }, [debouncedValue, setSearchQuery]);\n\n // Re-sync on external changes — back/forward, or \"Clear search\" in the empty\n // state.\n useEffect(() => {\n if (searchQuery === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [searchQuery]);\n\n // A folder navigation clears `_q`, but a term typed and never committed lives\n // only in the debounce — without this it lands afterwards and reactivates the\n // global search. `_q` alone can't see it: it was never non-empty.\n useEffect(() => {\n if (folderParam === lastFolderRef.current) {\n return;\n }\n\n lastFolderRef.current = folderParam;\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [folderParam, searchQuery]);\n\n const searchForm = (\n <StyledSearchForm onSubmit={(event: FormEvent<HTMLFormElement>) => event.preventDefault()}>\n <Searchbar\n name=\"search-assets\"\n value={value}\n onChange={(event: ChangeEvent<HTMLInputElement>) => setValue(event.target.value)}\n onClear={() => setValue('')}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n placeholder={formatMessage({\n id: getTranslationKey('header.search.placeholder'),\n defaultMessage: 'Search',\n })}\n size=\"S\"\n >\n {formatMessage({\n id: getTranslationKey('search.label'),\n defaultMessage: 'Search for an asset',\n })}\n </Searchbar>\n </StyledSearchForm>\n );\n\n // Mobile: fills the toolbar row (own line). Desktop: keeps its intrinsic size,\n // with empty space between it and the right-aligned Sort/Toggle group.\n if (isMobile) {\n return <Box width=\"100%\">{searchForm}</Box>;\n }\n\n return searchForm;\n};\n"],"names":["DEBOUNCE_MS","StyledSearchForm","styled","SearchForm","AssetsSearchInput","formatMessage","useIntl","searchQuery","setSearchQuery","useAssetSearch","isMobile","useIsMobile","value","setValue","useState","debouncedValue","useDebounce","lastCommittedRef","useRef","query","useQueryParams","folderParam","folder","lastFolderRef","useEffect","current","searchForm","_jsx","onSubmit","event","preventDefault","Searchbar","name","onChange","target","onClear","clearLabel","id","defaultMessage","placeholder","getTranslationKey","size","Box","width"],"mappings":"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"}
1
+ {"version":3,"file":"AssetsSearchInput.js","sources":["../../../../../../admin/src/future/pages/Assets/components/AssetsSearchInput.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ChangeEvent, type FormEvent } from 'react';\n\nimport { useDebounce, useIsMobile, useQueryParams } from '@strapi/admin/strapi-admin';\nimport { Box, Searchbar, SearchForm } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useTracking, MEDIA_LIBRARY_LOCATION } from '../../../hooks/useTracking';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSearch } from '../hooks/useAssetSearch';\n\nconst DEBOUNCE_MS = 300;\n\n// The DS Searchbar nests two bordered boxes: its own shell (neutral150) wrapping\n// the field (neutral200). Side by side they read as a single 2px, two-tone\n// border, which sits oddly next to the 1px neutral200 on the Filter button in the\n// same toolbar. Dropping the shell's border leaves the field's own — same width\n// and colour as the button — and costs nothing, since the focus ring lives on the\n// field too.\nconst StyledSearchForm = styled(SearchForm)`\n > div {\n border: none;\n }\n`;\n\n/**\n * Keyword search over the whole Media Library. Owns the typing state and the\n * debounce; `useAssetSearch` owns the `?_q=` URL param.\n */\nexport const AssetsSearchInput = () => {\n const { formatMessage } = useIntl();\n const { searchQuery, setSearchQuery } = useAssetSearch();\n const { trackUsage } = useTracking();\n const isMobile = useIsMobile();\n\n const [value, setValue] = useState(searchQuery);\n const debouncedValue = useDebounce(value, DEBOUNCE_MS);\n\n // Tracks the last value the URL and the input agreed on. Without it the two\n // effects below would ping-pong: each would see the other's write as a change\n // worth reacting to.\n const lastCommittedRef = useRef(searchQuery);\n\n // Read directly rather than through `useFolderNavigation`, which strips\n // malformed `?folder=` values as a side effect.\n const [{ query }] = useQueryParams<{ folder?: string }>();\n const folderParam = query?.folder ?? '';\n const lastFolderRef = useRef(folderParam);\n\n // Commit settled input to the URL.\n useEffect(() => {\n if (debouncedValue === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = debouncedValue;\n // Only a real query counts as a search — clearing the box (empty value) is\n // a reset, not a `didSearch`.\n if (debouncedValue) {\n trackUsage('didSearchMediaLibraryElements', { location: MEDIA_LIBRARY_LOCATION });\n }\n setSearchQuery(debouncedValue);\n }, [debouncedValue, setSearchQuery, trackUsage]);\n\n // Re-sync on external changes — back/forward, or \"Clear search\" in the empty\n // state.\n useEffect(() => {\n if (searchQuery === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [searchQuery]);\n\n // A folder navigation clears `_q`, but a term typed and never committed lives\n // only in the debounce — without this it lands afterwards and reactivates the\n // global search. `_q` alone can't see it: it was never non-empty.\n useEffect(() => {\n if (folderParam === lastFolderRef.current) {\n return;\n }\n\n lastFolderRef.current = folderParam;\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [folderParam, searchQuery]);\n\n const searchForm = (\n <StyledSearchForm onSubmit={(event: FormEvent<HTMLFormElement>) => event.preventDefault()}>\n <Searchbar\n name=\"search-assets\"\n value={value}\n onChange={(event: ChangeEvent<HTMLInputElement>) => setValue(event.target.value)}\n onClear={() => setValue('')}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n placeholder={formatMessage({\n id: getTranslationKey('header.search.placeholder'),\n defaultMessage: 'Search',\n })}\n size=\"S\"\n >\n {formatMessage({\n id: getTranslationKey('search.label'),\n defaultMessage: 'Search for an asset',\n })}\n </Searchbar>\n </StyledSearchForm>\n );\n\n // Mobile: fills the toolbar row (own line). Desktop: keeps its intrinsic size,\n // with empty space between it and the right-aligned Sort/Toggle group.\n if (isMobile) {\n return <Box width=\"100%\">{searchForm}</Box>;\n }\n\n return searchForm;\n};\n"],"names":["DEBOUNCE_MS","StyledSearchForm","styled","SearchForm","AssetsSearchInput","formatMessage","useIntl","searchQuery","setSearchQuery","useAssetSearch","trackUsage","useTracking","isMobile","useIsMobile","value","setValue","useState","debouncedValue","useDebounce","lastCommittedRef","useRef","query","useQueryParams","folderParam","folder","lastFolderRef","useEffect","current","location","MEDIA_LIBRARY_LOCATION","searchForm","_jsx","onSubmit","event","preventDefault","Searchbar","name","onChange","target","onClear","clearLabel","id","defaultMessage","placeholder","getTranslationKey","size","Box","width"],"mappings":"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"}
@@ -4,6 +4,7 @@ import { useIsMobile, useDebounce, useQueryParams } from '@strapi/admin/strapi-a
4
4
  import { Searchbar, Box, SearchForm } from '@strapi/design-system';
5
5
  import { useIntl } from 'react-intl';
6
6
  import { styled } from 'styled-components';
7
+ import { useTracking, MEDIA_LIBRARY_LOCATION } from '../../../hooks/useTracking.mjs';
7
8
  import { getTranslationKey } from '../../../utils/translations.mjs';
8
9
  import { useAssetSearch } from '../hooks/useAssetSearch.mjs';
9
10
 
@@ -25,6 +26,7 @@ const StyledSearchForm = styled(SearchForm)`
25
26
  */ const AssetsSearchInput = ()=>{
26
27
  const { formatMessage } = useIntl();
27
28
  const { searchQuery, setSearchQuery } = useAssetSearch();
29
+ const { trackUsage } = useTracking();
28
30
  const isMobile = useIsMobile();
29
31
  const [value, setValue] = useState(searchQuery);
30
32
  const debouncedValue = useDebounce(value, DEBOUNCE_MS);
@@ -43,10 +45,18 @@ const StyledSearchForm = styled(SearchForm)`
43
45
  return;
44
46
  }
45
47
  lastCommittedRef.current = debouncedValue;
48
+ // Only a real query counts as a search — clearing the box (empty value) is
49
+ // a reset, not a `didSearch`.
50
+ if (debouncedValue) {
51
+ trackUsage('didSearchMediaLibraryElements', {
52
+ location: MEDIA_LIBRARY_LOCATION
53
+ });
54
+ }
46
55
  setSearchQuery(debouncedValue);
47
56
  }, [
48
57
  debouncedValue,
49
- setSearchQuery
58
+ setSearchQuery,
59
+ trackUsage
50
60
  ]);
51
61
  // Re-sync on external changes — back/forward, or "Clear search" in the empty
52
62
  // state.
@@ -1 +1 @@
1
- {"version":3,"file":"AssetsSearchInput.mjs","sources":["../../../../../../admin/src/future/pages/Assets/components/AssetsSearchInput.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ChangeEvent, type FormEvent } from 'react';\n\nimport { useDebounce, useIsMobile, useQueryParams } from '@strapi/admin/strapi-admin';\nimport { Box, Searchbar, SearchForm } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSearch } from '../hooks/useAssetSearch';\n\nconst DEBOUNCE_MS = 300;\n\n// The DS Searchbar nests two bordered boxes: its own shell (neutral150) wrapping\n// the field (neutral200). Side by side they read as a single 2px, two-tone\n// border, which sits oddly next to the 1px neutral200 on the Filter button in the\n// same toolbar. Dropping the shell's border leaves the field's own — same width\n// and colour as the button — and costs nothing, since the focus ring lives on the\n// field too.\nconst StyledSearchForm = styled(SearchForm)`\n > div {\n border: none;\n }\n`;\n\n/**\n * Keyword search over the whole Media Library. Owns the typing state and the\n * debounce; `useAssetSearch` owns the `?_q=` URL param.\n */\nexport const AssetsSearchInput = () => {\n const { formatMessage } = useIntl();\n const { searchQuery, setSearchQuery } = useAssetSearch();\n const isMobile = useIsMobile();\n\n const [value, setValue] = useState(searchQuery);\n const debouncedValue = useDebounce(value, DEBOUNCE_MS);\n\n // Tracks the last value the URL and the input agreed on. Without it the two\n // effects below would ping-pong: each would see the other's write as a change\n // worth reacting to.\n const lastCommittedRef = useRef(searchQuery);\n\n // Read directly rather than through `useFolderNavigation`, which strips\n // malformed `?folder=` values as a side effect.\n const [{ query }] = useQueryParams<{ folder?: string }>();\n const folderParam = query?.folder ?? '';\n const lastFolderRef = useRef(folderParam);\n\n // Commit settled input to the URL.\n useEffect(() => {\n if (debouncedValue === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = debouncedValue;\n setSearchQuery(debouncedValue);\n }, [debouncedValue, setSearchQuery]);\n\n // Re-sync on external changes — back/forward, or \"Clear search\" in the empty\n // state.\n useEffect(() => {\n if (searchQuery === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [searchQuery]);\n\n // A folder navigation clears `_q`, but a term typed and never committed lives\n // only in the debounce — without this it lands afterwards and reactivates the\n // global search. `_q` alone can't see it: it was never non-empty.\n useEffect(() => {\n if (folderParam === lastFolderRef.current) {\n return;\n }\n\n lastFolderRef.current = folderParam;\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [folderParam, searchQuery]);\n\n const searchForm = (\n <StyledSearchForm onSubmit={(event: FormEvent<HTMLFormElement>) => event.preventDefault()}>\n <Searchbar\n name=\"search-assets\"\n value={value}\n onChange={(event: ChangeEvent<HTMLInputElement>) => setValue(event.target.value)}\n onClear={() => setValue('')}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n placeholder={formatMessage({\n id: getTranslationKey('header.search.placeholder'),\n defaultMessage: 'Search',\n })}\n size=\"S\"\n >\n {formatMessage({\n id: getTranslationKey('search.label'),\n defaultMessage: 'Search for an asset',\n })}\n </Searchbar>\n </StyledSearchForm>\n );\n\n // Mobile: fills the toolbar row (own line). Desktop: keeps its intrinsic size,\n // with empty space between it and the right-aligned Sort/Toggle group.\n if (isMobile) {\n return <Box width=\"100%\">{searchForm}</Box>;\n }\n\n return searchForm;\n};\n"],"names":["DEBOUNCE_MS","StyledSearchForm","styled","SearchForm","AssetsSearchInput","formatMessage","useIntl","searchQuery","setSearchQuery","useAssetSearch","isMobile","useIsMobile","value","setValue","useState","debouncedValue","useDebounce","lastCommittedRef","useRef","query","useQueryParams","folderParam","folder","lastFolderRef","useEffect","current","searchForm","_jsx","onSubmit","event","preventDefault","Searchbar","name","onChange","target","onClear","clearLabel","id","defaultMessage","placeholder","getTranslationKey","size","Box","width"],"mappings":"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"}
1
+ {"version":3,"file":"AssetsSearchInput.mjs","sources":["../../../../../../admin/src/future/pages/Assets/components/AssetsSearchInput.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ChangeEvent, type FormEvent } from 'react';\n\nimport { useDebounce, useIsMobile, useQueryParams } from '@strapi/admin/strapi-admin';\nimport { Box, Searchbar, SearchForm } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useTracking, MEDIA_LIBRARY_LOCATION } from '../../../hooks/useTracking';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSearch } from '../hooks/useAssetSearch';\n\nconst DEBOUNCE_MS = 300;\n\n// The DS Searchbar nests two bordered boxes: its own shell (neutral150) wrapping\n// the field (neutral200). Side by side they read as a single 2px, two-tone\n// border, which sits oddly next to the 1px neutral200 on the Filter button in the\n// same toolbar. Dropping the shell's border leaves the field's own — same width\n// and colour as the button — and costs nothing, since the focus ring lives on the\n// field too.\nconst StyledSearchForm = styled(SearchForm)`\n > div {\n border: none;\n }\n`;\n\n/**\n * Keyword search over the whole Media Library. Owns the typing state and the\n * debounce; `useAssetSearch` owns the `?_q=` URL param.\n */\nexport const AssetsSearchInput = () => {\n const { formatMessage } = useIntl();\n const { searchQuery, setSearchQuery } = useAssetSearch();\n const { trackUsage } = useTracking();\n const isMobile = useIsMobile();\n\n const [value, setValue] = useState(searchQuery);\n const debouncedValue = useDebounce(value, DEBOUNCE_MS);\n\n // Tracks the last value the URL and the input agreed on. Without it the two\n // effects below would ping-pong: each would see the other's write as a change\n // worth reacting to.\n const lastCommittedRef = useRef(searchQuery);\n\n // Read directly rather than through `useFolderNavigation`, which strips\n // malformed `?folder=` values as a side effect.\n const [{ query }] = useQueryParams<{ folder?: string }>();\n const folderParam = query?.folder ?? '';\n const lastFolderRef = useRef(folderParam);\n\n // Commit settled input to the URL.\n useEffect(() => {\n if (debouncedValue === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = debouncedValue;\n // Only a real query counts as a search — clearing the box (empty value) is\n // a reset, not a `didSearch`.\n if (debouncedValue) {\n trackUsage('didSearchMediaLibraryElements', { location: MEDIA_LIBRARY_LOCATION });\n }\n setSearchQuery(debouncedValue);\n }, [debouncedValue, setSearchQuery, trackUsage]);\n\n // Re-sync on external changes — back/forward, or \"Clear search\" in the empty\n // state.\n useEffect(() => {\n if (searchQuery === lastCommittedRef.current) {\n return;\n }\n\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [searchQuery]);\n\n // A folder navigation clears `_q`, but a term typed and never committed lives\n // only in the debounce — without this it lands afterwards and reactivates the\n // global search. `_q` alone can't see it: it was never non-empty.\n useEffect(() => {\n if (folderParam === lastFolderRef.current) {\n return;\n }\n\n lastFolderRef.current = folderParam;\n lastCommittedRef.current = searchQuery;\n setValue(searchQuery);\n }, [folderParam, searchQuery]);\n\n const searchForm = (\n <StyledSearchForm onSubmit={(event: FormEvent<HTMLFormElement>) => event.preventDefault()}>\n <Searchbar\n name=\"search-assets\"\n value={value}\n onChange={(event: ChangeEvent<HTMLInputElement>) => setValue(event.target.value)}\n onClear={() => setValue('')}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n placeholder={formatMessage({\n id: getTranslationKey('header.search.placeholder'),\n defaultMessage: 'Search',\n })}\n size=\"S\"\n >\n {formatMessage({\n id: getTranslationKey('search.label'),\n defaultMessage: 'Search for an asset',\n })}\n </Searchbar>\n </StyledSearchForm>\n );\n\n // Mobile: fills the toolbar row (own line). Desktop: keeps its intrinsic size,\n // with empty space between it and the right-aligned Sort/Toggle group.\n if (isMobile) {\n return <Box width=\"100%\">{searchForm}</Box>;\n }\n\n return searchForm;\n};\n"],"names":["DEBOUNCE_MS","StyledSearchForm","styled","SearchForm","AssetsSearchInput","formatMessage","useIntl","searchQuery","setSearchQuery","useAssetSearch","trackUsage","useTracking","isMobile","useIsMobile","value","setValue","useState","debouncedValue","useDebounce","lastCommittedRef","useRef","query","useQueryParams","folderParam","folder","lastFolderRef","useEffect","current","location","MEDIA_LIBRARY_LOCATION","searchForm","_jsx","onSubmit","event","preventDefault","Searchbar","name","onChange","target","onClear","clearLabel","id","defaultMessage","placeholder","getTranslationKey","size","Box","width"],"mappings":"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"}