@nualang/nualang-ui-components 0.1.1353 → 0.1.1355
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Dialogs/CreatePhrase/CreatePhrase.js +43 -0
- package/dist/Dialogs/CreatePhraseGroupDialog/CreatePhraseGroupDialog.js +1 -6
- package/dist/Dialogs/GeneratePhrases/GeneratePhrases.js +27 -62
- package/dist/Dialogs/GroupedFeedbackDialog/GroupedFeedbackDialog.js +146 -47
- package/dist/Dialogs/GroupedFeedbackDialog/package.json +6 -0
- package/dist/Editors/PhraseList/PhraseList.js +42 -40
- package/dist/Editors/Phrases/Phrases.js +24 -10
- package/dist/Exercises/Meaning/Meaning.js +788 -0
- package/dist/Exercises/PhraseGroup/Games/MeaningGame/MeaningGame.js +86 -0
- package/dist/Exercises/PhraseGroup/Games/index.js +2 -1
- package/dist/Exercises/PhraseGroup/PhraseGroup.js +6 -3
- package/dist/Exercises/PhraseGroup/PhraseGroupGameOptions/PhraseGroupGame/PhraseGroupGame.js +104 -84
- package/dist/Exercises/PhraseGroup/PhraseGroupGameOptions/PhraseGroupGames.js +2 -0
- package/dist/Exercises/PhraseGroup/PhraseGroupInfo/PhraseGroupInfo.js +22 -32
- package/dist/Exercises/Roleplay/Roleplay.js +2 -1
- package/dist/Exercises/Roleplay/RoleplayGameOptions/RoleplayGames.js +11 -4
- package/dist/Forms/CreateRoleplay/Steps/RoleplaySettings/RoleplaySettings.js +5 -2
- package/dist/Forms/UpdatePhraseList/UpdatePhraseList.js +8 -0
- package/dist/Forms/UpdateRoleplay/UpdateRoleplay.js +2 -1
- package/dist/Lists/Phrases/Phrases.js +16 -0
- package/dist/Misc/PhraseDisplay/PhraseDisplay.js +123 -0
- package/dist/Navigation/Breadcrumbs/Breadcrumbs.js +13 -16
- package/dist/Screens/Activity/Exercise/Attempt/Attempt.js +1 -1
- package/dist/Screens/Classrooms/ViewClassroom/ViewClassroom.js +6 -2
- package/dist/Screens/Courses/ViewCourse/ViewTopic/ViewTopic.js +94 -104
- package/dist/Tables/Attempt/Attempt.js +2 -2
- package/dist/Tables/Progress/Progress.js +33 -2
- package/dist/Tables/Progress/ProgressList.js +94 -5
- package/dist/Tables/Progress/ProgressTable.js +103 -3
- package/dist/Tables/Progress/ProgressTableRow.js +17 -4
- package/dist/Tables/Progress/cells/index.js +44 -0
- package/dist/Tables/Progress/useProgressUrlParams.js +18 -2
- package/dist/Tables/Progress/viewState.js +5 -3
- package/dist/hooks/useExerciseState.js +24 -4
- package/package.json +1 -1
|
@@ -56,6 +56,7 @@ function CreatePhrase({
|
|
|
56
56
|
validatePhraseRecognition,
|
|
57
57
|
verificationStatus,
|
|
58
58
|
makeChatGptApiRequest,
|
|
59
|
+
difficulty,
|
|
59
60
|
...otherProps
|
|
60
61
|
}) {
|
|
61
62
|
const translationInputRef = useRef();
|
|
@@ -78,6 +79,7 @@ function CreatePhrase({
|
|
|
78
79
|
const [definition, setDefinition] = useState("");
|
|
79
80
|
const [definitionList, setDefinitionList] = useState(otherProps.definitions || []);
|
|
80
81
|
const [autoTranslatedText, setAutoTranslatedText] = useState(false);
|
|
82
|
+
const [autoGeneratedDefinitions, setAutoGeneratedDefinitions] = useState(false);
|
|
81
83
|
const [checkingRecogniton, setCheckingRecogniton] = useState(false);
|
|
82
84
|
const [recognised, setRecognised] = useState(false);
|
|
83
85
|
const [notRecognised, setNotRecognised] = useState(false);
|
|
@@ -287,6 +289,39 @@ function CreatePhrase({
|
|
|
287
289
|
setIsSubmitting(false);
|
|
288
290
|
}
|
|
289
291
|
};
|
|
292
|
+
const generateDefinitions = async () => {
|
|
293
|
+
try {
|
|
294
|
+
setIsSubmitting(true);
|
|
295
|
+
let chatGptResponse = await makeChatGptApiRequest({
|
|
296
|
+
model: "gpt-4o",
|
|
297
|
+
promptKey: "generateDefinitions",
|
|
298
|
+
promptVariables: {
|
|
299
|
+
learnLang,
|
|
300
|
+
forLang,
|
|
301
|
+
siteLanguage,
|
|
302
|
+
difficulty,
|
|
303
|
+
phrases: [{
|
|
304
|
+
phrase,
|
|
305
|
+
translations: translationList
|
|
306
|
+
}],
|
|
307
|
+
generateDefinitions: true
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
const definitions = chatGptResponse?.result?.[0]?.definitions;
|
|
311
|
+
if (!validateResponse(definitions)) {
|
|
312
|
+
throw new Error("Invalid AI response");
|
|
313
|
+
}
|
|
314
|
+
setAutoGeneratedDefinitions(definitions[0]);
|
|
315
|
+
setDefinitionList(prevDefinitionList => {
|
|
316
|
+
const newDefinitions = definitions.filter(text => !prevDefinitionList.includes(text));
|
|
317
|
+
return [...prevDefinitionList, ...newDefinitions];
|
|
318
|
+
});
|
|
319
|
+
} catch (error) {
|
|
320
|
+
console.error("Error fetching definitions from OpenAI:", error.message);
|
|
321
|
+
} finally {
|
|
322
|
+
setIsSubmitting(false);
|
|
323
|
+
}
|
|
324
|
+
};
|
|
290
325
|
const handleEditTranslation = (event, index) => {
|
|
291
326
|
const {
|
|
292
327
|
target: {
|
|
@@ -320,6 +355,7 @@ function CreatePhrase({
|
|
|
320
355
|
setDefinitionList([]);
|
|
321
356
|
setSelectedImage(initialSelectedImagestate);
|
|
322
357
|
setAutoTranslatedText("");
|
|
358
|
+
setAutoGeneratedDefinitions("");
|
|
323
359
|
};
|
|
324
360
|
const removePhraseImage = () => {
|
|
325
361
|
setSelectedImage({
|
|
@@ -495,6 +531,13 @@ function CreatePhrase({
|
|
|
495
531
|
className: classes.alternativeVersionButton,
|
|
496
532
|
startIcon: /*#__PURE__*/_jsx(AutoFixHighIcon, {}),
|
|
497
533
|
children: t("auto_generate_phrase_translation")
|
|
534
|
+
}), learnLang !== forLang && /*#__PURE__*/_jsx(DefaultButton, {
|
|
535
|
+
onClick: generateDefinitions,
|
|
536
|
+
disabled: !phrase || Array.isArray(definitionList) && definitionList.includes(autoGeneratedDefinitions),
|
|
537
|
+
size: "sm",
|
|
538
|
+
className: classes.alternativeVersionButton,
|
|
539
|
+
startIcon: /*#__PURE__*/_jsx(AutoFixHighIcon, {}),
|
|
540
|
+
children: t("auto_generate_definitions")
|
|
498
541
|
}), learnLang !== forLang && (import.meta.env.REACT_APP_STAGE === "dev" || window.location.host === "localhost:9009") && /*#__PURE__*/_jsx(Box, {
|
|
499
542
|
sx: {
|
|
500
543
|
display: "inline-flex",
|
|
@@ -6,7 +6,6 @@ import Dialog from "@mui/material/Dialog";
|
|
|
6
6
|
import DialogTitle from "@mui/material/DialogTitle";
|
|
7
7
|
import DialogContent from "@mui/material/DialogContent";
|
|
8
8
|
import DialogActions from "@mui/material/DialogActions";
|
|
9
|
-
import CircularProgress from "@mui/material/CircularProgress";
|
|
10
9
|
import Grid from "@mui/material/Grid";
|
|
11
10
|
import ImageSelector from "../../Forms/ImageSelector/ImageSelector";
|
|
12
11
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -132,11 +131,7 @@ export default function CreatePhraseGroupDialog({
|
|
|
132
131
|
color: "primary",
|
|
133
132
|
variant: "contained",
|
|
134
133
|
disabled: !name.trim() || isLoading,
|
|
135
|
-
|
|
136
|
-
size: 16,
|
|
137
|
-
color: "inherit"
|
|
138
|
-
}) : null,
|
|
139
|
-
children: isLoading ? t("creating") || "Creating..." : t("create") || "Create"
|
|
134
|
+
children: t("create") || "Create"
|
|
140
135
|
})]
|
|
141
136
|
})]
|
|
142
137
|
});
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { useState, useEffect } from "react";
|
|
2
2
|
import ResponsiveDialog from "../ResponsiveDialog/ResponsiveDialog";
|
|
3
3
|
import { AutoFixHigh } from "@mui/icons-material";
|
|
4
|
-
import { Alert, Grid, InputAdornment, LinearProgress, MenuItem, Slider, TextField, Tooltip, Typography, ListItem,
|
|
4
|
+
import { Alert, Grid, InputAdornment, LinearProgress, MenuItem, Slider, TextField, Tooltip, Typography, ListItem, useMediaQuery, FormControlLabel, Switch, Box, List } from "@mui/material";
|
|
5
5
|
import { useTheme } from "@mui/material/styles";
|
|
6
6
|
import { Link } from "react-router";
|
|
7
7
|
import InfoIcon from "@mui/icons-material/Info";
|
|
8
8
|
import NualaCreating from "../../Misc/NualaCreating/NualaCreating";
|
|
9
9
|
import InputHelper from "../../Forms/InputHelper/InputHelper";
|
|
10
|
+
import PhraseDisplay from "../../Misc/PhraseDisplay/PhraseDisplay";
|
|
10
11
|
import { makeStyles } from "tss-react/mui";
|
|
11
12
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
12
13
|
const useStyles = makeStyles()(theme => ({
|
|
@@ -19,80 +20,43 @@ const useStyles = makeStyles()(theme => ({
|
|
|
19
20
|
width: "60%",
|
|
20
21
|
wordBreak: "break-word",
|
|
21
22
|
overflowWrap: "break-word"
|
|
22
|
-
},
|
|
23
|
-
avatar: {
|
|
24
|
-
cursor: "pointer",
|
|
25
|
-
margin: theme.spacing()
|
|
26
|
-
},
|
|
27
|
-
avatarNoClick: {
|
|
28
|
-
margin: theme.spacing()
|
|
29
23
|
}
|
|
30
24
|
}));
|
|
31
25
|
function Phrase({
|
|
32
26
|
alternativeVersions,
|
|
33
27
|
translations,
|
|
34
28
|
definitions,
|
|
35
|
-
phrase
|
|
29
|
+
phrase,
|
|
30
|
+
t
|
|
36
31
|
}) {
|
|
37
32
|
const theme = useTheme();
|
|
38
33
|
const {
|
|
39
34
|
classes
|
|
40
35
|
} = useStyles();
|
|
41
36
|
const isLargeScreen = useMediaQuery(theme.breakpoints.up("sm"));
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
if (Array.isArray(definitions) && definitions.length) {
|
|
50
|
-
secondaryParts.push((definitions || []).join(", "));
|
|
51
|
-
}
|
|
52
|
-
const secondary = secondaryParts.join("\n");
|
|
53
|
-
console.log({
|
|
54
|
-
primary,
|
|
55
|
-
secondary
|
|
56
|
-
});
|
|
57
|
-
console.log("Phrase render", {
|
|
58
|
-
phrase,
|
|
59
|
-
translations,
|
|
60
|
-
definitions,
|
|
61
|
-
alternativeVersions
|
|
62
|
-
});
|
|
63
|
-
return /*#__PURE__*/_jsx(ListItem, {
|
|
64
|
-
"data-cy": "phrase-list-item",
|
|
65
|
-
children: isLargeScreen ? /*#__PURE__*/_jsx(Grid, {
|
|
66
|
-
container: true,
|
|
67
|
-
sx: {
|
|
68
|
-
width: "100%"
|
|
69
|
-
},
|
|
70
|
-
className: classes.phraseText,
|
|
71
|
-
children: /*#__PURE__*/_jsx(ListItemText, {
|
|
72
|
-
className: classes.phrases,
|
|
73
|
-
primary: primary,
|
|
74
|
-
secondary: secondary,
|
|
75
|
-
secondaryTypographyProps: {
|
|
76
|
-
style: {
|
|
77
|
-
whiteSpace: "pre-line"
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
}) : /*#__PURE__*/_jsx(Grid, {
|
|
82
|
-
container: true,
|
|
37
|
+
return /*#__PURE__*/_jsx(List, {
|
|
38
|
+
dense: true,
|
|
39
|
+
disablePadding: true,
|
|
40
|
+
children: /*#__PURE__*/_jsx(ListItem, {
|
|
41
|
+
"data-cy": "phrase-list-item",
|
|
42
|
+
divider: true,
|
|
83
43
|
sx: {
|
|
84
|
-
|
|
44
|
+
flexDirection: "column",
|
|
45
|
+
alignItems: "flex-start",
|
|
46
|
+
py: 2
|
|
85
47
|
},
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
48
|
+
children: /*#__PURE__*/_jsx(Box, {
|
|
49
|
+
className: isLargeScreen ? classes.phraseText : classes.phraseTextSmall,
|
|
50
|
+
children: /*#__PURE__*/_jsx(PhraseDisplay, {
|
|
51
|
+
phrase: phrase,
|
|
52
|
+
translations: translations,
|
|
53
|
+
definitions: definitions,
|
|
54
|
+
alternativeVersions: alternativeVersions,
|
|
55
|
+
t: t,
|
|
56
|
+
variant: "body2",
|
|
57
|
+
showIcons: true,
|
|
58
|
+
showImage: false
|
|
59
|
+
})
|
|
96
60
|
})
|
|
97
61
|
})
|
|
98
62
|
});
|
|
@@ -388,7 +352,8 @@ function GeneratePhrases({
|
|
|
388
352
|
children: [/*#__PURE__*/_jsx(Typography, {
|
|
389
353
|
children: t("generated_phrases")
|
|
390
354
|
}), generatedPhrases.map((phrase, index) => /*#__PURE__*/_jsx(Phrase, {
|
|
391
|
-
...phrase
|
|
355
|
+
...phrase,
|
|
356
|
+
t: t
|
|
392
357
|
}, index))]
|
|
393
358
|
}), errorMessage && /*#__PURE__*/_jsx(Grid, {
|
|
394
359
|
mt: 2,
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import { useMemo, useEffect, useState, useRef, useCallback } from "react";
|
|
2
|
-
import { Dialog, DialogContent, IconButton, Box, Typography, AppBar, Toolbar, CircularProgress, Button, Checkbox, Paper, Divider, Tooltip, Skeleton, Grid } from "@mui/material";
|
|
2
|
+
import { Dialog, DialogContent, IconButton, Box, Typography, AppBar, Toolbar, CircularProgress, Button, Checkbox, Paper, Divider, Tooltip, Skeleton, Grid, TextField, LinearProgress, Alert } from "@mui/material";
|
|
3
|
+
import { Link } from "react-router";
|
|
4
|
+
import MuiLink from "@mui/material/Link";
|
|
3
5
|
import CloseIcon from "@mui/icons-material/Close";
|
|
4
6
|
import { red, orange, green, grey } from "@mui/material/colors";
|
|
5
7
|
import FeedbackCard from "../../Cards/FeedbackCard/FeedbackCard";
|
|
6
8
|
import AutoFixHighIcon from "@mui/icons-material/AutoFixHigh";
|
|
7
9
|
import NualaHeadphonesBackground from "../../img/NualaHeadphonesBackground.svg";
|
|
8
10
|
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
|
|
11
|
+
import { AutoFixHigh } from "@mui/icons-material";
|
|
9
12
|
import useConfirm from "../../hooks/useConfirm";
|
|
10
13
|
import NualaCreating from "../../Misc/NualaCreating/NualaCreating";
|
|
14
|
+
import ResponsiveDialog from "../ResponsiveDialog/ResponsiveDialog";
|
|
15
|
+
import PDFViewer from "../PDFViewer/PDFViewer";
|
|
16
|
+
import level1Rubric from "../PDFViewer/rubrics/level1Rubric.pdf";
|
|
17
|
+
import level2Rubric from "../PDFViewer/rubrics/level2Rubric.pdf";
|
|
18
|
+
import level3Rubric from "../PDFViewer/rubrics/level3Rubric.pdf";
|
|
19
|
+
import level4Rubric from "../PDFViewer/rubrics/level4Rubric.pdf";
|
|
11
20
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
12
21
|
export default function GroupFeedbackDialog({
|
|
13
22
|
open = false,
|
|
@@ -44,7 +53,20 @@ export default function GroupFeedbackDialog({
|
|
|
44
53
|
const [hasReachedBottom, setHasReachedBottom] = useState(false);
|
|
45
54
|
const [isGeneratingAll, setIsGeneratingAll] = useState(false);
|
|
46
55
|
const [isGeneratingIndividual, setIsGeneratingIndividual] = useState(false);
|
|
56
|
+
const [customFeedbackOpen, setCustomFeedbackOpen] = useState(false);
|
|
57
|
+
const [customFeedbackText, setCustomFeedbackText] = useState("");
|
|
58
|
+
const [openPDF, setOpenPDF] = useState(false);
|
|
59
|
+
const [pageNumber, setPageNumber] = useState(1);
|
|
60
|
+
const [scale, setScale] = useState(1);
|
|
47
61
|
const isAnyGenerating = isGeneratingAll || isGeneratingIndividual;
|
|
62
|
+
const pendingGenerateRef = useRef(null);
|
|
63
|
+
const rubricMap = {
|
|
64
|
+
1: level1Rubric,
|
|
65
|
+
2: level2Rubric,
|
|
66
|
+
3: level3Rubric,
|
|
67
|
+
4: level4Rubric
|
|
68
|
+
};
|
|
69
|
+
const pdfUrl = rubricMap[selectedRecording?.level] || level1Rubric;
|
|
48
70
|
const [confirm] = useConfirm(t);
|
|
49
71
|
const bottomRefCallback = useCallback(node => {
|
|
50
72
|
if (node) {
|
|
@@ -59,6 +81,12 @@ export default function GroupFeedbackDialog({
|
|
|
59
81
|
node._observer = observer;
|
|
60
82
|
}
|
|
61
83
|
}, []);
|
|
84
|
+
const handleOpenPDF = () => {
|
|
85
|
+
setOpenPDF(true);
|
|
86
|
+
};
|
|
87
|
+
const handleClosePDF = () => {
|
|
88
|
+
setOpenPDF(false);
|
|
89
|
+
};
|
|
62
90
|
useEffect(() => {
|
|
63
91
|
// dialog is shared between discussions, so reset when teacher selects another discussion
|
|
64
92
|
setGenerateAllUsed(false);
|
|
@@ -69,7 +97,42 @@ export default function GroupFeedbackDialog({
|
|
|
69
97
|
setCanSubmit({});
|
|
70
98
|
setHasReachedBottom(false);
|
|
71
99
|
setIsGeneratingAll(false);
|
|
100
|
+
pendingGenerateRef.current = null;
|
|
72
101
|
}, [groupedId]);
|
|
102
|
+
const openCustomPromptForAll = () => {
|
|
103
|
+
pendingGenerateRef.current = {
|
|
104
|
+
type: "all"
|
|
105
|
+
};
|
|
106
|
+
setCustomFeedbackText("");
|
|
107
|
+
setCustomFeedbackOpen(true);
|
|
108
|
+
};
|
|
109
|
+
const openCustomPromptForSingle = discussionData => {
|
|
110
|
+
pendingGenerateRef.current = {
|
|
111
|
+
type: "single",
|
|
112
|
+
payload: discussionData
|
|
113
|
+
};
|
|
114
|
+
setCustomFeedbackText("");
|
|
115
|
+
setCustomFeedbackOpen(true);
|
|
116
|
+
};
|
|
117
|
+
const handleCustomPromptCancel = () => {
|
|
118
|
+
setCustomFeedbackOpen(false);
|
|
119
|
+
pendingGenerateRef.current = null;
|
|
120
|
+
setCustomFeedbackText("");
|
|
121
|
+
};
|
|
122
|
+
const handleCustomPromptContinue = async () => {
|
|
123
|
+
try {
|
|
124
|
+
const pending = pendingGenerateRef.current;
|
|
125
|
+
pendingGenerateRef.current = null;
|
|
126
|
+
if (!pending) return;
|
|
127
|
+
if (pending.type === "all") {
|
|
128
|
+
await handleGenerateFeedbackForAll();
|
|
129
|
+
} else if (pending.type === "single") {
|
|
130
|
+
await handleGenerateFeedback(pending.payload);
|
|
131
|
+
}
|
|
132
|
+
} finally {
|
|
133
|
+
setCustomFeedbackOpen(false);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
73
136
|
useEffect(() => {
|
|
74
137
|
if (pendingSubmissions === 0 && submitTrigger !== null) {
|
|
75
138
|
setCheckedSubmissions({});
|
|
@@ -137,7 +200,9 @@ export default function GroupFeedbackDialog({
|
|
|
137
200
|
}).filter(member => member.name !== "Unknown");
|
|
138
201
|
};
|
|
139
202
|
const handleGenerateFeedback = async discussionData => {
|
|
140
|
-
if (handleBatchGradeConversations)
|
|
203
|
+
if (!handleBatchGradeConversations) return;
|
|
204
|
+
setIsGeneratingIndividual(true);
|
|
205
|
+
try {
|
|
141
206
|
const joinedMembersWithNames = getJoinedMembersNames(discussionData.joinedMembers || [], userData);
|
|
142
207
|
await handleBatchGradeConversations([{
|
|
143
208
|
meetingId: discussionData.meetingId || discussionData.meetingID,
|
|
@@ -148,8 +213,11 @@ export default function GroupFeedbackDialog({
|
|
|
148
213
|
meetingPrompt: discussionData.meetingPrompt,
|
|
149
214
|
learnLang: learnLang,
|
|
150
215
|
joinedMembers: discussionData.joinedMembers || [],
|
|
151
|
-
joinedMembersNames: joinedMembersWithNames
|
|
216
|
+
joinedMembersNames: joinedMembersWithNames,
|
|
217
|
+
customFeedback: customFeedbackText
|
|
152
218
|
}]);
|
|
219
|
+
} finally {
|
|
220
|
+
setIsGeneratingIndividual(false);
|
|
153
221
|
}
|
|
154
222
|
};
|
|
155
223
|
const handleGenerateFeedbackForAll = async () => {
|
|
@@ -171,7 +239,8 @@ export default function GroupFeedbackDialog({
|
|
|
171
239
|
meetingPrompt: discussion.meetingPrompt || submissionForThisDiscussion.meetingPrompt,
|
|
172
240
|
learnLang: learnLang,
|
|
173
241
|
joinedMembers: submissionForThisDiscussion.joinedMembers || [],
|
|
174
|
-
joinedMembersNames: joinedMembersWithNames
|
|
242
|
+
joinedMembersNames: joinedMembersWithNames,
|
|
243
|
+
customFeedback: customFeedbackText
|
|
175
244
|
};
|
|
176
245
|
});
|
|
177
246
|
if (conversationsToGrade.length > 0 && handleBatchGradeConversations) {
|
|
@@ -478,7 +547,7 @@ export default function GroupFeedbackDialog({
|
|
|
478
547
|
color: "secondary",
|
|
479
548
|
endIcon: /*#__PURE__*/_jsx(AutoFixHighIcon, {}),
|
|
480
549
|
disabled: selectedCount === 0 || isGeneratingAll,
|
|
481
|
-
onClick:
|
|
550
|
+
onClick: openCustomPromptForAll,
|
|
482
551
|
sx: {
|
|
483
552
|
fontWeight: 600
|
|
484
553
|
},
|
|
@@ -528,7 +597,7 @@ export default function GroupFeedbackDialog({
|
|
|
528
597
|
hasSubmission: hasSubmission,
|
|
529
598
|
aiGrade: aiGrade[discussionData.meetingId || discussionData.meetingID] || {},
|
|
530
599
|
existingFeedback: feedbackByMeetingId[feedbackMeetingId] || {},
|
|
531
|
-
onGenerateFeedback: () =>
|
|
600
|
+
onGenerateFeedback: () => openCustomPromptForSingle(discussionData),
|
|
532
601
|
onSubmitFeedback: handleSubmitFeedback,
|
|
533
602
|
setSelectedRecording: setSelectedRecording,
|
|
534
603
|
selectedRecording: selectedRecording,
|
|
@@ -556,53 +625,83 @@ export default function GroupFeedbackDialog({
|
|
|
556
625
|
})]
|
|
557
626
|
})
|
|
558
627
|
})]
|
|
559
|
-
}), /*#__PURE__*/_jsx(
|
|
560
|
-
open:
|
|
628
|
+
}), /*#__PURE__*/_jsx(ResponsiveDialog, {
|
|
629
|
+
open: customFeedbackOpen,
|
|
630
|
+
handleClose: handleCustomPromptCancel,
|
|
631
|
+
handleSubmit: handleCustomPromptContinue,
|
|
632
|
+
submitText: t("generate_feedback"),
|
|
561
633
|
maxWidth: "sm",
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
634
|
+
dialogTitle: isAnyGenerating ? t("generating_feedback") : t("generate_feedback"),
|
|
635
|
+
isSubmitDisabled: isAnyGenerating,
|
|
636
|
+
isExperimentalFeature: true,
|
|
637
|
+
startIcon: /*#__PURE__*/_jsx(AutoFixHigh, {}),
|
|
638
|
+
children: /*#__PURE__*/_jsxs(_Fragment, {
|
|
639
|
+
children: [/*#__PURE__*/_jsx(Grid, {
|
|
640
|
+
textAlign: "center",
|
|
641
|
+
sx: {
|
|
642
|
+
...(!isAnyGenerating && {
|
|
643
|
+
display: "none"
|
|
644
|
+
})
|
|
645
|
+
},
|
|
646
|
+
mx: 2,
|
|
647
|
+
size: 12,
|
|
648
|
+
children: /*#__PURE__*/_jsx(NualaCreating, {})
|
|
649
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
575
650
|
sx: {
|
|
576
|
-
|
|
651
|
+
...(!isAnyGenerating && {
|
|
652
|
+
display: "none"
|
|
653
|
+
})
|
|
577
654
|
},
|
|
578
|
-
|
|
655
|
+
mt: 2,
|
|
656
|
+
size: 12,
|
|
657
|
+
children: /*#__PURE__*/_jsx(LinearProgress, {})
|
|
658
|
+
}), !isAnyGenerating && /*#__PURE__*/_jsxs(Grid, {
|
|
659
|
+
container: true,
|
|
660
|
+
spacing: 2,
|
|
661
|
+
children: [/*#__PURE__*/_jsx(Grid, {
|
|
579
662
|
size: 12,
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
663
|
+
children: /*#__PURE__*/_jsxs(Alert, {
|
|
664
|
+
severity: "info",
|
|
665
|
+
children: [t("experimental_feature_desc"), " - ", " ", /*#__PURE__*/_jsxs(Link, {
|
|
666
|
+
to: "/contact",
|
|
667
|
+
children: [t("contact_form"), "."]
|
|
668
|
+
})]
|
|
669
|
+
})
|
|
670
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
671
|
+
size: {
|
|
672
|
+
xs: 12
|
|
588
673
|
},
|
|
589
|
-
children:
|
|
590
|
-
variant: "
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
674
|
+
children: /*#__PURE__*/_jsxs(Typography, {
|
|
675
|
+
variant: "body2",
|
|
676
|
+
children: [t("generate_feedback_view_the"), " ", /*#__PURE__*/_jsx(MuiLink, {
|
|
677
|
+
component: "button",
|
|
678
|
+
variant: "body2",
|
|
679
|
+
onClick: handleOpenPDF,
|
|
680
|
+
children: t("generate_feedback_rubric_name")
|
|
681
|
+
}), ", ", t("generate_feedback_rubric_desc")]
|
|
682
|
+
})
|
|
683
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
684
|
+
size: 12,
|
|
685
|
+
children: /*#__PURE__*/_jsx(TextField, {
|
|
686
|
+
value: customFeedbackText,
|
|
687
|
+
onChange: e => setCustomFeedbackText(e.target.value),
|
|
688
|
+
placeholder: t("custom_feedback_placeholder"),
|
|
689
|
+
multiline: true,
|
|
690
|
+
minRows: 4,
|
|
691
|
+
fullWidth: true
|
|
692
|
+
})
|
|
693
|
+
})]
|
|
694
|
+
})]
|
|
605
695
|
})
|
|
696
|
+
}), /*#__PURE__*/_jsx(PDFViewer, {
|
|
697
|
+
open: openPDF,
|
|
698
|
+
handleClose: handleClosePDF,
|
|
699
|
+
pdfUrl: pdfUrl,
|
|
700
|
+
pageNumber: pageNumber,
|
|
701
|
+
setPageNumber: setPageNumber,
|
|
702
|
+
scale: scale,
|
|
703
|
+
setScale: setScale,
|
|
704
|
+
t: t
|
|
606
705
|
})]
|
|
607
706
|
});
|
|
608
707
|
}
|
|
@@ -86,7 +86,6 @@ function PhraseList({
|
|
|
86
86
|
isCreatePhraseDialogOpen,
|
|
87
87
|
setIsCreatePhraseDialogOpen,
|
|
88
88
|
handleAddPhrase,
|
|
89
|
-
topicName,
|
|
90
89
|
validatePhraseRecognition,
|
|
91
90
|
difficulty,
|
|
92
91
|
topicGoal,
|
|
@@ -107,12 +106,6 @@ function PhraseList({
|
|
|
107
106
|
const handleChangeTab = (event, newValue) => {
|
|
108
107
|
setTabValue(newValue);
|
|
109
108
|
};
|
|
110
|
-
useEffect(() => {
|
|
111
|
-
if (!isSmallScreen && tabValue === 2) {
|
|
112
|
-
setTabValue(0);
|
|
113
|
-
}
|
|
114
|
-
}, [isSmallScreen]); // Only run when screen changes
|
|
115
|
-
|
|
116
109
|
const updatePhrases = async phrases => {
|
|
117
110
|
try {
|
|
118
111
|
handleUpdatePhrases(courseId, sectionId, topicId, phrases);
|
|
@@ -208,41 +201,50 @@ function PhraseList({
|
|
|
208
201
|
})]
|
|
209
202
|
})
|
|
210
203
|
})]
|
|
211
|
-
}), tabValue === 0 ? /*#__PURE__*/_jsx(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
204
|
+
}), tabValue === 0 ? /*#__PURE__*/_jsx(Box, {
|
|
205
|
+
className: hidden ? classes.paneFull : classes.pane,
|
|
206
|
+
sx: {
|
|
207
|
+
overflowY: "auto"
|
|
208
|
+
},
|
|
209
|
+
children: /*#__PURE__*/_jsx(PhrasesEditor, {
|
|
210
|
+
t: t,
|
|
211
|
+
phrases: phrases,
|
|
212
|
+
isCreator: isCreator,
|
|
213
|
+
isMember: isMember,
|
|
214
|
+
handleTranslate: handleTranslate,
|
|
215
|
+
handleUpdatePhrase: updatePhrase,
|
|
216
|
+
handleRemovePhrase: handleRemovePhrase,
|
|
217
|
+
uploadAudio: uploadAudio,
|
|
218
|
+
handleSpeak: handleSpeak,
|
|
219
|
+
updatePhrases: updatePhrases,
|
|
220
|
+
learnLang: learnLang,
|
|
221
|
+
forLang: forLang,
|
|
222
|
+
voices: voices,
|
|
223
|
+
userAttributes: userAttributes,
|
|
224
|
+
disablePadding: true,
|
|
225
|
+
forLangCharacters: forLangCharacters,
|
|
226
|
+
learnLangCharacters: learnLangCharacters,
|
|
227
|
+
fileSizeLimit: fileSizeLimit,
|
|
228
|
+
handleSpreadsheetSaveChanges: handleSpreadsheetSaveChanges,
|
|
229
|
+
isUploadPhrasesDialogOpen: isUploadPhrasesDialogOpen,
|
|
230
|
+
setIsUploadPhrasesDialogOpen: setIsUploadPhrasesDialogOpen,
|
|
231
|
+
isCreatePhraseDialogOpen: isCreatePhraseDialogOpen,
|
|
232
|
+
setIsCreatePhraseDialogOpen: setIsCreatePhraseDialogOpen,
|
|
233
|
+
handleAddPhrase: handleAddPhrase,
|
|
234
|
+
validatePhraseRecognition: validatePhraseRecognition,
|
|
235
|
+
siteLanguage: siteLanguage,
|
|
236
|
+
makeChatGptApiRequest: makeChatGptApiRequest,
|
|
237
|
+
difficulty: difficulty,
|
|
238
|
+
subscription: subscription,
|
|
239
|
+
topicGoal: topicGoal,
|
|
240
|
+
verificationStatus: verificationStatus,
|
|
241
|
+
phraseListName: initialValues.phraseListName
|
|
242
|
+
})
|
|
244
243
|
}) : null, tabValue === 1 ? /*#__PURE__*/_jsx(Box, {
|
|
245
244
|
className: hidden ? classes.paneFull : classes.pane,
|
|
245
|
+
sx: {
|
|
246
|
+
overflowY: "auto"
|
|
247
|
+
},
|
|
246
248
|
children: /*#__PURE__*/_jsx(UpdatePhraseList, {
|
|
247
249
|
t: t,
|
|
248
250
|
touched: touched,
|