Dynamic form to edit the label description of an either an input or a displayed relation

This commit is contained in:
cyril lopez 2018-07-20 15:23:09 +02:00
parent be3a28ea04
commit f4996b3663
20 changed files with 185 additions and 15 deletions

View File

@ -1,8 +1,26 @@
import { ON_CLICK_EDIT_LIST_ITEM } from './constants';
import {
ON_CLICK_EDIT_FIELD,
ON_CLICK_EDIT_LIST_ITEM,
ON_CLICK_EDIT_RELATION,
} from './constants';
export function onClickEditField(fieldToEdit) {
return {
type: ON_CLICK_EDIT_FIELD,
fieldToEdit,
};
}
export function onClickEditListItem(listItemToEdit) {
return {
type: ON_CLICK_EDIT_LIST_ITEM,
listItemToEdit,
};
}
export function onClickEditRelation(relationToEdit) {
return {
type: ON_CLICK_EDIT_RELATION,
relationToEdit,
};
}

View File

@ -1 +1,3 @@
export const ON_CLICK_EDIT_LIST_ITEM = 'contentManager/SettingPage/ON_CLICK_EDIT_LIST_ITEM';
export const ON_CLICK_EDIT_FIELD = 'contentManager/SettingPage/ON_CLICK_EDIT_FIELD';
export const ON_CLICK_EDIT_LIST_ITEM = 'contentManager/SettingPage/ON_CLICK_EDIT_LIST_ITEM';
export const ON_CLICK_EDIT_RELATION = 'contentManager/SettingPage/ON_CLICK_EDIT_RELATION';

View File

@ -105,6 +105,37 @@
"type": "string",
"validations": {}
}
],
"fieldForm": [
{
"label": { "id": "content-manager.form.Input.label" },
"customBootstrapClass": "col-md-8",
"didCheckErrors": false,
"errors": [],
"name": "label",
"placeholder": "SLUG (URL)",
"type": "string",
"validations": {}
},
{
"label": { "id": "content-manager.form.Input.disabled" },
"customBootstrapClass": "col-md-4",
"didCheckErrors": false,
"errors": [],
"name": "editable",
"type": "toggle",
"validations": {}
},
{
"label": { "id": "content-manager.form.Input.description" },
"customBootstrapClass": "col-md-12",
"didCheckErrors": false,
"errors": [],
"name": "description",
"placeholder": "content-manager.form.Input.description.placeholder",
"type": "string",
"validations": {}
}
]
}
}

View File

