@wordpress/media-utils 5.45.0 → 5.45.1-next.v.202605131006.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.
@@ -58,14 +58,16 @@ var LAYOUT_PICKER_GRID = "pickerGrid";
58
58
  var LAYOUT_PICKER_TABLE = "pickerTable";
59
59
  var NOTICES_CONTEXT = "media-modal";
60
60
  var NOTICE_ID_UPLOAD_PROGRESS = "media-modal-upload-progress";
61
+ var defaultQueryParams = {
62
+ page: 1,
63
+ search: ""
64
+ };
61
65
  var defaultView = {
62
66
  type: LAYOUT_PICKER_GRID,
63
67
  fields: [],
64
68
  showTitle: false,
65
69
  titleField: "title",
66
70
  mediaField: "media_thumbnail",
67
- search: "",
68
- page: 1,
69
71
  perPage: 50,
70
72
  filters: [],
71
73
  layout: {
@@ -115,12 +117,27 @@ function MediaUploadModal({
115
117
  });
116
118
  const { createSuccessNotice, removeAllNotices } = (0, import_data.useDispatch)(import_notices.store);
117
119
  const invalidateAttachmentResolutions = (0, import_use_invalidate_attachment_resolutions.useInvalidateAttachmentResolutions)();
120
+ const [queryParams, setQueryParams] = (0, import_element.useState)(
121
+ () => defaultQueryParams
122
+ );
118
123
  const { view, updateView, isModified, resetToDefault } = (0, import_views.useView)({
119
124
  kind: "postType",
120
125
  name: "attachment",
121
126
  slug: "media-modal",
122
- defaultView
127
+ defaultView,
128
+ queryParams,
129
+ onChangeQueryParams: setQueryParams
123
130
  });
131
+ const handleChangeView = (0, import_element.useCallback)(
132
+ (nextView) => {
133
+ const normalizedView = { ...nextView };
134
+ if (normalizedView.startPosition === void 0) {
135
+ delete normalizedView.startPosition;
136
+ }
137
+ updateView(normalizedView);
138
+ },
139
+ [updateView]
140
+ );
124
141
  const queryArgs = (0, import_element.useMemo)(() => {
125
142
  const filters = {};
126
143
  view.filters?.forEach((filter) => {
@@ -285,6 +302,11 @@ function MediaUploadModal({
285
302
  removeAllNotices("snackbar", NOTICES_CONTEXT);
286
303
  onClose?.();
287
304
  }, [removeAllNotices, onClose]);
305
+ (0, import_element.useEffect)(() => {
306
+ if (!isOpen) {
307
+ setQueryParams(defaultQueryParams);
308
+ }
309
+ }, [isOpen]);
288
310
  const handleUpload = onUpload || import_upload_media.uploadMedia;
289
311
  const prevAllCompleteRef = (0, import_element.useRef)(false);
290
312
  (0, import_element.useEffect)(() => {
@@ -409,7 +431,7 @@ function MediaUploadModal({
409
431
  data: mediaRecords || [],
410
432
  fields,
411
433
  view,
412
- onChangeView: updateView,
434
+ onChangeView: handleChangeView,
413
435
  actions,
414
436
  selection,
415
437
  onChangeSelection: setSelection,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/media-upload-modal/index.tsx"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tcreatePortal,\n\tuseState,\n\tuseCallback,\n\tuseMemo,\n\tuseRef,\n\tuseEffect,\n} from '@wordpress/element';\nimport { __, sprintf, _n } from '@wordpress/i18n';\nimport {\n\tprivateApis as coreDataPrivateApis,\n\tstore as coreStore,\n} from '@wordpress/core-data';\nimport { resolveSelect, useDispatch } from '@wordpress/data';\nimport { Modal, DropZone, FormFileUpload, Button } from '@wordpress/components';\nimport { upload as uploadIcon } from '@wordpress/icons';\nimport { DataViewsPicker } from '@wordpress/dataviews';\nimport type {\n\tField,\n\tActionButton,\n\tSupportedLayouts,\n\tView,\n} from '@wordpress/dataviews';\nimport { useView } from '@wordpress/views';\nimport { Stack } from '@wordpress/ui';\nimport {\n\taltTextField,\n\tattachedToField,\n\tauthorField,\n\tcaptionField,\n\tdateAddedField,\n\tdateModifiedField,\n\tdescriptionField,\n\tfilenameField,\n\tfilesizeField,\n\tmediaDimensionsField,\n\tmediaThumbnailField,\n\tmimeTypeField,\n} from '@wordpress/media-fields';\nimport { store as noticesStore, SnackbarNotices } from '@wordpress/notices';\n\n/**\n * Internal dependencies\n */\nimport type { Attachment, RestAttachment } from '../../utils/types';\nimport { transformAttachment } from '../../utils/transform-attachment';\nimport { uploadMedia } from '../../utils/upload-media';\nimport { unlock } from '../../lock-unlock';\nimport { UploadStatusPopover } from './upload-status-popover';\nimport { useInvalidateAttachmentResolutions } from './use-invalidate-attachment-resolutions';\nimport { useUploadStatus } from './use-upload-status';\n\nconst { useEntityRecordsWithPermissions } = unlock( coreDataPrivateApis );\n\n// Layout constants - matching the picker layout types\nconst LAYOUT_PICKER_GRID = 'pickerGrid';\nconst LAYOUT_PICKER_TABLE = 'pickerTable';\n\n// Custom notices context for the media modal\nconst NOTICES_CONTEXT = 'media-modal';\n\n// Notice ID - reused for all upload-related notices to prevent flooding\nconst NOTICE_ID_UPLOAD_PROGRESS = 'media-modal-upload-progress';\n\nconst defaultView: View = {\n\ttype: LAYOUT_PICKER_GRID,\n\tfields: [],\n\tshowTitle: false,\n\ttitleField: 'title',\n\tmediaField: 'media_thumbnail',\n\tsearch: '',\n\tpage: 1,\n\tperPage: 50,\n\tfilters: [],\n\tlayout: {\n\t\tpreviewSize: 170,\n\t\tdensity: 'compact',\n\t},\n};\n\nconst defaultLayouts: SupportedLayouts = {\n\t[ LAYOUT_PICKER_GRID ]: {\n\t\tfields: [],\n\t\tshowTitle: false,\n\t\tlayout: {\n\t\t\tpreviewSize: 170,\n\t\t\tdensity: 'compact',\n\t\t},\n\t},\n\t[ LAYOUT_PICKER_TABLE ]: {\n\t\tfields: [\n\t\t\t'filename',\n\t\t\t'filesize',\n\t\t\t'media_dimensions',\n\t\t\t'author',\n\t\t\t'date',\n\t\t],\n\t\tshowTitle: true,\n\t},\n};\n\ninterface MediaUploadModalProps {\n\t/**\n\t * Array of allowed media types.\n\t */\n\tallowedTypes?: string[];\n\n\t/**\n\t * Whether multiple files can be selected.\n\t * @default false\n\t */\n\tmultiple?: boolean;\n\n\t/**\n\t * The currently selected media item(s).\n\t * Can be a single ID number or array of IDs for multiple selection.\n\t */\n\tvalue?: number | number[];\n\n\t/**\n\t * Function called when media is selected.\n\t * Receives single attachment object or array of attachments.\n\t */\n\tonSelect: ( media: Attachment | Attachment[] ) => void;\n\n\t/**\n\t * Function called when the modal is closed without selection.\n\t */\n\tonClose?: () => void;\n\n\t/**\n\t * Function to handle media uploads.\n\t * If not provided, drag and drop will be disabled.\n\t */\n\tonUpload?: ( args: {\n\t\tallowedTypes?: string[];\n\t\tfilesList: File[];\n\t\tonFileChange?: ( attachments: Partial< Attachment >[] ) => void;\n\t\tonError?: ( error: Error ) => void;\n\t\tmultiple?: boolean;\n\t} ) => void;\n\n\t/**\n\t * Title for the modal.\n\t * @default 'Select Media'\n\t */\n\ttitle?: string;\n\n\t/**\n\t * Whether the modal is open.\n\t */\n\tisOpen: boolean;\n\n\t/**\n\t * Whether the modal can be closed by clicking outside or pressing escape.\n\t * @default true\n\t */\n\tisDismissible?: boolean;\n\n\t/**\n\t * Additional CSS class for the modal.\n\t */\n\tmodalClass?: string;\n\n\t/**\n\t * Whether to show a search input.\n\t * @default true\n\t */\n\tsearch?: boolean;\n\n\t/**\n\t * Label for the search input.\n\t */\n\tsearchLabel?: string;\n}\n\n/**\n * MediaUploadModal component that uses Modal and DataViewsPicker for media selection.\n *\n * This is a modern functional component alternative to the legacy MediaUpload class component.\n * It provides a cleaner API and better integration with the WordPress block editor.\n *\n * @param props Component props\n * @param props.allowedTypes Array of allowed media types\n * @param props.multiple Whether multiple files can be selected\n * @param props.value Currently selected media item(s)\n * @param props.onSelect Function called when media is selected\n * @param props.onClose Function called when modal is closed\n * @param props.onUpload Function to handle media uploads\n * @param props.title Title for the modal\n * @param props.isOpen Whether the modal is open\n * @param props.isDismissible Whether modal can be dismissed\n * @param props.modalClass Additional CSS class for modal\n * @param props.search Whether to show search input\n * @param props.searchLabel Label for search input\n * @return JSX element or null\n */\nexport function MediaUploadModal( {\n\tallowedTypes,\n\tmultiple = false,\n\tvalue,\n\tonSelect,\n\tonClose,\n\tonUpload,\n\ttitle = __( 'Select Media' ),\n\tisOpen,\n\tisDismissible = true,\n\tmodalClass,\n\tsearch = true,\n\tsearchLabel = __( 'Search media' ),\n}: MediaUploadModalProps ) {\n\tconst [ selection, setSelection ] = useState< string[] >( () => {\n\t\tif ( ! value ) {\n\t\t\treturn [];\n\t\t}\n\t\treturn Array.isArray( value )\n\t\t\t? value.map( String )\n\t\t\t: [ String( value ) ];\n\t} );\n\n\tconst { createSuccessNotice, removeAllNotices } =\n\t\tuseDispatch( noticesStore );\n\tconst invalidateAttachmentResolutions =\n\t\tuseInvalidateAttachmentResolutions();\n\n\t// Persist view configuration across sessions via the preferences store.\n\tconst { view, updateView, isModified, resetToDefault } = useView( {\n\t\tkind: 'postType',\n\t\tname: 'attachment',\n\t\tslug: 'media-modal',\n\t\tdefaultView,\n\t} );\n\n\t// Build query args based on view properties, similar to PostList\n\tconst queryArgs = useMemo( () => {\n\t\tconst filters: Record< string, any > = {};\n\n\t\tview.filters?.forEach( ( filter ) => {\n\t\t\t// Handle media type filters\n\t\t\tif ( filter.field === 'media_type' ) {\n\t\t\t\tfilters.media_type = filter.value;\n\t\t\t}\n\t\t\t// Handle author filters\n\t\t\tif ( filter.field === 'author' ) {\n\t\t\t\tif ( filter.operator === 'isAny' ) {\n\t\t\t\t\tfilters.author = filter.value;\n\t\t\t\t} else if ( filter.operator === 'isNone' ) {\n\t\t\t\t\tfilters.author_exclude = filter.value;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Handle date filters\n\t\t\tif ( filter.field === 'date' || filter.field === 'modified' ) {\n\t\t\t\tif ( filter.operator === 'before' ) {\n\t\t\t\t\tfilters.before = filter.value;\n\t\t\t\t} else if ( filter.operator === 'after' ) {\n\t\t\t\t\tfilters.after = filter.value;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Handle mime type filters\n\t\t\tif ( filter.field === 'mime_type' ) {\n\t\t\t\tfilters.mime_type = filter.value;\n\t\t\t}\n\t\t} );\n\n\t\t// Base media and mime type on allowedTypes if no filter is set\n\t\tif (\n\t\t\t! filters.media_type &&\n\t\t\t! filters.mime_type &&\n\t\t\tallowedTypes &&\n\t\t\t! allowedTypes.includes( '*' )\n\t\t) {\n\t\t\tconst { mediaTypes, mimeTypes } = allowedTypes.reduce(\n\t\t\t\t( acc, type ) => {\n\t\t\t\t\tif ( type.endsWith( '/*' ) ) {\n\t\t\t\t\t\tacc.mediaTypes.push( type.replace( '/*', '' ) );\n\t\t\t\t\t} else if ( type.includes( '/' ) ) {\n\t\t\t\t\t\tacc.mimeTypes.push( type );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tacc.mediaTypes.push( type );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn acc;\n\t\t\t\t},\n\t\t\t\t{ mediaTypes: [] as string[], mimeTypes: [] as string[] }\n\t\t\t);\n\n\t\t\tif ( mediaTypes.length ) {\n\t\t\t\tfilters.media_type = mediaTypes;\n\t\t\t}\n\t\t\tif ( mimeTypes.length ) {\n\t\t\t\tfilters.mime_type = mimeTypes;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tper_page: view.perPage || 20,\n\t\t\tpage: view.page || 1,\n\t\t\tstatus: 'inherit',\n\t\t\torder: view.sort?.direction,\n\t\t\torderby: view.sort?.field,\n\t\t\tsearch: view.search,\n\t\t\t_embed: 'author,wp:attached-to',\n\t\t\t...filters,\n\t\t};\n\t}, [ view, allowedTypes ] );\n\n\t// Per-batch completion handler: auto-select uploaded items and refresh the grid.\n\tconst handleBatchComplete = useCallback(\n\t\t( attachments: Partial< Attachment >[] ) => {\n\t\t\tconst uploadedIds = attachments\n\t\t\t\t.map( ( attachment ) => String( attachment.id ) )\n\t\t\t\t.filter( Boolean );\n\n\t\t\tif ( multiple ) {\n\t\t\t\tsetSelection( ( prev ) => {\n\t\t\t\t\tconst existing = new Set( prev );\n\t\t\t\t\tconst newIds = uploadedIds.filter(\n\t\t\t\t\t\t( id ) => ! existing.has( id )\n\t\t\t\t\t);\n\t\t\t\t\treturn [ ...prev, ...newIds ];\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tsetSelection( uploadedIds.slice( 0, 1 ) );\n\t\t\t}\n\n\t\t\t// Invalidate all cached attachment queries so every page of\n\t\t\t// results refreshes \u2014 not just the page the user is viewing.\n\t\t\tinvalidateAttachmentResolutions();\n\t\t},\n\t\t[ multiple, invalidateAttachmentResolutions ]\n\t);\n\n\tconst {\n\t\tuploadingFiles,\n\t\tregisterBatch,\n\t\tdismissError,\n\t\tclearCompleted,\n\t\tallComplete,\n\t} = useUploadStatus( { onBatchComplete: handleBatchComplete } );\n\n\tconst isPopoverOpenRef = useRef( false );\n\tconst handlePopoverOpenChange = useCallback(\n\t\t( open: boolean ) => {\n\t\t\tisPopoverOpenRef.current = open;\n\t\t\tif ( ! open ) {\n\t\t\t\tclearCompleted();\n\t\t\t}\n\t\t},\n\t\t[ clearCompleted ]\n\t);\n\n\t// Fetch all media attachments using WordPress core data with permissions\n\tconst {\n\t\trecords: mediaRecords,\n\t\tisResolving: isLoading,\n\t\ttotalItems,\n\t\ttotalPages,\n\t} = useEntityRecordsWithPermissions( 'postType', 'attachment', queryArgs );\n\n\tconst fields: Field< RestAttachment >[] = useMemo(\n\t\t() => [\n\t\t\t// Media field definitions from @wordpress/media-fields\n\t\t\t// Cast is safe because RestAttachment has the same properties as Attachment\n\t\t\t{\n\t\t\t\t...( mediaThumbnailField as Field< RestAttachment > ),\n\t\t\t\tenableHiding: false, // Within the modal, the thumbnail should always be shown.\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'title',\n\t\t\t\ttype: 'text' as const,\n\t\t\t\tlabel: __( 'Title' ),\n\t\t\t\tgetValue: ( { item }: { item: RestAttachment } ) => {\n\t\t\t\t\tconst titleValue = item.title.raw || item.title.rendered;\n\t\t\t\t\treturn titleValue || __( '(no title)' );\n\t\t\t\t},\n\t\t\t},\n\t\t\taltTextField as Field< RestAttachment >,\n\t\t\tcaptionField as Field< RestAttachment >,\n\t\t\tdescriptionField as Field< RestAttachment >,\n\t\t\tdateAddedField as Field< RestAttachment >,\n\t\t\tdateModifiedField as Field< RestAttachment >,\n\t\t\tauthorField as Field< RestAttachment >,\n\t\t\tfilenameField as Field< RestAttachment >,\n\t\t\tfilesizeField as Field< RestAttachment >,\n\t\t\tmediaDimensionsField as Field< RestAttachment >,\n\t\t\tmimeTypeField as Field< RestAttachment >,\n\t\t\tattachedToField as Field< RestAttachment >,\n\t\t],\n\t\t[]\n\t);\n\n\tconst actions: ActionButton< RestAttachment >[] = useMemo(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: 'select',\n\t\t\t\tlabel: __( 'Select' ),\n\t\t\t\tisPrimary: true,\n\t\t\t\tsupportsBulk: multiple,\n\t\t\t\tasync callback() {\n\t\t\t\t\tif ( selection.length === 0 ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst selectedPostsQuery = {\n\t\t\t\t\t\tinclude: selection,\n\t\t\t\t\t\tper_page: -1,\n\t\t\t\t\t};\n\n\t\t\t\t\tconst selectedPosts = await resolveSelect(\n\t\t\t\t\t\tcoreStore\n\t\t\t\t\t).getEntityRecords< RestAttachment >(\n\t\t\t\t\t\t'postType',\n\t\t\t\t\t\t'attachment',\n\t\t\t\t\t\tselectedPostsQuery\n\t\t\t\t\t);\n\n\t\t\t\t\t// Transform the selected posts to the expected Attachment format\n\t\t\t\t\tconst transformedPosts = ( selectedPosts ?? [] )\n\t\t\t\t\t\t.map( transformAttachment )\n\t\t\t\t\t\t.filter( Boolean );\n\n\t\t\t\t\tconst selectedItems = multiple\n\t\t\t\t\t\t? transformedPosts\n\t\t\t\t\t\t: transformedPosts?.[ 0 ];\n\n\t\t\t\t\tremoveAllNotices( 'snackbar', NOTICES_CONTEXT );\n\t\t\t\t\tonSelect( selectedItems );\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\t[ multiple, onSelect, selection, removeAllNotices ]\n\t);\n\n\tconst handleModalClose = useCallback( () => {\n\t\tremoveAllNotices( 'snackbar', NOTICES_CONTEXT );\n\t\tonClose?.();\n\t}, [ removeAllNotices, onClose ] );\n\n\t// Use onUpload if provided, otherwise fall back to uploadMedia\n\tconst handleUpload = onUpload || uploadMedia;\n\n\t// Show success notice and auto-clear completed entries when all batches finish.\n\tconst prevAllCompleteRef = useRef( false );\n\tuseEffect( () => {\n\t\tif ( allComplete && ! prevAllCompleteRef.current ) {\n\t\t\tconst completeCount = uploadingFiles.filter(\n\t\t\t\t( file ) => file.status === 'uploaded'\n\t\t\t).length;\n\t\t\tif ( completeCount > 0 ) {\n\t\t\t\tcreateSuccessNotice(\n\t\t\t\t\tsprintf(\n\t\t\t\t\t\t// translators: %s: number of files\n\t\t\t\t\t\t_n(\n\t\t\t\t\t\t\t'Uploaded %s file',\n\t\t\t\t\t\t\t'Uploaded %s files',\n\t\t\t\t\t\t\tcompleteCount\n\t\t\t\t\t\t),\n\t\t\t\t\t\tcompleteCount.toLocaleString()\n\t\t\t\t\t),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'snackbar',\n\t\t\t\t\t\tcontext: NOTICES_CONTEXT,\n\t\t\t\t\t\tid: NOTICE_ID_UPLOAD_PROGRESS,\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Auto-clear completed entries, unless the popover is\n\t\t\t// open \u2014 in that case, they'll be cleared on close.\n\t\t\tif ( ! isPopoverOpenRef.current ) {\n\t\t\t\tclearCompleted();\n\t\t\t}\n\t\t}\n\t\tprevAllCompleteRef.current = allComplete;\n\t}, [ allComplete, uploadingFiles, createSuccessNotice, clearCompleted ] );\n\n\tconst handleFileSelect = useCallback(\n\t\t( event: React.ChangeEvent< HTMLInputElement > ) => {\n\t\t\tconst files = event.target.files;\n\t\t\tif ( files && files.length > 0 ) {\n\t\t\t\tconst filesArray = Array.from( files );\n\t\t\t\tconst { onFileChange, onError } = registerBatch( filesArray );\n\n\t\t\t\thandleUpload( {\n\t\t\t\t\tallowedTypes,\n\t\t\t\t\tfilesList: filesArray,\n\t\t\t\t\tonFileChange,\n\t\t\t\t\tonError,\n\t\t\t\t} );\n\t\t\t}\n\t\t},\n\t\t[ allowedTypes, handleUpload, registerBatch ]\n\t);\n\n\tconst paginationInfo = useMemo(\n\t\t() => ( {\n\t\t\ttotalItems,\n\t\t\ttotalPages,\n\t\t} ),\n\t\t[ totalItems, totalPages ]\n\t);\n\n\t// Build accept attribute from allowedTypes\n\tconst acceptTypes = useMemo( () => {\n\t\tif ( allowedTypes?.includes( '*' ) ) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn allowedTypes?.join( ',' );\n\t}, [ allowedTypes ] );\n\n\tif ( ! isOpen ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<Modal\n\t\t\ttitle={ title }\n\t\t\tonRequestClose={ handleModalClose }\n\t\t\tisDismissible={ isDismissible }\n\t\t\tclassName={ modalClass }\n\t\t\toverlayClassName=\"media-upload-modal\"\n\t\t\tsize=\"fill\"\n\t\t\theaderActions={\n\t\t\t\t<FormFileUpload\n\t\t\t\t\taccept={ acceptTypes }\n\t\t\t\t\tmultiple\n\t\t\t\t\tonChange={ handleFileSelect }\n\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\trender={ ( { openFileDialog } ) => (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tonClick={ openFileDialog }\n\t\t\t\t\t\t\ticon={ uploadIcon }\n\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ __( 'Upload media' ) }\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t) }\n\t\t\t\t/>\n\t\t\t}\n\t\t>\n\t\t\t<DropZone\n\t\t\t\tonFilesDrop={ ( files ) => {\n\t\t\t\t\tlet filteredFiles = files;\n\t\t\t\t\t// Filter files by allowed types if specified\n\t\t\t\t\tif ( allowedTypes && ! allowedTypes.includes( '*' ) ) {\n\t\t\t\t\t\tfilteredFiles = files.filter( ( file ) =>\n\t\t\t\t\t\t\tallowedTypes.some( ( allowedType ) => {\n\t\t\t\t\t\t\t\t// Check if the file type matches the allowed MIME type\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\tfile.type === allowedType ||\n\t\t\t\t\t\t\t\t\tfile.type.startsWith(\n\t\t\t\t\t\t\t\t\t\tallowedType.replace( '*', '' )\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif ( filteredFiles.length > 0 ) {\n\t\t\t\t\t\tconst { onFileChange, onError } =\n\t\t\t\t\t\t\tregisterBatch( filteredFiles );\n\n\t\t\t\t\t\thandleUpload( {\n\t\t\t\t\t\t\tallowedTypes,\n\t\t\t\t\t\t\tfilesList: filteredFiles,\n\t\t\t\t\t\t\tonFileChange,\n\t\t\t\t\t\t\tonError,\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t} }\n\t\t\t\tlabel={ __( 'Drop files to upload' ) }\n\t\t\t/>\n\t\t\t<DataViewsPicker\n\t\t\t\tdata={ mediaRecords || [] }\n\t\t\t\tfields={ fields }\n\t\t\t\tview={ view }\n\t\t\t\tonChangeView={ updateView }\n\t\t\t\tactions={ actions }\n\t\t\t\tselection={ selection }\n\t\t\t\tonChangeSelection={ setSelection }\n\t\t\t\tisLoading={ isLoading }\n\t\t\t\tpaginationInfo={ paginationInfo }\n\t\t\t\tdefaultLayouts={ defaultLayouts }\n\t\t\t\tgetItemId={ ( item: RestAttachment ) => String( item.id ) }\n\t\t\t\titemListLabel={ __( 'Media items' ) }\n\t\t\t\tonReset={ isModified ? resetToDefault : false }\n\t\t\t>\n\t\t\t\t<Stack\n\t\t\t\t\tdirection=\"row\"\n\t\t\t\t\talign=\"top\"\n\t\t\t\t\tjustify=\"space-between\"\n\t\t\t\t\tclassName=\"dataviews__view-actions\"\n\t\t\t\t\tgap=\"xs\"\n\t\t\t\t>\n\t\t\t\t\t<Stack\n\t\t\t\t\t\tdirection=\"row\"\n\t\t\t\t\t\tgap=\"sm\"\n\t\t\t\t\t\tjustify=\"start\"\n\t\t\t\t\t\tclassName=\"dataviews__search\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{ search && (\n\t\t\t\t\t\t\t<DataViewsPicker.Search label={ searchLabel } />\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t<DataViewsPicker.FiltersToggle />\n\t\t\t\t\t</Stack>\n\t\t\t\t\t<Stack direction=\"row\" gap=\"xs\" style={ { flexShrink: 0 } }>\n\t\t\t\t\t\t<DataViewsPicker.LayoutSwitcher />\n\t\t\t\t\t\t<DataViewsPicker.ViewConfig />\n\t\t\t\t\t</Stack>\n\t\t\t\t</Stack>\n\t\t\t\t<DataViewsPicker.FiltersToggled className=\"dataviews-filters__container\" />\n\t\t\t\t<DataViewsPicker.Layout />\n\t\t\t\t<div\n\t\t\t\t\tclassName={ clsx( 'media-upload-modal__footer', {\n\t\t\t\t\t\t'is-uploading': uploadingFiles.length > 0,\n\t\t\t\t\t} ) }\n\t\t\t\t>\n\t\t\t\t\t<UploadStatusPopover\n\t\t\t\t\t\tuploadingFiles={ uploadingFiles }\n\t\t\t\t\t\tonDismissError={ dismissError }\n\t\t\t\t\t\tonOpenChange={ handlePopoverOpenChange }\n\t\t\t\t\t/>\n\t\t\t\t\t<DataViewsPicker.BulkActionToolbar />\n\t\t\t\t</div>\n\t\t\t</DataViewsPicker>\n\t\t\t{ createPortal(\n\t\t\t\t<SnackbarNotices\n\t\t\t\t\tclassName=\"media-upload-modal__snackbar\"\n\t\t\t\t\tcontext={ NOTICES_CONTEXT }\n\t\t\t\t/>,\n\t\t\t\tdocument.body\n\t\t\t) }\n\t\t</Modal>\n\t);\n}\n\nexport default MediaUploadModal;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tcreatePortal,\n\tuseState,\n\tuseCallback,\n\tuseMemo,\n\tuseRef,\n\tuseEffect,\n} from '@wordpress/element';\nimport { __, sprintf, _n } from '@wordpress/i18n';\nimport {\n\tprivateApis as coreDataPrivateApis,\n\tstore as coreStore,\n} from '@wordpress/core-data';\nimport { resolveSelect, useDispatch } from '@wordpress/data';\nimport { Modal, DropZone, FormFileUpload, Button } from '@wordpress/components';\nimport { upload as uploadIcon } from '@wordpress/icons';\nimport { DataViewsPicker } from '@wordpress/dataviews';\nimport type {\n\tField,\n\tActionButton,\n\tSupportedLayouts,\n\tView,\n} from '@wordpress/dataviews';\nimport { useView } from '@wordpress/views';\nimport { Stack } from '@wordpress/ui';\nimport {\n\taltTextField,\n\tattachedToField,\n\tauthorField,\n\tcaptionField,\n\tdateAddedField,\n\tdateModifiedField,\n\tdescriptionField,\n\tfilenameField,\n\tfilesizeField,\n\tmediaDimensionsField,\n\tmediaThumbnailField,\n\tmimeTypeField,\n} from '@wordpress/media-fields';\nimport { store as noticesStore, SnackbarNotices } from '@wordpress/notices';\n\n/**\n * Internal dependencies\n */\nimport type { Attachment, RestAttachment } from '../../utils/types';\nimport { transformAttachment } from '../../utils/transform-attachment';\nimport { uploadMedia } from '../../utils/upload-media';\nimport { unlock } from '../../lock-unlock';\nimport { UploadStatusPopover } from './upload-status-popover';\nimport { useInvalidateAttachmentResolutions } from './use-invalidate-attachment-resolutions';\nimport { useUploadStatus } from './use-upload-status';\n\nconst { useEntityRecordsWithPermissions } = unlock( coreDataPrivateApis );\n\n// Layout constants - matching the picker layout types\nconst LAYOUT_PICKER_GRID = 'pickerGrid';\nconst LAYOUT_PICKER_TABLE = 'pickerTable';\n\n// Custom notices context for the media modal\nconst NOTICES_CONTEXT = 'media-modal';\n\n// Notice ID - reused for all upload-related notices to prevent flooding\nconst NOTICE_ID_UPLOAD_PROGRESS = 'media-modal-upload-progress';\n\ntype ViewQueryParams = Pick< View, 'page' | 'search' >;\n\nconst defaultQueryParams: ViewQueryParams = {\n\tpage: 1,\n\tsearch: '',\n};\n\nconst defaultView: View = {\n\ttype: LAYOUT_PICKER_GRID,\n\tfields: [],\n\tshowTitle: false,\n\ttitleField: 'title',\n\tmediaField: 'media_thumbnail',\n\tperPage: 50,\n\tfilters: [],\n\tlayout: {\n\t\tpreviewSize: 170,\n\t\tdensity: 'compact',\n\t},\n};\n\nconst defaultLayouts: SupportedLayouts = {\n\t[ LAYOUT_PICKER_GRID ]: {\n\t\tfields: [],\n\t\tshowTitle: false,\n\t\tlayout: {\n\t\t\tpreviewSize: 170,\n\t\t\tdensity: 'compact',\n\t\t},\n\t},\n\t[ LAYOUT_PICKER_TABLE ]: {\n\t\tfields: [\n\t\t\t'filename',\n\t\t\t'filesize',\n\t\t\t'media_dimensions',\n\t\t\t'author',\n\t\t\t'date',\n\t\t],\n\t\tshowTitle: true,\n\t},\n};\n\ninterface MediaUploadModalProps {\n\t/**\n\t * Array of allowed media types.\n\t */\n\tallowedTypes?: string[];\n\n\t/**\n\t * Whether multiple files can be selected.\n\t * @default false\n\t */\n\tmultiple?: boolean;\n\n\t/**\n\t * The currently selected media item(s).\n\t * Can be a single ID number or array of IDs for multiple selection.\n\t */\n\tvalue?: number | number[];\n\n\t/**\n\t * Function called when media is selected.\n\t * Receives single attachment object or array of attachments.\n\t */\n\tonSelect: ( media: Attachment | Attachment[] ) => void;\n\n\t/**\n\t * Function called when the modal is closed without selection.\n\t */\n\tonClose?: () => void;\n\n\t/**\n\t * Function to handle media uploads.\n\t * If not provided, drag and drop will be disabled.\n\t */\n\tonUpload?: ( args: {\n\t\tallowedTypes?: string[];\n\t\tfilesList: File[];\n\t\tonFileChange?: ( attachments: Partial< Attachment >[] ) => void;\n\t\tonError?: ( error: Error ) => void;\n\t\tmultiple?: boolean;\n\t} ) => void;\n\n\t/**\n\t * Title for the modal.\n\t * @default 'Select Media'\n\t */\n\ttitle?: string;\n\n\t/**\n\t * Whether the modal is open.\n\t */\n\tisOpen: boolean;\n\n\t/**\n\t * Whether the modal can be closed by clicking outside or pressing escape.\n\t * @default true\n\t */\n\tisDismissible?: boolean;\n\n\t/**\n\t * Additional CSS class for the modal.\n\t */\n\tmodalClass?: string;\n\n\t/**\n\t * Whether to show a search input.\n\t * @default true\n\t */\n\tsearch?: boolean;\n\n\t/**\n\t * Label for the search input.\n\t */\n\tsearchLabel?: string;\n}\n\n/**\n * MediaUploadModal component that uses Modal and DataViewsPicker for media selection.\n *\n * This is a modern functional component alternative to the legacy MediaUpload class component.\n * It provides a cleaner API and better integration with the WordPress block editor.\n *\n * @param props Component props\n * @param props.allowedTypes Array of allowed media types\n * @param props.multiple Whether multiple files can be selected\n * @param props.value Currently selected media item(s)\n * @param props.onSelect Function called when media is selected\n * @param props.onClose Function called when modal is closed\n * @param props.onUpload Function to handle media uploads\n * @param props.title Title for the modal\n * @param props.isOpen Whether the modal is open\n * @param props.isDismissible Whether modal can be dismissed\n * @param props.modalClass Additional CSS class for modal\n * @param props.search Whether to show search input\n * @param props.searchLabel Label for search input\n * @return JSX element or null\n */\nexport function MediaUploadModal( {\n\tallowedTypes,\n\tmultiple = false,\n\tvalue,\n\tonSelect,\n\tonClose,\n\tonUpload,\n\ttitle = __( 'Select Media' ),\n\tisOpen,\n\tisDismissible = true,\n\tmodalClass,\n\tsearch = true,\n\tsearchLabel = __( 'Search media' ),\n}: MediaUploadModalProps ) {\n\tconst [ selection, setSelection ] = useState< string[] >( () => {\n\t\tif ( ! value ) {\n\t\t\treturn [];\n\t\t}\n\t\treturn Array.isArray( value )\n\t\t\t? value.map( String )\n\t\t\t: [ String( value ) ];\n\t} );\n\n\tconst { createSuccessNotice, removeAllNotices } =\n\t\tuseDispatch( noticesStore );\n\tconst invalidateAttachmentResolutions =\n\t\tuseInvalidateAttachmentResolutions();\n\tconst [ queryParams, setQueryParams ] = useState< ViewQueryParams >(\n\t\t() => defaultQueryParams\n\t);\n\n\t// Persist view configuration across sessions via the preferences store.\n\tconst { view, updateView, isModified, resetToDefault } = useView( {\n\t\tkind: 'postType',\n\t\tname: 'attachment',\n\t\tslug: 'media-modal',\n\t\tdefaultView,\n\t\tqueryParams,\n\t\tonChangeQueryParams: setQueryParams,\n\t} );\n\n\t// Normalize undefined transient DataViews values so they do not persist as modified modal preferences.\n\tconst handleChangeView = useCallback(\n\t\t( nextView: View ) => {\n\t\t\tconst normalizedView = { ...nextView };\n\t\t\tif ( normalizedView.startPosition === undefined ) {\n\t\t\t\tdelete normalizedView.startPosition;\n\t\t\t}\n\t\t\tupdateView( normalizedView );\n\t\t},\n\t\t[ updateView ]\n\t);\n\n\t// Build query args based on view properties, similar to PostList\n\tconst queryArgs = useMemo( () => {\n\t\tconst filters: Record< string, any > = {};\n\n\t\tview.filters?.forEach( ( filter ) => {\n\t\t\t// Handle media type filters\n\t\t\tif ( filter.field === 'media_type' ) {\n\t\t\t\tfilters.media_type = filter.value;\n\t\t\t}\n\t\t\t// Handle author filters\n\t\t\tif ( filter.field === 'author' ) {\n\t\t\t\tif ( filter.operator === 'isAny' ) {\n\t\t\t\t\tfilters.author = filter.value;\n\t\t\t\t} else if ( filter.operator === 'isNone' ) {\n\t\t\t\t\tfilters.author_exclude = filter.value;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Handle date filters\n\t\t\tif ( filter.field === 'date' || filter.field === 'modified' ) {\n\t\t\t\tif ( filter.operator === 'before' ) {\n\t\t\t\t\tfilters.before = filter.value;\n\t\t\t\t} else if ( filter.operator === 'after' ) {\n\t\t\t\t\tfilters.after = filter.value;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Handle mime type filters\n\t\t\tif ( filter.field === 'mime_type' ) {\n\t\t\t\tfilters.mime_type = filter.value;\n\t\t\t}\n\t\t} );\n\n\t\t// Base media and mime type on allowedTypes if no filter is set\n\t\tif (\n\t\t\t! filters.media_type &&\n\t\t\t! filters.mime_type &&\n\t\t\tallowedTypes &&\n\t\t\t! allowedTypes.includes( '*' )\n\t\t) {\n\t\t\tconst { mediaTypes, mimeTypes } = allowedTypes.reduce(\n\t\t\t\t( acc, type ) => {\n\t\t\t\t\tif ( type.endsWith( '/*' ) ) {\n\t\t\t\t\t\tacc.mediaTypes.push( type.replace( '/*', '' ) );\n\t\t\t\t\t} else if ( type.includes( '/' ) ) {\n\t\t\t\t\t\tacc.mimeTypes.push( type );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tacc.mediaTypes.push( type );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn acc;\n\t\t\t\t},\n\t\t\t\t{ mediaTypes: [] as string[], mimeTypes: [] as string[] }\n\t\t\t);\n\n\t\t\tif ( mediaTypes.length ) {\n\t\t\t\tfilters.media_type = mediaTypes;\n\t\t\t}\n\t\t\tif ( mimeTypes.length ) {\n\t\t\t\tfilters.mime_type = mimeTypes;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tper_page: view.perPage || 20,\n\t\t\tpage: view.page || 1,\n\t\t\tstatus: 'inherit',\n\t\t\torder: view.sort?.direction,\n\t\t\torderby: view.sort?.field,\n\t\t\tsearch: view.search,\n\t\t\t_embed: 'author,wp:attached-to',\n\t\t\t...filters,\n\t\t};\n\t}, [ view, allowedTypes ] );\n\n\t// Per-batch completion handler: auto-select uploaded items and refresh the grid.\n\tconst handleBatchComplete = useCallback(\n\t\t( attachments: Partial< Attachment >[] ) => {\n\t\t\tconst uploadedIds = attachments\n\t\t\t\t.map( ( attachment ) => String( attachment.id ) )\n\t\t\t\t.filter( Boolean );\n\n\t\t\tif ( multiple ) {\n\t\t\t\tsetSelection( ( prev ) => {\n\t\t\t\t\tconst existing = new Set( prev );\n\t\t\t\t\tconst newIds = uploadedIds.filter(\n\t\t\t\t\t\t( id ) => ! existing.has( id )\n\t\t\t\t\t);\n\t\t\t\t\treturn [ ...prev, ...newIds ];\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tsetSelection( uploadedIds.slice( 0, 1 ) );\n\t\t\t}\n\n\t\t\t// Invalidate all cached attachment queries so every page of\n\t\t\t// results refreshes \u2014 not just the page the user is viewing.\n\t\t\tinvalidateAttachmentResolutions();\n\t\t},\n\t\t[ multiple, invalidateAttachmentResolutions ]\n\t);\n\n\tconst {\n\t\tuploadingFiles,\n\t\tregisterBatch,\n\t\tdismissError,\n\t\tclearCompleted,\n\t\tallComplete,\n\t} = useUploadStatus( { onBatchComplete: handleBatchComplete } );\n\n\tconst isPopoverOpenRef = useRef( false );\n\tconst handlePopoverOpenChange = useCallback(\n\t\t( open: boolean ) => {\n\t\t\tisPopoverOpenRef.current = open;\n\t\t\tif ( ! open ) {\n\t\t\t\tclearCompleted();\n\t\t\t}\n\t\t},\n\t\t[ clearCompleted ]\n\t);\n\n\t// Fetch all media attachments using WordPress core data with permissions\n\tconst {\n\t\trecords: mediaRecords,\n\t\tisResolving: isLoading,\n\t\ttotalItems,\n\t\ttotalPages,\n\t} = useEntityRecordsWithPermissions( 'postType', 'attachment', queryArgs );\n\n\tconst fields: Field< RestAttachment >[] = useMemo(\n\t\t() => [\n\t\t\t// Media field definitions from @wordpress/media-fields\n\t\t\t// Cast is safe because RestAttachment has the same properties as Attachment\n\t\t\t{\n\t\t\t\t...( mediaThumbnailField as Field< RestAttachment > ),\n\t\t\t\tenableHiding: false, // Within the modal, the thumbnail should always be shown.\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'title',\n\t\t\t\ttype: 'text' as const,\n\t\t\t\tlabel: __( 'Title' ),\n\t\t\t\tgetValue: ( { item }: { item: RestAttachment } ) => {\n\t\t\t\t\tconst titleValue = item.title.raw || item.title.rendered;\n\t\t\t\t\treturn titleValue || __( '(no title)' );\n\t\t\t\t},\n\t\t\t},\n\t\t\taltTextField as Field< RestAttachment >,\n\t\t\tcaptionField as Field< RestAttachment >,\n\t\t\tdescriptionField as Field< RestAttachment >,\n\t\t\tdateAddedField as Field< RestAttachment >,\n\t\t\tdateModifiedField as Field< RestAttachment >,\n\t\t\tauthorField as Field< RestAttachment >,\n\t\t\tfilenameField as Field< RestAttachment >,\n\t\t\tfilesizeField as Field< RestAttachment >,\n\t\t\tmediaDimensionsField as Field< RestAttachment >,\n\t\t\tmimeTypeField as Field< RestAttachment >,\n\t\t\tattachedToField as Field< RestAttachment >,\n\t\t],\n\t\t[]\n\t);\n\n\tconst actions: ActionButton< RestAttachment >[] = useMemo(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: 'select',\n\t\t\t\tlabel: __( 'Select' ),\n\t\t\t\tisPrimary: true,\n\t\t\t\tsupportsBulk: multiple,\n\t\t\t\tasync callback() {\n\t\t\t\t\tif ( selection.length === 0 ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst selectedPostsQuery = {\n\t\t\t\t\t\tinclude: selection,\n\t\t\t\t\t\tper_page: -1,\n\t\t\t\t\t};\n\n\t\t\t\t\tconst selectedPosts = await resolveSelect(\n\t\t\t\t\t\tcoreStore\n\t\t\t\t\t).getEntityRecords< RestAttachment >(\n\t\t\t\t\t\t'postType',\n\t\t\t\t\t\t'attachment',\n\t\t\t\t\t\tselectedPostsQuery\n\t\t\t\t\t);\n\n\t\t\t\t\t// Transform the selected posts to the expected Attachment format\n\t\t\t\t\tconst transformedPosts = ( selectedPosts ?? [] )\n\t\t\t\t\t\t.map( transformAttachment )\n\t\t\t\t\t\t.filter( Boolean );\n\n\t\t\t\t\tconst selectedItems = multiple\n\t\t\t\t\t\t? transformedPosts\n\t\t\t\t\t\t: transformedPosts?.[ 0 ];\n\n\t\t\t\t\tremoveAllNotices( 'snackbar', NOTICES_CONTEXT );\n\t\t\t\t\tonSelect( selectedItems );\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\t[ multiple, onSelect, selection, removeAllNotices ]\n\t);\n\n\tconst handleModalClose = useCallback( () => {\n\t\tremoveAllNotices( 'snackbar', NOTICES_CONTEXT );\n\t\tonClose?.();\n\t}, [ removeAllNotices, onClose ] );\n\n\tuseEffect( () => {\n\t\tif ( ! isOpen ) {\n\t\t\tsetQueryParams( defaultQueryParams );\n\t\t}\n\t}, [ isOpen ] );\n\n\t// Use onUpload if provided, otherwise fall back to uploadMedia\n\tconst handleUpload = onUpload || uploadMedia;\n\n\t// Show success notice and auto-clear completed entries when all batches finish.\n\tconst prevAllCompleteRef = useRef( false );\n\tuseEffect( () => {\n\t\tif ( allComplete && ! prevAllCompleteRef.current ) {\n\t\t\tconst completeCount = uploadingFiles.filter(\n\t\t\t\t( file ) => file.status === 'uploaded'\n\t\t\t).length;\n\t\t\tif ( completeCount > 0 ) {\n\t\t\t\tcreateSuccessNotice(\n\t\t\t\t\tsprintf(\n\t\t\t\t\t\t// translators: %s: number of files\n\t\t\t\t\t\t_n(\n\t\t\t\t\t\t\t'Uploaded %s file',\n\t\t\t\t\t\t\t'Uploaded %s files',\n\t\t\t\t\t\t\tcompleteCount\n\t\t\t\t\t\t),\n\t\t\t\t\t\tcompleteCount.toLocaleString()\n\t\t\t\t\t),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'snackbar',\n\t\t\t\t\t\tcontext: NOTICES_CONTEXT,\n\t\t\t\t\t\tid: NOTICE_ID_UPLOAD_PROGRESS,\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Auto-clear completed entries, unless the popover is\n\t\t\t// open \u2014 in that case, they'll be cleared on close.\n\t\t\tif ( ! isPopoverOpenRef.current ) {\n\t\t\t\tclearCompleted();\n\t\t\t}\n\t\t}\n\t\tprevAllCompleteRef.current = allComplete;\n\t}, [ allComplete, uploadingFiles, createSuccessNotice, clearCompleted ] );\n\n\tconst handleFileSelect = useCallback(\n\t\t( event: React.ChangeEvent< HTMLInputElement > ) => {\n\t\t\tconst files = event.target.files;\n\t\t\tif ( files && files.length > 0 ) {\n\t\t\t\tconst filesArray = Array.from( files );\n\t\t\t\tconst { onFileChange, onError } = registerBatch( filesArray );\n\n\t\t\t\thandleUpload( {\n\t\t\t\t\tallowedTypes,\n\t\t\t\t\tfilesList: filesArray,\n\t\t\t\t\tonFileChange,\n\t\t\t\t\tonError,\n\t\t\t\t} );\n\t\t\t}\n\t\t},\n\t\t[ allowedTypes, handleUpload, registerBatch ]\n\t);\n\n\tconst paginationInfo = useMemo(\n\t\t() => ( {\n\t\t\ttotalItems,\n\t\t\ttotalPages,\n\t\t} ),\n\t\t[ totalItems, totalPages ]\n\t);\n\n\t// Build accept attribute from allowedTypes\n\tconst acceptTypes = useMemo( () => {\n\t\tif ( allowedTypes?.includes( '*' ) ) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn allowedTypes?.join( ',' );\n\t}, [ allowedTypes ] );\n\n\tif ( ! isOpen ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<Modal\n\t\t\ttitle={ title }\n\t\t\tonRequestClose={ handleModalClose }\n\t\t\tisDismissible={ isDismissible }\n\t\t\tclassName={ modalClass }\n\t\t\toverlayClassName=\"media-upload-modal\"\n\t\t\tsize=\"fill\"\n\t\t\theaderActions={\n\t\t\t\t<FormFileUpload\n\t\t\t\t\taccept={ acceptTypes }\n\t\t\t\t\tmultiple\n\t\t\t\t\tonChange={ handleFileSelect }\n\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\trender={ ( { openFileDialog } ) => (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tonClick={ openFileDialog }\n\t\t\t\t\t\t\ticon={ uploadIcon }\n\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ __( 'Upload media' ) }\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t) }\n\t\t\t\t/>\n\t\t\t}\n\t\t>\n\t\t\t<DropZone\n\t\t\t\tonFilesDrop={ ( files ) => {\n\t\t\t\t\tlet filteredFiles = files;\n\t\t\t\t\t// Filter files by allowed types if specified\n\t\t\t\t\tif ( allowedTypes && ! allowedTypes.includes( '*' ) ) {\n\t\t\t\t\t\tfilteredFiles = files.filter( ( file ) =>\n\t\t\t\t\t\t\tallowedTypes.some( ( allowedType ) => {\n\t\t\t\t\t\t\t\t// Check if the file type matches the allowed MIME type\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\tfile.type === allowedType ||\n\t\t\t\t\t\t\t\t\tfile.type.startsWith(\n\t\t\t\t\t\t\t\t\t\tallowedType.replace( '*', '' )\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif ( filteredFiles.length > 0 ) {\n\t\t\t\t\t\tconst { onFileChange, onError } =\n\t\t\t\t\t\t\tregisterBatch( filteredFiles );\n\n\t\t\t\t\t\thandleUpload( {\n\t\t\t\t\t\t\tallowedTypes,\n\t\t\t\t\t\t\tfilesList: filteredFiles,\n\t\t\t\t\t\t\tonFileChange,\n\t\t\t\t\t\t\tonError,\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t} }\n\t\t\t\tlabel={ __( 'Drop files to upload' ) }\n\t\t\t/>\n\t\t\t<DataViewsPicker\n\t\t\t\tdata={ mediaRecords || [] }\n\t\t\t\tfields={ fields }\n\t\t\t\tview={ view }\n\t\t\t\tonChangeView={ handleChangeView }\n\t\t\t\tactions={ actions }\n\t\t\t\tselection={ selection }\n\t\t\t\tonChangeSelection={ setSelection }\n\t\t\t\tisLoading={ isLoading }\n\t\t\t\tpaginationInfo={ paginationInfo }\n\t\t\t\tdefaultLayouts={ defaultLayouts }\n\t\t\t\tgetItemId={ ( item: RestAttachment ) => String( item.id ) }\n\t\t\t\titemListLabel={ __( 'Media items' ) }\n\t\t\t\tonReset={ isModified ? resetToDefault : false }\n\t\t\t>\n\t\t\t\t<Stack\n\t\t\t\t\tdirection=\"row\"\n\t\t\t\t\talign=\"top\"\n\t\t\t\t\tjustify=\"space-between\"\n\t\t\t\t\tclassName=\"dataviews__view-actions\"\n\t\t\t\t\tgap=\"xs\"\n\t\t\t\t>\n\t\t\t\t\t<Stack\n\t\t\t\t\t\tdirection=\"row\"\n\t\t\t\t\t\tgap=\"sm\"\n\t\t\t\t\t\tjustify=\"start\"\n\t\t\t\t\t\tclassName=\"dataviews__search\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{ search && (\n\t\t\t\t\t\t\t<DataViewsPicker.Search label={ searchLabel } />\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t<DataViewsPicker.FiltersToggle />\n\t\t\t\t\t</Stack>\n\t\t\t\t\t<Stack direction=\"row\" gap=\"xs\" style={ { flexShrink: 0 } }>\n\t\t\t\t\t\t<DataViewsPicker.LayoutSwitcher />\n\t\t\t\t\t\t<DataViewsPicker.ViewConfig />\n\t\t\t\t\t</Stack>\n\t\t\t\t</Stack>\n\t\t\t\t<DataViewsPicker.FiltersToggled className=\"dataviews-filters__container\" />\n\t\t\t\t<DataViewsPicker.Layout />\n\t\t\t\t<div\n\t\t\t\t\tclassName={ clsx( 'media-upload-modal__footer', {\n\t\t\t\t\t\t'is-uploading': uploadingFiles.length > 0,\n\t\t\t\t\t} ) }\n\t\t\t\t>\n\t\t\t\t\t<UploadStatusPopover\n\t\t\t\t\t\tuploadingFiles={ uploadingFiles }\n\t\t\t\t\t\tonDismissError={ dismissError }\n\t\t\t\t\t\tonOpenChange={ handlePopoverOpenChange }\n\t\t\t\t\t/>\n\t\t\t\t\t<DataViewsPicker.BulkActionToolbar />\n\t\t\t\t</div>\n\t\t\t</DataViewsPicker>\n\t\t\t{ createPortal(\n\t\t\t\t<SnackbarNotices\n\t\t\t\t\tclassName=\"media-upload-modal__snackbar\"\n\t\t\t\t\tcontext={ NOTICES_CONTEXT }\n\t\t\t\t/>,\n\t\t\t\tdocument.body\n\t\t\t) }\n\t\t</Modal>\n\t);\n}\n\nexport default MediaUploadModal;\n"],
5
+ "mappings": "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",
6
6
  "names": ["coreDataPrivateApis", "noticesStore", "coreStore", "uploadIcon", "clsx"]
7
7
  }
@@ -46,14 +46,16 @@ var LAYOUT_PICKER_GRID = "pickerGrid";
46
46
  var LAYOUT_PICKER_TABLE = "pickerTable";
47
47
  var NOTICES_CONTEXT = "media-modal";
48
48
  var NOTICE_ID_UPLOAD_PROGRESS = "media-modal-upload-progress";
49
+ var defaultQueryParams = {
50
+ page: 1,
51
+ search: ""
52
+ };
49
53
  var defaultView = {
50
54
  type: LAYOUT_PICKER_GRID,
51
55
  fields: [],
52
56
  showTitle: false,
53
57
  titleField: "title",
54
58
  mediaField: "media_thumbnail",
55
- search: "",
56
- page: 1,
57
59
  perPage: 50,
58
60
  filters: [],
59
61
  layout: {
@@ -103,12 +105,27 @@ function MediaUploadModal({
103
105
  });
104
106
  const { createSuccessNotice, removeAllNotices } = useDispatch(noticesStore);
105
107
  const invalidateAttachmentResolutions = useInvalidateAttachmentResolutions();
108
+ const [queryParams, setQueryParams] = useState(
109
+ () => defaultQueryParams
110
+ );
106
111
  const { view, updateView, isModified, resetToDefault } = useView({
107
112
  kind: "postType",
108
113
  name: "attachment",
109
114
  slug: "media-modal",
110
- defaultView
115
+ defaultView,
116
+ queryParams,
117
+ onChangeQueryParams: setQueryParams
111
118
  });
119
+ const handleChangeView = useCallback(
120
+ (nextView) => {
121
+ const normalizedView = { ...nextView };
122
+ if (normalizedView.startPosition === void 0) {
123
+ delete normalizedView.startPosition;
124
+ }
125
+ updateView(normalizedView);
126
+ },
127
+ [updateView]
128
+ );
112
129
  const queryArgs = useMemo(() => {
113
130
  const filters = {};
114
131
  view.filters?.forEach((filter) => {
@@ -273,6 +290,11 @@ function MediaUploadModal({
273
290
  removeAllNotices("snackbar", NOTICES_CONTEXT);
274
291
  onClose?.();
275
292
  }, [removeAllNotices, onClose]);
293
+ useEffect(() => {
294
+ if (!isOpen) {
295
+ setQueryParams(defaultQueryParams);
296
+ }
297
+ }, [isOpen]);
276
298
  const handleUpload = onUpload || uploadMedia;
277
299
  const prevAllCompleteRef = useRef(false);
278
300
  useEffect(() => {
@@ -397,7 +419,7 @@ function MediaUploadModal({
397
419
  data: mediaRecords || [],
398
420
  fields,
399
421
  view,
400
- onChangeView: updateView,
422
+ onChangeView: handleChangeView,
401
423
  actions,
402
424
  selection,
403
425
  onChangeSelection: setSelection,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/media-upload-modal/index.tsx"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tcreatePortal,\n\tuseState,\n\tuseCallback,\n\tuseMemo,\n\tuseRef,\n\tuseEffect,\n} from '@wordpress/element';\nimport { __, sprintf, _n } from '@wordpress/i18n';\nimport {\n\tprivateApis as coreDataPrivateApis,\n\tstore as coreStore,\n} from '@wordpress/core-data';\nimport { resolveSelect, useDispatch } from '@wordpress/data';\nimport { Modal, DropZone, FormFileUpload, Button } from '@wordpress/components';\nimport { upload as uploadIcon } from '@wordpress/icons';\nimport { DataViewsPicker } from '@wordpress/dataviews';\nimport type {\n\tField,\n\tActionButton,\n\tSupportedLayouts,\n\tView,\n} from '@wordpress/dataviews';\nimport { useView } from '@wordpress/views';\nimport { Stack } from '@wordpress/ui';\nimport {\n\taltTextField,\n\tattachedToField,\n\tauthorField,\n\tcaptionField,\n\tdateAddedField,\n\tdateModifiedField,\n\tdescriptionField,\n\tfilenameField,\n\tfilesizeField,\n\tmediaDimensionsField,\n\tmediaThumbnailField,\n\tmimeTypeField,\n} from '@wordpress/media-fields';\nimport { store as noticesStore, SnackbarNotices } from '@wordpress/notices';\n\n/**\n * Internal dependencies\n */\nimport type { Attachment, RestAttachment } from '../../utils/types';\nimport { transformAttachment } from '../../utils/transform-attachment';\nimport { uploadMedia } from '../../utils/upload-media';\nimport { unlock } from '../../lock-unlock';\nimport { UploadStatusPopover } from './upload-status-popover';\nimport { useInvalidateAttachmentResolutions } from './use-invalidate-attachment-resolutions';\nimport { useUploadStatus } from './use-upload-status';\n\nconst { useEntityRecordsWithPermissions } = unlock( coreDataPrivateApis );\n\n// Layout constants - matching the picker layout types\nconst LAYOUT_PICKER_GRID = 'pickerGrid';\nconst LAYOUT_PICKER_TABLE = 'pickerTable';\n\n// Custom notices context for the media modal\nconst NOTICES_CONTEXT = 'media-modal';\n\n// Notice ID - reused for all upload-related notices to prevent flooding\nconst NOTICE_ID_UPLOAD_PROGRESS = 'media-modal-upload-progress';\n\nconst defaultView: View = {\n\ttype: LAYOUT_PICKER_GRID,\n\tfields: [],\n\tshowTitle: false,\n\ttitleField: 'title',\n\tmediaField: 'media_thumbnail',\n\tsearch: '',\n\tpage: 1,\n\tperPage: 50,\n\tfilters: [],\n\tlayout: {\n\t\tpreviewSize: 170,\n\t\tdensity: 'compact',\n\t},\n};\n\nconst defaultLayouts: SupportedLayouts = {\n\t[ LAYOUT_PICKER_GRID ]: {\n\t\tfields: [],\n\t\tshowTitle: false,\n\t\tlayout: {\n\t\t\tpreviewSize: 170,\n\t\t\tdensity: 'compact',\n\t\t},\n\t},\n\t[ LAYOUT_PICKER_TABLE ]: {\n\t\tfields: [\n\t\t\t'filename',\n\t\t\t'filesize',\n\t\t\t'media_dimensions',\n\t\t\t'author',\n\t\t\t'date',\n\t\t],\n\t\tshowTitle: true,\n\t},\n};\n\ninterface MediaUploadModalProps {\n\t/**\n\t * Array of allowed media types.\n\t */\n\tallowedTypes?: string[];\n\n\t/**\n\t * Whether multiple files can be selected.\n\t * @default false\n\t */\n\tmultiple?: boolean;\n\n\t/**\n\t * The currently selected media item(s).\n\t * Can be a single ID number or array of IDs for multiple selection.\n\t */\n\tvalue?: number | number[];\n\n\t/**\n\t * Function called when media is selected.\n\t * Receives single attachment object or array of attachments.\n\t */\n\tonSelect: ( media: Attachment | Attachment[] ) => void;\n\n\t/**\n\t * Function called when the modal is closed without selection.\n\t */\n\tonClose?: () => void;\n\n\t/**\n\t * Function to handle media uploads.\n\t * If not provided, drag and drop will be disabled.\n\t */\n\tonUpload?: ( args: {\n\t\tallowedTypes?: string[];\n\t\tfilesList: File[];\n\t\tonFileChange?: ( attachments: Partial< Attachment >[] ) => void;\n\t\tonError?: ( error: Error ) => void;\n\t\tmultiple?: boolean;\n\t} ) => void;\n\n\t/**\n\t * Title for the modal.\n\t * @default 'Select Media'\n\t */\n\ttitle?: string;\n\n\t/**\n\t * Whether the modal is open.\n\t */\n\tisOpen: boolean;\n\n\t/**\n\t * Whether the modal can be closed by clicking outside or pressing escape.\n\t * @default true\n\t */\n\tisDismissible?: boolean;\n\n\t/**\n\t * Additional CSS class for the modal.\n\t */\n\tmodalClass?: string;\n\n\t/**\n\t * Whether to show a search input.\n\t * @default true\n\t */\n\tsearch?: boolean;\n\n\t/**\n\t * Label for the search input.\n\t */\n\tsearchLabel?: string;\n}\n\n/**\n * MediaUploadModal component that uses Modal and DataViewsPicker for media selection.\n *\n * This is a modern functional component alternative to the legacy MediaUpload class component.\n * It provides a cleaner API and better integration with the WordPress block editor.\n *\n * @param props Component props\n * @param props.allowedTypes Array of allowed media types\n * @param props.multiple Whether multiple files can be selected\n * @param props.value Currently selected media item(s)\n * @param props.onSelect Function called when media is selected\n * @param props.onClose Function called when modal is closed\n * @param props.onUpload Function to handle media uploads\n * @param props.title Title for the modal\n * @param props.isOpen Whether the modal is open\n * @param props.isDismissible Whether modal can be dismissed\n * @param props.modalClass Additional CSS class for modal\n * @param props.search Whether to show search input\n * @param props.searchLabel Label for search input\n * @return JSX element or null\n */\nexport function MediaUploadModal( {\n\tallowedTypes,\n\tmultiple = false,\n\tvalue,\n\tonSelect,\n\tonClose,\n\tonUpload,\n\ttitle = __( 'Select Media' ),\n\tisOpen,\n\tisDismissible = true,\n\tmodalClass,\n\tsearch = true,\n\tsearchLabel = __( 'Search media' ),\n}: MediaUploadModalProps ) {\n\tconst [ selection, setSelection ] = useState< string[] >( () => {\n\t\tif ( ! value ) {\n\t\t\treturn [];\n\t\t}\n\t\treturn Array.isArray( value )\n\t\t\t? value.map( String )\n\t\t\t: [ String( value ) ];\n\t} );\n\n\tconst { createSuccessNotice, removeAllNotices } =\n\t\tuseDispatch( noticesStore );\n\tconst invalidateAttachmentResolutions =\n\t\tuseInvalidateAttachmentResolutions();\n\n\t// Persist view configuration across sessions via the preferences store.\n\tconst { view, updateView, isModified, resetToDefault } = useView( {\n\t\tkind: 'postType',\n\t\tname: 'attachment',\n\t\tslug: 'media-modal',\n\t\tdefaultView,\n\t} );\n\n\t// Build query args based on view properties, similar to PostList\n\tconst queryArgs = useMemo( () => {\n\t\tconst filters: Record< string, any > = {};\n\n\t\tview.filters?.forEach( ( filter ) => {\n\t\t\t// Handle media type filters\n\t\t\tif ( filter.field === 'media_type' ) {\n\t\t\t\tfilters.media_type = filter.value;\n\t\t\t}\n\t\t\t// Handle author filters\n\t\t\tif ( filter.field === 'author' ) {\n\t\t\t\tif ( filter.operator === 'isAny' ) {\n\t\t\t\t\tfilters.author = filter.value;\n\t\t\t\t} else if ( filter.operator === 'isNone' ) {\n\t\t\t\t\tfilters.author_exclude = filter.value;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Handle date filters\n\t\t\tif ( filter.field === 'date' || filter.field === 'modified' ) {\n\t\t\t\tif ( filter.operator === 'before' ) {\n\t\t\t\t\tfilters.before = filter.value;\n\t\t\t\t} else if ( filter.operator === 'after' ) {\n\t\t\t\t\tfilters.after = filter.value;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Handle mime type filters\n\t\t\tif ( filter.field === 'mime_type' ) {\n\t\t\t\tfilters.mime_type = filter.value;\n\t\t\t}\n\t\t} );\n\n\t\t// Base media and mime type on allowedTypes if no filter is set\n\t\tif (\n\t\t\t! filters.media_type &&\n\t\t\t! filters.mime_type &&\n\t\t\tallowedTypes &&\n\t\t\t! allowedTypes.includes( '*' )\n\t\t) {\n\t\t\tconst { mediaTypes, mimeTypes } = allowedTypes.reduce(\n\t\t\t\t( acc, type ) => {\n\t\t\t\t\tif ( type.endsWith( '/*' ) ) {\n\t\t\t\t\t\tacc.mediaTypes.push( type.replace( '/*', '' ) );\n\t\t\t\t\t} else if ( type.includes( '/' ) ) {\n\t\t\t\t\t\tacc.mimeTypes.push( type );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tacc.mediaTypes.push( type );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn acc;\n\t\t\t\t},\n\t\t\t\t{ mediaTypes: [] as string[], mimeTypes: [] as string[] }\n\t\t\t);\n\n\t\t\tif ( mediaTypes.length ) {\n\t\t\t\tfilters.media_type = mediaTypes;\n\t\t\t}\n\t\t\tif ( mimeTypes.length ) {\n\t\t\t\tfilters.mime_type = mimeTypes;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tper_page: view.perPage || 20,\n\t\t\tpage: view.page || 1,\n\t\t\tstatus: 'inherit',\n\t\t\torder: view.sort?.direction,\n\t\t\torderby: view.sort?.field,\n\t\t\tsearch: view.search,\n\t\t\t_embed: 'author,wp:attached-to',\n\t\t\t...filters,\n\t\t};\n\t}, [ view, allowedTypes ] );\n\n\t// Per-batch completion handler: auto-select uploaded items and refresh the grid.\n\tconst handleBatchComplete = useCallback(\n\t\t( attachments: Partial< Attachment >[] ) => {\n\t\t\tconst uploadedIds = attachments\n\t\t\t\t.map( ( attachment ) => String( attachment.id ) )\n\t\t\t\t.filter( Boolean );\n\n\t\t\tif ( multiple ) {\n\t\t\t\tsetSelection( ( prev ) => {\n\t\t\t\t\tconst existing = new Set( prev );\n\t\t\t\t\tconst newIds = uploadedIds.filter(\n\t\t\t\t\t\t( id ) => ! existing.has( id )\n\t\t\t\t\t);\n\t\t\t\t\treturn [ ...prev, ...newIds ];\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tsetSelection( uploadedIds.slice( 0, 1 ) );\n\t\t\t}\n\n\t\t\t// Invalidate all cached attachment queries so every page of\n\t\t\t// results refreshes \u2014 not just the page the user is viewing.\n\t\t\tinvalidateAttachmentResolutions();\n\t\t},\n\t\t[ multiple, invalidateAttachmentResolutions ]\n\t);\n\n\tconst {\n\t\tuploadingFiles,\n\t\tregisterBatch,\n\t\tdismissError,\n\t\tclearCompleted,\n\t\tallComplete,\n\t} = useUploadStatus( { onBatchComplete: handleBatchComplete } );\n\n\tconst isPopoverOpenRef = useRef( false );\n\tconst handlePopoverOpenChange = useCallback(\n\t\t( open: boolean ) => {\n\t\t\tisPopoverOpenRef.current = open;\n\t\t\tif ( ! open ) {\n\t\t\t\tclearCompleted();\n\t\t\t}\n\t\t},\n\t\t[ clearCompleted ]\n\t);\n\n\t// Fetch all media attachments using WordPress core data with permissions\n\tconst {\n\t\trecords: mediaRecords,\n\t\tisResolving: isLoading,\n\t\ttotalItems,\n\t\ttotalPages,\n\t} = useEntityRecordsWithPermissions( 'postType', 'attachment', queryArgs );\n\n\tconst fields: Field< RestAttachment >[] = useMemo(\n\t\t() => [\n\t\t\t// Media field definitions from @wordpress/media-fields\n\t\t\t// Cast is safe because RestAttachment has the same properties as Attachment\n\t\t\t{\n\t\t\t\t...( mediaThumbnailField as Field< RestAttachment > ),\n\t\t\t\tenableHiding: false, // Within the modal, the thumbnail should always be shown.\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'title',\n\t\t\t\ttype: 'text' as const,\n\t\t\t\tlabel: __( 'Title' ),\n\t\t\t\tgetValue: ( { item }: { item: RestAttachment } ) => {\n\t\t\t\t\tconst titleValue = item.title.raw || item.title.rendered;\n\t\t\t\t\treturn titleValue || __( '(no title)' );\n\t\t\t\t},\n\t\t\t},\n\t\t\taltTextField as Field< RestAttachment >,\n\t\t\tcaptionField as Field< RestAttachment >,\n\t\t\tdescriptionField as Field< RestAttachment >,\n\t\t\tdateAddedField as Field< RestAttachment >,\n\t\t\tdateModifiedField as Field< RestAttachment >,\n\t\t\tauthorField as Field< RestAttachment >,\n\t\t\tfilenameField as Field< RestAttachment >,\n\t\t\tfilesizeField as Field< RestAttachment >,\n\t\t\tmediaDimensionsField as Field< RestAttachment >,\n\t\t\tmimeTypeField as Field< RestAttachment >,\n\t\t\tattachedToField as Field< RestAttachment >,\n\t\t],\n\t\t[]\n\t);\n\n\tconst actions: ActionButton< RestAttachment >[] = useMemo(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: 'select',\n\t\t\t\tlabel: __( 'Select' ),\n\t\t\t\tisPrimary: true,\n\t\t\t\tsupportsBulk: multiple,\n\t\t\t\tasync callback() {\n\t\t\t\t\tif ( selection.length === 0 ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst selectedPostsQuery = {\n\t\t\t\t\t\tinclude: selection,\n\t\t\t\t\t\tper_page: -1,\n\t\t\t\t\t};\n\n\t\t\t\t\tconst selectedPosts = await resolveSelect(\n\t\t\t\t\t\tcoreStore\n\t\t\t\t\t).getEntityRecords< RestAttachment >(\n\t\t\t\t\t\t'postType',\n\t\t\t\t\t\t'attachment',\n\t\t\t\t\t\tselectedPostsQuery\n\t\t\t\t\t);\n\n\t\t\t\t\t// Transform the selected posts to the expected Attachment format\n\t\t\t\t\tconst transformedPosts = ( selectedPosts ?? [] )\n\t\t\t\t\t\t.map( transformAttachment )\n\t\t\t\t\t\t.filter( Boolean );\n\n\t\t\t\t\tconst selectedItems = multiple\n\t\t\t\t\t\t? transformedPosts\n\t\t\t\t\t\t: transformedPosts?.[ 0 ];\n\n\t\t\t\t\tremoveAllNotices( 'snackbar', NOTICES_CONTEXT );\n\t\t\t\t\tonSelect( selectedItems );\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\t[ multiple, onSelect, selection, removeAllNotices ]\n\t);\n\n\tconst handleModalClose = useCallback( () => {\n\t\tremoveAllNotices( 'snackbar', NOTICES_CONTEXT );\n\t\tonClose?.();\n\t}, [ removeAllNotices, onClose ] );\n\n\t// Use onUpload if provided, otherwise fall back to uploadMedia\n\tconst handleUpload = onUpload || uploadMedia;\n\n\t// Show success notice and auto-clear completed entries when all batches finish.\n\tconst prevAllCompleteRef = useRef( false );\n\tuseEffect( () => {\n\t\tif ( allComplete && ! prevAllCompleteRef.current ) {\n\t\t\tconst completeCount = uploadingFiles.filter(\n\t\t\t\t( file ) => file.status === 'uploaded'\n\t\t\t).length;\n\t\t\tif ( completeCount > 0 ) {\n\t\t\t\tcreateSuccessNotice(\n\t\t\t\t\tsprintf(\n\t\t\t\t\t\t// translators: %s: number of files\n\t\t\t\t\t\t_n(\n\t\t\t\t\t\t\t'Uploaded %s file',\n\t\t\t\t\t\t\t'Uploaded %s files',\n\t\t\t\t\t\t\tcompleteCount\n\t\t\t\t\t\t),\n\t\t\t\t\t\tcompleteCount.toLocaleString()\n\t\t\t\t\t),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'snackbar',\n\t\t\t\t\t\tcontext: NOTICES_CONTEXT,\n\t\t\t\t\t\tid: NOTICE_ID_UPLOAD_PROGRESS,\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Auto-clear completed entries, unless the popover is\n\t\t\t// open \u2014 in that case, they'll be cleared on close.\n\t\t\tif ( ! isPopoverOpenRef.current ) {\n\t\t\t\tclearCompleted();\n\t\t\t}\n\t\t}\n\t\tprevAllCompleteRef.current = allComplete;\n\t}, [ allComplete, uploadingFiles, createSuccessNotice, clearCompleted ] );\n\n\tconst handleFileSelect = useCallback(\n\t\t( event: React.ChangeEvent< HTMLInputElement > ) => {\n\t\t\tconst files = event.target.files;\n\t\t\tif ( files && files.length > 0 ) {\n\t\t\t\tconst filesArray = Array.from( files );\n\t\t\t\tconst { onFileChange, onError } = registerBatch( filesArray );\n\n\t\t\t\thandleUpload( {\n\t\t\t\t\tallowedTypes,\n\t\t\t\t\tfilesList: filesArray,\n\t\t\t\t\tonFileChange,\n\t\t\t\t\tonError,\n\t\t\t\t} );\n\t\t\t}\n\t\t},\n\t\t[ allowedTypes, handleUpload, registerBatch ]\n\t);\n\n\tconst paginationInfo = useMemo(\n\t\t() => ( {\n\t\t\ttotalItems,\n\t\t\ttotalPages,\n\t\t} ),\n\t\t[ totalItems, totalPages ]\n\t);\n\n\t// Build accept attribute from allowedTypes\n\tconst acceptTypes = useMemo( () => {\n\t\tif ( allowedTypes?.includes( '*' ) ) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn allowedTypes?.join( ',' );\n\t}, [ allowedTypes ] );\n\n\tif ( ! isOpen ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<Modal\n\t\t\ttitle={ title }\n\t\t\tonRequestClose={ handleModalClose }\n\t\t\tisDismissible={ isDismissible }\n\t\t\tclassName={ modalClass }\n\t\t\toverlayClassName=\"media-upload-modal\"\n\t\t\tsize=\"fill\"\n\t\t\theaderActions={\n\t\t\t\t<FormFileUpload\n\t\t\t\t\taccept={ acceptTypes }\n\t\t\t\t\tmultiple\n\t\t\t\t\tonChange={ handleFileSelect }\n\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\trender={ ( { openFileDialog } ) => (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tonClick={ openFileDialog }\n\t\t\t\t\t\t\ticon={ uploadIcon }\n\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ __( 'Upload media' ) }\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t) }\n\t\t\t\t/>\n\t\t\t}\n\t\t>\n\t\t\t<DropZone\n\t\t\t\tonFilesDrop={ ( files ) => {\n\t\t\t\t\tlet filteredFiles = files;\n\t\t\t\t\t// Filter files by allowed types if specified\n\t\t\t\t\tif ( allowedTypes && ! allowedTypes.includes( '*' ) ) {\n\t\t\t\t\t\tfilteredFiles = files.filter( ( file ) =>\n\t\t\t\t\t\t\tallowedTypes.some( ( allowedType ) => {\n\t\t\t\t\t\t\t\t// Check if the file type matches the allowed MIME type\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\tfile.type === allowedType ||\n\t\t\t\t\t\t\t\t\tfile.type.startsWith(\n\t\t\t\t\t\t\t\t\t\tallowedType.replace( '*', '' )\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif ( filteredFiles.length > 0 ) {\n\t\t\t\t\t\tconst { onFileChange, onError } =\n\t\t\t\t\t\t\tregisterBatch( filteredFiles );\n\n\t\t\t\t\t\thandleUpload( {\n\t\t\t\t\t\t\tallowedTypes,\n\t\t\t\t\t\t\tfilesList: filteredFiles,\n\t\t\t\t\t\t\tonFileChange,\n\t\t\t\t\t\t\tonError,\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t} }\n\t\t\t\tlabel={ __( 'Drop files to upload' ) }\n\t\t\t/>\n\t\t\t<DataViewsPicker\n\t\t\t\tdata={ mediaRecords || [] }\n\t\t\t\tfields={ fields }\n\t\t\t\tview={ view }\n\t\t\t\tonChangeView={ updateView }\n\t\t\t\tactions={ actions }\n\t\t\t\tselection={ selection }\n\t\t\t\tonChangeSelection={ setSelection }\n\t\t\t\tisLoading={ isLoading }\n\t\t\t\tpaginationInfo={ paginationInfo }\n\t\t\t\tdefaultLayouts={ defaultLayouts }\n\t\t\t\tgetItemId={ ( item: RestAttachment ) => String( item.id ) }\n\t\t\t\titemListLabel={ __( 'Media items' ) }\n\t\t\t\tonReset={ isModified ? resetToDefault : false }\n\t\t\t>\n\t\t\t\t<Stack\n\t\t\t\t\tdirection=\"row\"\n\t\t\t\t\talign=\"top\"\n\t\t\t\t\tjustify=\"space-between\"\n\t\t\t\t\tclassName=\"dataviews__view-actions\"\n\t\t\t\t\tgap=\"xs\"\n\t\t\t\t>\n\t\t\t\t\t<Stack\n\t\t\t\t\t\tdirection=\"row\"\n\t\t\t\t\t\tgap=\"sm\"\n\t\t\t\t\t\tjustify=\"start\"\n\t\t\t\t\t\tclassName=\"dataviews__search\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{ search && (\n\t\t\t\t\t\t\t<DataViewsPicker.Search label={ searchLabel } />\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t<DataViewsPicker.FiltersToggle />\n\t\t\t\t\t</Stack>\n\t\t\t\t\t<Stack direction=\"row\" gap=\"xs\" style={ { flexShrink: 0 } }>\n\t\t\t\t\t\t<DataViewsPicker.LayoutSwitcher />\n\t\t\t\t\t\t<DataViewsPicker.ViewConfig />\n\t\t\t\t\t</Stack>\n\t\t\t\t</Stack>\n\t\t\t\t<DataViewsPicker.FiltersToggled className=\"dataviews-filters__container\" />\n\t\t\t\t<DataViewsPicker.Layout />\n\t\t\t\t<div\n\t\t\t\t\tclassName={ clsx( 'media-upload-modal__footer', {\n\t\t\t\t\t\t'is-uploading': uploadingFiles.length > 0,\n\t\t\t\t\t} ) }\n\t\t\t\t>\n\t\t\t\t\t<UploadStatusPopover\n\t\t\t\t\t\tuploadingFiles={ uploadingFiles }\n\t\t\t\t\t\tonDismissError={ dismissError }\n\t\t\t\t\t\tonOpenChange={ handlePopoverOpenChange }\n\t\t\t\t\t/>\n\t\t\t\t\t<DataViewsPicker.BulkActionToolbar />\n\t\t\t\t</div>\n\t\t\t</DataViewsPicker>\n\t\t\t{ createPortal(\n\t\t\t\t<SnackbarNotices\n\t\t\t\t\tclassName=\"media-upload-modal__snackbar\"\n\t\t\t\t\tcontext={ NOTICES_CONTEXT }\n\t\t\t\t/>,\n\t\t\t\tdocument.body\n\t\t\t) }\n\t\t</Modal>\n\t);\n}\n\nexport default MediaUploadModal;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tcreatePortal,\n\tuseState,\n\tuseCallback,\n\tuseMemo,\n\tuseRef,\n\tuseEffect,\n} from '@wordpress/element';\nimport { __, sprintf, _n } from '@wordpress/i18n';\nimport {\n\tprivateApis as coreDataPrivateApis,\n\tstore as coreStore,\n} from '@wordpress/core-data';\nimport { resolveSelect, useDispatch } from '@wordpress/data';\nimport { Modal, DropZone, FormFileUpload, Button } from '@wordpress/components';\nimport { upload as uploadIcon } from '@wordpress/icons';\nimport { DataViewsPicker } from '@wordpress/dataviews';\nimport type {\n\tField,\n\tActionButton,\n\tSupportedLayouts,\n\tView,\n} from '@wordpress/dataviews';\nimport { useView } from '@wordpress/views';\nimport { Stack } from '@wordpress/ui';\nimport {\n\taltTextField,\n\tattachedToField,\n\tauthorField,\n\tcaptionField,\n\tdateAddedField,\n\tdateModifiedField,\n\tdescriptionField,\n\tfilenameField,\n\tfilesizeField,\n\tmediaDimensionsField,\n\tmediaThumbnailField,\n\tmimeTypeField,\n} from '@wordpress/media-fields';\nimport { store as noticesStore, SnackbarNotices } from '@wordpress/notices';\n\n/**\n * Internal dependencies\n */\nimport type { Attachment, RestAttachment } from '../../utils/types';\nimport { transformAttachment } from '../../utils/transform-attachment';\nimport { uploadMedia } from '../../utils/upload-media';\nimport { unlock } from '../../lock-unlock';\nimport { UploadStatusPopover } from './upload-status-popover';\nimport { useInvalidateAttachmentResolutions } from './use-invalidate-attachment-resolutions';\nimport { useUploadStatus } from './use-upload-status';\n\nconst { useEntityRecordsWithPermissions } = unlock( coreDataPrivateApis );\n\n// Layout constants - matching the picker layout types\nconst LAYOUT_PICKER_GRID = 'pickerGrid';\nconst LAYOUT_PICKER_TABLE = 'pickerTable';\n\n// Custom notices context for the media modal\nconst NOTICES_CONTEXT = 'media-modal';\n\n// Notice ID - reused for all upload-related notices to prevent flooding\nconst NOTICE_ID_UPLOAD_PROGRESS = 'media-modal-upload-progress';\n\ntype ViewQueryParams = Pick< View, 'page' | 'search' >;\n\nconst defaultQueryParams: ViewQueryParams = {\n\tpage: 1,\n\tsearch: '',\n};\n\nconst defaultView: View = {\n\ttype: LAYOUT_PICKER_GRID,\n\tfields: [],\n\tshowTitle: false,\n\ttitleField: 'title',\n\tmediaField: 'media_thumbnail',\n\tperPage: 50,\n\tfilters: [],\n\tlayout: {\n\t\tpreviewSize: 170,\n\t\tdensity: 'compact',\n\t},\n};\n\nconst defaultLayouts: SupportedLayouts = {\n\t[ LAYOUT_PICKER_GRID ]: {\n\t\tfields: [],\n\t\tshowTitle: false,\n\t\tlayout: {\n\t\t\tpreviewSize: 170,\n\t\t\tdensity: 'compact',\n\t\t},\n\t},\n\t[ LAYOUT_PICKER_TABLE ]: {\n\t\tfields: [\n\t\t\t'filename',\n\t\t\t'filesize',\n\t\t\t'media_dimensions',\n\t\t\t'author',\n\t\t\t'date',\n\t\t],\n\t\tshowTitle: true,\n\t},\n};\n\ninterface MediaUploadModalProps {\n\t/**\n\t * Array of allowed media types.\n\t */\n\tallowedTypes?: string[];\n\n\t/**\n\t * Whether multiple files can be selected.\n\t * @default false\n\t */\n\tmultiple?: boolean;\n\n\t/**\n\t * The currently selected media item(s).\n\t * Can be a single ID number or array of IDs for multiple selection.\n\t */\n\tvalue?: number | number[];\n\n\t/**\n\t * Function called when media is selected.\n\t * Receives single attachment object or array of attachments.\n\t */\n\tonSelect: ( media: Attachment | Attachment[] ) => void;\n\n\t/**\n\t * Function called when the modal is closed without selection.\n\t */\n\tonClose?: () => void;\n\n\t/**\n\t * Function to handle media uploads.\n\t * If not provided, drag and drop will be disabled.\n\t */\n\tonUpload?: ( args: {\n\t\tallowedTypes?: string[];\n\t\tfilesList: File[];\n\t\tonFileChange?: ( attachments: Partial< Attachment >[] ) => void;\n\t\tonError?: ( error: Error ) => void;\n\t\tmultiple?: boolean;\n\t} ) => void;\n\n\t/**\n\t * Title for the modal.\n\t * @default 'Select Media'\n\t */\n\ttitle?: string;\n\n\t/**\n\t * Whether the modal is open.\n\t */\n\tisOpen: boolean;\n\n\t/**\n\t * Whether the modal can be closed by clicking outside or pressing escape.\n\t * @default true\n\t */\n\tisDismissible?: boolean;\n\n\t/**\n\t * Additional CSS class for the modal.\n\t */\n\tmodalClass?: string;\n\n\t/**\n\t * Whether to show a search input.\n\t * @default true\n\t */\n\tsearch?: boolean;\n\n\t/**\n\t * Label for the search input.\n\t */\n\tsearchLabel?: string;\n}\n\n/**\n * MediaUploadModal component that uses Modal and DataViewsPicker for media selection.\n *\n * This is a modern functional component alternative to the legacy MediaUpload class component.\n * It provides a cleaner API and better integration with the WordPress block editor.\n *\n * @param props Component props\n * @param props.allowedTypes Array of allowed media types\n * @param props.multiple Whether multiple files can be selected\n * @param props.value Currently selected media item(s)\n * @param props.onSelect Function called when media is selected\n * @param props.onClose Function called when modal is closed\n * @param props.onUpload Function to handle media uploads\n * @param props.title Title for the modal\n * @param props.isOpen Whether the modal is open\n * @param props.isDismissible Whether modal can be dismissed\n * @param props.modalClass Additional CSS class for modal\n * @param props.search Whether to show search input\n * @param props.searchLabel Label for search input\n * @return JSX element or null\n */\nexport function MediaUploadModal( {\n\tallowedTypes,\n\tmultiple = false,\n\tvalue,\n\tonSelect,\n\tonClose,\n\tonUpload,\n\ttitle = __( 'Select Media' ),\n\tisOpen,\n\tisDismissible = true,\n\tmodalClass,\n\tsearch = true,\n\tsearchLabel = __( 'Search media' ),\n}: MediaUploadModalProps ) {\n\tconst [ selection, setSelection ] = useState< string[] >( () => {\n\t\tif ( ! value ) {\n\t\t\treturn [];\n\t\t}\n\t\treturn Array.isArray( value )\n\t\t\t? value.map( String )\n\t\t\t: [ String( value ) ];\n\t} );\n\n\tconst { createSuccessNotice, removeAllNotices } =\n\t\tuseDispatch( noticesStore );\n\tconst invalidateAttachmentResolutions =\n\t\tuseInvalidateAttachmentResolutions();\n\tconst [ queryParams, setQueryParams ] = useState< ViewQueryParams >(\n\t\t() => defaultQueryParams\n\t);\n\n\t// Persist view configuration across sessions via the preferences store.\n\tconst { view, updateView, isModified, resetToDefault } = useView( {\n\t\tkind: 'postType',\n\t\tname: 'attachment',\n\t\tslug: 'media-modal',\n\t\tdefaultView,\n\t\tqueryParams,\n\t\tonChangeQueryParams: setQueryParams,\n\t} );\n\n\t// Normalize undefined transient DataViews values so they do not persist as modified modal preferences.\n\tconst handleChangeView = useCallback(\n\t\t( nextView: View ) => {\n\t\t\tconst normalizedView = { ...nextView };\n\t\t\tif ( normalizedView.startPosition === undefined ) {\n\t\t\t\tdelete normalizedView.startPosition;\n\t\t\t}\n\t\t\tupdateView( normalizedView );\n\t\t},\n\t\t[ updateView ]\n\t);\n\n\t// Build query args based on view properties, similar to PostList\n\tconst queryArgs = useMemo( () => {\n\t\tconst filters: Record< string, any > = {};\n\n\t\tview.filters?.forEach( ( filter ) => {\n\t\t\t// Handle media type filters\n\t\t\tif ( filter.field === 'media_type' ) {\n\t\t\t\tfilters.media_type = filter.value;\n\t\t\t}\n\t\t\t// Handle author filters\n\t\t\tif ( filter.field === 'author' ) {\n\t\t\t\tif ( filter.operator === 'isAny' ) {\n\t\t\t\t\tfilters.author = filter.value;\n\t\t\t\t} else if ( filter.operator === 'isNone' ) {\n\t\t\t\t\tfilters.author_exclude = filter.value;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Handle date filters\n\t\t\tif ( filter.field === 'date' || filter.field === 'modified' ) {\n\t\t\t\tif ( filter.operator === 'before' ) {\n\t\t\t\t\tfilters.before = filter.value;\n\t\t\t\t} else if ( filter.operator === 'after' ) {\n\t\t\t\t\tfilters.after = filter.value;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Handle mime type filters\n\t\t\tif ( filter.field === 'mime_type' ) {\n\t\t\t\tfilters.mime_type = filter.value;\n\t\t\t}\n\t\t} );\n\n\t\t// Base media and mime type on allowedTypes if no filter is set\n\t\tif (\n\t\t\t! filters.media_type &&\n\t\t\t! filters.mime_type &&\n\t\t\tallowedTypes &&\n\t\t\t! allowedTypes.includes( '*' )\n\t\t) {\n\t\t\tconst { mediaTypes, mimeTypes } = allowedTypes.reduce(\n\t\t\t\t( acc, type ) => {\n\t\t\t\t\tif ( type.endsWith( '/*' ) ) {\n\t\t\t\t\t\tacc.mediaTypes.push( type.replace( '/*', '' ) );\n\t\t\t\t\t} else if ( type.includes( '/' ) ) {\n\t\t\t\t\t\tacc.mimeTypes.push( type );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tacc.mediaTypes.push( type );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn acc;\n\t\t\t\t},\n\t\t\t\t{ mediaTypes: [] as string[], mimeTypes: [] as string[] }\n\t\t\t);\n\n\t\t\tif ( mediaTypes.length ) {\n\t\t\t\tfilters.media_type = mediaTypes;\n\t\t\t}\n\t\t\tif ( mimeTypes.length ) {\n\t\t\t\tfilters.mime_type = mimeTypes;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tper_page: view.perPage || 20,\n\t\t\tpage: view.page || 1,\n\t\t\tstatus: 'inherit',\n\t\t\torder: view.sort?.direction,\n\t\t\torderby: view.sort?.field,\n\t\t\tsearch: view.search,\n\t\t\t_embed: 'author,wp:attached-to',\n\t\t\t...filters,\n\t\t};\n\t}, [ view, allowedTypes ] );\n\n\t// Per-batch completion handler: auto-select uploaded items and refresh the grid.\n\tconst handleBatchComplete = useCallback(\n\t\t( attachments: Partial< Attachment >[] ) => {\n\t\t\tconst uploadedIds = attachments\n\t\t\t\t.map( ( attachment ) => String( attachment.id ) )\n\t\t\t\t.filter( Boolean );\n\n\t\t\tif ( multiple ) {\n\t\t\t\tsetSelection( ( prev ) => {\n\t\t\t\t\tconst existing = new Set( prev );\n\t\t\t\t\tconst newIds = uploadedIds.filter(\n\t\t\t\t\t\t( id ) => ! existing.has( id )\n\t\t\t\t\t);\n\t\t\t\t\treturn [ ...prev, ...newIds ];\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tsetSelection( uploadedIds.slice( 0, 1 ) );\n\t\t\t}\n\n\t\t\t// Invalidate all cached attachment queries so every page of\n\t\t\t// results refreshes \u2014 not just the page the user is viewing.\n\t\t\tinvalidateAttachmentResolutions();\n\t\t},\n\t\t[ multiple, invalidateAttachmentResolutions ]\n\t);\n\n\tconst {\n\t\tuploadingFiles,\n\t\tregisterBatch,\n\t\tdismissError,\n\t\tclearCompleted,\n\t\tallComplete,\n\t} = useUploadStatus( { onBatchComplete: handleBatchComplete } );\n\n\tconst isPopoverOpenRef = useRef( false );\n\tconst handlePopoverOpenChange = useCallback(\n\t\t( open: boolean ) => {\n\t\t\tisPopoverOpenRef.current = open;\n\t\t\tif ( ! open ) {\n\t\t\t\tclearCompleted();\n\t\t\t}\n\t\t},\n\t\t[ clearCompleted ]\n\t);\n\n\t// Fetch all media attachments using WordPress core data with permissions\n\tconst {\n\t\trecords: mediaRecords,\n\t\tisResolving: isLoading,\n\t\ttotalItems,\n\t\ttotalPages,\n\t} = useEntityRecordsWithPermissions( 'postType', 'attachment', queryArgs );\n\n\tconst fields: Field< RestAttachment >[] = useMemo(\n\t\t() => [\n\t\t\t// Media field definitions from @wordpress/media-fields\n\t\t\t// Cast is safe because RestAttachment has the same properties as Attachment\n\t\t\t{\n\t\t\t\t...( mediaThumbnailField as Field< RestAttachment > ),\n\t\t\t\tenableHiding: false, // Within the modal, the thumbnail should always be shown.\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'title',\n\t\t\t\ttype: 'text' as const,\n\t\t\t\tlabel: __( 'Title' ),\n\t\t\t\tgetValue: ( { item }: { item: RestAttachment } ) => {\n\t\t\t\t\tconst titleValue = item.title.raw || item.title.rendered;\n\t\t\t\t\treturn titleValue || __( '(no title)' );\n\t\t\t\t},\n\t\t\t},\n\t\t\taltTextField as Field< RestAttachment >,\n\t\t\tcaptionField as Field< RestAttachment >,\n\t\t\tdescriptionField as Field< RestAttachment >,\n\t\t\tdateAddedField as Field< RestAttachment >,\n\t\t\tdateModifiedField as Field< RestAttachment >,\n\t\t\tauthorField as Field< RestAttachment >,\n\t\t\tfilenameField as Field< RestAttachment >,\n\t\t\tfilesizeField as Field< RestAttachment >,\n\t\t\tmediaDimensionsField as Field< RestAttachment >,\n\t\t\tmimeTypeField as Field< RestAttachment >,\n\t\t\tattachedToField as Field< RestAttachment >,\n\t\t],\n\t\t[]\n\t);\n\n\tconst actions: ActionButton< RestAttachment >[] = useMemo(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: 'select',\n\t\t\t\tlabel: __( 'Select' ),\n\t\t\t\tisPrimary: true,\n\t\t\t\tsupportsBulk: multiple,\n\t\t\t\tasync callback() {\n\t\t\t\t\tif ( selection.length === 0 ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst selectedPostsQuery = {\n\t\t\t\t\t\tinclude: selection,\n\t\t\t\t\t\tper_page: -1,\n\t\t\t\t\t};\n\n\t\t\t\t\tconst selectedPosts = await resolveSelect(\n\t\t\t\t\t\tcoreStore\n\t\t\t\t\t).getEntityRecords< RestAttachment >(\n\t\t\t\t\t\t'postType',\n\t\t\t\t\t\t'attachment',\n\t\t\t\t\t\tselectedPostsQuery\n\t\t\t\t\t);\n\n\t\t\t\t\t// Transform the selected posts to the expected Attachment format\n\t\t\t\t\tconst transformedPosts = ( selectedPosts ?? [] )\n\t\t\t\t\t\t.map( transformAttachment )\n\t\t\t\t\t\t.filter( Boolean );\n\n\t\t\t\t\tconst selectedItems = multiple\n\t\t\t\t\t\t? transformedPosts\n\t\t\t\t\t\t: transformedPosts?.[ 0 ];\n\n\t\t\t\t\tremoveAllNotices( 'snackbar', NOTICES_CONTEXT );\n\t\t\t\t\tonSelect( selectedItems );\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\t[ multiple, onSelect, selection, removeAllNotices ]\n\t);\n\n\tconst handleModalClose = useCallback( () => {\n\t\tremoveAllNotices( 'snackbar', NOTICES_CONTEXT );\n\t\tonClose?.();\n\t}, [ removeAllNotices, onClose ] );\n\n\tuseEffect( () => {\n\t\tif ( ! isOpen ) {\n\t\t\tsetQueryParams( defaultQueryParams );\n\t\t}\n\t}, [ isOpen ] );\n\n\t// Use onUpload if provided, otherwise fall back to uploadMedia\n\tconst handleUpload = onUpload || uploadMedia;\n\n\t// Show success notice and auto-clear completed entries when all batches finish.\n\tconst prevAllCompleteRef = useRef( false );\n\tuseEffect( () => {\n\t\tif ( allComplete && ! prevAllCompleteRef.current ) {\n\t\t\tconst completeCount = uploadingFiles.filter(\n\t\t\t\t( file ) => file.status === 'uploaded'\n\t\t\t).length;\n\t\t\tif ( completeCount > 0 ) {\n\t\t\t\tcreateSuccessNotice(\n\t\t\t\t\tsprintf(\n\t\t\t\t\t\t// translators: %s: number of files\n\t\t\t\t\t\t_n(\n\t\t\t\t\t\t\t'Uploaded %s file',\n\t\t\t\t\t\t\t'Uploaded %s files',\n\t\t\t\t\t\t\tcompleteCount\n\t\t\t\t\t\t),\n\t\t\t\t\t\tcompleteCount.toLocaleString()\n\t\t\t\t\t),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'snackbar',\n\t\t\t\t\t\tcontext: NOTICES_CONTEXT,\n\t\t\t\t\t\tid: NOTICE_ID_UPLOAD_PROGRESS,\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Auto-clear completed entries, unless the popover is\n\t\t\t// open \u2014 in that case, they'll be cleared on close.\n\t\t\tif ( ! isPopoverOpenRef.current ) {\n\t\t\t\tclearCompleted();\n\t\t\t}\n\t\t}\n\t\tprevAllCompleteRef.current = allComplete;\n\t}, [ allComplete, uploadingFiles, createSuccessNotice, clearCompleted ] );\n\n\tconst handleFileSelect = useCallback(\n\t\t( event: React.ChangeEvent< HTMLInputElement > ) => {\n\t\t\tconst files = event.target.files;\n\t\t\tif ( files && files.length > 0 ) {\n\t\t\t\tconst filesArray = Array.from( files );\n\t\t\t\tconst { onFileChange, onError } = registerBatch( filesArray );\n\n\t\t\t\thandleUpload( {\n\t\t\t\t\tallowedTypes,\n\t\t\t\t\tfilesList: filesArray,\n\t\t\t\t\tonFileChange,\n\t\t\t\t\tonError,\n\t\t\t\t} );\n\t\t\t}\n\t\t},\n\t\t[ allowedTypes, handleUpload, registerBatch ]\n\t);\n\n\tconst paginationInfo = useMemo(\n\t\t() => ( {\n\t\t\ttotalItems,\n\t\t\ttotalPages,\n\t\t} ),\n\t\t[ totalItems, totalPages ]\n\t);\n\n\t// Build accept attribute from allowedTypes\n\tconst acceptTypes = useMemo( () => {\n\t\tif ( allowedTypes?.includes( '*' ) ) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn allowedTypes?.join( ',' );\n\t}, [ allowedTypes ] );\n\n\tif ( ! isOpen ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<Modal\n\t\t\ttitle={ title }\n\t\t\tonRequestClose={ handleModalClose }\n\t\t\tisDismissible={ isDismissible }\n\t\t\tclassName={ modalClass }\n\t\t\toverlayClassName=\"media-upload-modal\"\n\t\t\tsize=\"fill\"\n\t\t\theaderActions={\n\t\t\t\t<FormFileUpload\n\t\t\t\t\taccept={ acceptTypes }\n\t\t\t\t\tmultiple\n\t\t\t\t\tonChange={ handleFileSelect }\n\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\trender={ ( { openFileDialog } ) => (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tonClick={ openFileDialog }\n\t\t\t\t\t\t\ticon={ uploadIcon }\n\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ __( 'Upload media' ) }\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t) }\n\t\t\t\t/>\n\t\t\t}\n\t\t>\n\t\t\t<DropZone\n\t\t\t\tonFilesDrop={ ( files ) => {\n\t\t\t\t\tlet filteredFiles = files;\n\t\t\t\t\t// Filter files by allowed types if specified\n\t\t\t\t\tif ( allowedTypes && ! allowedTypes.includes( '*' ) ) {\n\t\t\t\t\t\tfilteredFiles = files.filter( ( file ) =>\n\t\t\t\t\t\t\tallowedTypes.some( ( allowedType ) => {\n\t\t\t\t\t\t\t\t// Check if the file type matches the allowed MIME type\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\tfile.type === allowedType ||\n\t\t\t\t\t\t\t\t\tfile.type.startsWith(\n\t\t\t\t\t\t\t\t\t\tallowedType.replace( '*', '' )\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif ( filteredFiles.length > 0 ) {\n\t\t\t\t\t\tconst { onFileChange, onError } =\n\t\t\t\t\t\t\tregisterBatch( filteredFiles );\n\n\t\t\t\t\t\thandleUpload( {\n\t\t\t\t\t\t\tallowedTypes,\n\t\t\t\t\t\t\tfilesList: filteredFiles,\n\t\t\t\t\t\t\tonFileChange,\n\t\t\t\t\t\t\tonError,\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t} }\n\t\t\t\tlabel={ __( 'Drop files to upload' ) }\n\t\t\t/>\n\t\t\t<DataViewsPicker\n\t\t\t\tdata={ mediaRecords || [] }\n\t\t\t\tfields={ fields }\n\t\t\t\tview={ view }\n\t\t\t\tonChangeView={ handleChangeView }\n\t\t\t\tactions={ actions }\n\t\t\t\tselection={ selection }\n\t\t\t\tonChangeSelection={ setSelection }\n\t\t\t\tisLoading={ isLoading }\n\t\t\t\tpaginationInfo={ paginationInfo }\n\t\t\t\tdefaultLayouts={ defaultLayouts }\n\t\t\t\tgetItemId={ ( item: RestAttachment ) => String( item.id ) }\n\t\t\t\titemListLabel={ __( 'Media items' ) }\n\t\t\t\tonReset={ isModified ? resetToDefault : false }\n\t\t\t>\n\t\t\t\t<Stack\n\t\t\t\t\tdirection=\"row\"\n\t\t\t\t\talign=\"top\"\n\t\t\t\t\tjustify=\"space-between\"\n\t\t\t\t\tclassName=\"dataviews__view-actions\"\n\t\t\t\t\tgap=\"xs\"\n\t\t\t\t>\n\t\t\t\t\t<Stack\n\t\t\t\t\t\tdirection=\"row\"\n\t\t\t\t\t\tgap=\"sm\"\n\t\t\t\t\t\tjustify=\"start\"\n\t\t\t\t\t\tclassName=\"dataviews__search\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{ search && (\n\t\t\t\t\t\t\t<DataViewsPicker.Search label={ searchLabel } />\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t<DataViewsPicker.FiltersToggle />\n\t\t\t\t\t</Stack>\n\t\t\t\t\t<Stack direction=\"row\" gap=\"xs\" style={ { flexShrink: 0 } }>\n\t\t\t\t\t\t<DataViewsPicker.LayoutSwitcher />\n\t\t\t\t\t\t<DataViewsPicker.ViewConfig />\n\t\t\t\t\t</Stack>\n\t\t\t\t</Stack>\n\t\t\t\t<DataViewsPicker.FiltersToggled className=\"dataviews-filters__container\" />\n\t\t\t\t<DataViewsPicker.Layout />\n\t\t\t\t<div\n\t\t\t\t\tclassName={ clsx( 'media-upload-modal__footer', {\n\t\t\t\t\t\t'is-uploading': uploadingFiles.length > 0,\n\t\t\t\t\t} ) }\n\t\t\t\t>\n\t\t\t\t\t<UploadStatusPopover\n\t\t\t\t\t\tuploadingFiles={ uploadingFiles }\n\t\t\t\t\t\tonDismissError={ dismissError }\n\t\t\t\t\t\tonOpenChange={ handlePopoverOpenChange }\n\t\t\t\t\t/>\n\t\t\t\t\t<DataViewsPicker.BulkActionToolbar />\n\t\t\t\t</div>\n\t\t\t</DataViewsPicker>\n\t\t\t{ createPortal(\n\t\t\t\t<SnackbarNotices\n\t\t\t\t\tclassName=\"media-upload-modal__snackbar\"\n\t\t\t\t\tcontext={ NOTICES_CONTEXT }\n\t\t\t\t/>,\n\t\t\t\tdocument.body\n\t\t\t) }\n\t\t</Modal>\n\t);\n}\n\nexport default MediaUploadModal;\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,11 +1,9 @@
1
- export default MediaUpload;
2
- declare class MediaUpload extends Component<any, any, any> {
3
- constructor(...args: any[]);
4
- openModal(): void;
5
- onOpen(): void;
6
- onSelect(): void;
7
- onUpdate(selections: any): void;
8
- onClose(): void;
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { Component } from '@wordpress/element';
5
+ declare class MediaUpload extends Component {
6
+ constructor();
9
7
  initializeListeners(): void;
10
8
  /**
11
9
  * Sets the Gallery frame and initializes listeners.
@@ -13,9 +11,6 @@ declare class MediaUpload extends Component<any, any, any> {
13
11
  * @return {void}
14
12
  */
15
13
  buildAndSetGalleryFrame(): void;
16
- lastGalleryValue: any;
17
- GalleryDetailsMediaFrame: any;
18
- frame: any;
19
14
  /**
20
15
  * Initializes the Media Library requirements for the featured image flow.
21
16
  *
@@ -29,8 +24,13 @@ declare class MediaUpload extends Component<any, any, any> {
29
24
  */
30
25
  buildAndSetSingleMediaFrame(): void;
31
26
  componentWillUnmount(): void;
27
+ onUpdate(selections: any): void;
28
+ onSelect(): void;
29
+ onOpen(): void;
30
+ onClose(): void;
32
31
  updateCollection(): void;
32
+ openModal(): void;
33
33
  render(): any;
34
34
  }
35
- import { Component } from '@wordpress/element';
35
+ export default MediaUpload;
36
36
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/media-upload/index.js"],"names":[],"mappings":";AAyQA;IACC,4BAOC;IAwOD,kBAsBC;IAzFD,eAqCC;IA5CD,iBAKC;IAzBD,gCAkBC;IAgDD,gBAQC;IAlND,4BAMC;IAED;;;;OAIG;IACH,2BAFY,IAAI,CA+Cf;IA7BA,sBAA6B;IAa5B,8BAA6D;IAO9D,WAMG;IAKJ;;;;OAIG;IACH,gCAFY,IAAI,CA0Bf;IAED;;;;OAIG;IACH,+BAFY,IAAI,CAoCf;IAED,6BAEC;IA8ED,yBAgBC;IA0BD,cAEC;CACD;0BAjhByB,oBAAoB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/media-upload/index.js"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAsQ/C,cAAM,WAAY,SAAQ,SAAS;IAClC,cAOC;IAED,mBAAmB,SAMlB;IAED;;;;OAIG;IACH,uBAAuB,IAFX,IAAI,CA+Cf;IAED;;;;OAIG;IACH,4BAA4B,IAFhB,IAAI,CA0Bf;IAED;;;;OAIG;IACH,2BAA2B,IAFf,IAAI,CAoCf;IAED,oBAAoB,SAEnB;IAED,QAAQ,CAAE,UAAU,KAAA,QAkBnB;IAED,QAAQ,SAKP;IAED,MAAM,SAqCL;IAED,OAAO,SAQN;IAED,gBAAgB,SAgBf;IAED,SAAS,SAsBR;IAED,MAAM,QAEL;CACD;eAEc,WAAW"}
@@ -86,6 +86,6 @@ interface MediaUploadModalProps {
86
86
  * @param props.searchLabel Label for search input
87
87
  * @return JSX element or null
88
88
  */
89
- export declare function MediaUploadModal({ allowedTypes, multiple, value, onSelect, onClose, onUpload, title, isOpen, isDismissible, modalClass, search, searchLabel, }: MediaUploadModalProps): import("react").JSX.Element | null;
89
+ export declare function MediaUploadModal({ allowedTypes, multiple, value, onSelect, onClose, onUpload, title, isOpen, isDismissible, modalClass, search, searchLabel }: MediaUploadModalProps): import("react").JSX.Element | null;
90
90
  export default MediaUploadModal;
91
91
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/media-upload-modal/index.tsx"],"names":[],"mappings":"AAiDA;;GAEG;AACH,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,mBAAmB,CAAC;AAyDpE,UAAU,qBAAqB;IAC9B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE1B;;;OAGG;IACH,QAAQ,EAAE,CAAE,KAAK,EAAE,UAAU,GAAG,UAAU,EAAE,KAAM,IAAI,CAAC;IAEvD;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAE,IAAI,EAAE;QAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,SAAS,EAAE,IAAI,EAAE,CAAC;QAClB,YAAY,CAAC,EAAE,CAAE,WAAW,EAAE,OAAO,CAAE,UAAU,CAAE,EAAE,KAAM,IAAI,CAAC;QAChE,OAAO,CAAC,EAAE,CAAE,KAAK,EAAE,KAAK,KAAM,IAAI,CAAC;QACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;KACnB,KAAM,IAAI,CAAC;IAEZ;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAE,EACjC,YAAY,EACZ,QAAgB,EAChB,KAAK,EACL,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,KAA4B,EAC5B,MAAM,EACN,aAAoB,EACpB,UAAU,EACV,MAAa,EACb,WAAkC,GAClC,EAAE,qBAAqB,sCAuavB;AAED,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/media-upload-modal/index.tsx"],"names":[],"mappings":"AAiDA;;GAEG;AACH,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,mBAAmB,CAAC;AA8DpE,UAAU,qBAAqB;IAC9B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE1B;;;OAGG;IACH,QAAQ,EAAE,CAAE,KAAK,EAAE,UAAU,GAAG,UAAU,EAAE,KAAM,IAAI,CAAC;IAEvD;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAE,IAAI,EAAE;QAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,SAAS,EAAE,IAAI,EAAE,CAAC;QAClB,YAAY,CAAC,EAAE,CAAE,WAAW,EAAE,OAAO,CAAE,UAAU,CAAE,EAAE,KAAM,IAAI,CAAC;QAChE,OAAO,CAAC,EAAE,CAAE,KAAK,EAAE,KAAK,KAAM,IAAI,CAAC;QACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;KACnB,KAAM,IAAI,CAAC;IAEZ;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAE,EACjC,YAAY,EACZ,QAAgB,EAChB,KAAK,EACL,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,KAA4B,EAC5B,MAAM,EACN,aAAoB,EACpB,UAAU,EACV,MAAa,EACb,WAAkC,EAClC,EAAE,qBAAqB,sCA8bvB;eAEc,gBAAgB"}
@@ -10,6 +10,6 @@ interface UploadStatusPopoverProps {
10
10
  onDismissError?: (fileId: string) => void;
11
11
  onOpenChange?: (open: boolean) => void;
12
12
  }
13
- export declare function UploadStatusPopover({ uploadingFiles, onDismissError, onOpenChange, }: UploadStatusPopoverProps): import("react").JSX.Element | null;
13
+ export declare function UploadStatusPopover({ uploadingFiles, onDismissError, onOpenChange }: UploadStatusPopoverProps): import("react").JSX.Element | null;
14
14
  export {};
15
15
  //# sourceMappingURL=upload-status-popover.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"upload-status-popover.d.ts","sourceRoot":"","sources":["../../../src/components/media-upload-modal/upload-status-popover.tsx"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,wBAAwB;IACjC,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,CAAE,MAAM,EAAE,MAAM,KAAM,IAAI,CAAC;IAC5C,YAAY,CAAC,EAAE,CAAE,IAAI,EAAE,OAAO,KAAM,IAAI,CAAC;CACzC;AAED,wBAAgB,mBAAmB,CAAE,EACpC,cAAc,EACd,cAAc,EACd,YAAY,GACZ,EAAE,wBAAwB,sCAgI1B"}
1
+ {"version":3,"file":"upload-status-popover.d.ts","sourceRoot":"","sources":["../../../src/components/media-upload-modal/upload-status-popover.tsx"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,wBAAwB;IACjC,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,CAAE,MAAM,EAAE,MAAM,KAAM,IAAI,CAAC;IAC5C,YAAY,CAAC,EAAE,CAAE,IAAI,EAAE,OAAO,KAAM,IAAI,CAAC;CACzC;AAED,wBAAgB,mBAAmB,CAAE,EACpC,cAAc,EACd,cAAc,EACd,YAAY,EACZ,EAAE,wBAAwB,sCAgI1B"}
@@ -36,6 +36,6 @@ interface UseUploadStatusReturn {
36
36
  /** True when tracked entries exist but none are still uploading. */
37
37
  allComplete: boolean;
38
38
  }
39
- export declare function useUploadStatus({ onBatchComplete, }?: UseUploadStatusOptions): UseUploadStatusReturn;
39
+ export declare function useUploadStatus({ onBatchComplete }?: UseUploadStatusOptions): UseUploadStatusReturn;
40
40
  export {};
41
41
  //# sourceMappingURL=use-upload-status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-upload-status.d.ts","sourceRoot":"","sources":["../../../src/components/media-upload-modal/use-upload-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH;;GAEG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAK7D,UAAU,sBAAsB;IAC/B,eAAe,CAAC,EAAE,CAAE,WAAW,EAAE,OAAO,CAAE,UAAU,CAAE,EAAE,KAAM,IAAI,CAAC;CACnE;AAED,UAAU,mBAAmB;IAC5B,YAAY,EAAE,CAAE,WAAW,EAAE,OAAO,CAAE,UAAU,CAAE,EAAE,KAAM,IAAI,CAAC;IAC/D,OAAO,EAAE,CAAE,KAAK,EAAE,KAAK,KAAM,IAAI,CAAC;CAClC;AAED,UAAU,qBAAqB;IAC9B,yCAAyC;IACzC,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC;;;OAGG;IACH,aAAa,EAAE,CAAE,KAAK,EAAE,IAAI,EAAE,KAAM,mBAAmB,CAAC;IACxD,8CAA8C;IAC9C,YAAY,EAAE,CAAE,MAAM,EAAE,MAAM,KAAM,IAAI,CAAC;IACzC,6DAA6D;IAC7D,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,oEAAoE;IACpE,WAAW,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAE,EAChC,eAAe,GACf,GAAE,sBAA2B,GAAI,qBAAqB,CAmJtD"}
1
+ {"version":3,"file":"use-upload-status.d.ts","sourceRoot":"","sources":["../../../src/components/media-upload-modal/use-upload-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH;;GAEG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAK7D,UAAU,sBAAsB;IAC/B,eAAe,CAAC,EAAE,CAAE,WAAW,EAAE,OAAO,CAAE,UAAU,CAAE,EAAE,KAAM,IAAI,CAAC;CACnE;AAED,UAAU,mBAAmB;IAC5B,YAAY,EAAE,CAAE,WAAW,EAAE,OAAO,CAAE,UAAU,CAAE,EAAE,KAAM,IAAI,CAAC;IAC/D,OAAO,EAAE,CAAE,KAAK,EAAE,KAAK,KAAM,IAAI,CAAC;CAClC;AAED,UAAU,qBAAqB;IAC9B,yCAAyC;IACzC,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC;;;OAGG;IACH,aAAa,EAAE,CAAE,KAAK,EAAE,IAAI,EAAE,KAAM,mBAAmB,CAAC;IACxD,8CAA8C;IAC9C,YAAY,EAAE,CAAE,MAAM,EAAE,MAAM,KAAM,IAAI,CAAC;IACzC,6DAA6D;IAC7D,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,oEAAoE;IACpE,WAAW,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAE,EAChC,eAAe,EACf,GAAE,sBAA2B,GAAI,qBAAqB,CAmJtD"}
@@ -25,6 +25,6 @@ interface SideloadMediaArgs {
25
25
  * @param $0.onSuccess Function called when the sideload completes with sub-size data.
26
26
  * @param $0.onError Function called when an error happens.
27
27
  */
28
- export declare function sideloadMedia({ file, attachmentId, additionalData, signal, onSuccess, onError, }: SideloadMediaArgs): Promise<void>;
28
+ export declare function sideloadMedia({ file, attachmentId, additionalData, signal, onSuccess, onError }: SideloadMediaArgs): Promise<void>;
29
29
  export {};
30
30
  //# sourceMappingURL=sideload-media.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sideload-media.d.ts","sourceRoot":"","sources":["../../src/utils/sideload-media.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,OAAO,KAAK,EACX,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,WAAW,EACX,MAAM,SAAS,CAAC;AAMjB,KAAK,gBAAgB,GAAG,CAAE,OAAO,EAAE,WAAW,KAAM,IAAI,CAAC;AAEzD,UAAU,iBAAiB;IAE1B,cAAc,CAAC,EAAE,kBAAkB,CAAC;IAEpC,IAAI,EAAE,IAAI,CAAC;IAEX,YAAY,EAAE,cAAc,CAAE,IAAI,CAAE,CAAC;IAErC,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAE7B,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CAAE,EACpC,IAAI,EACJ,YAAY,EACZ,cAAmB,EACnB,MAAM,EACN,SAAS,EACT,OAAc,GACd,EAAE,iBAAiB,iBA6BnB"}
1
+ {"version":3,"file":"sideload-media.d.ts","sourceRoot":"","sources":["../../src/utils/sideload-media.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,OAAO,KAAK,EACX,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,WAAW,EACX,MAAM,SAAS,CAAC;AAMjB,KAAK,gBAAgB,GAAG,CAAE,OAAO,EAAE,WAAW,KAAM,IAAI,CAAC;AAEzD,UAAU,iBAAiB;IAE1B,cAAc,CAAC,EAAE,kBAAkB,CAAC;IAEpC,IAAI,EAAE,IAAI,CAAC;IAEX,YAAY,EAAE,cAAc,CAAE,IAAI,CAAE,CAAC;IAErC,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAE7B,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CAAE,EACpC,IAAI,EACJ,YAAY,EACZ,cAAmB,EACnB,MAAM,EACN,SAAS,EACT,OAAc,EACd,EAAE,iBAAiB,iBA6BnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"upload-error.d.ts","sourceRoot":"","sources":["../../src/utils/upload-error.ts"],"names":[],"mappings":"AAAA,UAAU,eAAe;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,CAAC,EAAE,KAAK,CAAC;CACd;AAED;;;;;GAKG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;gBAEE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,eAAe;CAQ5D"}
1
+ {"version":3,"file":"upload-error.d.ts","sourceRoot":"","sources":["../../src/utils/upload-error.ts"],"names":[],"mappings":"AAAA,UAAU,eAAe;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,CAAC,EAAE,KAAK,CAAC;CACd;AAED;;;;;GAKG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;IAEX,YAAa,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,eAAe,EAO3D;CACD"}
@@ -34,6 +34,6 @@ interface UploadMediaArgs {
34
34
  * @param $0.signal Abort signal.
35
35
  * @param $0.multiple Whether to allow multiple files to be uploaded.
36
36
  */
37
- export declare function uploadMedia({ wpAllowedMimeTypes, allowedTypes, additionalData, filesList, maxUploadFileSize, onError, onFileChange, signal, multiple, }: UploadMediaArgs): void;
37
+ export declare function uploadMedia({ wpAllowedMimeTypes, allowedTypes, additionalData, filesList, maxUploadFileSize, onError, onFileChange, signal, multiple }: UploadMediaArgs): void;
38
38
  export {};
39
39
  //# sourceMappingURL=upload-media.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"upload-media.d.ts","sourceRoot":"","sources":["../../src/utils/upload-media.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,OAAO,KAAK,EACX,cAAc,EAEd,eAAe,EACf,cAAc,EACd,MAAM,SAAS,CAAC;AAOjB,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,MAAM;QACf,2BAA2B,CAAC,EAAE,OAAO,CAAC;QACtC,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC9B;CACD;AAED,UAAU,eAAe;IAExB,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB,SAAS,EAAE,IAAI,EAAE,CAAC;IAElB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB,YAAY,CAAC,EAAE,eAAe,CAAC;IAE/B,kBAAkB,CAAC,EAAE,MAAM,CAAE,MAAM,EAAE,MAAM,CAAE,GAAG,IAAI,CAAC;IAErD,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAE,EAC5B,kBAAkB,EAClB,YAAY,EACZ,cAAmB,EACnB,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,YAAY,EACZ,MAAM,EACN,QAAe,GACf,EAAE,eAAe,QAqGjB"}
1
+ {"version":3,"file":"upload-media.d.ts","sourceRoot":"","sources":["../../src/utils/upload-media.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,OAAO,KAAK,EACX,cAAc,EAEd,eAAe,EACf,cAAc,EACd,MAAM,SAAS,CAAC;AAOjB,OAAO,CAAC,MAAM,CAAC,CAAC;IACf,UAAU,MAAM;QACf,2BAA2B,CAAC,EAAE,OAAO,CAAC;QACtC,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC9B;CACD;AAED,UAAU,eAAe;IAExB,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB,SAAS,EAAE,IAAI,EAAE,CAAC;IAElB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB,YAAY,CAAC,EAAE,eAAe,CAAC;IAE/B,kBAAkB,CAAC,EAAE,MAAM,CAAE,MAAM,EAAE,MAAM,CAAE,GAAG,IAAI,CAAC;IAErD,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAE,EAC5B,kBAAkB,EAClB,YAAY,EACZ,cAAmB,EACnB,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,YAAY,EACZ,MAAM,EACN,QAAe,EACf,EAAE,eAAe,QAqGjB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/media-utils",
3
- "version": "5.45.0",
3
+ "version": "5.45.1-next.v.202605131006.0+2a3d07cab",
4
4
  "description": "WordPress Media Upload Utils.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -47,21 +47,21 @@
47
47
  "build-style/**"
48
48
  ],
49
49
  "dependencies": {
50
- "@wordpress/api-fetch": "^7.45.0",
51
- "@wordpress/base-styles": "^7.0.0",
52
- "@wordpress/blob": "^4.45.0",
53
- "@wordpress/components": "^33.0.0",
54
- "@wordpress/core-data": "^7.45.0",
55
- "@wordpress/data": "^10.45.0",
56
- "@wordpress/dataviews": "^14.2.0",
57
- "@wordpress/element": "^6.45.0",
58
- "@wordpress/i18n": "^6.18.0",
59
- "@wordpress/icons": "^13.0.0",
60
- "@wordpress/media-fields": "^0.10.0",
61
- "@wordpress/notices": "^5.45.0",
62
- "@wordpress/private-apis": "^1.45.0",
63
- "@wordpress/ui": "^0.12.0",
64
- "@wordpress/views": "^1.12.0",
50
+ "@wordpress/api-fetch": "^7.45.1-next.v.202605131006.0+2a3d07cab",
51
+ "@wordpress/base-styles": "^8.0.1-next.v.202605131006.0+2a3d07cab",
52
+ "@wordpress/blob": "^4.45.1-next.v.202605131006.0+2a3d07cab",
53
+ "@wordpress/components": "^33.1.1-next.v.202605131006.0+2a3d07cab",
54
+ "@wordpress/core-data": "^7.45.1-next.v.202605131006.0+2a3d07cab",
55
+ "@wordpress/data": "^10.45.1-next.v.202605131006.0+2a3d07cab",
56
+ "@wordpress/dataviews": "^14.2.1-next.v.202605131006.0+2a3d07cab",
57
+ "@wordpress/element": "^6.45.1-next.v.202605131006.0+2a3d07cab",
58
+ "@wordpress/i18n": "^6.18.1-next.v.202605131006.0+2a3d07cab",
59
+ "@wordpress/icons": "^13.0.1-next.v.202605131006.0+2a3d07cab",
60
+ "@wordpress/media-fields": "^0.10.1-next.v.202605131006.0+2a3d07cab",
61
+ "@wordpress/notices": "^5.45.1-next.v.202605131006.0+2a3d07cab",
62
+ "@wordpress/private-apis": "^1.45.1-next.v.202605131006.0+2a3d07cab",
63
+ "@wordpress/ui": "^0.13.1-next.v.202605131006.0+2a3d07cab",
64
+ "@wordpress/views": "^1.12.1-next.v.202605131006.0+2a3d07cab",
65
65
  "clsx": "^2.1.1"
66
66
  },
67
67
  "peerDependencies": {
@@ -70,5 +70,5 @@
70
70
  "publishConfig": {
71
71
  "access": "public"
72
72
  },
73
- "gitHead": "8c229eaed0e88c9827e2da3d73a78f9ddd77714b"
73
+ "gitHead": "8804fa29bc78a1d98e5a4d40c3e180ddd907016c"
74
74
  }
@@ -70,14 +70,19 @@ const NOTICES_CONTEXT = 'media-modal';
70
70
  // Notice ID - reused for all upload-related notices to prevent flooding
71
71
  const NOTICE_ID_UPLOAD_PROGRESS = 'media-modal-upload-progress';
72
72
 
73
+ type ViewQueryParams = Pick< View, 'page' | 'search' >;
74
+
75
+ const defaultQueryParams: ViewQueryParams = {
76
+ page: 1,
77
+ search: '',
78
+ };
79
+
73
80
  const defaultView: View = {
74
81
  type: LAYOUT_PICKER_GRID,
75
82
  fields: [],
76
83
  showTitle: false,
77
84
  titleField: 'title',
78
85
  mediaField: 'media_thumbnail',
79
- search: '',
80
- page: 1,
81
86
  perPage: 50,
82
87
  filters: [],
83
88
  layout: {
@@ -230,6 +235,9 @@ export function MediaUploadModal( {
230
235
  useDispatch( noticesStore );
231
236
  const invalidateAttachmentResolutions =
232
237
  useInvalidateAttachmentResolutions();
238
+ const [ queryParams, setQueryParams ] = useState< ViewQueryParams >(
239
+ () => defaultQueryParams
240
+ );
233
241
 
234
242
  // Persist view configuration across sessions via the preferences store.
235
243
  const { view, updateView, isModified, resetToDefault } = useView( {
@@ -237,8 +245,22 @@ export function MediaUploadModal( {
237
245
  name: 'attachment',
238
246
  slug: 'media-modal',
239
247
  defaultView,
248
+ queryParams,
249
+ onChangeQueryParams: setQueryParams,
240
250
  } );
241
251
 
252
+ // Normalize undefined transient DataViews values so they do not persist as modified modal preferences.
253
+ const handleChangeView = useCallback(
254
+ ( nextView: View ) => {
255
+ const normalizedView = { ...nextView };
256
+ if ( normalizedView.startPosition === undefined ) {
257
+ delete normalizedView.startPosition;
258
+ }
259
+ updateView( normalizedView );
260
+ },
261
+ [ updateView ]
262
+ );
263
+
242
264
  // Build query args based on view properties, similar to PostList
243
265
  const queryArgs = useMemo( () => {
244
266
  const filters: Record< string, any > = {};
@@ -444,6 +466,12 @@ export function MediaUploadModal( {
444
466
  onClose?.();
445
467
  }, [ removeAllNotices, onClose ] );
446
468
 
469
+ useEffect( () => {
470
+ if ( ! isOpen ) {
471
+ setQueryParams( defaultQueryParams );
472
+ }
473
+ }, [ isOpen ] );
474
+
447
475
  // Use onUpload if provided, otherwise fall back to uploadMedia
448
476
  const handleUpload = onUpload || uploadMedia;
449
477
 
@@ -581,7 +609,7 @@ export function MediaUploadModal( {
581
609
  data={ mediaRecords || [] }
582
610
  fields={ fields }
583
611
  view={ view }
584
- onChangeView={ updateView }
612
+ onChangeView={ handleChangeView }
585
613
  actions={ actions }
586
614
  selection={ selection }
587
615
  onChangeSelection={ setSelection }
@@ -0,0 +1,186 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { render, screen, waitFor } from '@testing-library/react';
5
+ import userEvent from '@testing-library/user-event';
6
+
7
+ /**
8
+ * WordPress dependencies
9
+ */
10
+ import { createRegistry, RegistryProvider } from '@wordpress/data';
11
+ import { privateApis as coreDataPrivateApis } from '@wordpress/core-data';
12
+ import { store as noticesStore } from '@wordpress/notices';
13
+ import { store as preferencesStore } from '@wordpress/preferences';
14
+
15
+ /**
16
+ * Internal dependencies
17
+ */
18
+ import { MediaUploadModal } from '../index';
19
+ import { unlock } from '../../../lock-unlock';
20
+
21
+ const preferenceKey = 'dataviews-postType-attachment-media-modal';
22
+
23
+ jest.mock( '@wordpress/core-data', () => {
24
+ const { __dangerousOptInToUnstableAPIsOnlyForCoreModules } =
25
+ jest.requireActual( '@wordpress/private-apis' );
26
+ const { lock } = __dangerousOptInToUnstableAPIsOnlyForCoreModules(
27
+ 'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.',
28
+ '@wordpress/core-data'
29
+ );
30
+ // Keep the private API contract real while replacing only the data hook.
31
+ const privateApis = {};
32
+ lock( privateApis, {
33
+ useEntityRecordsWithPermissions: jest.fn(),
34
+ } );
35
+
36
+ return {
37
+ privateApis,
38
+ store: {
39
+ name: 'core',
40
+ },
41
+ };
42
+ } );
43
+
44
+ const mockUseEntityRecordsWithPermissions = unlock( coreDataPrivateApis )
45
+ .useEntityRecordsWithPermissions as jest.Mock;
46
+
47
+ function renderModal( { isOpen = true } = {} ) {
48
+ const registry = createRegistry();
49
+ registry.register( noticesStore );
50
+ registry.register( preferencesStore );
51
+
52
+ const onSelect = jest.fn();
53
+ const onClose = jest.fn();
54
+
55
+ const view = render(
56
+ <RegistryProvider value={ registry }>
57
+ <MediaUploadModal
58
+ isOpen={ isOpen }
59
+ onSelect={ onSelect }
60
+ onClose={ onClose }
61
+ />
62
+ </RegistryProvider>
63
+ );
64
+
65
+ const rerender = ( props: { isOpen: boolean } ) => {
66
+ view.rerender(
67
+ <RegistryProvider value={ registry }>
68
+ <MediaUploadModal
69
+ { ...props }
70
+ onSelect={ onSelect }
71
+ onClose={ onClose }
72
+ />
73
+ </RegistryProvider>
74
+ );
75
+ };
76
+
77
+ return { ...view, registry, rerender };
78
+ }
79
+
80
+ describe( 'MediaUploadModal', () => {
81
+ beforeEach( () => {
82
+ mockUseEntityRecordsWithPermissions.mockReturnValue( {
83
+ records: [],
84
+ isResolving: false,
85
+ totalItems: 100,
86
+ totalPages: 2,
87
+ } );
88
+ } );
89
+
90
+ afterEach( () => {
91
+ jest.clearAllMocks();
92
+ } );
93
+
94
+ it( 'resets page and search when the modal is closed and reopened', async () => {
95
+ const user = userEvent.setup();
96
+ const { rerender } = renderModal();
97
+
98
+ await user.click( screen.getByRole( 'button', { name: 'Next page' } ) );
99
+
100
+ await waitFor( () => {
101
+ expect(
102
+ mockUseEntityRecordsWithPermissions
103
+ ).toHaveBeenLastCalledWith(
104
+ 'postType',
105
+ 'attachment',
106
+ expect.objectContaining( { page: 2 } )
107
+ );
108
+ } );
109
+
110
+ // Close the modal.
111
+ rerender( { isOpen: false } );
112
+
113
+ // Reopen the modal.
114
+ rerender( { isOpen: true } );
115
+
116
+ await waitFor( () => {
117
+ expect(
118
+ mockUseEntityRecordsWithPermissions
119
+ ).toHaveBeenLastCalledWith(
120
+ 'postType',
121
+ 'attachment',
122
+ expect.objectContaining( { page: 1, search: '' } )
123
+ );
124
+ } );
125
+ } );
126
+
127
+ it( 'updates the media query when the picker changes page', async () => {
128
+ const user = userEvent.setup();
129
+ const { registry } = renderModal();
130
+
131
+ expect( mockUseEntityRecordsWithPermissions ).toHaveBeenLastCalledWith(
132
+ 'postType',
133
+ 'attachment',
134
+ expect.objectContaining( {
135
+ page: 1,
136
+ } )
137
+ );
138
+
139
+ await user.click( screen.getByRole( 'button', { name: 'Next page' } ) );
140
+
141
+ await waitFor( () => {
142
+ expect(
143
+ mockUseEntityRecordsWithPermissions
144
+ ).toHaveBeenLastCalledWith(
145
+ 'postType',
146
+ 'attachment',
147
+ expect.objectContaining( {
148
+ page: 2,
149
+ } )
150
+ );
151
+ } );
152
+ expect(
153
+ registry
154
+ .select( preferencesStore )
155
+ .get( 'core/views', preferenceKey )
156
+ ).toBeUndefined();
157
+ } );
158
+
159
+ it( 'updates the media query when the picker changes search', async () => {
160
+ const user = userEvent.setup();
161
+ const { registry } = renderModal();
162
+
163
+ await user.type(
164
+ screen.getByRole( 'searchbox', { name: 'Search media' } ),
165
+ 'cat'
166
+ );
167
+
168
+ await waitFor( () => {
169
+ expect(
170
+ mockUseEntityRecordsWithPermissions
171
+ ).toHaveBeenLastCalledWith(
172
+ 'postType',
173
+ 'attachment',
174
+ expect.objectContaining( {
175
+ page: 1,
176
+ search: 'cat',
177
+ } )
178
+ );
179
+ } );
180
+ expect(
181
+ registry
182
+ .select( preferencesStore )
183
+ .get( 'core/views', preferenceKey )
184
+ ).toBeUndefined();
185
+ } );
186
+ } );