@pie-element/multiple-choice 6.2.0 → 6.2.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +346 -0
  2. package/README.md +1 -1
  3. package/configure/CHANGELOG.md +321 -0
  4. package/configure/lib/defaults.js +22 -1
  5. package/configure/lib/defaults.js.map +1 -1
  6. package/configure/lib/index.js +16 -2
  7. package/configure/lib/index.js.map +1 -1
  8. package/configure/lib/main.js +204 -159
  9. package/configure/lib/main.js.map +1 -1
  10. package/configure/lib/utils.js +18 -0
  11. package/configure/lib/utils.js.map +1 -0
  12. package/configure/package.json +5 -5
  13. package/controller/CHANGELOG.md +35 -0
  14. package/controller/lib/defaults.js.map +1 -1
  15. package/controller/lib/index.js +61 -3
  16. package/controller/lib/index.js.map +1 -1
  17. package/controller/lib/utils.js.map +1 -1
  18. package/controller/package.json +2 -2
  19. package/docs/config-schema.json +115 -0
  20. package/docs/config-schema.json.md +89 -1
  21. package/docs/demo/config.js +2 -2
  22. package/docs/demo/generate.js +13 -11
  23. package/docs/demo/index.html +1 -1
  24. package/docs/demo/session.js +1 -1
  25. package/docs/pie-schema.json +38 -0
  26. package/docs/pie-schema.json.md +28 -0
  27. package/lib/choice-input.js +17 -10
  28. package/lib/choice-input.js.map +1 -1
  29. package/lib/choice.js +14 -3
  30. package/lib/choice.js.map +1 -1
  31. package/lib/index.js +1 -1
  32. package/lib/index.js.map +1 -1
  33. package/lib/main.js +4 -1
  34. package/lib/main.js.map +1 -1
  35. package/lib/multiple-choice.js +12 -3
  36. package/lib/multiple-choice.js.map +1 -1
  37. package/lib/print.js +2 -0
  38. package/lib/print.js.map +1 -1
  39. package/lib/session-updater.js.map +1 -1
  40. package/package.json +6 -6
  41. package/module/configure.js +0 -771
  42. package/module/controller.js +0 -20641
  43. package/module/demo.js +0 -77
  44. package/module/element.js +0 -2004
  45. package/module/index.html +0 -21
  46. package/module/manifest.json +0 -14
  47. package/module/print-demo.js +0 -115
  48. package/module/print.html +0 -18
  49. package/module/print.js +0 -1966
