@pie-element/categorize 13.1.2-next.5 → 13.1.3

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.
Files changed (158) hide show
  1. package/CHANGELOG.json +1637 -0
  2. package/CHANGELOG.md +2550 -0
  3. package/LICENSE.md +5 -0
  4. package/README.md +5 -0
  5. package/configure/CHANGELOG.json +1202 -0
  6. package/configure/CHANGELOG.md +2131 -0
  7. package/configure/lib/defaults.js +222 -0
  8. package/configure/lib/defaults.js.map +1 -0
  9. package/configure/lib/design/builder.js +55 -0
  10. package/configure/lib/design/builder.js.map +1 -0
  11. package/configure/lib/design/buttons.js +59 -0
  12. package/configure/lib/design/buttons.js.map +1 -0
  13. package/configure/lib/design/categories/RowLabel.js +66 -0
  14. package/configure/lib/design/categories/RowLabel.js.map +1 -0
  15. package/configure/lib/design/categories/alternateResponses.js +116 -0
  16. package/configure/lib/design/categories/alternateResponses.js.map +1 -0
  17. package/configure/lib/design/categories/category.js +153 -0
  18. package/configure/lib/design/categories/category.js.map +1 -0
  19. package/configure/lib/design/categories/choice-preview.js +79 -0
  20. package/configure/lib/design/categories/choice-preview.js.map +1 -0
  21. package/configure/lib/design/categories/droppable-placeholder.js +93 -0
  22. package/configure/lib/design/categories/droppable-placeholder.js.map +1 -0
  23. package/configure/lib/design/categories/index.js +256 -0
  24. package/configure/lib/design/categories/index.js.map +1 -0
  25. package/configure/lib/design/choices/choice.js +187 -0
  26. package/configure/lib/design/choices/choice.js.map +1 -0
  27. package/configure/lib/design/choices/config.js +58 -0
  28. package/configure/lib/design/choices/config.js.map +1 -0
  29. package/configure/lib/design/choices/index.js +197 -0
  30. package/configure/lib/design/choices/index.js.map +1 -0
  31. package/configure/lib/design/header.js +71 -0
  32. package/configure/lib/design/header.js.map +1 -0
  33. package/configure/lib/design/index.js +727 -0
  34. package/configure/lib/design/index.js.map +1 -0
  35. package/configure/lib/design/input-header.js +105 -0
  36. package/configure/lib/design/input-header.js.map +1 -0
  37. package/configure/lib/design/utils.js +12 -0
  38. package/configure/lib/design/utils.js.map +1 -0
  39. package/configure/lib/index.js +147 -0
  40. package/configure/lib/index.js.map +1 -0
  41. package/configure/lib/main.js +44 -0
  42. package/configure/lib/main.js.map +1 -0
  43. package/configure/lib/utils.js +43 -0
  44. package/configure/lib/utils.js.map +1 -0
  45. package/configure/package.json +32 -0
  46. package/controller/CHANGELOG.json +452 -0
  47. package/controller/CHANGELOG.md +1384 -0
  48. package/controller/lib/defaults.js +33 -0
  49. package/controller/lib/defaults.js.map +1 -0
  50. package/controller/lib/index.js +493 -0
  51. package/controller/lib/index.js.map +1 -0
  52. package/controller/lib/utils.js +69 -0
  53. package/controller/lib/utils.js.map +1 -0
  54. package/controller/package.json +18 -0
  55. package/docs/config-schema.json +2897 -0
  56. package/docs/config-schema.json.md +2138 -0
  57. package/docs/demo/config.js +8 -0
  58. package/docs/demo/generate.js +357 -0
  59. package/docs/demo/index.html +1 -0
  60. package/docs/demo/session.js +12 -0
  61. package/docs/pie-schema.json +1784 -0
  62. package/docs/pie-schema.json.md +1046 -0
  63. package/lib/categorize/categories.js +135 -0
  64. package/lib/categorize/categories.js.map +1 -0
  65. package/lib/categorize/category.js +67 -0
  66. package/lib/categorize/category.js.map +1 -0
  67. package/lib/categorize/choice.js +140 -0
  68. package/lib/categorize/choice.js.map +1 -0
  69. package/lib/categorize/choices.js +99 -0
  70. package/lib/categorize/choices.js.map +1 -0
  71. package/lib/categorize/droppable-placeholder.js +84 -0
  72. package/lib/categorize/droppable-placeholder.js.map +1 -0
  73. package/lib/categorize/grid-content.js +55 -0
  74. package/lib/categorize/grid-content.js.map +1 -0
  75. package/lib/categorize/index.js +450 -0
  76. package/lib/categorize/index.js.map +1 -0
  77. package/lib/index.js +316 -0
  78. package/lib/index.js.map +1 -0
  79. package/package.json +22 -85
  80. package/configure.js +0 -2
  81. package/controller.js +0 -1
  82. package/dist/author/defaults.d.ts +0 -223
  83. package/dist/author/defaults.js +0 -170
  84. package/dist/author/design/builder.d.ts +0 -10
  85. package/dist/author/design/builder.js +0 -24
  86. package/dist/author/design/buttons.d.ts +0 -28
  87. package/dist/author/design/buttons.js +0 -36
  88. package/dist/author/design/categories/RowLabel.d.ts +0 -23
  89. package/dist/author/design/categories/RowLabel.js +0 -47
  90. package/dist/author/design/categories/alternateResponses.d.ts +0 -31
  91. package/dist/author/design/categories/alternateResponses.js +0 -62
  92. package/dist/author/design/categories/category.d.ts +0 -44
  93. package/dist/author/design/categories/category.js +0 -98
  94. package/dist/author/design/categories/choice-preview.d.ts +0 -25
  95. package/dist/author/design/categories/choice-preview.js +0 -60
  96. package/dist/author/design/categories/droppable-placeholder.d.ts +0 -11
  97. package/dist/author/design/categories/droppable-placeholder.js +0 -71
  98. package/dist/author/design/categories/index.d.ts +0 -41
  99. package/dist/author/design/categories/index.js +0 -146
  100. package/dist/author/design/choices/choice.d.ts +0 -11
  101. package/dist/author/design/choices/choice.js +0 -129
  102. package/dist/author/design/choices/config.d.ts +0 -21
  103. package/dist/author/design/choices/config.js +0 -33
  104. package/dist/author/design/choices/index.d.ts +0 -41
  105. package/dist/author/design/choices/index.js +0 -110
  106. package/dist/author/design/header.d.ts +0 -24
  107. package/dist/author/design/header.js +0 -49
  108. package/dist/author/design/index.d.ts +0 -52
  109. package/dist/author/design/index.js +0 -417
  110. package/dist/author/design/input-header.d.ts +0 -39
  111. package/dist/author/design/input-header.js +0 -69
  112. package/dist/author/design/utils.d.ts +0 -9
  113. package/dist/author/design/utils.js +0 -7
  114. package/dist/author/index.d.ts +0 -51
  115. package/dist/author/index.js +0 -87
  116. package/dist/author/main.d.ts +0 -23
  117. package/dist/author/main.js +0 -30
  118. package/dist/author/utils.d.ts +0 -16
  119. package/dist/author/utils.js +0 -17
  120. package/dist/browser/author/index.js +0 -2041
  121. package/dist/browser/author/index.js.map +0 -1
  122. package/dist/browser/categorize.css +0 -2
  123. package/dist/browser/controller/index.js +0 -299
  124. package/dist/browser/controller/index.js.map +0 -1
  125. package/dist/browser/delivery/index.js +0 -1051
  126. package/dist/browser/delivery/index.js.map +0 -1
  127. package/dist/browser/dist-7UsF60Ks.js +0 -55705
  128. package/dist/browser/dist-7UsF60Ks.js.map +0 -1
  129. package/dist/browser/dist-DnGF41FP.js +0 -1958
  130. package/dist/browser/dist-DnGF41FP.js.map +0 -1
  131. package/dist/controller/defaults.d.ts +0 -34
  132. package/dist/controller/defaults.js +0 -29
  133. package/dist/controller/index.d.ts +0 -61
  134. package/dist/controller/index.js +0 -155
  135. package/dist/controller/utils.d.ts +0 -20
  136. package/dist/controller/utils.js +0 -35
  137. package/dist/delivery/categorize/categories.d.ts +0 -34
  138. package/dist/delivery/categorize/categories.js +0 -66
  139. package/dist/delivery/categorize/category.d.ts +0 -28
  140. package/dist/delivery/categorize/category.js +0 -48
  141. package/dist/delivery/categorize/choice.d.ts +0 -27
  142. package/dist/delivery/categorize/choice.js +0 -94
  143. package/dist/delivery/categorize/choices.d.ts +0 -39
  144. package/dist/delivery/categorize/choices.js +0 -51
  145. package/dist/delivery/categorize/droppable-placeholder.d.ts +0 -32
  146. package/dist/delivery/categorize/droppable-placeholder.js +0 -64
  147. package/dist/delivery/categorize/grid-content.d.ts +0 -25
  148. package/dist/delivery/categorize/grid-content.js +0 -39
  149. package/dist/delivery/categorize/index.d.ts +0 -57
  150. package/dist/delivery/categorize/index.js +0 -260
  151. package/dist/delivery/index.d.ts +0 -27
  152. package/dist/delivery/index.js +0 -152
  153. package/dist/index.d.ts +0 -1
  154. package/dist/index.iife.d.ts +0 -8
  155. package/dist/index.iife.js +0 -152
  156. package/dist/index.js +0 -2
  157. package/dist/runtime-support.d.ts +0 -12
  158. package/dist/runtime-support.js +0 -12
