From 3e7adff87c091beea9d4d5041df7594af7a8a16f Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Mon, 10 Jul 2017 16:34:12 +0200 Subject: [PATCH 01/11] Created customizable input text --- .../admin/src/components/InputText/index.js | 138 ++++++++++++++++++ .../src/components/InputText/messages.js | 13 ++ .../src/components/InputText/styles.scss | 11 ++ .../components/InputText/tests/index.test.js | 11 ++ .../admin/src/containers/Home/index.js | 64 ++++++-- 5 files changed, 225 insertions(+), 12 deletions(-) create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/InputText/messages.js create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/InputText/styles.scss create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/InputText/tests/index.test.js diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js new file mode 100644 index 0000000000..eb4ab385cb --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js @@ -0,0 +1,138 @@ +/** +* +* InputText +* +*/ + +import React from 'react'; + +import { FormattedMessage } from 'react-intl'; +import messages from './messages'; +import styles from './styles.scss'; + +/* +* InpuText +* A customizable input +* Settings : +* - deactivateErrorHighlight +* - noBootstrap // remove bootStrapClass +* - overrideBootstrapGrid +* - overrideBootstrapCol +*/ + + + +class InputText extends React.Component { // eslint-disable-line react/prefer-stateless-function + constructor(props) { + super(props); + this.state = { + errors: false, + value: '', + }; + } + + componentWillReceiveProps(nextProps) { + if (this.props.errors !== nextProps.errors) { + const errors = _.isEmpty(nextProps.errors) ? nextProps.errors ? [] : false : nextProps.errors; + this.setState({ errors }); + } + } + + handleBlur = ({ target }) => { + // validates basic string validations + // add custom logic here such as alerts... + const errors = this.validate(target.value); + this.setState({ errors }); + } + + // Basic string validations + validate = (value) => { + let errors = []; + const requiredError = 'Field is required'; + _.mapKeys(this.props.validations, (validationValue, validationKey) => { + switch (validationKey) { + case 'maxLength': + if (value.length > validationValue) { + errors.push('Field is too long'); + } + break; + case 'minLength': + if (value.length < validationValue) { + errors.push('Field is too short'); + } + break; + case 'required': + if (value.length === 0) { + errors.push(requiredError); + } + break; + case 'regex': + if (!validationValue.test(value)) { + errors.push('Field is not valid'); + } + break; + default: + errors = false; + } + }); + if (_.isEmpty(errors)) { + errors = false; + } else if (_.includes(errors, requiredError)) { + errors = _.reject(errors, (value) => value !== requiredError); + } + return errors; + } + + render() { + const inputValue = this.props.value || ''; + // override default onBlur + const handleBlur = this.props.handleBlur || this.handleBlur; + // override bootStrapClass + const bootStrapClass = !this.props.noBootstrap ? + `col-${this.props.overrideBootstrapGrid || 'md'}-${this.props.overrideBootstrapCol || '6'}` + : ''; + // set error class with override possibility + const bootStrapClassDanger = !this.props.noBootstrap && !this.props.deactivateErrorHighlight && this.state.errors ? 'has-danger' : ''; + // use bootstrap class to display error + const formError = !this.props.noBootstrap ? 'form-control-feedback' : ''; + return ( +
+ + + {this.props.inputDescription} + {_.map(this.state.errors, (error, key) => ( +
{error}
+ ))} +
+ ); + } +} + +InputText.propTypes = { + errors: React.PropTypes.oneOfType([ + React.PropTypes.bool, + React.PropTypes.array, + ]), + deactivateErrorHighlight: React.PropTypes.bool, + handleBur: React.PropTypes.func, + handleChange: React.PropTypes.func.isRequired, + inputDescription: React.PropTypes.string, + name: React.PropTypes.string.isRequired, + noBootstrap: React.PropTypes.bool, + overrideBootstrapGrid: React.PropTypes.string, + overrideBootstrapCol: React.PropTypes.string, + placeholder: React.PropTypes.string, + value: React.PropTypes.string.isRequired, + validations: React.PropTypes.object.isRequired, +} + +export default InputText; diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputText/messages.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/messages.js new file mode 100644 index 0000000000..c275074664 --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/messages.js @@ -0,0 +1,13 @@ +/* + * InputText Messages + * + * This contains all the text for the InputText component. + */ +import { defineMessages } from 'react-intl'; + +export default defineMessages({ + header: { + id: 'app.components.InputText.header', + defaultMessage: 'This is the InputText component !', + }, +}); diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputText/styles.scss b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/styles.scss new file mode 100644 index 0000000000..4c93660779 --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/styles.scss @@ -0,0 +1,11 @@ +.inputText { /* stylelint-disable */ + margin-top: 1.8rem; + > label { + text-transform: capitalize; + } + > small { + margin-top: .5rem; + display: block; + color: #ABAFBB; + } +} diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputText/tests/index.test.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/tests/index.test.js new file mode 100644 index 0000000000..095f7b6e40 --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/tests/index.test.js @@ -0,0 +1,11 @@ +// import InputText from '../index'; + +import expect from 'expect'; +// import { shallow } from 'enzyme'; +// import React from 'react'; + +describe('', () => { + it('Expect to have unit tests specified', () => { + expect(true).toEqual(false); + }); +}); diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js b/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js index d09d296790..c557238f89 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js @@ -8,24 +8,38 @@ import React from 'react'; import { connect } from 'react-redux'; import Helmet from 'react-helmet'; import PluginLeftMenu from 'components/PluginLeftMenu'; +import InputText from 'components/InputText'; import selectHome from './selectors'; import styles from './styles.scss'; export class Home extends React.Component { // eslint-disable-line react/prefer-stateless-function - // constructor(props) { - // super(props); - // // this.leftMenuItems = [ - // // { - // // header: 'global settings', - // // items: [ - // // general, 'languages', 'advanced'], - // // } - // // ] - // } + constructor(props) { + super(props); + this.state = { + value: '', + } + } + handleChange = ({ target }) => { + console.log(target.value); + this.setState({ value: target.value }); + } render() { - + + const test = { + "name": "bame", + "slug": "name", + "target": "general.name", + "type": "text", + "value": "ExperienceApp", + "validations" : { + "maxLength": 2, + "required": true, + "regex": /^(([^<>()\[\]\\.,;:\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,}))$/ + } + }; + return (
@@ -39,7 +53,33 @@ export class Home extends React.Component { // eslint-disable-line react/prefer-
- f +
+ + + + +
From 1fc907f358754b276084b145624657b5440d022f Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Mon, 10 Jul 2017 16:40:58 +0200 Subject: [PATCH 02/11] remove useless state value --- .../admin/src/components/InputText/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js index eb4ab385cb..bd9ac8b573 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js @@ -27,7 +27,6 @@ class InputText extends React.Component { // eslint-disable-line react/prefer-st super(props); this.state = { errors: false, - value: '', }; } From 9abf0a0b80f0cc0c715e2342ab54e71d53014b23 Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Mon, 10 Jul 2017 17:55:46 +0200 Subject: [PATCH 03/11] created input number --- .../admin/src/components/InputNumber/index.js | 106 ++++++++++++++++++ .../src/components/InputNumber/messages.js | 13 +++ .../src/components/InputNumber/styles.scss | 11 ++ .../InputNumber/tests/index.test.js | 11 ++ .../admin/src/components/InputText/index.js | 12 +- .../admin/src/containers/Home/index.js | 17 +-- 6 files changed, 157 insertions(+), 13 deletions(-) create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/index.js create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/messages.js create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/styles.scss create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/tests/index.test.js diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/index.js new file mode 100644 index 0000000000..6533147a5b --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/index.js @@ -0,0 +1,106 @@ +/** +* +* InputNumber +* +*/ + +import React from 'react'; + +import { FormattedMessage } from 'react-intl'; +import messages from './messages'; +import styles from './styles.scss'; + +/* +* InputNumber +* A customizable input +* Settings : +* - deactivateErrorHighlight +* - noBootstrap // remove bootStrapClass +* - overrideBootstrapGrid +* - overrideBootstrapCol +* - handleBur : override default handleBlur function +*/ + + + +class InputNumber extends React.Component { // eslint-disable-line react/prefer-stateless-function + constructor(props) { + super(props); + this.state = { + errors: false, + }; + } + + componentWillReceiveProps(nextProps) { + if (this.props.errors !== nextProps.errors) { + const errors = _.isEmpty(nextProps.errors) ? nextProps.errors === true ? [] : false : nextProps.errors; + this.setState({ errors }); + } + } + + handleBlur = ({ target }) => { + const errors = this.validate(target.value); + this.setState({ errors }); + } + + validate = (value) => { + const errors = !_.isEmpty(_.pick(this.props.validations, 'required')) && value.length > 0 ? + false : ['This field is required']; + return errors; + } + + render() { + const inputValue = this.props.value || ''; + // override default onBlur + const handleBlur = this.props.handleBlur || this.handleBlur; + // override bootStrapClass + const bootStrapClass = !this.props.noBootstrap ? + `col-${this.props.overrideBootstrapGrid || 'md'}-${this.props.overrideBootstrapCol || '4'}` + : ''; + // set error class with override possibility + const bootStrapClassDanger = !this.props.noBootstrap && !this.props.deactivateErrorHighlight && this.state.errors ? 'has-danger' : ''; + // use bootstrap class to display error + const formError = !this.props.noBootstrap ? 'form-control-feedback' : ''; + const placeholder = this.props.placeholder || `Change ${this.props.name} field`; + return ( +
+ + + {this.props.inputDescription} + {_.map(this.state.errors, (error, key) => ( +
{error}
+ ))} +
+ ); + } +} + +InputNumber.propTypes = { + errors: React.PropTypes.oneOfType([ + React.PropTypes.bool, + React.PropTypes.array, + ]), + deactivateErrorHighlight: React.PropTypes.bool, + handleBur: React.PropTypes.func, + handleChange: React.PropTypes.func.isRequired, + inputDescription: React.PropTypes.string, + name: React.PropTypes.string.isRequired, + noBootstrap: React.PropTypes.bool, + overrideBootstrapGrid: React.PropTypes.string, + overrideBootstrapCol: React.PropTypes.string, + placeholder: React.PropTypes.string, + value: React.PropTypes.oneOfType([ + React.PropTypes.number.isRequired, + React.PropTypes.string.isRequired, + ]), + validations: React.PropTypes.object.isRequired, +} + +export default InputNumber; diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/messages.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/messages.js new file mode 100644 index 0000000000..73d80b9f9e --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/messages.js @@ -0,0 +1,13 @@ +/* + * InputNumber Messages + * + * This contains all the text for the InputNumber component. + */ +import { defineMessages } from 'react-intl'; + +export default defineMessages({ + header: { + id: 'app.components.InputNumber.header', + defaultMessage: 'This is the InputNumber component !', + }, +}); diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/styles.scss b/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/styles.scss new file mode 100644 index 0000000000..b1b0cb4056 --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/styles.scss @@ -0,0 +1,11 @@ +.inputNumber { /* stylelint-disable */ + margin-top: 1.8rem; + > label { + text-transform: capitalize; + } + > small { + margin-top: .5rem; + display: block; + color: #ABAFBB; + } +} diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/tests/index.test.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/tests/index.test.js new file mode 100644 index 0000000000..817540535a --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/tests/index.test.js @@ -0,0 +1,11 @@ +// import InputNumber from '../index'; + +import expect from 'expect'; +// import { shallow } from 'enzyme'; +// import React from 'react'; + +describe('', () => { + it('Expect to have unit tests specified', () => { + expect(true).toEqual(false); + }); +}); diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js index bd9ac8b573..2cc05d3a1d 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js @@ -11,13 +11,14 @@ import messages from './messages'; import styles from './styles.scss'; /* -* InpuText +* InputText * A customizable input * Settings : * - deactivateErrorHighlight * - noBootstrap // remove bootStrapClass * - overrideBootstrapGrid * - overrideBootstrapCol +* - handleBur : override default handleBlur function */ @@ -32,7 +33,7 @@ class InputText extends React.Component { // eslint-disable-line react/prefer-st componentWillReceiveProps(nextProps) { if (this.props.errors !== nextProps.errors) { - const errors = _.isEmpty(nextProps.errors) ? nextProps.errors ? [] : false : nextProps.errors; + const errors = _.isEmpty(nextProps.errors) ? nextProps.errors === true ? [] : false : nextProps.errors; this.setState({ errors }); } } @@ -94,6 +95,7 @@ class InputText extends React.Component { // eslint-disable-line react/prefer-st const bootStrapClassDanger = !this.props.noBootstrap && !this.props.deactivateErrorHighlight && this.state.errors ? 'has-danger' : ''; // use bootstrap class to display error const formError = !this.props.noBootstrap ? 'form-control-feedback' : ''; + const placeholder = this.props.placeholder || `Change ${this.props.name} field`; return (
@@ -104,8 +106,8 @@ class InputText extends React.Component { // eslint-disable-line react/prefer-st onChange={this.props.handleChange} value={inputValue} type="text" - className={`form-control ${this.state.errors? 'form-control-danger' : ''}`} - placeholder={`Change ${this.props.name} field`} + className={`${this.props.noBootstrap? '' : 'form-control'} ${this.state.errors? 'form-control-danger' : ''}`} + placeholder={placeholder} /> {this.props.inputDescription} {_.map(this.state.errors, (error, key) => ( @@ -122,7 +124,7 @@ InputText.propTypes = { React.PropTypes.array, ]), deactivateErrorHighlight: React.PropTypes.bool, - handleBur: React.PropTypes.func, + handleBlur: React.PropTypes.func, handleChange: React.PropTypes.func.isRequired, inputDescription: React.PropTypes.string, name: React.PropTypes.string.isRequired, diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js b/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js index c557238f89..0a3f599ff4 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js @@ -8,7 +8,7 @@ import React from 'react'; import { connect } from 'react-redux'; import Helmet from 'react-helmet'; import PluginLeftMenu from 'components/PluginLeftMenu'; -import InputText from 'components/InputText'; +import InputNumber from 'components/InputNumber'; import selectHome from './selectors'; import styles from './styles.scss'; @@ -34,7 +34,7 @@ export class Home extends React.Component { // eslint-disable-line react/prefer- "type": "text", "value": "ExperienceApp", "validations" : { - "maxLength": 2, + "maxLength": 255, "required": true, "regex": /^(([^<>()\[\]\\.,;:\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,}))$/ } @@ -55,28 +55,29 @@ export class Home extends React.Component { // eslint-disable-line react/prefer-
- - -
From aa5e0863b19d5b475890a88138133faa1cddc41d Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Tue, 11 Jul 2017 12:29:43 +0200 Subject: [PATCH 04/11] improve handleBlur function --- .../admin/src/components/InputText/index.js | 66 +++++++++++-------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js index 2cc05d3a1d..32f340655a 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js @@ -1,7 +1,26 @@ /** * * InputText +* Customization +* - deactivateErrorHighlight: bool +* allow the user to remove bootstrap class 'has-danger' on the inputText +* - customBootstrapClass : string +* overrides the default 'col-md-6' on the inputText +* - handleBlur: function +* overrides the default input validations +* - errors : array +* custom errors if set to false it deactivate error display * +* Required +* - name : string +* - handleChange : function +* - value : string +* - validations : object +* +* Optionnal +* - description : input description +* - handleFocus : function +* - placeholder : string if set to "" nothing will display */ import React from 'react'; @@ -10,27 +29,22 @@ import { FormattedMessage } from 'react-intl'; import messages from './messages'; import styles from './styles.scss'; -/* -* InputText -* A customizable input -* Settings : -* - deactivateErrorHighlight -* - noBootstrap // remove bootStrapClass -* - overrideBootstrapGrid -* - overrideBootstrapCol -* - handleBur : override default handleBlur function -*/ - - class InputText extends React.Component { // eslint-disable-line react/prefer-stateless-function constructor(props) { super(props); this.state = { errors: false, + hasInitialValue: false, }; } + componentDidMount() { + if (this.props.value.length > 0) { + this.setState({ hasInitialValue: true }); + } + } + componentWillReceiveProps(nextProps) { if (this.props.errors !== nextProps.errors) { const errors = _.isEmpty(nextProps.errors) ? nextProps.errors === true ? [] : false : nextProps.errors; @@ -39,10 +53,13 @@ class InputText extends React.Component { // eslint-disable-line react/prefer-st } handleBlur = ({ target }) => { - // validates basic string validations - // add custom logic here such as alerts... - const errors = this.validate(target.value); - this.setState({ errors }); + // prevent error display if input is initially empty + if (target.value.length > 0 || this.state.hasInitialValue) { + // validates basic string validations + // add custom logic here such as alerts... + const errors = this.validate(target.value); + this.setState({ errors }); + } } // Basic string validations @@ -88,13 +105,9 @@ class InputText extends React.Component { // eslint-disable-line react/prefer-st // override default onBlur const handleBlur = this.props.handleBlur || this.handleBlur; // override bootStrapClass - const bootStrapClass = !this.props.noBootstrap ? - `col-${this.props.overrideBootstrapGrid || 'md'}-${this.props.overrideBootstrapCol || '6'}` - : ''; + const bootStrapClass = this.props.customBootstrapClass ? this.props.customBootstrapClass : 'col-md-6'; // set error class with override possibility - const bootStrapClassDanger = !this.props.noBootstrap && !this.props.deactivateErrorHighlight && this.state.errors ? 'has-danger' : ''; - // use bootstrap class to display error - const formError = !this.props.noBootstrap ? 'form-control-feedback' : ''; + const bootStrapClassDanger = !this.props.deactivateErrorHighlight && this.state.errors ? 'has-danger' : ''; const placeholder = this.props.placeholder || `Change ${this.props.name} field`; return (
@@ -102,7 +115,7 @@ class InputText extends React.Component { // eslint-disable-line react/prefer-st {this.props.inputDescription} {_.map(this.state.errors, (error, key) => ( -
{error}
+
{error}
))}
); @@ -126,11 +139,10 @@ InputText.propTypes = { deactivateErrorHighlight: React.PropTypes.bool, handleBlur: React.PropTypes.func, handleChange: React.PropTypes.func.isRequired, + handleFocus: React.PropTypes.func, inputDescription: React.PropTypes.string, name: React.PropTypes.string.isRequired, - noBootstrap: React.PropTypes.bool, - overrideBootstrapGrid: React.PropTypes.string, - overrideBootstrapCol: React.PropTypes.string, + customBootstrapClass: React.PropTypes.string, placeholder: React.PropTypes.string, value: React.PropTypes.string.isRequired, validations: React.PropTypes.object.isRequired, From eb646999504f1a47af0335ddaadb1215a74ada60 Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Tue, 11 Jul 2017 15:39:00 +0200 Subject: [PATCH 05/11] added possibility to override bootstrap class --- .../admin/src/components/InputNumber/index.js | 71 ++++++++++------- .../admin/src/components/InputText/index.js | 79 ++++++++++--------- .../admin/src/components/InputToggle/index.js | 62 +++++++++++++++ .../src/components/InputToggle/messages.js | 13 +++ .../src/components/InputToggle/styles.scss | 3 + .../InputToggle/tests/index.test.js | 11 +++ .../admin/src/containers/Home/index.js | 43 ++++------ 7 files changed, 188 insertions(+), 94 deletions(-) create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/messages.js create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/styles.scss create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/tests/index.test.js diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/index.js index 6533147a5b..23b841bd72 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/index.js @@ -1,6 +1,26 @@ /** * * InputNumber +* Customization +* - deactivateErrorHighlight: bool +* allow the user to remove bootstrap class 'has-danger' on the inputText +* - customBootstrapClass : string +* overrides the default 'col-md-6' on the inputText +* - handleBlur: function +* overrides the default input validations +* - errors : array +* custom errors if set to false it deactivate error display +* +* Required +* - name : string +* - handleChange : function +* - value : string +* - validations : object +* +* Optionnal +* - description : input description +* - handleFocus : function +* - placeholder : string if set to "" nothing will display * */ @@ -10,27 +30,21 @@ import { FormattedMessage } from 'react-intl'; import messages from './messages'; import styles from './styles.scss'; -/* -* InputNumber -* A customizable input -* Settings : -* - deactivateErrorHighlight -* - noBootstrap // remove bootStrapClass -* - overrideBootstrapGrid -* - overrideBootstrapCol -* - handleBur : override default handleBlur function -*/ - - - class InputNumber extends React.Component { // eslint-disable-line react/prefer-stateless-function constructor(props) { super(props); this.state = { errors: false, + hasInitialValue: false, }; } + componentDidMount() { + if (this.props.value && this.props.value.length !== '') { + this.setState({ hasInitialValue: true }); + } + } + componentWillReceiveProps(nextProps) { if (this.props.errors !== nextProps.errors) { const errors = _.isEmpty(nextProps.errors) ? nextProps.errors === true ? [] : false : nextProps.errors; @@ -39,8 +53,13 @@ class InputNumber extends React.Component { // eslint-disable-line react/prefer- } handleBlur = ({ target }) => { - const errors = this.validate(target.value); - this.setState({ errors }); + // prevent error display if input is initially empty + if (target.value.length > 0 || this.state.hasInitialValue) { + // validates basic string validations + // add custom logic here such as alerts... + const errors = this.validate(target.value); + this.setState({ errors }); + } } validate = (value) => { @@ -54,28 +73,25 @@ class InputNumber extends React.Component { // eslint-disable-line react/prefer- // override default onBlur const handleBlur = this.props.handleBlur || this.handleBlur; // override bootStrapClass - const bootStrapClass = !this.props.noBootstrap ? - `col-${this.props.overrideBootstrapGrid || 'md'}-${this.props.overrideBootstrapCol || '4'}` - : ''; + const bootStrapClass = this.props.customBootstrapClass ? this.props.customBootstrapClass : 'col-md-4'; // set error class with override possibility - const bootStrapClassDanger = !this.props.noBootstrap && !this.props.deactivateErrorHighlight && this.state.errors ? 'has-danger' : ''; - // use bootstrap class to display error - const formError = !this.props.noBootstrap ? 'form-control-feedback' : ''; + const bootStrapClassDanger = !this.props.deactivateErrorHighlight && this.state.errors ? 'has-danger' : ''; const placeholder = this.props.placeholder || `Change ${this.props.name} field`; return (
- + {this.props.inputDescription} {_.map(this.state.errors, (error, key) => ( -
{error}
+
{error}
))}
); @@ -90,11 +106,10 @@ InputNumber.propTypes = { deactivateErrorHighlight: React.PropTypes.bool, handleBur: React.PropTypes.func, handleChange: React.PropTypes.func.isRequired, + handleFocus: React.PropTypes.func, inputDescription: React.PropTypes.string, name: React.PropTypes.string.isRequired, - noBootstrap: React.PropTypes.bool, - overrideBootstrapGrid: React.PropTypes.string, - overrideBootstrapCol: React.PropTypes.string, + customBootstrapClass: React.PropTypes.string, placeholder: React.PropTypes.string, value: React.PropTypes.oneOfType([ React.PropTypes.number.isRequired, diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js index 32f340655a..13a62ed400 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputText/index.js @@ -24,12 +24,8 @@ */ import React from 'react'; - -import { FormattedMessage } from 'react-intl'; -import messages from './messages'; import styles from './styles.scss'; - class InputText extends React.Component { // eslint-disable-line react/prefer-stateless-function constructor(props) { super(props); @@ -40,14 +36,19 @@ class InputText extends React.Component { // eslint-disable-line react/prefer-st } componentDidMount() { - if (this.props.value.length > 0) { + if (this.props.value && this.props.value.length > 0) { this.setState({ hasInitialValue: true }); } } componentWillReceiveProps(nextProps) { if (this.props.errors !== nextProps.errors) { - const errors = _.isEmpty(nextProps.errors) ? nextProps.errors === true ? [] : false : nextProps.errors; + let errors = false; + if (_.isEmpty(nextProps.errors)) { + errors = nextProps.errors === true ? [] : false; + } else { + errors = nextProps.errors; + } this.setState({ errors }); } } @@ -58,44 +59,45 @@ class InputText extends React.Component { // eslint-disable-line react/prefer-st // validates basic string validations // add custom logic here such as alerts... const errors = this.validate(target.value); - this.setState({ errors }); + this.setState({ errors, hasInitialValue: true }); } } // Basic string validations validate = (value) => { - let errors = []; - const requiredError = 'Field is required'; + let errors = []; + const requiredError = 'Field is required'; _.mapKeys(this.props.validations, (validationValue, validationKey) => { - switch (validationKey) { - case 'maxLength': - if (value.length > validationValue) { - errors.push('Field is too long'); - } - break; - case 'minLength': - if (value.length < validationValue) { - errors.push('Field is too short'); - } - break; - case 'required': - if (value.length === 0) { - errors.push(requiredError); - } - break; - case 'regex': - if (!validationValue.test(value)) { - errors.push('Field is not valid'); - } - break; - default: + switch (validationKey) { + case 'maxLength': + if (value.length > validationValue) { + errors.push('Field is too long'); + } + break; + case 'minLength': + if (value.length < validationValue) { + errors.push('Field is too short'); + } + break; + case 'required': + if (value.length === 0) { + errors.push(requiredError); + } + break; + case 'regex': + if (!validationValue.test(value)) { + errors.push('Field is not valid'); + } + break; + default: errors = false; - } + } }); + if (_.isEmpty(errors)) { errors = false; } else if (_.includes(errors, requiredError)) { - errors = _.reject(errors, (value) => value !== requiredError); + errors = _.reject(errors, (error) => error !== requiredError); } return errors; } @@ -111,15 +113,16 @@ class InputText extends React.Component { // eslint-disable-line react/prefer-st const placeholder = this.props.placeholder || `Change ${this.props.name} field`; return (
- + {this.props.inputDescription} @@ -132,20 +135,20 @@ class InputText extends React.Component { // eslint-disable-line react/prefer-st } InputText.propTypes = { + customBootstrapClass: React.PropTypes.string, + deactivateErrorHighlight: React.PropTypes.bool, errors: React.PropTypes.oneOfType([ React.PropTypes.bool, React.PropTypes.array, ]), - deactivateErrorHighlight: React.PropTypes.bool, handleBlur: React.PropTypes.func, handleChange: React.PropTypes.func.isRequired, handleFocus: React.PropTypes.func, inputDescription: React.PropTypes.string, name: React.PropTypes.string.isRequired, - customBootstrapClass: React.PropTypes.string, placeholder: React.PropTypes.string, - value: React.PropTypes.string.isRequired, validations: React.PropTypes.object.isRequired, + value: React.PropTypes.string.isRequired, } export default InputText; diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js new file mode 100644 index 0000000000..c0c21a26e8 --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js @@ -0,0 +1,62 @@ +/** +* +* InputToggle +* +*/ + +import React from 'react'; + +import { FormattedMessage } from 'react-intl'; +import messages from './messages'; +import styles from './styles.scss'; + +class InputToggle extends React.Component { // eslint-disable-line react/prefer-stateless-function + constructor(props) { + super(props); + this.state = { + + } + } + onChange = ({ target }) => { + console.log(target) + } + render() { + const btnClassOff = this.props.value ? 'btn btn-secondary' : 'btn btn-warning'; + const btnClassOn = this.props.value ? 'btn btn-primary' : 'btn btn-secondary'; + console.log(this.props.value); + + return ( +
+ + +
+ ); + } +} + +export default InputToggle; + + +// F76B00 diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/messages.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/messages.js new file mode 100644 index 0000000000..ab88ebb859 --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/messages.js @@ -0,0 +1,13 @@ +/* + * InputRadio Messages + * + * This contains all the text for the InputRadio component. + */ +import { defineMessages } from 'react-intl'; + +export default defineMessages({ + header: { + id: 'app.components.InputRadio.header', + defaultMessage: 'This is the InputRadio component !', + }, +}); diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/styles.scss b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/styles.scss new file mode 100644 index 0000000000..fd9581af5f --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/styles.scss @@ -0,0 +1,3 @@ +.inputRadio { /* stylelint-disable */ + +} diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/tests/index.test.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/tests/index.test.js new file mode 100644 index 0000000000..0543924b99 --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/tests/index.test.js @@ -0,0 +1,11 @@ +// import InputRadio from '../index'; + +import expect from 'expect'; +// import { shallow } from 'enzyme'; +// import React from 'react'; + +describe('', () => { + it('Expect to have unit tests specified', () => { + expect(true).toEqual(false); + }); +}); diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js b/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js index 0a3f599ff4..07162742b2 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js @@ -8,6 +8,7 @@ import React from 'react'; import { connect } from 'react-redux'; import Helmet from 'react-helmet'; import PluginLeftMenu from 'components/PluginLeftMenu'; +import InputToggle from 'components/InputToggle'; import InputNumber from 'components/InputNumber'; import selectHome from './selectors'; import styles from './styles.scss'; @@ -16,13 +17,14 @@ export class Home extends React.Component { // eslint-disable-line react/prefer- constructor(props) { super(props); this.state = { - value: '', + value: true, + value1: null, } } handleChange = ({ target }) => { - console.log(target.value); - this.setState({ value: target.value }); + + this.setState({ value1: target.value }); } render() { @@ -34,7 +36,7 @@ export class Home extends React.Component { // eslint-disable-line react/prefer- "type": "text", "value": "ExperienceApp", "validations" : { - "maxLength": 255, + "maxLength": 12, "required": true, "regex": /^(([^<>()\[\]\\.,;:\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,}))$/ } @@ -55,31 +57,16 @@ export class Home extends React.Component { // eslint-disable-line react/prefer-
- - - + +
From 4dd3b9675018e51b8819922e927fefa8a8ae0729 Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Tue, 11 Jul 2017 15:42:54 +0200 Subject: [PATCH 06/11] added override bootstrap class --- .../admin/src/components/InputNumber/index.js | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/index.js index 23b841bd72..01c1f53963 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputNumber/index.js @@ -25,9 +25,6 @@ */ import React from 'react'; - -import { FormattedMessage } from 'react-intl'; -import messages from './messages'; import styles from './styles.scss'; class InputNumber extends React.Component { // eslint-disable-line react/prefer-stateless-function @@ -47,7 +44,12 @@ class InputNumber extends React.Component { // eslint-disable-line react/prefer- componentWillReceiveProps(nextProps) { if (this.props.errors !== nextProps.errors) { - const errors = _.isEmpty(nextProps.errors) ? nextProps.errors === true ? [] : false : nextProps.errors; + let errors = false; + if (_.isEmpty(nextProps.errors)) { + errors = nextProps.errors === true ? [] : false; + } else { + errors = nextProps.errors; + } this.setState({ errors }); } } @@ -58,7 +60,7 @@ class InputNumber extends React.Component { // eslint-disable-line react/prefer- // validates basic string validations // add custom logic here such as alerts... const errors = this.validate(target.value); - this.setState({ errors }); + this.setState({ errors, hasInitialValue: true }); } } @@ -79,9 +81,11 @@ class InputNumber extends React.Component { // eslint-disable-line react/prefer- const placeholder = this.props.placeholder || `Change ${this.props.name} field`; return (
- + Date: Tue, 11 Jul 2017 18:41:51 +0200 Subject: [PATCH 07/11] created toggle input --- .../admin/src/components/InputToggle/index.js | 72 +++++++++---------- .../src/components/InputToggle/styles.scss | 37 +++++++++- .../admin/src/containers/Home/index.js | 18 ++--- 3 files changed, 79 insertions(+), 48 deletions(-) diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js index c0c21a26e8..59d57cf80a 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js @@ -5,9 +5,6 @@ */ import React from 'react'; - -import { FormattedMessage } from 'react-intl'; -import messages from './messages'; import styles from './styles.scss'; class InputToggle extends React.Component { // eslint-disable-line react/prefer-stateless-function @@ -17,46 +14,45 @@ class InputToggle extends React.Component { // eslint-disable-line react/prefer- } } - onChange = ({ target }) => { - console.log(target) - } - render() { - const btnClassOff = this.props.value ? 'btn btn-secondary' : 'btn btn-warning'; - const btnClassOn = this.props.value ? 'btn btn-primary' : 'btn btn-secondary'; - console.log(this.props.value); + render() { + const btnClassOff = this.props.isChecked ? 'btn ' : `btn ${styles.gradientOff}`; + const btnClassOn = this.props.isChecked ? `btn ${styles.gradientOn}` : 'btn'; + const customBootstrapClass = this.props.customBootstrapClass ? this.props.customBootstrapClass : 'col-md-4'; return ( -
- - +
+
+ + +
); } } +InputToggle.propTypes = { + customBootstrapClass: React.PropTypes.string, + handleChange: React.PropTypes.func.isRequired, + isChecked: React.PropTypes.bool.isRequired, + name: React.PropTypes.string.isRequired, +} + export default InputToggle; - - -// F76B00 diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/styles.scss b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/styles.scss index fd9581af5f..fd69de2011 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/styles.scss +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/styles.scss @@ -1,3 +1,36 @@ -.inputRadio { /* stylelint-disable */ - +.inputToggle { /* stylelint-disable */ + > label { + // display and box model + width: 5.3rem; + height: 3.4rem; + padding: 0; + line-height: 3.2rem; + border: 1px solid #E3E9F3; + // color + color: #333740; + background-color: white; + // text + font-weight: 600; + font-size: 1.2rem; + letter-spacing: 0.07rem; + &:first-of-type { + border-right: none; + } + &:nth-of-type(2) { + border-left: none; + } + &:hover { + z-index: 0 !important; + } + } +} + +.gradientOff { + background-image: linear-gradient( to bottom right, #F65A1D, #F68E0E ); + color: white !important; +} + +.gradientOn { + background-image: linear-gradient( to bottom right, #005EEA, #0097F6); + color: white !important; } diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js b/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js index 07162742b2..6e1a89f575 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js @@ -9,7 +9,7 @@ import { connect } from 'react-redux'; import Helmet from 'react-helmet'; import PluginLeftMenu from 'components/PluginLeftMenu'; import InputToggle from 'components/InputToggle'; -import InputNumber from 'components/InputNumber'; +import InputText from 'components/InputText'; import selectHome from './selectors'; import styles from './styles.scss'; @@ -17,14 +17,15 @@ export class Home extends React.Component { // eslint-disable-line react/prefer- constructor(props) { super(props); this.state = { - value: true, + value: false, value1: null, } } handleChange = ({ target }) => { - - this.setState({ value1: target.value }); + console.log('ok'); + console.log(target); + this.setState({ value: !this.state.value}); } render() { @@ -59,14 +60,15 @@ export class Home extends React.Component { // eslint-disable-line react/prefer- - +
From cf70cd69a5fea58b82acccd14198cb07d6caabbe Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Tue, 11 Jul 2017 19:10:17 +0200 Subject: [PATCH 08/11] disable eslint to use bootstrap checkbox group --- .../admin/src/components/InputToggle/index.js | 8 +------- .../admin/src/containers/Home/index.js | 1 - 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js index 59d57cf80a..d07ec913a3 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js @@ -8,14 +8,8 @@ import React from 'react'; import styles from './styles.scss'; class InputToggle extends React.Component { // eslint-disable-line react/prefer-stateless-function - constructor(props) { - super(props); - this.state = { - - } - } - render() { + /* eslint-disable react/jsx-no-duplicate-props */ const btnClassOff = this.props.isChecked ? 'btn ' : `btn ${styles.gradientOff}`; const btnClassOn = this.props.isChecked ? `btn ${styles.gradientOn}` : 'btn'; const customBootstrapClass = this.props.customBootstrapClass ? this.props.customBootstrapClass : 'col-md-4'; diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js b/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js index 6e1a89f575..9a55f954dd 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/Home/index.js @@ -9,7 +9,6 @@ import { connect } from 'react-redux'; import Helmet from 'react-helmet'; import PluginLeftMenu from 'components/PluginLeftMenu'; import InputToggle from 'components/InputToggle'; -import InputText from 'components/InputText'; import selectHome from './selectors'; import styles from './styles.scss'; From 0e837623294786c28a6c8167a733b77d426eb05b Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Wed, 12 Jul 2017 14:21:20 +0200 Subject: [PATCH 09/11] omprove behavior of InputToggle --- .../admin/src/components/InputToggle/index.js | 63 ++++++++++++------- .../src/components/InputToggle/styles.scss | 2 +- .../admin/src/containers/App/actions.js | 5 ++ .../admin/src/containers/App/constants.js | 3 + .../admin/src/containers/App/index.js | 24 ++++++- .../admin/src/routes.json | 4 +- 6 files changed, 73 insertions(+), 28 deletions(-) diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js index d07ec913a3..deda4827f2 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/index.js @@ -1,41 +1,58 @@ /** * * InputToggle +* Customization +* - customBootstrapClass : string +* overrides the default col-md-4 class * +* Required +* - handleChange: function +* - name: string +* - isChecked: bool */ import React from 'react'; import styles from './styles.scss'; class InputToggle extends React.Component { // eslint-disable-line react/prefer-stateless-function + constructor(props) { + super(props); + this.state = { + isChecked: false, + }; + } + + componentDidMount() { + const isChecked = this.props.isChecked ? this.props.isChecked : false; + this.setState({ isChecked }); + } + + toggle = (e) => { + let isChecked = this.state.isChecked; + + // prevent the toggle if the user clicks on the already selected input + if (e.target.id === "on" && !this.state.isChecked) { + isChecked = true; + } else if (e.target.id === "off" && this.state.isChecked) { + isChecked = false; + } + const target = { + name: this.props.name, + value: isChecked, + }; + this.setState({ isChecked }); + this.props.handleChange({target}); + } + render() { - /* eslint-disable react/jsx-no-duplicate-props */ - const btnClassOff = this.props.isChecked ? 'btn ' : `btn ${styles.gradientOff}`; - const btnClassOn = this.props.isChecked ? `btn ${styles.gradientOn}` : 'btn'; + const btnClassOff = this.state.isChecked ? 'btn ' : `btn ${styles.gradientOff}`; + const btnClassOn = this.state.isChecked ? `btn ${styles.gradientOn}` : 'btn'; const customBootstrapClass = this.props.customBootstrapClass ? this.props.customBootstrapClass : 'col-md-4'; return (
- - + +
); diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/styles.scss b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/styles.scss index fd69de2011..b13373e29d 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/styles.scss +++ b/packages/strapi-plugin-setings-manager/admin/src/components/InputToggle/styles.scss @@ -1,5 +1,5 @@ .inputToggle { /* stylelint-disable */ - > label { + > button { // display and box model width: 5.3rem; height: 3.4rem; diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/App/actions.js b/packages/strapi-plugin-setings-manager/admin/src/containers/App/actions.js index a5002ad023..5f87b32260 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/App/actions.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/App/actions.js @@ -3,3 +3,8 @@ * App actions * */ + +import { + LOAD_DATA, + DATA_LOADED, +} from './constants'; diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/App/constants.js b/packages/strapi-plugin-setings-manager/admin/src/containers/App/constants.js index f62c609507..8df60a1d58 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/App/constants.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/App/constants.js @@ -3,3 +3,6 @@ * App constants * */ + +export const LOAD_DATA = 'SettingsManager/App/LOAD_DATA'; +export const DATA_LOADED = 'SettingsManager/App/DATA_LOADED'; diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/App/index.js b/packages/strapi-plugin-setings-manager/admin/src/containers/App/index.js index a1aa9d8041..bf953df7fe 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/App/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/App/index.js @@ -9,8 +9,23 @@ import React from 'react'; import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; import { pluginId } from 'app'; +import PluginLeftMenu from 'components/PluginLeftMenu'; +import styles from './styles.scss'; class App extends React.Component { + + constructor(props) { + super(props); + this.state = { + value: false, + value1: null, + } + } + + handleChange = ({ target }) => { + this.setState({ value: target.value}); + } + render() { // Assign plugin component to children const content = React.Children.map(this.props.children, child => @@ -18,9 +33,14 @@ class App extends React.Component { exposedComponents: this.props.exposedComponents, }) ); - return ( -
+
+
+
+
+ +
+
{React.Children.toArray(content)}
); diff --git a/packages/strapi-plugin-setings-manager/admin/src/routes.json b/packages/strapi-plugin-setings-manager/admin/src/routes.json index 43d0316f07..ecdedccf41 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/routes.json +++ b/packages/strapi-plugin-setings-manager/admin/src/routes.json @@ -1,6 +1,6 @@ { "/": { - "name": "home", - "container": "Home" + "name": "app", + "container": "App" } } From 84261bffd75d88a3f67382ccc2bc3a7c9ef08677 Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Wed, 12 Jul 2017 15:57:15 +0200 Subject: [PATCH 10/11] added sagas to fetch settings --- .../admin/src/containers/App/actions.js | 18 +++++++++-- .../admin/src/containers/App/constants.js | 4 +-- .../admin/src/containers/App/index.js | 22 +++++++++++--- .../admin/src/containers/App/reducer.js | 11 +++++-- .../admin/src/containers/App/sagas.js | 30 +++++++++++++++++++ .../admin/src/containers/App/selectors.js | 5 ++-- .../admin/src/containers/App/styles.scss | 17 +++++++++++ 7 files changed, 95 insertions(+), 12 deletions(-) create mode 100644 packages/strapi-plugin-setings-manager/admin/src/containers/App/sagas.js create mode 100644 packages/strapi-plugin-setings-manager/admin/src/containers/App/styles.scss diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/App/actions.js b/packages/strapi-plugin-setings-manager/admin/src/containers/App/actions.js index 5f87b32260..53fe721d60 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/App/actions.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/App/actions.js @@ -5,6 +5,20 @@ */ import { - LOAD_DATA, - DATA_LOADED, + MENU_FETCH, + MENU_FETCH_SUCCEEDED, } from './constants'; + + +export function menuFetch() { + return { + type: MENU_FETCH, + }; +} + +export function fetchMenuSucceeded(menu) { + return { + type: MENU_FETCH_SUCCEEDED, + menu, + }; +} diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/App/constants.js b/packages/strapi-plugin-setings-manager/admin/src/containers/App/constants.js index 8df60a1d58..7dd0fdbe37 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/App/constants.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/App/constants.js @@ -4,5 +4,5 @@ * */ -export const LOAD_DATA = 'SettingsManager/App/LOAD_DATA'; -export const DATA_LOADED = 'SettingsManager/App/DATA_LOADED'; +export const MENU_FETCH = 'SettingsManager/App/MENU_FETCH'; +export const MENU_FETCH_SUCCEEDED = 'SettingsManager/App/MENU_FETCH_SUCCEEDED'; diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/App/index.js b/packages/strapi-plugin-setings-manager/admin/src/containers/App/index.js index bf953df7fe..7087a33bd8 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/App/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/App/index.js @@ -8,8 +8,12 @@ import React from 'react'; import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; +import { bindActionCreators } from 'redux'; import { pluginId } from 'app'; import PluginLeftMenu from 'components/PluginLeftMenu'; + +import { menuFetch } from './actions'; +import selectGlobalDomain from './selectors'; import styles from './styles.scss'; class App extends React.Component { @@ -22,6 +26,10 @@ class App extends React.Component { } } + componentDidMount() { + this.props.menuFetch(); + } + handleChange = ({ target }) => { this.setState({ value: target.value}); } @@ -33,6 +41,7 @@ class App extends React.Component { exposedComponents: this.props.exposedComponents, }) ); + console.log(this.props.app) return (
@@ -57,12 +66,17 @@ App.propTypes = { }; export function mapDispatchToProps(dispatch) { - return { - dispatch, - }; + return bindActionCreators( + { + menuFetch, + }, + dispatch + ); } -const mapStateToProps = createStructuredSelector({}); +const mapStateToProps = createStructuredSelector({ + app: selectGlobalDomain(), +}); // Wrap the component to inject dispatch and state into it export default connect(mapStateToProps, mapDispatchToProps)(App); diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/App/reducer.js b/packages/strapi-plugin-setings-manager/admin/src/containers/App/reducer.js index 38026c39cd..01d81d2fe5 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/App/reducer.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/App/reducer.js @@ -4,12 +4,19 @@ * */ -import { fromJS } from 'immutable'; +import { fromJS, List } from 'immutable'; +import { + MENU_FETCH_SUCCEEDED, +} from './constants'; -const initialState = fromJS({}); +const initialState = fromJS({ + sections: List() +}); function appReducer(state = initialState, action) { switch (action.type) { + case MENU_FETCH_SUCCEEDED: + return state.set('menuSections', action.menu.sections); default: return state; } diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/App/sagas.js b/packages/strapi-plugin-setings-manager/admin/src/containers/App/sagas.js new file mode 100644 index 0000000000..45e3ca5c5c --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/App/sagas.js @@ -0,0 +1,30 @@ +import { takeLatest } from 'redux-saga'; +import { LOCATION_CHANGE } from 'react-router-redux'; +import { put, fork } from 'redux-saga/effects'; + +import { fetchMenuSucceeded } from './actions'; +import { MENU_FETCH } from './constants'; + +export function* fetchMenu() { + try { + const opts = { + method: 'GET', + }; + const response = yield fetch('/settings-manager/menu', opts); + const data = yield response.json(); + + yield put(fetchMenuSucceeded(data)); + + } catch(err) { + window.Strapi.notification.error( + 'An error occurred.' + ); + } +} + + +function* defaultSaga() { + yield fork(takeLatest, MENU_FETCH, fetchMenu); +} + +export default [defaultSaga]; diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/App/selectors.js b/packages/strapi-plugin-setings-manager/admin/src/containers/App/selectors.js index b3654897ca..d65351b535 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/App/selectors.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/App/selectors.js @@ -1,10 +1,10 @@ -// import { createSelector } from 'reselect'; +import { createSelector } from 'reselect'; /** * Direct selector to the list state domain */ -// const selectGlobalDomain = () => state => state.get('global'); +const selectGlobalDomain = () => state => state.get('global'); const selectLocationState = () => { let prevRoutingState; @@ -23,3 +23,4 @@ const selectLocationState = () => { }; export { selectLocationState }; +export default selectGlobalDomain; diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/App/styles.scss b/packages/strapi-plugin-setings-manager/admin/src/containers/App/styles.scss new file mode 100644 index 0000000000..ea67d5f306 --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/App/styles.scss @@ -0,0 +1,17 @@ +.app { /* stylelint-disable */ + min-height: calc(100vh - 6rem); // TODO should be variable + background: rgba(14,22,34,0.02); +} +.baseline { + // display: none; + z-index: 100001; + opacity: .2; + position: absolute; + top:0; left:0; + width: 100%; + height: 500%; + min-height: 100%; + background: url('../../assets/images/baseline-18.png'); + // background: url('../../assets/images/baseline-20.png'); + pointer-events: none; +} From 2cfe18cedbccd93cb11d412bee0c609c66d01d68 Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Wed, 12 Jul 2017 16:18:58 +0200 Subject: [PATCH 11/11] remove useless console log change leftmenu stateless function to react component --- .../src/components/PluginLeftMenu/index.js | 28 +++++++++++++++---- .../components/PluginLeftMenuSection/index.js | 20 +++++++++++++ .../PluginLeftMenuSection/styles.scss | 3 ++ .../PluginLeftMenuSection/tests/index.test.js | 11 ++++++++ .../admin/src/containers/App/index.js | 5 ++-- .../admin/src/containers/App/reducer.js | 2 +- 6 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenuSection/index.js create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenuSection/styles.scss create mode 100644 packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenuSection/tests/index.test.js diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenu/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenu/index.js index afd3f5c424..e5db9618b4 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenu/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenu/index.js @@ -9,12 +9,28 @@ import React from 'react'; import PluginLeftMenuHeader from 'components/PluginLeftMenuHeader'; import styles from './styles.scss'; -function PluginLeftMenu() { - return ( -
- -
- ); +class PluginLeftMenu extends React.Component { // eslint-disable-line react/prefer-stateless-function + constructor(props) { + super(props); + } + + render() { + return ( +
+ +
+ ); + } } + + +// function PluginLeftMenu() { +// return ( +//
+// +//
+// ); +// } + export default PluginLeftMenu; diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenuSection/index.js b/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenuSection/index.js new file mode 100644 index 0000000000..9808e26b0b --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenuSection/index.js @@ -0,0 +1,20 @@ +/** +* +* PluginLeftMenuSection +* +*/ + +import React from 'react'; + +import styles from './styles.scss'; + +class PluginLeftMenuSection extends React.Component { // eslint-disable-line react/prefer-stateless-function + render() { + return ( +
+
+ ); + } +} + +export default PluginLeftMenuSection; diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenuSection/styles.scss b/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenuSection/styles.scss new file mode 100644 index 0000000000..7cc932c4f2 --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenuSection/styles.scss @@ -0,0 +1,3 @@ +.pluginLeftMenuSection { /* stylelint-disable */ + +} diff --git a/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenuSection/tests/index.test.js b/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenuSection/tests/index.test.js new file mode 100644 index 0000000000..ceb92b0f1c --- /dev/null +++ b/packages/strapi-plugin-setings-manager/admin/src/components/PluginLeftMenuSection/tests/index.test.js @@ -0,0 +1,11 @@ +// import PluginLeftMenuSection from '../index'; + +import expect from 'expect'; +// import { shallow } from 'enzyme'; +// import React from 'react'; + +describe('', () => { + it('Expect to have unit tests specified', () => { + expect(true).toEqual(false); + }); +}); diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/App/index.js b/packages/strapi-plugin-setings-manager/admin/src/containers/App/index.js index 7087a33bd8..ad67697595 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/App/index.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/App/index.js @@ -41,13 +41,12 @@ class App extends React.Component { exposedComponents: this.props.exposedComponents, }) ); - console.log(this.props.app) return (
- +
{React.Children.toArray(content)} @@ -61,7 +60,7 @@ App.contextTypes = { }; App.propTypes = { - children: React.PropTypes.node.isRequired, + children: React.PropTypes.node, exposedComponents: React.PropTypes.object.isRequired, }; diff --git a/packages/strapi-plugin-setings-manager/admin/src/containers/App/reducer.js b/packages/strapi-plugin-setings-manager/admin/src/containers/App/reducer.js index 01d81d2fe5..c302cf9b88 100644 --- a/packages/strapi-plugin-setings-manager/admin/src/containers/App/reducer.js +++ b/packages/strapi-plugin-setings-manager/admin/src/containers/App/reducer.js @@ -10,7 +10,7 @@ import { } from './constants'; const initialState = fromJS({ - sections: List() + sections: List(), }); function appReducer(state = initialState, action) {