@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
231 lines (230 loc) • 7.92 kB
JavaScript
function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
import React, { createContext, useContext } from 'react';
import update from 'immutability-helper';
import findIndex from 'lodash/findIndex';
import omit from 'lodash/omit';
import without from 'lodash/without';
var CategorizationPresenterContext = /*#__PURE__*/ createContext(null);
function CategorizationPresenterProvider(param) {
var interactionData = param.interactionData, scoringData = param.scoringData, changeItemState = param.changeItemState, newId = param.newId, children = param.children;
// =============
// HELPERS
// =============
function getCategoryOrder() {
// This is to protect against quizzes which were
// created before categoryOrder was introduced
return interactionData.categoryOrder || Object.keys(interactionData.categories);
}
function updateInteractionData(updates) {
changeItemState({
interactionData: Object.assign({}, interactionData || {}, updates)
});
}
// ===========
// ACTIONS - CATEGORIES
// ===========
function onCategoryInputChange(itemId, e) {
var categories = update(interactionData.categories, _define_property({}, itemId, {
itemBody: {
$set: e.target.value
}
}));
updateInteractionData({
categories: categories
});
}
function onCreateCategory() {
var newItemId = newId();
var newItem = {
id: newItemId,
itemBody: ''
};
var newCategories = update(interactionData.categories, _define_property({}, newItemId, {
$set: newItem
}));
var newCategoryOrder = update(getCategoryOrder(), {
$push: [
newItemId
]
});
var newCategoryScoringData = {
id: newItemId,
scoringAlgorithm: 'AllOrNothing',
scoringData: {
value: []
}
};
var newInteractionData = update(interactionData, {
categories: {
$set: newCategories
},
categoryOrder: {
$set: newCategoryOrder
}
});
var newScoringData = update(scoringData, {
value: {
$push: [
newCategoryScoringData
]
}
});
changeItemState({
interactionData: newInteractionData,
scoringData: newScoringData
});
}
function onRemoveCategory(categoryId) {
var newCategories = omit(interactionData.categories, categoryId);
var newCategoryOrder = getCategoryOrder().filter(function(c) {
return c !== categoryId;
});
var newDistractors = omit(interactionData.distractors, scoringData.value.filter(function(item) {
return item.id === categoryId;
})[0].scoringData.value);
var newScoringDataValue = scoringData.value.filter(function(item) {
return item.id !== categoryId;
});
var newInteractionData = update(interactionData, {
categoryOrder: {
$set: newCategoryOrder
},
categories: {
$set: newCategories
},
distractors: {
$set: newDistractors
}
});
var newScoringData = update(scoringData, {
value: {
$set: newScoringDataValue
}
});
changeItemState({
interactionData: newInteractionData,
scoringData: newScoringData
});
}
// ===========
// ACTIONS - ANSWERS
// ===========
function onCreateAnswer(categoryId) {
var newItemId = newId();
var newItem = {
id: newItemId,
itemBody: ''
};
var newDistractors = update(interactionData.distractors, _define_property({}, newItemId, {
$set: newItem
}));
var scoringDataCategoryIndex = findIndex(scoringData.value, function(item) {
return item.id === categoryId;
});
var newInteractionData = update(interactionData, {
distractors: {
$set: newDistractors
}
});
var newScoringData = update(scoringData, {
value: _define_property({}, scoringDataCategoryIndex, {
scoringData: {
value: {
// because kinesis does not save empty arrays well,
// we need to guard against this being null
$apply: function(answersList) {
return (answersList || []).concat([
newItemId
]);
}
}
}
})
});
changeItemState({
interactionData: newInteractionData,
scoringData: newScoringData
});
}
function onRemoveAnswer(itemId, categoryId) {
var newDistractors = omit(interactionData.distractors, itemId);
var scoringDataCategoryIndex = findIndex(scoringData.value, function(item) {
return item.id === categoryId;
});
var scoringDataCategory = scoringData.value[scoringDataCategoryIndex];
var newCategScoringDataValues = without(scoringDataCategory.scoringData.value, itemId);
var newInteractionData = update(interactionData, {
distractors: {
$set: newDistractors
}
});
var newScoringData = update(scoringData, {
value: _define_property({}, scoringDataCategoryIndex, {
scoringData: {
value: {
$set: newCategScoringDataValues
}
}
})
});
changeItemState({
interactionData: newInteractionData,
scoringData: newScoringData
});
}
// ===========
// ACTIONS - DISTRACTORS
// ===========
function onDistractorInputChange(itemId, e) {
var distractors = update(interactionData.distractors, _define_property({}, itemId, {
itemBody: {
$set: e.target.value
}
}));
updateInteractionData({
distractors: distractors
});
}
function onRemoveDistractor(itemId) {
var newList = omit(interactionData.distractors, itemId);
var newInteractionData = update(interactionData, {
distractors: {
$set: newList
}
});
changeItemState({
interactionData: newInteractionData
});
}
var value = {
getCategoryOrder: getCategoryOrder,
updateInteractionData: updateInteractionData,
onCategoryInputChange: onCategoryInputChange,
onCreateCategory: onCreateCategory,
onRemoveCategory: onRemoveCategory,
onCreateAnswer: onCreateAnswer,
onRemoveAnswer: onRemoveAnswer,
onDistractorInputChange: onDistractorInputChange,
onRemoveDistractor: onRemoveDistractor
};
return /*#__PURE__*/ React.createElement(CategorizationPresenterContext.Provider, {
value: value
}, children);
}
function useCategorizationPresenter() {
return useContext(CategorizationPresenterContext);
}
export { CategorizationPresenterContext, CategorizationPresenterProvider, useCategorizationPresenter };
export default CategorizationPresenterProvider;