@pie-lib/rubric 1.0.0-beta.5 → 1.0.0-next.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.
- package/CHANGELOG.json +1 -407
- package/CHANGELOG.md +332 -4
- package/LICENSE.md +5 -0
- package/NEXT.CHANGELOG.json +1 -0
- package/lib/authoring.js +261 -172
- package/lib/authoring.js.map +1 -1
- package/lib/index.js +3 -3
- package/lib/index.js.map +1 -1
- package/lib/point-menu.js +22 -37
- package/lib/point-menu.js.map +1 -1
- package/package.json +18 -7
- package/src/__tests__/rubric.test.jsx +179 -0
- package/src/authoring.jsx +211 -159
- package/src/index.js +1 -0
- package/src/point-menu.jsx +8 -15
package/src/authoring.jsx
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import Select from '@material
|
|
8
|
-
import FormControl from '@material
|
|
9
|
-
import MenuItem from '@material
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
|
|
5
|
+
import InputLabel from '@mui/material/InputLabel';
|
|
6
|
+
import OutlinedInput from '@mui/material/OutlinedInput';
|
|
7
|
+
import Select from '@mui/material/Select';
|
|
8
|
+
import FormControl from '@mui/material/FormControl';
|
|
9
|
+
import MenuItem from '@mui/material/MenuItem';
|
|
10
10
|
import times from 'lodash/times';
|
|
11
|
-
import Checkbox from '@material
|
|
12
|
-
import FormGroup from '@material
|
|
13
|
-
import FormControlLabel from '@material
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import EditableHtml from '@pie-lib/editable-html';
|
|
18
|
-
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
|
|
11
|
+
import Checkbox from '@mui/material/Checkbox';
|
|
12
|
+
import FormGroup from '@mui/material/FormGroup';
|
|
13
|
+
import FormControlLabel from '@mui/material/FormControlLabel';
|
|
14
|
+
import Typography from '@mui/material/Typography';
|
|
15
|
+
import DragIndicator from '@mui/icons-material/DragIndicator';
|
|
16
|
+
import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';
|
|
19
17
|
import debug from 'debug';
|
|
20
18
|
import takeRight from 'lodash/takeRight';
|
|
21
19
|
import PointMenu from './point-menu';
|
|
22
|
-
|
|
23
20
|
import range from 'lodash/range';
|
|
21
|
+
import EditableHtml from '@pie-lib/editable-html';
|
|
22
|
+
import { InputContainer } from '@pie-lib/config-ui';
|
|
23
|
+
import { grey } from '@mui/material/colors';
|
|
24
|
+
|
|
24
25
|
const log = debug('pie-lib:rubric:authoring');
|
|
25
26
|
|
|
26
27
|
const reorder = (list, startIndex, endIndex) => {
|
|
@@ -37,23 +38,25 @@ export const RubricType = PropTypes.shape({
|
|
|
37
38
|
points: PropTypes.arrayOf(PropTypes.string),
|
|
38
39
|
sampleAnswers: PropTypes.arrayOf(PropTypes.string),
|
|
39
40
|
maxPoints: PropTypes.number,
|
|
41
|
+
rubriclessInstruction: PropTypes.string,
|
|
40
42
|
});
|
|
41
43
|
|
|
42
|
-
const MaxPoints =
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
margin: theme.spacing.unit,
|
|
46
|
-
},
|
|
47
|
-
}))((props) => {
|
|
48
|
-
const { value, onChange, max, classes } = props;
|
|
44
|
+
const MaxPoints = (props) => {
|
|
45
|
+
const { value, onChange, max } = props;
|
|
46
|
+
const labelId = 'max-points-label';
|
|
49
47
|
|
|
50
48
|
return (
|
|
51
|
-
<FormControl
|
|
52
|
-
<InputLabel
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
{
|
|
49
|
+
<FormControl sx={{ minWidth: 120, m: 1 }} variant="outlined">
|
|
50
|
+
<InputLabel id={labelId}>Max Points</InputLabel>
|
|
51
|
+
<Select
|
|
52
|
+
labelId={labelId}
|
|
53
|
+
label="Max Points"
|
|
54
|
+
value={value}
|
|
55
|
+
onChange={(e) => onChange(e.target.value)}
|
|
56
|
+
input={<OutlinedInput label="Max Points" />}
|
|
57
|
+
MenuProps={{ transitionDuration: { enter: 225, exit: 195 } }}
|
|
58
|
+
>
|
|
59
|
+
{range(1, max + 1).map((v) => (
|
|
57
60
|
<MenuItem key={`${v}`} value={v}>
|
|
58
61
|
{v}
|
|
59
62
|
</MenuItem>
|
|
@@ -61,89 +64,102 @@ const MaxPoints = withStyles((theme) => ({
|
|
|
61
64
|
</Select>
|
|
62
65
|
</FormControl>
|
|
63
66
|
);
|
|
64
|
-
}
|
|
67
|
+
};
|
|
65
68
|
|
|
66
69
|
// if the value is null or 'null', the Sample Answer input field for that point will not be dispalyed
|
|
67
70
|
// if the value is '', the Sample Answer input field will be empty
|
|
68
71
|
const checkSampleAnswer = (sampleAnswer) => sampleAnswer === null || sampleAnswer === 'null';
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
right: 0,
|
|
96
|
-
},
|
|
97
|
-
}))((props) => {
|
|
98
|
-
const { points, content, classes, sampleAnswer, mathMlOptions = {} } = props;
|
|
73
|
+
const Row = styled('div')(() => ({ display: 'flex', width: '100%', position: 'relative' }));
|
|
74
|
+
|
|
75
|
+
const EditorDiv = styled('div')(({ theme }) => ({ width: '100%', backgroundColor: `${theme.palette.common.white}` }));
|
|
76
|
+
|
|
77
|
+
const DragIndicatorStyled = styled(DragIndicator)(({ theme }) => ({ paddingTop: theme.spacing(1), color: grey[500] }));
|
|
78
|
+
|
|
79
|
+
const PointsLabel = styled(Typography)(({ theme }) => ({
|
|
80
|
+
color: grey[500],
|
|
81
|
+
paddingBottom: theme.spacing(1),
|
|
82
|
+
textTransform: 'uppercase',
|
|
83
|
+
}));
|
|
84
|
+
|
|
85
|
+
const SampleAnswersEditor = styled('div')(({ theme }) => ({ paddingLeft: theme.spacing(3) }));
|
|
86
|
+
|
|
87
|
+
const ErrorText = styled('div')(({ theme }) => ({
|
|
88
|
+
fontSize: theme.typography.fontSize - 2,
|
|
89
|
+
color: theme.palette.error.main,
|
|
90
|
+
paddingLeft: theme.spacing(3),
|
|
91
|
+
paddingTop: theme.spacing(1),
|
|
92
|
+
}));
|
|
93
|
+
|
|
94
|
+
const PointMenuWrapper = styled('div')(() => ({ position: 'absolute', right: 0 }));
|
|
95
|
+
|
|
96
|
+
export const PointConfig = (props) => {
|
|
97
|
+
const { points, content, sampleAnswer, mathMlOptions = {}, error, pluginOpts = {} } = props;
|
|
99
98
|
const pointsLabel = `${points} ${points <= 1 ? 'pt' : 'pts'}`;
|
|
100
99
|
const showSampleAnswer = checkSampleAnswer(sampleAnswer);
|
|
101
100
|
|
|
102
101
|
return (
|
|
103
|
-
<div
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
<div className={classes.row}>
|
|
109
|
-
<DragIndicator className={classes.dragIndicator} />
|
|
110
|
-
<EditableHtml
|
|
111
|
-
className={classes.editor}
|
|
112
|
-
markup={content}
|
|
113
|
-
onChange={props.onChange}
|
|
114
|
-
mathMlOptions={mathMlOptions}
|
|
115
|
-
/>
|
|
116
|
-
<PointMenu
|
|
117
|
-
classes={{
|
|
118
|
-
icon: classes.pointMenu,
|
|
119
|
-
}}
|
|
120
|
-
showSampleAnswer={showSampleAnswer}
|
|
121
|
-
onChange={props.onMenuChange}
|
|
122
|
-
/>
|
|
123
|
-
</div>
|
|
124
|
-
|
|
125
|
-
{!showSampleAnswer && (
|
|
126
|
-
<div className={classes.sampleAnswersEditor}>
|
|
127
|
-
<Typography variant="overline" className={classes.dragIndicator}>
|
|
128
|
-
Sample Response
|
|
129
|
-
</Typography>
|
|
102
|
+
<div>
|
|
103
|
+
<PointsLabel variant="overline">{pointsLabel}</PointsLabel>
|
|
104
|
+
<Row>
|
|
105
|
+
<DragIndicatorStyled />
|
|
106
|
+
<EditorDiv>
|
|
130
107
|
<EditableHtml
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
108
|
+
error={error}
|
|
109
|
+
pluginProps={pluginOpts}
|
|
110
|
+
markup={content}
|
|
111
|
+
onChange={props.onChange}
|
|
134
112
|
mathMlOptions={mathMlOptions}
|
|
135
113
|
/>
|
|
136
|
-
</
|
|
114
|
+
</EditorDiv>
|
|
115
|
+
<PointMenuWrapper>
|
|
116
|
+
<PointMenu showSampleAnswer={showSampleAnswer} onChange={props.onMenuChange} />
|
|
117
|
+
</PointMenuWrapper>
|
|
118
|
+
</Row>
|
|
119
|
+
{error && <ErrorText>{error}</ErrorText>}
|
|
120
|
+
{!showSampleAnswer && (
|
|
121
|
+
<SampleAnswersEditor>
|
|
122
|
+
<DragIndicatorStyled as={Typography} variant="overline">
|
|
123
|
+
Sample Response
|
|
124
|
+
</DragIndicatorStyled>
|
|
125
|
+
<EditorDiv>
|
|
126
|
+
<EditableHtml
|
|
127
|
+
markup={sampleAnswer}
|
|
128
|
+
pluginProps={pluginOpts}
|
|
129
|
+
onChange={props.onSampleChange}
|
|
130
|
+
mathMlOptions={mathMlOptions}
|
|
131
|
+
/>
|
|
132
|
+
</EditorDiv>
|
|
133
|
+
</SampleAnswersEditor>
|
|
137
134
|
)}
|
|
138
135
|
</div>
|
|
139
136
|
);
|
|
140
|
-
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const Container = styled('div')(({ theme }) => ({
|
|
140
|
+
backgroundColor: grey[200],
|
|
141
|
+
borderWidth: 1,
|
|
142
|
+
borderStyle: 'solid',
|
|
143
|
+
borderColor: grey[300],
|
|
144
|
+
padding: theme.spacing(2),
|
|
145
|
+
margin: theme.spacing(1),
|
|
146
|
+
}));
|
|
147
|
+
const InputContainerWrapper = styled('div')(({ theme }) => ({
|
|
148
|
+
width: '100%',
|
|
149
|
+
paddingTop: theme.spacing(2),
|
|
150
|
+
marginBottom: theme.spacing(2),
|
|
151
|
+
'& MuiFormControl-root': { width: '100%' },
|
|
152
|
+
}));
|
|
153
|
+
const Rubricless = styled('div')(() => ({ display: 'none' }));
|
|
154
|
+
const ConfigHolder = styled('div')(({ theme }) => ({ paddingTop: theme.spacing(1), paddingBottom: theme.spacing(1) }));
|
|
155
|
+
const RubricTitle = styled(Typography)(({ theme }) => ({ paddingLeft: theme.spacing(1), margin: theme.spacing(1) }));
|
|
141
156
|
|
|
142
157
|
export class RawAuthoring extends React.Component {
|
|
143
158
|
static propTypes = {
|
|
144
|
-
classes: PropTypes.object.isRequired,
|
|
145
|
-
className: PropTypes.string,
|
|
146
159
|
value: RubricType,
|
|
160
|
+
config: PropTypes.object,
|
|
161
|
+
pluginOpts: PropTypes.object,
|
|
162
|
+
rubricless: PropTypes.bool,
|
|
147
163
|
onChange: PropTypes.func,
|
|
148
164
|
};
|
|
149
165
|
|
|
@@ -162,8 +178,13 @@ export class RawAuthoring extends React.Component {
|
|
|
162
178
|
onChange({ ...value, points, sampleAnswers });
|
|
163
179
|
};
|
|
164
180
|
|
|
165
|
-
|
|
181
|
+
changeRubriclessInstruction = (input) => {
|
|
166
182
|
const { value, onChange } = this.props;
|
|
183
|
+
onChange({ ...value, rubriclessInstruction: input });
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
changeMaxPoints = (maxPoints) => {
|
|
187
|
+
const { value, onChange, rubricless } = this.props;
|
|
167
188
|
const currentMax = value.points.length - 1;
|
|
168
189
|
|
|
169
190
|
log('current', currentMax, 'new: ', maxPoints);
|
|
@@ -184,8 +205,10 @@ export class RawAuthoring extends React.Component {
|
|
|
184
205
|
sampleAnswers = takeRight(value.sampleAnswers, maxPoints + 1);
|
|
185
206
|
}
|
|
186
207
|
|
|
187
|
-
if (points) {
|
|
188
|
-
onChange({ ...value, points, sampleAnswers });
|
|
208
|
+
if (points && !rubricless) {
|
|
209
|
+
onChange({ ...value, points, sampleAnswers, maxPoints });
|
|
210
|
+
} else {
|
|
211
|
+
onChange({ ...value, maxPoints });
|
|
189
212
|
}
|
|
190
213
|
};
|
|
191
214
|
|
|
@@ -242,21 +265,37 @@ export class RawAuthoring extends React.Component {
|
|
|
242
265
|
};
|
|
243
266
|
|
|
244
267
|
render() {
|
|
245
|
-
const {
|
|
246
|
-
let {
|
|
247
|
-
|
|
268
|
+
const { value, mathMlOptions = {}, config = {}, rubricless = false, pluginOpts = {} } = this.props;
|
|
269
|
+
let {
|
|
270
|
+
excludeZeroEnabled = true,
|
|
271
|
+
maxPointsEnabled = true,
|
|
272
|
+
errors = {},
|
|
273
|
+
rubriclessInstructionEnabled = false,
|
|
274
|
+
maxPoints = 10,
|
|
275
|
+
} = value || {};
|
|
276
|
+
// rubric will contain a max value for maxPoints
|
|
277
|
+
const { rubriclessInstruction = {}, maxMaxPoints = 10 } = config || {};
|
|
278
|
+
const { pointsDescriptorsErrors } = errors || {};
|
|
248
279
|
if (value && Number.isFinite(value.maxPoints)) {
|
|
249
280
|
// eslint-disable-next-line no-console
|
|
250
281
|
console.warn('maxPoints is deprecated - remove from model');
|
|
251
282
|
}
|
|
252
283
|
|
|
284
|
+
// for rubric value is computed based on points
|
|
285
|
+
const maxPointsValue = !rubricless ? value.points.length - 1 : maxPoints;
|
|
286
|
+
|
|
253
287
|
return (
|
|
254
|
-
<div
|
|
255
|
-
<
|
|
256
|
-
Rubric
|
|
257
|
-
</Typography>
|
|
288
|
+
<div>
|
|
289
|
+
<RubricTitle variant="h5">Rubric</RubricTitle>
|
|
258
290
|
<FormGroup row>
|
|
259
|
-
{maxPointsEnabled &&
|
|
291
|
+
{maxPointsEnabled && (
|
|
292
|
+
<MaxPoints
|
|
293
|
+
max={maxMaxPoints < 100 ? maxMaxPoints : 100}
|
|
294
|
+
value={maxPointsValue}
|
|
295
|
+
onChange={this.changeMaxPoints}
|
|
296
|
+
pluginOpts={pluginOpts}
|
|
297
|
+
/>
|
|
298
|
+
)}
|
|
260
299
|
{excludeZeroEnabled && (
|
|
261
300
|
<FormControlLabel
|
|
262
301
|
label="Exclude zeros"
|
|
@@ -265,69 +304,77 @@ export class RawAuthoring extends React.Component {
|
|
|
265
304
|
)}
|
|
266
305
|
</FormGroup>
|
|
267
306
|
|
|
268
|
-
|
|
269
|
-
<
|
|
270
|
-
<
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
307
|
+
{rubriclessInstructionEnabled && rubricless && (
|
|
308
|
+
<InputContainerWrapper>
|
|
309
|
+
<InputContainer label={rubriclessInstruction.label}>
|
|
310
|
+
<EditableHtml
|
|
311
|
+
markup={value.rubriclessInstruction || ''}
|
|
312
|
+
onChange={this.changeRubriclessInstruction}
|
|
313
|
+
pluginProps={pluginOpts}
|
|
314
|
+
nonEmpty={false}
|
|
315
|
+
disableUnderline
|
|
316
|
+
languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}
|
|
317
|
+
mathMlOptions={mathMlOptions}
|
|
318
|
+
/>
|
|
319
|
+
</InputContainer>
|
|
320
|
+
</InputContainerWrapper>
|
|
321
|
+
)}
|
|
322
|
+
|
|
323
|
+
<div>
|
|
324
|
+
{rubricless ? (
|
|
325
|
+
<Rubricless />
|
|
326
|
+
) : (
|
|
327
|
+
<Container>
|
|
328
|
+
<DragDropContext onDragEnd={this.dragEnd}>
|
|
329
|
+
<Droppable droppableId="droppable">
|
|
330
|
+
{(provided) => (
|
|
331
|
+
<div {...provided.droppableProps} ref={provided.innerRef}>
|
|
332
|
+
{value.points.map(
|
|
333
|
+
(p, index) =>
|
|
334
|
+
this.shouldRenderPoint(index, value) && (
|
|
335
|
+
<Draggable key={`${p.points}-${index}`} index={index} draggableId={index.toString()}>
|
|
336
|
+
{(provided) => (
|
|
337
|
+
<ConfigHolder
|
|
338
|
+
ref={provided.innerRef}
|
|
339
|
+
{...provided.draggableProps}
|
|
340
|
+
{...provided.dragHandleProps}
|
|
341
|
+
>
|
|
342
|
+
<PointConfig
|
|
343
|
+
points={value.points.length - 1 - index}
|
|
344
|
+
content={p}
|
|
345
|
+
error={
|
|
346
|
+
pointsDescriptorsErrors &&
|
|
347
|
+
pointsDescriptorsErrors[value.points.length - 1 - index]
|
|
348
|
+
}
|
|
349
|
+
sampleAnswer={value.sampleAnswers && value.sampleAnswers[index]}
|
|
350
|
+
onChange={(content) => this.changeContent(index, content, 'points')}
|
|
351
|
+
onSampleChange={(content) => this.changeContent(index, content, 'sampleAnswers')}
|
|
352
|
+
onMenuChange={(clickedItem) => this.onPointMenuChange(index, clickedItem)}
|
|
353
|
+
mathMlOptions={mathMlOptions}
|
|
354
|
+
pluginOpts={pluginOpts}
|
|
355
|
+
/>
|
|
356
|
+
</ConfigHolder>
|
|
357
|
+
)}
|
|
358
|
+
</Draggable>
|
|
359
|
+
),
|
|
360
|
+
)}
|
|
361
|
+
{provided.placeholder}
|
|
362
|
+
</div>
|
|
297
363
|
)}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
</DragDropContext>
|
|
364
|
+
</Droppable>
|
|
365
|
+
</DragDropContext>
|
|
366
|
+
</Container>
|
|
367
|
+
)}
|
|
303
368
|
</div>
|
|
304
369
|
</div>
|
|
305
370
|
);
|
|
306
371
|
}
|
|
307
372
|
}
|
|
308
373
|
|
|
309
|
-
|
|
310
|
-
container: {
|
|
311
|
-
backgroundColor: grey[200],
|
|
312
|
-
borderWidth: 1,
|
|
313
|
-
borderStyle: 'solid',
|
|
314
|
-
borderColor: grey[300],
|
|
315
|
-
padding: theme.spacing.unit * 2,
|
|
316
|
-
margin: theme.spacing.unit,
|
|
317
|
-
},
|
|
318
|
-
configHolder: {
|
|
319
|
-
paddingTop: theme.spacing.unit,
|
|
320
|
-
paddingBottom: theme.spacing.unit,
|
|
321
|
-
},
|
|
322
|
-
rubricTitle: {
|
|
323
|
-
paddingLeft: theme.spacing.unit,
|
|
324
|
-
margin: theme.spacing.unit,
|
|
325
|
-
},
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
const StyledRawAuthoring = withStyles(styles)(RawAuthoring);
|
|
374
|
+
// styles migrated to styled-components above
|
|
329
375
|
|
|
330
376
|
const Reverse = (props) => {
|
|
377
|
+
const { rubricless = false, config = {}, pluginOpts = {} } = props || {};
|
|
331
378
|
const points = Array.from(props.value.points || []).reverse();
|
|
332
379
|
let sampleAnswers = Array.from(props.value.sampleAnswers || []).reverse();
|
|
333
380
|
|
|
@@ -347,11 +394,16 @@ const Reverse = (props) => {
|
|
|
347
394
|
});
|
|
348
395
|
};
|
|
349
396
|
|
|
350
|
-
return
|
|
397
|
+
return (
|
|
398
|
+
<RawAuthoring value={value} config={config} onChange={onChange} rubricless={rubricless} pluginOpts={pluginOpts} />
|
|
399
|
+
);
|
|
351
400
|
};
|
|
352
401
|
|
|
353
402
|
Reverse.propTypes = {
|
|
354
403
|
value: RubricType,
|
|
404
|
+
config: PropTypes.object,
|
|
405
|
+
pluginOpts: PropTypes.object,
|
|
406
|
+
rubricless: PropTypes.bool,
|
|
355
407
|
getIndex: PropTypes.func,
|
|
356
408
|
onChange: PropTypes.func,
|
|
357
409
|
};
|
package/src/index.js
CHANGED
package/src/point-menu.jsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import Menu from '@material
|
|
2
|
-
import MenuItem from '@material
|
|
3
|
-
import MoreVertIcon from '@
|
|
4
|
-
import MoreHorizIcon from '@
|
|
5
|
-
import IconButton from '@material
|
|
1
|
+
import Menu from '@mui/material/Menu';
|
|
2
|
+
import MenuItem from '@mui/material/MenuItem';
|
|
3
|
+
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|
4
|
+
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
|
|
5
|
+
import IconButton from '@mui/material/IconButton';
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
7
7
|
import React from 'react';
|
|
8
8
|
|
|
@@ -10,7 +10,6 @@ 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,
|
|
14
13
|
};
|
|
15
14
|
|
|
16
15
|
constructor(props) {
|
|
@@ -26,7 +25,7 @@ export class IconMenu extends React.Component {
|
|
|
26
25
|
handleRequestClose = () => this.setState({ open: false });
|
|
27
26
|
|
|
28
27
|
render() {
|
|
29
|
-
const { opts, onClick
|
|
28
|
+
const { opts, onClick } = this.props;
|
|
30
29
|
const { open, anchorEl } = this.state;
|
|
31
30
|
const keys = Object.keys(opts) || [];
|
|
32
31
|
|
|
@@ -40,7 +39,7 @@ export class IconMenu extends React.Component {
|
|
|
40
39
|
return (
|
|
41
40
|
<div>
|
|
42
41
|
<div onClick={this.handleClick}>
|
|
43
|
-
<IconButton
|
|
42
|
+
<IconButton size="large">
|
|
44
43
|
{open ? <MoreVertIcon color={iconColor} /> : <MoreHorizIcon color={iconColor} />}
|
|
45
44
|
</IconButton>
|
|
46
45
|
</div>
|
|
@@ -69,16 +68,11 @@ export class IconMenu extends React.Component {
|
|
|
69
68
|
export default class PointMenu extends React.Component {
|
|
70
69
|
static propTypes = {
|
|
71
70
|
onChange: PropTypes.func.isRequired,
|
|
72
|
-
classes: PropTypes.object.isRequired,
|
|
73
71
|
showSampleAnswer: PropTypes.bool.isRequired,
|
|
74
72
|
};
|
|
75
73
|
|
|
76
|
-
static defaultProps = {
|
|
77
|
-
classes: {},
|
|
78
|
-
};
|
|
79
|
-
|
|
80
74
|
render() {
|
|
81
|
-
const { onChange,
|
|
75
|
+
const { onChange, showSampleAnswer } = this.props;
|
|
82
76
|
const sampleText = showSampleAnswer ? 'Provide Sample Response' : 'Remove Sample Response';
|
|
83
77
|
|
|
84
78
|
return (
|
|
@@ -87,7 +81,6 @@ export default class PointMenu extends React.Component {
|
|
|
87
81
|
opts={{
|
|
88
82
|
sample: sampleText,
|
|
89
83
|
}}
|
|
90
|
-
classes={classes}
|
|
91
84
|
/>
|
|
92
85
|
);
|
|
93
86
|
}
|