@pie-element/image-cloze-association 4.9.1-next.2 → 4.9.1-next.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -129,7 +129,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
129
129
 
130
130
  ### Features
131
131
 
132
- * add a different property in the config, forceEnabled, to force a value ([300c664](https://github.com/pie-framework/pie-elements/commit/300c664618f46177137deef3bced2d096cdb8126))
132
+ * add a different property in the config, to force a value ([300c664](https://github.com/pie-framework/pie-elements/commit/300c664618f46177137deef3bced2d096cdb8126))
133
133
 
134
134
 
135
135
 
@@ -113,8 +113,6 @@ var Root = /*#__PURE__*/function (_React$Component) {
113
113
  Properties: panelProperties
114
114
  }
115
115
  })
116
- }, /*#__PURE__*/_react["default"].createElement("div", {
117
- className: classes.content
118
116
  }, model && model.teacherInstructionsEnabled && /*#__PURE__*/_react["default"].createElement(_configUi.InputContainer, {
119
117
  label: teacherInstructions.label,
120
118
  className: classes.promptHolder
@@ -133,7 +131,7 @@ var Root = /*#__PURE__*/function (_React$Component) {
133
131
  }, {
134
132
  language: 'special'
135
133
  }]
136
- })), /*#__PURE__*/_react["default"].createElement("div", null, "Image cloze association")));
134
+ })), /*#__PURE__*/_react["default"].createElement("div", null, "Image cloze association"));
137
135
  }
138
136
  }]);
139
137
  return Root;
@@ -143,16 +141,10 @@ exports.Root = Root;
143
141
 
144
142
  var styles = function styles(theme) {
145
143
  return {
146
- base: {
147
- marginTop: theme.spacing.unit * 3
148
- },
149
144
  promptHolder: {
150
145
  width: '100%',
151
- paddingTop: theme.spacing.unit * 2
152
- },
153
- prompt: {
154
146
  paddingTop: theme.spacing.unit * 2,
155
- width: '100%'
147
+ marginBottom: theme.spacing.unit * 2
156
148
  }
157
149
  };
158
150
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/root.jsx"],"names":["Panel","settings","toggle","Root","teacherInstructions","props","onModelChanged","model","classes","configuration","onConfigurationChanged","imageSupport","uploadSoundSupport","maxImageWidth","maxImageHeight","settingsPanelDisabled","spellCheck","withRubric","spellCheckEnabled","panelProperties","teacherInstructionsEnabled","label","rubricEnabled","config","Properties","content","promptHolder","prompt","onTeacherInstructionsChanged","language","React","Component","styles","theme","base","marginTop","spacing","unit","width","paddingTop","propTypes","PropTypes","object","isRequired","func","shape","add"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;;;;;;;;;AAEA,IAAQA,KAAR,GAA0BC,kBAA1B,CAAQD,KAAR;AAAA,IAAeE,MAAf,GAA0BD,kBAA1B,CAAeC,MAAf;;IAEaC,I;;;;;;;;;;;;;;;qHACoB,UAACC,mBAAD,EAAyB;AACtD,YAAKC,KAAL,CAAWC,cAAX,iCAA+B,MAAKD,KAAL,CAAWE,KAA1C;AAAiDH,QAAAA,mBAAmB,EAAnBA;AAAjD;AACD,K;;;;;;WAED,kBAAS;AACP,wBACE,KAAKC,KADP;AAAA,UAAQG,OAAR,eAAQA,OAAR;AAAA,UAAiBD,KAAjB,eAAiBA,KAAjB;AAAA,UAAwBE,aAAxB,eAAwBA,aAAxB;AAAA,UAAuCH,cAAvC,eAAuCA,cAAvC;AAAA,UAAuDI,sBAAvD,eAAuDA,sBAAvD;AAAA,UAA+EC,YAA/E,eAA+EA,YAA/E;AAAA,UAA6FC,kBAA7F,eAA6FA,kBAA7F;;AAEA,iBAOIH,aAAa,IAAI,EAPrB;AAAA,oCACEI,aADF;AAAA,UACEA,aADF,mCACkB,EADlB;AAAA,qCAEEC,cAFF;AAAA,UAEEA,cAFF,oCAEmB,EAFnB;AAAA,UAGEC,qBAHF,QAGEA,qBAHF;AAAA,iCAIEC,UAJF;AAAA,UAIEA,UAJF,gCAIe,EAJf;AAAA,uCAKEZ,mBALF;AAAA,UAKEA,mBALF,sCAKwB,EALxB;AAAA,iCAMEa,UANF;AAAA,UAMEA,UANF,gCAMe,EANf;;AAQA,kBAA8BV,KAAK,IAAI,EAAvC;AAAA,UAAQW,iBAAR,SAAQA,iBAAR;;AAEA,UAAMC,eAAe,GAAG;AACtBC,QAAAA,0BAA0B,EAAEhB,mBAAmB,CAACH,QAApB,IAAgCC,MAAM,CAACE,mBAAmB,CAACiB,KAArB,CAD5C;AAEtBH,QAAAA,iBAAiB,EAAEF,UAAU,CAACf,QAAX,IAAuBC,MAAM,CAACc,UAAU,CAACK,KAAZ,CAF1B;AAGtBC,QAAAA,aAAa,EAAE,CAAAL,UAAU,SAAV,IAAAA,UAAU,WAAV,YAAAA,UAAU,CAAEhB,QAAZ,KAAwBC,MAAM,CAACe,UAAD,aAACA,UAAD,uBAACA,UAAU,CAAEI,KAAb;AAHvB,OAAxB;AAMA,0BACE,gCAAC,gBAAD,CAAQ,YAAR;AACE,QAAA,YAAY,EAAEN,qBADhB;AAEE,QAAA,QAAQ,eACN,gCAAC,KAAD;AACE,UAAA,KAAK,EAAER,KADT;AAEE,UAAA,aAAa,EAAEE,aAFjB;AAGE,UAAA,aAAa,EAAE,uBAACF,KAAD;AAAA,mBAAWD,cAAc,CAACC,KAAD,CAAzB;AAAA,WAHjB;AAIE,UAAA,qBAAqB,EAAE,+BAACgB,MAAD;AAAA,mBAAYb,sBAAsB,CAACa,MAAD,CAAlC;AAAA,WAJzB;AAKE,UAAA,MAAM,EAAE;AACNC,YAAAA,UAAU,EAAEL;AADN;AALV;AAHJ,sBAcE;AAAK,QAAA,SAAS,EAAEX,OAAO,CAACiB;AAAxB,SACGlB,KAAK,IAAIA,KAAK,CAACa,0BAAf,iBACC,gCAAC,wBAAD;AAAgB,QAAA,KAAK,EAAEhB,mBAAmB,CAACiB,KAA3C;AAAkD,QAAA,SAAS,EAAEb,OAAO,CAACkB;AAArE,sBACE,gCAAC,wBAAD;AACE,QAAA,SAAS,EAAElB,OAAO,CAACmB,MADrB;AAEE,QAAA,MAAM,EAAEpB,KAAK,CAACH,mBAAN,IAA6B,EAFvC;AAGE,QAAA,QAAQ,EAAE,KAAKwB,4BAHjB;AAIE,QAAA,YAAY,EAAEjB,YAJhB;AAKE,QAAA,QAAQ,EAAE,KALZ;AAME,QAAA,UAAU,EAAEO,iBANd;AAOE,QAAA,aAAa,EAAEL,aAAa,IAAIA,aAAa,CAACT,mBAPhD;AAQE,QAAA,cAAc,EAAEU,cAAc,IAAIA,cAAc,CAACV,mBARnD;AASE,QAAA,kBAAkB,EAAEQ,kBATtB;AAUE,QAAA,uBAAuB,EAAE,CAAC;AAAEiB,UAAAA,QAAQ,EAAE;AAAZ,SAAD,EAA0B;AAAEA,UAAAA,QAAQ,EAAE;AAAZ,SAA1B;AAV3B,QADF,CAFJ,eAkBE,uEAlBF,CAdF,CADF;AAqCD;;;EA7DuBC,kBAAMC,S;;;;AAgEhC,IAAMC,MAAM,GAAG,SAATA,MAAS,CAACC,KAAD;AAAA,SAAY;AACzBC,IAAAA,IAAI,EAAE;AACJC,MAAAA,SAAS,EAAEF,KAAK,CAACG,OAAN,CAAcC,IAAd,GAAqB;AAD5B,KADmB;AAIzBX,IAAAA,YAAY,EAAE;AACZY,MAAAA,KAAK,EAAE,MADK;AAEZC,MAAAA,UAAU,EAAEN,KAAK,CAACG,OAAN,CAAcC,IAAd,GAAqB;AAFrB,KAJW;AAQzBV,IAAAA,MAAM,EAAE;AACNY,MAAAA,UAAU,EAAEN,KAAK,CAACG,OAAN,CAAcC,IAAd,GAAqB,CAD3B;AAENC,MAAAA,KAAK,EAAE;AAFD;AARiB,GAAZ;AAAA,CAAf;;AAcAnC,IAAI,CAACqC,SAAL,GAAiB;AACfhC,EAAAA,OAAO,EAAEiC,sBAAUC,MAAV,CAAiBC,UADX;AAEfrC,EAAAA,cAAc,EAAEmC,sBAAUG,IAFX;AAGflC,EAAAA,sBAAsB,EAAE+B,sBAAUG,IAHnB;AAIfrC,EAAAA,KAAK,EAAEkC,sBAAUC,MAAV,CAAiBC,UAJT;AAKflC,EAAAA,aAAa,EAAEgC,sBAAUC,MAAV,CAAiBC,UALjB;AAMfhC,EAAAA,YAAY,EAAE8B,sBAAUI,KAAV,CAAgB;AAC5BC,IAAAA,GAAG,EAAEL,sBAAUG,IAAV,CAAeD,UADQ;AAE5B,cAAQF,sBAAUG,IAAV,CAAeD;AAFK,GAAhB,CANC;AAUf/B,EAAAA,kBAAkB,EAAE6B,sBAAUI,KAAV,CAAgB;AAClCC,IAAAA,GAAG,EAAEL,sBAAUG,IAAV,CAAeD,UADc;AAElC,cAAQF,sBAAUG,IAAV,CAAeD;AAFW,GAAhB;AAVL,CAAjB;;eAgBe,wBAAWX,MAAX,EAAmB7B,IAAnB,C","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { settings, layout, InputContainer } from '@pie-lib/config-ui';\nimport EditableHtml from '@pie-lib/editable-html';\nimport { withStyles } from '@material-ui/core/styles';\n\nconst { Panel, toggle } = settings;\n\nexport class Root extends React.Component {\n onTeacherInstructionsChanged = (teacherInstructions) => {\n this.props.onModelChanged({ ...this.props.model, teacherInstructions });\n };\n\n render() {\n const { classes, model, configuration, onModelChanged, onConfigurationChanged, imageSupport, uploadSoundSupport } =\n this.props;\n const {\n maxImageWidth = {},\n maxImageHeight = {},\n settingsPanelDisabled,\n spellCheck = {},\n teacherInstructions = {},\n withRubric = {},\n } = configuration || {};\n const { spellCheckEnabled } = model || {};\n\n const panelProperties = {\n teacherInstructionsEnabled: teacherInstructions.settings && toggle(teacherInstructions.label),\n spellCheckEnabled: spellCheck.settings && toggle(spellCheck.label),\n rubricEnabled: withRubric?.settings && toggle(withRubric?.label),\n };\n\n return (\n <layout.ConfigLayout\n hideSettings={settingsPanelDisabled}\n settings={\n <Panel\n model={model}\n configuration={configuration}\n onChangeModel={(model) => onModelChanged(model)}\n onChangeConfiguration={(config) => onConfigurationChanged(config)}\n groups={{\n Properties: panelProperties,\n }}\n />\n }\n >\n <div className={classes.content}>\n {model && model.teacherInstructionsEnabled && (\n <InputContainer label={teacherInstructions.label} className={classes.promptHolder}>\n <EditableHtml\n className={classes.prompt}\n markup={model.teacherInstructions || ''}\n onChange={this.onTeacherInstructionsChanged}\n imageSupport={imageSupport}\n nonEmpty={false}\n spellCheck={spellCheckEnabled}\n maxImageWidth={maxImageWidth && maxImageWidth.teacherInstructions}\n maxImageHeight={maxImageHeight && maxImageHeight.teacherInstructions}\n uploadSoundSupport={uploadSoundSupport}\n languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}\n />\n </InputContainer>\n )}\n\n <div>Image cloze association</div>\n </div>\n </layout.ConfigLayout>\n );\n }\n}\n\nconst styles = (theme) => ({\n base: {\n marginTop: theme.spacing.unit * 3,\n },\n promptHolder: {\n width: '100%',\n paddingTop: theme.spacing.unit * 2,\n },\n prompt: {\n paddingTop: theme.spacing.unit * 2,\n width: '100%',\n },\n});\n\nRoot.propTypes = {\n classes: PropTypes.object.isRequired,\n onModelChanged: PropTypes.func,\n onConfigurationChanged: PropTypes.func,\n model: PropTypes.object.isRequired,\n configuration: PropTypes.object.isRequired,\n imageSupport: PropTypes.shape({\n add: PropTypes.func.isRequired,\n delete: PropTypes.func.isRequired,\n }),\n uploadSoundSupport: PropTypes.shape({\n add: PropTypes.func.isRequired,\n delete: PropTypes.func.isRequired,\n }),\n};\n\nexport default withStyles(styles)(Root);\n"],"file":"root.js"}
1
+ {"version":3,"sources":["../src/root.jsx"],"names":["Panel","settings","toggle","Root","teacherInstructions","props","onModelChanged","model","classes","configuration","onConfigurationChanged","imageSupport","uploadSoundSupport","maxImageWidth","maxImageHeight","settingsPanelDisabled","spellCheck","withRubric","spellCheckEnabled","panelProperties","teacherInstructionsEnabled","label","rubricEnabled","config","Properties","promptHolder","prompt","onTeacherInstructionsChanged","language","React","Component","styles","theme","width","paddingTop","spacing","unit","marginBottom","propTypes","PropTypes","object","isRequired","func","shape","add"],"mappings":"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","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { settings, layout, InputContainer } from '@pie-lib/config-ui';\nimport EditableHtml from '@pie-lib/editable-html';\nimport { withStyles } from '@material-ui/core/styles';\n\nconst { Panel, toggle } = settings;\n\nexport class Root extends React.Component {\n onTeacherInstructionsChanged = (teacherInstructions) => {\n this.props.onModelChanged({ ...this.props.model, teacherInstructions });\n };\n\n render() {\n const { classes, model, configuration, onModelChanged, onConfigurationChanged, imageSupport, uploadSoundSupport } =\n this.props;\n const {\n maxImageWidth = {},\n maxImageHeight = {},\n settingsPanelDisabled,\n spellCheck = {},\n teacherInstructions = {},\n withRubric = {},\n } = configuration || {};\n const { spellCheckEnabled } = model || {};\n\n const panelProperties = {\n teacherInstructionsEnabled: teacherInstructions.settings && toggle(teacherInstructions.label),\n spellCheckEnabled: spellCheck.settings && toggle(spellCheck.label),\n rubricEnabled: withRubric?.settings && toggle(withRubric?.label),\n };\n\n return (\n <layout.ConfigLayout\n hideSettings={settingsPanelDisabled}\n settings={\n <Panel\n model={model}\n configuration={configuration}\n onChangeModel={(model) => onModelChanged(model)}\n onChangeConfiguration={(config) => onConfigurationChanged(config)}\n groups={{\n Properties: panelProperties,\n }}\n />\n }\n >\n {model && model.teacherInstructionsEnabled && (\n <InputContainer label={teacherInstructions.label} className={classes.promptHolder}>\n <EditableHtml\n className={classes.prompt}\n markup={model.teacherInstructions || ''}\n onChange={this.onTeacherInstructionsChanged}\n imageSupport={imageSupport}\n nonEmpty={false}\n spellCheck={spellCheckEnabled}\n maxImageWidth={maxImageWidth && maxImageWidth.teacherInstructions}\n maxImageHeight={maxImageHeight && maxImageHeight.teacherInstructions}\n uploadSoundSupport={uploadSoundSupport}\n languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}\n />\n </InputContainer>\n )}\n\n <div>Image cloze association</div>\n </layout.ConfigLayout>\n );\n }\n}\n\nconst styles = (theme) => ({\n promptHolder: {\n width: '100%',\n paddingTop: theme.spacing.unit * 2,\n marginBottom: theme.spacing.unit * 2,\n },\n});\n\nRoot.propTypes = {\n classes: PropTypes.object.isRequired,\n onModelChanged: PropTypes.func,\n onConfigurationChanged: PropTypes.func,\n model: PropTypes.object.isRequired,\n configuration: PropTypes.object.isRequired,\n imageSupport: PropTypes.shape({\n add: PropTypes.func.isRequired,\n delete: PropTypes.func.isRequired,\n }),\n uploadSoundSupport: PropTypes.shape({\n add: PropTypes.func.isRequired,\n delete: PropTypes.func.isRequired,\n }),\n};\n\nexport default withStyles(styles)(Root);\n"],"file":"root.js"}
@@ -45,42 +45,34 @@ export class Root extends React.Component {
45
45
  />
46
46
  }
