return (model, form, notification) => { if (!_.get(notification, 'handlers.slack.send')) { return null; } return ( <Ui.Tabs.Tab label={Webiny.I18n('Slack message')} icon="fa-slack"> <Ui.Grid.Row> <Ui.Grid.Col all={12}> <Ui.Input label={Webiny.I18n('Token')} name="slack.token" placeholder={Webiny.I18n('Leave empty to use Slack settings')}/> <Ui.Input label={Webiny.I18n('Team')} name="slack.team" placeholder={Webiny.I18n('Leave empty to use Slack settings')}/> <Ui.Input label={Webiny.I18n('Username')} name="slack.username" placeholder={Webiny.I18n('Leave empty to use Slack settings')}/> <Ui.Input label={Webiny.I18n('Channel/User')} name="slack.channel" placeholder={Webiny.I18n('Leave empty to use Slack message channel')} description={Webiny.I18n('Specify a channel or username: #general or @mark')}/> </Ui.Grid.Col> </Ui.Grid.Row> </Ui.Tabs.Tab> ); }
formValidator.addValidator('email', (value) => { const re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; if (!value || (value.length && re.test(value))) { return true; } throw new ValidationError(Webiny.I18n('Please enter a valid email address')); });
formValidator.addValidator('integer', (value) => { const re = new RegExp('^\-?[0-9]+$'); if (!value || (re.test(value))) { return true; } throw new ValidationError(Webiny.I18n('This field needs to be an integer')); });
formValidator.addValidator('lte', (value, max) => { if (!value || parseFloat(value) <= parseFloat(max)) { return true; } throw new ValidationError(Webiny.I18n('This field needs to be less than or equal to', {max})); });
formValidator.addValidator('creditCardExpiration', (value) => { if (_.isPlainObject(value) && !isNaN(parseInt(value.month)) && !isNaN(parseInt(value.year))) { return true; } throw new ValidationError(Webiny.I18n('Please select month and year')); });
formValidator.addValidator('url', (value) => { const regex = new RegExp(/^(https?:\/\/)((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3}))(\:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?(\#[-a-z\d_]*)?$/i); if (!value || regex.test(value)) { return true; } throw new ValidationError(Webiny.I18n('Please enter a valid URL')); });
init() { this.name = 'Settings'; const Menu = Webiny.Ui.Menu; const role = 'notification-manager'; this.registerMenus( <Menu label={Webiny.I18n('Marketing Tools')} icon="fa-bell"> <Menu label={Webiny.I18n('Notification Manager')} role={role}> <Menu label={Webiny.I18n('Settings')} route="NotificationManager.Settings"/> </Menu> </Menu> ); this.registerRoutes( new Webiny.Route('NotificationManager.Settings', '/notification-manager/settings', SettingsForm, 'Notification Manager - Settings').setRole(role) ); }
return form.api.get('/').then(apiResponse => { form.hideLoading(); if (apiResponse.isError()) { Webiny.Growl.danger(apiResponse.getMessage(), Webiny.I18n('That didn\'t go as expected...'), true); return form.handleApiError(apiResponse); } return apiResponse.getData(); });
formValidator.addValidator('minLength', (value, length) => { if (_.isObject(value)) { value = _.keys(value); } if (!value || (value.length && value.length >= length)) { return true; } throw new ValidationError(Webiny.I18n('This field requires at least {length} characters', {length})); });
init() { this.name = 'Templates'; const Menu = Webiny.Ui.Menu; const role = 'notification-manager'; this.registerMenus( <Menu label={Webiny.I18n('Marketing Tools')} icon="fa-bell"> <Menu label={Webiny.I18n('Notification Manager')} role={role}> <Menu label={Webiny.I18n('Templates')} route="NotificationManager.Templates"/> </Menu> </Menu> ); this.registerRoutes( new Webiny.Route('NotificationManager.Templates', '/notification-manager/templates', Views.TemplateList, 'Notification Manager - Templates').setRole(role), new Webiny.Route('NotificationManager.Template.Edit', '/notification-manager/template/:id', Views.TemplateForm, 'Notification Manager - Edit Template').setRole(role), new Webiny.Route('NotificationManager.Template.Create', '/notification-manager/template', Views.TemplateForm, 'Notification Manager - New Template').setRole(role) ); }
formValidator.addValidator('json', (value) => { if (!value) { return true; } try { JSON.parse(value); } catch (e) { throw new ValidationError(Webiny.I18n('Please enter a valid JSON string')); } return true; });
formValidator.addValidator('creditCard', (value) => { if (!value) { return true; } if (value.length < 12) { throw new ValidationError(Webiny.I18n('Credit card number too short')); } if (/[^0-9-\s]+/.test(value)) throw new ValidationError(Webiny.I18n('Credit card number invalid')); let nCheck = 0; let nDigit = 0; let bEven = false; value = value.replace(/ /g, ''); value = value.replace(/\D/g, ''); for (let n = value.length - 1; n >= 0; n--) { const cDigit = value.charAt(n); nDigit = parseInt(cDigit); if (bEven) { nDigit *= 2; if (nDigit > 9) { nDigit -= 9; } } nCheck += nDigit; bEven = !bEven; } if ((nCheck % 10) === 0) { return true; } throw new ValidationError(Webiny.I18n('Credit card number invalid')); });
formValidator.addValidator('password', (value) => { if (DEVELOPMENT) { if (!value || ['dev', 'admin'].indexOf(value) > -1) { return true; } } if (PRODUCTION) { if (!value) { return true; } } const test = value.match(/^.{8,}$/); if (test === null) { throw new ValidationError(Webiny.I18n('Password must contain at least 8 characters')); } return true; });
formValidator.addValidator('required', (value) => { if (!(!value || value === '' || value === 0 || (_.isArray(value) && value.length === 0))) { return true; } throw new ValidationError(Webiny.I18n('This field is required')); });
onSuccessMessage: () => Webiny.I18n('Settings saved!'),
Webiny.import(['Growl', 'Progress']).then(({Growl, Progress}) => { const cmp = <div>Your data is being uploaded...<Progress value={event.progress}/></div>; Webiny.Growl(<Growl.Info id={form.growlId} title={Webiny.I18n('Please be patient')} sticky={true}>{cmp}</Growl.Info>); });
createHttpMethod: 'post', validateOnFirstSubmit: false, onSubmit: null, onSubmitSuccess: null, onSubmitError: _.noop, onFailure: _.noop, onLoad: _.noop, prepareLoadedData: null, onProgress({event, form}) { Webiny.import(['Growl', 'Progress']).then(({Growl, Progress}) => { const cmp = <div>Your data is being uploaded...<Progress value={event.progress}/></div>; Webiny.Growl(<Growl.Info id={form.growlId} title={Webiny.I18n('Please be patient')} sticky={true}>{cmp}</Growl.Info>); }); }, onSuccessMessage() { return Webiny.I18n('Your record was saved successfully!'); }, renderer() { return ( <webiny-form-container onKeyDown={this.__onKeyDown}>{this.__renderContent()}</webiny-form-container> ); } }; export default Webiny.createComponent(Form, { api: [ 'bindTo', 'resetForm', 'getInitialModel', 'getModel', 'setModel',
formValidator.addValidator('gte', (value, min) => { if (!value || parseFloat(value) >= parseFloat(min)) { return true; } throw new ValidationError(Webiny.I18n('This field needs to be greater than or equal to', {min})); });
import React from 'react'; import _ from 'lodash'; import Webiny from 'webiny'; /** * @i18n.namespace Webiny.Ui.Form.Error */ class ContainerError extends Webiny.Ui.Component { } ContainerError.defaultProps = { error: null, title: Webiny.I18n('Oops'), type: 'error', message: null, className: null, close: true, onClose: _.noop, renderer() { const {error, onClose, close, title, type, className, message} = this.props; if (!error) { return null; } if (_.isFunction(this.props.children)) { return this.props.children({error}); } const {Alert} = this.props;
} /** * The `data` param can be used when creating a custom confirmation dialog (maybe even with a form). * When calling `confirm` callback - whatever data is passed to it will be passed down to original `onClick` handler. * That way you can dynamically handle the different scenarios of the confirmation dialog. * * @returns {Promise.<*>} */ onConfirm(data = {}) { return Promise.resolve(this.realOnClick(data, this)); } } ClickConfirm.defaultProps = { message: Webiny.I18n('We need you to confirm your action.'), onComplete: _.noop, onCancel: _.noop, renderDialog: null, renderer() { // Input const input = this.getInput(this.props); this.realOnClick = input.props.onClick; const props = _.omit(input.props, ['onClick']); props.onClick = this.onClick; const dialogProps = { ref: 'dialog', message: this.message, onConfirm: this.onConfirm,
action={cropper.action} onHidden={this.onCropperHidden} onCrop={this.applyCropping} config={cropper.config} image={this.state.cropImage}> {children} </Cropper.Modal> ); } } Gallery.defaultProps = { accept: ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'], sizeLimit: 10000000, maxImages: null, maxImagesMessage: Webiny.I18n('Maximum number of images reached!'), newCropper: {}, editCropper: {}, onSaveImage: _.noop, renderer() { const {FileReader, Alert, Input, FormGroup, styles} = this.props; let message = null; if (this.state.images.length === 0) { message = ( <div> <span className={styles.mainText}>{this.i18n('DRAG FILES HERE')}</span> </div> ); }
formValidator.addValidator('phone', (value) => { if (!value || value.match(/^[-+0-9()\s]+$/)) { return true; } throw new ValidationError(Webiny.I18n('Please enter a valid phone number')); });
formValidator.addValidator('eq', (value, equalTo) => { if (value === equalTo) { return true; } throw new ValidationError(Webiny.I18n('This field must be equal to {equalTo}', {equalTo})); });