@pie-element/explicit-constructed-response 3.9.3-next.137 → 3.9.3-next.1370
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 +329 -0
- package/configure/CHANGELOG.md +290 -0
- package/configure/lib/alternateResponses.js +45 -12
- package/configure/lib/alternateResponses.js.map +1 -1
- package/configure/lib/alternateSection.js +116 -19
- package/configure/lib/alternateSection.js.map +1 -1
- package/configure/lib/defaults.js +33 -0
- package/configure/lib/defaults.js.map +1 -1
- package/configure/lib/ecr-toolbar.js +19 -7
- package/configure/lib/ecr-toolbar.js.map +1 -1
- package/configure/lib/index.js +17 -3
- package/configure/lib/index.js.map +1 -1
- package/configure/lib/main.js +263 -42
- package/configure/lib/main.js.map +1 -1
- package/configure/lib/markupUtils.js +29 -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 +4 -4
- package/controller/CHANGELOG.md +91 -0
- package/controller/lib/index.js +99 -6
- package/controller/lib/index.js.map +1 -1
- package/controller/package.json +1 -1
- package/docs/config-schema.json +132 -0
- package/docs/config-schema.json.md +101 -1
- package/docs/demo/generate.js +3 -1
- package/docs/pie-schema.json +53 -0
- package/docs/pie-schema.json.md +38 -0
- package/lib/index.js +5 -1
- package/lib/index.js.map +1 -1
- package/lib/main.js +75 -24
- package/lib/main.js.map +1 -1
- package/lib/print.js +115 -0
- package/lib/print.js.map +1 -0
- package/package.json +11 -7
|
@@ -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"],"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,kBAAqBH,QAArB,uBAA0CC,QAA1C,yBAAiED,QAAjE,yBAAwFC,QAAxF,SAAsG,GAAtG,CAA3B;;AAEO,IAAMG,wBAAwB,GAAG,SAA3BA,wBAA2B,CAAAC,MAAM;AAAA,SAC5CA,MAAM,CAACC,OAAP,CAAeJ,kBAAf,EAAmC,EAAnC,EAAuCI,OAAvC,CAA+C,MAA/C,EAAuD,GAAvD,EAA4DA,OAA5D,CAAoE,OAApE,EAA6E,GAA7E,CAD4C;AAAA,CAAvC;;;;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,CAAAT,MAAM,EAAI;AACrC,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,UAAAC,CAAC,EAAI;AACvFA,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,CAAAC,MAAM,EAAI;AACzC,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(`(\\\\t(?!${tSymbols}))|(\\\\n(?!${nSymbols}))|(\\\\\\\\t(?!${tSymbols}))|(\\\\\\\\n(?!${nSymbols}))`, 'g');\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,CAAAC,MAAM,EAAI;AACjD,MAAQC,gBAAR,GAA6BD,MAA7B,CAAQC,gBAAR;AAEA,MAAMC,oBAAoB,GAAG,2CAC3B,6DAD2B,GAE3B,+BAF2B,IAG1BD,gBAAgB,yBAAkBA,gBAAlB,SAAwC,EAH9B,IAI3B,eAJ2B,IAIRA,gBAAgB,GAAG,GAAH,GAAS,EAJjB,IAIuB,WAJpD;AAMA,SAAO,6BAA6BC,oBAApC;AACD,CAVM","sourcesContent":["export const generateValidationMessage = config => {\n const { maxResponseAreas } = config;\n\n const responseAreasMessage = '\\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' + (maxResponseAreas ? 's' : '') + ' defined.';\n\n return 'Validation requirements:' + responseAreasMessage;\n};\n"],"file":"utils.js"}
|
package/configure/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-element/explicit-constructed-response-configure",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.1.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": "^11.0.20",
|
|
12
|
+
"@pie-lib/editable-html": "^9.2.2",
|
|
13
13
|
"classnames": "^2.2.6",
|
|
14
14
|
"debug": "^3.1.0",
|
|
15
15
|
"lodash": "^4.17.15",
|
package/controller/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,97 @@
|
|
|
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.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)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @pie-element/explicit-constructed-response-controller
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [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)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @pie-element/explicit-constructed-response-controller
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## [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)
|
|
23
|
+
|
|
24
|
+
**Note:** Version bump only for package @pie-element/explicit-constructed-response-controller
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## [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)
|
|
31
|
+
|
|
32
|
+
**Note:** Version bump only for package @pie-element/explicit-constructed-response-controller
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## [3.4.2](https://github.com/pie-framework/pie-elements/compare/@pie-element/explicit-constructed-response-controller@3.4.1...@pie-element/explicit-constructed-response-controller@3.4.2) (2021-11-29)
|
|
39
|
+
|
|
40
|
+
**Note:** Version bump only for package @pie-element/explicit-constructed-response-controller
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## [3.4.1](https://github.com/pie-framework/pie-elements/compare/@pie-element/explicit-constructed-response-controller@3.3.3...@pie-element/explicit-constructed-response-controller@3.4.1) (2021-11-11)
|
|
47
|
+
|
|
48
|
+
**Note:** Version bump only for package @pie-element/explicit-constructed-response-controller
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# [3.4.0](https://github.com/pie-framework/pie-elements/compare/@pie-element/explicit-constructed-response-controller@3.3.2...@pie-element/explicit-constructed-response-controller@3.4.0) (2021-11-11)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### Features
|
|
58
|
+
|
|
59
|
+
* **explicit-constructed-response:** Added a max limit of characters and adjusted the width PD-794 ([135f176](https://github.com/pie-framework/pie-elements/commit/135f176402187e9a6120b88768ae7fb0152ac418))
|
|
60
|
+
* **explicit-constructed-response:** Calculate maxChoicesLength if it's undefined. Fixed delete response area and choices bug. BREAKING CHANGE: add maxChoicesLength prop ([97431b9](https://github.com/pie-framework/pie-elements/commit/97431b9c3fbdafd84e040653c54d5f04bae16a1d))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
## [3.3.3](https://github.com/pie-framework/pie-elements/compare/@pie-element/explicit-constructed-response-controller@3.3.2...@pie-element/explicit-constructed-response-controller@3.3.3) (2021-10-18)
|
|
68
|
+
|
|
69
|
+
**Note:** Version bump only for package @pie-element/explicit-constructed-response-controller
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
## [3.3.2](https://github.com/pie-framework/pie-elements/compare/@pie-element/explicit-constructed-response-controller@3.3.0...@pie-element/explicit-constructed-response-controller@3.3.2) (2021-08-05)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
### Bug Fixes
|
|
79
|
+
|
|
80
|
+
* force bump ([5ea7295](https://github.com/pie-framework/pie-elements/commit/5ea7295e4755fbc492a76e7ec69e5fc35b196919))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# [3.3.0](https://github.com/pie-framework/pie-elements/compare/@pie-element/explicit-constructed-response-controller@3.2.16...@pie-element/explicit-constructed-response-controller@3.3.0) (2021-06-29)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
### Features
|
|
90
|
+
|
|
91
|
+
* Displayed a message when the item has one or more alternate answers - PD-167 ([#590](https://github.com/pie-framework/pie-elements/issues/590)) ([889d8b5](https://github.com/pie-framework/pie-elements/commit/889d8b578a915c997a95bd5cd4bdf18f53cc2b68))
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
6
97
|
## [3.2.16](https://github.com/pie-framework/pie-elements/compare/@pie-element/explicit-constructed-response-controller@3.2.13...@pie-element/explicit-constructed-response-controller@3.2.16) (2021-03-03)
|
|
7
98
|
|
|
8
99
|
**Note:** Version bump only for package @pie-element/explicit-constructed-response-controller
|
package/controller/lib/index.js
CHANGED
|
@@ -5,12 +5,18 @@ 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
|
+
|
|
18
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
19
|
+
|
|
14
20
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
15
21
|
|
|
16
22
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
@@ -27,9 +33,9 @@ var _debug = _interopRequireDefault(require("debug"));
|
|
|
27
33
|
|
|
28
34
|
var _controllerUtils = require("@pie-lib/controller-utils");
|
|
29
35
|
|
|
30
|
-
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; }
|
|
31
37
|
|
|
32
|
-
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; }
|
|
33
39
|
|
|
34
40
|
var log = (0, _debug["default"])('explicit-constructed-response:controller');
|
|
35
41
|
|
|
@@ -63,6 +69,23 @@ var getFeedback = function getFeedback(value) {
|
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
return 'incorrect';
|
|
72
|
+
}; // also used in configure/src/markupUtils.js
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
var getAdjustedLength = function getAdjustedLength(length) {
|
|
76
|
+
if (length <= 2) {
|
|
77
|
+
return length + 2;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (length <= 4) {
|
|
81
|
+
return length + 3;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (length <= 6) {
|
|
85
|
+
return length + 4;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return length + 5;
|
|
66
89
|
};
|
|
67
90
|
|
|
68
91
|
var normalize = function normalize(question) {
|
|
@@ -86,7 +109,7 @@ exports.normalize = normalize;
|
|
|
86
109
|
function model(question, session, env) {
|
|
87
110
|
return new Promise( /*#__PURE__*/function () {
|
|
88
111
|
var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(resolve) {
|
|
89
|
-
var normalizedQuestion, defaultFeedback, _ref2, _ref2$value, value, preparChoiceFn, choices, feedback, showNote, out;
|
|
112
|
+
var normalizedQuestion, defaultFeedback, _ref2, _ref2$value, value, preparChoiceFn, choices, feedback, showNote, _normalizedQuestion$m, maxLengthPerChoice, maxLengthPerChoiceEnabled, undefinedLengths, out;
|
|
90
113
|
|
|
91
114
|
return _regenerator["default"].wrap(function _callee$(_context) {
|
|
92
115
|
while (1) {
|
|
@@ -96,7 +119,7 @@ function model(question, session, env) {
|
|
|
96
119
|
// like: { label: 'test' }
|
|
97
120
|
if (question.choices) {
|
|
98
121
|
Object.keys(question.choices).forEach(function (key) {
|
|
99
|
-
question.choices[key] = question.choices[key].map(function (item, index) {
|
|
122
|
+
question.choices[key] = (question.choices[key] || []).map(function (item, index) {
|
|
100
123
|
if (!item.value) {
|
|
101
124
|
log('Choice does not contain "value" property, which is required.', item);
|
|
102
125
|
return _objectSpread({
|
|
@@ -140,6 +163,19 @@ function model(question, session, env) {
|
|
|
140
163
|
showNote = true;
|
|
141
164
|
}
|
|
142
165
|
});
|
|
166
|
+
_normalizedQuestion$m = normalizedQuestion.maxLengthPerChoice, maxLengthPerChoice = _normalizedQuestion$m === void 0 ? [] : _normalizedQuestion$m, maxLengthPerChoiceEnabled = normalizedQuestion.maxLengthPerChoiceEnabled;
|
|
167
|
+
undefinedLengths = !maxLengthPerChoice.length; // calculate maxLengthPerChoice array if it is not defined or defined incorrectly
|
|
168
|
+
|
|
169
|
+
Object.values(choices).forEach(function (choice, index) {
|
|
170
|
+
var labelLengthsArr = (choice || []).map(function (choice) {
|
|
171
|
+
return (choice.label || '').length;
|
|
172
|
+
});
|
|
173
|
+
var length = Math.max.apply(Math, (0, _toConsumableArray2["default"])(labelLengthsArr));
|
|
174
|
+
|
|
175
|
+
if (undefinedLengths || !maxLengthPerChoice[index] || maxLengthPerChoice[index] < length || maxLengthPerChoice[index] > length + 10) {
|
|
176
|
+
maxLengthPerChoice[index] = getAdjustedLength(length);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
143
179
|
out = {
|
|
144
180
|
disabled: env.mode !== 'gather',
|
|
145
181
|
mode: env.mode,
|
|
@@ -150,6 +186,10 @@ function model(question, session, env) {
|
|
|
150
186
|
env: env,
|
|
151
187
|
note: normalizedQuestion.note,
|
|
152
188
|
showNote: showNote,
|
|
189
|
+
maxLengthPerChoice: maxLengthPerChoice,
|
|
190
|
+
maxLengthPerChoiceEnabled: maxLengthPerChoiceEnabled,
|
|
191
|
+
displayType: normalizedQuestion.displayType,
|
|
192
|
+
playerSpellCheckEnabled: normalizedQuestion.playerSpellCheckEnabled,
|
|
153
193
|
responseCorrect: env.mode === 'evaluate' ? getScore(normalizedQuestion, session) === 1 : undefined
|
|
154
194
|
};
|
|
155
195
|
|
|
@@ -163,7 +203,7 @@ function model(question, session, env) {
|
|
|
163
203
|
|
|
164
204
|
resolve(out);
|
|
165
205
|
|
|
166
|
-
case
|
|
206
|
+
case 16:
|
|
167
207
|
case "end":
|
|
168
208
|
return _context.stop();
|
|
169
209
|
}
|
|
@@ -260,4 +300,57 @@ var createCorrectResponseSession = function createCorrectResponseSession(questio
|
|
|
260
300
|
};
|
|
261
301
|
|
|
262
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;
|
|
263
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","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","length","disabled","prompt","markup","note","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\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 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 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(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 = 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:\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\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
package/docs/config-schema.json
CHANGED
|
@@ -51,6 +51,38 @@
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
|
+
"spellCheck": {
|
|
55
|
+
"title": "ConfigureProp",
|
|
56
|
+
"type": "object",
|
|
57
|
+
"properties": {
|
|
58
|
+
"settings": {
|
|
59
|
+
"description": "Indicates if the item has to be displayed in the Settings Panel",
|
|
60
|
+
"type": "boolean",
|
|
61
|
+
"title": "settings"
|
|
62
|
+
},
|
|
63
|
+
"label": {
|
|
64
|
+
"description": "Indicates the label for the item that has to be displayed in the Settings Panel",
|
|
65
|
+
"type": "string",
|
|
66
|
+
"title": "label"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"playerSpellCheck": {
|
|
71
|
+
"title": "ConfigureProp",
|
|
72
|
+
"type": "object",
|
|
73
|
+
"properties": {
|
|
74
|
+
"settings": {
|
|
75
|
+
"description": "Indicates if the item has to be displayed in the Settings Panel",
|
|
76
|
+
"type": "boolean",
|
|
77
|
+
"title": "settings"
|
|
78
|
+
},
|
|
79
|
+
"label": {
|
|
80
|
+
"description": "Indicates the label for the item that has to be displayed in the Settings Panel",
|
|
81
|
+
"type": "string",
|
|
82
|
+
"title": "label"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
54
86
|
"autoScoring": {
|
|
55
87
|
"title": "ConfigureProp",
|
|
56
88
|
"type": "object",
|
|
@@ -131,6 +163,85 @@
|
|
|
131
163
|
}
|
|
132
164
|
}
|
|
133
165
|
},
|
|
166
|
+
"maxLengthPerChoice": {
|
|
167
|
+
"title": "ConfigureProp",
|
|
168
|
+
"type": "object",
|
|
169
|
+
"properties": {
|
|
170
|
+
"settings": {
|
|
171
|
+
"description": "Indicates if the item has to be displayed in the Settings Panel",
|
|
172
|
+
"type": "boolean",
|
|
173
|
+
"title": "settings"
|
|
174
|
+
},
|
|
175
|
+
"label": {
|
|
176
|
+
"description": "Indicates the label for the item that has to be displayed in the Settings Panel",
|
|
177
|
+
"type": "string",
|
|
178
|
+
"title": "label"
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"maxResponseAreas": {
|
|
183
|
+
"description": "Maximum number of response areas",
|
|
184
|
+
"type": "number",
|
|
185
|
+
"title": "maxResponseAreas"
|
|
186
|
+
},
|
|
187
|
+
"maxImageWidth": {
|
|
188
|
+
"title": "ConfigureMaxImageDimensionsProp",
|
|
189
|
+
"type": "object",
|
|
190
|
+
"properties": {
|
|
191
|
+
"teacherInstructions": {
|
|
192
|
+
"description": "Indicates the max dimension for images in teacher instructions",
|
|
193
|
+
"type": "number",
|
|
194
|
+
"title": "teacherInstructions"
|
|
195
|
+
},
|
|
196
|
+
"prompt": {
|
|
197
|
+
"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",
|
|
198
|
+
"type": "number",
|
|
199
|
+
"title": "prompt"
|
|
200
|
+
},
|
|
201
|
+
"rationale": {
|
|
202
|
+
"description": "Indicates the max dimension for images in rationale",
|
|
203
|
+
"type": "number",
|
|
204
|
+
"title": "rationale"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"maxImageHeight": {
|
|
209
|
+
"title": "ConfigureMaxImageDimensionsProp",
|
|
210
|
+
"type": "object",
|
|
211
|
+
"properties": {
|
|
212
|
+
"teacherInstructions": {
|
|
213
|
+
"description": "Indicates the max dimension for images in teacher instructions",
|
|
214
|
+
"type": "number",
|
|
215
|
+
"title": "teacherInstructions"
|
|
216
|
+
},
|
|
217
|
+
"prompt": {
|
|
218
|
+
"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",
|
|
219
|
+
"type": "number",
|
|
220
|
+
"title": "prompt"
|
|
221
|
+
},
|
|
222
|
+
"rationale": {
|
|
223
|
+
"description": "Indicates the max dimension for images in rationale",
|
|
224
|
+
"type": "number",
|
|
225
|
+
"title": "rationale"
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
"withRubric": {
|
|
230
|
+
"title": "ConfigureProp",
|
|
231
|
+
"type": "object",
|
|
232
|
+
"properties": {
|
|
233
|
+
"settings": {
|
|
234
|
+
"description": "Indicates if the item has to be displayed in the Settings Panel",
|
|
235
|
+
"type": "boolean",
|
|
236
|
+
"title": "settings"
|
|
237
|
+
},
|
|
238
|
+
"label": {
|
|
239
|
+
"description": "Indicates the label for the item that has to be displayed in the Settings Panel",
|
|
240
|
+
"type": "string",
|
|
241
|
+
"title": "label"
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
},
|
|
134
245
|
"showPrompt": {
|
|
135
246
|
"description": "Determines whether prompt field will be displayed or not",
|
|
136
247
|
"default": true,
|
|
@@ -166,6 +277,27 @@
|
|
|
166
277
|
"title": "label"
|
|
167
278
|
}
|
|
168
279
|
}
|
|
280
|
+
},
|
|
281
|
+
"ConfigureMaxImageDimensionsProp": {
|
|
282
|
+
"title": "ConfigureMaxImageDimensionsProp",
|
|
283
|
+
"type": "object",
|
|
284
|
+
"properties": {
|
|
285
|
+
"teacherInstructions": {
|
|
286
|
+
"description": "Indicates the max dimension for images in teacher instructions",
|
|
287
|
+
"type": "number",
|
|
288
|
+
"title": "teacherInstructions"
|
|
289
|
+
},
|
|
290
|
+
"prompt": {
|
|
291
|
+
"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",
|
|
292
|
+
"type": "number",
|
|
293
|
+
"title": "prompt"
|
|
294
|
+
},
|
|
295
|
+
"rationale": {
|
|
296
|
+
"description": "Indicates the max dimension for images in rationale",
|
|
297
|
+
"type": "number",
|
|
298
|
+
"title": "rationale"
|
|
299
|
+
}
|
|
300
|
+
}
|
|
169
301
|
}
|
|
170
302
|
},
|
|
171
303
|
"$schema": "http://json-schema.org/draft-07/schema#"
|