@@ -1,771 +0,0 @@
1
- import {_dll_react, _dll_prop_types, _dll_material_ui__core_styles, _dll_material_ui__core, _dll_lodash, _dll_pie_lib__render_ui, _dll_debug, _dll_react_dom} from "../../../@pie-lib/shared-module@^1.2.17/module/index.js";
2
- import {_dll_pie_lib__config_ui} from "../../../@pie-lib/config-module@^1.0.18/module/index.js";
3
- import {_dll_pie_lib__editable_html} from "../../../@pie-lib/editable-html-module@^1.0.18/module/index.js";
4
- var lib = {};
5
- Object.defineProperty(lib, "__esModule", {
6
- value: true
7
- });
8
- class ModelUpdatedEvent extends CustomEvent {
9
- constructor(update, reset = false) {
10
- super(ModelUpdatedEvent.TYPE, {
11
- bubbles: true,
12
- detail: {
13
- update,
14
- reset
15
- }
16
- });
17
- this.update = update;
18
- this.reset = reset;
19
- }
20
- }
21
- ModelUpdatedEvent.TYPE = 'model.updated';
22
- var ModelUpdatedEvent_1 = lib.ModelUpdatedEvent = ModelUpdatedEvent;
23
- class DeleteImageEvent extends CustomEvent {
24
- constructor(src, done) {
25
- super(DeleteImageEvent.TYPE, {
26
- bubbles: true,
27
- detail: {
28
- src,
29
- done
30
- }
31
- });
32
- this.src = src;
33
- this.done = done;
34
- }
35
- }
36
- DeleteImageEvent.TYPE = 'delete.image';
37
- var DeleteImageEvent_1 = lib.DeleteImageEvent = DeleteImageEvent;
38
- class InsertImageEvent extends CustomEvent {
39
- constructor(handler) {
40
- super(InsertImageEvent.TYPE, {
41
- bubbles: true,
42
- detail: handler
43
- });
44
- this.handler = handler;
45
- }
46
- }
47
- InsertImageEvent.TYPE = 'insert.image';
48
- var InsertImageEvent_1 = lib.InsertImageEvent = InsertImageEvent;
49
- const React$1 = _dll_react;
50
- const PropTypes = _dll_prop_types;
51
- const {color: color} = _dll_pie_lib__render_ui;
52
- const {withStyles: withStyles} = _dll_material_ui__core_styles;
53
- const {Button: Button} = _dll_material_ui__core;
54
- const {Tooltip: Tooltip} = _dll_material_ui__core;
55
- const {Dialog: Dialog} = _dll_material_ui__core;
56
- const {DialogTitle: DialogTitle} = _dll_material_ui__core;
57
- const {DialogActions: DialogActions} = _dll_material_ui__core;
58
- const {merge: merge} = _dll_lodash;
59
- const EditableHtml = _dll_pie_lib__editable_html;
60
- const {InputContainer: InputContainer} = _dll_pie_lib__config_ui;
61
- const {ChoiceConfiguration: ChoiceConfiguration} = _dll_pie_lib__config_ui;
62
- const {settings: settings} = _dll_pie_lib__config_ui;
63
- const {layout: layout} = _dll_pie_lib__config_ui;
64
- const {choiceUtils: utils$1} = _dll_pie_lib__config_ui;
65
- const _jsxFileName = "/home/circleci/repo/packages/multiple-choice/configure/src/main.jsx";
66
- const {Panel, toggle, radio, dropdown} = settings;
67
- const MAX_CHOICES = 9;
68
- const styles = theme => ({
69
- promptHolder: {
70
- width: '100%',
71
- paddingBottom: theme.spacing.unit * 2,
72
- marginBottom: theme.spacing.unit * 2
73
- },
74
- prompt: {
75
- paddingTop: theme.spacing.unit * 2,
76
- width: '100%'
77
- },
78
- rationaleHolder: {
79
- width: '70%'
80
- },
81
- accessibilityHolder: {
82
- width: '70%'
83
- },
84
- rationale: {
85
- paddingTop: theme.spacing.unit * 2
86
- },
87
- accessibility: {
88
- paddingTop: theme.spacing.unit * 2
89
- },
90
- design: {
91
- paddingTop: theme.spacing.unit * 3
92
- },
93
- choiceConfigurationHolder: {
94
- display: 'flex',
95
- flexDirection: 'column',
96
- alignItems: 'center'
97
- },
98
- choiceConfiguration: {
99
- width: '100%',
100
- paddingTop: theme.spacing.unit * 2,
101
- paddingBottom: theme.spacing.unit * 2
102
- },
103
- switchElement: {
104
- justifyContent: 'space-between',
105
- margin: 0
106
- },
107
- addButton: {
108
- float: 'right'
109
- },
110
- disableButton: {
111
- cursor: 'not-allowed',
112
- pointerEvents: 'all',
113
- backgroundColor: color.disabled(),
114
- '&:hover': {
115
- backgroundColor: color.disabled()
116
- },
117
- '&:focus': {
118
- backgroundColor: color.disabled()
119
- }
120
- }
121
- });
122
- const Design = withStyles(styles)(props => {
123
- const {classes, model, configuration, onPromptChanged, onChoiceChanged, onRemoveChoice, onAddChoice, imageSupport, onChangeModel, onConfigurationChanged, onTeacherInstructionsChanged} = props;
124
- const {prompt = {}, addChoiceButton = {}, feedback = {}, deleteChoice = {}, choiceMode = {}, choicePrefix = {}, partialScoring = {}, lockChoiceOrder = {}, teacherInstructions = {}, studentInstructions = {}, rationale = {}, accessibility = {}, scoringType = {}, sequentialChoiceLabels = {}, settingsPanelDisabled, choicesLayout, gridColumns} = configuration || ({});
125
- let {maxAnswerChoices} = configuration || ({});
126
- const {limitChoicesNumber, teacherInstructionsEnabled, rationaleEnabled, accessibilityLabelsEnabled, feedbackEnabled, promptEnabled, choices} = model || ({});
127
- const nrOfColumnsAvailable = choices && choices.length ? Array.from({
128
- length: choices.length
129
- }, (_, i) => `${i + 1}`) : [];
130
- const labelPlugins = {
131
- audio: {
132
- disabled: true
133
- },
134
- video: {
135
- disabled: true
136
- }
137
- };
138
- const toolbarOpts = {};
139
- switch (model.toolbarEditorPosition) {
140
- case 'top':
141
- toolbarOpts.position = 'top';
142
- break;
143
- default:
144
- toolbarOpts.position = 'bottom';
145
- break;
146
- }
147
- if (limitChoicesNumber) {
148
- maxAnswerChoices = MAX_CHOICES;
149
- }
150
- const Content = React$1.createElement('div', {
151
- __self: undefined,
152
- __source: {
153
- fileName: _jsxFileName,
154
- lineNumber: 149
155
- }
156
- }, teacherInstructionsEnabled && React$1.createElement(InputContainer, {
157
- label: teacherInstructions.label,
158
- className: classes.promptHolder,
159
- __self: undefined,
160
- __source: {
161
- fileName: _jsxFileName,
162
- lineNumber: 151
163
- }
164
- }, React$1.createElement(EditableHtml, {
165
- className: classes.prompt,
166
- markup: model.teacherInstructions || '',
167
- onChange: onTeacherInstructionsChanged,
168
- imageSupport: imageSupport,
169
- nonEmpty: false,
170
- toolbarOpts: toolbarOpts,
171
- __self: undefined,
172
- __source: {
173
- fileName: _jsxFileName,
174
- lineNumber: 155
175
- }
176
- })), promptEnabled && React$1.createElement(InputContainer, {
177
- label: prompt.label,
178
- className: classes.promptHolder,
179
- __self: undefined,
180
- __source: {
181
- fileName: _jsxFileName,
182
- lineNumber: 167
183
- }
184
- }, React$1.createElement(EditableHtml, {
185
- className: classes.prompt,
186
- markup: model.prompt,
187
- onChange: onPromptChanged,
188
- imageSupport: imageSupport,
189
- nonEmpty: false,
190
- disableUnderline: true,
191
- toolbarOpts: toolbarOpts,
192
- __self: undefined,
193
- __source: {
194
- fileName: _jsxFileName,
195
- lineNumber: 168
196
- }
197
- })), model.choices.map((choice, index) => React$1.createElement('div', {
198
- key: `choice-${index}`,
199
- className: classes.choiceConfigurationHolder,
200
- __self: undefined,
201
- __source: {
202
- fileName: _jsxFileName,
203
- lineNumber: 180
204
- }
205
- }, React$1.createElement(ChoiceConfiguration, {
206
- key: index,
207
- index: index + 1,
208
- useLetterOrdering: model.choicePrefix === 'letters',
209
- className: classes.choiceConfiguration,
210
- mode: model.choiceMode,
211
- data: choice,
212
- defaultFeedback: {},
213
- imageSupport: imageSupport,
214
- onDelete: () => onRemoveChoice(index),
215
- onChange: c => onChoiceChanged(index, c),
216
- allowFeedBack: feedbackEnabled,
217
- allowDelete: deleteChoice.settings,
218
- noLabels: true,
219
- toolbarOpts: toolbarOpts,
220
- __self: undefined,
221
- __source: {
222
- fileName: _jsxFileName,
223
- lineNumber: 184
224
- }
225
- }), rationaleEnabled && React$1.createElement(InputContainer, {
226
- key: `rationale-${index}`,
227
- label: rationale.label,
228
- className: classes.rationaleHolder,
229
- __self: undefined,
230
- __source: {
231
- fileName: _jsxFileName,
232
- lineNumber: 201
233
- }
234
- }, React$1.createElement(EditableHtml, {
235
- className: classes.rationale,
236
- markup: choice.rationale || '',
237
- onChange: c => onChoiceChanged(index, {
238
- ...choice,
239
- rationale: c
240
- }),
241
- imageSupport: imageSupport,
242
- toolbarOpts: toolbarOpts,
243
- pluginProps: labelPlugins,
244
- __self: undefined,
245
- __source: {
246
- fileName: _jsxFileName,
247
- lineNumber: 206
248
- }
249
- })), accessibilityLabelsEnabled && React$1.createElement(InputContainer, {
250
- key: `accessibility-${index}`,
251
- label: accessibility.label,
252
- className: classes.accessibilityHolder,
253
- __self: undefined,
254
- __source: {
255
- fileName: _jsxFileName,
256
- lineNumber: 222
257
- }
258
- }, React$1.createElement(EditableHtml, {
259
- className: classes.accessibility,
260
- markup: choice.accessibility || '',
261
- onChange: c => onChoiceChanged(index, {
262
- ...choice,
263
- accessibility: c
264
- }),
265
- imageSupport: imageSupport,
266
- pluginProps: labelPlugins,
267
- __self: undefined,
268
- __source: {
269
- fileName: _jsxFileName,
270
- lineNumber: 227
271
- }
272
- })))), React$1.createElement('br', {
273
- __self: undefined,
274
- __source: {
275
- fileName: _jsxFileName,
276
- lineNumber: 243
277
- }
278
- }), addChoiceButton.settings && React$1.createElement(Tooltip, {
279
- title: maxAnswerChoices && model.choices.length >= maxAnswerChoices ? `Only ${maxAnswerChoices} allowed maximum` : '',
280
- classes: {
281
- tooltip: classes.tooltip
282
- },
283
- __self: undefined,
284
- __source: {
285
- fileName: _jsxFileName,
286
- lineNumber: 245
287
- }
288
- }, React$1.createElement(Button, {
289
- classes: {
290
- root: maxAnswerChoices && model.choices.length >= maxAnswerChoices ? classes.disableButton : undefined
291
- },
292
- className: classes.addButton,
293
- variant: "contained",
294
- color: "primary",
295
- onClick: onAddChoice,
296
- __self: undefined,
297
- __source: {
298
- fileName: _jsxFileName,
299
- lineNumber: 246
300
- }
301
- }, addChoiceButton.label)));
302
- const settingsInPanel = {
303
- choiceMode: choiceMode.settings && radio(choiceMode.label, ['checkbox', 'radio']),
304
- 'sequentialChoiceLabels.enabled': sequentialChoiceLabels.settings && toggle(sequentialChoiceLabels.label, true),
305
- choicePrefix: choicePrefix.settings && radio(choicePrefix.label, ['numbers', 'letters']),
306
- partialScoring: partialScoring.settings && toggle(partialScoring.label),
307
- lockChoiceOrder: lockChoiceOrder.settings && toggle(lockChoiceOrder.label),
308
- feedbackEnabled: feedback.settings && toggle(feedback.label),
309
- choicesLayout: choicesLayout.settings && dropdown(choicesLayout.label, ['vertical', 'grid', 'horizontal']),
310
- gridColumns: choicesLayout.settings && model.choicesLayout === 'grid' && nrOfColumnsAvailable.length > 0 && dropdown(gridColumns.label, nrOfColumnsAvailable)
311
- };
312
- return React$1.createElement('div', {
313
- className: classes.design,
314
- __self: undefined,
315
- __source: {
316
- fileName: _jsxFileName,
317
- lineNumber: 284
318
- }
319
- }, settingsPanelDisabled ? Content : React$1.createElement(layout.ConfigLayout, {
320
- settings: React$1.createElement(Panel, {
321
- model: model,
322
- onChangeModel: onChangeModel,
323
- configuration: configuration,
324
- onChangeConfiguration: onConfigurationChanged,
325
- groups: {
326
- Settings: settingsInPanel,
327
- Properties: {
328
- teacherInstructionsEnabled: teacherInstructions.settings && toggle(teacherInstructions.label),
329
- studentInstructionsEnabled: studentInstructions.settings && toggle(studentInstructions.label),
330
- promptEnabled: prompt.settings && toggle(prompt.label),
331
- rationaleEnabled: rationale.settings && toggle(rationale.label),
332
- accessibilityLabelsEnabled: accessibility.settings && toggle(accessibility.label),
333
- scoringType: scoringType.settings && radio(scoringType.label, ['auto', 'rubric'])
334
- }
335
- },
336
- __self: undefined,
337
- __source: {
338
- fileName: _jsxFileName,
339
- lineNumber: 290
340
- }
341
- }),
342
- __self: undefined,
343
- __source: {
344
- fileName: _jsxFileName,
345
- lineNumber: 288
346
- }
347
- }, Content));
348
- });
349
- const InfoDialog = ({open, onCancel, onOk, title}) => React$1.createElement(Dialog, {
350
- open: open,
351
- __self: undefined,
352
- __source: {
353
- fileName: _jsxFileName,
354
- lineNumber: 325
355
- }
356
- }, React$1.createElement(DialogTitle, {
357
- __self: undefined,
358
- __source: {
359
- fileName: _jsxFileName,
360
- lineNumber: 326
361
- }
362
- }, title), React$1.createElement(DialogActions, {
363
- __self: undefined,
364
- __source: {
365
- fileName: _jsxFileName,
366
- lineNumber: 327
367
- }
368
- }, onOk && React$1.createElement(Button, {
369
- onClick: onOk,
370
- color: "primary",
371
- __self: undefined,
372
- __source: {
373
- fileName: _jsxFileName,
374
- lineNumber: 329
375
- }
376
- }, "OK"), onCancel && React$1.createElement(Button, {
377
- onClick: onCancel,
378
- color: "primary",
379
- __self: undefined,
380
- __source: {
381
- fileName: _jsxFileName,
382
- lineNumber: 334
383
- }
384
- }, "Cancel")));
385
- InfoDialog.propTypes = {
386
- open: PropTypes.bool,
387
- onCancel: PropTypes.func,
388
- onOk: PropTypes.func,
389
- title: PropTypes.string
390
- };
391
- class Main extends React$1.Component {
392
- constructor(...args) {
393
- super(...args);
394
- Main.prototype.__init.call(this);
395
- Main.prototype.__init2.call(this);
396
- Main.prototype.__init3.call(this);
397
- Main.prototype.__init4.call(this);
398
- Main.prototype.__init5.call(this);
399
- Main.prototype.__init6.call(this);
400
- Main.prototype.__init7.call(this);
401
- }
402
- static __initStatic() {
403
- this.propTypes = {
404
- model: PropTypes.object.isRequired,
405
- configuration: PropTypes.object.isRequired,
406
- disableSidePanel: PropTypes.bool,
407
- onModelChanged: PropTypes.func.isRequired,
408
- onConfigurationChanged: PropTypes.func.isRequired,
409
- classes: PropTypes.object.isRequired,
410
- imageSupport: PropTypes.shape({
411
- add: PropTypes.func.isRequired,
412
- delete: PropTypes.func.isRequired
413
- })
414
- };
415
- }
416
- __init() {
417
- this.state = {
418
- dialog: {
419
- open: false
420
- }
421
- };
422
- }
423
- __init2() {
424
- this.onRemoveChoice = index => {
425
- const {model, configuration} = this.props;
426
- const {minAnswerChoices} = configuration || ({});
427
- if (minAnswerChoices && model.choices.length === minAnswerChoices) {
428
- this.setState({
429
- dialog: {
430
- open: true,
431
- message: `There can't be less than ${minAnswerChoices} choices.`,
432
- onOk: () => {
433
- this.setState({
434
- dialog: {
435
- open: false
436
- }
437
- });
438
- },
439
- onCancel: () => this.setState({
440
- dialog: {
441
- open: false
442
- }
443
- })
444
- }
445
- });
446
- } else {
447
- model.choices.splice(index, 1);
448
- this.props.onModelChanged(model);
449
- }
450
- };
451
- }
452
- __init3() {
453
- this.onAddChoice = () => {
454
- const {model, configuration} = this.props;
455
- let {maxAnswerChoices} = configuration || ({});
456
- const {limitChoicesNumber} = model || ({});
457
- if (limitChoicesNumber) {
458
- maxAnswerChoices = MAX_CHOICES;
459
- }
460
- if (maxAnswerChoices && model.choices.length === maxAnswerChoices) {
461
- this.setState({
462
- dialog: {
463
- open: true,
464
- message: `There can't be more than ${maxAnswerChoices} choices.`,
465
- onOk: () => {
466
- this.setState({
467
- dialog: {
468
- open: false
469
- }
470
- });
471
- },
472
- onCancel: () => this.setState({
473
- dialog: {
474
- open: false
475
- }
476
- })
477
- }
478
- });
479
- } else {
480
- model.choices.push({
481
- label: '',
482
- value: utils$1.firstAvailableIndex(model.choices.map(c => c.value), 0),
483
- feedback: {
484
- type: 'none'
485
- }
486
- });
487
- this.props.onModelChanged(model);
488
- }
489
- };
490
- }
491
- __init4() {
492
- this.onChoiceChanged = (index, choice) => {
493
- const {model} = this.props;
494
- if (choice.correct && model.choiceMode === 'radio') {
495
- model.choices = model.choices.map(c => {
496
- return merge({}, c, {
497
- correct: false
498
- });
499
- });
500
- }
501
- model.choices.splice(index, 1, choice);
502
- this.props.onModelChanged(model);
503
- };
504
- }
505
- __init5() {
506
- this.onPromptChanged = prompt => {
507
- this.props.onModelChanged({
508
- ...this.props.model,
509
- prompt
510
- });
511
- };
512
- }
513
- __init6() {
514
- this.onTeacherInstructionsChanged = teacherInstructions => {
515
- this.props.onModelChanged({
516
- ...this.props.model,
517
- teacherInstructions
518
- });
519
- };
520
- }
521
- __init7() {
522
- this.onModelChanged = (model, key) => {
523
- const {onModelChanged} = this.props;
524
- switch (key) {
525
- case 'choiceMode':
526
- {
527
- let value = model.choiceMode;
528
- if (value === 'radio') {
529
- let correctFound = false;
530
- model.choices = model.choices.map(c => {
531
- if (correctFound) {
532
- c.correct = false;
533
- return c;
534
- }
535
- if (c.correct) {
536
- correctFound = true;
537
- }
538
- return c;
539
- });
540
- }
541
- onModelChanged(model, true);
542
- break;
543
- }
544
- default:
545
- onModelChanged(model);
546
- break;
547
- }
548
- };
549
- }
550
- render() {
551
- const {dialog} = this.state;
552
- return React$1.createElement(React$1.Fragment, null, React$1.createElement(InfoDialog, {
553
- open: dialog.open,
554
- title: dialog.message,
555
- onCancel: dialog.onCancel,
556
- onOk: dialog.onOk,
557
- __self: this,
558
- __source: {
559
- fileName: _jsxFileName,
560
- lineNumber: 511
561
- }
562
- }), React$1.createElement(Design, {
563
- ...this.props,
564
- onChangeModel: this.onModelChanged,
565
- onRemoveChoice: this.onRemoveChoice,
566
- onChoiceChanged: this.onChoiceChanged,
567
- onAddChoice: this.onAddChoice,
568
- onPromptChanged: this.onPromptChanged,
569
- onTeacherInstructionsChanged: this.onTeacherInstructionsChanged,
570
- __self: this,
571
- __source: {
572
- fileName: _jsxFileName,
573
- lineNumber: 517
574
- }
575
- }));
576
- }
577
- }
578
- Main.__initStatic();
579
- const Styled = withStyles(styles)(Main);
580
- var sensibleDefaults = {
581
- model: {
582
- choiceMode: 'checkbox',
583
- choicePrefix: 'letters',
584
- choices: [],
585
- prompt: 'Question Prompt goes here',
586
- lockChoiceOrder: true,
587
- partialScoring: true,
588
- scoringType: 'auto',
589
- feedbackEnabled: true,
590
- promptEnabled: true,
591
- rationaleEnabled: true,
592
- teacherInstructionsEnabled: true,
593
- studentInstructionsEnabled: true,
594
- toolbarEditorPosition: 'bottom',
595
- choicesLayout: 'vertical',
596
- gridColumns: '2'
597
- },
598
- configuration: {
599
- choicesLayout: {
600
- settings: false,
601
- label: 'Choices Layout'
602
- },
603
- gridColumns: {
604
- label: 'Grid columns'
605
- },
606
- answerChoiceCount: 0,
607
- addChoiceButton: {
608
- settings: true,
609
- label: 'Add a Choice'
610
- },
611
- choiceMode: {
612
- settings: true,
613
- label: 'Response Type'
614
- },
615
- choicePrefix: {
616
- settings: true,
617
- label: 'Choice Labels'
618
- },
619
- deleteChoice: {
620
- settings: true
621
- },
622
- feedback: {
623
- settings: true,
624
- label: 'Feedback'
625
- },
626
- prompt: {
627
- settings: true,
628
- label: 'Prompt'
629
- },
630
- lockChoiceOrder: {
631
- settings: true,
632
- label: 'Lock Choice Order'
633
- },
634
- partialScoring: {
635
- settings: false,
636
- label: 'Allow Partial Scoring'
637
- },
638
- rationale: {
639
- settings: true,
640
- label: 'Rationale'
641
- },
642
- accessibility: {
643
- settings: false,
644
- label: 'Accessibility Label'
645
- },
646
- scoringType: {
647
- settings: false,
648
- label: 'Scoring Type'
649
- },
650
- studentInstructions: {
651
- settings: false,
652
- label: 'Student Instructions'
653
- },
654
- teacherInstructions: {
655
- settings: true,
656
- label: 'Teacher Instructions'
657
- },
658
- toolbarEditorPosition: {
659
- settings: false,
660
- label: 'Toolbar Editor Position'
661
- },
662
- minAnswerChoices: 2,
663
- maxAnswerChoices: 5
664
- }
665
- };
666
- const React = _dll_react;
667
- const ReactDOM = _dll_react_dom;
668
- const debug = _dll_debug;
669
- const {defaults: defaults} = _dll_lodash;
670
- const {choiceUtils: utils} = _dll_pie_lib__config_ui;
671
- const log = debug('multiple-choice:configure');
672
- const generateFormattedChoices = (choices, choiceCount = 0) => {
673
- if (!choices || choices.length === 0) {
674
- let formattedChoices = [];
675
- for (let i = 0; i < choiceCount; i++) {
676
- formattedChoices.push({
677
- value: `${i}`,
678
- label: '',
679
- feedback: {
680
- type: 'none',
681
- value: ''
682
- }
683
- });
684
- }
685
- return formattedChoices;
686
- }
687
- return choices;
688
- };
689
- const prepareCustomizationObject = (config, model) => {
690
- const configuration = defaults(config, sensibleDefaults.configuration);
691
- return {
692
- configuration,
693
- model: {
694
- ...model,
695
- choices: generateFormattedChoices(model && model.choices || [], configuration && configuration.answerChoiceCount)
696
- }
697
- };
698
- };
699
- class MultipleChoice extends HTMLElement {
700
- static __initStatic() {
701
- this.createDefaultModel = (model = {}) => {
702
- const normalizedModel = utils.normalizeChoices({
703
- ...sensibleDefaults.model,
704
- ...model,
705
- choices: generateFormattedChoices(model && model.choices || [])
706
- });
707
- normalizedModel.choicesLayout = model.choicesLayout || model.verticalMode === false && 'horizontal' || sensibleDefaults.model.choicesLayout;
708
- return normalizedModel;
709
- };
710
- }
711
- constructor() {
712
- super();
713
- this._model = MultipleChoice.createDefaultModel();
714
- this._configuration = sensibleDefaults.configuration;
715
- this.onModelChanged = this.onModelChanged.bind(this);
716
- this.onConfigurationChanged = this.onConfigurationChanged.bind(this);
717
- }
718
- set model(s) {
719
- this._model = MultipleChoice.createDefaultModel(s);
720
- this._render();
721
- }
722
- set configuration(c) {
723
- const info = prepareCustomizationObject(c, this._model);
724
- this.onModelChanged(info.model);
725
- this._configuration = info.configuration;
726
- this._render();
727
- }
728
- set disableSidePanel(s) {
729
- this._disableSidePanel = s;
730
- this._render();
731
- }
732
- dispatchModelUpdated(reset) {
733
- const resetValue = !!reset;
734
- this.dispatchEvent(new ModelUpdatedEvent_1(this._model, resetValue));
735
- }
736
- onModelChanged(m, reset) {
737
- this._model = m;
738
- this._render();
739
- this.dispatchModelUpdated(reset);
740
- }
741
- onConfigurationChanged(c) {
742
- this._configuration = prepareCustomizationObject(c, this._model).configuration;
743
- if (this._model) {
744
- this.onModelChanged(this._model);
745
- }
746
- this._render();
747
- }
748
- insertImage(handler) {
749
- this.dispatchEvent(new InsertImageEvent_1(handler));
750
- }
751
- onDeleteImage(src, done) {
752
- this.dispatchEvent(new DeleteImageEvent_1(src, done));
753
- }
754
- _render() {
755
- log('_render');
756
- let element = React.createElement(Styled, {
757
- model: this._model,
758
- configuration: this._configuration,
759
- onModelChanged: this.onModelChanged,
760
- onConfigurationChanged: this.onConfigurationChanged,
761
- disableSidePanel: this._disableSidePanel,
762
- imageSupport: {
763
- add: this.insertImage.bind(this),
764
- delete: this.onDeleteImage.bind(this)
765
- }
766
- });
767
- ReactDOM.render(element, this);
768
- }
769
- }
770
- MultipleChoice.__initStatic();
771
- export {MultipleChoice as default};