@ -7,7 +7,7 @@ import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators, compose } from 'redux';
import { createStructuredSelector } from 'reselect';
import { findIndex, get, upperFirst } from 'lodash';
import { findIndex, get, isEmpty, upperFirst } from 'lodash';
import cn from 'classnames';
import HTML5Backend from 'react-dnd-html5-backend';
import { DragDropContext } from 'react-dnd';
@ -41,7 +41,7 @@ import VariableDraggableAttr from 'components/VariableDraggableAttr';
import injectReducer from 'utils/injectReducer';
import injectSaga from 'utils/injectSaga';
import { onClickEditListItem } from './actions';
import { onClickEditField, onClickEditListItem, onClickEditRelation } from './actions';
import forms from './forms.json';
import reducer from './reducer';
@ -61,6 +61,15 @@ class SettingPage extends React.PureComponent {
componentDidMount() {
this.handleClickEditAttr(0);
const fields = this.getEditPageDisplayedFields();
const relations = this.getEditPageDisplayedRelations();
if (fields.length === 0) {
this.handleClickEditField(0);
} else if (relations.length > 0) {
this.handleClickEditRelation(0);
}
}
componentDidUpdate(prevProps) {
@ -208,11 +217,25 @@ class SettingPage extends React.PureComponent {
}
}
handleClickEditAttr = (index) => {
handleClickEditAttr = index => {
const attrToEdit = get(this.props.schema, ['models'].concat(this.getPath().split('.')).concat(['listDisplay', index]), {});
this.props.onClickEditListItem(attrToEdit);
}
handleClickEditField = index => {
const fieldToEditName = get(this.props.schema, ['models', ...this.getPath().split('.'), 'editDisplay', 'fields', index], '');
const fieldToEdit = get(this.props.schema, ['models', ...this.getPath().split('.'), 'editDisplay', 'availableFields', fieldToEditName], {});
return this.props.onClickEditField(fieldToEdit);
}
handleClickEditRelation = index => {
const relationToEditName = get(this.getEditPageDisplayedRelations(), index, '');
const relationToEdit = get(this.props.schema, ['models', ...this.getPath().split('.'), 'relations', relationToEditName]);
return this.props.onClickEditRelation(relationToEdit);
}
handleConfirmReset = () => {
this.props.onReset();
this.toggleWarningCancel();
@ -348,13 +371,49 @@ class SettingPage extends React.PureComponent {
renderDropDownP = msg => <p>{msg}</p>;
renderForm = () => {
const { settingPage: { fieldToEdit, relationToEdit } } = this.props;
if (isEmpty(fieldToEdit)) {
return forms.editView.relationForm.map(this.renderFormEditSettingsRelation);
}
if (isEmpty(relationToEdit)) {
return forms.editView.fieldForm.map(this.renderFormEditSettingsField);
}
return null;
}
renderFormEditSettingsField = (input, i) => {
const { onChangeSettings, schema, settingPage: { fieldToEdit: { name } } } = this.props;
const path = [...this.getPath().split('.'), 'editDisplay', 'availableFields', name, input.name];
const value = get(schema, ['models', ...path], '');
return (
<Input
key={i}
onChange={onChangeSettings}
value={value}
{...input}
name={path.join('.')}
/>
);
}
renderFormEditSettingsRelation = (input, i) => {
const { onChangeSettings, schema, settingPage: { relationToEdit: { alias } } } = this.props;
const path = [...this.getPath().split('.'), 'relations', alias, input.name];
const value = get(schema, ['models', ...path], '');
return (
<Input
key={i}
onChange={() => {}}
value=""
onChange={onChangeSettings}
value={value}
{...input}
name={path.join('.')}
/>
);
}
@ -404,7 +463,6 @@ class SettingPage extends React.PureComponent {
const {
onSubmit,
} = this.props;
return (
<form onSubmit={this.handleSubmit}>
<BackHeader onClick={this.handleGoBack} />
@ -547,7 +605,7 @@ class SettingPage extends React.PureComponent {
<div className={styles.editWrapper}>
<div className="row">
{forms.editView.relationForm.map(this.renderFormEditSettingsRelation)}
{this.renderForm()}
</div>
</div>
@ -572,7 +630,9 @@ SettingPage.propTypes = {
moveVariableAttrEditView: PropTypes.func.isRequired,
onChangeSettings: PropTypes.func.isRequired,
onClickAddAttr: PropTypes.func.isRequired,
onClickEditField: PropTypes.func.isRequired,
onClickEditListItem: PropTypes.func.isRequired,
onClickEditRelation: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
onRemoveEditViewAttr: PropTypes.func.isRequired,
onRemoveEditViewFieldAttr: PropTypes.func.isRequired,
@ -591,7 +651,9 @@ const mapDispatchToProps = (dispatch) => (
moveVariableAttrEditView,
onChangeSettings,
onClickAddAttr,
onClickEditField,
onClickEditListItem,
onClickEditRelation,
onRemove,
onRemoveEditViewAttr,
onRemoveEditViewFieldAttr,

View File

@ -4,18 +4,31 @@
*/
import { fromJS } from 'immutable';
import { ON_CLICK_EDIT_LIST_ITEM } from './constants';
import {
ON_CLICK_EDIT_FIELD,
ON_CLICK_EDIT_LIST_ITEM,
ON_CLICK_EDIT_RELATION,
} from './constants';
const initialState = fromJS({
fieldToEdit: fromJS({}),
indexListItemToEdit: 0, // NOTE: need to check if this used in the code...
listItemToEdit: fromJS({}),
indexListItemToEdit: 0,
relationToEdit: fromJS({}),
});
function settingPageReducer(state = initialState, action) {
switch (action.type) {
case ON_CLICK_EDIT_LIST_ITEM:
case ON_CLICK_EDIT_FIELD:
return state
.update('listItemToEdit', () => fromJS(action.listItemToEdit));
.update('fieldToEdit', () => fromJS(action.fieldToEdit))
.update('relationToEdit', () => fromJS({})); // Both these object will be used to set the form so in order to know which form to display we set an empty object
case ON_CLICK_EDIT_LIST_ITEM:
return state.update('listItemToEdit', () => fromJS(action.listItemToEdit));
case ON_CLICK_EDIT_RELATION:
return state
.update('fieldToEdit', () => fromJS({}))
.update('relationToEdit', () => fromJS(action.relationToEdit));
default:
return state;
}

View File

@ -46,6 +46,7 @@
"error.attribute.sameKeyAndName": "لا تتطابق",
"error.validation.minSupMax": "لا يمكن أن تكون متفوقة",
"form.Input.disabled": "Editable field",
"form.Input.description": "Description",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",

View File

@ -46,6 +46,7 @@
"error.attribute.sameKeyAndName": "Darf nicht gleich sein",
"error.validation.minSupMax": "Darf nicht höher sein",
"form.Input.disabled": "Editable field",
"form.Input.description": "Description",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",

View File

@ -93,6 +93,7 @@
"form.Input.description": "Description",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",
"form.Input.disabled": "Editable field",
"form.Input.label.inputDescription": "This value overrides the label displayed in the table's head",
"form.Input.label": "Label",
"form.Input.search": "Enable search",

View File

@ -92,6 +92,7 @@
"form.Input.description": "Description",
"form.Input.description.placeholder": "N'oubliez pas de mettre l'URL complète!",
"form.Input.disabled": "Champ editable",
"form.Input.label": "Label",
"form.Input.label.inputDescription": "Cette valeur modifie celle du champs de la table",
"form.Input.search": "Autoriser la search",

View File

@ -75,7 +75,8 @@
"error.validation.minSupMax": "Non può essere superiore",
"form.Input.description": "Description",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",
"form.Input.disabled": "Editable field",
"notification.error.relationship.fetch": "Si è verificato un errore durante il rapporto di recupero.",

View File

@ -78,6 +78,7 @@
"form.Input.description": "Description",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",
"form.Input.disabled": "Editable field",
"notification.error.relationship.fetch": "데이터 관계를 가져오는 도중 에러가 발생했습니다.",

View File

@ -77,6 +77,7 @@
"form.Input.description": "Description",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",
"form.Input.disabled": "Editable field",
"notification.error.relationship.fetch": "Wystąpił błąd podczas pobierania relacji.",

View File

@ -78,6 +78,7 @@
"form.Input.description": "Description",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",
"form.Input.disabled": "Editable field",
"notification.error.relationship.fetch": "Ocorreu um erro durante a busca da relação.",

View File

@ -78,6 +78,7 @@
"form.Input.description": "Description",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",
"form.Input.disabled": "Editable field",
"notification.error.relationship.fetch": "Ocorreu um erro durante a busca da relação.",

View File

@ -48,6 +48,7 @@
"form.Input.description": "Description",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",
"form.Input.disabled": "Editable field",
"notification.error.relationship.fetch": "Возникла ошибка при получении связей.",

View File

@ -76,6 +76,7 @@
"form.Input.description": "Description",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",
"form.Input.disabled": "Editable field",
"notification.error.relationship.fetch": "İlişki getirme sırasında bir hata oluştu.",

View File

@ -48,6 +48,7 @@
"form.Input.description": "Description",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",
"form.Input.disabled": "Editable field",
"notification.error.relationship.fetch": "获取关联数据时发生错误",

View File

@ -49,6 +49,7 @@
"form.Input.description": "Description",
"form.Input.description.placeholder": "Please don't forget to fill the full URL!",
"form.Input.disabled": "Editable field",
"notification.error.relationship.fetch": "讀取關聯資料時發生錯誤",

View File

@ -65,6 +65,7 @@ module.exports = async cb => {
label: _.upperFirst(attribute),
description: '',
type: value.type || 'string',
disabled: false,
}));
schemaModel.fields = fields;
@ -109,7 +110,8 @@ module.exports = async cb => {
if (model.associations) {
// Model relations
schemaModel.relations = model.associations.reduce((acc, current) => {
const displayedAttribute = current.plugin ?
const label = _.upperFirst(current.alias);
const displayedAttribute = current.plugin ? // Value to modified to custom what's displayed in the react-select
_.get(pluginsModel, [current.plugin, 'models', current.model || current.collection, 'info', 'mainField']) ||
_.findKey(_.get(pluginsModel, [current.plugin, 'models', current.model || current.collection, 'attributes']), { type : 'string'}) ||
'id' :
@ -120,6 +122,7 @@ module.exports = async cb => {
acc[current.alias] = {
...current,
description: '',
label,
displayedAttribute,
};
@ -144,6 +147,7 @@ module.exports = async cb => {
name: current,
placeholder: '',
type: 'file',
disabled: false,
};
}

View File

@ -27,6 +27,33 @@
},
"date": {
"appearance": ""
},
"bool1": {
"appearance": ""
},
"bool2": {
"appearance": ""
},
"number": {
"appearance": ""
},
"enum": {
"appearance": ""
},
"json": {
"appearance": ""
},
"bool3": {
"appearance": ""
},
"bool4": {
"appearance": ""
},
"bool5": {
"appearance": ""
},
"bool6": {
"appearance": ""
}
}
},