@pie-element/ebsr 6.5.0 → 6.5.1-beta.587

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 (39) hide show
  1. package/CHANGELOG.md +463 -0
  2. package/configure/CHANGELOG.md +447 -0
  3. package/configure/lib/defaults.js +34 -11
  4. package/configure/lib/defaults.js.map +1 -1
  5. package/configure/lib/index.js +30 -23
  6. package/configure/lib/index.js.map +1 -1
  7. package/configure/lib/main.js +109 -72
  8. package/configure/lib/main.js.map +1 -1
  9. package/configure/package.json +3 -3
  10. package/configure/src/__tests__/__snapshots__/index.test.js.snap +12 -2
  11. package/configure/src/__tests__/index.test.js +164 -211
  12. package/configure/src/defaults.js +49 -27
  13. package/configure/src/index.js +19 -39
  14. package/configure/src/main.jsx +165 -149
  15. package/controller/CHANGELOG.md +67 -0
  16. package/controller/lib/defaults.js.map +1 -1
  17. package/controller/lib/index.js +123 -29
  18. package/controller/lib/index.js.map +1 -1
  19. package/controller/lib/utils.js.map +1 -1
  20. package/controller/package.json +2 -2
  21. package/controller/src/__tests__/index.test.js +113 -141
  22. package/controller/src/__tests__/utils.test.js +6 -9
  23. package/controller/src/defaults.js +1 -1
  24. package/controller/src/index.js +109 -70
  25. package/controller/src/utils.js +6 -4
  26. package/docs/config-schema.json +376 -0
  27. package/docs/config-schema.json.md +289 -1
  28. package/docs/demo/config.js +2 -2
  29. package/docs/demo/generate.js +3 -3
  30. package/docs/pie-schema.json +177 -0
  31. package/docs/pie-schema.json.md +138 -0
  32. package/lib/index.js +12 -9
  33. package/lib/index.js.map +1 -1
  34. package/lib/print.js +243 -0
  35. package/lib/print.js.map +1 -0
  36. package/package.json +8 -4
  37. package/src/__tests__/index.test.js +2 -7
  38. package/src/index.js +7 -5
  39. package/src/print.js +179 -0
@@ -3,46 +3,71 @@ import cloneDeep from 'lodash/cloneDeep';
3
3
  const defaultConfig = {
4
4
  addChoiceButton: {
5
5
  settings: true,
6
- label: 'Add a Choice'
6
+ label: 'Add a Choice',
7
7
  },
8
8
  choiceMode: {
9
9
  settings: true,
10
- label: 'Response Type'
10
+ label: 'Response Type',
11
11
  },
12
12
  choicePrefix: {
13
13
  settings: true,
14
- label: 'Choice Labels'
14
+ label: 'Choice Labels',
15
15
  },
16
16
  deleteChoice: {
17
- settings: true
17
+ settings: true,
18
18
  },
19
19
  feedback: {
20
20
  settings: true,
21
- label: 'Feedback'
21
+ label: 'Feedback',
22
22
  },
23
23
  lockChoiceOrder: {
24
24
  settings: true,
25
- label: 'Lock Choice Order'
25
+ label: 'Lock Choice Order',
26
26
  },
27
27
  prompt: {
28
28
  settings: true,
29
- label: 'Prompt'
29
+ label: 'Prompt',
30
30
  },
31
31
  rationale: {
32
32
  settings: true,
33
- label: 'Rationale'
33
+ label: 'Rationale',
34
34
  },
35
+ settingsPanelDisabled: true,
35
36
  studentInstructions: {
36
37
  settings: false,
37
- label: 'Student Instructions'
38
+ label: 'Student Instructions',
38
39
  },
39
40
  teacherInstructions: {
40
41
  settings: true,
41
- label: 'Teacher Instructions'
42
- }
42
+ label: 'Teacher Instructions',
43
+ },
44
+ choicesLayout: {
45
+ settings: false,
46
+ label: 'Choices Layout',
47
+ },
48
+ gridColumns: {
49
+ label: 'Grid columns',
50
+ },
51
+ spellCheck: {
52
+ label: 'Spellcheck',
53
+ settings: false,
54
+ enabled: true,
55
+ },
56
+ maxImageWidth: {
57
+ teacherInstructions: 300,
58
+ prompt: 300,
59
+ rationale: 636,
60
+ choices: 636,
61
+ },
62
+ maxImageHeight: {
63
+ teacherInstructions: 300,
64
+ prompt: 300,
65
+ rationale: 300,
66
+ choices: 300,
67
+ },
43
68
  };
