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