Skip to content

Commit

Permalink
Merge pull request #1034 from slidewiki/SWIK-2488-Enable_selection_of…
Browse files Browse the repository at this point in the history
…_questions_for_exam_mode

Swik 2488 enable selection of questions for exam mode
  • Loading branch information
kprist authored Oct 27, 2018
2 parents af901ec + c94e863 commit 0bef040
Show file tree
Hide file tree
Showing 24 changed files with 783 additions and 238 deletions.
4 changes: 4 additions & 0 deletions actions/loadContentModules.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import deckContentTypeError from './error/deckContentTypeError';
import slideIdTypeError from './error/slideIdTypeError';
import { AllowedPattern } from './error/util/allowedPattern';
import serviceUnavailable from './error/serviceUnavailable';
import PermissionsStore from '../stores/PermissionsStore';
const log = require('./log/clog');


Expand All @@ -35,6 +36,9 @@ export default function loadContentModules(context, payload, done) {
// },

(callback) => {
let editPermission = (context.getStore(PermissionsStore) && context.getStore(PermissionsStore).permissions && (context.getStore(PermissionsStore).permissions.admin || context.getStore(PermissionsStore).permissions.edit));

payload.params.nonExamQuestionsOnly = !editPermission;
context.executeAction(loadQuestionsCount, payload, callback);
},
(callback) => {
Expand Down
5 changes: 1 addition & 4 deletions actions/loadContentQuestions.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,12 @@ export default function loadContentQuestions(context, payload, done) {
if (err) {
log.error(context, {filepath: __filename});
context.executeAction(serviceUnavailable, payload, done);
//context.dispatch('LOAD_CONTENT_QUESTIONS_FAILURE', err);
} else {
context.dispatch('LOAD_CONTENT_QUESTIONS_SUCCESS', res);
context.dispatch('UPDATE_MODULE_TYPE_SUCCESS', {moduleType: 'questions'});
}
let pageTitle = shortTitle + ' | Content Questions | ' + payload.params.stype + ' | ' + payload.params.sid;
//context.dispatch('UPDATE_PAGE_TITLE', {
// pageTitle: pageTitle
//});

done();
});
}
7 changes: 7 additions & 0 deletions actions/questions/invertExamListFlag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const log = require('../log/clog');

export default function invertExamListFlag(context, payload, done) {
log.info(context);
context.dispatch('INVERT_EXAM_LIST_FLAG', payload);
done();
}
37 changes: 37 additions & 0 deletions actions/questions/loadExamQuestions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const log = require('../log/clog');
import ContentQuestionsStore from '../../stores/ContentQuestionsStore';
import deckContentTypeError from '../error/deckContentTypeError';
import serviceUnavailable from '../error/serviceUnavailable';
import slideIdTypeError from '../error/slideIdTypeError';
import { AllowedPattern } from '../error/util/allowedPattern';
export default function loadExamQuestions(context, payload, done) {
log.info(context);
const selector = context.getStore(ContentQuestionsStore).selector;
const sid = (selector.sid) ? selector.sid.split('-')[0] : '';
if (payload.params.sid.split('-')[0] !== sid || payload.params.stype !== selector.stype) {

if (!(['deck', 'slide', 'question'].indexOf(payload.params.stype) > -1 || payload.params.stype === undefined)){
context.executeAction(deckContentTypeError, payload, done);
return;
}

if (!(AllowedPattern.SLIDE_ID.test(payload.params.sid) || payload.params.sid === undefined)) {
context.executeAction(slideIdTypeError, payload, done);
return;
}

context.service.read('questions.examlist', payload, {timeout: 20 * 1000}, (err, res) => {
if (err) {
log.error(context, {filepath: __filename});
context.executeAction(serviceUnavailable, payload, done);
} else {
context.dispatch('LOAD_CONTENT_QUESTIONS_SUCCESS', res);
context.dispatch('UPDATE_MODULE_TYPE_SUCCESS', {moduleType: 'questions'});
}

done();
});
} else {
done();
}
}
6 changes: 6 additions & 0 deletions actions/questions/resetExamAnswers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import log from '../log/clog';
export default function resetExamAnswers(context, payload, done) {
log.info(context);
context.dispatch('RESET_ANSWERS', payload);
done();
}
6 changes: 6 additions & 0 deletions actions/questions/selectExamAnswer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import log from '../log/clog';
export default function selectExamAnswer(context, payload, done) {
log.info(context);
context.dispatch('QUESTION_ANSWER_SELECTED', payload);
done();
}
6 changes: 6 additions & 0 deletions actions/questions/showCorrectExamAnswers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import log from '../log/clog';
export default function showCorrectExamAnswers(context, payload, done) {
log.info(context);
context.dispatch('SHOW_CORRECT_EXAM_ANSWERS', payload);
done();
}
17 changes: 17 additions & 0 deletions actions/questions/updateExamList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const log = require('../log/clog');
import serviceUnavailable from '../error/serviceUnavailable';
import ContentQuestionsStore from '../../stores/ContentQuestionsStore';

