From 387fcbf05b2152811f7e797c26565161dd2f3f81 Mon Sep 17 00:00:00 2001 From: Vladislav Shkodin Date: Sun, 14 Mar 2021 19:14:01 +0200 Subject: [PATCH] fix: proper type for media library action (#5100) --- .../src/actions/mediaLibrary.ts | 90 ++++++++++++++----- .../src/reducers/mediaLibrary.ts | 21 ++++- packages/netlify-cms-core/src/types/redux.ts | 21 ----- 3 files changed, 85 insertions(+), 47 deletions(-) diff --git a/packages/netlify-cms-core/src/actions/mediaLibrary.ts b/packages/netlify-cms-core/src/actions/mediaLibrary.ts index 76933ea1..9cfefd9b 100644 --- a/packages/netlify-cms-core/src/actions/mediaLibrary.ts +++ b/packages/netlify-cms-core/src/actions/mediaLibrary.ts @@ -53,7 +53,7 @@ export function createMediaLibrary(instance: MediaLibraryInstance) { onRemoveControl: instance.onRemoveControl || (() => undefined), enableStandalone: instance.enableStandalone || (() => undefined), }; - return { type: MEDIA_LIBRARY_CREATE, payload: api }; + return { type: MEDIA_LIBRARY_CREATE, payload: api } as const; } export function clearMediaControl(id: string) { @@ -79,12 +79,12 @@ export function removeMediaControl(id: string) { export function openMediaLibrary( payload: { controlID?: string; - value?: string; - config?: Map; - allowMultiple?: boolean; forImage?: boolean; - mediaFolder?: string; - publicFolder?: string; + privateUpload?: boolean; + value?: string; + allowMultiple?: boolean; + config?: Map; + field?: EntryField; } = {}, ) { return (dispatch: ThunkDispatch, getState: () => State) => { @@ -94,7 +94,7 @@ export function openMediaLibrary( const { controlID: id, value, config = Map(), allowMultiple, forImage } = payload; mediaLibrary.show({ id, value, config: config.toJS(), allowMultiple, imagesOnly: forImage }); } - dispatch({ type: MEDIA_LIBRARY_OPEN, payload }); + dispatch(mediaLibraryOpened(payload)); }; } @@ -105,7 +105,7 @@ export function closeMediaLibrary() { if (mediaLibrary) { mediaLibrary.hide(); } - dispatch({ type: MEDIA_LIBRARY_CLOSE }); + dispatch(mediaLibraryClosed()); }; } @@ -123,12 +123,12 @@ export function insertMedia(mediaPath: string | string[], field: EntryField | un } else { mediaPath = selectMediaFilePublicPath(config, collection, mediaPath as string, entry, field); } - dispatch({ type: MEDIA_INSERT, payload: { mediaPath } }); + dispatch(mediaInserted(mediaPath)); }; } export function removeInsertedMedia(controlID: string) { - return { type: MEDIA_REMOVE_INSERTED, payload: { controlID } }; + return { type: MEDIA_REMOVE_INSERTED, payload: { controlID } } as const; } export function loadMedia( @@ -398,37 +398,62 @@ export function loadMediaDisplayURL(file: MediaFile) { throw new Error('No display URL was returned!'); } } catch (err) { + console.error(err); dispatch(mediaDisplayURLFailure(id, err)); } }; } +function mediaLibraryOpened(payload: { + controlID?: string; + forImage?: boolean; + privateUpload?: boolean; + value?: string; + allowMultiple?: boolean; + config?: Map; + field?: EntryField; +}) { + return { type: MEDIA_LIBRARY_OPEN, payload } as const; +} + +function mediaLibraryClosed() { + return { type: MEDIA_LIBRARY_CLOSE } as const; +} + +function mediaInserted(mediaPath: string | string[]) { + return { type: MEDIA_INSERT, payload: { mediaPath } } as const; +} + export function mediaLoading(page: number) { return { type: MEDIA_LOAD_REQUEST, payload: { page }, - }; + } as const; } interface MediaOptions { privateUpload?: boolean; field?: EntryField; + page?: number; + canPaginate?: boolean; + dynamicSearch?: boolean; + dynamicSearchQuery?: string; } export function mediaLoaded(files: ImplementationMediaFile[], opts: MediaOptions = {}) { return { type: MEDIA_LOAD_SUCCESS, payload: { files, ...opts }, - }; + } as const; } export function mediaLoadFailed(opts: MediaOptions = {}) { const { privateUpload } = opts; - return { type: MEDIA_LOAD_FAILURE, payload: { privateUpload } }; + return { type: MEDIA_LOAD_FAILURE, payload: { privateUpload } } as const; } export function mediaPersisting() { - return { type: MEDIA_PERSIST_REQUEST }; + return { type: MEDIA_PERSIST_REQUEST } as const; } export function mediaPersisted(file: ImplementationMediaFile, opts: MediaOptions = {}) { @@ -436,16 +461,16 @@ export function mediaPersisted(file: ImplementationMediaFile, opts: MediaOptions return { type: MEDIA_PERSIST_SUCCESS, payload: { file, privateUpload }, - }; + } as const; } export function mediaPersistFailed(opts: MediaOptions = {}) { const { privateUpload } = opts; - return { type: MEDIA_PERSIST_FAILURE, payload: { privateUpload } }; + return { type: MEDIA_PERSIST_FAILURE, payload: { privateUpload } } as const; } export function mediaDeleting() { - return { type: MEDIA_DELETE_REQUEST }; + return { type: MEDIA_DELETE_REQUEST } as const; } export function mediaDeleted(file: MediaFile, opts: MediaOptions = {}) { @@ -453,31 +478,30 @@ export function mediaDeleted(file: MediaFile, opts: MediaOptions = {}) { return { type: MEDIA_DELETE_SUCCESS, payload: { file, privateUpload }, - }; + } as const; } export function mediaDeleteFailed(opts: MediaOptions = {}) { const { privateUpload } = opts; - return { type: MEDIA_DELETE_FAILURE, payload: { privateUpload } }; + return { type: MEDIA_DELETE_FAILURE, payload: { privateUpload } } as const; } export function mediaDisplayURLRequest(key: string) { - return { type: MEDIA_DISPLAY_URL_REQUEST, payload: { key } }; + return { type: MEDIA_DISPLAY_URL_REQUEST, payload: { key } } as const; } export function mediaDisplayURLSuccess(key: string, url: string) { return { type: MEDIA_DISPLAY_URL_SUCCESS, payload: { key, url }, - }; + } as const; } export function mediaDisplayURLFailure(key: string, err: Error) { - console.error(err); return { type: MEDIA_DISPLAY_URL_FAILURE, payload: { key, err }, - }; + } as const; } export async function waitForMediaLibraryToLoad( @@ -525,3 +549,23 @@ export async function getMediaDisplayURL( return url; } + +export type MediaLibraryAction = ReturnType< + | typeof createMediaLibrary + | typeof mediaLibraryOpened + | typeof mediaLibraryClosed + | typeof mediaInserted + | typeof removeInsertedMedia + | typeof mediaLoading + | typeof mediaLoaded + | typeof mediaLoadFailed + | typeof mediaPersisting + | typeof mediaPersisted + | typeof mediaPersistFailed + | typeof mediaDeleting + | typeof mediaDeleted + | typeof mediaDeleteFailed + | typeof mediaDisplayURLRequest + | typeof mediaDisplayURLSuccess + | typeof mediaDisplayURLFailure +>; diff --git a/packages/netlify-cms-core/src/reducers/mediaLibrary.ts b/packages/netlify-cms-core/src/reducers/mediaLibrary.ts index b9c089d1..cc4a6fe6 100644 --- a/packages/netlify-cms-core/src/reducers/mediaLibrary.ts +++ b/packages/netlify-cms-core/src/reducers/mediaLibrary.ts @@ -18,12 +18,12 @@ import { MEDIA_DISPLAY_URL_REQUEST, MEDIA_DISPLAY_URL_SUCCESS, MEDIA_DISPLAY_URL_FAILURE, + MediaLibraryAction, } from '../actions/mediaLibrary'; import { selectEditingDraft, selectMediaFolder } from './entries'; import { selectIntegration } from './'; import { State, - MediaLibraryAction, MediaLibraryInstance, MediaFile, MediaFileMap, @@ -41,7 +41,7 @@ const defaultState: { controlID?: string; page?: number; files?: MediaFile[]; - config: Map; + config: Map; field?: EntryField; } = { isVisible: false, @@ -58,6 +58,7 @@ function mediaLibrary(state = Map(defaultState), action: MediaLibraryAction) { map.set('externalLibrary', action.payload); map.set('showMediaButton', action.payload.enableStandalone()); }); + case MEDIA_LIBRARY_OPEN: { const { controlID, forImage, privateUpload, config, field } = action.payload; const libConfig = config || Map(); @@ -85,8 +86,10 @@ function mediaLibrary(state = Map(defaultState), action: MediaLibraryAction) { map.set('field', field); }); } + case MEDIA_LIBRARY_CLOSE: return state.set('isVisible', false); + case MEDIA_INSERT: { const { mediaPath } = action.payload; const controlID = state.get('controlID'); @@ -94,15 +97,18 @@ function mediaLibrary(state = Map(defaultState), action: MediaLibraryAction) { map.setIn(['controlMedia', controlID], mediaPath); }); } + case MEDIA_REMOVE_INSERTED: { const controlID = action.payload.controlID; return state.setIn(['controlMedia', controlID], ''); } + case MEDIA_LOAD_REQUEST: return state.withMutations(map => { map.set('isLoading', true); map.set('isPaginating', action.payload.page > 1); }); + case MEDIA_LOAD_SUCCESS: { const { files = [], @@ -135,6 +141,7 @@ function mediaLibrary(state = Map(defaultState), action: MediaLibraryAction) { } }); } + case MEDIA_LOAD_FAILURE: { const privateUploadChanged = state.get('privateUpload') !== action.payload.privateUpload; if (privateUploadChanged) { @@ -142,8 +149,10 @@ function mediaLibrary(state = Map(defaultState), action: MediaLibraryAction) { } return state.set('isLoading', false); } + case MEDIA_PERSIST_REQUEST: return state.set('isPersisting', true); + case MEDIA_PERSIST_SUCCESS: { const { file, privateUpload } = action.payload; const privateUploadChanged = state.get('privateUpload') !== privateUpload; @@ -158,6 +167,7 @@ function mediaLibrary(state = Map(defaultState), action: MediaLibraryAction) { map.set('isPersisting', false); }); } + case MEDIA_PERSIST_FAILURE: { const privateUploadChanged = state.get('privateUpload') !== action.payload.privateUpload; if (privateUploadChanged) { @@ -165,10 +175,13 @@ function mediaLibrary(state = Map(defaultState), action: MediaLibraryAction) { } return state.set('isPersisting', false); } + case MEDIA_DELETE_REQUEST: return state.set('isDeleting', true); + case MEDIA_DELETE_SUCCESS: { - const { id, key, privateUpload } = action.payload.file; + const { file, privateUpload } = action.payload; + const { key, id } = file; const privateUploadChanged = state.get('privateUpload') !== privateUpload; if (privateUploadChanged) { return state; @@ -181,6 +194,7 @@ function mediaLibrary(state = Map(defaultState), action: MediaLibraryAction) { map.set('isDeleting', false); }); } + case MEDIA_DELETE_FAILURE: { const privateUploadChanged = state.get('privateUpload') !== action.payload.privateUpload; if (privateUploadChanged) { @@ -210,6 +224,7 @@ function mediaLibrary(state = Map(defaultState), action: MediaLibraryAction) { .deleteIn([...displayURLPath, 'url']) ); } + default: return state; } diff --git a/packages/netlify-cms-core/src/types/redux.ts b/packages/netlify-cms-core/src/types/redux.ts index bbeeb919..b37e7cb3 100644 --- a/packages/netlify-cms-core/src/types/redux.ts +++ b/packages/netlify-cms-core/src/types/redux.ts @@ -814,24 +814,3 @@ export interface EditorialWorkflowAction extends Action { newStatus: string; }; } - -export interface MediaLibraryAction extends Action { - payload: MediaLibraryInstance & { - controlID: string; - forImage: boolean; - privateUpload: boolean; - config: Map; - field?: EntryField; - } & { mediaPath: string | string[] } & { page: number } & { - files: MediaFile[]; - page: number; - canPaginate: boolean; - dynamicSearch: boolean; - dynamicSearchQuery: boolean; - } & { - file: MediaFile; - privateUpload: boolean; - } & { - file: { id: string; key: string; privateUpload: boolean }; - } & { key: string } & { url: string } & { err: Error }; -}