fix conflict

This commit is contained in:
cyril lopez 2017-09-28 12:20:52 +02:00
commit 2772219a44
67 changed files with 261 additions and 205 deletions

View File

@ -8,6 +8,8 @@ import 'babel-polyfill';
// Import all the third party stuff
import { Provider } from 'react-redux';
import React from 'react';
import ReactDOM from 'react-dom';
import { ConnectedRouter } from 'react-router-redux';
import createHistory from 'history/createBrowserHistory';
import { merge, isFunction } from 'lodash';
@ -20,7 +22,6 @@ import App from 'containers/App';
import { showNotification } from 'containers/NotificationProvider/actions';
import { pluginLoaded, updatePlugin } from 'containers/App/actions';
import { plugins } from '../../config/admin.json';
import configureStore from './store';
import { translationMessages, languages } from './i18n';
@ -147,23 +148,6 @@ window.Strapi = {
languages,
};
// Ping each plugins port defined in configuration
if (window.location.hostname === 'localhost') {
plugins.ports.forEach(pluginPort => {
// Define plugin url
const pluginUrl = `http://localhost:${pluginPort}/main.js`;
// Check that the server in running
fetch(pluginUrl)
.then(() => {
// Inject `script` tag in DOM
const script = window.document.createElement('script');
script.src = pluginUrl;
window.document.body.appendChild(script);
});
});
}
const dispatch = store.dispatch;
export {
dispatch,

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import styles from './styles.scss';
class Header extends React.Component { // eslint-disable-line react/prefer-stateless-function

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import { defineMessages, FormattedMessage } from 'react-intl';
import LocaleToggle from 'containers/LocaleToggle';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import { Link } from 'react-router-dom';
import styles from './styles.scss';

View File

@ -4,7 +4,8 @@
*
*/
import _ from 'lodash';
import React from 'react';
import { startsWith } from 'lodash';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router-dom';
@ -15,7 +16,7 @@ class LeftMenuLink extends React.Component { // eslint-disable-line react/prefer
render() {
// We need to create our own active url checker,
// because of the two levels router.
const isLinkActive = _.startsWith(window.location.pathname.replace('/admin', ''), this.props.destination);
const isLinkActive = startsWith(window.location.pathname.replace('/admin', ''), this.props.destination);
return (
<li className={styles.item}>

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { map } from 'lodash';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';

View File

@ -4,13 +4,14 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import Notification from 'components/Notification';
import styles from './styles.scss';
const { CSSTransition, TransitionGroup } = ReactTransitionGroup;
class NotificationsContainer extends React.Component { // eslint-disable-line react/prefer-stateless-function
render() {
if (this.props.notifications.length === 0) {

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import ToggleOption from 'components/ToggleOption';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from 'react-intl';

View File

@ -9,6 +9,7 @@
* the linting exception.
*/
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';

View File

@ -11,6 +11,7 @@
* the linting exception.
*/
import React from 'react';
import PropTypes from 'prop-types';
import { Switch, Route } from 'react-router-dom';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import { connect } from 'react-redux';
import Helmet from 'react-helmet';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import { connect } from 'react-redux';
import Helmet from 'react-helmet';
import { FormattedMessage } from 'react-intl';

View File

@ -6,6 +6,7 @@
* IntlProvider component and i18n messages (loaded from `app/translations`)
*/
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';

View File

@ -9,6 +9,7 @@
* the linting exception.
*/
import React from 'react';
import PropTypes from 'prop-types';
import { defineMessages, FormattedMessage } from 'react-intl';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
@ -12,7 +13,6 @@ import NotificationsContainer from 'components/NotificationsContainer';
import { selectNotifications } from './selectors';
import { hideNotification } from './actions';
export class NotificationProvider extends React.Component { // eslint-disable-line react/prefer-stateless-function
render() {
return (

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Helmet from 'react-helmet';

View File

@ -12,9 +12,5 @@
<!-- The app hooks into this div -->
<div id="app"></div>
<!-- A lot of magic happens in this file. HtmlWebpackPlugin automatically includes all assets (e.g. bundle.js, main.css) with the correct HTML tags, which is why they are missing in this HTML file. Don't add any assets here! (Check out webpackconfig.js if you want to know more) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-transition-group/2.2.0/react-transition-group.js"></script>
</body>
</html>

View File

@ -1,4 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import hoistNonReactStatics from 'hoist-non-react-statics';

View File

@ -1,4 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import hoistNonReactStatics from 'hoist-non-react-statics';

View File

@ -10,7 +10,7 @@
},
{
"method": "GET",
"path": "/:plugin/main.js",
"path": "/:plugin/:file",
"handler": "Admin.pluginFile",
"config": {
"policies": []

View File

@ -20,7 +20,7 @@ module.exports = {
pluginFile: async ctx => {
try {
const file = fs.readFileSync(path.resolve(process.cwd(), 'plugins', ctx.params.plugin, 'admin', 'build', 'main.js'));
const file = fs.readFileSync(path.resolve(process.cwd(), 'plugins', ctx.params.plugin, 'admin', 'build', `${ctx.params.file}`));
ctx.body = file;
} catch (err) {
ctx.body = ctx.notFound();

View File

@ -11,6 +11,7 @@
"preanalyze": "npm run analyze:clean",
"analyze": "node node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js",
"build": "cross-env NODE_ENV=production IS_ADMIN=true webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress",
"build:dll": "cross-env NODE_ENV=production webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.dll.babel.js --color -p --progress",
"build:clean": "rimraf admin/build",
"start": "cross-env NODE_ENV=development PORT=4000 IS_ADMIN=true node node_modules/strapi-helper-plugin/lib/server",
"generate": "plop --plopfile node_modules/strapi-helper-plugin/lib/internals/generators/index.js",
@ -22,9 +23,7 @@
"postinstall": "node node_modules/strapi-helper-plugin/lib/internals/scripts/postinstall.js"
},
"dependencies": {
"cheerio": "^1.0.0-rc.2",
"fs-extra": "^0.30.0",
"lodash": "^4.17.4",
"sanitize.css": "^4.1.0",
"strapi-utils": "3.0.0-alpha.5.5"
},

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":3,"file":"vendor.dll.js","sources":["webpack:///vendor.dll.js"],"mappings":"AAAA;;;;;AA4PA;;;;;;;;;;;;;;AA8lIA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,7 @@
* COMMON WEBPACK CONFIGURATION
*/
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
@ -9,6 +10,15 @@ const webpack = require('webpack');
const pkg = require(path.resolve(process.cwd(), 'package.json'));
const pluginId = pkg.name.replace(/^strapi-/i, '');
const plugins = process.env.IS_ADMIN === 'true' ? fs.readdirSync(path.resolve(process.env.PWD, '..', 'plugins'))
.filter(x => x[0] !== '.') : [];
const pluginFolders = plugins.reduce((acc, current) => {
acc[current] = path.resolve(process.env.PWD, '..', 'plugins', current, 'node_modules', 'strapi-helper-plugin', 'lib', 'src');
return acc;
}, {});
module.exports = (options) => ({
entry: options.entry,
output: Object.assign({ // Compile into js/build.js
@ -16,11 +26,6 @@ module.exports = (options) => ({
publicPath: '/',
}, options.output), // Merge with env dependent settings
module: {
// Comment
noParse: [
/\/react\//g,
/\/react-dom\//g,
],
loaders: [{
test: /\.js$/, // Transform all .js files required somewhere with Babel,
use: {
@ -46,11 +51,13 @@ module.exports = (options) => ({
},
},
},
include: [
path.join(process.cwd(), 'admin', 'src'),
// Add the `strapi-helper-plugin` folders watched by babel
path.join(process.cwd(), 'node_modules', 'strapi-helper-plugin', 'lib', 'src'),
],
include: [path.join(process.cwd(), 'admin', 'src')]
.concat(plugins.reduce((acc, current) => {
acc.push(path.resolve(process.env.PWD, '..', 'plugins', current, 'admin', 'src'), pluginFolders[current]);
return acc;
}, []))
.concat([path.join(process.cwd(), 'node_modules', 'strapi-helper-plugin', 'lib', 'src')])
}, {
// Transform our own .scss files
test: /\.scss$/,
@ -63,6 +70,7 @@ module.exports = (options) => ({
modules: true,
importLoaders: 1,
sourceMap: true,
minimize: process.env.NODE_ENV === 'production'
},
}, {
loader: 'postcss-loader',
@ -82,7 +90,13 @@ module.exports = (options) => ({
// So, no need for ExtractTextPlugin here.
test: /\.css$/,
include: /node_modules/,
loaders: ['style-loader', 'css-loader'],
loaders: ['style-loader', {
loader: 'css-loader',
options: {
minimize: process.env.NODE_ENV === 'production',
sourceMap: true,
}
}],
}, {
test: /\.(eot|svg|ttf|woff|woff2)$/,
loader: 'file-loader',
@ -120,7 +134,7 @@ module.exports = (options) => ({
loader: 'url-loader?limit=10000',
}],
},
plugins: options.plugins.concat([
plugins: [
new webpack.ProvidePlugin({
// make fetch available
fetch: 'exports-loader?self.fetch!whatwg-fetch',
@ -134,8 +148,8 @@ module.exports = (options) => ({
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
},
}),
new webpack.NamedModulesPlugin(),
]),
new webpack.NamedModulesPlugin()
].concat(options.plugins),
resolve: {
modules: [
'admin/src',
@ -143,12 +157,7 @@ module.exports = (options) => ({
'node_modules/strapi-helper-plugin/node_modules',
'node_modules',
],
alias: {
moment: 'moment/moment.js',
'react': 'react',
'react-dom': 'react-dom',
'react-transition-group': 'react-transition-group',
},
alias: options.alias,
symlinks: false,
extensions: [
'.js',
@ -161,7 +170,7 @@ module.exports = (options) => ({
'main',
],
},
externals: generateExternals(),
externals: options.externals,
resolveLoader: {
modules: [
path.join(__dirname, '..', '..', '..', 'node_modules'),
@ -169,13 +178,5 @@ module.exports = (options) => ({
],
},
devtool: options.devtool,
target: 'web', // Make web variables accessible to webpack, e.g. window
target: 'web', // Make web variables accessible to webpack, e.g. window,
});
function generateExternals() {
return {
'react': 'React',
'react-dom': 'ReactDOM',
'react-transition-group': 'ReactTransitionGroup',
};
}

View File

@ -11,24 +11,19 @@ const argv = require('minimist')(process.argv.slice(2));
const cssnext = require('postcss-cssnext');
const postcssFocus = require('postcss-focus');
const postcssReporter = require('postcss-reporter');
const plugins = [
new webpack.HotModuleReplacementPlugin(), // Tell webpack we want hot reloading
];
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
const isAdmin = process.env.IS_ADMIN === 'true';
const plugins = process.env.IS_ADMIN === 'true' ? fs.readdirSync(path.resolve(process.env.PWD, '..', 'plugins'))
.filter(x => x[0] !== '.') : [];
// Build the `index.htm file`
if (isAdmin) {
plugins.push(new HtmlWebpackPlugin({
favicon: 'admin/src/favicon.ico',
inject: true, // Inject all files that are generated by webpack, e.g. bundle.js
templateContent: templateContent(), // eslint-disable-line no-use-before-define
}));
}
const pluginFolders = plugins.reduce((acc, current) => {
acc[current] = path.resolve(process.env.PWD, '..', 'plugins', current, 'node_modules', 'strapi-helper-plugin', 'lib', 'src');
const appPath = isAdmin
? path.join(process.cwd(), 'admin', 'src', 'app.js')
: path.join(process.cwd(), 'node_modules', 'strapi-helper-plugin', 'lib', 'src', 'app.js');
return acc;
}, {});
const appPath = path.join(process.cwd(), 'admin', 'src', 'app.js')
const logger = require('../../server/logger');
@ -38,10 +33,17 @@ const port = argv.port || process.env.PORT || 3000;
module.exports = require('./webpack.base.babel')({
// Add hot reloading in development
entry: [
`webpack-hot-middleware/client?path=http://localhost:${port}/__webpack_hmr`,
appPath,
],
entry: Object.assign({
main: [
`webpack-hot-middleware/client?path=http://localhost:${port}/__webpack_hmr`,
appPath,
]
}, plugins.reduce((acc, current) => {
acc[current] = path.resolve(pluginFolders[current], 'app.js');
return acc;
}, {})
),
// Don't use hashes in dev mode for better performance
output: {
@ -51,7 +53,22 @@ module.exports = require('./webpack.base.babel')({
},
// Add development plugins
plugins: dependencyHandlers().concat(plugins), // eslint-disable-line no-use-before-define,
plugins: [
new webpack.HotModuleReplacementPlugin(), // Tell webpack we want hot reloading
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: 2,
}),
new LodashModuleReplacementPlugin(),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new HtmlWebpackPlugin({
favicon: 'admin/src/favicon.ico',
inject: true, // Inject all files that are generated by webpack, e.g. bundle.js
templateContent: templateContent(), // eslint-disable-line no-use-before-define
chunksSortMode: 'auto',
}),
// new BundleAnalyzerPlugin(),
], // eslint-disable-line no-use-before-define,
// Process the CSS with PostCSS
postcssPlugins: [
@ -78,80 +95,20 @@ module.exports = require('./webpack.base.babel')({
require.resolve('babel-preset-stage-0'),
require.resolve('babel-preset-react-hmre'),
],
alias: {
moment: 'moment/moment.js',
'lodash': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'lodash'),
'immutable': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'immutable'),
'react-intl': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'react-intl'),
'react': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'react'),
'react-dom': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'react-dom'),
'react-transition-group': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'react-transition-group')
},
// Emit a source map for easier debugging
devtool: 'cheap-module-eval-source-map',
devtool: 'cheap-module-source-map',
});
/**
* Select which plugins to use to optimize the bundle's handling of
* third party dependencies.
*
* If there is a dllPlugin key on the project's package.json, the
* Webpack DLL Plugin will be used. Otherwise the CommonsChunkPlugin
* will be used.
*
*/
function dependencyHandlers() {
// Don't do anything during the DLL Build step
if (process.env.BUILDING_DLL) {
return [];
}
// If the package.json does not have a dllPlugin property, use the CommonsChunkPlugin
if (!dllPlugin) {
return [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
children: true,
minChunks: 2,
async: true,
}),
];
}
const dllPath = dllPlugin.path;
/**
* If DLLs aren't explicitly defined, we assume all production dependencies listed in package.json
* Reminder: You need to exclude any server side dependencies by listing them in dllConfig.exclude
*/
if (!dllPlugin.dlls) {
const manifestPath = path.resolve(dllPath, 'strapiPluginDeps.json');
if (!fs.existsSync(manifestPath)) {
logger.error('The DLL manifest is missing. Please run `npm run build:dll`');
process.exit(0);
}
return [
new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(manifestPath), // eslint-disable-line global-require
}),
];
}
// If DLLs are explicitly defined, we automatically create a DLLReferencePlugin for each of them.
const dllManifests = Object.keys(dllPlugin.dlls).map((name) => path.join(dllPath, `/${name}.json`));
return dllManifests.map((manifestPath) => {
if (!fs.existsSync(path)) {
if (!fs.existsSync(manifestPath)) {
logger.error(`The following Webpack DLL manifest is missing: ${path.basename(manifestPath)}`);
logger.error(`Expected to find it in ${dllPath}`);
logger.error('Please run: npm run build:dll');
process.exit(0);
}
}
return new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(manifestPath), // eslint-disable-line global-require
});
});
}
/**
* We dynamically generate the HTML content in development so that the different

View File

@ -8,35 +8,55 @@
* the webpack process.
*/
const { join } = require('path');
const defaults = require('lodash/defaultsDeep');
const path = require('path');
const webpack = require('webpack');
const dllPlugin = require('../config').dllPlugin;
const helperPkg = require(join(__dirname, '..', '..', '..', 'package.json'));
const pluginPkg = require(join(process.cwd(), 'package.json'));
if (!pluginPkg.dllPlugin) { pluginPkg.dllPlugin = {}; }
const dllConfig = defaults(pluginPkg.dllPlugin, dllPlugin.defaults);
const outputPath = dllConfig.path;
module.exports = {
context: process.cwd(),
entry: dllPlugin.entry(helperPkg, pluginPkg),
devtool: 'eval',
entry: {
vendor: ['react', 'react-dom', 'react-intl', 'react-transition-group', 'immutable', 'lodash'] // Shared dependencies accross the admin and plugins.
},
devtool: 'cheap-module-source-map',
output: {
filename: '[name].dll.js',
path: outputPath,
library: '[name]',
path: path.resolve(__dirname, 'dist/'),
// The name of the global variable which the library's
// require() function will be assigned to
library: '[name]_lib',
},
plugins: [
new webpack.DllPlugin({ name: '[name]', path: join(outputPath, '[name].json') }), // eslint-disable-line no-new
new webpack.DllPlugin({
name: '[name]_lib',
path: path.join(__dirname, 'manifest.json'),
})
],
resolve: {
modules: [
'node_modules',
'admin/src',
'node_modules/strapi-helper-plugin/lib/src',
'node_modules/strapi-helper-plugin/node_modules',
'node_modules',
],
alias: {
moment: 'moment/moment.js',
'lodash': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'lodash'),
'immutable': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'immutable'),
'react-intl': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'react-intl'),
'react': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'react'),
'react-dom': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'react-dom'),
'react-transition-group': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'react-transition-group')
},
symlinks: false,
extensions: [
'.js',
'.jsx',
'.react.js',
],
mainFields: [
'browser',
'jsnext:main',
'main',
],
},
};

View File

@ -7,29 +7,34 @@ const cssnext = require('postcss-cssnext');
const postcssFocus = require('postcss-focus');
const postcssReporter = require('postcss-reporter');
const webpack = require('webpack');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
const pkg = require(path.resolve(process.cwd(), 'package.json'));
const pluginId = pkg.name.replace(/^strapi-plugin-/i, '');
const dllPlugin = pkg.dllPlugin;
const isAdmin = process.env.IS_ADMIN === 'true';
const plugins = [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
children: true,
minChunks: 2,
async: true,
new webpack.DllReferencePlugin({
manifest: require(path.join(__dirname, 'manifest.json')),
}),
// Minify and optimize the JavaScript
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false, // ...but do not show warnings in the console (there is a lot of them)
warnings: false
},
}),
new webpack.LoaderOptionsPlugin({
minimize: true
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// new BundleAnalyzerPlugin(),
];
// Build the `index.htm file`
// Build the `index.html file`
if (isAdmin) {
plugins.push(new HtmlWebpackPlugin({
template: 'admin/src/index.html',
@ -45,9 +50,14 @@ if (isAdmin) {
minifyCSS: true,
minifyURLs: true,
},
chunksSortMode: 'manual',
chunks: ['main'],
inject: true,
}));
plugins.push(new ExtractTextPlugin('[name].[contenthash].css'));
plugins.push(new AddAssetHtmlPlugin({
filepath: path.resolve(__dirname, 'dist/*.dll.js')
}));
}
const appPath = isAdmin
@ -56,9 +66,9 @@ const appPath = isAdmin
module.exports = require('./webpack.base.babel')({
// In production, we skip all hot-reloading stuff
entry: [
appPath,
],
entry: {
main: appPath
},
// Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets
output: {
@ -94,4 +104,16 @@ module.exports = require('./webpack.base.babel')({
require.resolve('babel-preset-react'),
require.resolve('babel-preset-stage-0'),
],
alias: {
moment: 'moment/moment.js',
'lodash': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'lodash'),
'immutable': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'immutable'),
'react-intl': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'react-intl'),
'react': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'react'),
'react-dom': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'react-dom'),
'react-transition-group': path.resolve(__dirname, '..', '..', '..', 'node_modules', 'react-transition-group')
},
devtool: 'cheap-module-source-map',
});

View File

@ -15,7 +15,7 @@ const addDevMiddlewares = (app, webpackConfig) => {
stats: 'errors-only',
headers: {
'Access-Control-Allow-Origin': '*',
},
}
});
app.use(middleware);

View File

@ -5,6 +5,7 @@
* only setup and plugin code.
*/
import React from 'react';
import { Provider } from 'react-redux';
import App from 'containers/App'; // eslint-disable-line

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import styles from './styles.scss';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import moment from 'moment';
import PropTypes from 'prop-types';
import { get, isEmpty, map, mapKeys, isObject, reject, includes } from 'lodash';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import PluginHeaderTitle from 'components/PluginHeaderTitle';
import PluginHeaderActions from 'components/PluginHeaderActions';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import Button from 'components/Button';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
// modal

View File

@ -1,4 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import hoistNonReactStatics from 'hoist-non-react-statics';

View File

@ -1,4 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import hoistNonReactStatics from 'hoist-non-react-statics';

View File

@ -29,6 +29,7 @@
"lint:admin"
],
"dependencies": {
"add-asset-html-webpack-plugin": "^2.1.2",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-eslint": "^7.2.3",
@ -76,6 +77,7 @@
"invariant": "2.2.1",
"json-loader": "^0.5.7",
"lodash": "^4.17.4",
"lodash-webpack-plugin": "^0.11.4",
"mocha": "3.1.2",
"moment": "^2.16.0",
"node-sass": "^4.5.3",
@ -88,15 +90,15 @@
"postcss-smart-import": "^0.7.5",
"precss": "^2.0.0",
"prettier": "^1.5.3",
"react": "^15.6.1",
"react": "^15.6.2",
"react-datetime": "^2.8.6",
"react-dom": "^15.6.1",
"react-dom": "^15.6.2",
"react-helmet": "^5.1.3",
"react-intl": "^2.3.0",
"react-redux": "^5.0.6",
"react-router-dom": "^4.1.2",
"react-router-redux": "^5.0.0-alpha.6",
"react-transition-group": "1.1.2",
"react-transition-group": "^2.2.0",
"reactstrap": "^5.0.0-alpha.1",
"redux": "^3.7.2",
"redux-immutable": "^4.0.0",
@ -106,12 +108,11 @@
"sass-loader": "^6.0.6",
"shelljs": "^0.7.8",
"style-loader": "^0.18.2",
"uglifyjs-webpack-plugin": "^1.0.0-beta.2",
"url-loader": "^0.5.9",
"webpack": "^3.5.5",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-middleware": "^1.12.0",
"webpack-hot-middleware": "^2.18.2",
"whatwg-fetch": "^2.0.3"
},
"devDependencies": {}
}
}
}

View File

@ -248,8 +248,6 @@ module.exports = function (strapi) {
case 'belongsTo':
FK = _.find(definition.associations, {alias: name});
console.log(name, FK);
if (FK && FK.nature !== 'oneToOne' && FK.nature !== 'oneToMany') {
definition.loadedModel[name] = {
type: 'virtual',

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
class Container extends React.Component {

View File

@ -5,6 +5,7 @@
*/
// Dependencies.
import React from 'react';
import PropTypes from 'prop-types';
import { findIndex, get, omit, isFunction, merge } from 'lodash';
@ -30,6 +31,10 @@ class EditForm extends React.Component {
case 'date':
case 'datetime':
return 'date';
case 'float':
case 'integer':
case 'bigint':
return 'number';
default:
return 'text';
}

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { map } from 'lodash';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { map } from 'lodash';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import { map } from 'lodash';
import PropTypes from 'prop-types';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import Select from 'react-select';
import PropTypes from 'prop-types';
import 'react-select/dist/react-select.css';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import Select from 'react-select';
import PropTypes from 'prop-types';
import 'react-select/dist/react-select.css';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import TableHeader from '../TableHeader';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import styles from './styles.scss';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import LimitSelect from '../LimitSelect';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import styles from './styles.scss';

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import { isEmpty } from 'lodash';
@ -27,8 +28,11 @@ class TableRow extends React.Component {
getDisplayedValue(type, value) {
switch (type.toLowerCase()) {
case 'string':
case 'text':
return value && !isEmpty(value.toString()) ? value.toString() : '-';
case 'float':
case 'integer':
case 'biginteger':
return value && !isEmpty(value.toString()) ? value.toString() : '-';
case 'boolean':
return value && !isEmpty(value.toString()) ? value.toString() : '-';

View File

@ -5,11 +5,12 @@
*
*/
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators, compose } from 'redux';
import { createStructuredSelector } from 'reselect';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { isEmpty, get } from 'lodash';
import { Switch, Route } from 'react-router-dom';
import injectSaga from 'utils/injectSaga';
@ -35,7 +36,7 @@ class App extends React.Component {
componentDidMount() {
const config = tryRequire('../../../../config/admin.json');
if (!_.isEmpty(_.get(config, 'admin.schema'))) {
if (!isEmpty(get(config, 'admin.schema'))) {
this.props.updateSchema(config.admin.schema);
} else {
this.props.loadModels();

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { map } from 'lodash';
import { fork, put, select, call, takeLatest } from 'redux-saga/effects';
import request from 'utils/request';
@ -16,7 +16,7 @@ export const generateMenu = function () {
.then(displayedModels => {
return [{
name: 'Content Types',
links: _.map(displayedModels, (model, key) => ({
links: map(displayedModels, (model, key) => ({
label: model.labelPlural || model.label || key,
destination: key,
})),

View File

@ -5,12 +5,13 @@
*/
// Dependencies.
import React from 'react';
import moment from 'moment';
import { connect } from 'react-redux';
import { bindActionCreators, compose } from 'redux';
import { createStructuredSelector } from 'reselect';
import PropTypes from 'prop-types';
import { map, get, isObject, isEmpty, replace } from 'lodash';
import { map, get, isObject, isEmpty, replace, toNumber } from 'lodash';
import { router } from 'app';
// Components.
@ -141,11 +142,15 @@ export class Edit extends React.Component {
}
handleChange = (e) => {
let formattedValue = e.target.value;
if (isObject(e.target.value) && e.target.value._isAMomentObject === true) {
e.target.value = moment(e.target.value, 'YYYY-MM-DD HH:mm:ss').format();
formattedValue = moment(e.target.value, 'YYYY-MM-DD HH:mm:ss').format();
} else if (['float', 'integer', 'bigint'].indexOf(this.props.schema[this.props.currentModelName].fields[e.target.name].type) !== -1) {
formattedValue = toNumber(e.target.value);
}
this.props.setRecordAttribute(e.target.name, e.target.value);
this.props.setRecordAttribute(e.target.name, formattedValue);
}
handleSubmit = (e) => {

View File

@ -2,6 +2,7 @@
* Home
*/
import React from 'react';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import { FormattedMessage } from 'react-intl';
@ -11,7 +12,7 @@ import PluginHeader from 'components/PluginHeader';
import styles from './styles.scss';
export class Home extends React.Component {
render() {
render() {
return (
<div>
<div className={`container-fluid ${styles.containerFluid}`}>

View File

@ -4,6 +4,7 @@
*
*/
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators, compose } from 'redux';
import { createStructuredSelector } from 'reselect';

View File

@ -9,6 +9,7 @@
* the linting exception.
*/
import React from 'react';
import { FormattedMessage } from 'react-intl';
export default class NotFound extends React.Component {

View File

@ -176,7 +176,7 @@ class Input extends React.Component { // eslint-disable-line react/prefer-statel
>
{map(this.props.selectOptions, (option, key) => (
option.name ?
<FormattedMessage id='select.option.message' defaultMessage='{option}' values={{ option: option.name }} key={key}>
<FormattedMessage id={option.name} defaultMessage={option.name} values={{ option: option.name }} key={key}>
{(message) => (
<option value={option.value}>
{message}

View File

@ -1,5 +1,5 @@
import 'whatwg-fetch';
import _ from 'lodash';
import { startsWith } from 'lodash';
/**
* Parses the JSON returned by a network request
@ -62,7 +62,7 @@ export default function request(url, options) {
};
// Add parameters to url
let urlFormatted = _.startsWith(url, '/')
let urlFormatted = startsWith(url, '/')
? `${Strapi.apiUrl}${url}`
: url;

View File

@ -148,7 +148,8 @@ class Strapi extends EventEmitter {
async load() {
strapi.app.use(async (ctx, next) => {
if (ctx.request.url === '/_health' && ctx.request.method === 'HEAD') {
ctx.set('strapi', 'heartbeat');
ctx.set('strapi', 'You are so French !');
ctx.set('status', 204);
} else {
await next();
}