mirror of
https://github.com/strapi/strapi.git
synced 2025-11-11 07:39:16 +00:00
Merge branch 'master' into fix/users-front
This commit is contained in:
commit
54a4f33371
@ -6,131 +6,6 @@ This section gives use cases examples on front-end plugin development.
|
|||||||
|
|
||||||
This section contains advanced resources to develop plugins.
|
This section contains advanced resources to develop plugins.
|
||||||
|
|
||||||
## Handle user navigation
|
|
||||||
|
|
||||||
User navigation within your plugin can be managed by two different ways :
|
|
||||||
- Using the [React Router V4 API](https://reacttraining.com/react-router/web/guides/philosophy)
|
|
||||||
- Using the main router from the app
|
|
||||||
|
|
||||||
### Using React Router
|
|
||||||
|
|
||||||
[Link](https://reacttraining.com/react-router/web/api/Link) provides declarative, accessible navigation around your application :
|
|
||||||
|
|
||||||
```js
|
|
||||||
<Link to={{
|
|
||||||
pathname: `/plugins/my-plugin/foo/${this.props.bar}`,
|
|
||||||
search: '?foo=bar',
|
|
||||||
hash: '#the-hash',
|
|
||||||
}} />
|
|
||||||
|
|
||||||
// Same as
|
|
||||||
|
|
||||||
<Link to=`/plugins/my-plugin/foo/${this.props.bar}?foo=bar#the-hash` />
|
|
||||||
```
|
|
||||||
|
|
||||||
[NavLink](https://reacttraining.com/react-router/web/api/NavLink) will add styling attributes to the rendered element when it matches the current URL.
|
|
||||||
|
|
||||||
|
|
||||||
```js
|
|
||||||
<NavLink
|
|
||||||
to="/faq"
|
|
||||||
activeClassName="selected"
|
|
||||||
>
|
|
||||||
FAQs
|
|
||||||
</NavLink>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Using the App Router
|
|
||||||
|
|
||||||
We use the app router if we want to make a redirection after some user actions (ex: after submitting a form).
|
|
||||||
|
|
||||||
**Path —** `./plugins/my-plugin/admin/src/containers/FooPage/index.js`.
|
|
||||||
```js
|
|
||||||
import React from 'react';
|
|
||||||
import { bindActionCreators } from 'redux';
|
|
||||||
import { connect, compose } from 'react-redux';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
// App router
|
|
||||||
import { router } from 'app';
|
|
||||||
|
|
||||||
// Components
|
|
||||||
import Input from 'components/inputs';
|
|
||||||
import Button from 'components/button';
|
|
||||||
|
|
||||||
// Utils
|
|
||||||
import injectSaga from 'utils/injectSaga';
|
|
||||||
import injectReducer from 'utils/injectReducer';
|
|
||||||
|
|
||||||
// Actions
|
|
||||||
import { changeInput, submitForm } from './actions';
|
|
||||||
// Sagas
|
|
||||||
import saga from './sagas';
|
|
||||||
// Selectors
|
|
||||||
import selectFooPage from './selectors';
|
|
||||||
// Reducer
|
|
||||||
import reducer from './reducer';
|
|
||||||
|
|
||||||
export class FooPage extends React.Component {
|
|
||||||
handleSubmit = () => {
|
|
||||||
this.props.handleSubmit();
|
|
||||||
const hash = this.props.location.hash;
|
|
||||||
const pathname = this.props.match.pathname;
|
|
||||||
const search = '?foo=bar';
|
|
||||||
router.push({ pathname, search, hash });
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<form onSubmit={this.handleSubmit}>
|
|
||||||
<Input
|
|
||||||
value={this.state.value}
|
|
||||||
handleChange={this.props.changeInput}
|
|
||||||
validations={{ required: true }}
|
|
||||||
label="Text field"
|
|
||||||
target="data"
|
|
||||||
type="text"
|
|
||||||
/>
|
|
||||||
<Button primary onClick={this.handleSubmit}>Submit form</Button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FooPage.propTypes = {
|
|
||||||
changeInput: PropTypes.func.isRequired,
|
|
||||||
location: PropTypes.object.isRequired,
|
|
||||||
match: PropTypes.object.isRequired,
|
|
||||||
submitForm: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = selectFooPage();
|
|
||||||
|
|
||||||
function mapDispatchToProps(dispatch) {
|
|
||||||
return bindActionCreators(
|
|
||||||
{
|
|
||||||
changeInput,
|
|
||||||
submitForm,
|
|
||||||
},
|
|
||||||
dispatch
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const withConnect = connect(mapStateToProps, mapDispatchToProps);
|
|
||||||
const withReducer = injectReducer({ key: 'fooPage', reducer });
|
|
||||||
const withSagas = injectSaga({ key: 'fooPage', saga });
|
|
||||||
|
|
||||||
export default compose(
|
|
||||||
withReducer,
|
|
||||||
withSagas,
|
|
||||||
withConnect,
|
|
||||||
)(FooPage);
|
|
||||||
```
|
|
||||||
|
|
||||||
***
|
|
||||||
|
|
||||||
## Inject design
|
## Inject design
|
||||||
|
|
||||||
The `ExtendComponent` allows you to inject design from one plugin into another.
|
The `ExtendComponent` allows you to inject design from one plugin into another.
|
||||||
@ -264,7 +139,7 @@ export { makeSelectShowLorem };
|
|||||||
|
|
||||||
That's all now your plugin's container is injectable!
|
That's all now your plugin's container is injectable!
|
||||||
|
|
||||||
Let's see how to inject some design from another plugin.
|
Let's see how to inject a React Component from a plugin into another.
|
||||||
|
|
||||||
|
|
||||||
### Create your injectedComponent
|
### Create your injectedComponent
|
||||||
@ -301,7 +176,7 @@ BarContainer.defaultProps = {
|
|||||||
export default BarContainer;
|
export default BarContainer;
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tell the admin that you want to inject some design into another plugin
|
### Tell the admin that you want to inject a React Component from a plugin into another
|
||||||
|
|
||||||
You have to create a file called `injectedComponents.js` at the root of your `another-plugin` src folder.
|
You have to create a file called `injectedComponents.js` at the root of your `another-plugin` src folder.
|
||||||
|
|
||||||
|
|||||||
@ -84,19 +84,6 @@ module.exports = cb => {
|
|||||||
if (!_.get(strapi.plugins['users-permissions'], 'config.email')) {
|
if (!_.get(strapi.plugins['users-permissions'], 'config.email')) {
|
||||||
try {
|
try {
|
||||||
const email = {
|
const email = {
|
||||||
'validation_email': {
|
|
||||||
display: 'Email.template.validation_email',
|
|
||||||
icon: 'envelope',
|
|
||||||
options: {
|
|
||||||
from: {
|
|
||||||
name: 'Administration Panel',
|
|
||||||
email: 'no-reply@strapi.io'
|
|
||||||
},
|
|
||||||
response_email: '',
|
|
||||||
object: '',
|
|
||||||
message: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'reset_password': {
|
'reset_password': {
|
||||||
display: 'Email.template.reset_password',
|
display: 'Email.template.reset_password',
|
||||||
icon: 'refresh',
|
icon: 'refresh',
|
||||||
@ -111,23 +98,10 @@ module.exports = cb => {
|
|||||||
|
|
||||||
<p>But don’t worry! You can use the following link to reset your password:</p>
|
<p>But don’t worry! You can use the following link to reset your password:</p>
|
||||||
|
|
||||||
<p><%= url %>?code=<%= token %></p>
|
<p><%= URL %>?code=<%= TOKEN %></p>
|
||||||
|
|
||||||
<p>Thanks.</p>`
|
<p>Thanks.</p>`
|
||||||
}
|
}
|
||||||
},
|
|
||||||
'success_register': {
|
|
||||||
display: 'Email.template.success_register',
|
|
||||||
icon: 'check',
|
|
||||||
options: {
|
|
||||||
from: {
|
|
||||||
name: 'Administration Panel',
|
|
||||||
email: 'no-reply@strapi.io'
|
|
||||||
},
|
|
||||||
response_email: '',
|
|
||||||
object: '',
|
|
||||||
message: ''
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -158,13 +158,13 @@ module.exports = {
|
|||||||
const settings = strapi.plugins['users-permissions'].config.email['reset_password'].options;
|
const settings = strapi.plugins['users-permissions'].config.email['reset_password'].options;
|
||||||
|
|
||||||
settings.message = await strapi.plugins['users-permissions'].services.userspermissions.template(settings.message, {
|
settings.message = await strapi.plugins['users-permissions'].services.userspermissions.template(settings.message, {
|
||||||
url,
|
URL: url,
|
||||||
user: _.omit(user.toJSON(), ['password', 'resetPasswordToken', 'role', 'provider']),
|
USER: _.omit(user.toJSON(), ['password', 'resetPasswordToken', 'role', 'provider']),
|
||||||
token: resetPasswordToken
|
TOKEN: resetPasswordToken
|
||||||
});
|
});
|
||||||
|
|
||||||
settings.object = await strapi.plugins['users-permissions'].services.userspermissions.template(settings.object, {
|
settings.object = await strapi.plugins['users-permissions'].services.userspermissions.template(settings.object, {
|
||||||
user: _.omit(user.toJSON(), ['password', 'resetPasswordToken', 'role', 'provider'])
|
USER: _.omit(user.toJSON(), ['password', 'resetPasswordToken', 'role', 'provider'])
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -70,6 +70,14 @@ module.exports = {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
create: async (ctx) => {
|
create: async (ctx) => {
|
||||||
|
if (strapi.plugins['users-permissions'].config.advanced.unique_email && ctx.request.body.email) {
|
||||||
|
const user = await strapi.query('user', 'users-permissions').findOne({ email: ctx.request.body.email });
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.email.taken' }] }] : 'Email is already taken.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await strapi.plugins['users-permissions'].services.user.add(ctx.request.body);
|
const data = await strapi.plugins['users-permissions'].services.user.add(ctx.request.body);
|
||||||
// Send 201 `created`
|
// Send 201 `created`
|
||||||
@ -88,6 +96,14 @@ module.exports = {
|
|||||||
|
|
||||||
update: async (ctx, next) => {
|
update: async (ctx, next) => {
|
||||||
try {
|
try {
|
||||||
|
if (strapi.plugins['users-permissions'].config.advanced.unique_email && ctx.request.body.email) {
|
||||||
|
const user = await strapi.query('user', 'users-permissions').findOne({ email: ctx.request.body.email });
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.email.taken' }] }] : 'Email is already taken.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const user = await strapi.plugins['users-permissions'].services.user.fetch(ctx.params);
|
const user = await strapi.plugins['users-permissions'].services.user.fetch(ctx.params);
|
||||||
|
|
||||||
if (_.get(ctx.request, 'body.password') === user.password) {
|
if (_.get(ctx.request, 'body.password') === user.password) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user