@nualang/nualang-ui-components 0.1.1253 → 0.1.1255

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.
@@ -176,7 +176,7 @@ function CreateAssignmentDialog({
176
176
  (0, _react.useEffect)(() => {
177
177
  setAssignment(prev => ({
178
178
  ...prev,
179
- assignedStudents: members?.map(member => member.memberId)
179
+ assignedStudents: initialData.assignedStudents?.length ? initialData.assignedStudents : members?.map(member => member.memberId)
180
180
  }));
181
181
  }, [members]);
182
182
  (0, _react.useEffect)(() => {
@@ -87,6 +87,18 @@ function OverflowMenu({
87
87
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
88
88
  children: t("leave_course")
89
89
  })]
90
+ }), classroomId && !isClassroomArchived && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.MenuItem, {
91
+ onClick: () => {
92
+ localStorage.setItem("focusCourseSettings", true);
93
+ window.location.hash = "Settings";
94
+ },
95
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_CardElements.CardMenuIcon, {
96
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Settings.default, {
97
+ fontSize: "small"
98
+ })
99
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
100
+ children: t("change_settings")
101
+ })]
90
102
  }), !isClassroomArchived && /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
91
103
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, {
92
104
  title: !canDuplicateCourse ? t("duplicate_disabled_tooltip") : "",
@@ -117,18 +129,6 @@ function OverflowMenu({
117
129
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
118
130
  children: t("remove_course")
119
131
  })]
120
- }), classroomId && !isClassroomArchived && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.MenuItem, {
121
- onClick: () => {
122
- localStorage.setItem("focusCourseSettings", true);
123
- window.location.hash = "Settings";
124
- },
125
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_CardElements.CardMenuIcon, {
126
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Settings.default, {
127
- fontSize: "small"
128
- })
129
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
130
- children: t("change_settings")
131
- })]
132
132
  })]
133
133
  });
134
134
  }
@@ -8,12 +8,68 @@ var _react = require("react");
8
8
  var _ResponsiveDialog = _interopRequireDefault(require("../ResponsiveDialog/ResponsiveDialog"));
9
9
  var _iconsMaterial = require("@mui/icons-material");
10
10
  var _material = require("@mui/material");
11
+ var _styles = require("@mui/material/styles");
11
12
  var _reactRouterDom = require("react-router-dom");
12
13
  var _Info = _interopRequireDefault(require("@mui/icons-material/Info"));
13
14
  var _NualaCreating = _interopRequireDefault(require("../../Misc/NualaCreating/NualaCreating"));
14
15
  var _InputHelper = _interopRequireDefault(require("../../Forms/InputHelper/InputHelper"));
16
+ var _mui = require("tss-react/mui");
15
17
  var _jsxRuntime = require("react/jsx-runtime");
