@pie-element/complex-rubric 3.1.3 → 3.1.4-next.43
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/configure/lib/defaults.js +4 -4
- package/configure/lib/defaults.js.map +1 -1
- package/configure/src/defaults.js +4 -4
- package/controller/lib/defaults.js +21 -109
- package/controller/lib/defaults.js.map +1 -1
- package/controller/lib/index.js +5 -4
- package/controller/lib/index.js.map +1 -1
- package/controller/package.json +1 -1
- package/controller/src/__tests__/index.test.js +2 -2
- package/controller/src/defaults.js +18 -137
- package/controller/src/index.js +41 -34
- package/module/configure.js +34 -19
- package/module/controller.js +57 -170
- package/module/element.js +24 -9
- package/module/index.html +1 -1
- package/module/manifest.json +3 -3
- package/module/print.html +1 -1
- package/module/print.js +24 -9
- package/package.json +4 -4
package/controller/src/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import defaults from './defaults';
|
|
2
2
|
import { markupToText } from './utils';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
// todo the import from pie-lib/rubric WILL break pslb
|
|
6
|
+
// so don't use it unless you also test "yarn build"
|
|
5
7
|
const RUBRIC_TYPES = {
|
|
6
8
|
SIMPLE_RUBRIC: 'simpleRubric',
|
|
7
9
|
MULTI_TRAIT_RUBRIC: 'multiTraitRubric',
|
|
@@ -9,10 +11,10 @@ const RUBRIC_TYPES = {
|
|
|
9
11
|
};
|
|
10
12
|
|
|
11
13
|
export function createDefaultModel(model = {}) {
|
|
12
|
-
return new Promise((resolve) => resolve({ ...defaults
|
|
14
|
+
return new Promise((resolve) => resolve({ ...defaults, ...model }));
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
export const normalize = (question) => ({ ...defaults
|
|
17
|
+
export const normalize = (question) => ({ ...defaults, ...question });
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* @param {*} question
|
|
@@ -22,20 +24,23 @@ export const normalize = (question) => ({ ...defaults.model, ...question });
|
|
|
22
24
|
export async function model(question, session, env) {
|
|
23
25
|
const normalizedQuestion = normalize(question);
|
|
24
26
|
|
|
25
|
-
if (
|
|
27
|
+
if (
|
|
28
|
+
normalizedQuestion.rubricType === RUBRIC_TYPES.SIMPLE_RUBRIC ||
|
|
29
|
+
normalizedQuestion.rubricType === RUBRIC_TYPES.RUBRICLESS
|
|
30
|
+
) {
|
|
26
31
|
return new Promise((resolve) => {
|
|
27
32
|
resolve(
|
|
28
33
|
env && env.role && env.role === 'instructor'
|
|
29
34
|
? {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
...normalizedQuestion,
|
|
36
|
+
rubrics: {
|
|
37
|
+
...normalizedQuestion.rubrics,
|
|
38
|
+
multiTraitRubric: {
|
|
39
|
+
...normalizedQuestion.rubrics.multiTraitRubric,
|
|
40
|
+
visible: false,
|
|
41
|
+
},
|
|
36
42
|
},
|
|
37
|
-
}
|
|
38
|
-
}
|
|
43
|
+
}
|
|
39
44
|
: {},
|
|
40
45
|
);
|
|
41
46
|
});
|
|
@@ -111,7 +116,7 @@ const validateSimpleRubric = (model) => {
|
|
|
111
116
|
if (!point || point === '<div></div>') {
|
|
112
117
|
pointsDescriptorsErrors[index] = 'Points descriptors cannot be empty.';
|
|
113
118
|
} else {
|
|
114
|
-
const identicalPointDescr = points.slice(index + 1).some(p => markupToText(p) === markupToText(point));
|
|
119
|
+
const identicalPointDescr = points.slice(index + 1).some((p) => markupToText(p) === markupToText(point));
|
|
115
120
|
|
|
116
121
|
if (identicalPointDescr) {
|
|
117
122
|
pointsDescriptorsErrors[index] = 'Points descriptors should be unique.';
|
|
@@ -140,64 +145,66 @@ const validateMultiTraitRubric = (model) => {
|
|
|
140
145
|
const scaleErrors = {};
|
|
141
146
|
const scorePointsLabelsErrors = {};
|
|
142
147
|
|
|
143
|
-
if(pointLabels) {
|
|
148
|
+
if (pointLabels) {
|
|
144
149
|
scorePointsLabels.forEach((scorePointLabel, scoreIndex) => {
|
|
145
150
|
if (!scorePointLabel || scorePointLabel === '<div></div>') {
|
|
146
151
|
scorePointsLabelsErrors[scoreIndex] = 'Points labels should not be empty.';
|
|
147
152
|
} else {
|
|
148
|
-
const identicalScorePointLabel = scorePointsLabels
|
|
153
|
+
const identicalScorePointLabel = scorePointsLabels
|
|
154
|
+
.slice(scoreIndex + 1)
|
|
155
|
+
.some((s) => markupToText(s) === markupToText(scorePointLabel));
|
|
149
156
|
|
|
150
157
|
if (identicalScorePointLabel) {
|
|
151
158
|
scorePointsLabelsErrors[scoreIndex] = 'Points labels should be unique.';
|
|
152
159
|
}
|
|
153
160
|
}
|
|
154
|
-
})
|
|
161
|
+
});
|
|
155
162
|
}
|
|
156
163
|
|
|
157
|
-
if(Object.keys(scorePointsLabelsErrors).length > 0){
|
|
164
|
+
if (Object.keys(scorePointsLabelsErrors).length > 0) {
|
|
158
165
|
scorePointsErrors[scaleIndex] = scorePointsLabelsErrors;
|
|
159
166
|
}
|
|
160
167
|
|
|
161
168
|
traits.forEach((trait, traitIndex) => {
|
|
162
|
-
if(!trait.name || trait.name === '<div></div>') {
|
|
163
|
-
scaleErrors[traitIndex] = {name: 'Trait names should not be empty.'};
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
|
|
169
|
+
if (!trait.name || trait.name === '<div></div>') {
|
|
170
|
+
scaleErrors[traitIndex] = { name: 'Trait names should not be empty.' };
|
|
171
|
+
} else {
|
|
172
|
+
const identicalTraitName = traits
|
|
173
|
+
.slice(traitIndex + 1)
|
|
174
|
+
.some((t) => markupToText(t.name) === markupToText(trait.name));
|
|
167
175
|
|
|
168
176
|
if (identicalTraitName) {
|
|
169
|
-
scaleErrors[traitIndex] = {name: 'Trait names should be unique.'};
|
|
177
|
+
scaleErrors[traitIndex] = { name: 'Trait names should be unique.' };
|
|
170
178
|
}
|
|
171
179
|
}
|
|
172
|
-
if(description && (!trait.description || trait.description === '<div></div>')) {
|
|
173
|
-
scaleErrors[traitIndex] = {...
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
180
|
+
if (description && (!trait.description || trait.description === '<div></div>')) {
|
|
181
|
+
scaleErrors[traitIndex] = { ...scaleErrors[traitIndex], description: 'Trait description should not be empty' };
|
|
182
|
+
} else {
|
|
183
|
+
const identicalTraitDescr = traits
|
|
184
|
+
.slice(traitIndex + 1)
|
|
185
|
+
.some((t) => markupToText(t.description) === markupToText(trait.description));
|
|
177
186
|
|
|
178
187
|
if (description && identicalTraitDescr) {
|
|
179
|
-
scaleErrors[traitIndex] = {...
|
|
188
|
+
scaleErrors[traitIndex] = { ...scaleErrors[traitIndex], description: 'Trait descriptions should be unique.' };
|
|
180
189
|
}
|
|
181
190
|
}
|
|
182
|
-
|
|
183
191
|
});
|
|
184
|
-
if(Object.keys(scaleErrors).length > 0){
|
|
192
|
+
if (Object.keys(scaleErrors).length > 0) {
|
|
185
193
|
traitsErrors[scaleIndex] = scaleErrors;
|
|
186
194
|
}
|
|
187
195
|
});
|
|
188
196
|
|
|
189
|
-
if(Object.keys(traitsErrors).length > 0){
|
|
197
|
+
if (Object.keys(traitsErrors).length > 0) {
|
|
190
198
|
errors.traitsErrors = traitsErrors;
|
|
191
199
|
}
|
|
192
200
|
|
|
193
|
-
if(Object.keys(scorePointsErrors).length > 0){
|
|
201
|
+
if (Object.keys(scorePointsErrors).length > 0) {
|
|
194
202
|
errors.scorePointsErrors = scorePointsErrors;
|
|
195
203
|
}
|
|
196
204
|
|
|
197
205
|
return errors;
|
|
198
206
|
};
|
|
199
207
|
|
|
200
|
-
|
|
201
208
|
export const validate = (model = {}, config = {}) => {
|
|
202
209
|
const { rubrics = {}, rubricType } = model;
|
|
203
210
|
const { multiTraitRubric = {}, simpleRubric = {} } = rubrics;
|
package/module/configure.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {_dll_react, _dll_prop_types, _dll_classnames, _dll_react_dom, _dll_debug, _dll_lodash, _dll_react_dom_server, _dll_pie_framework__mathquill} from "../../../@pie-lib/pie-toolbox-math-rendering-module@2.0.
|
|
1
|
+
import {_dll_react, _dll_prop_types, _dll_classnames, _dll_react_dom, _dll_debug, _dll_lodash, _dll_react_dom_server, _dll_pie_framework__mathquill} from "../../../@pie-lib/pie-toolbox-math-rendering-module@2.0.12/module/index.js";
|
|
2
2
|
import RubricConfigure from '@pie-element/rubric/configure/lib';
|
|
3
|
-
import {_dll_pie_lib__pie_toolbox_editable_html, _dll_pie_lib__pie_toolbox_render_ui, _dll_pie_lib__pie_toolbox_config_ui} from "../../../@pie-lib/pie-toolbox-module@5.0.
|
|
3
|
+
import {_dll_pie_lib__pie_toolbox_editable_html, _dll_pie_lib__pie_toolbox_render_ui, _dll_pie_lib__pie_toolbox_config_ui} from "../../../@pie-lib/pie-toolbox-module@5.0.11/module/index.js";
|
|
4
4
|
function _mergeNamespaces(n, m) {
|
|
5
5
|
m.forEach(function (e) {
|
|
6
6
|
e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
|
|
@@ -68486,15 +68486,15 @@ var defaults$1 = {};
|
|
|
68486
68486
|
exports["default"] = void 0;
|
|
68487
68487
|
var _default = {
|
|
68488
68488
|
model: {
|
|
68489
|
-
|
|
68490
|
-
halfScoring: false,
|
|
68491
|
-
pointLabels: true,
|
|
68489
|
+
addScaleEnabled: true,
|
|
68492
68490
|
description: false,
|
|
68493
|
-
standards: false,
|
|
68494
|
-
scales: [],
|
|
68495
68491
|
excludeZero: false,
|
|
68492
|
+
halfScoring: false,
|
|
68496
68493
|
maxPointsEnabled: true,
|
|
68497
|
-
|
|
68494
|
+
pointLabels: true,
|
|
68495
|
+
scales: [],
|
|
68496
|
+
standards: false,
|
|
68497
|
+
visibleToStudent: true
|
|
68498
68498
|
},
|
|
68499
68499
|
configuration: {
|
|
68500
68500
|
baseInputConfiguration: {
|
|
@@ -88966,6 +88966,7 @@ toolbarButtons.RawMarkButton = RawMarkButton;
|
|
|
88966
88966
|
(0, _defineProperty2$O["default"])(RawMarkButton, "propTypes", {
|
|
88967
88967
|
onToggle: _propTypes$1g["default"].func.isRequired,
|
|
88968
88968
|
mark: _propTypes$1g["default"].string,
|
|
88969
|
+
label: _propTypes$1g["default"].string.isRequired,
|
|
88969
88970
|
children: _propTypes$1g["default"].oneOfType([_propTypes$1g["default"].arrayOf(_propTypes$1g["default"].node), _propTypes$1g["default"].node]).isRequired,
|
|
88970
88971
|
classes: _propTypes$1g["default"].object.isRequired,
|
|
88971
88972
|
active: _propTypes$1g["default"].bool
|
|
@@ -97478,12 +97479,19 @@ const require$$10$q = _dll_debug;
|
|
|
97478
97479
|
if (props.isMark) {
|
|
97479
97480
|
var isActive = (0, _utils.hasMark)(props.value, props.type);
|
|
97480
97481
|
log('[ToolbarButton] mark:isActive: ', isActive);
|
|
97482
|
+
var ariaLabel;
|
|
97483
|
+
if (props.type === 'sup') {
|
|
97484
|
+
ariaLabel = 'Superscript (marks text as superscripted)';
|
|
97485
|
+
} else if (props.type === 'sub') {
|
|
97486
|
+
ariaLabel = 'Subscript (marks text as subscripted)';
|
|
97487
|
+
} else {
|
|
97488
|
+
ariaLabel = props.type;
|
|
97489
|
+
}
|
|
97481
97490
|
return _react["default"].createElement(_toolbarButtons.MarkButton, {
|
|
97482
97491
|
active: isActive,
|
|
97483
|
-
label: props.type,
|
|
97484
97492
|
onToggle: onToggle,
|
|
97485
97493
|
mark: props.type,
|
|
97486
|
-
|
|
97494
|
+
label: ariaLabel
|
|
97487
97495
|
}, props.icon);
|
|
97488
97496
|
} else {
|
|
97489
97497
|
var disabled = props.disabled;
|
|
@@ -100288,7 +100296,8 @@ const require$$3$y = _dll_prop_types;
|
|
|
100288
100296
|
border: '1px solid #C0C3CF',
|
|
100289
100297
|
boxSizing: 'border-box',
|
|
100290
100298
|
borderRadius: '3px',
|
|
100291
|
-
position: 'relative'
|
|
100299
|
+
position: 'relative',
|
|
100300
|
+
alignItems: 'center'
|
|
100292
100301
|
}
|
|
100293
100302
|
}, _react["default"].createElement("div", {
|
|
100294
100303
|
style: {
|
|
@@ -100296,13 +100305,17 @@ const require$$3$y = _dll_prop_types;
|
|
|
100296
100305
|
overflow: 'hidden',
|
|
100297
100306
|
padding: '0 25px 0 8px',
|
|
100298
100307
|
whiteSpace: 'nowrap',
|
|
100299
|
-
textOverflow: 'ellipsis'
|
|
100300
|
-
|
|
100308
|
+
textOverflow: 'ellipsis'
|
|
100309
|
+
}
|
|
100310
|
+
}, _react["default"].createElement("span", {
|
|
100311
|
+
style: {
|
|
100312
|
+
display: 'inline-block',
|
|
100313
|
+
verticalAlign: 'middle'
|
|
100301
100314
|
},
|
|
100302
100315
|
dangerouslySetInnerHTML: {
|
|
100303
100316
|
__html: html
|
|
100304
100317
|
}
|
|
100305
|
-
}), _react["default"].createElement(_icons.Chevron, {
|
|
100318
|
+
})), _react["default"].createElement(_icons.Chevron, {
|
|
100306
100319
|
direction: "down",
|
|
100307
100320
|
style: {
|
|
100308
100321
|
position: 'absolute',
|
|
@@ -105628,6 +105641,7 @@ function UndoRedo(type) {
|
|
|
105628
105641
|
toolbar: {
|
|
105629
105642
|
type: type,
|
|
105630
105643
|
icon: _react$1e["default"].createElement(IconToUse, null),
|
|
105644
|
+
ariaLabel: type === 'undo' ? 'Undo (revert the last action)' : 'Redo (reapply the last undone action)',
|
|
105631
105645
|
onClick: function onClick(value, onChange) {
|
|
105632
105646
|
var change = value.change();
|
|
105633
105647
|
onChange(change[type]());
|
|
@@ -114689,7 +114703,8 @@ const require$$23 = _dll_classnames;
|
|
|
114689
114703
|
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "renderPlaceholder", function (props) {
|
|
114690
114704
|
var editor = props.editor;
|
|
114691
114705
|
var document = editor.value.document;
|
|
114692
|
-
|
|
114706
|
+
var stateValue = _this.state.value;
|
|
114707
|
+
if (!editor.props.placeholder || document.text !== '' || document.nodes.size !== 1 || !document.isEmpty || stateValue.isFocused) {
|
|
114693
114708
|
return false;
|
|
114694
114709
|
}
|
|
114695
114710
|
return _react["default"].createElement("span", {
|
|
@@ -188862,13 +188877,13 @@ class Main extends React$1.Component {
|
|
|
188862
188877
|
Main.__initStatic();
|
|
188863
188878
|
var Main$1 = styles$1J.withStyles(styles)(Main);
|
|
188864
188879
|
const multiTraitDefaultModel = {
|
|
188865
|
-
|
|
188880
|
+
description: false,
|
|
188881
|
+
excludeZero: false,
|
|
188866
188882
|
halfScoring: false,
|
|
188867
188883
|
pointLabels: true,
|
|
188868
|
-
description: false,
|
|
188869
|
-
standards: false,
|
|
188870
188884
|
scales: [],
|
|
188871
|
-
|
|
188885
|
+
standards: false,
|
|
188886
|
+
visibleToStudent: true
|
|
188872
188887
|
};
|
|
188873
188888
|
const rubricDefaultModel = {
|
|
188874
188889
|
points: ['', '', '', ''],
|
package/module/controller.js
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
|
+
// todo the import from pie-lib/rubric WILL break pslb
|
|
2
|
+
// so don't use it unless you also test "yarn build"
|
|
3
|
+
const RUBRIC_TYPES$1 = {
|
|
4
|
+
SIMPLE_RUBRIC: 'simpleRubric',
|
|
5
|
+
MULTI_TRAIT_RUBRIC: 'multiTraitRubric',
|
|
6
|
+
'rubricless': 'rubricless',
|
|
7
|
+
};
|
|
8
|
+
|
|
1
9
|
const multiTraitDefaultModel = {
|
|
2
|
-
|
|
10
|
+
description: false,
|
|
11
|
+
excludeZero: false,
|
|
3
12
|
halfScoring: false,
|
|
4
13
|
pointLabels: true,
|
|
5
|
-
description: false,
|
|
6
|
-
standards: false,
|
|
7
14
|
scales: [],
|
|
8
|
-
|
|
15
|
+
standards: false,
|
|
16
|
+
visibleToStudent: true,
|
|
9
17
|
};
|
|
10
18
|
|
|
11
19
|
const rubricDefaultModel = {
|
|
12
20
|
points: ['', '', '', ''],
|
|
13
21
|
sampleAnswers: [null, null, null, null],
|
|
14
|
-
maxPoints:
|
|
22
|
+
maxPoints: 3,
|
|
15
23
|
excludeZero: false,
|
|
16
24
|
};
|
|
17
25
|
|
|
@@ -21,139 +29,12 @@ const rubriclessDefaultModel = {
|
|
|
21
29
|
rubriclessInstructionEnabled: true,
|
|
22
30
|
};
|
|
23
31
|
|
|
24
|
-
const multiTraitDefaultConfiguration = {
|
|
25
|
-
settingsPanelDisabled: false,
|
|
26
|
-
excludeZeroDialogBoxContent: {
|
|
27
|
-
title: 'Exclude 0 (Zero) from Score Point Values.',
|
|
28
|
-
text: `<div>
|
|
29
|
-
You are about to exclude 0 from score point values.
|
|
30
|
-
<br/>
|
|
31
|
-
Some of the existing data has to be changed.
|
|
32
|
-
<br/>
|
|
33
|
-
Please choose if you want to:
|
|
34
|
-
<ul>
|
|
35
|
-
<li>
|
|
36
|
-
shift Labels and Descriptions to the left
|
|
37
|
-
</li>
|
|
38
|
-
<li>
|
|
39
|
-
remove 0 column with its Label and Description
|
|
40
|
-
</li>
|
|
41
|
-
</ul>
|
|
42
|
-
</div>`,
|
|
43
|
-
},
|
|
44
|
-
includeZeroDialogBoxContent: {
|
|
45
|
-
title: 'Include 0 (Zero) in Score Point Values.',
|
|
46
|
-
text: `<div>
|
|
47
|
-
You are about to include 0 in score point values.
|
|
48
|
-
<br/>
|
|
49
|
-
Some of the existing data has to be changed.
|
|
50
|
-
<br/>
|
|
51
|
-
Please choose if you want to:
|
|
52
|
-
<ul>
|
|
53
|
-
<li>
|
|
54
|
-
shift Labels and Descriptions to the right
|
|
55
|
-
</li>
|
|
56
|
-
<li>
|
|
57
|
-
add 0 column with empty Label and Descriptions
|
|
58
|
-
</li>
|
|
59
|
-
</ul>
|
|
60
|
-
</div>`,
|
|
61
|
-
},
|
|
62
|
-
deleteScaleDialogBoxContent: {
|
|
63
|
-
title: 'Delete Scale',
|
|
64
|
-
text: 'Are you sure you want to delete this scale?',
|
|
65
|
-
},
|
|
66
|
-
maxPointsDialogBoxContent: {
|
|
67
|
-
title: 'Decreasing Max Points.',
|
|
68
|
-
text: ` You are about to decrease max score point value.
|
|
69
|
-
<br/>
|
|
70
|
-
All the Labels and Descriptions for scores above Max Point will be deleted.`,
|
|
71
|
-
},
|
|
72
|
-
spellCheck: {
|
|
73
|
-
label: 'Spellcheck',
|
|
74
|
-
settings: false,
|
|
75
|
-
enabled: true,
|
|
76
|
-
},
|
|
77
|
-
showExcludeZero: {
|
|
78
|
-
settings: true,
|
|
79
|
-
label: 'Exclude Zero',
|
|
80
|
-
},
|
|
81
|
-
showScorePointLabels: {
|
|
82
|
-
settings: true,
|
|
83
|
-
label: 'Show Score Point Labels',
|
|
84
|
-
},
|
|
85
|
-
showDescription: {
|
|
86
|
-
settings: true,
|
|
87
|
-
label: 'Show Description',
|
|
88
|
-
},
|
|
89
|
-
showVisibleToStudent: {
|
|
90
|
-
settings: true,
|
|
91
|
-
label: 'Visible to Student',
|
|
92
|
-
},
|
|
93
|
-
showHalfScoring: {
|
|
94
|
-
settings: true,
|
|
95
|
-
label: 'Half Scoring',
|
|
96
|
-
},
|
|
97
|
-
width: '900px',
|
|
98
|
-
// these should not be set to true (should not be used) for now
|
|
99
|
-
showStandards: {
|
|
100
|
-
settings: false,
|
|
101
|
-
label: 'Show Standards',
|
|
102
|
-
},
|
|
103
|
-
showLevelTagInput: {
|
|
104
|
-
settings: false,
|
|
105
|
-
label: 'Show Level Tag Input',
|
|
106
|
-
enabled: false,
|
|
107
|
-
},
|
|
108
|
-
dragAndDrop: {
|
|
109
|
-
settings: true,
|
|
110
|
-
label: 'Enable Drag and Drop',
|
|
111
|
-
enabled: false,
|
|
112
|
-
},
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
const rubricDefaultConfiguration = {
|
|
116
|
-
showExcludeZero: {
|
|
117
|
-
settings: true,
|
|
118
|
-
label: 'Ability to exclude zero',
|
|
119
|
-
},
|
|
120
|
-
showMaxPoint: {
|
|
121
|
-
settings: true,
|
|
122
|
-
label: 'Show max points dropdown',
|
|
123
|
-
},
|
|
124
|
-
settingsPanelDisabled: false,
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
const rubriclessDefaultConfiguration = {
|
|
128
|
-
showExcludeZero: {
|
|
129
|
-
settings: true,
|
|
130
|
-
label: 'Ability to exclude zero',
|
|
131
|
-
},
|
|
132
|
-
showMaxPoint: {
|
|
133
|
-
settings: true,
|
|
134
|
-
label: 'Show max points dropdown',
|
|
135
|
-
},
|
|
136
|
-
settingsPanelDisabled: false,
|
|
137
|
-
// shows us if it simple rubric or rubricless(simple rubric with less structure)
|
|
138
|
-
rubricless: true,
|
|
139
|
-
// scoring instruction for rubricless
|
|
140
|
-
rubriclessInstruction: {
|
|
141
|
-
settings: true,
|
|
142
|
-
label: 'Instruction',
|
|
143
|
-
},
|
|
144
|
-
maxMaxPoints: 100,
|
|
145
|
-
};
|
|
146
|
-
|
|
147
32
|
var defaults = {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
configuration: {
|
|
154
|
-
multiTraitRubric: multiTraitDefaultConfiguration,
|
|
155
|
-
simpleRubric: rubricDefaultConfiguration,
|
|
156
|
-
rubricless: rubriclessDefaultConfiguration,
|
|
33
|
+
rubricType: 'simpleRubric',
|
|
34
|
+
rubrics: {
|
|
35
|
+
[RUBRIC_TYPES$1.SIMPLE_RUBRIC]: rubricDefaultModel,
|
|
36
|
+
[RUBRIC_TYPES$1.MULTI_TRAIT_RUBRIC]: multiTraitDefaultModel,
|
|
37
|
+
[RUBRIC_TYPES$1.RUBRICLESS]: rubriclessDefaultModel,
|
|
157
38
|
},
|
|
158
39
|
};
|
|
159
40
|
|
|
@@ -161,7 +42,8 @@ const markupToText = (s) => {
|
|
|
161
42
|
return (s || '').replace(/(<([^>]+)>)/ig, '');
|
|
162
43
|
};
|
|
163
44
|
|
|
164
|
-
// todo the import from pie-lib/rubric
|
|
45
|
+
// todo the import from pie-lib/rubric WILL break pslb
|
|
46
|
+
// so don't use it unless you also test "yarn build"
|
|
165
47
|
const RUBRIC_TYPES = {
|
|
166
48
|
SIMPLE_RUBRIC: 'simpleRubric',
|
|
167
49
|
MULTI_TRAIT_RUBRIC: 'multiTraitRubric',
|
|
@@ -169,10 +51,10 @@ const RUBRIC_TYPES = {
|
|
|
169
51
|
};
|
|
170
52
|
|
|
171
53
|
function createDefaultModel(model = {}) {
|
|
172
|
-
return new Promise((resolve) => resolve({ ...defaults
|
|
54
|
+
return new Promise((resolve) => resolve({ ...defaults, ...model }));
|
|
173
55
|
}
|
|
174
56
|
|
|
175
|
-
const normalize = (question) => ({ ...defaults
|
|
57
|
+
const normalize = (question) => ({ ...defaults, ...question });
|
|
176
58
|
|
|
177
59
|
/**
|
|
178
60
|
* @param {*} question
|
|
@@ -182,20 +64,23 @@ const normalize = (question) => ({ ...defaults.model, ...question });
|
|
|
182
64
|
async function model(question, session, env) {
|
|
183
65
|
const normalizedQuestion = normalize(question);
|
|
184
66
|
|
|
185
|
-
if (
|
|
67
|
+
if (
|
|
68
|
+
normalizedQuestion.rubricType === RUBRIC_TYPES.SIMPLE_RUBRIC ||
|
|
69
|
+
normalizedQuestion.rubricType === RUBRIC_TYPES.RUBRICLESS
|
|
70
|
+
) {
|
|
186
71
|
return new Promise((resolve) => {
|
|
187
72
|
resolve(
|
|
188
73
|
env && env.role && env.role === 'instructor'
|
|
189
74
|
? {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
75
|
+
...normalizedQuestion,
|
|
76
|
+
rubrics: {
|
|
77
|
+
...normalizedQuestion.rubrics,
|
|
78
|
+
multiTraitRubric: {
|
|
79
|
+
...normalizedQuestion.rubrics.multiTraitRubric,
|
|
80
|
+
visible: false,
|
|
81
|
+
},
|
|
196
82
|
},
|
|
197
|
-
}
|
|
198
|
-
}
|
|
83
|
+
}
|
|
199
84
|
: {},
|
|
200
85
|
);
|
|
201
86
|
});
|
|
@@ -271,7 +156,7 @@ const validateSimpleRubric = (model) => {
|
|
|
271
156
|
if (!point || point === '<div></div>') {
|
|
272
157
|
pointsDescriptorsErrors[index] = 'Points descriptors cannot be empty.';
|
|
273
158
|
} else {
|
|
274
|
-
const identicalPointDescr = points.slice(index + 1).some(p => markupToText(p) === markupToText(point));
|
|
159
|
+
const identicalPointDescr = points.slice(index + 1).some((p) => markupToText(p) === markupToText(point));
|
|
275
160
|
|
|
276
161
|
if (identicalPointDescr) {
|
|
277
162
|
pointsDescriptorsErrors[index] = 'Points descriptors should be unique.';
|
|
@@ -300,12 +185,14 @@ const validateMultiTraitRubric = (model) => {
|
|
|
300
185
|
const scaleErrors = {};
|
|
301
186
|
const scorePointsLabelsErrors = {};
|
|
302
187
|
|
|
303
|
-
if(pointLabels) {
|
|
188
|
+
if (pointLabels) {
|
|
304
189
|
scorePointsLabels.forEach((scorePointLabel, scoreIndex) => {
|
|
305
190
|
if (!scorePointLabel || scorePointLabel === '<div></div>') {
|
|
306
191
|
scorePointsLabelsErrors[scoreIndex] = 'Points labels should not be empty.';
|
|
307
192
|
} else {
|
|
308
|
-
const identicalScorePointLabel = scorePointsLabels
|
|
193
|
+
const identicalScorePointLabel = scorePointsLabels
|
|
194
|
+
.slice(scoreIndex + 1)
|
|
195
|
+
.some((s) => markupToText(s) === markupToText(scorePointLabel));
|
|
309
196
|
|
|
310
197
|
if (identicalScorePointLabel) {
|
|
311
198
|
scorePointsLabelsErrors[scoreIndex] = 'Points labels should be unique.';
|
|
@@ -314,50 +201,50 @@ const validateMultiTraitRubric = (model) => {
|
|
|
314
201
|
});
|
|
315
202
|
}
|
|
316
203
|
|
|
317
|
-
if(Object.keys(scorePointsLabelsErrors).length > 0){
|
|
204
|
+
if (Object.keys(scorePointsLabelsErrors).length > 0) {
|
|
318
205
|
scorePointsErrors[scaleIndex] = scorePointsLabelsErrors;
|
|
319
206
|
}
|
|
320
207
|
|
|
321
208
|
traits.forEach((trait, traitIndex) => {
|
|
322
|
-
if(!trait.name || trait.name === '<div></div>') {
|
|
323
|
-
scaleErrors[traitIndex] = {name: 'Trait names should not be empty.'};
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
|
|
209
|
+
if (!trait.name || trait.name === '<div></div>') {
|
|
210
|
+
scaleErrors[traitIndex] = { name: 'Trait names should not be empty.' };
|
|
211
|
+
} else {
|
|
212
|
+
const identicalTraitName = traits
|
|
213
|
+
.slice(traitIndex + 1)
|
|
214
|
+
.some((t) => markupToText(t.name) === markupToText(trait.name));
|
|
327
215
|
|
|
328
216
|
if (identicalTraitName) {
|
|
329
|
-
scaleErrors[traitIndex] = {name: 'Trait names should be unique.'};
|
|
217
|
+
scaleErrors[traitIndex] = { name: 'Trait names should be unique.' };
|
|
330
218
|
}
|
|
331
219
|
}
|
|
332
|
-
if(description && (!trait.description || trait.description === '<div></div>')) {
|
|
333
|
-
scaleErrors[traitIndex] = {...
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
|
|
220
|
+
if (description && (!trait.description || trait.description === '<div></div>')) {
|
|
221
|
+
scaleErrors[traitIndex] = { ...scaleErrors[traitIndex], description: 'Trait description should not be empty' };
|
|
222
|
+
} else {
|
|
223
|
+
const identicalTraitDescr = traits
|
|
224
|
+
.slice(traitIndex + 1)
|
|
225
|
+
.some((t) => markupToText(t.description) === markupToText(trait.description));
|
|
337
226
|
|
|
338
227
|
if (description && identicalTraitDescr) {
|
|
339
|
-
scaleErrors[traitIndex] = {...
|
|
228
|
+
scaleErrors[traitIndex] = { ...scaleErrors[traitIndex], description: 'Trait descriptions should be unique.' };
|
|
340
229
|
}
|
|
341
230
|
}
|
|
342
|
-
|
|
343
231
|
});
|
|
344
|
-
if(Object.keys(scaleErrors).length > 0){
|
|
232
|
+
if (Object.keys(scaleErrors).length > 0) {
|
|
345
233
|
traitsErrors[scaleIndex] = scaleErrors;
|
|
346
234
|
}
|
|
347
235
|
});
|
|
348
236
|
|
|
349
|
-
if(Object.keys(traitsErrors).length > 0){
|
|
237
|
+
if (Object.keys(traitsErrors).length > 0) {
|
|
350
238
|
errors.traitsErrors = traitsErrors;
|
|
351
239
|
}
|
|
352
240
|
|
|
353
|
-
if(Object.keys(scorePointsErrors).length > 0){
|
|
241
|
+
if (Object.keys(scorePointsErrors).length > 0) {
|
|
354
242
|
errors.scorePointsErrors = scorePointsErrors;
|
|
355
243
|
}
|
|
356
244
|
|
|
357
245
|
return errors;
|
|
358
246
|
};
|
|
359
247
|
|
|
360
|
-
|
|
361
248
|
const validate = (model = {}, config = {}) => {
|
|
362
249
|
const { rubrics = {}, rubricType } = model;
|
|
363
250
|
const { multiTraitRubric = {}, simpleRubric = {} } = rubrics;
|