mirror of
https://github.com/strapi/strapi.git
synced 2025-08-12 10:48:12 +00:00
Merge branch 'plugin/settings-manager-dev' of github.com:soupette/strapi into plugin/settings-manager-dev
This commit is contained in:
commit
1b0e48014d
@ -0,0 +1,125 @@
|
||||
/**
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import styles from './styles.scss';
|
||||
|
||||
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) {
|
||||
let errors = false;
|
||||
if (_.isEmpty(nextProps.errors)) {
|
||||
errors = nextProps.errors === true ? [] : false;
|
||||
} else {
|
||||
errors = nextProps.errors;
|
||||
}
|
||||
this.setState({ errors });
|
||||
}
|
||||
}
|
||||
|
||||
handleBlur = ({ target }) => {
|
||||
// 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, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
|
||||
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.customBootstrapClass ? this.props.customBootstrapClass : 'col-md-4';
|
||||
// set error class with override possibility
|
||||
const bootStrapClassDanger = !this.props.deactivateErrorHighlight && this.state.errors ? 'has-danger' : '';
|
||||
const placeholder = this.props.placeholder || `Change ${this.props.name} field`;
|
||||
return (
|
||||
<div className={`${styles.inputNumber} ${bootStrapClass} ${bootStrapClassDanger}`}>
|
||||
<label htmlFor={this.props.name}>{this.props.name}</label>
|
||||
<input
|
||||
type="number"
|
||||
name={this.props.name}
|
||||
id={this.props.name}
|
||||
value={inputValue}
|
||||
onBlur={handleBlur}
|
||||
onChange={this.props.handleChange}
|
||||
onFocus={this.props.handleFocus}
|
||||
className={`form-control ${this.state.errors? 'form-control-danger' : ''}`}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
<small>{this.props.inputDescription}</small>
|
||||
{_.map(this.state.errors, (error, key) => (
|
||||
<div key={key} className="form-control-feedback">{error}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
InputNumber.propTypes = {
|
||||
customBootstrapClass: React.PropTypes.string,
|
||||
deactivateErrorHighlight: React.PropTypes.bool,
|
||||
errors: React.PropTypes.oneOfType([
|
||||
React.PropTypes.bool,
|
||||
React.PropTypes.array,
|
||||
]),
|
||||
handleBlur: React.PropTypes.func,
|
||||
handleChange: React.PropTypes.func.isRequired,
|
||||
handleFocus: React.PropTypes.func,
|
||||
inputDescription: React.PropTypes.string,
|
||||
name: React.PropTypes.string.isRequired,
|
||||
placeholder: React.PropTypes.string,
|
||||
validations: React.PropTypes.object.isRequired,
|
||||
value: React.PropTypes.oneOfType([
|
||||
React.PropTypes.number.isRequired,
|
||||
React.PropTypes.string.isRequired,
|
||||
]),
|
||||
}
|
||||
|
||||
export default InputNumber;
|
@ -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 !',
|
||||
},
|
||||
});
|
@ -0,0 +1,11 @@
|
||||
.inputNumber { /* stylelint-disable */
|
||||
margin-top: 1.8rem;
|
||||
> label {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
> small {
|
||||
margin-top: .5rem;
|
||||
display: block;
|
||||
color: #ABAFBB;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
// import InputNumber from '../index';
|
||||
|
||||
import expect from 'expect';
|
||||
// import { shallow } from 'enzyme';
|
||||
// import React from 'react';
|
||||
|
||||
describe('<InputNumber />', () => {
|
||||
it('Expect to have unit tests specified', () => {
|
||||
expect(true).toEqual(false);
|
||||
});
|
||||
});
|
@ -0,0 +1,154 @@
|
||||
/**
|
||||
*
|
||||
* 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';
|
||||
import styles from './styles.scss';
|
||||
|
||||
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 && this.props.value.length > 0) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.errors !== nextProps.errors) {
|
||||
let errors = false;
|
||||
if (_.isEmpty(nextProps.errors)) {
|
||||
errors = nextProps.errors === true ? [] : false;
|
||||
} else {
|
||||
errors = nextProps.errors;
|
||||
}
|
||||
this.setState({ errors });
|
||||
}
|
||||
}
|
||||
|
||||
handleBlur = ({ target }) => {
|
||||
// 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, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
|
||||
// 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, (error) => error !== 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.customBootstrapClass ? this.props.customBootstrapClass : 'col-md-6';
|
||||
// set error class with override possibility
|
||||
const bootStrapClassDanger = !this.props.deactivateErrorHighlight && this.state.errors ? 'has-danger' : '';
|
||||
const placeholder = this.props.placeholder || `Change ${this.props.name} field`;
|
||||
return (
|
||||
<div className={`${styles.inputText} ${bootStrapClass} ${bootStrapClassDanger}`}>
|
||||
<label htmlFor={this.props.name}>{this.props.name}</label>
|
||||
<input
|
||||
name={this.props.name}
|
||||
id={this.props.name}
|
||||
onBlur={handleBlur}
|
||||
onFocus={this.props.handleFocus}
|
||||
onChange={this.props.handleChange}
|
||||
value={inputValue}
|
||||
type="text"
|
||||
className={`form-control ${this.state.errors? 'form-control-danger' : ''}`}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
<small>{this.props.inputDescription}</small>
|
||||
{_.map(this.state.errors, (error, key) => (
|
||||
<div key={key} className="form-control-feedback">{error}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
InputText.propTypes = {
|
||||
customBootstrapClass: React.PropTypes.string,
|
||||
deactivateErrorHighlight: React.PropTypes.bool,
|
||||
errors: React.PropTypes.oneOfType([
|
||||
React.PropTypes.bool,
|
||||
React.PropTypes.array,
|
||||
]),
|
||||
handleBlur: React.PropTypes.func,
|
||||
handleChange: React.PropTypes.func.isRequired,
|
||||
handleFocus: React.PropTypes.func,
|
||||
inputDescription: React.PropTypes.string,
|
||||
name: React.PropTypes.string.isRequired,
|
||||
placeholder: React.PropTypes.string,
|
||||
validations: React.PropTypes.object.isRequired,
|
||||
value: React.PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
export default InputText;
|
@ -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 !',
|
||||
},
|
||||
});
|
@ -0,0 +1,11 @@
|
||||
.inputText { /* stylelint-disable */
|
||||
margin-top: 1.8rem;
|
||||
> label {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
> small {
|
||||
margin-top: .5rem;
|
||||
display: block;
|
||||
color: #ABAFBB;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
// import InputText from '../index';
|
||||
|
||||
import expect from 'expect';
|
||||
// import { shallow } from 'enzyme';
|
||||
// import React from 'react';
|
||||
|
||||
describe('<InputText />', () => {
|
||||
it('Expect to have unit tests specified', () => {
|
||||
expect(true).toEqual(false);
|
||||
});
|
||||
});
|
@ -0,0 +1,69 @@
|
||||
/**
|
||||
*
|
||||
* 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() {
|
||||
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 (
|
||||
<div className={customBootstrapClass}>
|
||||
<div className={`${styles.inputToggle} btn-group`} data-toggle="buttons">
|
||||
<button className={btnClassOff} id="off" onClick={this.toggle}>OFF</button>
|
||||
<button className={btnClassOn} id="on" onClick={this.toggle}>ON</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
InputToggle.propTypes = {
|
||||
customBootstrapClass: React.PropTypes.string,
|
||||
handleChange: React.PropTypes.func.isRequired,
|
||||
isChecked: React.PropTypes.bool.isRequired,
|
||||
name: React.PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
export default InputToggle;
|
@ -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 !',
|
||||
},
|
||||
});
|
@ -0,0 +1,36 @@
|
||||
.inputToggle { /* stylelint-disable */
|
||||
> button {
|
||||
// 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;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
// import InputRadio from '../index';
|
||||
|
||||
import expect from 'expect';
|
||||
// import { shallow } from 'enzyme';
|
||||
// import React from 'react';
|
||||
|
||||
describe('<InputRadio />', () => {
|
||||
it('Expect to have unit tests specified', () => {
|
||||
expect(true).toEqual(false);
|
||||
});
|
||||
});
|
@ -9,12 +9,28 @@ import React from 'react';
|
||||
import PluginLeftMenuHeader from 'components/PluginLeftMenuHeader';
|
||||
import styles from './styles.scss';
|
||||
|
||||
function PluginLeftMenu() {
|
||||
return (
|
||||
<div className={`${styles.pluginLeftMenu} col-md-3`}>
|
||||
<PluginLeftMenuHeader />
|
||||
</div>
|
||||
);
|
||||
class PluginLeftMenu extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={`${styles.pluginLeftMenu} col-md-3`}>
|
||||
<PluginLeftMenuHeader />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// function PluginLeftMenu() {
|
||||
// return (
|
||||
// <div className={`${styles.pluginLeftMenu} col-md-3`}>
|
||||
// <PluginLeftMenuHeader />
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
||||
export default PluginLeftMenu;
|
||||
|
@ -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 (
|
||||
<div className={styles.pluginLeftMenuSection}>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PluginLeftMenuSection;
|
@ -0,0 +1,3 @@
|
||||
.pluginLeftMenuSection { /* stylelint-disable */
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
// import PluginLeftMenuSection from '../index';
|
||||
|
||||
import expect from 'expect';
|
||||
// import { shallow } from 'enzyme';
|
||||
// import React from 'react';
|
||||
|
||||
describe('<PluginLeftMenuSection />', () => {
|
||||
it('Expect to have unit tests specified', () => {
|
||||
expect(true).toEqual(false);
|
||||
});
|
||||
});
|
@ -3,3 +3,22 @@
|
||||
* App actions
|
||||
*
|
||||
*/
|
||||
|
||||
import {
|
||||
MENU_FETCH,
|
||||
MENU_FETCH_SUCCEEDED,
|
||||
} from './constants';
|
||||
|
||||
|
||||
export function menuFetch() {
|
||||
return {
|
||||
type: MENU_FETCH,
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchMenuSucceeded(menu) {
|
||||
return {
|
||||
type: MENU_FETCH_SUCCEEDED,
|
||||
menu,
|
||||
};
|
||||
}
|
||||
|
@ -3,3 +3,6 @@
|
||||
* App constants
|
||||
*
|
||||
*/
|
||||
|
||||
export const MENU_FETCH = 'SettingsManager/App/MENU_FETCH';
|
||||
export const MENU_FETCH_SUCCEEDED = 'SettingsManager/App/MENU_FETCH_SUCCEEDED';
|
||||
|
@ -8,9 +8,32 @@
|
||||
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 {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: false,
|
||||
value1: null,
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.menuFetch();
|
||||
}
|
||||
|
||||
handleChange = ({ target }) => {
|
||||
this.setState({ value: target.value});
|
||||
}
|
||||
|
||||
render() {
|
||||
// Assign plugin component to children
|
||||
const content = React.Children.map(this.props.children, child =>
|
||||
@ -18,9 +41,14 @@ class App extends React.Component {
|
||||
exposedComponents: this.props.exposedComponents,
|
||||
})
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={pluginId}>
|
||||
<div className={`${pluginId} ${styles.app}`}>
|
||||
<div className={styles.baseline}></div>
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<PluginLeftMenu sections={this.props.app.sections} />
|
||||
</div>
|
||||
</div>
|
||||
{React.Children.toArray(content)}
|
||||
</div>
|
||||
);
|
||||
@ -32,17 +60,22 @@ App.contextTypes = {
|
||||
};
|
||||
|
||||
App.propTypes = {
|
||||
children: React.PropTypes.node.isRequired,
|
||||
children: React.PropTypes.node,
|
||||
exposedComponents: React.PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
@ -8,24 +8,40 @@ 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 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: false,
|
||||
value1: null,
|
||||
}
|
||||
}
|
||||
|
||||
handleChange = ({ target }) => {
|
||||
console.log('ok');
|
||||
console.log(target);
|
||||
this.setState({ value: !this.state.value});
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
|
||||
const test = {
|
||||
"name": "bame",
|
||||
"slug": "name",
|
||||
"target": "general.name",
|
||||
"type": "text",
|
||||
"value": "ExperienceApp",
|
||||
"validations" : {
|
||||
"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,}))$/
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.home}>
|
||||
<div className={styles.baseline}></div>
|
||||
@ -39,7 +55,20 @@ export class Home extends React.Component { // eslint-disable-line react/prefer-
|
||||
<div className="row">
|
||||
<PluginLeftMenu />
|
||||
<div className="col-md-9">
|
||||
f
|
||||
<div className="form-group">
|
||||
|
||||
|
||||
|
||||
<InputToggle
|
||||
handleChange={this.handleChange}
|
||||
isChecked={this.state.value}
|
||||
name={test.name}
|
||||
validations={test.validations}
|
||||
customBootstrapClass={'col-lg-2 offset-lg-4'}
|
||||
errors={[]}
|
||||
/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"/": {
|
||||
"name": "home",
|
||||
"container": "Home"
|
||||
"name": "app",
|
||||
"container": "App"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user