@nualang/nualang-ui-components 0.1.1356 → 0.1.1359

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 (42) hide show
  1. package/dist/Assignments/AssignmentBotSelection/package.json +1 -1
  2. package/dist/Assignments/AssignmentCard/AssignmentCard.js +2 -0
  3. package/dist/Assignments/AssignmentCardsList/AssignmentCardsList.js +3 -0
  4. package/dist/Assignments/AssignmentCourseSelection/AssignmentCourseSelection.js +6 -2
  5. package/dist/Assignments/AssignmentExerciseSelection/AssignmentExerciseSelection.js +126 -119
  6. package/dist/Assignments/AssignmentExerciseSelector/AssignmentExerciseSelector.js +2 -0
  7. package/dist/Assignments/AssignmentPhraseListSelection/AssignmentPhraseListSelection.js +440 -0
  8. package/dist/Assignments/AssignmentPhraseListSelection/package.json +6 -0
  9. package/dist/Assignments/AssignmentSelectExercise/AssignmentSelectExercise.js +14 -6
  10. package/dist/Dialogs/SelectExercise/SelectExercise.js +2 -0
  11. package/dist/Editors/PhraseList/PhraseList.js +14 -2
  12. package/dist/Exercises/Meaning/Meaning.js +11 -7
  13. package/dist/Lists/CourseSelection/CourseSelection.js +4 -0
  14. package/dist/Lists/ExerciseSelection/ExerciseSelection.js +56 -61
  15. package/dist/Lists/Exercises/Exercises.js +1 -1
  16. package/dist/Lists/PhraseListSelection/PhraseListSelection.js +206 -0
  17. package/dist/Lists/Phrases/Phrases.js +12 -18
  18. package/dist/Live/Game/Game.js +18 -0
  19. package/dist/Live/LiveMeaning/LiveMeaning.js +380 -0
  20. package/dist/Misc/AnswerResult/AnswerResult.js +1 -1
  21. package/dist/Misc/ExerciseBottomBar/ExerciseBottomBar.js +2 -0
  22. package/dist/Misc/PhraseDisplay/PhraseDisplay.js +2 -6
  23. package/dist/Screens/Classrooms/ViewClassroom/ViewClassroom.js +7 -1
  24. package/dist/Screens/Pricing/Pricing.js +0 -48
  25. package/dist/Tables/Progress/ProgressList.js +2 -2
  26. package/dist/Tables/Progress/cells/index.js +2 -2
  27. package/dist/config.js +0 -3
  28. package/package.json +2 -4
  29. package/dist/Payments/BillingInfo/BillingInfo.js +0 -54
  30. package/dist/Payments/BillingInfo/BillingInfo.test.js +0 -15
  31. package/dist/Payments/BillingInfo/package.json +0 -6
  32. package/dist/Payments/CardDetails/CardDetails.js +0 -54
  33. package/dist/Payments/CardDetails/CardDetails.test.js +0 -22
  34. package/dist/Payments/CardDetails/commonTextFields.js +0 -69
  35. package/dist/Payments/CardDetails/package.json +0 -6
  36. package/dist/Payments/Payment/Payment.js +0 -163
  37. package/dist/Payments/Payment/styles.css +0 -222
  38. package/dist/Payments/StripeInput/StripeInput.js +0 -17
  39. package/dist/Payments/Subscription/Subscription.js +0 -245
  40. package/dist/Payments/Subscription/commonTextFields.js +0 -57
  41. package/dist/Payments/SubscriptionPayment/Subscription.js +0 -246
  42. package/dist/Payments/SubscriptionPayment/styles.css +0 -222
@@ -2,5 +2,5 @@
2
2
  "name": "AssignmentBotSelection",
3
3
  "version": "0.0.0",
4
4
  "private": true,
5
- "main": "./AssignmentBotSelection.js"
5
+ "main": "./AssignmentBotSelection.jsx"
6
6
  }
