UNPKG

@plone/volto

Version:
374 lines (359 loc) 12.1 kB
/** * Add content rule component. * @module components/manage/Controlpanels/Rules/AddRule */ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { compose } from 'redux'; import { Link } from 'react-router-dom'; import { getBaseUrl, getParentUrl } from '@plone/volto/helpers/Url/Url'; import Helmet from '@plone/volto/helpers/Helmet/Helmet'; import { createPortal } from 'react-dom'; import { Button, Checkbox, Container, Form, Grid, Segment, } from 'semantic-ui-react'; import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; import Icon from '@plone/volto/components/theme/Icon/Icon'; import Toolbar from '@plone/volto/components/manage/Toolbar/Toolbar'; import Toast from '@plone/volto/components/manage/Toast/Toast'; import { Field } from '@plone/volto/components/manage/Form'; import { toast } from 'react-toastify'; import { getContentRulesEvents, addNewRule, } from '@plone/volto/actions/rules/rules'; import backSVG from '@plone/volto/icons/back.svg'; const messages = defineMessages({ back: { id: 'Back', defaultMessage: 'Back', }, addRule: { id: 'Add Content Rule', defaultMessage: 'Add Content Rule', }, success: { id: 'Success', defaultMessage: 'Success', }, add: { id: 'Rule added', defaultMessage: 'Rule added', }, }); /** * AddRule class. * @class AddRule * @extends Component */ class AddRule extends Component { /** * Property types. * @property {Object} propTypes Property types. * @static */ static propTypes = { getContentRulesEvents: PropTypes.func.isRequired, addNewRule: PropTypes.func.isRequired, }; /** * Constructor * @method constructor * @param {Object} props Component properties * @constructs Rules */ constructor(props) { super(props); this.state = { isClient: false, title: '', description: '', event: '', cascading: false, stop: false, enabled: false, invalidForm: true, invalidTitle: false, invalidEvent: false, }; } /** * Component did mount * @method componentDidMount * @returns {undefined} */ componentDidMount() { this.setState({ isClient: true }); this.props.getContentRulesEvents(getBaseUrl(this.props.pathname)); } /** * Component did mount * @method componentDidUpdate * @returns {undefined} */ componentDidUpdate(prevProps, prevState) { if ( prevState.title !== this.state.title || prevState.event !== this.state.event ) { if (this.state.title && this.state.event) { this.setState({ invalidForm: false, invalidTitle: false, invalidEvent: false, }); } else { if (!this.state.title) { this.setState({ invalidForm: true, invalidTitle: true }); } if (!this.state.event) { this.setState({ invalidForm: true, invalidEvent: true }); } } } } /** * Component will receive props * @method componentWillReceiveProps * @param {Object} nextProps Next properties * @returns {undefined} */ UNSAFE_componentWillReceiveProps(nextProps) { if (this.props.rules.add.loading && nextProps.rules.add.loaded) { toast.success( <Toast success title={this.props.intl.formatMessage(messages.success)} content={this.props.intl.formatMessage(messages.add)} />, ); this.props.history.push(getParentUrl(this.props.pathname)); } } /** * Back/Cancel handler * @method onCancel * @returns {undefined} */ onCancel() { this.props.history.push(getParentUrl(this.props.pathname)); } /** * Add rule handler * @method handleAdd * @returns {undefined} */ handleAdd() { const { title, description, event, cascading, stop, enabled, invalidForm } = this.state; const data = { title, description, event, cascading, enabled, stop }; if (!invalidForm) { this.props.addNewRule(getBaseUrl(this.props.pathname), data); } } /** * Render method. * @method render * @returns {string} Markup for the component. */ render() { const { title, description, event, cascading, stop, enabled } = this.state; const triggeringEvents = this.props.events?.items && this.props.events?.items.length > 0 ? this.props.events?.items.map((event) => [event.token, event.title]) : ''; return ( <div id="page-rule-add"> <Helmet title={this.props.intl.formatMessage(messages.addRule)} /> <Container> <article id="content"> <Segment.Group raised> <Segment className="primary"> <FormattedMessage id="Add Rule" defaultMessage="Add Rule" /> </Segment> <Segment className="secondary"> <FormattedMessage id="Use the form below to define the new content rule" defaultMessage="Use the form below to define the new content rule" /> </Segment> <Segment> <Form> <Grid> <Grid.Row stretched> <Grid.Column> <Field className={'title-field'} title={'Title'} description="Please set a descriptive title for the rule." value={title} required onChange={(e, t) => this.setState({ title: t })} /> </Grid.Column> </Grid.Row> <Grid.Row stretched> <Grid.Column> <Field title={'Description'} description="Enter a short description of the rule and its purpose." value={description} onChange={(e, d) => this.setState({ description: d })} /> </Grid.Column> </Grid.Row> <Grid.Row stretched> <Grid.Column> <Field required title={'Triggering event'} description="The rule will execute when the following event occurs." choices={triggeringEvents} value={event} onChange={(e, v) => this.setState({ event: v })} /> </Grid.Column> </Grid.Row> </Grid> </Form> </Segment> <Segment> <div style={{ display: 'flex', flexDirection: 'column' }}> <Checkbox onChange={(e, { checked }) => this.setState({ enabled: checked }) } label={'Enabled'} checked={enabled} /> <p style={{ color: '#878f93', paddingTop: '0.7rem', paddingBottom: '0.7rem', fontSize: '0.9rem', }} > <FormattedMessage id="Whether or not the rule is currently enabled" defaultMessage="Whether or not the rule is currently enabled" /> </p> </div> </Segment> <Segment> <div style={{ display: 'flex', flexDirection: 'column' }}> <Checkbox onChange={(e, { checked }) => this.setState({ stop: checked }) } label={'Stop Executing rules'} checked={stop} /> <p style={{ color: '#878f93', paddingTop: '0.7rem', paddingBottom: '0.7rem', fontSize: '0.9rem', }} > <FormattedMessage id="Whether or not execution of further rules should stop after this rule is executed" defaultMessage="Whether or not execution of further rules should stop after this rule is executed" /> </p> </div> </Segment> <Segment> <div style={{ display: 'flex', flexDirection: 'column' }}> <Checkbox onChange={(e, { checked }) => this.setState({ cascading: checked }) } label={'Cascading rule'} checked={cascading} /> <p style={{ color: '#878f93', paddingTop: '0.7rem', paddingBottom: '0.7rem', fontSize: '0.9rem', }} > <FormattedMessage id="Whether or not other rules should be triggered by the actions launched by this rule. Activate this only if you are sure this won't create infinite loops" defaultMessage="Whether or not other rules should be triggered by the actions launched by this rule. Activate this only if you are sure this won't create infinite loops" /> </p> </div> </Segment> <Segment> <Button onClick={() => this.handleAdd()} primary> <FormattedMessage id="Save" defaultMessage="Save" /> </Button> <Button onClick={() => this.onCancel()} secondary> <FormattedMessage id="Cancel" defaultMessage="Cancel" /> </Button> </Segment> <Segment> {this.state.invalidTitle && ( <p style={{ color: 'red' }}> <FormattedMessage id="Title field error. Value not provided or already existing." defaultMessage="Title field error. Value not provided or already existing." /> </p> )} {this.state.invalidEvent && ( <p style={{ color: 'red' }}> <FormattedMessage id="Triggering event field error. Please select a value" defaultMessage="Triggering event field error. Please select a value" /> </p> )} </Segment> </Segment.Group> </article> </Container> {this.state.isClient && createPortal( <Toolbar pathname={this.props.pathname} hideDefaultViewButtons inner={ <Link className="item" to="#" onClick={() => this.onCancel()}> <Icon name={backSVG} className="contents circled" size="30px" title={this.props.intl.formatMessage(messages.back)} /> </Link> } />, document.getElementById('toolbar'), )} </div> ); } } export default compose( injectIntl, connect( (state, props) => ({ rules: state.controlpanelrules, events: state.contentrulesevents, pathname: props.location.pathname, }), { getContentRulesEvents, addNewRule }, ), )(AddRule);