@openedx/frontend-app-instructor-dashboard 1.0.0-alpha.2 → 1.0.0-alpha.21
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/Main.d.ts +1 -1
- package/dist/Main.js +4 -13
- package/dist/Main.js.map +1 -1
- package/dist/app.js +2 -11
- package/dist/app.js.map +1 -1
- package/dist/certificates/CertificatesPage.d.ts +1 -0
- package/dist/certificates/CertificatesPage.js +162 -2
- package/dist/certificates/CertificatesPage.js.map +1 -1
- package/dist/certificates/CertificatesPage.scss +81 -0
- package/dist/certificates/components/CertificateTable.d.ts +14 -0
- package/dist/certificates/components/CertificateTable.js +85 -0
- package/dist/certificates/components/CertificateTable.js.map +1 -0
- package/dist/certificates/components/CertificatesPageHeader.d.ts +7 -0
- package/dist/certificates/components/CertificatesPageHeader.js +11 -0
- package/dist/certificates/components/CertificatesPageHeader.js.map +1 -0
- package/dist/certificates/components/CertificatesToolbar.d.ts +10 -0
- package/dist/certificates/components/CertificatesToolbar.js +12 -0
- package/dist/certificates/components/CertificatesToolbar.js.map +1 -0
- package/dist/certificates/components/DisableCertificatesModal.d.ts +9 -0
- package/dist/certificates/components/DisableCertificatesModal.js +16 -0
- package/dist/certificates/components/DisableCertificatesModal.js.map +1 -0
- package/dist/certificates/components/FilterDropdown.d.ts +8 -0
- package/dist/certificates/components/FilterDropdown.js +50 -0
- package/dist/certificates/components/FilterDropdown.js.map +1 -0
- package/dist/certificates/components/GenerationHistoryTable.d.ts +11 -0
- package/dist/certificates/components/GenerationHistoryTable.js +40 -0
- package/dist/certificates/components/GenerationHistoryTable.js.map +1 -0
- package/dist/certificates/components/GrantExceptionsModal.d.ts +8 -0
- package/dist/certificates/components/GrantExceptionsModal.js +10 -0
- package/dist/certificates/components/GrantExceptionsModal.js.map +1 -0
- package/dist/certificates/components/InvalidateCertificateModal.d.ts +8 -0
- package/dist/certificates/components/InvalidateCertificateModal.js +10 -0
- package/dist/certificates/components/InvalidateCertificateModal.js.map +1 -0
- package/dist/certificates/components/IssuedCertificatesTab.d.ts +18 -0
- package/dist/certificates/components/IssuedCertificatesTab.js +6 -0
- package/dist/certificates/components/IssuedCertificatesTab.js.map +1 -0
- package/dist/certificates/components/LearnerActionModal.d.ts +16 -0
- package/dist/certificates/components/LearnerActionModal.js +22 -0
- package/dist/certificates/components/LearnerActionModal.js.map +1 -0
- package/dist/certificates/components/RemoveInvalidationModal.d.ts +9 -0
- package/dist/certificates/components/RemoveInvalidationModal.js +10 -0
- package/dist/certificates/components/RemoveInvalidationModal.js.map +1 -0
- package/dist/certificates/constants.d.ts +15 -0
- package/dist/certificates/constants.js +16 -0
- package/dist/certificates/constants.js.map +1 -0
- package/dist/certificates/data/api.d.ts +9 -0
- package/dist/certificates/data/api.js +63 -0
- package/dist/certificates/data/api.js.map +1 -0
- package/dist/certificates/data/apiHook.d.ts +30 -0
- package/dist/certificates/data/apiHook.js +90 -0
- package/dist/certificates/data/apiHook.js.map +1 -0
- package/dist/certificates/data/dummyData.d.ts +2 -0
- package/dist/certificates/data/dummyData.js +234 -0
- package/dist/certificates/data/dummyData.js.map +1 -0
- package/dist/certificates/data/queryKeys.d.ts +8 -0
- package/dist/certificates/data/queryKeys.js +8 -0
- package/dist/certificates/data/queryKeys.js.map +1 -0
- package/dist/certificates/messages.d.ts +313 -0
- package/dist/certificates/messages.js +315 -0
- package/dist/certificates/messages.js.map +1 -0
- package/dist/certificates/types.d.ts +61 -0
- package/dist/certificates/types.js +26 -0
- package/dist/certificates/types.js.map +1 -0
- package/dist/certificates/utils/errorHandling.d.ts +10 -0
- package/dist/certificates/utils/errorHandling.js +3 -0
- package/dist/certificates/utils/errorHandling.js.map +1 -0
- package/dist/certificates/utils/filterUtils.d.ts +4 -0
- package/dist/certificates/utils/filterUtils.js +31 -0
- package/dist/certificates/utils/filterUtils.js.map +1 -0
- package/dist/certificates/utils/index.d.ts +2 -0
- package/dist/certificates/utils/index.js +2 -0
- package/dist/certificates/utils/index.js.map +1 -0
- package/dist/cohorts/data/queryKeys.d.ts +4 -4
- package/dist/components/ActionCard.d.ts +2 -2
- package/dist/components/ActionCard.js +1 -1
- package/dist/components/ActionCard.js.map +1 -1
- package/dist/components/PendingTasks.d.ts +3 -1
- package/dist/components/PendingTasks.js +3 -2
- package/dist/components/PendingTasks.js.map +1 -1
- package/dist/components/SpecifyLearnerField.d.ts +4 -1
- package/dist/components/SpecifyLearnerField.js +24 -10
- package/dist/components/SpecifyLearnerField.js.map +1 -1
- package/dist/components/SpecifyProblemField.d.ts +13 -0
- package/dist/components/SpecifyProblemField.js +46 -0
- package/dist/components/SpecifyProblemField.js.map +1 -0
- package/dist/components/UsernameFilter.d.ts +7 -0
- package/dist/components/UsernameFilter.js +19 -0
- package/dist/components/UsernameFilter.js.map +1 -0
- package/dist/components/messages.d.ts +30 -0
- package/dist/components/messages.js +30 -0
- package/dist/components/messages.js.map +1 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/courseInfo/types.d.ts +2 -0
- package/dist/courseInfo/types.js.map +1 -1
- package/dist/courseTeam/CourseTeamPage.js +20 -2
- package/dist/courseTeam/CourseTeamPage.js.map +1 -1
- package/dist/courseTeam/components/AddTeamMemberModal.d.ts +6 -0
- package/dist/courseTeam/components/AddTeamMemberModal.js +60 -0
- package/dist/courseTeam/components/AddTeamMemberModal.js.map +1 -0
- package/dist/courseTeam/components/EditTeamMemberModal.d.ts +8 -0
- package/dist/courseTeam/components/EditTeamMemberModal.js +90 -0
- package/dist/courseTeam/components/EditTeamMemberModal.js.map +1 -0
- package/dist/courseTeam/components/MembersContent.d.ts +6 -0
- package/dist/courseTeam/components/MembersContent.js +48 -0
- package/dist/courseTeam/components/MembersContent.js.map +1 -0
- package/dist/courseTeam/components/RoleFilter.d.ts +7 -0
- package/dist/courseTeam/components/RoleFilter.js +22 -0
- package/dist/courseTeam/components/RoleFilter.js.map +1 -0
- package/dist/courseTeam/components/RolesContent.d.ts +3 -0
- package/dist/courseTeam/components/RolesContent.js +25 -0
- package/dist/courseTeam/components/RolesContent.js.map +1 -0
- package/dist/courseTeam/data/api.d.ts +6 -0
- package/dist/courseTeam/data/api.js +38 -0
- package/dist/courseTeam/data/api.js.map +1 -0
- package/dist/courseTeam/data/apiHook.d.ts +11 -0
- package/dist/courseTeam/data/apiHook.js +32 -0
- package/dist/courseTeam/data/apiHook.js.map +1 -0
- package/dist/courseTeam/data/queryKeys.d.ts +7 -0
- package/dist/courseTeam/data/queryKeys.js +14 -0
- package/dist/courseTeam/data/queryKeys.js.map +1 -0
- package/dist/courseTeam/messages.d.ts +243 -0
- package/dist/courseTeam/messages.js +245 -0
- package/dist/courseTeam/messages.js.map +1 -0
- package/dist/courseTeam/types.d.ts +22 -0
- package/dist/courseTeam/types.js +3 -0
- package/dist/courseTeam/types.js.map +1 -0
- package/dist/data/api.d.ts +2 -1
- package/dist/data/api.js +9 -3
- package/dist/data/api.js.map +1 -1
- package/dist/data/apiHook.d.ts +1 -0
- package/dist/data/apiHook.js +10 -2
- package/dist/data/apiHook.js.map +1 -1
- package/dist/data/queryKeys.d.ts +10 -6
- package/dist/data/queryKeys.js +4 -0
- package/dist/data/queryKeys.js.map +1 -1
- package/dist/dataDownloads/data/queryKeys.d.ts +3 -3
- package/dist/dateExtensions/components/AddExtensionModal.d.ts +1 -1
- package/dist/dateExtensions/components/AddExtensionModal.js +5 -6
- package/dist/dateExtensions/components/AddExtensionModal.js.map +1 -1
- package/dist/dateExtensions/components/DateExtensionsList.js +2 -13
- package/dist/dateExtensions/components/DateExtensionsList.js.map +1 -1
- package/dist/dateExtensions/data/apiHook.d.ts +2 -2
- package/dist/dateExtensions/data/apiHook.js +4 -4
- package/dist/dateExtensions/data/apiHook.js.map +1 -1
- package/dist/dateExtensions/data/queryKeys.d.ts +5 -5
- package/dist/dateExtensions/messages.d.ts +0 -5
- package/dist/dateExtensions/messages.js +1 -6
- package/dist/dateExtensions/messages.js.map +1 -1
- package/dist/enrollments/EnrollmentsPage.js +41 -7
- package/dist/enrollments/EnrollmentsPage.js.map +1 -1
- package/dist/enrollments/components/AddBetaTestersModal.d.ts +6 -0
- package/dist/enrollments/components/AddBetaTestersModal.js +61 -0
- package/dist/enrollments/components/AddBetaTestersModal.js.map +1 -0
- package/dist/enrollments/components/EnrollLearnersModal.d.ts +6 -0
- package/dist/enrollments/components/EnrollLearnersModal.js +53 -0
- package/dist/enrollments/components/EnrollLearnersModal.js.map +1 -0
- package/dist/enrollments/components/EnrollmentStatusModal.js +3 -3
- package/dist/enrollments/components/EnrollmentStatusModal.js.map +1 -1
- package/dist/enrollments/components/EnrollmentsList.d.ts +3 -2
- package/dist/enrollments/components/EnrollmentsList.js +13 -14
- package/dist/enrollments/components/EnrollmentsList.js.map +1 -1
- package/dist/enrollments/components/UnenrollModal.d.ts +1 -1
- package/dist/enrollments/components/UnenrollModal.js +29 -3
- package/dist/enrollments/components/UnenrollModal.js.map +1 -1
- package/dist/enrollments/components/UpdateBetaTesterModal.d.ts +8 -0
- package/dist/enrollments/components/UpdateBetaTesterModal.js +52 -0
- package/dist/enrollments/components/UpdateBetaTesterModal.js.map +1 -0
- package/dist/enrollments/data/api.d.ts +3 -1
- package/dist/enrollments/data/api.js +11 -1
- package/dist/enrollments/data/api.js.map +1 -1
- package/dist/enrollments/data/apiHook.d.ts +5 -3
- package/dist/enrollments/data/apiHook.js +21 -3
- package/dist/enrollments/data/apiHook.js.map +1 -1
- package/dist/enrollments/data/queryKeys.d.ts +5 -5
- package/dist/enrollments/data/queryKeys.js.map +1 -1
- package/dist/enrollments/messages.d.ts +121 -1
- package/dist/enrollments/messages.js +126 -6
- package/dist/enrollments/messages.js.map +1 -1
- package/dist/enrollments/types.d.ts +24 -0
- package/dist/enrollments/types.js.map +1 -1
- package/dist/grading/GradingPage.js +15 -2
- package/dist/grading/GradingPage.js.map +1 -1
- package/dist/grading/components/GradingActionRow.d.ts +2 -0
- package/dist/grading/components/GradingActionRow.js +28 -0
- package/dist/grading/components/GradingActionRow.js.map +1 -0
- package/dist/grading/components/GradingConfigurationModal.d.ts +6 -0
- package/dist/grading/components/GradingConfigurationModal.js +14 -0
- package/dist/grading/components/GradingConfigurationModal.js.map +1 -0
- package/dist/grading/components/GradingLearnerContent.d.ts +7 -0
- package/dist/grading/components/GradingLearnerContent.js +114 -0
- package/dist/grading/components/GradingLearnerContent.js.map +1 -0
- package/dist/grading/data/api.d.ts +6 -0
- package/dist/grading/data/api.js +59 -0
- package/dist/grading/data/api.js.map +1 -0
- package/dist/grading/data/apiHook.d.ts +6 -0
- package/dist/grading/data/apiHook.js +29 -0
- package/dist/grading/data/apiHook.js.map +1 -0
- package/dist/grading/data/queryKeys.d.ts +9 -0
- package/dist/grading/data/queryKeys.js +8 -0
- package/dist/grading/data/queryKeys.js.map +1 -0
- package/dist/grading/messages.d.ts +173 -0
- package/dist/grading/messages.js +175 -0
- package/dist/grading/messages.js.map +1 -0
- package/dist/grading/types.d.ts +11 -0
- package/dist/grading/types.js +2 -0
- package/dist/grading/types.js.map +1 -0
- package/dist/hooks/useDebouncedFilter.d.ts +1 -0
- package/dist/hooks/useDebouncedFilter.js +5 -0
- package/dist/hooks/useDebouncedFilter.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/instructorNav/InstructorNav.js +1 -1
- package/dist/instructorNav/InstructorNav.js.map +1 -1
- package/dist/provides.d.ts +4 -0
- package/dist/provides.js +7 -0
- package/dist/provides.js.map +1 -0
- package/dist/routes.d.ts +1 -1
- package/dist/routes.js +5 -4
- package/dist/routes.js.map +1 -1
- package/dist/specialExams/SpecialExamsPage.js +10 -2
- package/dist/specialExams/SpecialExamsPage.js.map +1 -1
- package/dist/specialExams/components/Allowances.d.ts +2 -0
- package/dist/specialExams/components/Allowances.js +6 -0
- package/dist/specialExams/components/Allowances.js.map +1 -0
- package/dist/specialExams/components/AttemptsList.d.ts +3 -0
- package/dist/specialExams/components/AttemptsList.js +44 -0
- package/dist/specialExams/components/AttemptsList.js.map +1 -0
- package/dist/specialExams/data/api.d.ts +3 -0
- package/dist/specialExams/data/api.js +23 -0
- package/dist/specialExams/data/api.js.map +1 -0
- package/dist/specialExams/data/apiHook.d.ts +2 -0
- package/dist/specialExams/data/apiHook.js +9 -0
- package/dist/specialExams/data/apiHook.js.map +1 -0
- package/dist/specialExams/data/queryKeys.d.ts +5 -0
- package/dist/specialExams/data/queryKeys.js +6 -0
- package/dist/specialExams/data/queryKeys.js.map +1 -0
- package/dist/specialExams/messages.d.ts +58 -0
- package/dist/specialExams/messages.js +60 -0
- package/dist/specialExams/messages.js.map +1 -0
- package/dist/specialExams/types.d.ts +13 -0
- package/dist/specialExams/types.js +2 -0
- package/dist/specialExams/types.js.map +1 -0
- package/dist/style.scss +16 -0
- package/dist/testUtils.js +1 -1
- package/dist/testUtils.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/formatters.d.ts +5 -0
- package/dist/utils/formatters.js +10 -0
- package/dist/utils/formatters.js.map +1 -1
- package/package.json +2 -5
- package/dist/app.scss +0 -10
- package/dist/providers/QueryProvider.d.ts +0 -6
- package/dist/providers/QueryProvider.js +0 -16
- package/dist/providers/QueryProvider.js.map +0 -1
- package/dist/providers.d.ts +0 -3
- package/dist/providers.js +0 -8
- package/dist/providers.js.map +0 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { useParams } from 'react-router-dom';
|
|
4
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
+
import { ActionRow, Button, Form, FormControl, FormLabel, ModalDialog } from '@openedx/paragon';
|
|
6
|
+
import { useAddTeamMember, useRemoveTeamMember, useRoles } from '../../courseTeam/data/apiHook';
|
|
7
|
+
import messages from '../../courseTeam/messages';
|
|
8
|
+
import { useAlert } from '../../providers/AlertProvider';
|
|
9
|
+
const EditTeamMemberModal = ({ isOpen, user, onClose }) => {
|
|
10
|
+
const intl = useIntl();
|
|
11
|
+
const { courseId = '' } = useParams();
|
|
12
|
+
const [selectedRole, setSelectedRole] = useState('');
|
|
13
|
+
const [keepRoles, setKeepRoles] = useState([]);
|
|
14
|
+
const { mutate: addTeamMember, isPending: isAdding } = useAddTeamMember(courseId);
|
|
15
|
+
const { mutate: removeTeamMember, isPending: isRemoving } = useRemoveTeamMember(courseId);
|
|
16
|
+
const { showModal } = useAlert();
|
|
17
|
+
const { data: { results } = { results: [] } } = useRoles(courseId);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (isOpen) {
|
|
20
|
+
setKeepRoles(user.roles.map(role => role.role));
|
|
21
|
+
setSelectedRole('');
|
|
22
|
+
}
|
|
23
|
+
}, [isOpen, user]);
|
|
24
|
+
const filteredRoles = (results === null || results === void 0 ? void 0 : results.filter(role => !user.roles.some(userRole => userRole.role === role.role))) || [];
|
|
25
|
+
const roles = [{ role: '', displayName: intl.formatMessage(messages.rolePlaceholder) }, ...filteredRoles];
|
|
26
|
+
const handleToggleRole = (roleName) => {
|
|
27
|
+
if (keepRoles.includes(roleName)) {
|
|
28
|
+
setKeepRoles(keepRoles.filter(role => role !== roleName));
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
setKeepRoles([...keepRoles, roleName]);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const handleSave = () => {
|
|
35
|
+
const rolesToRemove = user.roles.filter(role => !keepRoles.includes(role.role)).map(role => role.role);
|
|
36
|
+
const hasRolesToAdd = selectedRole;
|
|
37
|
+
const hasRolesToRemove = rolesToRemove.length > 0;
|
|
38
|
+
// Sequential approach: remove roles first, then add new role
|
|
39
|
+
if (hasRolesToRemove) {
|
|
40
|
+
removeTeamMember({ identifier: user.username, roles: rolesToRemove }, {
|
|
41
|
+
onSuccess: () => {
|
|
42
|
+
// After successful removal, add new role if needed
|
|
43
|
+
if (hasRolesToAdd) {
|
|
44
|
+
addTeamMember({ identifiers: [user.username], role: selectedRole }, {
|
|
45
|
+
onSuccess: () => {
|
|
46
|
+
onClose();
|
|
47
|
+
},
|
|
48
|
+
onError: () => {
|
|
49
|
+
showModal({
|
|
50
|
+
message: intl.formatMessage(messages.addRoleError),
|
|
51
|
+
variant: 'danger',
|
|
52
|
+
confirmText: intl.formatMessage(messages.closeButton),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
onClose();
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
onError: () => {
|
|
62
|
+
showModal({
|
|
63
|
+
message: intl.formatMessage(messages.removeTeamMemberError, { username: user.username }),
|
|
64
|
+
variant: 'danger',
|
|
65
|
+
confirmText: intl.formatMessage(messages.closeButton),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
else if (hasRolesToAdd) {
|
|
71
|
+
// Only add operation needed
|
|
72
|
+
addTeamMember({ identifiers: [user.username], role: selectedRole }, {
|
|
73
|
+
onSuccess: () => {
|
|
74
|
+
onClose();
|
|
75
|
+
},
|
|
76
|
+
onError: () => {
|
|
77
|
+
showModal({
|
|
78
|
+
message: intl.formatMessage(messages.addRoleError),
|
|
79
|
+
variant: 'danger',
|
|
80
|
+
confirmText: intl.formatMessage(messages.closeButton),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
return (_jsxs(ModalDialog, { isOpen: isOpen, title: intl.formatMessage(messages.editTeamTitle, { username: user.username }), onClose: onClose, isOverflowVisible: false, children: [_jsx(ModalDialog.Header, { className: "border-light-700 border-bottom", children: _jsx("h3", { className: "text-primary-500", children: intl.formatMessage(messages.editTeamTitle, { username: user.username }) }) }), _jsxs(ModalDialog.Body, { className: "position-relative overflow-auto", children: [_jsx("p", { children: intl.formatMessage(messages.editInstructions, { username: user.username }) }), _jsx(Form.CheckboxSet, { onChange: (e) => handleToggleRole(e.target.value), value: keepRoles, name: "keepRoles", children: (user.roles || [])
|
|
87
|
+
.map((role) => (_jsx(Form.Checkbox, { className: "mt-2", value: role.role, children: role.displayName }, role.role))) }), _jsx(FormLabel, { className: "mt-4", children: intl.formatMessage(messages.addRole) }), _jsx(FormControl, { as: "select", disabled: roles.length === 1, onChange: (e) => setSelectedRole(e.target.value), value: selectedRole, children: roles.map((role) => (_jsx("option", { value: role.role, children: role.displayName }, role.role))) })] }), _jsx(ModalDialog.Footer, { className: "border-light-700 border-top", children: _jsxs(ActionRow, { children: [_jsx(Button, { variant: "tertiary", onClick: onClose, children: intl.formatMessage(messages.cancelButton) }), _jsx(Button, { variant: "primary", onClick: handleSave, disabled: isAdding || isRemoving || (keepRoles.length === user.roles.length && !selectedRole), children: intl.formatMessage(messages.saveButton) })] }) })] }));
|
|
88
|
+
};
|
|
89
|
+
export default EditTeamMemberModal;
|
|
90
|
+
//# sourceMappingURL=EditTeamMemberModal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditTeamMemberModal.js","sourceRoot":"","sources":["../../../src/courseTeam/components/EditTeamMemberModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { ActionRow, Button, Form, FormControl, FormLabel, ModalDialog } from '@openedx/paragon';\nimport { useAddTeamMember, useRemoveTeamMember, useRoles } from '@src/courseTeam/data/apiHook';\nimport messages from '@src/courseTeam/messages';\nimport { CourseTeamMember, Role } from '@src/courseTeam/types';\nimport { useAlert } from '@src/providers/AlertProvider';\n\ninterface EditTeamMemberModalProps {\n isOpen: boolean,\n user: CourseTeamMember,\n onClose: () => void,\n}\n\nconst EditTeamMemberModal = ({ isOpen, user, onClose }: EditTeamMemberModalProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [selectedRole, setSelectedRole] = useState('');\n const [keepRoles, setKeepRoles] = useState<string[]>([]);\n const { mutate: addTeamMember, isPending: isAdding } = useAddTeamMember(courseId);\n const { mutate: removeTeamMember, isPending: isRemoving } = useRemoveTeamMember(courseId);\n const { showModal } = useAlert();\n\n const { data: { results } = { results: [] } } = useRoles(courseId);\n\n useEffect(() => {\n if (isOpen) {\n setKeepRoles(user.roles.map(role => role.role));\n setSelectedRole('');\n }\n }, [isOpen, user]);\n\n const filteredRoles = results?.filter(role => !user.roles.some(userRole => userRole.role === role.role)) || [];\n\n const roles = [{ role: '', displayName: intl.formatMessage(messages.rolePlaceholder) }, ...filteredRoles];\n\n const handleToggleRole = (roleName: string) => {\n if (keepRoles.includes(roleName)) {\n setKeepRoles(keepRoles.filter(role => role !== roleName));\n } else {\n setKeepRoles([...keepRoles, roleName]);\n }\n };\n\n const handleSave = () => {\n const rolesToRemove = user.roles.filter(role => !keepRoles.includes(role.role)).map(role => role.role);\n const hasRolesToAdd = selectedRole;\n const hasRolesToRemove = rolesToRemove.length > 0;\n\n // Sequential approach: remove roles first, then add new role\n if (hasRolesToRemove) {\n removeTeamMember({ identifier: user.username, roles: rolesToRemove }, {\n onSuccess: () => {\n // After successful removal, add new role if needed\n if (hasRolesToAdd) {\n addTeamMember({ identifiers: [user.username], role: selectedRole }, {\n onSuccess: () => {\n onClose();\n },\n onError: () => {\n showModal({\n message: intl.formatMessage(messages.addRoleError),\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n } else {\n onClose();\n }\n },\n onError: () => {\n showModal({\n message: intl.formatMessage(messages.removeTeamMemberError, { username: user.username }),\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n } else if (hasRolesToAdd) {\n // Only add operation needed\n addTeamMember({ identifiers: [user.username], role: selectedRole }, {\n onSuccess: () => {\n onClose();\n },\n onError: () => {\n showModal({\n message: intl.formatMessage(messages.addRoleError),\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n }\n };\n\n return (\n <ModalDialog\n isOpen={isOpen}\n title={intl.formatMessage(messages.editTeamTitle, { username: user.username })}\n onClose={onClose}\n isOverflowVisible={false}\n >\n <ModalDialog.Header className=\"border-light-700 border-bottom\">\n <h3 className=\"text-primary-500\">{intl.formatMessage(messages.editTeamTitle, { username: user.username })}</h3>\n </ModalDialog.Header>\n <ModalDialog.Body className=\"position-relative overflow-auto\">\n <p>{intl.formatMessage(messages.editInstructions, { username: user.username })}</p>\n <Form.CheckboxSet onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleToggleRole(e.target.value)} value={keepRoles} name=\"keepRoles\">\n {\n (user.roles || [])\n .map((role: Role) => (\n <Form.Checkbox className=\"mt-2\" key={role.role} value={role.role}>\n {role.displayName}\n </Form.Checkbox>\n ))\n }\n </Form.CheckboxSet>\n <FormLabel className=\"mt-4\">{intl.formatMessage(messages.addRole)}</FormLabel>\n <FormControl\n as=\"select\"\n disabled={roles.length === 1}\n onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setSelectedRole(e.target.value)}\n value={selectedRole}\n >\n {\n roles.map((role) => (\n <option key={role.role} value={role.role}>\n {role.displayName}\n </option>\n ))\n }\n </FormControl>\n </ModalDialog.Body>\n <ModalDialog.Footer className=\"border-light-700 border-top\">\n <ActionRow>\n <Button variant=\"tertiary\" onClick={onClose}>{intl.formatMessage(messages.cancelButton)}</Button>\n <Button variant=\"primary\" onClick={handleSave} disabled={isAdding || isRemoving || (keepRoles.length === user.roles.length && !selectedRole)}>\n {intl.formatMessage(messages.saveButton)}\n </Button>\n </ActionRow>\n </ModalDialog.Footer>\n </ModalDialog>\n );\n};\n\nexport default EditTeamMemberModal;\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CourseTeamMember } from '../../courseTeam/types';
|
|
2
|
+
interface MembersContentProps {
|
|
3
|
+
onEdit: (user: CourseTeamMember) => void;
|
|
4
|
+
}
|
|
5
|
+
declare const MembersContent: ({ onEdit }: MembersContentProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export default MembersContent;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useMemo } from 'react';
|
|
3
|
+
import { useParams } from 'react-router-dom';
|
|
4
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
+
import { Button, DataTable } from '@openedx/paragon';
|
|
6
|
+
import UsernameFilter from '../../components/UsernameFilter';
|
|
7
|
+
import RoleFilter from '../../courseTeam/components/RoleFilter';
|
|
8
|
+
import { useTeamMembers } from '../../courseTeam/data/apiHook';
|
|
9
|
+
import messages from '../../courseTeam/messages';
|
|
10
|
+
const TEAM_MEMBERS_PAGE_SIZE = 25;
|
|
11
|
+
const MembersContent = ({ onEdit }) => {
|
|
12
|
+
const intl = useIntl();
|
|
13
|
+
const { courseId = '' } = useParams();
|
|
14
|
+
const [filters, setFilters] = useState({ page: 0, emailOrUsername: '', role: '' });
|
|
15
|
+
const { data: { results: teamMembers = [], numPages = 1, count = 0 } = {}, isLoading = false } = useTeamMembers(courseId, Object.assign(Object.assign({}, filters), { pageSize: TEAM_MEMBERS_PAGE_SIZE }));
|
|
16
|
+
const tableColumns = useMemo(() => [
|
|
17
|
+
{ accessor: 'username', Header: intl.formatMessage(messages.username), Filter: UsernameFilter },
|
|
18
|
+
{ accessor: 'email', Header: intl.formatMessage(messages.email), disableFilters: true },
|
|
19
|
+
{ accessor: 'roles', Header: intl.formatMessage(messages.role), Cell: ({ cell: { value } }) => value.map(role => role.displayName).join(', '), Filter: RoleFilter },
|
|
20
|
+
], [intl]);
|
|
21
|
+
const additionalColumns = useMemo(() => [{
|
|
22
|
+
id: 'actions',
|
|
23
|
+
Header: intl.formatMessage(messages.actions),
|
|
24
|
+
Cell: ({ row }) => (_jsx(Button, { variant: "link", size: "inline", onClick: () => onEdit(row.original), children: intl.formatMessage(messages.edit) }))
|
|
25
|
+
}], [intl, onEdit]);
|
|
26
|
+
const handleFetchData = (data) => {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
const usernameFilter = (_a = data.filters) === null || _a === void 0 ? void 0 : _a.find((f) => f.id === 'username');
|
|
29
|
+
const newEmailOrUsername = usernameFilter ? usernameFilter.value : '';
|
|
30
|
+
const rolesFilter = (_b = data.filters) === null || _b === void 0 ? void 0 : _b.find((f) => f.id === 'roles');
|
|
31
|
+
const newRole = rolesFilter ? rolesFilter.value : '';
|
|
32
|
+
const filtersChanged = (newEmailOrUsername !== filters.emailOrUsername) || (newRole !== filters.role);
|
|
33
|
+
if (filtersChanged) {
|
|
34
|
+
setFilters((prevFilters) => (Object.assign(Object.assign({}, prevFilters), { emailOrUsername: newEmailOrUsername, role: newRole, page: 0 })));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (data.pageIndex !== filters.page) {
|
|
38
|
+
setFilters((prevFilters) => (Object.assign(Object.assign({}, prevFilters), { page: data.pageIndex })));
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const tableState = useMemo(() => ({
|
|
42
|
+
pageIndex: filters.page,
|
|
43
|
+
pageSize: TEAM_MEMBERS_PAGE_SIZE,
|
|
44
|
+
}), [filters.page]);
|
|
45
|
+
return (_jsxs(DataTable, { additionalColumns: additionalColumns, columns: tableColumns, data: teamMembers, fetchData: handleFetchData, state: tableState, isFilterable: true, isLoading: isLoading, isPaginated: true, itemCount: count, manualFilters: true, manualPagination: true, numBreakoutFilters: 2, pageSize: TEAM_MEMBERS_PAGE_SIZE, pageCount: numPages, RowStatusComponent: () => null, children: [_jsx(DataTable.TableControlBar, {}), _jsx(DataTable.Table, {}), _jsx(DataTable.EmptyTable, { content: intl.formatMessage(messages.noTeamMembers) }), _jsx(DataTable.TableFooter, {})] }));
|
|
46
|
+
};
|
|
47
|
+
export default MembersContent;
|
|
48
|
+
//# sourceMappingURL=MembersContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MembersContent.js","sourceRoot":"","sources":["../../../src/courseTeam/components/MembersContent.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState, useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, DataTable } from '@openedx/paragon';\nimport UsernameFilter from '@src/components/UsernameFilter';\nimport RoleFilter from '@src/courseTeam/components/RoleFilter';\nimport { useTeamMembers } from '@src/courseTeam/data/apiHook';\nimport messages from '@src/courseTeam/messages';\nimport { CourseTeamMember, Role } from '@src/courseTeam/types';\nimport { DataTableFetchDataProps } from '@src/types';\n\nconst TEAM_MEMBERS_PAGE_SIZE = 25;\n\ninterface MembersContentProps {\n onEdit: (user: CourseTeamMember) => void,\n}\n\nconst MembersContent = ({ onEdit }: MembersContentProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [filters, setFilters] = useState({ page: 0, emailOrUsername: '', role: '' });\n const { data: { results: teamMembers = [], numPages = 1, count = 0 } = {}, isLoading = false } = useTeamMembers(courseId, { ...filters, pageSize: TEAM_MEMBERS_PAGE_SIZE });\n\n const tableColumns = useMemo(() => [\n { accessor: 'username', Header: intl.formatMessage(messages.username), Filter: UsernameFilter },\n { accessor: 'email', Header: intl.formatMessage(messages.email), disableFilters: true },\n { accessor: 'roles', Header: intl.formatMessage(messages.role), Cell: ({ cell: { value } }: { cell: { value: Role[] } }) => value.map(role => role.displayName).join(', '), Filter: RoleFilter },\n ], [intl]);\n\n const additionalColumns = useMemo(() => [{\n id: 'actions',\n Header: intl.formatMessage(messages.actions),\n Cell: ({ row }: { row: { original: any } }) => (\n <Button variant=\"link\" size=\"inline\" onClick={() => onEdit(row.original)}>\n {intl.formatMessage(messages.edit)}\n </Button>\n )\n }], [intl, onEdit]);\n\n const handleFetchData = (data: DataTableFetchDataProps) => {\n const usernameFilter = data.filters?.find((f) => f.id === 'username');\n const newEmailOrUsername = usernameFilter ? usernameFilter.value : '';\n const rolesFilter = data.filters?.find((f) => f.id === 'roles');\n const newRole = rolesFilter ? rolesFilter.value : '';\n const filtersChanged = (newEmailOrUsername !== filters.emailOrUsername) || (newRole !== filters.role);\n\n if (filtersChanged) {\n setFilters((prevFilters) => ({\n ...prevFilters,\n emailOrUsername: newEmailOrUsername,\n role: newRole,\n page: 0,\n }));\n return;\n }\n\n if (data.pageIndex !== filters.page) {\n setFilters((prevFilters) => ({ ...prevFilters, page: data.pageIndex }));\n }\n };\n\n const tableState = useMemo(() => ({\n pageIndex: filters.page,\n pageSize: TEAM_MEMBERS_PAGE_SIZE,\n }), [filters.page]);\n\n return (\n <DataTable\n additionalColumns={additionalColumns}\n columns={tableColumns}\n data={teamMembers}\n fetchData={handleFetchData}\n state={tableState}\n isFilterable\n isLoading={isLoading}\n isPaginated\n itemCount={count}\n manualFilters\n manualPagination\n numBreakoutFilters={2}\n pageSize={TEAM_MEMBERS_PAGE_SIZE}\n pageCount={numPages}\n RowStatusComponent={() => null}\n >\n <DataTable.TableControlBar />\n <DataTable.Table />\n <DataTable.EmptyTable content={intl.formatMessage(messages.noTeamMembers)} />\n <DataTable.TableFooter />\n </DataTable>\n );\n};\n\nexport default MembersContent;\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { useParams } from 'react-router-dom';
|
|
4
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
+
import { FormControl, Icon } from '@openedx/paragon';
|
|
6
|
+
import { FilterList } from '@openedx/paragon/icons';
|
|
7
|
+
import { useRoles } from '../../courseTeam/data/apiHook';
|
|
8
|
+
import messages from '../../courseTeam/messages';
|
|
9
|
+
const RoleFilter = ({ column: { filterValue, setFilter } }) => {
|
|
10
|
+
const intl = useIntl();
|
|
11
|
+
const { courseId = '' } = useParams();
|
|
12
|
+
const { data } = useRoles(courseId);
|
|
13
|
+
const handleSelectChange = (e) => {
|
|
14
|
+
setFilter(e.target.value);
|
|
15
|
+
};
|
|
16
|
+
const roles = useMemo(() => {
|
|
17
|
+
return [{ value: '', label: intl.formatMessage(messages.allRoles) }, ...((data === null || data === void 0 ? void 0 : data.results) || []).map((role) => ({ value: role.role, label: role.displayName }))];
|
|
18
|
+
}, [data, intl]);
|
|
19
|
+
return (_jsx(FormControl, { as: "select", className: "mb-0", disabled: !data, name: "role", size: "md", value: filterValue, onChange: handleSelectChange, leadingElement: _jsx(Icon, { src: FilterList }), children: roles.map(role => (_jsx("option", { value: role.value, children: role.label }, role.value))) }));
|
|
20
|
+
};
|
|
21
|
+
export default RoleFilter;
|
|
22
|
+
//# sourceMappingURL=RoleFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoleFilter.js","sourceRoot":"","sources":["../../../src/courseTeam/components/RoleFilter.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,QAAQ,MAAM,0BAA0B,CAAC;AAGhD,MAAM,UAAU,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,EAA2E,EAAE,EAAE;IACrI,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,SAAS,EAAwB,CAAC;IAC5D,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEpC,MAAM,kBAAkB,GAAG,CAAC,CAAuC,EAAE,EAAE;QACrE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE;QACzB,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,KAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAU,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IACtK,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAEjB,OAAO,CACL,KAAC,WAAW,IACV,EAAE,EAAC,QAAQ,EACX,SAAS,EAAC,MAAM,EAChB,QAAQ,EAAE,CAAC,IAAI,EACf,IAAI,EAAC,MAAM,EACX,IAAI,EAAC,IAAI,EACT,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,kBAAkB,EAC5B,cAAc,EAAE,KAAC,IAAI,IAAC,GAAG,EAAE,UAAU,GAAI,YAExC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CACjB,iBAAyB,KAAK,EAAE,IAAI,CAAC,KAAK,YACvC,IAAI,CAAC,KAAK,IADA,IAAI,CAAC,KAAK,CAEd,CACV,CAAC,GACU,CACf,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC","sourcesContent":["import { useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { FormControl, Icon } from '@openedx/paragon';\nimport { FilterList } from '@openedx/paragon/icons';\nimport { useRoles } from '@src/courseTeam/data/apiHook';\nimport messages from '@src/courseTeam/messages';\nimport { Role } from '@src/courseTeam/types';\n\nconst RoleFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const { data } = useRoles(courseId);\n\n const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n setFilter(e.target.value);\n };\n\n const roles = useMemo(() => {\n return [{ value: '', label: intl.formatMessage(messages.allRoles) }, ...(data?.results || []).map((role: Role) => ({ value: role.role, label: role.displayName }))];\n }, [data, intl]);\n\n return (\n <FormControl\n as=\"select\"\n className=\"mb-0\"\n disabled={!data}\n name=\"role\"\n size=\"md\"\n value={filterValue}\n onChange={handleSelectChange}\n leadingElement={<Icon src={FilterList} />}\n >\n {roles.map(role => (\n <option key={role.value} value={role.value}>\n {role.label}\n </option>\n ))}\n </FormControl>\n );\n};\n\nexport default RoleFilter;\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const rolesOrder: readonly ["staff", "limitedStaff", "admin", "beta", "courseDataResearchers", "discussionAdmin", "discussionModerator", "groupCommunityTA", "communityTA"];
|
|
2
|
+
declare const RolesContent: () => import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export default RolesContent;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useParams } from 'react-router-dom';
|
|
3
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
4
|
+
import messages from '../../courseTeam/messages';
|
|
5
|
+
import { useRoles } from '../../courseTeam/data/apiHook';
|
|
6
|
+
export const rolesOrder = [
|
|
7
|
+
'staff',
|
|
8
|
+
'limitedStaff',
|
|
9
|
+
'admin',
|
|
10
|
+
'beta',
|
|
11
|
+
'courseDataResearchers',
|
|
12
|
+
'discussionAdmin',
|
|
13
|
+
'discussionModerator',
|
|
14
|
+
'groupCommunityTA',
|
|
15
|
+
'communityTA'
|
|
16
|
+
];
|
|
17
|
+
const RolesContent = () => {
|
|
18
|
+
const intl = useIntl();
|
|
19
|
+
const { courseId = '' } = useParams();
|
|
20
|
+
const { data: { results } = { results: [] } } = useRoles(courseId);
|
|
21
|
+
const isCCXCoachEnabled = !!(results === null || results === void 0 ? void 0 : results.find(({ role }) => role === 'ccx_coach'));
|
|
22
|
+
return (_jsxs("div", { className: "mt-4", children: [rolesOrder.map((role) => (_jsxs("div", { className: "mb-4", children: [_jsx("h4", { className: "text-primary-500", children: intl.formatMessage(messages[role]) }), _jsx("p", { className: "text-gray-700", children: intl.formatMessage(messages[`${role}Description`]) })] }, role))), isCCXCoachEnabled && (_jsxs("div", { className: "mb-4", children: [_jsx("h4", { className: "text-primary-500", children: intl.formatMessage(messages.ccxCoach) }), _jsx("p", { className: "text-gray-700", children: intl.formatMessage(messages.ccxCoachDescription) })] }))] }));
|
|
23
|
+
};
|
|
24
|
+
export default RolesContent;
|
|
25
|
+
//# sourceMappingURL=RolesContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RolesContent.js","sourceRoot":"","sources":["../../../src/courseTeam/components/RolesContent.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,QAAQ,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAGxD,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,OAAO;IACP,cAAc;IACd,OAAO;IACP,MAAM;IACN,uBAAuB;IACvB,iBAAiB;IACjB,qBAAqB;IACrB,kBAAkB;IAClB,aAAa;CACL,CAAC;AAEX,MAAM,YAAY,GAAG,GAAG,EAAE;IACxB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,SAAS,EAAwB,CAAC;IAC5D,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnE,MAAM,iBAAiB,GAAG,CAAC,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAQ,EAAE,EAAE,CAAC,IAAI,KAAK,WAAW,CAAC,CAAA,CAAC;IAEpF,OAAO,CACL,eAAK,SAAS,EAAC,MAAM,aAEjB,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACvB,eAAgB,SAAS,EAAC,MAAM,aAC9B,aAAI,SAAS,EAAC,kBAAkB,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAM,EAC1E,YAAG,SAAS,EAAC,eAAe,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,IAAI,aAAa,CAAC,CAAC,GAAK,KAF7E,IAAI,CAGR,CACP,CAAC,EAGF,iBAAiB,IAAI,CACnB,eAAK,SAAS,EAAC,MAAM,aACnB,aAAI,SAAS,EAAC,kBAAkB,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAM,EAC7E,YAAG,SAAS,EAAC,eAAe,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,mBAAmB,CAAC,GAAK,IAC/E,CACP,IAEC,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,YAAY,CAAC","sourcesContent":["import { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport messages from '@src/courseTeam/messages';\nimport { useRoles } from '@src/courseTeam/data/apiHook';\nimport { Role } from '@src/courseTeam/types';\n\nexport const rolesOrder = [\n 'staff',\n 'limitedStaff',\n 'admin',\n 'beta',\n 'courseDataResearchers',\n 'discussionAdmin',\n 'discussionModerator',\n 'groupCommunityTA',\n 'communityTA'\n] as const;\n\nconst RolesContent = () => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const { data: { results } = { results: [] } } = useRoles(courseId);\n const isCCXCoachEnabled = !!results?.find(({ role }: Role) => role === 'ccx_coach');\n\n return (\n <div className=\"mt-4\">\n {\n rolesOrder.map((role) => (\n <div key={role} className=\"mb-4\">\n <h4 className=\"text-primary-500\">{intl.formatMessage(messages[role])}</h4>\n <p className=\"text-gray-700\">{intl.formatMessage(messages[`${role}Description`])}</p>\n </div>\n ))\n }\n {\n isCCXCoachEnabled && (\n <div className=\"mb-4\">\n <h4 className=\"text-primary-500\">{intl.formatMessage(messages.ccxCoach)}</h4>\n <p className=\"text-gray-700\">{intl.formatMessage(messages.ccxCoachDescription)}</p>\n </div>\n )\n }\n </div>\n );\n};\n\nexport default RolesContent;\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DataList } from '../../types';
|
|
2
|
+
import { TeamMembersResponse, CourseTeamMember, CourseTeamMemberQueryParams, Role } from '../../courseTeam/types';
|
|
3
|
+
export declare const getTeamMembers: (courseId: string, params: CourseTeamMemberQueryParams) => Promise<DataList<CourseTeamMember>>;
|
|
4
|
+
export declare const getRoles: (courseId: string) => Promise<Omit<DataList<Role>, "numPages" | "count">>;
|
|
5
|
+
export declare const addTeamMember: (courseId: string, identifiers: string[], role: string) => Promise<TeamMembersResponse>;
|
|
6
|
+
export declare const removeTeamMember: (courseId: string, identifier: string, roles: string[]) => Promise<TeamMembersResponse>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { camelCaseObject, getAuthenticatedHttpClient } from '@openedx/frontend-base';
|
|
11
|
+
import { getApiBaseUrl } from '../../data/api';
|
|
12
|
+
export const getTeamMembers = (courseId, params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
const queryParams = new URLSearchParams({
|
|
14
|
+
page: (params.page + 1).toString(),
|
|
15
|
+
page_size: params.pageSize.toString(),
|
|
16
|
+
});
|
|
17
|
+
if (params.emailOrUsername) {
|
|
18
|
+
queryParams.append('email_or_username', params.emailOrUsername);
|
|
19
|
+
}
|
|
20
|
+
if (params.role) {
|
|
21
|
+
queryParams.append('role', params.role);
|
|
22
|
+
}
|
|
23
|
+
const { data } = yield getAuthenticatedHttpClient().get(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team?${queryParams.toString()}`);
|
|
24
|
+
return camelCaseObject(data);
|
|
25
|
+
});
|
|
26
|
+
export const getRoles = (courseId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
|
+
const { data } = yield getAuthenticatedHttpClient().get(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team/roles`);
|
|
28
|
+
return camelCaseObject(data);
|
|
29
|
+
});
|
|
30
|
+
export const addTeamMember = (courseId, identifiers, role) => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
|
+
const { data } = yield getAuthenticatedHttpClient().post(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team`, { identifiers, role });
|
|
32
|
+
return camelCaseObject(data);
|
|
33
|
+
});
|
|
34
|
+
export const removeTeamMember = (courseId, identifier, roles) => __awaiter(void 0, void 0, void 0, function* () {
|
|
35
|
+
const { data } = yield getAuthenticatedHttpClient().delete(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team/${identifier}`, { data: { roles } });
|
|
36
|
+
return camelCaseObject(data);
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/courseTeam/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI9C,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,QAAgB,EAChB,MAAmC,EACE,EAAE;IACvC,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC;QACtC,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;QAClC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE;KACtC,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,WAAW,CAAC,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,SAAS,WAAW,CAAC,QAAQ,EAAE,EAAE,CAC1F,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAO,QAAgB,EAAuD,EAAE;IACtG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,aAAa,CACtE,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,QAAgB,EAAE,WAAqB,EAAE,IAAY,EAAgC,EAAE;IACzH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,IAAI,CACtD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,OAAO,EAC/D,EAAE,WAAW,EAAE,IAAI,EAAE,CACtB,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAO,QAAgB,EAAE,UAAkB,EAAE,KAAe,EAAgC,EAAE;IAC5H,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,MAAM,CACxD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,SAAS,UAAU,EAAE,EAC7E,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,CACpB,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC","sourcesContent":["import { camelCaseObject, getAuthenticatedHttpClient } from '@openedx/frontend-base';\nimport { getApiBaseUrl } from '@src/data/api';\nimport { DataList } from '@src/types';\nimport { TeamMembersResponse, CourseTeamMember, CourseTeamMemberQueryParams, Role } from '@src/courseTeam/types';\n\nexport const getTeamMembers = async (\n courseId: string,\n params: CourseTeamMemberQueryParams\n): Promise<DataList<CourseTeamMember>> => {\n const queryParams = new URLSearchParams({\n page: (params.page + 1).toString(),\n page_size: params.pageSize.toString(),\n });\n\n if (params.emailOrUsername) {\n queryParams.append('email_or_username', params.emailOrUsername);\n }\n\n if (params.role) {\n queryParams.append('role', params.role);\n }\n\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team?${queryParams.toString()}`\n );\n return camelCaseObject(data);\n};\n\nexport const getRoles = async (courseId: string): Promise<Omit<DataList<Role>, 'numPages' | 'count'>> => {\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team/roles`\n );\n return camelCaseObject(data);\n};\n\nexport const addTeamMember = async (courseId: string, identifiers: string[], role: string): Promise<TeamMembersResponse> => {\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team`,\n { identifiers, role }\n );\n return camelCaseObject(data);\n};\n\nexport const removeTeamMember = async (courseId: string, identifier: string, roles: string[]): Promise<TeamMembersResponse> => {\n const { data } = await getAuthenticatedHttpClient().delete(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team/${identifier}`,\n { data: { roles } }\n );\n return camelCaseObject(data);\n};\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CourseTeamMemberQueryParams } from '../../courseTeam/types';
|
|
2
|
+
export declare const useTeamMembers: (courseId: string, params: CourseTeamMemberQueryParams) => import("@tanstack/react-query").UseQueryResult<import("../../types").DataList<import("../../courseTeam/types").CourseTeamMember>, Error>;
|
|
3
|
+
export declare const useRoles: (courseId: string) => import("@tanstack/react-query").UseQueryResult<Omit<import("../../types").DataList<import("../../courseTeam/types").Role>, "count" | "numPages">, Error>;
|
|
4
|
+
export declare const useAddTeamMember: (courseId: string) => import("@tanstack/react-query").UseMutationResult<import("../../courseTeam/types").TeamMembersResponse, Error, {
|
|
5
|
+
identifiers: string[];
|
|
6
|
+
role: string;
|
|
7
|
+
}, unknown>;
|
|
8
|
+
export declare const useRemoveTeamMember: (courseId: string) => import("@tanstack/react-query").UseMutationResult<import("../../courseTeam/types").TeamMembersResponse, Error, {
|
|
9
|
+
identifier: string;
|
|
10
|
+
roles: string[];
|
|
11
|
+
}, unknown>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
2
|
+
import { addTeamMember, getRoles, getTeamMembers, removeTeamMember } from '../../courseTeam/data/api';
|
|
3
|
+
import { courseTeamQueryKeys } from '../../courseTeam/data/queryKeys';
|
|
4
|
+
export const useTeamMembers = (courseId, params) => (useQuery({
|
|
5
|
+
queryKey: courseTeamQueryKeys.byCoursePaginated(courseId, params),
|
|
6
|
+
queryFn: () => getTeamMembers(courseId, params),
|
|
7
|
+
enabled: !!courseId,
|
|
8
|
+
}));
|
|
9
|
+
export const useRoles = (courseId) => (useQuery({
|
|
10
|
+
queryKey: courseTeamQueryKeys.roles(courseId),
|
|
11
|
+
queryFn: () => getRoles(courseId),
|
|
12
|
+
enabled: !!courseId,
|
|
13
|
+
}));
|
|
14
|
+
export const useAddTeamMember = (courseId) => {
|
|
15
|
+
const queryClient = useQueryClient();
|
|
16
|
+
return (useMutation({
|
|
17
|
+
mutationFn: ({ identifiers, role }) => addTeamMember(courseId, identifiers, role),
|
|
18
|
+
onSuccess: () => {
|
|
19
|
+
queryClient.invalidateQueries({ queryKey: courseTeamQueryKeys.byCourse(courseId) });
|
|
20
|
+
}
|
|
21
|
+
}));
|
|
22
|
+
};
|
|
23
|
+
export const useRemoveTeamMember = (courseId) => {
|
|
24
|
+
const queryClient = useQueryClient();
|
|
25
|
+
return (useMutation({
|
|
26
|
+
mutationFn: ({ identifier, roles }) => removeTeamMember(courseId, identifier, roles),
|
|
27
|
+
onSuccess: () => {
|
|
28
|
+
queryClient.invalidateQueries({ queryKey: courseTeamQueryKeys.byCourse(courseId) });
|
|
29
|
+
}
|
|
30
|
+
}));
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=apiHook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/courseTeam/data/apiHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACrG,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAGrE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAgB,EAAE,MAAmC,EAAE,EAAE,CAAC,CACvF,QAAQ,CAAC;IACP,QAAQ,EAAE,mBAAmB,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC;IACjE,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC/C,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,CAC5C,QAAQ,CAAC;IACP,QAAQ,EAAE,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7C,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACjC,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACnD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,CAAC,WAAW,CAAC;QAClB,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,EAA2C,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC;QAC1H,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACtF,CAAC;KACF,CAAC,CACD,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACtD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,CAAC,WAAW,CAAC;QAClB,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,EAA2C,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC;QAC7H,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACtF,CAAC;KACF,CAAC,CACD,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { addTeamMember, getRoles, getTeamMembers, removeTeamMember } from '@src/courseTeam/data/api';\nimport { courseTeamQueryKeys } from '@src/courseTeam/data/queryKeys';\nimport { CourseTeamMemberQueryParams } from '@src/courseTeam/types';\n\nexport const useTeamMembers = (courseId: string, params: CourseTeamMemberQueryParams) => (\n useQuery({\n queryKey: courseTeamQueryKeys.byCoursePaginated(courseId, params),\n queryFn: () => getTeamMembers(courseId, params),\n enabled: !!courseId,\n })\n);\n\nexport const useRoles = (courseId: string) => (\n useQuery({\n queryKey: courseTeamQueryKeys.roles(courseId),\n queryFn: () => getRoles(courseId),\n enabled: !!courseId,\n })\n);\n\nexport const useAddTeamMember = (courseId: string) => {\n const queryClient = useQueryClient();\n return (useMutation({\n mutationFn: ({ identifiers, role }: { identifiers: string[], role: string }) => addTeamMember(courseId, identifiers, role),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: courseTeamQueryKeys.byCourse(courseId) });\n }\n })\n );\n};\n\nexport const useRemoveTeamMember = (courseId: string) => {\n const queryClient = useQueryClient();\n return (useMutation({\n mutationFn: ({ identifier, roles }: { identifier: string, roles: string[] }) => removeTeamMember(courseId, identifier, roles),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: courseTeamQueryKeys.byCourse(courseId) });\n }\n })\n );\n};\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CourseTeamMemberQueryParams } from '../../courseTeam/types';
|
|
2
|
+
export declare const courseTeamQueryKeys: {
|
|
3
|
+
all: readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam"];
|
|
4
|
+
byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam", string];
|
|
5
|
+
byCoursePaginated: (courseId: string, params: CourseTeamMemberQueryParams) => readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam", string, number, number, string, string];
|
|
6
|
+
roles: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam", string, "roles"];
|
|
7
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { appId } from '../../constants';
|
|
2
|
+
export const courseTeamQueryKeys = {
|
|
3
|
+
all: [appId, 'courseTeam'],
|
|
4
|
+
byCourse: (courseId) => [...courseTeamQueryKeys.all, courseId],
|
|
5
|
+
byCoursePaginated: (courseId, params) => [
|
|
6
|
+
...courseTeamQueryKeys.byCourse(courseId),
|
|
7
|
+
params.page,
|
|
8
|
+
params.pageSize,
|
|
9
|
+
params.emailOrUsername || '',
|
|
10
|
+
params.role || ''
|
|
11
|
+
],
|
|
12
|
+
roles: (courseId) => [...courseTeamQueryKeys.byCourse(courseId), 'roles'],
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=queryKeys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../../src/courseTeam/data/queryKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,EAAE,CAAC,KAAK,EAAE,YAAY,CAAU;IACnC,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,mBAAmB,CAAC,GAAG,EAAE,QAAQ,CAAU;IAC/E,iBAAiB,EAAE,CACjB,QAAgB,EAChB,MAAmC,EACnC,EAAE,CAAC;QACH,GAAG,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACzC,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,QAAQ;QACf,MAAM,CAAC,eAAe,IAAI,EAAE;QAC5B,MAAM,CAAC,IAAI,IAAI,EAAE;KACT;IACV,KAAK,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAU;CAC3F,CAAC","sourcesContent":["import { appId } from '@src/constants';\nimport { CourseTeamMemberQueryParams } from '@src/courseTeam/types';\n\nexport const courseTeamQueryKeys = {\n all: [appId, 'courseTeam'] as const,\n byCourse: (courseId: string) => [...courseTeamQueryKeys.all, courseId] as const,\n byCoursePaginated: (\n courseId: string,\n params: CourseTeamMemberQueryParams\n ) => [\n ...courseTeamQueryKeys.byCourse(courseId),\n params.page,\n params.pageSize,\n params.emailOrUsername || '',\n params.role || ''\n ] as const,\n roles: (courseId: string) => [...courseTeamQueryKeys.byCourse(courseId), 'roles'] as const,\n};\n"]}
|