refactor: remove immutable from 'config' state slice (#4960)
This commit is contained in:
committed by
GitHub
parent
133689247b
commit
6623740a8c
@ -1,5 +1,5 @@
|
||||
import { OrderedMap, fromJS } from 'immutable';
|
||||
import { configLoaded } from 'Actions/config';
|
||||
import { fromJS, Map } from 'immutable';
|
||||
import { configLoaded } from '../../actions/config';
|
||||
import collections, {
|
||||
selectAllowDeletion,
|
||||
selectEntryPath,
|
||||
@ -11,39 +11,51 @@ import collections, {
|
||||
selectField,
|
||||
updateFieldByKey,
|
||||
} from '../collections';
|
||||
import { FILES, FOLDER } from 'Constants/collectionTypes';
|
||||
import { FILES, FOLDER } from '../../constants/collectionTypes';
|
||||
|
||||
describe('collections', () => {
|
||||
it('should handle an empty state', () => {
|
||||
expect(collections(undefined, {})).toEqual(null);
|
||||
expect(collections(undefined, {})).toEqual(Map());
|
||||
});
|
||||
|
||||
it('should load the collections from the config', () => {
|
||||
expect(
|
||||
collections(
|
||||
undefined,
|
||||
configLoaded(
|
||||
fromJS({
|
||||
collections: [
|
||||
{
|
||||
name: 'posts',
|
||||
folder: '_posts',
|
||||
fields: [{ name: 'title', widget: 'string' }],
|
||||
},
|
||||
],
|
||||
}),
|
||||
),
|
||||
),
|
||||
).toEqual(
|
||||
OrderedMap({
|
||||
posts: fromJS({
|
||||
name: 'posts',
|
||||
folder: '_posts',
|
||||
fields: [{ name: 'title', widget: 'string' }],
|
||||
type: FOLDER,
|
||||
configLoaded({
|
||||
collections: [
|
||||
{
|
||||
name: 'posts',
|
||||
folder: '_posts',
|
||||
fields: [{ name: 'title', widget: 'string' }],
|
||||
},
|
||||
],
|
||||
}),
|
||||
).toJS(),
|
||||
).toEqual({
|
||||
posts: {
|
||||
name: 'posts',
|
||||
folder: '_posts',
|
||||
fields: [{ name: 'title', widget: 'string' }],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should maintain config collections order', () => {
|
||||
const collectionsData = new Array(1000).fill(0).map((_, index) => ({
|
||||
name: `collection_${index}`,
|
||||
folder: `collection_${index}`,
|
||||
fields: [{ name: 'title', widget: 'string' }],
|
||||
}));
|
||||
|
||||
const newState = collections(
|
||||
undefined,
|
||||
configLoaded({
|
||||
collections: collectionsData,
|
||||
}),
|
||||
);
|
||||
const keyArray = newState.keySeq().toArray();
|
||||
expect(keyArray).toEqual(collectionsData.map(({ name }) => name));
|
||||
});
|
||||
|
||||
describe('selectAllowDeletions', () => {
|
||||
@ -234,11 +246,11 @@ describe('collections', () => {
|
||||
sanitize_replacement: '-',
|
||||
};
|
||||
|
||||
const config = fromJS({ slug, media_folder: '/static/img' });
|
||||
const config = { slug, media_folder: '/static/img' };
|
||||
it('should return fields and collection folders', () => {
|
||||
expect(
|
||||
selectMediaFolders(
|
||||
{ config },
|
||||
config,
|
||||
fromJS({
|
||||
folder: 'posts',
|
||||
media_folder: '{{media_folder}}/general/',
|
||||
@ -265,7 +277,7 @@ describe('collections', () => {
|
||||
it('should return fields, file and collection folders', () => {
|
||||
expect(
|
||||
selectMediaFolders(
|
||||
{ config },
|
||||
config,
|
||||
fromJS({
|
||||
media_folder: '{{media_folder}}/general/',
|
||||
files: [
|
||||
|
@ -1,29 +1,38 @@
|
||||
import { Map } from 'immutable';
|
||||
import { configLoaded, configLoading, configFailed } from 'Actions/config';
|
||||
import config, { selectLocale } from 'Reducers/config';
|
||||
import { configLoaded, configLoading, configFailed } from '../../actions/config';
|
||||
import config, { selectLocale } from '../config';
|
||||
|
||||
describe('config', () => {
|
||||
it('should handle an empty state', () => {
|
||||
expect(config(undefined, {})).toEqual(Map({ isFetching: true }));
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
||||
// @ts-ignore config reducer doesn't accept empty action
|
||||
expect(config(undefined, {})).toEqual({ isFetching: true });
|
||||
});
|
||||
|
||||
it('should handle an update', () => {
|
||||
expect(config(Map({ a: 'b', c: 'd' }), configLoaded(Map({ a: 'changed', e: 'new' })))).toEqual(
|
||||
Map({ a: 'changed', e: 'new' }),
|
||||
);
|
||||
expect(
|
||||
config({ isFetching: true }, configLoaded({ locale: 'fr', backend: { name: 'proxy' } })),
|
||||
).toEqual({
|
||||
locale: 'fr',
|
||||
backend: { name: 'proxy' },
|
||||
isFetching: false,
|
||||
error: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it('should mark the config as loading', () => {
|
||||
expect(config(undefined, configLoading())).toEqual(Map({ isFetching: true }));
|
||||
expect(config({ isFetching: false }, configLoading())).toEqual({ isFetching: true });
|
||||
});
|
||||
|
||||
it('should handle an error', () => {
|
||||
expect(config(Map(), configFailed(new Error('Config could not be loaded')))).toEqual(
|
||||
Map({ error: 'Error: Config could not be loaded' }),
|
||||
);
|
||||
expect(
|
||||
config({ isFetching: true }, configFailed(new Error('Config could not be loaded'))),
|
||||
).toEqual({
|
||||
error: 'Error: Config could not be loaded',
|
||||
isFetching: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should default to "en" locale', () => {
|
||||
expect(selectLocale(Map())).toEqual('en');
|
||||
expect(selectLocale({})).toEqual('en');
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { OrderedMap, fromJS } from 'immutable';
|
||||
import * as actions from 'Actions/entries';
|
||||
import * as actions from '../../actions/entries';
|
||||
import reducer, {
|
||||
selectMediaFolder,
|
||||
selectMediaFilePath,
|
||||
@ -76,7 +76,7 @@ describe('entries', () => {
|
||||
it("should return global media folder when collection doesn't specify media_folder", () => {
|
||||
expect(
|
||||
selectMediaFolder(
|
||||
fromJS({ media_folder: 'static/media' }),
|
||||
{ media_folder: 'static/media' },
|
||||
fromJS({ name: 'posts' }),
|
||||
undefined,
|
||||
undefined,
|
||||
@ -87,7 +87,7 @@ describe('entries', () => {
|
||||
it('should return draft media folder when collection specifies media_folder and entry is undefined', () => {
|
||||
expect(
|
||||
selectMediaFolder(
|
||||
fromJS({ media_folder: 'static/media' }),
|
||||
{ media_folder: 'static/media' },
|
||||
fromJS({ name: 'posts', folder: 'posts', media_folder: '' }),
|
||||
undefined,
|
||||
undefined,
|
||||
@ -98,7 +98,7 @@ describe('entries', () => {
|
||||
it('should return relative media folder when collection specifies media_folder and entry path is not null', () => {
|
||||
expect(
|
||||
selectMediaFolder(
|
||||
fromJS({ media_folder: 'static/media' }),
|
||||
{ media_folder: 'static/media' },
|
||||
fromJS({ name: 'posts', folder: 'posts', media_folder: '' }),
|
||||
fromJS({ path: 'posts/title/index.md' }),
|
||||
undefined,
|
||||
@ -121,7 +121,7 @@ describe('entries', () => {
|
||||
const field = fromJS({ media_folder: '' });
|
||||
expect(
|
||||
selectMediaFolder(
|
||||
fromJS({ media_folder: '/static/img' }),
|
||||
{ media_folder: '/static/img' },
|
||||
fromJS({
|
||||
name: 'other',
|
||||
folder: 'other',
|
||||
@ -137,7 +137,7 @@ describe('entries', () => {
|
||||
it('should return collection absolute media folder without leading slash', () => {
|
||||
expect(
|
||||
selectMediaFolder(
|
||||
fromJS({ media_folder: '/static/Images' }),
|
||||
{ media_folder: '/static/Images' },
|
||||
fromJS({
|
||||
name: 'getting-started',
|
||||
folder: 'src/docs/getting-started',
|
||||
@ -169,7 +169,7 @@ describe('entries', () => {
|
||||
|
||||
expect(
|
||||
selectMediaFolder(
|
||||
fromJS({ media_folder: 'static/media', slug: slugConfig }),
|
||||
{ media_folder: 'static/media', slug: slugConfig },
|
||||
collection,
|
||||
entry,
|
||||
undefined,
|
||||
@ -196,7 +196,7 @@ describe('entries', () => {
|
||||
|
||||
expect(
|
||||
selectMediaFolder(
|
||||
fromJS({ media_folder: '/static/images', slug: slugConfig }),
|
||||
{ media_folder: '/static/images', slug: slugConfig },
|
||||
collection,
|
||||
entry,
|
||||
undefined,
|
||||
@ -229,7 +229,7 @@ describe('entries', () => {
|
||||
|
||||
expect(
|
||||
selectMediaFolder(
|
||||
fromJS({ media_folder: 'static/media', slug: slugConfig }),
|
||||
{ media_folder: 'static/media', slug: slugConfig },
|
||||
collection,
|
||||
entry,
|
||||
collection.get('fields').get(0),
|
||||
@ -258,7 +258,7 @@ describe('entries', () => {
|
||||
|
||||
expect(
|
||||
selectMediaFolder(
|
||||
fromJS({ media_folder: '/static/img/', slug: slugConfig }),
|
||||
{ media_folder: '/static/img/', slug: slugConfig },
|
||||
collection,
|
||||
entry,
|
||||
undefined,
|
||||
@ -267,7 +267,7 @@ describe('entries', () => {
|
||||
|
||||
expect(
|
||||
selectMediaFolder(
|
||||
fromJS({ media_folder: 'static/img/', slug: slugConfig }),
|
||||
{ media_folder: 'static/img/', slug: slugConfig },
|
||||
collection,
|
||||
entry,
|
||||
undefined,
|
||||
@ -278,7 +278,7 @@ describe('entries', () => {
|
||||
it('should handle file media_folder', () => {
|
||||
expect(
|
||||
selectMediaFolder(
|
||||
fromJS({ media_folder: 'static/media' }),
|
||||
{ media_folder: 'static/media' },
|
||||
fromJS({ name: 'posts', files: [{ name: 'index', media_folder: '/static/images/' }] }),
|
||||
fromJS({ path: 'posts/title/index.md', slug: 'index' }),
|
||||
undefined,
|
||||
@ -302,7 +302,7 @@ describe('entries', () => {
|
||||
});
|
||||
|
||||
const args = [
|
||||
fromJS({ media_folder: '/static/img' }),
|
||||
{ media_folder: '/static/img' },
|
||||
fromJS({
|
||||
name: 'general',
|
||||
media_folder: '{{media_folder}}/general/',
|
||||
@ -345,7 +345,7 @@ describe('entries', () => {
|
||||
it('should resolve path from global media folder for collection with no media folder', () => {
|
||||
expect(
|
||||
selectMediaFilePath(
|
||||
fromJS({ media_folder: 'static/media' }),
|
||||
{ media_folder: 'static/media' },
|
||||
fromJS({ name: 'posts', folder: 'posts' }),
|
||||
undefined,
|
||||
'image.png',
|
||||
@ -357,7 +357,7 @@ describe('entries', () => {
|
||||
it('should resolve path from collection media folder for collection with media folder', () => {
|
||||
expect(
|
||||
selectMediaFilePath(
|
||||
fromJS({ media_folder: 'static/media' }),
|
||||
{ media_folder: 'static/media' },
|
||||
fromJS({ name: 'posts', folder: 'posts', media_folder: '' }),
|
||||
undefined,
|
||||
'image.png',
|
||||
@ -369,7 +369,7 @@ describe('entries', () => {
|
||||
it('should handle relative media_folder', () => {
|
||||
expect(
|
||||
selectMediaFilePath(
|
||||
fromJS({ media_folder: 'static/media' }),
|
||||
{ media_folder: 'static/media' },
|
||||
fromJS({ name: 'posts', folder: 'posts', media_folder: '../../static/media/' }),
|
||||
fromJS({ path: 'posts/title/index.md' }),
|
||||
'image.png',
|
||||
@ -382,7 +382,7 @@ describe('entries', () => {
|
||||
const field = fromJS({ media_folder: '../../static/media/' });
|
||||
expect(
|
||||
selectMediaFilePath(
|
||||
fromJS({ media_folder: 'static/media' }),
|
||||
{ media_folder: 'static/media' },
|
||||
fromJS({ name: 'posts', folder: 'posts', fields: [field] }),
|
||||
fromJS({ path: 'posts/title/index.md' }),
|
||||
'image.png',
|
||||
@ -402,7 +402,7 @@ describe('entries', () => {
|
||||
it('should resolve path from public folder for collection with no media folder', () => {
|
||||
expect(
|
||||
selectMediaFilePublicPath(
|
||||
fromJS({ public_folder: '/media' }),
|
||||
{ public_folder: '/media' },
|
||||
null,
|
||||
'/media/image.png',
|
||||
undefined,
|
||||
@ -414,7 +414,7 @@ describe('entries', () => {
|
||||
it('should resolve path from collection public folder for collection with public folder', () => {
|
||||
expect(
|
||||
selectMediaFilePublicPath(
|
||||
fromJS({ public_folder: '/media' }),
|
||||
{ public_folder: '/media' },
|
||||
fromJS({ name: 'posts', folder: 'posts', public_folder: '' }),
|
||||
'image.png',
|
||||
undefined,
|
||||
@ -426,7 +426,7 @@ describe('entries', () => {
|
||||
it('should handle relative public_folder', () => {
|
||||
expect(
|
||||
selectMediaFilePublicPath(
|
||||
fromJS({ public_folder: '/media' }),
|
||||
{ public_folder: '/media' },
|
||||
fromJS({ name: 'posts', folder: 'posts', public_folder: '../../static/media/' }),
|
||||
'image.png',
|
||||
undefined,
|
||||
@ -455,7 +455,7 @@ describe('entries', () => {
|
||||
|
||||
expect(
|
||||
selectMediaFilePublicPath(
|
||||
fromJS({ public_folder: 'static/media', slug: slugConfig }),
|
||||
{ public_folder: 'static/media', slug: slugConfig },
|
||||
collection,
|
||||
'image.png',
|
||||
entry,
|
||||
@ -489,7 +489,7 @@ describe('entries', () => {
|
||||
|
||||
expect(
|
||||
selectMediaFilePublicPath(
|
||||
fromJS({ public_folder: 'static/media', slug: slugConfig }),
|
||||
{ public_folder: 'static/media', slug: slugConfig },
|
||||
collection,
|
||||
'image.png',
|
||||
entry,
|
||||
@ -523,7 +523,7 @@ describe('entries', () => {
|
||||
|
||||
expect(
|
||||
selectMediaFilePublicPath(
|
||||
fromJS({ public_folder: 'static/media/', slug: slugConfig }),
|
||||
{ public_folder: 'static/media/', slug: slugConfig },
|
||||
collection,
|
||||
'image.png',
|
||||
entry,
|
||||
@ -551,7 +551,7 @@ describe('entries', () => {
|
||||
|
||||
expect(
|
||||
selectMediaFilePublicPath(
|
||||
fromJS({ public_folder: 'static/media/' }),
|
||||
{ public_folder: 'static/media/' },
|
||||
collection,
|
||||
'image.png',
|
||||
entry,
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { fromJS } from 'immutable';
|
||||
import integrations from '../integrations';
|
||||
import { CONFIG_SUCCESS } from '../../actions/config';
|
||||
import { CONFIG_SUCCESS, ConfigAction } from '../../actions/config';
|
||||
import { FOLDER } from '../../constants/collectionTypes';
|
||||
|
||||
describe('integrations', () => {
|
||||
it('should return default state when no integrations', () => {
|
||||
const result = integrations(null, {
|
||||
type: CONFIG_SUCCESS,
|
||||
payload: fromJS({ integrations: [] }),
|
||||
});
|
||||
payload: { integrations: [] },
|
||||
} as ConfigAction);
|
||||
expect(result && result.toJS()).toEqual({
|
||||
providers: {},
|
||||
hooks: {},
|
||||
@ -17,7 +17,7 @@ describe('integrations', () => {
|
||||
it('should return hooks and providers map when has integrations', () => {
|
||||
const result = integrations(null, {
|
||||
type: CONFIG_SUCCESS,
|
||||
payload: fromJS({
|
||||
payload: {
|
||||
integrations: [
|
||||
{
|
||||
hooks: ['listEntries'],
|
||||
@ -39,9 +39,13 @@ describe('integrations', () => {
|
||||
getSignedFormURL: 'https://asset.store.com/signedUrl',
|
||||
},
|
||||
],
|
||||
collections: [{ name: 'posts' }, { name: 'pages' }, { name: 'faq' }],
|
||||
}),
|
||||
});
|
||||
collections: [
|
||||
{ name: 'posts', label: 'Posts', type: FOLDER },
|
||||
{ name: 'pages', label: 'Pages', type: FOLDER },
|
||||
{ name: 'faq', label: 'FAQ', type: FOLDER },
|
||||
],
|
||||
},
|
||||
} as ConfigAction);
|
||||
|
||||
expect(result && result.toJS()).toEqual({
|
||||
providers: {
|
||||
|
@ -1,19 +1,20 @@
|
||||
import { List, Set } from 'immutable';
|
||||
import { List, Set, fromJS, OrderedMap } from 'immutable';
|
||||
import { get, escapeRegExp } from 'lodash';
|
||||
import consoleError from '../lib/consoleError';
|
||||
import { CONFIG_SUCCESS } from '../actions/config';
|
||||
import { CONFIG_SUCCESS, ConfigAction } from '../actions/config';
|
||||
import { FILES, FOLDER } from '../constants/collectionTypes';
|
||||
import { COMMIT_DATE, COMMIT_AUTHOR } from '../constants/commitProps';
|
||||
import { INFERABLE_FIELDS, IDENTIFIER_FIELDS, SORTABLE_FIELDS } from '../constants/fieldInference';
|
||||
import { formatExtensions } from '../formats/formats';
|
||||
import {
|
||||
CollectionsAction,
|
||||
Collection,
|
||||
Collections,
|
||||
CollectionFiles,
|
||||
EntryField,
|
||||
State,
|
||||
EntryMap,
|
||||
ViewFilter,
|
||||
ViewGroup,
|
||||
CmsConfig,
|
||||
} from '../types/redux';
|
||||
import { selectMediaFolder } from './entries';
|
||||
import { stringTemplate } from 'netlify-cms-lib-widgets';
|
||||
@ -22,29 +23,17 @@ import { Backend } from '../backend';
|
||||
|
||||
const { keyToPathArray } = stringTemplate;
|
||||
|
||||
function collections(state = null, action: CollectionsAction) {
|
||||
const defaultState: Collections = fromJS({});
|
||||
|
||||
function collections(state = defaultState, action: ConfigAction) {
|
||||
switch (action.type) {
|
||||
case CONFIG_SUCCESS: {
|
||||
const configCollections = action.payload
|
||||
? action.payload.get('collections')
|
||||
: List<Collection>();
|
||||
|
||||
return (
|
||||
configCollections
|
||||
.toOrderedMap()
|
||||
.map(item => {
|
||||
const collection = item as Collection;
|
||||
if (collection.has('folder')) {
|
||||
return collection.set('type', FOLDER);
|
||||
}
|
||||
if (collection.has('files')) {
|
||||
return collection.set('type', FILES);
|
||||
}
|
||||
})
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
||||
// @ts-ignore
|
||||
.mapKeys((key: string, collection: Collection) => collection.get('name'))
|
||||
);
|
||||
const collections = action.payload.collections;
|
||||
let newState = OrderedMap({});
|
||||
collections.forEach(collection => {
|
||||
newState = newState.set(collection.name, fromJS(collection));
|
||||
});
|
||||
return newState;
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
@ -165,19 +154,19 @@ export function selectFieldsWithMediaFolders(collection: Collection, slug: strin
|
||||
return [];
|
||||
}
|
||||
|
||||
export function selectMediaFolders(state: State, collection: Collection, entry: EntryMap) {
|
||||
export function selectMediaFolders(config: CmsConfig, collection: Collection, entry: EntryMap) {
|
||||
const fields = selectFieldsWithMediaFolders(collection, entry.get('slug'));
|
||||
const folders = fields.map(f => selectMediaFolder(state.config, collection, entry, f));
|
||||
const folders = fields.map(f => selectMediaFolder(config, collection, entry, f));
|
||||
if (collection.has('files')) {
|
||||
const file = getFileFromSlug(collection, entry.get('slug'));
|
||||
if (file) {
|
||||
folders.unshift(selectMediaFolder(state.config, collection, entry, undefined));
|
||||
folders.unshift(selectMediaFolder(config, collection, entry, undefined));
|
||||
}
|
||||
}
|
||||
if (collection.has('media_folder')) {
|
||||
// stop evaluating media folders at collection level
|
||||
collection = collection.delete('files');
|
||||
folders.unshift(selectMediaFolder(state.config, collection, entry, undefined));
|
||||
folders.unshift(selectMediaFolder(config, collection, entry, undefined));
|
||||
}
|
||||
|
||||
return Set(folders).toArray();
|
||||
@ -317,10 +306,10 @@ export function updateFieldByKey(
|
||||
|
||||
export function selectIdentifier(collection: Collection) {
|
||||
const identifier = collection.get('identifier_field');
|
||||
const identifierFields = identifier ? [identifier, ...IDENTIFIER_FIELDS] : IDENTIFIER_FIELDS;
|
||||
const fieldNames = getFieldsNames(collection.get('fields', List<EntryField>()).toArray());
|
||||
const identifierFields = identifier ? [identifier, ...IDENTIFIER_FIELDS] : [...IDENTIFIER_FIELDS];
|
||||
const fieldNames = getFieldsNames(collection.get('fields', List()).toArray());
|
||||
return identifierFields.find(id =>
|
||||
fieldNames.find(name => name?.toLowerCase().trim() === id.toLowerCase().trim()),
|
||||
fieldNames.find(name => name.toLowerCase().trim() === id.toLowerCase().trim()),
|
||||
);
|
||||
}
|
||||
|
||||
@ -390,9 +379,6 @@ export function selectEntryCollectionTitle(collection: Collection, entry: EntryM
|
||||
return titleField && entryData.getIn(keyToPathArray(titleField));
|
||||
}
|
||||
|
||||
export const COMMIT_AUTHOR = 'commit_author';
|
||||
export const COMMIT_DATE = 'commit_date';
|
||||
|
||||
export function selectDefaultSortableFields(
|
||||
collection: Collection,
|
||||
backend: Backend,
|
||||
|
@ -1,37 +1,35 @@
|
||||
import { Map } from 'immutable';
|
||||
import { CONFIG_REQUEST, CONFIG_SUCCESS, CONFIG_FAILURE } from '../actions/config';
|
||||
import { Config, ConfigAction } from '../types/redux';
|
||||
import { produce } from 'immer';
|
||||
import { CONFIG_REQUEST, CONFIG_SUCCESS, CONFIG_FAILURE, ConfigAction } from '../actions/config';
|
||||
import { EDITORIAL_WORKFLOW } from '../constants/publishModes';
|
||||
import { CmsConfig } from '../types/redux';
|
||||
|
||||
const defaultState: Map<string, boolean | string> = Map({ isFetching: true });
|
||||
const defaultState = {
|
||||
isFetching: true,
|
||||
};
|
||||
|
||||
function config(state = defaultState, action: ConfigAction) {
|
||||
const config = produce((state: CmsConfig, action: ConfigAction) => {
|
||||
switch (action.type) {
|
||||
case CONFIG_REQUEST:
|
||||
return state.set('isFetching', true);
|
||||
state.isFetching = true;
|
||||
break;
|
||||
case CONFIG_SUCCESS:
|
||||
/**
|
||||
* The loadConfig action merges any existing config into the loaded config
|
||||
* before firing this action (so the resulting config can be validated),
|
||||
* so we don't have to merge it here.
|
||||
*/
|
||||
return action.payload;
|
||||
return {
|
||||
...action.payload,
|
||||
isFetching: false,
|
||||
error: undefined,
|
||||
};
|
||||
case CONFIG_FAILURE:
|
||||
return state.withMutations(s => {
|
||||
s.delete('isFetching');
|
||||
s.set('error', action.payload.toString());
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
state.isFetching = false;
|
||||
state.error = action.payload.toString();
|
||||
}
|
||||
}, defaultState);
|
||||
|
||||
export function selectLocale(state: CmsConfig) {
|
||||
return state.locale || 'en';
|
||||
}
|
||||
|
||||
export function selectLocale(state: Config) {
|
||||
return state.get('locale', 'en') as string;
|
||||
}
|
||||
|
||||
export function selectUseWorkflow(state: Config) {
|
||||
return state.get('publish_mode') === EDITORIAL_WORKFLOW;
|
||||
export function selectUseWorkflow(state: CmsConfig) {
|
||||
return state.publish_mode === EDITORIAL_WORKFLOW;
|
||||
}
|
||||
|
||||
export default config;
|
||||
|
@ -24,7 +24,7 @@ import { EditorialWorkflowAction, EditorialWorkflow, Entities } from '../types/r
|
||||
function unpublishedEntries(state = Map(), action: EditorialWorkflowAction) {
|
||||
switch (action.type) {
|
||||
case CONFIG_SUCCESS: {
|
||||
const publishMode = action.payload && action.payload.get('publish_mode');
|
||||
const publishMode = action.payload && action.payload.publish_mode;
|
||||
if (publishMode === EDITORIAL_WORKFLOW) {
|
||||
// Editorial workflow state is explicitly initiated after the config.
|
||||
return Map({ entities: Map(), pages: Map() });
|
||||
|
@ -27,7 +27,7 @@ import {
|
||||
EntriesSuccessPayload,
|
||||
EntryObject,
|
||||
Entries,
|
||||
Config,
|
||||
CmsConfig,
|
||||
Collection,
|
||||
EntryFailurePayload,
|
||||
EntryDeletePayload,
|
||||
@ -564,7 +564,7 @@ function hasCustomFolder(
|
||||
|
||||
function traverseFields(
|
||||
folderKey: 'media_folder' | 'public_folder',
|
||||
config: Config,
|
||||
config: CmsConfig,
|
||||
collection: Collection,
|
||||
entryMap: EntryMap | undefined,
|
||||
field: EntryField,
|
||||
@ -579,7 +579,7 @@ function traverseFields(
|
||||
collection,
|
||||
currentFolder,
|
||||
folderKey,
|
||||
config.get('slug'),
|
||||
config.slug,
|
||||
);
|
||||
}
|
||||
|
||||
@ -594,7 +594,7 @@ function traverseFields(
|
||||
collection,
|
||||
currentFolder,
|
||||
folderKey,
|
||||
config.get('slug'),
|
||||
config.slug,
|
||||
);
|
||||
let fieldFolder = null;
|
||||
if (f.has('fields')) {
|
||||
@ -638,12 +638,12 @@ function traverseFields(
|
||||
|
||||
function evaluateFolder(
|
||||
folderKey: 'media_folder' | 'public_folder',
|
||||
config: Config,
|
||||
config: CmsConfig,
|
||||
collection: Collection,
|
||||
entryMap: EntryMap | undefined,
|
||||
field: EntryField | undefined,
|
||||
) {
|
||||
let currentFolder = config.get(folderKey);
|
||||
let currentFolder = config[folderKey]!;
|
||||
|
||||
// add identity template if doesn't exist
|
||||
if (!collection.has(folderKey)) {
|
||||
@ -659,7 +659,7 @@ function evaluateFolder(
|
||||
collection,
|
||||
currentFolder,
|
||||
folderKey,
|
||||
config.get('slug'),
|
||||
config.slug,
|
||||
);
|
||||
|
||||
let file = getFileField(collection.get('files')!, entryMap?.get('slug'));
|
||||
@ -676,7 +676,7 @@ function evaluateFolder(
|
||||
collection,
|
||||
currentFolder,
|
||||
folderKey,
|
||||
config.get('slug'),
|
||||
config.slug,
|
||||
);
|
||||
|
||||
if (field) {
|
||||
@ -704,7 +704,7 @@ function evaluateFolder(
|
||||
collection,
|
||||
currentFolder,
|
||||
folderKey,
|
||||
config.get('slug'),
|
||||
config.slug,
|
||||
);
|
||||
|
||||
if (field) {
|
||||
@ -728,13 +728,13 @@ function evaluateFolder(
|
||||
}
|
||||
|
||||
export function selectMediaFolder(
|
||||
config: Config,
|
||||
config: CmsConfig,
|
||||
collection: Collection | null,
|
||||
entryMap: EntryMap | undefined,
|
||||
field: EntryField | undefined,
|
||||
) {
|
||||
const name = 'media_folder';
|
||||
let mediaFolder = config.get(name);
|
||||
let mediaFolder = config[name];
|
||||
|
||||
const customFolder = hasCustomFolder(name, collection, entryMap?.get('slug'), field);
|
||||
|
||||
@ -755,7 +755,7 @@ export function selectMediaFolder(
|
||||
}
|
||||
|
||||
export function selectMediaFilePath(
|
||||
config: Config,
|
||||
config: CmsConfig,
|
||||
collection: Collection | null,
|
||||
entryMap: EntryMap | undefined,
|
||||
mediaPath: string,
|
||||
@ -771,7 +771,7 @@ export function selectMediaFilePath(
|
||||
}
|
||||
|
||||
export function selectMediaFilePublicPath(
|
||||
config: Config,
|
||||
config: CmsConfig,
|
||||
collection: Collection | null,
|
||||
mediaPath: string,
|
||||
entryMap: EntryMap | undefined,
|
||||
@ -782,7 +782,7 @@ export function selectMediaFilePublicPath(
|
||||
}
|
||||
|
||||
const name = 'public_folder';
|
||||
let publicFolder = config.get(name);
|
||||
let publicFolder = config[name]!;
|
||||
|
||||
const customFolder = hasCustomFolder(name, collection, entryMap?.get('slug'), field);
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { fromJS, List } from 'immutable';
|
||||
import { CONFIG_SUCCESS } from '../actions/config';
|
||||
import { Integrations, IntegrationsAction, Integration, Config } from '../types/redux';
|
||||
import { fromJS } from 'immutable';
|
||||
import { CONFIG_SUCCESS, ConfigAction } from '../actions/config';
|
||||
import { Integrations, CmsConfig } from '../types/redux';
|
||||
|
||||
interface Acc {
|
||||
providers: Record<string, {}>;
|
||||
hooks: Record<string, string | Record<string, string>>;
|
||||
}
|
||||
|
||||
export function getIntegrations(config: Config) {
|
||||
const integrations: Integration[] = config.get('integrations', List()).toJS() || [];
|
||||
export function getIntegrations(config: CmsConfig) {
|
||||
const integrations = config.integrations || [];
|
||||
const newState = integrations.reduce(
|
||||
(acc, integration) => {
|
||||
const { hooks, collections, provider, ...providerData } = integration;
|
||||
@ -20,12 +20,7 @@ export function getIntegrations(config: Config) {
|
||||
return acc;
|
||||
}
|
||||
const integrationCollections =
|
||||
collections === '*'
|
||||
? config
|
||||
.get('collections')
|
||||
.map(collection => collection!.get('name'))
|
||||
.toArray()
|
||||
: (collections as string[]);
|
||||
collections === '*' ? config.collections.map(collection => collection.name) : collections;
|
||||
integrationCollections.forEach(collection => {
|
||||
hooks.forEach(hook => {
|
||||
acc.hooks[collection]
|
||||
@ -40,7 +35,9 @@ export function getIntegrations(config: Config) {
|
||||
return fromJS(newState);
|
||||
}
|
||||
|
||||
function integrations(state = null, action: IntegrationsAction): Integrations | null {
|
||||
const defaultState = fromJS({ providers: {}, hooks: {} });
|
||||
|
||||
function integrations(state = defaultState, action: ConfigAction): Integrations | null {
|
||||
switch (action.type) {
|
||||
case CONFIG_SUCCESS: {
|
||||
return getIntegrations(action.payload);
|
||||
|
Reference in New Issue
Block a user