@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.
- package/CHANGELOG.md +463 -0
- package/configure/CHANGELOG.md +447 -0
- package/configure/lib/defaults.js +34 -11
- package/configure/lib/defaults.js.map +1 -1
- package/configure/lib/index.js +30 -23
- package/configure/lib/index.js.map +1 -1
- package/configure/lib/main.js +109 -72
- package/configure/lib/main.js.map +1 -1
- package/configure/package.json +3 -3
- package/configure/src/__tests__/__snapshots__/index.test.js.snap +12 -2
- package/configure/src/__tests__/index.test.js +164 -211
- package/configure/src/defaults.js +49 -27
- package/configure/src/index.js +19 -39
- package/configure/src/main.jsx +165 -149
- package/controller/CHANGELOG.md +67 -0
- package/controller/lib/defaults.js.map +1 -1
- package/controller/lib/index.js +123 -29
- package/controller/lib/index.js.map +1 -1
- package/controller/lib/utils.js.map +1 -1
- package/controller/package.json +2 -2
- package/controller/src/__tests__/index.test.js +113 -141
- package/controller/src/__tests__/utils.test.js +6 -9
- package/controller/src/defaults.js +1 -1
- package/controller/src/index.js +109 -70
- package/controller/src/utils.js +6 -4
- package/docs/config-schema.json +376 -0
- package/docs/config-schema.json.md +289 -1
- package/docs/demo/config.js +2 -2
- package/docs/demo/generate.js +3 -3
- package/docs/pie-schema.json +177 -0
- package/docs/pie-schema.json.md +138 -0
- package/lib/index.js +12 -9
- package/lib/index.js.map +1 -1
- package/lib/print.js +243 -0
- package/lib/print.js.map +1 -0
- package/package.json +8 -4
- package/src/__tests__/index.test.js +2 -7
- package/src/index.js +7 -5
- 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
|
-
|
|
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:
|
|
93
|
-
}
|
|
114
|
+
settingsPanelDisabled: false,
|
|
115
|
+
},
|
|
94
116
|
};
|
package/configure/src/index.js
CHANGED
|
@@ -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
|
-
...
|
|
36
|
+
static createDefaultModel = ({ partA = {}, partB = {}, ...model } = {}, defaults = modelDefault) => ({
|
|
37
|
+
...defaults,
|
|
41
38
|
...model,
|
|
42
39
|
partA: {
|
|
43
|
-
...
|
|
44
|
-
...
|
|
40
|
+
...defaults.partA,
|
|
41
|
+
...partA,
|
|
42
|
+
choicesLayout:
|
|
43
|
+
partA.choicesLayout || (partA.verticalMode === false && 'horizontal') || defaults.partA.choicesLayout,
|
|
45
44
|
},
|
|
46
45
|
partB: {
|
|
47
|
-
...
|
|
48
|
-
...
|
|
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
|
}
|
package/configure/src/main.jsx
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
30
|
-
|
|
27
|
+
removeExtraChoices = (choices) => {
|
|
28
|
+
let correctFound = false;
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
41
|
+
return choice;
|
|
42
|
+
});
|
|
43
|
+
};
|
|
37
44
|
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
onModelChanged = (model, key) => {
|
|
46
|
+
const { onModelChanged } = this.props;
|
|
40
47
|
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
};
|
|
51
|
+
return onModelChanged(model, true);
|
|
52
|
+
}
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
};
|
|
54
|
+
if (key === 'partB.choiceMode' && model.partB.choiceMode === 'radio') {
|
|
55
|
+
model.partB.choices = this.removeExtraChoices(model.partB.choices);
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
return onModelChanged(model, true);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return onModelChanged(model);
|
|
61
|
+
};
|
|
58
62
|
|
|
59
63
|
render() {
|
|
60
|
-
const {
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
<
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
-
</
|
|
206
|
-
</
|
|
221
|
+
</div>
|
|
222
|
+
</layout.ConfigLayout>
|
|
207
223
|
);
|
|
208
224
|
}
|
|
209
225
|
}
|