kopia lustrzana https://github.com/wagtail/wagtail
Tooling for modern front-end components: React JS, ES6, and BEM CSS
Thanks to @justinvdm for the help Merges: #2275pull/2275/merge
rodzic
985a987436
commit
14f02a0b50
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
"es2015",
|
||||||
|
"react"
|
||||||
|
]
|
||||||
|
}
|
|
@ -6,11 +6,12 @@ build:
|
||||||
commands:
|
commands:
|
||||||
- XDG_CACHE_HOME=/drone/pip-cache pip install flake8
|
- XDG_CACHE_HOME=/drone/pip-cache pip install flake8
|
||||||
- flake8 wagtail
|
- flake8 wagtail
|
||||||
jscs:
|
js:
|
||||||
image: node:4.2.4
|
image: node:4.2.4
|
||||||
commands:
|
commands:
|
||||||
- npm install -g jscs@"^1.12.0" --quiet
|
- npm install --quiet
|
||||||
- jscs ./wagtail
|
- npm run lint
|
||||||
|
- npm run test:unit
|
||||||
scss-lint:
|
scss-lint:
|
||||||
image: wagtail-scss-lint
|
image: wagtail-scss-lint
|
||||||
commands:
|
commands:
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
node_modules
|
||||||
|
*.min.js
|
||||||
|
**/lib/
|
||||||
|
public/
|
||||||
|
coverage/
|
||||||
|
gulp/
|
||||||
|
**/vendor/
|
||||||
|
gulpfile.js
|
||||||
|
client/src/cli
|
||||||
|
wagtail/wagtailadmin/static
|
||||||
|
wagtail/wagtaildocs/static
|
||||||
|
wagtail/wagtailimages/static
|
||||||
|
wagtail/wagtailimages/static
|
||||||
|
wagtail/wagtailembeds/static
|
||||||
|
wagtail/wagtailsnippets/static
|
||||||
|
wagtail/wagtailusers/static
|
||||||
|
wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/inline_panel.js
|
||||||
|
wagtail/contrib/wagtailsearchpromotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js
|
||||||
|
wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_formset.js
|
||||||
|
wagtail/wagtailsnippets/templates/wagtailsnippets/chooser/chosen.js
|
||||||
|
wagtail/wagtailimages/templates/wagtailimages/chooser/image_chosen.js
|
||||||
|
wagtail/wagtailimages/templates/wagtailimages/chooser/chooser.js
|
||||||
|
wagtail/wagtailsearch/templates/wagtailsearch/queries/chooser/chooser.js
|
||||||
|
wagtail/wagtailimages/templates/wagtailimages/chooser/select_format.js
|
||||||
|
wagtail/wagtailembeds/templates/wagtailembeds/chooser/embed_chosen.js
|
||||||
|
wagtail/wagtailembeds/templates/wagtailembeds/chooser/chooser.js
|
||||||
|
wagtail/wagtaildocs/templates/wagtaildocs/chooser/chooser.js
|
||||||
|
wagtail/wagtaildocs/templates/wagtaildocs/chooser/document_chosen.js
|
||||||
|
wagtail/wagtailadmin/templates/wagtailadmin/page_privacy/set_privacy.js
|
||||||
|
wagtail/wagtailadmin/templates/wagtailadmin/chooser/external_link_chosen.js
|
||||||
|
wagtail/wagtailadmin/templates/wagtailadmin/chooser/external_link.js
|
||||||
|
wagtail/wagtailadmin/templates/wagtailadmin/chooser/email_link.js
|
||||||
|
wagtail/wagtailadmin/templates/wagtailadmin/chooser/browse.js
|
||||||
|
wagtail/wagtailadmin/templates/wagtailadmin/page_privacy/set_privacy_done.js
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"extends": "airbnb",
|
||||||
|
|
||||||
|
"rules": {
|
||||||
|
"indent": [2, 2],
|
||||||
|
"max-len": [1, 120, 4, {"ignoreUrls": true}],
|
||||||
|
"id-length": [1, {"min": 2, "exceptions": ["x", "y", "e", "i", "j", "k", "d", "n", "_", "$"]}],
|
||||||
|
"object-shorthand": [2, "methods"],
|
||||||
|
"no-new": [1],
|
||||||
|
"comma-dangle": [0],
|
||||||
|
"no-multi-spaces": [0],
|
||||||
|
"prefer-template": [0],
|
||||||
|
"no-var": [0],
|
||||||
|
"prefer-arrow-callback": [1],
|
||||||
|
"no-undef": [1],
|
||||||
|
"no-unused-vars": [1],
|
||||||
|
"no-warning-comments": [1, { "terms": ["todo", "fixme", "xxx"], "location": "start" }],
|
||||||
|
"react/sort-comp": [0],
|
||||||
|
"react/jsx-boolean-value": [0],
|
||||||
|
"react/jsx-no-bind": [0],
|
||||||
|
"react/prefer-es6-class": [0, 'never'],
|
||||||
|
"react/jsx-indent-props": [2, 4],
|
||||||
|
"jsx-quotes": [1, "prefer-double"]
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,3 +18,4 @@ npm-debug.log
|
||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
*.iws
|
*.iws
|
||||||
|
coverage/
|
||||||
|
|
37
.jscsrc
37
.jscsrc
|
@ -1,37 +0,0 @@
|
||||||
{
|
|
||||||
"validateIndentation": 4,
|
|
||||||
"safeContextKeyword": ["_this", "widget", "jcropapi"],
|
|
||||||
"requireSpaceBeforeKeywords": [
|
|
||||||
"else",
|
|
||||||
"while",
|
|
||||||
"catch"
|
|
||||||
],
|
|
||||||
"disallowMultipleVarDecl": "exceptUndefined",
|
|
||||||
"excludeFiles": [
|
|
||||||
"node_modules/**",
|
|
||||||
"**/*.min.js",
|
|
||||||
"**/vendor/**/*.js",
|
|
||||||
"./wagtail/wagtailadmin/static/**",
|
|
||||||
"./wagtail/wagtailadmin/templates/wagtailadmin/edit_handlers/inline_panel.js",
|
|
||||||
"./wagtail/contrib/wagtailsearchpromotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js",
|
|
||||||
"./wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_formset.js",
|
|
||||||
"./wagtail/wagtailsnippets/templates/wagtailsnippets/chooser/chosen.js",
|
|
||||||
"./wagtail/wagtailimages/templates/wagtailimages/chooser/image_chosen.js",
|
|
||||||
"./wagtail/wagtailimages/templates/wagtailimages/chooser/chooser.js",
|
|
||||||
"./wagtail/wagtailsearch/templates/wagtailsearch/queries/chooser/chooser.js",
|
|
||||||
"./wagtail/wagtailimages/templates/wagtailimages/chooser/select_format.js",
|
|
||||||
"./wagtail/wagtailembeds/templates/wagtailembeds/chooser/embed_chosen.js",
|
|
||||||
"./wagtail/wagtailembeds/templates/wagtailembeds/chooser/chooser.js",
|
|
||||||
"./wagtail/wagtaildocs/templates/wagtaildocs/chooser/chooser.js",
|
|
||||||
"./wagtail/wagtaildocs/templates/wagtaildocs/chooser/document_chosen.js",
|
|
||||||
"./wagtail/wagtailadmin/templates/wagtailadmin/page_privacy/set_privacy.js",
|
|
||||||
"./wagtail/wagtailadmin/templates/wagtailadmin/chooser/external_link_chosen.js",
|
|
||||||
"./wagtail/wagtailadmin/templates/wagtailadmin/chooser/external_link.js",
|
|
||||||
"./wagtail/wagtailadmin/templates/wagtailadmin/chooser/email_link.js",
|
|
||||||
"./wagtail/wagtailadmin/templates/wagtailadmin/chooser/browse.js",
|
|
||||||
"./wagtail/wagtailadmin/templates/wagtailadmin/page_privacy/set_privacy_done.js"
|
|
||||||
],
|
|
||||||
"fileExtensions": [".js"],
|
|
||||||
"preset":"airbnb",
|
|
||||||
"requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties"
|
|
||||||
}
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Wagtail client-side components
|
||||||
|
|
||||||
|
This library aims to give developers the ability to subclass and configure Wagtail's UI components.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install wagtail
|
||||||
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import { Explorer } from 'wagtail';
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
<Explorer onChoosePage={(page)=> { console.log(`You picked ${page}`); }} />
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Available components
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
- [ ] Explorer
|
||||||
|
- [ ] Modal
|
||||||
|
- [ ] DatePicker
|
||||||
|
- [ ] LinkChooser
|
||||||
|
- [ ] DropDown
|
||||||
|
|
||||||
|
## Building in development
|
||||||
|
|
||||||
|
Run `webpack` from the Wagtail project root.
|
||||||
|
|
||||||
|
```
|
||||||
|
webpack
|
||||||
|
```
|
||||||
|
|
||||||
|
## How to release
|
||||||
|
|
||||||
|
The front-end is bundled at the same time as the Wagtail project, via `setuptools`. You'll need to set the `__semver__` property to a npm-compliant version number in `wagtail.wagtailcore`.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"name": "wagtail",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"author": "Wagtail",
|
||||||
|
"version": "0.0.2",
|
||||||
|
"bin": {
|
||||||
|
"wagtail": "./src/cli/index.js"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "npm test"
|
||||||
|
},
|
||||||
|
"main": "src/index.js",
|
||||||
|
"description": "Wagtail's client side code",
|
||||||
|
"dependencies": {
|
||||||
|
"mustache": "^2.2.1",
|
||||||
|
"yargs": "^4.2.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
@import '../src/components/explorer/style';
|
||||||
|
@import '../src/components/loading-indicator/style';
|
||||||
|
@import '../src/components/state-indicator/style';
|
|
@ -0,0 +1 @@
|
||||||
|
@import 'objects/o.icon';
|
|
@ -0,0 +1,3 @@
|
||||||
|
.o-icon {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
.is-spinning {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
// =============================================================================
|
||||||
|
// Wagtail CMS main stylesheet
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
@import 'objects';
|
||||||
|
@import 'components';
|
||||||
|
@import 'states/states';
|
||||||
|
@import 'states/animations';
|
||||||
|
@import 'utilities/utilities';
|
||||||
|
@import 'themes/themes';
|
|
@ -0,0 +1,9 @@
|
||||||
|
.u-text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 15em) {
|
||||||
|
.u-text-center\@sm {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
var path = require('path');
|
||||||
|
var fs = require('fs');
|
||||||
|
var Mustache = require('mustache');
|
||||||
|
|
||||||
|
var TEMPLATES = path.join(__dirname, '..', '..', 'template');
|
||||||
|
|
||||||
|
var files = [
|
||||||
|
{
|
||||||
|
name: 'index.js',
|
||||||
|
template: 'component.mst'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'style.scss',
|
||||||
|
template: 'style.mst'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'README.md',
|
||||||
|
template: 'README.mst'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Helper methods
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
function slugify(text) {
|
||||||
|
return text.toString().split(/(?=[A-Z])/).join('-').toLowerCase().trim()
|
||||||
|
.replace(/\s+/g, '-') // Replace spaces with -
|
||||||
|
.replace(/&/g, '-and-') // Replace & with 'and'
|
||||||
|
.replace(/[^\w\-]+/g, '') // Remove all non-word chars
|
||||||
|
.replace(/\-\-+/g, '-'); // Replace multiple - with single -
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function write(name, data) {
|
||||||
|
fs.writeFile(name, data, function(err) {
|
||||||
|
if (err) {
|
||||||
|
return console.log('[ error ] ' + err);
|
||||||
|
}
|
||||||
|
console.log('[ created ] ' + name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Write files!
|
||||||
|
// =============================================================================
|
||||||
|
function run(argv) {
|
||||||
|
var name = argv.name;
|
||||||
|
var slug = slugify(name);
|
||||||
|
var directory = path.join(argv.dir, slug);
|
||||||
|
|
||||||
|
if (!fs.existsSync(directory)) {
|
||||||
|
fs.mkdirSync(directory);
|
||||||
|
} else {
|
||||||
|
console.warn('[ error ] ' + directory + ' already exists');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
files.forEach(function(file) {
|
||||||
|
var template = fs.readFileSync(path.join(TEMPLATES, file.template), 'utf8');
|
||||||
|
var newPath = path.join(directory, file.name);
|
||||||
|
var context = {
|
||||||
|
name: name,
|
||||||
|
slug: slug
|
||||||
|
};
|
||||||
|
|
||||||
|
write(newPath, Mustache.render(template, context));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function build(cli) {
|
||||||
|
return cli
|
||||||
|
.option('dir', {
|
||||||
|
default: process.env.PWD
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
exports.handler = run;
|
||||||
|
exports.builder = build;
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
var cli = require('yargs');
|
||||||
|
|
||||||
|
cli
|
||||||
|
.usage('Usage: $0 <command> [options]')
|
||||||
|
.help('help');
|
||||||
|
|
||||||
|
cli
|
||||||
|
.command(
|
||||||
|
'component <name>',
|
||||||
|
'scaffold out a wagtail component',
|
||||||
|
require('./component'));
|
||||||
|
|
||||||
|
cli
|
||||||
|
.argv;
|
|
@ -0,0 +1 @@
|
||||||
|
# Explorer
|
|
@ -0,0 +1,28 @@
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import StateIndicator from 'components/state-indicator';
|
||||||
|
|
||||||
|
export default class ExplorerItem extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { title, data } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="c-explorer__item">
|
||||||
|
<h3 className="c-explorer__title">
|
||||||
|
<StateIndicator state={data.state} />
|
||||||
|
{title}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExplorerItem.propTypes = {
|
||||||
|
title: PropTypes.string,
|
||||||
|
data: PropTypes.object
|
||||||
|
};
|
|
@ -0,0 +1,67 @@
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import LoadingIndicator from 'components/loading-indicator';
|
||||||
|
import ExplorerItem from './explorer-item';
|
||||||
|
|
||||||
|
import { API } from 'config';
|
||||||
|
|
||||||
|
|
||||||
|
class Explorer extends Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { cursor: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
fetch(`${API}/pages/?child_of=root`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(body => {
|
||||||
|
this.setState({
|
||||||
|
cursor: body
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount(cursor) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_getPages(cursor) {
|
||||||
|
if (!cursor) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return cursor.pages.map(item =>
|
||||||
|
<ExplorerItem key={item.id} title={item.title} data={item} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPosition() {
|
||||||
|
const { position } = this.props;
|
||||||
|
return {
|
||||||
|
left: position.right + 'px',
|
||||||
|
top: position.top + 'px'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { cursor } = this.state;
|
||||||
|
const pages = this._getPages(cursor);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={this.getPosition()} className="c-explorer">
|
||||||
|
{cursor ? pages : <LoadingIndicator />}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Explorer.propTypes = {
|
||||||
|
onPageSelect: PropTypes.func,
|
||||||
|
initialPath: PropTypes.string,
|
||||||
|
apiPath: PropTypes.string,
|
||||||
|
size: PropTypes.number,
|
||||||
|
position: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Explorer;
|
|
@ -0,0 +1,13 @@
|
||||||
|
.c-explorer {
|
||||||
|
width: 320px;
|
||||||
|
height: 500px;
|
||||||
|
background: #333;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 25;
|
||||||
|
top: 0;
|
||||||
|
left: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-explorer__item {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import Explorer from './explorer';
|
||||||
|
import LoadingIndicator from './loading-indicator';
|
||||||
|
import StateIndicator from './state-indicator';
|
||||||
|
|
||||||
|
export { Explorer };
|
||||||
|
export { LoadingIndicator };
|
||||||
|
export { StateIndicator };
|
|
@ -0,0 +1 @@
|
||||||
|
# Loading indicator
|
|
@ -0,0 +1,9 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const LoadingIndicator = () =>
|
||||||
|
<div className="o-icon c-indicator is-spinning">
|
||||||
|
<span ariaRole="presentation">Loading...</span>
|
||||||
|
</div>;
|
||||||
|
|
||||||
|
|
||||||
|
export default LoadingIndicator;
|
|
@ -0,0 +1,3 @@
|
||||||
|
.c-indicator {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
# StateIndicator
|
||||||
|
|
||||||
|
About this component
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import { StateIndicator } from 'wagtail';
|
||||||
|
```
|
|
@ -0,0 +1,16 @@
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
export default class StateIndicator extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="c-state-indicator">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
// StateIndicator
|
||||||
|
|
||||||
|
.c-state-indicator {
|
||||||
|
display: block;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export const API = '/admin/api/v2beta/';
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './components';
|
|
@ -0,0 +1,9 @@
|
||||||
|
# {{ name }}
|
||||||
|
|
||||||
|
About this component
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import { {{ name }} } from 'wagtail';
|
||||||
|
```
|
|
@ -0,0 +1,15 @@
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
|
||||||
|
export default class {{ name }} extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="c-{{ slug }}">
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
// {{ name }}
|
||||||
|
|
||||||
|
.c-{{ slug }} {
|
||||||
|
display: block;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
/*eslint-disable */
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import Explorer from '../../src/components/explorer';
|
||||||
|
|
||||||
|
|
||||||
|
describe('Explorer', () => {
|
||||||
|
it('exists', () => {
|
||||||
|
expect(Explorer).to.exist;
|
||||||
|
});
|
||||||
|
});
|
|
@ -7,6 +7,7 @@ var config = require('../config');
|
||||||
*/
|
*/
|
||||||
gulp.task('watch', ['build'], function () {
|
gulp.task('watch', ['build'], function () {
|
||||||
config.apps.forEach(function(app) {
|
config.apps.forEach(function(app) {
|
||||||
|
gulp.watch(path.join('./client/src/**/*.scss'), ['styles:sass']);
|
||||||
gulp.watch(path.join(app.sourceFiles, '*/scss/**'), ['styles:sass']);
|
gulp.watch(path.join(app.sourceFiles, '*/scss/**'), ['styles:sass']);
|
||||||
gulp.watch(path.join(app.sourceFiles, '*/css/**'), ['styles:css']);
|
gulp.watch(path.join(app.sourceFiles, '*/css/**'), ['styles:css']);
|
||||||
gulp.watch(path.join(app.sourceFiles, '*/js/**'), ['scripts']);
|
gulp.watch(path.join(app.sourceFiles, '*/js/**'), ['scripts']);
|
||||||
|
|
43
package.json
43
package.json
|
@ -11,22 +11,47 @@
|
||||||
},
|
},
|
||||||
"browserify-shim": {},
|
"browserify-shim": {},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"browserify": "~3.46.1",
|
"babel-cli": "^6.5.1",
|
||||||
"browserify-shim": "~3.4.1",
|
"babel-core": "^6.5.2",
|
||||||
|
"babel-loader": "^6.2.3",
|
||||||
|
"babel-preset-es2015": "^6.5.0",
|
||||||
|
"babel-preset-react": "^6.5.0",
|
||||||
|
"chai": "^3.5.0",
|
||||||
|
"eslint": "^2.2.0",
|
||||||
|
"eslint-config-airbnb": "^6.0.2",
|
||||||
|
"eslint-plugin-react": "^4.1.0",
|
||||||
|
"glob": "^7.0.0",
|
||||||
"gulp": "~3.8.11",
|
"gulp": "~3.8.11",
|
||||||
"gulp-autoprefixer": "~3.0.2",
|
"gulp-autoprefixer": "~3.0.2",
|
||||||
"gulp-rename": "^1.2.2",
|
"gulp-rename": "^1.2.2",
|
||||||
"gulp-sass": "~2.0.4",
|
"gulp-sass": "~2.0.4",
|
||||||
"gulp-sourcemaps": "~1.5.2",
|
"gulp-sourcemaps": "~1.5.2",
|
||||||
"gulp-util": "~2.2.14",
|
"gulp-util": "~2.2.14",
|
||||||
"jscs": "^1.12.0",
|
"isparta": "^4.0.0",
|
||||||
"require-dir": "^0.3.0"
|
"lodash": "^4.5.1",
|
||||||
|
"mocha": "^2.4.5",
|
||||||
|
"mustache": "^2.2.1",
|
||||||
|
"redux-devtools": "^3.1.1",
|
||||||
|
"require-dir": "^0.3.0",
|
||||||
|
"sinon": "^1.17.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"exports-loader": "^0.6.3",
|
||||||
|
"imports-loader": "^0.6.5",
|
||||||
|
"react-redux": "^4.4.0",
|
||||||
|
"redux": "^3.3.1",
|
||||||
|
"whatwg-fetch": "^0.11.0"
|
||||||
},
|
},
|
||||||
"dependencies": {},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "gulp build",
|
"install": "pushd ./client; npm install; popd",
|
||||||
"start": "gulp watch",
|
"build": "gulp build; webpack --progress --colors --config webpack.prd.config.js",
|
||||||
"lint:js": "./node_modules/.bin/jscs ./wagtail || true",
|
"watch": "webpack --progress --colors --config webpack.dev.config.js & gulp watch",
|
||||||
"format:js": "./node_modules/.bin/jscs ./wagtail -x"
|
"start": "npm run watch",
|
||||||
|
"lint:js": "eslint --max-warnings 16 webpack.*.config.js ./client/src",
|
||||||
|
"lint": "npm run lint:js",
|
||||||
|
"test": "npm run test:unit",
|
||||||
|
"test:unit": "env NODE_PATH=$NODE_PATH:$PWD/client/src mocha --compilers js:babel-core/register client/tests/**/*.test.js",
|
||||||
|
"test:unit:coverage": "env NODE_PATH=$NODE_PATH:$PWD/client/src babel-node $(npm bin)/isparta cover node_modules/mocha/bin/_mocha -- client/tests/**/*.test.js",
|
||||||
|
"component": "node ./client/src/cli/index.js component --dir ./client/src/components/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
from __future__ import absolute_import, print_function, unicode_literals
|
from __future__ import absolute_import, print_function, unicode_literals
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import io
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
from setuptools import Command
|
from setuptools import Command
|
||||||
from setuptools.command.bdist_egg import bdist_egg
|
from setuptools.command.bdist_egg import bdist_egg
|
||||||
from setuptools.command.sdist import sdist as base_sdist
|
from setuptools.command.sdist import sdist as base_sdist
|
||||||
|
from wagtail.wagtailcore import __semver__
|
||||||
|
|
||||||
|
|
||||||
class assets_mixin(object):
|
class assets_mixin(object):
|
||||||
|
@ -17,6 +21,37 @@ class assets_mixin(object):
|
||||||
print('Error compiling assets: ' + str(e))
|
print('Error compiling assets: ' + str(e))
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
|
def publish_assets(self):
|
||||||
|
try:
|
||||||
|
subprocess.check_call(['npm', 'publish', 'client'])
|
||||||
|
except (OSError, subprocess.CalledProcessError) as e:
|
||||||
|
print('Error publishing front-end assets: ' + str(e))
|
||||||
|
raise SystemExit(1)
|
||||||
|
|
||||||
|
def bump_client_version(self):
|
||||||
|
"""
|
||||||
|
Writes the current Wagtail version number into package.json
|
||||||
|
"""
|
||||||
|
path = os.path.join('.', 'client', 'package.json')
|
||||||
|
input_file = io.open(path, "r")
|
||||||
|
|
||||||
|
try:
|
||||||
|
package = json.loads(input_file.read().decode("utf-8"))
|
||||||
|
except (ValueError) as e:
|
||||||
|
print('Unable to read ' + path + ' ' + e)
|
||||||
|
raise SystemExit(1)
|
||||||
|
|
||||||
|
package['version'] = __semver__
|
||||||
|
|
||||||
|
try:
|
||||||
|
with io.open(path, 'w', encoding='utf-8') as f:
|
||||||
|
from django.utils import six
|
||||||
|
|
||||||
|
f.write(six.text_type(json.dumps(package, indent=2, ensure_ascii=False)))
|
||||||
|
except (IOError) as e:
|
||||||
|
print('Error setting the version for front-end assets: ' + str(e))
|
||||||
|
raise SystemExit(1)
|
||||||
|
|
||||||
|
|
||||||
class assets(Command, assets_mixin):
|
class assets(Command, assets_mixin):
|
||||||
user_options = []
|
user_options = []
|
||||||
|
@ -28,7 +63,9 @@ class assets(Command, assets_mixin):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
self.bump_client_version()
|
||||||
self.compile_assets()
|
self.compile_assets()
|
||||||
|
self.publish_assets()
|
||||||
|
|
||||||
|
|
||||||
class sdist(base_sdist, assets_mixin):
|
class sdist(base_sdist, assets_mixin):
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import Explorer from 'components/explorer';
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', e => {
|
||||||
|
const top = document.querySelector('.wrapper');
|
||||||
|
const div = document.createElement('div');
|
||||||
|
const trigger = document.querySelector('[data-explorer-menu-url]');
|
||||||
|
|
||||||
|
trigger.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
if (!div.childNodes.length) {
|
||||||
|
ReactDOM.render(<Explorer position={trigger.getBoundingClientRect()} />, div);
|
||||||
|
} else {
|
||||||
|
ReactDOM.unmountComponentAtNode(div);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
top.parentNode.appendChild(div);
|
||||||
|
});
|
|
@ -19,6 +19,12 @@
|
||||||
|
|
||||||
@import 'wagtailadmin/scss/fonts';
|
@import 'wagtailadmin/scss/fonts';
|
||||||
|
|
||||||
|
// scss-lint:disable all
|
||||||
|
#wagtail {
|
||||||
|
@import '../../../../../client/scss/style';
|
||||||
|
}
|
||||||
|
// scss-lint:enable all
|
||||||
|
|
||||||
html {
|
html {
|
||||||
background: $color-grey-4;
|
background: $color-grey-4;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<script src="{% static 'wagtailadmin/js/vendor/jquery.dlmenu.js' %}"></script>
|
<script src="{% static 'wagtailadmin/js/vendor/jquery.dlmenu.js' %}"></script>
|
||||||
<script src="{% static 'wagtailadmin/js/vendor/tag-it.js' %}"></script>
|
<script src="{% static 'wagtailadmin/js/vendor/tag-it.js' %}"></script>
|
||||||
<script src="{% static 'wagtailadmin/js/core.js' %}"></script>
|
<script src="{% static 'wagtailadmin/js/core.js' %}"></script>
|
||||||
|
|
||||||
{% main_nav_js %}
|
{% main_nav_js %}
|
||||||
|
|
||||||
{% block extra_js %}{% endblock %}
|
{% block extra_js %}{% endblock %}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
{% block branding_favicon %}{% endblock %}
|
{% block branding_favicon %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body class="{% block bodyclass %}{% endblock %} {% if messages %}has-messages{% endif %}">
|
<body id="wagtail" class="{% block bodyclass %}{% endblock %} {% if messages %}has-messages{% endif %}">
|
||||||
<!--[if lt IE 9]>
|
<!--[if lt IE 9]>
|
||||||
<p class="capabilitymessage">{% blocktrans %}You are using an <strong>outdated</strong> browser not supported by this software. Please <a href="http://browsehappy.com/">upgrade your browser</a>.{% endblocktrans %}</p>
|
<p class="capabilitymessage">{% blocktrans %}You are using an <strong>outdated</strong> browser not supported by this software. Please <a href="http://browsehappy.com/">upgrade your browser</a>.{% endblocktrans %}</p>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
__version__ = '1.4a0'
|
__version__ = '1.4a0'
|
||||||
|
# Required for npm package for frontend
|
||||||
|
__semver__ = '1.4.0-alpha'
|
||||||
default_app_config = 'wagtail.wagtailcore.apps.WagtailCoreAppConfig'
|
default_app_config = 'wagtail.wagtailcore.apps.WagtailCoreAppConfig'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
var _ = require('lodash');
|
||||||
|
var path = require('path');
|
||||||
|
var glob = require('glob').sync;
|
||||||
|
var webpack = require('webpack');
|
||||||
|
|
||||||
|
var COMMON_PATH = './wagtail/wagtailadmin/static/wagtailadmin/js/common.js';
|
||||||
|
|
||||||
|
|
||||||
|
function appName(filename) {
|
||||||
|
return _(filename)
|
||||||
|
.split(path.sep)
|
||||||
|
.get(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function entryPoint(filename) {
|
||||||
|
var name = appName(filename);
|
||||||
|
var entryName = path.basename(filename, '.entry.js');
|
||||||
|
var outputPath = path.join('wagtail', name, 'static', name, 'js', entryName);
|
||||||
|
return [outputPath, filename];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function entryPoints(paths) {
|
||||||
|
return _(glob(paths))
|
||||||
|
.map(entryPoint)
|
||||||
|
.fromPairs()
|
||||||
|
.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = function exports() {
|
||||||
|
var CLIENT_DIR = path.resolve(__dirname, 'client', 'src');
|
||||||
|
|
||||||
|
return {
|
||||||
|
entry: entryPoints('./wagtail/**/static_src/**/app/*.entry.js'),
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
components: path.resolve(CLIENT_DIR, 'components')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
path: './',
|
||||||
|
filename: '[name].js',
|
||||||
|
publicPath: '/static/js/'
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.ProvidePlugin({
|
||||||
|
fetch: 'imports?this=>global!exports?global.fetch!whatwg-fetch'
|
||||||
|
}),
|
||||||
|
new webpack.optimize.CommonsChunkPlugin('common', COMMON_PATH, Infinity)
|
||||||
|
],
|
||||||
|
devtool: '#inline-source-map',
|
||||||
|
module: {
|
||||||
|
loaders: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
loader: 'babel',
|
||||||
|
exclude: /node_modules/,
|
||||||
|
include: [
|
||||||
|
CLIENT_DIR,
|
||||||
|
path.resolve(__dirname, 'wagtail')
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.jsx$/,
|
||||||
|
loader: 'babel',
|
||||||
|
exclude: /node_modules/,
|
||||||
|
include: [
|
||||||
|
CLIENT_DIR,
|
||||||
|
path.resolve(__dirname, 'wagtail')
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
var base = require('./webpack.base.config');
|
||||||
|
var config = base('development');
|
||||||
|
|
||||||
|
|
||||||
|
// development overrides go here
|
||||||
|
config.watch = true;
|
||||||
|
|
||||||
|
module.exports = config;
|
|
@ -0,0 +1,8 @@
|
||||||
|
var base = require('./webpack.base.config');
|
||||||
|
var config = base('production');
|
||||||
|
|
||||||
|
|
||||||
|
// production overrides go here
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = config;
|
Ładowanie…
Reference in New Issue