@pie-element/complex-rubric 2.2.0-next.1 → 2.2.1-next.12

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.
Files changed (71) hide show
  1. package/LICENSE.md +5 -0
  2. package/configure/lib/defaults.js +2 -2
  3. package/configure/lib/defaults.js.map +1 -1
  4. package/configure/lib/index.js +1 -1
  5. package/configure/lib/main.js +1 -1
  6. package/configure/node_modules/@pie-lib/render-ui/CHANGELOG.json +937 -0
  7. package/configure/node_modules/@pie-lib/render-ui/CHANGELOG.md +848 -0
  8. package/configure/node_modules/@pie-lib/render-ui/LICENSE.md +5 -0
  9. package/configure/node_modules/@pie-lib/render-ui/README.md +33 -0
  10. package/configure/node_modules/@pie-lib/render-ui/lib/collapsible/index.js +134 -0
  11. package/configure/node_modules/@pie-lib/render-ui/lib/collapsible/index.js.map +1 -0
  12. package/configure/node_modules/@pie-lib/render-ui/lib/color.js +157 -0
  13. package/configure/node_modules/@pie-lib/render-ui/lib/color.js.map +1 -0
  14. package/configure/node_modules/@pie-lib/render-ui/lib/feedback.js +151 -0
  15. package/configure/node_modules/@pie-lib/render-ui/lib/feedback.js.map +1 -0
  16. package/configure/node_modules/@pie-lib/render-ui/lib/has-text.js +24 -0
  17. package/configure/node_modules/@pie-lib/render-ui/lib/has-text.js.map +1 -0
  18. package/configure/node_modules/@pie-lib/render-ui/lib/html-and-math.js +90 -0
  19. package/configure/node_modules/@pie-lib/render-ui/lib/html-and-math.js.map +1 -0
  20. package/configure/node_modules/@pie-lib/render-ui/lib/index.js +104 -0
  21. package/configure/node_modules/@pie-lib/render-ui/lib/index.js.map +1 -0
  22. package/configure/node_modules/@pie-lib/render-ui/lib/input-container.js +60 -0
  23. package/configure/node_modules/@pie-lib/render-ui/lib/input-container.js.map +1 -0
  24. package/configure/node_modules/@pie-lib/render-ui/lib/preview-layout.js +133 -0
  25. package/configure/node_modules/@pie-lib/render-ui/lib/preview-layout.js.map +1 -0
  26. package/configure/node_modules/@pie-lib/render-ui/lib/preview-prompt.js +206 -0
  27. package/configure/node_modules/@pie-lib/render-ui/lib/preview-prompt.js.map +1 -0
  28. package/configure/node_modules/@pie-lib/render-ui/lib/purpose.js +28 -0
  29. package/configure/node_modules/@pie-lib/render-ui/lib/purpose.js.map +1 -0
  30. package/configure/node_modules/@pie-lib/render-ui/lib/readable.js +28 -0
  31. package/configure/node_modules/@pie-lib/render-ui/lib/readable.js.map +1 -0
  32. package/configure/node_modules/@pie-lib/render-ui/lib/response-indicators.js +151 -0
  33. package/configure/node_modules/@pie-lib/render-ui/lib/response-indicators.js.map +1 -0
  34. package/configure/node_modules/@pie-lib/render-ui/lib/withUndoReset.js +181 -0
  35. package/configure/node_modules/@pie-lib/render-ui/lib/withUndoReset.js.map +1 -0
  36. package/configure/node_modules/@pie-lib/render-ui/package.json +30 -0
  37. package/configure/node_modules/@pie-lib/render-ui/src/collapsible/index.jsx +63 -0
  38. package/configure/node_modules/@pie-lib/render-ui/src/color.js +55 -0
  39. package/configure/node_modules/@pie-lib/render-ui/src/feedback.jsx +100 -0
  40. package/configure/node_modules/@pie-lib/render-ui/src/has-text.js +14 -0
  41. package/configure/node_modules/@pie-lib/render-ui/src/html-and-math.js +34 -0
  42. package/configure/node_modules/@pie-lib/render-ui/src/index.js +27 -0
  43. package/configure/node_modules/@pie-lib/render-ui/src/input-container.jsx +41 -0
  44. package/configure/node_modules/@pie-lib/render-ui/src/preview-layout.jsx +84 -0
  45. package/configure/node_modules/@pie-lib/render-ui/src/preview-prompt.jsx +130 -0
  46. package/configure/node_modules/@pie-lib/render-ui/src/purpose.jsx +17 -0
  47. package/configure/node_modules/@pie-lib/render-ui/src/readable.jsx +19 -0
  48. package/configure/node_modules/@pie-lib/render-ui/src/response-indicators.jsx +89 -0
  49. package/configure/node_modules/@pie-lib/render-ui/src/withUndoReset.jsx +116 -0
  50. package/configure/src/defaults.js +1 -1
  51. package/controller/lib/defaults.js +2 -2
  52. package/controller/lib/defaults.js.map +1 -1
  53. package/controller/lib/index.js +1 -1
  54. package/controller/lib/utils.js +1 -1
  55. package/controller/src/defaults.js +1 -1
  56. package/docs/demo/generate.js +1 -1
  57. package/lib/index.js +1 -1
  58. package/lib/print.js +1 -1
  59. package/module/configure.js +232989 -0
  60. package/module/controller.js +375 -0
  61. package/module/demo.js +1 -1
  62. package/module/element.js +57005 -34984
  63. package/module/manifest.json +1 -1
  64. package/module/print-demo.js +1 -1
  65. package/module/print.js +57005 -34984
  66. package/package.json +4 -4
  67. package/configure/lib/__tests__/index.test.js +0 -57
  68. package/configure/lib/__tests__/main.test.js +0 -138
  69. package/controller/lib/__tests__/index.test.js +0 -134
  70. package/docs/demo/pie.manifest.json +0 -11
  71. package/lib/__tests__/index.test.js +0 -127
