Skip to content

Commit

Permalink
allow manual initialization and config as an arg
Browse files Browse the repository at this point in the history
  • Loading branch information
erquhart committed Mar 1, 2018
1 parent 7caa156 commit 88e2e6a
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 53 deletions.
22 changes: 19 additions & 3 deletions src/actions/config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import yaml from "js-yaml";
import { set, defaultsDeep, get } from "lodash";
import Immutable from "immutable";
import { set, defaultsDeep, get, flow } from "lodash";
import { authenticateUser } from "Actions/auth";
import * as publishModes from "Constants/publishModes";

export const CONFIG_REQUEST = "CONFIG_REQUEST";
export const CONFIG_SUCCESS = "CONFIG_SUCCESS";
export const CONFIG_FAILURE = "CONFIG_FAILURE";
export const CONFIG_MERGE = "CONFIG_MERGE";

const defaults = {
publish_mode: publishModes.SIMPLE,
Expand Down Expand Up @@ -82,21 +84,35 @@ export function configDidLoad(config) {
};
}

export function mergeConfig(config) {
return { type: CONFIG_MERGE, payload: config };
}

export function loadConfig() {
if (window.CMS_CONFIG) {
return configDidLoad(window.CMS_CONFIG);
}
return (dispatch) => {
return (dispatch, getState) => {
dispatch(configLoading());
const config = getState().config;

fetch("config.yml", { credentials: 'same-origin' })
.then((response) => {
if (response.status !== 200) {
if (!config && response.status !== 200) {
throw new Error(`Failed to load config.yml (${ response.status })`);
} else if (response.status !== 200) {
return '';
}
return response.text();
})
.then(parseConfig)
.then(resp => {
/**
* Merge any existing configuration using `Immutable.mergeDeep` for
* consistency with reducers.
*/
return config ? config.mergeDeep(Immutable.fromJS(resp)).toJS() : config;
})
.then(validateConfig)
.then(applyDefaults)
.then((config) => {
Expand Down
67 changes: 67 additions & 0 deletions src/bootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { Route } from 'react-router-dom';
import { ConnectedRouter } from 'react-router-redux';
import history from 'Routing/history';
import configureStore from 'Redux/configureStore';
import { mergeConfig } from 'Actions/config';
import { setStore } from 'ValueObjects/AssetProxy';
import { ErrorBoundary } from 'UI'
import App from 'App/App';
import 'EditorWidgets';
import 'MarkdownPlugins';
import './index.css';

function bootstrap({ config }) {
/**
* Log the version number.
*/
console.log(`Netlify CMS version ${NETLIFY_CMS_VERSION}`);

/**
* Create mount element dynamically.
*/
const el = document.createElement('div');
el.id = 'nc-root';
document.body.appendChild(el);

/**
* Configure Redux store.
*/
const store = configureStore();

/**
* Dispatch config to store if received. This config will be merged into
* config.yml if it exists, and any portion that produces a conflict will be
* overwritten.
*/
if (config) {
store.dispatch(mergeConfig(config));
}

/**
* Pass initial state into AssetProxy factory.
*/
setStore(store);

/**
* Create connected root component.
*/
const Root = () => (
<ErrorBoundary>
<Provider store={store}>
<ConnectedRouter history={history}>
<Route component={App}/>
</ConnectedRouter>
</Provider>
</ErrorBoundary>
);

/**
* Render application root.
*/
render(<Root />, el);
}

export default bootstrap;
3 changes: 1 addition & 2 deletions src/components/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ class App extends React.Component {
openMediaLibrary,
} = this.props;


if (config === null) {
return null;
}
Expand All @@ -114,7 +113,7 @@ class App extends React.Component {
return App.configError(config);
}

if (config.get('isFetching')) {
if (config.get('isFetching') || !config.get('isLoaded')) {
return <Loader active>Loading configuration...</Loader>;
}

Expand Down
54 changes: 8 additions & 46 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,16 @@
import React from 'react';
import createReactClass from 'create-react-class';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { Route } from 'react-router-dom';
import { ConnectedRouter } from 'react-router-redux';
import history from 'Routing/history';
import configureStore from 'Redux/configureStore';
import { setStore } from 'ValueObjects/AssetProxy';
import { ErrorBoundary } from 'UI'
import registry from 'Lib/registry';
import App from 'App/App';
import 'EditorWidgets';
import 'MarkdownPlugins';
import './index.css';

/**
* Log the version number.
*/
console.log(`Netlify CMS version ${NETLIFY_CMS_VERSION}`);

/**
* Create mount element dynamically.
*/
const el = document.createElement('div');
el.id = 'nc-root';
document.body.appendChild(el);

/**
* Configure Redux store.
*/
const store = configureStore();
setStore(store);

/**
* Create connected root component.
* This module provides a self-initializing CMS instance with API hooks added to
* the `window` object.
*/
const Root = () => (
<ErrorBoundary>
<Provider store={store}>
<ConnectedRouter history={history}>
<Route component={App}/>
</ConnectedRouter>
</Provider>
</ErrorBoundary>
);
import React from 'react';
import bootstrap from './bootstrap';
import registry from 'Lib/registry';
import createReactClass from 'create-react-class';

/**
* Render application root.
* Load the app.
*/
render(<Root />, el);
bootstrap();

/**
* Add extension hooks to global scope.
Expand Down
7 changes: 7 additions & 0 deletions src/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* This module provides manual initialization and registry hooks.
*/
import bootstrap from './bootstrap';
import registry from 'Lib/registry';

export { bootstrap as init, registry };
13 changes: 11 additions & 2 deletions src/reducers/config.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import Immutable from 'immutable';
import { CONFIG_REQUEST, CONFIG_SUCCESS, CONFIG_FAILURE } from 'Actions/config';
import { CONFIG_REQUEST, CONFIG_SUCCESS, CONFIG_FAILURE, CONFIG_MERGE } from 'Actions/config';

const config = (state = null, action) => {
switch (action.type) {
case CONFIG_MERGE: {
const newConfig = Immutable.fromJS(action.payload);
return state ? state.mergeDeep(newConfig) : newConfig;
}
case CONFIG_REQUEST:
if (state) {
return state.set('isFetching', true);
}
return Immutable.Map({ isFetching: true });
case CONFIG_SUCCESS:
return Immutable.fromJS(action.payload);
return Immutable.fromJS(action.payload).withMutations(map => {
map.set('isFetching', false).set('isLoaded', true);
});
case CONFIG_FAILURE:
return Immutable.Map({ error: action.payload.toString() });
default:
Expand Down
1 change: 1 addition & 0 deletions webpack.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module.exports = merge.smart(require('./webpack.base.js'), {
`webpack-dev-server/client?http://${ HOST }:${ PORT }/`,
'./index',
],
init: './init',
},
output: {
path: path.join(__dirname, 'dist'),
Expand Down
1 change: 1 addition & 0 deletions webpack.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = merge.smart(require('./webpack.base.js'), {
entry: {
cms: './index',
init: './init',
},
output: {
path: path.join(__dirname, 'dist'),
Expand Down

0 comments on commit 88e2e6a

Please sign in to comment.