UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

231 lines (230 loc) • 7.92 kB
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;