@pie-element/explicit-constructed-response 3.12.0 → 3.12.1-beta.1443
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 +350 -0
- package/configure/CHANGELOG.md +330 -0
- package/configure/lib/alternateResponses.js +13 -7
- package/configure/lib/alternateResponses.js.map +1 -1
- package/configure/lib/alternateSection.js +39 -17
- package/configure/lib/alternateSection.js.map +1 -1
- package/configure/lib/defaults.js +28 -0
- package/configure/lib/defaults.js.map +1 -1
- package/configure/lib/ecr-toolbar.js +15 -6
- package/configure/lib/ecr-toolbar.js.map +1 -1
- package/configure/lib/index.js +16 -2
- package/configure/lib/index.js.map +1 -1
- package/configure/lib/main.js +234 -74
- package/configure/lib/main.js.map +1 -1
- package/configure/lib/markupUtils.js +9 -3
- package/configure/lib/markupUtils.js.map +1 -1
- package/configure/lib/utils.js +15 -0
- package/configure/lib/utils.js.map +1 -0
- package/configure/package.json +23 -5
- package/controller/CHANGELOG.md +40 -0
- package/controller/lib/index.js +64 -6
- package/controller/lib/index.js.map +1 -1
- package/controller/package.json +2 -2
- package/docs/config-schema.json +121 -0
- package/docs/config-schema.json.md +93 -1
- package/docs/demo/config.js +2 -2
- package/docs/demo/generate.js +4 -3
- package/docs/pie-schema.json +39 -0
- package/docs/pie-schema.json.md +28 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/main.js +6 -3
- package/lib/main.js.map +1 -1
- package/lib/print.js +2 -2
- package/lib/print.js.map +1 -1
- package/package.json +6 -6
- package/module/configure.js +0 -1953
- package/module/controller.js +0 -21340
- package/module/demo.js +0 -45
- package/module/element.js +0 -14384
- package/module/index.html +0 -21
- package/module/manifest.json +0 -18
- package/module/print-demo.js +0 -83
- package/module/print.html +0 -18
- package/module/print.js +0 -14331
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/markupUtils.js"],"names":["removeUnwantedCharacters","markup","replace","createElementFromHTML","htmlString","div","document","createElement","innerHTML","trim","processMarkup","newMarkup","slateMarkup","index","querySelectorAll","forEach","s","replaceWith","REGEX","createSlateMarkup","choices","match","g","label","getAdjustedLength","length"],"mappings":";;;;;;;;;AAAA;;
|
|
1
|
+
{"version":3,"sources":["../src/markupUtils.js"],"names":["tSymbols","nSymbols","matchTabAndNewLine","RegExp","removeUnwantedCharacters","markup","replace","createElementFromHTML","htmlString","div","document","createElement","innerHTML","trim","processMarkup","newMarkup","slateMarkup","index","querySelectorAll","forEach","s","replaceWith","REGEX","createSlateMarkup","choices","match","g","label","getAdjustedLength","length"],"mappings":";;;;;;;;;AAAA;;AAEA;AACA,IAAMA,QAAQ,GAAG,+BAAjB,C,CACA;;AACA,IAAMC,QAAQ,GAAG,sCAAjB,C,CACA;;AACA,IAAMC,kBAAkB,GAAG,IAAIC,MAAJ,kBACfH,QADe,uBACMC,QADN,yBAC6BD,QAD7B,yBACoDC,QADpD,SAEzB,GAFyB,CAA3B;;AAKO,IAAMG,wBAAwB,GAAG,SAA3BA,wBAA2B,CAACC,MAAD;AAAA,SACtCA,MAAM,CAACC,OAAP,CAAeJ,kBAAf,EAAmC,EAAnC,EAAuCI,OAAvC,CAA+C,MAA/C,EAAuD,GAAvD,EAA4DA,OAA5D,CAAoE,OAApE,EAA6E,GAA7E,CADsC;AAAA,CAAjC;;;;AAGP,IAAMC,qBAAqB,GAAG,SAAxBA,qBAAwB,GAAqB;AAAA,MAApBC,UAAoB,uEAAP,EAAO;AACjD,MAAMC,GAAG,GAAGC,QAAQ,CAACC,aAAT,CAAuB,KAAvB,CAAZ;AAEAF,EAAAA,GAAG,CAACG,SAAJ,GAAgBJ,UAAU,CAACK,IAAX,EAAhB;AAEA,SAAOJ,GAAP;AACD,CAND;;AAQO,IAAMK,aAAa,GAAG,SAAhBA,aAAgB,CAACT,MAAD,EAAY;AACvC,MAAMU,SAAS,GAAGX,wBAAwB,CAACC,MAAM,IAAI,EAAX,CAA1C;AACA,MAAMW,WAAW,GAAGT,qBAAqB,CAACQ,SAAS,IAAI,EAAd,CAAzC;AACA,MAAIE,KAAK,GAAG,CAAZ;AAEAD,EAAAA,WAAW,CAACE,gBAAZ,CAA6B,6CAA7B,EAA4EC,OAA5E,CAAoF,UAACC,CAAD,EAAO;AACzFA,IAAAA,CAAC,CAACC,WAAF,aAAmBJ,KAAK,EAAxB;AACD,GAFD;AAIA,SAAOD,WAAW,CAACJ,SAAnB;AACD,CAVM;;;AAYP,IAAMU,KAAK,GAAG,gBAAd;;AAEO,IAAMC,iBAAiB,GAAG,SAApBA,iBAAoB,CAAClB,MAAD,EAASmB,OAAT,EAAqB;AACpD,MAAI,CAACnB,MAAL,EAAa;AACX,WAAO,EAAP;AACD;;AAED,MAAMU,SAAS,GAAGX,wBAAwB,CAACC,MAAD,CAA1C;AAEA,SAAOU,SAAS,CAACT,OAAV,CAAkBgB,KAAlB,EAAyB,UAACG,KAAD,EAAQC,CAAR,EAAc;AAC5C,QAAMC,KAAK,GAAGH,OAAO,CAACE,CAAD,CAAP,CAAW,CAAX,EAAcC,KAAd,IAAuB,EAArC;AAEA,oFAAsED,CAAtE,6BAAwF,wBAAOC,KAAP,CAAxF;AACD,GAJM,CAAP;AAKD,CAZM,C,CAcP;;;;;AACO,IAAMC,iBAAiB,GAAG,SAApBA,iBAAoB,CAACC,MAAD,EAAY;AAC3C,MAAIA,MAAM,IAAI,CAAd,EAAiB;AACf,WAAOA,MAAM,GAAG,CAAhB;AACD;;AAED,MAAIA,MAAM,IAAI,CAAd,EAAiB;AACf,WAAOA,MAAM,GAAG,CAAhB;AACD;;AAED,MAAIA,MAAM,IAAI,CAAd,EAAiB;AACf,WAAOA,MAAM,GAAG,CAAhB;AACD;;AAED,SAAOA,MAAM,GAAG,CAAhB;AACD,CAdM","sourcesContent":["import escape from 'lodash/escape';\n\n// do not remove \\t from \\times, \\triangle, \\tan, \\theta or \\therefore\nconst tSymbols = 'imes|riangle|an|heta|herefore';\n// do not remove \\n from \\nthroot, \\nparallel, \\ncong, \\napprox, \\neq, \\ne or \\nsim\nconst nSymbols = 'throot|parallel|cong|approx|eq|e|sim';\n// match all \\t and \\n that are not part of math symbols that starts with \\t or \\n\nconst matchTabAndNewLine = new RegExp(\n `(\\\\t(?!${tSymbols}))|(\\\\n(?!${nSymbols}))|(\\\\\\\\t(?!${tSymbols}))|(\\\\\\\\n(?!${nSymbols}))`,\n 'g',\n);\n\nexport const removeUnwantedCharacters = (markup) =>\n markup.replace(matchTabAndNewLine, '').replace(/\\\\\"/g, '\"').replace(/\\\\\\//g, '/');\n\nconst createElementFromHTML = (htmlString = '') => {\n const div = document.createElement('div');\n\n div.innerHTML = htmlString.trim();\n\n return div;\n};\n\nexport const processMarkup = (markup) => {\n const newMarkup = removeUnwantedCharacters(markup || '');\n const slateMarkup = createElementFromHTML(newMarkup || '');\n let index = 0;\n\n slateMarkup.querySelectorAll('[data-type=\"explicit_constructed_response\"]').forEach((s) => {\n s.replaceWith(`{{${index++}}}`);\n });\n\n return slateMarkup.innerHTML;\n};\n\nconst REGEX = /\\{\\{(\\d+)\\}\\}/g;\n\nexport const createSlateMarkup = (markup, choices) => {\n if (!markup) {\n return '';\n }\n\n const newMarkup = removeUnwantedCharacters(markup);\n\n return newMarkup.replace(REGEX, (match, g) => {\n const label = choices[g][0].label || '';\n\n return `<span data-type=\"explicit_constructed_response\" data-index=\"${g}\" data-value=\"${escape(label)}\"></span>`;\n });\n};\n\n// also used in controller/src/index.js\nexport const getAdjustedLength = (length) => {\n if (length <= 2) {\n return length + 2;\n }\n\n if (length <= 4) {\n return length + 3;\n }\n\n if (length <= 6) {\n return length + 4;\n }\n\n return length + 5;\n};\n"],"file":"markupUtils.js"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.generateValidationMessage = void 0;
|
|
7
|
+
|
|
8
|
+
var generateValidationMessage = function generateValidationMessage(config) {
|
|
9
|
+
var maxResponseAreas = config.maxResponseAreas;
|
|
10
|
+
var responseAreasMessage = '\nCorrect answers should not be blank.' + '\nEach answer defined for a response area should be unique.' + '\nThere should be at least 1 ' + (maxResponseAreas ? "and at most ".concat(maxResponseAreas, " ") : '') + 'response area' + (maxResponseAreas ? 's' : '') + ' defined.';
|
|
11
|
+
return 'Validation requirements:' + responseAreasMessage;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
exports.generateValidationMessage = generateValidationMessage;
|
|
15
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.js"],"names":["generateValidationMessage","config","maxResponseAreas","responseAreasMessage"],"mappings":";;;;;;;AAAO,IAAMA,yBAAyB,GAAG,SAA5BA,yBAA4B,CAACC,MAAD,EAAY;AACnD,MAAQC,gBAAR,GAA6BD,MAA7B,CAAQC,gBAAR;AAEA,MAAMC,oBAAoB,GACxB,2CACA,6DADA,GAEA,+BAFA,IAGCD,gBAAgB,yBAAkBA,gBAAlB,SAAwC,EAHzD,IAIA,eAJA,IAKCA,gBAAgB,GAAG,GAAH,GAAS,EAL1B,IAMA,WAPF;AASA,SAAO,6BAA6BC,oBAApC;AACD,CAbM","sourcesContent":["export const generateValidationMessage = (config) => {\n const { maxResponseAreas } = config;\n\n const responseAreasMessage =\n '\\nCorrect answers should not be blank.' +\n '\\nEach answer defined for a response area should be unique.' +\n '\\nThere should be at least 1 ' +\n (maxResponseAreas ? `and at most ${maxResponseAreas} ` : '') +\n 'response area' +\n (maxResponseAreas ? 's' : '') +\n ' defined.';\n\n return 'Validation requirements:' + responseAreasMessage;\n};\n"],"file":"utils.js"}
|
package/configure/package.json
CHANGED
|
@@ -1,20 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-element/explicit-constructed-response-configure",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"modue": "src/index.js",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@material-ui/core": "^3.9.2",
|
|
9
9
|
"@material-ui/icons": "^3.0.1",
|
|
10
|
-
"@pie-framework/pie-configure-events": "^1.
|
|
11
|
-
"@pie-lib/config-ui": "
|
|
12
|
-
"@pie-lib/editable-html": "
|
|
10
|
+
"@pie-framework/pie-configure-events": "^1.3.0",
|
|
11
|
+
"@pie-lib/config-ui": "12.0.0-beta.2",
|
|
12
|
+
"@pie-lib/editable-html": "10.0.0-beta.2",
|
|
13
13
|
"classnames": "^2.2.6",
|
|
14
14
|
"debug": "^3.1.0",
|
|
15
15
|
"lodash": "^4.17.15",
|
|
16
16
|
"prop-types": "^15.6.2",
|
|
17
17
|
"react": "^16.8.1",
|
|
18
|
-
"react-dom": "^16.8.1"
|
|
18
|
+
"react-dom": "^16.8.1",
|
|
19
|
+
"@types/is-hotkey": "^0.1.1",
|
|
20
|
+
"@types/lodash": "^4.14.149",
|
|
21
|
+
"direction": "^1.0.3",
|
|
22
|
+
"is-plain-object": "^5.0.0",
|
|
23
|
+
"scroll-into-view-if-needed": "^2.2.20",
|
|
24
|
+
"tiny-invariant": "1.0.6",
|
|
25
|
+
"@emotion/css": "^11.10.0",
|
|
26
|
+
"is-hotkey": "^0.2.0",
|
|
27
|
+
"slate": "^0.82.1",
|
|
28
|
+
"slate-dev-environment": "^0.2.5",
|
|
29
|
+
"slate-edit-list": "^0.12.1",
|
|
30
|
+
"slate-edit-table": "^0.18.0",
|
|
31
|
+
"slate-history": "^0.66.0",
|
|
32
|
+
"slate-html-serializer": "^0.8.13",
|
|
33
|
+
"slate-hyperscript": "^0.77.0",
|
|
34
|
+
"slate-plain-serializer": "^0.7.13",
|
|
35
|
+
"slate-prop-types": "^0.5.44",
|
|
36
|
+
"slate-react": "^0.83.0"
|
|
19
37
|
}
|
|
20
38
|
}
|
package/controller/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,46 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [3.5.0](https://github.com/pie-framework/pie-elements/compare/@pie-element/explicit-constructed-response-controller@3.4.9...@pie-element/explicit-constructed-response-controller@3.5.0) (2022-12-07)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* update libs ([441f403](https://github.com/pie-framework/pie-elements/commit/441f403870b7bec0d61fab58b8d93dbe0ead4c32))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* **explicit-constructed-response:** added configurable validation PD-1706 ([327af4a](https://github.com/pie-framework/pie-elements/commit/327af4abe87af52389232c56afdd6e0dfd6c77f7))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## [3.4.9](https://github.com/pie-framework/pie-elements/compare/@pie-element/explicit-constructed-response-controller@3.4.8...@pie-element/explicit-constructed-response-controller@3.4.9) (2022-05-16)
|
|
23
|
+
|
|
24
|
+
**Note:** Version bump only for package @pie-element/explicit-constructed-response-controller
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## [3.4.8](https://github.com/pie-framework/pie-elements/compare/@pie-element/explicit-constructed-response-controller@3.4.7...@pie-element/explicit-constructed-response-controller@3.4.8) (2022-03-28)
|
|
31
|
+
|
|
32
|
+
**Note:** Version bump only for package @pie-element/explicit-constructed-response-controller
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## [3.4.7](https://github.com/pie-framework/pie-elements/compare/@pie-element/explicit-constructed-response-controller@3.4.6...@pie-element/explicit-constructed-response-controller@3.4.7) (2022-03-08)
|
|
39
|
+
|
|
40
|
+
**Note:** Version bump only for package @pie-element/explicit-constructed-response-controller
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
6
46
|
## [3.4.3](https://github.com/pie-framework/pie-elements/compare/@pie-element/explicit-constructed-response-controller@3.4.2...@pie-element/explicit-constructed-response-controller@3.4.3) (2021-12-01)
|
|
7
47
|
|
|
8
48
|
**Note:** Version bump only for package @pie-element/explicit-constructed-response-controller
|
package/controller/lib/index.js
CHANGED
|
@@ -5,12 +5,16 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
+
exports.getScore = exports.createCorrectResponseSession = void 0;
|
|
8
9
|
exports.model = model;
|
|
10
|
+
exports.normalize = void 0;
|
|
9
11
|
exports.outcome = outcome;
|
|
10
|
-
exports.
|
|
12
|
+
exports.validate = exports.prepareVal = exports.prepareChoice = void 0;
|
|
11
13
|
|
|
12
14
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
13
15
|
|
|
16
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
17
|
+
|
|
14
18
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
15
19
|
|
|
16
20
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
@@ -29,9 +33,9 @@ var _debug = _interopRequireDefault(require("debug"));
|
|
|
29
33
|
|
|
30
34
|
var _controllerUtils = require("@pie-lib/controller-utils");
|
|
31
35
|
|
|
32
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object);
|
|
36
|
+
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; }
|
|
33
37
|
|
|
34
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]
|
|
38
|
+
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; }
|
|
35
39
|
|
|
36
40
|
var log = (0, _debug["default"])('explicit-constructed-response:controller');
|
|
37
41
|
|
|
@@ -166,10 +170,10 @@ function model(question, session, env) {
|
|
|
166
170
|
var labelLengthsArr = (choice || []).map(function (choice) {
|
|
167
171
|
return (choice.label || '').length;
|
|
168
172
|
});
|
|
169
|
-
var length =
|
|
173
|
+
var length = Math.max.apply(Math, (0, _toConsumableArray2["default"])(labelLengthsArr));
|
|
170
174
|
|
|
171
|
-
if (undefinedLengths || !maxLengthPerChoice[index] || maxLengthPerChoice[index] < length) {
|
|
172
|
-
maxLengthPerChoice[index] = length;
|
|
175
|
+
if (undefinedLengths || !maxLengthPerChoice[index] || maxLengthPerChoice[index] < length || maxLengthPerChoice[index] > length + 10) {
|
|
176
|
+
maxLengthPerChoice[index] = getAdjustedLength(length);
|
|
173
177
|
}
|
|
174
178
|
});
|
|
175
179
|
out = {
|
|
@@ -185,6 +189,7 @@ function model(question, session, env) {
|
|
|
185
189
|
maxLengthPerChoice: maxLengthPerChoice,
|
|
186
190
|
maxLengthPerChoiceEnabled: maxLengthPerChoiceEnabled,
|
|
187
191
|
displayType: normalizedQuestion.displayType,
|
|
192
|
+
playerSpellCheckEnabled: normalizedQuestion.playerSpellCheckEnabled,
|
|
188
193
|
responseCorrect: env.mode === 'evaluate' ? getScore(normalizedQuestion, session) === 1 : undefined
|
|
189
194
|
};
|
|
190
195
|
|
|
@@ -295,4 +300,57 @@ var createCorrectResponseSession = function createCorrectResponseSession(questio
|
|
|
295
300
|
};
|
|
296
301
|
|
|
297
302
|
exports.createCorrectResponseSession = createCorrectResponseSession;
|
|
303
|
+
|
|
304
|
+
var validate = function validate() {
|
|
305
|
+
var model = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
306
|
+
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
307
|
+
var choices = model.choices,
|
|
308
|
+
markup = model.markup;
|
|
309
|
+
var maxResponseAreas = config.maxResponseAreas;
|
|
310
|
+
var allChoicesErrors = {};
|
|
311
|
+
Object.entries(choices || {}).forEach(function (_ref4) {
|
|
312
|
+
var _ref5 = (0, _slicedToArray2["default"])(_ref4, 2),
|
|
313
|
+
key = _ref5[0],
|
|
314
|
+
values = _ref5[1];
|
|
315
|
+
|
|
316
|
+
var reversedChoices = (0, _toConsumableArray2["default"])(values || []).reverse();
|
|
317
|
+
var choicesErrors = {};
|
|
318
|
+
reversedChoices.forEach(function (choice, index) {
|
|
319
|
+
var value = choice.value,
|
|
320
|
+
label = choice.label;
|
|
321
|
+
|
|
322
|
+
if (label === '' || label === '<div></div>') {
|
|
323
|
+
choicesErrors[value] = 'Content should not be empty.';
|
|
324
|
+
} else {
|
|
325
|
+
var identicalAnswer = reversedChoices.slice(index + 1).some(function (c) {
|
|
326
|
+
return c.label === label;
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
if (identicalAnswer) {
|
|
330
|
+
choicesErrors[value] = 'Content should be unique.';
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
if (!(0, _isEmpty["default"])(choicesErrors)) {
|
|
336
|
+
allChoicesErrors[key] = choicesErrors;
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
var errors = {};
|
|
340
|
+
var nbOfResponseAreas = (markup.match(/\{\{(\d+)\}\}/g) || []).length;
|
|
341
|
+
|
|
342
|
+
if (nbOfResponseAreas > maxResponseAreas) {
|
|
343
|
+
errors.responseAreasError = "No more than ".concat(maxResponseAreas, " response areas should be defined.");
|
|
344
|
+
} else if (nbOfResponseAreas < 1) {
|
|
345
|
+
errors.responseAreasError = 'There should be at least 1 response area defined.';
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (!(0, _isEmpty["default"])(allChoicesErrors)) {
|
|
349
|
+
errors.choicesErrors = allChoicesErrors;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return errors;
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
exports.validate = validate;
|
|
298
356
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"names":["log","prepareChoice","mode","defaultFeedback","choice","out","label","value","correct","feedbackType","feedback","type","getFeedback","getAdjustedLength","length","normalize","question","rationaleEnabled","promptEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","model","session","env","Promise","resolve","choices","Object","keys","forEach","key","map","item","index","normalizedQuestion","assign","incorrect","preparChoiceFn","obj","area","respArea","chosenValue","val","c","prepareVal","showNote","values","maxLengthPerChoice","maxLengthPerChoiceEnabled","undefinedLengths","labelLengthsArr","Math","max","disabled","prompt","markup","note","displayType","responseCorrect","getScore","undefined","role","rationale","teacherInstructions","getTextFromHTML","html","replace","trim","config","responseAreas","match","maxScore","correctCount","total","str","toFixed","parseFloat","outcome","partialScoringEnabled","partialScoring","enabled","score","empty","createCorrectResponseSession","i","id"],"mappings":"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","sourcesContent":["import map from 'lodash/map';\nimport reduce from 'lodash/reduce';\nimport find from 'lodash/find';\nimport isEmpty from 'lodash/isEmpty';\nimport debug from 'debug';\nimport { partialScoring } from '@pie-lib/controller-utils';\n\nconst log = debug('explicit-constructed-response:controller');\n\nexport const prepareChoice = (mode, defaultFeedback) => choice => {\n const out = {\n label: choice.label,\n value: choice.value\n };\n\n if (mode === 'evaluate') {\n out.correct = true;\n\n const feedbackType = (choice.feedback && choice.feedback.type) || 'none';\n\n if (feedbackType === 'default') {\n out.feedback = defaultFeedback['correct'];\n } else if (feedbackType === 'custom') {\n out.feedback = choice.feedback.value;\n }\n }\n\n return out;\n};\n\nconst getFeedback = value => {\n if (value) {\n return 'correct';\n }\n\n return 'incorrect';\n};\n\n// also used in configure/src/markupUtils.js\nconst getAdjustedLength = length => {\n if (length <= 2) {\n return length + 2;\n }\n\n if (length <= 4) {\n return length + 3;\n }\n\n if (length <= 6) {\n return length + 4;\n }\n\n return length + 5;\n};\n\nexport const normalize = question => ({\n rationaleEnabled: true,\n promptEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n ...question,\n});\n\n/**\n *\n * @param {*} question\n * @param {*} session\n * @param {*} env\n */\nexport function model(question, session, env) {\n return new Promise(async resolve => {\n // this was added to treat an exception, when the model has choices without the \"value\" property\n // like: { label: 'test' }\n if (question.choices) {\n Object.keys(question.choices).forEach(key => {\n question.choices[key] = (question.choices[key] || []).map((item, index) => {\n if (!item.value) {\n log('Choice does not contain \"value\" property, which is required.', item);\n return { value: `${index}`, ...item };\n }\n\n return item;\n })\n });\n }\n\n const normalizedQuestion = normalize(question);\n const defaultFeedback = Object.assign(\n { correct: 'Correct', incorrect: 'Incorrect' },\n normalizedQuestion.defaultFeedback\n );\n\n const { value = {} } = session || {};\n\n const preparChoiceFn = prepareChoice(env.mode, defaultFeedback);\n\n let choices = reduce(\n normalizedQuestion.choices,\n (obj, area, key) => {\n obj[key] = map(area, preparChoiceFn);\n\n return obj;\n },\n {}\n );\n let feedback = {};\n\n if (env.mode === 'evaluate') {\n feedback = reduce(normalizedQuestion.choices, (obj, respArea, key) => {\n const chosenValue = value && value[key];\n const val = !isEmpty(chosenValue) && find(respArea, c => prepareVal(c.label) === prepareVal(chosenValue));\n\n obj[key] = getFeedback(val);\n\n return obj;\n }, {});\n }\n\n let showNote = false;\n // check if a choice has an alternate\n Object.values(choices).forEach(choice => {\n if (choice && choice.length > 1) {\n showNote = true;\n }\n });\n\n const { maxLengthPerChoice = [], maxLengthPerChoiceEnabled } = normalizedQuestion;\n const undefinedLengths = !maxLengthPerChoice.length;\n\n // calculate maxLengthPerChoice array if it is not defined or defined incorrectly\n Object.values(choices).forEach((choice, index) => {\n const labelLengthsArr = (choice || []).map(choice => (choice.label || '').length);\n const length = getAdjustedLength(Math.max(...labelLengthsArr));\n\n if (undefinedLengths || !maxLengthPerChoice[index] || maxLengthPerChoice[index] < length) {\n maxLengthPerChoice[index] = length;\n }\n });\n\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n markup: normalizedQuestion.markup,\n choices,\n feedback,\n env,\n note: normalizedQuestion.note,\n showNote,\n maxLengthPerChoice,\n maxLengthPerChoiceEnabled,\n displayType: normalizedQuestion.displayType,\n responseCorrect:\n env.mode === 'evaluate' ? getScore(normalizedQuestion, session) === 1 : undefined\n };\n\n if (\n env.role === 'instructor' &&\n (env.mode === 'view' || env.mode === 'evaluate')\n ) {\n out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled ? normalizedQuestion.teacherInstructions : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n resolve(out);\n });\n}\n\nconst getTextFromHTML = (html) => {\n return (html || '').replace(/<\\/?[^>]+(>|$)/g, '');\n};\n\nexport const prepareVal = html => {\n const value = getTextFromHTML(html);\n\n return value.trim();\n};\n\nexport const getScore = (config, session) => {\n const { value } = session || {};\n\n if (!session || isEmpty(session) || !value) {\n return 0;\n }\n\n const responseAreas = config.markup && config.markup.match(/\\{\\{(.)\\}\\}/g);\n const maxScore = responseAreas ? responseAreas.length : 0;\n const correctCount = reduce(config.choices, (total, respArea, key) => {\n const chosenValue = value && value[key];\n\n if (isEmpty(chosenValue) || !find(respArea, c => prepareVal(c.label) === prepareVal(chosenValue))) {\n return total;\n }\n\n return total + 1;\n }, 0);\n\n const str = maxScore ? (correctCount / maxScore).toFixed(2) : 0;\n\n return parseFloat(str);\n};\n\n/**\n *\n * The score is partial by default for checkbox mode, allOrNothing for radio mode.\n * To disable partial scoring for checkbox mode you either set model.partialScoring = false or env.partialScoring =\n * false. the value in `env` will override the value in `model`.\n * @param {Object} model - the main model\n * @param {boolean} model.partialScoring - is partial scoring enabled (if undefined set to to true)\n * @param {*} session\n * @param {Object} env\n * @param {boolean} env.partialScoring - is partial scoring enabled (if undefined default to true) This overrides\n * `model.partialScoring`.\n */\nexport function outcome(model, session, env = {}) {\n return new Promise(resolve => {\n const partialScoringEnabled = partialScoring.enabled(model, env);\n const score = getScore(model, session);\n\n resolve({ score: partialScoringEnabled ? score : score === 1 ? 1 : 0, empty: isEmpty(session) });\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise(resolve => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { choices } = question;\n const value = {};\n\n Object.keys(choices).forEach((key, i) => {\n value[i] = choices[key][0].label;\n });\n\n resolve({\n id: '1',\n value\n });\n } else {\n resolve(null);\n }\n });\n};\n"],"file":"index.js"}
|
|
1
|
+
{"version":3,"sources":["../src/index.js"],"names":["log","prepareChoice","mode","defaultFeedback","choice","out","label","value","correct","feedbackType","feedback","type","getFeedback","getAdjustedLength","length","normalize","question","rationaleEnabled","promptEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","model","session","env","Promise","resolve","choices","Object","keys","forEach","key","map","item","index","normalizedQuestion","assign","incorrect","preparChoiceFn","obj","area","respArea","chosenValue","val","c","prepareVal","showNote","values","maxLengthPerChoice","maxLengthPerChoiceEnabled","undefinedLengths","labelLengthsArr","Math","max","disabled","prompt","markup","note","displayType","playerSpellCheckEnabled","responseCorrect","getScore","undefined","role","rationale","teacherInstructions","getTextFromHTML","html","replace","trim","config","responseAreas","match","maxScore","correctCount","total","str","toFixed","parseFloat","outcome","partialScoringEnabled","partialScoring","enabled","score","empty","createCorrectResponseSession","i","id","validate","maxResponseAreas","allChoicesErrors","entries","reversedChoices","reverse","choicesErrors","identicalAnswer","slice","some","errors","nbOfResponseAreas","responseAreasError"],"mappings":"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","sourcesContent":["import map from 'lodash/map';\nimport reduce from 'lodash/reduce';\nimport find from 'lodash/find';\nimport isEmpty from 'lodash/isEmpty';\nimport debug from 'debug';\nimport { partialScoring } from '@pie-lib/controller-utils';\n\nconst log = debug('explicit-constructed-response:controller');\n\nexport const prepareChoice = (mode, defaultFeedback) => (choice) => {\n const out = {\n label: choice.label,\n value: choice.value,\n };\n\n if (mode === 'evaluate') {\n out.correct = true;\n\n const feedbackType = (choice.feedback && choice.feedback.type) || 'none';\n\n if (feedbackType === 'default') {\n out.feedback = defaultFeedback['correct'];\n } else if (feedbackType === 'custom') {\n out.feedback = choice.feedback.value;\n }\n }\n\n return out;\n};\n\nconst getFeedback = (value) => {\n if (value) {\n return 'correct';\n }\n\n return 'incorrect';\n};\n\n// also used in configure/src/markupUtils.js\nconst getAdjustedLength = (length) => {\n if (length <= 2) {\n return length + 2;\n }\n\n if (length <= 4) {\n return length + 3;\n }\n\n if (length <= 6) {\n return length + 4;\n }\n\n return length + 5;\n};\n\nexport const normalize = (question) => ({\n rationaleEnabled: true,\n promptEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n ...question,\n});\n\n/**\n *\n * @param {*} question\n * @param {*} session\n * @param {*} env\n */\nexport function model(question, session, env) {\n return new Promise(async (resolve) => {\n // this was added to treat an exception, when the model has choices without the \"value\" property\n // like: { label: 'test' }\n if (question.choices) {\n Object.keys(question.choices).forEach((key) => {\n question.choices[key] = (question.choices[key] || []).map((item, index) => {\n if (!item.value) {\n log('Choice does not contain \"value\" property, which is required.', item);\n return { value: `${index}`, ...item };\n }\n\n return item;\n });\n });\n }\n\n const normalizedQuestion = normalize(question);\n const defaultFeedback = Object.assign(\n { correct: 'Correct', incorrect: 'Incorrect' },\n normalizedQuestion.defaultFeedback,\n );\n\n const { value = {} } = session || {};\n\n const preparChoiceFn = prepareChoice(env.mode, defaultFeedback);\n\n let choices = reduce(\n normalizedQuestion.choices,\n (obj, area, key) => {\n obj[key] = map(area, preparChoiceFn);\n\n return obj;\n },\n {},\n );\n let feedback = {};\n\n if (env.mode === 'evaluate') {\n feedback = reduce(\n normalizedQuestion.choices,\n (obj, respArea, key) => {\n const chosenValue = value && value[key];\n const val = !isEmpty(chosenValue) && find(respArea, (c) => prepareVal(c.label) === prepareVal(chosenValue));\n\n obj[key] = getFeedback(val);\n\n return obj;\n },\n {},\n );\n }\n\n let showNote = false;\n // check if a choice has an alternate\n Object.values(choices).forEach((choice) => {\n if (choice && choice.length > 1) {\n showNote = true;\n }\n });\n\n const { maxLengthPerChoice = [], maxLengthPerChoiceEnabled } = normalizedQuestion;\n const undefinedLengths = !maxLengthPerChoice.length;\n\n // calculate maxLengthPerChoice array if it is not defined or defined incorrectly\n Object.values(choices).forEach((choice, index) => {\n const labelLengthsArr = (choice || []).map((choice) => (choice.label || '').length);\n const length = Math.max(...labelLengthsArr);\n\n if (\n undefinedLengths ||\n !maxLengthPerChoice[index] ||\n maxLengthPerChoice[index] < length ||\n maxLengthPerChoice[index] > length + 10\n ) {\n maxLengthPerChoice[index] = getAdjustedLength(length);\n }\n });\n\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n markup: normalizedQuestion.markup,\n choices,\n feedback,\n env,\n note: normalizedQuestion.note,\n showNote,\n maxLengthPerChoice,\n maxLengthPerChoiceEnabled,\n displayType: normalizedQuestion.displayType,\n playerSpellCheckEnabled: normalizedQuestion.playerSpellCheckEnabled,\n responseCorrect: env.mode === 'evaluate' ? getScore(normalizedQuestion, session) === 1 : undefined,\n };\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n resolve(out);\n });\n}\n\nconst getTextFromHTML = (html) => {\n return (html || '').replace(/<\\/?[^>]+(>|$)/g, '');\n};\n\nexport const prepareVal = (html) => {\n const value = getTextFromHTML(html);\n\n return value.trim();\n};\n\nexport const getScore = (config, session) => {\n const { value } = session || {};\n\n if (!session || isEmpty(session) || !value) {\n return 0;\n }\n\n const responseAreas = config.markup && config.markup.match(/\\{\\{(.)\\}\\}/g);\n const maxScore = responseAreas ? responseAreas.length : 0;\n const correctCount = reduce(\n config.choices,\n (total, respArea, key) => {\n const chosenValue = value && value[key];\n\n if (isEmpty(chosenValue) || !find(respArea, (c) => prepareVal(c.label) === prepareVal(chosenValue))) {\n return total;\n }\n\n return total + 1;\n },\n 0,\n );\n\n const str = maxScore ? (correctCount / maxScore).toFixed(2) : 0;\n\n return parseFloat(str);\n};\n\n/**\n *\n * The score is partial by default for checkbox mode, allOrNothing for radio mode.\n * To disable partial scoring for checkbox mode you either set model.partialScoring = false or env.partialScoring =\n * false. the value in `env` will override the value in `model`.\n * @param {Object} model - the main model\n * @param {boolean} model.partialScoring - is partial scoring enabled (if undefined set to to true)\n * @param {*} session\n * @param {Object} env\n * @param {boolean} env.partialScoring - is partial scoring enabled (if undefined default to true) This overrides\n * `model.partialScoring`.\n */\nexport function outcome(model, session, env = {}) {\n return new Promise((resolve) => {\n const partialScoringEnabled = partialScoring.enabled(model, env);\n const score = getScore(model, session);\n\n resolve({ score: partialScoringEnabled ? score : score === 1 ? 1 : 0, empty: isEmpty(session) });\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { choices } = question;\n const value = {};\n\n Object.keys(choices).forEach((key, i) => {\n value[i] = choices[key][0].label;\n });\n\n resolve({\n id: '1',\n value,\n });\n } else {\n resolve(null);\n }\n });\n};\n\nexport const validate = (model = {}, config = {}) => {\n const { choices, markup } = model;\n const { maxResponseAreas } = config;\n const allChoicesErrors = {};\n\n Object.entries(choices || {}).forEach(([key, values]) => {\n const reversedChoices = [...(values || [])].reverse();\n const choicesErrors = {};\n\n reversedChoices.forEach((choice, index) => {\n const { value, label } = choice;\n\n if (label === '' || label === '<div></div>') {\n choicesErrors[value] = 'Content should not be empty.';\n } else {\n const identicalAnswer = reversedChoices.slice(index + 1).some((c) => c.label === label);\n\n if (identicalAnswer) {\n choicesErrors[value] = 'Content should be unique.';\n }\n }\n });\n\n if (!isEmpty(choicesErrors)) {\n allChoicesErrors[key] = choicesErrors;\n }\n });\n\n const errors = {};\n const nbOfResponseAreas = (markup.match(/\\{\\{(\\d+)\\}\\}/g) || []).length;\n\n if (nbOfResponseAreas > maxResponseAreas) {\n errors.responseAreasError = `No more than ${maxResponseAreas} response areas should be defined.`;\n } else if (nbOfResponseAreas < 1) {\n errors.responseAreasError = 'There should be at least 1 response area defined.';\n }\n\n if (!isEmpty(allChoicesErrors)) {\n errors.choicesErrors = allChoicesErrors;\n }\n\n return errors;\n};\n"],"file":"index.js"}
|
package/controller/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-element/explicit-constructed-response-controller",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.5.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"module": "src/index.js",
|
|
8
8
|
"author": "",
|
|
9
9
|
"license": "ISC",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@pie-lib/controller-utils": "^0.2.
|
|
11
|
+
"@pie-lib/controller-utils": "^0.2.42",
|
|
12
12
|
"debug": "^3.1.0",
|
|
13
13
|
"lodash": "^4.17.15",
|
|
14
14
|
"type-of": "^2.0.1"
|
package/docs/config-schema.json
CHANGED
|
@@ -51,6 +51,43 @@
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
|
+
"settingsPanelDisabled": {
|
|
55
|
+
"description": "Indicates if the settings panel is not available",
|
|
56
|
+
"type": "boolean",
|
|
57
|
+
"title": "settingsPanelDisabled"
|
|
58
|
+
},
|
|
59
|
+
"spellCheck": {
|
|
60
|
+
"title": "ConfigureProp",
|
|
61
|
+
"type": "object",
|
|
62
|
+
"properties": {
|
|
63
|
+
"settings": {
|
|
64
|
+
"description": "Indicates if the item has to be displayed in the Settings Panel",
|
|
65
|
+
"type": "boolean",
|
|
66
|
+
"title": "settings"
|
|
67
|
+
},
|
|
68
|
+
"label": {
|
|
69
|
+
"description": "Indicates the label for the item that has to be displayed in the Settings Panel",
|
|
70
|
+
"type": "string",
|
|
71
|
+
"title": "label"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"playerSpellCheck": {
|
|
76
|
+
"title": "ConfigureProp",
|
|
77
|
+
"type": "object",
|
|
78
|
+
"properties": {
|
|
79
|
+
"settings": {
|
|
80
|
+
"description": "Indicates if the item has to be displayed in the Settings Panel",
|
|
81
|
+
"type": "boolean",
|
|
82
|
+
"title": "settings"
|
|
83
|
+
},
|
|
84
|
+
"label": {
|
|
85
|
+
"description": "Indicates the label for the item that has to be displayed in the Settings Panel",
|
|
86
|
+
"type": "string",
|
|
87
|
+
"title": "label"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
},
|
|
54
91
|
"autoScoring": {
|
|
55
92
|
"title": "ConfigureProp",
|
|
56
93
|
"type": "object",
|
|
@@ -147,6 +184,69 @@
|
|
|
147
184
|
}
|
|
148
185
|
}
|
|
149
186
|
},
|
|
187
|
+
"maxResponseAreas": {
|
|
188
|
+
"description": "Maximum number of response areas",
|
|
189
|
+
"type": "number",
|
|
190
|
+
"title": "maxResponseAreas"
|
|
191
|
+
},
|
|
192
|
+
"maxImageWidth": {
|
|
193
|
+
"title": "ConfigureMaxImageDimensionsProp",
|
|
194
|
+
"type": "object",
|
|
195
|
+
"properties": {
|
|
196
|
+
"teacherInstructions": {
|
|
197
|
+
"description": "Indicates the max dimension for images in teacher instructions",
|
|
198
|
+
"type": "number",
|
|
199
|
+
"title": "teacherInstructions"
|
|
200
|
+
},
|
|
201
|
+
"prompt": {
|
|
202
|
+
"description": "Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified",
|
|
203
|
+
"type": "number",
|
|
204
|
+
"title": "prompt"
|
|
205
|
+
},
|
|
206
|
+
"rationale": {
|
|
207
|
+
"description": "Indicates the max dimension for images in rationale",
|
|
208
|
+
"type": "number",
|
|
209
|
+
"title": "rationale"
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
"maxImageHeight": {
|
|
214
|
+
"title": "ConfigureMaxImageDimensionsProp",
|
|
215
|
+
"type": "object",
|
|
216
|
+
"properties": {
|
|
217
|
+
"teacherInstructions": {
|
|
218
|
+
"description": "Indicates the max dimension for images in teacher instructions",
|
|
219
|
+
"type": "number",
|
|
220
|
+
"title": "teacherInstructions"
|
|
221
|
+
},
|
|
222
|
+
"prompt": {
|
|
223
|
+
"description": "Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified",
|
|
224
|
+
"type": "number",
|
|
225
|
+
"title": "prompt"
|
|
226
|
+
},
|
|
227
|
+
"rationale": {
|
|
228
|
+
"description": "Indicates the max dimension for images in rationale",
|
|
229
|
+
"type": "number",
|
|
230
|
+
"title": "rationale"
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"withRubric": {
|
|
235
|
+
"title": "ConfigureProp",
|
|
236
|
+
"type": "object",
|
|
237
|
+
"properties": {
|
|
238
|
+
"settings": {
|
|
239
|
+
"description": "Indicates if the item has to be displayed in the Settings Panel",
|
|
240
|
+
"type": "boolean",
|
|
241
|
+
"title": "settings"
|
|
242
|
+
},
|
|
243
|
+
"label": {
|
|
244
|
+
"description": "Indicates the label for the item that has to be displayed in the Settings Panel",
|
|
245
|
+
"type": "string",
|
|
246
|
+
"title": "label"
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
},
|
|
150
250
|
"showPrompt": {
|
|
151
251
|
"description": "Determines whether prompt field will be displayed or not",
|
|
152
252
|
"default": true,
|
|
@@ -182,6 +282,27 @@
|
|
|
182
282
|
"title": "label"
|
|
183
283
|
}
|
|
184
284
|
}
|
|
285
|
+
},
|
|
286
|
+
"ConfigureMaxImageDimensionsProp": {
|
|
287
|
+
"title": "ConfigureMaxImageDimensionsProp",
|
|
288
|
+
"type": "object",
|
|
289
|
+
"properties": {
|
|
290
|
+
"teacherInstructions": {
|
|
291
|
+
"description": "Indicates the max dimension for images in teacher instructions",
|
|
292
|
+
"type": "number",
|
|
293
|
+
"title": "teacherInstructions"
|
|
294
|
+
},
|
|
295
|
+
"prompt": {
|
|
296
|
+
"description": "Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified",
|
|
297
|
+
"type": "number",
|
|
298
|
+
"title": "prompt"
|
|
299
|
+
},
|
|
300
|
+
"rationale": {
|
|
301
|
+
"description": "Indicates the max dimension for images in rationale",
|
|
302
|
+
"type": "number",
|
|
303
|
+
"title": "rationale"
|
|
304
|
+
}
|
|
305
|
+
}
|
|
185
306
|
}
|
|
186
307
|
},
|
|
187
308
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
@@ -38,6 +38,34 @@ Indicates if the item has to be displayed in the Settings Panel
|
|
|
38
38
|
|
|
39
39
|
Indicates the label for the item that has to be displayed in the Settings Panel
|
|
40
40
|
|
|
41
|
+
# `settingsPanelDisabled` (boolean)
|
|
42
|
+
|
|
43
|
+
Indicates if the settings panel is not available
|
|
44
|
+
|
|
45
|
+
# `spellCheck` (object)
|
|
46
|
+
|
|
47
|
+
Properties of the `spellCheck` object:
|
|
48
|
+
|
|
49
|
+
## `settings` (boolean)
|
|
50
|
+
|
|
51
|
+
Indicates if the item has to be displayed in the Settings Panel
|
|
52
|
+
|
|
53
|
+
## `label` (string)
|
|
54
|
+
|
|
55
|
+
Indicates the label for the item that has to be displayed in the Settings Panel
|
|
56
|
+
|
|
57
|
+
# `playerSpellCheck` (object)
|
|
58
|
+
|
|
59
|
+
Properties of the `playerSpellCheck` object:
|
|
60
|
+
|
|
61
|
+
## `settings` (boolean)
|
|
62
|
+
|
|
63
|
+
Indicates if the item has to be displayed in the Settings Panel
|
|
64
|
+
|
|
65
|
+
## `label` (string)
|
|
66
|
+
|
|
67
|
+
Indicates the label for the item that has to be displayed in the Settings Panel
|
|
68
|
+
|
|
41
69
|
# `autoScoring` (object)
|
|
42
70
|
|
|
43
71
|
Properties of the `autoScoring` object:
|
|
@@ -110,6 +138,54 @@ Indicates if the item has to be displayed in the Settings Panel
|
|
|
110
138
|
|
|
111
139
|
Indicates the label for the item that has to be displayed in the Settings Panel
|
|
112
140
|
|
|
141
|
+
# `maxResponseAreas` (number)
|
|
142
|
+
|
|
143
|
+
Maximum number of response areas
|
|
144
|
+
|
|
145
|
+
# `maxImageWidth` (object)
|
|
146
|
+
|
|
147
|
+
Properties of the `maxImageWidth` object:
|
|
148
|
+
|
|
149
|
+
## `teacherInstructions` (number)
|
|
150
|
+
|
|
151
|
+
Indicates the max dimension for images in teacher instructions
|
|
152
|
+
|
|
153
|
+
## `prompt` (number)
|
|
154
|
+
|
|
155
|
+
Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified
|
|
156
|
+
|
|
157
|
+
## `rationale` (number)
|
|
158
|
+
|
|
159
|
+
Indicates the max dimension for images in rationale
|
|
160
|
+
|
|
161
|
+
# `maxImageHeight` (object)
|
|
162
|
+
|
|
163
|
+
Properties of the `maxImageHeight` object:
|
|
164
|
+
|
|
165
|
+
## `teacherInstructions` (number)
|
|
166
|
+
|
|
167
|
+
Indicates the max dimension for images in teacher instructions
|
|
168
|
+
|
|
169
|
+
## `prompt` (number)
|
|
170
|
+
|
|
171
|
+
Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified
|
|
172
|
+
|
|
173
|
+
## `rationale` (number)
|
|
174
|
+
|
|
175
|
+
Indicates the max dimension for images in rationale
|
|
176
|
+
|
|
177
|
+
# `withRubric` (object)
|
|
178
|
+
|
|
179
|
+
Properties of the `withRubric` object:
|
|
180
|
+
|
|
181
|
+
## `settings` (boolean)
|
|
182
|
+
|
|
183
|
+
Indicates if the item has to be displayed in the Settings Panel
|
|
184
|
+
|
|
185
|
+
## `label` (string)
|
|
186
|
+
|
|
187
|
+
Indicates the label for the item that has to be displayed in the Settings Panel
|
|
188
|
+
|
|
113
189
|
# `showPrompt` (boolean)
|
|
114
190
|
|
|
115
191
|
Determines whether prompt field will be displayed or not
|
|
@@ -144,4 +220,20 @@ Indicates if the item has to be displayed in the Settings Panel
|
|
|
144
220
|
|
|
145
221
|
### `label` (string)
|
|
146
222
|
|
|
147
|
-
Indicates the label for the item that has to be displayed in the Settings Panel
|
|
223
|
+
Indicates the label for the item that has to be displayed in the Settings Panel
|
|
224
|
+
|
|
225
|
+
## `ConfigureMaxImageDimensionsProp` (object)
|
|
226
|
+
|
|
227
|
+
Properties of the `ConfigureMaxImageDimensionsProp` object:
|
|
228
|
+
|
|
229
|
+
### `teacherInstructions` (number)
|
|
230
|
+
|
|
231
|
+
Indicates the max dimension for images in teacher instructions
|
|
232
|
+
|
|
233
|
+
### `prompt` (number)
|
|
234
|
+
|
|
235
|
+
Indicates the max dimension for images in prompt - this is also the default dimension for all other input fields if it's not specified
|
|
236
|
+
|
|
237
|
+
### `rationale` (number)
|
|
238
|
+
|
|
239
|
+
Indicates the max dimension for images in rationale
|
package/docs/demo/config.js
CHANGED
|
@@ -2,7 +2,7 @@ const { model } = require('./generate');
|
|
|
2
2
|
|
|
3
3
|
module.exports = {
|
|
4
4
|
elements: {
|
|
5
|
-
'explicit-constructed-response': '../..'
|
|
5
|
+
'explicit-constructed-response': '../..',
|
|
6
6
|
},
|
|
7
|
-
models: [model('1', 'explicit-constructed-response')]
|
|
7
|
+
models: [model('1', 'explicit-constructed-response')],
|
|
8
8
|
};
|
package/docs/demo/generate.js
CHANGED
|
@@ -10,11 +10,12 @@ exports.model = (id, element) => ({
|
|
|
10
10
|
choices: {
|
|
11
11
|
0: [choice('cow', '0'), choice('cattle', '1'), choice('calf', '2')],
|
|
12
12
|
1: [choice('over', '0'), choice('past', '1'), choice('beyond', '2')],
|
|
13
|
-
2: [choice('moon', '0')]
|
|
13
|
+
2: [choice('moon', '0')],
|
|
14
14
|
},
|
|
15
|
-
maxLengthPerChoice: [
|
|
15
|
+
maxLengthPerChoice: [7, 10, 4],
|
|
16
16
|
prompt: 'Complete the sentence',
|
|
17
17
|
note: 'The answer shown above is the most common correct answer for this item. One or more additional correct answers are also defined, and will also be recognized as correct.',
|
|
18
18
|
promptEnabled: true,
|
|
19
|
-
toolbarEditorPosition: 'bottom'
|
|
19
|
+
toolbarEditorPosition: 'bottom',
|
|
20
|
+
rubricEnabled: false,
|
|
20
21
|
});
|