16
18
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
+ const useStyles = (0, _mui.makeStyles)()(theme => ({
20
+ phraseText: {
21
+ width: "80%",
22
+ wordBreak: "break-all"
23
+ },
24
+ phraseTextSmall: {
25
+ width: "60%",
26
+ wordBreak: "break-all"
27
+ },
28
+ avatar: {
29
+ cursor: "pointer",
30
+ margin: theme.spacing()
31
+ },
32
+ avatarNoClick: {
33
+ margin: theme.spacing()
34
+ }
35
+ }));
36
+ function Phrase({
37
+ alternativeVersions,
38
+ translations,
39
+ phrase
40
+ }) {
41
+ const theme = (0, _styles.useTheme)();
42
+ const {
43
+ classes
44
+ } = useStyles();
45
+ const isLargeScreen = (0, _material.useMediaQuery)(theme.breakpoints.up("sm"));
46
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.ListItem, {
47
+ "data-cy": "phrase-list-item",
48
+ children: isLargeScreen ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, {
49
+ container: true,
50
+ sx: {
51
+ width: "100%"
52
+ },
53
+ className: classes.phraseText,
54
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.ListItemText, {
55
+ className: classes.phrases,
56
+ primary: `${phrase}${Array.isArray(alternativeVersions) && alternativeVersions.length ? " - " : ""}${(alternativeVersions || []).join(", ")}`,
57
+ secondary: (translations || []).join(", ")
58
+ })
59
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, {
60
+ container: true,
61
+ sx: {
62
+ width: "100%"
63
+ },
64
+ className: classes.phraseTextSmall,
65
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.ListItemText, {
66
+ className: classes.phrases,
67
+ primary: `${phrase}${Array.isArray(alternativeVersions) && alternativeVersions.length ? " - " : ""}${(alternativeVersions || []).join(", ")}`,
68
+ secondary: (translations || []).join(", ")
69
+ })
70
+ })
71
+ });
72
+ }
17
73
  function GeneratePhrases({
18
74
  t,
19
75
  open,
@@ -31,6 +87,7 @@ function GeneratePhrases({
31
87
  const [values, setValues] = (0, _react.useState)(initialValues);
32
88
  const [errorMessage, setErrorMessage] = (0, _react.useState)(null);
33
89
  const [phraseType, setPhraseType] = (0, _react.useState)("words");
90
+ const [generatedPhrases, setGeneratedPhrases] = (0, _react.useState)([]);
34
91
  const isPhrases = currentPhrases && currentPhrases.length > 0;
35
92
  const phrases = isPhrases ? currentPhrases.map(({
36
93
  phrase,
@@ -130,22 +187,30 @@ function GeneratePhrases({
130
187
  const phrasesArray = extractPhrasesArray(chatGptResponse);
131
188
  const parsedPhrases = JSON.parse(phrasesArray);
132
189
  if (!validateResponse(parsedPhrases)) {
133
- throw new Error("Invalid response from GPT-3.5");
190
+ throw new Error("Invalid response from GPT-4o-mini");
134
191
  }
135
- handleAppendPhrases(parsedPhrases);
192
+ setGeneratedPhrases(parsedPhrases);
136
193
  setIsGenerating(false);
137
- handleClose();
138
194
  } catch (error) {
139
195
  console.error(error);
140
196
  setIsGenerating(false);
141
197
  setErrorMessage("There was a problem generating phrases. Please try again.");
142
198
  }
143
199
  };
200
+ const handleConfirm = () => {
201
+ handleAppendPhrases(generatedPhrases);
202
+ setGeneratedPhrases([]);
203
+ handleClose();
204
+ };
205
+ const handleCancel = () => {
206
+ setGeneratedPhrases([]);
207
+ handleClose();
208
+ };
144
209
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_ResponsiveDialog.default, {
145
210
  open: open,
146
- handleClose: handleClose,
147
- handleSubmit: handleGeneratePhrases,
148
- submitText: t("generate_phrases"),
211
+ handleClose: handleCancel,
212
+ handleSubmit: generatedPhrases.length > 0 ? handleConfirm : handleGeneratePhrases,
213
+ submitText: generatedPhrases.length > 0 ? t("confirm") : t("generate_phrases"),
149
214
  dialogTitle: isGenerating ? t("generating_phrases") : t("generate_phrases"),
150
215
  isSubmitDisabled: isGenerating,
151
216
  isExperimentalFeature: true,
@@ -170,111 +235,119 @@ function GeneratePhrases({
170
235
  size: 12,
171
236
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.LinearProgress, {})
172
237
  }), !isGenerating && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
173
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
174
- fontSize: 14,
175
- sx: {
176
- opacity: 0.8,
177
- marginBottom: 1
178
- },
179
- children: t("required_field")
180
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, {
181
- size: 12,
182
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Alert, {
183
- severity: "info",
184
- children: [t("experimental_feature_desc_phrases"), " -", " ", /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactRouterDom.Link, {
185
- to: "/contact",
186
- children: [t("contact_form"), "."]
187
- })]
188
- })
189
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, {
190
- size: 12,
191
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_InputHelper.default, {
192
- t: t,
193
- id: "phrasesTopic",
194
- name: "phrasesTopic",
195
- "data-cy": "phrasesTopic",
196
- label: t("choose_topic_for_phrases"),
197
- value: values.phrasesTopic,
198
- type: "text",
199
- margin: "normal",
200
- variant: "outlined",
201
- fullWidth: true,
202
- required: true,
203
- onChange: handleChange,
204
- multiline: true,
205
- rows: 3
206
- })
207
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, {
208
- mb: 2,
209
- size: 12,
210
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TextField, {
211
- id: "topicGoal",
212
- name: "topicGoal",
213
- "data-cy": "topicGoal",
214
- label: t("topic_goal"),
215
- placeholder: t("topic_goal_placeholder"),
216
- value: values.topicGoal,
217
- type: "text",
218
- margin: "normal",
219
- variant: "outlined",
220
- fullWidth: true,
221
- onChange: handleChange,
222
- InputProps: {
223
- endAdornment: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputAdornment, {
224
- position: "end",
225
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, {
226
- title: t("topic_goal_info_text"),
227
- placement: "top",
228
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Info.default, {
229
- fontSize: "small",
230
- style: {
231
- color: "lightgrey"
232
- }
238
+ children: [generatedPhrases.length === 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
239
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
240
+ fontSize: 14,
241
+ sx: {
242
+ opacity: 0.8,
243
+ marginBottom: 1
244
+ },
245
+ children: t("required_field")
246
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, {
247
+ size: 12,
248
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Alert, {
249
+ severity: "info",
250
+ children: [t("experimental_feature_desc_phrases"), " -", " ", /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactRouterDom.Link, {
251
+ to: "/contact",
252
+ children: [t("contact_form"), "."]
253
+ })]
254
+ })
255
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, {
256
+ size: 12,
257
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_InputHelper.default, {
258
+ t: t,
259
+ id: "phrasesTopic",
260
+ name: "phrasesTopic",
261
+ "data-cy": "phrasesTopic",
262
+ label: t("choose_topic_for_phrases"),
263
+ value: values.phrasesTopic,
264
+ type: "text",
265
+ margin: "normal",
266
+ variant: "outlined",
267
+ fullWidth: true,
268
+ required: true,
269
+ onChange: handleChange,
270
+ multiline: true,
271
+ rows: 3
272
+ })
273
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, {
274
+ mb: 2,
275
+ size: 12,
276
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.TextField, {
277
+ id: "topicGoal",
278
+ name: "topicGoal",
279
+ "data-cy": "topicGoal",
280
+ label: t("topic_goal"),
281
+ placeholder: t("topic_goal_placeholder"),
282
+ value: values.topicGoal,
283
+ type: "text",
284
+ margin: "normal",
285
+ variant: "outlined",
286
+ fullWidth: true,
287
+ onChange: handleChange,
288
+ InputProps: {
289
+ endAdornment: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.InputAdornment, {
290
+ position: "end",
291
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, {
292
+ title: t("topic_goal_info_text"),
293
+ placement: "top",
294
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Info.default, {
295
+ fontSize: "small",
296
+ style: {
297
+ color: "lightgrey"
298
+ }
299
+ })
233
300
  })
234
301
  })
302
+ }
303
+ })
304
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, {
305
+ mb: 2,
306
+ size: 12,
307
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TextField, {
308
+ select: true,
309
+ label: t("phrase_type"),
310
+ value: phraseType,
311
+ onChange: e => setPhraseType(e.target.value),
312
+ fullWidth: true,
313
+ variant: "outlined",
314
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, {
315
+ value: "words",
316
+ children: t("words")
317
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, {
318
+ value: "sentences",
319
+ children: t("sentences")
320
+ })]
321
+ })
322
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Grid, {
323
+ size: 12,
324
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
325
+ id: "input-slider",
326
+ gutterBottom: true,
327
+ children: t("how_many_phrases", {
328
+ phraseAmount: values.phraseAmount
235
329
  })
236
- }
237
- })
238
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, {
239
- mb: 2,
240
- size: 12,
241
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.TextField, {
242
- select: true,
243
- label: t("phrase_type"),
244
- value: phraseType,
245
- onChange: e => setPhraseType(e.target.value),
246
- fullWidth: true,
247
- variant: "outlined",
248
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, {
249
- value: "words",
250
- children: t("words")
251
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, {
252
- value: "sentences",
253
- children: t("sentences")
330
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Slider, {
331
+ "aria-label": "Number of phrases",
332
+ defaultValue: values.phraseAmount,
333
+ valueLabelDisplay: "auto",
334
+ value: values.phraseAmount,
335
+ onChange: (e, value) => setValues({
336
+ ...values,
337
+ phraseAmount: value
338
+ }),
339
+ step: 2,
340
+ marks: true,
341
+ min: 4,
342
+ max: 16
254
343
  })]
255
- })
256
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Grid, {
257
- size: 12,
258
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
259
- id: "input-slider",
260
- gutterBottom: true,
261
- children: t("how_many_phrases", {
262
- phraseAmount: values.phraseAmount
263
- })
264
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Slider, {
265
- "aria-label": "Number of phrases",
266
- defaultValue: values.phraseAmount,
267
- valueLabelDisplay: "auto",
268
- value: values.phraseAmount,
269
- onChange: (e, value) => setValues({
270
- ...values,
271
- phraseAmount: value
272
- }),
273
- step: 2,
274
- marks: true,
275
- min: 4,
276
- max: 16
277
344
  })]
345
+ }), generatedPhrases.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
346
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
347
+ children: t("generated_phrases")
348
+ }), generatedPhrases.map((phrase, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(Phrase, {
349
+ ...phrase
350
+ }, index))]
278
351
  }), errorMessage && /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Grid, {
279
352
  mt: 2,
280
353
  size: 12,
@@ -127,7 +127,7 @@ function CourseSettings({
127
127
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.FormControlLabel, {
128
128
  value: "collaborators",
129
129
  control: /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Radio, {}),
130
- label: t("collaborators"),
130
+ label: t("collaborators_only"),
131
131
  disabled: duplicated
132
132
  })]
