@nualang/nualang-ui-components 0.1.1387 → 0.1.1393

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 (72) hide show
  1. package/README.md +18 -0
  2. package/dist/Assignments/AssignmentExerciseSelection/AssignmentExerciseSelection.js +3 -3
  3. package/dist/Assignments/CreateAssignmentDialog/CreateAssignmentDialog.js +4 -39
  4. package/dist/Exercises/ListenAndSpeak/ListenAndSpeak.js +963 -0
  5. package/dist/Exercises/Meaning/Meaning.js +5 -3
  6. package/dist/Exercises/MeaningReadWrite/MeaningReadWriteGame.js +725 -0
  7. package/dist/Exercises/PhraseGroup/Games/ListenAndSpeakGame/ListenAndSpeakGame.js +95 -0
  8. package/dist/Exercises/PhraseGroup/Games/MeaningGame/MeaningGame.js +3 -1
  9. package/dist/Exercises/PhraseGroup/Games/MeaningReadWriteGame/MeaningReadWriteGame.js +90 -0
  10. package/dist/Exercises/PhraseGroup/Games/index.js +3 -1
  11. package/dist/Exercises/PhraseGroup/PhraseGroup.js +10 -3
  12. package/dist/Exercises/PhraseGroup/PhraseGroupGameOptions/PhraseGroupGame/PhraseGroupGame.js +21 -5
  13. package/dist/Exercises/PhraseGroup/PhraseGroupGameOptions/PhraseGroupGames.js +8 -2
  14. package/dist/Forms/UpdatePhraseList/UpdatePhraseList.js +49 -2
  15. package/dist/Lists/Exercises/Exercises.js +1 -1
  16. package/dist/Lists/PhraseListSelection/PhraseListSelection.js +15 -0
  17. package/dist/Live/Game/Game.js +18 -0
  18. package/dist/Live/LiveMeaningReadWrite/LiveMeaningReadWrite.js +393 -0
  19. package/dist/Live/WaitingRoom/WaitingRoom.js +7 -1
  20. package/dist/Misc/AnswerResult/AnswerResult.js +104 -15
  21. package/dist/Misc/ExerciseBottomBar/ExerciseBottomBar.js +4 -0
  22. package/dist/Misc/WaveFormLite/WaveFormLite.js +1 -0
  23. package/dist/Screens/Courses/ViewCourse/ViewTopic/ViewTopic.js +3 -1
  24. package/dist/Tables/Progress/ProgressList.js +4 -4
  25. package/dist/Tables/Progress/ProgressTable.js +3 -3
  26. package/dist/Tables/Progress/constants.js +4 -0
  27. package/dist/hooks/useExerciseState.js +83 -18
  28. package/package.json +28 -21
  29. package/dist/Dialogs/SelectCourses/SelectCourses.js +0 -27
  30. package/dist/Dialogs/SelectCourses/SelectCourses.test.js +0 -30
  31. package/dist/Dialogs/SelectCourses/package.json +0 -6
  32. package/dist/Screens/Activity/Activity.js +0 -894
  33. package/dist/Screens/Activity/Exercise/Attempt/Attempt.js +0 -1019
  34. package/dist/Screens/Activity/Exercise/Attempt/package.json +0 -6
  35. package/dist/Screens/Activity/Exercise/Exercise.js +0 -868
  36. package/dist/Screens/Activity/Exercise/package.json +0 -6
  37. package/dist/Screens/Activity/package.json +0 -6
  38. package/dist/Screens/Classrooms/Classrooms.js +0 -218
  39. package/dist/Screens/Classrooms/SearchClassrooms/SearchClassrooms.js +0 -277
  40. package/dist/Screens/Classrooms/SearchClassrooms/package.json +0 -6
  41. package/dist/Screens/Classrooms/ViewClassroom/ViewClassroom.js +0 -1829
  42. package/dist/Screens/Classrooms/ViewClassroom/package.json +0 -6
  43. package/dist/Screens/Classrooms/package.json +0 -6
  44. package/dist/Screens/Courses/Courses.js +0 -189
  45. package/dist/Screens/Courses/SearchCourses/SearchCourses.js +0 -343
  46. package/dist/Screens/Courses/SearchCourses/package.json +0 -6
  47. package/dist/Screens/Courses/SearchTopic/SearchTopic.js +0 -169
  48. package/dist/Screens/Courses/SearchTopic/package.json +0 -6
  49. package/dist/Screens/Courses/ViewCourse/ViewTopic/package.json +0 -6
  50. package/dist/Screens/Courses/ViewCourse/package.json +0 -6
  51. package/dist/Screens/Courses/package.json +0 -6
  52. package/dist/Screens/Dashboard/Dashboard.js +0 -323
  53. package/dist/Screens/Dashboard/package.json +0 -6
  54. package/dist/Screens/GenerateAudio/GenerateAudio.js +0 -1474
  55. package/dist/Screens/Library/Library.js +0 -53
  56. package/dist/Screens/Library/package.json +0 -6
  57. package/dist/Screens/Onboard/Onboard.js +0 -126
  58. package/dist/Screens/Onboard/Steps/Benefits.js +0 -136
  59. package/dist/Screens/Onboard/Steps/LanguageSelection.js +0 -94
  60. package/dist/Screens/Onboard/Steps/RoleSelection.js +0 -136
  61. package/dist/Screens/Onboard/Steps/index.js +0 -3
  62. package/dist/Screens/Onboard/package.json +0 -6
  63. package/dist/Screens/Pricing/Pricing.js +0 -156
  64. package/dist/Screens/Pricing/package.json +0 -6
  65. package/dist/Screens/Profile/Profile.js +0 -399
  66. package/dist/Screens/Profile/package.json +0 -6
  67. package/dist/Screens/Roleplays/Roleplays.js +0 -251
  68. package/dist/Screens/Roleplays/ViewRoleplay/ViewRoleplay.js +0 -84
  69. package/dist/Screens/Roleplays/ViewRoleplay/package.json +0 -6
  70. package/dist/Screens/Roleplays/package.json +0 -6
  71. package/dist/Screens/Search/Search.js +0 -276
  72. package/dist/Screens/Search/package.json +0 -6