@@ -21,6 +21,7 @@ export default function AssignmentCard({
21
21
  deleteAssignment,
22
22
  handleEditAssignment,
23
23
  progressHelpers,
24
+ completionHelpers,
24
25
  preferred_username,
25
26
  memberId,
26
27
  fetchMemberCourseCompletions,
@@ -219,6 +220,7 @@ export default function AssignmentCard({
219
220
  useCase: isCreator ? "assignment-view" : "assignment-start",
220
221
  preferred_username: preferred_username,
221
222
  progressHelpers: progressHelpers,
223
+ completionHelpers: completionHelpers,
222
224
  memberCourseCompletions: memberCourseCompletions,
223
225
  lastClickedExerciseId: lastClickedExerciseId,
224
226
  isChallengeModeStudent: isChallengeModeStudent
@@ -21,6 +21,7 @@ const AssignmentCardsList = ({
21
21
  username,
22
22
  preferred_username,
23
23
  progressHelpers,
24
+ completionHelpers,
24
25
  fetchMemberCourseCompletions,
25
26
  memberId,
26
27
  handleViewProgress,
@@ -337,6 +338,7 @@ const AssignmentCardsList = ({
337
338
  handleEditAssignment: handleEditAssignment,
338
339
  lastClickedExerciseId: lastClickedExerciseId,
339
340
  progressHelpers: progressHelpers,
341
+ completionHelpers: completionHelpers,
340
342
  fetchMemberCourseCompletions: fetchMemberCourseCompletions,
341
343
  username: username,
342
344
  preferred_username: preferred_username,
@@ -362,6 +364,7 @@ AssignmentCardsList.propTypes = {
362
364
  username: PropTypes.string,
363
365
  preferred_username: PropTypes.string,
364
366
  progressHelpers: PropTypes.object,
367
+ completionHelpers: PropTypes.object,
365
368
  fetchMemberCourseCompletions: PropTypes.func,
366
369
  memberId: PropTypes.string,
367
370
  handleViewProgress: PropTypes.func,
@@ -27,6 +27,7 @@ function Course({
27
27
  viewOnly,
28
28
  preferred_username,
29
29
  progressHelpers,
30
+ completionHelpers,
30
31
  memberCourseCompletions,
31
32
  lastClickedExerciseId,
32
33
  handleRemoveExercise,
@@ -174,6 +175,7 @@ function Course({
174
175
  username: username,
175
176
  preferred_username: preferred_username,
176
177
  progressHelpers: progressHelpers,
178
+ completionHelpers: completionHelpers,
177
179
  memberCourseCompletions: memberCourseCompletions,
178
180
  lastClickedExerciseId: lastClickedExerciseId,
179
181
  isChallengeModeStudent: isChallengeModeStudent
@@ -201,6 +203,7 @@ function Course({
201
203
  username: username,
202
204
  preferred_username: preferred_username,
203
205
  progressHelpers: progressHelpers,
206
+ completionHelpers: completionHelpers,
204
207
  memberCourseCompletions: memberCourseCompletions,
205
208
  lastClickedExerciseId: lastClickedExerciseId,
206
209
  course: course,
@@ -229,12 +232,12 @@ function AssignmentCourseSelection({
229
232
  viewOnly,
230
233
  preferred_username,
231
234
  progressHelpers,
235
+ completionHelpers,
232
236
  memberCourseCompletions,
233
237
  lastClickedExerciseId,
234
238
  handleRemoveExercise,
235
239
  isPreview,
236
- isChallengeModeStudent,
237
- ...otherProps
240
+ isChallengeModeStudent
238
241
  }) {
239
242
  return /*#__PURE__*/_jsx("div", {
240
243
  children: courses.map((course, index) => /*#__PURE__*/_jsx(Course, {
@@ -257,6 +260,7 @@ function AssignmentCourseSelection({
257
260
  preferred_username: preferred_username,
258
261
  memberCourseCompletions: memberCourseCompletions,
259
262
  progressHelpers: progressHelpers,
263
+ completionHelpers: completionHelpers,
260
264
  lastClickedExerciseId: lastClickedExerciseId,
261
265
  handleRemoveExercise: handleRemoveExercise,
262
266
  isPreview: isPreview,
@@ -4,23 +4,22 @@ import { useTheme } from "@mui/material/styles";
4
4
  import useMediaQuery from "@mui/material/useMediaQuery";
5
5
  import ImageSearchIcon from "@mui/icons-material/ImageSearch";
6
6
  import ClearIcon from "@mui/icons-material/Clear";
7
- import HearingIcon from "@mui/icons-material/Hearing";
8
- import SwapHorizIcon from "@mui/icons-material/SwapHoriz";
9
7
  import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
10
8
  import ExpandLessIcon from "@mui/icons-material/ExpandLess";
11
- import RecordVoiceOverIcon from "@mui/icons-material/RecordVoiceOver";
12
9
  import ForumIcon from "@mui/icons-material/Forum";
13
10
  import FaceIcon from "@mui/icons-material/Face";
11
+ import MenuBookIcon from "@mui/icons-material/MenuBook";
14
12
  import OndemandVideoIcon from "@mui/icons-material/OndemandVideo";
15
13
  import AssignmentRoleplaySelection from "../AssignmentRoleplaySelection/AssignmentRoleplaySelection";
16
14
  import { CardInfoSectionItem } from "../../Cards/CardElements";
17
15
  import { getCourseSectionTopicProgress } from "@nualang/nualang-api-and-queries/APIs/Progress";
18
- import { progress as progressQuerys } from "@nualang/nualang-api-and-queries/Queries";
16
+ import { progress as progressQuerys, courses as courseQuerys } from "@nualang/nualang-api-and-queries/Queries";
19
17
  import { useNavigate, useParams } from "react-router";
20
18
  import { ProgressBadge, InProgressBadge } from "../../Lists/Exercises/Exercises";
21
19
  import ColorLinearProgress from "../../Misc/ColorLinearProgress/ColorLinearProgress";
22
20
  import { calcCompletions } from "../../utils";
23
21
  import AssignmentBotSelection from "../AssignmentBotSelection/AssignmentBotSelection";
22
+ import AssignmentPhraseListSelection from "../AssignmentPhraseListSelection/AssignmentPhraseListSelection";
24
23
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
25
24
  function Exercise({
26
25
  name,
@@ -31,8 +30,6 @@ function Exercise({
31
30
  isExerciseSelected,
32
31
  roleplays,
33
32
  bots,
34
- roleplayId,
35
- botId,
36
33
  phrases,
37
34
  handleSelectExercise = null,
38
35
  selectedExercises,
@@ -48,12 +45,10 @@ function Exercise({
48
45
  lastClickedExerciseId,
49
46
  isPreview,
50
47
  handleRemoveExercise = null,
51
- isChallengeModeStudent
48
+ isChallengeModeStudent,
49
+ phraseLists = [],
50
+ completionHelpers
52
51
  }) {
53
- const [listeningHidden, setListeningHidden] = useState(false);
54
- const [translationHidden, setTranslationHidden] = useState(false);
55
- const [pronunciationHidden, setPronunciationHidden] = useState(false);
56
-
57
52
  //progress
58
53
  const [pronunciationProgress, setPronunciationProgress] = useState(null);
59
54
  const [translationProgress, setTranslationProgress] = useState(null);
@@ -105,11 +100,11 @@ function Exercise({
105
100
  };
106
101
  fetchProgress();
107
102
  }, [topicProgress, isCreator]);
108
- const isAssignmentExerciseSelected = selectedExercises?.some(e => e.name === name && e.courseSectionTopicId === courseSectionTopicId);
109
103
  const noRoleplays = name.toLowerCase() === "roleplays" && roleplays.length === 0;
110
104
  const [roleplaysOpen, setRoleplaysOpen] = useState(noRoleplays ? false : true);
111
105
  const noBots = name.toLowerCase() === "bots" && bots?.length === 0;
112
106
  const [botsOpen, setBotsOpen] = useState(noBots ? false : true);
107
+ const [phraseListsOpen, setPhraseListsOpen] = useState(phraseLists && phraseLists.length > 0 ? true : false);
113
108
  const navigate = useNavigate();
114
109
  const params = useParams();
115
110
  const {
@@ -128,18 +123,10 @@ function Exercise({
128
123
  const handleToggleBots = () => {
129
124
  setBotsOpen(!botsOpen);
130
125
  };
131
- useEffect(() => {
132
- const currentTopicId = courseSectionTopicId.split("|")[2];
133
- const currentTopic = section?.topics?.find(t => t.topicId === currentTopicId) || {};
134
- const hidden = (currentTopic.hiddenExercises || []).map(x => String(x).toLowerCase());
135
- setListeningHidden(hidden.includes("listening"));
136
- setTranslationHidden(hidden.includes("translation"));
137
- setPronunciationHidden(hidden.includes("pronunciation"));
138
- }, [section, courseSectionTopicId]);
139
- const isValidExercise = phrases.length >= 2 || name.toLowerCase() === "roleplays" || name.toLowerCase() === "bots";
140
- if (name.toLowerCase() === "listening" && listeningHidden || name.toLowerCase() === "translation" && translationHidden || name.toLowerCase() === "pronunciation" && pronunciationHidden) {
141
- return null;
142
- }
126
+ const handleTogglePhraseLists = () => {
127
+ setPhraseListsOpen(!phraseListsOpen);
128
+ };
129
+ const isValidExercise = phrases.length >= 2 || name.toLowerCase() === "roleplays" || name.toLowerCase() === "bots" || name.toLowerCase() === "phrases";
143
130
  return /*#__PURE__*/_jsxs(Tooltip, {
144
131
  title: isCreator ? name === "roleplays" && noRoleplays ? t("topic_no_roleplays") : !isValidExercise ? t("minimum_two_phrases") : "" : null,
145
132
  children: [/*#__PURE__*/_jsxs(ListItemButton, {
@@ -148,6 +135,8 @@ function Exercise({
148
135
  handleToggleRoleplays();
149
136
  } else if (name.toLowerCase() === "bots") {
150
137
  handleToggleBots();
138
+ } else if (name.toLowerCase() === "phrases") {
139
+ handleTogglePhraseLists();
151
140
  } else if (useCase === "assignment-select") {
152
141
  handleSelectExercise([{
153
142
  name,
@@ -157,11 +146,11 @@ function Exercise({
157
146
  addSearchParams();
158
147
  }
159
148
  },
160
- display: "flex",
161
- alignItems: "center",
162
- justifyContent: "space-between",
163
149
  disabled: isExerciseSelected || !isValidExercise || noRoleplays || noBots,
164
150
  sx: theme => ({
151
+ display: "flex",
152
+ alignItems: "center",
153
+ justifyContent: "space-between",
165
154
  [theme.breakpoints.up("md")]: {
166
155
  ml: "60px"
167
156
  }
@@ -171,16 +160,12 @@ function Exercise({
171
160
  xs: "none",
172
161
  sm: "flex"
173
162
  },
174
- children: [name.toLowerCase() === "listening" && /*#__PURE__*/_jsx(ListItemIcon, {
175
- children: /*#__PURE__*/_jsx(HearingIcon, {})
176
- }), name.toLowerCase() === "translation" && /*#__PURE__*/_jsx(ListItemIcon, {
177
- children: /*#__PURE__*/_jsx(SwapHorizIcon, {})
178
- }), name.toLowerCase() === "pronunciation" && /*#__PURE__*/_jsx(ListItemIcon, {
179
- children: /*#__PURE__*/_jsx(RecordVoiceOverIcon, {})
180
- }), name.toLowerCase() === "roleplays" && /*#__PURE__*/_jsx(ListItemIcon, {
163
+ children: [name.toLowerCase() === "roleplays" && /*#__PURE__*/_jsx(ListItemIcon, {
181
164
  children: /*#__PURE__*/_jsx(ForumIcon, {})
182
165
  }), name.toLowerCase() === "bots" && /*#__PURE__*/_jsx(ListItemIcon, {
183
166
  children: /*#__PURE__*/_jsx(FaceIcon, {})
167
+ }), name.toLowerCase() === "phrases" && /*#__PURE__*/_jsx(ListItemIcon, {
168
+ children: /*#__PURE__*/_jsx(MenuBookIcon, {})
184
169
  })]
185
170
  }), /*#__PURE__*/_jsx(Box, {
186
171
  width: "100%",
@@ -198,52 +183,39 @@ function Exercise({
198
183
  mr: useCase === "assignment-select" ? 2 : 0
199
184
  },
200
185
  children: botsOpen ? /*#__PURE__*/_jsx(ExpandLessIcon, {}) : /*#__PURE__*/_jsx(ExpandMoreIcon, {})
201
- }), (name.toLowerCase() === "listening" || name.toLowerCase() === "translation" || name.toLowerCase() === "pronunciation") && /*#__PURE__*/_jsxs(ListItemIcon, {
202
- children: [useCase === "assignment-select" && /*#__PURE__*/_jsx(Checkbox, {
203
- checked: isAssignmentExerciseSelected,
204
- onClick: event => {
205
- event.stopPropagation();
206
- } //so clicking on the checkbox doesnt also trigger the onclick of the listItemButton
207
- ,
208
- onChange: () => {
209
- handleSelectExercise([{
210
- name,
211
- courseSectionTopicId
212
- }]);
213
- }
214
- }), useCase === "assignment-view" && isPreview && /*#__PURE__*/_jsx(IconButton, {
215
- edge: "end",
216
- "aria-label": "remove-exercise",
217
- onClick: e => {
218
- e.stopPropagation();
219
- handleRemoveExercise({
220
- courseSectionTopicId,
221
- name
222
- });
223
- },
224
- children: /*#__PURE__*/_jsx(ClearIcon, {
225
- fontSize: "small"
226
- })
227
- }), !isCreator && name.toLowerCase() === "pronunciation" && /*#__PURE__*/_jsxs(_Fragment, {
228
- children: [/*#__PURE__*/_jsx(InProgressBadge, {
229
- progressCount: pronunciationProgress && pronunciationProgress.remainingQuestions?.length || 0
230
- }), /*#__PURE__*/_jsx(ProgressBadge, {
231
- completions: pronunciation && pronunciation.completedCount ? pronunciation.completedCount : 0
232
- })]
233
- }), !isCreator && name.toLowerCase() === "translation" && /*#__PURE__*/_jsxs(_Fragment, {
234
- children: [/*#__PURE__*/_jsx(InProgressBadge, {
235
- progressCount: translationProgress && translationProgress.remainingQuestions?.length || 0
236
- }), /*#__PURE__*/_jsx(ProgressBadge, {
237
- completions: translation && translation.completedCount ? translation.completedCount : 0
238
- })]
239
- }), !isCreator && name.toLowerCase() === "listening" && /*#__PURE__*/_jsxs(_Fragment, {
240
- children: [/*#__PURE__*/_jsx(InProgressBadge, {
241
- progressCount: listeningProgress && listeningProgress.remainingQuestions?.length || 0
242
- }), /*#__PURE__*/_jsx(ProgressBadge, {
243
- completions: listening && listening.completedCount ? listening.completedCount : 0
244
- })]
245
- })]
186
+ }), name.toLowerCase() === "phrases" && /*#__PURE__*/_jsx(IconButton, {
187
+ sx: {
188
+ mr: useCase === "assignment-select" ? 2 : 0
189
+ },
190
+ children: phraseListsOpen ? /*#__PURE__*/_jsx(ExpandLessIcon, {}) : /*#__PURE__*/_jsx(ExpandMoreIcon, {})
246
191
  })]
192
+ }), name.toLowerCase() === "phrases" && /*#__PURE__*/_jsx(Collapse, {
193
+ in: phraseListsOpen,
194
+ timeout: "auto",
195
+ unmountOnExit: true,
196
+ children: /*#__PURE__*/_jsx(Box, {
197
+ ml: {
198
+ sm: 0,
199
+ md: 7
200
+ },
201
+ children: /*#__PURE__*/_jsx(AssignmentPhraseListSelection, {
202
+ t: t,
203
+ phraseLists: phraseLists,
204
+ courseSectionTopicId: courseSectionTopicId,
205
+ assignment: assignment,
206
+ useCase: useCase,
207
+ selectedExercises: selectedExercises,
208
+ handleSelectExercise: handleSelectExercise,
209
+ handleRemoveExercise: handleRemoveExercise,
210
+ isPreview: isPreview,
211
+ viewOnly: viewOnly,
212
+ progressHelpers: progressHelpers,
213
+ completionHelpers: completionHelpers,
214
+ username: username,
215
+ preferred_username: preferred_username,
216
+ isCreator: isCreator
217
+ })
218
+ })
247
219
  }), name.toLowerCase() === "roleplays" && /*#__PURE__*/_jsx(Collapse, {
248
220
  in: roleplaysOpen,
249
221
  timeout: "auto",
@@ -323,6 +295,7 @@ function ExerciseList({
323
295
  handleStartExercise,
324
296
  isCreator,
325
297
  progressHelpers,
298
+ completionHelpers,
326
299
  memberCourseCompletions,
327
300
  username,
328
301
  preferred_username,
@@ -330,6 +303,7 @@ function ExerciseList({
330
303
  completion,
331
304
  handleRemoveExercise,
332
305
  isPreview,
306
+ phraseLists,
333
307
  ...otherProps
334
308
  }) {
335
309
  const courseSectionTopicId = `${courseId}|${sectionId}|${topicId}`;
@@ -362,11 +336,13 @@ function ExerciseList({
362
336
  username: username,
363
337
  preferred_username: preferred_username,
364
338
  progressHelpers: progressHelpers,
339
+ completionHelpers: completionHelpers,
365
340
  memberCourseCompletions: memberCourseCompletions,
366
341
  lastClickedExerciseId: lastClickedExerciseId,
367
342
  completion: completion,
368
343
  handleRemoveExercise: handleRemoveExercise,
369
344
  isPreview: isPreview,
345
+ phraseLists: phraseLists,
370
346
  ...otherProps
371
347
  }, keyId);
372
348
  })
@@ -398,12 +374,11 @@ function Topic({
398
374
  username,
399
375
  preferred_username,
400
376
  progressHelpers,
377
+ completionHelpers,
401
378
  memberCourseCompletions,
402
379
  lastClickedExerciseId,
403
380
  completion,
404
381
  viewOnly,
405
- getRoleplays,
406
- getBots,
407
382
  handleRemoveExercise,
408
383
  isPreview,
409
384
  isChallengeModeStudent,
@@ -413,6 +388,17 @@ function Topic({
413
388
  const isLargeScreen = useMediaQuery(theme.breakpoints.up("sm"));
414
389
  const topicRef = useRef(null);
415
390
  const numOfIds = lastClickedExerciseId ? lastClickedExerciseId.split("|") : [];
391
+ const phraseListsQuery = courseQuerys.useCourseSectionTopicPhraseLists(undefined, {
392
+ courseId,
393
+ sectionId,
394
+ topicId,
395
+ filters: {
396
+ returnvalues: "phrases"
397
+ }
398
+ }, {
399
+ enabled: !!courseId && !!sectionId && !!topicId
400
+ });
401
+ const phraseLists = phraseListsQuery.isSuccess && phraseListsQuery.data && Array.isArray(phraseListsQuery.data.Items) ? phraseListsQuery.data.Items.filter(pl => pl.phrases && pl.phrases.length > 0) : [];
416
402
 
417
403
  // Define a single variable for clarity
418
404
  const matchesLastClickedExercise = lastClickedExerciseId && (numOfIds.length === 4 && lastClickedExerciseId.endsWith(`|${assignment.assignmentId}`) && numOfIds[2] === topicId || numOfIds.length === 5 && numOfIds[3] === assignment.assignmentId && numOfIds[2] === topicId);
@@ -431,22 +417,13 @@ function Topic({
431
417
  });
432
418
  }
433
419
  }, [matchesLastClickedExercise, topicRef]);
434
- const currentTopic = (section?.topics || []).find(t => t.topicId === topicId) || {};
435
- const hidden = new Set((currentTopic.hiddenExercises || []).map(x => String(x).toLowerCase()));
436
- const baseRegular = [{
437
- name: "translation",
438
- description: "translation_exercise_desc"
439
- }, {
440
- name: "listening",
441
- description: "listening_exercise_desc"
442
- }, {
443
- name: "pronunciation",
444
- description: "pronunciation_exercise_desc"
445
- }].filter(e => !hidden.has(e.name));
446
420
  let exercises;
447
421
  switch (useCase) {
448
422
  case "assignment-select":
449
- exercises = [...baseRegular, {
423
+ exercises = [{
424
+ name: "phrases",
425
+ description: "phrases_exercise_desc"
426
+ }, {
450
427
  name: "roleplays",
451
428
  description: "roleplay_exercise_desc"
452
429
  }, {
@@ -455,23 +432,28 @@ function Topic({
455
432
  }];
456
433
  break;
457
434
  case "assignment-view":
458
- exercises = [...baseRegular, {
435
+ exercises = [{
436
+ name: "phrases",
437
+ description: "phrases_exercise_desc"
438
+ }, {
459
439
  name: "roleplays",
460
440
  description: "roleplay_exercise_desc"
461
441
  }, {
462
442
  name: "bots",
463
443
  description: "chatbot_exercise_desc"
464
- }].filter(exercise => selectedExercises?.some(e => e.name === exercise.name || exercise.name === "roleplays" && e.roleplayId || exercise.name === "bots" && e.botId));
444
+ }].filter(exercise => selectedExercises?.some(e => e.name === exercise.name || exercise.name === "roleplays" && e.roleplayId || exercise.name === "bots" && e.botId || exercise.name === "phrases" && e.phraseListId));
465
445
  break;
466
446
  case "assignment-start":
467
- exercises = [...baseRegular, {
447
+ exercises = [{
448
+ name: "phrases",
449
+ description: "phrases_exercise_desc"
450
+ }, {
468
451
  name: "roleplays",
469
452
  description: "roleplay_exercise_desc"
470
453
  }, {
471
454
  name: "bots",
472
455
  description: "chatbot_exercise_desc"
473
- }].filter(exercise => selectedExercises?.some(e => e.name === exercise.name || exercise.name === "roleplays" && e.roleplayId || exercise.name === "bots" && e.botId));
474
- exercises = exercises.filter(ex => !["translation", "listening", "pronunciation"].includes(ex.name) || !hidden.has(ex.name));
456
+ }].filter(exercise => selectedExercises?.some(e => e.name === exercise.name || exercise.name === "roleplays" && e.roleplayId || exercise.name === "bots" && e.botId || exercise.name === "phrases" && e.phraseListId));
475
457
  break;
476
458
  default:
477
459
  exercises = [];
@@ -488,17 +470,21 @@ function Topic({
488
470
  games = ["roleplay-story", "roleplay-fill-in-the-blanks", "roleplay-act-it-out", "roleplay-act-it-out-listening", "roleplay-act-it-out-speaking", "roleplay-act-it-out-listening-speaking"];
489
471
  }
490
472
  useEffect(() => {
491
- const expectedRegularCount = exercises?.filter(e => e.name !== "roleplays" && !selectedExercises?.some(sel => sel.name === e.name && sel.courseSectionTopicId === `${courseId}|${sectionId}|${topicId}`)).length || 0;
492
473
  const expectedRoleplayCount = roleplays?.length * games?.length || 0;
493
474
  const expectedBotCount = bots?.length || 0;
494
- const totalExpected = (exercises?.filter(e => e.name !== "roleplays").length || 0) + expectedRoleplayCount + expectedBotCount;
495
- const regularNames = new Set(baseRegular.map(e => e.name));
496
- const selectedRegular = selectedExercises?.filter(e => e.courseSectionTopicId === courseSectionTopicId && !e.roleplayId && !e.botId && regularNames.has(e.name)).length || 0;
475
+ const expectedPhraseListCount = phraseLists?.reduce((total, pl) => {
476
+ const hasDefinitions = pl.phrases?.some(p => p.definitions?.length > 0);
477
+ const hidden = new Set(Object.entries(pl.hiddenPhraseGroupGames || {}).filter(([, v]) => v).map(([k]) => String(k).toLowerCase()));
478
+ const plGames = ["translation", "listening", "pronunciation", ...(hasDefinitions ? ["meaning"] : [])].filter(g => !hidden.has(g));
479
+ return total + plGames.length;
480
+ }, 0) || 0;
481
+ const totalExpected = expectedRoleplayCount + expectedBotCount + expectedPhraseListCount;
497
482
  const selectedRoleplays = selectedExercises?.filter(exercise => exercise.roleplayId && roleplays?.some(roleplay => roleplay.roleplayId === exercise.roleplayId)).length || 0;
498
483
  const selectedBots = selectedExercises?.filter(exercise => exercise.botId && bots?.some(bot => bot.botId === exercise.botId)).length || 0;
499
- const totalSelected = selectedRegular + selectedRoleplays + selectedBots;
484
+ const selectedPhraseLists = selectedExercises?.filter(exercise => exercise.phraseListId && phraseLists?.some(pl => pl.phraseListId === exercise.phraseListId)).length || 0;
485
+ const totalSelected = selectedRoleplays + selectedBots + selectedPhraseLists;
500
486
  setIsWholeTopicSelected(totalSelected === totalExpected);
501
- }, [selectedExercises, exercises, roleplays, bots, courseId, sectionId, topicId, games]);
487
+ }, [selectedExercises, exercises, roleplays, bots, phraseLists, courseId, sectionId, topicId, games]);
502
488
  const handleSelectAll = () => {
503
489
  const isAllSelected = selectedCount === totalCount;
504
490
  if (isAllSelected) {
@@ -506,14 +492,6 @@ function Topic({
506
492
  handleSelectExercise(removeExercises);
507
493
  } else {
508
494
  let exercisesToAdd = [];
509
- baseRegular.forEach(exercise => {
510
- if (!selectedExercises?.some(e => e.courseSectionTopicId === courseSectionTopicId && e.name === exercise.name)) {
511
- exercisesToAdd.push({
512
- courseSectionTopicId,
513
- name: exercise.name
514
- });
515
- }
516
- });
517
495
  roleplays.forEach(roleplay => {
518
496
  games.forEach(name => {
519
497
  if (!selectedExercises?.some(e => e.roleplayId === roleplay.roleplayId && e.name === name)) {
@@ -534,6 +512,20 @@ function Topic({
534
512
  });
535
513
  }
536
514
  });
515
+ phraseLists?.forEach(pl => {
516
+ const hasDefinitions = pl.phrases?.some(p => p.definitions?.length > 0);
517
+ const hidden = new Set(Object.entries(pl.hiddenPhraseGroupGames || {}).filter(([, v]) => v).map(([k]) => String(k).toLowerCase()));
518
+ const plGames = ["translation", "listening", "pronunciation", ...(hasDefinitions ? ["meaning"] : [])].filter(g => !hidden.has(g));
519
+ plGames.forEach(gameName => {
520
+ if (!selectedExercises?.some(e => e.phraseListId === pl.phraseListId && e.name === gameName)) {
521
+ exercisesToAdd.push({
522
+ phraseListId: pl.phraseListId,
523
+ name: gameName,
524
+ courseSectionTopicId: courseSectionTopicId
525
+ });
526
+ }
527
+ });
528
+ });
537
529
  handleSelectExercise(exercisesToAdd);
538
530
  }
539
531
  };
@@ -542,14 +534,19 @@ function Topic({
542
534
  };
543
535
  const hasNonEmptyRoleplay = roleplays?.some(roleplay => roleplay?.script?.length !== 0 && roleplay?.script?.some(line => line.text !== undefined));
544
536
  const courseSectionTopicId = `${courseId}|${sectionId}|${topicId}`;
545
- const selectedRegular = selectedExercises?.filter(e => e.courseSectionTopicId === courseSectionTopicId && !e.roleplayId && !e.botId && e.name !== "roleplays" && e.name !== "bots").length || 0;
546
537
  const selectedRoleplays = selectedExercises?.filter(e => e.courseSectionTopicId === courseSectionTopicId && e.roleplayId).length || 0;
547
538
  const selectedBots = selectedExercises?.filter(e => e.courseSectionTopicId === courseSectionTopicId && e.botId).length || 0;
548
- const selectedCount = selectedRegular + selectedRoleplays + selectedBots;
549
- const totalRegular = baseRegular.length;
539
+ const selectedPhraseLists = selectedExercises?.filter(e => e.courseSectionTopicId === courseSectionTopicId && e.phraseListId).length || 0;
540
+ const selectedCount = selectedRoleplays + selectedBots + selectedPhraseLists;
550
541
  const totalRoleplays = (roleplays?.length || 0) * (games?.length || 0);
551
542
  const totalBots = bots?.length || 0;
552
- const totalCount = totalRegular + totalRoleplays + totalBots;
543
+ const totalPhraseLists = phraseLists?.reduce((total, pl) => {
544
+ const hasDefinitions = pl.phrases?.some(p => p.definitions?.length > 0);
545
+ const hidden = new Set(Object.entries(pl.hiddenPhraseGroupGames || {}).filter(([, v]) => v).map(([k]) => String(k).toLowerCase()));
546
+ const plGames = ["translation", "listening", "pronunciation", ...(hasDefinitions ? ["meaning"] : [])].filter(g => !hidden.has(g));
547
+ return total + plGames.length;
548
+ }, 0) || 0;
549
+ const totalCount = totalRoleplays + totalBots + totalPhraseLists;
553
550
  const isTopicDisabled = phrases.length === 0 && !hasNonEmptyRoleplay || isExerciseSelected;
554
551
  return /*#__PURE__*/_jsx(_Fragment, {
555
552
  children: /*#__PURE__*/_jsxs(Tooltip, {
@@ -654,7 +651,7 @@ function Topic({
654
651
  children: isExerciseListOpen ? /*#__PURE__*/_jsx(ExpandLessIcon, {}) : /*#__PURE__*/_jsx(ExpandMoreIcon, {})
655
652
  }), useCase === "assignment-select" && /*#__PURE__*/_jsx(ListItemIcon, {
656
653
  children: /*#__PURE__*/_jsx(Checkbox, {
657
- checked: selectedCount === totalCount,
654
+ checked: !isTopicDisabled && selectedCount === totalCount,
658
655
  indeterminate: selectedCount > 0 && selectedCount < totalCount,
659
656
  onClick: event => {
660
657
  event.stopPropagation();
@@ -703,6 +700,7 @@ function Topic({
703
700
  username: username,
704
701
  preferred_username: preferred_username,
705
702
  progressHelpers: progressHelpers,
703
+ completionHelpers: completionHelpers,
706
704
  memberCourseCompletions: memberCourseCompletions,
707
705
  lastClickedExerciseId: lastClickedExerciseId,
708
706
  bots: bots,
@@ -710,7 +708,8 @@ function Topic({
710
708
  completion: completion,
711
709
  handleRemoveExercise: handleRemoveExercise,
712
710
  isPreview: isPreview,
713
- isChallengeModeStudent: isChallengeModeStudent
711
+ isChallengeModeStudent: isChallengeModeStudent,
712
+ phraseLists: phraseLists
714
713
  })
715
714
  })]
716
715
  })
@@ -738,6 +737,7 @@ function Section({
738
737
  username,
739
738
  preferred_username,
740
739
  progressHelpers,
740
+ completionHelpers,
741
741
  memberCourseCompletions,
742
742
  lastClickedExerciseId,
743
743
  completion,
@@ -820,6 +820,7 @@ function Section({
820
820
  username: username,
821
821
  preferred_username: preferred_username,
822
822
  progressHelpers: progressHelpers,
823
+ completionHelpers: completionHelpers,
823
824
  handleRemoveExercise: handleRemoveExercise,
824
825
  isPreview: isPreview,
825
826
  memberCourseCompletions: memberCourseCompletions,
@@ -851,6 +852,7 @@ function Section({
851
852
  username: username,
852
853
  preferred_username: preferred_username,
853
854
  progressHelpers: progressHelpers,
855
+ completionHelpers: completionHelpers,
854
856
  memberCourseCompletions: memberCourseCompletions,
855
857
  isChallengeModeStudent: isChallengeModeStudent
856
858
  }, `${sectionId}-${topic.topicId}`))
@@ -877,6 +879,7 @@ function SectionList({
877
879
  username,
878
880
  preferred_username,
879
881
  progressHelpers,
882
+ completionHelpers,
880
883
  memberCourseCompletions,
881
884
  lastClickedExerciseId,
882
885
  course,
@@ -917,6 +920,7 @@ function SectionList({
917
920
  username: username,
918
921
  preferred_username: preferred_username,
919
922
  progressHelpers: progressHelpers,
923
+ completionHelpers: completionHelpers,
920
924
  memberCourseCompletions: memberCourseCompletions,
921
925
  lastClickedExerciseId: lastClickedExerciseId,
922
926
  course: course,
@@ -954,6 +958,7 @@ function AssignmentExerciseSelection({
954
958
  username,
955
959
  preferred_username,
956
960
  progressHelpers,
961
+ completionHelpers,
957
962
  memberCourseCompletions,
958
963
  lastClickedExerciseId,
959
964
  course,
@@ -984,6 +989,7 @@ function AssignmentExerciseSelection({
984
989
  username: username,
985
990
  preferred_username: preferred_username,
986
991
  progressHelpers: progressHelpers,
992
+ completionHelpers: completionHelpers,
987
993
  memberCourseCompletions: memberCourseCompletions,
988
994
  lastClickedExerciseId: lastClickedExerciseId,
989
995
  course: course,
@@ -1015,6 +1021,7 @@ function AssignmentExerciseSelection({
1015
1021
  username: username,
1016
1022
  preferred_username: preferred_username,
1017
1023
  progressHelpers: progressHelpers,
1024
+ completionHelpers: completionHelpers,
1018
1025
  memberCourseCompletions: memberCourseCompletions,
1019
1026
  lastClickedExerciseId: lastClickedExerciseId,
1020
1027
  course: course,
@@ -16,6 +16,7 @@ function AssignmentExerciseSelector({
16
16
  useCase,
17
17
  preferred_username,
18
18
  progressHelpers,
19
+ completionHelpers,
19
20
  memberCourseCompletions,
20
21
  lastClickedExerciseId,
21
22
  handleRemoveExercise,
@@ -38,6 +39,7 @@ function AssignmentExerciseSelector({
38
39
  useCase: useCase,
39
40
  preferred_username: preferred_username,
40
41
  progressHelpers: progressHelpers,
42
+ completionHelpers: completionHelpers,
41
43
  memberCourseCompletions: memberCourseCompletions,
42
44
  lastClickedExerciseId: lastClickedExerciseId,
43
45
  handleRemoveExercise: handleRemoveExercise,