133
133
  })]
@@ -143,7 +143,7 @@ function UpdateCourse({
143
143
  enrolmentKey,
144
144
  allowedDomains,
145
145
  collaborators,
146
- isShareable,
146
+ isShareable: isShareable ?? "collaborators",
147
147
  duplicated
148
148
  },
149
149
  enableReinitialize: enableReinitialize,
@@ -346,10 +346,10 @@ function AssignmentCellData({
346
346
  if (filter === "percentage_complete" && data.percentComplete) {
347
347
  cellData = data.percentComplete;
348
348
  cellData.type = "percent";
349
- } else if (filter === "correct_answer_percentage" && data.percentCorrect) {
349
+ } else if (filter === "correct_answer_percentage" && data.percentCorrect !== null) {
350
350
  cellData = data.percentCorrect;
351
351
  cellData.type = "correct";
352
- } else if (filter === "avg_pronunciation_score" && data.avgPronunciationScore) {
352
+ } else if (filter === "avg_pronunciation_score" && data.avgPronunciationScore !== null) {
353
353
  cellData = data.avgPronunciationScore;
354
354
  cellData.type = "avgPronuc";
355
355
  }
@@ -89,25 +89,16 @@ const formatMemberCourseCompletions = (courses = [], completions = [], assignmen
89
89
  };
90
90
  exports.formatMemberCourseCompletions = formatMemberCourseCompletions;
91
91
  const formatMemberAssignmentCompletions = (assignments = [], courses = [], completions = []) => {
92
- const stats = assignments.reduce((obj, v) => {
93
- const assignmentCourseCompletions = formatMemberCourseCompletions(courses, completions, v?.exercises);
94
- const result = Object.values(assignmentCourseCompletions).reduce((a, course) => {
95
- if (a && course && course.percentComplete) {
96
- a.percentComplete.completed += course.percentComplete.completed;
97
- a.percentComplete.total += course.percentComplete.total;
98
- a.percentComplete.percentage = Math.floor(a.percentComplete.completed / a.percentComplete.total * 100);
99
- }
100
- if (a && course && course.percentCorrect) {
101
- a.percentCorrect.completed += course.percentCorrect.completed;
102
- a.percentCorrect.total += course.percentCorrect.total;
103
- a.percentCorrect.percentage = Math.floor(a.percentCorrect.completed / a.percentCorrect.total * 100);
104
- }
105
- if (a && course && course.avgPronunciationScore && course.avgPronunciationScore.percentage > 0) {
106
- a.avgPronunciationScore.total += 1;
107
- a.avgPronunciationScore.percentage = Math.floor(course.avgPronunciationScore.percentage / a.avgPronunciationScore.total);
108
- }
109
- return a;
110
- }, {
92
+ const stats = assignments.reduce((obj, assignment) => {
93
+ const assignmentCompletions = completions.filter(completion => assignment.exercises?.some(e => {
94
+ if (e.name && completion.exercise !== e.name) return false;
95
+ if (e.roleplayId && completion.roleplayId !== e.roleplayId) return false;
96
+ if (e.botId && completion.botId !== e.botId) return false;
97
+ if (e.courseSectionTopicId && `${completion.courseSectionId}|${completion.topicId}` !== e.courseSectionTopicId) return false;
98
+ return true;
99
+ }));
100
+ const assignmentCourseCompletions = formatMemberCourseCompletions(courses, assignmentCompletions, assignment?.exercises);
101
+ const accumulator = {
111
102
  percentComplete: {
112
103
  completed: 0,
113
104
  total: 0,
@@ -120,10 +111,35 @@ const formatMemberAssignmentCompletions = (assignments = [], courses = [], compl
120
111
  },
121
112
  avgPronunciationScore: {
122
113
  total: 0,
114
+ sum: 0,
123
115
  percentage: 0
124
116
  }
117
+ };
118
+ Object.values(assignmentCourseCompletions).forEach(course => {
119
+ if (course?.percentComplete) {
120
+ accumulator.percentComplete.completed += course.percentComplete.completed || 0;
121
+ accumulator.percentComplete.total += course.percentComplete.total || 0;
122
+ }
123
+ if (course?.percentCorrect) {
124
+ accumulator.percentCorrect.completed += course.percentCorrect.completed || 0;
125
+ accumulator.percentCorrect.total += course.percentCorrect.total || 0;
126
+ }
127
+ if (course?.avgPronunciationScore && course.avgPronunciationScore.percentage >= 0) {
128
+ accumulator.avgPronunciationScore.total += 1;
129
+ accumulator.avgPronunciationScore.sum += course.avgPronunciationScore.percentage;
130
+ }
125
131
  });
126
- obj[v.assignmentId] = result;
132
+ if (accumulator.percentComplete.total > 0) {
133
+ accumulator.percentComplete.percentage = Math.floor(accumulator.percentComplete.completed / accumulator.percentComplete.total * 100);
134
+ }
135
+ if (accumulator.percentCorrect.total > 0) {
136
+ accumulator.percentCorrect.percentage = Math.floor(accumulator.percentCorrect.completed / accumulator.percentCorrect.total * 100);
137
+ }
138
+ if (accumulator.avgPronunciationScore.total > 0) {
139
+ accumulator.avgPronunciationScore.percentage = Math.floor(accumulator.avgPronunciationScore.sum / accumulator.avgPronunciationScore.total);
140
+ }
141
+ delete accumulator.avgPronunciationScore.sum;
142
+ obj[assignment.assignmentId] = accumulator;
127
143
  return obj;
128
144
  }, {});
129
145
  return stats;
@@ -144,7 +144,15 @@ const getScoreValues = (type, id, completions) => {
144
144
  percentCorrect.total = totalAnswers;
145
145
  percentCorrect.percentage = totalAnswers > 0 ? Math.floor(totalAnswersCorrect / totalAnswers * 100) : 0;
146
146
  const avgPronunciationScore = pronunciationScoreCount > 0 ? Math.floor(totalPronunciationScore / pronunciationScoreCount) : -1;
147
- return [percentCorrect, avgPronunciationScore];
147
+ if (totalAnswers > 0) {
148
+ return [percentCorrect, avgPronunciationScore];
149
+ } else {
150
+ return [{
151
+ completed: 0,
152
+ total: 0,
153
+ percentage: 0
154
+ }, avgPronunciationScore];
155
+ }
148
156
  };
149
157
  exports.getScoreValues = getScoreValues;
150
158
  const calcTopicCompletions = (topic, completions = [], isSectionHidden, assignmentExercises) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nualang/nualang-ui-components",
3
- "version": "0.1.1253",
3
+ "version": "0.1.1255",
4
4
  "main": "dist/index.js",
5
5
  "files": [
6
6
  "dist",