package/README.md CHANGED
@@ -81,3 +81,21 @@ npm run test:coverage
81
81
  Coverage reports will be written to the `coverage` directory. A text summary is printed to the console;
82
82
  an LCOV file (`coverage/lcov.info`) and a JSON report are also generated. This coverage step is intentionally
83
83
  not wired into CI — run it locally when you want to inspect or publish coverage results.
84
+
85
+ ## Supply-Chain Security
86
+
87
+ This repository uses **pnpm** and enforces a **30-day minimum release-age policy** via `pnpm-workspace.yaml`:
88
+
89
+ ```yaml
90
+ minimumReleaseAge: 43200 # 30 days in minutes
91
+ minimumReleaseAgeExclude:
92
+ - '@nualang/*'
93
+ ```
94
+
95
+ This means `pnpm install` will reject any package version published to the npm registry fewer than 30 days ago. This protects against supply-chain attacks where a compromised maintainer account pushes malicious code.
96
+
97
+ Internal `@nualang/*` packages are excluded from this policy via `minimumReleaseAgeExclude`, so freshly-published internal packages can be installed immediately.
98
+
99
+ ### Package manager
100
+
101
+ This repo uses pnpm. Use `pnpm install`, `pnpm run <script>`, and `pnpm add <package>` instead of npm equivalents. CI uses `pnpm install --frozen-lockfile`.
@@ -466,7 +466,7 @@ function Topic({
466
466
  const expectedPhraseListCount = phraseLists?.reduce((total, pl) => {
467
467
  const hasDefinitions = pl.phrases?.some(p => p.definitions?.length > 0);
468
468
  const hidden = new Set(Object.entries(pl.hiddenPhraseGroupGames || {}).filter(([, v]) => v).map(([k]) => String(k).toLowerCase()));
469
- const plGames = ["translation", "listening", "pronunciation", ...(hasDefinitions ? ["meaning"] : [])].filter(g => !hidden.has(g));
469
+ const plGames = ["translation", "listening", "pronunciation", ...(hasDefinitions ? ["meaning", "meaning-listen-and-speak", "meaning-read-and-write"] : [])].filter(g => !hidden.has(g));
470
470
  return total + plGames.length;
471
471
  }, 0) || 0;
472
472
  const totalExpected = expectedRoleplayCount + expectedBotCount + expectedPhraseListCount;
@@ -506,7 +506,7 @@ function Topic({
506
506
  phraseLists?.forEach(pl => {
507
507
  const hasDefinitions = pl.phrases?.some(p => p.definitions?.length > 0);
508
508
  const hidden = new Set(Object.entries(pl.hiddenPhraseGroupGames || {}).filter(([, v]) => v).map(([k]) => String(k).toLowerCase()));
509
- const plGames = ["translation", "listening", "pronunciation", ...(hasDefinitions ? ["meaning"] : [])].filter(g => !hidden.has(g));
509
+ const plGames = ["translation", "listening", "pronunciation", ...(hasDefinitions ? ["meaning", "meaning-listen-and-speak", "meaning-read-and-write"] : [])].filter(g => !hidden.has(g));
510
510
  plGames.forEach(gameName => {
511
511
  if (!selectedExercises?.some(e => e.phraseListId === pl.phraseListId && e.name === gameName)) {
512
512
  exercisesToAdd.push({
@@ -534,7 +534,7 @@ function Topic({
534
534
  const totalPhraseLists = phraseLists?.reduce((total, pl) => {
535
535
  const hasDefinitions = pl.phrases?.some(p => p.definitions?.length > 0);
536
536
  const hidden = new Set(Object.entries(pl.hiddenPhraseGroupGames || {}).filter(([, v]) => v).map(([k]) => String(k).toLowerCase()));
537
- const plGames = ["translation", "listening", "pronunciation", ...(hasDefinitions ? ["meaning"] : [])].filter(g => !hidden.has(g));
537
+ const plGames = ["translation", "listening", "pronunciation", ...(hasDefinitions ? ["meaning", "meaning-listen-and-speak", "meaning-read-and-write"] : [])].filter(g => !hidden.has(g));
538
538
  return total + plGames.length;
539
539
  }, 0) || 0;
540
540
  const totalCount = totalRoleplays + totalBots + totalPhraseLists;
@@ -45,7 +45,6 @@ export default function CreateAssignmentDialog({
45
45
  createAssignment,
46
46
  username,
47
47
  getMemberDetails,
48
- getClassroom,
49
48
  getCourses,
50
49
  initialData = {},
51
50
  dialogTitle,
@@ -74,45 +73,11 @@ export default function CreateAssignmentDialog({
74
73
  });
75
74
  const [isTitleEdited, setIsTitleEdited] = useState(Boolean(initialData.title));
76
75
  const [isCreating, setIsCreating] = useState(false);
77
- const classroomQuery = useQueries({
78
- queries: (Array.isArray(assignment.classroomId) ? assignment.classroomId : [assignment.classroomId]).map(cId => ({
79
- queryKey: classroomQuerys.classroomKeys.item(cId, username),
80
- queryFn: () => getClassroom(cId, filters),
81
- queryOptions: {
82
- enabled: !!(Array.isArray(assignment.classroomId) ? assignment.classroomId.length > 0 : assignment.classroomId)
83
- }
84
- })),
85
- combine: results => {
86
- const normalizedData = results.map(result => {
87
- const data = result.data;
88
- if (data?.classroomId) {
89
- return data;
90
- }
91
- if (data?.Item?.classroomId) {
92
- return data.Item;
93
- }
94
- return null;
95
- }).filter(Boolean);
96
- return {
97
- data: normalizedData,
98
- pending: results.some(result => result.isPending)
99
- };
100
- }
101
- });
102
76
  const selectedClassroomCourses = useMemo(() => {
103
- if (!classroomQuery.pending && classroomQuery.data.length > 0) {
104
- const allCourses = classroomQuery.data.flatMap(classroom => classroom.courses || []);
105
- const seen = new Set();
106
- const uniqueCourses = allCourses.filter(courseId => {
107
- if (seen.has(courseId)) return false;
108
- seen.add(courseId);
109
- return true;
110
- });
111
- return uniqueCourses;
112
- } else {
113
- return [];
114
- }
115
- }, [classroomQuery.data, classroomQuery.pending]);
77
+ const selectedIds = Array.isArray(assignment.classroomId) ? assignment.classroomId : [assignment.classroomId];
78
+ const allCourses = (classrooms || []).filter(c => selectedIds.includes(c.classroomId)).flatMap(c => c.courses || []);
79
+ return [...new Set(allCourses)];
80
+ }, [classrooms, assignment.classroomId]);
116
81
  const coursesQuery = courseQuerys.useCourses(async filters => {
117
82
  const response = await getCourses(filters);
118
83
  return response;