Skip to content

Commit

Permalink
templates validation WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
konzz committed May 31, 2016
1 parent 1790806 commit b9e8235
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 36 deletions.
1 change: 1 addition & 0 deletions app/react/Templates/actions/templateActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export function selectProperty(index) {
export function removeProperty(index) {
return function (dispatch, getState) {
let properties = getState().template.model.properties.slice(0);
dispatch(formActions.move('template.model.properties', index, properties.length - 1));
properties.splice(index, 1);
dispatch(formActions.change('template.model.properties', properties));
};
Expand Down
49 changes: 37 additions & 12 deletions app/react/Templates/components/FilterSuggestions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import {connect} from 'react-redux';

export class FilterSuggestions extends Component {

findSameLabelProperties(label, templates, currentTemplateId) {
findSameLabelProperties(label, templates) {
return templates
.filter((template) => template._id !== currentTemplateId)
.filter((template) => template._id !== this.props.model._id)
.map((template) => {
let property = template.properties.find((prop) => {
return prop.label.toLowerCase() === label.toLowerCase() & prop.filter;
Expand Down Expand Up @@ -82,23 +82,48 @@ export class FilterSuggestions extends Component {
}).name;
}

filterSuggestions() {
let label = this.props.label;
let type = this.props.type;
let content = this.props.content;

return this.findSameLabelProperties(label, this.props.uiState.toJS().templates, this.props.parentTemplateId)
filterSuggestions(label, type, content, hasThesauri) {
return this.findSameLabelProperties(label, this.props.uiState.toJS().templates)
.map((propertyMatch, index) => {
let typeConflict = propertyMatch.property.type !== type;
let contentConflict = propertyMatch.property.content !== content;
let hasThesauri = typeof content !== 'undefined';
return this.renderMatch(propertyMatch, typeConflict, contentConflict, hasThesauri, index);
});
}

render() {
let label = this.props.label;
let type = this.props.type;
let content = this.props.content;
let hasThesauri = typeof content !== 'undefined';
let activeClass = this.props.filter ? 'property-atributes is-active' : 'property-atributes';
let title = 'This is the current property and will be used togheter with equal properties.';
let icon = this.getTypeIcon(type);


return <div className="filter-suggestions col-sm-12">
{this.filterSuggestions()}
<div className={activeClass} title={title}>
<span>
<i className="fa fa-file-o"></i> {this.props.model.name}
</span>
<i className="fa fa-angle-right"></i>
<span>
<i className={icon}></i>{type}
</span>
{(() => {
if (hasThesauri) {
let thesauri = this.getThesauriName(content);
return <span>
<i className="fa fa-angle-right"></i>
<span>
<i className="fa fa-book"></i>Thesauri: {thesauri}
</span>
</span>;
}
})()}
<i className="fa fa-info-circle"></i>
</div>
{this.filterSuggestions(label, type, content, hasThesauri)}
</div>;
}
}
Expand All @@ -107,15 +132,15 @@ FilterSuggestions.propTypes = {
label: PropTypes.string,
type: PropTypes.string,
filter: PropTypes.any,
parentTemplateId: PropTypes.string,
model: PropTypes.object,
uiState: PropTypes.object,
content: PropTypes.string
};

export function mapStateToProps(state) {
return {
uiState: state.template.uiState,
parentTemplateId: state.template.model._id
model: state.template.model
};
}

Expand Down
20 changes: 15 additions & 5 deletions app/react/Templates/components/FormConfigInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export class FormConfigInput extends Component {
required: (val) => val.trim() !== '',
duplicated: (val) => {
return this.props.model.properties.reduce((validity, prop) => {
let differemtLabel = prop.localID !== this.props.localID && prop.label !== val;
return validity && differemtLabel;
let differentLabel = prop.localID === this.props.formKey || prop.label !== val;
return validity && differentLabel;
}, true);
}
};
Expand All @@ -22,10 +22,11 @@ export class FormConfigInput extends Component {
const ptoperty = model.properties[index];
let labelClass = 'input-group';
let labelKey = `properties.${index}.label`;
let duplicatedLabel = formState.fields[labelKey] && formState.fields[labelKey].errors.duplicated;
if (
formState.fields[labelKey] &&
!formState.fields[labelKey].valid &&
(formState.submitFailed || formState.fields[labelKey].dirty || formState.fields[labelKey].errors.duplicated)) {
(formState.submitFailed || formState.fields[labelKey].dirty || duplicatedLabel)) {
labelClass += ' has-error';
}

Expand All @@ -34,7 +35,16 @@ export class FormConfigInput extends Component {
<div className="row">
<div className="col-sm-4">
<div className={labelClass}>
<span className="input-group-addon">Label</span>
<span className="input-group-addon">
{(() => {
if (duplicatedLabel) {
return <span>
Duplicated&nbsp;
</span>;
}
})()}
Label
</span>
<FormField model={`template.model.properties[${index}].label`} validators={this.validation()}>
<input className="form-control" />
</FormField>
Expand Down Expand Up @@ -75,7 +85,7 @@ FormConfigInput.propTypes = {
model: PropTypes.object,
index: PropTypes.number,
formState: PropTypes.object,
localID: PropTypes.string
formKey: PropTypes.string
};

export function mapStateToProps({template}) {
Expand Down
20 changes: 15 additions & 5 deletions app/react/Templates/components/FormConfigSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export class FormConfigSelect extends Component {
required: (val) => val.trim() !== '',
duplicated: (val) => {
return this.props.model.properties.reduce((validity, prop) => {
let differemtLabel = prop.localID !== this.props.localID && prop.label !== val;
return validity && differemtLabel;
let differentLabel = prop.localID === this.props.formKey || prop.label !== val;
return validity && differentLabel;
}, true);
}
};
Expand All @@ -28,9 +28,10 @@ export class FormConfigSelect extends Component {

let labelClass = 'input-group';
let labelKey = `properties.${index}.label`;
let duplicatedLabel = formState.fields[labelKey] && formState.fields[labelKey].errors.duplicated;
if (formState.fields[labelKey] &&
!formState.fields[labelKey].valid &&
(formState.submitFailed || formState.fields[labelKey].dirty || formState.fields[labelKey].errors.duplicated)) {
(formState.submitFailed || formState.fields[labelKey].dirty || duplicatedLabel)) {
labelClass += ' has-error';
}

Expand All @@ -45,7 +46,16 @@ export class FormConfigSelect extends Component {
<div className="row">
<div className="col-sm-4">
<div className={labelClass}>
<span className="input-group-addon">Label</span>
<span className="input-group-addon">
{(() => {
if (duplicatedLabel) {
return <span>
Duplicated&nbsp;
</span>;
}
})()}
Label
</span>
<FormField model={`template.model.properties[${index}].label`} validators={this.nameValidation()}>
<input className="form-control"/>
</FormField>
Expand Down Expand Up @@ -95,7 +105,7 @@ FormConfigSelect.propTypes = {
model: PropTypes.object,
index: PropTypes.number,
formState: PropTypes.object,
localID: PropTypes.string
formKey: PropTypes.string
};

export function mapStateToProps(state) {
Expand Down
15 changes: 12 additions & 3 deletions app/react/Templates/components/MetadataProperty.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,20 @@ export class MetadataProperty extends Component {
}

render() {
const {label, connectDragSource, isDragging, connectDropTarget, uiState, index, localID, inserting} = this.props;
const {label, connectDragSource, isDragging, connectDropTarget, uiState, index, localID, inserting, formState} = this.props;
const editingProperty = uiState.toJS().editingProperty;

let propertyClass = 'list-group-item';
if (isDragging || inserting) {
propertyClass += ' dragging';
}

let labelError = formState.fields[`properties.${index}.label`] && !formState.fields[`properties.${index}.label`].valid;
let contentError = formState.fields[`properties.${index}.content`] && !formState.fields[`properties.${index}.content`].valid;
if (labelError || contentError) {
propertyClass += ' error';
}

let iconClass = {
select: 'fa fa-sort',
list: 'fa fa-list',
Expand Down Expand Up @@ -90,7 +96,9 @@ const target = {
item.index = 0;
return props.addProperty({label: item.label, type: item.type, inserting: true}, item.index);
}

if (dragIndex === hoverIndex) {
return;
}
props.reorderProperty(dragIndex, hoverIndex);
monitor.getItem().index = hoverIndex;
}
Expand Down Expand Up @@ -121,7 +129,8 @@ function mapDispatchToProps(dispatch) {

const mapStateToProps = (state) => {
return {
uiState: state.template.uiState
uiState: state.template.uiState,
formState: state.template.formState
};
};

Expand Down
2 changes: 1 addition & 1 deletion app/react/Templates/components/PropertyOption.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const optionSource = {
const item = monitor.getItem();
const dropResult = monitor.getDropResult();
if (!dropResult) {
return props.removeProperty(item.index);
props.removeProperty(item.index);
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('FormConfigInput', () => {
type: 'text',
index: 0,
model: {properties: [{lable: ''}]},
formState: {fields: {'properties.0.label': {valid: true, dirty: false}}}
formState: {fields: {'properties.0.label': {valid: true, dirty: false, errors: {}}}}
};
});

Expand Down
4 changes: 2 additions & 2 deletions app/react/Templates/components/specs/FormConfigSelect.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ describe('FormConfigSelect', () => {
index: 0,
model: {properties: []},
formState: {fields: {
'properties.0.label': {valid: true, dirty: false},
'properties.0.content': {valid: true, dirty: false}
'properties.0.label': {valid: true, dirty: false, errors: {}},
'properties.0.content': {valid: true, dirty: false, errors: {}}
}}
};
});
Expand Down
14 changes: 7 additions & 7 deletions app/react/Templates/components/specs/MetadataProperty.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,17 @@ function sourceTargetTestContext(Target, Source, actions) {
localID: 'target',
connectDragSource: identity,
isDragging: false,
uiState: Immutable.fromJS({})
uiState: Immutable.fromJS({}),
formState: {fields: []}
};
let sourceProps = {
label: 'source',
type: 'type',
index: 2, localID: 'source',
connectDragSource: identity,
isDragging: false,
uiState: Immutable.fromJS({})
uiState: Immutable.fromJS({}),
formState: {fields: []}
};
return <div>
<Target {...targetProps} {...actions}/>
Expand Down Expand Up @@ -69,9 +71,7 @@ describe('MetadataProperty', () => {
label: 'test',
index: 1,
localID: 'id',
form: {},
errors: {},
fields: {properties: []},
formState: {fields: []},
removeProperty,
editProperty,
uiState: Immutable.fromJS({editingProperty: ''})
Expand Down Expand Up @@ -131,7 +131,7 @@ describe('MetadataProperty', () => {
template: {
model: templateData,
uiState: Immutable.fromJS({templates: []}),
formState: {fields: {}}
formState: {fields: []}
},
modals: Immutable.fromJS({})
};
Expand All @@ -143,7 +143,7 @@ describe('MetadataProperty', () => {
describe('dragSource', () => {
beforeEach(() => {
let TestComponent = wrapInTestContext(dragSource);
component = renderComponent(TestComponent, {label: 'test', type: 'type', index: 0, localID: 'id', uiState: Immutable.fromJS({})});
component = renderComponent(TestComponent, {label: 'test', type: 'type', index: 0, localID: 'id', uiState: Immutable.fromJS({}), formState: {fields: []}});
backend = component.getManager().getBackend();
monitor = component.getManager().getMonitor();
});
Expand Down

0 comments on commit b9e8235

Please sign in to comment.