@pie-element/hotspot 5.4.3-next.41 → 5.4.3-next.54
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/configure/lib/button.js.map +1 -1
- package/configure/lib/defaults.js.map +1 -1
- package/configure/lib/hotspot-container.js.map +1 -1
- package/configure/lib/hotspot-drawable.js.map +1 -1
- package/configure/lib/hotspot-palette.js.map +1 -1
- package/configure/lib/hotspot-polygon.js.map +1 -1
- package/configure/lib/hotspot-rectangle.js.map +1 -1
- package/configure/lib/index.js.map +1 -1
- package/configure/lib/root.js +1 -1
- package/configure/lib/root.js.map +1 -1
- package/configure/lib/upload-control.js.map +1 -1
- package/configure/lib/utils.js.map +1 -1
- package/configure/src/__tests__/hotspot-container.test.js +98 -71
- package/configure/src/__tests__/hotspot-drawable.test.js +48 -49
- package/configure/src/__tests__/index.test.js +28 -51
- package/configure/src/__tests__/root.test.js +162 -82
- package/configure/src/__tests__/utils.test.js +112 -98
- package/configure/src/button.jsx +4 -4
- package/configure/src/defaults.js +16 -20
- package/configure/src/hotspot-container.jsx +72 -89
- package/configure/src/hotspot-drawable.jsx +55 -55
- package/configure/src/hotspot-palette.jsx +12 -25
- package/configure/src/hotspot-polygon.jsx +20 -22
- package/configure/src/hotspot-rectangle.jsx +5 -15
- package/configure/src/index.js +20 -20
- package/configure/src/root.jsx +38 -67
- package/configure/src/upload-control.jsx +9 -20
- package/configure/src/utils.js +35 -28
- package/controller/lib/defaults.js.map +1 -1
- package/controller/lib/index.js.map +1 -1
- package/controller/lib/utils.js.map +1 -1
- package/controller/src/__tests__/index.test.js +29 -50
- package/controller/src/defaults.js +4 -8
- package/controller/src/index.js +22 -34
- package/controller/src/utils.js +9 -6
- package/docs/config-schema.json.md +1 -1
- package/docs/demo/config.js +2 -2
- package/docs/demo/generate.js +49 -37
- package/docs/demo/session.js +2 -2
- package/docs/pie-schema.json.md +1 -1
- package/lib/hotspot/container.js.map +1 -1
- package/lib/hotspot/icons.js.map +1 -1
- package/lib/hotspot/image.js.map +1 -1
- package/lib/hotspot/index.js.map +1 -1
- package/lib/hotspot/polygon.js.map +1 -1
- package/lib/hotspot/rectangle.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/session-updater.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/container.test.jsx +57 -43
- package/src/__tests__/image.test.jsx +2 -2
- package/src/__tests__/polygon.test.jsx +31 -20
- package/src/__tests__/rectangle.test.jsx +22 -18
- package/src/__tests__/session-updater.test.jsx +22 -31
- package/src/hotspot/container.jsx +20 -23
- package/src/hotspot/icons.js +4 -2
- package/src/hotspot/image.jsx +4 -8
- package/src/hotspot/index.jsx +27 -47
- package/src/hotspot/polygon.jsx +13 -18
- package/src/hotspot/rectangle.jsx +11 -16
- package/src/index.js +5 -18
- package/src/session-updater.js +1 -1
|
@@ -6,8 +6,8 @@ import { withStyles } from '@material-ui/core/styles/index';
|
|
|
6
6
|
class PolComponent extends React.Component {
|
|
7
7
|
static getDerivedStateFromProps(nextProps) {
|
|
8
8
|
const { points } = nextProps;
|
|
9
|
-
const xList = points.map(p =>
|
|
10
|
-
const yList = points.map(p =>
|
|
9
|
+
const xList = points.map((p) => p.x);
|
|
10
|
+
const yList = points.map((p) => p.y);
|
|
11
11
|
|
|
12
12
|
const xOffset = Math.min(...xList);
|
|
13
13
|
const yOffset = Math.max(...yList);
|
|
@@ -16,14 +16,16 @@ class PolComponent extends React.Component {
|
|
|
16
16
|
return {
|
|
17
17
|
x: xOffset,
|
|
18
18
|
y: yOffset,
|
|
19
|
-
points: points.reduce((acc, point) => {
|
|
19
|
+
points: points.reduce((acc, point) => {
|
|
20
|
+
return acc.concat([point.x - xOffset, point.y - yOffset]);
|
|
21
|
+
}, []),
|
|
20
22
|
};
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
return {
|
|
24
26
|
x: 0,
|
|
25
27
|
y: 0,
|
|
26
|
-
points: []
|
|
28
|
+
points: [],
|
|
27
29
|
};
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -31,8 +33,8 @@ class PolComponent extends React.Component {
|
|
|
31
33
|
|
|
32
34
|
handleClick = (e) => {
|
|
33
35
|
const { points } = this.props;
|
|
34
|
-
const xList = points.map(p =>
|
|
35
|
-
const yList = points.map(p =>
|
|
36
|
+
const xList = points.map((p) => p.x);
|
|
37
|
+
const yList = points.map((p) => p.y);
|
|
36
38
|
|
|
37
39
|
const width = Math.max(...xList) - Math.min(...xList);
|
|
38
40
|
const height = Math.max(...yList) - Math.min(...yList);
|
|
@@ -63,7 +65,7 @@ class PolComponent extends React.Component {
|
|
|
63
65
|
if (index % 2 === 0 && index + 1 < points.length) {
|
|
64
66
|
acc.push({
|
|
65
67
|
x: currentPointCoordinate + e.target.x(),
|
|
66
|
-
y: points[index + 1]
|
|
68
|
+
y: points[index + 1] + e.target.y(),
|
|
67
69
|
});
|
|
68
70
|
|
|
69
71
|
return acc;
|
|
@@ -73,18 +75,12 @@ class PolComponent extends React.Component {
|
|
|
73
75
|
}, []);
|
|
74
76
|
|
|
75
77
|
onDragEnd(id, {
|
|
76
|
-
points: newPoints
|
|
77
|
-
})
|
|
78
|
+
points: newPoints,
|
|
79
|
+
});
|
|
78
80
|
};
|
|
79
81
|
|
|
80
82
|
render() {
|
|
81
|
-
const {
|
|
82
|
-
classes,
|
|
83
|
-
correct,
|
|
84
|
-
hotspotColor,
|
|
85
|
-
outlineColor,
|
|
86
|
-
strokeWidth = 5
|
|
87
|
-
} = this.props;
|
|
83
|
+
const { classes, correct, hotspotColor, outlineColor, strokeWidth = 5 } = this.props;
|
|
88
84
|
const { points, x, y } = this.state;
|
|
89
85
|
|
|
90
86
|
return (
|
|
@@ -113,7 +109,7 @@ class PolComponent extends React.Component {
|
|
|
113
109
|
const styles = () => ({
|
|
114
110
|
base: {
|
|
115
111
|
cursor: 'pointer',
|
|
116
|
-
opacity: 0.5
|
|
112
|
+
opacity: 0.5,
|
|
117
113
|
},
|
|
118
114
|
});
|
|
119
115
|
|
|
@@ -126,11 +122,13 @@ PolComponent.propTypes = {
|
|
|
126
122
|
onClick: PropTypes.func.isRequired,
|
|
127
123
|
onDragEnd: PropTypes.func.isRequired,
|
|
128
124
|
outlineColor: PropTypes.string.isRequired,
|
|
129
|
-
points: PropTypes.arrayOf(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
125
|
+
points: PropTypes.arrayOf(
|
|
126
|
+
PropTypes.shape({
|
|
127
|
+
x: PropTypes.number,
|
|
128
|
+
y: PropTypes.number,
|
|
129
|
+
}),
|
|
130
|
+
).isRequired,
|
|
131
|
+
strokeWidth: PropTypes.number,
|
|
134
132
|
};
|
|
135
133
|
|
|
136
134
|
PolComponent.defaultProps = {
|
|
@@ -26,22 +26,12 @@ class RectComponent extends React.Component {
|
|
|
26
26
|
|
|
27
27
|
onDragEnd(id, {
|
|
28
28
|
x: e.target.x(),
|
|
29
|
-
y: e.target.y()
|
|
30
|
-
})
|
|
29
|
+
y: e.target.y(),
|
|
30
|
+
});
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
render() {
|
|
34
|
-
const {
|
|
35
|
-
classes,
|
|
36
|
-
correct,
|
|
37
|
-
height,
|
|
38
|
-
hotspotColor,
|
|
39
|
-
outlineColor,
|
|
40
|
-
width,
|
|
41
|
-
x,
|
|
42
|
-
y,
|
|
43
|
-
strokeWidth = 5
|
|
44
|
-
} = this.props;
|
|
34
|
+
const { classes, correct, height, hotspotColor, outlineColor, width, x, y, strokeWidth = 5 } = this.props;
|
|
45
35
|
|
|
46
36
|
return (
|
|
47
37
|
<Group>
|
|
@@ -69,7 +59,7 @@ class RectComponent extends React.Component {
|
|
|
69
59
|
const styles = () => ({
|
|
70
60
|
base: {
|
|
71
61
|
cursor: 'pointer',
|
|
72
|
-
opacity: 0.5
|
|
62
|
+
opacity: 0.5,
|
|
73
63
|
},
|
|
74
64
|
});
|
|
75
65
|
|
|
@@ -86,7 +76,7 @@ RectComponent.propTypes = {
|
|
|
86
76
|
width: PropTypes.number.isRequired,
|
|
87
77
|
x: PropTypes.number.isRequired,
|
|
88
78
|
y: PropTypes.number.isRequired,
|
|
89
|
-
strokeWidth: PropTypes.number
|
|
79
|
+
strokeWidth: PropTypes.number,
|
|
90
80
|
};
|
|
91
81
|
|
|
92
82
|
RectComponent.defaultProps = {
|
package/configure/src/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
DeleteImageEvent,
|
|
7
7
|
InsertImageEvent,
|
|
8
8
|
InsertSoundEvent,
|
|
9
|
-
DeleteSoundEvent
|
|
9
|
+
DeleteSoundEvent,
|
|
10
10
|
} from '@pie-framework/pie-configure-events';
|
|
11
11
|
|
|
12
12
|
import Root from './root';
|
|
@@ -20,7 +20,7 @@ export default class HotspotConfigure extends HTMLElement {
|
|
|
20
20
|
...model,
|
|
21
21
|
hotspotList: model.hotspotList || [model.hotspotColor] || sensibleDefaults.model.hotspotList,
|
|
22
22
|
outlineList: model.outlineList || [model.outlineColor] || sensibleDefaults.model.outlineList,
|
|
23
|
-
shapes: model.shapes || sensibleDefaults.model.shapes || {}
|
|
23
|
+
shapes: model.shapes || sensibleDefaults.model.shapes || {},
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
constructor() {
|
|
@@ -63,8 +63,8 @@ export default class HotspotConfigure extends HTMLElement {
|
|
|
63
63
|
if (propertyType === 'multipleCorrect') {
|
|
64
64
|
const { rectangles = [], polygons = [] } = _model.shapes || {};
|
|
65
65
|
|
|
66
|
-
_model.shapes.rectangles = rectangles.map(shape => ({ ...shape, correct: false }));
|
|
67
|
-
_model.shapes.polygons = polygons.map(shape => ({ ...shape, correct: false }));
|
|
66
|
+
_model.shapes.rectangles = rectangles.map((shape) => ({ ...shape, correct: false }));
|
|
67
|
+
_model.shapes.polygons = polygons.map((shape) => ({ ...shape, correct: false }));
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
this.onModelChanged(_model);
|
|
@@ -73,53 +73,53 @@ export default class HotspotConfigure extends HTMLElement {
|
|
|
73
73
|
onColorChanged = (colorType, color) => {
|
|
74
74
|
this.onModelChanged({
|
|
75
75
|
...this._model,
|
|
76
|
-
[colorType]: color
|
|
76
|
+
[colorType]: color,
|
|
77
77
|
});
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
-
onPromptChanged = prompt => {
|
|
80
|
+
onPromptChanged = (prompt) => {
|
|
81
81
|
this.onModelChanged({
|
|
82
82
|
...this._model,
|
|
83
|
-
prompt
|
|
83
|
+
prompt,
|
|
84
84
|
});
|
|
85
85
|
};
|
|
86
86
|
|
|
87
|
-
onRationaleChanged = rationale => {
|
|
87
|
+
onRationaleChanged = (rationale) => {
|
|
88
88
|
this.onModelChanged({
|
|
89
89
|
...this._model,
|
|
90
|
-
rationale
|
|
90
|
+
rationale,
|
|
91
91
|
});
|
|
92
92
|
};
|
|
93
93
|
|
|
94
|
-
onTeacherInstructionsChanged = teacherInstructions => {
|
|
94
|
+
onTeacherInstructionsChanged = (teacherInstructions) => {
|
|
95
95
|
this.onModelChanged({
|
|
96
96
|
...this._model,
|
|
97
|
-
teacherInstructions
|
|
97
|
+
teacherInstructions,
|
|
98
98
|
});
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
-
onUpdateImageDimension = dimensions => {
|
|
101
|
+
onUpdateImageDimension = (dimensions) => {
|
|
102
102
|
this.onModelChanged({
|
|
103
103
|
...this._model,
|
|
104
|
-
dimensions
|
|
104
|
+
dimensions,
|
|
105
105
|
});
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
-
onUpdateShapes = shapes => {
|
|
108
|
+
onUpdateShapes = (shapes) => {
|
|
109
109
|
this.onModelChanged({
|
|
110
110
|
...this._model,
|
|
111
|
-
shapes
|
|
111
|
+
shapes,
|
|
112
112
|
});
|
|
113
113
|
};
|
|
114
114
|
|
|
115
|
-
onImageUpload = imageUrl => {
|
|
115
|
+
onImageUpload = (imageUrl) => {
|
|
116
116
|
this.onModelChanged({
|
|
117
117
|
...this._model,
|
|
118
|
-
imageUrl
|
|
118
|
+
imageUrl,
|
|
119
119
|
});
|
|
120
120
|
};
|
|
121
121
|
|
|
122
|
-
insertImage = handler => {
|
|
122
|
+
insertImage = (handler) => {
|
|
123
123
|
this.dispatchEvent(new InsertImageEvent(handler));
|
|
124
124
|
};
|
|
125
125
|
|
|
@@ -148,11 +148,11 @@ export default class HotspotConfigure extends HTMLElement {
|
|
|
148
148
|
onUpdateImageDimension: this.onUpdateImageDimension,
|
|
149
149
|
imageSupport: {
|
|
150
150
|
add: this.insertImage,
|
|
151
|
-
delete: this.onDeleteImage
|
|
151
|
+
delete: this.onDeleteImage,
|
|
152
152
|
},
|
|
153
153
|
uploadSoundSupport: {
|
|
154
154
|
add: this.insertSound.bind(this),
|
|
155
|
-
delete: this.onDeleteSound.bind(this)
|
|
155
|
+
delete: this.onDeleteSound.bind(this),
|
|
156
156
|
},
|
|
157
157
|
onUpdateShapes: this.onUpdateShapes,
|
|
158
158
|
onModelChangedByConfig: this.onModelChangedByConfig,
|
package/configure/src/root.jsx
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
settings,
|
|
4
|
-
layout,
|
|
5
|
-
InputContainer,
|
|
6
|
-
NumberTextField
|
|
7
|
-
} from '@pie-lib/config-ui';
|
|
2
|
+
import { settings, layout, InputContainer, NumberTextField } from '@pie-lib/config-ui';
|
|
8
3
|
import PropTypes from 'prop-types';
|
|
9
4
|
import EditableHtml from '@pie-lib/editable-html';
|
|
10
5
|
import { withStyles } from '@material-ui/core/styles';
|
|
@@ -14,13 +9,7 @@ import Tooltip from '@material-ui/core/Tooltip';
|
|
|
14
9
|
import HotspotPalette from './hotspot-palette';
|
|
15
10
|
import HotspotContainer from './hotspot-container';
|
|
16
11
|
import classNames from 'classnames';
|
|
17
|
-
import {
|
|
18
|
-
updateImageDimensions,
|
|
19
|
-
generateValidationMessage,
|
|
20
|
-
getUpdatedShapes,
|
|
21
|
-
getAllShapes,
|
|
22
|
-
groupShapes
|
|
23
|
-
} from './utils';
|
|
12
|
+
import { updateImageDimensions, generateValidationMessage, getUpdatedShapes, getAllShapes, groupShapes } from './utils';
|
|
24
13
|
|
|
25
14
|
const { Panel, toggle } = settings;
|
|
26
15
|
|
|
@@ -47,7 +36,7 @@ export class Root extends React.Component {
|
|
|
47
36
|
dimensions,
|
|
48
37
|
nextImageDimensions,
|
|
49
38
|
preserveAspectRatio.enabled,
|
|
50
|
-
resizeType
|
|
39
|
+
resizeType,
|
|
51
40
|
);
|
|
52
41
|
// transform shapes map into shapes array
|
|
53
42
|
const shapesArray = getAllShapes(shapes);
|
|
@@ -73,7 +62,7 @@ export class Root extends React.Component {
|
|
|
73
62
|
onRationaleChanged,
|
|
74
63
|
onUpdateImageDimension,
|
|
75
64
|
onTeacherInstructionsChanged,
|
|
76
|
-
onUpdateShapes
|
|
65
|
+
onUpdateShapes,
|
|
77
66
|
} = this.props;
|
|
78
67
|
const {
|
|
79
68
|
multipleCorrect = {},
|
|
@@ -85,16 +74,10 @@ export class Root extends React.Component {
|
|
|
85
74
|
preserveAspectRatio = {},
|
|
86
75
|
maxImageWidth = {},
|
|
87
76
|
maxImageHeight = {},
|
|
88
|
-
withRubric = {}
|
|
77
|
+
withRubric = {},
|
|
89
78
|
} = configuration || {};
|
|
90
|
-
const {
|
|
91
|
-
|
|
92
|
-
promptEnabled,
|
|
93
|
-
rationaleEnabled,
|
|
94
|
-
spellCheckEnabled,
|
|
95
|
-
errors,
|
|
96
|
-
rubricEnabled
|
|
97
|
-
} = model || {};
|
|
79
|
+
const { teacherInstructionsEnabled, promptEnabled, rationaleEnabled, spellCheckEnabled, errors, rubricEnabled } =
|
|
80
|
+
model || {};
|
|
98
81
|
const { shapesError, selectionsError } = errors || {};
|
|
99
82
|
const toolbarOpts = {};
|
|
100
83
|
|
|
@@ -122,22 +105,17 @@ export class Root extends React.Component {
|
|
|
122
105
|
configuration={configuration}
|
|
123
106
|
onChangeConfiguration={onConfigurationChanged}
|
|
124
107
|
groups={{
|
|
125
|
-
|
|
126
|
-
multipleCorrect:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
partialScoring.settings && toggle(partialScoring.label),
|
|
130
|
-
promptEnabled:
|
|
131
|
-
prompt.settings && toggle(prompt.label),
|
|
108
|
+
Settings: {
|
|
109
|
+
multipleCorrect: multipleCorrect.settings && toggle(multipleCorrect.label),
|
|
110
|
+
partialScoring: partialScoring.settings && toggle(partialScoring.label),
|
|
111
|
+
promptEnabled: prompt.settings && toggle(prompt.label),
|
|
132
112
|
},
|
|
133
113
|
Properties: {
|
|
134
|
-
teacherInstructionsEnabled:
|
|
135
|
-
teacherInstructions.settings && toggle(teacherInstructions.label),
|
|
114
|
+
teacherInstructionsEnabled: teacherInstructions.settings && toggle(teacherInstructions.label),
|
|
136
115
|
rationaleEnabled: rationale.settings && toggle(rationale.label),
|
|
137
|
-
spellCheckEnabled:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
116
|
+
spellCheckEnabled: spellCheck.settings && toggle(spellCheck.label),
|
|
117
|
+
rubricEnabled: withRubric?.settings && toggle(withRubric?.label),
|
|
118
|
+
},
|
|
141
119
|
}}
|
|
142
120
|
/>
|
|
143
121
|
}
|
|
@@ -152,8 +130,8 @@ export class Root extends React.Component {
|
|
|
152
130
|
nonEmpty={false}
|
|
153
131
|
toolbarOpts={toolbarOpts}
|
|
154
132
|
spellCheck={spellCheckEnabled}
|
|
155
|
-
maxImageWidth={maxImageWidth && maxImageWidth.teacherInstructions || defaultImageMaxWidth}
|
|
156
|
-
maxImageHeight={maxImageHeight && maxImageHeight.teacherInstructions || defaultImageMaxHeight}
|
|
133
|
+
maxImageWidth={(maxImageWidth && maxImageWidth.teacherInstructions) || defaultImageMaxWidth}
|
|
134
|
+
maxImageHeight={(maxImageHeight && maxImageHeight.teacherInstructions) || defaultImageMaxHeight}
|
|
157
135
|
uploadSoundSupport={uploadSoundSupport}
|
|
158
136
|
languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}
|
|
159
137
|
/>
|
|
@@ -177,18 +155,15 @@ export class Root extends React.Component {
|
|
|
177
155
|
)}
|
|
178
156
|
|
|
179
157
|
{rationaleEnabled && (
|
|
180
|
-
<InputContainer
|
|
181
|
-
label={rationale.label}
|
|
182
|
-
className={classes.prompt}
|
|
183
|
-
>
|
|
158
|
+
<InputContainer label={rationale.label} className={classes.prompt}>
|
|
184
159
|
<EditableHtml
|
|
185
160
|
markup={model.rationale || ''}
|
|
186
161
|
onChange={onRationaleChanged}
|
|
187
162
|
imageSupport={imageSupport}
|
|
188
163
|
toolbarOpts={toolbarOpts}
|
|
189
164
|
spellCheck={spellCheckEnabled}
|
|
190
|
-
maxImageWidth={maxImageWidth && maxImageWidth.rationale || defaultImageMaxWidth}
|
|
191
|
-
maxImageHeight={maxImageHeight && maxImageHeight.rationale || defaultImageMaxHeight}
|
|
165
|
+
maxImageWidth={(maxImageWidth && maxImageWidth.rationale) || defaultImageMaxWidth}
|
|
166
|
+
maxImageHeight={(maxImageHeight && maxImageHeight.rationale) || defaultImageMaxHeight}
|
|
192
167
|
uploadSoundSupport={uploadSoundSupport}
|
|
193
168
|
languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}
|
|
194
169
|
/>
|
|
@@ -206,7 +181,7 @@ export class Root extends React.Component {
|
|
|
206
181
|
placement={'left'}
|
|
207
182
|
title={validationMessage}
|
|
208
183
|
>
|
|
209
|
-
<Info fontSize={'small'} color={'primary'} style={{ float: 'right' }}/>
|
|
184
|
+
<Info fontSize={'small'} color={'primary'} style={{ float: 'right' }} />
|
|
210
185
|
</Tooltip>
|
|
211
186
|
</div>
|
|
212
187
|
{shapesError && <div className={classes.errorText}>{shapesError}</div>}
|
|
@@ -217,12 +192,8 @@ export class Root extends React.Component {
|
|
|
217
192
|
hotspotList={model.hotspotList}
|
|
218
193
|
outlineColor={model.outlineColor}
|
|
219
194
|
outlineList={model.outlineList}
|
|
220
|
-
onHotspotColorChange={color =>
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
onOutlineColorChange={color =>
|
|
224
|
-
this.handleColorChange('outline', color)
|
|
225
|
-
}
|
|
195
|
+
onHotspotColorChange={(color) => this.handleColorChange('hotspot', color)}
|
|
196
|
+
onOutlineColorChange={(color) => this.handleColorChange('outline', color)}
|
|
226
197
|
/>
|
|
227
198
|
|
|
228
199
|
<HotspotContainer
|
|
@@ -274,41 +245,41 @@ export class Root extends React.Component {
|
|
|
274
245
|
}
|
|
275
246
|
}
|
|
276
247
|
|
|
277
|
-
const styles = theme => ({
|
|
248
|
+
const styles = (theme) => ({
|
|
278
249
|
base: {
|
|
279
|
-
marginTop: theme.spacing.unit * 3
|
|
250
|
+
marginTop: theme.spacing.unit * 3,
|
|
280
251
|
},
|
|
281
252
|
container: {
|
|
282
253
|
display: 'flex',
|
|
283
|
-
marginTop: theme.spacing.unit
|
|
254
|
+
marginTop: theme.spacing.unit,
|
|
284
255
|
},
|
|
285
256
|
dimensions: {
|
|
286
|
-
display: 'flex'
|
|
257
|
+
display: 'flex',
|
|
287
258
|
},
|
|
288
259
|
field: {
|
|
289
260
|
flex: 1,
|
|
290
|
-
width: '90%'
|
|
261
|
+
width: '90%',
|
|
291
262
|
},
|
|
292
263
|
label: {
|
|
293
|
-
marginTop: theme.spacing.unit * 4
|
|
264
|
+
marginTop: theme.spacing.unit * 4,
|
|
294
265
|
},
|
|
295
266
|
prompt: {
|
|
296
267
|
paddingTop: theme.spacing.unit * 2,
|
|
297
|
-
width: '100%'
|
|
268
|
+
width: '100%',
|
|
298
269
|
},
|
|
299
270
|
subheading: {
|
|
300
|
-
marginRight: '5px'
|
|
271
|
+
marginRight: '5px',
|
|
301
272
|
},
|
|
302
273
|
regular: {
|
|
303
|
-
marginBottom: theme.spacing.unit * 3
|
|
274
|
+
marginBottom: theme.spacing.unit * 3,
|
|
304
275
|
},
|
|
305
276
|
switchElement: {
|
|
306
277
|
justifyContent: 'space-between',
|
|
307
|
-
margin: 0
|
|
278
|
+
margin: 0,
|
|
308
279
|
},
|
|
309
280
|
flexContainer: {
|
|
310
281
|
display: 'flex',
|
|
311
|
-
alignItems: 'center'
|
|
282
|
+
alignItems: 'center',
|
|
312
283
|
},
|
|
313
284
|
tooltip: {
|
|
314
285
|
fontSize: '12px',
|
|
@@ -318,8 +289,8 @@ const styles = theme => ({
|
|
|
318
289
|
errorText: {
|
|
319
290
|
fontSize: '12px',
|
|
320
291
|
color: 'red',
|
|
321
|
-
padding: '5px 0'
|
|
322
|
-
}
|
|
292
|
+
padding: '5px 0',
|
|
293
|
+
},
|
|
323
294
|
});
|
|
324
295
|
|
|
325
296
|
Root.propTypes = {
|
|
@@ -328,11 +299,11 @@ Root.propTypes = {
|
|
|
328
299
|
model: PropTypes.object.isRequired,
|
|
329
300
|
imageSupport: PropTypes.shape({
|
|
330
301
|
add: PropTypes.func,
|
|
331
|
-
delete: PropTypes.func
|
|
302
|
+
delete: PropTypes.func,
|
|
332
303
|
}),
|
|
333
304
|
uploadSoundSupport: PropTypes.shape({
|
|
334
305
|
add: PropTypes.func,
|
|
335
|
-
delete: PropTypes.func
|
|
306
|
+
delete: PropTypes.func,
|
|
336
307
|
}),
|
|
337
308
|
onImageUpload: PropTypes.func.isRequired,
|
|
338
309
|
onColorChanged: PropTypes.func.isRequired,
|
|
@@ -4,36 +4,25 @@ import { withStyles } from '@material-ui/core/styles/index';
|
|
|
4
4
|
|
|
5
5
|
import Button from './button';
|
|
6
6
|
|
|
7
|
-
const UploadControl = ({
|
|
8
|
-
classNameButton,
|
|
9
|
-
classNameSection,
|
|
10
|
-
classes,
|
|
11
|
-
label,
|
|
12
|
-
onInputClick,
|
|
13
|
-
onUploadImage,
|
|
14
|
-
setRef
|
|
15
|
-
}) => (
|
|
7
|
+
const UploadControl = ({ classNameButton, classNameSection, classes, label, onInputClick, onUploadImage, setRef }) => (
|
|
16
8
|
<div className={classNameSection}>
|
|
17
|
-
<Button
|
|
18
|
-
className={classNameButton}
|
|
19
|
-
label={label}
|
|
20
|
-
onClick={onInputClick}
|
|
21
|
-
/>
|
|
9
|
+
<Button className={classNameButton} label={label} onClick={onInputClick} />
|
|
22
10
|
<input
|
|
23
11
|
accept="image/*"
|
|
24
12
|
className={classes.input}
|
|
25
13
|
onChange={onUploadImage}
|
|
26
|
-
ref={ref => {
|
|
14
|
+
ref={(ref) => {
|
|
15
|
+
setRef(ref);
|
|
16
|
+
}}
|
|
27
17
|
type="file"
|
|
28
18
|
/>
|
|
29
19
|
</div>
|
|
30
20
|
);
|
|
31
21
|
|
|
32
|
-
|
|
33
22
|
const styles = () => ({
|
|
34
23
|
input: {
|
|
35
|
-
display: 'none'
|
|
36
|
-
}
|
|
24
|
+
display: 'none',
|
|
25
|
+
},
|
|
37
26
|
});
|
|
38
27
|
|
|
39
28
|
UploadControl.propTypes = {
|
|
@@ -43,12 +32,12 @@ UploadControl.propTypes = {
|
|
|
43
32
|
label: PropTypes.string.isRequired,
|
|
44
33
|
onInputClick: PropTypes.func.isRequired,
|
|
45
34
|
onUploadImage: PropTypes.func.isRequired,
|
|
46
|
-
setRef: PropTypes.func.isRequired
|
|
35
|
+
setRef: PropTypes.func.isRequired,
|
|
47
36
|
};
|
|
48
37
|
|
|
49
38
|
UploadControl.defaultProps = {
|
|
50
39
|
classNameButton: '',
|
|
51
|
-
classNameSection: ''
|
|
40
|
+
classNameSection: '',
|
|
52
41
|
};
|
|
53
42
|
|
|
54
43
|
export default withStyles(styles)(UploadControl);
|
package/configure/src/utils.js
CHANGED
|
@@ -9,28 +9,29 @@ const updateImageDimensions = (initialDim, nextDim, keepAspectRatio, resizeType)
|
|
|
9
9
|
// if we want to change image height => we update the width accordingly
|
|
10
10
|
return {
|
|
11
11
|
width: nextDim.height * imageAspectRatio,
|
|
12
|
-
height: nextDim.height
|
|
13
|
-
}
|
|
12
|
+
height: nextDim.height,
|
|
13
|
+
};
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
// if we want to change image width => we update the height accordingly
|
|
17
17
|
return {
|
|
18
18
|
width: nextDim.width,
|
|
19
|
-
height: nextDim.width / imageAspectRatio
|
|
20
|
-
}
|
|
19
|
+
height: nextDim.width / imageAspectRatio,
|
|
20
|
+
};
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
// if we don't want to keep aspect ratio, we just update both values
|
|
24
24
|
return {
|
|
25
25
|
width: nextDim.width,
|
|
26
|
-
height: nextDim.height
|
|
27
|
-
}
|
|
26
|
+
height: nextDim.height,
|
|
27
|
+
};
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
// referenceInitialValue = the initial value of the Stage
|
|
31
31
|
// referenceNextValue = the next value of the Stage
|
|
32
32
|
// currentValue = the value that has to be re-sized influenced by the changes that were made on the Stage
|
|
33
|
-
const getDelta = (referenceInitialValue, referenceNextValue, currentValue) =>
|
|
33
|
+
const getDelta = (referenceInitialValue, referenceNextValue, currentValue) =>
|
|
34
|
+
(referenceNextValue / referenceInitialValue) * currentValue;
|
|
34
35
|
|
|
35
36
|
const getUpdatedRectangle = (initialDim, nextDim, shape) => ({
|
|
36
37
|
...shape,
|
|
@@ -42,17 +43,17 @@ const getUpdatedRectangle = (initialDim, nextDim, shape) => ({
|
|
|
42
43
|
|
|
43
44
|
const getUpdatedPlygon = (initialDim, nextDim, shape) => ({
|
|
44
45
|
...shape,
|
|
45
|
-
points: shape.points.map(point => ({
|
|
46
|
+
points: shape.points.map((point) => ({
|
|
46
47
|
x: getDelta(initialDim.width, nextDim.width, point.x),
|
|
47
48
|
y: getDelta(initialDim.height, nextDim.height, point.y),
|
|
48
|
-
}))
|
|
49
|
+
})),
|
|
49
50
|
});
|
|
50
51
|
|
|
51
52
|
// initialDim = the initial dimensions: { width, height } of the Stage
|
|
52
53
|
// nextDim = the next dimensions: { width, height } of the Stage
|
|
53
54
|
// shapes = array of shapes that have to be re-sized and re-positioned
|
|
54
55
|
const getUpdatedShapes = (initialDim, nextDim, shapes) => {
|
|
55
|
-
return shapes.map(shape => {
|
|
56
|
+
return shapes.map((shape) => {
|
|
56
57
|
if (shape.group === 'rectangles') {
|
|
57
58
|
return getUpdatedRectangle(initialDim, nextDim, shape);
|
|
58
59
|
}
|
|
@@ -75,16 +76,19 @@ const getAllShapes = (shapesMap) => {
|
|
|
75
76
|
const shapesKeys = Object.keys(shapesMap);
|
|
76
77
|
|
|
77
78
|
return shapesKeys.length
|
|
78
|
-
? shapesKeys.reduce(
|
|
79
|
-
acc
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
79
|
+
? shapesKeys.reduce(
|
|
80
|
+
(acc, currentShapeKey) =>
|
|
81
|
+
acc.concat(
|
|
82
|
+
shapesMap[currentShapeKey]
|
|
83
|
+
? shapesMap[currentShapeKey].map((shape, index) => ({
|
|
84
|
+
...shape,
|
|
85
|
+
group: currentShapeKey,
|
|
86
|
+
index: shape.index || acc.length + index,
|
|
87
|
+
}))
|
|
88
|
+
: [],
|
|
89
|
+
),
|
|
90
|
+
shapesArray,
|
|
91
|
+
)
|
|
88
92
|
: shapesArray;
|
|
89
93
|
};
|
|
90
94
|
|
|
@@ -97,7 +101,7 @@ const groupShapes = (shapesArray) => {
|
|
|
97
101
|
shapesArray = shapesArray || [];
|
|
98
102
|
const shapesMap = {
|
|
99
103
|
rectangles: [],
|
|
100
|
-
polygons: []
|
|
104
|
+
polygons: [],
|
|
101
105
|
};
|
|
102
106
|
|
|
103
107
|
if (shapesArray.length) {
|
|
@@ -110,15 +114,18 @@ const groupShapes = (shapesArray) => {
|
|
|
110
114
|
return cloneDeep(shapesMap);
|
|
111
115
|
};
|
|
112
116
|
|
|
113
|
-
const generateValidationMessage = config => {
|
|
117
|
+
const generateValidationMessage = (config) => {
|
|
114
118
|
const { minShapes, maxShapes, maxSelections } = config;
|
|
115
119
|
|
|
116
|
-
const shapesMessage =
|
|
117
|
-
(maxShapes ? `and at most ${maxShapes} ` : '') + 'shapes defined.';
|
|
120
|
+
const shapesMessage =
|
|
121
|
+
`\nThere should be at least ${minShapes} ` + (maxShapes ? `and at most ${maxShapes} ` : '') + 'shapes defined.';
|
|
118
122
|
|
|
119
|
-
const selectionsMessage =
|
|
120
|
-
|
|
121
|
-
(maxSelections ?
|
|
123
|
+
const selectionsMessage =
|
|
124
|
+
`\nThere should be at least 1 ` +
|
|
125
|
+
(maxSelections ? `and at most ${maxSelections} ` : '') +
|
|
126
|
+
'shape' +
|
|
127
|
+
(maxSelections ? 's' : '') +
|
|
128
|
+
' selected.';
|
|
122
129
|
|
|
123
130
|
const message = 'Validation requirements:' + shapesMessage + selectionsMessage;
|
|
124
131
|
|
|
@@ -132,5 +139,5 @@ export {
|
|
|
132
139
|
getAllShapes,
|
|
133
140
|
groupShapes,
|
|
134
141
|
getUpdatedRectangle,
|
|
135
|
-
getUpdatedPlygon
|
|
142
|
+
getUpdatedPlygon,
|
|
136
143
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/defaults.js"],"names":["prompt","imageUrl","shapes","rectangles","polygons","multipleCorrect","partialScoring","dimensions","height","width","hotspotColor","hotspotList","outlineColor","outlineList"],"mappings":";;;;;;eAAe;AACbA,EAAAA,MAAM,EAAE,6BADK;AAEbC,EAAAA,QAAQ,EAAE,EAFG;AAGbC,EAAAA,MAAM,EAAE;AACNC,IAAAA,UAAU,EAAE,EADN;AAENC,IAAAA,QAAQ,EAAE;AAFJ,GAHK;AAObC,EAAAA,eAAe,EAAE,IAPJ;AAQbC,EAAAA,cAAc,EAAE,KARH;AASbC,EAAAA,UAAU,EAAE;AACVC,IAAAA,MAAM,EAAE,CADE;AAEVC,IAAAA,KAAK,EAAE;AAFG,GATC;AAabC,EAAAA,YAAY,EAAE,2BAbD;AAcbC,EAAAA,WAAW,EAAE,
|
|
1
|
+
{"version":3,"sources":["../src/defaults.js"],"names":["prompt","imageUrl","shapes","rectangles","polygons","multipleCorrect","partialScoring","dimensions","height","width","hotspotColor","hotspotList","outlineColor","outlineList"],"mappings":";;;;;;eAAe;AACbA,EAAAA,MAAM,EAAE,6BADK;AAEbC,EAAAA,QAAQ,EAAE,EAFG;AAGbC,EAAAA,MAAM,EAAE;AACNC,IAAAA,UAAU,EAAE,EADN;AAENC,IAAAA,QAAQ,EAAE;AAFJ,GAHK;AAObC,EAAAA,eAAe,EAAE,IAPJ;AAQbC,EAAAA,cAAc,EAAE,KARH;AASbC,EAAAA,UAAU,EAAE;AACVC,IAAAA,MAAM,EAAE,CADE;AAEVC,IAAAA,KAAK,EAAE;AAFG,GATC;AAabC,EAAAA,YAAY,EAAE,2BAbD;AAcbC,EAAAA,WAAW,EAAE,CAAC,2BAAD,CAdA;AAebC,EAAAA,YAAY,EAAE,MAfD;AAgBbC,EAAAA,WAAW,EAAE,CAAC,MAAD;AAhBA,C","sourcesContent":["export default {\n prompt: 'This is the question prompt',\n imageUrl: '',\n shapes: {\n rectangles: [],\n polygons: [],\n },\n multipleCorrect: true,\n partialScoring: false,\n dimensions: {\n height: 0,\n width: 0,\n },\n hotspotColor: 'rgba(137, 183, 244, 0.65)',\n hotspotList: ['rgba(137, 183, 244, 0.65)'],\n outlineColor: 'blue',\n outlineList: ['blue'],\n};\n"],"file":"defaults.js"}
|