Merge branch 'react-pr' of https://github.com/netlify/netlify-cms into react-pr
This commit is contained in:
commit
98972ae21e
@ -2,7 +2,6 @@ import { configure } from '@kadira/storybook';
|
|||||||
import '../src/index.css';
|
import '../src/index.css';
|
||||||
|
|
||||||
function loadStories() {
|
function loadStories() {
|
||||||
require('../src/containers/stories/');
|
|
||||||
require('../src/components/stories/');
|
require('../src/components/stories/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,34 +1 @@
|
|||||||
/* global module, __dirname, require */
|
module.exports = require('../webpack.base.js');
|
||||||
var webpack = require("webpack");
|
|
||||||
const path = require("path");
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
module: {
|
|
||||||
loaders: [
|
|
||||||
{
|
|
||||||
test: /\.((png)|(eot)|(woff)|(woff2)|(ttf)|(svg)|(gif))(\?v=\d+\.\d+\.\d+)?$/,
|
|
||||||
loader: 'url-loader?limit=100000'
|
|
||||||
},
|
|
||||||
{ test: /\.json$/, loader: 'json-loader' },
|
|
||||||
{
|
|
||||||
test: /\.css$/,
|
|
||||||
loader: 'style!css?modules&importLoaders=1!postcss'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
loader: 'babel',
|
|
||||||
test: /\.js?$/,
|
|
||||||
exclude: /(node_modules|bower_components)/,
|
|
||||||
query: {
|
|
||||||
cacheDirectory: true,
|
|
||||||
presets: ['react', 'es2015'],
|
|
||||||
plugins: ['transform-class-properties', 'transform-object-assign', 'transform-object-rest-spread']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
postcss: [
|
|
||||||
require("postcss-import")({addDependencyTo: webpack}),
|
|
||||||
require("postcss-cssnext")()
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"description": "Netlify CMS lets content editors work on structured content stored in git",
|
"description": "Netlify CMS lets content editors work on structured content stored in git",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "webpack-dev-server --config webpack.config.js",
|
"start": "webpack-dev-server --config webpack.dev.js",
|
||||||
"test": "NODE_ENV=test mocha --recursive --compilers js:babel-register --require ./test/setup.js",
|
"test": "NODE_ENV=test mocha --recursive --compilers js:babel-register --require ./test/setup.js",
|
||||||
"test:watch": "npm test -- --watch",
|
"test:watch": "npm test -- --watch",
|
||||||
"build": "webpack --config webpack.config.js",
|
"build": "webpack --config webpack.config.js",
|
||||||
@ -53,6 +53,7 @@
|
|||||||
"lint-staged": "^3.0.2",
|
"lint-staged": "^3.0.2",
|
||||||
"mocha": "^2.4.5",
|
"mocha": "^2.4.5",
|
||||||
"moment": "^2.11.2",
|
"moment": "^2.11.2",
|
||||||
|
"node-sass": "^3.10.0",
|
||||||
"normalizr": "^2.0.0",
|
"normalizr": "^2.0.0",
|
||||||
"postcss-cssnext": "^2.7.0",
|
"postcss-cssnext": "^2.7.0",
|
||||||
"postcss-import": "^8.1.2",
|
"postcss-import": "^8.1.2",
|
||||||
@ -69,10 +70,12 @@
|
|||||||
"react-router-redux": "^4.0.5",
|
"react-router-redux": "^4.0.5",
|
||||||
"redux": "^3.3.1",
|
"redux": "^3.3.1",
|
||||||
"redux-thunk": "^1.0.3",
|
"redux-thunk": "^1.0.3",
|
||||||
|
"sass-loader": "^4.0.2",
|
||||||
"style-loader": "^0.13.0",
|
"style-loader": "^0.13.0",
|
||||||
"url-loader": "^0.5.7",
|
"url-loader": "^0.5.7",
|
||||||
"webpack": "^1.13.2",
|
"webpack": "^1.13.2",
|
||||||
"webpack-dev-server": "^1.15.1",
|
"webpack-dev-server": "^1.15.1",
|
||||||
|
"webpack-merge": "^0.14.1",
|
||||||
"webpack-postcss-tools": "^1.1.1",
|
"webpack-postcss-tools": "^1.1.1",
|
||||||
"whatwg-fetch": "^1.0.0"
|
"whatwg-fetch": "^1.0.0"
|
||||||
},
|
},
|
||||||
@ -80,16 +83,20 @@
|
|||||||
"bricks.js": "^1.7.0",
|
"bricks.js": "^1.7.0",
|
||||||
"dateformat": "^1.0.12",
|
"dateformat": "^1.0.12",
|
||||||
"fuzzy": "^0.1.1",
|
"fuzzy": "^0.1.1",
|
||||||
|
"immutability-helper": "^2.0.0",
|
||||||
"js-base64": "^2.1.9",
|
"js-base64": "^2.1.9",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"localforage": "^1.4.2",
|
"localforage": "^1.4.2",
|
||||||
"lodash": "^4.13.1",
|
"lodash": "^4.13.1",
|
||||||
"markup-it": "git+https://github.com/cassiozen/markup-it.git",
|
"markup-it": "git+https://github.com/cassiozen/markup-it.git",
|
||||||
|
"material-design-icons": "^3.0.1",
|
||||||
|
"normalize.css": "^4.2.0",
|
||||||
"pluralize": "^3.0.0",
|
"pluralize": "^3.0.0",
|
||||||
"prismjs": "^1.5.1",
|
"prismjs": "^1.5.1",
|
||||||
"react-addons-css-transition-group": "^15.3.1",
|
"react-addons-css-transition-group": "^15.3.1",
|
||||||
"react-datetime": "^2.6.0",
|
"react-datetime": "^2.6.0",
|
||||||
"react-portal": "^2.2.1",
|
"react-portal": "^2.2.1",
|
||||||
|
"react-toolbox": "^1.2.1",
|
||||||
"react-simple-dnd": "^0.1.2",
|
"react-simple-dnd": "^0.1.2",
|
||||||
"selection-position": "^1.0.0",
|
"selection-position": "^1.0.0",
|
||||||
"semaphore": "^1.0.5",
|
"semaphore": "^1.0.5",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import history from '../routing/history';
|
import history from '../routing/history';
|
||||||
import { SEARCH } from '../containers/FindBar';
|
import { SEARCH } from '../components/UI/FindBar/FindBar';
|
||||||
|
|
||||||
export const RUN_COMMAND = 'RUN_COMMAND';
|
export const RUN_COMMAND = 'RUN_COMMAND';
|
||||||
export const SHOW_COLLECTION = 'SHOW_COLLECTION';
|
export const SHOW_COLLECTION = 'SHOW_COLLECTION';
|
||||||
@ -10,14 +10,22 @@ export function run(commandName, payload) {
|
|||||||
return { type: RUN_COMMAND, command: commandName, payload };
|
return { type: RUN_COMMAND, command: commandName, payload };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function navigateToCollection(collectionName) {
|
||||||
|
return runCommand(SHOW_COLLECTION, { collectionName });
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createNewEntryInCollection(collectionName) {
|
||||||
|
return runCommand(CREATE_COLLECTION, { collectionName });
|
||||||
|
}
|
||||||
|
|
||||||
export function runCommand(commandName, payload) {
|
export function runCommand(commandName, payload) {
|
||||||
return (dispatch, getState) => {
|
return dispatch => {
|
||||||
switch (commandName) {
|
switch (commandName) {
|
||||||
case SHOW_COLLECTION:
|
case SHOW_COLLECTION:
|
||||||
history.push(`/collections/${payload.collectionName}`);
|
history.push(`/collections/${payload.collectionName}`);
|
||||||
break;
|
break;
|
||||||
case CREATE_COLLECTION:
|
case CREATE_COLLECTION:
|
||||||
window.alert(`Create a new ${payload.collectionName} - not supported yet`);
|
history.push(`/collections/${payload.collectionName}/entries/new`);
|
||||||
break;
|
break;
|
||||||
case HELP:
|
case HELP:
|
||||||
window.alert('Find Bar Help (PLACEHOLDER)\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit.');
|
window.alert('Find Bar Help (PLACEHOLDER)\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit.');
|
||||||
|
17
src/components/UI/AppHeader/AppHeader.css
Normal file
17
src/components/UI/AppHeader/AppHeader.css
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
:root {
|
||||||
|
--foregroundColor: #fff;
|
||||||
|
--backgroundColor: #272e30;
|
||||||
|
--textFieldBorderColor: #e7e7e7;
|
||||||
|
--highlightFGColor: #fff;
|
||||||
|
--highlightBGColor: #3ab7a5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appBar {
|
||||||
|
background-color: var(--backgroundColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.createBtn {
|
||||||
|
position: fixed;
|
||||||
|
right: 2rem;
|
||||||
|
top: 3.5rem;
|
||||||
|
}
|
90
src/components/UI/AppHeader/AppHeader.js
Normal file
90
src/components/UI/AppHeader/AppHeader.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import pluralize from 'pluralize';
|
||||||
|
import { IndexLink } from 'react-router';
|
||||||
|
import { Menu, MenuItem, Button, IconButton } from 'react-toolbox';
|
||||||
|
import AppBar from 'react-toolbox/lib/app_bar';
|
||||||
|
import FindBar from '../FindBar/FindBar';
|
||||||
|
import styles from './AppHeader.css';
|
||||||
|
|
||||||
|
export default class AppHeader extends React.Component {
|
||||||
|
|
||||||
|
state = {
|
||||||
|
createMenuActive: false
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCreatePostClick = collectionName => {
|
||||||
|
const { onCreateEntryClick } = this.props;
|
||||||
|
if (onCreateEntryClick) {
|
||||||
|
onCreateEntryClick(collectionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCreateButtonClick = () => {
|
||||||
|
this.setState({
|
||||||
|
createMenuActive: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCreateMenuHide = () => {
|
||||||
|
this.setState({
|
||||||
|
createMenuActive: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
collections,
|
||||||
|
commands,
|
||||||
|
defaultCommands,
|
||||||
|
runCommand,
|
||||||
|
toggleNavDrawer
|
||||||
|
} = this.props;
|
||||||
|
const { createMenuActive } = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppBar
|
||||||
|
fixed
|
||||||
|
theme={styles}
|
||||||
|
>
|
||||||
|
<IconButton
|
||||||
|
icon="menu"
|
||||||
|
inverse
|
||||||
|
onClick={toggleNavDrawer}
|
||||||
|
/>
|
||||||
|
<IndexLink to="/">
|
||||||
|
Dashboard
|
||||||
|
</IndexLink>
|
||||||
|
<FindBar
|
||||||
|
commands={commands}
|
||||||
|
defaultCommands={defaultCommands}
|
||||||
|
runCommand={runCommand}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className={styles.createBtn}
|
||||||
|
icon='add'
|
||||||
|
floating
|
||||||
|
accent
|
||||||
|
onClick={this.handleCreateButtonClick}
|
||||||
|
>
|
||||||
|
<Menu
|
||||||
|
active={createMenuActive}
|
||||||
|
position="topRight"
|
||||||
|
onHide={this.handleCreateMenuHide}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
collections.valueSeq().map(collection =>
|
||||||
|
<MenuItem
|
||||||
|
key={collection.get('name')}
|
||||||
|
value={collection.get('name')}
|
||||||
|
onClick={this.handleCreatePostClick.bind(this, collection.get('name'))}
|
||||||
|
caption={pluralize(collection.get('label'), 1)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Menu>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
</AppBar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -7,15 +7,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.root {
|
.root {
|
||||||
|
flex: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: var(--backgroundColor);
|
background-color: var(--backgroundColor);
|
||||||
padding: 1px 0;
|
padding: 5px;
|
||||||
margin: 4px auto;
|
|
||||||
}
|
}
|
||||||
.inputArea {
|
.inputArea {
|
||||||
display: table;
|
display: table;
|
||||||
width: calc(100% - 10px);
|
width: 100%;
|
||||||
margin: 5px;
|
|
||||||
color: var(--foregroundColor);
|
color: var(--foregroundColor);
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid var(--textFieldBorderColor);
|
border: 1px solid var(--textFieldBorderColor);
|
@ -1,9 +1,7 @@
|
|||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import fuzzy from 'fuzzy';
|
import fuzzy from 'fuzzy';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { runCommand } from '../actions/findbar';
|
import { Icon } from '../index';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { Icon } from '../components/UI';
|
|
||||||
import styles from './FindBar.css';
|
import styles from './FindBar.css';
|
||||||
|
|
||||||
export const SEARCH = 'SEARCH';
|
export const SEARCH = 'SEARCH';
|
||||||
@ -102,13 +100,15 @@ class FindBar extends Component {
|
|||||||
const paramName = command && command.param ? command.param.name : null;
|
const paramName = command && command.param ? command.param.name : null;
|
||||||
const enteredParamValue = command && command.param && match[1] ? match[1].trim() : null;
|
const enteredParamValue = command && command.param && match[1] ? match[1].trim() : null;
|
||||||
|
|
||||||
|
console.log(this.props.runCommand);
|
||||||
|
|
||||||
if (command.search) {
|
if (command.search) {
|
||||||
this.setState({
|
this.setState({
|
||||||
activeScope: SEARCH,
|
activeScope: SEARCH,
|
||||||
placeholder: ''
|
placeholder: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
enteredParamValue && this.props.dispatch(runCommand(SEARCH, { searchTerm: enteredParamValue }));
|
enteredParamValue && this.props.runCommand(SEARCH, { searchTerm: enteredParamValue });
|
||||||
} else if (command.param && !enteredParamValue) {
|
} else if (command.param && !enteredParamValue) {
|
||||||
// Partial Match
|
// Partial Match
|
||||||
// Command was partially matched: It requires a param, but param wasn't entered
|
// Command was partially matched: It requires a param, but param wasn't entered
|
||||||
@ -133,7 +133,7 @@ class FindBar extends Component {
|
|||||||
if (paramName) {
|
if (paramName) {
|
||||||
payload[paramName] = enteredParamValue;
|
payload[paramName] = enteredParamValue;
|
||||||
}
|
}
|
||||||
this.props.dispatch(runCommand(command.type, payload));
|
this.props.runCommand(command.type, payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,8 +373,7 @@ FindBar.propTypes = {
|
|||||||
pattern: PropTypes.string.isRequired
|
pattern: PropTypes.string.isRequired
|
||||||
})).isRequired,
|
})).isRequired,
|
||||||
defaultCommands: PropTypes.arrayOf(PropTypes.string),
|
defaultCommands: PropTypes.arrayOf(PropTypes.string),
|
||||||
dispatch: PropTypes.func.isRequired,
|
runCommand: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export { FindBar };
|
export default FindBar;
|
||||||
export default connect()(FindBar);
|
|
@ -2,3 +2,4 @@ export { default as Card } from './card/Card';
|
|||||||
export { default as Loader } from './loader/Loader';
|
export { default as Loader } from './loader/Loader';
|
||||||
export { default as Icon } from './icon/Icon';
|
export { default as Icon } from './icon/Icon';
|
||||||
export { default as Toast } from './toast/Toast';
|
export { default as Toast } from './toast/Toast';
|
||||||
|
export { default as AppHeader } from './AppHeader/AppHeader';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { storiesOf, action } from '@kadira/storybook';
|
import { storiesOf, action } from '@kadira/storybook';
|
||||||
|
|
||||||
import { FindBar } from '../FindBar';
|
import FindBar from '../UI/FindBar/FindBar';
|
||||||
|
|
||||||
const CREATE_COLLECTION = 'CREATE_COLLECTION';
|
const CREATE_COLLECTION = 'CREATE_COLLECTION';
|
||||||
const CREATE_POST = 'CREATE_POST';
|
const CREATE_POST = 'CREATE_POST';
|
||||||
@ -30,15 +30,13 @@ const style = {
|
|||||||
margin: 20
|
margin: 20
|
||||||
};
|
};
|
||||||
|
|
||||||
const dispatch = action('DISPATCH');
|
|
||||||
|
|
||||||
storiesOf('FindBar', module)
|
storiesOf('FindBar', module)
|
||||||
.add('Default View', () => (
|
.add('Default View', () => (
|
||||||
<div style={style}>
|
<div style={style}>
|
||||||
<FindBar
|
<FindBar
|
||||||
commands={commands}
|
commands={commands}
|
||||||
defaultCommands={[CREATE_POST, CREATE_COLLECTION, OPEN_SETTINGS, HELP, MORE_COMMANDS]}
|
defaultCommands={[CREATE_POST, CREATE_COLLECTION, OPEN_SETTINGS, HELP, MORE_COMMANDS]}
|
||||||
dispatch={f => f(dispatch)}
|
runCommand={action}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
));
|
));
|
@ -1,3 +1,4 @@
|
|||||||
import './Card';
|
import './Card';
|
||||||
import './Icon';
|
import './Icon';
|
||||||
import './Toast';
|
import './Toast';
|
||||||
|
import './FindBar';
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
.layout .navDrawer .drawerContent {
|
||||||
|
padding-top: 54px;
|
||||||
|
}
|
||||||
|
.nav {
|
||||||
|
display: block;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
.main {
|
.main {
|
||||||
padding-top: 54px;
|
padding-top: 54px;
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,27 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import pluralize from 'pluralize';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { Layout, Panel, NavDrawer, Navigation, Link } from 'react-toolbox';
|
||||||
import { loadConfig } from '../actions/config';
|
import { loadConfig } from '../actions/config';
|
||||||
import { loginUser } from '../actions/auth';
|
import { loginUser } from '../actions/auth';
|
||||||
import { currentBackend } from '../backends/backend';
|
import { currentBackend } from '../backends/backend';
|
||||||
import { Loader } from '../components/UI';
|
import {
|
||||||
import { SHOW_COLLECTION, CREATE_COLLECTION, HELP } from '../actions/findbar';
|
SHOW_COLLECTION,
|
||||||
import FindBar from './FindBar';
|
CREATE_COLLECTION,
|
||||||
|
HELP,
|
||||||
|
runCommand,
|
||||||
|
navigateToCollection,
|
||||||
|
createNewEntryInCollection
|
||||||
|
} from '../actions/findbar';
|
||||||
|
import { AppHeader, Loader } from '../components/UI/index';
|
||||||
import styles from './App.css';
|
import styles from './App.css';
|
||||||
import pluralize from 'pluralize';
|
|
||||||
|
|
||||||
class App extends React.Component {
|
class App extends React.Component {
|
||||||
|
|
||||||
|
state = {
|
||||||
|
navDrawerIsVisible: false
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.dispatch(loadConfig());
|
this.props.dispatch(loadConfig());
|
||||||
}
|
}
|
||||||
@ -62,7 +74,7 @@ class App extends React.Component {
|
|||||||
id: `show_${collection.get('name')}`,
|
id: `show_${collection.get('name')}`,
|
||||||
pattern: `Show ${pluralize(collection.get('label'))}`,
|
pattern: `Show ${pluralize(collection.get('label'))}`,
|
||||||
type: SHOW_COLLECTION,
|
type: SHOW_COLLECTION,
|
||||||
payload: { collectionName:collection.get('name') }
|
payload: { collectionName: collection.get('name') }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (defaultCommands.length < 5) defaultCommands.push(`show_${collection.get('name')}`);
|
if (defaultCommands.length < 5) defaultCommands.push(`show_${collection.get('name')}`);
|
||||||
@ -72,7 +84,7 @@ class App extends React.Component {
|
|||||||
id: `create_${collection.get('name')}`,
|
id: `create_${collection.get('name')}`,
|
||||||
pattern: `Create new ${pluralize(collection.get('label'), 1)}(:itemName as ${pluralize(collection.get('label'), 1)} Name)`,
|
pattern: `Create new ${pluralize(collection.get('label'), 1)}(:itemName as ${pluralize(collection.get('label'), 1)} Name)`,
|
||||||
type: CREATE_COLLECTION,
|
type: CREATE_COLLECTION,
|
||||||
payload: { collectionName:collection.get('name') }
|
payload: { collectionName: collection.get('name') }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -83,8 +95,23 @@ class App extends React.Component {
|
|||||||
return { commands, defaultCommands };
|
return { commands, defaultCommands };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleNavDrawer = () => {
|
||||||
|
this.setState({
|
||||||
|
navDrawerIsVisible: !this.state.navDrawerIsVisible
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { user, config, children } = this.props;
|
const { navDrawerIsVisible } = this.state;
|
||||||
|
const {
|
||||||
|
user,
|
||||||
|
config,
|
||||||
|
children,
|
||||||
|
collections,
|
||||||
|
runCommand,
|
||||||
|
navigateToCollection,
|
||||||
|
createNewEntryInCollection
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
if (config === null) {
|
if (config === null) {
|
||||||
return null;
|
return null;
|
||||||
@ -105,19 +132,42 @@ class App extends React.Component {
|
|||||||
const { commands, defaultCommands } = this.generateFindBarCommands();
|
const { commands, defaultCommands } = this.generateFindBarCommands();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Layout theme={styles}>
|
||||||
<header>
|
<NavDrawer
|
||||||
<div className={styles.alignable}>
|
active={navDrawerIsVisible}
|
||||||
<FindBar
|
scrollY
|
||||||
commands={commands}
|
permanentAt="md"
|
||||||
defaultCommands={defaultCommands}
|
>
|
||||||
/>
|
<nav className={styles.nav}>
|
||||||
|
<h1>Collections</h1>
|
||||||
|
<Navigation type='vertical'>
|
||||||
|
{
|
||||||
|
collections.valueSeq().map(collection =>
|
||||||
|
<Link
|
||||||
|
key={collection.get('name')}
|
||||||
|
onClick={navigateToCollection.bind(this, collection.get('name'))}
|
||||||
|
>
|
||||||
|
{collection.get('label')}
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Navigation>
|
||||||
|
</nav>
|
||||||
|
</NavDrawer>
|
||||||
|
<Panel scrollY>
|
||||||
|
<AppHeader
|
||||||
|
collections={collections}
|
||||||
|
commands={commands}
|
||||||
|
defaultCommands={defaultCommands}
|
||||||
|
runCommand={runCommand}
|
||||||
|
onCreateEntryClick={createNewEntryInCollection}
|
||||||
|
toggleNavDrawer={this.toggleNavDrawer}
|
||||||
|
/>
|
||||||
|
<div className={`${styles.alignable} ${styles.main}`}>
|
||||||
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</Panel>
|
||||||
<div className={`${styles.alignable} ${styles.main}`}>
|
</Layout>
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,4 +179,19 @@ function mapStateToProps(state) {
|
|||||||
return { auth, config, collections, user };
|
return { auth, config, collections, user };
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps)(App);
|
function mapDispatchToProps(dispatch) {
|
||||||
|
return {
|
||||||
|
dispatch,
|
||||||
|
runCommand: (type, payload) => {
|
||||||
|
dispatch(runCommand(type, payload));
|
||||||
|
},
|
||||||
|
navigateToCollection: (collection) => {
|
||||||
|
dispatch(navigateToCollection(collection));
|
||||||
|
},
|
||||||
|
createNewEntryInCollection: (collectionName) => {
|
||||||
|
dispatch(createNewEntryInCollection(collectionName));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(App);
|
||||||
|
@ -1 +0,0 @@
|
|||||||
import './FindBar';
|
|
@ -1,3 +1,5 @@
|
|||||||
|
@import "material-icons.css";
|
||||||
|
|
||||||
html {
|
html {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-ms-text-size-adjust: 100%;
|
-ms-text-size-adjust: 100%;
|
||||||
@ -18,16 +20,6 @@ body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
|
||||||
background-color: #272e30;
|
|
||||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.22);
|
|
||||||
height: 54px;
|
|
||||||
border-bottom: 2px solid #3ab7a5;
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global #root, :global #root > * {
|
:global #root, :global #root > * {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@ -44,19 +36,6 @@ h1 {
|
|||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
header input {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
border: 1px solid #3ab7a5;
|
|
||||||
padding: 3px 20px;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 18px;
|
|
||||||
background-color: #fff;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global {
|
:global {
|
||||||
& .cms-widget {
|
& .cms-widget {
|
||||||
border-bottom: 1px solid #e8eae8;
|
border-bottom: 1px solid #e8eae8;
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render } from 'react-dom';
|
import { render } from 'react-dom';
|
||||||
import { AppContainer } from 'react-hot-loader'
|
import { AppContainer } from 'react-hot-loader';
|
||||||
import Root from './root'
|
import Root from './root';
|
||||||
import registry from './lib/registry';
|
import registry from './lib/registry';
|
||||||
import 'file?name=index.html!../example/index.html';
|
import 'file?name=index.html!../example/index.html';
|
||||||
|
import 'react-toolbox/lib/commons.scss';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
// Create mount element dynamically
|
// Create mount element dynamically
|
||||||
|
35
src/material-icons.css
Normal file
35
src/material-icons.css
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Material Icons';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Material Icons'),
|
||||||
|
local('MaterialIcons-Regular'),
|
||||||
|
url('material-design-icons/iconfont/MaterialIcons-Regular.woff2') format('woff2'),
|
||||||
|
url('material-design-icons/iconfont/MaterialIcons-Regular.woff') format('woff'),
|
||||||
|
url('material-design-icons/iconfont/MaterialIcons-Regular.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
:global .material-icons {
|
||||||
|
font-family: 'Material Icons';
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 24px; /* Preferred icon size */
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 1;
|
||||||
|
text-transform: none;
|
||||||
|
letter-spacing: normal;
|
||||||
|
word-wrap: normal;
|
||||||
|
white-space: nowrap;
|
||||||
|
direction: ltr;
|
||||||
|
|
||||||
|
/* Support for all WebKit browsers. */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
/* Support for Safari and Chrome. */
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
|
||||||
|
/* Support for Firefox. */
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
|
/* Support for IE. */
|
||||||
|
font-feature-settings: 'liga';
|
||||||
|
}
|
45
webpack.base.js
Normal file
45
webpack.base.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
const webpack = require('webpack');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
module: {
|
||||||
|
loaders: [
|
||||||
|
{
|
||||||
|
test: /\.((png)|(eot)|(woff)|(woff2)|(ttf)|(svg)|(gif))(\?v=\d+\.\d+\.\d+)?$/,
|
||||||
|
loader: 'url-loader?limit=100000'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.json$/,
|
||||||
|
loader: 'json-loader'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.scss$/,
|
||||||
|
loader: 'style!css?modules!sass',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
loader: 'style!css?modules&importLoaders=1&&localIdentName=cms__[name]__[local]!postcss',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: 'babel',
|
||||||
|
test: /\.js?$/,
|
||||||
|
exclude: /(node_modules|bower_components)/,
|
||||||
|
query: {
|
||||||
|
cacheDirectory: true,
|
||||||
|
presets: ['react', 'es2015'],
|
||||||
|
plugins: [
|
||||||
|
'transform-class-properties',
|
||||||
|
'transform-object-assign',
|
||||||
|
'transform-object-rest-spread',
|
||||||
|
'lodash',
|
||||||
|
'react-hot-loader/babel'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
postcss: [
|
||||||
|
require('postcss-import')({ addDependencyTo: webpack }),
|
||||||
|
require('postcss-cssnext')
|
||||||
|
],
|
||||||
|
};
|
@ -1,74 +0,0 @@
|
|||||||
/* global module, __dirname, require */
|
|
||||||
var webpack = require('webpack');
|
|
||||||
var path = require('path');
|
|
||||||
|
|
||||||
const HOST = 'localhost';
|
|
||||||
const PORT = '8080';
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
module: {
|
|
||||||
loaders: [
|
|
||||||
{
|
|
||||||
test: /\.((png)|(eot)|(woff)|(woff2)|(ttf)|(svg)|(gif))(\?v=\d+\.\d+\.\d+)?$/,
|
|
||||||
loader: 'url-loader?limit=100000'
|
|
||||||
},
|
|
||||||
{ test: /\.json$/, loader: 'json-loader' },
|
|
||||||
{
|
|
||||||
test: /\.css$/,
|
|
||||||
loader: 'style!css?modules&importLoaders=1&&localIdentName=cms__[name]__[local]!postcss',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
loader: 'babel',
|
|
||||||
test: /\.js?$/,
|
|
||||||
exclude: /(node_modules|bower_components)/,
|
|
||||||
query: {
|
|
||||||
cacheDirectory: true,
|
|
||||||
presets: ['react', 'es2015'],
|
|
||||||
plugins: [
|
|
||||||
'transform-class-properties',
|
|
||||||
'transform-object-assign',
|
|
||||||
'transform-object-rest-spread',
|
|
||||||
'lodash',
|
|
||||||
'react-hot-loader/babel'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
postcss: [
|
|
||||||
require('postcss-import')({ addDependencyTo: webpack }),
|
|
||||||
require('postcss-cssnext')
|
|
||||||
],
|
|
||||||
|
|
||||||
plugins: [
|
|
||||||
new webpack.optimize.OccurenceOrderPlugin(),
|
|
||||||
new webpack.HotModuleReplacementPlugin(),
|
|
||||||
new webpack.NoErrorsPlugin(),
|
|
||||||
new webpack.ProvidePlugin({
|
|
||||||
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
|
|
||||||
})
|
|
||||||
],
|
|
||||||
|
|
||||||
context: path.join(__dirname, 'src'),
|
|
||||||
entry: {
|
|
||||||
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',
|
|
||||||
publicPath: `http://${HOST}:${PORT}/`,
|
|
||||||
},
|
|
||||||
externals: [/^vendor\/.+\.js$/],
|
|
||||||
devServer: {
|
|
||||||
hot: true,
|
|
||||||
contentBase: 'example/',
|
|
||||||
historyApiFallback: true,
|
|
||||||
devTool: 'cheap-module-source-map'
|
|
||||||
},
|
|
||||||
};
|
|
37
webpack.dev.js
Normal file
37
webpack.dev.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* global module, __dirname, require */
|
||||||
|
const path = require('path');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const merge = require('webpack-merge');
|
||||||
|
const HOST = 'localhost';
|
||||||
|
const PORT = '8080';
|
||||||
|
|
||||||
|
module.exports = merge.smart(require('./webpack.base.js'), {
|
||||||
|
entry: {
|
||||||
|
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',
|
||||||
|
publicPath: `http://${HOST}:${PORT}/`,
|
||||||
|
},
|
||||||
|
context: path.join(__dirname, 'src'),
|
||||||
|
plugins: [
|
||||||
|
new webpack.optimize.OccurenceOrderPlugin(),
|
||||||
|
new webpack.HotModuleReplacementPlugin(),
|
||||||
|
new webpack.NoErrorsPlugin(),
|
||||||
|
new webpack.ProvidePlugin({
|
||||||
|
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
|
||||||
|
})
|
||||||
|
],
|
||||||
|
devServer: {
|
||||||
|
hot: true,
|
||||||
|
contentBase: 'example/',
|
||||||
|
historyApiFallback: true,
|
||||||
|
devTool: 'cheap-module-source-map'
|
||||||
|
},
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user