UNPKG

trc-client-core

Version:
282 lines (255 loc) 9.39 kB
import React from 'react'; import _ from 'lodash'; import Reflux from 'reflux'; import StoreMixin from 'reflux-immutable/StoreMixin'; import moment from 'moment'; import {Link, History, State} from 'react-router'; // Stampy import DataTable from 'bd-stampy/components/DataTable'; import {Tab, TabView, TabContent} from 'bd-stampy/components/Tabs'; // TRC import CourseStore from 'trc-client-core/src/course/CourseStore'; import CourseActions from 'trc-client-core/src/course/CourseActions'; import Loader from 'trc-client-core/src/components/Loader'; import ModalConfirm from 'trc-client-core/src/Modal/ModalConfirm'; import ModalManager from 'trc-client-core/src/Modal/ModalManager'; import UserStore from 'trc-client-core/src/user/UserStore'; import CourseListQueryView from 'trc-client-core/src/course/CourseListQueryView'; import { IconClipboard, IconDocument, IconPerson, IconTelevision, IconAward, IconThumbsUp } from 'trc-client-core/src/components/Icons'; import { E_LEARNING, FACE_TO_FACE, LOCAL_QUIZ, DOCUMENT, ACHIEVEMENT, CERTIFICATION } from 'trc-client-core/src/constants/CourseType'; var CoursesAdminView = React.createClass({ displayName: 'CoursesAdminView', contextTypes: { location: React.PropTypes.object }, mixins: [ require('bd-stampy/mixins/FormMixin'), Reflux.listenTo(CourseStore, 'onStoreChange'), StoreMixin, History, State ], getStoreState() { return { courses: CourseStore.get('courses') }; }, componentDidMount() { CourseActions.fetchCourses({onlyViewable: false}); }, FormMixin_initialFormData(nextState) { nextState.formData = _.defaults(this.context.location.query, { type: 'ALL', stream: 'ALL', departmentCategory: 'ALL' }); return nextState; }, onDelete(id) { ModalManager.showModal(ModalConfirm, { title: 'Delete Course', yes: 'Delete', message: 'Are you sure you want to delete this course?', onYes: () => { CourseStore.course.del(id).then( () => { CourseActions.fetchCourses({onlyViewable: false}); this.history.pushState(null, '/course', this.context.location.query); } ); } }); }, onPublish(course) { ModalManager.showModal(ModalConfirm, { title: 'Publish Course', yes: 'Publish', message: `Are you sure you want to publish this course?`, onYes: () => { CourseActions.publish(course); } }); }, onChange(e, details) { var param = {}; param[details.key] = details.value; this.history.replaceState(null, '/course', _.defaults(param, this.context.location.query)); this.FormMixin_onFormChange(e, details); }, onTabChange(e) { this.history.replaceState(null, '/course', {tab: e}); }, onPagingate(e, page) { this.history.replaceState(null, '/course', { tab: this.context.location.query.tab, page: page }); }, filterMissingCourses() { return this.state.courses.toJS().filter((data) => { return [ 'workshopName', 'abbreviatedName', 'attendance', 'courseCode', 'courseIcon', 'departmentCategory', 'duration', 'learningOutcomes', 'overview' ].some(prop => { return !(data[prop] && /\S/.test(data[prop])); }); }); }, render() { if(!this.state.courses) { return null; } var qaCourses = this.filterMissingCourses(); return ( <div> <h1>Courses</h1> <CourseListQueryView onChange={this.onChange} value={this.state.formData}/> <div className="padding flush-right right"> <Link to="/course/new" className="Button Button-edit">New Course</Link> </div> <TabView onChange={this.onTabChange} transition={false} defaultTab={parseInt(this.context.location.query.tab || 1)}> <Tab>All Courses</Tab> <TabContent> {this.renderErrors(this.state.error)} {this.renderCourseTable(this.state.courses.toJS())} </TabContent> <Tab onClick={this.tabClick}>{`QA (${qaCourses.length})`}</Tab> <TabContent> {this.renderCourseTable(qaCourses)} </TabContent> </TabView> </div> ); }, renderQueryView(key) { return <CourseListQueryView key={key} onChange={this.onChange} value={this.state.formData}/>; }, renderErrors(error) { if(error) { return <div className="InfoBox InfoBox-error"> {error.errorMessage} </div>; } }, renderCourseTable(courses) { var pageAmmount = 50; var currentPage = parseInt(this.context.location.query.page, 10) || 0; if(!courses) { return <Loader></Loader>; } var filtered = courses.filter(CourseStore.filterCourses(this.state.formData)); var tableSchema = [{ heading: 'Name', filter: 'workshopName', width: '30%', render: (item) => <Link to={`/course/${item.courseCode}`} className="link">{item.workshopName}</Link> }, { heading: 'Course Code', filter: 'courseCode', width: '15%', render: (item) => item.courseCode || ' - ' }, { heading: 'Date Modified', filter: 'lastModified', render: (item) => moment(new Date(item.lastModified || 0)).format('YYYY-MM-DD') }, { heading: 'Stream', filter: 'stream', render: (item) => _.startCase(item.stream) }, { heading: 'Type', filter: 'type', render: this.renderCourseStatus }, { heading: 'Quality', filter: 'type', render: item => { var values = _(item).values(); var filled = values.filter(str => !(String(str).length === 0 || !String(str).trim())); var decimal = filled.value().length / values.value().length return <span className={(decimal <= 0.8) ? 't-red' : ''}>{`${Math.floor(decimal * 100)}%`}</span> } }, { heading: 'Actions', render: this.renderActions, width: '15%' }]; return <DataTable schema={tableSchema} data={filtered} pagination={true} paginationLength={pageAmmount} paginationPage={currentPage} onPagingate={this.onPagingate} modifier="data" />; }, renderActions(dd) { var test; var badgeColor = (dd.draft) ? 'Button-green' : ''; var publish = <a key="publish" className={badgeColor + " Button Button-small w100"} onClick={this.onPublish.bind(null, dd)}>Publish</a>; var deleteButton = <a key="delete" className="Button Button-small Button-grey w100" onClick={this.onDelete.bind(this, dd.id)}>Delete</a>; if(dd.type === 'E_LEARNING' && dd.eLearningTag.moduleId) { test = <a key="test" className="Button Button-small Button-grey w100" href={`${UserStore.get('elearningServer')}tester/${dd.eLearningTag.moduleId}`}>Test</a>; } // You cannot publish an elearning course that hasnt been tested if(!dd.draft || (dd.type === 'E_LEARNING' && !dd.eLearningTag.testResult) && UserStore.isnt('ROLE_MEGA_ADMIN')) { publish = null; } // You cannot delte published courses if(!dd.draft) { deleteButton = null; } return <div> <Link key="edit" to={`/course/${dd.courseCode}/edit`} className="Button Button-small Button-edit w100">Edit</Link> {deleteButton} {test} {publish} </div>; }, renderCourseStatus(dd) { var className; if(dd.type === 'E_LEARNING') { className = (dd.eLearningTag.testResult) ? 't-green' : 't-red'; if(!dd.eLearningTag.moduleId) { className = ''; } } switch(dd.type) { case E_LEARNING: return <IconTelevision className={className} />; case FACE_TO_FACE: return <IconPerson className={className} />; case LOCAL_QUIZ: return <IconClipboard className={className} />; case DOCUMENT: return <IconDocument className={className} />; case ACHIEVEMENT: return <IconThumbsUp className={className} />; case CERTIFICATION: return <IconAward className={className} />; } } }); module.exports = CoursesAdminView;