44
69
 
45
- const partModel = base => ({
70
+ const partModel = (base) => ({
46
71
  choiceMode: 'radio',
47
72
  choices: [],
48
73
  choicePrefix: 'numbers',
@@ -54,16 +79,19 @@ const partModel = base => ({
54
79
  rationale: '',
55
80
  teacherInstructionsEnabled: true,
56
81
  studentInstructionsEnabled: true,
57
- ...base
82
+ spellCheckEnabled: true,
83
+ choicesLayout: 'vertical',
84
+ gridColumns: '2',
85
+ ...base,
58
86
  });
59
87
 
60
88
  export default {
61
89
  model: {
62
90
  partLabels: true,
63
91
  partLabelType: 'Letters',
64
- partialScoring: false,
92
+ // partialScoring: false,
65
93
  partA: partModel({ prompt: 'Prompt A' }),
66
- partB: partModel({ prompt: 'Prompt B' })
94
+ partB: partModel({ prompt: 'Prompt B' }),
67
95
  },
68
96
  configuration: {
69
97
  partialScoring: {
@@ -71,24 +99,18 @@ export default {
71
99
  // this will turn off partial scoring toggle in the settings tab by default for the interaction
72
100
  // as we'd like partial scoring to be controlled from the environment entirely
73
101
  // if any other consumers would like to enable it for themselves, they can do so from their model directly.
74
- settings: false
102
+ settings: false,
75
103
  },
76
104
  scoringType: {
77
105
  settings: false,
78
- label: 'Scoring Type'
79
- },
80
- partA: {
81
- ...cloneDeep(defaultConfig),
82
- choiceMode: {
83
- settings: false,
84
- label: 'Response Type'
85
- }
106
+ label: 'Scoring Type',
86
107
  },
108
+ partA: cloneDeep(defaultConfig),
87
109
  partB: cloneDeep(defaultConfig),
88
110
  partLabels: {
89
111
  settings: true,
90
- label: 'Part Labels'
112
+ label: 'Part Labels',
91
113
  },
92
- settingsPanelDisabled: true
93
- }
114
+ settingsPanelDisabled: false,
115
+ },
94
116
  };
@@ -10,7 +10,7 @@ import sensibleDefaults from './defaults';
10
10
  const MODEL_UPDATED = ModelUpdatedEvent.TYPE;
11
11
  const MC_TAG_NAME = 'ebsr-multiple-choice-configure';
12
12
 
13
- class EbsrMCConfigure extends MultipleChoiceConfigure { }
13
+ class EbsrMCConfigure extends MultipleChoiceConfigure {}
14
14
 
15
15
  const defineMultipleChoice = () => {
16
16
  if (!customElements.get(MC_TAG_NAME)) {
@@ -23,29 +23,30 @@ defineMultipleChoice();
23
23
  const prepareCustomizationObject = (config, model) => {
24
24
  const configuration = defaults(config, sensibleDefaults.configuration);
25
25
  configuration.settingsPanelDisabled = true;
26
- // it is required for ebsr partA not to allow changing response type
27
- configuration.partA.choiceMode = {
28
- settings: false,
29
- label: 'Response Type'
30
- };
31
26
 
32
27
  return {
33
28
  configuration,
34
- model
29
+ model,
35
30
  };
36
31
  };
37
32
 
33
+ const { model: modelDefault } = sensibleDefaults || {};
34
+
38
35
  export default class EbsrConfigure extends HTMLElement {
39
- static createDefaultModel = (model = {}) => ({
40
- ...sensibleDefaults.model,
36
+ static createDefaultModel = ({ partA = {}, partB = {}, ...model } = {}, defaults = modelDefault) => ({
37
+ ...defaults,
41
38
  ...model,
42
39
  partA: {
43
- ...sensibleDefaults.model.partA,
44
- ...model.partA
40
+ ...defaults.partA,
41
+ ...partA,
42
+ choicesLayout:
43
+ partA.choicesLayout || (partA.verticalMode === false && 'horizontal') || defaults.partA.choicesLayout,
45
44
  },
46
45
  partB: {
47
- ...sensibleDefaults.model.partB,
48
- ...model.partB
46
+ ...defaults.partB,
47
+ ...partB,
48
+ choicesLayout:
49
+ partB.choicesLayout || (partB.verticalMode === false && 'horizontal') || defaults.partB.choicesLayout,
49
50
  },
50
51
  });
51
52
 
@@ -53,23 +54,13 @@ export default class EbsrConfigure extends HTMLElement {
53
54
  super();
54
55
 
55
56
  this._model = EbsrConfigure.createDefaultModel();
57
+
56
58
  this._configuration = sensibleDefaults.configuration;
57
59
  this.onConfigurationChanged = this.onConfigurationChanged.bind(this);
58
60
  }
59
61
 
60
62
  set model(m) {
61
- this._model = {
62
- ...this._model,
63
- ...m,
64
- partA: {
65
- ...this._model.partA,
66
- ...m.partA,
67
- },
68
- partB: {
69
- ...this._model.partB,
70
- ...m.partB,
71
- }
72
- };
63
+ this._model = EbsrConfigure.createDefaultModel(m, this._model);
73
64
 
74
65
  this._render();
75
66
  }
@@ -81,22 +72,10 @@ export default class EbsrConfigure extends HTMLElement {
81
72
  }
82
73
 
83
74
  onModelChanged = (m, reset) => {
84
- this._model = {
85
- ...this._model,
86
- ...m,
87
- partA: {
88
- ...this._model.partA,
89
- ...m.partA,
90
- },
91
- partB: {
92
- ...this._model.partB,
93
- ...m.partB,
94
- }
95
- };
75
+ this._model = EbsrConfigure.createDefaultModel(m, this._model);
96
76
 
97
77
  this.dispatchModelUpdated(reset);
98
78
  this._render();
99
-
100
79
  };
101
80
 
102
81
  set configuration(c) {
@@ -116,7 +95,7 @@ export default class EbsrConfigure extends HTMLElement {
116
95
  this._render();
117
96
  }
118
97
 
119
- onModelUpdated = e => {
98
+ onModelUpdated = (e) => {
120
99
  if (e.target === this) {
121
100
  return;
122
101
  }
@@ -151,6 +130,7 @@ export default class EbsrConfigure extends HTMLElement {
151
130
  onModelChanged: this.onModelChanged,
152
131
  onConfigurationChanged: this.onConfigurationChanged,
153
132
  });
133
+
154
134
  ReactDOM.render(element, this);
155
135
  }
156
136
  }
@@ -2,19 +2,17 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { settings, layout } from '@pie-lib/config-ui';
4
4
  import { withStyles } from '@material-ui/core/styles';
5
- import cloneDeep from 'lodash/cloneDeep';
6
5
 
7
6
  const { Panel, toggle, radio, dropdown } = settings;
8
7
 
9
- const styles = theme => ({
10
- design: {
11
- paddingTop: theme.spacing.unit * 3
12
- },
8
+ const styles = (theme) => ({
13
9
  part: {
14
10
  display: 'flex',
15
11
  flexDirection: 'column',
16
- padding: '16px 0 32px'
17
- }
12
+ '&:not(:first-child)': {
13
+ paddingTop: theme.spacing.unit * 4,
14
+ },
15
+ },
18
16
  });
19
17
 
20
18
  export class Main extends React.Component {
@@ -23,48 +21,49 @@ export class Main extends React.Component {
23
21
  configuration: PropTypes.object,
24
22
  model: PropTypes.object,
25
23
  onModelChanged: PropTypes.func,
26
- onConfigurationChanged: PropTypes.func
24
+ onConfigurationChanged: PropTypes.func,
27
25
  };
28
26
 
29
- onModelChanged = (model, key) => {
30
- const { onModelChanged } = this.props;
27
+ removeExtraChoices = (choices) => {
28
+ let correctFound = false;
31
29
 
32
- if (key !== 'partB.choiceMode') {
33
- return onModelChanged(model);
34
- };
30
+ return (choices || []).map((choice) => {
31
+ if (correctFound) {
32
+ choice.correct = false;
33
+
34
+ return choice;
35
+ }
36
+
37
+ if (choice.correct) {
38
+ correctFound = true;
39
+ }
35
40
 
36
- const value = model.partB.choiceMode;
41
+ return choice;
42
+ });
43
+ };
37
44
 
38
- if (value === 'radio') {
39
- let correctFound = false;
45
+ onModelChanged = (model, key) => {
46
+ const { onModelChanged } = this.props;
40
47
 
41
- model.partB.choices = model.partB.choices.map(c => {
42
- // keep only one (first defined) correct answer
43
- if (correctFound) {
44
- c.correct = false;
45
- return c;
46
- };
48
+ if (key === 'partA.choiceMode' && model.partA.choiceMode === 'radio') {
49
+ model.partA.choices = this.removeExtraChoices(model.partA.choices);
47
50
 
48
- if (c.correct) {
49
- correctFound = true;
50
- };
51
+ return onModelChanged(model, true);
52
+ }
51
53
 
52
- return c;
53
- });
54
- };
54
+ if (key === 'partB.choiceMode' && model.partB.choiceMode === 'radio') {
55
+ model.partB.choices = this.removeExtraChoices(model.partB.choices);
55
56
 
56
- return onModelChanged(model, true);
57
- }
57
+ return onModelChanged(model, true);
58
+ }
59
+
60
+ return onModelChanged(model);
61
+ };
58
62
 
59
63
  render() {
60
- const {
61
- classes,
62
- model,
63
- configuration,
64
- onConfigurationChanged
65
- } = this.props;
66
- const { partLabelType } = model;
67
- const { partA, partB, partialScoring, scoringType, ...generalConfiguration } = configuration;
64
+ const { classes, model, configuration, onConfigurationChanged } = this.props;
65
+ const { partLabelType, partA: modelPartA, partB: modelPartB } = model;
66
+ const { partA, partB, partialScoring, settingsPanelDisabled, scoringType, ...generalConfiguration } = configuration;
68
67
  const {
69
68
  feedback: feedbackA = {},
70
69
  choiceMode: choiceModeA = {},
@@ -73,7 +72,10 @@ export class Main extends React.Component {
73
72
  prompt: promptA = {},
74
73
  teacherInstructions: teacherInstructionsA = {},
75
74
  studentInstructions: studentInstructionsA = {},
76
- rationale: rationaleA = {}
75
+ choicesLayout: choicesLayoutA = {},
76
+ gridColumns: gridColumnsA = {},
77
+ rationale: rationaleA = {},
78
+ spellCheck: spellCheckA = {},
77
79
  } = partA || {};
78
80
  const {
79
81
  feedback: feedbackB = {},
@@ -83,127 +85,141 @@ export class Main extends React.Component {
83
85
  prompt: promptB = {},
84
86
  teacherInstructions: teacherInstructionsB = {},
85
87
  studentInstructions: studentInstructionsB = {},
86
- rationale: rationaleB = {}
88
+ choicesLayout: choicesLayoutB = {},
89
+ gridColumns: gridColumnsB = {},
90
+ rationale: rationaleB = {},
91
+ spellCheck: spellCheckB = {},
87
92
  } = partB || {};
93
+
88
94
  const type = partLabelType || 'Numbers';
89
95
  const typeIsNumber = type === 'Numbers';
90
96
  const firstPart = `Part ${typeIsNumber ? '1' : 'A'}`;
91
97
  const secondPart = `Part ${typeIsNumber ? '2' : 'B'}`;
98
+ const nrOfColumnsAvailable = {
99
+ partA:
100
+ modelPartA.choices && modelPartA.choices.length
101
+ ? Array.from({ length: modelPartA.choices.length }, (_, i) => `${i + 1}`)
102
+ : [],
103
+ partB:
104
+ modelPartB.choices && modelPartB.choices.length
105
+ ? Array.from({ length: modelPartB.choices.length }, (_, i) => `${i + 1}`)
106
+ : [],
107
+ };
108
+
109
+ const panelSettings = {
110
+ partLabels: generalConfiguration.partLabels.settings && toggle(generalConfiguration.partLabels.label),
111
+ partLabelType: model.partLabels && dropdown('', ['Numbers', 'Letters']),
112
+ partialScoring: partialScoring.settings && toggle(partialScoring.label),
113
+ scoringType: scoringType.settings && radio(scoringType.label, ['auto', 'rubric']),
114
+ };
115
+
116
+ const panelSettingsPartA = {
117
+ 'partA.choiceMode': choiceModeA.settings && radio(choiceModeA.label, ['checkbox', 'radio']),
118
+ 'partA.choicePrefix': choicePrefixA.settings && radio(choicePrefixA.label, ['numbers', 'letters']),
119
+ 'partA.lockChoiceOrder': lockChoiceOrderA.settings && toggle(lockChoiceOrderA.label),
120
+ 'partA.choicesLayout':
121
+ choicesLayoutA.settings && dropdown(choicesLayoutA.label, ['vertical', 'grid', 'horizontal']),
122
+ 'partA.gridColumns':
123
+ choicesLayoutA.settings &&
124
+ modelPartA.choicesLayout === 'grid' &&
125
+ nrOfColumnsAvailable.partA.length > 0 &&
126
+ dropdown(gridColumnsA.label, nrOfColumnsAvailable.partA),
127
+ };
128
+ const panelPropertiesPartA = {
129
+ 'partA.feedbackEnabled': feedbackA.settings && toggle(feedbackA.label),
130
+ 'partA.promptEnabled': promptA.settings && toggle(promptA.label),
131
+ 'partA.teacherInstructionsEnabled': teacherInstructionsA.settings && toggle(teacherInstructionsA.label),
132
+ 'partA.studentInstructionsEnabled': studentInstructionsA.settings && toggle(studentInstructionsA.label),
133
+ 'partA.rationaleEnabled': rationaleA.settings && toggle(rationaleA.label),
134
+ 'partA.spellCheckEnabled': spellCheckA.settings && toggle(spellCheckA.label),
135
+ };
136
+
137
+ const panelSettingsPartB = {
138
+ 'partB.choiceMode': choiceModeB.settings && radio(choiceModeB.label, ['checkbox', 'radio']),
139
+ 'partB.choicePrefix': choicePrefixB.settings && radio(choicePrefixB.label, ['numbers', 'letters']),
140
+ 'partB.lockChoiceOrder': lockChoiceOrderB.settings && toggle(lockChoiceOrderB.label),
141
+ 'partB.choicesLayout':
142
+ choicesLayoutB.settings && dropdown(choicesLayoutB.label, ['vertical', 'grid', 'horizontal']),
143
+ 'partB.gridColumns':
144
+ choicesLayoutB.settings &&
145
+ modelPartB.choicesLayout === 'grid' &&
146
+ nrOfColumnsAvailable.partB.length > 0 &&
147
+ dropdown(gridColumnsB.label, nrOfColumnsAvailable.partB),
148
+ };
149
+ const panelPropertiesPartB = {
150
+ 'partB.feedbackEnabled': feedbackB.settings && toggle(feedbackB.label),
151
+ 'partB.promptEnabled': promptB.settings && toggle(promptB.label),
152
+ 'partB.teacherInstructionsEnabled': teacherInstructionsB.settings && toggle(teacherInstructionsB.label),
153
+ 'partB.studentInstructionsEnabled': studentInstructionsB.settings && toggle(studentInstructionsB.label),
154
+ 'partB.rationaleEnabled': rationaleB.settings && toggle(rationaleB.label),
155
+ 'partB.spellCheckEnabled': spellCheckB.settings && toggle(spellCheckB.label),
156
+ };
92
157
 
93
158
  return (
94
- <div className={classes.design}>
95
- <layout.ConfigLayout
96
- settings={
97
- <Panel
98
- model={model}
99
- onChangeModel={this.onModelChanged}
100
- configuration={configuration}
101
- onChangeConfiguration={onConfigurationChanged}
102
- groups={{
103
- 'Settings for both': {
104
- partLabels:
105
- generalConfiguration.partLabels.settings &&
106
- toggle(generalConfiguration.partLabels.label),
107
- partLabelType:
108
- model.partLabels && dropdown('', ['Numbers', 'Letters']),
109
- partialScoring:
110
- partialScoring.settings && toggle(partialScoring.label),
111
- scoringType:
112
- scoringType.settings && radio(scoringType.label, ['auto', 'rubric'])
113
- },
114
- [`Settings ${firstPart}`]: {
115
- 'partA.choiceMode':
116
- choiceModeA.settings &&
117
- radio(choiceModeA.label, ['checkbox', 'radio']),
118
- 'partA.choicePrefix':
119
- choicePrefixA.settings &&
120
- radio(choicePrefixA.label, ['numbers', 'letters']),
121
- 'partA.lockChoiceOrder':
122
- lockChoiceOrderA.settings && toggle(lockChoiceOrderA.label),
123
- },
124
- [`Properties ${firstPart}`]: {
125
- 'partA.feedbackEnabled': feedbackA.settings &&
126
- toggle(feedbackA.label),
127
- 'partA.promptEnabled':
128
- promptA.settings && toggle(promptA.label),
129
- 'partA.teacherInstructionsEnabled':
130
- teacherInstructionsA.settings &&
131
- toggle(teacherInstructionsA.label),
132
- 'partA.studentInstructionsEnabled':
133
- studentInstructionsA.settings &&
134
- toggle(studentInstructionsA.label),
135
- 'partA.rationaleEnabled':
136
- rationaleA.settings && toggle(rationaleA.label)
137
- },
138
- [`Settings ${secondPart}`]: {
139
- 'partB.choiceMode':
140
- choiceModeB.settings &&
141
- radio(choiceModeB.label, ['checkbox', 'radio']),
142
- 'partB.choicePrefix':
143
- choicePrefixB.settings &&
144
- radio(choicePrefixB.label, ['numbers', 'letters']),
145
- 'partB.lockChoiceOrder':
146
- lockChoiceOrderB.settings && toggle(lockChoiceOrderB.label)
147
- },
148
- [`Properties ${secondPart}`]: {
149
- 'partB.feedbackEnabled':
150
- feedbackB.settings && toggle(feedbackB.label),
151
- 'partB.promptEnabled':
152
- promptB.settings && toggle(promptB.label),
153
- 'partB.teacherInstructionsEnabled':
154
- teacherInstructionsB.settings &&
155
- toggle(teacherInstructionsB.label),
156
- 'partB.studentInstructionsEnabled':
157
- studentInstructionsB.settings &&
158
- toggle(studentInstructionsB.label),
159
- 'partB.rationaleEnabled':
160
- rationaleB.settings && toggle(rationaleB.label)
159
+ <layout.ConfigLayout
160
+ hideSettings={settingsPanelDisabled}
161
+ settings={
162
+ <Panel
163
+ model={model}
164
+ onChangeModel={this.onModelChanged}
165
+ configuration={configuration}
166
+ onChangeConfiguration={onConfigurationChanged}
167
+ groups={{
168
+ 'Settings for both': panelSettings,
169
+ [`Settings ${firstPart}`]: panelSettingsPartA,
170
+ [`Properties ${firstPart}`]: panelPropertiesPartA,
171
+ [`Settings ${secondPart}`]: panelSettingsPartB,
172
+ [`Properties ${secondPart}`]: panelPropertiesPartB,
173
+ }}
174
+ />
175
+ }
176
+ >
177
+ <div>
178
+ <div className={classes.part}>
179
+ {model.partLabels && <div>{firstPart}</div>}
180
+ <ebsr-multiple-choice-configure
181
+ id="A"
182
+ key="partA"
183
+ ref={(ref) => {
184
+ if (ref) {
185
+ // do not use destructuring to get model from props
186
+ this.partA = ref;
187
+ this.partA._model = {
188
+ ...this.props.model.partA,
189
+ errors: (this.props.model.errors && this.props.model.errors.partA) || {},
190
+ };
191
+ this.partA.configuration = {
192
+ ...partA,
193
+ ...generalConfiguration,
194
+ };
195
+ }
196
+ }}
197
+ />
198
+ </div>
199
+
200
+ <div className={classes.part}>
201
+ {model.partLabels && <div>{secondPart}</div>}
202
+ <ebsr-multiple-choice-configure
203
+ id="B"
204
+ key="partB"
205
+ ref={(ref) => {
206
+ if (ref) {
207
+ // do not use destructuring to get model from props
208
+ this.partB = ref;
209
+ this.partB._model = {
210
+ ...this.props.model.partB,
211
+ errors: (this.props.model.errors && this.props.model.errors.partB) || {},
212
+ };
213
+ this.partB.configuration = {
214
+ ...partB,
215
+ ...generalConfiguration,
216
+ };
161
217
  }
162
218
  }}
163
219
  />
164
- }
165
- >
166
- <div>
167
- <div className={classes.part}>
168
- {model.partLabels && <p>{firstPart}</p>}
169
- <ebsr-multiple-choice-configure
170
- id="A"
171
- key="partA"
172
- ref={ref => {
173
- if (ref) {
174
- // do not use destructuring to get model from props
175
- this.partA = ref;
176
- this.partA._model = cloneDeep(this.props.model.partA);
177
- this.partA.configuration = {
178
- ...partA,
179
- ...generalConfiguration
180
- };
181
- }
182
- }}
183
- />
184
- </div>
185
-
186
- <div className={classes.part}>
187
- {model.partLabels && <p>{secondPart}</p>}
188
- <ebsr-multiple-choice-configure
189
- id="B"
190
- key="partB"
191
- ref={ref => {
192
- if (ref) {
193
- // do not use destructuring to get model from props
194
- this.partB = ref;
195
- this.partB._model = cloneDeep(this.props.model.partB);
196
- this.partB.configuration = {
197
- ...partB,
198
- ...generalConfiguration
199
- };
200
- }
201
- }}
202
- />
203
- </div>
204
220
  </div>
205
- </layout.ConfigLayout>
206
- </div>
221
+ </div>
222
+ </layout.ConfigLayout>
207
223
  );
208
224
  }
209
225
  }