@strapi/upload 5.57.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.
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js +141 -0
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs +139 -0
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetDropZone.js +129 -0
- package/dist/admin/components/MediaLibraryInput/AssetDropZone.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs +127 -0
- package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetRow.js +144 -0
- package/dist/admin/components/MediaLibraryInput/AssetRow.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetRow.mjs +142 -0
- package/dist/admin/components/MediaLibraryInput/AssetRow.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +397 -0
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +395 -0
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js +45 -0
- package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs +43 -0
- package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs.map +1 -0
- package/dist/admin/hooks/useAIMetadataAvailability.js +5 -1
- package/dist/admin/hooks/useAIMetadataAvailability.js.map +1 -1
- package/dist/admin/hooks/useAIMetadataAvailability.mjs +5 -1
- package/dist/admin/hooks/useAIMetadataAvailability.mjs.map +1 -1
- package/dist/admin/hooks/useAIMetadataEnabled.js +7 -1
- package/dist/admin/hooks/useAIMetadataEnabled.js.map +1 -1
- package/dist/admin/hooks/useAIMetadataEnabled.mjs +7 -1
- package/dist/admin/hooks/useAIMetadataEnabled.mjs.map +1 -1
- package/dist/admin/hooks/useMediaLibraryPermissions.js +4 -0
- package/dist/admin/hooks/useMediaLibraryPermissions.js.map +1 -1
- package/dist/admin/hooks/useMediaLibraryPermissions.mjs +4 -0
- package/dist/admin/hooks/useMediaLibraryPermissions.mjs.map +1 -1
- package/dist/admin/hooks/useTracking.js +5 -1
- package/dist/admin/hooks/useTracking.js.map +1 -1
- package/dist/admin/hooks/useTracking.mjs +5 -1
- package/dist/admin/hooks/useTracking.mjs.map +1 -1
- package/dist/admin/index.js +7 -2
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +7 -2
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/legacy/components/AssetCard/AssetCardBase.js.map +1 -1
- package/dist/admin/legacy/components/AssetCard/AssetCardBase.mjs.map +1 -1
- package/dist/admin/legacy/components/AssetCard/UploadingAssetCard.js +9 -1
- package/dist/admin/legacy/components/AssetCard/UploadingAssetCard.js.map +1 -1
- package/dist/admin/legacy/components/AssetCard/UploadingAssetCard.mjs +9 -1
- package/dist/admin/legacy/components/AssetCard/UploadingAssetCard.mjs.map +1 -1
- package/dist/admin/legacy/components/AssetCard/VideoPreview.js +2 -1
- package/dist/admin/legacy/components/AssetCard/VideoPreview.js.map +1 -1
- package/dist/admin/legacy/components/AssetCard/VideoPreview.mjs +2 -1
- package/dist/admin/legacy/components/AssetCard/VideoPreview.mjs.map +1 -1
- package/dist/admin/legacy/components/AssetDialog/AssetDialog.js +3 -1
- package/dist/admin/legacy/components/AssetDialog/AssetDialog.js.map +1 -1
- package/dist/admin/legacy/components/AssetDialog/AssetDialog.mjs +3 -1
- package/dist/admin/legacy/components/AssetDialog/AssetDialog.mjs.map +1 -1
- package/dist/admin/legacy/components/AssetDialog/BrowseStep/BrowseStep.js +3 -1
- package/dist/admin/legacy/components/AssetDialog/BrowseStep/BrowseStep.js.map +1 -1
- package/dist/admin/legacy/components/AssetDialog/BrowseStep/BrowseStep.mjs +3 -1
- package/dist/admin/legacy/components/AssetDialog/BrowseStep/BrowseStep.mjs.map +1 -1
- package/dist/admin/legacy/components/AssetDialog/BrowseStep/Filters.js.map +1 -1
- package/dist/admin/legacy/components/AssetDialog/BrowseStep/Filters.mjs.map +1 -1
- package/dist/admin/legacy/components/AssetGridList/AssetGridList.js +7 -6
- package/dist/admin/legacy/components/AssetGridList/AssetGridList.js.map +1 -1
- package/dist/admin/legacy/components/AssetGridList/AssetGridList.mjs +7 -6
- package/dist/admin/legacy/components/AssetGridList/AssetGridList.mjs.map +1 -1
- package/dist/admin/legacy/components/Breadcrumbs/CrumbSimpleMenuAsync.js +2 -1
- package/dist/admin/legacy/components/Breadcrumbs/CrumbSimpleMenuAsync.js.map +1 -1
- package/dist/admin/legacy/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs +2 -1
- package/dist/admin/legacy/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs.map +1 -1
- package/dist/admin/legacy/components/BulkMoveDialog/BulkMoveDialog.js +2 -1
- package/dist/admin/legacy/components/BulkMoveDialog/BulkMoveDialog.js.map +1 -1
- package/dist/admin/legacy/components/BulkMoveDialog/BulkMoveDialog.mjs +2 -1
- package/dist/admin/legacy/components/BulkMoveDialog/BulkMoveDialog.mjs.map +1 -1
- package/dist/admin/legacy/components/EditAssetDialog/EditAssetContent.js +3 -1
- package/dist/admin/legacy/components/EditAssetDialog/EditAssetContent.js.map +1 -1
- package/dist/admin/legacy/components/EditAssetDialog/EditAssetContent.mjs +3 -1
- package/dist/admin/legacy/components/EditAssetDialog/EditAssetContent.mjs.map +1 -1
- package/dist/admin/legacy/components/EditAssetDialog/PreviewBox/PreviewBox.js +20 -6
- package/dist/admin/legacy/components/EditAssetDialog/PreviewBox/PreviewBox.js.map +1 -1
- package/dist/admin/legacy/components/EditAssetDialog/PreviewBox/PreviewBox.mjs +20 -6
- package/dist/admin/legacy/components/EditAssetDialog/PreviewBox/PreviewBox.mjs.map +1 -1
- package/dist/admin/legacy/components/FilterList/FilterList.js.map +1 -1
- package/dist/admin/legacy/components/FilterList/FilterList.mjs.map +1 -1
- package/dist/admin/legacy/components/FilterPopover/FilterPopover.js.map +1 -1
- package/dist/admin/legacy/components/FilterPopover/FilterPopover.mjs.map +1 -1
- package/dist/admin/legacy/components/FilterPopover/FilterValueInput.js +2 -1
- package/dist/admin/legacy/components/FilterPopover/FilterValueInput.js.map +1 -1
- package/dist/admin/legacy/components/FilterPopover/FilterValueInput.mjs +2 -1
- package/dist/admin/legacy/components/FilterPopover/FilterValueInput.mjs.map +1 -1
- package/dist/admin/legacy/components/MediaLibraryDialog/MediaLibraryDialog.js +4 -2
- package/dist/admin/legacy/components/MediaLibraryDialog/MediaLibraryDialog.js.map +1 -1
- package/dist/admin/legacy/components/MediaLibraryDialog/MediaLibraryDialog.mjs +4 -2
- package/dist/admin/legacy/components/MediaLibraryDialog/MediaLibraryDialog.mjs.map +1 -1
- package/dist/admin/legacy/components/MediaLibraryInput/MediaLibraryInput.js +2 -1
- package/dist/admin/legacy/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
- package/dist/admin/legacy/components/MediaLibraryInput/MediaLibraryInput.mjs +2 -1
- package/dist/admin/legacy/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
- package/dist/admin/legacy/components/SelectTree/SelectTree.js +3 -1
- package/dist/admin/legacy/components/SelectTree/SelectTree.js.map +1 -1
- package/dist/admin/legacy/components/SelectTree/SelectTree.mjs +3 -1
- package/dist/admin/legacy/components/SelectTree/SelectTree.mjs.map +1 -1
- package/dist/admin/legacy/components/TableList/TableList.js +3 -1
- package/dist/admin/legacy/components/TableList/TableList.js.map +1 -1
- package/dist/admin/legacy/components/TableList/TableList.mjs +3 -1
- package/dist/admin/legacy/components/TableList/TableList.mjs.map +1 -1
- package/dist/admin/legacy/components/TableList/TableRows.js +3 -1
- package/dist/admin/legacy/components/TableList/TableRows.js.map +1 -1
- package/dist/admin/legacy/components/TableList/TableRows.mjs +3 -1
- package/dist/admin/legacy/components/TableList/TableRows.mjs.map +1 -1
- package/dist/admin/legacy/components/UploadAssetDialog/UploadAssetDialog.js +3 -1
- package/dist/admin/legacy/components/UploadAssetDialog/UploadAssetDialog.js.map +1 -1
- package/dist/admin/legacy/components/UploadAssetDialog/UploadAssetDialog.mjs +3 -1
- package/dist/admin/legacy/components/UploadAssetDialog/UploadAssetDialog.mjs.map +1 -1
- package/dist/admin/legacy/hooks/useEditAsset.js +11 -6
- package/dist/admin/legacy/hooks/useEditAsset.js.map +1 -1
- package/dist/admin/legacy/hooks/useEditAsset.mjs +12 -7
- package/dist/admin/legacy/hooks/useEditAsset.mjs.map +1 -1
- package/dist/admin/legacy/hooks/useUpload.js +6 -4
- package/dist/admin/legacy/hooks/useUpload.js.map +1 -1
- package/dist/admin/legacy/hooks/useUpload.mjs +6 -4
- package/dist/admin/legacy/hooks/useUpload.mjs.map +1 -1
- package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
- package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.mjs.map +1 -1
- package/dist/admin/legacy/pages/App/components/BulkActions.js +2 -1
- package/dist/admin/legacy/pages/App/components/BulkActions.js.map +1 -1
- package/dist/admin/legacy/pages/App/components/BulkActions.mjs +2 -1
- package/dist/admin/legacy/pages/App/components/BulkActions.mjs.map +1 -1
- package/dist/admin/legacy/pages/App/components/BulkMoveButton.js +2 -1
- package/dist/admin/legacy/pages/App/components/BulkMoveButton.js.map +1 -1
- package/dist/admin/legacy/pages/App/components/BulkMoveButton.mjs +2 -1
- package/dist/admin/legacy/pages/App/components/BulkMoveButton.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsGrid.js +2 -1
- package/dist/admin/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsGrid.mjs +2 -1
- package/dist/admin/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsTable.js +2 -1
- package/dist/admin/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsTable.mjs +2 -1
- package/dist/admin/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/BulkActionsBar.js +3 -1
- package/dist/admin/pages/Assets/components/BulkActionsBar.js.map +1 -1
- package/dist/admin/pages/Assets/components/BulkActionsBar.mjs +3 -1
- package/dist/admin/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/DateRangeCalendar.js +10 -7
- package/dist/admin/pages/Assets/components/DateRangeCalendar.js.map +1 -1
- package/dist/admin/pages/Assets/components/DateRangeCalendar.mjs +10 -7
- package/dist/admin/pages/Assets/components/DateRangeCalendar.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/DropZone/UploadDropZoneContext.js +4 -2
- package/dist/admin/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
- package/dist/admin/pages/Assets/components/DropZone/UploadDropZoneContext.mjs +5 -3
- package/dist/admin/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/FilterBadges.js +32 -3
- package/dist/admin/pages/Assets/components/FilterBadges.js.map +1 -1
- package/dist/admin/pages/Assets/components/FilterBadges.mjs +33 -4
- package/dist/admin/pages/Assets/components/FilterBadges.mjs.map +1 -1
- package/dist/admin/services/api.js +15 -5
- package/dist/admin/services/api.js.map +1 -1
- package/dist/admin/services/api.mjs +15 -5
- package/dist/admin/services/api.mjs.map +1 -1
- package/dist/admin/src/components/MediaLibraryInput/AddAssetMenu.d.ts +19 -0
- package/dist/admin/src/components/MediaLibraryInput/AssetDropZone.d.ts +13 -0
- package/dist/admin/src/components/MediaLibraryInput/AssetRow.d.ts +15 -0
- package/dist/admin/src/components/MediaLibraryInput/MediaLibraryInput.d.ts +26 -0
- package/dist/admin/src/components/MediaLibraryInput/NoLibraryAccessDialog.d.ts +10 -0
- package/dist/admin/src/hooks/useMediaLibraryPermissions.d.ts +1 -0
- package/dist/admin/src/legacy/components/BulkMoveDialog/BulkMoveDialog.d.ts +1 -1
- package/dist/admin/src/legacy/hooks/useEditAsset.d.ts +13 -22
- package/dist/admin/src/legacy/hooks/useUpload.d.ts +1 -1
- package/dist/admin/src/legacy/pages/App/components/BulkActions.d.ts +1 -1
- package/dist/admin/src/services/api.d.ts +6 -0
- package/dist/admin/src/utils/allowedMediaTypes.d.ts +16 -0
- package/dist/admin/translations/ca.json.js +3 -3
- package/dist/admin/translations/ca.json.mjs +3 -3
- package/dist/admin/translations/da.json.js +1 -1
- package/dist/admin/translations/da.json.mjs +1 -1
- package/dist/admin/translations/de.json.js +1 -1
- package/dist/admin/translations/de.json.mjs +1 -1
- package/dist/admin/translations/en.json.js +9 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +9 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/translations/es.json.js +1 -1
- package/dist/admin/translations/es.json.mjs +1 -1
- package/dist/admin/translations/sk.json.js +2 -2
- package/dist/admin/translations/sk.json.mjs +2 -2
- package/dist/admin/translations/tr.json.js +2 -2
- package/dist/admin/translations/tr.json.mjs +2 -2
- package/dist/admin/translations/zh-Hans.json.js +1 -1
- package/dist/admin/translations/zh-Hans.json.mjs +1 -1
- package/dist/admin/translations/zh.json.js +2 -2
- package/dist/admin/translations/zh.json.mjs +2 -2
- package/dist/admin/utils/allowedMediaTypes.js +42 -0
- package/dist/admin/utils/allowedMediaTypes.js.map +1 -0
- package/dist/admin/utils/allowedMediaTypes.mjs +39 -0
- package/dist/admin/utils/allowedMediaTypes.mjs.map +1 -0
- package/dist/server/config.js +6 -0
- package/dist/server/config.js.map +1 -1
- package/dist/server/config.mjs +6 -0
- package/dist/server/config.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/upload.js.map +1 -1
- package/dist/server/controllers/validation/admin/upload.mjs.map +1 -1
- package/dist/server/controllers/validation/content-api/upload.js.map +1 -1
- package/dist/server/controllers/validation/content-api/upload.mjs.map +1 -1
- package/dist/server/mcp/ambient-instance.js +7 -5
- package/dist/server/mcp/ambient-instance.js.map +1 -1
- package/dist/server/mcp/ambient-instance.mjs +7 -5
- package/dist/server/mcp/ambient-instance.mjs.map +1 -1
- package/dist/server/mcp/handlers/folder-handlers.js +4 -16
- package/dist/server/mcp/handlers/folder-handlers.js.map +1 -1
- package/dist/server/mcp/handlers/folder-handlers.mjs +5 -17
- package/dist/server/mcp/handlers/folder-handlers.mjs.map +1 -1
- package/dist/server/mcp/handlers/read-handlers.js +6 -14
- package/dist/server/mcp/handlers/read-handlers.js.map +1 -1
- package/dist/server/mcp/handlers/read-handlers.mjs +7 -15
- package/dist/server/mcp/handlers/read-handlers.mjs.map +1 -1
- package/dist/server/mcp/handlers/write-handlers.js +3 -13
- package/dist/server/mcp/handlers/write-handlers.js.map +1 -1
- package/dist/server/mcp/handlers/write-handlers.mjs +3 -13
- package/dist/server/mcp/handlers/write-handlers.mjs.map +1 -1
- package/dist/server/mcp/register-upload-mcp-tools.js +215 -195
- package/dist/server/mcp/register-upload-mcp-tools.js.map +1 -1
- package/dist/server/mcp/register-upload-mcp-tools.mjs +215 -195
- package/dist/server/mcp/register-upload-mcp-tools.mjs.map +1 -1
- package/dist/server/services/extensions/utils.js +1 -1
- package/dist/server/services/extensions/utils.js.map +1 -1
- package/dist/server/services/extensions/utils.mjs +1 -1
- package/dist/server/services/extensions/utils.mjs.map +1 -1
- package/dist/server/services/image-manipulation.js +33 -14
- package/dist/server/services/image-manipulation.js.map +1 -1
- package/dist/server/services/image-manipulation.mjs +33 -14
- package/dist/server/services/image-manipulation.mjs.map +1 -1
- package/dist/server/src/config.d.ts +3 -0
- package/dist/server/src/config.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/upload.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/content-api/upload.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +3 -0
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/mcp/ambient-instance.d.ts +7 -5
- package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -1
- package/dist/server/src/mcp/handlers/folder-handlers.d.ts.map +1 -1
- package/dist/server/src/mcp/handlers/read-handlers.d.ts +3 -2
- package/dist/server/src/mcp/handlers/read-handlers.d.ts.map +1 -1
- package/dist/server/src/mcp/handlers/write-handlers.d.ts.map +1 -1
- package/dist/server/src/mcp/register-upload-mcp-tools.d.ts +9 -14
- package/dist/server/src/mcp/register-upload-mcp-tools.d.ts.map +1 -1
- package/dist/server/src/services/extensions/utils.d.ts +1 -1
- package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
- package/dist/server/src/types.d.ts +1 -0
- package/dist/server/src/types.d.ts.map +1 -1
- package/dist/server/utils/mime-validation.js +1 -1
- package/dist/server/utils/mime-validation.js.map +1 -1
- package/dist/server/utils/mime-validation.mjs +1 -1
- package/dist/server/utils/mime-validation.mjs.map +1 -1
- package/package.json +7 -7
|
@@ -98,9 +98,12 @@ const DateRangeCalendar = ({ from, to, onSelect })=>{
|
|
|
98
98
|
onSelect(start, end);
|
|
99
99
|
};
|
|
100
100
|
const weeks = buildWeeks(viewYear, viewMonth);
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
const weekDays = weeks[0].map((day)=>({
|
|
102
|
+
key: day.getDay(),
|
|
103
|
+
label: formatDate(day, {
|
|
104
|
+
weekday: 'short'
|
|
105
|
+
}).slice(0, 2)
|
|
106
|
+
}));
|
|
104
107
|
return(// role="group" (not "application"): these are plain buttons — hijacking
|
|
105
108
|
// the screen reader's own key handling would take away navigation and
|
|
106
109
|
// give nothing back.
|
|
@@ -148,7 +151,7 @@ const DateRangeCalendar = ({ from, to, onSelect })=>{
|
|
|
148
151
|
]
|
|
149
152
|
}),
|
|
150
153
|
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
|
|
151
|
-
children:
|
|
154
|
+
children: weekDays.map(({ key, label })=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
|
|
152
155
|
width: "3rem",
|
|
153
156
|
height: "2.4rem",
|
|
154
157
|
justifyContent: "center",
|
|
@@ -158,9 +161,9 @@ const DateRangeCalendar = ({ from, to, onSelect })=>{
|
|
|
158
161
|
textColor: "neutral600",
|
|
159
162
|
children: label
|
|
160
163
|
})
|
|
161
|
-
},
|
|
164
|
+
}, key))
|
|
162
165
|
}),
|
|
163
|
-
weeks.map((week
|
|
166
|
+
weeks.map((week)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
|
|
164
167
|
children: week.map((day)=>{
|
|
165
168
|
const key = toKey(day);
|
|
166
169
|
const isEdge = key === rangeStart || key === rangeEnd;
|
|
@@ -184,7 +187,7 @@ const DateRangeCalendar = ({ from, to, onSelect })=>{
|
|
|
184
187
|
]
|
|
185
188
|
}, key);
|
|
186
189
|
})
|
|
187
|
-
},
|
|
190
|
+
}, toKey(week[0])))
|
|
188
191
|
]
|
|
189
192
|
}));
|
|
190
193
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateRangeCalendar.js","sources":["../../../../../admin/src/pages/Assets/components/DateRangeCalendar.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport { Box, Flex, IconButton, Typography, VisuallyHidden } from '@strapi/design-system';\nimport { ChevronLeft, ChevronRight } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../utils/translations';\n\n/**\n * Month-grid range picker: first click sets the start, second click the end\n * (clicks are reordered when the second date is before the first). The DS only\n * ships a single-value DatePicker, so the range grid is built locally.\n *\n * Month/year move via chevrons rather than the mock's dropdowns — nested\n * popovers inside a dropdown menu fight Radix's outside-interaction handling.\n */\n\nconst DayCell = styled.button<{ $inRange?: boolean; $isEdge?: boolean; $isMuted?: boolean }>`\n width: 3rem;\n height: 3rem;\n border: none;\n border-radius: ${({ theme }) => theme.borderRadius};\n cursor: pointer;\n font: inherit;\n color: ${({ theme, $isEdge, $isMuted }) => {\n if ($isEdge) return theme.colors.primary600;\n if ($isMuted) return theme.colors.neutral400;\n return theme.colors.neutral800;\n }};\n background: ${({ theme, $inRange, $isEdge }) => {\n if ($isEdge) return theme.colors.primary200;\n if ($inRange) return theme.colors.primary100;\n return 'transparent';\n }};\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\nconst toKey = (date: Date): string => {\n const month = `${date.getMonth() + 1}`.padStart(2, '0');\n const day = `${date.getDate()}`.padStart(2, '0');\n return `${date.getFullYear()}-${month}-${day}`;\n};\n\nconst fromKey = (key: string): Date => {\n const [year, month, day] = key.split('-').map(Number);\n return new Date(year, month - 1, day);\n};\n\n/** Monday-first weeks covering the given month, padded with adjacent days. */\nconst buildWeeks = (year: number, month: number): Date[][] => {\n const first = new Date(year, month, 1);\n const start = new Date(first.getTime());\n start.setDate(first.getDate() - ((first.getDay() + 6) % 7));\n\n const weeks: Date[][] = [];\n const cursor = new Date(start.getTime());\n\n do {\n const week: Date[] = [];\n for (let i = 0; i < 7; i += 1) {\n week.push(new Date(cursor.getTime()));\n cursor.setDate(cursor.getDate() + 1);\n }\n weeks.push(week);\n } while (cursor.getMonth() === month && cursor.getFullYear() === year);\n\n return weeks;\n};\n\ninterface DateRangeCalendarProps {\n /** `YYYY-MM-DD`, both set when editing an existing range badge. */\n from?: string;\n to?: string;\n onSelect: (from: string, to: string) => void;\n}\n\nexport const DateRangeCalendar = ({ from, to, onSelect }: DateRangeCalendarProps) => {\n const { formatMessage, formatDate } = useIntl();\n\n const initialMonth = from ? fromKey(from) : new Date();\n const [viewYear, setViewYear] = useState(initialMonth.getFullYear());\n const [viewMonth, setViewMonth] = useState(initialMonth.getMonth());\n // In-progress selection: set on the first click, cleared on commit.\n const [pendingStart, setPendingStart] = useState<string | null>(null);\n\n const rangeStart = pendingStart ?? from ?? null;\n const rangeEnd = pendingStart ? null : (to ?? null);\n\n const moveMonth = (delta: number) => {\n const next = new Date(viewYear, viewMonth + delta, 1);\n setViewYear(next.getFullYear());\n setViewMonth(next.getMonth());\n };\n\n const handleDayClick = (day: Date) => {\n const key = toKey(day);\n\n if (!pendingStart) {\n setPendingStart(key);\n return;\n }\n\n const [start, end] = key < pendingStart ? [key, pendingStart] : [pendingStart, key];\n setPendingStart(null);\n onSelect(start, end);\n };\n\n const weeks = buildWeeks(viewYear, viewMonth);\n const weekDayLabels = weeks[0].map((day) => formatDate(day, { weekday: 'short' }).slice(0, 2));\n\n return (\n // role=\"group\" (not \"application\"): these are plain buttons — hijacking\n // the screen reader's own key handling would take away navigation and\n // give nothing back.\n <Box\n padding={2}\n width=\"100%\"\n role=\"group\"\n aria-label={formatMessage({\n id: getTranslationKey('list.filters.calendar.label'),\n defaultMessage: 'Select date range',\n })}\n data-testid=\"date-range-calendar\"\n >\n <Flex justifyContent=\"space-between\" alignItems=\"center\" paddingBottom={2}>\n <IconButton\n variant=\"ghost\"\n label={formatMessage({\n id: getTranslationKey('list.filters.calendar.previous-month'),\n defaultMessage: 'Previous month',\n })}\n onClick={() => moveMonth(-1)}\n >\n <ChevronLeft />\n </IconButton>\n <Typography fontWeight=\"semiBold\" textColor=\"neutral800\">\n {formatDate(new Date(viewYear, viewMonth, 1), { month: 'long', year: 'numeric' })}\n </Typography>\n <IconButton\n variant=\"ghost\"\n label={formatMessage({\n id: getTranslationKey('list.filters.calendar.next-month'),\n defaultMessage: 'Next month',\n })}\n onClick={() => moveMonth(1)}\n >\n <ChevronRight />\n </IconButton>\n </Flex>\n\n <Flex>\n {weekDayLabels.map((label, index) => (\n <Flex key={index} width=\"3rem\" height=\"2.4rem\" justifyContent=\"center\">\n <Typography variant=\"pi\" fontWeight=\"semiBold\" textColor=\"neutral600\">\n {label}\n </Typography>\n </Flex>\n ))}\n </Flex>\n\n {weeks.map((week, weekIndex) => (\n <Flex key={weekIndex}>\n {week.map((day) => {\n const key = toKey(day);\n const isEdge = key === rangeStart || key === rangeEnd;\n const inRange =\n rangeStart !== null && rangeEnd !== null && key > rangeStart && key < rangeEnd;\n\n return (\n <DayCell\n key={key}\n type=\"button\"\n $isEdge={isEdge}\n $inRange={inRange}\n $isMuted={day.getMonth() !== viewMonth}\n onClick={() => handleDayClick(day)}\n >\n <VisuallyHidden>{formatDate(day, { dateStyle: 'long' })}</VisuallyHidden>\n <span aria-hidden>{day.getDate()}</span>\n </DayCell>\n );\n })}\n </Flex>\n ))}\n </Box>\n );\n};\n"],"names":["DayCell","styled","button","theme","borderRadius","$isEdge","$isMuted","colors","primary600","neutral400","neutral800","$inRange","primary200","primary100","toKey","date","month","getMonth","padStart","day","getDate","getFullYear","fromKey","key","year","split","map","Number","Date","buildWeeks","first","start","getTime","setDate","getDay","weeks","cursor","week","i","push","DateRangeCalendar","from","to","onSelect","formatMessage","formatDate","useIntl","initialMonth","viewYear","setViewYear","useState","viewMonth","setViewMonth","pendingStart","setPendingStart","rangeStart","rangeEnd","moveMonth","delta","next","handleDayClick","end","weekDayLabels","weekday","slice","_jsxs","Box","padding","width","role","aria-label","id","getTranslationKey","defaultMessage","data-testid","Flex","justifyContent","alignItems","paddingBottom","_jsx","IconButton","variant","label","onClick","ChevronLeft","Typography","fontWeight","textColor","ChevronRight","index","height","weekIndex","isEdge","inRange","type","VisuallyHidden","dateStyle","span","aria-hidden"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DateRangeCalendar.js","sources":["../../../../../admin/src/pages/Assets/components/DateRangeCalendar.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport { Box, Flex, IconButton, Typography, VisuallyHidden } from '@strapi/design-system';\nimport { ChevronLeft, ChevronRight } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../utils/translations';\n\n/**\n * Month-grid range picker: first click sets the start, second click the end\n * (clicks are reordered when the second date is before the first). The DS only\n * ships a single-value DatePicker, so the range grid is built locally.\n *\n * Month/year move via chevrons rather than the mock's dropdowns — nested\n * popovers inside a dropdown menu fight Radix's outside-interaction handling.\n */\n\nconst DayCell = styled.button<{ $inRange?: boolean; $isEdge?: boolean; $isMuted?: boolean }>`\n width: 3rem;\n height: 3rem;\n border: none;\n border-radius: ${({ theme }) => theme.borderRadius};\n cursor: pointer;\n font: inherit;\n color: ${({ theme, $isEdge, $isMuted }) => {\n if ($isEdge) return theme.colors.primary600;\n if ($isMuted) return theme.colors.neutral400;\n return theme.colors.neutral800;\n }};\n background: ${({ theme, $inRange, $isEdge }) => {\n if ($isEdge) return theme.colors.primary200;\n if ($inRange) return theme.colors.primary100;\n return 'transparent';\n }};\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\nconst toKey = (date: Date): string => {\n const month = `${date.getMonth() + 1}`.padStart(2, '0');\n const day = `${date.getDate()}`.padStart(2, '0');\n return `${date.getFullYear()}-${month}-${day}`;\n};\n\nconst fromKey = (key: string): Date => {\n const [year, month, day] = key.split('-').map(Number);\n return new Date(year, month - 1, day);\n};\n\n/** Monday-first weeks covering the given month, padded with adjacent days. */\nconst buildWeeks = (year: number, month: number): Date[][] => {\n const first = new Date(year, month, 1);\n const start = new Date(first.getTime());\n start.setDate(first.getDate() - ((first.getDay() + 6) % 7));\n\n const weeks: Date[][] = [];\n const cursor = new Date(start.getTime());\n\n do {\n const week: Date[] = [];\n for (let i = 0; i < 7; i += 1) {\n week.push(new Date(cursor.getTime()));\n cursor.setDate(cursor.getDate() + 1);\n }\n weeks.push(week);\n } while (cursor.getMonth() === month && cursor.getFullYear() === year);\n\n return weeks;\n};\n\ninterface DateRangeCalendarProps {\n /** `YYYY-MM-DD`, both set when editing an existing range badge. */\n from?: string;\n to?: string;\n onSelect: (from: string, to: string) => void;\n}\n\nexport const DateRangeCalendar = ({ from, to, onSelect }: DateRangeCalendarProps) => {\n const { formatMessage, formatDate } = useIntl();\n\n const initialMonth = from ? fromKey(from) : new Date();\n const [viewYear, setViewYear] = useState(initialMonth.getFullYear());\n const [viewMonth, setViewMonth] = useState(initialMonth.getMonth());\n // In-progress selection: set on the first click, cleared on commit.\n const [pendingStart, setPendingStart] = useState<string | null>(null);\n\n const rangeStart = pendingStart ?? from ?? null;\n const rangeEnd = pendingStart ? null : (to ?? null);\n\n const moveMonth = (delta: number) => {\n const next = new Date(viewYear, viewMonth + delta, 1);\n setViewYear(next.getFullYear());\n setViewMonth(next.getMonth());\n };\n\n const handleDayClick = (day: Date) => {\n const key = toKey(day);\n\n if (!pendingStart) {\n setPendingStart(key);\n return;\n }\n\n const [start, end] = key < pendingStart ? [key, pendingStart] : [pendingStart, key];\n setPendingStart(null);\n onSelect(start, end);\n };\n\n const weeks = buildWeeks(viewYear, viewMonth);\n const weekDays = weeks[0].map((day) => ({\n key: day.getDay(),\n label: formatDate(day, { weekday: 'short' }).slice(0, 2),\n }));\n\n return (\n // role=\"group\" (not \"application\"): these are plain buttons — hijacking\n // the screen reader's own key handling would take away navigation and\n // give nothing back.\n <Box\n padding={2}\n width=\"100%\"\n role=\"group\"\n aria-label={formatMessage({\n id: getTranslationKey('list.filters.calendar.label'),\n defaultMessage: 'Select date range',\n })}\n data-testid=\"date-range-calendar\"\n >\n <Flex justifyContent=\"space-between\" alignItems=\"center\" paddingBottom={2}>\n <IconButton\n variant=\"ghost\"\n label={formatMessage({\n id: getTranslationKey('list.filters.calendar.previous-month'),\n defaultMessage: 'Previous month',\n })}\n onClick={() => moveMonth(-1)}\n >\n <ChevronLeft />\n </IconButton>\n <Typography fontWeight=\"semiBold\" textColor=\"neutral800\">\n {formatDate(new Date(viewYear, viewMonth, 1), { month: 'long', year: 'numeric' })}\n </Typography>\n <IconButton\n variant=\"ghost\"\n label={formatMessage({\n id: getTranslationKey('list.filters.calendar.next-month'),\n defaultMessage: 'Next month',\n })}\n onClick={() => moveMonth(1)}\n >\n <ChevronRight />\n </IconButton>\n </Flex>\n\n <Flex>\n {weekDays.map(({ key, label }) => (\n <Flex key={key} width=\"3rem\" height=\"2.4rem\" justifyContent=\"center\">\n <Typography variant=\"pi\" fontWeight=\"semiBold\" textColor=\"neutral600\">\n {label}\n </Typography>\n </Flex>\n ))}\n </Flex>\n\n {weeks.map((week) => (\n <Flex key={toKey(week[0])}>\n {week.map((day) => {\n const key = toKey(day);\n const isEdge = key === rangeStart || key === rangeEnd;\n const inRange =\n rangeStart !== null && rangeEnd !== null && key > rangeStart && key < rangeEnd;\n\n return (\n <DayCell\n key={key}\n type=\"button\"\n $isEdge={isEdge}\n $inRange={inRange}\n $isMuted={day.getMonth() !== viewMonth}\n onClick={() => handleDayClick(day)}\n >\n <VisuallyHidden>{formatDate(day, { dateStyle: 'long' })}</VisuallyHidden>\n <span aria-hidden>{day.getDate()}</span>\n </DayCell>\n );\n })}\n </Flex>\n ))}\n </Box>\n );\n};\n"],"names":["DayCell","styled","button","theme","borderRadius","$isEdge","$isMuted","colors","primary600","neutral400","neutral800","$inRange","primary200","primary100","toKey","date","month","getMonth","padStart","day","getDate","getFullYear","fromKey","key","year","split","map","Number","Date","buildWeeks","first","start","getTime","setDate","getDay","weeks","cursor","week","i","push","DateRangeCalendar","from","to","onSelect","formatMessage","formatDate","useIntl","initialMonth","viewYear","setViewYear","useState","viewMonth","setViewMonth","pendingStart","setPendingStart","rangeStart","rangeEnd","moveMonth","delta","next","handleDayClick","end","weekDays","label","weekday","slice","_jsxs","Box","padding","width","role","aria-label","id","getTranslationKey","defaultMessage","data-testid","Flex","justifyContent","alignItems","paddingBottom","_jsx","IconButton","variant","onClick","ChevronLeft","Typography","fontWeight","textColor","ChevronRight","height","isEdge","inRange","type","VisuallyHidden","dateStyle","span","aria-hidden"],"mappings":"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"}
|
|
@@ -96,9 +96,12 @@ const DateRangeCalendar = ({ from, to, onSelect })=>{
|
|
|
96
96
|
onSelect(start, end);
|
|
97
97
|
};
|
|
98
98
|
const weeks = buildWeeks(viewYear, viewMonth);
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
const weekDays = weeks[0].map((day)=>({
|
|
100
|
+
key: day.getDay(),
|
|
101
|
+
label: formatDate(day, {
|
|
102
|
+
weekday: 'short'
|
|
103
|
+
}).slice(0, 2)
|
|
104
|
+
}));
|
|
102
105
|
return(// role="group" (not "application"): these are plain buttons — hijacking
|
|
103
106
|
// the screen reader's own key handling would take away navigation and
|
|
104
107
|
// give nothing back.
|
|
@@ -146,7 +149,7 @@ const DateRangeCalendar = ({ from, to, onSelect })=>{
|
|
|
146
149
|
]
|
|
147
150
|
}),
|
|
148
151
|
/*#__PURE__*/ jsx(Flex, {
|
|
149
|
-
children:
|
|
152
|
+
children: weekDays.map(({ key, label })=>/*#__PURE__*/ jsx(Flex, {
|
|
150
153
|
width: "3rem",
|
|
151
154
|
height: "2.4rem",
|
|
152
155
|
justifyContent: "center",
|
|
@@ -156,9 +159,9 @@ const DateRangeCalendar = ({ from, to, onSelect })=>{
|
|
|
156
159
|
textColor: "neutral600",
|
|
157
160
|
children: label
|
|
158
161
|
})
|
|
159
|
-
},
|
|
162
|
+
}, key))
|
|
160
163
|
}),
|
|
161
|
-
weeks.map((week
|
|
164
|
+
weeks.map((week)=>/*#__PURE__*/ jsx(Flex, {
|
|
162
165
|
children: week.map((day)=>{
|
|
163
166
|
const key = toKey(day);
|
|
164
167
|
const isEdge = key === rangeStart || key === rangeEnd;
|
|
@@ -182,7 +185,7 @@ const DateRangeCalendar = ({ from, to, onSelect })=>{
|
|
|
182
185
|
]
|
|
183
186
|
}, key);
|
|
184
187
|
})
|
|
185
|
-
},
|
|
188
|
+
}, toKey(week[0])))
|
|
186
189
|
]
|
|
187
190
|
}));
|
|
188
191
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateRangeCalendar.mjs","sources":["../../../../../admin/src/pages/Assets/components/DateRangeCalendar.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport { Box, Flex, IconButton, Typography, VisuallyHidden } from '@strapi/design-system';\nimport { ChevronLeft, ChevronRight } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../utils/translations';\n\n/**\n * Month-grid range picker: first click sets the start, second click the end\n * (clicks are reordered when the second date is before the first). The DS only\n * ships a single-value DatePicker, so the range grid is built locally.\n *\n * Month/year move via chevrons rather than the mock's dropdowns — nested\n * popovers inside a dropdown menu fight Radix's outside-interaction handling.\n */\n\nconst DayCell = styled.button<{ $inRange?: boolean; $isEdge?: boolean; $isMuted?: boolean }>`\n width: 3rem;\n height: 3rem;\n border: none;\n border-radius: ${({ theme }) => theme.borderRadius};\n cursor: pointer;\n font: inherit;\n color: ${({ theme, $isEdge, $isMuted }) => {\n if ($isEdge) return theme.colors.primary600;\n if ($isMuted) return theme.colors.neutral400;\n return theme.colors.neutral800;\n }};\n background: ${({ theme, $inRange, $isEdge }) => {\n if ($isEdge) return theme.colors.primary200;\n if ($inRange) return theme.colors.primary100;\n return 'transparent';\n }};\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\nconst toKey = (date: Date): string => {\n const month = `${date.getMonth() + 1}`.padStart(2, '0');\n const day = `${date.getDate()}`.padStart(2, '0');\n return `${date.getFullYear()}-${month}-${day}`;\n};\n\nconst fromKey = (key: string): Date => {\n const [year, month, day] = key.split('-').map(Number);\n return new Date(year, month - 1, day);\n};\n\n/** Monday-first weeks covering the given month, padded with adjacent days. */\nconst buildWeeks = (year: number, month: number): Date[][] => {\n const first = new Date(year, month, 1);\n const start = new Date(first.getTime());\n start.setDate(first.getDate() - ((first.getDay() + 6) % 7));\n\n const weeks: Date[][] = [];\n const cursor = new Date(start.getTime());\n\n do {\n const week: Date[] = [];\n for (let i = 0; i < 7; i += 1) {\n week.push(new Date(cursor.getTime()));\n cursor.setDate(cursor.getDate() + 1);\n }\n weeks.push(week);\n } while (cursor.getMonth() === month && cursor.getFullYear() === year);\n\n return weeks;\n};\n\ninterface DateRangeCalendarProps {\n /** `YYYY-MM-DD`, both set when editing an existing range badge. */\n from?: string;\n to?: string;\n onSelect: (from: string, to: string) => void;\n}\n\nexport const DateRangeCalendar = ({ from, to, onSelect }: DateRangeCalendarProps) => {\n const { formatMessage, formatDate } = useIntl();\n\n const initialMonth = from ? fromKey(from) : new Date();\n const [viewYear, setViewYear] = useState(initialMonth.getFullYear());\n const [viewMonth, setViewMonth] = useState(initialMonth.getMonth());\n // In-progress selection: set on the first click, cleared on commit.\n const [pendingStart, setPendingStart] = useState<string | null>(null);\n\n const rangeStart = pendingStart ?? from ?? null;\n const rangeEnd = pendingStart ? null : (to ?? null);\n\n const moveMonth = (delta: number) => {\n const next = new Date(viewYear, viewMonth + delta, 1);\n setViewYear(next.getFullYear());\n setViewMonth(next.getMonth());\n };\n\n const handleDayClick = (day: Date) => {\n const key = toKey(day);\n\n if (!pendingStart) {\n setPendingStart(key);\n return;\n }\n\n const [start, end] = key < pendingStart ? [key, pendingStart] : [pendingStart, key];\n setPendingStart(null);\n onSelect(start, end);\n };\n\n const weeks = buildWeeks(viewYear, viewMonth);\n const weekDayLabels = weeks[0].map((day) => formatDate(day, { weekday: 'short' }).slice(0, 2));\n\n return (\n // role=\"group\" (not \"application\"): these are plain buttons — hijacking\n // the screen reader's own key handling would take away navigation and\n // give nothing back.\n <Box\n padding={2}\n width=\"100%\"\n role=\"group\"\n aria-label={formatMessage({\n id: getTranslationKey('list.filters.calendar.label'),\n defaultMessage: 'Select date range',\n })}\n data-testid=\"date-range-calendar\"\n >\n <Flex justifyContent=\"space-between\" alignItems=\"center\" paddingBottom={2}>\n <IconButton\n variant=\"ghost\"\n label={formatMessage({\n id: getTranslationKey('list.filters.calendar.previous-month'),\n defaultMessage: 'Previous month',\n })}\n onClick={() => moveMonth(-1)}\n >\n <ChevronLeft />\n </IconButton>\n <Typography fontWeight=\"semiBold\" textColor=\"neutral800\">\n {formatDate(new Date(viewYear, viewMonth, 1), { month: 'long', year: 'numeric' })}\n </Typography>\n <IconButton\n variant=\"ghost\"\n label={formatMessage({\n id: getTranslationKey('list.filters.calendar.next-month'),\n defaultMessage: 'Next month',\n })}\n onClick={() => moveMonth(1)}\n >\n <ChevronRight />\n </IconButton>\n </Flex>\n\n <Flex>\n {weekDayLabels.map((label, index) => (\n <Flex key={index} width=\"3rem\" height=\"2.4rem\" justifyContent=\"center\">\n <Typography variant=\"pi\" fontWeight=\"semiBold\" textColor=\"neutral600\">\n {label}\n </Typography>\n </Flex>\n ))}\n </Flex>\n\n {weeks.map((week, weekIndex) => (\n <Flex key={weekIndex}>\n {week.map((day) => {\n const key = toKey(day);\n const isEdge = key === rangeStart || key === rangeEnd;\n const inRange =\n rangeStart !== null && rangeEnd !== null && key > rangeStart && key < rangeEnd;\n\n return (\n <DayCell\n key={key}\n type=\"button\"\n $isEdge={isEdge}\n $inRange={inRange}\n $isMuted={day.getMonth() !== viewMonth}\n onClick={() => handleDayClick(day)}\n >\n <VisuallyHidden>{formatDate(day, { dateStyle: 'long' })}</VisuallyHidden>\n <span aria-hidden>{day.getDate()}</span>\n </DayCell>\n );\n })}\n </Flex>\n ))}\n </Box>\n );\n};\n"],"names":["DayCell","styled","button","theme","borderRadius","$isEdge","$isMuted","colors","primary600","neutral400","neutral800","$inRange","primary200","primary100","toKey","date","month","getMonth","padStart","day","getDate","getFullYear","fromKey","key","year","split","map","Number","Date","buildWeeks","first","start","getTime","setDate","getDay","weeks","cursor","week","i","push","DateRangeCalendar","from","to","onSelect","formatMessage","formatDate","useIntl","initialMonth","viewYear","setViewYear","useState","viewMonth","setViewMonth","pendingStart","setPendingStart","rangeStart","rangeEnd","moveMonth","delta","next","handleDayClick","end","weekDayLabels","weekday","slice","_jsxs","Box","padding","width","role","aria-label","id","getTranslationKey","defaultMessage","data-testid","Flex","justifyContent","alignItems","paddingBottom","_jsx","IconButton","variant","label","onClick","ChevronLeft","Typography","fontWeight","textColor","ChevronRight","index","height","weekIndex","isEdge","inRange","type","VisuallyHidden","dateStyle","span","aria-hidden"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DateRangeCalendar.mjs","sources":["../../../../../admin/src/pages/Assets/components/DateRangeCalendar.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport { Box, Flex, IconButton, Typography, VisuallyHidden } from '@strapi/design-system';\nimport { ChevronLeft, ChevronRight } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../utils/translations';\n\n/**\n * Month-grid range picker: first click sets the start, second click the end\n * (clicks are reordered when the second date is before the first). The DS only\n * ships a single-value DatePicker, so the range grid is built locally.\n *\n * Month/year move via chevrons rather than the mock's dropdowns — nested\n * popovers inside a dropdown menu fight Radix's outside-interaction handling.\n */\n\nconst DayCell = styled.button<{ $inRange?: boolean; $isEdge?: boolean; $isMuted?: boolean }>`\n width: 3rem;\n height: 3rem;\n border: none;\n border-radius: ${({ theme }) => theme.borderRadius};\n cursor: pointer;\n font: inherit;\n color: ${({ theme, $isEdge, $isMuted }) => {\n if ($isEdge) return theme.colors.primary600;\n if ($isMuted) return theme.colors.neutral400;\n return theme.colors.neutral800;\n }};\n background: ${({ theme, $inRange, $isEdge }) => {\n if ($isEdge) return theme.colors.primary200;\n if ($inRange) return theme.colors.primary100;\n return 'transparent';\n }};\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\nconst toKey = (date: Date): string => {\n const month = `${date.getMonth() + 1}`.padStart(2, '0');\n const day = `${date.getDate()}`.padStart(2, '0');\n return `${date.getFullYear()}-${month}-${day}`;\n};\n\nconst fromKey = (key: string): Date => {\n const [year, month, day] = key.split('-').map(Number);\n return new Date(year, month - 1, day);\n};\n\n/** Monday-first weeks covering the given month, padded with adjacent days. */\nconst buildWeeks = (year: number, month: number): Date[][] => {\n const first = new Date(year, month, 1);\n const start = new Date(first.getTime());\n start.setDate(first.getDate() - ((first.getDay() + 6) % 7));\n\n const weeks: Date[][] = [];\n const cursor = new Date(start.getTime());\n\n do {\n const week: Date[] = [];\n for (let i = 0; i < 7; i += 1) {\n week.push(new Date(cursor.getTime()));\n cursor.setDate(cursor.getDate() + 1);\n }\n weeks.push(week);\n } while (cursor.getMonth() === month && cursor.getFullYear() === year);\n\n return weeks;\n};\n\ninterface DateRangeCalendarProps {\n /** `YYYY-MM-DD`, both set when editing an existing range badge. */\n from?: string;\n to?: string;\n onSelect: (from: string, to: string) => void;\n}\n\nexport const DateRangeCalendar = ({ from, to, onSelect }: DateRangeCalendarProps) => {\n const { formatMessage, formatDate } = useIntl();\n\n const initialMonth = from ? fromKey(from) : new Date();\n const [viewYear, setViewYear] = useState(initialMonth.getFullYear());\n const [viewMonth, setViewMonth] = useState(initialMonth.getMonth());\n // In-progress selection: set on the first click, cleared on commit.\n const [pendingStart, setPendingStart] = useState<string | null>(null);\n\n const rangeStart = pendingStart ?? from ?? null;\n const rangeEnd = pendingStart ? null : (to ?? null);\n\n const moveMonth = (delta: number) => {\n const next = new Date(viewYear, viewMonth + delta, 1);\n setViewYear(next.getFullYear());\n setViewMonth(next.getMonth());\n };\n\n const handleDayClick = (day: Date) => {\n const key = toKey(day);\n\n if (!pendingStart) {\n setPendingStart(key);\n return;\n }\n\n const [start, end] = key < pendingStart ? [key, pendingStart] : [pendingStart, key];\n setPendingStart(null);\n onSelect(start, end);\n };\n\n const weeks = buildWeeks(viewYear, viewMonth);\n const weekDays = weeks[0].map((day) => ({\n key: day.getDay(),\n label: formatDate(day, { weekday: 'short' }).slice(0, 2),\n }));\n\n return (\n // role=\"group\" (not \"application\"): these are plain buttons — hijacking\n // the screen reader's own key handling would take away navigation and\n // give nothing back.\n <Box\n padding={2}\n width=\"100%\"\n role=\"group\"\n aria-label={formatMessage({\n id: getTranslationKey('list.filters.calendar.label'),\n defaultMessage: 'Select date range',\n })}\n data-testid=\"date-range-calendar\"\n >\n <Flex justifyContent=\"space-between\" alignItems=\"center\" paddingBottom={2}>\n <IconButton\n variant=\"ghost\"\n label={formatMessage({\n id: getTranslationKey('list.filters.calendar.previous-month'),\n defaultMessage: 'Previous month',\n })}\n onClick={() => moveMonth(-1)}\n >\n <ChevronLeft />\n </IconButton>\n <Typography fontWeight=\"semiBold\" textColor=\"neutral800\">\n {formatDate(new Date(viewYear, viewMonth, 1), { month: 'long', year: 'numeric' })}\n </Typography>\n <IconButton\n variant=\"ghost\"\n label={formatMessage({\n id: getTranslationKey('list.filters.calendar.next-month'),\n defaultMessage: 'Next month',\n })}\n onClick={() => moveMonth(1)}\n >\n <ChevronRight />\n </IconButton>\n </Flex>\n\n <Flex>\n {weekDays.map(({ key, label }) => (\n <Flex key={key} width=\"3rem\" height=\"2.4rem\" justifyContent=\"center\">\n <Typography variant=\"pi\" fontWeight=\"semiBold\" textColor=\"neutral600\">\n {label}\n </Typography>\n </Flex>\n ))}\n </Flex>\n\n {weeks.map((week) => (\n <Flex key={toKey(week[0])}>\n {week.map((day) => {\n const key = toKey(day);\n const isEdge = key === rangeStart || key === rangeEnd;\n const inRange =\n rangeStart !== null && rangeEnd !== null && key > rangeStart && key < rangeEnd;\n\n return (\n <DayCell\n key={key}\n type=\"button\"\n $isEdge={isEdge}\n $inRange={inRange}\n $isMuted={day.getMonth() !== viewMonth}\n onClick={() => handleDayClick(day)}\n >\n <VisuallyHidden>{formatDate(day, { dateStyle: 'long' })}</VisuallyHidden>\n <span aria-hidden>{day.getDate()}</span>\n </DayCell>\n );\n })}\n </Flex>\n ))}\n </Box>\n );\n};\n"],"names":["DayCell","styled","button","theme","borderRadius","$isEdge","$isMuted","colors","primary600","neutral400","neutral800","$inRange","primary200","primary100","toKey","date","month","getMonth","padStart","day","getDate","getFullYear","fromKey","key","year","split","map","Number","Date","buildWeeks","first","start","getTime","setDate","getDay","weeks","cursor","week","i","push","DateRangeCalendar","from","to","onSelect","formatMessage","formatDate","useIntl","initialMonth","viewYear","setViewYear","useState","viewMonth","setViewMonth","pendingStart","setPendingStart","rangeStart","rangeEnd","moveMonth","delta","next","handleDayClick","end","weekDays","label","weekday","slice","_jsxs","Box","padding","width","role","aria-label","id","getTranslationKey","defaultMessage","data-testid","Flex","justifyContent","alignItems","paddingBottom","_jsx","IconButton","variant","onClick","ChevronLeft","Typography","fontWeight","textColor","ChevronRight","height","isEdge","inRange","type","VisuallyHidden","dateStyle","span","aria-hidden"],"mappings":"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"}
|
|
@@ -19,9 +19,11 @@ var styledComponents = require('styled-components');
|
|
|
19
19
|
const UploadDropZoneProvider = ({ children, onDrop, disabled = false })=>{
|
|
20
20
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
21
21
|
const dragCounterRef = React.useRef(0);
|
|
22
|
-
const contextValue = {
|
|
22
|
+
const contextValue = React.useMemo(()=>({
|
|
23
|
+
isDragging
|
|
24
|
+
}), [
|
|
23
25
|
isDragging
|
|
24
|
-
|
|
26
|
+
]);
|
|
25
27
|
React.useEffect(()=>{
|
|
26
28
|
const handleDragEnd = ()=>{
|
|
27
29
|
setIsDragging(false);
|
|
@@ -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
|
|
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
|
|
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:
|
|
434
|
+
children: filtersWithKeys.map(({ filter, index, key })=>/*#__PURE__*/ jsxRuntime.jsx(FilterBadge, {
|
|
409
435
|
filter: filter,
|
|
410
436
|
onChange: (next)=>updateFilter(index, next),
|
|
411
|
-
onRemove: ()=>
|
|
412
|
-
|
|
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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"}
|