export default function updateExamList(context, payload, done) {
log.info(context, payload);

context.service.update('questions.updateExamList', {modifiedSelections: payload.modifiedSelections}, {timeout: 20 * 1000}, (err, res) => {
if (err) {
log.error(context, {filepath: __filename});
context.executeAction(serviceUnavailable, payload, done);
} else {
context.dispatch('UPDATE_QUESTIONS', payload);
}
done();
});
}
11 changes: 8 additions & 3 deletions components/Deck/ContentModulesPanel/ContentModulesPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import DataSourcePanel from './DataSourcePanel/DataSourcePanel';
import TagsPanel from './TagsPanel/TagsPanel';
//import ContributorsPanel from './ContributorsPanel/ContributorsPanel';
import ContentModulesStore from '../../../stores/ContentModulesStore';
import PermissionsStore from '../../../stores/PermissionsStore';
import { isLocalStorageOn } from '../../../common.js';
import loadCollectionsTab from '../../../actions/collections/loadCollectionsTab';
import CollectionsPanel from './CollectionsPanel/CollectionsPanel';
Expand Down Expand Up @@ -78,7 +79,10 @@ class ContentModulesPanel extends React.Component {
handleTabClick(type, e) {
switch (type) {
case 'questions':
this.context.executeAction(loadContentQuestions, {params: this.props.ContentModulesStore.selector});
let editPermission = (this.props.PermissionsStore && this.props.PermissionsStore.permissions && (this.props.PermissionsStore.permissions.admin || this.props.PermissionsStore.permissions.edit));
let params = this.props.ContentModulesStore.selector;
this.context.executeAction(loadContentQuestions, {params: params});

break;
case 'datasource':
this.context.executeAction(loadDataSources, {params: this.props.ContentModulesStore.selector});
Expand Down Expand Up @@ -277,9 +281,10 @@ class ContentModulesPanel extends React.Component {
ContentModulesPanel.contextTypes = {
executeAction: PropTypes.func.isRequired
};
ContentModulesPanel = connectToStores(ContentModulesPanel, [ContentModulesStore], (context, props) => {
ContentModulesPanel = connectToStores(ContentModulesPanel, [ContentModulesStore, PermissionsStore], (context, props) => {
return {
ContentModulesStore: context.getStore(ContentModulesStore).getState()
ContentModulesStore: context.getStore(ContentModulesStore).getState(),
PermissionsStore: context.getStore(PermissionsStore).getState()
};
});
export default ContentModulesPanel;
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class ContentQuestionAdd extends React.Component {
userId: this.props.userId,
relatedObjectId: this.props.selector.sid,
relatedObject: this.props.selector.stype,
isExamQuestion: false
};
this.updateQuestionTitle = this.updateQuestionTitle.bind(this);
this.updateQuestionDifficulty = this.updateQuestionDifficulty.bind(this);
Expand All @@ -39,6 +40,7 @@ class ContentQuestionAdd extends React.Component {
this.updateCorrect4 = this.updateCorrect4.bind(this);

this.updateExplanation = this.updateExplanation.bind(this);
this.updateIsExamQuestion = this.updateIsExamQuestion.bind(this);
this.saveButtonClick = this.saveButtonClick.bind(this);
this.cancelButtonClick = this.cancelButtonClick.bind(this);
}
Expand Down Expand Up @@ -132,14 +134,18 @@ class ContentQuestionAdd extends React.Component {
updateQuestionDifficulty(e) {
this.setState({difficulty: e.target.value});
}

updateIsExamQuestion(e) {
this.setState({isExamQuestion: e.target.checked});
}

render() {
//const numAnswers = this.props.question.answers.length;
const answerChoiceWidth = {
width: '680px',
};
return (
<div className="ui bottom attached" data-reactid="637">
<div className="ui bottom attached">
<div className="ui padded segment">
<form className="ui form" ref="questionadd_form">
<div className="two fields inline">
Expand Down Expand Up @@ -213,6 +219,12 @@ class ContentQuestionAdd extends React.Component {
<label htmlFor="explanation">Explanation (optional)</label>
<textarea rows="2" id="explanation" onChange={this.updateExplanation}></textarea>
</div>
<div className="field">
<div className="ui checkbox">
<input type="checkbox" name="exam" id="exam" tabIndex="0" className="hidden" defaultChecked={this.state.isExamQuestion} onChange={this.updateIsExamQuestion}/>
<label htmlFor="exam">This is an exam question</label>
</div>
</div>
<div className="field">
<div className="ui container">
<div >
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,12 @@ class ContentQuestionAnswersItem extends React.Component {

render() {
const answer = this.props.answer;
const name = this.props.name;

// let rightIcon = (<i className="icon"></i>);
// switch (answer.correct) {
// case true:
// rightIcon = (<i className="checkmark icon teal"></i>);
// break;
// }


return (
//<div className="item"> {rightIcon}
// <div className="content"> {answer.answer} </div>
// </div>

<div className="field">
<div className="ui checkbox">
<input type="checkbox" name={name} id={name} /> {/* defaultChecked={answer.correct} */}
<label htmlFor={name}>
<div className="ui ">
<i className="ui small circle outline icon" />
<label >
{answer.answer}
</label>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class ContentQuestionAnswersList extends React.Component {
constructor(props){
super(props);
this.state = {
// isEditButtonClicked: false,
showCorrect: false,
};
this.handleButtonClick = this.handleButtonClick.bind(this);
Expand All @@ -26,16 +25,10 @@ class ContentQuestionAnswersList extends React.Component {
}

handleEditButtonClick() {
// this.setState({
// isEditButtonClicked: true
// });

this.context.executeAction(loadQuestion, {qstid: this.props.qstid});
}

render() {
const creatorId = this.props.DeckViewStore.creatorData._id;
const userId = this.props.UserProfileStore.userid;
const editButton = (
<button className="ui compact button primary" onClick={this.handleEditButtonClick}>
<i className="edit icon" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class ContentQuestionEdit extends React.Component {
explanation: this.props.question.explanation,
userId: this.props.userId,
relatedObjectId: this.props.question.relatedObjectId,
relatedObject: this.props.question.relatedObject
relatedObject: this.props.question.relatedObject,
isExamQuestion: this.props.question.isExamQuestion
};
this.updateQuestionTitle = this.updateQuestionTitle.bind(this);
this.updateQuestionDifficulty = this.updateQuestionDifficulty.bind(this);
Expand All @@ -41,6 +42,7 @@ class ContentQuestionEdit extends React.Component {
this.updateCorrect4 = this.updateCorrect4.bind(this);

this.updateExplanation = this.updateExplanation.bind(this);
this.updateIsExamQuestion = this.updateIsExamQuestion.bind(this);
this.saveButtonClick = this.saveButtonClick.bind(this);
this.cancelButtonClick = this.cancelButtonClick.bind(this);
this.deleteButtonClick = this.deleteButtonClick.bind(this);
Expand Down Expand Up @@ -148,14 +150,18 @@ class ContentQuestionEdit extends React.Component {
updateQuestionDifficulty(e) {
this.setState({difficulty: e.target.value});
}


updateIsExamQuestion(e) {
this.setState({isExamQuestion: e.target.checked});
}

render() {
// const numAnswers = this.props.question.answers.length;
const answerChoiceWidth = {
width: '680px',
};
return (
<div className="ui bottom attached" data-reactid="637">
<div className="ui bottom attached">
<div className="ui padded segment">
<form className="ui form" ref="questionedit_form">
<div className="two fields inline">
Expand Down Expand Up @@ -238,6 +244,12 @@ class ContentQuestionEdit extends React.Component {
<label htmlFor="explanation">Explanation (optional)</label>
<textarea rows="2" id="explanation" defaultValue={this.state.explanation} onChange={this.updateExplanation}></textarea>
</div>
<div className="field">
<div className="ui checkbox">
<input type="checkbox" name="exam" id="exam" tabIndex="0" className="hidden" defaultChecked={this.state.isExamQuestion} onChange={this.updateIsExamQuestion}/>
<label htmlFor="exam">This is an exam question</label>
</div>
</div>
<div className="field">
<div className="ui container">
<div >
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,7 @@ class ContentQuestionsItem extends React.Component {
{difficultyStars(question.difficulty)}
</div>

<div
className={activeIfFirst + ' content'}
data-reactid={653}>
<div className={activeIfFirst + ' content'}>
{answers}
</div>
{nodeRef}
Expand Down
Loading

0 comments on commit 0bef040

Please sign in to comment.