trc-client-core
Version:
The core of the TRC Client
309 lines (263 loc) • 11.6 kB
JSX
import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';
import { connect } from 'react-redux';
import { Map, fromJS, OrderedMap } from 'immutable';
import { reduxForm, initialize } from 'redux-form';
// components
import ErrorMessage from 'trc-client-core/src/components/ErrorMessage';
import ErrorList from 'trc-client-core/src/components/ErrorList';
import Grid from 'trc-client-core/src/components/Grid';
import Col from 'trc-client-core/src/components/Col';
import Widget from 'trc-client-core/src/components/Widget';
import CourseSelect from 'trc-client-core/src/components/CourseSelect';
import SortableFieldArray from 'trc-client-core/src/components/SortableFieldArray';
import FormError from 'trc-client-core/src/forms/FormError';
import Input from 'bd-stampy/components/InputElement';
import Label from 'bd-stampy/components/Label';
import Textarea from 'bd-stampy/components/Textarea';
import Fieldset from 'bd-stampy/components/Fieldset';
import InputRow from 'bd-stampy/components/InputRow';
import Select from 'toyota-styles/lib/components/Select';
import Button from 'bd-stampy/components/Button';
import PATHWAY_TYPE_OPTIONS from 'trc-client-core/src/constants/PathwayTypes';
import DEPARTMENT_OPTIONS from 'trc-client-core/src/constants/Departments';
const LEARNING_PLAN_FORM_NAME = 'learningPlanForm';
//
// fields in form
//
export const LEARNING_PLAN_FORM_FIELDS = [
'careerPlanId',
'brand',
'pathwayType',
'displayName',
'visible',
'displayText.headerText',
'displayText.footerText',
'displayText.additonalResource',
'segments[].name',
'segments[].courses[].courseCode',
'accessRule.jobPositionId',
'accessRule.departments',
'certifications[].name',
'certifications[].courses[].itemCode',
'certifications[].courses[].itemName'
];
class AdminLearningPlanForm extends Component {
submitForm(values, dispatch) {
this.props.onSubmitForm(values, dispatch);
this.setCurrentFormDataAsDefault();
}
resetForm(ee) {
ee.preventDefault();
if(this.props.onResetClick) {
this.props.onResetClick(() => {
this.props.resetForm();
});
} else {
this.props.resetForm();
}
return false;
}
close(ee) {
ee.preventDefault();
this.props.onCloseClick(ee, this.props.dirty);
}
setCurrentFormDataAsDefault() {
this.props.dispatch(initialize(LEARNING_PLAN_FORM_NAME, this.props.values, LEARNING_PLAN_FORM_FIELDS));
}
//
// render
//
render() {
const {
fields: {
displayName,
careerPlanId,
brand,
pathwayType,
visible,
displayText,
segments,
certifications,
accessRule: {
jobPositionId,
departments
}
},
handleSubmit,
courses,
jobPositions,
onDeleteClick,
savesToExisting,
copiesExisting,
isSaving,
isDeleting,
dirty,
errors
} = this.props;
return (
<form onSubmit={handleSubmit(this.submitForm.bind(this))}>
<p>
<Button onClick={this.close.bind(this)} modifier="grey">Cancel</Button>
<Button type="submit" modifier="edit" disabled={isSaving || isDeleting}>{copiesExisting ? "Save new copy" : "Save"}</Button>
<Button onClick={this.resetForm.bind(this)} modifier="edit" disabled={!dirty || isSaving || isDeleting}>Reset</Button>
<Button onClick={onDeleteClick} modifier="edit" disabled={!savesToExisting || isSaving || isDeleting}>Delete</Button>
</p>
<ErrorList {...this.props} />
<Fieldset legend="General">
<Input type="hidden" {...brand} />
<InputRow label="Display name">
<Input type="text" {...displayName} />
<FormError {...displayName} />
</InputRow>
{savesToExisting &&
<InputRow label="Learning plan ID">
<Input type="text" disabled {...careerPlanId} />
<FormError {...careerPlanId} />
</InputRow>}
<InputRow label="Pathway type">
<Select onChangeString options={PATHWAY_TYPE_OPTIONS} {...pathwayType} />
<FormError {...pathwayType} />
</InputRow>
<InputRow label="Assigned">
<Input type="checkbox" {...visible} />
<FormError {...visible} />
</InputRow>
</Fieldset>
<Fieldset legend="Content">
<InputRow label="Header text">
<Textarea {...displayText.headerText} rows="9" />
<FormError {...displayText.headerText} />
</InputRow>
<InputRow label="Footer text">
<Textarea {...displayText.footerText} rows="9" />
<FormError {...displayText.footerText} />
</InputRow>
<InputRow label="Additional resources">
<Textarea {...displayText.additonalResource} rows="9" />
<FormError {...displayText.additonalResource} />
</InputRow>
</Fieldset>
<Fieldset legend="Access">
<InputRow label="Job positions">
<Select onChangeString multi {...jobPositionId} options={jobPositions} />
<FormError {...jobPositionId} />
</InputRow>
<InputRow label="Departments">
<Select onChangeString multi {...departments} options={DEPARTMENT_OPTIONS} />
<FormError {...departments} />
</InputRow>
</Fieldset>
<Fieldset legend="Courses">
<SortableFieldArray items={segments} itemName="segment" modifier="large">
{segments.map((segment, index) =>
<div>
<InputRow label="Segment name">
<Input type="text" {...segment.name} />
<FormError {...segment.name} />
</InputRow>
<InputRow label="Courses">
<SortableFieldArray items={segment.courses} itemName="course">
{segment.courses.map((course, index) =>
<div>
<CourseSelect onChangeString {...course.courseCode} className="hug-bottom" courses={courses} />
<FormError {...course.courseCode} />
</div>
)}
</SortableFieldArray>
</InputRow>
</div>
)}
</SortableFieldArray>
</Fieldset>
<Fieldset legend="Certification map">
<SortableFieldArray items={certifications} itemName="certifications" modifier="large">
{certifications.map((segment, index) =>
<div>
<InputRow label="Segment name">
<Input type="text" {...segment.name}/>
<FormError {...segment.name} />
<FormError {...segment.coursesError} />
</InputRow>
<InputRow label="Items">
<SortableFieldArray items={segment.courses}>
{segment.courses.map((course, index) =>
<Grid>
<Col width={6}>
<Input type="text" className="hug-bottom" placeholder="ABC123" {...course.itemCode} />
<FormError {...course.itemCode} />
</Col>
<Col width={6}>
<Input type="text" className="hug-bottom" {...course.itemName} />
<FormError {...course.itemName} />
</Col>
</Grid>
)}
</SortableFieldArray>
</InputRow>
</div>
)}
</SortableFieldArray>
</Fieldset>
<p>
<Button onClick={this.close.bind(this)} modifier="grey">Cancel</Button>
<Button type="submit" modifier="edit" disabled={isSaving || isDeleting}>{copiesExisting ? "Save new copy" : "Save"}</Button>
<Button onClick={this.resetForm.bind(this)} modifier="edit" disabled={!dirty || isSaving || isDeleting}>Reset</Button>
<Button onClick={onDeleteClick} modifier="edit" disabled={!savesToExisting || isSaving || isDeleting}>Delete</Button>
</p>
<ErrorList {...this.props} />
</form>
);
}
}
AdminLearningPlanForm.propTypes = {
initialValues: PropTypes.object,
courses: PropTypes.array,
jobPositions: PropTypes.array,
onDeleteClick: PropTypes.func,
savesToExisting: PropTypes.bool,
copiesExisting: PropTypes.bool,
isSaving: PropTypes.bool,
isDeleting: PropTypes.bool
};
//
// validation
//
const AdminLearningPlanFormValidation = function(data) {
const errors = {
segments: [],
certifications: []
};
if(!data.displayName || data.displayName.trim()=="") {
errors.displayName = 'You must supply a display name';
}
data.segments.map((seg, ii) => {
if(!seg.name || seg.name.trim()=="") {
errors.segments[ii] = {
name: 'You must supply a segment name for course segment #'+(ii+1)
};
}
});
data.certifications.map((cert, ii) => {
var certErrors = {};
if(!cert.name || cert.name.trim()=="") {
certErrors.name = 'You must supply a segment name for certification segment #'+(ii+1);
}
errors.certifications[ii] = certErrors;
});
return errors;
}
//
// redux form
//
export default reduxForm({
form: LEARNING_PLAN_FORM_NAME,
fields: LEARNING_PLAN_FORM_FIELDS,
validate: AdminLearningPlanFormValidation
},
(state, props) => {
return {
initialValues: props.initialValues
};
}
)(AdminLearningPlanForm);