@pie-lib/rubric 1.0.0-beta.2 → 1.0.0-beta.4
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 +159 -77
- package/package.json +2 -3
- package/src/authoring.jsx +60 -62
- package/src/index.js +1 -1
- package/src/point-menu.jsx +9 -9
- package/lib/authoring.js +0 -460
- package/lib/authoring.js.map +0 -1
- package/lib/index.js +0 -23
- package/lib/index.js.map +0 -1
- package/lib/point-menu.js +0 -172
- package/lib/point-menu.js.map +0 -1
package/src/authoring.jsx
CHANGED
|
@@ -35,15 +35,16 @@ const reorder = (list, startIndex, endIndex) => {
|
|
|
35
35
|
export const RubricType = PropTypes.shape({
|
|
36
36
|
excludeZero: PropTypes.bool,
|
|
37
37
|
points: PropTypes.arrayOf(PropTypes.string),
|
|
38
|
-
sampleAnswers: PropTypes.arrayOf(PropTypes.string)
|
|
38
|
+
sampleAnswers: PropTypes.arrayOf(PropTypes.string),
|
|
39
|
+
maxPoints: PropTypes.number,
|
|
39
40
|
});
|
|
40
41
|
|
|
41
|
-
const MaxPoints = withStyles(theme => ({
|
|
42
|
+
const MaxPoints = withStyles((theme) => ({
|
|
42
43
|
formControl: {
|
|
43
44
|
minWidth: '120px',
|
|
44
|
-
margin: theme.spacing.unit
|
|
45
|
-
}
|
|
46
|
-
}))(props => {
|
|
45
|
+
margin: theme.spacing.unit,
|
|
46
|
+
},
|
|
47
|
+
}))((props) => {
|
|
47
48
|
const { value, onChange, max, classes } = props;
|
|
48
49
|
|
|
49
50
|
return (
|
|
@@ -51,12 +52,8 @@ const MaxPoints = withStyles(theme => ({
|
|
|
51
52
|
<InputLabel width={100} htmlFor="...">
|
|
52
53
|
Max Points
|
|
53
54
|
</InputLabel>
|
|
54
|
-
<Select
|
|
55
|
-
|
|
56
|
-
onChange={e => onChange(e.target.value)}
|
|
57
|
-
input={<OutlinedInput labelWidth={80} />}
|
|
58
|
-
>
|
|
59
|
-
{range(1, max).map(v => (
|
|
55
|
+
<Select value={value} onChange={(e) => onChange(e.target.value)} input={<OutlinedInput labelWidth={80} />}>
|
|
56
|
+
{range(1, max).map((v) => (
|
|
60
57
|
<MenuItem key={`${v}`} value={v}>
|
|
61
58
|
{v}
|
|
62
59
|
</MenuItem>
|
|
@@ -68,37 +65,37 @@ const MaxPoints = withStyles(theme => ({
|
|
|
68
65
|
|
|
69
66
|
// if the value is null or 'null', the Sample Answer input field for that point will not be dispalyed
|
|
70
67
|
// if the value is '', the Sample Answer input field will be empty
|
|
71
|
-
const checkSampleAnswer = sampleAnswer => sampleAnswer === null || sampleAnswer === 'null';
|
|
68
|
+
const checkSampleAnswer = (sampleAnswer) => sampleAnswer === null || sampleAnswer === 'null';
|
|
72
69
|
|
|
73
|
-
export const PointConfig = withStyles(theme => ({
|
|
70
|
+
export const PointConfig = withStyles((theme) => ({
|
|
74
71
|
pointConfig: {},
|
|
75
72
|
row: {
|
|
76
73
|
display: 'flex',
|
|
77
74
|
width: '100%',
|
|
78
|
-
position: 'relative'
|
|
75
|
+
position: 'relative',
|
|
79
76
|
},
|
|
80
77
|
editor: {
|
|
81
78
|
width: '100%',
|
|
82
|
-
backgroundColor:
|
|
79
|
+
backgroundColor: `${theme.palette.common.white} !important`,
|
|
83
80
|
},
|
|
84
81
|
dragIndicator: {
|
|
85
82
|
paddingTop: theme.spacing.unit,
|
|
86
|
-
color: grey[500]
|
|
83
|
+
color: grey[500],
|
|
87
84
|
},
|
|
88
85
|
pointsLabel: {
|
|
89
86
|
color: grey[500],
|
|
90
87
|
paddingBottom: theme.spacing.unit,
|
|
91
|
-
textTransform: 'uppercase'
|
|
88
|
+
textTransform: 'uppercase',
|
|
92
89
|
},
|
|
93
90
|
sampleAnswersEditor: {
|
|
94
|
-
paddingLeft: theme.spacing.unit * 3
|
|
91
|
+
paddingLeft: theme.spacing.unit * 3,
|
|
95
92
|
},
|
|
96
93
|
pointMenu: {
|
|
97
94
|
position: 'absolute',
|
|
98
|
-
right: 0
|
|
99
|
-
}
|
|
100
|
-
}))(props => {
|
|
101
|
-
const { points, content, classes, sampleAnswer } = props;
|
|
95
|
+
right: 0,
|
|
96
|
+
},
|
|
97
|
+
}))((props) => {
|
|
98
|
+
const { points, content, classes, sampleAnswer, mathMlOptions = {} } = props;
|
|
102
99
|
const pointsLabel = `${points} ${points <= 1 ? 'pt' : 'pts'}`;
|
|
103
100
|
const showSampleAnswer = checkSampleAnswer(sampleAnswer);
|
|
104
101
|
|
|
@@ -107,17 +104,24 @@ export const PointConfig = withStyles(theme => ({
|
|
|
107
104
|
<Typography variant="overline" className={classes.pointsLabel}>
|
|
108
105
|
{pointsLabel}
|
|
109
106
|
</Typography>
|
|
107
|
+
|
|
110
108
|
<div className={classes.row}>
|
|
111
109
|
<DragIndicator className={classes.dragIndicator} />
|
|
112
|
-
<EditableHtml
|
|
110
|
+
<EditableHtml
|
|
111
|
+
className={classes.editor}
|
|
112
|
+
markup={content}
|
|
113
|
+
onChange={props.onChange}
|
|
114
|
+
mathMlOptions={mathMlOptions}
|
|
115
|
+
/>
|
|
113
116
|
<PointMenu
|
|
114
117
|
classes={{
|
|
115
|
-
icon: classes.pointMenu
|
|
118
|
+
icon: classes.pointMenu,
|
|
116
119
|
}}
|
|
117
120
|
showSampleAnswer={showSampleAnswer}
|
|
118
121
|
onChange={props.onMenuChange}
|
|
119
122
|
/>
|
|
120
123
|
</div>
|
|
124
|
+
|
|
121
125
|
{!showSampleAnswer && (
|
|
122
126
|
<div className={classes.sampleAnswersEditor}>
|
|
123
127
|
<Typography variant="overline" className={classes.dragIndicator}>
|
|
@@ -127,6 +131,7 @@ export const PointConfig = withStyles(theme => ({
|
|
|
127
131
|
className={classes.editor}
|
|
128
132
|
markup={sampleAnswer}
|
|
129
133
|
onChange={props.onSampleChange}
|
|
134
|
+
mathMlOptions={mathMlOptions}
|
|
130
135
|
/>
|
|
131
136
|
</div>
|
|
132
137
|
)}
|
|
@@ -139,12 +144,12 @@ export class RawAuthoring extends React.Component {
|
|
|
139
144
|
classes: PropTypes.object.isRequired,
|
|
140
145
|
className: PropTypes.string,
|
|
141
146
|
value: RubricType,
|
|
142
|
-
onChange: PropTypes.func
|
|
147
|
+
onChange: PropTypes.func,
|
|
143
148
|
};
|
|
144
149
|
|
|
145
150
|
static defaultProps = {};
|
|
146
151
|
|
|
147
|
-
dragEnd = result => {
|
|
152
|
+
dragEnd = (result) => {
|
|
148
153
|
if (!result.destination) {
|
|
149
154
|
return;
|
|
150
155
|
}
|
|
@@ -152,16 +157,12 @@ export class RawAuthoring extends React.Component {
|
|
|
152
157
|
const { value, onChange } = this.props;
|
|
153
158
|
|
|
154
159
|
const points = reorder(value.points, result.source.index, result.destination.index);
|
|
155
|
-
const sampleAnswers = reorder(
|
|
156
|
-
value.sampleAnswers,
|
|
157
|
-
result.source.index,
|
|
158
|
-
result.destination.index
|
|
159
|
-
);
|
|
160
|
+
const sampleAnswers = reorder(value.sampleAnswers, result.source.index, result.destination.index);
|
|
160
161
|
|
|
161
162
|
onChange({ ...value, points, sampleAnswers });
|
|
162
163
|
};
|
|
163
164
|
|
|
164
|
-
changeMaxPoints = maxPoints => {
|
|
165
|
+
changeMaxPoints = (maxPoints) => {
|
|
165
166
|
const { value, onChange } = this.props;
|
|
166
167
|
const currentMax = value.points.length - 1;
|
|
167
168
|
|
|
@@ -241,7 +242,8 @@ export class RawAuthoring extends React.Component {
|
|
|
241
242
|
};
|
|
242
243
|
|
|
243
244
|
render() {
|
|
244
|
-
const { classes, className, value } = this.props;
|
|
245
|
+
const { classes, className, value, mathMlOptions = {} } = this.props;
|
|
246
|
+
let { excludeZeroEnabled = true, maxPointsEnabled = true } = value || {};
|
|
245
247
|
|
|
246
248
|
if (value && Number.isFinite(value.maxPoints)) {
|
|
247
249
|
// eslint-disable-next-line no-console
|
|
@@ -254,26 +256,25 @@ export class RawAuthoring extends React.Component {
|
|
|
254
256
|
Rubric
|
|
255
257
|
</Typography>
|
|
256
258
|
<FormGroup row>
|
|
257
|
-
<MaxPoints max={10} value={value.points.length - 1} onChange={this.changeMaxPoints} />
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
259
|
+
{maxPointsEnabled && <MaxPoints max={10} value={value.points.length - 1} onChange={this.changeMaxPoints} />}
|
|
260
|
+
{excludeZeroEnabled && (
|
|
261
|
+
<FormControlLabel
|
|
262
|
+
label="Exclude zeros"
|
|
263
|
+
control={<Checkbox checked={value.excludeZero} onChange={this.excludeZeros} />}
|
|
264
|
+
/>
|
|
265
|
+
)}
|
|
262
266
|
</FormGroup>
|
|
267
|
+
|
|
263
268
|
<div className={classes.container}>
|
|
264
269
|
<DragDropContext onDragEnd={this.dragEnd}>
|
|
265
270
|
<Droppable droppableId="droppable">
|
|
266
|
-
{provided => (
|
|
271
|
+
{(provided) => (
|
|
267
272
|
<div {...provided.droppableProps} ref={provided.innerRef}>
|
|
268
273
|
{value.points.map(
|
|
269
274
|
(p, index) =>
|
|
270
275
|
this.shouldRenderPoint(index, value) && (
|
|
271
|
-
<Draggable
|
|
272
|
-
|
|
273
|
-
index={index}
|
|
274
|
-
draggableId={index.toString()}
|
|
275
|
-
>
|
|
276
|
-
{provided => (
|
|
276
|
+
<Draggable key={`${p.points}-${index}`} index={index} draggableId={index.toString()}>
|
|
277
|
+
{(provided) => (
|
|
277
278
|
<div
|
|
278
279
|
className={classes.configHolder}
|
|
279
280
|
ref={provided.innerRef}
|
|
@@ -284,18 +285,15 @@ export class RawAuthoring extends React.Component {
|
|
|
284
285
|
points={value.points.length - 1 - index}
|
|
285
286
|
content={p}
|
|
286
287
|
sampleAnswer={value.sampleAnswers && value.sampleAnswers[index]}
|
|
287
|
-
onChange={content => this.changeContent(index, content, 'points')}
|
|
288
|
-
onSampleChange={content =>
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
onMenuChange={clickedItem =>
|
|
292
|
-
this.onPointMenuChange(index, clickedItem)
|
|
293
|
-
}
|
|
288
|
+
onChange={(content) => this.changeContent(index, content, 'points')}
|
|
289
|
+
onSampleChange={(content) => this.changeContent(index, content, 'sampleAnswers')}
|
|
290
|
+
onMenuChange={(clickedItem) => this.onPointMenuChange(index, clickedItem)}
|
|
291
|
+
mathMlOptions={mathMlOptions}
|
|
294
292
|
/>
|
|
295
293
|
</div>
|
|
296
294
|
)}
|
|
297
295
|
</Draggable>
|
|
298
|
-
)
|
|
296
|
+
),
|
|
299
297
|
)}
|
|
300
298
|
{provided.placeholder}
|
|
301
299
|
</div>
|
|
@@ -308,28 +306,28 @@ export class RawAuthoring extends React.Component {
|
|
|
308
306
|
}
|
|
309
307
|
}
|
|
310
308
|
|
|
311
|
-
const styles = theme => ({
|
|
309
|
+
const styles = (theme) => ({
|
|
312
310
|
container: {
|
|
313
311
|
backgroundColor: grey[200],
|
|
314
312
|
borderWidth: 1,
|
|
315
313
|
borderStyle: 'solid',
|
|
316
314
|
borderColor: grey[300],
|
|
317
315
|
padding: theme.spacing.unit * 2,
|
|
318
|
-
margin: theme.spacing.unit
|
|
316
|
+
margin: theme.spacing.unit,
|
|
319
317
|
},
|
|
320
318
|
configHolder: {
|
|
321
319
|
paddingTop: theme.spacing.unit,
|
|
322
|
-
paddingBottom: theme.spacing.unit
|
|
320
|
+
paddingBottom: theme.spacing.unit,
|
|
323
321
|
},
|
|
324
322
|
rubricTitle: {
|
|
325
323
|
paddingLeft: theme.spacing.unit,
|
|
326
|
-
margin: theme.spacing.unit
|
|
327
|
-
}
|
|
324
|
+
margin: theme.spacing.unit,
|
|
325
|
+
},
|
|
328
326
|
});
|
|
329
327
|
|
|
330
328
|
const StyledRawAuthoring = withStyles(styles)(RawAuthoring);
|
|
331
329
|
|
|
332
|
-
const Reverse = props => {
|
|
330
|
+
const Reverse = (props) => {
|
|
333
331
|
const points = Array.from(props.value.points || []).reverse();
|
|
334
332
|
let sampleAnswers = Array.from(props.value.sampleAnswers || []).reverse();
|
|
335
333
|
|
|
@@ -341,11 +339,11 @@ const Reverse = props => {
|
|
|
341
339
|
|
|
342
340
|
const value = { ...props.value, points, sampleAnswers };
|
|
343
341
|
|
|
344
|
-
const onChange = value => {
|
|
342
|
+
const onChange = (value) => {
|
|
345
343
|
props.onChange({
|
|
346
344
|
...value,
|
|
347
345
|
points: Array.from(value.points || []).reverse(),
|
|
348
|
-
sampleAnswers: Array.from(value.sampleAnswers || []).reverse()
|
|
346
|
+
sampleAnswers: Array.from(value.sampleAnswers || []).reverse(),
|
|
349
347
|
});
|
|
350
348
|
};
|
|
351
349
|
|
|
@@ -355,7 +353,7 @@ const Reverse = props => {
|
|
|
355
353
|
Reverse.propTypes = {
|
|
356
354
|
value: RubricType,
|
|
357
355
|
getIndex: PropTypes.func,
|
|
358
|
-
onChange: PropTypes.func
|
|
356
|
+
onChange: PropTypes.func,
|
|
359
357
|
};
|
|
360
358
|
|
|
361
359
|
export default Reverse;
|
package/src/index.js
CHANGED
package/src/point-menu.jsx
CHANGED
|
@@ -10,18 +10,18 @@ export class IconMenu extends React.Component {
|
|
|
10
10
|
static propTypes = {
|
|
11
11
|
opts: PropTypes.object,
|
|
12
12
|
onClick: PropTypes.func.isRequired,
|
|
13
|
-
classes: PropTypes.object.isRequired
|
|
13
|
+
classes: PropTypes.object.isRequired,
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
constructor(props) {
|
|
17
17
|
super(props);
|
|
18
18
|
this.state = {
|
|
19
19
|
anchorEl: undefined,
|
|
20
|
-
open: false
|
|
20
|
+
open: false,
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
handleClick = event => this.setState({ open: true, anchorEl: event.currentTarget });
|
|
24
|
+
handleClick = (event) => this.setState({ open: true, anchorEl: event.currentTarget });
|
|
25
25
|
|
|
26
26
|
handleRequestClose = () => this.setState({ open: false });
|
|
27
27
|
|
|
@@ -30,7 +30,7 @@ export class IconMenu extends React.Component {
|
|
|
30
30
|
const { open, anchorEl } = this.state;
|
|
31
31
|
const keys = Object.keys(opts) || [];
|
|
32
32
|
|
|
33
|
-
const handleMenuClick = key => () => {
|
|
33
|
+
const handleMenuClick = (key) => () => {
|
|
34
34
|
onClick(key);
|
|
35
35
|
this.handleRequestClose();
|
|
36
36
|
};
|
|
@@ -52,7 +52,7 @@ export class IconMenu extends React.Component {
|
|
|
52
52
|
style={{ transform: 'translate(-15px, -15px)' }}
|
|
53
53
|
transformOrigin={{
|
|
54
54
|
vertical: 'center',
|
|
55
|
-
horizontal: 'right'
|
|
55
|
+
horizontal: 'right',
|
|
56
56
|
}}
|
|
57
57
|
>
|
|
58
58
|
{keys.map((k, index) => (
|
|
@@ -70,11 +70,11 @@ export default class PointMenu extends React.Component {
|
|
|
70
70
|
static propTypes = {
|
|
71
71
|
onChange: PropTypes.func.isRequired,
|
|
72
72
|
classes: PropTypes.object.isRequired,
|
|
73
|
-
showSampleAnswer: PropTypes.bool.isRequired
|
|
73
|
+
showSampleAnswer: PropTypes.bool.isRequired,
|
|
74
74
|
};
|
|
75
75
|
|
|
76
76
|
static defaultProps = {
|
|
77
|
-
classes: {}
|
|
77
|
+
classes: {},
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
render() {
|
|
@@ -83,9 +83,9 @@ export default class PointMenu extends React.Component {
|
|
|
83
83
|
|
|
84
84
|
return (
|
|
85
85
|
<IconMenu
|
|
86
|
-
onClick={key => onChange(key)}
|
|
86
|
+
onClick={(key) => onChange(key)}
|
|
87
87
|
opts={{
|
|
88
|
-
sample: sampleText
|
|
88
|
+
sample: sampleText,
|
|
89
89
|
}}
|
|
90
90
|
classes={classes}
|
|
91
91
|
/>
|