@pie-element/multiple-choice 6.1.8 → 6.2.0

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.
@@ -0,0 +1,771 @@
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};