mirror of
https://github.com/strapi/strapi.git
synced 2025-10-26 23:51:10 +00:00
Load users and email
This commit is contained in:
parent
e1d619065b
commit
61f115fbee
@ -40,6 +40,9 @@ import { translationMessages, languages } from './i18n';
|
||||
|
||||
// Create redux store with history
|
||||
import history from './utils/history';
|
||||
|
||||
import plugins from './plugins';
|
||||
|
||||
const initialState = {};
|
||||
const store = configureStore(initialState, history);
|
||||
const { dispatch } = store;
|
||||
@ -47,7 +50,18 @@ const MOUNT_NODE = document.getElementById('app');
|
||||
|
||||
// TODO remove temporary to access the admin
|
||||
|
||||
dispatch(getAppPluginsSucceeded([]));
|
||||
dispatch(getAppPluginsSucceeded(Object.keys(plugins)));
|
||||
|
||||
Object.keys(plugins).forEach(plugin => {
|
||||
const currentPlugin = plugins[plugin];
|
||||
|
||||
try {
|
||||
merge(translationMessages, currentPlugin.translationMessages);
|
||||
dispatch(pluginLoaded(currentPlugin));
|
||||
} catch (err) {
|
||||
console.log({ err });
|
||||
}
|
||||
});
|
||||
|
||||
// TODO
|
||||
const remoteURL = (() => {
|
||||
@ -63,14 +77,6 @@ const remoteURL = (() => {
|
||||
return process.env.REMOTE_URL.replace(/\/$/, '');
|
||||
})();
|
||||
|
||||
const registerPlugin = plugin => {
|
||||
// Merge admin translation messages
|
||||
merge(translationMessages, plugin.translationMessages);
|
||||
|
||||
plugin.leftMenuSections = plugin.leftMenuSections || [];
|
||||
|
||||
dispatch(pluginLoaded(plugin));
|
||||
};
|
||||
const displayNotification = (message, status) => {
|
||||
dispatch(showNotification(message, status));
|
||||
};
|
||||
@ -85,7 +91,6 @@ window.strapi = Object.assign(window.strapi || {}, {
|
||||
node: MODE || 'host',
|
||||
remoteURL,
|
||||
backendURL: BACKEND_URL,
|
||||
registerPlugin,
|
||||
notification: {
|
||||
success: message => {
|
||||
displayNotification(message, 'success');
|
||||
|
||||
@ -16,9 +16,7 @@ import styles from './styles.scss';
|
||||
|
||||
class OnboardingVideo extends React.Component {
|
||||
componentDidMount() {
|
||||
this.hiddenPlayer.current.subscribeToStateChange(
|
||||
this.handleChangeState,
|
||||
);
|
||||
this.hiddenPlayer.current.subscribeToStateChange(this.handleChangeState);
|
||||
}
|
||||
|
||||
hiddenPlayer = React.createRef();
|
||||
@ -28,7 +26,7 @@ class OnboardingVideo extends React.Component {
|
||||
handleChangeState = (state, prevState) => {
|
||||
const { duration } = state;
|
||||
const { id } = this.props;
|
||||
|
||||
|
||||
if (duration !== prevState.duration) {
|
||||
this.props.setVideoDuration(id, duration);
|
||||
}
|
||||
@ -43,14 +41,16 @@ class OnboardingVideo extends React.Component {
|
||||
}
|
||||
};
|
||||
|
||||
handleCurrentTimeChange = (curr) => {
|
||||
this.props.getVideoCurrentTime(this.props.id, curr, this.props.video.duration);
|
||||
}
|
||||
handleCurrentTimeChange = curr => {
|
||||
this.props.getVideoCurrentTime(
|
||||
this.props.id,
|
||||
curr,
|
||||
this.props.video.duration,
|
||||
);
|
||||
};
|
||||
|
||||
handleModalOpen = () => {
|
||||
this.player.current.subscribeToStateChange(
|
||||
this.handleChangeIsPlayingState,
|
||||
);
|
||||
this.player.current.subscribeToStateChange(this.handleChangeIsPlayingState);
|
||||
|
||||
this.player.current.play();
|
||||
|
||||
@ -89,7 +89,7 @@ class OnboardingVideo extends React.Component {
|
||||
key={this.props.id}
|
||||
onClick={this.props.onClick}
|
||||
id={this.props.id}
|
||||
className={cn(styles.listItem, video.end && (styles.finished))}
|
||||
className={cn(styles.listItem, video.end && styles.finished)}
|
||||
>
|
||||
<div className={styles.thumbWrapper}>
|
||||
<img src={video.preview} alt="preview" />
|
||||
@ -98,9 +98,15 @@ class OnboardingVideo extends React.Component {
|
||||
</div>
|
||||
<div className={styles.txtWrapper}>
|
||||
<p className={styles.title}>{video.title}</p>
|
||||
<p className={styles.time}>{isNaN(video.duration) ? '\xA0' : `${Math.floor(video.duration / 60)}:${Math.floor(video.duration)%60}`}</p>
|
||||
<p className={styles.time}>
|
||||
{isNaN(video.duration)
|
||||
? '\xA0'
|
||||
: `${Math.floor(video.duration / 60)}:${Math.floor(
|
||||
video.duration,
|
||||
) % 60}`}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<Modal
|
||||
isOpen={video.isOpen}
|
||||
toggle={this.props.onClick} // eslint-disable-line react/jsx-handler-names
|
||||
@ -119,7 +125,7 @@ class OnboardingVideo extends React.Component {
|
||||
<Player
|
||||
ref={this.player}
|
||||
className={styles.videoPlayer}
|
||||
poster="/assets/poster.png"
|
||||
// poster="/assets/poster.png"
|
||||
src={video.video}
|
||||
startTime={video.startTime}
|
||||
preload="auto"
|
||||
@ -135,7 +141,7 @@ class OnboardingVideo extends React.Component {
|
||||
<div className={cn(styles.hiddenPlayerWrapper)}>
|
||||
<Player
|
||||
ref={this.hiddenPlayer}
|
||||
poster="/assets/poster.png"
|
||||
// poster="/assets/poster.png"
|
||||
src={video.video}
|
||||
preload="auto"
|
||||
subscribeToStateChange={this.subscribeToStateChange}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { includes, isEmpty } from 'lodash';
|
||||
|
||||
@ -48,7 +49,7 @@ class Row extends React.Component {
|
||||
onClick: e => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.context.router.history.push(settingsPath);
|
||||
this.props.history.push(settingsPath);
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -106,7 +107,6 @@ class Row extends React.Component {
|
||||
|
||||
Row.contextTypes = {
|
||||
currentEnvironment: PropTypes.string,
|
||||
router: PropTypes.object,
|
||||
};
|
||||
|
||||
Row.propTypes = {
|
||||
@ -117,4 +117,4 @@ Row.propTypes = {
|
||||
pluginActionSucceeded: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export default Row;
|
||||
export default withRouter(Row);
|
||||
|
||||
@ -18,7 +18,7 @@ const initialState = fromJS({
|
||||
blockApp: false,
|
||||
overlayBlockerData: null,
|
||||
hasUserPlugin: true,
|
||||
isAppLoading: false,
|
||||
isAppLoading: true,
|
||||
plugins: {},
|
||||
showGlobalAppBlocker: true,
|
||||
});
|
||||
|
||||
@ -14,12 +14,19 @@ import { IntlProvider } from 'react-intl';
|
||||
import { defaultsDeep } from 'lodash';
|
||||
import { selectLocale } from './selectors';
|
||||
|
||||
export class LanguageProvider extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
export class LanguageProvider extends React.Component {
|
||||
// eslint-disable-line react/prefer-stateless-function
|
||||
render() {
|
||||
const messages = defaultsDeep(this.props.messages[this.props.locale], this.props.messages.en);
|
||||
|
||||
const messages = defaultsDeep(
|
||||
this.props.messages[this.props.locale],
|
||||
this.props.messages.en,
|
||||
);
|
||||
return (
|
||||
<IntlProvider locale={this.props.locale} defaultLocale="en" messages={messages}>
|
||||
<IntlProvider
|
||||
locale={this.props.locale}
|
||||
defaultLocale="en"
|
||||
messages={messages}
|
||||
>
|
||||
{React.Children.only(this.props.children)}
|
||||
</IntlProvider>
|
||||
);
|
||||
@ -32,10 +39,9 @@ LanguageProvider.propTypes = {
|
||||
messages: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
selectLocale(),
|
||||
(locale) => ({ locale })
|
||||
locale => ({ locale }),
|
||||
);
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
@ -44,4 +50,7 @@ function mapDispatchToProps(dispatch) {
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(LanguageProvider);
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
)(LanguageProvider);
|
||||
|
||||
23
packages/strapi-admin/admin/src/plugins.js
Normal file
23
packages/strapi-admin/admin/src/plugins.js
Normal file
@ -0,0 +1,23 @@
|
||||
// console.log(window);
|
||||
const injectReducer = require('./utils/injectReducer').default;
|
||||
const injectSaga = require('./utils/injectSaga').default;
|
||||
const { languages } = require('./i18n');
|
||||
|
||||
window.strapi = Object.assign(window.strapi || {}, {
|
||||
node: MODE || 'host',
|
||||
backendURL: BACKEND_URL,
|
||||
languages,
|
||||
currentLanguage:
|
||||
window.localStorage.getItem('strapi-admin-language') ||
|
||||
window.navigator.language ||
|
||||
window.navigator.userLanguage ||
|
||||
'en',
|
||||
injectReducer,
|
||||
injectSaga,
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
email: require('../../../strapi-plugin-email/admin/src').default,
|
||||
'users-permissions': require('../../../strapi-plugin-users-permissions/admin/src')
|
||||
.default,
|
||||
};
|
||||
@ -28,11 +28,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.4.3",
|
||||
"@babel/runtime": "^7.4.3",
|
||||
"classnames": "^2.2.6",
|
||||
"crypto": "^1.0.1",
|
||||
"friendly-errors-webpack-plugin": "^1.7.0",
|
||||
"history": "^4.9.0",
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"immutable": "^3.8.2",
|
||||
"intl": "^1.2.5",
|
||||
"invariant": "^2.2.4",
|
||||
@ -56,7 +56,6 @@
|
||||
"redux-saga": "^0.16.0",
|
||||
"remove-markdown": "^0.2.2",
|
||||
"reselect": "^3.0.1",
|
||||
"shelljs": "^0.7.8",
|
||||
"strapi-helper-plugin": "3.0.0-alpha.25.2",
|
||||
"video-react": "^0.13.2"
|
||||
},
|
||||
@ -74,7 +73,9 @@
|
||||
"css-loader": "^2.1.1",
|
||||
"duplicate-package-checker-webpack-plugin": "^3.0.0",
|
||||
"file-loader": "^3.0.1",
|
||||
"friendly-errors-webpack-plugin": "^1.7.0",
|
||||
"html-loader": "^0.5.5",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"image-webpack-loader": "^4.6.0",
|
||||
"mini-css-extract-plugin": "^0.6.0",
|
||||
"node-sass": "^4.11.0",
|
||||
@ -84,6 +85,7 @@
|
||||
"precss": "^4.0.0",
|
||||
"sanitize.css": "^4.1.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"shelljs": "^0.7.8",
|
||||
"simple-progress-webpack-plugin": "^1.1.2",
|
||||
"strapi-utils": "3.0.0-alpha.25.2",
|
||||
"style-loader": "^0.23.1",
|
||||
@ -110,4 +112,4 @@
|
||||
"npm": ">= 6.0.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
const path = require('path');
|
||||
const alias = [
|
||||
'core-js',
|
||||
'create-react-context',
|
||||
'invariant',
|
||||
'hoist-non-react-statics',
|
||||
const pkg = require('./package.json');
|
||||
|
||||
const alias = Object.keys(pkg.dependencies).concat([
|
||||
'object-assign',
|
||||
'react-popper',
|
||||
'reactstrap',
|
||||
'whatwg-fetch',
|
||||
];
|
||||
]);
|
||||
|
||||
module.exports = alias.reduce((acc, curr) => {
|
||||
acc[curr] = path.resolve(__dirname, 'node_modules', curr);
|
||||
|
||||
@ -91,11 +91,6 @@ module.exports = {
|
||||
{
|
||||
test: /\.m?js$/,
|
||||
exclude: /node_modules/,
|
||||
include: [
|
||||
path.resolve(__dirname, 'admin/src'),
|
||||
path.resolve(__dirname, '../strapi-helper-plugin/lib/src'),
|
||||
path.resolve(__dirname, 'node_modules/strapi-helper-plugin/lib/src'),
|
||||
],
|
||||
use: {
|
||||
loader: require.resolve('babel-loader'),
|
||||
options: {
|
||||
|
||||
@ -107,6 +107,7 @@ strapi.registerPlugin({
|
||||
layout,
|
||||
lifecycles,
|
||||
leftMenuLinks: [],
|
||||
leftMenuSections: [],
|
||||
mainComponent: Comp,
|
||||
name: pluginPkg.strapi.name,
|
||||
preventComponentRendering: false,
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
.helperContainerFluid {
|
||||
padding: 18px 30px;
|
||||
padding: 18px 30px !important;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
.headerNav { /* stylelint-disable */
|
||||
|
||||
.headerNav {
|
||||
/* stylelint-disable */
|
||||
}
|
||||
|
||||
.headerContainer {
|
||||
@ -8,10 +8,11 @@
|
||||
overflow: hidden;
|
||||
margin-top: 4.3rem;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 2px 4px #E3E9F3;
|
||||
box-shadow: 0 2px 4px #e3e9f3;
|
||||
> a {
|
||||
box-shadow: 1px 0 0px rgba(#DBDBDB, 0.5), inset 0px -1px 0px -2px rgba(#DBDBDB, 0.5);
|
||||
background-color: #F5F5F5;
|
||||
box-shadow: 1px 0 0px rgba(#dbdbdb, 0.5),
|
||||
inset 0px -1px 0px -2px rgba(#dbdbdb, 0.5);
|
||||
background-color: #f5f5f5;
|
||||
&:first-child {
|
||||
border-radius: 2px 0 0 0;
|
||||
}
|
||||
@ -28,7 +29,7 @@
|
||||
// max-width: 33%;
|
||||
height: 3.6rem;
|
||||
border-radius: 2px 0 0 0;
|
||||
background-color: darken(#F5F5F5, 50%);
|
||||
background-color: darken(#f5f5f5, 50%);
|
||||
text-decoration: none !important;
|
||||
font-family: Lato;
|
||||
font-size: 1.3rem;
|
||||
@ -38,30 +39,37 @@
|
||||
|
||||
.linkActive {
|
||||
z-index: 10;
|
||||
&:not(:first-child, :last-child) {
|
||||
background-color: #ffffff !important;
|
||||
font-weight: bold;
|
||||
text-decoration: none !important;
|
||||
box-shadow: 0 0 2px rgba(#dbdbdb, 0.5);
|
||||
border-top: 0.2rem solid #1c5de7;
|
||||
}
|
||||
}
|
||||
|
||||
.linkActive:first-child {
|
||||
background-color: #FFFFFF!important;
|
||||
background-color: #ffffff !important;
|
||||
font-weight: bold;
|
||||
text-decoration: none !important;
|
||||
box-shadow: 0 0 2px rgba(#DBDBDB, 0.5);
|
||||
border-top: 0.2rem solid #1C5DE7;
|
||||
box-shadow: 0 0 2px rgba(#dbdbdb, 0.5);
|
||||
border-top: 0.2rem solid #1c5de7;
|
||||
}
|
||||
|
||||
.linkActive:last-child {
|
||||
background-color: #FFFFFF!important;
|
||||
background-color: #ffffff !important;
|
||||
font-weight: bold;
|
||||
text-decoration: none !important;
|
||||
box-shadow: 0 0 2px rgba(#DBDBDB, 0.5);
|
||||
border-top: 0.2rem solid #1C5DE7;
|
||||
box-shadow: 0 0 2px rgba(#dbdbdb, 0.5);
|
||||
border-top: 0.2rem solid #1c5de7;
|
||||
}
|
||||
|
||||
.linkActive:not(:first-child, :last-child) {
|
||||
background-color: #FFFFFF!important;
|
||||
background-color: #ffffff !important;
|
||||
font-weight: bold;
|
||||
text-decoration: none !important;
|
||||
box-shadow: 0 0 2px rgba(#DBDBDB, 0.5);
|
||||
border-top: 0.2rem solid #1C5DE7;
|
||||
box-shadow: 0 0 2px rgba(#dbdbdb, 0.5);
|
||||
border-top: 0.2rem solid #1c5de7;
|
||||
}
|
||||
|
||||
.linkText {
|
||||
@ -71,10 +79,10 @@
|
||||
}
|
||||
|
||||
.notifPoint {
|
||||
height: 0.4rem;
|
||||
height: 0.4rem;
|
||||
width: 0.4rem;
|
||||
margin: 1px 0 0 0.7rem;
|
||||
align-self: center;
|
||||
border-radius: 0.5rem;
|
||||
background-color: #27B70F;
|
||||
background-color: #27b70f;
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
.textInput {
|
||||
height: 3.4rem;
|
||||
margin-top: .9rem;
|
||||
margin-top: 0.9rem;
|
||||
padding-left: 1rem;
|
||||
background-size: 0 !important;
|
||||
border: 1px solid #E3E9F3;
|
||||
border: 1px solid #e3e9f3;
|
||||
border-radius: 0.25rem;
|
||||
line-height: 3.4rem;
|
||||
font-size: 1.3rem;
|
||||
|
||||
@ -12,6 +12,7 @@ export {
|
||||
export { default as ErrorBoundary } from './components/ErrorBoundary';
|
||||
export { default as ExtendComponent } from './components/ExtendComponent';
|
||||
export { default as GlobalPagination } from './components/GlobalPagination';
|
||||
export { default as HeaderNav } from './components/HeaderNav';
|
||||
export { default as IcoContainer } from './components/IcoContainer';
|
||||
export { default as InputAddon } from './components/InputAddon';
|
||||
|
||||
@ -22,10 +23,10 @@ export { default as InputCheckbox } from './components/InputCheckbox';
|
||||
export {
|
||||
default as InputCheckboxWithErrors,
|
||||
} from './components/InputCheckboxWithErrors';
|
||||
// export { default as InputDate } from './components/InputDate';
|
||||
// export {
|
||||
// default as InputDateWithErrors,
|
||||
// } from './components/InputDateWithErrors';
|
||||
export { default as InputDate } from './components/InputDate';
|
||||
export {
|
||||
default as InputDateWithErrors,
|
||||
} from './components/InputDateWithErrors';
|
||||
export { default as InputEmail } from './components/InputEmail';
|
||||
export {
|
||||
default as InputEmailWithErrors,
|
||||
|
||||
@ -67,6 +67,7 @@
|
||||
"rollup-plugin-postcss": "^2.0.3",
|
||||
"rollup-plugin-sass": "^1.2.2",
|
||||
"rollup-plugin-scss": "^1.0.1",
|
||||
"rollup-plugin-sizes": "^0.5.1",
|
||||
"rollup-plugin-svg": "^1.0.1",
|
||||
"shelljs": "^0.7.8"
|
||||
},
|
||||
@ -90,4 +91,4 @@
|
||||
"styled-components": "^3.2.6",
|
||||
"whatwg-fetch": "^2.0.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ export default {
|
||||
format: 'cjs',
|
||||
sourceMap: true,
|
||||
name: 'strapi-helper-plugin',
|
||||
compact: true,
|
||||
},
|
||||
{
|
||||
exports: 'named',
|
||||
@ -21,6 +22,7 @@ export default {
|
||||
file: pkg.module,
|
||||
format: 'es',
|
||||
name: 'strapi-helper-plugin',
|
||||
compact: true,
|
||||
},
|
||||
],
|
||||
|
||||
@ -34,6 +36,7 @@ export default {
|
||||
resolve(),
|
||||
commonjs(),
|
||||
svg(),
|
||||
require('rollup-plugin-sizes')(),
|
||||
],
|
||||
|
||||
external: [
|
||||
|
||||
@ -7,26 +7,30 @@
|
||||
import React from 'react';
|
||||
import { findIndex, get, isEmpty, map } from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
// You can find these components in either
|
||||
// ./node_modules/strapi-helper-plugin/lib/src
|
||||
// or strapi/packages/strapi-helper-plugin/lib/src
|
||||
import Input from 'components/InputsIndex';
|
||||
import { InputsIndex as Input } from 'strapi-helper-plugin';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class EditForm extends React.Component {
|
||||
getProviderForm = () => get(this.props.settings, ['providers', this.props.selectedProviderIndex, 'auth'], {});
|
||||
class EditForm extends React.Component {
|
||||
getProviderForm = () =>
|
||||
get(
|
||||
this.props.settings,
|
||||
['providers', this.props.selectedProviderIndex, 'auth'],
|
||||
{},
|
||||
);
|
||||
|
||||
generateSelectOptions = () => (
|
||||
Object.keys(get(this.props.settings, 'providers', {})).reduce((acc, current) => {
|
||||
const option = {
|
||||
id: get(this.props.settings, ['providers', current, 'name']),
|
||||
value: get(this.props.settings, ['providers', current, 'provider']),
|
||||
};
|
||||
acc.push(option);
|
||||
return acc;
|
||||
}, [])
|
||||
)
|
||||
generateSelectOptions = () =>
|
||||
Object.keys(get(this.props.settings, 'providers', {})).reduce(
|
||||
(acc, current) => {
|
||||
const option = {
|
||||
id: get(this.props.settings, ['providers', current, 'name']),
|
||||
value: get(this.props.settings, ['providers', current, 'provider']),
|
||||
};
|
||||
acc.push(option);
|
||||
return acc;
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
render() {
|
||||
return (
|
||||
@ -34,7 +38,9 @@ class EditForm extends React.Component {
|
||||
<div className="row">
|
||||
<Input
|
||||
customBootstrapClass="col-md-6"
|
||||
inputDescription={{ id: 'email.EditForm.Input.select.inputDescription' }}
|
||||
inputDescription={{
|
||||
id: 'email.EditForm.Input.select.inputDescription',
|
||||
}}
|
||||
inputClassName={styles.inputStyle}
|
||||
label={{ id: 'email.EditForm.Input.select.label' }}
|
||||
name="provider"
|
||||
@ -50,7 +56,10 @@ class EditForm extends React.Component {
|
||||
{map(this.getProviderForm(), (value, key) => (
|
||||
<Input
|
||||
didCheckErrors={this.props.didCheckErrors}
|
||||
errors={get(this.props.formErrors, [findIndex(this.props.formErrors, ['name', key]), 'errors'])}
|
||||
errors={get(this.props.formErrors, [
|
||||
findIndex(this.props.formErrors, ['name', key]),
|
||||
'errors',
|
||||
])}
|
||||
key={key}
|
||||
label={{ id: value.label }}
|
||||
name={key}
|
||||
|
||||
@ -13,22 +13,14 @@ import { findIndex, get, isEmpty } from 'lodash';
|
||||
// You can find these components in either
|
||||
// ./node_modules/strapi-helper-plugin/lib/src
|
||||
// or strapi/packages/strapi-helper-plugin/lib/src
|
||||
import ContainerFluid from 'components/ContainerFluid';
|
||||
import HeaderNav from 'components/HeaderNav';
|
||||
import PluginHeader from 'components/PluginHeader';
|
||||
import { ContainerFluid, HeaderNav, PluginHeader } from 'strapi-helper-plugin';
|
||||
|
||||
import pluginId from '../../pluginId';
|
||||
|
||||
// Plugin's components
|
||||
import EditForm from '../../components/EditForm';
|
||||
|
||||
import {
|
||||
getSettings,
|
||||
onCancel,
|
||||
onChange,
|
||||
setErrors,
|
||||
submit,
|
||||
} from './actions';
|
||||
import { getSettings, onCancel, onChange, setErrors, submit } from './actions';
|
||||
|
||||
import reducer from './reducer';
|
||||
import saga from './saga';
|
||||
@ -47,35 +39,55 @@ class ConfigPage extends React.Component {
|
||||
|
||||
// Redirect the user to the email list after modifying is provider
|
||||
if (prevProps.submitSuccess !== this.props.submitSuccess) {
|
||||
this.props.history.push(`/plugins/email/configurations/${this.props.match.params.env}`);
|
||||
this.props.history.push(
|
||||
`/plugins/email/configurations/${this.props.match.params.env}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
getSelectedProviderIndex = () => findIndex(this.props.settings.providers, ['provider', get(this.props.modifiedData, 'provider')]);
|
||||
getSelectedProviderIndex = () =>
|
||||
findIndex(this.props.settings.providers, [
|
||||
'provider',
|
||||
get(this.props.modifiedData, 'provider'),
|
||||
]);
|
||||
|
||||
/**
|
||||
* Get Settings depending on the props
|
||||
* @param {Object} props
|
||||
* @return {Func} calls the saga that gets the current settings
|
||||
*/
|
||||
getSettings = (props) => {
|
||||
const { match: { params: { env} } } = props;
|
||||
getSettings = props => {
|
||||
const {
|
||||
match: {
|
||||
params: { env },
|
||||
},
|
||||
} = props;
|
||||
this.props.getSettings(env);
|
||||
}
|
||||
};
|
||||
|
||||
generateLinks = () => {
|
||||
const headerNavLinks = this.props.appEnvironments.reduce((acc, current) => {
|
||||
const link = Object.assign(current, { to: `/plugins/email/configurations/${current.name}` });
|
||||
acc.push(link);
|
||||
return acc;
|
||||
}, []).sort(link => link.name === 'production');
|
||||
const headerNavLinks = this.props.appEnvironments
|
||||
.reduce((acc, current) => {
|
||||
const link = Object.assign(current, {
|
||||
to: `/plugins/email/configurations/${current.name}`,
|
||||
});
|
||||
acc.push(link);
|
||||
return acc;
|
||||
}, [])
|
||||
.sort(link => link.name === 'production');
|
||||
|
||||
return headerNavLinks;
|
||||
}
|
||||
};
|
||||
|
||||
handleSubmit = (e) => {
|
||||
handleSubmit = e => {
|
||||
e.preventDefault();
|
||||
const formErrors = Object.keys(get(this.props.settings, ['providers', this.getSelectedProviderIndex(), 'auth'], {})).reduce((acc, current) => {
|
||||
const formErrors = Object.keys(
|
||||
get(
|
||||
this.props.settings,
|
||||
['providers', this.getSelectedProviderIndex(), 'auth'],
|
||||
{},
|
||||
),
|
||||
).reduce((acc, current) => {
|
||||
if (isEmpty(get(this.props.modifiedData, current, ''))) {
|
||||
acc.push({
|
||||
name: current,
|
||||
@ -90,7 +102,7 @@ class ConfigPage extends React.Component {
|
||||
}
|
||||
|
||||
return this.props.submit();
|
||||
}
|
||||
};
|
||||
|
||||
pluginHeaderActions = [
|
||||
{
|
||||
@ -115,7 +127,7 @@ class ConfigPage extends React.Component {
|
||||
<PluginHeader
|
||||
actions={this.pluginHeaderActions}
|
||||
description={{ id: 'email.ConfigPage.description' }}
|
||||
title={{ id: 'email.ConfigPage.title'}}
|
||||
title={{ id: 'email.ConfigPage.title' }}
|
||||
/>
|
||||
<HeaderNav links={this.generateLinks()} />
|
||||
<EditForm
|
||||
@ -174,9 +186,16 @@ function mapDispatchToProps(dispatch) {
|
||||
|
||||
const mapStateToProps = selectConfigPage();
|
||||
|
||||
const withConnect = connect(mapStateToProps, mapDispatchToProps);
|
||||
const withConnect = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
);
|
||||
|
||||
const withReducer = strapi.injectReducer({ key: 'configPage', reducer, pluginId });
|
||||
const withReducer = strapi.injectReducer({
|
||||
key: 'configPage',
|
||||
reducer,
|
||||
pluginId,
|
||||
});
|
||||
const withSaga = strapi.injectSaga({ key: 'configPage', saga, pluginId });
|
||||
|
||||
export default compose(
|
||||
|
||||
@ -1,18 +1,9 @@
|
||||
// import { LOCATION_CHANGE } from 'react-router-redux';
|
||||
import { all, call, fork, put, select, takeLatest } from 'redux-saga/effects';
|
||||
import request from 'utils/request';
|
||||
import {
|
||||
getSettingsSucceeded,
|
||||
submitSucceeded,
|
||||
} from './actions';
|
||||
import {
|
||||
GET_SETTINGS,
|
||||
SUBMIT,
|
||||
} from './constants';
|
||||
import {
|
||||
makeSelectEnv,
|
||||
makeSelectModifiedData,
|
||||
} from './selectors';
|
||||
import { request } from 'strapi-helper-plugin';
|
||||
import { getSettingsSucceeded, submitSucceeded } from './actions';
|
||||
import { GET_SETTINGS, SUBMIT } from './constants';
|
||||
import { makeSelectEnv, makeSelectModifiedData } from './selectors';
|
||||
|
||||
export function* settingsGet(action) {
|
||||
try {
|
||||
@ -23,7 +14,7 @@ export function* settingsGet(action) {
|
||||
]);
|
||||
|
||||
yield put(getSettingsSucceeded(response[0], response[1].environments));
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
strapi.notification.error('notification.error');
|
||||
}
|
||||
}
|
||||
@ -46,7 +37,7 @@ export function* submit() {
|
||||
// Update reducer with optimisticResponse
|
||||
strapi.notification.success('email.notification.config.success');
|
||||
yield put(submitSucceeded(body));
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
strapi.notification.error('notification.error');
|
||||
// TODO handle error PUT
|
||||
}
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
/**
|
||||
* NotFoundPage
|
||||
*
|
||||
* This is the page we show when the user visits a url that doesn't have a route
|
||||
*
|
||||
* NOTE: while this component should technically be a stateless functional
|
||||
* component (SFC), hot reloading does not currently support SFCs. If hot
|
||||
* reloading is not a neccessity for you then you can refactor it and remove
|
||||
* the linting exception.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import NotFound from 'components/NotFound';
|
||||
|
||||
export default class NotFoundPage extends React.Component {
|
||||
render() {
|
||||
return <NotFound {...this.props} />;
|
||||
}
|
||||
}
|
||||
93
packages/strapi-plugin-email/admin/src/index.js
Normal file
93
packages/strapi-plugin-email/admin/src/index.js
Normal file
@ -0,0 +1,93 @@
|
||||
import React from 'react';
|
||||
import { reduce } from 'lodash';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginId from './pluginId';
|
||||
|
||||
import App from './containers/App';
|
||||
|
||||
const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
|
||||
|
||||
const formatMessages = messages =>
|
||||
reduce(
|
||||
messages,
|
||||
(result, value, key) => {
|
||||
result[`${pluginId}.${key}`] = value;
|
||||
|
||||
return result;
|
||||
},
|
||||
{},
|
||||
);
|
||||
const requireTranslations = language => {
|
||||
try {
|
||||
return require(`./translations/${language}.json`); // eslint-disable-line global-require
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`Unable to load "${language}" translation for the plugin ${pluginId}. Please make sure "${language}.json" file exists in "pluginPath/admin/src/translations" folder.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const translationMessages = reduce(
|
||||
strapi.languages,
|
||||
(result, language) => {
|
||||
result[language] = formatMessages(requireTranslations(language));
|
||||
return result;
|
||||
},
|
||||
{},
|
||||
);
|
||||
const layout = (() => {
|
||||
try {
|
||||
return require('../../config/layout.js'); // eslint-disable-line import/no-unresolved
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
|
||||
const injectedComponents = (() => {
|
||||
try {
|
||||
return require('./injectedComponents').default; // eslint-disable-line import/no-unresolved
|
||||
} catch (err) {
|
||||
return [];
|
||||
}
|
||||
})();
|
||||
|
||||
const initializer = (() => {
|
||||
try {
|
||||
return require('./initializer');
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
|
||||
const lifecycles = (() => {
|
||||
try {
|
||||
return require('./lifecycles');
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
|
||||
function Comp(props) {
|
||||
return <App {...props} />;
|
||||
}
|
||||
|
||||
const plugin = {
|
||||
blockerComponent: null,
|
||||
blockerComponentProps: {},
|
||||
description: pluginDescription,
|
||||
icon: pluginPkg.strapi.icon,
|
||||
id: pluginId,
|
||||
initializer,
|
||||
injectedComponents,
|
||||
layout,
|
||||
lifecycles,
|
||||
leftMenuLinks: [],
|
||||
leftMenuSections: [],
|
||||
mainComponent: Comp,
|
||||
name: pluginPkg.strapi.name,
|
||||
preventComponentRendering: false,
|
||||
translationMessages,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
@ -1,21 +1,21 @@
|
||||
/**
|
||||
*
|
||||
* EditForm
|
||||
*
|
||||
*/
|
||||
*
|
||||
* EditForm
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { get } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
|
||||
import LoadingIndicator from 'components/LoadingIndicator';
|
||||
import Input from 'components/InputsIndex';
|
||||
import { InputsIndex as Input, LoadingIndicator } from 'strapi-helper-plugin';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class EditForm extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
generateSelectOptions = () => (
|
||||
class EditForm extends React.Component {
|
||||
// eslint-disable-line react/prefer-stateless-function
|
||||
generateSelectOptions = () =>
|
||||
Object.keys(get(this.props.values, 'roles', [])).reduce((acc, current) => {
|
||||
const option = {
|
||||
id: get(this.props.values.roles, [current, 'name']),
|
||||
@ -23,13 +23,17 @@ class EditForm extends React.Component { // eslint-disable-line react/prefer-sta
|
||||
};
|
||||
acc.push(option);
|
||||
return acc;
|
||||
}, [])
|
||||
)
|
||||
}, []);
|
||||
|
||||
render() {
|
||||
if (this.props.showLoaders) {
|
||||
return (
|
||||
<div className={cn(styles.editForm, this.props.showLoaders && styles.loadIndicatorContainer)}>
|
||||
<div
|
||||
className={cn(
|
||||
styles.editForm,
|
||||
this.props.showLoaders && styles.loadIndicatorContainer,
|
||||
)}
|
||||
>
|
||||
<LoadingIndicator />
|
||||
</div>
|
||||
);
|
||||
@ -39,7 +43,9 @@ class EditForm extends React.Component { // eslint-disable-line react/prefer-sta
|
||||
<div className={styles.editForm}>
|
||||
<div className="row">
|
||||
<Input
|
||||
inputDescription={{ id: 'users-permissions.EditForm.inputSelect.description.role' }}
|
||||
inputDescription={{
|
||||
id: 'users-permissions.EditForm.inputSelect.description.role',
|
||||
}}
|
||||
inputClassName={styles.inputStyle}
|
||||
label={{ id: 'users-permissions.EditForm.inputSelect.label.role' }}
|
||||
name="advanced.settings.default_role"
|
||||
@ -53,7 +59,9 @@ class EditForm extends React.Component { // eslint-disable-line react/prefer-sta
|
||||
<div className="row">
|
||||
<Input
|
||||
label={{ id: 'users-permissions.EditForm.inputToggle.label.email' }}
|
||||
inputDescription={{ id: 'users-permissions.EditForm.inputToggle.description.email' }}
|
||||
inputDescription={{
|
||||
id: 'users-permissions.EditForm.inputToggle.description.email',
|
||||
}}
|
||||
name="advanced.settings.unique_email"
|
||||
onChange={this.props.onChange}
|
||||
type="toggle"
|
||||
@ -89,8 +97,12 @@ class EditForm extends React.Component { // eslint-disable-line react/prefer-sta
|
||||
*/}
|
||||
<div className="row">
|
||||
<Input
|
||||
label={{ id: 'users-permissions.EditForm.inputToggle.label.sign-up' }}
|
||||
inputDescription={{ id: 'users-permissions.EditForm.inputToggle.description.sign-up' }}
|
||||
label={{
|
||||
id: 'users-permissions.EditForm.inputToggle.label.sign-up',
|
||||
}}
|
||||
inputDescription={{
|
||||
id: 'users-permissions.EditForm.inputToggle.description.sign-up',
|
||||
}}
|
||||
name="advanced.settings.allow_register"
|
||||
onChange={this.props.onChange}
|
||||
type="toggle"
|
||||
@ -100,8 +112,14 @@ class EditForm extends React.Component { // eslint-disable-line react/prefer-sta
|
||||
<div className={styles.separator} />
|
||||
<div className="row">
|
||||
<Input
|
||||
label={{ id: 'users-permissions.EditForm.inputToggle.label.email-confirmation' }}
|
||||
inputDescription={{ id: 'users-permissions.EditForm.inputToggle.description.email-confirmation' }}
|
||||
label={{
|
||||
id:
|
||||
'users-permissions.EditForm.inputToggle.label.email-confirmation',
|
||||
}}
|
||||
inputDescription={{
|
||||
id:
|
||||
'users-permissions.EditForm.inputToggle.description.email-confirmation',
|
||||
}}
|
||||
name="advanced.settings.email_confirmation"
|
||||
onChange={this.props.onChange}
|
||||
type="toggle"
|
||||
@ -110,12 +128,21 @@ class EditForm extends React.Component { // eslint-disable-line react/prefer-sta
|
||||
</div>
|
||||
<div className="row">
|
||||
<Input
|
||||
label={{ id: 'users-permissions.EditForm.inputToggle.label.email-confirmation-redirection' }}
|
||||
inputDescription={{ id: 'users-permissions.EditForm.inputToggle.description.email-confirmation-redirection' }}
|
||||
label={{
|
||||
id:
|
||||
'users-permissions.EditForm.inputToggle.label.email-confirmation-redirection',
|
||||
}}
|
||||
inputDescription={{
|
||||
id:
|
||||
'users-permissions.EditForm.inputToggle.description.email-confirmation-redirection',
|
||||
}}
|
||||
name="advanced.settings.email_confirmation_redirection"
|
||||
onChange={this.props.onChange}
|
||||
type="text"
|
||||
value={get(this.props.values.settings, 'email_confirmation_redirection')}
|
||||
value={get(
|
||||
this.props.values.settings,
|
||||
'email_confirmation_redirection',
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
*
|
||||
* InputSearchContainer
|
||||
*
|
||||
*/
|
||||
*
|
||||
* InputSearchContainer
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
@ -10,12 +10,13 @@ import { findIndex, has, includes, isEmpty, map, toLower } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Label from 'components/Label';
|
||||
import { Label } from 'strapi-helper-plugin';
|
||||
import InputSearchLi from '../InputSearchLi';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputSearchContainer extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
class InputSearchContainer extends React.Component {
|
||||
// eslint-disable-line react/prefer-stateless-function
|
||||
state = {
|
||||
errors: [],
|
||||
filteredUsers: this.props.values,
|
||||
@ -27,11 +28,17 @@ class InputSearchContainer extends React.Component { // eslint-disable-line reac
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.didDeleteUser !== this.props.didDeleteUser) {
|
||||
this.setState({ users: nextProps.values, filteredUsers: nextProps.values });
|
||||
this.setState({
|
||||
users: nextProps.values,
|
||||
filteredUsers: nextProps.values,
|
||||
});
|
||||
}
|
||||
|
||||
if (nextProps.didGetUsers !== this.props.didGetUsers) {
|
||||
this.setState({ users: nextProps.values, filteredUsers: nextProps.values });
|
||||
this.setState({
|
||||
users: nextProps.values,
|
||||
filteredUsers: nextProps.values,
|
||||
});
|
||||
}
|
||||
|
||||
if (nextProps.didFetchUsers !== this.props.didFetchUsers) {
|
||||
@ -42,24 +49,31 @@ class InputSearchContainer extends React.Component { // eslint-disable-line reac
|
||||
handleBlur = () => this.setState({ isFocused: !this.state.isFocused });
|
||||
|
||||
handleChange = ({ target }) => {
|
||||
const filteredUsers = isEmpty(target.value) ?
|
||||
this.state.users
|
||||
: this.state.users.filter((user) => includes(toLower(user.name), toLower(target.value)));
|
||||
const filteredUsers = isEmpty(target.value)
|
||||
? this.state.users
|
||||
: this.state.users.filter(user =>
|
||||
includes(toLower(user.name), toLower(target.value)),
|
||||
);
|
||||
|
||||
if (isEmpty(filteredUsers) && !isEmpty(target.value)) {
|
||||
this.props.getUser(target.value);
|
||||
}
|
||||
|
||||
if (isEmpty(target.value)) {
|
||||
return this.setState({ value: target.value, isAdding: false, users: this.props.values, filteredUsers: this.props.values });
|
||||
return this.setState({
|
||||
value: target.value,
|
||||
isAdding: false,
|
||||
users: this.props.values,
|
||||
filteredUsers: this.props.values,
|
||||
});
|
||||
}
|
||||
|
||||
this.setState({ value: target.value, filteredUsers });
|
||||
}
|
||||
};
|
||||
|
||||
handleFocus = () => this.setState({ isFocused: !this.state.isFocused });
|
||||
|
||||
handleClick = (item) => {
|
||||
handleClick = item => {
|
||||
if (this.state.isAdding) {
|
||||
const id = has(item, '_id') ? '_id' : 'id';
|
||||
const users = this.props.values;
|
||||
@ -72,22 +86,36 @@ class InputSearchContainer extends React.Component { // eslint-disable-line reac
|
||||
// Reset the input focus
|
||||
this.searchInput.focus();
|
||||
// Empty the input and display users
|
||||
this.setState({ value: '', isAdding: false, users, filteredUsers: users });
|
||||
this.setState({
|
||||
value: '',
|
||||
isAdding: false,
|
||||
users,
|
||||
filteredUsers: users,
|
||||
});
|
||||
} else {
|
||||
this.props.onClickDelete(item);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={cn(styles.inputSearch, 'col-md-6')}>
|
||||
<Label htmlFor={this.props.name} message={this.props.label} />
|
||||
<div className={cn('input-group')}>
|
||||
<span className={cn('input-group-addon', styles.addon, this.state.isFocused && styles.addonFocus,)} />
|
||||
<span
|
||||
className={cn(
|
||||
'input-group-addon',
|
||||
styles.addon,
|
||||
this.state.isFocused && styles.addonFocus,
|
||||
)}
|
||||
/>
|
||||
<FormattedMessage id="users-permissions.InputSearch.placeholder">
|
||||
{(message) => (
|
||||
{message => (
|
||||
<input
|
||||
className={cn('form-control', !isEmpty(this.state.errors) ? 'is-invalid': '')}
|
||||
className={cn(
|
||||
'form-control',
|
||||
!isEmpty(this.state.errors) ? 'is-invalid' : '',
|
||||
)}
|
||||
id={this.props.name}
|
||||
name={this.props.name}
|
||||
onBlur={this.handleBlur}
|
||||
@ -96,14 +124,21 @@ class InputSearchContainer extends React.Component { // eslint-disable-line reac
|
||||
value={this.state.value}
|
||||
placeholder={message}
|
||||
type="text"
|
||||
ref={(input) => { this.searchInput = input; }}
|
||||
ref={input => {
|
||||
this.searchInput = input;
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</FormattedMessage>
|
||||
</div>
|
||||
<div className={cn(styles.ulContainer, this.state.isFocused && styles.ulFocused)}>
|
||||
<div
|
||||
className={cn(
|
||||
styles.ulContainer,
|
||||
this.state.isFocused && styles.ulFocused,
|
||||
)}
|
||||
>
|
||||
<ul>
|
||||
{map(this.state.filteredUsers, (user) => (
|
||||
{map(this.state.filteredUsers, user => (
|
||||
<InputSearchLi
|
||||
key={user.id || user._id}
|
||||
item={user}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
*
|
||||
* List
|
||||
*
|
||||
*/
|
||||
*
|
||||
* List
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
@ -11,11 +11,8 @@ import { map, omitBy, size } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
|
||||
// Components from strapi-helper-plugin
|
||||
import LoadingBar from 'components/LoadingBar';
|
||||
import LoadingIndicator from 'components/LoadingIndicator';
|
||||
import { Button, LoadingBar, LoadingIndicator } from 'strapi-helper-plugin';
|
||||
|
||||
// Design
|
||||
import Button from 'components/Button';
|
||||
import ListRow from '../ListRow';
|
||||
|
||||
import styles from './styles.scss';
|
||||
@ -23,57 +20,117 @@ import styles from './styles.scss';
|
||||
const generateListTitle = (data, settingType) => {
|
||||
switch (settingType) {
|
||||
case 'roles': {
|
||||
const title = size(data) < 2 ?
|
||||
<FormattedMessage id="users-permissions.List.title.roles.singular" values={{ number: size(data) }} />
|
||||
: <FormattedMessage id="users-permissions.List.title.roles.plural" values={{ number: size(data) }} />;
|
||||
const title =
|
||||
size(data) < 2 ? (
|
||||
<FormattedMessage
|
||||
id="users-permissions.List.title.roles.singular"
|
||||
values={{ number: size(data) }}
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="users-permissions.List.title.roles.plural"
|
||||
values={{ number: size(data) }}
|
||||
/>
|
||||
);
|
||||
|
||||
return title;
|
||||
}
|
||||
case 'providers': {
|
||||
const enabledProvidersSize = data.filter(o => o.enabled).length;
|
||||
|
||||
const enabledProviders = enabledProvidersSize > 1 ?
|
||||
<FormattedMessage id="users-permissions.List.title.providers.enabled.plural" values={{ number: enabledProvidersSize }} />
|
||||
: <FormattedMessage id="users-permissions.List.title.providers.enabled.singular" values={{ number: enabledProvidersSize }} />;
|
||||
const enabledProviders =
|
||||
enabledProvidersSize > 1 ? (
|
||||
<FormattedMessage
|
||||
id="users-permissions.List.title.providers.enabled.plural"
|
||||
values={{ number: enabledProvidersSize }}
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="users-permissions.List.title.providers.enabled.singular"
|
||||
values={{ number: enabledProvidersSize }}
|
||||
/>
|
||||
);
|
||||
|
||||
const disabledProviders = size(data) - enabledProvidersSize > 1 ?
|
||||
<FormattedMessage id="users-permissions.List.title.providers.disabled.plural" values={{ number: size(data) - enabledProvidersSize }} />
|
||||
: <FormattedMessage id="users-permissions.List.title.providers.disabled.singular" values={{ number: size(data) - enabledProvidersSize }} />;
|
||||
|
||||
return <div>{enabledProviders} {disabledProviders}</div>;
|
||||
const disabledProviders =
|
||||
size(data) - enabledProvidersSize > 1 ? (
|
||||
<FormattedMessage
|
||||
id="users-permissions.List.title.providers.disabled.plural"
|
||||
values={{ number: size(data) - enabledProvidersSize }}
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="users-permissions.List.title.providers.disabled.singular"
|
||||
values={{ number: size(data) - enabledProvidersSize }}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{enabledProviders} {disabledProviders}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
case 'email-templates': {
|
||||
return size(data) > 1 ?
|
||||
<FormattedMessage id="users-permissions.List.title.emailTemplates.plural" values={{ number: size(data) }} />
|
||||
: <FormattedMessage id="users-permissions.List.title.emailTemplates.singular" values={{ number: size(data) }} />;
|
||||
return size(data) > 1 ? (
|
||||
<FormattedMessage
|
||||
id="users-permissions.List.title.emailTemplates.plural"
|
||||
values={{ number: size(data) }}
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="users-permissions.List.title.emailTemplates.singular"
|
||||
values={{ number: size(data) }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
function List({ data, deleteData, noButton, onButtonClick, settingType, showLoaders, values }) {
|
||||
const object = omitBy(data, (v) => v.name === 'server'); // Remove the server key when displaying providers
|
||||
function List({
|
||||
data,
|
||||
deleteData,
|
||||
noButton,
|
||||
onButtonClick,
|
||||
settingType,
|
||||
showLoaders,
|
||||
values,
|
||||
}) {
|
||||
const object = omitBy(data, v => v.name === 'server'); // Remove the server key when displaying providers
|
||||
|
||||
return (
|
||||
<div className={styles.list}>
|
||||
<div className={styles.flex}>
|
||||
<div className={styles.titleContainer}>
|
||||
{showLoaders ? <LoadingBar style={{ marginTop: '0' }} /> : generateListTitle(data, settingType)}
|
||||
{showLoaders ? (
|
||||
<LoadingBar style={{ marginTop: '0' }} />
|
||||
) : (
|
||||
generateListTitle(data, settingType)
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.buttonContainer}>
|
||||
{noButton ? (
|
||||
''
|
||||
) : (
|
||||
<Button onClick={onButtonClick} secondaryHotlineAdd>
|
||||
<FormattedMessage id={`users-permissions.List.button.${settingType}`} />
|
||||
<FormattedMessage
|
||||
id={`users-permissions.List.button.${settingType}`}
|
||||
/>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={cn(styles.ulContainer, showLoaders && styles.loadingContainer, showLoaders && settingType === 'roles' && styles.loadingContainerRole )}>
|
||||
{showLoaders ? <LoadingIndicator /> : (
|
||||
<div
|
||||
className={cn(
|
||||
styles.ulContainer,
|
||||
showLoaders && styles.loadingContainer,
|
||||
showLoaders && settingType === 'roles' && styles.loadingContainerRole,
|
||||
)}
|
||||
>
|
||||
{showLoaders ? (
|
||||
<LoadingIndicator />
|
||||
) : (
|
||||
<ul className={noButton ? styles.listPadded : ''}>
|
||||
{map(object, item => (
|
||||
<ListRow
|
||||
|
||||
@ -11,8 +11,7 @@ import { FormattedMessage } from 'react-intl';
|
||||
import { capitalize, get, includes } from 'lodash';
|
||||
|
||||
// Design
|
||||
import IcoContainer from 'components/IcoContainer';
|
||||
import PopUpWarning from 'components/PopUpWarning';
|
||||
import { IcoContainer, PopUpWarning } from 'strapi-helper-plugin';
|
||||
|
||||
import en from '../../translations/en.json';
|
||||
import styles from './styles.scss';
|
||||
@ -88,10 +87,10 @@ class ListRow extends React.Component {
|
||||
get(this.props.item, 'name'),
|
||||
'enabled',
|
||||
]) ? (
|
||||
<span style={{ color: '#5A9E06' }}>Enabled</span>
|
||||
) : (
|
||||
<span style={{ color: '#F64D0A' }}>Disabled</span>
|
||||
)}
|
||||
<span style={{ color: '#5A9E06' }}>Enabled</span>
|
||||
) : (
|
||||
<span style={{ color: '#F64D0A' }}>Disabled</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="col-md-2">
|
||||
<IcoContainer icons={icons} />
|
||||
@ -185,7 +184,7 @@ ListRow.contextTypes = {
|
||||
ListRow.defaultProps = {
|
||||
item: {
|
||||
name: 'Owner',
|
||||
description: "Rule them all. This role can't be deleted",
|
||||
description: 'Rule them all. This role can\'t be deleted',
|
||||
nb_users: 1,
|
||||
icon: 'envelope',
|
||||
},
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
*
|
||||
* Policies
|
||||
*
|
||||
*/
|
||||
*
|
||||
* Policies
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import cn from 'classnames';
|
||||
@ -10,24 +10,42 @@ import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { get, isEmpty, map, takeRight, toLower, without } from 'lodash';
|
||||
|
||||
import Input from 'components/InputsIndex';
|
||||
import { InputsIndex as Input } from 'strapi-helper-plugin';
|
||||
import BoundRoute from '../BoundRoute';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class Policies extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
handleChange = (e) => this.context.onChange(e);
|
||||
class Policies extends React.Component {
|
||||
// eslint-disable-line react/prefer-stateless-function
|
||||
handleChange = e => this.context.onChange(e);
|
||||
|
||||
render() {
|
||||
const baseTitle = 'users-permissions.Policies.header';
|
||||
const title = this.props.shouldDisplayPoliciesHint ? 'hint' : 'title';
|
||||
const value = get(this.props.values, this.props.inputSelectName);
|
||||
const path = without(this.props.inputSelectName.split('.'), 'permissions', 'controllers', 'policy');
|
||||
const controllerRoutes = get(this.props.routes, without(this.props.inputSelectName.split('.'), 'permissions', 'controllers', 'policy')[0]);
|
||||
const routes = isEmpty(controllerRoutes) ? [] : controllerRoutes.filter(o => toLower(o.handler) === toLower(takeRight(path, 2).join('.')));
|
||||
const path = without(
|
||||
this.props.inputSelectName.split('.'),
|
||||
'permissions',
|
||||
'controllers',
|
||||
'policy',
|
||||
);
|
||||
const controllerRoutes = get(
|
||||
this.props.routes,
|
||||
without(
|
||||
this.props.inputSelectName.split('.'),
|
||||
'permissions',
|
||||
'controllers',
|
||||
'policy',
|
||||
)[0],
|
||||
);
|
||||
const routes = isEmpty(controllerRoutes)
|
||||
? []
|
||||
: controllerRoutes.filter(
|
||||
o => toLower(o.handler) === toLower(takeRight(path, 2).join('.')),
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={cn('col-md-5',styles.policies)}>
|
||||
<div className={cn('col-md-5', styles.policies)}>
|
||||
<div className="container-fluid">
|
||||
<div className={cn('row', styles.inputWrapper)}>
|
||||
<div className={cn('col-md-12', styles.header)}>
|
||||
@ -44,12 +62,16 @@ class Policies extends React.Component { // eslint-disable-line react/prefer-sta
|
||||
validations={{}}
|
||||
value={value}
|
||||
/>
|
||||
) : ''}
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</div>
|
||||
<div className="row">
|
||||
{!this.props.shouldDisplayPoliciesHint ? (
|
||||
map(routes, (route, key) => <BoundRoute key={key} route={route} />)
|
||||
) : ''}
|
||||
{!this.props.shouldDisplayPoliciesHint
|
||||
? map(routes, (route, key) => (
|
||||
<BoundRoute key={key} route={route} />
|
||||
))
|
||||
: ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -23,7 +23,7 @@ import {
|
||||
takeRight,
|
||||
} from 'lodash';
|
||||
|
||||
import Input from 'components/InputsIndex';
|
||||
import { InputsIndex as Input } from 'strapi-helper-plugin';
|
||||
|
||||
// Translations
|
||||
import en from '../../translations/en.json';
|
||||
|
||||
@ -33,13 +33,21 @@ class App extends React.Component {
|
||||
return (
|
||||
<div className={pluginId}>
|
||||
<Switch>
|
||||
<Route path={`/plugins/${pluginId}/auth/:authType/:id?`} component={AuthPage} exact />
|
||||
<Route
|
||||
path={`/plugins/${pluginId}/auth/:authType/:id?`}
|
||||
component={AuthPage}
|
||||
exact
|
||||
/>
|
||||
<Route
|
||||
path={`/plugins/${pluginId}/:settingType/:actionType/:id?`}
|
||||
component={EditPage}
|
||||
exact
|
||||
/>
|
||||
<Route path={`/plugins/${pluginId}/:settingType`} component={HomePage} exact />
|
||||
<Route
|
||||
path={`/plugins/${pluginId}/:settingType`}
|
||||
component={HomePage}
|
||||
exact
|
||||
/>
|
||||
<Route component={NotFoundPage} />
|
||||
</Switch>
|
||||
</div>
|
||||
|
||||
@ -14,11 +14,7 @@ import { findIndex, get, isBoolean, isEmpty, map, replace } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
|
||||
// Design
|
||||
import Button from 'components/Button';
|
||||
import Input from 'components/InputsIndex';
|
||||
|
||||
// Utils
|
||||
import auth from 'utils/auth';
|
||||
import { auth, Button, InputsIndex as Input } from 'strapi-helper-plugin';
|
||||
|
||||
import pluginId from '../../pluginId';
|
||||
|
||||
@ -39,20 +35,19 @@ import makeSelectAuthPage from './selectors';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
export class AuthPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
export class AuthPage extends React.Component {
|
||||
// eslint-disable-line react/prefer-stateless-function
|
||||
componentDidMount() {
|
||||
auth.clearAppStorage();
|
||||
this.setForm();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const {
|
||||
const {
|
||||
hideLoginErrorsInput,
|
||||
match: {
|
||||
params : {
|
||||
authType,
|
||||
},
|
||||
},
|
||||
match: {
|
||||
params: { authType },
|
||||
},
|
||||
submitSuccess,
|
||||
} = this.props;
|
||||
|
||||
@ -64,7 +59,7 @@ export class AuthPage extends React.Component { // eslint-disable-line react/pre
|
||||
if (submitSuccess) {
|
||||
switch (authType) {
|
||||
case 'login':
|
||||
case 'reset-password':
|
||||
case 'reset-password':
|
||||
// Check if we have token to handle redirection to login or admin.
|
||||
// Done to prevent redirection to admin after reset password if user should
|
||||
// not have access.
|
||||
@ -86,46 +81,71 @@ export class AuthPage extends React.Component { // eslint-disable-line react/pre
|
||||
getFormErrors = () => {
|
||||
const { formErrors } = this.props;
|
||||
return get(formErrors, ['0', 'errors', '0', 'id']);
|
||||
}
|
||||
};
|
||||
|
||||
setForm = () => {
|
||||
const {
|
||||
location: {
|
||||
search,
|
||||
},
|
||||
location: { search },
|
||||
match: {
|
||||
params: {
|
||||
authType,
|
||||
id,
|
||||
},
|
||||
params: { authType, id },
|
||||
},
|
||||
setForm,
|
||||
} = this.props;
|
||||
setForm,
|
||||
} = this.props;
|
||||
const params = search ? replace(search, '?code=', '') : id;
|
||||
|
||||
|
||||
setForm(authType, params);
|
||||
}
|
||||
};
|
||||
|
||||
isAuthType = type => {
|
||||
const { match: { params: { authType } } } = this.props;
|
||||
const {
|
||||
match: {
|
||||
params: { authType },
|
||||
},
|
||||
} = this.props;
|
||||
return authType === type;
|
||||
}
|
||||
|
||||
handleSubmit = (e) => {
|
||||
};
|
||||
|
||||
handleSubmit = e => {
|
||||
const { modifiedData, setErrors, submit } = this.props;
|
||||
e.preventDefault();
|
||||
const formErrors = Object.keys(modifiedData).reduce((acc, key) => {
|
||||
if (isEmpty(get(modifiedData, key)) && !isBoolean(get(modifiedData, key))) {
|
||||
acc.push({ name: key, errors: [{ id: 'components.Input.error.validation.required' }] });
|
||||
if (
|
||||
isEmpty(get(modifiedData, key)) &&
|
||||
!isBoolean(get(modifiedData, key))
|
||||
) {
|
||||
acc.push({
|
||||
name: key,
|
||||
errors: [{ id: 'components.Input.error.validation.required' }],
|
||||
});
|
||||
}
|
||||
|
||||
if (!isEmpty(get(modifiedData, 'password')) && !isEmpty(get(modifiedData, 'confirmPassword')) && findIndex(acc, ['name', 'confirmPassword']) === -1) {
|
||||
if (
|
||||
!isEmpty(get(modifiedData, 'password')) &&
|
||||
!isEmpty(get(modifiedData, 'confirmPassword')) &&
|
||||
findIndex(acc, ['name', 'confirmPassword']) === -1
|
||||
) {
|
||||
if (modifiedData.password.length < 6) {
|
||||
acc.push({ name: 'password', errors: [{ id: 'users-permissions.components.Input.error.password.length' }] });
|
||||
acc.push({
|
||||
name: 'password',
|
||||
errors: [
|
||||
{
|
||||
id: 'users-permissions.components.Input.error.password.length',
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (get(modifiedData, 'password') !== get(modifiedData, 'confirmPassword')) {
|
||||
acc.push({ name: 'confirmPassword', errors: [{ id: 'users-permissions.components.Input.error.password.noMatch' }] });
|
||||
|
||||
if (
|
||||
get(modifiedData, 'password') !== get(modifiedData, 'confirmPassword')
|
||||
) {
|
||||
acc.push({
|
||||
name: 'confirmPassword',
|
||||
errors: [
|
||||
{
|
||||
id: 'users-permissions.components.Input.error.password.noMatch',
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,23 +157,35 @@ export class AuthPage extends React.Component { // eslint-disable-line react/pre
|
||||
if (isEmpty(formErrors)) {
|
||||
submit(this.context);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
redirect = path => this.props.history.push(path);
|
||||
|
||||
renderButton = () => {
|
||||
const { match: { params: { authType } }, submitSuccess } = this.props;
|
||||
const {
|
||||
match: {
|
||||
params: { authType },
|
||||
},
|
||||
submitSuccess,
|
||||
} = this.props;
|
||||
|
||||
if (this.isAuthType('login')) {
|
||||
return (
|
||||
<div className={cn('col-md-6', styles.loginButton)}>
|
||||
<Button primary label="users-permissions.Auth.form.button.login" type="submit" />
|
||||
<Button
|
||||
primary
|
||||
label="users-permissions.Auth.form.button.login"
|
||||
type="submit"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const isEmailForgotSent = this.isAuthType('forgot-password') && submitSuccess;
|
||||
const label = isEmailForgotSent ? 'users-permissions.Auth.form.button.forgot-password.success' : `users-permissions.Auth.form.button.${authType}`;
|
||||
|
||||
const isEmailForgotSent =
|
||||
this.isAuthType('forgot-password') && submitSuccess;
|
||||
const label = isEmailForgotSent
|
||||
? 'users-permissions.Auth.form.button.forgot-password.success'
|
||||
: `users-permissions.Auth.form.button.${authType}`;
|
||||
|
||||
return (
|
||||
<div className={cn('col-md-12', styles.buttonContainer)}>
|
||||
<Button
|
||||
@ -165,10 +197,15 @@ export class AuthPage extends React.Component { // eslint-disable-line react/pre
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
renderLogo = () =>
|
||||
this.isAuthType('register') && (
|
||||
<div className={styles.logoContainer}>
|
||||
<img src={LogoStrapi} alt="logo" />
|
||||
</div>
|
||||
);
|
||||
|
||||
renderLogo = () => this.isAuthType('register') && <div className={styles.logoContainer}><img src={LogoStrapi} alt="logo" /></div>;
|
||||
|
||||
renderLink = () => {
|
||||
if (this.isAuthType('login')) {
|
||||
return (
|
||||
@ -178,7 +215,10 @@ export class AuthPage extends React.Component { // eslint-disable-line react/pre
|
||||
);
|
||||
}
|
||||
|
||||
if (this.isAuthType('forgot-password') || this.isAuthType('register-success')) {
|
||||
if (
|
||||
this.isAuthType('forgot-password') ||
|
||||
this.isAuthType('register-success')
|
||||
) {
|
||||
return (
|
||||
<Link to="/plugins/users-permissions/auth/login">
|
||||
<FormattedMessage id="users-permissions.Auth.link.ready" />
|
||||
@ -187,37 +227,41 @@ export class AuthPage extends React.Component { // eslint-disable-line react/pre
|
||||
}
|
||||
|
||||
return <div />;
|
||||
}
|
||||
};
|
||||
|
||||
renderInputs = () => {
|
||||
const {
|
||||
const {
|
||||
didCheckErrors,
|
||||
formErrors,
|
||||
match: {
|
||||
params: {
|
||||
authType,
|
||||
},
|
||||
params: { authType },
|
||||
},
|
||||
modifiedData,
|
||||
noErrorsDescription,
|
||||
onChangeInput,
|
||||
submitSuccess,
|
||||
} = this.props;
|
||||
|
||||
|
||||
const inputs = get(form, ['form', authType]);
|
||||
const isForgotEmailSent = this.isAuthType('forgot-password') && submitSuccess;
|
||||
const isForgotEmailSent =
|
||||
this.isAuthType('forgot-password') && submitSuccess;
|
||||
return map(inputs, (input, key) => {
|
||||
const label =
|
||||
isForgotEmailSent
|
||||
? { id: 'users-permissions.Auth.form.forgot-password.email.label.success' }
|
||||
: get(input, 'label');
|
||||
|
||||
const label = isForgotEmailSent
|
||||
? {
|
||||
id:
|
||||
'users-permissions.Auth.form.forgot-password.email.label.success',
|
||||
}
|
||||
: get(input, 'label');
|
||||
|
||||
return (
|
||||
<Input
|
||||
autoFocus={key === 0}
|
||||
customBootstrapClass={get(input, 'customBootstrapClass')}
|
||||
didCheckErrors={didCheckErrors}
|
||||
errors={get(formErrors, [findIndex(formErrors, ['name', input.name]), 'errors'])}
|
||||
errors={get(formErrors, [
|
||||
findIndex(formErrors, ['name', input.name]),
|
||||
'errors',
|
||||
])}
|
||||
key={get(input, 'name')}
|
||||
label={label}
|
||||
name={get(input, 'name')}
|
||||
@ -230,11 +274,13 @@ export class AuthPage extends React.Component { // eslint-disable-line react/pre
|
||||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { modifiedData, noErrorsDescription, submitSuccess } = this.props;
|
||||
let divStyle = this.isAuthType('register') ? { marginTop: '3.2rem' } : { marginTop: '.9rem' };
|
||||
let divStyle = this.isAuthType('register')
|
||||
? { marginTop: '3.2rem' }
|
||||
: { marginTop: '.9rem' };
|
||||
|
||||
if (this.isAuthType('forgot-password') && submitSuccess) {
|
||||
divStyle = { marginTop: '.9rem', minHeight: '18.2rem' };
|
||||
@ -251,26 +297,32 @@ export class AuthPage extends React.Component { // eslint-disable-line react/pre
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.headerDescription}>
|
||||
{this.isAuthType('register') && <FormattedMessage id="users-permissions.Auth.header.register.description" />}
|
||||
{this.isAuthType('register') && (
|
||||
<FormattedMessage id="users-permissions.Auth.header.register.description" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={cn(
|
||||
styles.formContainer,
|
||||
this.isAuthType('forgot-password') && submitSuccess ? styles.borderedSuccess : styles.bordered,
|
||||
this.isAuthType('forgot-password') && submitSuccess
|
||||
? styles.borderedSuccess
|
||||
: styles.bordered,
|
||||
)}
|
||||
style={divStyle}
|
||||
>
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<div className="container-fluid">
|
||||
{noErrorsDescription && !isEmpty(this.getFormErrors())? (
|
||||
{noErrorsDescription && !isEmpty(this.getFormErrors()) ? (
|
||||
<div className={styles.errorsContainer}>
|
||||
<FormattedMessage id={this.getFormErrors()} />
|
||||
</div>
|
||||
): ''}
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<div className="row" style={{ textAlign: 'start' }}>
|
||||
{!submitSuccess && this.renderInputs()}
|
||||
{ this.isAuthType('forgot-password') && submitSuccess && (
|
||||
{this.isAuthType('forgot-password') && submitSuccess && (
|
||||
<div className={styles.forgotSuccess}>
|
||||
<FormattedMessage id="users-permissions.Auth.form.forgot-password.email.label.success" />
|
||||
<br />
|
||||
@ -282,9 +334,7 @@ export class AuthPage extends React.Component { // eslint-disable-line react/pre
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div className={styles.linkContainer}>
|
||||
{this.renderLink()}
|
||||
</div>
|
||||
<div className={styles.linkContainer}>{this.renderLink()}</div>
|
||||
</div>
|
||||
{this.renderLogo()}
|
||||
</div>
|
||||
@ -323,13 +373,20 @@ function mapDispatchToProps(dispatch) {
|
||||
setForm,
|
||||
submit,
|
||||
},
|
||||
dispatch
|
||||
dispatch,
|
||||
);
|
||||
}
|
||||
|
||||
const withConnect = connect(mapStateToProps, mapDispatchToProps);
|
||||
const withReducer = strapi.injectReducer({ key: 'authPage', reducer, pluginId });
|
||||
const withSaga = strapi.injectSaga({ key: 'authPage', saga, pluginId });
|
||||
const withConnect = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
);
|
||||
const withReducer = window.strapi.injectReducer({
|
||||
key: 'authPage',
|
||||
reducer,
|
||||
pluginId,
|
||||
});
|
||||
const withSaga = window.strapi.injectSaga({ key: 'authPage', saga, pluginId });
|
||||
|
||||
export default compose(
|
||||
withReducer,
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { get, includes, isArray, omit, set } from 'lodash';
|
||||
import { call, fork, put, select, takeLatest } from 'redux-saga/effects';
|
||||
import auth from 'utils/auth';
|
||||
import request from 'utils/request';
|
||||
import { auth, request } from 'strapi-helper-plugin';
|
||||
|
||||
import { updateHasAdmin } from '../Initializer/actions';
|
||||
|
||||
|
||||
@ -14,11 +14,13 @@ import { findIndex, get, isEmpty, isEqual, size } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
|
||||
// Design
|
||||
import BackHeader from 'components/BackHeader';
|
||||
import Input from 'components/InputsIndex';
|
||||
import LoadingIndicator from 'components/LoadingIndicator';
|
||||
import LoadingIndicatorPage from 'components/LoadingIndicatorPage';
|
||||
import PluginHeader from 'components/PluginHeader';
|
||||
import {
|
||||
BackHeader,
|
||||
InputsIndex as Input,
|
||||
LoadingIndicator,
|
||||
LoadingIndicatorPage,
|
||||
PluginHeader,
|
||||
} from 'strapi-helper-plugin';
|
||||
|
||||
import InputSearch from '../../components/InputSearchContainer';
|
||||
import Plugins from '../../components/Plugins';
|
||||
@ -56,16 +58,15 @@ import saga from './saga';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
export class EditPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
getChildContext = () => (
|
||||
{
|
||||
onChange: this.props.onChangeInput,
|
||||
selectAllActions: this.props.selectAllActions,
|
||||
setInputPoliciesPath: this.props.setInputPoliciesPath,
|
||||
setShouldDisplayPolicieshint: this.props.setShouldDisplayPolicieshint,
|
||||
resetShouldDisplayPoliciesHint: this.props.resetShouldDisplayPoliciesHint,
|
||||
}
|
||||
);
|
||||
export class EditPage extends React.Component {
|
||||
// eslint-disable-line react/prefer-stateless-function
|
||||
getChildContext = () => ({
|
||||
onChange: this.props.onChangeInput,
|
||||
selectAllActions: this.props.selectAllActions,
|
||||
setInputPoliciesPath: this.props.setInputPoliciesPath,
|
||||
setShouldDisplayPolicieshint: this.props.setShouldDisplayPolicieshint,
|
||||
resetShouldDisplayPoliciesHint: this.props.resetShouldDisplayPoliciesHint,
|
||||
});
|
||||
|
||||
componentDidMount() {
|
||||
this.props.setActionType(this.props.match.params.actionType);
|
||||
@ -100,23 +101,35 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre
|
||||
handleSubmit = () => {
|
||||
// Check if the name field is filled
|
||||
if (isEmpty(get(this.props.editPage, ['modifiedData', 'name']))) {
|
||||
return this.props.setErrors([{ name: 'name', errors: [{ id: 'users-permissions.EditPage.form.roles.name.error' }] }]);
|
||||
return this.props.setErrors([
|
||||
{
|
||||
name: 'name',
|
||||
errors: [{ id: 'users-permissions.EditPage.form.roles.name.error' }],
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
this.props.submit(this.context);
|
||||
}
|
||||
};
|
||||
|
||||
showLoaderForm = () => {
|
||||
const { editPage: { modifiedData }, match: { params: { actionType } } } = this.props;
|
||||
const {
|
||||
editPage: { modifiedData },
|
||||
match: {
|
||||
params: { actionType },
|
||||
},
|
||||
} = this.props;
|
||||
|
||||
return actionType !== 'create' && isEmpty(modifiedData);
|
||||
}
|
||||
};
|
||||
|
||||
showLoaderPermissions = () => {
|
||||
const { editPage: { modifiedData } } = this.props;
|
||||
const {
|
||||
editPage: { modifiedData },
|
||||
} = this.props;
|
||||
|
||||
return isEmpty(get(modifiedData, ['permissions']));
|
||||
}
|
||||
};
|
||||
|
||||
renderFirstBlock = () => (
|
||||
<React.Fragment>
|
||||
@ -125,7 +138,11 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre
|
||||
<Input
|
||||
autoFocus
|
||||
customBootstrapClass="col-md-12"
|
||||
errors={get(this.props.editPage, ['formErrors', findIndex(this.props.editPage.formErrors, ['name', 'name']), 'errors'])}
|
||||
errors={get(this.props.editPage, [
|
||||
'formErrors',
|
||||
findIndex(this.props.editPage.formErrors, ['name', 'name']),
|
||||
'errors',
|
||||
])}
|
||||
didCheckErrors={this.props.editPage.didCheckErrors}
|
||||
label={{ id: 'users-permissions.EditPage.form.roles.label.name' }}
|
||||
name="name"
|
||||
@ -138,7 +155,9 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre
|
||||
<div className="row">
|
||||
<Input
|
||||
customBootstrapClass="col-md-12"
|
||||
label={{ id: 'users-permissions.EditPage.form.roles.label.description' }}
|
||||
label={{
|
||||
id: 'users-permissions.EditPage.form.roles.label.description',
|
||||
}}
|
||||
name="description"
|
||||
onChange={this.props.onChangeInput}
|
||||
type="textarea"
|
||||
@ -174,15 +193,17 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre
|
||||
<div className={styles.separator} />
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
);
|
||||
|
||||
render() {
|
||||
const pluginHeaderTitle = this.props.match.params.actionType === 'create' ?
|
||||
'users-permissions.EditPage.header.title.create'
|
||||
: 'users-permissions.EditPage.header.title';
|
||||
const pluginHeaderDescription = this.props.match.params.actionType === 'create' ?
|
||||
'users-permissions.EditPage.header.description.create'
|
||||
: 'users-permissions.EditPage.header.description';
|
||||
const pluginHeaderTitle =
|
||||
this.props.match.params.actionType === 'create'
|
||||
? 'users-permissions.EditPage.header.title.create'
|
||||
: 'users-permissions.EditPage.header.title';
|
||||
const pluginHeaderDescription =
|
||||
this.props.match.params.actionType === 'create'
|
||||
? 'users-permissions.EditPage.header.description.create'
|
||||
: 'users-permissions.EditPage.header.description';
|
||||
const pluginHeaderActions = [
|
||||
{
|
||||
label: 'users-permissions.EditPage.cancel',
|
||||
@ -195,10 +216,13 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre
|
||||
label: 'users-permissions.EditPage.submit',
|
||||
onClick: this.handleSubmit,
|
||||
type: 'submit',
|
||||
disabled: isEqual(this.props.editPage.modifiedData, this.props.editPage.initialData),
|
||||
disabled: isEqual(
|
||||
this.props.editPage.modifiedData,
|
||||
this.props.editPage.initialData,
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
if (this.showLoaderForm()) {
|
||||
return <LoadingIndicatorPage />;
|
||||
}
|
||||
@ -217,7 +241,8 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre
|
||||
description={{
|
||||
id: pluginHeaderDescription,
|
||||
values: {
|
||||
description: get(this.props.editPage.initialData, 'description') || '',
|
||||
description:
|
||||
get(this.props.editPage.initialData, 'description') || '',
|
||||
},
|
||||
}}
|
||||
actions={pluginHeaderActions}
|
||||
@ -231,22 +256,34 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre
|
||||
<form className={styles.form}>
|
||||
<div className="row">
|
||||
{this.showLoaderForm() ? (
|
||||
<div className={styles.loaderWrapper}><LoadingIndicator /></div>
|
||||
) : this.renderFirstBlock()}
|
||||
<div className={styles.loaderWrapper}>
|
||||
<LoadingIndicator />
|
||||
</div>
|
||||
) : (
|
||||
this.renderFirstBlock()
|
||||
)}
|
||||
</div>
|
||||
<div className="row" style={{ marginRight: '-30px'}}>
|
||||
<div className="row" style={{ marginRight: '-30px' }}>
|
||||
{this.showLoaderPermissions() && (
|
||||
<div className={styles.loaderWrapper} style={{ minHeight: '400px' }}>
|
||||
<div
|
||||
className={styles.loaderWrapper}
|
||||
style={{ minHeight: '400px' }}
|
||||
>
|
||||
<LoadingIndicator />
|
||||
</div>
|
||||
)}
|
||||
{!this.showLoaderPermissions() && (
|
||||
<Plugins
|
||||
plugins={get(this.props.editPage, ['modifiedData', 'permissions'])}
|
||||
plugins={get(this.props.editPage, [
|
||||
'modifiedData',
|
||||
'permissions',
|
||||
])}
|
||||
/>
|
||||
)}
|
||||
<Policies
|
||||
shouldDisplayPoliciesHint={this.props.editPage.shouldDisplayPoliciesHint}
|
||||
shouldDisplayPoliciesHint={
|
||||
this.props.editPage.shouldDisplayPoliciesHint
|
||||
}
|
||||
inputSelectName={this.props.editPage.inputPoliciesPath}
|
||||
routes={this.props.editPage.routes}
|
||||
selectOptions={this.props.editPage.policies}
|
||||
@ -331,8 +368,15 @@ function mapDispatchToProps(dispatch) {
|
||||
);
|
||||
}
|
||||
|
||||
const withConnect = connect(mapStateToProps, mapDispatchToProps);
|
||||
const withReducer = strapi.injectReducer({ key: 'editPage', reducer, pluginId });
|
||||
const withConnect = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
);
|
||||
const withReducer = strapi.injectReducer({
|
||||
key: 'editPage',
|
||||
reducer,
|
||||
pluginId,
|
||||
});
|
||||
const withSaga = strapi.injectSaga({ key: 'editPage', saga, pluginId });
|
||||
|
||||
export default compose(
|
||||
|
||||
@ -1,15 +1,5 @@
|
||||
import { LOCATION_CHANGE } from 'react-router-redux';
|
||||
import {
|
||||
all,
|
||||
call,
|
||||
cancel,
|
||||
fork,
|
||||
put,
|
||||
select,
|
||||
take,
|
||||
takeLatest,
|
||||
} from 'redux-saga/effects';
|
||||
import request from 'utils/request';
|
||||
import { all, call, fork, put, select, takeLatest } from 'redux-saga/effects';
|
||||
import { request } from 'strapi-helper-plugin';
|
||||
import {
|
||||
getPermissionsSucceeded,
|
||||
getPoliciesSucceeded,
|
||||
@ -33,10 +23,14 @@ import {
|
||||
|
||||
export function* fetchUser(action) {
|
||||
try {
|
||||
const data = yield call(request, `/users-permissions/search/${action.user}`, { method: 'GET' });
|
||||
const data = yield call(
|
||||
request,
|
||||
`/users-permissions/search/${action.user}`,
|
||||
{ method: 'GET' },
|
||||
);
|
||||
|
||||
yield put(getUserSucceeded(data));
|
||||
} catch(error) {
|
||||
} catch (error) {
|
||||
strapi.notification.error('users-permissions.notification.error.fetchUser');
|
||||
}
|
||||
}
|
||||
@ -51,8 +45,10 @@ export function* permissionsGet() {
|
||||
});
|
||||
|
||||
yield put(getPermissionsSucceeded(response));
|
||||
} catch(err) {
|
||||
strapi.notification.error('users-permissions.EditPage.notification.permissions.error');
|
||||
} catch (err) {
|
||||
strapi.notification.error(
|
||||
'users-permissions.EditPage.notification.permissions.error',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,11 +58,13 @@ export function* policiesGet() {
|
||||
call(request, '/users-permissions/policies', { method: 'GET' }),
|
||||
call(request, '/users-permissions/routes', { method: 'GET' }),
|
||||
]);
|
||||
|
||||
|
||||
yield put(getPoliciesSucceeded(policies));
|
||||
yield put(getRoutesSucceeded(routes));
|
||||
} catch(err) {
|
||||
strapi.notification.error('users-permissions.EditPage.notification.policies.error');
|
||||
} catch (err) {
|
||||
strapi.notification.error(
|
||||
'users-permissions.EditPage.notification.policies.error',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,8 +78,10 @@ export function* roleGet(action) {
|
||||
});
|
||||
|
||||
yield put(getRoleSucceeded(role));
|
||||
} catch(err) {
|
||||
strapi.notification.error('users-permissions.EditPage.notification.role.error');
|
||||
} catch (err) {
|
||||
strapi.notification.error(
|
||||
'users-permissions.EditPage.notification.role.error',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,32 +95,35 @@ export function* submit(action) {
|
||||
body,
|
||||
};
|
||||
|
||||
const requestURL = actionType === 'POST' ? '/users-permissions/roles' : `/users-permissions/roles/${roleId}`;
|
||||
const requestURL =
|
||||
actionType === 'POST'
|
||||
? '/users-permissions/roles'
|
||||
: `/users-permissions/roles/${roleId}`;
|
||||
const response = yield call(request, requestURL, opts);
|
||||
|
||||
|
||||
if (actionType === 'POST') {
|
||||
action.context.emitEvent('didCreateRole');
|
||||
}
|
||||
|
||||
|
||||
if (response.ok) {
|
||||
yield put(submitSucceeded());
|
||||
}
|
||||
} catch(error) {
|
||||
} catch (error) {
|
||||
console.log(error); // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
|
||||
export default function* defaultSaga() {
|
||||
const loadPermissionsWatcher = yield fork(takeLatest, GET_PERMISSIONS, permissionsGet);
|
||||
const loadPoliciesWatcher = yield fork(takeLatest, GET_POLICIES, policiesGet);
|
||||
const loadRoleWatcher = yield fork(takeLatest, GET_ROLE, roleGet);
|
||||
yield fork(takeLatest, GET_PERMISSIONS, permissionsGet);
|
||||
yield fork(takeLatest, GET_POLICIES, policiesGet);
|
||||
yield fork(takeLatest, GET_ROLE, roleGet);
|
||||
|
||||
yield fork(takeLatest, GET_USER, fetchUser);
|
||||
yield fork(takeLatest, SUBMIT, submit);
|
||||
|
||||
yield take(LOCATION_CHANGE);
|
||||
// yield take(LOCATION_CHANGE);
|
||||
|
||||
yield cancel(loadPermissionsWatcher);
|
||||
yield cancel(loadPoliciesWatcher);
|
||||
yield cancel(loadRoleWatcher);
|
||||
// yield cancel(loadPermissionsWatcher);
|
||||
// yield cancel(loadPoliciesWatcher);
|
||||
// yield cancel(loadRoleWatcher);
|
||||
}
|
||||
|
||||
@ -12,8 +12,8 @@ import { bindActionCreators, compose } from 'redux';
|
||||
import cn from 'classnames';
|
||||
import { clone, get, includes, isEqual, isEmpty } from 'lodash';
|
||||
|
||||
import HeaderNav from 'components/HeaderNav';
|
||||
import PluginHeader from 'components/PluginHeader';
|
||||
import { HeaderNav, PluginHeader } from 'strapi-helper-plugin';
|
||||
// import PluginHeader from 'components/PluginHeader';
|
||||
|
||||
import pluginId from '../../pluginId';
|
||||
|
||||
@ -257,7 +257,7 @@ export class HomePage extends React.Component {
|
||||
{component}
|
||||
</div>
|
||||
<PopUpForm
|
||||
actionType='edit'
|
||||
actionType="edit"
|
||||
isOpen={this.state.showModalEdit}
|
||||
dataToEdit={dataToEdit}
|
||||
didCheckErrors={didCheckErrors}
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
call,
|
||||
} from 'redux-saga/effects';
|
||||
|
||||
import request from 'utils/request';
|
||||
import { request } from 'strapi-helper-plugin';
|
||||
|
||||
import {
|
||||
deleteDataSucceeded,
|
||||
@ -19,11 +19,7 @@ import {
|
||||
submitSucceeded,
|
||||
} from './actions';
|
||||
|
||||
import {
|
||||
DELETE_DATA,
|
||||
FETCH_DATA,
|
||||
SUBMIT,
|
||||
} from './constants';
|
||||
import { DELETE_DATA, FETCH_DATA, SUBMIT } from './constants';
|
||||
|
||||
import {
|
||||
makeSelectAllData,
|
||||
@ -37,7 +33,10 @@ export function* dataDelete() {
|
||||
const allData = yield select(makeSelectAllData());
|
||||
const dataToDelete = yield select(makeSelectDataToDelete());
|
||||
const endPointAPI = yield select(makeSelectDeleteEndPoint());
|
||||
const indexDataToDelete = findIndex(allData[endPointAPI], ['name', dataToDelete.name]);
|
||||
const indexDataToDelete = findIndex(allData[endPointAPI], [
|
||||
'name',
|
||||
dataToDelete.name,
|
||||
]);
|
||||
|
||||
if (indexDataToDelete !== -1) {
|
||||
const id = dataToDelete.id;
|
||||
@ -46,17 +45,23 @@ export function* dataDelete() {
|
||||
|
||||
if (response.ok) {
|
||||
yield put(deleteDataSucceeded(indexDataToDelete));
|
||||
strapi.notification.success('users-permissions.notification.success.delete');
|
||||
strapi.notification.success(
|
||||
'users-permissions.notification.success.delete',
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
strapi.notification.error('users-permissions.notification.error.delete');
|
||||
}
|
||||
}
|
||||
|
||||
export function* dataFetch(action) {
|
||||
try {
|
||||
const response = yield call(request, `/users-permissions/${action.endPoint}`, { method: 'GET' });
|
||||
const response = yield call(
|
||||
request,
|
||||
`/users-permissions/${action.endPoint}`,
|
||||
{ method: 'GET' },
|
||||
);
|
||||
|
||||
if (action.endPoint === 'advanced') {
|
||||
yield put(setForm(response));
|
||||
@ -64,7 +69,7 @@ export function* dataFetch(action) {
|
||||
const data = response[action.endPoint] || response;
|
||||
yield put(fetchDataSucceeded(data));
|
||||
}
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
strapi.notification.error('users-permissions.notification.error.fetch');
|
||||
}
|
||||
}
|
||||
@ -72,7 +77,13 @@ export function* dataFetch(action) {
|
||||
export function* submitData(action) {
|
||||
try {
|
||||
const body = yield select(makeSelectModifiedData());
|
||||
const opts = { method: 'PUT', body: (action.endPoint === 'advanced') ? get(body, ['advanced', 'settings'], {}) : body };
|
||||
const opts = {
|
||||
method: 'PUT',
|
||||
body:
|
||||
action.endPoint === 'advanced'
|
||||
? get(body, ['advanced', 'settings'], {})
|
||||
: body,
|
||||
};
|
||||
|
||||
yield call(request, `/users-permissions/${action.endPoint}`, opts);
|
||||
|
||||
@ -83,8 +94,10 @@ export function* submitData(action) {
|
||||
}
|
||||
|
||||
yield put(submitSucceeded());
|
||||
strapi.notification.success('users-permissions.notification.success.submit');
|
||||
} catch(error) {
|
||||
strapi.notification.success(
|
||||
'users-permissions.notification.success.submit',
|
||||
);
|
||||
} catch (error) {
|
||||
strapi.notification.error('notification.error');
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { fork, takeLatest, call, put } from 'redux-saga/effects';
|
||||
|
||||
import request from 'utils/request';
|
||||
import { request } from 'strapi-helper-plugin';
|
||||
|
||||
import { INITIALIZE } from './constants';
|
||||
import { initializeSucceeded } from './actions';
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import NotFound from 'components/NotFound';
|
||||
import { NotFound } from 'strapi-helper-plugin';
|
||||
|
||||
export default class NotFoundPage extends React.Component {
|
||||
render() {
|
||||
|
||||
93
packages/strapi-plugin-users-permissions/admin/src/index.js
Normal file
93
packages/strapi-plugin-users-permissions/admin/src/index.js
Normal file
@ -0,0 +1,93 @@
|
||||
import React from 'react';
|
||||
import { reduce } from 'lodash';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginId from './pluginId';
|
||||
|
||||
import App from './containers/App';
|
||||
|
||||
const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
|
||||
|
||||
const formatMessages = messages =>
|
||||
reduce(
|
||||
messages,
|
||||
(result, value, key) => {
|
||||
result[`${pluginId}.${key}`] = value;
|
||||
|
||||
return result;
|
||||
},
|
||||
{},
|
||||
);
|
||||
const requireTranslations = language => {
|
||||
try {
|
||||
return require(`./translations/${language}.json`); // eslint-disable-line global-require
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`Unable to load "${language}" translation for the plugin ${pluginId}. Please make sure "${language}.json" file exists in "pluginPath/admin/src/translations" folder.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const translationMessages = reduce(
|
||||
strapi.languages,
|
||||
(result, language) => {
|
||||
result[language] = formatMessages(requireTranslations(language));
|
||||
return result;
|
||||
},
|
||||
{},
|
||||
);
|
||||
const layout = (() => {
|
||||
try {
|
||||
return require('../../config/layout.js'); // eslint-disable-line import/no-unresolved
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
|
||||
const injectedComponents = (() => {
|
||||
try {
|
||||
return require('./injectedComponents').default; // eslint-disable-line import/no-unresolved
|
||||
} catch (err) {
|
||||
return [];
|
||||
}
|
||||
})();
|
||||
|
||||
const initializer = (() => {
|
||||
try {
|
||||
return require('./initializer');
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
|
||||
const lifecycles = (() => {
|
||||
try {
|
||||
return require('./lifecycles');
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
|
||||
function Comp(props) {
|
||||
return <App {...props} />;
|
||||
}
|
||||
|
||||
const plugin = {
|
||||
blockerComponent: null,
|
||||
blockerComponentProps: {},
|
||||
description: pluginDescription,
|
||||
icon: pluginPkg.strapi.icon,
|
||||
id: pluginId,
|
||||
initializer,
|
||||
injectedComponents,
|
||||
layout,
|
||||
lifecycles,
|
||||
leftMenuLinks: [],
|
||||
leftMenuSections: [],
|
||||
mainComponent: Comp,
|
||||
name: pluginPkg.strapi.name,
|
||||
preventComponentRendering: false,
|
||||
translationMessages,
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
@ -1,4 +1,4 @@
|
||||
const auth = require('utils/auth').default;
|
||||
const { auth } = require('strapi-helper-plugin');
|
||||
|
||||
module.exports = function willSecure() {
|
||||
const {
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
"koa": "^2.1.0",
|
||||
"koa2-ratelimit": "^0.6.1",
|
||||
"purest": "^2.0.1",
|
||||
"react": "^16.8.6",
|
||||
"request": "^2.83.0",
|
||||
"strapi-utils": "3.0.0-alpha.25.2",
|
||||
"uuid": "^3.1.0"
|
||||
@ -56,4 +57,4 @@
|
||||
"npm": ">= 6.0.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user