@strapi/upload 5.58.0 → 5.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js +141 -0
  2. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js.map +1 -0
  3. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs +139 -0
  4. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs.map +1 -0
  5. package/dist/admin/components/MediaLibraryInput/AssetDropZone.js +129 -0
  6. package/dist/admin/components/MediaLibraryInput/AssetDropZone.js.map +1 -0
  7. package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs +127 -0
  8. package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs.map +1 -0
  9. package/dist/admin/components/MediaLibraryInput/AssetRow.js +144 -0
  10. package/dist/admin/components/MediaLibraryInput/AssetRow.js.map +1 -0
  11. package/dist/admin/components/MediaLibraryInput/AssetRow.mjs +142 -0
  12. package/dist/admin/components/MediaLibraryInput/AssetRow.mjs.map +1 -0
  13. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +397 -0
  14. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -0
  15. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +395 -0
  16. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -0
  17. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js +45 -0
  18. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js.map +1 -0
  19. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs +43 -0
  20. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs.map +1 -0
  21. package/dist/admin/hooks/useAIMetadataAvailability.js +5 -1
  22. package/dist/admin/hooks/useAIMetadataAvailability.js.map +1 -1
  23. package/dist/admin/hooks/useAIMetadataAvailability.mjs +5 -1
  24. package/dist/admin/hooks/useAIMetadataAvailability.mjs.map +1 -1
  25. package/dist/admin/hooks/useAIMetadataEnabled.js +7 -1
  26. package/dist/admin/hooks/useAIMetadataEnabled.js.map +1 -1
  27. package/dist/admin/hooks/useAIMetadataEnabled.mjs +7 -1
  28. package/dist/admin/hooks/useAIMetadataEnabled.mjs.map +1 -1
  29. package/dist/admin/hooks/useMediaLibraryPermissions.js +4 -0
  30. package/dist/admin/hooks/useMediaLibraryPermissions.js.map +1 -1
  31. package/dist/admin/hooks/useMediaLibraryPermissions.mjs +4 -0
  32. package/dist/admin/hooks/useMediaLibraryPermissions.mjs.map +1 -1
  33. package/dist/admin/hooks/useTracking.js +5 -1
  34. package/dist/admin/hooks/useTracking.js.map +1 -1
  35. package/dist/admin/hooks/useTracking.mjs +5 -1
  36. package/dist/admin/hooks/useTracking.mjs.map +1 -1
  37. package/dist/admin/index.js +7 -2
  38. package/dist/admin/index.js.map +1 -1
  39. package/dist/admin/index.mjs +7 -2
  40. package/dist/admin/index.mjs.map +1 -1
  41. package/dist/admin/legacy/components/AssetCard/AssetCardBase.js.map +1 -1
  42. package/dist/admin/legacy/components/AssetCard/AssetCardBase.mjs.map +1 -1
  43. package/dist/admin/legacy/components/AssetCard/VideoPreview.js +2 -1
  44. package/dist/admin/legacy/components/AssetCard/VideoPreview.js.map +1 -1
  45. package/dist/admin/legacy/components/AssetCard/VideoPreview.mjs +2 -1
  46. package/dist/admin/legacy/components/AssetCard/VideoPreview.mjs.map +1 -1
  47. package/dist/admin/legacy/components/AssetDialog/AssetDialog.js +3 -1
  48. package/dist/admin/legacy/components/AssetDialog/AssetDialog.js.map +1 -1
  49. package/dist/admin/legacy/components/AssetDialog/AssetDialog.mjs +3 -1
  50. package/dist/admin/legacy/components/AssetDialog/AssetDialog.mjs.map +1 -1
  51. package/dist/admin/legacy/components/AssetDialog/BrowseStep/BrowseStep.js +3 -1
  52. package/dist/admin/legacy/components/AssetDialog/BrowseStep/BrowseStep.js.map +1 -1
  53. package/dist/admin/legacy/components/AssetDialog/BrowseStep/BrowseStep.mjs +3 -1
  54. package/dist/admin/legacy/components/AssetDialog/BrowseStep/BrowseStep.mjs.map +1 -1
  55. package/dist/admin/legacy/components/AssetDialog/BrowseStep/Filters.js.map +1 -1
  56. package/dist/admin/legacy/components/AssetDialog/BrowseStep/Filters.mjs.map +1 -1
  57. package/dist/admin/legacy/components/AssetGridList/AssetGridList.js +7 -6
  58. package/dist/admin/legacy/components/AssetGridList/AssetGridList.js.map +1 -1
  59. package/dist/admin/legacy/components/AssetGridList/AssetGridList.mjs +7 -6
  60. package/dist/admin/legacy/components/AssetGridList/AssetGridList.mjs.map +1 -1
  61. package/dist/admin/legacy/components/Breadcrumbs/CrumbSimpleMenuAsync.js +2 -1
  62. package/dist/admin/legacy/components/Breadcrumbs/CrumbSimpleMenuAsync.js.map +1 -1
  63. package/dist/admin/legacy/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs +2 -1
  64. package/dist/admin/legacy/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs.map +1 -1
  65. package/dist/admin/legacy/components/BulkMoveDialog/BulkMoveDialog.js +2 -1
  66. package/dist/admin/legacy/components/BulkMoveDialog/BulkMoveDialog.js.map +1 -1
  67. package/dist/admin/legacy/components/BulkMoveDialog/BulkMoveDialog.mjs +2 -1
  68. package/dist/admin/legacy/components/BulkMoveDialog/BulkMoveDialog.mjs.map +1 -1
  69. package/dist/admin/legacy/components/EditAssetDialog/EditAssetContent.js +3 -1
  70. package/dist/admin/legacy/components/EditAssetDialog/EditAssetContent.js.map +1 -1
  71. package/dist/admin/legacy/components/EditAssetDialog/EditAssetContent.mjs +3 -1
  72. package/dist/admin/legacy/components/EditAssetDialog/EditAssetContent.mjs.map +1 -1
  73. package/dist/admin/legacy/components/FilterList/FilterList.js.map +1 -1
  74. package/dist/admin/legacy/components/FilterList/FilterList.mjs.map +1 -1
  75. package/dist/admin/legacy/components/FilterPopover/FilterPopover.js.map +1 -1
  76. package/dist/admin/legacy/components/FilterPopover/FilterPopover.mjs.map +1 -1
  77. package/dist/admin/legacy/components/FilterPopover/FilterValueInput.js +2 -1
  78. package/dist/admin/legacy/components/FilterPopover/FilterValueInput.js.map +1 -1
  79. package/dist/admin/legacy/components/FilterPopover/FilterValueInput.mjs +2 -1
  80. package/dist/admin/legacy/components/FilterPopover/FilterValueInput.mjs.map +1 -1
  81. package/dist/admin/legacy/components/MediaLibraryDialog/MediaLibraryDialog.js +4 -2
  82. package/dist/admin/legacy/components/MediaLibraryDialog/MediaLibraryDialog.js.map +1 -1
  83. package/dist/admin/legacy/components/MediaLibraryDialog/MediaLibraryDialog.mjs +4 -2
  84. package/dist/admin/legacy/components/MediaLibraryDialog/MediaLibraryDialog.mjs.map +1 -1
  85. package/dist/admin/legacy/components/MediaLibraryInput/MediaLibraryInput.js +2 -1
  86. package/dist/admin/legacy/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
  87. package/dist/admin/legacy/components/MediaLibraryInput/MediaLibraryInput.mjs +2 -1
  88. package/dist/admin/legacy/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
  89. package/dist/admin/legacy/components/SelectTree/SelectTree.js +3 -1
  90. package/dist/admin/legacy/components/SelectTree/SelectTree.js.map +1 -1
  91. package/dist/admin/legacy/components/SelectTree/SelectTree.mjs +3 -1
  92. package/dist/admin/legacy/components/SelectTree/SelectTree.mjs.map +1 -1
  93. package/dist/admin/legacy/components/TableList/TableList.js +3 -1
  94. package/dist/admin/legacy/components/TableList/TableList.js.map +1 -1
  95. package/dist/admin/legacy/components/TableList/TableList.mjs +3 -1
  96. package/dist/admin/legacy/components/TableList/TableList.mjs.map +1 -1
  97. package/dist/admin/legacy/components/TableList/TableRows.js +3 -1
  98. package/dist/admin/legacy/components/TableList/TableRows.js.map +1 -1
  99. package/dist/admin/legacy/components/TableList/TableRows.mjs +3 -1
  100. package/dist/admin/legacy/components/TableList/TableRows.mjs.map +1 -1
  101. package/dist/admin/legacy/components/UploadAssetDialog/UploadAssetDialog.js +3 -1
  102. package/dist/admin/legacy/components/UploadAssetDialog/UploadAssetDialog.js.map +1 -1
  103. package/dist/admin/legacy/components/UploadAssetDialog/UploadAssetDialog.mjs +3 -1
  104. package/dist/admin/legacy/components/UploadAssetDialog/UploadAssetDialog.mjs.map +1 -1
  105. package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
  106. package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.mjs.map +1 -1
  107. package/dist/admin/legacy/pages/App/components/BulkActions.js +2 -1
  108. package/dist/admin/legacy/pages/App/components/BulkActions.js.map +1 -1
  109. package/dist/admin/legacy/pages/App/components/BulkActions.mjs +2 -1
  110. package/dist/admin/legacy/pages/App/components/BulkActions.mjs.map +1 -1
  111. package/dist/admin/legacy/pages/App/components/BulkMoveButton.js +2 -1
  112. package/dist/admin/legacy/pages/App/components/BulkMoveButton.js.map +1 -1
  113. package/dist/admin/legacy/pages/App/components/BulkMoveButton.mjs +2 -1
  114. package/dist/admin/legacy/pages/App/components/BulkMoveButton.mjs.map +1 -1
  115. package/dist/admin/pages/Assets/components/AssetsGrid.js +2 -1
  116. package/dist/admin/pages/Assets/components/AssetsGrid.js.map +1 -1
  117. package/dist/admin/pages/Assets/components/AssetsGrid.mjs +2 -1
  118. package/dist/admin/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  119. package/dist/admin/pages/Assets/components/AssetsTable.js +2 -1
  120. package/dist/admin/pages/Assets/components/AssetsTable.js.map +1 -1
  121. package/dist/admin/pages/Assets/components/AssetsTable.mjs +2 -1
  122. package/dist/admin/pages/Assets/components/AssetsTable.mjs.map +1 -1
  123. package/dist/admin/pages/Assets/components/BulkActionsBar.js +3 -1
  124. package/dist/admin/pages/Assets/components/BulkActionsBar.js.map +1 -1
  125. package/dist/admin/pages/Assets/components/BulkActionsBar.mjs +3 -1
  126. package/dist/admin/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
  127. package/dist/admin/pages/Assets/components/DateRangeCalendar.js +10 -7
  128. package/dist/admin/pages/Assets/components/DateRangeCalendar.js.map +1 -1
  129. package/dist/admin/pages/Assets/components/DateRangeCalendar.mjs +10 -7
  130. package/dist/admin/pages/Assets/components/DateRangeCalendar.mjs.map +1 -1
  131. package/dist/admin/pages/Assets/components/DropZone/UploadDropZoneContext.js +4 -2
  132. package/dist/admin/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
  133. package/dist/admin/pages/Assets/components/DropZone/UploadDropZoneContext.mjs +5 -3
  134. package/dist/admin/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
  135. package/dist/admin/pages/Assets/components/FilterBadges.js +32 -3
  136. package/dist/admin/pages/Assets/components/FilterBadges.js.map +1 -1
  137. package/dist/admin/pages/Assets/components/FilterBadges.mjs +33 -4
  138. package/dist/admin/pages/Assets/components/FilterBadges.mjs.map +1 -1
  139. package/dist/admin/services/api.js +15 -5
  140. package/dist/admin/services/api.js.map +1 -1
  141. package/dist/admin/services/api.mjs +15 -5
  142. package/dist/admin/services/api.mjs.map +1 -1
  143. package/dist/admin/src/components/MediaLibraryInput/AddAssetMenu.d.ts +19 -0
  144. package/dist/admin/src/components/MediaLibraryInput/AssetDropZone.d.ts +13 -0
  145. package/dist/admin/src/components/MediaLibraryInput/AssetRow.d.ts +15 -0
  146. package/dist/admin/src/components/MediaLibraryInput/MediaLibraryInput.d.ts +26 -0
  147. package/dist/admin/src/components/MediaLibraryInput/NoLibraryAccessDialog.d.ts +10 -0
  148. package/dist/admin/src/hooks/useMediaLibraryPermissions.d.ts +1 -0
  149. package/dist/admin/src/legacy/components/BulkMoveDialog/BulkMoveDialog.d.ts +1 -1
  150. package/dist/admin/src/legacy/pages/App/components/BulkActions.d.ts +1 -1
  151. package/dist/admin/src/services/api.d.ts +6 -0
  152. package/dist/admin/src/utils/allowedMediaTypes.d.ts +16 -0
  153. package/dist/admin/translations/ca.json.js +3 -3
  154. package/dist/admin/translations/ca.json.mjs +3 -3
  155. package/dist/admin/translations/da.json.js +1 -1
  156. package/dist/admin/translations/da.json.mjs +1 -1
  157. package/dist/admin/translations/de.json.js +1 -1
  158. package/dist/admin/translations/de.json.mjs +1 -1
  159. package/dist/admin/translations/en.json.js +9 -0
  160. package/dist/admin/translations/en.json.js.map +1 -1
  161. package/dist/admin/translations/en.json.mjs +9 -0
  162. package/dist/admin/translations/en.json.mjs.map +1 -1
  163. package/dist/admin/translations/es.json.js +1 -1
  164. package/dist/admin/translations/es.json.mjs +1 -1
  165. package/dist/admin/translations/sk.json.js +2 -2
  166. package/dist/admin/translations/sk.json.mjs +2 -2
  167. package/dist/admin/translations/tr.json.js +2 -2
  168. package/dist/admin/translations/tr.json.mjs +2 -2
  169. package/dist/admin/translations/zh-Hans.json.js +1 -1
  170. package/dist/admin/translations/zh-Hans.json.mjs +1 -1
  171. package/dist/admin/translations/zh.json.js +2 -2
  172. package/dist/admin/translations/zh.json.mjs +2 -2
  173. package/dist/admin/utils/allowedMediaTypes.js +42 -0
  174. package/dist/admin/utils/allowedMediaTypes.js.map +1 -0
  175. package/dist/admin/utils/allowedMediaTypes.mjs +39 -0
  176. package/dist/admin/utils/allowedMediaTypes.mjs.map +1 -0
  177. package/dist/server/config.js +6 -0
  178. package/dist/server/config.js.map +1 -1
  179. package/dist/server/config.mjs +6 -0
  180. package/dist/server/config.mjs.map +1 -1
  181. package/dist/server/controllers/validation/admin/upload.js.map +1 -1
  182. package/dist/server/controllers/validation/admin/upload.mjs.map +1 -1
  183. package/dist/server/controllers/validation/content-api/upload.js.map +1 -1
  184. package/dist/server/controllers/validation/content-api/upload.mjs.map +1 -1
  185. package/dist/server/mcp/ambient-instance.js +7 -5
  186. package/dist/server/mcp/ambient-instance.js.map +1 -1
  187. package/dist/server/mcp/ambient-instance.mjs +7 -5
  188. package/dist/server/mcp/ambient-instance.mjs.map +1 -1
  189. package/dist/server/mcp/handlers/folder-handlers.js +4 -16
  190. package/dist/server/mcp/handlers/folder-handlers.js.map +1 -1
  191. package/dist/server/mcp/handlers/folder-handlers.mjs +5 -17
  192. package/dist/server/mcp/handlers/folder-handlers.mjs.map +1 -1
  193. package/dist/server/mcp/handlers/read-handlers.js +6 -14
  194. package/dist/server/mcp/handlers/read-handlers.js.map +1 -1
  195. package/dist/server/mcp/handlers/read-handlers.mjs +7 -15
  196. package/dist/server/mcp/handlers/read-handlers.mjs.map +1 -1
  197. package/dist/server/mcp/handlers/write-handlers.js +3 -13
  198. package/dist/server/mcp/handlers/write-handlers.js.map +1 -1
  199. package/dist/server/mcp/handlers/write-handlers.mjs +3 -13
  200. package/dist/server/mcp/handlers/write-handlers.mjs.map +1 -1
  201. package/dist/server/mcp/register-upload-mcp-tools.js +215 -195
  202. package/dist/server/mcp/register-upload-mcp-tools.js.map +1 -1
  203. package/dist/server/mcp/register-upload-mcp-tools.mjs +215 -195
  204. package/dist/server/mcp/register-upload-mcp-tools.mjs.map +1 -1
  205. package/dist/server/services/image-manipulation.js +33 -14
  206. package/dist/server/services/image-manipulation.js.map +1 -1
  207. package/dist/server/services/image-manipulation.mjs +33 -14
  208. package/dist/server/services/image-manipulation.mjs.map +1 -1
  209. package/dist/server/src/config.d.ts +3 -0
  210. package/dist/server/src/config.d.ts.map +1 -1
  211. package/dist/server/src/controllers/validation/admin/upload.d.ts.map +1 -1
  212. package/dist/server/src/controllers/validation/content-api/upload.d.ts.map +1 -1
  213. package/dist/server/src/index.d.ts +3 -0
  214. package/dist/server/src/index.d.ts.map +1 -1
  215. package/dist/server/src/mcp/ambient-instance.d.ts +7 -5
  216. package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -1
  217. package/dist/server/src/mcp/handlers/folder-handlers.d.ts.map +1 -1
  218. package/dist/server/src/mcp/handlers/read-handlers.d.ts +3 -2
  219. package/dist/server/src/mcp/handlers/read-handlers.d.ts.map +1 -1
  220. package/dist/server/src/mcp/handlers/write-handlers.d.ts.map +1 -1
  221. package/dist/server/src/mcp/register-upload-mcp-tools.d.ts +9 -14
  222. package/dist/server/src/mcp/register-upload-mcp-tools.d.ts.map +1 -1
  223. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  224. package/dist/server/src/types.d.ts +1 -0
  225. package/dist/server/src/types.d.ts.map +1 -1
  226. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"UploadDropZoneContext.js","sources":["../../../../../../admin/src/pages/Assets/components/DropZone/UploadDropZoneContext.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n type DragEvent,\n type ReactNode,\n} from 'react';\n\nimport { Box } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n\ntype DropHandler = (files: File[]) => void | Promise<void>;\n\ninterface UploadDropZoneContextValue {\n isDragging: boolean;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\nconst UploadDropZoneContext = createContext<UploadDropZoneContextValue | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Components\n * -----------------------------------------------------------------------------------------------*/\n\nconst DropZoneWrapper = styled(Box)`\n position: relative;\n display: flex;\n flex-direction: column;\n min-height: 100%;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\n\ninterface UploadDropZoneProps {\n children: ReactNode;\n onDrop?: DropHandler;\n /**\n * When true, the zone never enters the dragging state and never fires\n * `onDrop` — no overlay, no \"drop here\" invitation. Used to hide the whole\n * upload affordance from users without `assets.create`, so they don't drag a\n * file onto an inviting target that then silently discards it.\n */\n disabled?: boolean;\n}\n\nexport const UploadDropZoneProvider = ({\n children,\n onDrop,\n disabled = false,\n}: UploadDropZoneProps) => {\n const [isDragging, setIsDragging] = useState(false);\n const dragCounterRef = useRef(0);\n\n const contextValue: UploadDropZoneContextValue = {\n isDragging,\n };\n\n useEffect(() => {\n const handleDragEnd = () => {\n setIsDragging(false);\n dragCounterRef.current = 0;\n };\n\n // Handle drag leaving the entire document/window\n const handleDocumentDragLeave = (e: globalThis.DragEvent) => {\n // When relatedTarget is null, we're leaving the document entirely\n if (!e.relatedTarget) {\n setIsDragging(false);\n dragCounterRef.current = 0;\n }\n };\n\n document.addEventListener('dragend', handleDragEnd);\n document.addEventListener('dragleave', handleDocumentDragLeave);\n\n return () => {\n document.removeEventListener('dragend', handleDragEnd);\n document.removeEventListener('dragleave', handleDocumentDragLeave);\n };\n }, []);\n\n const handleDragEnter = useCallback(\n (e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n\n // No upload permission → never light up the drop target.\n if (disabled) {\n return;\n }\n\n // Bidirectional guard with AssetsDndProvider — internal item drags must not\n // activate the upload overlay. See AssetsDndProvider.tsx.\n if (!e.dataTransfer.types.includes('Files')) {\n return;\n }\n\n dragCounterRef.current += 1;\n setIsDragging(true);\n },\n [disabled]\n );\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n\n dragCounterRef.current -= 1;\n\n // Only set dragging to false if we've left the dropzone completely\n // (counter reaches 0 or negative)\n if (dragCounterRef.current <= 0) {\n setIsDragging(false);\n dragCounterRef.current = 0;\n }\n }, []);\n\n const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n e.dataTransfer.dropEffect = 'copy';\n }, []);\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n dragCounterRef.current = 0;\n\n if (disabled) {\n return;\n }\n\n const { files } = e.dataTransfer;\n if (files?.length && onDrop) {\n onDrop(Array.from(files));\n }\n },\n [onDrop, disabled]\n );\n\n return (\n <UploadDropZoneContext.Provider value={contextValue}>\n <DropZoneWrapper\n data-testid=\"assets-dropzone\"\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n >\n {children}\n </DropZoneWrapper>\n </UploadDropZoneContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Hook\n * -----------------------------------------------------------------------------------------------*/\n\nexport const useUploadDropZone = () => {\n const context = useContext(UploadDropZoneContext);\n\n if (!context) {\n throw new Error('useUploadDropZone must be used within UploadDropZone');\n }\n\n return {\n isDragging: context.isDragging,\n };\n};\n"],"names":["UploadDropZoneContext","createContext","DropZoneWrapper","styled","Box","UploadDropZoneProvider","children","onDrop","disabled","isDragging","setIsDragging","useState","dragCounterRef","useRef","contextValue","useEffect","handleDragEnd","current","handleDocumentDragLeave","e","relatedTarget","document","addEventListener","removeEventListener","handleDragEnter","useCallback","preventDefault","stopPropagation","dataTransfer","types","includes","handleDragLeave","handleDragOver","dropEffect","handleDrop","files","length","Array","from","_jsx","Provider","value","data-testid","onDragEnter","onDragLeave","onDragOver","useUploadDropZone","context","useContext","Error"],"mappings":"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"}