47
47
  >
48
- <div className={classes.content}>
49
- {model && model.teacherInstructionsEnabled && (
50
- <InputContainer label={teacherInstructions.label} className={classes.promptHolder}>
51
- <EditableHtml
52
- className={classes.prompt}
53
- markup={model.teacherInstructions || ''}
54
- onChange={this.onTeacherInstructionsChanged}
55
- imageSupport={imageSupport}
56
- nonEmpty={false}
57
- spellCheck={spellCheckEnabled}
58
- maxImageWidth={maxImageWidth && maxImageWidth.teacherInstructions}
59
- maxImageHeight={maxImageHeight && maxImageHeight.teacherInstructions}
60
- uploadSoundSupport={uploadSoundSupport}
61
- languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}
62
- />
63
- </InputContainer>
64
- )}
48
+ {model && model.teacherInstructionsEnabled && (
49
+ <InputContainer label={teacherInstructions.label} className={classes.promptHolder}>
50
+ <EditableHtml
51
+ className={classes.prompt}
52
+ markup={model.teacherInstructions || ''}
53
+ onChange={this.onTeacherInstructionsChanged}
54
+ imageSupport={imageSupport}
55
+ nonEmpty={false}
56
+ spellCheck={spellCheckEnabled}
57
+ maxImageWidth={maxImageWidth && maxImageWidth.teacherInstructions}
58
+ maxImageHeight={maxImageHeight && maxImageHeight.teacherInstructions}
59
+ uploadSoundSupport={uploadSoundSupport}
60
+ languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}
61
+ />
62
+ </InputContainer>
63
+ )}
65
64
 
66
- <div>Image cloze association</div>
67
- </div>
65
+ <div>Image cloze association</div>
68
66
  </layout.ConfigLayout>
69
67
  );
70
68
  }
71
69
  }
72
70
 
73
71
  const styles = (theme) => ({
74
- base: {
75
- marginTop: theme.spacing.unit * 3,
76
- },
77
72
  promptHolder: {
78
73
  width: '100%',
79
74
  paddingTop: theme.spacing.unit * 2,
80
- },
81
- prompt: {
82
- paddingTop: theme.spacing.unit * 2,
83
- width: '100%',
75
+ marginBottom: theme.spacing.unit * 2,
84
76
  },
85
77
  });
86
78
 
@@ -24,6 +24,8 @@ var _controllerUtils = require("@pie-lib/controller-utils");
24
24
 
25
25
  var _utils = require("./utils");
26
26
 
27
+ var _lodash = require("lodash");
28
+
27
29
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
28
30
 
