@nualang/nualang-ui-components 0.1.1435 → 0.1.1437
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/Assignments/CreateAssignmentDialog/CreateAssignmentDialog.js +3 -1
- package/dist/Cards/Course/Course.js +2 -2
- package/dist/Cards/FeedbackCard/FeedbackCard.js +6 -1
- package/dist/Chat/Messages/Messages.js +1 -1
- package/dist/Chat/Messages/Question/Question.js +2 -2
- package/dist/Dialogs/DynamicAIWarning/DynamicAIWarning.js +2 -2
- package/dist/Dialogs/GroupedFeedbackDialog/GroupedFeedbackDialog.js +7 -3
- package/dist/Dialogs/GroupedFeedbackDialog/GroupedFeedbackDialog.test.js +39 -0
- package/dist/Dialogs/QuickCreateClassroomDialog/QuickCreateClassroomDialog.js +0 -1
- package/dist/Exercises/Bot/Bot.js +12 -6
- package/dist/Forms/CreateClassroom/Steps/AISettings/AISettings.js +235 -0
- package/dist/Forms/CreateClassroom/Steps/AISettings/AISettings.test.js +237 -0
- package/dist/Forms/CreateClassroom/Steps/ClassroomSettings/ClassroomSettings.js +22 -79
- package/dist/Forms/CreateClassroom/Steps/CourseSettings/CourseSettings.js +16 -13
- package/dist/Forms/CreateClassroom/Steps/index.js +2 -1
- package/dist/Forms/UpdateClassroom/UpdateClassroom.js +75 -10
- package/dist/Lists/CourseOutline/CourseOutline.js +363 -69
- package/dist/Lists/CourseOutline/CourseOutline.test.js +209 -2
- package/dist/Lists/Timeline/EventItem.js +15 -0
- package/dist/Tables/Attempt/Attempt.js +2 -2
- package/dist/Tables/MeetingPrompstList/MeetingPromptsList.js +4 -0
- package/dist/hooks/useExerciseState.js +10 -8
- package/dist/hooks/useRecognition.js +71 -22
- package/dist/utils/aiControls.js +63 -0
- package/package.json +1 -1
|
@@ -83,7 +83,9 @@ export default function CreateAssignmentDialog({
|
|
|
83
83
|
return response;
|
|
84
84
|
}, {
|
|
85
85
|
filters: {
|
|
86
|
-
courseIds: selectedClassroomCourses?.toString()
|
|
86
|
+
courseIds: selectedClassroomCourses?.toString(),
|
|
87
|
+
// Sections/topics are only returned when verbose; needed for the title autofill
|
|
88
|
+
verbose: true
|
|
87
89
|
}
|
|
88
90
|
}, {
|
|
89
91
|
enabled: !!assignment.classroomId
|
|
@@ -862,7 +862,7 @@ function CourseCard({
|
|
|
862
862
|
handleViewCourse(parentId);
|
|
863
863
|
}
|
|
864
864
|
};
|
|
865
|
-
const courseSections = sectionsQuery.isSuccess
|
|
865
|
+
const courseSections = sectionsQuery.isSuccess && sectionsQuery.data?.Items || [];
|
|
866
866
|
const topicDifficulties = sectionsQuery.isSuccess ? [...new Set(courseSections.flatMap(section => section.topics || []).map(topic => topic.difficulty).filter(Boolean))] : [];
|
|
867
867
|
const deleteCourse = async () => {
|
|
868
868
|
const confirmed = await confirm(t("delete_course"), t("delete_course_confirmation"), "", true, t("course_deletion_note", {
|
|
@@ -1263,7 +1263,7 @@ function CourseCard({
|
|
|
1263
1263
|
dialogTitle: courseName,
|
|
1264
1264
|
open: isOutlineOpen,
|
|
1265
1265
|
handleClose: handleCloseOutline,
|
|
1266
|
-
sections:
|
|
1266
|
+
sections: courseSections,
|
|
1267
1267
|
isLoading: sectionsQuery.isLoading,
|
|
1268
1268
|
isMember: isMember,
|
|
1269
1269
|
completions: completions,
|
|
@@ -55,6 +55,10 @@ export default function FeedbackCard({
|
|
|
55
55
|
userData = [],
|
|
56
56
|
hasSubmission = false,
|
|
57
57
|
aiGrade = {},
|
|
58
|
+
// Discuss AI feedback, already combined with the all-AI switch. It stops new
|
|
59
|
+
// AI feedback being generated; assessments already saved stay visible, since
|
|
60
|
+
// a teacher may have set them.
|
|
61
|
+
isDiscussAIFeedbackEnabled = true,
|
|
58
62
|
onGenerateFeedback = () => {},
|
|
59
63
|
onSubmitFeedback = () => {},
|
|
60
64
|
setSelectedRecording = () => {},
|
|
@@ -201,6 +205,7 @@ export default function FeedbackCard({
|
|
|
201
205
|
}
|
|
202
206
|
}, [submitTrigger]);
|
|
203
207
|
const handleGenerateAI = async () => {
|
|
208
|
+
if (!isDiscussAIFeedbackEnabled) return;
|
|
204
209
|
setAiJustGenerated(true);
|
|
205
210
|
setIsGeneratingFeedback(true);
|
|
206
211
|
setIsGeneratingIndividual(true);
|
|
@@ -566,7 +571,7 @@ export default function FeedbackCard({
|
|
|
566
571
|
disabled: !hasSubmission || isGeneratingFeedback,
|
|
567
572
|
onClick: handleOpenRecordingDialog,
|
|
568
573
|
children: t("view_recording")
|
|
569
|
-
}), /*#__PURE__*/_jsx(Button, {
|
|
574
|
+
}), isDiscussAIFeedbackEnabled && /*#__PURE__*/_jsx(Button, {
|
|
570
575
|
variant: "contained",
|
|
571
576
|
color: "secondary",
|
|
572
577
|
disabled: !hasSubmission || isGeneratingFeedback,
|
|
@@ -100,11 +100,11 @@ function Answers({
|
|
|
100
100
|
if (!isLiveGame) {
|
|
101
101
|
if (value.correct) {
|
|
102
102
|
setAnsweredCorrectly(true);
|
|
103
|
-
handleCorrectQuestionAnswer(question, value);
|
|
103
|
+
handleCorrectQuestionAnswer(question, value, answers);
|
|
104
104
|
}
|
|
105
105
|
if (!value.correct) {
|
|
106
106
|
setAnsweredCorrectly(false);
|
|
107
|
-
handleIncorrectQuestionAnswer(question, value);
|
|
107
|
+
handleIncorrectQuestionAnswer(question, value, answers);
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
};
|
|
@@ -23,7 +23,7 @@ function DynamicAIWarning({
|
|
|
23
23
|
return /*#__PURE__*/_jsxs(ResponsiveDialog, {
|
|
24
24
|
open: open,
|
|
25
25
|
handleClose: handleClose,
|
|
26
|
-
submitText: t("
|
|
26
|
+
submitText: t("ai_settings"),
|
|
27
27
|
dialogTitle: dialogTitle,
|
|
28
28
|
children: [/*#__PURE__*/_jsxs(Box, {
|
|
29
29
|
sx: {
|
|
@@ -168,7 +168,7 @@ function DynamicAIWarning({
|
|
|
168
168
|
fontWeight: "bold"
|
|
169
169
|
},
|
|
170
170
|
onClick: submit,
|
|
171
|
-
children: t("
|
|
171
|
+
children: t("ai_settings")
|
|
172
172
|
}), " ", "for this class."]
|
|
173
173
|
})]
|
|
174
174
|
}), /*#__PURE__*/_jsx(Divider, {
|
|
@@ -28,6 +28,9 @@ export default function GroupFeedbackDialog({
|
|
|
28
28
|
t = x => x,
|
|
29
29
|
handleBatchGradeConversations = () => {},
|
|
30
30
|
aiGrade = {},
|
|
31
|
+
// Discuss AI feedback, already combined with the all-AI switch, so the
|
|
32
|
+
// generate controls disappear when either is off.
|
|
33
|
+
isDiscussAIFeedbackEnabled = true,
|
|
31
34
|
selectedGroup = {},
|
|
32
35
|
setSelectedRecording = () => {},
|
|
33
36
|
selectedRecording = {},
|
|
@@ -200,7 +203,7 @@ export default function GroupFeedbackDialog({
|
|
|
200
203
|
}).filter(member => member.name !== "Unknown");
|
|
201
204
|
};
|
|
202
205
|
const handleGenerateFeedback = async discussionData => {
|
|
203
|
-
if (!handleBatchGradeConversations) return;
|
|
206
|
+
if (!isDiscussAIFeedbackEnabled || !handleBatchGradeConversations) return;
|
|
204
207
|
setIsGeneratingIndividual(true);
|
|
205
208
|
try {
|
|
206
209
|
const joinedMembersWithNames = getJoinedMembersNames(discussionData.joinedMembers || [], userData);
|
|
@@ -243,7 +246,7 @@ export default function GroupFeedbackDialog({
|
|
|
243
246
|
customFeedback: customFeedbackText
|
|
244
247
|
};
|
|
245
248
|
});
|
|
246
|
-
if (conversationsToGrade.length > 0 && handleBatchGradeConversations) {
|
|
249
|
+
if (isDiscussAIFeedbackEnabled && conversationsToGrade.length > 0 && handleBatchGradeConversations) {
|
|
247
250
|
setIsGeneratingAll(true);
|
|
248
251
|
setGenerateAllUsed(true);
|
|
249
252
|
try {
|
|
@@ -546,7 +549,7 @@ export default function GroupFeedbackDialog({
|
|
|
546
549
|
sx: {
|
|
547
550
|
flex: 1
|
|
548
551
|
}
|
|
549
|
-
}), /*#__PURE__*/_jsx(Button, {
|
|
552
|
+
}), isDiscussAIFeedbackEnabled && /*#__PURE__*/_jsx(Button, {
|
|
550
553
|
variant: "contained",
|
|
551
554
|
color: "secondary",
|
|
552
555
|
endIcon: /*#__PURE__*/_jsx(AutoFixHighIcon, {}),
|
|
@@ -603,6 +606,7 @@ export default function GroupFeedbackDialog({
|
|
|
603
606
|
existingFeedback: feedbackByMeetingId[feedbackMeetingId] || {},
|
|
604
607
|
onGenerateFeedback: () => openCustomPromptForSingle(discussionData),
|
|
605
608
|
onSubmitFeedback: handleSubmitFeedback,
|
|
609
|
+
isDiscussAIFeedbackEnabled: isDiscussAIFeedbackEnabled,
|
|
606
610
|
setSelectedRecording: setSelectedRecording,
|
|
607
611
|
selectedRecording: selectedRecording,
|
|
608
612
|
s3Url: s3Url,
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { render } from "@testing-library/react";
|
|
2
|
+
import { describe, it, expect } from "vitest";
|
|
3
|
+
import { createTheme, ThemeProvider } from "@mui/material/styles";
|
|
4
|
+
import GroupedFeedbackDialog from "./GroupedFeedbackDialog";
|
|
5
|
+
import { WithData } from "./GroupedFeedbackDialog.stories";
|
|
6
|
+
|
|
7
|
+
// This repo has no jest-dom matchers and no auto-cleanup, so assertions are
|
|
8
|
+
// plain and each test unmounts - matching AISettings.test.jsx.
|
|
9
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
|
+
const setup = (props = {}) => render(/*#__PURE__*/_jsx(ThemeProvider, {
|
|
11
|
+
theme: createTheme(),
|
|
12
|
+
children: /*#__PURE__*/_jsx(GroupedFeedbackDialog, {
|
|
13
|
+
...WithData.args,
|
|
14
|
+
...props
|
|
15
|
+
})
|
|
16
|
+
}));
|
|
17
|
+
describe("GroupedFeedbackDialog AI controls", () => {
|
|
18
|
+
it("offers feedback generation when the classroom allows AI", () => {
|
|
19
|
+
const {
|
|
20
|
+
queryAllByText,
|
|
21
|
+
unmount
|
|
22
|
+
} = setup();
|
|
23
|
+
expect(queryAllByText("generate_feedback").length).toBeGreaterThan(0);
|
|
24
|
+
unmount();
|
|
25
|
+
});
|
|
26
|
+
it("removes every generate control when the classroom limits AI", () => {
|
|
27
|
+
// Teachers can still write and submit their own feedback - only the AI
|
|
28
|
+
// route away from the page is closed.
|
|
29
|
+
const {
|
|
30
|
+
queryAllByText,
|
|
31
|
+
unmount
|
|
32
|
+
} = setup({
|
|
33
|
+
isDiscussAIFeedbackEnabled: false
|
|
34
|
+
});
|
|
35
|
+
expect(queryAllByText("generate_feedback").length).toBe(0);
|
|
36
|
+
expect(queryAllByText("submit_feedback").length).toBeGreaterThan(0);
|
|
37
|
+
unmount();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -145,7 +145,6 @@ export default function QuickCreateClassroomDialog({
|
|
|
145
145
|
visibility: "private",
|
|
146
146
|
vchatEnabled: true,
|
|
147
147
|
vchatEnabledInSettings: true,
|
|
148
|
-
isDynamicResponsesEnabled: "enabled",
|
|
149
148
|
enrolmentKey: generateRandomEnrolmentKey(),
|
|
150
149
|
allowedDomains: [],
|
|
151
150
|
collaborators: [],
|
|
@@ -29,8 +29,8 @@ import ReportProblem from "../../Misc/ReportProblem/ReportProblem";
|
|
|
29
29
|
import NualaSignInImage from "../../img/nuala_sign_in.svg";
|
|
30
30
|
import { startJoyrideWhenReady } from "../../utils/joyride";
|
|
31
31
|
import { collectCorrections } from "../../utils/correction";
|
|
32
|
-
import { getDynamicResponsesSetting } from "../../utils/dynamicResponses";
|
|
33
32
|
import { getBotContentTemplateType } from "../../utils";
|
|
33
|
+
import { AI_ENABLED, courseAIValue, isCourseAIEnabled } from "../../utils/aiControls";
|
|
34
34
|
import { useTheme } from "@mui/material/styles";
|
|
35
35
|
import config from "../../config";
|
|
36
36
|
import { useNavigate } from "react-router";
|
|
@@ -288,11 +288,17 @@ function Bot({
|
|
|
288
288
|
} = getRecognitionParams();
|
|
289
289
|
toggleListen(learnLang, speechContexts, model, undefined, autoStopOptions);
|
|
290
290
|
};
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
291
|
+
|
|
292
|
+
// The classroom's all-AI and chatbot switches, and the course's, can each
|
|
293
|
+
// silence dynamic responses whatever the bot's own setting. Only when they
|
|
294
|
+
// allow AI does the bot's setting decide - except for courses saved as
|
|
295
|
+
// "enabled", which older classroom records can still carry.
|
|
296
|
+
let isDynamicResponsesClassroomEnabled = isDynamicResponsesEnabled;
|
|
297
|
+
if (!isCourseAIEnabled(parentClassroom, courseSettings)) {
|
|
298
|
+
isDynamicResponsesClassroomEnabled = "disable";
|
|
299
|
+
} else if (courseAIValue(courseSettings) === AI_ENABLED) {
|
|
300
|
+
isDynamicResponsesClassroomEnabled = "enable";
|
|
301
|
+
}
|
|
296
302
|
const exerciseState = useExerciseState({
|
|
297
303
|
t,
|
|
298
304
|
open,
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
import * as Yup from "yup";
|
|
3
|
+
import { Alert, Box, FormControl, FormControlLabel, FormLabel, Grid, IconButton, Radio, RadioGroup, Tooltip, Typography } from "@mui/material";
|
|
4
|
+
import HelpIcon from "@mui/icons-material/Help";
|
|
5
|
+
import SearchIcon from "@mui/icons-material/Search";
|
|
6
|
+
import EastIcon from "@mui/icons-material/East";
|
|
7
|
+
import { AI_DISABLED, AI_ENABLED, AI_FIELDS, aiLockedBy, classroomAIValue, courseAIValue } from "../../../../utils/aiControls";
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
export const AI_INFO_URL = "https://www.waysidepublishing.com/digital-solutions/ai-safety-and-trust";
|
|
10
|
+
|
|
11
|
+
// One Allowed / Limited choice for one of AI_FIELDS.
|
|
12
|
+
function AISwitch({
|
|
13
|
+
t,
|
|
14
|
+
name,
|
|
15
|
+
label,
|
|
16
|
+
description,
|
|
17
|
+
info,
|
|
18
|
+
value,
|
|
19
|
+
disabled,
|
|
20
|
+
dataCy,
|
|
21
|
+
handleChange,
|
|
22
|
+
handleBlur
|
|
23
|
+
}) {
|
|
24
|
+
return /*#__PURE__*/_jsxs(FormControl, {
|
|
25
|
+
component: "fieldset",
|
|
26
|
+
children: [/*#__PURE__*/_jsxs(FormLabel, {
|
|
27
|
+
component: "legend",
|
|
28
|
+
children: [t(label), info && /*#__PURE__*/_jsx(Tooltip, {
|
|
29
|
+
title: t(info),
|
|
30
|
+
placement: "right",
|
|
31
|
+
children: /*#__PURE__*/_jsx(IconButton, {
|
|
32
|
+
sx: {
|
|
33
|
+
padding: 0,
|
|
34
|
+
marginLeft: 1
|
|
35
|
+
},
|
|
36
|
+
children: /*#__PURE__*/_jsx(HelpIcon, {
|
|
37
|
+
fontSize: "small"
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
})]
|
|
41
|
+
}), /*#__PURE__*/_jsx(Typography, {
|
|
42
|
+
color: "textSecondary",
|
|
43
|
+
children: t(description)
|
|
44
|
+
}), /*#__PURE__*/_jsxs(RadioGroup, {
|
|
45
|
+
row: true,
|
|
46
|
+
"aria-label": name,
|
|
47
|
+
name: name,
|
|
48
|
+
value: value,
|
|
49
|
+
onChange: handleChange,
|
|
50
|
+
onBlur: handleBlur,
|
|
51
|
+
children: [/*#__PURE__*/_jsx(FormControlLabel, {
|
|
52
|
+
value: AI_ENABLED,
|
|
53
|
+
control: /*#__PURE__*/_jsx(Radio, {}),
|
|
54
|
+
label: t("ai_allowed"),
|
|
55
|
+
disabled: disabled,
|
|
56
|
+
"data-cy": `allow-${dataCy}-in-settings`
|
|
57
|
+
}), /*#__PURE__*/_jsx(FormControlLabel, {
|
|
58
|
+
value: AI_DISABLED,
|
|
59
|
+
control: /*#__PURE__*/_jsx(Radio, {}),
|
|
60
|
+
label: t("ai_limited"),
|
|
61
|
+
disabled: disabled,
|
|
62
|
+
"data-cy": `limit-${dataCy}-in-settings`
|
|
63
|
+
})]
|
|
64
|
+
})]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// The classroom's AI section: a switch for all AI, and one each for chatbot
|
|
69
|
+
// dynamic responses and Discuss AI feedback. Per-course chatbot overrides stay
|
|
70
|
+
// in Course Settings, so this section only reports them.
|
|
71
|
+
function AISettings({
|
|
72
|
+
t = text => text,
|
|
73
|
+
values,
|
|
74
|
+
handleChange,
|
|
75
|
+
handleBlur,
|
|
76
|
+
courses = [],
|
|
77
|
+
courseSettings = {},
|
|
78
|
+
scrollToDynamicResponses = false,
|
|
79
|
+
setScrollToDynamicResponses,
|
|
80
|
+
// The saved classroom record, which the API stamps with `aiLockedBy` when
|
|
81
|
+
// the classroom's customer has limited AI. `values` is only the form state.
|
|
82
|
+
classroom
|
|
83
|
+
}) {
|
|
84
|
+
const aiControlRef = useRef(null);
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
// Guarded: the notice can fire before this section has mounted.
|
|
87
|
+
if (scrollToDynamicResponses && aiControlRef.current) {
|
|
88
|
+
aiControlRef.current.scrollIntoView({
|
|
89
|
+
behavior: "smooth",
|
|
90
|
+
block: "center"
|
|
91
|
+
});
|
|
92
|
+
setScrollToDynamicResponses && setScrollToDynamicResponses(false);
|
|
93
|
+
}
|
|
94
|
+
}, [scrollToDynamicResponses]);
|
|
95
|
+
const isAllLimited = classroomAIValue(values) === AI_DISABLED;
|
|
96
|
+
const isAllLocked = Boolean(aiLockedBy(classroom));
|
|
97
|
+
|
|
98
|
+
// While all AI is off, a feature shows as limited - which is what students
|
|
99
|
+
// get - but keeps its own value for when all AI is turned back on.
|
|
100
|
+
const featureValue = field => isAllLimited ? AI_DISABLED : classroomAIValue(values, field);
|
|
101
|
+
const isChatbotLimited = featureValue(AI_FIELDS.chatbot) === AI_DISABLED;
|
|
102
|
+
|
|
103
|
+
// Courses that have turned the chatbot off for themselves. Read from the
|
|
104
|
+
// saved classroom, so this is what students currently get.
|
|
105
|
+
const overriddenCourses = courses.filter(course => courseAIValue(courseSettings?.[course.courseId]) === AI_DISABLED);
|
|
106
|
+
const switchProps = {
|
|
107
|
+
t,
|
|
108
|
+
handleChange,
|
|
109
|
+
handleBlur
|
|
110
|
+
};
|
|
111
|
+
return /*#__PURE__*/_jsxs(Grid, {
|
|
112
|
+
container: true,
|
|
113
|
+
spacing: 2,
|
|
114
|
+
ref: aiControlRef,
|
|
115
|
+
children: [/*#__PURE__*/_jsxs(Grid, {
|
|
116
|
+
size: 12,
|
|
117
|
+
children: [/*#__PURE__*/_jsx(Typography, {
|
|
118
|
+
color: "textSecondary",
|
|
119
|
+
gutterBottom: true,
|
|
120
|
+
children: t("ai_settings_desc")
|
|
121
|
+
}), /*#__PURE__*/_jsxs(Box, {
|
|
122
|
+
component: "a",
|
|
123
|
+
href: AI_INFO_URL,
|
|
124
|
+
target: "_blank",
|
|
125
|
+
rel: "noopener noreferrer",
|
|
126
|
+
sx: {
|
|
127
|
+
display: "inline-flex",
|
|
128
|
+
alignItems: "center",
|
|
129
|
+
textDecoration: "none",
|
|
130
|
+
color: "primary.main"
|
|
131
|
+
},
|
|
132
|
+
children: [/*#__PURE__*/_jsx(SearchIcon, {
|
|
133
|
+
sx: {
|
|
134
|
+
mr: 0.5
|
|
135
|
+
},
|
|
136
|
+
fontSize: "small"
|
|
137
|
+
}), /*#__PURE__*/_jsx(Typography, {
|
|
138
|
+
variant: "body2",
|
|
139
|
+
children: t("ai_learn_more")
|
|
140
|
+
}), /*#__PURE__*/_jsx(EastIcon, {
|
|
141
|
+
sx: {
|
|
142
|
+
ml: 0.5
|
|
143
|
+
},
|
|
144
|
+
fontSize: "small"
|
|
145
|
+
})]
|
|
146
|
+
})]
|
|
147
|
+
}), /*#__PURE__*/_jsxs(Grid, {
|
|
148
|
+
size: 12,
|
|
149
|
+
children: [/*#__PURE__*/_jsx(AISwitch, {
|
|
150
|
+
...switchProps,
|
|
151
|
+
name: AI_FIELDS.all,
|
|
152
|
+
label: "limit_ai",
|
|
153
|
+
description: "limit_ai_desc",
|
|
154
|
+
info: "limit_ai_info",
|
|
155
|
+
value: classroomAIValue(values),
|
|
156
|
+
disabled: isAllLocked,
|
|
157
|
+
dataCy: "ai"
|
|
158
|
+
}), isAllLocked && /*#__PURE__*/_jsx(Alert, {
|
|
159
|
+
severity: "info",
|
|
160
|
+
"data-cy": "ai-locked-notice",
|
|
161
|
+
sx: {
|
|
162
|
+
mt: 1
|
|
163
|
+
},
|
|
164
|
+
children: t("ai_locked_notice")
|
|
165
|
+
}), !isAllLocked && isAllLimited && /*#__PURE__*/_jsx(Alert, {
|
|
166
|
+
severity: "info",
|
|
167
|
+
"data-cy": "ai-limited-notice",
|
|
168
|
+
sx: {
|
|
169
|
+
mt: 1
|
|
170
|
+
},
|
|
171
|
+
children: t("ai_limited_classroom_notice")
|
|
172
|
+
})]
|
|
173
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
174
|
+
size: 12,
|
|
175
|
+
children: /*#__PURE__*/_jsxs(Box, {
|
|
176
|
+
sx: {
|
|
177
|
+
pl: 4,
|
|
178
|
+
display: "grid",
|
|
179
|
+
gap: 2
|
|
180
|
+
},
|
|
181
|
+
children: [/*#__PURE__*/_jsxs(Box, {
|
|
182
|
+
children: [/*#__PURE__*/_jsx(AISwitch, {
|
|
183
|
+
...switchProps,
|
|
184
|
+
name: AI_FIELDS.chatbot,
|
|
185
|
+
label: "chatbot_ai",
|
|
186
|
+
description: "chatbot_ai_desc",
|
|
187
|
+
info: "dynamic_responses_info",
|
|
188
|
+
value: featureValue(AI_FIELDS.chatbot),
|
|
189
|
+
disabled: isAllLimited || Boolean(aiLockedBy(classroom, AI_FIELDS.chatbot)),
|
|
190
|
+
dataCy: "chatbot-ai"
|
|
191
|
+
}), !isAllLocked && Boolean(aiLockedBy(classroom, AI_FIELDS.chatbot)) && /*#__PURE__*/_jsx(Alert, {
|
|
192
|
+
severity: "info",
|
|
193
|
+
"data-cy": "ai-partly-locked-notice",
|
|
194
|
+
sx: {
|
|
195
|
+
mt: 1
|
|
196
|
+
},
|
|
197
|
+
children: t("ai_partly_locked_notice")
|
|
198
|
+
}), !isChatbotLimited && overriddenCourses.length > 0 && /*#__PURE__*/_jsxs(Alert, {
|
|
199
|
+
severity: "info",
|
|
200
|
+
"data-cy": "ai-course-overrides-notice",
|
|
201
|
+
sx: {
|
|
202
|
+
mt: 1
|
|
203
|
+
},
|
|
204
|
+
children: [t("ai_course_overrides_notice"), ": ", overriddenCourses.map(course => course.courseName).join(", ")]
|
|
205
|
+
})]
|
|
206
|
+
}), /*#__PURE__*/_jsxs(Box, {
|
|
207
|
+
children: [/*#__PURE__*/_jsx(AISwitch, {
|
|
208
|
+
...switchProps,
|
|
209
|
+
name: AI_FIELDS.discuss,
|
|
210
|
+
label: "discuss_ai",
|
|
211
|
+
description: "discuss_ai_desc",
|
|
212
|
+
value: featureValue(AI_FIELDS.discuss),
|
|
213
|
+
disabled: isAllLimited || Boolean(aiLockedBy(classroom, AI_FIELDS.discuss)),
|
|
214
|
+
dataCy: "discuss-ai"
|
|
215
|
+
}), !isAllLocked && Boolean(aiLockedBy(classroom, AI_FIELDS.discuss)) && /*#__PURE__*/_jsx(Alert, {
|
|
216
|
+
severity: "info",
|
|
217
|
+
"data-cy": "ai-partly-locked-notice",
|
|
218
|
+
sx: {
|
|
219
|
+
mt: 1
|
|
220
|
+
},
|
|
221
|
+
children: t("ai_partly_locked_notice")
|
|
222
|
+
})]
|
|
223
|
+
})]
|
|
224
|
+
})
|
|
225
|
+
})]
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
AISettings.propTypes = {};
|
|
229
|
+
AISettings.label = "ai_settings";
|
|
230
|
+
AISettings.validationSchema = Yup.object().shape({
|
|
231
|
+
isAIEnabled: Yup.string(),
|
|
232
|
+
isDynamicResponsesEnabled: Yup.string(),
|
|
233
|
+
isDiscussAIFeedbackEnabled: Yup.string()
|
|
234
|
+
});
|
|
235
|
+
export default AISettings;
|