@pie-lib/rubric 2.1.0-beta.9 → 3.0.0-next.36
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/dist/authoring.d.ts +62 -0
- package/dist/authoring.js +298 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +9 -0
- package/dist/point-menu.d.ts +27 -0
- package/dist/point-menu.js +73 -0
- package/package.json +32 -11
- package/CHANGELOG.json +0 -1
- package/CHANGELOG.md +0 -1448
- package/lib/authoring.js +0 -496
- package/lib/authoring.js.map +0 -1
- package/lib/index.js +0 -20
- package/lib/index.js.map +0 -1
- package/lib/point-menu.js +0 -125
- package/lib/point-menu.js.map +0 -1
- package/src/authoring.jsx +0 -413
- package/src/index.js +0 -9
- package/src/point-menu.jsx +0 -87
package/lib/point-menu.js
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports["default"] = exports.IconMenu = void 0;
|
|
8
|
-
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
9
|
-
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
10
|
-
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
11
|
-
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
12
|
-
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
13
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
14
|
-
var _Menu = _interopRequireDefault(require("@mui/material/Menu"));
|
|
15
|
-
var _MenuItem = _interopRequireDefault(require("@mui/material/MenuItem"));
|
|
16
|
-
var _MoreVert = _interopRequireDefault(require("@mui/icons-material/MoreVert"));
|
|
17
|
-
var _MoreHoriz = _interopRequireDefault(require("@mui/icons-material/MoreHoriz"));
|
|
18
|
-
var _IconButton = _interopRequireDefault(require("@mui/material/IconButton"));
|
|
19
|
-
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
20
|
-
var _react = _interopRequireDefault(require("react"));
|
|
21
|
-
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
|
|
22
|
-
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
23
|
-
var IconMenu = exports.IconMenu = /*#__PURE__*/function (_React$Component) {
|
|
24
|
-
function IconMenu(props) {
|
|
25
|
-
var _this;
|
|
26
|
-
(0, _classCallCheck2["default"])(this, IconMenu);
|
|
27
|
-
_this = _callSuper(this, IconMenu, [props]);
|
|
28
|
-
(0, _defineProperty2["default"])(_this, "handleClick", function (event) {
|
|
29
|
-
return _this.setState({
|
|
30
|
-
open: true,
|
|
31
|
-
anchorEl: event.currentTarget
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
(0, _defineProperty2["default"])(_this, "handleRequestClose", function () {
|
|
35
|
-
return _this.setState({
|
|
36
|
-
open: false
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
_this.state = {
|
|
40
|
-
anchorEl: undefined,
|
|
41
|
-
open: false
|
|
42
|
-
};
|
|
43
|
-
return _this;
|
|
44
|
-
}
|
|
45
|
-
(0, _inherits2["default"])(IconMenu, _React$Component);
|
|
46
|
-
return (0, _createClass2["default"])(IconMenu, [{
|
|
47
|
-
key: "render",
|
|
48
|
-
value: function render() {
|
|
49
|
-
var _this2 = this;
|
|
50
|
-
var _this$props = this.props,
|
|
51
|
-
opts = _this$props.opts,
|
|
52
|
-
onClick = _this$props.onClick;
|
|
53
|
-
var _this$state = this.state,
|
|
54
|
-
open = _this$state.open,
|
|
55
|
-
anchorEl = _this$state.anchorEl;
|
|
56
|
-
var keys = Object.keys(opts) || [];
|
|
57
|
-
var handleMenuClick = function handleMenuClick(key) {
|
|
58
|
-
return function () {
|
|
59
|
-
onClick(key);
|
|
60
|
-
_this2.handleRequestClose();
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
|
-
var iconColor = open ? 'inherit' : 'disabled';
|
|
64
|
-
return /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("div", {
|
|
65
|
-
onClick: this.handleClick
|
|
66
|
-
}, /*#__PURE__*/_react["default"].createElement(_IconButton["default"], {
|
|
67
|
-
size: "large"
|
|
68
|
-
}, open ? /*#__PURE__*/_react["default"].createElement(_MoreVert["default"], {
|
|
69
|
-
color: iconColor
|
|
70
|
-
}) : /*#__PURE__*/_react["default"].createElement(_MoreHoriz["default"], {
|
|
71
|
-
color: iconColor
|
|
72
|
-
}))), /*#__PURE__*/_react["default"].createElement(_Menu["default"], {
|
|
73
|
-
id: "point-menu",
|
|
74
|
-
anchorEl: anchorEl,
|
|
75
|
-
open: open,
|
|
76
|
-
onClose: this.handleRequestClose,
|
|
77
|
-
style: {
|
|
78
|
-
transform: 'translate(-15px, -15px)'
|
|
79
|
-
},
|
|
80
|
-
transformOrigin: {
|
|
81
|
-
vertical: 'center',
|
|
82
|
-
horizontal: 'right'
|
|
83
|
-
}
|
|
84
|
-
}, keys.map(function (k, index) {
|
|
85
|
-
return /*#__PURE__*/_react["default"].createElement(_MenuItem["default"], {
|
|
86
|
-
key: index,
|
|
87
|
-
onClick: handleMenuClick(k)
|
|
88
|
-
}, opts[k]);
|
|
89
|
-
})));
|
|
90
|
-
}
|
|
91
|
-
}]);
|
|
92
|
-
}(_react["default"].Component);
|
|
93
|
-
(0, _defineProperty2["default"])(IconMenu, "propTypes", {
|
|
94
|
-
opts: _propTypes["default"].object,
|
|
95
|
-
onClick: _propTypes["default"].func.isRequired
|
|
96
|
-
});
|
|
97
|
-
var PointMenu = exports["default"] = /*#__PURE__*/function (_React$Component2) {
|
|
98
|
-
function PointMenu() {
|
|
99
|
-
(0, _classCallCheck2["default"])(this, PointMenu);
|
|
100
|
-
return _callSuper(this, PointMenu, arguments);
|
|
101
|
-
}
|
|
102
|
-
(0, _inherits2["default"])(PointMenu, _React$Component2);
|
|
103
|
-
return (0, _createClass2["default"])(PointMenu, [{
|
|
104
|
-
key: "render",
|
|
105
|
-
value: function render() {
|
|
106
|
-
var _this$props2 = this.props,
|
|
107
|
-
onChange = _this$props2.onChange,
|
|
108
|
-
showSampleAnswer = _this$props2.showSampleAnswer;
|
|
109
|
-
var sampleText = showSampleAnswer ? 'Provide Sample Response' : 'Remove Sample Response';
|
|
110
|
-
return /*#__PURE__*/_react["default"].createElement(IconMenu, {
|
|
111
|
-
onClick: function onClick(key) {
|
|
112
|
-
return onChange(key);
|
|
113
|
-
},
|
|
114
|
-
opts: {
|
|
115
|
-
sample: sampleText
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
}]);
|
|
120
|
-
}(_react["default"].Component);
|
|
121
|
-
(0, _defineProperty2["default"])(PointMenu, "propTypes", {
|
|
122
|
-
onChange: _propTypes["default"].func.isRequired,
|
|
123
|
-
showSampleAnswer: _propTypes["default"].bool.isRequired
|
|
124
|
-
});
|
|
125
|
-
//# sourceMappingURL=point-menu.js.map
|
package/lib/point-menu.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"point-menu.js","names":["_Menu","_interopRequireDefault","require","_MenuItem","_MoreVert","_MoreHoriz","_IconButton","_propTypes","_react","_callSuper","t","o","e","_getPrototypeOf2","_possibleConstructorReturn2","_isNativeReflectConstruct","Reflect","construct","constructor","apply","Boolean","prototype","valueOf","call","IconMenu","exports","_React$Component","props","_this","_classCallCheck2","_defineProperty2","event","setState","open","anchorEl","currentTarget","state","undefined","_inherits2","_createClass2","key","value","render","_this2","_this$props","opts","onClick","_this$state","keys","Object","handleMenuClick","handleRequestClose","iconColor","createElement","handleClick","size","color","id","onClose","style","transform","transformOrigin","vertical","horizontal","map","k","index","React","Component","PropTypes","object","func","isRequired","PointMenu","_React$Component2","arguments","_this$props2","onChange","showSampleAnswer","sampleText","sample","bool"],"sources":["../src/point-menu.jsx"],"sourcesContent":["import Menu from '@mui/material/Menu';\nimport MenuItem from '@mui/material/MenuItem';\nimport MoreVertIcon from '@mui/icons-material/MoreVert';\nimport MoreHorizIcon from '@mui/icons-material/MoreHoriz';\nimport IconButton from '@mui/material/IconButton';\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\nexport class IconMenu extends React.Component {\n static propTypes = {\n opts: PropTypes.object,\n onClick: PropTypes.func.isRequired,\n };\n\n constructor(props) {\n super(props);\n this.state = {\n anchorEl: undefined,\n open: false,\n };\n }\n\n handleClick = (event) => this.setState({ open: true, anchorEl: event.currentTarget });\n\n handleRequestClose = () => this.setState({ open: false });\n\n render() {\n const { opts, onClick } = this.props;\n const { open, anchorEl } = this.state;\n const keys = Object.keys(opts) || [];\n\n const handleMenuClick = (key) => () => {\n onClick(key);\n this.handleRequestClose();\n };\n\n const iconColor = open ? 'inherit' : 'disabled';\n\n return (\n <div>\n <div onClick={this.handleClick}>\n <IconButton size=\"large\">\n {open ? <MoreVertIcon color={iconColor} /> : <MoreHorizIcon color={iconColor} />}\n </IconButton>\n </div>\n <Menu\n id=\"point-menu\"\n anchorEl={anchorEl}\n open={open}\n onClose={this.handleRequestClose}\n style={{ transform: 'translate(-15px, -15px)' }}\n transformOrigin={{\n vertical: 'center',\n horizontal: 'right',\n }}\n >\n {keys.map((k, index) => (\n <MenuItem key={index} onClick={handleMenuClick(k)}>\n {opts[k]}\n </MenuItem>\n ))}\n </Menu>\n </div>\n );\n }\n}\n\nexport default class PointMenu extends React.Component {\n static propTypes = {\n onChange: PropTypes.func.isRequired,\n showSampleAnswer: PropTypes.bool.isRequired,\n };\n\n render() {\n const { onChange, showSampleAnswer } = this.props;\n const sampleText = showSampleAnswer ? 'Provide Sample Response' : 'Remove Sample Response';\n\n return (\n <IconMenu\n onClick={(key) => onChange(key)}\n opts={{\n sample: sampleText,\n }}\n />\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/src/authoring.jsx
DELETED
|
@@ -1,413 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
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
|
-
import { range, takeRight, times } from 'lodash-es';
|
|
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, Draggable, Droppable } from '@hello-pangea/dnd';
|
|
17
|
-
import debug from 'debug';
|
|
18
|
-
import PointMenu from './point-menu';
|
|
19
|
-
import EditableHtml from '@pie-lib/editable-html-tip-tap';
|
|
20
|
-
import { InputContainer } from '@pie-lib/config-ui';
|
|
21
|
-
import { grey } from '@mui/material/colors';
|
|
22
|
-
|
|
23
|
-
const log = debug('pie-lib:rubric:authoring');
|
|
24
|
-
|
|
25
|
-
const reorder = (list, startIndex, endIndex) => {
|
|
26
|
-
const result = Array.from(list);
|
|
27
|
-
const [removed] = result.splice(startIndex, 1);
|
|
28
|
-
|
|
29
|
-
result.splice(endIndex, 0, removed);
|
|
30
|
-
|
|
31
|
-
return result;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const RubricType = PropTypes.shape({
|
|
35
|
-
excludeZero: PropTypes.bool,
|
|
36
|
-
points: PropTypes.arrayOf(PropTypes.string),
|
|
37
|
-
sampleAnswers: PropTypes.arrayOf(PropTypes.string),
|
|
38
|
-
maxPoints: PropTypes.number,
|
|
39
|
-
rubriclessInstruction: PropTypes.string,
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const MaxPoints = (props) => {
|
|
43
|
-
const { value, onChange, max } = props;
|
|
44
|
-
const labelId = 'max-points-label';
|
|
45
|
-
|
|
46
|
-
return (
|
|
47
|
-
<FormControl sx={{ minWidth: 120, m: 1 }} variant="outlined">
|
|
48
|
-
<InputLabel id={labelId}>Max Points</InputLabel>
|
|
49
|
-
<Select
|
|
50
|
-
labelId={labelId}
|
|
51
|
-
label="Max Points"
|
|
52
|
-
value={value}
|
|
53
|
-
onChange={(e) => onChange(e.target.value)}
|
|
54
|
-
input={<OutlinedInput label="Max Points" />}
|
|
55
|
-
MenuProps={{ transitionDuration: { enter: 225, exit: 195 } }}
|
|
56
|
-
>
|
|
57
|
-
{range(1, max + 1).map((v) => (
|
|
58
|
-
<MenuItem key={`${v}`} value={v}>
|
|
59
|
-
{v}
|
|
60
|
-
</MenuItem>
|
|
61
|
-
))}
|
|
62
|
-
</Select>
|
|
63
|
-
</FormControl>
|
|
64
|
-
);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
// if the value is null or 'null', the Sample Answer input field for that point will not be dispalyed
|
|
68
|
-
// if the value is '', the Sample Answer input field will be empty
|
|
69
|
-
const checkSampleAnswer = (sampleAnswer) => sampleAnswer === null || sampleAnswer === 'null';
|
|
70
|
-
|
|
71
|
-
const Row = styled('div')(() => ({ display: 'flex', width: '100%', position: 'relative' }));
|
|
72
|
-
|
|
73
|
-
const EditorDiv = styled('div')(({ theme }) => ({ width: '100%', backgroundColor: `${theme.palette.common.white}` }));
|
|
74
|
-
|
|
75
|
-
const DragIndicatorStyled = styled(DragIndicator)(({ theme }) => ({ paddingTop: theme.spacing(1), color: grey[500] }));
|
|
76
|
-
|
|
77
|
-
const PointsLabel = styled(Typography)(({ theme }) => ({
|
|
78
|
-
color: grey[500],
|
|
79
|
-
paddingBottom: theme.spacing(1),
|
|
80
|
-
textTransform: 'uppercase',
|
|
81
|
-
}));
|
|
82
|
-
|
|
83
|
-
const SampleAnswersEditor = styled('div')(({ theme }) => ({ paddingLeft: theme.spacing(3) }));
|
|
84
|
-
|
|
85
|
-
const ErrorText = styled('div')(({ theme }) => ({
|
|
86
|
-
fontSize: theme.typography.fontSize - 2,
|
|
87
|
-
color: theme.palette.error.main,
|
|
88
|
-
paddingLeft: theme.spacing(3),
|
|
89
|
-
paddingTop: theme.spacing(1),
|
|
90
|
-
}));
|
|
91
|
-
|
|
92
|
-
const PointMenuWrapper = styled('div')(() => ({ position: 'absolute', right: 0 }));
|
|
93
|
-
|
|
94
|
-
export const PointConfig = (props) => {
|
|
95
|
-
const { points, content, sampleAnswer, mathMlOptions = {}, error, pluginOpts = {} } = props;
|
|
96
|
-
const pointsLabel = `${points} ${points <= 1 ? 'pt' : 'pts'}`;
|
|
97
|
-
const showSampleAnswer = checkSampleAnswer(sampleAnswer);
|
|
98
|
-
|
|
99
|
-
return (
|
|
100
|
-
<div>
|
|
101
|
-
<PointsLabel variant="overline">{pointsLabel}</PointsLabel>
|
|
102
|
-
<Row>
|
|
103
|
-
<DragIndicatorStyled />
|
|
104
|
-
<EditorDiv>
|
|
105
|
-
<EditableHtml
|
|
106
|
-
error={error}
|
|
107
|
-
pluginProps={pluginOpts}
|
|
108
|
-
markup={content}
|
|
109
|
-
onChange={props.onChange}
|
|
110
|
-
mathMlOptions={mathMlOptions}
|
|
111
|
-
/>
|
|
112
|
-
</EditorDiv>
|
|
113
|
-
<PointMenuWrapper>
|
|
114
|
-
<PointMenu showSampleAnswer={showSampleAnswer} onChange={props.onMenuChange} />
|
|
115
|
-
</PointMenuWrapper>
|
|
116
|
-
</Row>
|
|
117
|
-
{error && <ErrorText>{error}</ErrorText>}
|
|
118
|
-
{!showSampleAnswer && (
|
|
119
|
-
<SampleAnswersEditor>
|
|
120
|
-
<DragIndicatorStyled as={Typography} variant="overline">
|
|
121
|
-
Sample Response
|
|
122
|
-
</DragIndicatorStyled>
|
|
123
|
-
<EditorDiv>
|
|
124
|
-
<EditableHtml
|
|
125
|
-
markup={sampleAnswer}
|
|
126
|
-
pluginProps={pluginOpts}
|
|
127
|
-
onChange={props.onSampleChange}
|
|
128
|
-
mathMlOptions={mathMlOptions}
|
|
129
|
-
/>
|
|
130
|
-
</EditorDiv>
|
|
131
|
-
</SampleAnswersEditor>
|
|
132
|
-
)}
|
|
133
|
-
</div>
|
|
134
|
-
);
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
const Container = styled('div')(({ theme }) => ({
|
|
138
|
-
backgroundColor: grey[200],
|
|
139
|
-
borderWidth: 1,
|
|
140
|
-
borderStyle: 'solid',
|
|
141
|
-
borderColor: grey[300],
|
|
142
|
-
padding: theme.spacing(2),
|
|
143
|
-
margin: theme.spacing(1),
|
|
144
|
-
}));
|
|
145
|
-
|
|
146
|
-
const StyledInputContainer = styled(InputContainer)(({ theme }) => ({
|
|
147
|
-
width: '100%',
|
|
148
|
-
paddingTop: theme.spacing(2.5),
|
|
149
|
-
marginBottom: theme.spacing(2),
|
|
150
|
-
marginTop: theme.spacing(1),
|
|
151
|
-
'& .MuiFormControl-root': { width: '100%' },
|
|
152
|
-
'& > .MuiFormLabel-root.MuiInputLabel-shrink': {
|
|
153
|
-
fontSize: theme.typography.fontSize + 2,
|
|
154
|
-
transform: 'translate(0, 1.5px) scale(0.75)',
|
|
155
|
-
},
|
|
156
|
-
}));
|
|
157
|
-
|
|
158
|
-
const Rubricless = styled('div')(() => ({ display: 'none' }));
|
|
159
|
-
const ConfigHolder = styled('div')(({ theme }) => ({ paddingTop: theme.spacing(1), paddingBottom: theme.spacing(1) }));
|
|
160
|
-
const RubricTitle = styled(Typography)(({ theme }) => ({ paddingLeft: theme.spacing(1), margin: theme.spacing(1) }));
|
|
161
|
-
|
|
162
|
-
export class RawAuthoring extends React.Component {
|
|
163
|
-
static propTypes = {
|
|
164
|
-
value: RubricType,
|
|
165
|
-
config: PropTypes.object,
|
|
166
|
-
pluginOpts: PropTypes.object,
|
|
167
|
-
rubricless: PropTypes.bool,
|
|
168
|
-
onChange: PropTypes.func,
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
static defaultProps = {};
|
|
172
|
-
|
|
173
|
-
dragEnd = (result) => {
|
|
174
|
-
if (!result.destination) {
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const { value, onChange } = this.props;
|
|
179
|
-
|
|
180
|
-
const points = reorder(value.points, result.source.index, result.destination.index);
|
|
181
|
-
const sampleAnswers = reorder(value.sampleAnswers, result.source.index, result.destination.index);
|
|
182
|
-
|
|
183
|
-
onChange({ ...value, points, sampleAnswers });
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
changeRubriclessInstruction = (input) => {
|
|
187
|
-
const { value, onChange } = this.props;
|
|
188
|
-
onChange({ ...value, rubriclessInstruction: input });
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
changeMaxPoints = (maxPoints) => {
|
|
192
|
-
const { value, onChange, rubricless } = this.props;
|
|
193
|
-
const currentMax = value.points.length - 1;
|
|
194
|
-
|
|
195
|
-
log('current', currentMax, 'new: ', maxPoints);
|
|
196
|
-
|
|
197
|
-
let points, sampleAnswers;
|
|
198
|
-
if (maxPoints > currentMax) {
|
|
199
|
-
points = times(maxPoints - currentMax)
|
|
200
|
-
.map(() => '')
|
|
201
|
-
.concat(value.points);
|
|
202
|
-
sampleAnswers = times(maxPoints - currentMax)
|
|
203
|
-
.map(() => null)
|
|
204
|
-
.concat(value.sampleAnswers);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if (maxPoints < currentMax) {
|
|
208
|
-
log('less than');
|
|
209
|
-
points = takeRight(value.points, maxPoints + 1);
|
|
210
|
-
sampleAnswers = takeRight(value.sampleAnswers, maxPoints + 1);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (points && !rubricless) {
|
|
214
|
-
onChange({ ...value, points, sampleAnswers, maxPoints });
|
|
215
|
-
} else {
|
|
216
|
-
onChange({ ...value, maxPoints });
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
changeContent = (index, content, type) => {
|
|
221
|
-
// type could be 'points' or 'sampleAnswers'
|
|
222
|
-
log(`changeModel[${type}]:`, index, content);
|
|
223
|
-
|
|
224
|
-
if (type !== 'points' && type !== 'sampleAnswers') {
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const { value, onChange } = this.props;
|
|
229
|
-
const items = value[type] && Array.from(value[type]);
|
|
230
|
-
|
|
231
|
-
items.splice(index, 1, content);
|
|
232
|
-
log(`changeModel[${type}]:`, items);
|
|
233
|
-
|
|
234
|
-
onChange({ ...value, [type]: items });
|
|
235
|
-
};
|
|
236
|
-
|
|
237
|
-
excludeZeros = () => {
|
|
238
|
-
const { value, onChange } = this.props;
|
|
239
|
-
|
|
240
|
-
onChange({ ...value, excludeZero: !value.excludeZero });
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
getPointForIndex = (index, value) => {
|
|
244
|
-
const maxPoint = value.excludeZero ? value.points.length - 1 + 1 : value.points.length - 1;
|
|
245
|
-
return maxPoint - index;
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
getMaxPoint = (value) => (value.excludeZero ? value.points.length : value.points.length - 1);
|
|
249
|
-
|
|
250
|
-
shouldRenderPoint = (index, value) => {
|
|
251
|
-
const point = this.getPointForIndex(index, value);
|
|
252
|
-
return point > 0 || !value.excludeZero;
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
onPointMenuChange = (index, clickedItem) => {
|
|
256
|
-
if (clickedItem === 'sample') {
|
|
257
|
-
const { value } = this.props;
|
|
258
|
-
const sampleAnswers = Array.from(value.sampleAnswers || []);
|
|
259
|
-
|
|
260
|
-
if (checkSampleAnswer(sampleAnswers[index])) {
|
|
261
|
-
// an empty string will display an empty Sample Answer input field
|
|
262
|
-
this.changeContent(index, '', 'sampleAnswers');
|
|
263
|
-
} else {
|
|
264
|
-
// when the content is null or 'null', the Sample Answer input field will not be displayed
|
|
265
|
-
this.changeContent(index, null, 'sampleAnswers');
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
render() {
|
|
271
|
-
const { value, mathMlOptions = {}, config = {}, rubricless = false, pluginOpts = {} } = this.props;
|
|
272
|
-
let {
|
|
273
|
-
excludeZeroEnabled = true,
|
|
274
|
-
maxPointsEnabled = true,
|
|
275
|
-
errors = {},
|
|
276
|
-
rubriclessInstructionEnabled = false,
|
|
277
|
-
maxPoints = 10,
|
|
278
|
-
} = value || {};
|
|
279
|
-
// rubric will contain a max value for maxPoints
|
|
280
|
-
const { rubriclessInstruction = {}, maxMaxPoints = 10 } = config || {};
|
|
281
|
-
const { pointsDescriptorsErrors } = errors || {};
|
|
282
|
-
if (value && Number.isFinite(value.maxPoints)) {
|
|
283
|
-
// eslint-disable-next-line no-console
|
|
284
|
-
console.warn('maxPoints is deprecated - remove from model');
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// for rubric value is computed based on points
|
|
288
|
-
const maxPointsValue = rubricless ? maxPoints : value.excludeZero ? value.points.length : value.points.length - 1;
|
|
289
|
-
|
|
290
|
-
return (
|
|
291
|
-
<div>
|
|
292
|
-
<RubricTitle variant="h5">Rubric</RubricTitle>
|
|
293
|
-
<FormGroup row>
|
|
294
|
-
{maxPointsEnabled && (
|
|
295
|
-
<MaxPoints
|
|
296
|
-
max={maxMaxPoints < 100 ? maxMaxPoints : 100}
|
|
297
|
-
value={maxPointsValue}
|
|
298
|
-
onChange={this.changeMaxPoints}
|
|
299
|
-
pluginOpts={pluginOpts}
|
|
300
|
-
/>
|
|
301
|
-
)}
|
|
302
|
-
{excludeZeroEnabled && (
|
|
303
|
-
<FormControlLabel
|
|
304
|
-
label="Exclude zeros"
|
|
305
|
-
control={<Checkbox checked={value.excludeZero} onChange={this.excludeZeros} />}
|
|
306
|
-
/>
|
|
307
|
-
)}
|
|
308
|
-
</FormGroup>
|
|
309
|
-
|
|
310
|
-
{rubriclessInstructionEnabled && rubricless && (
|
|
311
|
-
<StyledInputContainer label={rubriclessInstruction.label}>
|
|
312
|
-
<EditableHtml
|
|
313
|
-
markup={value.rubriclessInstruction || ''}
|
|
314
|
-
onChange={this.changeRubriclessInstruction}
|
|
315
|
-
pluginProps={pluginOpts}
|
|
316
|
-
nonEmpty={false}
|
|
317
|
-
disableUnderline
|
|
318
|
-
languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}
|
|
319
|
-
mathMlOptions={mathMlOptions}
|
|
320
|
-
autoWidthToolbar
|
|
321
|
-
/>
|
|
322
|
-
</StyledInputContainer>
|
|
323
|
-
)}
|
|
324
|
-
|
|
325
|
-
<div>
|
|
326
|
-
{rubricless ? (
|
|
327
|
-
<Rubricless />
|
|
328
|
-
) : (
|
|
329
|
-
<Container>
|
|
330
|
-
<DragDropContext onDragEnd={this.dragEnd}>
|
|
331
|
-
<Droppable droppableId="droppable">
|
|
332
|
-
{(provided) => (
|
|
333
|
-
<div {...provided.droppableProps} ref={provided.innerRef}>
|
|
334
|
-
{value.points.map(
|
|
335
|
-
(p, index) =>
|
|
336
|
-
this.shouldRenderPoint(index, value) && (
|
|
337
|
-
<Draggable key={`${p.points}-${index}`} index={index} draggableId={index.toString()}>
|
|
338
|
-
{(provided) => (
|
|
339
|
-
<ConfigHolder
|
|
340
|
-
ref={provided.innerRef}
|
|
341
|
-
{...provided.draggableProps}
|
|
342
|
-
{...provided.dragHandleProps}
|
|
343
|
-
>
|
|
344
|
-
<PointConfig
|
|
345
|
-
points={this.getPointForIndex(index, value)}
|
|
346
|
-
content={p}
|
|
347
|
-
error={
|
|
348
|
-
pointsDescriptorsErrors &&
|
|
349
|
-
pointsDescriptorsErrors[value.points.length - 1 - index]
|
|
350
|
-
}
|
|
351
|
-
sampleAnswer={value.sampleAnswers && value.sampleAnswers[index]}
|
|
352
|
-
onChange={(content) => this.changeContent(index, content, 'points')}
|
|
353
|
-
onSampleChange={(content) => this.changeContent(index, content, 'sampleAnswers')}
|
|
354
|
-
onMenuChange={(clickedItem) => this.onPointMenuChange(index, clickedItem)}
|
|
355
|
-
mathMlOptions={mathMlOptions}
|
|
356
|
-
pluginOpts={pluginOpts}
|
|
357
|
-
/>
|
|
358
|
-
</ConfigHolder>
|
|
359
|
-
)}
|
|
360
|
-
</Draggable>
|
|
361
|
-
),
|
|
362
|
-
)}
|
|
363
|
-
{provided.placeholder}
|
|
364
|
-
</div>
|
|
365
|
-
)}
|
|
366
|
-
</Droppable>
|
|
367
|
-
</DragDropContext>
|
|
368
|
-
</Container>
|
|
369
|
-
)}
|
|
370
|
-
</div>
|
|
371
|
-
</div>
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
// styles migrated to styled-components above
|
|
377
|
-
|
|
378
|
-
const Reverse = (props) => {
|
|
379
|
-
const { rubricless = false, config = {}, pluginOpts = {} } = props || {};
|
|
380
|
-
const points = Array.from(props.value.points || []).reverse();
|
|
381
|
-
let sampleAnswers = Array.from(props.value.sampleAnswers || []).reverse();
|
|
382
|
-
|
|
383
|
-
if (points.length > sampleAnswers.length) {
|
|
384
|
-
sampleAnswers = times(points.length - sampleAnswers.length)
|
|
385
|
-
.map(() => null)
|
|
386
|
-
.concat(sampleAnswers);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
const value = { ...props.value, points, sampleAnswers };
|
|
390
|
-
|
|
391
|
-
const onChange = (value) => {
|
|
392
|
-
props.onChange({
|
|
393
|
-
...value,
|
|
394
|
-
points: Array.from(value.points || []).reverse(),
|
|
395
|
-
sampleAnswers: Array.from(value.sampleAnswers || []).reverse(),
|
|
396
|
-
});
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
return (
|
|
400
|
-
<RawAuthoring value={value} config={config} onChange={onChange} rubricless={rubricless} pluginOpts={pluginOpts} />
|
|
401
|
-
);
|
|
402
|
-
};
|
|
403
|
-
|
|
404
|
-
Reverse.propTypes = {
|
|
405
|
-
value: RubricType,
|
|
406
|
-
config: PropTypes.object,
|
|
407
|
-
pluginOpts: PropTypes.object,
|
|
408
|
-
rubricless: PropTypes.bool,
|
|
409
|
-
getIndex: PropTypes.func,
|
|
410
|
-
onChange: PropTypes.func,
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
export default Reverse;
|
package/src/index.js
DELETED
package/src/point-menu.jsx
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
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
|
-
import PropTypes from 'prop-types';
|
|
7
|
-
import React from 'react';
|
|
8
|
-
|
|
9
|
-
export class IconMenu extends React.Component {
|
|
10
|
-
static propTypes = {
|
|
11
|
-
opts: PropTypes.object,
|
|
12
|
-
onClick: PropTypes.func.isRequired,
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
constructor(props) {
|
|
16
|
-
super(props);
|
|
17
|
-
this.state = {
|
|
18
|
-
anchorEl: undefined,
|
|
19
|
-
open: false,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
handleClick = (event) => this.setState({ open: true, anchorEl: event.currentTarget });
|
|
24
|
-
|
|
25
|
-
handleRequestClose = () => this.setState({ open: false });
|
|
26
|
-
|
|
27
|
-
render() {
|
|
28
|
-
const { opts, onClick } = this.props;
|
|
29
|
-
const { open, anchorEl } = this.state;
|
|
30
|
-
const keys = Object.keys(opts) || [];
|
|
31
|
-
|
|
32
|
-
const handleMenuClick = (key) => () => {
|
|
33
|
-
onClick(key);
|
|
34
|
-
this.handleRequestClose();
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const iconColor = open ? 'inherit' : 'disabled';
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<div>
|
|
41
|
-
<div onClick={this.handleClick}>
|
|
42
|
-
<IconButton size="large">
|
|
43
|
-
{open ? <MoreVertIcon color={iconColor} /> : <MoreHorizIcon color={iconColor} />}
|
|
44
|
-
</IconButton>
|
|
45
|
-
</div>
|
|
46
|
-
<Menu
|
|
47
|
-
id="point-menu"
|
|
48
|
-
anchorEl={anchorEl}
|
|
49
|
-
open={open}
|
|
50
|
-
onClose={this.handleRequestClose}
|
|
51
|
-
style={{ transform: 'translate(-15px, -15px)' }}
|
|
52
|
-
transformOrigin={{
|
|
53
|
-
vertical: 'center',
|
|
54
|
-
horizontal: 'right',
|
|
55
|
-
}}
|
|
56
|
-
>
|
|
57
|
-
{keys.map((k, index) => (
|
|
58
|
-
<MenuItem key={index} onClick={handleMenuClick(k)}>
|
|
59
|
-
{opts[k]}
|
|
60
|
-
</MenuItem>
|
|
61
|
-
))}
|
|
62
|
-
</Menu>
|
|
63
|
-
</div>
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export default class PointMenu extends React.Component {
|
|
69
|
-
static propTypes = {
|
|
70
|
-
onChange: PropTypes.func.isRequired,
|
|
71
|
-
showSampleAnswer: PropTypes.bool.isRequired,
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
render() {
|
|
75
|
-
const { onChange, showSampleAnswer } = this.props;
|
|
76
|
-
const sampleText = showSampleAnswer ? 'Provide Sample Response' : 'Remove Sample Response';
|
|
77
|
-
|
|
78
|
-
return (
|
|
79
|
-
<IconMenu
|
|
80
|
-
onClick={(key) => onChange(key)}
|
|
81
|
-
opts={{
|
|
82
|
-
sample: sampleText,
|
|
83
|
-
}}
|
|
84
|
-
/>
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
}
|