1
+ {"version":3,"file":"UploadDropZoneContext.js","sources":["../../../../../../admin/src/pages/Assets/components/DropZone/UploadDropZoneContext.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type DragEvent,\n type ReactNode,\n} from 'react';\n\nimport { Box } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n\ntype DropHandler = (files: File[]) => void | Promise<void>;\n\ninterface UploadDropZoneContextValue {\n isDragging: boolean;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\nconst UploadDropZoneContext = createContext<UploadDropZoneContextValue | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Components\n * -----------------------------------------------------------------------------------------------*/\n\nconst DropZoneWrapper = styled(Box)`\n position: relative;\n display: flex;\n flex-direction: column;\n min-height: 100%;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\n\ninterface UploadDropZoneProps {\n children: ReactNode;\n onDrop?: DropHandler;\n /**\n * When true, the zone never enters the dragging state and never fires\n * `onDrop` — no overlay, no \"drop here\" invitation. Used to hide the whole\n * upload affordance from users without `assets.create`, so they don't drag a\n * file onto an inviting target that then silently discards it.\n */\n disabled?: boolean;\n}\n\nexport const UploadDropZoneProvider = ({\n children,\n onDrop,\n disabled = false,\n}: UploadDropZoneProps) => {\n const [isDragging, setIsDragging] = useState(false);\n const dragCounterRef = useRef(0);\n\n const contextValue = useMemo<UploadDropZoneContextValue>(() => ({ isDragging }), [isDragging]);\n\n useEffect(() => {\n const handleDragEnd = () => {\n setIsDragging(false);\n dragCounterRef.current = 0;\n };\n\n // Handle drag leaving the entire document/window\n const handleDocumentDragLeave = (e: globalThis.DragEvent) => {\n // When relatedTarget is null, we're leaving the document entirely\n if (!e.relatedTarget) {\n setIsDragging(false);\n dragCounterRef.current = 0;\n }\n };\n\n document.addEventListener('dragend', handleDragEnd);\n document.addEventListener('dragleave', handleDocumentDragLeave);\n\n return () => {\n document.removeEventListener('dragend', handleDragEnd);\n document.removeEventListener('dragleave', handleDocumentDragLeave);\n };\n }, []);\n\n const handleDragEnter = useCallback(\n (e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n\n // No upload permission → never light up the drop target.\n if (disabled) {\n return;\n }\n\n // Bidirectional guard with AssetsDndProvider — internal item drags must not\n // activate the upload overlay. See AssetsDndProvider.tsx.\n if (!e.dataTransfer.types.includes('Files')) {\n return;\n }\n\n dragCounterRef.current += 1;\n setIsDragging(true);\n },\n [disabled]\n );\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n\n dragCounterRef.current -= 1;\n\n // Only set dragging to false if we've left the dropzone completely\n // (counter reaches 0 or negative)\n if (dragCounterRef.current <= 0) {\n setIsDragging(false);\n dragCounterRef.current = 0;\n }\n }, []);\n\n const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n e.dataTransfer.dropEffect = 'copy';\n }, []);\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n dragCounterRef.current = 0;\n\n if (disabled) {\n return;\n }\n\n const { files } = e.dataTransfer;\n if (files?.length && onDrop) {\n onDrop(Array.from(files));\n }\n },\n [onDrop, disabled]\n );\n\n return (\n <UploadDropZoneContext.Provider value={contextValue}>\n <DropZoneWrapper\n data-testid=\"assets-dropzone\"\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n >\n {children}\n </DropZoneWrapper>\n </UploadDropZoneContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Hook\n * -----------------------------------------------------------------------------------------------*/\n\nexport const useUploadDropZone = () => {\n const context = useContext(UploadDropZoneContext);\n\n if (!context) {\n throw new Error('useUploadDropZone must be used within UploadDropZone');\n }\n\n return {\n isDragging: context.isDragging,\n };\n};\n"],"names":["UploadDropZoneContext","createContext","DropZoneWrapper","styled","Box","UploadDropZoneProvider","children","onDrop","disabled","isDragging","setIsDragging","useState","dragCounterRef","useRef","contextValue","useMemo","useEffect","handleDragEnd","current","handleDocumentDragLeave","e","relatedTarget","document","addEventListener","removeEventListener","handleDragEnter","useCallback","preventDefault","stopPropagation","dataTransfer","types","includes","handleDragLeave","handleDragOver","dropEffect","handleDrop","files","length","Array","from","_jsx","Provider","value","data-testid","onDragEnter","onDragLeave","onDragOver","useUploadDropZone","context","useContext","Error"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { useState, useRef, useEffect, useCallback, createContext, useContext } from 'react';
2
+ import { useState, useRef, useMemo, useEffect, useCallback, createContext, useContext } from 'react';
3
3
  import { Box } from '@strapi/design-system';
4
4
  import { styled } from 'styled-components';
5
5
 
@@ -17,9 +17,11 @@ import { styled } from 'styled-components';
17
17
  const UploadDropZoneProvider = ({ children, onDrop, disabled = false })=>{
18
18
  const [isDragging, setIsDragging] = useState(false);
19
19
  const dragCounterRef = useRef(0);
20
- const contextValue = {
20
+ const contextValue = useMemo(()=>({
21
+ isDragging
22
+ }), [
21
23
  isDragging
22
- };
24
+ ]);
23
25
  useEffect(()=>{
24
26
  const handleDragEnd = ()=>{
25
27
  setIsDragging(false);
@@ -1 +1 @@
1
- {"version":3,"file":"UploadDropZoneContext.mjs","sources":["../../../../../../admin/src/pages/Assets/components/DropZone/UploadDropZoneContext.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n type DragEvent,\n type ReactNode,\n} from 'react';\n\nimport { Box } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n\ntype DropHandler = (files: File[]) => void | Promise<void>;\n\ninterface UploadDropZoneContextValue {\n isDragging: boolean;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\nconst UploadDropZoneContext = createContext<UploadDropZoneContextValue | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Components\n * -----------------------------------------------------------------------------------------------*/\n\nconst DropZoneWrapper = styled(Box)`\n position: relative;\n display: flex;\n flex-direction: column;\n min-height: 100%;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\n\ninterface UploadDropZoneProps {\n children: ReactNode;\n onDrop?: DropHandler;\n /**\n * When true, the zone never enters the dragging state and never fires\n * `onDrop` — no overlay, no \"drop here\" invitation. Used to hide the whole\n * upload affordance from users without `assets.create`, so they don't drag a\n * file onto an inviting target that then silently discards it.\n */\n disabled?: boolean;\n}\n\nexport const UploadDropZoneProvider = ({\n children,\n onDrop,\n disabled = false,\n}: UploadDropZoneProps) => {\n const [isDragging, setIsDragging] = useState(false);\n const dragCounterRef = useRef(0);\n\n const contextValue: UploadDropZoneContextValue = {\n isDragging,\n };\n\n useEffect(() => {\n const handleDragEnd = () => {\n setIsDragging(false);\n dragCounterRef.current = 0;\n };\n\n // Handle drag leaving the entire document/window\n const handleDocumentDragLeave = (e: globalThis.DragEvent) => {\n // When relatedTarget is null, we're leaving the document entirely\n if (!e.relatedTarget) {\n setIsDragging(false);\n dragCounterRef.current = 0;\n }\n };\n\n document.addEventListener('dragend', handleDragEnd);\n document.addEventListener('dragleave', handleDocumentDragLeave);\n\n return () => {\n document.removeEventListener('dragend', handleDragEnd);\n document.removeEventListener('dragleave', handleDocumentDragLeave);\n };\n }, []);\n\n const handleDragEnter = useCallback(\n (e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n\n // No upload permission → never light up the drop target.\n if (disabled) {\n return;\n }\n\n // Bidirectional guard with AssetsDndProvider — internal item drags must not\n // activate the upload overlay. See AssetsDndProvider.tsx.\n if (!e.dataTransfer.types.includes('Files')) {\n return;\n }\n\n dragCounterRef.current += 1;\n setIsDragging(true);\n },\n [disabled]\n );\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n\n dragCounterRef.current -= 1;\n\n // Only set dragging to false if we've left the dropzone completely\n // (counter reaches 0 or negative)\n if (dragCounterRef.current <= 0) {\n setIsDragging(false);\n dragCounterRef.current = 0;\n }\n }, []);\n\n const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n e.dataTransfer.dropEffect = 'copy';\n }, []);\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n dragCounterRef.current = 0;\n\n if (disabled) {\n return;\n }\n\n const { files } = e.dataTransfer;\n if (files?.length && onDrop) {\n onDrop(Array.from(files));\n }\n },\n [onDrop, disabled]\n );\n\n return (\n <UploadDropZoneContext.Provider value={contextValue}>\n <DropZoneWrapper\n data-testid=\"assets-dropzone\"\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n >\n {children}\n </DropZoneWrapper>\n </UploadDropZoneContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Hook\n * -----------------------------------------------------------------------------------------------*/\n\nexport const useUploadDropZone = () => {\n const context = useContext(UploadDropZoneContext);\n\n if (!context) {\n throw new Error('useUploadDropZone must be used within UploadDropZone');\n }\n\n return {\n isDragging: context.isDragging,\n };\n};\n"],"names":["UploadDropZoneContext","createContext","DropZoneWrapper","styled","Box","UploadDropZoneProvider","children","onDrop","disabled","isDragging","setIsDragging","useState","dragCounterRef","useRef","contextValue","useEffect","handleDragEnd","current","handleDocumentDragLeave","e","relatedTarget","document","addEventListener","removeEventListener","handleDragEnter","useCallback","preventDefault","stopPropagation","dataTransfer","types","includes","handleDragLeave","handleDragOver","dropEffect","handleDrop","files","length","Array","from","_jsx","Provider","value","data-testid","onDragEnter","onDragLeave","onDragOver","useUploadDropZone","context","useContext","Error"],"mappings":"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"}
1
+ {"version":3,"file":"UploadDropZoneContext.mjs","sources":["../../../../../../admin/src/pages/Assets/components/DropZone/UploadDropZoneContext.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type DragEvent,\n type ReactNode,\n} from 'react';\n\nimport { Box } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\n/* -------------------------------------------------------------------------------------------------\n * Types\n * -----------------------------------------------------------------------------------------------*/\n\ntype DropHandler = (files: File[]) => void | Promise<void>;\n\ninterface UploadDropZoneContextValue {\n isDragging: boolean;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\nconst UploadDropZoneContext = createContext<UploadDropZoneContextValue | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Components\n * -----------------------------------------------------------------------------------------------*/\n\nconst DropZoneWrapper = styled(Box)`\n position: relative;\n display: flex;\n flex-direction: column;\n min-height: 100%;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\n\ninterface UploadDropZoneProps {\n children: ReactNode;\n onDrop?: DropHandler;\n /**\n * When true, the zone never enters the dragging state and never fires\n * `onDrop` — no overlay, no \"drop here\" invitation. Used to hide the whole\n * upload affordance from users without `assets.create`, so they don't drag a\n * file onto an inviting target that then silently discards it.\n */\n disabled?: boolean;\n}\n\nexport const UploadDropZoneProvider = ({\n children,\n onDrop,\n disabled = false,\n}: UploadDropZoneProps) => {\n const [isDragging, setIsDragging] = useState(false);\n const dragCounterRef = useRef(0);\n\n const contextValue = useMemo<UploadDropZoneContextValue>(() => ({ isDragging }), [isDragging]);\n\n useEffect(() => {\n const handleDragEnd = () => {\n setIsDragging(false);\n dragCounterRef.current = 0;\n };\n\n // Handle drag leaving the entire document/window\n const handleDocumentDragLeave = (e: globalThis.DragEvent) => {\n // When relatedTarget is null, we're leaving the document entirely\n if (!e.relatedTarget) {\n setIsDragging(false);\n dragCounterRef.current = 0;\n }\n };\n\n document.addEventListener('dragend', handleDragEnd);\n document.addEventListener('dragleave', handleDocumentDragLeave);\n\n return () => {\n document.removeEventListener('dragend', handleDragEnd);\n document.removeEventListener('dragleave', handleDocumentDragLeave);\n };\n }, []);\n\n const handleDragEnter = useCallback(\n (e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n\n // No upload permission → never light up the drop target.\n if (disabled) {\n return;\n }\n\n // Bidirectional guard with AssetsDndProvider — internal item drags must not\n // activate the upload overlay. See AssetsDndProvider.tsx.\n if (!e.dataTransfer.types.includes('Files')) {\n return;\n }\n\n dragCounterRef.current += 1;\n setIsDragging(true);\n },\n [disabled]\n );\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n\n dragCounterRef.current -= 1;\n\n // Only set dragging to false if we've left the dropzone completely\n // (counter reaches 0 or negative)\n if (dragCounterRef.current <= 0) {\n setIsDragging(false);\n dragCounterRef.current = 0;\n }\n }, []);\n\n const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n e.dataTransfer.dropEffect = 'copy';\n }, []);\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n dragCounterRef.current = 0;\n\n if (disabled) {\n return;\n }\n\n const { files } = e.dataTransfer;\n if (files?.length && onDrop) {\n onDrop(Array.from(files));\n }\n },\n [onDrop, disabled]\n );\n\n return (\n <UploadDropZoneContext.Provider value={contextValue}>\n <DropZoneWrapper\n data-testid=\"assets-dropzone\"\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n >\n {children}\n </DropZoneWrapper>\n </UploadDropZoneContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Hook\n * -----------------------------------------------------------------------------------------------*/\n\nexport const useUploadDropZone = () => {\n const context = useContext(UploadDropZoneContext);\n\n if (!context) {\n throw new Error('useUploadDropZone must be used within UploadDropZone');\n }\n\n return {\n isDragging: context.isDragging,\n };\n};\n"],"names":["UploadDropZoneContext","createContext","DropZoneWrapper","styled","Box","UploadDropZoneProvider","children","onDrop","disabled","isDragging","setIsDragging","useState","dragCounterRef","useRef","contextValue","useMemo","useEffect","handleDragEnd","current","handleDocumentDragLeave","e","relatedTarget","document","addEventListener","removeEventListener","handleDragEnter","useCallback","preventDefault","stopPropagation","dataTransfer","types","includes","handleDragLeave","handleDragOver","dropEffect","handleDrop","files","length","Array","from","_jsx","Provider","value","data-testid","onDragEnter","onDragLeave","onDragOver","useUploadDropZone","context","useContext","Error"],"mappings":"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"}
@@ -397,6 +397,32 @@ const BadgesRoot = styledComponents.styled(designSystem.Flex)`
397
397
  `;
398
398
  const FilterBadges = ({ listFilters, compact = false })=>{
399
399
  const { filters, updateFilter, removeFilter } = listFilters;
400
+ /**
401
+ * Stable per-slot keys held in a ref. The ref is written during render, but
402
+ * the bookkeeping depends on the list length rather than on how often render
403
+ * runs, so the second pass of a StrictMode double render sees equal lengths
404
+ * and does nothing. A content-derived key fails twice over here: filters may
405
+ * legitimately repeat, and the key would change while the user edits a badge,
406
+ * remounting the badge under its open popover.
407
+ */ const filterKeyPrefix = React.useId();
408
+ const nextFilterKey = React.useRef(0);
409
+ const filterKeys = React.useRef([]);
410
+ while(filterKeys.current.length < filters.length){
411
+ filterKeys.current.push(`${filterKeyPrefix}-${nextFilterKey.current}`);
412
+ nextFilterKey.current += 1;
413
+ }
414
+ /**
415
+ * Keys are truncated from the tail. The `onRemove` closure below splices the
416
+ * removed slot out first, so removal through this component is correct. Any
417
+ * other shrink path (browser back or forward, an external filter reset)
418
+ * shifts the remaining keys and degrades to the index keys this replaced.
419
+ * Known and accepted.
420
+ */ filterKeys.current.length = filters.length;
421
+ const filtersWithKeys = filters.map((filter, index)=>({
422
+ filter,
423
+ index,
424
+ key: filterKeys.current[index]
425
+ }));
400
426
  if (filters.length === 0) {
401
427
  return null;
402
428
  }
@@ -405,11 +431,14 @@ const FilterBadges = ({ listFilters, compact = false })=>{
405
431
  gap: 2,
406
432
  wrap: "wrap",
407
433
  "data-testid": "filter-badges",
408
- children: filters.map((filter, index)=>/*#__PURE__*/ jsxRuntime.jsx(FilterBadge, {
434
+ children: filtersWithKeys.map(({ filter, index, key })=>/*#__PURE__*/ jsxRuntime.jsx(FilterBadge, {
409
435
  filter: filter,
410
436
  onChange: (next)=>updateFilter(index, next),
411
- onRemove: ()=>removeFilter(index)
412
- }, index))
437
+ onRemove: ()=>{
438
+ filterKeys.current.splice(index, 1);
439
+ removeFilter(index);
440
+ }
441
+ }, key))
413
442
  });
414
443
  };
415
444
 
@@ -1 +1 @@
1
- {"version":3,"file":"FilterBadges.js","sources":["../../../../../admin/src/pages/Assets/components/FilterBadges.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport { Checkbox, Flex, Popover, Typography } from '@strapi/design-system';\nimport { Check, Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../utils/translations';\nimport {\n DATE_PRESETS,\n TYPE_VALUES,\n type DateFilter,\n type DatePreset,\n type ListFilter,\n type ListFilters,\n type PresetCondition,\n type RangeCondition,\n type TypeCondition,\n type TypeFilter,\n type TypeValue,\n} from '../hooks/useListFilters';\nimport { parseCalendarDate } from '../utils/buildAssetFilters';\n\nimport { DateRangeCalendar } from './DateRangeCalendar';\nimport { DATE_FIELD_LABELS, FILTER_PANEL_WIDTH, PRESET_LABELS, TYPE_LABELS } from './FilterMenu';\n\nimport type { MessageDescriptor } from 'react-intl';\n\n/**\n * Row of applied-filter badges under the toolbar. A badge has three segments —\n * field (static), condition (click → select popover), value (click → type\n * checkboxes / preset list / range calendar) — plus a remove button.\n */\n\nconst BadgePill = styled(Flex)`\n border: 1px solid ${({ theme }) => theme.colors.neutral200};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme }) => theme.colors.neutral0};\n overflow: hidden;\n`;\n\nconst Segment = styled.button<{ $interactive?: boolean }>`\n border: none;\n background: transparent;\n font: inherit;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`};\n cursor: ${({ $interactive }) => ($interactive ? 'pointer' : 'default')};\n border-right: 1px solid ${({ theme }) => theme.colors.neutral200};\n\n ${({ theme }) => theme.breakpoints.medium} {\n padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};\n }\n ${({ $interactive, theme }) =>\n $interactive && `&:hover { background: ${theme.colors.primary100}; }`}\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\n// Non-interactive field segment (first pill cell).\nconst FieldSegment = styled.span`\n display: inline-flex;\n align-items: center;\n padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};\n border-right: 1px solid ${({ theme }) => theme.colors.neutral200};\n`;\n\n// Badge popovers mirror the filter-menu panels: same fixed width, same font.\nconst PanelPopoverContent = styled(Popover.Content)`\n width: ${FILTER_PANEL_WIDTH};\n`;\n\n// Option row inside a segment popover — sized like a DS Menu.Item so the badge\n// dropdowns read as the same control family as the filter menu.\nconst OptionButton = styled.button`\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: ${({ theme }) => theme.spaces[4]};\n width: 100%;\n border: none;\n background: transparent;\n font-size: ${({ theme }) => theme.fontSizes[2]};\n line-height: ${({ theme }) => theme.lineHeights[4]};\n font-family: inherit;\n text-align: left;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[4]}`};\n border-radius: ${({ theme }) => theme.borderRadius};\n cursor: pointer;\n color: ${({ theme }) => theme.colors.neutral800};\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 RemoveButton = styled.button`\n border: none;\n background: transparent;\n display: inline-flex;\n align-items: center;\n padding: ${({ theme }) => `0 ${theme.spaces[2]}`};\n cursor: pointer;\n color: ${({ theme }) => theme.colors.neutral600};\n\n &:hover {\n color: ${({ theme }) => theme.colors.neutral800};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\nconst TYPE_CONDITION_LABELS: Record<TypeCondition, MessageDescriptor> = {\n is: { id: getTranslationKey('list.filters.condition.is'), defaultMessage: 'is' },\n isNot: { id: getTranslationKey('list.filters.condition.is-not'), defaultMessage: 'is not' },\n};\n\nconst PRESET_CONDITION_LABELS: Record<PresetCondition, MessageDescriptor> = {\n isExactly: {\n id: getTranslationKey('list.filters.condition.is-exactly'),\n defaultMessage: 'is exactly',\n },\n withinLast: {\n id: getTranslationKey('list.filters.condition.within-last'),\n defaultMessage: 'within the last',\n },\n notWithinLast: {\n id: getTranslationKey('list.filters.condition.not-within-last'),\n defaultMessage: 'not within the last',\n },\n};\n\nconst RANGE_CONDITION_LABELS: Record<RangeCondition, MessageDescriptor> = {\n is: { id: getTranslationKey('list.filters.condition.is'), defaultMessage: 'is' },\n isNot: { id: getTranslationKey('list.filters.condition.is-not'), defaultMessage: 'is not' },\n};\n\n/** A small single-choice popover listing options with a check on the active one. */\ninterface SegmentPopoverProps<T extends string> {\n label: string;\n options: T[];\n active: T;\n getOptionLabel: (option: T) => string;\n onPick: (option: T) => void;\n}\n\nconst SegmentPopover = <T extends string>({\n label,\n options,\n active,\n getOptionLabel,\n onPick,\n}: SegmentPopoverProps<T>) => {\n const [open, setOpen] = useState(false);\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Segment type=\"button\" $interactive>\n <Typography variant=\"pi\" textColor=\"neutral800\">\n {label}\n </Typography>\n </Segment>\n </Popover.Trigger>\n <PanelPopoverContent>\n <Flex direction=\"column\" alignItems=\"stretch\" padding={1}>\n {options.map((option) => (\n <OptionButton\n key={option}\n type=\"button\"\n onClick={() => {\n onPick(option);\n setOpen(false);\n }}\n >\n {getOptionLabel(option)}\n {option === active && <Check aria-hidden width=\"1.6rem\" height=\"1.6rem\" />}\n </OptionButton>\n ))}\n </Flex>\n </PanelPopoverContent>\n </Popover.Root>\n );\n};\n\nconst TypeValuePopover = ({\n filter,\n onChange,\n}: {\n filter: TypeFilter;\n onChange: (next: TypeFilter) => void;\n}) => {\n const { formatMessage } = useIntl();\n const [open, setOpen] = useState(false);\n\n const label = filter.values.map((value) => formatMessage(TYPE_LABELS[value])).join(', ');\n\n const toggleValue = (value: TypeValue) => {\n const nextValues = filter.values.includes(value)\n ? filter.values.filter((v) => v !== value)\n : [...filter.values, value];\n\n // At least one value stays checked — an empty badge is removed via ×, not here.\n if (nextValues.length > 0) {\n onChange({ ...filter, values: nextValues });\n }\n };\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Segment type=\"button\" $interactive>\n <Typography variant=\"pi\" textColor=\"neutral800\">\n {label}\n </Typography>\n </Segment>\n </Popover.Trigger>\n <PanelPopoverContent>\n <Flex direction=\"column\" alignItems=\"flex-start\" padding={3} gap={2}>\n {TYPE_VALUES.map((value) => (\n <Checkbox\n key={value}\n checked={filter.values.includes(value)}\n onCheckedChange={() => toggleValue(value)}\n >\n {formatMessage(TYPE_LABELS[value])}\n </Checkbox>\n ))}\n </Flex>\n </PanelPopoverContent>\n </Popover.Root>\n );\n};\n\nconst DateValuePopover = ({\n filter,\n onChange,\n}: {\n filter: DateFilter;\n onChange: (next: DateFilter) => void;\n}) => {\n const { formatMessage, formatDate } = useIntl();\n const [open, setOpen] = useState(false);\n\n // Parse as LOCAL calendar dates before formatting: react-intl would coerce\n // the raw `YYYY-MM-DD` strings via `new Date(value)` = UTC midnight, showing\n // the previous day in every timezone west of UTC while the query (also\n // local, see buildAssetFilters) filters the day the user actually picked.\n const label =\n filter.mode === 'preset'\n ? formatMessage(PRESET_LABELS[filter.preset])\n : `${formatDate(parseCalendarDate(filter.from), {\n day: '2-digit',\n month: 'short',\n })} - ${formatDate(parseCalendarDate(filter.to), {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n })}`;\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Segment type=\"button\" $interactive>\n <Typography variant=\"pi\" textColor=\"neutral800\">\n {label}\n </Typography>\n </Segment>\n </Popover.Trigger>\n <PanelPopoverContent>\n {filter.mode === 'preset' ? (\n <Flex direction=\"column\" alignItems=\"stretch\" padding={1}>\n {DATE_PRESETS.map((preset: DatePreset) => (\n <OptionButton\n key={preset}\n type=\"button\"\n onClick={() => {\n onChange({ ...filter, preset });\n setOpen(false);\n }}\n >\n {formatMessage(PRESET_LABELS[preset])}\n {preset === filter.preset && <Check aria-hidden width=\"1.6rem\" height=\"1.6rem\" />}\n </OptionButton>\n ))}\n </Flex>\n ) : (\n <DateRangeCalendar\n from={filter.from}\n to={filter.to}\n onSelect={(from, to) => {\n onChange({ ...filter, from, to });\n setOpen(false);\n }}\n />\n )}\n </PanelPopoverContent>\n </Popover.Root>\n );\n};\n\nconst FilterBadge = ({\n filter,\n onChange,\n onRemove,\n}: {\n filter: ListFilter;\n onChange: (next: ListFilter) => void;\n onRemove: () => void;\n}) => {\n const { formatMessage } = useIntl();\n\n const fieldLabel =\n filter.kind === 'type'\n ? formatMessage({ id: getTranslationKey('list.filters.field.type'), defaultMessage: 'Type' })\n : formatMessage(DATE_FIELD_LABELS[filter.field]);\n\n return (\n <BadgePill alignItems=\"stretch\" data-testid=\"filter-badge\">\n <FieldSegment>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {fieldLabel}\n </Typography>\n </FieldSegment>\n\n {filter.kind === 'type' && (\n <>\n <SegmentPopover\n label={formatMessage(TYPE_CONDITION_LABELS[filter.condition])}\n options={['is', 'isNot'] as TypeCondition[]}\n active={filter.condition}\n getOptionLabel={(option) => formatMessage(TYPE_CONDITION_LABELS[option])}\n onPick={(condition) => onChange({ ...filter, condition })}\n />\n <TypeValuePopover filter={filter} onChange={onChange} />\n </>\n )}\n\n {filter.kind === 'date' && filter.mode === 'preset' && (\n <>\n <SegmentPopover\n label={formatMessage(PRESET_CONDITION_LABELS[filter.condition])}\n options={['isExactly', 'withinLast', 'notWithinLast'] as PresetCondition[]}\n active={filter.condition}\n getOptionLabel={(option) => formatMessage(PRESET_CONDITION_LABELS[option])}\n onPick={(condition) => onChange({ ...filter, condition })}\n />\n <DateValuePopover filter={filter} onChange={onChange} />\n </>\n )}\n\n {filter.kind === 'date' && filter.mode === 'range' && (\n <>\n <SegmentPopover\n label={formatMessage(RANGE_CONDITION_LABELS[filter.condition])}\n options={['is', 'isNot'] as RangeCondition[]}\n active={filter.condition}\n getOptionLabel={(option) => formatMessage(RANGE_CONDITION_LABELS[option])}\n onPick={(condition) => onChange({ ...filter, condition })}\n />\n <DateValuePopover filter={filter} onChange={onChange} />\n </>\n )}\n\n <RemoveButton\n type=\"button\"\n onClick={onRemove}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.filters.remove'),\n defaultMessage: 'Remove {filter} filter',\n },\n { filter: fieldLabel }\n )}\n >\n <Cross width=\"1.2rem\" height=\"1.2rem\" aria-hidden />\n </RemoveButton>\n </BadgePill>\n );\n};\n\n// Tighten the gap above the badges when the sticky header is in its compact\n// (scrolled) state, matching the header's own shrink.\nconst BadgesRoot = styled(Flex)<{ $compact: boolean }>`\n padding-top: ${({ theme, $compact }) => ($compact ? theme.spaces[1] : theme.spaces[6])};\n transition: padding-top 0.2s ease;\n`;\n\ninterface FilterBadgesProps {\n listFilters: ListFilters;\n /** Sticky header is scrolled/compact — reduce the space above the badges. */\n compact?: boolean;\n}\n\nexport const FilterBadges = ({ listFilters, compact = false }: FilterBadgesProps) => {\n const { filters, updateFilter, removeFilter } = listFilters;\n\n if (filters.length === 0) {\n return null;\n }\n\n return (\n <BadgesRoot $compact={compact} gap={2} wrap=\"wrap\" data-testid=\"filter-badges\">\n {filters.map((filter, index) => (\n <FilterBadge\n // Position is identity: badges are edited/removed by index.\n key={index}\n filter={filter}\n onChange={(next) => updateFilter(index, next)}\n onRemove={() => removeFilter(index)}\n />\n ))}\n </BadgesRoot>\n );\n};\n"],"names":["BadgePill","styled","Flex","theme","colors","neutral200","borderRadius","neutral0","Segment","button","spaces","$interactive","breakpoints","medium","primary100","primary600","FieldSegment","span","PanelPopoverContent","Popover","Content","FILTER_PANEL_WIDTH","OptionButton","fontSizes","lineHeights","neutral800","RemoveButton","neutral600","TYPE_CONDITION_LABELS","is","id","getTranslationKey","defaultMessage","isNot","PRESET_CONDITION_LABELS","isExactly","withinLast","notWithinLast","RANGE_CONDITION_LABELS","SegmentPopover","label","options","active","getOptionLabel","onPick","open","setOpen","useState","_jsxs","Root","onOpenChange","_jsx","Trigger","type","Typography","variant","textColor","direction","alignItems","padding","map","option","onClick","Check","aria-hidden","width","height","TypeValuePopover","filter","onChange","formatMessage","useIntl","values","value","TYPE_LABELS","join","toggleValue","nextValues","includes","v","length","gap","TYPE_VALUES","Checkbox","checked","onCheckedChange","DateValuePopover","formatDate","mode","PRESET_LABELS","preset","parseCalendarDate","from","day","month","to","year","DATE_PRESETS","DateRangeCalendar","onSelect","FilterBadge","onRemove","fieldLabel","kind","DATE_FIELD_LABELS","field","data-testid","_Fragment","condition","aria-label","Cross","BadgesRoot","$compact","FilterBadges","listFilters","compact","filters","updateFilter","removeFilter","wrap","index","next"],"mappings":"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"}
1
+ {"version":3,"file":"FilterBadges.js","sources":["../../../../../admin/src/pages/Assets/components/FilterBadges.tsx"],"sourcesContent":["import { useId, useRef, useState } from 'react';\n\nimport { Checkbox, Flex, Popover, Typography } from '@strapi/design-system';\nimport { Check, Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../utils/translations';\nimport {\n DATE_PRESETS,\n TYPE_VALUES,\n type DateFilter,\n type DatePreset,\n type ListFilter,\n type ListFilters,\n type PresetCondition,\n type RangeCondition,\n type TypeCondition,\n type TypeFilter,\n type TypeValue,\n} from '../hooks/useListFilters';\nimport { parseCalendarDate } from '../utils/buildAssetFilters';\n\nimport { DateRangeCalendar } from './DateRangeCalendar';\nimport { DATE_FIELD_LABELS, FILTER_PANEL_WIDTH, PRESET_LABELS, TYPE_LABELS } from './FilterMenu';\n\nimport type { MessageDescriptor } from 'react-intl';\n\n/**\n * Row of applied-filter badges under the toolbar. A badge has three segments —\n * field (static), condition (click → select popover), value (click → type\n * checkboxes / preset list / range calendar) — plus a remove button.\n */\n\nconst BadgePill = styled(Flex)`\n border: 1px solid ${({ theme }) => theme.colors.neutral200};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme }) => theme.colors.neutral0};\n overflow: hidden;\n`;\n\nconst Segment = styled.button<{ $interactive?: boolean }>`\n border: none;\n background: transparent;\n font: inherit;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`};\n cursor: ${({ $interactive }) => ($interactive ? 'pointer' : 'default')};\n border-right: 1px solid ${({ theme }) => theme.colors.neutral200};\n\n ${({ theme }) => theme.breakpoints.medium} {\n padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};\n }\n ${({ $interactive, theme }) =>\n $interactive && `&:hover { background: ${theme.colors.primary100}; }`}\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\n// Non-interactive field segment (first pill cell).\nconst FieldSegment = styled.span`\n display: inline-flex;\n align-items: center;\n padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};\n border-right: 1px solid ${({ theme }) => theme.colors.neutral200};\n`;\n\n// Badge popovers mirror the filter-menu panels: same fixed width, same font.\nconst PanelPopoverContent = styled(Popover.Content)`\n width: ${FILTER_PANEL_WIDTH};\n`;\n\n// Option row inside a segment popover — sized like a DS Menu.Item so the badge\n// dropdowns read as the same control family as the filter menu.\nconst OptionButton = styled.button`\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: ${({ theme }) => theme.spaces[4]};\n width: 100%;\n border: none;\n background: transparent;\n font-size: ${({ theme }) => theme.fontSizes[2]};\n line-height: ${({ theme }) => theme.lineHeights[4]};\n font-family: inherit;\n text-align: left;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[4]}`};\n border-radius: ${({ theme }) => theme.borderRadius};\n cursor: pointer;\n color: ${({ theme }) => theme.colors.neutral800};\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 RemoveButton = styled.button`\n border: none;\n background: transparent;\n display: inline-flex;\n align-items: center;\n padding: ${({ theme }) => `0 ${theme.spaces[2]}`};\n cursor: pointer;\n color: ${({ theme }) => theme.colors.neutral600};\n\n &:hover {\n color: ${({ theme }) => theme.colors.neutral800};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\nconst TYPE_CONDITION_LABELS: Record<TypeCondition, MessageDescriptor> = {\n is: { id: getTranslationKey('list.filters.condition.is'), defaultMessage: 'is' },\n isNot: { id: getTranslationKey('list.filters.condition.is-not'), defaultMessage: 'is not' },\n};\n\nconst PRESET_CONDITION_LABELS: Record<PresetCondition, MessageDescriptor> = {\n isExactly: {\n id: getTranslationKey('list.filters.condition.is-exactly'),\n defaultMessage: 'is exactly',\n },\n withinLast: {\n id: getTranslationKey('list.filters.condition.within-last'),\n defaultMessage: 'within the last',\n },\n notWithinLast: {\n id: getTranslationKey('list.filters.condition.not-within-last'),\n defaultMessage: 'not within the last',\n },\n};\n\nconst RANGE_CONDITION_LABELS: Record<RangeCondition, MessageDescriptor> = {\n is: { id: getTranslationKey('list.filters.condition.is'), defaultMessage: 'is' },\n isNot: { id: getTranslationKey('list.filters.condition.is-not'), defaultMessage: 'is not' },\n};\n\n/** A small single-choice popover listing options with a check on the active one. */\ninterface SegmentPopoverProps<T extends string> {\n label: string;\n options: T[];\n active: T;\n getOptionLabel: (option: T) => string;\n onPick: (option: T) => void;\n}\n\nconst SegmentPopover = <T extends string>({\n label,\n options,\n active,\n getOptionLabel,\n onPick,\n}: SegmentPopoverProps<T>) => {\n const [open, setOpen] = useState(false);\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Segment type=\"button\" $interactive>\n <Typography variant=\"pi\" textColor=\"neutral800\">\n {label}\n </Typography>\n </Segment>\n </Popover.Trigger>\n <PanelPopoverContent>\n <Flex direction=\"column\" alignItems=\"stretch\" padding={1}>\n {options.map((option) => (\n <OptionButton\n key={option}\n type=\"button\"\n onClick={() => {\n onPick(option);\n setOpen(false);\n }}\n >\n {getOptionLabel(option)}\n {option === active && <Check aria-hidden width=\"1.6rem\" height=\"1.6rem\" />}\n </OptionButton>\n ))}\n </Flex>\n </PanelPopoverContent>\n </Popover.Root>\n );\n};\n\nconst TypeValuePopover = ({\n filter,\n onChange,\n}: {\n filter: TypeFilter;\n onChange: (next: TypeFilter) => void;\n}) => {\n const { formatMessage } = useIntl();\n const [open, setOpen] = useState(false);\n\n const label = filter.values.map((value) => formatMessage(TYPE_LABELS[value])).join(', ');\n\n const toggleValue = (value: TypeValue) => {\n const nextValues = filter.values.includes(value)\n ? filter.values.filter((v) => v !== value)\n : [...filter.values, value];\n\n // At least one value stays checked — an empty badge is removed via ×, not here.\n if (nextValues.length > 0) {\n onChange({ ...filter, values: nextValues });\n }\n };\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Segment type=\"button\" $interactive>\n <Typography variant=\"pi\" textColor=\"neutral800\">\n {label}\n </Typography>\n </Segment>\n </Popover.Trigger>\n <PanelPopoverContent>\n <Flex direction=\"column\" alignItems=\"flex-start\" padding={3} gap={2}>\n {TYPE_VALUES.map((value) => (\n <Checkbox\n key={value}\n checked={filter.values.includes(value)}\n onCheckedChange={() => toggleValue(value)}\n >\n {formatMessage(TYPE_LABELS[value])}\n </Checkbox>\n ))}\n </Flex>\n </PanelPopoverContent>\n </Popover.Root>\n );\n};\n\nconst DateValuePopover = ({\n filter,\n onChange,\n}: {\n filter: DateFilter;\n onChange: (next: DateFilter) => void;\n}) => {\n const { formatMessage, formatDate } = useIntl();\n const [open, setOpen] = useState(false);\n\n // Parse as LOCAL calendar dates before formatting: react-intl would coerce\n // the raw `YYYY-MM-DD` strings via `new Date(value)` = UTC midnight, showing\n // the previous day in every timezone west of UTC while the query (also\n // local, see buildAssetFilters) filters the day the user actually picked.\n const label =\n filter.mode === 'preset'\n ? formatMessage(PRESET_LABELS[filter.preset])\n : `${formatDate(parseCalendarDate(filter.from), {\n day: '2-digit',\n month: 'short',\n })} - ${formatDate(parseCalendarDate(filter.to), {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n })}`;\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Segment type=\"button\" $interactive>\n <Typography variant=\"pi\" textColor=\"neutral800\">\n {label}\n </Typography>\n </Segment>\n </Popover.Trigger>\n <PanelPopoverContent>\n {filter.mode === 'preset' ? (\n <Flex direction=\"column\" alignItems=\"stretch\" padding={1}>\n {DATE_PRESETS.map((preset: DatePreset) => (\n <OptionButton\n key={preset}\n type=\"button\"\n onClick={() => {\n onChange({ ...filter, preset });\n setOpen(false);\n }}\n >\n {formatMessage(PRESET_LABELS[preset])}\n {preset === filter.preset && <Check aria-hidden width=\"1.6rem\" height=\"1.6rem\" />}\n </OptionButton>\n ))}\n </Flex>\n ) : (\n <DateRangeCalendar\n from={filter.from}\n to={filter.to}\n onSelect={(from, to) => {\n onChange({ ...filter, from, to });\n setOpen(false);\n }}\n />\n )}\n </PanelPopoverContent>\n </Popover.Root>\n );\n};\n\nconst FilterBadge = ({\n filter,\n onChange,\n onRemove,\n}: {\n filter: ListFilter;\n onChange: (next: ListFilter) => void;\n onRemove: () => void;\n}) => {\n const { formatMessage } = useIntl();\n\n const fieldLabel =\n filter.kind === 'type'\n ? formatMessage({ id: getTranslationKey('list.filters.field.type'), defaultMessage: 'Type' })\n : formatMessage(DATE_FIELD_LABELS[filter.field]);\n\n return (\n <BadgePill alignItems=\"stretch\" data-testid=\"filter-badge\">\n <FieldSegment>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {fieldLabel}\n </Typography>\n </FieldSegment>\n\n {filter.kind === 'type' && (\n <>\n <SegmentPopover\n label={formatMessage(TYPE_CONDITION_LABELS[filter.condition])}\n options={['is', 'isNot'] as TypeCondition[]}\n active={filter.condition}\n getOptionLabel={(option) => formatMessage(TYPE_CONDITION_LABELS[option])}\n onPick={(condition) => onChange({ ...filter, condition })}\n />\n <TypeValuePopover filter={filter} onChange={onChange} />\n </>\n )}\n\n {filter.kind === 'date' && filter.mode === 'preset' && (\n <>\n <SegmentPopover\n label={formatMessage(PRESET_CONDITION_LABELS[filter.condition])}\n options={['isExactly', 'withinLast', 'notWithinLast'] as PresetCondition[]}\n active={filter.condition}\n getOptionLabel={(option) => formatMessage(PRESET_CONDITION_LABELS[option])}\n onPick={(condition) => onChange({ ...filter, condition })}\n />\n <DateValuePopover filter={filter} onChange={onChange} />\n </>\n )}\n\n {filter.kind === 'date' && filter.mode === 'range' && (\n <>\n <SegmentPopover\n label={formatMessage(RANGE_CONDITION_LABELS[filter.condition])}\n options={['is', 'isNot'] as RangeCondition[]}\n active={filter.condition}\n getOptionLabel={(option) => formatMessage(RANGE_CONDITION_LABELS[option])}\n onPick={(condition) => onChange({ ...filter, condition })}\n />\n <DateValuePopover filter={filter} onChange={onChange} />\n </>\n )}\n\n <RemoveButton\n type=\"button\"\n onClick={onRemove}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.filters.remove'),\n defaultMessage: 'Remove {filter} filter',\n },\n { filter: fieldLabel }\n )}\n >\n <Cross width=\"1.2rem\" height=\"1.2rem\" aria-hidden />\n </RemoveButton>\n </BadgePill>\n );\n};\n\n// Tighten the gap above the badges when the sticky header is in its compact\n// (scrolled) state, matching the header's own shrink.\nconst BadgesRoot = styled(Flex)<{ $compact: boolean }>`\n padding-top: ${({ theme, $compact }) => ($compact ? theme.spaces[1] : theme.spaces[6])};\n transition: padding-top 0.2s ease;\n`;\n\ninterface FilterBadgesProps {\n listFilters: ListFilters;\n /** Sticky header is scrolled/compact — reduce the space above the badges. */\n compact?: boolean;\n}\n\nexport const FilterBadges = ({ listFilters, compact = false }: FilterBadgesProps) => {\n const { filters, updateFilter, removeFilter } = listFilters;\n /**\n * Stable per-slot keys held in a ref. The ref is written during render, but\n * the bookkeeping depends on the list length rather than on how often render\n * runs, so the second pass of a StrictMode double render sees equal lengths\n * and does nothing. A content-derived key fails twice over here: filters may\n * legitimately repeat, and the key would change while the user edits a badge,\n * remounting the badge under its open popover.\n */\n const filterKeyPrefix = useId();\n const nextFilterKey = useRef(0);\n const filterKeys = useRef<string[]>([]);\n\n while (filterKeys.current.length < filters.length) {\n filterKeys.current.push(`${filterKeyPrefix}-${nextFilterKey.current}`);\n nextFilterKey.current += 1;\n }\n /**\n * Keys are truncated from the tail. The `onRemove` closure below splices the\n * removed slot out first, so removal through this component is correct. Any\n * other shrink path (browser back or forward, an external filter reset)\n * shifts the remaining keys and degrades to the index keys this replaced.\n * Known and accepted.\n */\n filterKeys.current.length = filters.length;\n\n const filtersWithKeys = filters.map((filter, index) => ({\n filter,\n index,\n key: filterKeys.current[index],\n }));\n\n if (filters.length === 0) {\n return null;\n }\n\n return (\n <BadgesRoot $compact={compact} gap={2} wrap=\"wrap\" data-testid=\"filter-badges\">\n {filtersWithKeys.map(({ filter, index, key }) => (\n <FilterBadge\n key={key}\n filter={filter}\n onChange={(next) => updateFilter(index, next)}\n onRemove={() => {\n filterKeys.current.splice(index, 1);\n removeFilter(index);\n }}\n />\n ))}\n </BadgesRoot>\n );\n};\n"],"names":["BadgePill","styled","Flex","theme","colors","neutral200","borderRadius","neutral0","Segment","button","spaces","$interactive","breakpoints","medium","primary100","primary600","FieldSegment","span","PanelPopoverContent","Popover","Content","FILTER_PANEL_WIDTH","OptionButton","fontSizes","lineHeights","neutral800","RemoveButton","neutral600","TYPE_CONDITION_LABELS","is","id","getTranslationKey","defaultMessage","isNot","PRESET_CONDITION_LABELS","isExactly","withinLast","notWithinLast","RANGE_CONDITION_LABELS","SegmentPopover","label","options","active","getOptionLabel","onPick","open","setOpen","useState","_jsxs","Root","onOpenChange","_jsx","Trigger","type","Typography","variant","textColor","direction","alignItems","padding","map","option","onClick","Check","aria-hidden","width","height","TypeValuePopover","filter","onChange","formatMessage","useIntl","values","value","TYPE_LABELS","join","toggleValue","nextValues","includes","v","length","gap","TYPE_VALUES","Checkbox","checked","onCheckedChange","DateValuePopover","formatDate","mode","PRESET_LABELS","preset","parseCalendarDate","from","day","month","to","year","DATE_PRESETS","DateRangeCalendar","onSelect","FilterBadge","onRemove","fieldLabel","kind","DATE_FIELD_LABELS","field","data-testid","_Fragment","condition","aria-label","Cross","BadgesRoot","$compact","FilterBadges","listFilters","compact","filters","updateFilter","removeFilter","filterKeyPrefix","useId","nextFilterKey","useRef","filterKeys","current","push","filtersWithKeys","index","key","wrap","next","splice"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { useState } from 'react';
2
+ import { useId, useRef, useState } from 'react';
3
3
  import { Flex, Typography, Popover, Checkbox } from '@strapi/design-system';
4
4
  import { Cross, Check } from '@strapi/icons';
5
5
  import { useIntl } from 'react-intl';
@@ -395,6 +395,32 @@ const BadgesRoot = styled(Flex)`
395
395
  `;
396
396
  const FilterBadges = ({ listFilters, compact = false })=>{
397
397
  const { filters, updateFilter, removeFilter } = listFilters;
398
+ /**
399
+ * Stable per-slot keys held in a ref. The ref is written during render, but
400
+ * the bookkeeping depends on the list length rather than on how often render
401
+ * runs, so the second pass of a StrictMode double render sees equal lengths
402
+ * and does nothing. A content-derived key fails twice over here: filters may
403
+ * legitimately repeat, and the key would change while the user edits a badge,
404
+ * remounting the badge under its open popover.
405
+ */ const filterKeyPrefix = useId();
406
+ const nextFilterKey = useRef(0);
407
+ const filterKeys = useRef([]);
408
+ while(filterKeys.current.length < filters.length){
409
+ filterKeys.current.push(`${filterKeyPrefix}-${nextFilterKey.current}`);
410
+ nextFilterKey.current += 1;
411
+ }
412
+ /**
413
+ * Keys are truncated from the tail. The `onRemove` closure below splices the
414
+ * removed slot out first, so removal through this component is correct. Any
415
+ * other shrink path (browser back or forward, an external filter reset)
416
+ * shifts the remaining keys and degrades to the index keys this replaced.
417
+ * Known and accepted.
418
+ */ filterKeys.current.length = filters.length;
419
+ const filtersWithKeys = filters.map((filter, index)=>({
420
+ filter,
421
+ index,
422
+ key: filterKeys.current[index]
423
+ }));
398
424
  if (filters.length === 0) {
399
425
  return null;
400
426
  }
@@ -403,11 +429,14 @@ const FilterBadges = ({ listFilters, compact = false })=>{
403
429
  gap: 2,
404
430
  wrap: "wrap",
405
431
  "data-testid": "filter-badges",
406
- children: filters.map((filter, index)=>/*#__PURE__*/ jsx(FilterBadge, {
432
+ children: filtersWithKeys.map(({ filter, index, key })=>/*#__PURE__*/ jsx(FilterBadge, {
407
433
  filter: filter,
408
434
  onChange: (next)=>updateFilter(index, next),
409
- onRemove: ()=>removeFilter(index)
410
- }, index))
435
+ onRemove: ()=>{
436
+ filterKeys.current.splice(index, 1);
437
+ removeFilter(index);
438
+ }
439
+ }, key))
411
440
  });
412
441
  };
413
442
 
@@ -1 +1 @@
1
- {"version":3,"file":"FilterBadges.mjs","sources":["../../../../../admin/src/pages/Assets/components/FilterBadges.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport { Checkbox, Flex, Popover, Typography } from '@strapi/design-system';\nimport { Check, Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../utils/translations';\nimport {\n DATE_PRESETS,\n TYPE_VALUES,\n type DateFilter,\n type DatePreset,\n type ListFilter,\n type ListFilters,\n type PresetCondition,\n type RangeCondition,\n type TypeCondition,\n type TypeFilter,\n type TypeValue,\n} from '../hooks/useListFilters';\nimport { parseCalendarDate } from '../utils/buildAssetFilters';\n\nimport { DateRangeCalendar } from './DateRangeCalendar';\nimport { DATE_FIELD_LABELS, FILTER_PANEL_WIDTH, PRESET_LABELS, TYPE_LABELS } from './FilterMenu';\n\nimport type { MessageDescriptor } from 'react-intl';\n\n/**\n * Row of applied-filter badges under the toolbar. A badge has three segments —\n * field (static), condition (click → select popover), value (click → type\n * checkboxes / preset list / range calendar) — plus a remove button.\n */\n\nconst BadgePill = styled(Flex)`\n border: 1px solid ${({ theme }) => theme.colors.neutral200};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme }) => theme.colors.neutral0};\n overflow: hidden;\n`;\n\nconst Segment = styled.button<{ $interactive?: boolean }>`\n border: none;\n background: transparent;\n font: inherit;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`};\n cursor: ${({ $interactive }) => ($interactive ? 'pointer' : 'default')};\n border-right: 1px solid ${({ theme }) => theme.colors.neutral200};\n\n ${({ theme }) => theme.breakpoints.medium} {\n padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};\n }\n ${({ $interactive, theme }) =>\n $interactive && `&:hover { background: ${theme.colors.primary100}; }`}\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\n// Non-interactive field segment (first pill cell).\nconst FieldSegment = styled.span`\n display: inline-flex;\n align-items: center;\n padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};\n border-right: 1px solid ${({ theme }) => theme.colors.neutral200};\n`;\n\n// Badge popovers mirror the filter-menu panels: same fixed width, same font.\nconst PanelPopoverContent = styled(Popover.Content)`\n width: ${FILTER_PANEL_WIDTH};\n`;\n\n// Option row inside a segment popover — sized like a DS Menu.Item so the badge\n// dropdowns read as the same control family as the filter menu.\nconst OptionButton = styled.button`\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: ${({ theme }) => theme.spaces[4]};\n width: 100%;\n border: none;\n background: transparent;\n font-size: ${({ theme }) => theme.fontSizes[2]};\n line-height: ${({ theme }) => theme.lineHeights[4]};\n font-family: inherit;\n text-align: left;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[4]}`};\n border-radius: ${({ theme }) => theme.borderRadius};\n cursor: pointer;\n color: ${({ theme }) => theme.colors.neutral800};\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 RemoveButton = styled.button`\n border: none;\n background: transparent;\n display: inline-flex;\n align-items: center;\n padding: ${({ theme }) => `0 ${theme.spaces[2]}`};\n cursor: pointer;\n color: ${({ theme }) => theme.colors.neutral600};\n\n &:hover {\n color: ${({ theme }) => theme.colors.neutral800};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\nconst TYPE_CONDITION_LABELS: Record<TypeCondition, MessageDescriptor> = {\n is: { id: getTranslationKey('list.filters.condition.is'), defaultMessage: 'is' },\n isNot: { id: getTranslationKey('list.filters.condition.is-not'), defaultMessage: 'is not' },\n};\n\nconst PRESET_CONDITION_LABELS: Record<PresetCondition, MessageDescriptor> = {\n isExactly: {\n id: getTranslationKey('list.filters.condition.is-exactly'),\n defaultMessage: 'is exactly',\n },\n withinLast: {\n id: getTranslationKey('list.filters.condition.within-last'),\n defaultMessage: 'within the last',\n },\n notWithinLast: {\n id: getTranslationKey('list.filters.condition.not-within-last'),\n defaultMessage: 'not within the last',\n },\n};\n\nconst RANGE_CONDITION_LABELS: Record<RangeCondition, MessageDescriptor> = {\n is: { id: getTranslationKey('list.filters.condition.is'), defaultMessage: 'is' },\n isNot: { id: getTranslationKey('list.filters.condition.is-not'), defaultMessage: 'is not' },\n};\n\n/** A small single-choice popover listing options with a check on the active one. */\ninterface SegmentPopoverProps<T extends string> {\n label: string;\n options: T[];\n active: T;\n getOptionLabel: (option: T) => string;\n onPick: (option: T) => void;\n}\n\nconst SegmentPopover = <T extends string>({\n label,\n options,\n active,\n getOptionLabel,\n onPick,\n}: SegmentPopoverProps<T>) => {\n const [open, setOpen] = useState(false);\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Segment type=\"button\" $interactive>\n <Typography variant=\"pi\" textColor=\"neutral800\">\n {label}\n </Typography>\n </Segment>\n </Popover.Trigger>\n <PanelPopoverContent>\n <Flex direction=\"column\" alignItems=\"stretch\" padding={1}>\n {options.map((option) => (\n <OptionButton\n key={option}\n type=\"button\"\n onClick={() => {\n onPick(option);\n setOpen(false);\n }}\n >\n {getOptionLabel(option)}\n {option === active && <Check aria-hidden width=\"1.6rem\" height=\"1.6rem\" />}\n </OptionButton>\n ))}\n </Flex>\n </PanelPopoverContent>\n </Popover.Root>\n );\n};\n\nconst TypeValuePopover = ({\n filter,\n onChange,\n}: {\n filter: TypeFilter;\n onChange: (next: TypeFilter) => void;\n}) => {\n const { formatMessage } = useIntl();\n const [open, setOpen] = useState(false);\n\n const label = filter.values.map((value) => formatMessage(TYPE_LABELS[value])).join(', ');\n\n const toggleValue = (value: TypeValue) => {\n const nextValues = filter.values.includes(value)\n ? filter.values.filter((v) => v !== value)\n : [...filter.values, value];\n\n // At least one value stays checked — an empty badge is removed via ×, not here.\n if (nextValues.length > 0) {\n onChange({ ...filter, values: nextValues });\n }\n };\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Segment type=\"button\" $interactive>\n <Typography variant=\"pi\" textColor=\"neutral800\">\n {label}\n </Typography>\n </Segment>\n </Popover.Trigger>\n <PanelPopoverContent>\n <Flex direction=\"column\" alignItems=\"flex-start\" padding={3} gap={2}>\n {TYPE_VALUES.map((value) => (\n <Checkbox\n key={value}\n checked={filter.values.includes(value)}\n onCheckedChange={() => toggleValue(value)}\n >\n {formatMessage(TYPE_LABELS[value])}\n </Checkbox>\n ))}\n </Flex>\n </PanelPopoverContent>\n </Popover.Root>\n );\n};\n\nconst DateValuePopover = ({\n filter,\n onChange,\n}: {\n filter: DateFilter;\n onChange: (next: DateFilter) => void;\n}) => {\n const { formatMessage, formatDate } = useIntl();\n const [open, setOpen] = useState(false);\n\n // Parse as LOCAL calendar dates before formatting: react-intl would coerce\n // the raw `YYYY-MM-DD` strings via `new Date(value)` = UTC midnight, showing\n // the previous day in every timezone west of UTC while the query (also\n // local, see buildAssetFilters) filters the day the user actually picked.\n const label =\n filter.mode === 'preset'\n ? formatMessage(PRESET_LABELS[filter.preset])\n : `${formatDate(parseCalendarDate(filter.from), {\n day: '2-digit',\n month: 'short',\n })} - ${formatDate(parseCalendarDate(filter.to), {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n })}`;\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Segment type=\"button\" $interactive>\n <Typography variant=\"pi\" textColor=\"neutral800\">\n {label}\n </Typography>\n </Segment>\n </Popover.Trigger>\n <PanelPopoverContent>\n {filter.mode === 'preset' ? (\n <Flex direction=\"column\" alignItems=\"stretch\" padding={1}>\n {DATE_PRESETS.map((preset: DatePreset) => (\n <OptionButton\n key={preset}\n type=\"button\"\n onClick={() => {\n onChange({ ...filter, preset });\n setOpen(false);\n }}\n >\n {formatMessage(PRESET_LABELS[preset])}\n {preset === filter.preset && <Check aria-hidden width=\"1.6rem\" height=\"1.6rem\" />}\n </OptionButton>\n ))}\n </Flex>\n ) : (\n <DateRangeCalendar\n from={filter.from}\n to={filter.to}\n onSelect={(from, to) => {\n onChange({ ...filter, from, to });\n setOpen(false);\n }}\n />\n )}\n </PanelPopoverContent>\n </Popover.Root>\n );\n};\n\nconst FilterBadge = ({\n filter,\n onChange,\n onRemove,\n}: {\n filter: ListFilter;\n onChange: (next: ListFilter) => void;\n onRemove: () => void;\n}) => {\n const { formatMessage } = useIntl();\n\n const fieldLabel =\n filter.kind === 'type'\n ? formatMessage({ id: getTranslationKey('list.filters.field.type'), defaultMessage: 'Type' })\n : formatMessage(DATE_FIELD_LABELS[filter.field]);\n\n return (\n <BadgePill alignItems=\"stretch\" data-testid=\"filter-badge\">\n <FieldSegment>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {fieldLabel}\n </Typography>\n </FieldSegment>\n\n {filter.kind === 'type' && (\n <>\n <SegmentPopover\n label={formatMessage(TYPE_CONDITION_LABELS[filter.condition])}\n options={['is', 'isNot'] as TypeCondition[]}\n active={filter.condition}\n getOptionLabel={(option) => formatMessage(TYPE_CONDITION_LABELS[option])}\n onPick={(condition) => onChange({ ...filter, condition })}\n />\n <TypeValuePopover filter={filter} onChange={onChange} />\n </>\n )}\n\n {filter.kind === 'date' && filter.mode === 'preset' && (\n <>\n <SegmentPopover\n label={formatMessage(PRESET_CONDITION_LABELS[filter.condition])}\n options={['isExactly', 'withinLast', 'notWithinLast'] as PresetCondition[]}\n active={filter.condition}\n getOptionLabel={(option) => formatMessage(PRESET_CONDITION_LABELS[option])}\n onPick={(condition) => onChange({ ...filter, condition })}\n />\n <DateValuePopover filter={filter} onChange={onChange} />\n </>\n )}\n\n {filter.kind === 'date' && filter.mode === 'range' && (\n <>\n <SegmentPopover\n label={formatMessage(RANGE_CONDITION_LABELS[filter.condition])}\n options={['is', 'isNot'] as RangeCondition[]}\n active={filter.condition}\n getOptionLabel={(option) => formatMessage(RANGE_CONDITION_LABELS[option])}\n onPick={(condition) => onChange({ ...filter, condition })}\n />\n <DateValuePopover filter={filter} onChange={onChange} />\n </>\n )}\n\n <RemoveButton\n type=\"button\"\n onClick={onRemove}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.filters.remove'),\n defaultMessage: 'Remove {filter} filter',\n },\n { filter: fieldLabel }\n )}\n >\n <Cross width=\"1.2rem\" height=\"1.2rem\" aria-hidden />\n </RemoveButton>\n </BadgePill>\n );\n};\n\n// Tighten the gap above the badges when the sticky header is in its compact\n// (scrolled) state, matching the header's own shrink.\nconst BadgesRoot = styled(Flex)<{ $compact: boolean }>`\n padding-top: ${({ theme, $compact }) => ($compact ? theme.spaces[1] : theme.spaces[6])};\n transition: padding-top 0.2s ease;\n`;\n\ninterface FilterBadgesProps {\n listFilters: ListFilters;\n /** Sticky header is scrolled/compact — reduce the space above the badges. */\n compact?: boolean;\n}\n\nexport const FilterBadges = ({ listFilters, compact = false }: FilterBadgesProps) => {\n const { filters, updateFilter, removeFilter } = listFilters;\n\n if (filters.length === 0) {\n return null;\n }\n\n return (\n <BadgesRoot $compact={compact} gap={2} wrap=\"wrap\" data-testid=\"filter-badges\">\n {filters.map((filter, index) => (\n <FilterBadge\n // Position is identity: badges are edited/removed by index.\n key={index}\n filter={filter}\n onChange={(next) => updateFilter(index, next)}\n onRemove={() => removeFilter(index)}\n />\n ))}\n </BadgesRoot>\n );\n};\n"],"names":["BadgePill","styled","Flex","theme","colors","neutral200","borderRadius","neutral0","Segment","button","spaces","$interactive","breakpoints","medium","primary100","primary600","FieldSegment","span","PanelPopoverContent","Popover","Content","FILTER_PANEL_WIDTH","OptionButton","fontSizes","lineHeights","neutral800","RemoveButton","neutral600","TYPE_CONDITION_LABELS","is","id","getTranslationKey","defaultMessage","isNot","PRESET_CONDITION_LABELS","isExactly","withinLast","notWithinLast","RANGE_CONDITION_LABELS","SegmentPopover","label","options","active","getOptionLabel","onPick","open","setOpen","useState","_jsxs","Root","onOpenChange","_jsx","Trigger","type","Typography","variant","textColor","direction","alignItems","padding","map","option","onClick","Check","aria-hidden","width","height","TypeValuePopover","filter","onChange","formatMessage","useIntl","values","value","TYPE_LABELS","join","toggleValue","nextValues","includes","v","length","gap","TYPE_VALUES","Checkbox","checked","onCheckedChange","DateValuePopover","formatDate","mode","PRESET_LABELS","preset","parseCalendarDate","from","day","month","to","year","DATE_PRESETS","DateRangeCalendar","onSelect","FilterBadge","onRemove","fieldLabel","kind","DATE_FIELD_LABELS","field","data-testid","_Fragment","condition","aria-label","Cross","BadgesRoot","$compact","FilterBadges","listFilters","compact","filters","updateFilter","removeFilter","wrap","index","next"],"mappings":"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"}
1
+ {"version":3,"file":"FilterBadges.mjs","sources":["../../../../../admin/src/pages/Assets/components/FilterBadges.tsx"],"sourcesContent":["import { useId, useRef, useState } from 'react';\n\nimport { Checkbox, Flex, Popover, Typography } from '@strapi/design-system';\nimport { Check, Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../utils/translations';\nimport {\n DATE_PRESETS,\n TYPE_VALUES,\n type DateFilter,\n type DatePreset,\n type ListFilter,\n type ListFilters,\n type PresetCondition,\n type RangeCondition,\n type TypeCondition,\n type TypeFilter,\n type TypeValue,\n} from '../hooks/useListFilters';\nimport { parseCalendarDate } from '../utils/buildAssetFilters';\n\nimport { DateRangeCalendar } from './DateRangeCalendar';\nimport { DATE_FIELD_LABELS, FILTER_PANEL_WIDTH, PRESET_LABELS, TYPE_LABELS } from './FilterMenu';\n\nimport type { MessageDescriptor } from 'react-intl';\n\n/**\n * Row of applied-filter badges under the toolbar. A badge has three segments —\n * field (static), condition (click → select popover), value (click → type\n * checkboxes / preset list / range calendar) — plus a remove button.\n */\n\nconst BadgePill = styled(Flex)`\n border: 1px solid ${({ theme }) => theme.colors.neutral200};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme }) => theme.colors.neutral0};\n overflow: hidden;\n`;\n\nconst Segment = styled.button<{ $interactive?: boolean }>`\n border: none;\n background: transparent;\n font: inherit;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`};\n cursor: ${({ $interactive }) => ($interactive ? 'pointer' : 'default')};\n border-right: 1px solid ${({ theme }) => theme.colors.neutral200};\n\n ${({ theme }) => theme.breakpoints.medium} {\n padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};\n }\n ${({ $interactive, theme }) =>\n $interactive && `&:hover { background: ${theme.colors.primary100}; }`}\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\n// Non-interactive field segment (first pill cell).\nconst FieldSegment = styled.span`\n display: inline-flex;\n align-items: center;\n padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};\n border-right: 1px solid ${({ theme }) => theme.colors.neutral200};\n`;\n\n// Badge popovers mirror the filter-menu panels: same fixed width, same font.\nconst PanelPopoverContent = styled(Popover.Content)`\n width: ${FILTER_PANEL_WIDTH};\n`;\n\n// Option row inside a segment popover — sized like a DS Menu.Item so the badge\n// dropdowns read as the same control family as the filter menu.\nconst OptionButton = styled.button`\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: ${({ theme }) => theme.spaces[4]};\n width: 100%;\n border: none;\n background: transparent;\n font-size: ${({ theme }) => theme.fontSizes[2]};\n line-height: ${({ theme }) => theme.lineHeights[4]};\n font-family: inherit;\n text-align: left;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[4]}`};\n border-radius: ${({ theme }) => theme.borderRadius};\n cursor: pointer;\n color: ${({ theme }) => theme.colors.neutral800};\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 RemoveButton = styled.button`\n border: none;\n background: transparent;\n display: inline-flex;\n align-items: center;\n padding: ${({ theme }) => `0 ${theme.spaces[2]}`};\n cursor: pointer;\n color: ${({ theme }) => theme.colors.neutral600};\n\n &:hover {\n color: ${({ theme }) => theme.colors.neutral800};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\nconst TYPE_CONDITION_LABELS: Record<TypeCondition, MessageDescriptor> = {\n is: { id: getTranslationKey('list.filters.condition.is'), defaultMessage: 'is' },\n isNot: { id: getTranslationKey('list.filters.condition.is-not'), defaultMessage: 'is not' },\n};\n\nconst PRESET_CONDITION_LABELS: Record<PresetCondition, MessageDescriptor> = {\n isExactly: {\n id: getTranslationKey('list.filters.condition.is-exactly'),\n defaultMessage: 'is exactly',\n },\n withinLast: {\n id: getTranslationKey('list.filters.condition.within-last'),\n defaultMessage: 'within the last',\n },\n notWithinLast: {\n id: getTranslationKey('list.filters.condition.not-within-last'),\n defaultMessage: 'not within the last',\n },\n};\n\nconst RANGE_CONDITION_LABELS: Record<RangeCondition, MessageDescriptor> = {\n is: { id: getTranslationKey('list.filters.condition.is'), defaultMessage: 'is' },\n isNot: { id: getTranslationKey('list.filters.condition.is-not'), defaultMessage: 'is not' },\n};\n\n/** A small single-choice popover listing options with a check on the active one. */\ninterface SegmentPopoverProps<T extends string> {\n label: string;\n options: T[];\n active: T;\n getOptionLabel: (option: T) => string;\n onPick: (option: T) => void;\n}\n\nconst SegmentPopover = <T extends string>({\n label,\n options,\n active,\n getOptionLabel,\n onPick,\n}: SegmentPopoverProps<T>) => {\n const [open, setOpen] = useState(false);\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Segment type=\"button\" $interactive>\n <Typography variant=\"pi\" textColor=\"neutral800\">\n {label}\n </Typography>\n </Segment>\n </Popover.Trigger>\n <PanelPopoverContent>\n <Flex direction=\"column\" alignItems=\"stretch\" padding={1}>\n {options.map((option) => (\n <OptionButton\n key={option}\n type=\"button\"\n onClick={() => {\n onPick(option);\n setOpen(false);\n }}\n >\n {getOptionLabel(option)}\n {option === active && <Check aria-hidden width=\"1.6rem\" height=\"1.6rem\" />}\n </OptionButton>\n ))}\n </Flex>\n </PanelPopoverContent>\n </Popover.Root>\n );\n};\n\nconst TypeValuePopover = ({\n filter,\n onChange,\n}: {\n filter: TypeFilter;\n onChange: (next: TypeFilter) => void;\n}) => {\n const { formatMessage } = useIntl();\n const [open, setOpen] = useState(false);\n\n const label = filter.values.map((value) => formatMessage(TYPE_LABELS[value])).join(', ');\n\n const toggleValue = (value: TypeValue) => {\n const nextValues = filter.values.includes(value)\n ? filter.values.filter((v) => v !== value)\n : [...filter.values, value];\n\n // At least one value stays checked — an empty badge is removed via ×, not here.\n if (nextValues.length > 0) {\n onChange({ ...filter, values: nextValues });\n }\n };\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Segment type=\"button\" $interactive>\n <Typography variant=\"pi\" textColor=\"neutral800\">\n {label}\n </Typography>\n </Segment>\n </Popover.Trigger>\n <PanelPopoverContent>\n <Flex direction=\"column\" alignItems=\"flex-start\" padding={3} gap={2}>\n {TYPE_VALUES.map((value) => (\n <Checkbox\n key={value}\n checked={filter.values.includes(value)}\n onCheckedChange={() => toggleValue(value)}\n >\n {formatMessage(TYPE_LABELS[value])}\n </Checkbox>\n ))}\n </Flex>\n </PanelPopoverContent>\n </Popover.Root>\n );\n};\n\nconst DateValuePopover = ({\n filter,\n onChange,\n}: {\n filter: DateFilter;\n onChange: (next: DateFilter) => void;\n}) => {\n const { formatMessage, formatDate } = useIntl();\n const [open, setOpen] = useState(false);\n\n // Parse as LOCAL calendar dates before formatting: react-intl would coerce\n // the raw `YYYY-MM-DD` strings via `new Date(value)` = UTC midnight, showing\n // the previous day in every timezone west of UTC while the query (also\n // local, see buildAssetFilters) filters the day the user actually picked.\n const label =\n filter.mode === 'preset'\n ? formatMessage(PRESET_LABELS[filter.preset])\n : `${formatDate(parseCalendarDate(filter.from), {\n day: '2-digit',\n month: 'short',\n })} - ${formatDate(parseCalendarDate(filter.to), {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n })}`;\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Segment type=\"button\" $interactive>\n <Typography variant=\"pi\" textColor=\"neutral800\">\n {label}\n </Typography>\n </Segment>\n </Popover.Trigger>\n <PanelPopoverContent>\n {filter.mode === 'preset' ? (\n <Flex direction=\"column\" alignItems=\"stretch\" padding={1}>\n {DATE_PRESETS.map((preset: DatePreset) => (\n <OptionButton\n key={preset}\n type=\"button\"\n onClick={() => {\n onChange({ ...filter, preset });\n setOpen(false);\n }}\n >\n {formatMessage(PRESET_LABELS[preset])}\n {preset === filter.preset && <Check aria-hidden width=\"1.6rem\" height=\"1.6rem\" />}\n </OptionButton>\n ))}\n </Flex>\n ) : (\n <DateRangeCalendar\n from={filter.from}\n to={filter.to}\n onSelect={(from, to) => {\n onChange({ ...filter, from, to });\n setOpen(false);\n }}\n />\n )}\n </PanelPopoverContent>\n </Popover.Root>\n );\n};\n\nconst FilterBadge = ({\n filter,\n onChange,\n onRemove,\n}: {\n filter: ListFilter;\n onChange: (next: ListFilter) => void;\n onRemove: () => void;\n}) => {\n const { formatMessage } = useIntl();\n\n const fieldLabel =\n filter.kind === 'type'\n ? formatMessage({ id: getTranslationKey('list.filters.field.type'), defaultMessage: 'Type' })\n : formatMessage(DATE_FIELD_LABELS[filter.field]);\n\n return (\n <BadgePill alignItems=\"stretch\" data-testid=\"filter-badge\">\n <FieldSegment>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {fieldLabel}\n </Typography>\n </FieldSegment>\n\n {filter.kind === 'type' && (\n <>\n <SegmentPopover\n label={formatMessage(TYPE_CONDITION_LABELS[filter.condition])}\n options={['is', 'isNot'] as TypeCondition[]}\n active={filter.condition}\n getOptionLabel={(option) => formatMessage(TYPE_CONDITION_LABELS[option])}\n onPick={(condition) => onChange({ ...filter, condition })}\n />\n <TypeValuePopover filter={filter} onChange={onChange} />\n </>\n )}\n\n {filter.kind === 'date' && filter.mode === 'preset' && (\n <>\n <SegmentPopover\n label={formatMessage(PRESET_CONDITION_LABELS[filter.condition])}\n options={['isExactly', 'withinLast', 'notWithinLast'] as PresetCondition[]}\n active={filter.condition}\n getOptionLabel={(option) => formatMessage(PRESET_CONDITION_LABELS[option])}\n onPick={(condition) => onChange({ ...filter, condition })}\n />\n <DateValuePopover filter={filter} onChange={onChange} />\n </>\n )}\n\n {filter.kind === 'date' && filter.mode === 'range' && (\n <>\n <SegmentPopover\n label={formatMessage(RANGE_CONDITION_LABELS[filter.condition])}\n options={['is', 'isNot'] as RangeCondition[]}\n active={filter.condition}\n getOptionLabel={(option) => formatMessage(RANGE_CONDITION_LABELS[option])}\n onPick={(condition) => onChange({ ...filter, condition })}\n />\n <DateValuePopover filter={filter} onChange={onChange} />\n </>\n )}\n\n <RemoveButton\n type=\"button\"\n onClick={onRemove}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.filters.remove'),\n defaultMessage: 'Remove {filter} filter',\n },\n { filter: fieldLabel }\n )}\n >\n <Cross width=\"1.2rem\" height=\"1.2rem\" aria-hidden />\n </RemoveButton>\n </BadgePill>\n );\n};\n\n// Tighten the gap above the badges when the sticky header is in its compact\n// (scrolled) state, matching the header's own shrink.\nconst BadgesRoot = styled(Flex)<{ $compact: boolean }>`\n padding-top: ${({ theme, $compact }) => ($compact ? theme.spaces[1] : theme.spaces[6])};\n transition: padding-top 0.2s ease;\n`;\n\ninterface FilterBadgesProps {\n listFilters: ListFilters;\n /** Sticky header is scrolled/compact — reduce the space above the badges. */\n compact?: boolean;\n}\n\nexport const FilterBadges = ({ listFilters, compact = false }: FilterBadgesProps) => {\n const { filters, updateFilter, removeFilter } = listFilters;\n /**\n * Stable per-slot keys held in a ref. The ref is written during render, but\n * the bookkeeping depends on the list length rather than on how often render\n * runs, so the second pass of a StrictMode double render sees equal lengths\n * and does nothing. A content-derived key fails twice over here: filters may\n * legitimately repeat, and the key would change while the user edits a badge,\n * remounting the badge under its open popover.\n */\n const filterKeyPrefix = useId();\n const nextFilterKey = useRef(0);\n const filterKeys = useRef<string[]>([]);\n\n while (filterKeys.current.length < filters.length) {\n filterKeys.current.push(`${filterKeyPrefix}-${nextFilterKey.current}`);\n nextFilterKey.current += 1;\n }\n /**\n * Keys are truncated from the tail. The `onRemove` closure below splices the\n * removed slot out first, so removal through this component is correct. Any\n * other shrink path (browser back or forward, an external filter reset)\n * shifts the remaining keys and degrades to the index keys this replaced.\n * Known and accepted.\n */\n filterKeys.current.length = filters.length;\n\n const filtersWithKeys = filters.map((filter, index) => ({\n filter,\n index,\n key: filterKeys.current[index],\n }));\n\n if (filters.length === 0) {\n return null;\n }\n\n return (\n <BadgesRoot $compact={compact} gap={2} wrap=\"wrap\" data-testid=\"filter-badges\">\n {filtersWithKeys.map(({ filter, index, key }) => (\n <FilterBadge\n key={key}\n filter={filter}\n onChange={(next) => updateFilter(index, next)}\n onRemove={() => {\n filterKeys.current.splice(index, 1);\n removeFilter(index);\n }}\n />\n ))}\n </BadgesRoot>\n );\n};\n"],"names":["BadgePill","styled","Flex","theme","colors","neutral200","borderRadius","neutral0","Segment","button","spaces","$interactive","breakpoints","medium","primary100","primary600","FieldSegment","span","PanelPopoverContent","Popover","Content","FILTER_PANEL_WIDTH","OptionButton","fontSizes","lineHeights","neutral800","RemoveButton","neutral600","TYPE_CONDITION_LABELS","is","id","getTranslationKey","defaultMessage","isNot","PRESET_CONDITION_LABELS","isExactly","withinLast","notWithinLast","RANGE_CONDITION_LABELS","SegmentPopover","label","options","active","getOptionLabel","onPick","open","setOpen","useState","_jsxs","Root","onOpenChange","_jsx","Trigger","type","Typography","variant","textColor","direction","alignItems","padding","map","option","onClick","Check","aria-hidden","width","height","TypeValuePopover","filter","onChange","formatMessage","useIntl","values","value","TYPE_LABELS","join","toggleValue","nextValues","includes","v","length","gap","TYPE_VALUES","Checkbox","checked","onCheckedChange","DateValuePopover","formatDate","mode","PRESET_LABELS","preset","parseCalendarDate","from","day","month","to","year","DATE_PRESETS","DateRangeCalendar","onSelect","FilterBadge","onRemove","fieldLabel","kind","DATE_FIELD_LABELS","field","data-testid","_Fragment","condition","aria-label","Cross","BadgesRoot","$compact","FilterBadges","listFilters","compact","filters","updateFilter","removeFilter","filterKeyPrefix","useId","nextFilterKey","useRef","filterKeys","current","push","filtersWithKeys","index","key","wrap","next","splice"],"mappings":"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"}
@@ -166,6 +166,7 @@ const trackPoolRun = (uploadId, run)=>{
166
166
  uploadId,
167
167
  completedAt: Date.now()
168
168
  }));
169
+ entry.onUploaded?.(file);
169
170
  // Not awaited: overlaps with the next file's upload and can't fail the batch.
170
171
  maybeGenerateMetadata({
171
172
  file,
@@ -231,7 +232,8 @@ const trackPoolRun = (uploadId, run)=>{
231
232
  const earlier = previous?.data ?? [];
232
233
  if (abortController.signal.aborted) {
233
234
  return {
234
- data: earlier
235
+ data: earlier,
236
+ own: []
235
237
  };
236
238
  }
237
239
  registerAbortController(uploadId, abortController);
@@ -248,11 +250,18 @@ const trackPoolRun = (uploadId, run)=>{
248
250
  data: [
249
251
  ...earlier,
250
252
  ...result.data ?? []
251
- ]
253
+ ],
254
+ own: result.data ?? []
252
255
  });
253
256
  });
254
257
  trackPoolRun(uploadId, run);
255
- return run;
258
+ // The chained value keeps every file in the batch, because the next merged leg
259
+ // reads it as its own `earlier`. The caller gets only what it handed in: a
260
+ // consumer that attaches the result — the Content Manager field — would
261
+ // otherwise re-attach the files the earlier drop already added.
262
+ return run.then((result)=>result.error ? result : {
263
+ data: result.own ?? result.data
264
+ });
256
265
  };
257
266
  /* -------------------------------------------------------------------------------------------------
258
267
  * URL upload flow (SSE) — kept as-is for this iteration
@@ -431,7 +440,7 @@ const uploadApi = strapiAdmin.adminApi.enhanceEndpoints({
431
440
  * pool of `concurrency` parallel requests (default 1 = sequential). Real
432
441
  * per-file byte progress comes from `XHR.upload.onprogress`.
433
442
  */ uploadFiles: builder.mutation({
434
- queryFn: async ({ formData, totalFiles, concurrency = 1, generateAiMetadata }, { dispatch, getState })=>{
443
+ queryFn: async ({ formData, totalFiles, concurrency = 1, generateAiMetadata, onFileUploaded }, { dispatch, getState })=>{
435
444
  const token = getState().admin_app?.token;
436
445
  // Extract the original files and their per-file fileInfo from the combined FormData.
437
446
  const files = formData.getAll('files');
@@ -444,7 +453,8 @@ const uploadApi = strapiAdmin.adminApi.enhanceEndpoints({
444
453
  caption: null,
445
454
  alternativeText: null,
446
455
  folder: null
447
- }
456
+ },
457
+ onUploaded: onFileUploaded
448
458
  }));
449
459
  const fileNames = entries.map((entry)=>entry.fileInfo.name ?? entry.file.name);
450
460
  const fileSizes = entries.map((entry)=>entry.file.size);