diff --git a/packages/netlify-cms-core/src/components/App/App.js b/packages/netlify-cms-core/src/components/App/App.js index f4d1e9df..645a0916 100644 --- a/packages/netlify-cms-core/src/components/App/App.js +++ b/packages/netlify-cms-core/src/components/App/App.js @@ -255,7 +255,7 @@ class App extends React.Component { function mapStateToProps(state) { const { auth, config, collections, globalUI, mediaLibrary } = state; const user = auth.user; - const isFetching = globalUI.get('isFetching'); + const isFetching = globalUI.isFetching; const publishMode = config.publish_mode; const useMediaLibrary = !mediaLibrary.get('externalLibrary'); const showMediaButton = mediaLibrary.get('showMediaButton'); diff --git a/packages/netlify-cms-core/src/components/Editor/Editor.js b/packages/netlify-cms-core/src/components/Editor/Editor.js index 516d8e54..2a2e27ac 100644 --- a/packages/netlify-cms-core/src/components/Editor/Editor.js +++ b/packages/netlify-cms-core/src/components/Editor/Editor.js @@ -436,7 +436,7 @@ function mapStateToProps(state, ownProps) { const hasChanged = entryDraft.get('hasChanged'); const displayUrl = config.display_url; const hasWorkflow = config.publish_mode === EDITORIAL_WORKFLOW; - const useOpenAuthoring = globalUI.get('useOpenAuthoring', false); + const useOpenAuthoring = globalUI.useOpenAuthoring; const isModification = entryDraft.getIn(['entry', 'isModification']); const collectionEntriesLoaded = !!entries.getIn(['pages', collectionName]); const unPublishedEntry = selectUnpublishedEntry(state, collectionName, slug); diff --git a/packages/netlify-cms-core/src/components/Workflow/Workflow.js b/packages/netlify-cms-core/src/components/Workflow/Workflow.js index cd3dc3e8..6099bad5 100644 --- a/packages/netlify-cms-core/src/components/Workflow/Workflow.js +++ b/packages/netlify-cms-core/src/components/Workflow/Workflow.js @@ -138,7 +138,7 @@ class Workflow extends Component { function mapStateToProps(state) { const { collections, config, globalUI } = state; const isEditorialWorkflow = config.publish_mode === EDITORIAL_WORKFLOW; - const isOpenAuthoring = globalUI.get('useOpenAuthoring', false); + const isOpenAuthoring = globalUI.useOpenAuthoring; const returnObj = { collections, isEditorialWorkflow, isOpenAuthoring }; if (isEditorialWorkflow) { diff --git a/packages/netlify-cms-core/src/reducers/__tests__/globalUI.js b/packages/netlify-cms-core/src/reducers/__tests__/globalUI.js index d84617a9..6d200821 100644 --- a/packages/netlify-cms-core/src/reducers/__tests__/globalUI.js +++ b/packages/netlify-cms-core/src/reducers/__tests__/globalUI.js @@ -1,50 +1,43 @@ -import { Map } from 'immutable'; -import { USE_OPEN_AUTHORING } from 'Actions/auth'; +import { USE_OPEN_AUTHORING } from '../../actions/auth'; import { DEPLOY_PREVIEW_REQUEST, DEPLOY_PREVIEW_SUCCESS, DEPLOY_PREVIEW_FAILURE, -} from 'Actions/deploys'; -import { ENTRY_REQUEST, ENTRY_SUCCESS, ENTRY_FAILURE } from 'Actions/entries'; +} from '../../actions/deploys'; +import { ENTRY_REQUEST, ENTRY_SUCCESS, ENTRY_FAILURE } from '../../actions/entries'; import reducer from '../globalUI'; describe('globalUI', () => { it('should set isFetching to true on entry request', () => { - expect(reducer(Map({ isFetching: false }), { type: ENTRY_REQUEST })).toEqual( - Map({ isFetching: true }), - ); + expect(reducer({ isFetching: false }, { type: ENTRY_REQUEST })).toEqual({ isFetching: true }); }); it('should set isFetching to false on entry success', () => { - expect(reducer(Map({ isFetching: true }), { type: ENTRY_SUCCESS })).toEqual( - Map({ isFetching: false }), - ); + expect(reducer({ isFetching: true }, { type: ENTRY_SUCCESS })).toEqual({ isFetching: false }); }); it('should set isFetching to false on entry failure', () => { - expect(reducer(Map({ isFetching: true }), { type: ENTRY_FAILURE })).toEqual( - Map({ isFetching: false }), - ); + expect(reducer({ isFetching: true }, { type: ENTRY_FAILURE })).toEqual({ isFetching: false }); }); it('should not change state on deploy preview request', () => { - const state = Map({ isFetching: false }); + const state = { isFetching: false }; expect(reducer(state, { type: DEPLOY_PREVIEW_REQUEST })).toBe(state); }); it('should not change state on deploy preview success', () => { - const state = Map({ isFetching: true }); + const state = { isFetching: true }; expect(reducer(state, { type: DEPLOY_PREVIEW_SUCCESS })).toBe(state); }); it('should not change state on deploy preview failure', () => { - const state = Map({ isFetching: true }); + const state = { isFetching: true }; expect(reducer(state, { type: DEPLOY_PREVIEW_FAILURE })).toBe(state); }); it('should set useOpenAuthoring to true on USE_OPEN_AUTHORING', () => { - expect(reducer(Map({ useOpenAuthoring: false }), { type: USE_OPEN_AUTHORING })).toEqual( - Map({ useOpenAuthoring: true }), - ); + expect(reducer({ useOpenAuthoring: false }, { type: USE_OPEN_AUTHORING })).toEqual({ + useOpenAuthoring: true, + }); }); }); diff --git a/packages/netlify-cms-core/src/reducers/globalUI.js b/packages/netlify-cms-core/src/reducers/globalUI.ts similarity index 53% rename from packages/netlify-cms-core/src/reducers/globalUI.js rename to packages/netlify-cms-core/src/reducers/globalUI.ts index 5f2e0862..6c5876a4 100644 --- a/packages/netlify-cms-core/src/reducers/globalUI.js +++ b/packages/netlify-cms-core/src/reducers/globalUI.ts @@ -1,5 +1,11 @@ -import { Map } from 'immutable'; -import { USE_OPEN_AUTHORING } from 'Actions/auth'; +import { AnyAction } from 'redux'; +import { produce } from 'immer'; +import { USE_OPEN_AUTHORING } from '../actions/auth'; + +export type GlobalUI = { + isFetching: boolean; + useOpenAuthoring: boolean; +}; const LOADING_IGNORE_LIST = [ 'DEPLOY_PREVIEW', @@ -8,26 +14,30 @@ const LOADING_IGNORE_LIST = [ 'STATUS_FAILURE', ]; -function ignoreWhenLoading(action) { +function ignoreWhenLoading(action: AnyAction) { return LOADING_IGNORE_LIST.some(type => action.type.includes(type)); } +const defaultState: GlobalUI = { + isFetching: false, + useOpenAuthoring: false, +}; + /** * Reducer for some global UI state that we want to share between components */ -function globalUI(state = Map({ isFetching: false, useOpenAuthoring: false }), action) { +const globalUI = produce((state: GlobalUI, action: AnyAction) => { // Generic, global loading indicator if (!ignoreWhenLoading(action) && action.type.includes('REQUEST')) { - return state.set('isFetching', true); + state.isFetching = true; } else if ( !ignoreWhenLoading(action) && (action.type.includes('SUCCESS') || action.type.includes('FAILURE')) ) { - return state.set('isFetching', false); + state.isFetching = false; } else if (action.type === USE_OPEN_AUTHORING) { - return state.set('useOpenAuthoring', true); + state.useOpenAuthoring = true; } - return state; -} +}, defaultState); export default globalUI; diff --git a/packages/netlify-cms-core/src/types/redux.ts b/packages/netlify-cms-core/src/types/redux.ts index d1ac97fc..6afba7b1 100644 --- a/packages/netlify-cms-core/src/types/redux.ts +++ b/packages/netlify-cms-core/src/types/redux.ts @@ -8,6 +8,7 @@ import { Status } from '../reducers/status'; import { Medias } from '../reducers/medias'; import { Deploys } from '../reducers/deploys'; import { Search } from '../reducers/search'; +import { GlobalUI } from '../reducers/globalUI'; export type CmsBackendType = | 'azure' @@ -684,6 +685,7 @@ export interface State { cursors: Cursors; collections: Collections; deploys: Deploys; + globalUI: GlobalUI; editorialWorkflow: EditorialWorkflow; entries: Entries; entryDraft: EntryDraft;