UNPKG

trc-client-core

Version:
363 lines (300 loc) 11.9 kB
import { Component, PropTypes } from 'react'; import { Link } from 'react-router'; import { connect } from 'react-redux'; // actions import { learningPlanRequestGet, learningPlanRequestCreate, learningPlanRequestUpdate, learningPlanRequestDelete } from 'trc-client-core/src/learningPlan/LearningPlanActions.js'; import { requestCourseList } from 'trc-client-core/src/course/CourseActions'; import { jobPositionRequest } from 'trc-client-core/src/participant/ParticipantActions'; import { LEARNING_PLAN_GET_FETCH, LEARNING_PLAN_GET_ERROR, LEARNING_PLAN_CREATE_FETCH, LEARNING_PLAN_CREATE_ERROR, LEARNING_PLAN_UPDATE_FETCH, LEARNING_PLAN_UPDATE_ERROR, LEARNING_PLAN_DELETE_FETCH, LEARNING_PLAN_DELETE_ERROR } from 'trc-client-core/src/constants/ActionTypes'; // components import Page from 'trc-client-core/src/components/Page'; import Loader from 'trc-client-core/src/components/Loader'; import ErrorMessage from 'trc-client-core/src/components/ErrorMessage'; import AutoRequest from 'trc-client-core/src/components/AutoRequest'; import Button from 'bd-stampy/components/Button'; import ModalManager from 'trc-client-core/src/Modal/ModalManager'; import ModalConfirm from 'trc-client-core/src/Modal/ModalConfirm'; import LoadingActions from 'trc-client-core/src/global/LoadingActions'; import AdminLearningPlanForm from 'trc-client-core/src/admin/AdminLearningPlanForm'; // // AdminLearningPlanEditView class // class AdminLearningPlanEditView extends Component { // // lifecycle methods // initialState() { return { created: false, copied: false, deleted: false, saveError: false }; } constructor(props) { super(props); this.state = this.initialState(); } componentWillMount() { this.props.dispatch(jobPositionRequest()); this.props.dispatch(requestCourseList()); } componentWillReceiveProps(newProps) { // reset state if a new learning plan's info is to be shown in the form if(this.loadsFromExisting(newProps)) { this.setState(this.initialState()); } } // // helpers // currentLearningPlan() { // gets the current learning plan object (an immutable map), or null if none correspond to current learningPlanId prop return this.props.learningPlans.get(this.props.params.learningPlanId); } loadsFromExisting(props = this.props) { // returns true if the form loads from an existing record, false if the form starts blank return !!props.params.learningPlanId; // true if a learningPlanId exists } savesToExisting(props = this.props) { // returns true if the form saves to an existing record, false if the form is to create a new record on save return !!props.route.savesToExisting; // true if savesToExisting is true on the route } copiesExisting(props = this.props) { return this.loadsFromExisting() && !this.savesToExisting(); } getInitialFormValues(currentLearningPlan) { if(!currentLearningPlan) { return { brand: "Toyota" }; } var plan = currentLearningPlan.toJS(); return plan; } // // event and click handlers // handleSubmit(values, dispatch) { this.saveLearningPlan(values); } handleResetClick(resetForm) { ModalManager.showModal(ModalConfirm, { title: 'Are you sure you want to reset?', message: 'Are you sure you want to reset? Any changes since your last save will be lost.', yes: 'Yes I\'m sure', onYes: resetForm, no: 'Cancel' }); } handleCloseClick(ee, dirty = false) { ee.preventDefault(); if(dirty) { ModalManager.showModal(ModalConfirm, { title: 'Unsaved changes', message: 'You may have unsaved changes, are you sure you want to leave this page?', yes: 'Leave page', onYes: this.closeLearningPlan.bind(this), no: 'Cancel' }); } else { this.closeLearningPlan(); } } handleDeleteClick(ee) { ee.preventDefault(); ModalManager.showModal(ModalConfirm, { title: 'Delete learning plan', message: 'Are you sure you want to delete this? This action cannot be undone', yes: 'Yes I\'m sure', onYes: this.deleteLearningPlan.bind(this), no: 'Cancel' }); } // // form actions // closeLearningPlan() { this.props.history.push('/admin/learning-plans'); } saveLearningPlan(learningPlanObject) { const { learningPlanId } = this.props.params; if(this.copiesExisting()) { this.props.dispatch(learningPlanRequestUpdate(learningPlanId,learningPlanObject)).then( (data) => { this.setState({ copied: data.payload.careerPlanId }); } ); } else if(this.savesToExisting()) { LoadingActions.startLoading(); this.props.dispatch(learningPlanRequestUpdate(learningPlanId,learningPlanObject)).then( (data) => { if(data.type == LEARNING_PLAN_UPDATE_ERROR) { LoadingActions.flashMessage('failure long', 'An error occurred. Your work is not yet saved.\n'+data.payload.message, 5000); } else { LoadingActions.flashMessage('success', 'Save complete'); } } ); } else { this.props.dispatch(learningPlanRequestCreate(learningPlanObject)).then( (data) => { this.setState({ created: data.payload.careerPlanId }); } ); } } deleteLearningPlan() { const { learningPlanId } = this.props.params; LoadingActions.startLoading(); this.props.dispatch(learningPlanRequestDelete(learningPlanId)).then( (data) => { if(data.type == LEARNING_PLAN_DELETE_ERROR) { LoadingActions.flashMessage('failure long', 'An error occurred. This learning plan is not yet deleted.\n'+data.payload.message, 5000); } else { LoadingActions.clearAll(); this.setState({ deleted: true }); } } ); } // // render // render() { return ( <Page title="Learning Plan Editor"> <div> {this.renderEditor()} </div> </Page> ); } renderEditor() { const { params: { learningPlanId }, fetching, saving, deleting, error, handleSubmit, courses, jobPositions } = this.props; const { created, copied, deleted } = this.state; var showErrorPage = false; if(fetching) { return <Loader />; } else if(error) { // if there's an error we'll usually want to show an error page, except if the error happens on save showErrorPage = true; } else if (created) { return ( <div> <h2 className="hug-top">Learning plan created</h2> <p><Button onClick={this.handleCloseClick.bind(this)}>Back to list</Button>&nbsp;<Link to={`/admin/learning-plans/${created}/edit`} activeClassName="is-active" className="Button Button-edit">Edit learning plan</Link></p> </div> ); } else if (copied) { return ( <div> <h2 className="hug-top">Learning plan copied</h2> <p><Button onClick={this.handleCloseClick.bind(this)}>Back to list</Button>&nbsp;<Link to={`/admin/learning-plans/${copied}/edit`} activeClassName="is-active" className="Button Button-edit">Edit learning plan</Link></p> </div> ); } else if(deleted) { return ( <div> <h2 className="hug-top">Learning plan deleted</h2> <p><Button onClick={this.handleCloseClick.bind(this)}>Back to list</Button></p> </div> ); } var title, id, plan; // if trying to display a learning plan, get learning plan details if(learningPlanId) { plan = this.currentLearningPlan(); if(!plan) { // learning plan at this URL doesn't exist return ( <div> <h2 className="hug-top">No learning plan found at this URL</h2> <p><Button onClick={this.handleCloseClick.bind(this)}>Back to list</Button></p> </div> ); } var planJS = plan.toJS(); title = planJS.displayName || "Unnamed learning plan"; id = planJS.careerPlanId; showErrorPage = false; } else { // no learning plan id means this must be a new one title = "New learning plan"; } if(this.copiesExisting()) { title = "New copy of " + title; } if(showErrorPage) { return <ErrorMessage code={400} message={error.message} />; } var initialValues = this.getInitialFormValues(plan); return ( <div> <h1 className="hug-top">{title}</h1> <AdminLearningPlanForm onSubmit={this.handleSubmit} savesToExisting={this.savesToExisting()} copiesExisting={this.copiesExisting()} isSaving={saving} isDeleting={deleting} onCloseClick={this.handleCloseClick.bind(this)} onDeleteClick={this.handleDeleteClick.bind(this)} onResetClick={this.handleResetClick.bind(this)} onSubmitForm={this.handleSubmit.bind(this)} initialValues={initialValues} courses={courses} jobPositions={jobPositions} /> </div> ); } } AdminLearningPlanEditView.propTypes = { learningPlanEdit: PropTypes.object, fetching: PropTypes.bool, saving: PropTypes.bool, deleting: PropTypes.bool, error: PropTypes.object }; const autoRequest = AutoRequest(['params.learningPlanId'], (props) => { // get learning plan info if(props.params.learningPlanId) { props.dispatch(learningPlanRequestGet(props.params.learningPlanId)); } }); const connectWithAdminLearningPlan = connect( (state) => ({ learningPlans: state.learningPlan.get('collection'), fetching: state.async.get( LEARNING_PLAN_GET_FETCH ), saving: state.async.get( LEARNING_PLAN_CREATE_FETCH ) || state.async.get( LEARNING_PLAN_UPDATE_FETCH ), deleting: state.async.get( LEARNING_PLAN_DELETE_FETCH ), error: state.async.get( LEARNING_PLAN_GET_ERROR ) || state.async.get( LEARNING_PLAN_CREATE_ERROR ) || state.async.get( LEARNING_PLAN_UPDATE_ERROR ) || state.async.get( LEARNING_PLAN_DELETE_ERROR ), courses: state.course.get('collection'), jobPositions: state.participant.get('jobPositions').toJS() }) ); export default connectWithAdminLearningPlan(autoRequest(AdminLearningPlanEditView));