Your past searches and commands
@@ -328,7 +335,7 @@ class FindBar extends Component {
renderActiveScope() {
if (this.state.activeScope === SEARCH) {
- return
;
+ return
;
} else {
return
{this.state.activeScope}
;
}
@@ -358,6 +365,7 @@ class FindBar extends Component {
);
}
}
+
FindBar.propTypes = {
commands: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string.isRequired,
diff --git a/src/formats/yaml.js b/src/formats/yaml.js
index 9fd73c07..d939c068 100644
--- a/src/formats/yaml.js
+++ b/src/formats/yaml.js
@@ -41,6 +41,6 @@ export default class YAML {
}
toFile(data) {
- return yaml.safeDump(data, {schema: OutputSchema});
+ return yaml.safeDump(data, { schema: OutputSchema });
}
}
diff --git a/src/index.css b/src/index.css
index 13806227..91c45f0d 100644
--- a/src/index.css
+++ b/src/index.css
@@ -3,8 +3,9 @@ html {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
margin: 0;
- font-family: Roboto,"Helvetica Neue",HelveticaNeue,Helvetica,Arial,sans-serif;
+ font-family: Roboto, "Helvetica Neue", HelveticaNeue, Helvetica, Arial, sans-serif;
}
+
*, *:before, *:after {
box-sizing: inherit;
}
@@ -13,15 +14,15 @@ body {
font-family: 'Roboto', sans-serif;
height: 100%;
background-color: #f2f5f4;
- color:#7c8382;
+ color: #7c8382;
margin: 0;
}
header {
background-color: #272e30;
- box-shadow: 0 1px 2px 0 rgba(0,0,0,0.22);
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.22);
height: 54px;
- border-bottom:2px solid #3ab7a5;
+ border-bottom: 2px solid #3ab7a5;
position: fixed;
width: 100%;
z-index: 999;
@@ -35,23 +36,24 @@ h1, h2, h3, h4, h5, h6, p {
margin: 0;
}
-h1{
- color: #3ab7a5;
- border-bottom: 1px solid #3ab7a5;
- margin: 30px auto 25px;
- padding-bottom: 15px;
- font-size: 25px;
+h1 {
+ color: #3ab7a5;
+ border-bottom: 1px solid #3ab7a5;
+ margin: 30px auto 25px;
+ padding-bottom: 15px;
+ font-size: 25px;
}
-header input{
- margin-bottom:0;
+header input {
+ margin-bottom: 0;
}
-button{
+
+button {
border: 1px solid #3ab7a5;
padding: 3px 20px;
font-size: 12px;
line-height: 18px;
- background-color:#fff;
+ background-color: #fff;
cursor: pointer;
}
@@ -120,7 +122,7 @@ button{
margin-top: 1px;
z-index: 99999 !important;
background: #fff;
- box-shadow: 0 1px 3px rgba(0,0,0,.1);
+ box-shadow: 0 1px 3px rgba(0, 0, 0, .1);
border: 1px solid #f9f9f9;
}
& .rdtOpen .rdtPicker {
@@ -217,10 +219,10 @@ button{
& .rdtNext span {
display: block;
-webkit-touch-callout: none; /* iOS Safari */
- -webkit-user-select: none; /* Chrome/Safari/Opera */
- -khtml-user-select: none; /* Konqueror */
- -moz-user-select: none; /* Firefox */
- -ms-user-select: none; /* Internet Explorer/Edge */
+ -webkit-user-select: none; /* Chrome/Safari/Opera */
+ -khtml-user-select: none; /* Konqueror */
+ -moz-user-select: none; /* Firefox */
+ -ms-user-select: none; /* Internet Explorer/Edge */
user-select: none;
}
@@ -293,10 +295,10 @@ button{
display: block;
-webkit-touch-callout: none; /* iOS Safari */
- -webkit-user-select: none; /* Chrome/Safari/Opera */
- -khtml-user-select: none; /* Konqueror */
- -moz-user-select: none; /* Firefox */
- -ms-user-select: none; /* Internet Explorer/Edge */
+ -webkit-user-select: none; /* Chrome/Safari/Opera */
+ -khtml-user-select: none; /* Konqueror */
+ -moz-user-select: none; /* Firefox */
+ -ms-user-select: none; /* Internet Explorer/Edge */
user-select: none;
}
& .rdtCounter .rdtBtn:hover {
diff --git a/src/index.js b/src/index.js
index 965e5bd2..ae127d1e 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,31 +1,33 @@
import React from 'react';
import { render } from 'react-dom';
-import { Provider } from 'react-redux';
-import { Router } from 'react-router';
+import { AppContainer } from 'react-hot-loader'
+import Root from './root'
import registry from './lib/registry';
-import configureStore from './store/configureStore';
-import routes from './routing/routes';
-import history, { syncHistory } from './routing/history';
import 'file?name=index.html!../example/index.html';
import './index.css';
-const store = configureStore();
-
-// Create an enhanced history that syncs navigation events with the store
-syncHistory(store);
-
+// Create mount element dynamically
const el = document.createElement('div');
el.id = 'root';
document.body.appendChild(el);
render((
-
-
- {routes}
-
-
+
+
+
), el);
+if (module.hot) {
+ module.hot.accept('./root', () => {
+ const NextRoot = require('./root').default;
+ render((
+
+
+
+ ), el);
+ });
+}
+
window.CMS = {};
console.log('reg: ', registry);
for (const method in registry) {
diff --git a/src/lib/registry.js b/src/lib/registry.js
index 4d7f14e9..e4de5183 100644
--- a/src/lib/registry.js
+++ b/src/lib/registry.js
@@ -1,5 +1,5 @@
-import {List} from 'immutable';
-import {newEditorPlugin} from '../components/Widgets/MarkdownControlElements/plugins';
+import { List } from 'immutable';
+import { newEditorPlugin } from '../components/Widgets/MarkdownControlElements/plugins';
const _registry = {
templates: {},
diff --git a/src/reducers/combinedReducer.js b/src/reducers/combinedReducer.js
new file mode 100644
index 00000000..97e00e3f
--- /dev/null
+++ b/src/reducers/combinedReducer.js
@@ -0,0 +1,8 @@
+import { combineReducers } from 'redux';
+import { routerReducer } from 'react-router-redux';
+import reducers from '.';
+
+export default combineReducers({
+ ...reducers,
+ routing: routerReducer
+});
diff --git a/src/root.js b/src/root.js
new file mode 100644
index 00000000..dcfd944a
--- /dev/null
+++ b/src/root.js
@@ -0,0 +1,21 @@
+import React from 'react';
+import { Provider } from 'react-redux';
+import { Router } from 'react-router';
+import routes from './routing/routes';
+import history, { syncHistory } from './routing/history';
+import configureStore from './store/configureStore';
+
+const store = configureStore();
+
+// Create an enhanced history that syncs navigation events with the store
+syncHistory(store);
+
+const Root = () => (
+
+
+ {routes}
+
+
+);
+
+export default Root;
diff --git a/src/store/configureStore.js b/src/store/configureStore.js
index d7552c00..19fe8a45 100644
--- a/src/store/configureStore.js
+++ b/src/store/configureStore.js
@@ -1,18 +1,20 @@
-import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
+import { createStore, applyMiddleware, compose } from 'redux';
import thunkMiddleware from 'redux-thunk';
-import { routerReducer } from 'react-router-redux';
-import reducers from '../reducers';
+import reducer from '../reducers/combinedReducer';
-const reducer = combineReducers({
- ...reducers,
- routing: routerReducer
-});
+export default function configureStore(initialState) {
+ const store = createStore(reducer, initialState, compose(
+ applyMiddleware(thunkMiddleware),
+ window.devToolsExtension ? window.devToolsExtension() : f => f
+ ));
-const createStoreWithMiddleware = compose(
- applyMiddleware(thunkMiddleware),
- window.devToolsExtension ? window.devToolsExtension() : (f) => f
-)(createStore);
+ if (module.hot) {
+ // Enable Webpack hot module replacement for reducers
+ module.hot.accept('../reducers/combinedReducer', () => {
+ const nextReducer = require('../reducers/combinedReducer') // eslint-disable-line
+ store.replaceReducer(nextReducer);
+ });
+ }
-export default (initialState) => (
- createStoreWithMiddleware(reducer, initialState)
-);
+ return store;
+}
diff --git a/test/reducers/auth.spec.js b/test/reducers/auth.spec.js
index 1d766f53..83830fd5 100644
--- a/test/reducers/auth.spec.js
+++ b/test/reducers/auth.spec.js
@@ -16,15 +16,15 @@ describe('auth', () => {
expect(
auth(undefined, authenticating())
).toEqual(
- Immutable.Map({isFetching: true})
+ Immutable.Map({ isFetching: true })
);
});
it('should handle authentication', () => {
expect(
- auth(undefined, authenticate({email: 'joe@example.com'}))
+ auth(undefined, authenticate({ email: 'joe@example.com' }))
).toEqual(
- Immutable.fromJS({user: {email: 'joe@example.com'}})
+ Immutable.fromJS({ user: { email: 'joe@example.com' } })
);
});
diff --git a/test/reducers/collections.spec.js b/test/reducers/collections.spec.js
index f3f31583..18ba43d0 100644
--- a/test/reducers/collections.spec.js
+++ b/test/reducers/collections.spec.js
@@ -15,39 +15,39 @@ describe('collections', () => {
it('should load the collections from the config', () => {
expect(
- collections(undefined, configLoaded({collections: [
- {name: 'posts', folder: '_posts', fields: [{name: 'title', widget: 'string'}]}
- ]}))
+ collections(undefined, configLoaded({ collections: [
+ { name: 'posts', folder: '_posts', fields: [{ name: 'title', widget: 'string' }] }
+ ] }))
).toEqual(
OrderedMap({
- posts: fromJS({name: 'posts', folder: '_posts', fields: [{name: 'title', widget: 'string'}]})
+ posts: fromJS({ name: 'posts', folder: '_posts', fields: [{ name: 'title', widget: 'string' }] })
})
);
});
it('should mark entries as loading', () => {
const state = OrderedMap({
- 'posts': Map({name: 'posts'})
+ 'posts': Map({ name: 'posts' })
});
expect(
- collections(state, entriesLoading(Map({name: 'posts'})))
+ collections(state, entriesLoading(Map({ name: 'posts' })))
).toEqual(
OrderedMap({
- 'posts': Map({name: 'posts', isFetching: true})
+ 'posts': Map({ name: 'posts', isFetching: true })
})
);
});
it('should handle loaded entries', () => {
const state = OrderedMap({
- 'posts': Map({name: 'posts'})
+ 'posts': Map({ name: 'posts' })
});
- const entries = [{slug: 'a', path: ''}, {slug: 'b', title: 'B'}];
+ const entries = [{ slug: 'a', path: '' }, { slug: 'b', title: 'B' }];
expect(
- collections(state, entriesLoaded(Map({name: 'posts'}), entries))
+ collections(state, entriesLoaded(Map({ name: 'posts' }), entries))
).toEqual(
OrderedMap({
- 'posts': fromJS({name: 'posts', entries: entries})
+ 'posts': fromJS({ name: 'posts', entries: entries })
})
);
});
diff --git a/test/reducers/config.spec.js b/test/reducers/config.spec.js
index 75aa9aad..9167e542 100644
--- a/test/reducers/config.spec.js
+++ b/test/reducers/config.spec.js
@@ -14,9 +14,9 @@ describe('config', () => {
it('should handle an update', () => {
expect(
- config(Immutable.Map({'a': 'b', 'c': 'd'}), configLoaded({'a': 'changed', 'e': 'new'}))
+ config(Immutable.Map({ 'a': 'b', 'c': 'd' }), configLoaded({ 'a': 'changed', 'e': 'new' }))
).toEqual(
- Immutable.Map({'a': 'changed', 'e': 'new'})
+ Immutable.Map({ 'a': 'changed', 'e': 'new' })
);
});
@@ -24,15 +24,15 @@ describe('config', () => {
expect(
config(undefined, configLoading())
).toEqual(
- Immutable.Map({isFetching: true})
+ Immutable.Map({ isFetching: true })
);
});
it('should handle an error', () => {
expect(
- config(Immutable.Map({isFetching: true}), configFailed(new Error('Config could not be loaded')))
+ config(Immutable.Map({ isFetching: true }), configFailed(new Error('Config could not be loaded')))
).toEqual(
- Immutable.Map({error: 'Error: Config could not be loaded'})
+ Immutable.Map({ error: 'Error: Config could not be loaded' })
);
});
});
diff --git a/webpack.config.js b/webpack.config.js
index b5dbcf83..94222a49 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,8 +1,10 @@
/* global module, __dirname, require */
var webpack = require('webpack');
-var ExtractTextPlugin = require('extract-text-webpack-plugin');
var path = require('path');
+const HOST = 'localhost';
+const PORT = '8080';
+
module.exports = {
module: {
loaders: [
@@ -13,7 +15,7 @@ module.exports = {
{ test: /\.json$/, loader: 'json-loader' },
{
test: /\.css$/,
- loader: ExtractTextPlugin.extract("style", "css?modules&importLoaders=1&&localIdentName=cms__[name]__[local]!postcss"),
+ loader: 'style!css?modules&importLoaders=1&&localIdentName=cms__[name]__[local]!postcss',
},
{
loader: 'babel',
@@ -22,7 +24,13 @@ module.exports = {
query: {
cacheDirectory: true,
presets: ['react', 'es2015'],
- plugins: ['transform-class-properties', 'transform-object-assign', 'transform-object-rest-spread', 'lodash']
+ plugins: [
+ 'transform-class-properties',
+ 'transform-object-assign',
+ 'transform-object-rest-spread',
+ 'lodash',
+ 'react-hot-loader/babel'
+ ]
}
}
]
@@ -34,7 +42,9 @@ module.exports = {
],
plugins: [
- new ExtractTextPlugin('cms.css', { allChunks: true }),
+ new webpack.optimize.OccurenceOrderPlugin(),
+ new webpack.HotModuleReplacementPlugin(),
+ new webpack.NoErrorsPlugin(),
new webpack.ProvidePlugin({
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
})
@@ -42,16 +52,23 @@ module.exports = {
context: path.join(__dirname, 'src'),
entry: {
- cms: './index',
+ cms: [
+ 'webpack/hot/dev-server',
+ `webpack-dev-server/client?http://${HOST}:${PORT}/`,
+ 'react-hot-loader/patch',
+ './index'
+ ],
},
output: {
path: path.join(__dirname, 'dist'),
- filename: '[name].js'
+ filename: '[name].js',
+ publicPath: `http://${HOST}:${PORT}/`,
},
- externals: [/^vendor\/.+\.js$/],
+ externals: [/^vendor\/.+\.js$/],
devServer: {
+ hot: true,
contentBase: 'example/',
historyApiFallback: true,
- devTool: 'source-map'
+ devTool: 'cheap-module-source-map'
},
};