@@ -0,0 +1,375 @@
1
+ const multiTraitDefaultModel = {
2
+ visibleToStudent: true,
3
+ halfScoring: false,
4
+ pointLabels: true,
5
+ description: false,
6
+ standards: false,
7
+ scales: [],
8
+ excludeZero: false,
9
+ };
10
+
11
+ const rubricDefaultModel = {
12
+ points: ['', '', '', ''],
13
+ sampleAnswers: [null, null, null, null],
14
+ maxPoints: 4,
15
+ excludeZero: false,
16
+ };
17
+
18
+ const rubriclessDefaultModel = {
19
+ maxPoints: 100,
20
+ excludeZero: false,
21
+ rubriclessInstructionEnabled: true,
22
+ };
23
+
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
+ var defaults = {
148
+ model: {
149
+ rubricOptions: ['simpleRubric', 'multiTraitRubric'],
150
+ rubricType: 'simpleRubric',
151
+ rubrics: { simpleRubric: rubricDefaultModel, multiTraitRubric: multiTraitDefaultModel, rubricless: rubriclessDefaultModel },
152
+ },
153
+ configuration: {
154
+ multiTraitRubric: multiTraitDefaultConfiguration,
155
+ simpleRubric: rubricDefaultConfiguration,
156
+ rubricless: rubriclessDefaultConfiguration,
157
+ },
158
+ };
159
+
160
+ const markupToText = (s) => {
161
+ return (s || '').replace(/(<([^>]+)>)/ig, '');
162
+ };
163
+
164
+ // todo the import from pie-lib/rubric might break webpack
165
+ const RUBRIC_TYPES = {
166
+ SIMPLE_RUBRIC: 'simpleRubric',
167
+ MULTI_TRAIT_RUBRIC: 'multiTraitRubric',
168
+ 'rubricless': 'rubricless',
169
+ };
170
+
171
+ function createDefaultModel(model = {}) {
172
+ return new Promise((resolve) => resolve({ ...defaults.model, ...model }));
173
+ }
174
+
175
+ const normalize = (question) => ({ ...defaults.model, ...question });
176
+
177
+ /**
178
+ * @param {*} question
179
+ * @param {*} session
180
+ * @param {*} env
181
+ */
182
+ async function model(question, session, env) {
183
+ const normalizedQuestion = normalize(question);
184
+
185
+ if (normalizedQuestion.rubricType === RUBRIC_TYPES.SIMPLE_RUBRIC || normalizedQuestion.rubricType === 'rubricless') {
186
+ return new Promise((resolve) => {
187
+ resolve(
188
+ env && env.role && env.role === 'instructor'
189
+ ? {
190
+ ...normalizedQuestion,
191
+ rubrics: {
192
+ ...normalizedQuestion.rubrics,
193
+ multiTraitRubric: {
194
+ ...normalizedQuestion.rubrics.multiTraitRubric,
195
+ visible: false,
196
+ },
197
+ },
198
+ }
199
+ : {},
200
+ );
201
+ });
202
+ } else {
203
+ if (
204
+ !env.role ||
205
+ (env.role === 'student' && normalizedQuestion.rubrics && normalizedQuestion.rubrics.multiTraitRubric)
206
+ ) {
207
+ normalizedQuestion.rubrics.multiTraitRubric.visible = normalizedQuestion.visibleToStudent;
208
+ } else {
209
+ normalizedQuestion.rubrics.multiTraitRubric.visible = true;
210
+ }
211
+
212
+ // todo update pie-ui instead of parsing this here:
213
+ const { scales, excludeZero } = normalizedQuestion.rubrics.multiTraitRubric || {};
214
+ const parsedScales = (scales || []).map((scale) => ({ ...scale, excludeZero }));
215
+
216
+ return {
217
+ ...normalizedQuestion,
218
+ rubrics: {
219
+ ...normalizedQuestion.rubrics,
220
+ simpleRubric: {
221
+ ...normalizedQuestion.rubrics.simpleRubric,
222
+ visible: false,
223
+ },
224
+ rubricless: {
225
+ ...normalizedQuestion.rubrics.rubricless,
226
+ visible: false,
227
+ },
228
+ multiTraitRubric: {
229
+ ...normalizedQuestion.rubrics.multiTraitRubric,
230
+ scales: parsedScales,
231
+ },
232
+ },
233
+ };
234
+ }
235
+ }
236
+
237
+ const getScore = () => 0;
238
+
239
+ /**
240
+ * @param {Object} model - the main model
241
+ * @param {*} session
242
+ * @param {Object} env
243
+ */
244
+ function outcome() {
245
+ return new Promise((resolve) => resolve({ score: 0, empty: true }));
246
+ }
247
+
248
+ const createCorrectResponseSession = (question, env) => {
249
+ return new Promise((resolve) => {
250
+ if (env.mode !== 'evaluate' && env.role === 'instructor') {
251
+ resolve({ id: '1' });
252
+ } else {
253
+ resolve(null);
254
+ }
255
+ });
256
+ };
257
+
258
+ // IMPORTANT! This function is a duplicate of rubric/controller/validate function!
259
+ // If you make any changes to this function, please make sure you also update rubric/controller/validate function!“.
260
+ const validateSimpleRubric = (model) => {
261
+ const { points } = model;
262
+ const errors = {};
263
+ const pointsDescriptorsErrors = {};
264
+
265
+ (points || []).forEach((point, index) => {
266
+ if(!point|| point === '<div></div>') {
267
+ pointsDescriptorsErrors[index] = 'Points descriptors cannot be empty.';
268
+ }
269
+ else {
270
+ const identicalPointDescr = points.slice(index + 1).some(p => markupToText(p) === markupToText(point));
271
+
272
+ if (identicalPointDescr) {
273
+ pointsDescriptorsErrors[index] = 'Points descriptors should be unique.';
274
+ }
275
+ }
276
+ });
277
+
278
+ if(Object.keys(pointsDescriptorsErrors).length > 0){
279
+ errors.pointsDescriptorsErrors = pointsDescriptorsErrors;
280
+ }
281
+
282
+ return errors;
283
+ };
284
+
285
+ // IMPORTANT! This function is a duplicate of multi-trait-rubric/controller/validate function!
286
+ // If you make any changes to this function, please make sure you also update multi-trait-rubric/controller/validate function!“.
287
+ const validateMultiTraitRubric = (model) => {
288
+ const { scales, description = false, pointLabels = false } = model;
289
+ const errors = {};
290
+ const traitsErrors = {};
291
+ const scorePointsErrors = {};
292
+
293
+ (scales || []).forEach((scale, scaleIndex) => {
294
+ const { traits = [] } = scale;
295
+ const { scorePointsLabels = [] } = scale;
296
+ const scaleErrors = {};
297
+ const scorePointsLabelsErrors = {};
298
+
299
+ if(pointLabels) {
300
+ scorePointsLabels.forEach((scorePointLabel, scoreIndex) => {
301
+ if (!scorePointLabel || scorePointLabel === '<div></div>') {
302
+ scorePointsLabelsErrors[scoreIndex] = 'Points labels should not be empty.';
303
+ } else {
304
+ const identicalScorePointLabel = scorePointsLabels.slice(scoreIndex + 1).some(s => markupToText(s) === markupToText(scorePointLabel));
305
+
306
+ if (identicalScorePointLabel) {
307
+ scorePointsLabelsErrors[scoreIndex] = 'Points labels should be unique.';
308
+ }
309
+ }
310
+ });
311
+ }
312
+
313
+ if(Object.keys(scorePointsLabelsErrors).length > 0){
314
+ scorePointsErrors[scaleIndex] = scorePointsLabelsErrors;
315
+ }
316
+
317
+ traits.forEach((trait, traitIndex) => {
318
+ if(!trait.name || trait.name === '<div></div>') {
319
+ scaleErrors[traitIndex] = {name: 'Trait names should not be empty.'};
320
+ }
321
+ else {
322
+ const identicalTraitName = traits.slice(traitIndex + 1).some(t => markupToText(t.name) === markupToText(trait.name));
323
+
324
+ if (identicalTraitName) {
325
+ scaleErrors[traitIndex] = {name: 'Trait names should be unique.'};
326
+ }
327
+ }
328
+ if(description && (!trait.description || trait.description === '<div></div>')) {
329
+ scaleErrors[traitIndex] = {... scaleErrors[traitIndex], description: 'Trait description should not be empty'};
330
+ }
331
+ else {
332
+ const identicalTraitDescr = traits.slice(traitIndex + 1).some(t => markupToText(t.description) === markupToText(trait.description));
333
+
334
+ if (description && identicalTraitDescr) {
335
+ scaleErrors[traitIndex] = {... scaleErrors[traitIndex], description: 'Trait descriptions should be unique.'};
336
+ }
337
+ }
338
+
339
+ });
340
+ if(Object.keys(scaleErrors).length > 0){
341
+ traitsErrors[scaleIndex] = scaleErrors;
342
+ }
343
+ });
344
+
345
+ if(Object.keys(traitsErrors).length > 0){
346
+ errors.traitsErrors = traitsErrors;
347
+ }
348
+
349
+ if(Object.keys(scorePointsErrors).length > 0){
350
+ errors.scorePointsErrors = scorePointsErrors;
351
+ }
352
+
353
+ return errors;
354
+ };
355
+
356
+
357
+ const validate = (model = {}, config = {}) => {
358
+ const { rubrics = {}, rubricType } = model;
359
+ const { multiTraitRubric = {}, simpleRubric = {} } = rubrics;
360
+ let errors = {};
361
+
362
+ switch (rubricType) {
363
+ case RUBRIC_TYPES.SIMPLE_RUBRIC:
364
+ default:
365
+ errors = validateSimpleRubric(simpleRubric);
366
+ break;
367
+ case RUBRIC_TYPES.MULTI_TRAIT_RUBRIC:
368
+ errors = validateMultiTraitRubric(multiTraitRubric);
369
+ break;
370
+ }
371
+
372
+ return errors;
373
+ };
374
+
375
+ export { createCorrectResponseSession, createDefaultModel, getScore, model, normalize, outcome, validate };
package/module/demo.js CHANGED
@@ -8,7 +8,7 @@ generate.model = (id, element) => ({
8
8
  id,
9
9
  element,
10
10
  rubricType: 'simpleRubric',
11
- rubricOptions: ['simpleRubric', 'multiTraitRubric', 'rubricless'],
11
+ rubricOptions: ['simpleRubric', 'multiTraitRubric'],
12
12
  rubrics: {
13
13
  simpleRubric: {
14
14
  points: ['nothing right', 'a teeny bit right', 'mostly right', 'bingo'],