@@ -0,0 +1,727 @@
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.Design = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _utils = require("./utils");
10
+ var _react = _interopRequireDefault(require("react"));
11
+ var _propTypes = _interopRequireDefault(require("prop-types"));
12
+ var _styles = require("@mui/material/styles");
13
+ var _core = require("@dnd-kit/core");
14
+ var _configUi = require("@pie-lib/config-ui");
15
+ var _categorize = require("@pie-lib/categorize");
16
+ var _editableHtmlTipTap = _interopRequireDefault(require("@pie-lib/editable-html-tip-tap"));
17
+ var _drag = require("@pie-lib/drag");
18
+ var _mathRendering = require("@pie-lib/math-rendering");
19
+ var _categories = _interopRequireDefault(require("./categories"));
20
+ var _alternateResponses = _interopRequireDefault(require("./categories/alternateResponses"));
21
+ var _choices = _interopRequireDefault(require("./choices"));
22
+ var _choice = _interopRequireDefault(require("./choices/choice"));
23
+ var _choicePreview = _interopRequireDefault(require("./categories/choice-preview"));
24
+ var _builder = require("./builder");
25
+ var _header = _interopRequireDefault(require("./header"));
26
+ var _utils2 = require("../utils");
27
+ var _translator = _interopRequireDefault(require("@pie-lib/translator"));
28
+ const {
29
+ translator
30
+ } = _translator.default;
31
+ const {
32
+ dropdown,
33
+ Panel,
34
+ toggle,
35
+ radio,
36
+ numberField
37
+ } = _configUi.settings;
38
+ const {
39
+ Provider: IdProvider
40
+ } = _drag.uid;
41
+
42
+ // Simple wrapper to render math in DragOverlay portal
43
+ class DragPreviewWrapper extends _react.default.Component {
44
+ constructor(...args) {
45
+ super(...args);
46
+ (0, _defineProperty2.default)(this, "containerRef", /*#__PURE__*/_react.default.createRef());
47
+ }
48
+ componentDidMount() {
49
+ if (this.containerRef.current) {
50
+ setTimeout(() => (0, _mathRendering.renderMath)(this.containerRef.current), 0);
51
+ }
52
+ }
53
+ render() {
54
+ return /*#__PURE__*/_react.default.createElement("div", {
55
+ ref: this.containerRef
56
+ }, this.props.children);
57
+ }
58
+ }
59
+ const StyledHeader = (0, _styles.styled)(_header.default)(({
60
+ theme
61
+ }) => ({
62
+ marginBottom: theme.spacing(2)
63
+ }));
64
+ const StyledInputContainer = (0, _styles.styled)(_configUi.InputContainer)(({
65
+ theme
66
+ }) => ({
67
+ width: '100%',
68
+ paddingTop: theme.spacing(1),
69
+ marginTop: theme.spacing(1),
70
+ marginBottom: theme.spacing(2)
71
+ }));
72
+ const ErrorText = (0, _styles.styled)('div')(({
73
+ theme
74
+ }) => ({
75
+ fontSize: theme.typography.fontSize - 2,
76
+ color: theme.palette.error.main,
77
+ paddingTop: theme.spacing(1)
78
+ }));
79
+ class Design extends _react.default.Component {
80
+ constructor(_props) {
81
+ super(_props);
82
+ (0, _defineProperty2.default)(this, "updateModel", props => {
83
+ const {
84
+ model,
85
+ onChange
86
+ } = this.props;
87
+ const updatedModel = {
88
+ ...model,
89
+ ...props
90
+ };
91
+ updatedModel.choices = updatedModel.choices.map(c => ({
92
+ ...c,
93
+ categoryCount: this.checkAllowMultiplePlacements(updatedModel.allowMultiplePlacementsEnabled, c)
94
+ }));
95
+
96
+ //Ensure that there are no extra choices in correctResponse, if the user has decided that only one choice may be used.
97
+ updatedModel.correctResponse = (0, _categorize.ensureNoExtraChoicesInAnswer)(updatedModel.correctResponse || [], updatedModel.choices);
98
+
99
+ //Ensure that there are no extra choices in alternate responses, if the user has decided that only one choice may be used.
100
+ updatedModel.correctResponse = (0, _categorize.ensureNoExtraChoicesInAlternate)(updatedModel.correctResponse || [], updatedModel.choices);
101
+
102
+ //clean categories
103
+ updatedModel.categories = updatedModel.categories.map(c => ({
104
+ id: c.id,
105
+ label: c.label
106
+ }));
107
+ updatedModel.choices = updatedModel.choices.map(h => ({
108
+ id: h.id,
109
+ content: h.content,
110
+ categoryCount: h.categoryCount
111
+ }));
112
+
113
+ // ensure that maxChoicesPerCategory is reset if author switch back the corresponding switch (allowMaxChoicesPerCategory)
114
+ updatedModel.maxChoicesPerCategory = updatedModel.allowMaxChoicesPerCategory ? updatedModel.maxChoicesPerCategory : 0;
115
+ onChange(updatedModel);
116
+ });
117
+ (0, _defineProperty2.default)(this, "changeRationale", rationale => {
118
+ const {
119
+ model,
120
+ onChange
121
+ } = this.props;
122
+ onChange({
123
+ ...model,
124
+ rationale
125
+ });
126
+ });
127
+ (0, _defineProperty2.default)(this, "changeTeacherInstructions", teacherInstructions => {
128
+ const {
129
+ model,
130
+ onChange
131
+ } = this.props;
132
+ onChange({
133
+ ...model,
134
+ teacherInstructions
135
+ });
136
+ });
137
+ (0, _defineProperty2.default)(this, "changeFeedback", feedback => {
138
+ this.updateModel({
139
+ feedback
140
+ });
141
+ });
142
+ (0, _defineProperty2.default)(this, "onAddAlternateResponse", () => {
143
+ const {
144
+ model: {
145
+ correctResponse
146
+ }
147
+ } = this.props;
148
+ this.updateModel({
149
+ correctResponse: (correctResponse || []).map(cr => ({
150
+ ...cr,
151
+ alternateResponses: [...(cr.alternateResponses || []), []]
152
+ }))
153
+ });
154
+ });
155
+ (0, _defineProperty2.default)(this, "onPromptChanged", prompt => this.updateModel({
156
+ prompt
157
+ }));
158
+ (0, _defineProperty2.default)(this, "onRemoveAlternateResponse", index => {
159
+ const {
160
+ model: {
161
+ correctResponse
162
+ }
163
+ } = this.props;
164
+ this.updateModel({
165
+ correctResponse: (correctResponse || []).map(cr => ({
166
+ ...cr,
167
+ alternateResponses: (cr.alternateResponses || []).filter((alt, altIndex) => altIndex !== index)
168
+ }))
169
+ });
170
+ });
171
+ (0, _defineProperty2.default)(this, "countChoiceInCorrectResponse", choice => {
172
+ const {
173
+ model
174
+ } = this.props;
175
+ return (0, _categorize.countInAnswer)(choice.id, model.correctResponse);
176
+ });
177
+ (0, _defineProperty2.default)(this, "checkAllowMultiplePlacements", (allowMultiplePlacements, c) => {
178
+ if (allowMultiplePlacements === _utils2.multiplePlacements.enabled) {
179
+ return 0;
180
+ }
181
+ if (allowMultiplePlacements === _utils2.multiplePlacements.disabled) {
182
+ return 1;
183
+ }
184
+ return c.categoryCount || 0;
185
+ });
186
+ (0, _defineProperty2.default)(this, "isAlertModalOpened", () => {
187
+ const {
188
+ model
189
+ } = this.props;
190
+ const {
191
+ maxChoicesPerCategory = 0
192
+ } = model || {};
193
+ const maxChoices = (0, _utils2.getMaxCategoryChoices)(model);
194
+ // when maxChoicesPerCategory is set to 0, there is no limit so modal should not be opened
195
+ return maxChoicesPerCategory !== 0 ? maxChoices > maxChoicesPerCategory : false;
196
+ });
197
+ (0, _defineProperty2.default)(this, "onAlertModalCancel", () => {
198
+ const {
199
+ model
200
+ } = this.props;
201
+ const maxChoices = (0, _utils2.getMaxCategoryChoices)(model);
202
+ this.updateModel({
203
+ maxChoicesPerCategory: maxChoices
204
+ });
205
+ });
206
+ (0, _defineProperty2.default)(this, "onDragStart", event => {
207
+ const {
208
+ active
209
+ } = event;
210
+ const draggedItem = active.data.current;
211
+ this.setState({
212
+ activeDragItem: draggedItem
213
+ });
214
+ });
215
+ (0, _defineProperty2.default)(this, "onDragEnd", ({
216
+ active,
217
+ over
218
+ }) => {
219
+ // scrolls back to the original draggable element (scrollIntoViewIfNeeded).
220
+ const scrollX = window.scrollX;
221
+ const scrollY = window.scrollY;
222
+ this.setState({
223
+ activeDragItem: null
224
+ });
225
+ if (!active) {
226
+ return;
227
+ }
228
+
229
+ // Restore scroll position after dnd-kit's drop animation fires scrollIntoViewIfNeeded.
230
+ // Two rAF frames are needed: dnd-kit uses one rAF internally for focus/scroll restoration.
231
+ requestAnimationFrame(() => {
232
+ requestAnimationFrame(() => {
233
+ window.scrollTo(scrollX, scrollY);
234
+ });
235
+ });
236
+ const {
237
+ model
238
+ } = this.props;
239
+ const {
240
+ allowAlternateEnabled,
241
+ categories = [],
242
+ choices = []
243
+ } = model;
244
+ const activeData = active?.data?.current;
245
+ const overData = over?.data?.current;
246
+ if (!activeData) return;
247
+ const choiceIndex = activeData.choiceIndex || 0;
248
+ const overType = overData?.type;
249
+ const isPreview = activeData.type === 'choice-preview';
250
+ const isNewChoice = activeData.type === 'choice';
251
+ const choiceId = activeData.choice?.id || (typeof activeData.id === 'string' ? activeData.id.split('-')[0] : activeData.id);
252
+ if (isPreview && (!overData || overType === 'choice')) {
253
+ this.removeChoiceFromSource(activeData, choiceIndex, {
254
+ allowAlternateEnabled,
255
+ categories,
256
+ choices
257
+ });
258
+ return;
259
+ }
260
+ if (isPreview && overType === 'category') {
261
+ return this.moveChoice(choiceId, activeData.categoryId, overData.id, choiceIndex);
262
+ }
263
+ if (isNewChoice && overType === 'category') {
264
+ return this.addChoiceToCategory({
265
+ id: activeData.id
266
+ }, overData.id);
267
+ }
268
+ if (isPreview && overType === 'category-alternate') {
269
+ return this.moveChoiceInAlternate(choiceId, activeData.categoryId, overData.id, choiceIndex, overData.alternateResponseIndex);
270
+ }
271
+ if (allowAlternateEnabled && isNewChoice && overType === 'category-alternate') {
272
+ return this.addChoiceToAlternateCategory({
273
+ id: activeData.id
274
+ }, overData.id, overData.alternateResponseIndex);
275
+ }
276
+ });
277
+ (0, _defineProperty2.default)(this, "removeChoiceFromSource", (activeData, choiceIndex, {
278
+ allowAlternateEnabled,
279
+ categories,
280
+ choices
281
+ }) => {
282
+ const isAlternateSource = activeData.alternateResponseIndex !== undefined;
283
+ if (!isAlternateSource) {
284
+ this.deleteChoiceFromCategory(activeData.categoryId, activeData.choiceId, choiceIndex);
285
+ return;
286
+ }
287
+ if (!allowAlternateEnabled) return;
288
+ const category = categories?.find(c => c.id === activeData.categoryId);
289
+ const choice = choices?.find(c => c.id === activeData.choiceId);
290
+ if (category && choice) {
291
+ this.deleteChoiceFromAlternateCategory(category, choice, choiceIndex, activeData.alternateResponseIndex);
292
+ }
293
+ });
294
+ (0, _defineProperty2.default)(this, "addChoiceToCategory", (addedChoice, categoryId) => {
295
+ const {
296
+ model
297
+ } = this.props;
298
+ let {
299
+ choices = [],
300
+ correctResponse = [],
301
+ maxChoicesPerCategory = 0
302
+ } = model || {};
303
+ const choice = (choices || []).find(choice => choice.id === addedChoice.id);
304
+ let newCorrectResponse = (0, _categorize.moveChoiceToCategory)(addedChoice.id, undefined, categoryId, 0, correctResponse);
305
+ if (choice.categoryCount !== 0) {
306
+ newCorrectResponse = (0, _categorize.verifyAllowMultiplePlacements)(addedChoice, categoryId, newCorrectResponse);
307
+ }
308
+ const maxCategoryChoices = (0, _utils2.getMaxCategoryChoices)(model);
309
+ this.updateModel({
310
+ correctResponse: newCorrectResponse,
311
+ maxChoicesPerCategory: maxChoicesPerCategory !== 0 && maxChoicesPerCategory < maxCategoryChoices ? maxChoicesPerCategory + 1 : maxChoicesPerCategory
312
+ });
313
+ });
314
+ (0, _defineProperty2.default)(this, "deleteChoiceFromCategory", (categoryId, choiceId, choiceIndex) => {
315
+ const {
316
+ model
317
+ } = this.props;
318
+ const correctResponse = (0, _categorize.removeChoiceFromCategory)(choiceId, categoryId, choiceIndex, model.correctResponse);
319
+ this.updateModel({
320
+ correctResponse
321
+ });
322
+ });
323
+ (0, _defineProperty2.default)(this, "moveChoice", (choiceId, from, to, choiceIndex) => {
324
+ const {
325
+ model
326
+ } = this.props;
327
+ let {
328
+ choices,
329
+ correctResponse = [],
330
+ maxChoicesPerCategory = 0
331
+ } = model || {};
332
+ const choice = (choices || []).find(choice => choice.id === choiceId);
333
+ if (to === from || !choice) {
334
+ return;
335
+ }
336
+ if (choice.categoryCount !== 0) {
337
+ correctResponse = (0, _categorize.moveChoiceToCategory)(choice.id, from, to, choiceIndex, correctResponse);
338
+ correctResponse = (0, _categorize.verifyAllowMultiplePlacements)(choice, to, correctResponse);
339
+ } else if (choice.categoryCount === 0) {
340
+ correctResponse = (0, _categorize.moveChoiceToCategory)(choice.id, undefined, to, 0, correctResponse);
341
+ }
342
+ const maxCategoryChoices = (0, _utils2.getMaxCategoryChoices)(model);
343
+ // when maxChoicesPerCategory is set to 0, there is no limit so it should not be updated
344
+ this.updateModel({
345
+ correctResponse,
346
+ maxChoicesPerCategory: maxChoicesPerCategory !== 0 && maxChoicesPerCategory < maxCategoryChoices ? maxChoicesPerCategory + 1 : maxChoicesPerCategory
347
+ });
348
+ });
349
+ // methods for alternate responses
350
+ (0, _defineProperty2.default)(this, "addChoiceToAlternateCategory", (addedChoice, categoryId, altIndex) => {
351
+ const {
352
+ model
353
+ } = this.props;
354
+ const {
355
+ correctResponse,
356
+ choices,
357
+ maxChoicesPerCategory = 0
358
+ } = model;
359
+ const choice = choices.find(c => c.id === addedChoice.id);
360
+ correctResponse.forEach(a => {
361
+ if (a.category === categoryId) {
362
+ a.alternateResponses = a.alternateResponses || [];
363
+ if (a.alternateResponses[altIndex] === undefined) {
364
+ a.alternateResponses[altIndex] = [];
365
+ }
366
+ a.alternateResponses[altIndex].push(addedChoice.id);
367
+ if (choice.categoryCount && choice.categoryCount !== 0) {
368
+ a.alternateResponses[altIndex] = a.alternateResponses[altIndex].reduce((acc, currentValue) => {
369
+ if (currentValue === choice.id) {
370
+ const foundIndex = acc.findIndex(c => c === choice.id);
371
+ if (foundIndex === -1) {
372
+ acc.push(currentValue);
373
+ }
374
+ } else {
375
+ acc.push(currentValue);
376
+ }
377
+ return acc;
378
+ }, []);
379
+ }
380
+ return a;
381
+ } else {
382
+ if (a.alternateResponses[altIndex] && choice.categoryCount !== 0) {
383
+ a.alternateResponses[altIndex] = a.alternateResponses[altIndex].filter(c => c !== addedChoice.id);
384
+ return a;
385
+ }
386
+ }
387
+ return a;
388
+ });
389
+ const maxCategoryChoices = (0, _utils2.getMaxCategoryChoices)(model);
390
+ // when maxChoicesPerCategory is set to 0, there is no limit so it should not be updated
391
+ this.updateModel({
392
+ correctResponse,
393
+ maxChoicesPerCategory: maxChoicesPerCategory !== 0 && maxChoicesPerCategory < maxCategoryChoices ? maxChoicesPerCategory + 1 : maxChoicesPerCategory
394
+ });
395
+ });
396
+ (0, _defineProperty2.default)(this, "moveChoiceInAlternate", (choiceId, from, to, choiceIndex, alternateIndex) => {
397
+ const {
398
+ model
399
+ } = this.props;
400
+ let {
401
+ choices,
402
+ correctResponse = [],
403
+ maxChoicesPerCategory = 0
404
+ } = model || {};
405
+ const choice = (choices || []).find(choice => choice.id === choiceId);
406
+ correctResponse = (0, _categorize.moveChoiceToAlternate)(choiceId, from, to, choiceIndex, correctResponse, alternateIndex, choice?.categoryCount);
407
+ const maxCategoryChoices = (0, _utils2.getMaxCategoryChoices)(model);
408
+ // when maxChoicesPerCategory is set to 0, there is no limit so it should not be updated
409
+ this.updateModel({
410
+ correctResponse,
411
+ maxChoicesPerCategory: maxChoicesPerCategory !== 0 && maxChoicesPerCategory < maxCategoryChoices ? maxChoicesPerCategory + 1 : maxChoicesPerCategory
412
+ });
413
+ });
414
+ (0, _defineProperty2.default)(this, "deleteChoiceFromAlternateCategory", (category, choice, choiceIndex, altIndex) => {
415
+ const {
416
+ model
417
+ } = this.props;
418
+ const correctResponse = (0, _categorize.removeChoiceFromAlternate)(choice.id, category.id, choiceIndex, altIndex, model.correctResponse);
419
+ this.updateModel({
420
+ correctResponse
421
+ });
422
+ });
423
+ (0, _defineProperty2.default)(this, "renderDragOverlay", () => {
424
+ const {
425
+ activeDragItem
426
+ } = this.state;
427
+ const {
428
+ model,
429
+ configuration
430
+ } = this.props;
431
+ if (!activeDragItem) return null;
432
+ if (activeDragItem.type === 'choice') {
433
+ const choice = model.choices?.find(c => c.id === activeDragItem.id);
434
+ if (!choice) return null;
435
+ return /*#__PURE__*/_react.default.createElement(_choice.default, {
436
+ choice: choice,
437
+ configuration: configuration
438
+ });
439
+ } else if (activeDragItem.type === 'choice-preview' && activeDragItem.alternateResponseIndex === undefined) {
440
+ const choice = model.choices?.find(c => c.id === activeDragItem.id);
441
+ if (!choice) return null;
442
+ return /*#__PURE__*/_react.default.createElement(_choicePreview.default, {
443
+ choice: choice
444
+ });
445
+ } else if (activeDragItem.type === 'choice-preview' && activeDragItem.alternateResponseIndex !== undefined) {
446
+ const choice = model.choices?.find(c => c.id === activeDragItem.id);
447
+ if (!choice) return null;
448
+ return /*#__PURE__*/_react.default.createElement(_choicePreview.default, {
449
+ choice: choice,
450
+ alternateResponseIndex: activeDragItem.alternateResponseIndex
451
+ });
452
+ }
453
+ return null;
454
+ });
455
+ this.uid = _props.uid || _drag.uid.generateId();
456
+ this.state = {
457
+ activeDragItem: null
458
+ };
459
+ }
460
+ render() {
461
+ const {
462
+ configuration,
463
+ imageSupport,
464
+ model,
465
+ uploadSoundSupport,
466
+ onConfigurationChanged
467
+ } = this.props;
468
+ const {
469
+ allowAlternate = {},
470
+ allowMultiplePlacements = {},
471
+ baseInputConfiguration = {},
472
+ categoriesPerRow = {},
473
+ choicesPosition = {},
474
+ contentDimensions = {},
475
+ feedback = {},
476
+ lockChoiceOrder = {},
477
+ maxImageHeight = {},
478
+ maxImageWidth = {},
479
+ maxPlacements = {},
480
+ minCategoriesPerRow = 1,
481
+ partialScoring = {},
482
+ prompt = {},
483
+ rationale = {},
484
+ scoringType = {},
485
+ settingsPanelDisabled,
486
+ spellCheck = {},
487
+ studentInstructions = {},
488
+ teacherInstructions = {},
489
+ withRubric = {},
490
+ mathMlOptions = {},
491
+ language = {},
492
+ languageChoices = {},
493
+ allowMaxAnswerChoices = {}
494
+ } = configuration || {};
495
+ const {
496
+ allowAlternateEnabled,
497
+ allowMaxChoicesPerCategory,
498
+ errors,
499
+ feedbackEnabled,
500
+ maxChoicesPerCategory,
501
+ promptEnabled,
502
+ rationaleEnabled,
503
+ spellCheckEnabled,
504
+ teacherInstructionsEnabled,
505
+ toolbarEditorPosition,
506
+ extraCSSRules
507
+ } = model || {};
508
+ const {
509
+ prompt: promptError,
510
+ rationale: rationaleError,
511
+ teacherInstructions: teacherInstructionsError
512
+ } = errors || {};
513
+ const toolbarOpts = {
514
+ position: toolbarEditorPosition === 'top' ? 'top' : 'bottom'
515
+ };
516
+ const config = model.config || {};
517
+ config.choices = config.choices || {
518
+ label: '',
519
+ columns: 2
520
+ };
521
+ const categories = (0, _builder.buildCategories)(model.categories || [], model.choices || [], model.correctResponse || []);
522
+ const alternateResponses = (0, _builder.buildAlternateResponses)(model.categories || [], model.choices || [], model.correctResponse || []);
523
+ const choices = model.choices.map(c => {
524
+ c.correctResponseCount = this.countChoiceInCorrectResponse(c);
525
+ // ensure categoryCount is set even though updatedModel hasn't been called
526
+ c.categoryCount = this.checkAllowMultiplePlacements(model.allowMultiplePlacementsEnabled, c);
527
+ return c;
528
+ });
529
+ const defaultImageMaxWidth = maxImageWidth && maxImageWidth.prompt;
530
+ const defaultImageMaxHeight = maxImageHeight && maxImageHeight.prompt;
531
+ const panelSettings = {
532
+ partialScoring: partialScoring.settings && toggle(partialScoring.label),
533
+ lockChoiceOrder: lockChoiceOrder.settings && toggle(lockChoiceOrder.label),
534
+ categoriesPerRow: categoriesPerRow.settings && numberField(categoriesPerRow.label, {
535
+ label: categoriesPerRow.label,
536
+ min: minCategoriesPerRow,
537
+ max: 6
538
+ }),
539
+ choicesPosition: choicesPosition.settings && radio(choicesPosition.label, ['below', 'above', 'left', 'right']),
540
+ allowMultiplePlacementsEnabled: allowMultiplePlacements.settings && dropdown(allowMultiplePlacements.label, [_utils2.multiplePlacements.enabled, _utils2.multiplePlacements.disabled, _utils2.multiplePlacements.perChoice]),
541
+ maxAnswerChoices: allowMaxAnswerChoices.settings && numberField(allowMaxAnswerChoices.label, {
542
+ label: '',
543
+ min: choices?.length || 0,
544
+ max: 30
545
+ }),
546
+ allowMaxChoicesPerCategory: maxPlacements.settings && toggle(maxPlacements.label),
547
+ maxChoicesPerCategory: allowMaxChoicesPerCategory === true && numberField(maxPlacements.label, {
548
+ label: '',
549
+ min: 0,
550
+ max: 30
551
+ }),
552
+ promptEnabled: prompt.settings && toggle(prompt.label),
553
+ feedbackEnabled: feedback.settings && toggle(feedback.label),
554
+ allowAlternateEnabled: allowAlternate.settings && toggle(allowAlternate.label),
555
+ 'language.enabled': language.settings && toggle(language.label, true),
556
+ language: language.settings && language.enabled && dropdown(languageChoices.label, languageChoices.options)
557
+ };
558
+ const panelProperties = {
559
+ teacherInstructionsEnabled: teacherInstructions.settings && toggle(teacherInstructions.label),
560
+ studentInstructionsEnabled: studentInstructions.settings && toggle(studentInstructions.label),
561
+ rationaleEnabled: rationale.settings && toggle(rationale.label),
562
+ spellCheckEnabled: spellCheck.settings && toggle(spellCheck.label),
563
+ scoringType: scoringType.settings && radio(scoringType.label, ['auto', 'rubric']),
564
+ rubricEnabled: withRubric?.settings && toggle(withRubric?.label)
565
+ };
566
+ const isOpened = this.isAlertModalOpened();
567
+ const alertMaxChoicesMsg = translator.t('translation:categorize:maxChoicesPerCategoryRestriction', {
568
+ lng: model.language,
569
+ maxChoicesPerCategory
570
+ });
571
+ return /*#__PURE__*/_react.default.createElement(_drag.DragProvider, {
572
+ onDragStart: this.onDragStart,
573
+ onDragEnd: this.onDragEnd
574
+ }, /*#__PURE__*/_react.default.createElement(IdProvider, {
575
+ value: this.uid
576
+ }, /*#__PURE__*/_react.default.createElement(_configUi.layout.ConfigLayout, {
577
+ extraCSSRules: extraCSSRules,
578
+ dimensions: contentDimensions,
579
+ hideSettings: settingsPanelDisabled,
580
+ settings: /*#__PURE__*/_react.default.createElement(Panel, {
581
+ model: model,
582
+ onChangeModel: this.updateModel,
583
+ configuration: configuration,
584
+ onChangeConfiguration: onConfigurationChanged,
585
+ groups: {
586
+ Settings: panelSettings,
587
+ Properties: panelProperties
588
+ },
589
+ modal: /*#__PURE__*/_react.default.createElement(_configUi.AlertDialog, {
590
+ title: 'Warning',
591
+ text: alertMaxChoicesMsg,
592
+ open: isOpened,
593
+ onClose: this.onAlertModalCancel
594
+ })
595
+ })
596
+ }, teacherInstructionsEnabled && /*#__PURE__*/_react.default.createElement(StyledInputContainer, {
597
+ label: teacherInstructions.label
598
+ }, /*#__PURE__*/_react.default.createElement(_editableHtmlTipTap.default, {
599
+ markup: model.teacherInstructions || '',
600
+ onChange: this.changeTeacherInstructions,
601
+ imageSupport: imageSupport,
602
+ error: teacherInstructionsError,
603
+ nonEmpty: false,
604
+ toolbarOpts: toolbarOpts,
605
+ pluginProps: (0, _utils.getPluginProps)(teacherInstructions?.inputConfiguration, baseInputConfiguration),
606
+ spellCheck: spellCheckEnabled,
607
+ maxImageWidth: maxImageWidth && maxImageWidth.teacherInstructions || defaultImageMaxWidth,
608
+ maxImageHeight: maxImageHeight && maxImageHeight.teacherInstructions || defaultImageMaxHeight,
609
+ uploadSoundSupport: uploadSoundSupport,
610
+ languageCharactersProps: [{
611
+ language: 'spanish'
612
+ }, {
613
+ language: 'special'
614
+ }],
615
+ mathMlOptions: mathMlOptions
616
+ }), teacherInstructionsError && /*#__PURE__*/_react.default.createElement(ErrorText, null, teacherInstructionsError)), promptEnabled && /*#__PURE__*/_react.default.createElement(StyledInputContainer, {
617
+ label: prompt.label
618
+ }, /*#__PURE__*/_react.default.createElement(_editableHtmlTipTap.default, {
619
+ markup: model.prompt || '',
620
+ onChange: this.onPromptChanged,
621
+ imageSupport: imageSupport,
622
+ error: promptError,
623
+ nonEmpty: false,
624
+ disableUnderline: true,
625
+ toolbarOpts: toolbarOpts,
626
+ pluginProps: (0, _utils.getPluginProps)(prompt?.inputConfiguration, baseInputConfiguration),
627
+ spellCheck: spellCheckEnabled,
628
+ maxImageWidth: maxImageWidth && maxImageWidth.prompt,
629
+ maxImageHeight: maxImageHeight && maxImageHeight.prompt,
630
+ uploadSoundSupport: uploadSoundSupport,
631
+ languageCharactersProps: [{
632
+ language: 'spanish'
633
+ }, {
634
+ language: 'special'
635
+ }],
636
+ mathMlOptions: mathMlOptions
637
+ }), promptError && /*#__PURE__*/_react.default.createElement(ErrorText, null, promptError)), /*#__PURE__*/_react.default.createElement(_categories.default, {
638
+ imageSupport: imageSupport,
639
+ uploadSoundSupport: uploadSoundSupport,
640
+ model: model,
641
+ categories: categories || [],
642
+ onModelChanged: this.updateModel,
643
+ toolbarOpts: toolbarOpts,
644
+ spellCheck: spellCheckEnabled,
645
+ configuration: configuration,
646
+ defaultImageMaxWidth: defaultImageMaxWidth,
647
+ defaultImageMaxHeight: defaultImageMaxHeight,
648
+ mathMlOptions: mathMlOptions
649
+ }), /*#__PURE__*/_react.default.createElement(_choices.default, {
650
+ imageSupport: imageSupport,
651
+ uploadSoundSupport: uploadSoundSupport,
652
+ choices: choices,
653
+ model: model,
654
+ onModelChanged: this.updateModel,
655
+ toolbarOpts: toolbarOpts,
656
+ spellCheck: spellCheckEnabled,
657
+ configuration: configuration,
658
+ defaultImageMaxWidth: defaultImageMaxWidth,
659
+ defaultImageMaxHeight: defaultImageMaxHeight
660
+ }), allowAlternateEnabled && /*#__PURE__*/_react.default.createElement(StyledHeader, {
661
+ label: "Alternate Responses",
662
+ buttonLabel: "ADD AN ALTERNATE RESPONSE",
663
+ onAdd: this.onAddAlternateResponse
664
+ }), allowAlternateEnabled && alternateResponses.map((categoriesList, index) => {
665
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, {
666
+ key: index
667
+ }, /*#__PURE__*/_react.default.createElement(StyledHeader, {
668
+ variant: 'subtitle1',
669
+ label: "Alternate Response",
670
+ buttonLabel: "REMOVE ALTERNATE RESPONSE",
671
+ onAdd: () => this.onRemoveAlternateResponse(index)
672
+ }), /*#__PURE__*/_react.default.createElement(_alternateResponses.default, {
673
+ altIndex: index,
674
+ imageSupport: imageSupport,
675
+ model: model,
676
+ configuration: configuration,
677
+ categories: categoriesList,
678
+ onModelChanged: this.updateModel,
679
+ uploadSoundSupport: uploadSoundSupport,
680
+ mathMlOptions: mathMlOptions
681
+ }));
682
+ }), rationaleEnabled && /*#__PURE__*/_react.default.createElement(StyledInputContainer, {
683
+ label: rationale.label
684
+ }, /*#__PURE__*/_react.default.createElement(_editableHtmlTipTap.default, {
685
+ markup: model.rationale || '',
686
+ onChange: this.changeRationale,
687
+ imageSupport: imageSupport,
688
+ error: rationaleError,
689
+ nonEmpty: false,
690
+ toolbarOpts: toolbarOpts,
691
+ pluginProps: (0, _utils.getPluginProps)(prompt?.inputConfiguration, baseInputConfiguration),
692
+ spellCheck: spellCheckEnabled,
693
+ maxImageWidth: maxImageWidth && maxImageWidth.rationale || defaultImageMaxWidth,
694
+ maxImageHeight: maxImageHeight && maxImageHeight.rationale || defaultImageMaxHeight,
695
+ uploadSoundSupport: uploadSoundSupport,
696
+ languageCharactersProps: [{
697
+ language: 'spanish'
698
+ }, {
699
+ language: 'special'
700
+ }],
701
+ mathMlOptions: mathMlOptions
702
+ }), rationaleError && /*#__PURE__*/_react.default.createElement(ErrorText, null, rationaleError)), feedbackEnabled && /*#__PURE__*/_react.default.createElement(_configUi.FeedbackConfig, {
703
+ feedback: model.feedback,
704
+ onChange: this.changeFeedback,
705
+ toolbarOpts: toolbarOpts
706
+ })), /*#__PURE__*/_react.default.createElement(_core.DragOverlay, null, /*#__PURE__*/_react.default.createElement(DragPreviewWrapper, null, this.renderDragOverlay()))));
707
+ }
708
+ }
709
+ exports.Design = Design;
710
+ (0, _defineProperty2.default)(Design, "propTypes", {
711
+ configuration: _propTypes.default.object,
712
+ className: _propTypes.default.string,
713
+ onConfigurationChanged: _propTypes.default.func,
714
+ model: _propTypes.default.object.isRequired,
715
+ onChange: _propTypes.default.func.isRequired,
716
+ uid: _propTypes.default.string,
717
+ imageSupport: _propTypes.default.shape({
718
+ add: _propTypes.default.func.isRequired,
719
+ delete: _propTypes.default.func.isRequired
720
+ }),
721
+ uploadSoundSupport: _propTypes.default.shape({
722
+ add: _propTypes.default.func.isRequired,
723
+ delete: _propTypes.default.func.isRequired
724
+ })
725
+ });
726
+ var _default = exports.default = Design;
727
+ //# sourceMappingURL=index.js.map