29
31
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
@@ -79,7 +81,7 @@ var isResponseCorrect = function isResponseCorrect(responses, session) {
79
81
 
80
82
  if (session.answers && totalValidResponses === session.answers.length) {
81
83
  session.answers.forEach(function (answer) {
82
- if (!(responses[answer.containerIndex].images || []).includes(answer.value)) {
84
+ if (!(responses[answer.containerIndex] && responses[answer.containerIndex].images || []).includes(answer.value)) {
83
85
  isCorrect = false;
84
86
  }
85
87
  });
@@ -88,15 +90,23 @@ var isResponseCorrect = function isResponseCorrect(responses, session) {
88
90
  }
89
91
 
90
92
  return isCorrect;
91
- }; // This applies for items that don't support partial scoring.
93
+ }; // This applies for correct responses that have empty values
92
94
 
93
95
 
94
96
  exports.isResponseCorrect = isResponseCorrect;
95
97
 
98
+ var keepNonEmptyResponses = function keepNonEmptyResponses(responses) {
99
+ var filtered = responses.filter(function (response) {
100
+ return response.images && response.images.length;
101
+ });
102
+ return (0, _lodash.cloneDeep)(filtered);
103
+ }; // This applies for items that don't support partial scoring.
104
+
105
+
96
106
  var isDefaultOrAltResponseCorrect = function isDefaultOrAltResponseCorrect(question, session) {
97
- var _question$validation = question.validation,
98
- value = _question$validation.validResponse.value,
99
- altResponses = _question$validation.altResponses;
107
+ var altResponses = question.validation.altResponses;
108
+ var value = question.validation.validResponse.value;
109
+ value = keepNonEmptyResponses(value);
100
110
  var isCorrect = isResponseCorrect(value, session); // Look for correct answers in alternate responses.
101
111
 
102
112
  if (!isCorrect && altResponses && altResponses.length) {
@@ -130,8 +140,7 @@ var getDeductionPerContainer = function getDeductionPerContainer(containerIndex,
130
140
 
131
141
  var getPartialScore = function getPartialScore(question, session) {
132
142
  var validResponse = question.validation.validResponse,
133
- maxResponsePerZone = question.maxResponsePerZone,
134
- responseContainers = question.responseContainers;
143
+ maxResponsePerZone = question.maxResponsePerZone;
135
144
  var correctAnswers = 0;
136
145
  var possibleResponses = 0;
137
146
 
@@ -139,6 +148,7 @@ var getPartialScore = function getPartialScore(question, session) {
139
148
  return 0;
140
149
  }
141
150
 
151
+ validResponse.value = keepNonEmptyResponses(validResponse.value);
142
152
  validResponse.value.forEach(function (value) {
143
153
  return possibleResponses += (value.images || []).length;
144
154
  });
@@ -167,8 +177,9 @@ var getPartialScore = function getPartialScore(question, session) {
167
177
  } // negative values will implicitly make the score equal to zero
168
178
 
169
179
 
170
- correctAnswers = correctAnswers < 0 ? 0 : correctAnswers;
171
- var denominator = maxResponsePerZone > 1 ? possibleResponses : responseContainers.length;
180
+ correctAnswers = correctAnswers < 0 ? 0 : correctAnswers; // use length of validResponse since some containers can be left empty
181
+
182
+ var denominator = maxResponsePerZone > 1 ? possibleResponses : (validResponse.value || []).length;
172
183
  var str = (correctAnswers / denominator).toFixed(2);
173
184
  return parseFloat(str);
174
185
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["log","normalize","question","rationaleEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","model","session","env","questionNormalized","questionCamelized","Promise","resolve","out","disabled","mode","responseCorrect","getScore","undefined","shuffle","possibleResponses","possible_responses","role","teacherInstructions","isResponseCorrect","responses","isCorrect","totalValidResponses","forEach","value","images","length","answers","answer","containerIndex","includes","isDefaultOrAltResponseCorrect","validation","validResponse","altResponses","altResponse","getDeductionPerContainer","valid","totalStack","filter","item","incorrectStack","maxValid","ignored","slice","getPartialScore","maxResponsePerZone","responseContainers","correctAnswers","all","deductionList","id","denominator","str","toFixed","parseFloat","config","isPartialScoring","partialScoring","enabled","correct","outcome","score","empty","configCamelized","createCorrectResponseSession","valid_response","container","i","v","push"],"mappings":"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","sourcesContent":["import debug from 'debug';\nimport isEmpty from 'lodash/isEmpty';\nimport shuffle from 'lodash/shuffle';\nimport { camelizeKeys } from 'humps';\nimport { partialScoring } from '@pie-lib/controller-utils';\n\nimport { getAllUniqueCorrectness } from './utils';\n\nconst log = debug('pie-elements:image-cloze-association:controller');\n\nexport const normalize = (question) => ({\n rationaleEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n ...question,\n});\n\nexport function model(question, session, env) {\n const questionNormalized = normalize(question);\n const questionCamelized = camelizeKeys(questionNormalized);\n\n return new Promise((resolve) => {\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n ...questionCamelized,\n responseCorrect: env.mode === 'evaluate' ? getScore(questionCamelized, session) === 1 : undefined,\n };\n\n if (questionNormalized.shuffle) {\n out.possibleResponses = shuffle(questionNormalized.possible_responses);\n }\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.teacherInstructions = questionCamelized.teacherInstructionsEnabled\n ? questionCamelized.teacherInstructions\n : null;\n } else {\n out.teacherInstructions = null;\n }\n\n resolve(out);\n });\n}\n\nexport const isResponseCorrect = (responses, session) => {\n let isCorrect = true;\n let totalValidResponses = 0;\n\n if (!session || isEmpty(session)) {\n return false;\n }\n\n responses.forEach((value) => (totalValidResponses += (value.images || []).length));\n\n if (session.answers && totalValidResponses === session.answers.length) {\n session.answers.forEach((answer) => {\n if (!(responses[answer.containerIndex].images || []).includes(answer.value)) {\n isCorrect = false;\n }\n });\n } else {\n isCorrect = false;\n }\n return isCorrect;\n};\n\n// This applies for items that don't support partial scoring.\nconst isDefaultOrAltResponseCorrect = (question, session) => {\n const {\n validation: {\n validResponse: { value },\n altResponses,\n },\n } = question;\n\n let isCorrect = isResponseCorrect(value, session);\n\n // Look for correct answers in alternate responses.\n if (!isCorrect && altResponses && altResponses.length) {\n altResponses.forEach((altResponse) => {\n if (isResponseCorrect(altResponse.value, session)) {\n isCorrect = true;\n }\n });\n }\n return isCorrect;\n};\n\n// Deduct only the items that exceeded the maximum valid response per container.\nconst getDeductionPerContainer = (containerIndex, answers, valid) => {\n const totalStack = answers.filter((item) => item.containerIndex === containerIndex);\n const incorrectStack = totalStack.filter((item) => !item.isCorrect);\n const maxValid = (valid.value[containerIndex].images || []).length;\n\n if (totalStack.length > maxValid) {\n const ignored = totalStack.length - maxValid;\n return incorrectStack.slice(-ignored);\n }\n return [];\n};\n\nexport const getPartialScore = (question, session) => {\n const {\n validation: { validResponse },\n maxResponsePerZone,\n responseContainers,\n } = question;\n let correctAnswers = 0;\n let possibleResponses = 0;\n\n if (!session || isEmpty(session)) {\n return 0;\n }\n\n validResponse.value.forEach((value) => (possibleResponses += (value.images || []).length));\n\n if (session.answers && session.answers.length) {\n const all = getAllUniqueCorrectness(session.answers, validResponse.value);\n correctAnswers = all.filter((item) => item.isCorrect).length;\n\n // deduction rules: https://docs.google.com/document/d/1Oprm8Qs5fg_Dwoj2pNpsfu4D63QgCZgvcqTgeaVel7I/edit\n session.answers.forEach((answer) => {\n if (maxResponsePerZone > 1) {\n const deductionList = getDeductionPerContainer(answer.containerIndex, all, validResponse);\n\n if (deductionList.length) {\n deductionList.forEach((item) => {\n if (item.id === answer.id) {\n correctAnswers -= 1;\n }\n });\n }\n }\n });\n } else {\n correctAnswers = 0;\n }\n // negative values will implicitly make the score equal to zero\n correctAnswers = correctAnswers < 0 ? 0 : correctAnswers;\n\n const denominator = maxResponsePerZone > 1 ? possibleResponses : responseContainers.length;\n const str = (correctAnswers / denominator).toFixed(2);\n\n return parseFloat(str);\n};\n\nconst getScore = (config, session, env = {}) => {\n const isPartialScoring = partialScoring.enabled(config, env);\n const correct = isDefaultOrAltResponseCorrect(config, session);\n\n return isPartialScoring ? getPartialScore(config, session) : correct ? 1 : 0;\n};\n\nexport function outcome(config, session, env = {}) {\n return new Promise((resolve) => {\n log('outcome...');\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n const configCamelized = camelizeKeys(config);\n\n if (session.answers || []) {\n const score = getScore(configCamelized, session, env);\n resolve({ score });\n }\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const {\n validation: {\n valid_response: { value },\n },\n } = question;\n const answers = [];\n\n if (value) {\n value.forEach((container, i) => {\n (container.images || []).forEach((v) => {\n answers.push({\n value: v,\n containerIndex: i,\n });\n });\n });\n }\n\n resolve({\n answers,\n id: '1',\n });\n } else {\n resolve(null);\n }\n });\n};\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["log","normalize","question","rationaleEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","model","session","env","questionNormalized","questionCamelized","Promise","resolve","out","disabled","mode","responseCorrect","getScore","undefined","shuffle","possibleResponses","possible_responses","role","teacherInstructions","isResponseCorrect","responses","isCorrect","totalValidResponses","forEach","value","images","length","answers","answer","containerIndex","includes","keepNonEmptyResponses","filtered","filter","response","isDefaultOrAltResponseCorrect","altResponses","validation","validResponse","altResponse","getDeductionPerContainer","valid","totalStack","item","incorrectStack","maxValid","ignored","slice","getPartialScore","maxResponsePerZone","correctAnswers","all","deductionList","id","denominator","str","toFixed","parseFloat","config","isPartialScoring","partialScoring","enabled","correct","outcome","score","empty","configCamelized","createCorrectResponseSession","valid_response","container","i","v","push"],"mappings":"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","sourcesContent":["import debug from 'debug';\nimport isEmpty from 'lodash/isEmpty';\nimport shuffle from 'lodash/shuffle';\nimport { camelizeKeys } from 'humps';\nimport { partialScoring } from '@pie-lib/controller-utils';\n\nimport { getAllUniqueCorrectness } from './utils';\nimport { cloneDeep } from 'lodash';\n\nconst log = debug('pie-elements:image-cloze-association:controller');\n\nexport const normalize = (question) => ({\n rationaleEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n ...question,\n});\n\nexport function model(question, session, env) {\n const questionNormalized = normalize(question);\n const questionCamelized = camelizeKeys(questionNormalized);\n\n return new Promise((resolve) => {\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n ...questionCamelized,\n responseCorrect: env.mode === 'evaluate' ? getScore(questionCamelized, session) === 1 : undefined,\n };\n\n if (questionNormalized.shuffle) {\n out.possibleResponses = shuffle(questionNormalized.possible_responses);\n }\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.teacherInstructions = questionCamelized.teacherInstructionsEnabled\n ? questionCamelized.teacherInstructions\n : null;\n } else {\n out.teacherInstructions = null;\n }\n\n resolve(out);\n });\n}\n\nexport const isResponseCorrect = (responses, session) => {\n let isCorrect = true;\n let totalValidResponses = 0;\n\n if (!session || isEmpty(session)) {\n return false;\n }\n\n responses.forEach((value) => (totalValidResponses += (value.images || []).length));\n\n if (session.answers && totalValidResponses === session.answers.length) {\n session.answers.forEach((answer) => {\n if (!(responses[answer.containerIndex] && responses[answer.containerIndex].images || []).includes(answer.value)) {\n isCorrect = false;\n }\n });\n } else {\n isCorrect = false;\n }\n return isCorrect;\n};\n\n// This applies for correct responses that have empty values\nconst keepNonEmptyResponses = (responses) => {\n const filtered = responses.filter(response => response.images && response.images.length);\n return cloneDeep(filtered);\n};\n\n// This applies for items that don't support partial scoring.\nconst isDefaultOrAltResponseCorrect = (question, session) => {\n const {\n validation: { altResponses }\n } = question;\n let {\n validation: {\n validResponse: { value },\n }\n } = question;\n\n value = keepNonEmptyResponses(value);\n\n let isCorrect = isResponseCorrect(value, session);\n\n // Look for correct answers in alternate responses.\n if (!isCorrect && altResponses && altResponses.length) {\n altResponses.forEach((altResponse) => {\n if (isResponseCorrect(altResponse.value, session)) {\n isCorrect = true;\n }\n });\n }\n return isCorrect;\n};\n\n// Deduct only the items that exceeded the maximum valid response per container.\nconst getDeductionPerContainer = (containerIndex, answers, valid) => {\n const totalStack = answers.filter((item) => item.containerIndex === containerIndex);\n const incorrectStack = totalStack.filter((item) => !item.isCorrect);\n const maxValid = (valid.value[containerIndex].images || []).length;\n\n if (totalStack.length > maxValid) {\n const ignored = totalStack.length - maxValid;\n return incorrectStack.slice(-ignored);\n }\n return [];\n};\n\nexport const getPartialScore = (question, session) => {\n const {\n validation: { validResponse },\n maxResponsePerZone,\n } = question;\n let correctAnswers = 0;\n let possibleResponses = 0;\n\n if (!session || isEmpty(session)) {\n return 0;\n }\n validResponse.value = keepNonEmptyResponses(validResponse.value);\n\n validResponse.value.forEach((value) => (possibleResponses += (value.images || []).length));\n\n if (session.answers && session.answers.length) {\n const all = getAllUniqueCorrectness(session.answers, validResponse.value);\n correctAnswers = all.filter((item) => item.isCorrect).length;\n\n // deduction rules: https://docs.google.com/document/d/1Oprm8Qs5fg_Dwoj2pNpsfu4D63QgCZgvcqTgeaVel7I/edit\n session.answers.forEach((answer) => {\n if (maxResponsePerZone > 1) {\n const deductionList = getDeductionPerContainer(answer.containerIndex, all, validResponse);\n\n if (deductionList.length) {\n deductionList.forEach((item) => {\n if (item.id === answer.id) {\n correctAnswers -= 1;\n }\n });\n }\n }\n });\n } else {\n correctAnswers = 0;\n }\n // negative values will implicitly make the score equal to zero\n correctAnswers = correctAnswers < 0 ? 0 : correctAnswers;\n\n // use length of validResponse since some containers can be left empty\n const denominator = maxResponsePerZone > 1 ? possibleResponses : (validResponse.value || []).length;\n const str = (correctAnswers / denominator).toFixed(2);\n\n return parseFloat(str);\n};\n\nconst getScore = (config, session, env = {}) => {\n const isPartialScoring = partialScoring.enabled(config, env);\n const correct = isDefaultOrAltResponseCorrect(config, session);\n\n return isPartialScoring ? getPartialScore(config, session) : correct ? 1 : 0;\n};\n\nexport function outcome(config, session, env = {}) {\n return new Promise((resolve) => {\n log('outcome...');\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n const configCamelized = camelizeKeys(config);\n\n if (session.answers || []) {\n const score = getScore(configCamelized, session, env);\n resolve({ score });\n }\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const {\n validation: {\n valid_response: { value },\n },\n } = question;\n const answers = [];\n\n if (value) {\n value.forEach((container, i) => {\n (container.images || []).forEach((v) => {\n answers.push({\n value: v,\n containerIndex: i,\n });\n });\n });\n }\n\n resolve({\n answers,\n id: '1',\n });\n } else {\n resolve(null);\n }\n });\n};\n"],"file":"index.js"}
@@ -16,13 +16,13 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
16
16
  var getAllCorrectness = function getAllCorrectness(answers, responses) {
17
17
  return answers.map(function (answer) {
18
18
  return _objectSpread(_objectSpread({}, answer), {}, {
19
- isCorrect: (responses[answer.containerIndex].images || []).includes(answer.value)
19
+ isCorrect: (responses[answer.containerIndex] && responses[answer.containerIndex].images || []).includes(answer.value)
20
20
  });
21
21
  });
22
22
  };
23
23
 
24
24
  var getValidAnswer = function getValidAnswer(answer, response) {
25
- return (response[answer.containerIndex].images || []).filter(function (res) {
25
+ return (response[answer.containerIndex] && response[answer.containerIndex].images || []).filter(function (res) {
26
26
  return res === answer.value;
27
27
  });
28
28
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.js"],"names":["getAllCorrectness","answers","responses","map","answer","isCorrect","containerIndex","images","includes","value","getValidAnswer","response","filter","res","getAllUniqueCorrectness","validResponses","allCorrectness","forEach","answer1","valuesToParse","answer2","length","shift","index","finalAnswer","id","valid"],"mappings":";;;;;;;;;;;;;;;AAAA,IAAMA,iBAAiB,GAAG,SAApBA,iBAAoB,CAACC,OAAD,EAAUC,SAAV;AAAA,SACxBD,OAAO,CAACE,GAAR,CAAY,UAACC,MAAD;AAAA,2CACPA,MADO;AAEVC,MAAAA,SAAS,EAAE,CAACH,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,CAAiCC,MAAjC,IAA2C,EAA5C,EAAgDC,QAAhD,CAAyDJ,MAAM,CAACK,KAAhE;AAFD;AAAA,GAAZ,CADwB;AAAA,CAA1B;;AAMA,IAAMC,cAAc,GAAG,SAAjBA,cAAiB,CAACN,MAAD,EAASO,QAAT;AAAA,SACrB,CAACA,QAAQ,CAACP,MAAM,CAACE,cAAR,CAAR,CAAgCC,MAAhC,IAA0C,EAA3C,EAA+CK,MAA/C,CAAsD,UAACC,GAAD;AAAA,WAASA,GAAG,KAAKT,MAAM,CAACK,KAAxB;AAAA,GAAtD,CADqB;AAAA,CAAvB;;AAGO,IAAMK,uBAAuB,GAAG,SAA1BA,uBAA0B,CAACb,OAAD,EAAUc,cAAV,EAA6B;AAClE,MAAIC,cAAc,GAAGhB,iBAAiB,CAACC,OAAD,EAAUc,cAAV,CAAtC;AAEAd,EAAAA,OAAO,CAACgB,OAAR,CAAgB,UAACC,OAAD,EAAa;AAC3B,QAAMC,aAAa,GAAGlB,OAAO,CAACW,MAAR,CACpB,UAACQ,OAAD;AAAA,aAAaA,OAAO,CAACX,KAAR,KAAkBS,OAAO,CAACT,KAA1B,IAAmCW,OAAO,CAACd,cAAR,KAA2BY,OAAO,CAACZ,cAAnF;AAAA,KADoB,CAAtB;;AAIA,QAAIa,aAAa,CAACE,MAAd,GAAuB,CAA3B,EAA8B;AAC5B;AACAF,MAAAA,aAAa,CAACG,KAAd,GAF4B,CAG5B;;AACAH,MAAAA,aAAa,CAACF,OAAd,CAAsB,UAACR,KAAD,EAAQc,KAAR,EAAkB;AACtCP,QAAAA,cAAc,GAAGA,cAAc,CAACb,GAAf,CAAmB,UAACqB,WAAD,EAAiB;AACnD,cAAIA,WAAW,CAACC,EAAZ,KAAmBhB,KAAK,CAACgB,EAA7B,EAAiC;AAC/B,gBAAIC,KAAK,GAAGhB,cAAc,CAACc,WAAD,EAAcT,cAAd,CAA1B;AACA,mDACKS,WADL;AAEEnB,cAAAA,SAAS,EAAEqB,KAAK,CAACL,MAAN,GAAeE,KAAK,GAAG;AAFpC;AAID;;AACD,iBAAOC,WAAP;AACD,SATgB,CAAjB;AAUD,OAXD;AAYD;AACF,GAtBD;AAuBA,SAAOR,cAAP;AACD,CA3BM","sourcesContent":["const getAllCorrectness = (answers, responses) =>\n answers.map((answer) => ({\n ...answer,\n isCorrect: (responses[answer.containerIndex].images || []).includes(answer.value),\n }));\n\nconst getValidAnswer = (answer, response) =>\n (response[answer.containerIndex].images || []).filter((res) => res === answer.value);\n\nexport const getAllUniqueCorrectness = (answers, validResponses) => {\n let allCorrectness = getAllCorrectness(answers, validResponses);\n\n answers.forEach((answer1) => {\n const valuesToParse = answers.filter(\n (answer2) => answer2.value === answer1.value && answer2.containerIndex === answer1.containerIndex,\n );\n\n if (valuesToParse.length > 1) {\n // point only to duplicates but first\n valuesToParse.shift();\n // mark duplicates as incorrect\n valuesToParse.forEach((value, index) => {\n allCorrectness = allCorrectness.map((finalAnswer) => {\n if (finalAnswer.id === value.id) {\n let valid = getValidAnswer(finalAnswer, validResponses);\n return {\n ...finalAnswer,\n isCorrect: valid.length > index + 1,\n };\n }\n return finalAnswer;\n });\n });\n }\n });\n return allCorrectness;\n};\n"],"file":"utils.js"}
1
+ {"version":3,"sources":["../src/utils.js"],"names":["getAllCorrectness","answers","responses","map","answer","isCorrect","containerIndex","images","includes","value","getValidAnswer","response","filter","res","getAllUniqueCorrectness","validResponses","allCorrectness","forEach","answer1","valuesToParse","answer2","length","shift","index","finalAnswer","id","valid"],"mappings":";;;;;;;;;;;;;;;AAAA,IAAMA,iBAAiB,GAAG,SAApBA,iBAAoB,CAACC,OAAD,EAAUC,SAAV;AAAA,SACxBD,OAAO,CAACE,GAAR,CAAY,UAACC,MAAD;AAAA,2CACPA,MADO;AAEVC,MAAAA,SAAS,EAAE,CAACH,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,IAAoCJ,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,CAAiCC,MAArE,IAA+E,EAAhF,EAAoFC,QAApF,CAA6FJ,MAAM,CAACK,KAApG;AAFD;AAAA,GAAZ,CADwB;AAAA,CAA1B;;AAMA,IAAMC,cAAc,GAAG,SAAjBA,cAAiB,CAACN,MAAD,EAASO,QAAT;AAAA,SACrB,CAACA,QAAQ,CAACP,MAAM,CAACE,cAAR,CAAR,IAAmCK,QAAQ,CAACP,MAAM,CAACE,cAAR,CAAR,CAAgCC,MAAnE,IAA6E,EAA9E,EAAkFK,MAAlF,CAAyF,UAACC,GAAD;AAAA,WAASA,GAAG,KAAKT,MAAM,CAACK,KAAxB;AAAA,GAAzF,CADqB;AAAA,CAAvB;;AAGO,IAAMK,uBAAuB,GAAG,SAA1BA,uBAA0B,CAACb,OAAD,EAAUc,cAAV,EAA6B;AAClE,MAAIC,cAAc,GAAGhB,iBAAiB,CAACC,OAAD,EAAUc,cAAV,CAAtC;AAEAd,EAAAA,OAAO,CAACgB,OAAR,CAAgB,UAACC,OAAD,EAAa;AAC3B,QAAMC,aAAa,GAAGlB,OAAO,CAACW,MAAR,CACpB,UAACQ,OAAD;AAAA,aAAaA,OAAO,CAACX,KAAR,KAAkBS,OAAO,CAACT,KAA1B,IAAmCW,OAAO,CAACd,cAAR,KAA2BY,OAAO,CAACZ,cAAnF;AAAA,KADoB,CAAtB;;AAIA,QAAIa,aAAa,CAACE,MAAd,GAAuB,CAA3B,EAA8B;AAC5B;AACAF,MAAAA,aAAa,CAACG,KAAd,GAF4B,CAG5B;;AACAH,MAAAA,aAAa,CAACF,OAAd,CAAsB,UAACR,KAAD,EAAQc,KAAR,EAAkB;AACtCP,QAAAA,cAAc,GAAGA,cAAc,CAACb,GAAf,CAAmB,UAACqB,WAAD,EAAiB;AACnD,cAAIA,WAAW,CAACC,EAAZ,KAAmBhB,KAAK,CAACgB,EAA7B,EAAiC;AAC/B,gBAAIC,KAAK,GAAGhB,cAAc,CAACc,WAAD,EAAcT,cAAd,CAA1B;AACA,mDACKS,WADL;AAEEnB,cAAAA,SAAS,EAAEqB,KAAK,CAACL,MAAN,GAAeE,KAAK,GAAG;AAFpC;AAID;;AACD,iBAAOC,WAAP;AACD,SATgB,CAAjB;AAUD,OAXD;AAYD;AACF,GAtBD;AAuBA,SAAOR,cAAP;AACD,CA3BM","sourcesContent":["const getAllCorrectness = (answers, responses) =>\n answers.map((answer) => ({\n ...answer,\n isCorrect: (responses[answer.containerIndex] && responses[answer.containerIndex].images || []).includes(answer.value),\n }));\n\nconst getValidAnswer = (answer, response) =>\n (response[answer.containerIndex] && response[answer.containerIndex].images || []).filter((res) => res === answer.value);\n\nexport const getAllUniqueCorrectness = (answers, validResponses) => {\n let allCorrectness = getAllCorrectness(answers, validResponses);\n\n answers.forEach((answer1) => {\n const valuesToParse = answers.filter(\n (answer2) => answer2.value === answer1.value && answer2.containerIndex === answer1.containerIndex,\n );\n\n if (valuesToParse.length > 1) {\n // point only to duplicates but first\n valuesToParse.shift();\n // mark duplicates as incorrect\n valuesToParse.forEach((value, index) => {\n allCorrectness = allCorrectness.map((finalAnswer) => {\n if (finalAnswer.id === value.id) {\n let valid = getValidAnswer(finalAnswer, validResponses);\n return {\n ...finalAnswer,\n isCorrect: valid.length > index + 1,\n };\n }\n return finalAnswer;\n });\n });\n }\n });\n return allCorrectness;\n};\n"],"file":"utils.js"}
@@ -163,6 +163,58 @@ describe('controller', () => {
163
163
  expect(result.score).toEqual(1);
164
164
  });
165
165
 
166
+ it('returns correct score for valid response with empty response containers and partialScoring: false', async () => {
167
+ const result = await outcome({
168
+ ...question,
169
+ validation: {
170
+ valid_response: {
171
+ score: 1,
172
+ value: [
173
+ {
174
+ images: [rhomb, square],
175
+ },
176
+ {
177
+ images: [],
178
+ },
179
+ ],
180
+ },
181
+ }
182
+ }, {
183
+ answers: [
184
+ { value: rhomb, containerIndex: 0 },
185
+ { value: square, containerIndex: 0 },
186
+ ],
187
+ });
188
+
189
+ expect(result.score).toEqual(1);
190
+ });
191
+
192
+ it('returns correct score for valid response with empty response containers and partialScoring: true', async () => {
193
+ const result = await outcome({
194
+ ...question,
195
+ partialScoring: true,
196
+ validation: {
197
+ valid_response: {
198
+ score: 1,
199
+ value: [
200
+ {
201
+ images: [rhomb, square],
202
+ },
203
+ {
204
+ images: [],
205
+ },
206
+ ],
207
+ },
208
+ }
209
+ }, {
210
+ answers: [
211
+ { value: rhomb, containerIndex: 0 },
212
+ ],
213
+ });
214
+
215
+ expect(result.score).toEqual(0.5);
216
+ });
217
+
166
218
  describe('returns score 0 for wrong validation format', () => {
167
219
  it('returns 0 for old value format', async () => {
168
220
  const result = await outcome(
@@ -5,6 +5,7 @@ import { camelizeKeys } from 'humps';
5
5
  import { partialScoring } from '@pie-lib/controller-utils';
6
6
 
7
7
  import { getAllUniqueCorrectness } from './utils';
8
+ import { cloneDeep } from 'lodash';
8
9
 
9
10
  const log = debug('pie-elements:image-cloze-association:controller');
10
11
 
@@ -55,7 +56,7 @@ export const isResponseCorrect = (responses, session) => {
55
56
 
56
57
  if (session.answers && totalValidResponses === session.answers.length) {
57
58
  session.answers.forEach((answer) => {
58
- if (!(responses[answer.containerIndex].images || []).includes(answer.value)) {
59
+ if (!(responses[answer.containerIndex] && responses[answer.containerIndex].images || []).includes(answer.value)) {
59
60
  isCorrect = false;
60
61
  }
61
62
  });
@@ -65,15 +66,25 @@ export const isResponseCorrect = (responses, session) => {
65
66
  return isCorrect;
66
67
  };
67
68
 
69
+ // This applies for correct responses that have empty values
70
+ const keepNonEmptyResponses = (responses) => {
71
+ const filtered = responses.filter(response => response.images && response.images.length);
72
+ return cloneDeep(filtered);
73
+ };
74
+
68
75
  // This applies for items that don't support partial scoring.
69
76
  const isDefaultOrAltResponseCorrect = (question, session) => {
70
77
  const {
78
+ validation: { altResponses }
79
+ } = question;
80
+ let {
71
81
  validation: {
72
82
  validResponse: { value },
73
- altResponses,
74
- },
83
+ }
75
84
  } = question;
76
85
 
86
+ value = keepNonEmptyResponses(value);
87
+
77
88
  let isCorrect = isResponseCorrect(value, session);
78
89
 
79
90
  // Look for correct answers in alternate responses.
@@ -104,7 +115,6 @@ export const getPartialScore = (question, session) => {
104
115
  const {
105
116
  validation: { validResponse },
106
117
  maxResponsePerZone,
107
- responseContainers,
108
118
  } = question;
109
119
  let correctAnswers = 0;
110
120
  let possibleResponses = 0;
@@ -112,6 +122,7 @@ export const getPartialScore = (question, session) => {
112
122
  if (!session || isEmpty(session)) {
113
123
  return 0;
114
124
  }
125
+ validResponse.value = keepNonEmptyResponses(validResponse.value);
115
126
 
116
127
  validResponse.value.forEach((value) => (possibleResponses += (value.images || []).length));
117
128
 
@@ -139,7 +150,8 @@ export const getPartialScore = (question, session) => {
139
150
  // negative values will implicitly make the score equal to zero
140
151
  correctAnswers = correctAnswers < 0 ? 0 : correctAnswers;
141
152
 
142
- const denominator = maxResponsePerZone > 1 ? possibleResponses : responseContainers.length;
153
+ // use length of validResponse since some containers can be left empty
154
+ const denominator = maxResponsePerZone > 1 ? possibleResponses : (validResponse.value || []).length;
143
155
  const str = (correctAnswers / denominator).toFixed(2);
144
156
 
145
157
  return parseFloat(str);
@@ -1,11 +1,11 @@
1
1
  const getAllCorrectness = (answers, responses) =>
2
2
  answers.map((answer) => ({
3
3
  ...answer,
4
- isCorrect: (responses[answer.containerIndex].images || []).includes(answer.value),
4
+ isCorrect: (responses[answer.containerIndex] && responses[answer.containerIndex].images || []).includes(answer.value),
5
5
  }));
6
6
 
7
7
  const getValidAnswer = (answer, response) =>
8
- (response[answer.containerIndex].images || []).filter((res) => res === answer.value);
8
+ (response[answer.containerIndex] && response[answer.containerIndex].images || []).filter((res) => res === answer.value);
9
9
 
10
10
  export const getAllUniqueCorrectness = (answers, validResponses) => {
11
11
  let allCorrectness = getAllCorrectness(answers, validResponses);
@@ -99,15 +99,18 @@ InteractiveSection.defaultProps = {
99
99
  responseCorrect: undefined
100
100
  };
101
101
 
102
- var styles = function styles() {
102
+ var styles = function styles(theme) {
103
103
  return {
104
104
  interactiveDefault: {
105
+ marginTop: theme.spacing.unit * 2,
105
106
  border: "1px solid ".concat(_renderUi.color.disabled())
106
107
  },
107
108
  interactiveCorrect: {
109
+ marginTop: theme.spacing.unit * 2,
108
110
  border: "2px solid ".concat(_renderUi.color.correct())
109
111
  },
110
112
  interactiveIncorrect: {
113
+ marginTop: theme.spacing.unit * 2,
111
114
  border: "2px solid ".concat(_renderUi.color.incorrect())
112
115
  }
113
116
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/interactive-section.jsx"],"names":["InteractiveSection","props","classes","responseCorrect","styleProp","undefined","children","classname","getClassname","evaluationStyle","display","margin","marginTop","React","Component","propTypes","PropTypes","object","oneOfType","element","array","isRequired","bool","number","defaultProps","styles","interactiveDefault","border","color","disabled","interactiveCorrect","correct","interactiveIncorrect","incorrect"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;AAEA;;;;;;IAEMA,kB;;;;;;;;;;;;WACJ,wBAAe;AACb,wBAAqC,KAAKC,KAA1C;AAAA,UAAQC,OAAR,eAAQA,OAAR;AAAA,UAAiBC,eAAjB,eAAiBA,eAAjB;AACA,UAAIC,SAAJ;;AAEA,cAAQD,eAAR;AACE,aAAKE,SAAL;AACED,UAAAA,SAAS,GAAG,oBAAZ;AACA;;AACF,aAAK,IAAL;AACEA,UAAAA,SAAS,GAAG,oBAAZ;AACA;;AACF;AACEA,UAAAA,SAAS,GAAG,sBAAZ;AACA;AATJ;;AAWA,aAAOF,OAAO,CAACE,SAAD,CAAd;AACD;;;WAED,kBAAS;AACP,yBAAsC,KAAKH,KAA3C;AAAA,UAAQK,QAAR,gBAAQA,QAAR;AAAA,UAAkBH,eAAlB,gBAAkBA,eAAlB;AACA,UAAMI,SAAS,GAAG,KAAKC,YAAL,EAAlB;AACA,UAAMC,eAAe,GAAG;AACtBC,QAAAA,OAAO,EAAE,MADa;AAEtBC,QAAAA,MAAM,EAAE,QAFc;AAGtBC,QAAAA,SAAS,EAAE,CAAC;AAHU,OAAxB;AAMA,0BACE;AAAK,QAAA,SAAS,EAAEL;AAAhB,sBACE,gCAAC,0BAAD;AAAgB,QAAA,cAAc,EAAEE,eAAhC;AAAiD,QAAA,MAAM,MAAvD;AAAwD,QAAA,SAAS,EAAEN;AAAnE,QADF,EAEGG,QAFH,CADF;AAMD;;;EAlC8BO,kBAAMC,S;;AAqCvCd,kBAAkB,CAACe,SAAnB,GAA+B;AAC7Bb,EAAAA,OAAO,EAAEc,sBAAUC,MADU;AAE7BX,EAAAA,QAAQ,EAAEU,sBAAUE,SAAV,CAAoB,CAACF,sBAAUG,OAAX,EAAoBH,sBAAUI,KAA9B,CAApB,EAA0DC,UAFvC;AAG7BlB,EAAAA,eAAe,EAAEa,sBAAUE,SAAV,CAAoB,CAACF,sBAAUM,IAAX,EAAiBN,sBAAUO,MAA3B,CAApB;AAHY,CAA/B;AAMAvB,kBAAkB,CAACwB,YAAnB,GAAkC;AAChCtB,EAAAA,OAAO,EAAE,EADuB;AAEhCC,EAAAA,eAAe,EAAEE;AAFe,CAAlC;;AAKA,IAAMoB,MAAM,GAAG,SAATA,MAAS;AAAA,SAAO;AACpBC,IAAAA,kBAAkB,EAAE;AAClBC,MAAAA,MAAM,sBAAeC,gBAAMC,QAAN,EAAf;AADY,KADA;AAIpBC,IAAAA,kBAAkB,EAAE;AAClBH,MAAAA,MAAM,sBAAeC,gBAAMG,OAAN,EAAf;AADY,KAJA;AAOpBC,IAAAA,oBAAoB,EAAE;AACpBL,MAAAA,MAAM,sBAAeC,gBAAMK,SAAN,EAAf;AADc;AAPF,GAAP;AAAA,CAAf;;eAYe,sBAAWR,MAAX,EAAmBzB,kBAAnB,C","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { withStyles } from '@material-ui/core';\nimport { color } from '@pie-lib/render-ui';\n\nimport EvaluationIcon from './evaluation-icon';\n\nclass InteractiveSection extends React.Component {\n getClassname() {\n const { classes, responseCorrect } = this.props;\n let styleProp;\n\n switch (responseCorrect) {\n case undefined:\n styleProp = 'interactiveDefault';\n break;\n case true:\n styleProp = 'interactiveCorrect';\n break;\n default:\n styleProp = 'interactiveIncorrect';\n break;\n }\n return classes[styleProp];\n }\n\n render() {\n const { children, responseCorrect } = this.props;\n const classname = this.getClassname();\n const evaluationStyle = {\n display: 'flex',\n margin: '0 auto',\n marginTop: -14,\n };\n\n return (\n <div className={classname}>\n <EvaluationIcon containerStyle={evaluationStyle} filled isCorrect={responseCorrect} />\n {children}\n </div>\n );\n }\n}\n\nInteractiveSection.propTypes = {\n classes: PropTypes.object,\n children: PropTypes.oneOfType([PropTypes.element, PropTypes.array]).isRequired,\n responseCorrect: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),\n};\n\nInteractiveSection.defaultProps = {\n classes: {},\n responseCorrect: undefined,\n};\n\nconst styles = () => ({\n interactiveDefault: {\n border: `1px solid ${color.disabled()}`,\n },\n interactiveCorrect: {\n border: `2px solid ${color.correct()}`,\n },\n interactiveIncorrect: {\n border: `2px solid ${color.incorrect()}`,\n },\n});\n\nexport default withStyles(styles)(InteractiveSection);\n"],"file":"interactive-section.js"}
1
+ {"version":3,"sources":["../src/interactive-section.jsx"],"names":["InteractiveSection","props","classes","responseCorrect","styleProp","undefined","children","classname","getClassname","evaluationStyle","display","margin","marginTop","React","Component","propTypes","PropTypes","object","oneOfType","element","array","isRequired","bool","number","defaultProps","styles","theme","interactiveDefault","spacing","unit","border","color","disabled","interactiveCorrect","correct","interactiveIncorrect","incorrect"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;AAEA;;;;;;IAEMA,kB;;;;;;;;;;;;WACJ,wBAAe;AACb,wBAAqC,KAAKC,KAA1C;AAAA,UAAQC,OAAR,eAAQA,OAAR;AAAA,UAAiBC,eAAjB,eAAiBA,eAAjB;AACA,UAAIC,SAAJ;;AAEA,cAAQD,eAAR;AACE,aAAKE,SAAL;AACED,UAAAA,SAAS,GAAG,oBAAZ;AACA;;AACF,aAAK,IAAL;AACEA,UAAAA,SAAS,GAAG,oBAAZ;AACA;;AACF;AACEA,UAAAA,SAAS,GAAG,sBAAZ;AACA;AATJ;;AAWA,aAAOF,OAAO,CAACE,SAAD,CAAd;AACD;;;WAED,kBAAS;AACP,yBAAsC,KAAKH,KAA3C;AAAA,UAAQK,QAAR,gBAAQA,QAAR;AAAA,UAAkBH,eAAlB,gBAAkBA,eAAlB;AACA,UAAMI,SAAS,GAAG,KAAKC,YAAL,EAAlB;AACA,UAAMC,eAAe,GAAG;AACtBC,QAAAA,OAAO,EAAE,MADa;AAEtBC,QAAAA,MAAM,EAAE,QAFc;AAGtBC,QAAAA,SAAS,EAAE,CAAC;AAHU,OAAxB;AAMA,0BACE;AAAK,QAAA,SAAS,EAAEL;AAAhB,sBACE,gCAAC,0BAAD;AAAgB,QAAA,cAAc,EAAEE,eAAhC;AAAiD,QAAA,MAAM,MAAvD;AAAwD,QAAA,SAAS,EAAEN;AAAnE,QADF,EAEGG,QAFH,CADF;AAMD;;;EAlC8BO,kBAAMC,S;;AAqCvCd,kBAAkB,CAACe,SAAnB,GAA+B;AAC7Bb,EAAAA,OAAO,EAAEc,sBAAUC,MADU;AAE7BX,EAAAA,QAAQ,EAAEU,sBAAUE,SAAV,CAAoB,CAACF,sBAAUG,OAAX,EAAoBH,sBAAUI,KAA9B,CAApB,EAA0DC,UAFvC;AAG7BlB,EAAAA,eAAe,EAAEa,sBAAUE,SAAV,CAAoB,CAACF,sBAAUM,IAAX,EAAiBN,sBAAUO,MAA3B,CAApB;AAHY,CAA/B;AAMAvB,kBAAkB,CAACwB,YAAnB,GAAkC;AAChCtB,EAAAA,OAAO,EAAE,EADuB;AAEhCC,EAAAA,eAAe,EAAEE;AAFe,CAAlC;;AAKA,IAAMoB,MAAM,GAAG,SAATA,MAAS,CAACC,KAAD;AAAA,SAAY;AACzBC,IAAAA,kBAAkB,EAAE;AAClBf,MAAAA,SAAS,EAAEc,KAAK,CAACE,OAAN,CAAcC,IAAd,GAAqB,CADd;AAElBC,MAAAA,MAAM,sBAAeC,gBAAMC,QAAN,EAAf;AAFY,KADK;AAKzBC,IAAAA,kBAAkB,EAAE;AAClBrB,MAAAA,SAAS,EAAEc,KAAK,CAACE,OAAN,CAAcC,IAAd,GAAqB,CADd;AAElBC,MAAAA,MAAM,sBAAeC,gBAAMG,OAAN,EAAf;AAFY,KALK;AASzBC,IAAAA,oBAAoB,EAAE;AACpBvB,MAAAA,SAAS,EAAEc,KAAK,CAACE,OAAN,CAAcC,IAAd,GAAqB,CADZ;AAEpBC,MAAAA,MAAM,sBAAeC,gBAAMK,SAAN,EAAf;AAFc;AATG,GAAZ;AAAA,CAAf;;eAee,sBAAWX,MAAX,EAAmBzB,kBAAnB,C","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { withStyles } from '@material-ui/core';\nimport { color } from '@pie-lib/render-ui';\n\nimport EvaluationIcon from './evaluation-icon';\n\nclass InteractiveSection extends React.Component {\n getClassname() {\n const { classes, responseCorrect } = this.props;\n let styleProp;\n\n switch (responseCorrect) {\n case undefined:\n styleProp = 'interactiveDefault';\n break;\n case true:\n styleProp = 'interactiveCorrect';\n break;\n default:\n styleProp = 'interactiveIncorrect';\n break;\n }\n return classes[styleProp];\n }\n\n render() {\n const { children, responseCorrect } = this.props;\n const classname = this.getClassname();\n const evaluationStyle = {\n display: 'flex',\n margin: '0 auto',\n marginTop: -14,\n };\n\n return (\n <div className={classname}>\n <EvaluationIcon containerStyle={evaluationStyle} filled isCorrect={responseCorrect} />\n {children}\n </div>\n );\n }\n}\n\nInteractiveSection.propTypes = {\n classes: PropTypes.object,\n children: PropTypes.oneOfType([PropTypes.element, PropTypes.array]).isRequired,\n responseCorrect: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),\n};\n\nInteractiveSection.defaultProps = {\n classes: {},\n responseCorrect: undefined,\n};\n\nconst styles = (theme) => ({\n interactiveDefault: {\n marginTop: theme.spacing.unit * 2,\n border: `1px solid ${color.disabled()}`,\n },\n interactiveCorrect: {\n marginTop: theme.spacing.unit * 2,\n border: `2px solid ${color.correct()}`,\n },\n interactiveIncorrect: {\n marginTop: theme.spacing.unit * 2,\n border: `2px solid ${color.incorrect()}`,\n },\n});\n\nexport default withStyles(styles)(InteractiveSection);\n"],"file":"interactive-section.js"}
package/lib/root.js CHANGED
@@ -63,6 +63,14 @@ var generateId = function generateId() {
63
63
  return Math.random().toString(36).substring(2) + new Date().getTime().toString(36);
64
64
  };
65
65
 
66
+ var styles = function styles(theme) {
67
+ return {
68
+ teacherInstructions: {
69
+ marginBottom: theme.spacing.unit * 2
70
+ }
71
+ };
72
+ };
73
+
66
74
  var ImageClozeAssociationComponent = /*#__PURE__*/function (_React$Component) {
67
75
  (0, _inherits2["default"])(ImageClozeAssociationComponent, _React$Component);
68
76
 
@@ -254,17 +262,19 @@ var ImageClozeAssociationComponent = /*#__PURE__*/function (_React$Component) {
254
262
  (0, _createClass2["default"])(ImageClozeAssociationComponent, [{
255
263
  key: "render",
256
264
  value: function render() {
257
- var _this$props$model = this.props.model,
258
- disabled = _this$props$model.disabled,
259
- duplicateResponses = _this$props$model.duplicateResponses,
260
- image = _this$props$model.image,
261
- stimulus = _this$props$model.stimulus,
262
- responseCorrect = _this$props$model.responseCorrect,
263
- validation = _this$props$model.validation,
264
- teacherInstructions = _this$props$model.teacherInstructions,
265
- prompt = _this$props$model.prompt,
266
- showDashedBorder = _this$props$model.showDashedBorder,
267
- mode = _this$props$model.mode;
265
+ var _this$props3 = this.props,
266
+ classes = _this$props3.classes,
267
+ _this$props3$model = _this$props3.model,
268
+ disabled = _this$props3$model.disabled,
269
+ duplicateResponses = _this$props3$model.duplicateResponses,
270
+ image = _this$props3$model.image,
271
+ stimulus = _this$props3$model.stimulus,
272
+ responseCorrect = _this$props3$model.responseCorrect,
273
+ validation = _this$props3$model.validation,
274
+ teacherInstructions = _this$props3$model.teacherInstructions,
275
+ prompt = _this$props3$model.prompt,
276
+ showDashedBorder = _this$props3$model.showDashedBorder,
277
+ mode = _this$props3$model.mode;
268
278
  var _this$state3 = this.state,
269
279
  answers = _this$state3.answers,
270
280
  draggingElement = _this$state3.draggingElement,
@@ -299,17 +309,18 @@ var ImageClozeAssociationComponent = /*#__PURE__*/function (_React$Component) {
299
309
  answersToShow = [].concat((0, _toConsumableArray2["default"])(answersToShow), (0, _toConsumableArray2["default"])((0, _utilsCorrectness.getUnansweredAnswers)(answersToShow, validation)));
300
310
  }
301
311
 
302
- return /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement(_renderUi.PreviewPrompt, {
303
- className: "prompt",
304
- prompt: prompt
305
- }), teacherInstructions && /*#__PURE__*/_react["default"].createElement(_renderUi.Collapsible, {
312
+ return /*#__PURE__*/_react["default"].createElement("div", null, teacherInstructions && /*#__PURE__*/_react["default"].createElement(_renderUi.Collapsible, {
313
+ className: classes.teacherInstructions,
306
314
  labels: {
307
315
  hidden: 'Show Teacher Instructions',
308
316
  visible: 'Hide Teacher Instructions'
309
317
  }
310
318
  }, /*#__PURE__*/_react["default"].createElement(_renderUi.PreviewPrompt, {
311
319
  prompt: teacherInstructions
312
- })), /*#__PURE__*/_react["default"].createElement(_Typography["default"], null, /*#__PURE__*/_react["default"].createElement("span", {
320
+ })), /*#__PURE__*/_react["default"].createElement(_renderUi.PreviewPrompt, {
321
+ className: "prompt",
322
+ prompt: prompt
323
+ }), /*#__PURE__*/_react["default"].createElement(_Typography["default"], null, /*#__PURE__*/_react["default"].createElement("span", {
313
324
  dangerouslySetInnerHTML: {
314
325
  __html: stimulus
315
326
  }
@@ -317,7 +328,7 @@ var ImageClozeAssociationComponent = /*#__PURE__*/function (_React$Component) {
317
328
  show: showToggle,
318
329
  toggled: showCorrect,
319
330
  onToggle: this.toggleCorrect
320
- }), /*#__PURE__*/_react["default"].createElement("br", null), showCorrect && showToggle ? /*#__PURE__*/_react["default"].createElement(_interactiveSection["default"], {
331
+ }), showCorrect && showToggle ? /*#__PURE__*/_react["default"].createElement(_interactiveSection["default"], {
321
332
  responseCorrect: true
322
333
  }, /*#__PURE__*/_react["default"].createElement(_imageContainer["default"], {
323
334
  canDrag: false,
@@ -410,8 +421,9 @@ ImageClozeAssociationComponent.propTypes = {
410
421
  ImageClozeAssociationComponent.defaultProps = {
411
422
  classes: {}
412
423
  };
424
+ var StyledComponent = (0, _styles.withStyles)(styles)(ImageClozeAssociationComponent);
413
425
 
414
- var _default = (0, _drag.withDragContext)(ImageClozeAssociationComponent);
426
+ var _default = (0, _drag.withDragContext)(StyledComponent);
415
427
 
416
428
  exports["default"] = _default;
417
429
  //# sourceMappingURL=root.js.map
package/lib/root.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/root.jsx"],"names":["generateId","Math","random","toString","substring","Date","getTime","ImageClozeAssociationComponent","props","draggingElement","setState","id","value","answer","responseContainerIndex","duplicateResponses","model","updateAnswer","state","answers","possibleResponses","maxResponsePerZone","answersToStore","filter","a","containerIndex","length","answersInThisContainer","answersInOtherContainers","b","shiftedItem","shift","maxResponsePerZoneWarning","push","_","max","map","c","parseInt","isNaN","response","shouldNotPushInPossibleResponses","undefined","showCorrect","responseContainers","session","possibleResponsesWithIds","item","index","groupBy","grp","slice","flatMap","possibleResponsesFiltered","find","disabled","image","stimulus","responseCorrect","validation","teacherInstructions","prompt","showDashedBorder","mode","isEvaluateMode","showToggle","validResponse","correctAnswers","forEach","container","i","images","v","warningMessage","answersToShow","hidden","visible","__html","toggleCorrect","handleOnAnswerSelect","beginDrag","handleOnDragEnd","handleOnAnswerRemove","React","Component","WarningInfo","warning","margin","backgroundColor","padding","display","alignItems","width","height","message","paddingLeft","userSelect","classes","propTypes","PropTypes","string","object","isRequired","func","defaultProps"],"mappings":"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","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport Typography from '@material-ui/core/Typography';\nimport { withDragContext } from '@pie-lib/drag';\nimport { CSSTransition, TransitionGroup } from 'react-transition-group';\nimport { ShowRationale } from '@pie-lib/icons';\nimport { Collapsible, PreviewPrompt } from '@pie-lib/render-ui';\nimport { withStyles } from '@material-ui/core/styles';\nimport CorrectAnswerToggle from '@pie-lib/correct-answer-toggle';\n\nimport Image from './image-container';\nimport InteractiveSection from './interactive-section';\nimport PossibleResponses from './possible-responses';\nimport { getUnansweredAnswers, getAnswersCorrectness } from './utils-correctness';\nimport _ from 'lodash';\n\nconst generateId = () => Math.random().toString(36).substring(2) + new Date().getTime().toString(36);\n\nclass ImageClozeAssociationComponent extends React.Component {\n constructor(props) {\n super(props);\n const {\n model: { possibleResponses, responseContainers, duplicateResponses, maxResponsePerZone },\n session,\n } = props;\n let { answers } = session || {};\n // set id for each possible response\n const possibleResponsesWithIds = (possibleResponses || []).map((item, index) => ({\n value: item,\n id: `${index}`,\n }));\n\n answers = _(answers || [])\n .groupBy('containerIndex')\n // keep only last maxResponsePerZone answers for each zone\n .map((grp) => grp.slice(-(maxResponsePerZone || 1)))\n .flatMap()\n // set id for each answer\n .map((answer, index) => ({ ...answer, id: `${index}` }))\n // return only answer which have a valid container index\n .filter((answer) => answer.containerIndex < responseContainers.length)\n .value();\n\n const possibleResponsesFiltered = possibleResponsesWithIds.filter(\n (response) => !answers.find((answer) => answer.value === response.value),\n );\n this.state = {\n answers: answers || [],\n draggingElement: { id: '', value: '' },\n possibleResponses: duplicateResponses ? possibleResponsesWithIds : possibleResponsesFiltered,\n // set id for each response containers\n responseContainers: responseContainers.map((item, index) => ({\n index,\n ...item,\n id: `${index}`,\n })),\n maxResponsePerZone: maxResponsePerZone || 1,\n showCorrect: false,\n };\n }\n\n beginDrag = (draggingElement) => {\n this.setState({\n draggingElement,\n });\n };\n\n handleOnDragEnd = () => {\n this.setState({\n draggingElement: { id: '', value: '' },\n });\n };\n\n handleOnAnswerSelect = (answer, responseContainerIndex) => {\n const {\n model: { duplicateResponses },\n updateAnswer,\n } = this.props;\n const { answers, possibleResponses, maxResponsePerZone } = this.state;\n let answersToStore;\n\n if (maxResponsePerZone === answers.filter((a) => a.containerIndex === responseContainerIndex).length) {\n const answersInThisContainer = answers.filter((a) => a.containerIndex === responseContainerIndex);\n const answersInOtherContainers = answers.filter((b) => b.containerIndex !== responseContainerIndex);\n\n const shiftedItem = answersInThisContainer[0];\n if (maxResponsePerZone === 1) {\n answersInThisContainer.shift(); // FIFO\n } else {\n this.setState({ maxResponsePerZoneWarning: true });\n return;\n }\n\n // if duplicates are not allowed, make sure to put the shifted value back in possible responses\n if (!duplicateResponses) {\n possibleResponses.push({\n ...shiftedItem,\n containerIndex: '',\n id: `${_.max(possibleResponses.map((c) => parseInt(c.id)).filter((id) => !isNaN(id))) + 1}`,\n });\n }\n\n // answers will be:\n // + shifted answers for the current container\n // + if duplicatesAllowed, all the other answers from other containers\n // else: all the answers from other containers that are not having the same value\n // + new answer\n answersToStore = [\n ...answersInThisContainer, // shifted\n // TODO allow duplicates case Question: should we remove answer from a container if dragged to another container?\n // if yes, this should do it: add a.id !== answer.id instead of 'true'\n ...answersInOtherContainers.filter((a) => (duplicateResponses ? true : a.value !== answer.value)), // un-shifted\n {\n ...answer,\n containerIndex: responseContainerIndex,\n ...(duplicateResponses ? { id: generateId() } : {}),\n },\n ];\n } else {\n // answers will be:\n // + if duplicatesAllowed, all the other answers, except the one that was dragged\n // else: all the answers that are not having the same value\n // + new answer\n answersToStore = [\n // TODO allow duplicates case Question: should we remove answer from a container if dragged to another container?\n // if yes, this should do it: add a.id !== answer.id instead of 'true'\n ...answers.filter((a) => (duplicateResponses ? a.id !== answer.id : a.value !== answer.value)),\n {\n ...answer,\n containerIndex: responseContainerIndex,\n ...(duplicateResponses ? { id: generateId() } : {}),\n },\n ];\n }\n\n this.setState({\n maxResponsePerZoneWarning: false,\n answers: answersToStore,\n possibleResponses:\n // for single response per container remove answer from possible responses\n duplicateResponses\n ? possibleResponses\n : possibleResponses.filter((response) => response.value !== answer.value),\n });\n updateAnswer(answersToStore);\n };\n\n handleOnAnswerRemove = (answer) => {\n const {\n model: { duplicateResponses },\n updateAnswer,\n } = this.props;\n const { answers, possibleResponses } = this.state;\n const answersToStore = answers.filter((a) => a.id !== answer.id);\n const shouldNotPushInPossibleResponses = answer.containerIndex === undefined; // don't duplicate possible responses\n\n this.setState({\n maxResponsePerZoneWarning: false,\n answers: answersToStore,\n // push back into possible responses the removed answer if responses cannot be duplicated\n possibleResponses:\n duplicateResponses || shouldNotPushInPossibleResponses\n ? possibleResponses\n : [\n ...possibleResponses,\n {\n ...answer,\n containerIndex: undefined,\n },\n ],\n });\n updateAnswer(answersToStore);\n };\n\n toggleCorrect = (showCorrect) => this.setState({ showCorrect });\n\n render() {\n const {\n model: {\n disabled,\n duplicateResponses,\n image,\n stimulus,\n responseCorrect,\n validation,\n teacherInstructions,\n prompt,\n showDashedBorder,\n mode,\n },\n } = this.props;\n const {\n answers,\n draggingElement,\n possibleResponses,\n responseContainers,\n maxResponsePerZone,\n maxResponsePerZoneWarning,\n showCorrect,\n } = this.state;\n const isEvaluateMode = mode === 'evaluate';\n const showToggle = isEvaluateMode && !responseCorrect;\n\n const { validResponse } = validation || {};\n const correctAnswers = [];\n\n if (validResponse) {\n (validResponse.value || []).forEach((container, i) => {\n (container.images || []).forEach((v) => {\n correctAnswers.push({\n value: v,\n containerIndex: i,\n });\n });\n });\n }\n\n const warningMessage =\n `You’ve reached the limit of ${maxResponsePerZone} responses per area.` +\n 'To add another response, one must first be removed.';\n\n let answersToShow =\n responseCorrect !== undefined ? getAnswersCorrectness(answers, validation, duplicateResponses) : answers;\n\n if (responseCorrect === false && maxResponsePerZone === 1) {\n answersToShow = [...answersToShow, ...getUnansweredAnswers(answersToShow, validation)];\n }\n\n return (\n <div>\n <PreviewPrompt className=\"prompt\" prompt={prompt} />\n\n {teacherInstructions && (\n <Collapsible\n labels={{\n hidden: 'Show Teacher Instructions',\n visible: 'Hide Teacher Instructions',\n }}\n >\n <PreviewPrompt prompt={teacherInstructions} />\n </Collapsible>\n )}\n\n <Typography>\n <span dangerouslySetInnerHTML={{ __html: stimulus }} />\n </Typography>\n\n <CorrectAnswerToggle show={showToggle} toggled={showCorrect} onToggle={this.toggleCorrect} />\n <br />\n\n {showCorrect && showToggle ? (\n <InteractiveSection responseCorrect={true}>\n <Image\n canDrag={false}\n answers={correctAnswers}\n draggingElement={draggingElement}\n duplicateResponses={duplicateResponses}\n image={image}\n onAnswerSelect={this.handleOnAnswerSelect}\n onDragAnswerBegin={this.beginDrag}\n onDragAnswerEnd={this.handleOnDragEnd}\n responseContainers={responseContainers}\n showDashedBorder={showDashedBorder}\n />\n </InteractiveSection>\n ) : (\n <InteractiveSection responseCorrect={responseCorrect}>\n <Image\n canDrag={!disabled}\n answers={answersToShow}\n draggingElement={draggingElement}\n duplicateResponses={duplicateResponses}\n image={image}\n onAnswerSelect={this.handleOnAnswerSelect}\n onDragAnswerBegin={this.beginDrag}\n onDragAnswerEnd={this.handleOnDragEnd}\n responseContainers={responseContainers}\n showDashedBorder={showDashedBorder}\n />\n\n {maxResponsePerZoneWarning && <WarningInfo message={warningMessage} />}\n\n <PossibleResponses\n canDrag={!disabled}\n data={possibleResponses}\n onAnswerRemove={this.handleOnAnswerRemove}\n onDragBegin={this.beginDrag}\n onDragEnd={this.handleOnDragEnd}\n />\n </InteractiveSection>\n )}\n </div>\n );\n }\n}\n\nconst WarningInfo = withStyles({\n warning: {\n margin: '0 16px',\n backgroundColor: '#dddddd',\n padding: '10px',\n display: 'flex',\n alignItems: 'center',\n width: 'fit-content',\n '& svg': {\n height: '30px',\n },\n '& h1': {\n padding: '0px',\n margin: '0px',\n },\n },\n message: {\n paddingLeft: '5px',\n userSelect: 'none',\n },\n})(({ classes, message }) => (\n <TransitionGroup>\n <CSSTransition classNames={'fb'} key=\"fb\" timeout={300}>\n <div key=\"panel\" className={classes.warning}>\n <ShowRationale iconSet=\"emoji\" shape=\"square\" />\n <span className={classes.message} dangerouslySetInnerHTML={{ __html: message }} />\n </div>\n </CSSTransition>\n </TransitionGroup>\n));\n\nWarningInfo.propTypes = {\n message: PropTypes.string,\n classes: PropTypes.object.isRequired,\n};\n\nImageClozeAssociationComponent.propTypes = {\n classes: PropTypes.object,\n model: PropTypes.object.isRequired,\n session: PropTypes.object,\n updateAnswer: PropTypes.func.isRequired,\n};\n\nImageClozeAssociationComponent.defaultProps = {\n classes: {},\n};\n\nexport default withDragContext(ImageClozeAssociationComponent);\n"],"file":"root.js"}
1
+ {"version":3,"sources":["../src/root.jsx"],"names":["generateId","Math","random","toString","substring","Date","getTime","styles","theme","teacherInstructions","marginBottom","spacing","unit","ImageClozeAssociationComponent","props","draggingElement","setState","id","value","answer","responseContainerIndex","duplicateResponses","model","updateAnswer","state","answers","possibleResponses","maxResponsePerZone","answersToStore","filter","a","containerIndex","length","answersInThisContainer","answersInOtherContainers","b","shiftedItem","shift","maxResponsePerZoneWarning","push","_","max","map","c","parseInt","isNaN","response","shouldNotPushInPossibleResponses","undefined","showCorrect","responseContainers","session","possibleResponsesWithIds","item","index","groupBy","grp","slice","flatMap","possibleResponsesFiltered","find","classes","disabled","image","stimulus","responseCorrect","validation","prompt","showDashedBorder","mode","isEvaluateMode","showToggle","validResponse","correctAnswers","forEach","container","i","images","v","warningMessage","answersToShow","hidden","visible","__html","toggleCorrect","handleOnAnswerSelect","beginDrag","handleOnDragEnd","handleOnAnswerRemove","React","Component","WarningInfo","warning","margin","backgroundColor","padding","display","alignItems","width","height","message","paddingLeft","userSelect","propTypes","PropTypes","string","object","isRequired","func","defaultProps","StyledComponent"],"mappings":"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","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport Typography from '@material-ui/core/Typography';\nimport { withDragContext } from '@pie-lib/drag';\nimport { CSSTransition, TransitionGroup } from 'react-transition-group';\nimport { ShowRationale } from '@pie-lib/icons';\nimport { Collapsible, PreviewPrompt } from '@pie-lib/render-ui';\nimport { withStyles } from '@material-ui/core/styles';\nimport CorrectAnswerToggle from '@pie-lib/correct-answer-toggle';\n\nimport Image from './image-container';\nimport InteractiveSection from './interactive-section';\nimport PossibleResponses from './possible-responses';\nimport { getUnansweredAnswers, getAnswersCorrectness } from './utils-correctness';\nimport _ from 'lodash';\n\nconst generateId = () => Math.random().toString(36).substring(2) + new Date().getTime().toString(36);\n\nconst styles = (theme) => ({\n teacherInstructions: {\n marginBottom: theme.spacing.unit * 2,\n },\n});\n\nclass ImageClozeAssociationComponent extends React.Component {\n constructor(props) {\n super(props);\n const {\n model: { possibleResponses, responseContainers, duplicateResponses, maxResponsePerZone },\n session,\n } = props;\n let { answers } = session || {};\n // set id for each possible response\n const possibleResponsesWithIds = (possibleResponses || []).map((item, index) => ({\n value: item,\n id: `${index}`,\n }));\n\n answers = _(answers || [])\n .groupBy('containerIndex')\n // keep only last maxResponsePerZone answers for each zone\n .map((grp) => grp.slice(-(maxResponsePerZone || 1)))\n .flatMap()\n // set id for each answer\n .map((answer, index) => ({ ...answer, id: `${index}` }))\n // return only answer which have a valid container index\n .filter((answer) => answer.containerIndex < responseContainers.length)\n .value();\n\n const possibleResponsesFiltered = possibleResponsesWithIds.filter(\n (response) => !answers.find((answer) => answer.value === response.value),\n );\n this.state = {\n answers: answers || [],\n draggingElement: { id: '', value: '' },\n possibleResponses: duplicateResponses ? possibleResponsesWithIds : possibleResponsesFiltered,\n // set id for each response containers\n responseContainers: responseContainers.map((item, index) => ({\n index,\n ...item,\n id: `${index}`,\n })),\n maxResponsePerZone: maxResponsePerZone || 1,\n showCorrect: false,\n };\n }\n\n beginDrag = (draggingElement) => {\n this.setState({\n draggingElement,\n });\n };\n\n handleOnDragEnd = () => {\n this.setState({\n draggingElement: { id: '', value: '' },\n });\n };\n\n handleOnAnswerSelect = (answer, responseContainerIndex) => {\n const {\n model: { duplicateResponses },\n updateAnswer,\n } = this.props;\n const { answers, possibleResponses, maxResponsePerZone } = this.state;\n let answersToStore;\n\n if (maxResponsePerZone === answers.filter((a) => a.containerIndex === responseContainerIndex).length) {\n const answersInThisContainer = answers.filter((a) => a.containerIndex === responseContainerIndex);\n const answersInOtherContainers = answers.filter((b) => b.containerIndex !== responseContainerIndex);\n\n const shiftedItem = answersInThisContainer[0];\n if (maxResponsePerZone === 1) {\n answersInThisContainer.shift(); // FIFO\n } else {\n this.setState({ maxResponsePerZoneWarning: true });\n return;\n }\n\n // if duplicates are not allowed, make sure to put the shifted value back in possible responses\n if (!duplicateResponses) {\n possibleResponses.push({\n ...shiftedItem,\n containerIndex: '',\n id: `${_.max(possibleResponses.map((c) => parseInt(c.id)).filter((id) => !isNaN(id))) + 1}`,\n });\n }\n\n // answers will be:\n // + shifted answers for the current container\n // + if duplicatesAllowed, all the other answers from other containers\n // else: all the answers from other containers that are not having the same value\n // + new answer\n answersToStore = [\n ...answersInThisContainer, // shifted\n // TODO allow duplicates case Question: should we remove answer from a container if dragged to another container?\n // if yes, this should do it: add a.id !== answer.id instead of 'true'\n ...answersInOtherContainers.filter((a) => (duplicateResponses ? true : a.value !== answer.value)), // un-shifted\n {\n ...answer,\n containerIndex: responseContainerIndex,\n ...(duplicateResponses ? { id: generateId() } : {}),\n },\n ];\n } else {\n // answers will be:\n // + if duplicatesAllowed, all the other answers, except the one that was dragged\n // else: all the answers that are not having the same value\n // + new answer\n answersToStore = [\n // TODO allow duplicates case Question: should we remove answer from a container if dragged to another container?\n // if yes, this should do it: add a.id !== answer.id instead of 'true'\n ...answers.filter((a) => (duplicateResponses ? a.id !== answer.id : a.value !== answer.value)),\n {\n ...answer,\n containerIndex: responseContainerIndex,\n ...(duplicateResponses ? { id: generateId() } : {}),\n },\n ];\n }\n\n this.setState({\n maxResponsePerZoneWarning: false,\n answers: answersToStore,\n possibleResponses:\n // for single response per container remove answer from possible responses\n duplicateResponses\n ? possibleResponses\n : possibleResponses.filter((response) => response.value !== answer.value),\n });\n updateAnswer(answersToStore);\n };\n\n handleOnAnswerRemove = (answer) => {\n const {\n model: { duplicateResponses },\n updateAnswer,\n } = this.props;\n const { answers, possibleResponses } = this.state;\n const answersToStore = answers.filter((a) => a.id !== answer.id);\n const shouldNotPushInPossibleResponses = answer.containerIndex === undefined; // don't duplicate possible responses\n\n this.setState({\n maxResponsePerZoneWarning: false,\n answers: answersToStore,\n // push back into possible responses the removed answer if responses cannot be duplicated\n possibleResponses:\n duplicateResponses || shouldNotPushInPossibleResponses\n ? possibleResponses\n : [\n ...possibleResponses,\n {\n ...answer,\n containerIndex: undefined,\n },\n ],\n });\n updateAnswer(answersToStore);\n };\n\n toggleCorrect = (showCorrect) => this.setState({ showCorrect });\n\n render() {\n const {\n classes,\n model: {\n disabled,\n duplicateResponses,\n image,\n stimulus,\n responseCorrect,\n validation,\n teacherInstructions,\n prompt,\n showDashedBorder,\n mode,\n },\n } = this.props;\n const {\n answers,\n draggingElement,\n possibleResponses,\n responseContainers,\n maxResponsePerZone,\n maxResponsePerZoneWarning,\n showCorrect,\n } = this.state;\n const isEvaluateMode = mode === 'evaluate';\n const showToggle = isEvaluateMode && !responseCorrect;\n\n const { validResponse } = validation || {};\n const correctAnswers = [];\n\n if (validResponse) {\n (validResponse.value || []).forEach((container, i) => {\n (container.images || []).forEach((v) => {\n correctAnswers.push({\n value: v,\n containerIndex: i,\n });\n });\n });\n }\n\n const warningMessage =\n `You’ve reached the limit of ${maxResponsePerZone} responses per area.` +\n 'To add another response, one must first be removed.';\n\n let answersToShow =\n responseCorrect !== undefined ? getAnswersCorrectness(answers, validation, duplicateResponses) : answers;\n\n if (responseCorrect === false && maxResponsePerZone === 1) {\n answersToShow = [...answersToShow, ...getUnansweredAnswers(answersToShow, validation)];\n }\n\n return (\n <div>\n {teacherInstructions && (\n <Collapsible\n className={classes.teacherInstructions}\n labels={{\n hidden: 'Show Teacher Instructions',\n visible: 'Hide Teacher Instructions',\n }}\n >\n <PreviewPrompt prompt={teacherInstructions} />\n </Collapsible>\n )}\n\n <PreviewPrompt className=\"prompt\" prompt={prompt} />\n\n <Typography>\n <span dangerouslySetInnerHTML={{ __html: stimulus }} />\n </Typography>\n\n <CorrectAnswerToggle show={showToggle} toggled={showCorrect} onToggle={this.toggleCorrect} />\n\n {showCorrect && showToggle ? (\n <InteractiveSection responseCorrect={true}>\n <Image\n canDrag={false}\n answers={correctAnswers}\n draggingElement={draggingElement}\n duplicateResponses={duplicateResponses}\n image={image}\n onAnswerSelect={this.handleOnAnswerSelect}\n onDragAnswerBegin={this.beginDrag}\n onDragAnswerEnd={this.handleOnDragEnd}\n responseContainers={responseContainers}\n showDashedBorder={showDashedBorder}\n />\n </InteractiveSection>\n ) : (\n <InteractiveSection responseCorrect={responseCorrect}>\n <Image\n canDrag={!disabled}\n answers={answersToShow}\n draggingElement={draggingElement}\n duplicateResponses={duplicateResponses}\n image={image}\n onAnswerSelect={this.handleOnAnswerSelect}\n onDragAnswerBegin={this.beginDrag}\n onDragAnswerEnd={this.handleOnDragEnd}\n responseContainers={responseContainers}\n showDashedBorder={showDashedBorder}\n />\n\n {maxResponsePerZoneWarning && <WarningInfo message={warningMessage} />}\n\n <PossibleResponses\n canDrag={!disabled}\n data={possibleResponses}\n onAnswerRemove={this.handleOnAnswerRemove}\n onDragBegin={this.beginDrag}\n onDragEnd={this.handleOnDragEnd}\n />\n </InteractiveSection>\n )}\n </div>\n );\n }\n}\n\nconst WarningInfo = withStyles({\n warning: {\n margin: '0 16px',\n backgroundColor: '#dddddd',\n padding: '10px',\n display: 'flex',\n alignItems: 'center',\n width: 'fit-content',\n '& svg': {\n height: '30px',\n },\n '& h1': {\n padding: '0px',\n margin: '0px',\n },\n },\n message: {\n paddingLeft: '5px',\n userSelect: 'none',\n },\n})(({ classes, message }) => (\n <TransitionGroup>\n <CSSTransition classNames={'fb'} key=\"fb\" timeout={300}>\n <div key=\"panel\" className={classes.warning}>\n <ShowRationale iconSet=\"emoji\" shape=\"square\" />\n <span className={classes.message} dangerouslySetInnerHTML={{ __html: message }} />\n </div>\n </CSSTransition>\n </TransitionGroup>\n));\n\nWarningInfo.propTypes = {\n message: PropTypes.string,\n classes: PropTypes.object.isRequired,\n};\n\nImageClozeAssociationComponent.propTypes = {\n classes: PropTypes.object,\n model: PropTypes.object.isRequired,\n session: PropTypes.object,\n updateAnswer: PropTypes.func.isRequired,\n};\n\nImageClozeAssociationComponent.defaultProps = {\n classes: {},\n};\n\nconst StyledComponent = withStyles(styles)(ImageClozeAssociationComponent);\n\nexport default withDragContext(StyledComponent);\n"],"file":"root.js"}
@@ -18,7 +18,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
18
18
  var getAllCorrectAnswers = function getAllCorrectAnswers(answers, responses) {
19
19
  return answers.map(function (answer) {
20
20
  return _objectSpread(_objectSpread({}, answer), {}, {
21
- isCorrect: (responses[answer.containerIndex].images || []).includes(answer.value)
21
+ isCorrect: (responses[answer.containerIndex] && responses[answer.containerIndex].images || []).includes(answer.value)
22
22
  });
23
23
  });
24
24
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils-correctness.js"],"names":["getAllCorrectAnswers","answers","responses","map","answer","isCorrect","containerIndex","images","includes","value","getValidAnswer","response","filter","res","getUniqueCorrectAnswers","validResponses","finalAnswers","forEach","answer1","valuesToParse","answer2","length","shift","index","finalAnswer","id","valid","getUnansweredAnswers","validation","validResponse","unansweredAnswers","reduce","unanswered","isAnswered","find","hidden","getAnswersCorrectness","altResponses","allCorrect","uniqueAnswers","noOfCorrect","altUniqueStack","altResponse","altValue","altAllCorrect","sort","a","b","c"],"mappings":"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","sourcesContent":["const getAllCorrectAnswers = (answers, responses) =>\n answers.map((answer) => ({\n ...answer,\n isCorrect: (responses[answer.containerIndex].images || []).includes(answer.value),\n }));\n\nconst getValidAnswer = (answer, response) =>\n (response[answer.containerIndex].images || []).filter((res) => res === answer.value);\n\nconst getUniqueCorrectAnswers = (answers, validResponses) => {\n let finalAnswers = answers;\n\n answers.forEach((answer1) => {\n const valuesToParse = answers.filter(\n (answer2) => answer2.value === answer1.value && answer2.containerIndex === answer1.containerIndex,\n );\n\n if (valuesToParse.length > 1) {\n // point only to duplicates but first\n valuesToParse.shift();\n // mark duplicates as incorrect\n valuesToParse.forEach((value, index) => {\n finalAnswers = finalAnswers.map((finalAnswer) => {\n if (finalAnswer.id === value.id) {\n let valid = getValidAnswer(finalAnswer, validResponses);\n\n return {\n ...finalAnswer,\n isCorrect: valid.length > index + 1,\n };\n }\n return finalAnswer;\n });\n });\n }\n });\n return finalAnswers;\n};\n\nexport const getUnansweredAnswers = (answers, validation) => {\n const { validResponse: { value } = {} } = validation;\n\n const unansweredAnswers = (value || []).reduce((unanswered, response, index) => {\n const isAnswered = !!answers.find((answer) => answer.containerIndex === index);\n\n if (!isAnswered) {\n return [\n ...unanswered,\n {\n id: `unanswered-${index}`,\n value: response.images[0] || '',\n containerIndex: index,\n isCorrect: false,\n hidden: true,\n },\n ];\n }\n\n return unanswered;\n }, []);\n\n return unansweredAnswers;\n};\n\nexport const getAnswersCorrectness = (answers, validation) => {\n const {\n validResponse: { value },\n altResponses,\n } = validation;\n\n const allCorrect = getAllCorrectAnswers(answers, value);\n const uniqueAnswers = getUniqueCorrectAnswers(allCorrect, value);\n const noOfCorrect = uniqueAnswers.filter((answer) => answer.isCorrect).length;\n\n // Look for alternate correct responses if there are incorrect responses.\n if (noOfCorrect < uniqueAnswers.length && altResponses && altResponses.length) {\n const altUniqueStack = altResponses.map((altResponse) => {\n const altValue = altResponse.value;\n\n const altAllCorrect = getAllCorrectAnswers(answers, altValue);\n return getUniqueCorrectAnswers(altAllCorrect, altValue);\n });\n // Return the one with most correct answers.\n return altUniqueStack.sort((a, b) => b.filter((c) => c.isCorrect).length - a.filter((c) => c.isCorrect).length)[0];\n }\n return uniqueAnswers;\n};\n"],"file":"utils-correctness.js"}
1
+ {"version":3,"sources":["../src/utils-correctness.js"],"names":["getAllCorrectAnswers","answers","responses","map","answer","isCorrect","containerIndex","images","includes","value","getValidAnswer","response","filter","res","getUniqueCorrectAnswers","validResponses","finalAnswers","forEach","answer1","valuesToParse","answer2","length","shift","index","finalAnswer","id","valid","getUnansweredAnswers","validation","validResponse","unansweredAnswers","reduce","unanswered","isAnswered","find","hidden","getAnswersCorrectness","altResponses","allCorrect","uniqueAnswers","noOfCorrect","altUniqueStack","altResponse","altValue","altAllCorrect","sort","a","b","c"],"mappings":";;;;;;;;;;;;;;;;;AAAA,IAAMA,oBAAoB,GAAG,SAAvBA,oBAAuB,CAACC,OAAD,EAAUC,SAAV;AAAA,SAC3BD,OAAO,CAACE,GAAR,CAAY,UAACC,MAAD;AAAA,2CACPA,MADO;AAEVC,MAAAA,SAAS,EAAE,CAACH,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,IAAoCJ,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,CAAiCC,MAArE,IAA+E,EAAhF,EAAoFC,QAApF,CAA6FJ,MAAM,CAACK,KAApG;AAFD;AAAA,GAAZ,CAD2B;AAAA,CAA7B;;AAMA,IAAMC,cAAc,GAAG,SAAjBA,cAAiB,CAACN,MAAD,EAASO,QAAT;AAAA,SACrB,CAACA,QAAQ,CAACP,MAAM,CAACE,cAAR,CAAR,CAAgCC,MAAhC,IAA0C,EAA3C,EAA+CK,MAA/C,CAAsD,UAACC,GAAD;AAAA,WAASA,GAAG,KAAKT,MAAM,CAACK,KAAxB;AAAA,GAAtD,CADqB;AAAA,CAAvB;;AAGA,IAAMK,uBAAuB,GAAG,SAA1BA,uBAA0B,CAACb,OAAD,EAAUc,cAAV,EAA6B;AAC3D,MAAIC,YAAY,GAAGf,OAAnB;AAEAA,EAAAA,OAAO,CAACgB,OAAR,CAAgB,UAACC,OAAD,EAAa;AAC3B,QAAMC,aAAa,GAAGlB,OAAO,CAACW,MAAR,CACpB,UAACQ,OAAD;AAAA,aAAaA,OAAO,CAACX,KAAR,KAAkBS,OAAO,CAACT,KAA1B,IAAmCW,OAAO,CAACd,cAAR,KAA2BY,OAAO,CAACZ,cAAnF;AAAA,KADoB,CAAtB;;AAIA,QAAIa,aAAa,CAACE,MAAd,GAAuB,CAA3B,EAA8B;AAC5B;AACAF,MAAAA,aAAa,CAACG,KAAd,GAF4B,CAG5B;;AACAH,MAAAA,aAAa,CAACF,OAAd,CAAsB,UAACR,KAAD,EAAQc,KAAR,EAAkB;AACtCP,QAAAA,YAAY,GAAGA,YAAY,CAACb,GAAb,CAAiB,UAACqB,WAAD,EAAiB;AAC/C,cAAIA,WAAW,CAACC,EAAZ,KAAmBhB,KAAK,CAACgB,EAA7B,EAAiC;AAC/B,gBAAIC,KAAK,GAAGhB,cAAc,CAACc,WAAD,EAAcT,cAAd,CAA1B;AAEA,mDACKS,WADL;AAEEnB,cAAAA,SAAS,EAAEqB,KAAK,CAACL,MAAN,GAAeE,KAAK,GAAG;AAFpC;AAID;;AACD,iBAAOC,WAAP;AACD,SAVc,CAAf;AAWD,OAZD;AAaD;AACF,GAvBD;AAwBA,SAAOR,YAAP;AACD,CA5BD;;AA8BO,IAAMW,oBAAoB,GAAG,SAAvBA,oBAAuB,CAAC1B,OAAD,EAAU2B,UAAV,EAAyB;AAC3D,8BAA0CA,UAA1C,CAAQC,aAAR;AAAA,6DAAmC,EAAnC;AAAA,MAAyBpB,KAAzB,yBAAyBA,KAAzB;AAEA,MAAMqB,iBAAiB,GAAG,CAACrB,KAAK,IAAI,EAAV,EAAcsB,MAAd,CAAqB,UAACC,UAAD,EAAarB,QAAb,EAAuBY,KAAvB,EAAiC;AAC9E,QAAMU,UAAU,GAAG,CAAC,CAAChC,OAAO,CAACiC,IAAR,CAAa,UAAC9B,MAAD;AAAA,aAAYA,MAAM,CAACE,cAAP,KAA0BiB,KAAtC;AAAA,KAAb,CAArB;;AAEA,QAAI,CAACU,UAAL,EAAiB;AACf,2DACKD,UADL,IAEE;AACEP,QAAAA,EAAE,uBAAgBF,KAAhB,CADJ;AAEEd,QAAAA,KAAK,EAAEE,QAAQ,CAACJ,MAAT,CAAgB,CAAhB,KAAsB,EAF/B;AAGED,QAAAA,cAAc,EAAEiB,KAHlB;AAIElB,QAAAA,SAAS,EAAE,KAJb;AAKE8B,QAAAA,MAAM,EAAE;AALV,OAFF;AAUD;;AAED,WAAOH,UAAP;AACD,GAjByB,EAiBvB,EAjBuB,CAA1B;AAmBA,SAAOF,iBAAP;AACD,CAvBM;;;;AAyBA,IAAMM,qBAAqB,GAAG,SAAxBA,qBAAwB,CAACnC,OAAD,EAAU2B,UAAV,EAAyB;AAC5D,MACmBnB,KADnB,GAGImB,UAHJ,CACEC,aADF,CACmBpB,KADnB;AAAA,MAEE4B,YAFF,GAGIT,UAHJ,CAEES,YAFF;AAKA,MAAMC,UAAU,GAAGtC,oBAAoB,CAACC,OAAD,EAAUQ,KAAV,CAAvC;AACA,MAAM8B,aAAa,GAAGzB,uBAAuB,CAACwB,UAAD,EAAa7B,KAAb,CAA7C;AACA,MAAM+B,WAAW,GAAGD,aAAa,CAAC3B,MAAd,CAAqB,UAACR,MAAD;AAAA,WAAYA,MAAM,CAACC,SAAnB;AAAA,GAArB,EAAmDgB,MAAvE,CAR4D,CAU5D;;AACA,MAAImB,WAAW,GAAGD,aAAa,CAAClB,MAA5B,IAAsCgB,YAAtC,IAAsDA,YAAY,CAAChB,MAAvE,EAA+E;AAC7E,QAAMoB,cAAc,GAAGJ,YAAY,CAAClC,GAAb,CAAiB,UAACuC,WAAD,EAAiB;AACvD,UAAMC,QAAQ,GAAGD,WAAW,CAACjC,KAA7B;AAEA,UAAMmC,aAAa,GAAG5C,oBAAoB,CAACC,OAAD,EAAU0C,QAAV,CAA1C;AACA,aAAO7B,uBAAuB,CAAC8B,aAAD,EAAgBD,QAAhB,CAA9B;AACD,KALsB,CAAvB,CAD6E,CAO7E;;AACA,WAAOF,cAAc,CAACI,IAAf,CAAoB,UAACC,CAAD,EAAIC,CAAJ;AAAA,aAAUA,CAAC,CAACnC,MAAF,CAAS,UAACoC,CAAD;AAAA,eAAOA,CAAC,CAAC3C,SAAT;AAAA,OAAT,EAA6BgB,MAA7B,GAAsCyB,CAAC,CAAClC,MAAF,CAAS,UAACoC,CAAD;AAAA,eAAOA,CAAC,CAAC3C,SAAT;AAAA,OAAT,EAA6BgB,MAA7E;AAAA,KAApB,EAAyG,CAAzG,CAAP;AACD;;AACD,SAAOkB,aAAP;AACD,CAtBM","sourcesContent":["const getAllCorrectAnswers = (answers, responses) =>\n answers.map((answer) => ({\n ...answer,\n isCorrect: (responses[answer.containerIndex] && responses[answer.containerIndex].images || []).includes(answer.value),\n }));\n\nconst getValidAnswer = (answer, response) =>\n (response[answer.containerIndex].images || []).filter((res) => res === answer.value);\n\nconst getUniqueCorrectAnswers = (answers, validResponses) => {\n let finalAnswers = answers;\n\n answers.forEach((answer1) => {\n const valuesToParse = answers.filter(\n (answer2) => answer2.value === answer1.value && answer2.containerIndex === answer1.containerIndex,\n );\n\n if (valuesToParse.length > 1) {\n // point only to duplicates but first\n valuesToParse.shift();\n // mark duplicates as incorrect\n valuesToParse.forEach((value, index) => {\n finalAnswers = finalAnswers.map((finalAnswer) => {\n if (finalAnswer.id === value.id) {\n let valid = getValidAnswer(finalAnswer, validResponses);\n\n return {\n ...finalAnswer,\n isCorrect: valid.length > index + 1,\n };\n }\n return finalAnswer;\n });\n });\n }\n });\n return finalAnswers;\n};\n\nexport const getUnansweredAnswers = (answers, validation) => {\n const { validResponse: { value } = {} } = validation;\n\n const unansweredAnswers = (value || []).reduce((unanswered, response, index) => {\n const isAnswered = !!answers.find((answer) => answer.containerIndex === index);\n\n if (!isAnswered) {\n return [\n ...unanswered,\n {\n id: `unanswered-${index}`,\n value: response.images[0] || '',\n containerIndex: index,\n isCorrect: false,\n hidden: true,\n },\n ];\n }\n\n return unanswered;\n }, []);\n\n return unansweredAnswers;\n};\n\nexport const getAnswersCorrectness = (answers, validation) => {\n const {\n validResponse: { value },\n altResponses,\n } = validation;\n\n const allCorrect = getAllCorrectAnswers(answers, value);\n const uniqueAnswers = getUniqueCorrectAnswers(allCorrect, value);\n const noOfCorrect = uniqueAnswers.filter((answer) => answer.isCorrect).length;\n\n // Look for alternate correct responses if there are incorrect responses.\n if (noOfCorrect < uniqueAnswers.length && altResponses && altResponses.length) {\n const altUniqueStack = altResponses.map((altResponse) => {\n const altValue = altResponse.value;\n\n const altAllCorrect = getAllCorrectAnswers(answers, altValue);\n return getUniqueCorrectAnswers(altAllCorrect, altValue);\n });\n // Return the one with most correct answers.\n return altUniqueStack.sort((a, b) => b.filter((c) => c.isCorrect).length - a.filter((c) => c.isCorrect).length)[0];\n }\n return uniqueAnswers;\n};\n"],"file":"utils-correctness.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pie-element/image-cloze-association",
3
- "version": "4.9.1-next.2+755b939e9",
3
+ "version": "4.9.1-next.39+a42a408d1",
4
4
  "description": "",
5
5
  "repository": "pie-framework/pie-elements",
6
6
  "publishConfig": {
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "author": "pie framework developers",
23
23
  "license": "ISC",
24
- "gitHead": "755b939e9891a6523a5d20360e52dce285fbc83a",
24
+ "gitHead": "a42a408d1d238e52cbcf907fbbaec2ee98550385",
25
25
  "scripts": {
26
26
  "postpublish": "../../scripts/postpublish"
27
27
  },
@@ -1,50 +1,39 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`Root snapshots model renders 1`] = `
4
- <div>
5
- <WithStyles(PreviewPrompt)
6
- className="prompt"
7
- />
8
- <WithStyles(Typography)>
9
- <span
10
- dangerouslySetInnerHTML={
4
+ <ImageClozeAssociationComponent
5
+ classes={
6
+ Object {
7
+ "teacherInstructions": "ImageClozeAssociationComponent-teacherInstructions-1",
8
+ }
9
+ }
10
+ model={
11
+ Object {
12
+ "answers": Array [
11
13
  Object {
12
- "__html": undefined,
13
- }
14
- }
15
- />
16
- </WithStyles(Typography)>
17
- <WithStyles(CorrectAnswerToggle)
18
- onToggle={[Function]}
19
- show={false}
20
- toggled={false}
21
- />
22
- <br />
23
- <WithStyles(InteractiveSection)>
24
- <WithStyles(ImageContainer)
25
- answers={Array []}
26
- canDrag={true}
27
- draggingElement={
14
+ "containerIndex": 0,
15
+ "id": 1,
16
+ "value": "1",
17
+ },
28
18
  Object {
29
- "id": "",
30
- "value": "",
31
- }
32
- }
33
- duplicateResponses={false}
34
- image={Object {}}
35
- onAnswerSelect={[Function]}
36
- onDragAnswerBegin={[Function]}
37
- onDragAnswerEnd={[Function]}
38
- responseContainers={Array []}
39
- showDashedBorder={true}
40
- />
41
- <[object Object]
42
- canDrag={true}
43
- data={Array []}
44
- onAnswerRemove={[Function]}
45
- onDragBegin={[Function]}
46
- onDragEnd={[Function]}
47
- />
48
- </WithStyles(InteractiveSection)>
49
- </div>
19
+ "containerIndex": 1,
20
+ "id": 2,
21
+ "value": "2",
22
+ },
23
+ ],
24
+ "canDrag": true,
25
+ "draggingElement": Object {},
26
+ "duplicateResponses": false,
27
+ "image": Object {},
28
+ "maxResponsePerZone": 5,
29
+ "onAnswerSelect": [Function],
30
+ "onDragAnswerBegin": [Function],
31
+ "onDragAnswerEnd": [Function],
32
+ "possibleResponses": Array [],
33
+ "responseContainers": Array [],
34
+ "showDashedBorder": true,
35
+ }
36
+ }
37
+ updateAnswer={[Function]}
38
+ />
50
39
  `;
@@ -53,14 +53,17 @@ InteractiveSection.defaultProps = {
53
53
  responseCorrect: undefined,
54
54
  };
55
55
 
56
- const styles = () => ({
56
+ const styles = (theme) => ({
57
57
  interactiveDefault: {
58
+ marginTop: theme.spacing.unit * 2,
58
59
  border: `1px solid ${color.disabled()}`,
59
60
  },
60
61
  interactiveCorrect: {
62
+ marginTop: theme.spacing.unit * 2,
61
63
  border: `2px solid ${color.correct()}`,
62
64
  },
63
65
  interactiveIncorrect: {
66
+ marginTop: theme.spacing.unit * 2,
64
67
  border: `2px solid ${color.incorrect()}`,
65
68
  },
66
69
  });
package/src/root.jsx CHANGED
@@ -16,6 +16,12 @@ import _ from 'lodash';
16
16
 
17
17
  const generateId = () => Math.random().toString(36).substring(2) + new Date().getTime().toString(36);
18
18
 
19
+ const styles = (theme) => ({
20
+ teacherInstructions: {
21
+ marginBottom: theme.spacing.unit * 2,
22
+ },
23
+ });
24
+
19
25
  class ImageClozeAssociationComponent extends React.Component {
20
26
  constructor(props) {
21
27
  super(props);
@@ -176,6 +182,7 @@ class ImageClozeAssociationComponent extends React.Component {
176
182
 
177
183
  render() {
178
184
  const {
185
+ classes,
179
186
  model: {
180
187
  disabled,
181
188
  duplicateResponses,
@@ -228,10 +235,9 @@ class ImageClozeAssociationComponent extends React.Component {
228
235
 
229
236
  return (
230
237
  <div>
231
- <PreviewPrompt className="prompt" prompt={prompt} />
232
-
233
238
  {teacherInstructions && (
234
239
  <Collapsible
240
+ className={classes.teacherInstructions}
235
241
  labels={{
236
242
  hidden: 'Show Teacher Instructions',
237
243
  visible: 'Hide Teacher Instructions',
@@ -241,12 +247,13 @@ class ImageClozeAssociationComponent extends React.Component {
241
247
  </Collapsible>
242
248
  )}
243
249
 
250
+ <PreviewPrompt className="prompt" prompt={prompt} />
251
+
244
252
  <Typography>
245
253
  <span dangerouslySetInnerHTML={{ __html: stimulus }} />
246
254
  </Typography>
247
255
 
248
256
  <CorrectAnswerToggle show={showToggle} toggled={showCorrect} onToggle={this.toggleCorrect} />
249
- <br />
250
257
 
251
258
  {showCorrect && showToggle ? (
252
259
  <InteractiveSection responseCorrect={true}>
@@ -341,4 +348,6 @@ ImageClozeAssociationComponent.defaultProps = {
341
348
  classes: {},
342
349
  };
343
350
 
344
- export default withDragContext(ImageClozeAssociationComponent);
351
+ const StyledComponent = withStyles(styles)(ImageClozeAssociationComponent);
352
+
353
+ export default withDragContext(StyledComponent);
@@ -1,7 +1,7 @@
1
1
  const getAllCorrectAnswers = (answers, responses) =>
2
2
  answers.map((answer) => ({
3
3
  ...answer,
4
- isCorrect: (responses[answer.containerIndex].images || []).includes(answer.value),
4
+ isCorrect: (responses[answer.containerIndex] && responses[answer.containerIndex].images || []).includes(answer.value),
5
5
  }));
6
6
 
7
7
  const getValidAnswer = (answer, response) =>