@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.
Files changed (261) hide show
  1. package/dist/Main.d.ts +1 -1
  2. package/dist/Main.js +4 -13
  3. package/dist/Main.js.map +1 -1
  4. package/dist/app.js +2 -11
  5. package/dist/app.js.map +1 -1
  6. package/dist/certificates/CertificatesPage.d.ts +1 -0
  7. package/dist/certificates/CertificatesPage.js +162 -2
  8. package/dist/certificates/CertificatesPage.js.map +1 -1
  9. package/dist/certificates/CertificatesPage.scss +81 -0
  10. package/dist/certificates/components/CertificateTable.d.ts +14 -0
  11. package/dist/certificates/components/CertificateTable.js +85 -0
  12. package/dist/certificates/components/CertificateTable.js.map +1 -0
  13. package/dist/certificates/components/CertificatesPageHeader.d.ts +7 -0
  14. package/dist/certificates/components/CertificatesPageHeader.js +11 -0
  15. package/dist/certificates/components/CertificatesPageHeader.js.map +1 -0
  16. package/dist/certificates/components/CertificatesToolbar.d.ts +10 -0
  17. package/dist/certificates/components/CertificatesToolbar.js +12 -0
  18. package/dist/certificates/components/CertificatesToolbar.js.map +1 -0
  19. package/dist/certificates/components/DisableCertificatesModal.d.ts +9 -0
  20. package/dist/certificates/components/DisableCertificatesModal.js +16 -0
  21. package/dist/certificates/components/DisableCertificatesModal.js.map +1 -0
  22. package/dist/certificates/components/FilterDropdown.d.ts +8 -0
  23. package/dist/certificates/components/FilterDropdown.js +50 -0
  24. package/dist/certificates/components/FilterDropdown.js.map +1 -0
  25. package/dist/certificates/components/GenerationHistoryTable.d.ts +11 -0
  26. package/dist/certificates/components/GenerationHistoryTable.js +40 -0
  27. package/dist/certificates/components/GenerationHistoryTable.js.map +1 -0
  28. package/dist/certificates/components/GrantExceptionsModal.d.ts +8 -0
  29. package/dist/certificates/components/GrantExceptionsModal.js +10 -0
  30. package/dist/certificates/components/GrantExceptionsModal.js.map +1 -0
  31. package/dist/certificates/components/InvalidateCertificateModal.d.ts +8 -0
  32. package/dist/certificates/components/InvalidateCertificateModal.js +10 -0
  33. package/dist/certificates/components/InvalidateCertificateModal.js.map +1 -0
  34. package/dist/certificates/components/IssuedCertificatesTab.d.ts +18 -0
  35. package/dist/certificates/components/IssuedCertificatesTab.js +6 -0
  36. package/dist/certificates/components/IssuedCertificatesTab.js.map +1 -0
  37. package/dist/certificates/components/LearnerActionModal.d.ts +16 -0
  38. package/dist/certificates/components/LearnerActionModal.js +22 -0
  39. package/dist/certificates/components/LearnerActionModal.js.map +1 -0
  40. package/dist/certificates/components/RemoveInvalidationModal.d.ts +9 -0
  41. package/dist/certificates/components/RemoveInvalidationModal.js +10 -0
  42. package/dist/certificates/components/RemoveInvalidationModal.js.map +1 -0
  43. package/dist/certificates/constants.d.ts +15 -0
  44. package/dist/certificates/constants.js +16 -0
  45. package/dist/certificates/constants.js.map +1 -0
  46. package/dist/certificates/data/api.d.ts +9 -0
  47. package/dist/certificates/data/api.js +63 -0
  48. package/dist/certificates/data/api.js.map +1 -0
  49. package/dist/certificates/data/apiHook.d.ts +30 -0
  50. package/dist/certificates/data/apiHook.js +90 -0
  51. package/dist/certificates/data/apiHook.js.map +1 -0
  52. package/dist/certificates/data/dummyData.d.ts +2 -0
  53. package/dist/certificates/data/dummyData.js +234 -0
  54. package/dist/certificates/data/dummyData.js.map +1 -0
  55. package/dist/certificates/data/queryKeys.d.ts +8 -0
  56. package/dist/certificates/data/queryKeys.js +8 -0
  57. package/dist/certificates/data/queryKeys.js.map +1 -0
  58. package/dist/certificates/messages.d.ts +313 -0
  59. package/dist/certificates/messages.js +315 -0
  60. package/dist/certificates/messages.js.map +1 -0
  61. package/dist/certificates/types.d.ts +61 -0
  62. package/dist/certificates/types.js +26 -0
  63. package/dist/certificates/types.js.map +1 -0
  64. package/dist/certificates/utils/errorHandling.d.ts +10 -0
  65. package/dist/certificates/utils/errorHandling.js +3 -0
  66. package/dist/certificates/utils/errorHandling.js.map +1 -0
  67. package/dist/certificates/utils/filterUtils.d.ts +4 -0
  68. package/dist/certificates/utils/filterUtils.js +31 -0
  69. package/dist/certificates/utils/filterUtils.js.map +1 -0
  70. package/dist/certificates/utils/index.d.ts +2 -0
  71. package/dist/certificates/utils/index.js +2 -0
  72. package/dist/certificates/utils/index.js.map +1 -0
  73. package/dist/cohorts/data/queryKeys.d.ts +4 -4
  74. package/dist/components/ActionCard.d.ts +2 -2
  75. package/dist/components/ActionCard.js +1 -1
  76. package/dist/components/ActionCard.js.map +1 -1
  77. package/dist/components/PendingTasks.d.ts +3 -1
  78. package/dist/components/PendingTasks.js +3 -2
  79. package/dist/components/PendingTasks.js.map +1 -1
  80. package/dist/components/SpecifyLearnerField.d.ts +4 -1
  81. package/dist/components/SpecifyLearnerField.js +24 -10
  82. package/dist/components/SpecifyLearnerField.js.map +1 -1
  83. package/dist/components/SpecifyProblemField.d.ts +13 -0
  84. package/dist/components/SpecifyProblemField.js +46 -0
  85. package/dist/components/SpecifyProblemField.js.map +1 -0
  86. package/dist/components/UsernameFilter.d.ts +7 -0
  87. package/dist/components/UsernameFilter.js +19 -0
  88. package/dist/components/UsernameFilter.js.map +1 -0
  89. package/dist/components/messages.d.ts +30 -0
  90. package/dist/components/messages.js +30 -0
  91. package/dist/components/messages.js.map +1 -1
  92. package/dist/constants.d.ts +2 -1
  93. package/dist/constants.js +2 -1
  94. package/dist/constants.js.map +1 -1
  95. package/dist/courseInfo/types.d.ts +2 -0
  96. package/dist/courseInfo/types.js.map +1 -1
  97. package/dist/courseTeam/CourseTeamPage.js +20 -2
  98. package/dist/courseTeam/CourseTeamPage.js.map +1 -1
  99. package/dist/courseTeam/components/AddTeamMemberModal.d.ts +6 -0
  100. package/dist/courseTeam/components/AddTeamMemberModal.js +60 -0
  101. package/dist/courseTeam/components/AddTeamMemberModal.js.map +1 -0
  102. package/dist/courseTeam/components/EditTeamMemberModal.d.ts +8 -0
  103. package/dist/courseTeam/components/EditTeamMemberModal.js +90 -0
  104. package/dist/courseTeam/components/EditTeamMemberModal.js.map +1 -0
  105. package/dist/courseTeam/components/MembersContent.d.ts +6 -0
  106. package/dist/courseTeam/components/MembersContent.js +48 -0
  107. package/dist/courseTeam/components/MembersContent.js.map +1 -0
  108. package/dist/courseTeam/components/RoleFilter.d.ts +7 -0
  109. package/dist/courseTeam/components/RoleFilter.js +22 -0
  110. package/dist/courseTeam/components/RoleFilter.js.map +1 -0
  111. package/dist/courseTeam/components/RolesContent.d.ts +3 -0
  112. package/dist/courseTeam/components/RolesContent.js +25 -0
  113. package/dist/courseTeam/components/RolesContent.js.map +1 -0
  114. package/dist/courseTeam/data/api.d.ts +6 -0
  115. package/dist/courseTeam/data/api.js +38 -0
  116. package/dist/courseTeam/data/api.js.map +1 -0
  117. package/dist/courseTeam/data/apiHook.d.ts +11 -0
  118. package/dist/courseTeam/data/apiHook.js +32 -0
  119. package/dist/courseTeam/data/apiHook.js.map +1 -0
  120. package/dist/courseTeam/data/queryKeys.d.ts +7 -0
  121. package/dist/courseTeam/data/queryKeys.js +14 -0
  122. package/dist/courseTeam/data/queryKeys.js.map +1 -0
  123. package/dist/courseTeam/messages.d.ts +243 -0
  124. package/dist/courseTeam/messages.js +245 -0
  125. package/dist/courseTeam/messages.js.map +1 -0
  126. package/dist/courseTeam/types.d.ts +22 -0
  127. package/dist/courseTeam/types.js +3 -0
  128. package/dist/courseTeam/types.js.map +1 -0
  129. package/dist/data/api.d.ts +2 -1
  130. package/dist/data/api.js +9 -3
  131. package/dist/data/api.js.map +1 -1
  132. package/dist/data/apiHook.d.ts +1 -0
  133. package/dist/data/apiHook.js +10 -2
  134. package/dist/data/apiHook.js.map +1 -1
  135. package/dist/data/queryKeys.d.ts +10 -6
  136. package/dist/data/queryKeys.js +4 -0
  137. package/dist/data/queryKeys.js.map +1 -1
  138. package/dist/dataDownloads/data/queryKeys.d.ts +3 -3
  139. package/dist/dateExtensions/components/AddExtensionModal.d.ts +1 -1
  140. package/dist/dateExtensions/components/AddExtensionModal.js +5 -6
  141. package/dist/dateExtensions/components/AddExtensionModal.js.map +1 -1
  142. package/dist/dateExtensions/components/DateExtensionsList.js +2 -13
  143. package/dist/dateExtensions/components/DateExtensionsList.js.map +1 -1
  144. package/dist/dateExtensions/data/apiHook.d.ts +2 -2
  145. package/dist/dateExtensions/data/apiHook.js +4 -4
  146. package/dist/dateExtensions/data/apiHook.js.map +1 -1
  147. package/dist/dateExtensions/data/queryKeys.d.ts +5 -5
  148. package/dist/dateExtensions/messages.d.ts +0 -5
  149. package/dist/dateExtensions/messages.js +1 -6
  150. package/dist/dateExtensions/messages.js.map +1 -1
  151. package/dist/enrollments/EnrollmentsPage.js +41 -7
  152. package/dist/enrollments/EnrollmentsPage.js.map +1 -1
  153. package/dist/enrollments/components/AddBetaTestersModal.d.ts +6 -0
  154. package/dist/enrollments/components/AddBetaTestersModal.js +61 -0
  155. package/dist/enrollments/components/AddBetaTestersModal.js.map +1 -0
  156. package/dist/enrollments/components/EnrollLearnersModal.d.ts +6 -0
  157. package/dist/enrollments/components/EnrollLearnersModal.js +53 -0
  158. package/dist/enrollments/components/EnrollLearnersModal.js.map +1 -0
  159. package/dist/enrollments/components/EnrollmentStatusModal.js +3 -3
  160. package/dist/enrollments/components/EnrollmentStatusModal.js.map +1 -1
  161. package/dist/enrollments/components/EnrollmentsList.d.ts +3 -2
  162. package/dist/enrollments/components/EnrollmentsList.js +13 -14
  163. package/dist/enrollments/components/EnrollmentsList.js.map +1 -1
  164. package/dist/enrollments/components/UnenrollModal.d.ts +1 -1
  165. package/dist/enrollments/components/UnenrollModal.js +29 -3
  166. package/dist/enrollments/components/UnenrollModal.js.map +1 -1
  167. package/dist/enrollments/components/UpdateBetaTesterModal.d.ts +8 -0
  168. package/dist/enrollments/components/UpdateBetaTesterModal.js +52 -0
  169. package/dist/enrollments/components/UpdateBetaTesterModal.js.map +1 -0
  170. package/dist/enrollments/data/api.d.ts +3 -1
  171. package/dist/enrollments/data/api.js +11 -1
  172. package/dist/enrollments/data/api.js.map +1 -1
  173. package/dist/enrollments/data/apiHook.d.ts +5 -3
  174. package/dist/enrollments/data/apiHook.js +21 -3
  175. package/dist/enrollments/data/apiHook.js.map +1 -1
  176. package/dist/enrollments/data/queryKeys.d.ts +5 -5
  177. package/dist/enrollments/data/queryKeys.js.map +1 -1
  178. package/dist/enrollments/messages.d.ts +121 -1
  179. package/dist/enrollments/messages.js +126 -6
  180. package/dist/enrollments/messages.js.map +1 -1
  181. package/dist/enrollments/types.d.ts +24 -0
  182. package/dist/enrollments/types.js.map +1 -1
  183. package/dist/grading/GradingPage.js +15 -2
  184. package/dist/grading/GradingPage.js.map +1 -1
  185. package/dist/grading/components/GradingActionRow.d.ts +2 -0
  186. package/dist/grading/components/GradingActionRow.js +28 -0
  187. package/dist/grading/components/GradingActionRow.js.map +1 -0
  188. package/dist/grading/components/GradingConfigurationModal.d.ts +6 -0
  189. package/dist/grading/components/GradingConfigurationModal.js +14 -0
  190. package/dist/grading/components/GradingConfigurationModal.js.map +1 -0
  191. package/dist/grading/components/GradingLearnerContent.d.ts +7 -0
  192. package/dist/grading/components/GradingLearnerContent.js +114 -0
  193. package/dist/grading/components/GradingLearnerContent.js.map +1 -0
  194. package/dist/grading/data/api.d.ts +6 -0
  195. package/dist/grading/data/api.js +59 -0
  196. package/dist/grading/data/api.js.map +1 -0
  197. package/dist/grading/data/apiHook.d.ts +6 -0
  198. package/dist/grading/data/apiHook.js +29 -0
  199. package/dist/grading/data/apiHook.js.map +1 -0
  200. package/dist/grading/data/queryKeys.d.ts +9 -0
  201. package/dist/grading/data/queryKeys.js +8 -0
  202. package/dist/grading/data/queryKeys.js.map +1 -0
  203. package/dist/grading/messages.d.ts +173 -0
  204. package/dist/grading/messages.js +175 -0
  205. package/dist/grading/messages.js.map +1 -0
  206. package/dist/grading/types.d.ts +11 -0
  207. package/dist/grading/types.js +2 -0
  208. package/dist/grading/types.js.map +1 -0
  209. package/dist/hooks/useDebouncedFilter.d.ts +1 -0
  210. package/dist/hooks/useDebouncedFilter.js +5 -0
  211. package/dist/hooks/useDebouncedFilter.js.map +1 -1
  212. package/dist/index.d.ts +2 -3
  213. package/dist/index.js +2 -3
  214. package/dist/index.js.map +1 -1
  215. package/dist/instructorNav/InstructorNav.js +1 -1
  216. package/dist/instructorNav/InstructorNav.js.map +1 -1
  217. package/dist/provides.d.ts +4 -0
  218. package/dist/provides.js +7 -0
  219. package/dist/provides.js.map +1 -0
  220. package/dist/routes.d.ts +1 -1
  221. package/dist/routes.js +5 -4
  222. package/dist/routes.js.map +1 -1
  223. package/dist/specialExams/SpecialExamsPage.js +10 -2
  224. package/dist/specialExams/SpecialExamsPage.js.map +1 -1
  225. package/dist/specialExams/components/Allowances.d.ts +2 -0
  226. package/dist/specialExams/components/Allowances.js +6 -0
  227. package/dist/specialExams/components/Allowances.js.map +1 -0
  228. package/dist/specialExams/components/AttemptsList.d.ts +3 -0
  229. package/dist/specialExams/components/AttemptsList.js +44 -0
  230. package/dist/specialExams/components/AttemptsList.js.map +1 -0
  231. package/dist/specialExams/data/api.d.ts +3 -0
  232. package/dist/specialExams/data/api.js +23 -0
  233. package/dist/specialExams/data/api.js.map +1 -0
  234. package/dist/specialExams/data/apiHook.d.ts +2 -0
  235. package/dist/specialExams/data/apiHook.js +9 -0
  236. package/dist/specialExams/data/apiHook.js.map +1 -0
  237. package/dist/specialExams/data/queryKeys.d.ts +5 -0
  238. package/dist/specialExams/data/queryKeys.js +6 -0
  239. package/dist/specialExams/data/queryKeys.js.map +1 -0
  240. package/dist/specialExams/messages.d.ts +58 -0
  241. package/dist/specialExams/messages.js +60 -0
  242. package/dist/specialExams/messages.js.map +1 -0
  243. package/dist/specialExams/types.d.ts +13 -0
  244. package/dist/specialExams/types.js +2 -0
  245. package/dist/specialExams/types.js.map +1 -0
  246. package/dist/style.scss +16 -0
  247. package/dist/testUtils.js +1 -1
  248. package/dist/testUtils.js.map +1 -1
  249. package/dist/types/index.d.ts +1 -0
  250. package/dist/types/index.js.map +1 -1
  251. package/dist/utils/formatters.d.ts +5 -0
  252. package/dist/utils/formatters.js +10 -0
  253. package/dist/utils/formatters.js.map +1 -1
  254. package/package.json +2 -5
  255. package/dist/app.scss +0 -10
  256. package/dist/providers/QueryProvider.d.ts +0 -6
  257. package/dist/providers/QueryProvider.js +0 -16
  258. package/dist/providers/QueryProvider.js.map +0 -1
  259. package/dist/providers.d.ts +0 -3
  260. package/dist/providers.js +0 -8
  261. package/dist/providers.js.map +0 -1
@@ -1,12 +1,16 @@
1
1
  export declare const courseInfoQueryKeys: {
2
- all: readonly ["org.openedx.frontend.app.instructor", "courseInfo"];
3
- byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructor", "courseInfo", string];
2
+ all: readonly ["org.openedx.frontend.app.instructorDashboard", "courseInfo"];
3
+ byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "courseInfo", string];
4
4
  };
5
5
  export declare const pendingTasksQueryKey: {
6
- all: readonly ["org.openedx.frontend.app.instructor", "pendingTasks"];
7
- byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructor", "pendingTasks", string];
6
+ all: readonly ["org.openedx.frontend.app.instructorDashboard", "pendingTasks"];
7
+ byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "pendingTasks", string];
8
8
  };
9
9
  export declare const learnerQueryKeys: {
10
- all: readonly ["org.openedx.frontend.app.instructor", "learner"];
11
- byCourseAndLearner: (courseId: string, emailOrUsername: string) => readonly ["org.openedx.frontend.app.instructor", "learner", string, string];
10
+ all: readonly ["org.openedx.frontend.app.instructorDashboard", "learner"];
11
+ byCourseAndLearner: (courseId: string, emailOrUsername: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "learner", string, string];
12
+ };
13
+ export declare const problemQueryKeys: {
14
+ all: readonly ["org.openedx.frontend.app.instructorDashboard", "problemDetails"];
15
+ byCourseAndLearner: (courseId: string, blockId: string, emailOrUsername: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "problemDetails", string, string, string];
12
16
  };
@@ -11,4 +11,8 @@ export const learnerQueryKeys = {
11
11
  all: [appId, 'learner'],
12
12
  byCourseAndLearner: (courseId, emailOrUsername) => [appId, 'learner', courseId, emailOrUsername],
13
13
  };
14
+ export const problemQueryKeys = {
15
+ all: [appId, 'problemDetails'],
16
+ byCourseAndLearner: (courseId, blockId, emailOrUsername) => [appId, 'problemDetails', courseId, blockId, emailOrUsername],
17
+ };
14
18
  //# sourceMappingURL=queryKeys.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../src/data/queryKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,EAAE,CAAC,KAAK,EAAE,YAAY,CAAU;IACnC,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,CAAU;CACzE,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,GAAG,EAAE,CAAC,KAAK,EAAE,cAAc,CAAU;IACrC,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,CAAU;CAC3E,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,GAAG,EAAE,CAAC,KAAK,EAAE,SAAS,CAAU;IAChC,kBAAkB,EAAE,CAAC,QAAgB,EAAE,eAAuB,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,CAAU;CAC1H,CAAC","sourcesContent":["import { appId } from '@src/constants';\n\nexport const courseInfoQueryKeys = {\n all: [appId, 'courseInfo'] as const,\n byCourse: (courseId: string) => [appId, 'courseInfo', courseId] as const,\n};\n\nexport const pendingTasksQueryKey = {\n all: [appId, 'pendingTasks'] as const,\n byCourse: (courseId: string) => [appId, 'pendingTasks', courseId] as const,\n};\n\nexport const learnerQueryKeys = {\n all: [appId, 'learner'] as const,\n byCourseAndLearner: (courseId: string, emailOrUsername: string) => [appId, 'learner', courseId, emailOrUsername] as const,\n};\n"]}
1
+ {"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../src/data/queryKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,EAAE,CAAC,KAAK,EAAE,YAAY,CAAU;IACnC,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,CAAU;CACzE,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,GAAG,EAAE,CAAC,KAAK,EAAE,cAAc,CAAU;IACrC,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,CAAU;CAC3E,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,GAAG,EAAE,CAAC,KAAK,EAAE,SAAS,CAAU;IAChC,kBAAkB,EAAE,CAAC,QAAgB,EAAE,eAAuB,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,CAAU;CAC1H,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,GAAG,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAU;IACvC,kBAAkB,EAAE,CAAC,QAAgB,EAAE,OAAe,EAAE,eAAuB,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,eAAe,CAAU;CAC3J,CAAC","sourcesContent":["import { appId } from '@src/constants';\n\nexport const courseInfoQueryKeys = {\n all: [appId, 'courseInfo'] as const,\n byCourse: (courseId: string) => [appId, 'courseInfo', courseId] as const,\n};\n\nexport const pendingTasksQueryKey = {\n all: [appId, 'pendingTasks'] as const,\n byCourse: (courseId: string) => [appId, 'pendingTasks', courseId] as const,\n};\n\nexport const learnerQueryKeys = {\n all: [appId, 'learner'] as const,\n byCourseAndLearner: (courseId: string, emailOrUsername: string) => [appId, 'learner', courseId, emailOrUsername] as const,\n};\n\nexport const problemQueryKeys = {\n all: [appId, 'problemDetails'] as const,\n byCourseAndLearner: (courseId: string, blockId: string, emailOrUsername: string) => [appId, 'problemDetails', courseId, blockId, emailOrUsername] as const,\n};\n"]}
@@ -1,5 +1,5 @@
1
1
  export declare const dataDownloadsQueryKeys: {
2
- all: readonly ["org.openedx.frontend.app.instructor", "dataDownloads"];
3
- generatedReports: (courseId: string) => readonly ["org.openedx.frontend.app.instructor", "dataDownloads", "generatedReports", string];
4
- generateReportLink: (courseId: string) => readonly ["org.openedx.frontend.app.instructor", "dataDownloads", "reportLink", string];
2
+ all: readonly ["org.openedx.frontend.app.instructorDashboard", "dataDownloads"];
3
+ generatedReports: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "dataDownloads", "generatedReports", string];
4
+ generateReportLink: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "dataDownloads", "reportLink", string];
5
5
  };
@@ -1,4 +1,4 @@
1
- import { AddDateExtensionParams } from '../types';
1
+ import { AddDateExtensionParams } from '../../dateExtensions/types';
2
2
  interface AddExtensionModalProps {
3
3
  isOpen: boolean;
4
4
  title: string;
@@ -3,13 +3,13 @@ import { useState } from 'react';
3
3
  import { ActionRow, Button, Form, FormControl, FormGroup, FormLabel, ModalDialog } from '@openedx/paragon';
4
4
  import { useIntl } from '@openedx/frontend-base';
5
5
  import SpecifyLearnerField from '../../components/SpecifyLearnerField';
6
- import messages from '../messages';
7
- import SelectGradedSubsection from './SelectGradedSubsection';
6
+ import SelectGradedSubsection from '../../dateExtensions/components/SelectGradedSubsection';
7
+ import messages from '../../dateExtensions/messages';
8
8
  const initialFormData = {
9
9
  emailOrUsername: '',
10
10
  blockId: '',
11
11
  dueDate: '',
12
- dueTime: '',
12
+ dueTime: '23:59',
13
13
  reason: '',
14
14
  };
15
15
  const AddExtensionModal = ({ isOpen, title, onClose, onSubmit }) => {
@@ -18,8 +18,7 @@ const AddExtensionModal = ({ isOpen, title, onClose, onSubmit }) => {
18
18
  const isFormFilled = (formData) => {
19
19
  return (formData.emailOrUsername.trim() !== ''
20
20
  && formData.blockId.trim() !== ''
21
- && formData.dueDate.trim() !== ''
22
- && formData.dueTime.trim() !== '');
21
+ && formData.dueDate.trim() !== '');
23
22
  };
24
23
  const resetForm = () => {
25
24
  setFormData(initialFormData);
@@ -42,7 +41,7 @@ const AddExtensionModal = ({ isOpen, title, onClose, onSubmit }) => {
42
41
  const { name, value } = event.target;
43
42
  setFormData((prevData) => (Object.assign(Object.assign({}, prevData), { [name]: value })));
44
43
  };
45
- return (_jsxs(ModalDialog, { isOpen: isOpen, onClose: onClose, title: title, isOverflowVisible: false, size: "xl", children: [_jsx(ModalDialog.Header, { className: "p-3 pl-4 border-bottom", children: _jsx(ModalDialog.Title, { as: "h3", className: "m-0", children: title }) }), _jsxs(Form, { onSubmit: handleSubmit, className: "position-relative overflow-auto", children: [_jsx(ModalDialog.Body, { children: _jsxs("div", { className: "pt-3", children: [_jsx("p", { children: intl.formatMessage(messages.extensionInstructions) }), _jsx("div", { className: "container-fluid border-bottom mb-4.5 pb-3", children: _jsxs("div", { className: "row", children: [_jsx("div", { className: "col-sm-12 col-md-6", children: _jsx(SpecifyLearnerField, { onClickSelect: (emailOrUsername) => setFormData((prevData) => (Object.assign(Object.assign({}, prevData), { emailOrUsername }))) }) }), _jsx("div", { className: "col-sm-12 col-md-4", children: _jsx(SelectGradedSubsection, { label: intl.formatMessage(messages.selectGradedSubsection), placeholder: intl.formatMessage(messages.selectGradedSubsection), onChange: onChange }) })] }) }), _jsxs("div", { children: [_jsx("h4", { children: intl.formatMessage(messages.defineExtension) }), _jsxs(FormGroup, { size: "sm", children: [_jsxs(FormLabel, { children: [intl.formatMessage(messages.extensionDate), ":"] }), _jsxs("div", { className: "d-md-flex w-md-50 align-items-center", children: [_jsx(FormControl, { name: "dueDate", type: "date", size: "md", onChange: onChange }), _jsx(FormControl, { name: "dueTime", type: "time", size: "md", className: "mt-sm-3 mt-md-0", onChange: onChange })] })] }), _jsxs(FormGroup, { className: "mt-3", size: "sm", children: [_jsxs(FormLabel, { children: [intl.formatMessage(messages.reasonForExtension), ":"] }), _jsx(FormControl, { name: "reason", placeholder: intl.formatMessage(messages.reasonForExtension), size: "md", onChange: onChange })] })] })] }) }), _jsx(ModalDialog.Footer, { className: "p-4 border-top", children: _jsxs(ActionRow, { children: [_jsx(Button, { variant: "tertiary", onClick: handleCancel, children: intl.formatMessage(messages.cancel) }), _jsx(Button, { type: "submit", disabled: !isFormFilled(formData), children: intl.formatMessage(messages.addExtension) })] }) })] })] }));
44
+ return (_jsxs(ModalDialog, { isOpen: isOpen, onClose: onClose, title: title, isOverflowVisible: false, size: "xl", children: [_jsx(ModalDialog.Header, { className: "p-3 pl-4 border-bottom", children: _jsx(ModalDialog.Title, { as: "h3", className: "m-0", children: title }) }), _jsxs(Form, { onSubmit: handleSubmit, className: "position-relative overflow-auto", children: [_jsx(ModalDialog.Body, { children: _jsxs("div", { className: "pt-3", children: [_jsx("p", { children: intl.formatMessage(messages.extensionInstructions) }), _jsx("div", { className: "container-fluid border-bottom mb-4.5 pb-3", children: _jsxs("div", { className: "row", children: [_jsx("div", { className: "col-sm-12 col-md-6", children: _jsx(SpecifyLearnerField, { onClickSelect: (emailOrUsername) => setFormData((prevData) => (Object.assign(Object.assign({}, prevData), { emailOrUsername }))) }) }), _jsx("div", { className: "col-sm-12 col-md-4", children: _jsx(SelectGradedSubsection, { label: intl.formatMessage(messages.selectGradedSubsection), placeholder: intl.formatMessage(messages.selectGradedSubsection), onChange: onChange }) })] }) }), _jsxs("div", { children: [_jsx("h4", { children: intl.formatMessage(messages.defineExtension) }), _jsxs(FormGroup, { size: "sm", children: [_jsxs(FormLabel, { children: [intl.formatMessage(messages.extensionDate), ":"] }), _jsxs("div", { className: "d-md-flex w-md-50 align-items-center", children: [_jsx(FormControl, { name: "dueDate", type: "date", size: "md", onChange: onChange }), _jsx(FormControl, { name: "dueTime", type: "time", size: "md", className: "mt-sm-3 mt-md-0", defaultValue: initialFormData.dueTime, onChange: onChange })] })] }), _jsxs(FormGroup, { className: "mt-3", size: "sm", children: [_jsxs(FormLabel, { children: [intl.formatMessage(messages.reasonForExtension), ":"] }), _jsx(FormControl, { name: "reason", placeholder: intl.formatMessage(messages.reasonForExtension), size: "md", onChange: onChange })] })] })] }) }), _jsx(ModalDialog.Footer, { className: "p-4 border-top", children: _jsxs(ActionRow, { children: [_jsx(Button, { variant: "tertiary", onClick: handleCancel, children: intl.formatMessage(messages.cancel) }), _jsx(Button, { type: "submit", disabled: !isFormFilled(formData), children: intl.formatMessage(messages.addExtension) })] }) })] })] }));
46
45
  };
47
46
  export default AddExtensionModal;
48
47
  //# sourceMappingURL=AddExtensionModal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AddExtensionModal.js","sourceRoot":"","sources":["../../../src/dateExtensions/components/AddExtensionModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { ActionRow, Button, Form, FormControl, FormGroup, FormLabel, ModalDialog } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport SpecifyLearnerField from '@src/components/SpecifyLearnerField';\nimport messages from '../messages';\nimport SelectGradedSubsection from './SelectGradedSubsection';\nimport { AddDateExtensionFormData, AddDateExtensionParams } from '../types';\n\ninterface AddExtensionModalProps {\n isOpen: boolean,\n title: string,\n onClose: () => void,\n onSubmit: ({ emailOrUsername, blockId, dueDatetime, reason }: AddDateExtensionParams) => void,\n}\n\nconst initialFormData: AddDateExtensionFormData = {\n emailOrUsername: '',\n blockId: '',\n dueDate: '',\n dueTime: '',\n reason: '',\n};\n\nconst AddExtensionModal = ({ isOpen, title, onClose, onSubmit }: AddExtensionModalProps) => {\n const intl = useIntl();\n const [formData, setFormData] = useState(initialFormData);\n\n const isFormFilled = (formData: AddDateExtensionFormData) => {\n return (\n formData.emailOrUsername.trim() !== ''\n && formData.blockId.trim() !== ''\n && formData.dueDate.trim() !== ''\n && formData.dueTime.trim() !== ''\n );\n };\n\n const resetForm = () => {\n setFormData(initialFormData);\n };\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const { emailOrUsername, blockId, dueDate, dueTime, reason } = formData;\n onSubmit({\n emailOrUsername,\n blockId,\n dueDatetime: new Date(`${dueDate}T${dueTime}`).toISOString(),\n reason\n });\n };\n\n const handleCancel = () => {\n resetForm();\n onClose();\n };\n\n const onChange = (event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {\n const { name, value } = event.target;\n setFormData((prevData) => ({\n ...prevData,\n [name]: value,\n }));\n };\n\n return (\n <ModalDialog isOpen={isOpen} onClose={onClose} title={title} isOverflowVisible={false} size=\"xl\">\n <ModalDialog.Header className=\"p-3 pl-4 border-bottom\">\n <ModalDialog.Title as=\"h3\" className=\"m-0\">\n {title}\n </ModalDialog.Title>\n </ModalDialog.Header>\n <Form onSubmit={handleSubmit} className=\"position-relative overflow-auto\">\n <ModalDialog.Body>\n <div className=\"pt-3\">\n <p>{intl.formatMessage(messages.extensionInstructions)}</p>\n <div className=\"container-fluid border-bottom mb-4.5 pb-3\">\n <div className=\"row\">\n <div className=\"col-sm-12 col-md-6\">\n <SpecifyLearnerField onClickSelect={(emailOrUsername) => setFormData((prevData) => ({ ...prevData, emailOrUsername }))} />\n </div>\n <div className=\"col-sm-12 col-md-4\">\n <SelectGradedSubsection\n label={intl.formatMessage(messages.selectGradedSubsection)}\n placeholder={intl.formatMessage(messages.selectGradedSubsection)}\n onChange={onChange}\n />\n </div>\n </div>\n </div>\n <div>\n <h4>{intl.formatMessage(messages.defineExtension)}</h4>\n <FormGroup size=\"sm\">\n <FormLabel>\n {intl.formatMessage(messages.extensionDate)}:\n </FormLabel>\n <div className=\"d-md-flex w-md-50 align-items-center\">\n <FormControl name=\"dueDate\" type=\"date\" size=\"md\" onChange={onChange} />\n <FormControl name=\"dueTime\" type=\"time\" size=\"md\" className=\"mt-sm-3 mt-md-0\" onChange={onChange} />\n </div>\n </FormGroup>\n <FormGroup className=\"mt-3\" size=\"sm\">\n <FormLabel>\n {intl.formatMessage(messages.reasonForExtension)}:\n </FormLabel>\n <FormControl name=\"reason\" placeholder={intl.formatMessage(messages.reasonForExtension)} size=\"md\" onChange={onChange} />\n </FormGroup>\n </div>\n </div>\n </ModalDialog.Body>\n <ModalDialog.Footer className=\"p-4 border-top\">\n <ActionRow>\n <Button variant=\"tertiary\" onClick={handleCancel}>{intl.formatMessage(messages.cancel)}</Button>\n <Button type=\"submit\" disabled={!isFormFilled(formData)}>\n {intl.formatMessage(messages.addExtension)}\n </Button>\n </ActionRow>\n </ModalDialog.Footer>\n </Form>\n </ModalDialog>\n );\n};\n\nexport default AddExtensionModal;\n"]}
1
+ {"version":3,"file":"AddExtensionModal.js","sourceRoot":"","sources":["../../../src/dateExtensions/components/AddExtensionModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { ActionRow, Button, Form, FormControl, FormGroup, FormLabel, ModalDialog } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport SpecifyLearnerField from '@src/components/SpecifyLearnerField';\nimport SelectGradedSubsection from '@src/dateExtensions/components/SelectGradedSubsection';\nimport messages from '@src/dateExtensions/messages';\nimport { AddDateExtensionFormData, AddDateExtensionParams } from '@src/dateExtensions/types';\n\ninterface AddExtensionModalProps {\n isOpen: boolean,\n title: string,\n onClose: () => void,\n onSubmit: ({ emailOrUsername, blockId, dueDatetime, reason }: AddDateExtensionParams) => void,\n}\n\nconst initialFormData: AddDateExtensionFormData = {\n emailOrUsername: '',\n blockId: '',\n dueDate: '',\n dueTime: '23:59',\n reason: '',\n};\n\nconst AddExtensionModal = ({ isOpen, title, onClose, onSubmit }: AddExtensionModalProps) => {\n const intl = useIntl();\n const [formData, setFormData] = useState(initialFormData);\n\n const isFormFilled = (formData: AddDateExtensionFormData) => {\n return (\n formData.emailOrUsername.trim() !== ''\n && formData.blockId.trim() !== ''\n && formData.dueDate.trim() !== ''\n );\n };\n\n const resetForm = () => {\n setFormData(initialFormData);\n };\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const { emailOrUsername, blockId, dueDate, dueTime, reason } = formData;\n onSubmit({\n emailOrUsername,\n blockId,\n dueDatetime: new Date(`${dueDate}T${dueTime}`).toISOString(),\n reason\n });\n };\n\n const handleCancel = () => {\n resetForm();\n onClose();\n };\n\n const onChange = (event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {\n const { name, value } = event.target;\n setFormData((prevData) => ({\n ...prevData,\n [name]: value,\n }));\n };\n\n return (\n <ModalDialog isOpen={isOpen} onClose={onClose} title={title} isOverflowVisible={false} size=\"xl\">\n <ModalDialog.Header className=\"p-3 pl-4 border-bottom\">\n <ModalDialog.Title as=\"h3\" className=\"m-0\">\n {title}\n </ModalDialog.Title>\n </ModalDialog.Header>\n <Form onSubmit={handleSubmit} className=\"position-relative overflow-auto\">\n <ModalDialog.Body>\n <div className=\"pt-3\">\n <p>{intl.formatMessage(messages.extensionInstructions)}</p>\n <div className=\"container-fluid border-bottom mb-4.5 pb-3\">\n <div className=\"row\">\n <div className=\"col-sm-12 col-md-6\">\n <SpecifyLearnerField onClickSelect={(emailOrUsername) => setFormData((prevData) => ({ ...prevData, emailOrUsername }))} />\n </div>\n <div className=\"col-sm-12 col-md-4\">\n <SelectGradedSubsection\n label={intl.formatMessage(messages.selectGradedSubsection)}\n placeholder={intl.formatMessage(messages.selectGradedSubsection)}\n onChange={onChange}\n />\n </div>\n </div>\n </div>\n <div>\n <h4>{intl.formatMessage(messages.defineExtension)}</h4>\n <FormGroup size=\"sm\">\n <FormLabel>\n {intl.formatMessage(messages.extensionDate)}:\n </FormLabel>\n <div className=\"d-md-flex w-md-50 align-items-center\">\n <FormControl name=\"dueDate\" type=\"date\" size=\"md\" onChange={onChange} />\n <FormControl name=\"dueTime\" type=\"time\" size=\"md\" className=\"mt-sm-3 mt-md-0\" defaultValue={initialFormData.dueTime} onChange={onChange} />\n </div>\n </FormGroup>\n <FormGroup className=\"mt-3\" size=\"sm\">\n <FormLabel>\n {intl.formatMessage(messages.reasonForExtension)}:\n </FormLabel>\n <FormControl name=\"reason\" placeholder={intl.formatMessage(messages.reasonForExtension)} size=\"md\" onChange={onChange} />\n </FormGroup>\n </div>\n </div>\n </ModalDialog.Body>\n <ModalDialog.Footer className=\"p-4 border-top\">\n <ActionRow>\n <Button variant=\"tertiary\" onClick={handleCancel}>{intl.formatMessage(messages.cancel)}</Button>\n <Button type=\"submit\" disabled={!isFormFilled(formData)}>\n {intl.formatMessage(messages.addExtension)}\n </Button>\n </ActionRow>\n </ModalDialog.Footer>\n </Form>\n </ModalDialog>\n );\n};\n\nexport default AddExtensionModal;\n"]}
@@ -2,24 +2,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from 'react';
3
3
  import { useParams } from 'react-router-dom';
4
4
  import { useIntl } from '@openedx/frontend-base';
5
- import { Button, DataTable, FormControl, Icon } from '@openedx/paragon';
5
+ import { Button, DataTable } from '@openedx/paragon';
6
6
  import messages from '../messages';
7
7
  import { useDateExtensions } from '../data/apiHook';
8
- import { Search } from '@openedx/paragon/icons';
9
8
  import SelectGradedSubsection from './SelectGradedSubsection';
10
9
  import { useDebouncedFilter } from '../../hooks/useDebouncedFilter';
10
+ import UsernameFilter from '../../components/UsernameFilter';
11
11
  const DATE_EXTENSIONS_PAGE_SIZE = 25;
12
- const UsernameFilter = ({ column: { filterValue, setFilter } }) => {
13
- const intl = useIntl();
14
- const { inputValue, handleChange } = useDebouncedFilter({
15
- filterValue,
16
- setFilter,
17
- });
18
- const handleInputChange = (e) => {
19
- handleChange(e.target.value);
20
- };
21
- return (_jsx(FormControl, { className: "mb-0", onChange: handleInputChange, placeholder: intl.formatMessage(messages.searchLearnerPlaceholder), trailingElement: _jsx(Icon, { src: Search }), value: inputValue }));
22
- };
23
12
  const GradedSubsectionFilter = ({ column: { filterValue, setFilter } }) => {
24
13
  const intl = useIntl();
25
14
  const { inputValue, handleChange } = useDebouncedFilter({
@@ -1 +1 @@
1
- {"version":3,"file":"DateExtensionsList.js","sourceRoot":"","sources":["../../../src/dateExtensions/components/DateExtensionsList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, DataTable, FormControl, Icon } from '@openedx/paragon';\nimport messages from '../messages';\nimport { LearnerDateExtension } from '../types';\nimport { useDateExtensions } from '../data/apiHook';\nimport { Search } from '@openedx/paragon/icons';\nimport SelectGradedSubsection from './SelectGradedSubsection';\nimport { useDebouncedFilter } from '../../hooks/useDebouncedFilter';\nimport { DataTableFetchDataProps } from '@src/types';\n\nconst DATE_EXTENSIONS_PAGE_SIZE = 25;\n\nexport interface DateExtensionListProps {\n onResetExtensions?: (user: LearnerDateExtension) => void,\n onClickAdd?: () => void,\n}\n\nconst UsernameFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue,\n setFilter,\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n handleChange(e.target.value);\n };\n\n return (\n <FormControl\n className=\"mb-0\"\n onChange={handleInputChange}\n placeholder={intl.formatMessage(messages.searchLearnerPlaceholder)}\n trailingElement={<Icon src={Search} />}\n value={inputValue}\n />\n );\n};\n\nconst GradedSubsectionFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue,\n setFilter,\n });\n\n const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n handleChange(e.target.value);\n };\n\n return (\n <SelectGradedSubsection\n placeholder={intl.formatMessage(messages.allGradedSubsections)}\n onChange={handleSelectChange}\n value={inputValue}\n />\n );\n};\n\nconst DateExtensionsList = ({\n onResetExtensions = () => {},\n onClickAdd = () => {},\n}: DateExtensionListProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [filters, setFilters] = useState<{ page: number, emailOrUsername: string, blockId: string }>({\n page: 0,\n emailOrUsername: '',\n blockId: '',\n });\n\n const { data = { count: 0, results: [], numPages: 0 }, isLoading } = useDateExtensions(courseId ?? '', {\n blockId: filters.blockId,\n emailOrUsername: filters.emailOrUsername,\n page: filters.page,\n pageSize: DATE_EXTENSIONS_PAGE_SIZE,\n });\n\n const tableColumns = [\n { accessor: 'username',\n Header: intl.formatMessage(messages.username),\n Filter: UsernameFilter,\n },\n { accessor: 'fullName', Header: intl.formatMessage(messages.fullname), disableFilters: true, },\n { accessor: 'email', Header: intl.formatMessage(messages.email), disableFilters: true, },\n { accessor: 'unitTitle',\n Header: intl.formatMessage(messages.gradedSubsection),\n Filter: GradedSubsectionFilter,\n },\n {\n accessor: 'extendedDueDate',\n Header: intl.formatMessage(messages.extendedDueDate),\n Cell: ({ value }: { value: string }) => (\n intl.formatDate(value, { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', timeZone: 'UTC' })\n ),\n disableFilters: true,\n },\n ];\n\n const additionalColumns = [{\n id: 'reset',\n Header: intl.formatMessage(messages.reset),\n Cell: ({ row }: { row: { original: LearnerDateExtension } }) => (\n <Button\n variant=\"link\"\n size=\"inline\"\n onClick={() => onResetExtensions(row.original)}\n >\n {intl.formatMessage(messages.resetExtensions)}\n </Button>\n )\n }];\n\n const handleFetchData = (data: DataTableFetchDataProps) => {\n const emailOrUsernameFilter = data.filters.find((filter) => filter.id === 'username');\n const newEmailOrUsername = emailOrUsernameFilter ? emailOrUsernameFilter.value : '';\n const blockIdFilter = data.filters.find((filter) => filter.id === 'unitTitle');\n const newBlockId = blockIdFilter ? blockIdFilter.value : '';\n\n const filterChanged = newEmailOrUsername !== filters.emailOrUsername || newBlockId !== filters.blockId;\n const pageChanged = data.pageIndex !== filters.page;\n\n // If filters changed, reset to page 0\n if (filterChanged) {\n setFilters({ page: 0, emailOrUsername: newEmailOrUsername, blockId: newBlockId });\n } else if (pageChanged) {\n // If only page changed (filters didn't change), update page\n setFilters({ page: data.pageIndex, emailOrUsername: newEmailOrUsername, blockId: newBlockId });\n }\n };\n\n return (\n <DataTable\n columns={tableColumns}\n additionalColumns={additionalColumns}\n data={data.results}\n fetchData={handleFetchData}\n state={{\n pageIndex: filters.page,\n pageSize: DATE_EXTENSIONS_PAGE_SIZE,\n filters: [\n {\n id: 'username',\n value: filters.emailOrUsername,\n },\n {\n id: 'unitTitle',\n value: filters.blockId,\n }\n ]\n }}\n isFilterable\n numBreakoutFilters={2}\n isLoading={isLoading}\n isPaginated\n itemCount={data.count}\n manualFilters\n manualPagination\n pageSize={DATE_EXTENSIONS_PAGE_SIZE}\n pageCount={data.numPages}\n FilterStatusComponent={DataTable.RowStatus}\n >\n <div className=\"d-flex justify-content-between align-items-start pt-1 mx-3 mb-3\">\n <DataTable.TableControlBar />\n <Button className=\"mt-2.5\" onClick={onClickAdd}>+ {intl.formatMessage(messages.addIndividualExtension)}</Button>\n </div>\n <DataTable.Table />\n <DataTable.EmptyTable content={intl.formatMessage(messages.noDateExtensions)} />\n <DataTable.TableFooter />\n </DataTable>\n );\n};\n\nexport default DateExtensionsList;\n"]}
1
+ {"version":3,"file":"DateExtensionsList.js","sourceRoot":"","sources":["../../../src/dateExtensions/components/DateExtensionsList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, DataTable } from '@openedx/paragon';\nimport messages from '../messages';\nimport { LearnerDateExtension } from '../types';\nimport { useDateExtensions } from '../data/apiHook';\nimport SelectGradedSubsection from './SelectGradedSubsection';\nimport { useDebouncedFilter } from '../../hooks/useDebouncedFilter';\nimport { DataTableFetchDataProps } from '@src/types';\nimport UsernameFilter from '@src/components/UsernameFilter';\n\nconst DATE_EXTENSIONS_PAGE_SIZE = 25;\n\nexport interface DateExtensionListProps {\n onResetExtensions?: (user: LearnerDateExtension) => void,\n onClickAdd?: () => void,\n}\n\nconst GradedSubsectionFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue,\n setFilter,\n });\n\n const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n handleChange(e.target.value);\n };\n\n return (\n <SelectGradedSubsection\n placeholder={intl.formatMessage(messages.allGradedSubsections)}\n onChange={handleSelectChange}\n value={inputValue}\n />\n );\n};\n\nconst DateExtensionsList = ({\n onResetExtensions = () => {},\n onClickAdd = () => {},\n}: DateExtensionListProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [filters, setFilters] = useState<{ page: number, emailOrUsername: string, blockId: string }>({\n page: 0,\n emailOrUsername: '',\n blockId: '',\n });\n\n const { data = { count: 0, results: [], numPages: 0 }, isLoading } = useDateExtensions(courseId ?? '', {\n blockId: filters.blockId,\n emailOrUsername: filters.emailOrUsername,\n page: filters.page,\n pageSize: DATE_EXTENSIONS_PAGE_SIZE,\n });\n\n const tableColumns = [\n { accessor: 'username',\n Header: intl.formatMessage(messages.username),\n Filter: UsernameFilter,\n },\n { accessor: 'fullName', Header: intl.formatMessage(messages.fullname), disableFilters: true, },\n { accessor: 'email', Header: intl.formatMessage(messages.email), disableFilters: true, },\n { accessor: 'unitTitle',\n Header: intl.formatMessage(messages.gradedSubsection),\n Filter: GradedSubsectionFilter,\n },\n {\n accessor: 'extendedDueDate',\n Header: intl.formatMessage(messages.extendedDueDate),\n Cell: ({ value }: { value: string }) => (\n intl.formatDate(value, { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', timeZone: 'UTC' })\n ),\n disableFilters: true,\n },\n ];\n\n const additionalColumns = [{\n id: 'reset',\n Header: intl.formatMessage(messages.reset),\n Cell: ({ row }: { row: { original: LearnerDateExtension } }) => (\n <Button\n variant=\"link\"\n size=\"inline\"\n onClick={() => onResetExtensions(row.original)}\n >\n {intl.formatMessage(messages.resetExtensions)}\n </Button>\n )\n }];\n\n const handleFetchData = (data: DataTableFetchDataProps) => {\n const emailOrUsernameFilter = data.filters.find((filter) => filter.id === 'username');\n const newEmailOrUsername = emailOrUsernameFilter ? emailOrUsernameFilter.value : '';\n const blockIdFilter = data.filters.find((filter) => filter.id === 'unitTitle');\n const newBlockId = blockIdFilter ? blockIdFilter.value : '';\n\n const filterChanged = newEmailOrUsername !== filters.emailOrUsername || newBlockId !== filters.blockId;\n const pageChanged = data.pageIndex !== filters.page;\n\n // If filters changed, reset to page 0\n if (filterChanged) {\n setFilters({ page: 0, emailOrUsername: newEmailOrUsername, blockId: newBlockId });\n } else if (pageChanged) {\n // If only page changed (filters didn't change), update page\n setFilters({ page: data.pageIndex, emailOrUsername: newEmailOrUsername, blockId: newBlockId });\n }\n };\n\n return (\n <DataTable\n columns={tableColumns}\n additionalColumns={additionalColumns}\n data={data.results}\n fetchData={handleFetchData}\n state={{\n pageIndex: filters.page,\n pageSize: DATE_EXTENSIONS_PAGE_SIZE,\n filters: [\n {\n id: 'username',\n value: filters.emailOrUsername,\n },\n {\n id: 'unitTitle',\n value: filters.blockId,\n }\n ]\n }}\n isFilterable\n numBreakoutFilters={2}\n isLoading={isLoading}\n isPaginated\n itemCount={data.count}\n manualFilters\n manualPagination\n pageSize={DATE_EXTENSIONS_PAGE_SIZE}\n pageCount={data.numPages}\n FilterStatusComponent={DataTable.RowStatus}\n >\n <div className=\"d-flex justify-content-between align-items-start pt-1 mx-3 mb-3\">\n <DataTable.TableControlBar />\n <Button className=\"mt-2.5\" onClick={onClickAdd}>+ {intl.formatMessage(messages.addIndividualExtension)}</Button>\n </div>\n <DataTable.Table />\n <DataTable.EmptyTable content={intl.formatMessage(messages.noDateExtensions)} />\n <DataTable.TableFooter />\n </DataTable>\n );\n};\n\nexport default DateExtensionsList;\n"]}
@@ -1,5 +1,5 @@
1
- import { DateExtensionQueryParams, ResetDueDateParams } from '../types';
2
- export declare const useDateExtensions: (courseId: string, params: DateExtensionQueryParams) => import("@tanstack/react-query").UseQueryResult<import("../../types").DataList<import("../types").LearnerDateExtension>, Error>;
1
+ import { DateExtensionQueryParams, ResetDueDateParams } from '../../dateExtensions/types';
2
+ export declare const useDateExtensions: (courseId: string, params: DateExtensionQueryParams) => import("@tanstack/react-query").UseQueryResult<import("../../types").DataList<import("../../dateExtensions/types").LearnerDateExtension>, Error>;
3
3
  export declare const useResetDateExtensionMutation: () => import("@tanstack/react-query").UseMutationResult<any, Error, {
4
4
  courseId: string;
5
5
  params: ResetDueDateParams;
@@ -1,6 +1,6 @@
1
1
  import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
2
- import { getDateExtensions, resetDateExtension, addDateExtension, getGradedSubsections } from './api';
3
- import { dateExtensionsQueryKeys, gradedSubsectionsQueryKeys } from './queryKeys';
2
+ import { getDateExtensions, resetDateExtension, addDateExtension, getGradedSubsections } from '../../dateExtensions/data/api';
3
+ import { dateExtensionsQueryKeys, gradedSubsectionsQueryKeys } from '../../dateExtensions/data/queryKeys';
4
4
  export const useDateExtensions = (courseId, params) => (useQuery({
5
5
  queryKey: dateExtensionsQueryKeys.byCoursePaginated(courseId, params),
6
6
  queryFn: () => getDateExtensions(courseId, params),
@@ -19,8 +19,8 @@ export const useAddDateExtensionMutation = () => {
19
19
  const queryClient = useQueryClient();
20
20
  return useMutation({
21
21
  mutationFn: ({ courseId, extensionData }) => addDateExtension(courseId, extensionData),
22
- onSuccess: ({ courseId }) => {
23
- queryClient.invalidateQueries({ queryKey: dateExtensionsQueryKeys.byCourse(courseId) });
22
+ onSuccess: (_, { courseId }) => {
23
+ queryClient.invalidateQueries({ queryKey: dateExtensionsQueryKeys.byCourse(courseId), exact: false });
24
24
  },
25
25
  });
26
26
  };
@@ -1 +1 @@
1
- {"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/dateExtensions/data/apiHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AACtG,OAAO,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAGlF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAE,MAAgC,EAAE,EAAE,CAAC,CACvF,QAAQ,CAAC;IACP,QAAQ,EAAE,uBAAuB,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC;IACrE,OAAO,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC;IAClD,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,EAAE;IAChD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAoD,EAAE,EAAE,CACrF,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC;QACtC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;YAC7B,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,uBAAuB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACxG,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,EAAE;IAC9C,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,aAAa,EAA4C,EAAE,EAAE,CACpF,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC;QAC3C,SAAS,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;YAC1B,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,uBAAuB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC1F,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,CACxD,QAAQ,CAAC;IACP,QAAQ,EAAE,0BAA0B,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACvD,OAAO,EAAE,GAAG,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC;CAC9C,CAAC,CACH,CAAC","sourcesContent":["import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { getDateExtensions, resetDateExtension, addDateExtension, getGradedSubsections } from './api';\nimport { dateExtensionsQueryKeys, gradedSubsectionsQueryKeys } from './queryKeys';\nimport { DateExtensionQueryParams, ResetDueDateParams } from '../types';\n\nexport const useDateExtensions = (courseId: string, params: DateExtensionQueryParams) => (\n useQuery({\n queryKey: dateExtensionsQueryKeys.byCoursePaginated(courseId, params),\n queryFn: () => getDateExtensions(courseId, params),\n enabled: !!courseId,\n })\n);\n\nexport const useResetDateExtensionMutation = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ courseId, params }: { courseId: string, params: ResetDueDateParams }) =>\n resetDateExtension(courseId, params),\n onSuccess: (_, { courseId }) => {\n queryClient.invalidateQueries({ queryKey: dateExtensionsQueryKeys.byCourse(courseId), exact: false });\n },\n });\n};\n\nexport const useAddDateExtensionMutation = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ courseId, extensionData }: { courseId: string, extensionData: any }) =>\n addDateExtension(courseId, extensionData),\n onSuccess: ({ courseId }) => {\n queryClient.invalidateQueries({ queryKey: dateExtensionsQueryKeys.byCourse(courseId) });\n },\n });\n};\n\nexport const useGradedSubsections = (courseId: string) => (\n useQuery({\n queryKey: gradedSubsectionsQueryKeys.byCourse(courseId),\n queryFn: () => getGradedSubsections(courseId),\n })\n);\n"]}
1
+ {"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/dateExtensions/data/apiHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAC7H,OAAO,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAGzG,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAE,MAAgC,EAAE,EAAE,CAAC,CACvF,QAAQ,CAAC;IACP,QAAQ,EAAE,uBAAuB,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC;IACrE,OAAO,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC;IAClD,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,EAAE;IAChD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAoD,EAAE,EAAE,CACrF,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC;QACtC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;YAC7B,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,uBAAuB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACxG,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,EAAE;IAC9C,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,aAAa,EAA4C,EAAE,EAAE,CACpF,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC;QAC3C,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;YAC7B,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,uBAAuB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACxG,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,CACxD,QAAQ,CAAC;IACP,QAAQ,EAAE,0BAA0B,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACvD,OAAO,EAAE,GAAG,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC;CAC9C,CAAC,CACH,CAAC","sourcesContent":["import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { getDateExtensions, resetDateExtension, addDateExtension, getGradedSubsections } from '@src/dateExtensions/data/api';\nimport { dateExtensionsQueryKeys, gradedSubsectionsQueryKeys } from '@src/dateExtensions/data/queryKeys';\nimport { DateExtensionQueryParams, ResetDueDateParams } from '@src/dateExtensions/types';\n\nexport const useDateExtensions = (courseId: string, params: DateExtensionQueryParams) => (\n useQuery({\n queryKey: dateExtensionsQueryKeys.byCoursePaginated(courseId, params),\n queryFn: () => getDateExtensions(courseId, params),\n enabled: !!courseId,\n })\n);\n\nexport const useResetDateExtensionMutation = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ courseId, params }: { courseId: string, params: ResetDueDateParams }) =>\n resetDateExtension(courseId, params),\n onSuccess: (_, { courseId }) => {\n queryClient.invalidateQueries({ queryKey: dateExtensionsQueryKeys.byCourse(courseId), exact: false });\n },\n });\n};\n\nexport const useAddDateExtensionMutation = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ courseId, extensionData }: { courseId: string, extensionData: any }) =>\n addDateExtension(courseId, extensionData),\n onSuccess: (_, { courseId }) => {\n queryClient.invalidateQueries({ queryKey: dateExtensionsQueryKeys.byCourse(courseId), exact: false });\n },\n });\n};\n\nexport const useGradedSubsections = (courseId: string) => (\n useQuery({\n queryKey: gradedSubsectionsQueryKeys.byCourse(courseId),\n queryFn: () => getGradedSubsections(courseId),\n })\n);\n"]}
@@ -1,10 +1,10 @@
1
1
  import { DateExtensionQueryParams } from '../types';
2
2
  export declare const dateExtensionsQueryKeys: {
3
- all: readonly ["org.openedx.frontend.app.instructor", "dateExtensions"];
4
- byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructor", "dateExtensions", string];
5
- byCoursePaginated: (courseId: string, params: DateExtensionQueryParams) => readonly ["org.openedx.frontend.app.instructor", "dateExtensions", string, number, number, string, string];
3
+ all: readonly ["org.openedx.frontend.app.instructorDashboard", "dateExtensions"];
4
+ byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "dateExtensions", string];
5
+ byCoursePaginated: (courseId: string, params: DateExtensionQueryParams) => readonly ["org.openedx.frontend.app.instructorDashboard", "dateExtensions", string, number, number, string, string];
6
6
  };
7
7
  export declare const gradedSubsectionsQueryKeys: {
8
- all: readonly ["org.openedx.frontend.app.instructor", "gradedSubsections"];
9
- byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructor", "gradedSubsections", string];
8
+ all: readonly ["org.openedx.frontend.app.instructorDashboard", "gradedSubsections"];
9
+ byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "gradedSubsections", string];
10
10
  };
@@ -114,11 +114,6 @@ declare const messages: {
114
114
  defaultMessage: string;
115
115
  description: string;
116
116
  };
117
- searchLearnerPlaceholder: {
118
- id: string;
119
- defaultMessage: string;
120
- description: string;
121
- };
122
117
  noDateExtensions: {
123
118
  id: string;
124
119
  defaultMessage: string;
@@ -97,7 +97,7 @@ const messages = defineMessages({
97
97
  },
98
98
  extensionDate: {
99
99
  id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.extensionDate',
100
- defaultMessage: 'Extension Date',
100
+ defaultMessage: 'Extension Date and time (in UTC)',
101
101
  description: 'Label for the extension date field',
102
102
  },
103
103
  reasonForExtension: {
@@ -115,11 +115,6 @@ const messages = defineMessages({
115
115
  defaultMessage: 'All Graded Subsections',
116
116
  description: 'Label for the all graded subsections option in filters',
117
117
  },
118
- searchLearnerPlaceholder: {
119
- id: 'instruct.dateExtensions.page.filters.searchLearnerPlaceholder',
120
- defaultMessage: 'Search for a Learner',
121
- description: 'Placeholder text for the search learner input field',
122
- },
123
118
  noDateExtensions: {
124
119
  id: 'instruct.dateExtensions.page.noDateExtensions',
125
120
  defaultMessage: 'No results found',
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/dateExtensions/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n dateExtensionsTitle: {\n id: 'instruct.dateExtensions.page.title',\n defaultMessage: 'Viewing Granted Extensions',\n description: 'Title for date extensions page',\n },\n addIndividualExtension: {\n id: 'instruct.dateExtensions.page.addIndividualExtension',\n defaultMessage: 'Add Individual Extension',\n description: 'Button text for adding an individual date extension',\n },\n username: {\n id: 'instruct.dateExtensions.page.tableHeader.username',\n defaultMessage: 'User Name',\n description: 'Label for the user name column in the date extensions table',\n },\n fullname: {\n id: 'instruct.dateExtensions.page.tableHeader.fullname',\n defaultMessage: 'Full Name',\n description: 'Label for the full name column in the date extensions table',\n },\n email: {\n id: 'instruct.dateExtensions.page.tableHeader.email',\n defaultMessage: 'Email',\n description: 'Label for the email column in the date extensions table',\n },\n gradedSubsection: {\n id: 'instruct.dateExtensions.page.tableHeader.gradedSubsection',\n defaultMessage: 'Graded Subsection',\n description: 'Label for the graded subsection column in the date extensions table',\n },\n extendedDueDate: {\n id: 'instruct.dateExtensions.page.tableHeader.extendedDueDate',\n defaultMessage: 'Extended Due Date',\n description: 'Label for the extended due date column in the date extensions table',\n },\n reset: {\n id: 'instruct.dateExtensions.page.tableHeader.reset',\n defaultMessage: 'Reset',\n description: 'Label for the reset column in the date extensions table',\n },\n resetExtensions: {\n id: 'instruct.dateExtensions.page.button.resetExtensions',\n defaultMessage: 'Reset Extensions',\n description: 'Button text for resetting date extensions for a user',\n },\n resetConfirmationHeader: {\n id: 'instruct.dateExtensions.page.resetModal.confirmationHeader',\n defaultMessage: 'Reset extensions for {username}?',\n description: 'Header for the reset confirmation modal',\n },\n resetConfirmationMessage: {\n id: 'instruct.dateExtensions.page.resetModal.confirmationMessage',\n defaultMessage: 'Resetting a problem\\'s due date rescinds a due date extension for a student on a particular subsection. This will revert the due date for the student back to the problem\\'s original due date.',\n description: 'Confirmation message for resetting extensions in the reset modal',\n },\n cancel: {\n id: 'instruct.dateExtensions.page.resetModal.cancel',\n defaultMessage: 'Cancel',\n description: 'Label for the cancel button in the reset modal',\n },\n confirm: {\n id: 'instruct.dateExtensions.page.resetModal.confirm',\n defaultMessage: 'Reset Due Date for Student',\n description: 'Label for the confirm button in the reset modal',\n },\n close: {\n id: 'instruct.dateExtensions.page.resetModal.close',\n defaultMessage: 'Close',\n description: 'Label for the close button in the reset modal',\n },\n missingUserOrCourseIdError: {\n id: 'instruct.dateExtensions.page.error.missingUserOrCourseId',\n defaultMessage: 'Unable to reset extension: missing user or course ID.',\n description: 'Error message shown when user or course ID is missing during reset',\n },\n addIndividualDueDateExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.title',\n defaultMessage: 'Add Individual Due Date Extension',\n description: 'Title for the add individual due date extension modal',\n },\n addExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.addExtension',\n defaultMessage: 'Add Extension',\n description: 'Label for the add extension button',\n },\n extensionInstructions: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.extensionInstructions',\n defaultMessage: 'To grant an extension, select a student, graded subsection, and define the extension due date and time.',\n description: 'Instructions for adding an individual due date extension',\n },\n defineExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.defineExtension',\n defaultMessage: 'Define Extension',\n description: 'Label for the define extension section',\n },\n extensionDate: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.extensionDate',\n defaultMessage: 'Extension Date',\n description: 'Label for the extension date field',\n },\n reasonForExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.reasonForExtension',\n defaultMessage: 'Reason for Extension',\n description: 'Label for the reason for extension field',\n },\n selectGradedSubsection: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.selectGradedSubsection',\n defaultMessage: 'Select Graded Subsection',\n description: 'Label for the select graded subsection field',\n },\n allGradedSubsections: {\n id: 'instruct.dateExtensions.page.filters.allGradedSubsections',\n defaultMessage: 'All Graded Subsections',\n description: 'Label for the all graded subsections option in filters',\n },\n searchLearnerPlaceholder: {\n id: 'instruct.dateExtensions.page.filters.searchLearnerPlaceholder',\n defaultMessage: 'Search for a Learner',\n description: 'Placeholder text for the search learner input field',\n },\n noDateExtensions: {\n id: 'instruct.dateExtensions.page.noDateExtensions',\n defaultMessage: 'No results found',\n description: 'Message shown when there are no date extensions to display in the table',\n },\n});\n\nexport default messages;\n"]}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/dateExtensions/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n dateExtensionsTitle: {\n id: 'instruct.dateExtensions.page.title',\n defaultMessage: 'Viewing Granted Extensions',\n description: 'Title for date extensions page',\n },\n addIndividualExtension: {\n id: 'instruct.dateExtensions.page.addIndividualExtension',\n defaultMessage: 'Add Individual Extension',\n description: 'Button text for adding an individual date extension',\n },\n username: {\n id: 'instruct.dateExtensions.page.tableHeader.username',\n defaultMessage: 'User Name',\n description: 'Label for the user name column in the date extensions table',\n },\n fullname: {\n id: 'instruct.dateExtensions.page.tableHeader.fullname',\n defaultMessage: 'Full Name',\n description: 'Label for the full name column in the date extensions table',\n },\n email: {\n id: 'instruct.dateExtensions.page.tableHeader.email',\n defaultMessage: 'Email',\n description: 'Label for the email column in the date extensions table',\n },\n gradedSubsection: {\n id: 'instruct.dateExtensions.page.tableHeader.gradedSubsection',\n defaultMessage: 'Graded Subsection',\n description: 'Label for the graded subsection column in the date extensions table',\n },\n extendedDueDate: {\n id: 'instruct.dateExtensions.page.tableHeader.extendedDueDate',\n defaultMessage: 'Extended Due Date',\n description: 'Label for the extended due date column in the date extensions table',\n },\n reset: {\n id: 'instruct.dateExtensions.page.tableHeader.reset',\n defaultMessage: 'Reset',\n description: 'Label for the reset column in the date extensions table',\n },\n resetExtensions: {\n id: 'instruct.dateExtensions.page.button.resetExtensions',\n defaultMessage: 'Reset Extensions',\n description: 'Button text for resetting date extensions for a user',\n },\n resetConfirmationHeader: {\n id: 'instruct.dateExtensions.page.resetModal.confirmationHeader',\n defaultMessage: 'Reset extensions for {username}?',\n description: 'Header for the reset confirmation modal',\n },\n resetConfirmationMessage: {\n id: 'instruct.dateExtensions.page.resetModal.confirmationMessage',\n defaultMessage: 'Resetting a problem\\'s due date rescinds a due date extension for a student on a particular subsection. This will revert the due date for the student back to the problem\\'s original due date.',\n description: 'Confirmation message for resetting extensions in the reset modal',\n },\n cancel: {\n id: 'instruct.dateExtensions.page.resetModal.cancel',\n defaultMessage: 'Cancel',\n description: 'Label for the cancel button in the reset modal',\n },\n confirm: {\n id: 'instruct.dateExtensions.page.resetModal.confirm',\n defaultMessage: 'Reset Due Date for Student',\n description: 'Label for the confirm button in the reset modal',\n },\n close: {\n id: 'instruct.dateExtensions.page.resetModal.close',\n defaultMessage: 'Close',\n description: 'Label for the close button in the reset modal',\n },\n missingUserOrCourseIdError: {\n id: 'instruct.dateExtensions.page.error.missingUserOrCourseId',\n defaultMessage: 'Unable to reset extension: missing user or course ID.',\n description: 'Error message shown when user or course ID is missing during reset',\n },\n addIndividualDueDateExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.title',\n defaultMessage: 'Add Individual Due Date Extension',\n description: 'Title for the add individual due date extension modal',\n },\n addExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.addExtension',\n defaultMessage: 'Add Extension',\n description: 'Label for the add extension button',\n },\n extensionInstructions: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.extensionInstructions',\n defaultMessage: 'To grant an extension, select a student, graded subsection, and define the extension due date and time.',\n description: 'Instructions for adding an individual due date extension',\n },\n defineExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.defineExtension',\n defaultMessage: 'Define Extension',\n description: 'Label for the define extension section',\n },\n extensionDate: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.extensionDate',\n defaultMessage: 'Extension Date and time (in UTC)',\n description: 'Label for the extension date field',\n },\n reasonForExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.reasonForExtension',\n defaultMessage: 'Reason for Extension',\n description: 'Label for the reason for extension field',\n },\n selectGradedSubsection: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.selectGradedSubsection',\n defaultMessage: 'Select Graded Subsection',\n description: 'Label for the select graded subsection field',\n },\n allGradedSubsections: {\n id: 'instruct.dateExtensions.page.filters.allGradedSubsections',\n defaultMessage: 'All Graded Subsections',\n description: 'Label for the all graded subsections option in filters',\n },\n noDateExtensions: {\n id: 'instruct.dateExtensions.page.noDateExtensions',\n defaultMessage: 'No results found',\n description: 'Message shown when there are no date extensions to display in the table',\n },\n});\n\nexport default messages;\n"]}
@@ -1,19 +1,30 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useState } from 'react';
3
3
  import { useIntl } from '@openedx/frontend-base';
4
- import { ActionRow, Button, IconButton } from '@openedx/paragon';
4
+ import { ActionRow, Button, IconButton, Menu, MenuItem, ModalPopup, useToggle } from '@openedx/paragon';
5
5
  import { MoreVert } from '@openedx/paragon/icons';
6
- import messages from './messages';
7
- import EnrollmentsList from './components/EnrollmentsList';
8
- import EnrollmentStatusModal from './components/EnrollmentStatusModal';
9
- import UnenrollModal from './components/UnenrollModal';
6
+ import messages from '../enrollments/messages';
7
+ import AddBetaTestersModal from '../enrollments/components/AddBetaTestersModal';
8
+ import EnrollLearnersModal from '../enrollments/components/EnrollLearnersModal';
9
+ import EnrollmentsList from '../enrollments/components/EnrollmentsList';
10
+ import EnrollmentStatusModal from '../enrollments/components/EnrollmentStatusModal';
11
+ import UnenrollModal from '../enrollments/components/UnenrollModal';
12
+ import { AlertOutlet, useAlert } from '../providers/AlertProvider';
13
+ import UpdateBetaTesterModal from './components/UpdateBetaTesterModal';
10
14
  const EnrollmentsPage = () => {
11
15
  const intl = useIntl();
12
16
  const [isEnrollmentStatusModalOpen, setIsEnrollmentStatusModalOpen] = useState(false);
17
+ const [isEnrollLearnersModalOpen, setIsEnrollLearnersModalOpen] = useState(false);
18
+ const [isAddBetaTestersModalOpen, setIsAddBetaTestersModalOpen] = useState(false);
13
19
  const [isUnenrollModalOpen, setIsUnenrollModalOpen] = useState(false);
20
+ const [isUpdateBetaTesterModalOpen, setIsUpdateBetaTesterModalOpen] = useState(false);
14
21
  const [selectedLearner, setSelectedLearner] = useState(null);
15
- const handleMoreButton = () => {
22
+ const [statusMenuTarget, setStatusMenuTarget] = useState(null);
23
+ const [isOpenMenu, openMenu, closeMenu] = useToggle(false);
24
+ const { clearAlerts } = useAlert();
25
+ const handleOpenEnrollmentStatusModal = () => {
16
26
  setIsEnrollmentStatusModalOpen(true);
27
+ closeMenu();
17
28
  };
18
29
  const handleUnenroll = (learner) => {
19
30
  setIsUnenrollModalOpen(true);
@@ -26,7 +37,30 @@ const EnrollmentsPage = () => {
26
37
  const handleCloseEnrollmentStatusModal = () => {
27
38
  setIsEnrollmentStatusModalOpen(false);
28
39
  };
29
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "d-flex justify-content-between align-items-center", children: [_jsx("h3", { className: "text-primary-700", children: intl.formatMessage(messages.enrollmentsPageTitle) }), _jsxs(ActionRow, { children: [_jsx(IconButton, { alt: intl.formatMessage(messages.checkEnrollmentStatus), className: "lead", iconAs: MoreVert, onClick: handleMoreButton }), _jsxs(Button, { variant: "outline-primary", children: ["+ ", intl.formatMessage(messages.addBetaTesters)] }), _jsxs(Button, { children: ["+ ", intl.formatMessage(messages.enrollLearners)] })] })] }), _jsx(EnrollmentsList, { onUnenroll: handleUnenroll }), _jsx(EnrollmentStatusModal, { isOpen: isEnrollmentStatusModalOpen, onClose: handleCloseEnrollmentStatusModal }), selectedLearner && _jsx(UnenrollModal, { isOpen: isUnenrollModalOpen, learner: selectedLearner, onClose: handleUnenrollModalClose })] }));
40
+ const handleEnrollLearners = () => {
41
+ setIsEnrollLearnersModalOpen(true);
42
+ clearAlerts();
43
+ };
44
+ const handleCloseEnrollLearnersModal = () => {
45
+ setIsEnrollLearnersModalOpen(false);
46
+ };
47
+ const handleAddBetaTesters = () => {
48
+ setIsAddBetaTestersModalOpen(true);
49
+ clearAlerts();
50
+ };
51
+ const handleBetaTesterChange = (learner) => {
52
+ setIsUpdateBetaTesterModalOpen(true);
53
+ setSelectedLearner(learner);
54
+ };
55
+ const handleCloseUpdateBetaTesterModal = () => {
56
+ setIsUpdateBetaTesterModalOpen(false);
57
+ setSelectedLearner(null);
58
+ };
59
+ const handleStatusMenuClick = (event) => {
60
+ setStatusMenuTarget(event === null || event === void 0 ? void 0 : event.currentTarget);
61
+ openMenu();
62
+ };
63
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "d-flex justify-content-between align-items-center", children: [_jsx("h3", { className: "text-primary-700", children: intl.formatMessage(messages.enrollmentsPageTitle) }), _jsxs(ActionRow, { children: [_jsx(IconButton, { alt: intl.formatMessage(messages.checkEnrollmentStatus), className: "lead", iconAs: MoreVert, onClick: handleStatusMenuClick }), _jsxs(Button, { variant: "outline-primary", onClick: handleAddBetaTesters, children: ["+ ", intl.formatMessage(messages.addBetaTesters)] }), _jsxs(Button, { onClick: handleEnrollLearners, children: ["+ ", intl.formatMessage(messages.enrollLearners)] })] })] }), _jsx(ModalPopup, { positionRef: statusMenuTarget, onClose: closeMenu, isOpen: isOpenMenu, children: _jsx(Menu, { children: _jsx(MenuItem, { onClick: handleOpenEnrollmentStatusModal, children: intl.formatMessage(messages.checkEnrollmentStatus) }) }) }), _jsx(AlertOutlet, {}), _jsx(EnrollmentsList, { onUnenroll: handleUnenroll, onBetaTesterChange: handleBetaTesterChange }), _jsx(EnrollmentStatusModal, { isOpen: isEnrollmentStatusModalOpen, onClose: handleCloseEnrollmentStatusModal }), selectedLearner && _jsx(UnenrollModal, { isOpen: isUnenrollModalOpen, learner: selectedLearner, onClose: handleUnenrollModalClose }), _jsx(EnrollLearnersModal, { isOpen: isEnrollLearnersModalOpen, onClose: handleCloseEnrollLearnersModal }), _jsx(AddBetaTestersModal, { isOpen: isAddBetaTestersModalOpen, onClose: () => setIsAddBetaTestersModalOpen(false) }), selectedLearner && _jsx(UpdateBetaTesterModal, { isOpen: isUpdateBetaTesterModalOpen, learner: selectedLearner, onClose: handleCloseUpdateBetaTesterModal })] }));
30
64
  };
31
65
  export default EnrollmentsPage;
32
66
  //# sourceMappingURL=EnrollmentsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EnrollmentsPage.js","sourceRoot":"","sources":["../../src/enrollments/EnrollmentsPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,eAAe,MAAM,8BAA8B,CAAC;AAC3D,OAAO,qBAAqB,MAAM,oCAAoC,CAAC;AACvE,OAAO,aAAa,MAAM,4BAA4B,CAAC;AAGvD,MAAM,eAAe,GAAG,GAAG,EAAE;IAC3B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,CAAC,2BAA2B,EAAE,8BAA8B,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtF,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtE,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAyB,IAAI,CAAC,CAAC;IAErF,MAAM,gBAAgB,GAAG,GAAG,EAAE;QAC5B,8BAA8B,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,CAAC,OAAwB,EAAE,EAAE;QAClD,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAC7B,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC,CAAC;IAEF,MAAM,wBAAwB,GAAG,GAAG,EAAE;QACpC,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAC9B,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC,CAAC;IAEF,MAAM,gCAAgC,GAAG,GAAG,EAAE;QAC5C,8BAA8B,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC,CAAC;IAEF,OAAO,CACL,8BACE,eAAK,SAAS,EAAC,mDAAmD,aAChE,aAAI,SAAS,EAAC,kBAAkB,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC,GAAM,EACzF,MAAC,SAAS,eACR,KAAC,UAAU,IACT,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EACvD,SAAS,EAAC,MAAM,EAChB,MAAM,EAAE,QAAQ,EAChB,OAAO,EAAE,gBAAgB,GACzB,EACF,MAAC,MAAM,IAAC,OAAO,EAAC,iBAAiB,mBAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAU,EAC1F,MAAC,MAAM,qBAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAU,IACtD,IACR,EACN,KAAC,eAAe,IAAC,UAAU,EAAE,cAAc,GAAI,EAC/C,KAAC,qBAAqB,IAAC,MAAM,EAAE,2BAA2B,EAAE,OAAO,EAAE,gCAAgC,GAAI,EACxG,eAAe,IAAI,KAAC,aAAa,IAAC,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,wBAAwB,GAAI,IAC9H,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,eAAe,CAAC","sourcesContent":["import { useState } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { ActionRow, Button, IconButton } from '@openedx/paragon';\nimport { MoreVert } from '@openedx/paragon/icons';\nimport messages from './messages';\nimport EnrollmentsList from './components/EnrollmentsList';\nimport EnrollmentStatusModal from './components/EnrollmentStatusModal';\nimport UnenrollModal from './components/UnenrollModal';\nimport { EnrolledLearner } from './types';\n\nconst EnrollmentsPage = () => {\n const intl = useIntl();\n const [isEnrollmentStatusModalOpen, setIsEnrollmentStatusModalOpen] = useState(false);\n const [isUnenrollModalOpen, setIsUnenrollModalOpen] = useState(false);\n const [selectedLearner, setSelectedLearner] = useState<EnrolledLearner | null>(null);\n\n const handleMoreButton = () => {\n setIsEnrollmentStatusModalOpen(true);\n };\n\n const handleUnenroll = (learner: EnrolledLearner) => {\n setIsUnenrollModalOpen(true);\n setSelectedLearner(learner);\n };\n\n const handleUnenrollModalClose = () => {\n setIsUnenrollModalOpen(false);\n setSelectedLearner(null);\n };\n\n const handleCloseEnrollmentStatusModal = () => {\n setIsEnrollmentStatusModalOpen(false);\n };\n\n return (\n <>\n <div className=\"d-flex justify-content-between align-items-center\">\n <h3 className=\"text-primary-700\">{intl.formatMessage(messages.enrollmentsPageTitle)}</h3>\n <ActionRow>\n <IconButton\n alt={intl.formatMessage(messages.checkEnrollmentStatus)}\n className=\"lead\"\n iconAs={MoreVert}\n onClick={handleMoreButton}\n />\n <Button variant=\"outline-primary\">+ {intl.formatMessage(messages.addBetaTesters)}</Button>\n <Button>+ {intl.formatMessage(messages.enrollLearners)}</Button>\n </ActionRow>\n </div>\n <EnrollmentsList onUnenroll={handleUnenroll} />\n <EnrollmentStatusModal isOpen={isEnrollmentStatusModalOpen} onClose={handleCloseEnrollmentStatusModal} />\n {selectedLearner && <UnenrollModal isOpen={isUnenrollModalOpen} learner={selectedLearner} onClose={handleUnenrollModalClose} />}\n </>\n );\n};\n\nexport default EnrollmentsPage;\n"]}
1
+ {"version":3,"file":"EnrollmentsPage.js","sourceRoot":"","sources":["../../src/enrollments/EnrollmentsPage.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { ActionRow, Button, IconButton, Menu, MenuItem, ModalPopup, useToggle } from '@openedx/paragon';\nimport { MoreVert } from '@openedx/paragon/icons';\nimport messages from '@src/enrollments/messages';\nimport AddBetaTestersModal from '@src/enrollments/components/AddBetaTestersModal';\nimport EnrollLearnersModal from '@src/enrollments/components/EnrollLearnersModal';\nimport EnrollmentsList from '@src/enrollments/components/EnrollmentsList';\nimport EnrollmentStatusModal from '@src/enrollments/components/EnrollmentStatusModal';\nimport UnenrollModal from '@src/enrollments/components/UnenrollModal';\nimport { EnrolledLearner } from '@src/enrollments/types';\nimport { AlertOutlet, useAlert } from '@src/providers/AlertProvider';\nimport UpdateBetaTesterModal from './components/UpdateBetaTesterModal';\n\nconst EnrollmentsPage = () => {\n const intl = useIntl();\n const [isEnrollmentStatusModalOpen, setIsEnrollmentStatusModalOpen] = useState(false);\n const [isEnrollLearnersModalOpen, setIsEnrollLearnersModalOpen] = useState(false);\n const [isAddBetaTestersModalOpen, setIsAddBetaTestersModalOpen] = useState(false);\n const [isUnenrollModalOpen, setIsUnenrollModalOpen] = useState(false);\n const [isUpdateBetaTesterModalOpen, setIsUpdateBetaTesterModalOpen] = useState(false);\n const [selectedLearner, setSelectedLearner] = useState<EnrolledLearner | null>(null);\n const [statusMenuTarget, setStatusMenuTarget] = useState<HTMLButtonElement | null>(null);\n const [isOpenMenu, openMenu, closeMenu] = useToggle(false);\n const { clearAlerts } = useAlert();\n\n const handleOpenEnrollmentStatusModal = () => {\n setIsEnrollmentStatusModalOpen(true);\n closeMenu();\n };\n\n const handleUnenroll = (learner: EnrolledLearner) => {\n setIsUnenrollModalOpen(true);\n setSelectedLearner(learner);\n };\n\n const handleUnenrollModalClose = () => {\n setIsUnenrollModalOpen(false);\n setSelectedLearner(null);\n };\n\n const handleCloseEnrollmentStatusModal = () => {\n setIsEnrollmentStatusModalOpen(false);\n };\n\n const handleEnrollLearners = () => {\n setIsEnrollLearnersModalOpen(true);\n clearAlerts();\n };\n\n const handleCloseEnrollLearnersModal = () => {\n setIsEnrollLearnersModalOpen(false);\n };\n\n const handleAddBetaTesters = () => {\n setIsAddBetaTestersModalOpen(true);\n clearAlerts();\n };\n\n const handleBetaTesterChange = (learner: EnrolledLearner) => {\n setIsUpdateBetaTesterModalOpen(true);\n setSelectedLearner(learner);\n };\n\n const handleCloseUpdateBetaTesterModal = () => {\n setIsUpdateBetaTesterModalOpen(false);\n setSelectedLearner(null);\n };\n\n const handleStatusMenuClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setStatusMenuTarget(event?.currentTarget);\n openMenu();\n };\n\n return (\n <>\n <div className=\"d-flex justify-content-between align-items-center\">\n <h3 className=\"text-primary-700\">{intl.formatMessage(messages.enrollmentsPageTitle)}</h3>\n <ActionRow>\n <IconButton\n alt={intl.formatMessage(messages.checkEnrollmentStatus)}\n className=\"lead\"\n iconAs={MoreVert}\n onClick={handleStatusMenuClick}\n />\n <Button variant=\"outline-primary\" onClick={handleAddBetaTesters}>+ {intl.formatMessage(messages.addBetaTesters)}</Button>\n <Button onClick={handleEnrollLearners}>+ {intl.formatMessage(messages.enrollLearners)}</Button>\n </ActionRow>\n </div>\n <ModalPopup positionRef={statusMenuTarget} onClose={closeMenu} isOpen={isOpenMenu}>\n <Menu>\n <MenuItem onClick={handleOpenEnrollmentStatusModal}>\n {intl.formatMessage(messages.checkEnrollmentStatus)}\n </MenuItem>\n </Menu>\n </ModalPopup>\n <AlertOutlet />\n <EnrollmentsList onUnenroll={handleUnenroll} onBetaTesterChange={handleBetaTesterChange} />\n <EnrollmentStatusModal isOpen={isEnrollmentStatusModalOpen} onClose={handleCloseEnrollmentStatusModal} />\n {selectedLearner && <UnenrollModal isOpen={isUnenrollModalOpen} learner={selectedLearner} onClose={handleUnenrollModalClose} />}\n <EnrollLearnersModal isOpen={isEnrollLearnersModalOpen} onClose={handleCloseEnrollLearnersModal} />\n <AddBetaTestersModal isOpen={isAddBetaTestersModalOpen} onClose={() => setIsAddBetaTestersModalOpen(false)} />\n {selectedLearner && <UpdateBetaTesterModal isOpen={isUpdateBetaTesterModalOpen} learner={selectedLearner} onClose={handleCloseUpdateBetaTesterModal} />}\n </>\n );\n};\n\nexport default EnrollmentsPage;\n"]}
@@ -0,0 +1,6 @@
1
+ export interface AddBetaTestersModalProps {
2
+ isOpen: boolean;
3
+ onClose: () => void;
4
+ }
5
+ declare const AddBetaTestersModal: ({ isOpen, onClose }: AddBetaTestersModalProps) => import("react/jsx-runtime").JSX.Element;
6
+ export default AddBetaTestersModal;
@@ -0,0 +1,61 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { useParams } from 'react-router-dom';
4
+ import { isAxiosError } from 'axios';
5
+ import { useIntl } from '@openedx/frontend-base';
6
+ import { Button, FormControl, ModalDialog, Form } from '@openedx/paragon';
7
+ import { useUpdateBetaTesters } from '../../enrollments/data/apiHook';
8
+ import messages from '../../enrollments/messages';
9
+ import { useAlert } from '../../providers/AlertProvider';
10
+ import { useDebouncedFilter } from '../../hooks/useDebouncedFilter';
11
+ const AddBetaTestersModal = ({ isOpen, onClose }) => {
12
+ const intl = useIntl();
13
+ const { courseId = '' } = useParams();
14
+ const [emails, setEmails] = useState('');
15
+ const [autoEnroll, setAutoEnroll] = useState(true);
16
+ const [emailStudents, setEmailStudents] = useState(true);
17
+ const { mutate: addBetaTesters } = useUpdateBetaTesters(courseId);
18
+ const { showModal, addAlert } = useAlert();
19
+ const { inputValue, handleChange } = useDebouncedFilter({
20
+ filterValue: emails,
21
+ setFilter: setEmails,
22
+ });
23
+ const handleInputChange = (e) => {
24
+ handleChange(e.target.value);
25
+ };
26
+ const handleSave = () => {
27
+ const identifier = inputValue.split(',').map(email => email.trim()).filter(email => email);
28
+ addBetaTesters({ identifier, action: 'add', autoEnroll, emailStudents }, {
29
+ onSuccess: (data) => {
30
+ var _a;
31
+ const failedUsernames = ((_a = data.results) === null || _a === void 0 ? void 0 : _a.filter(user => user.userDoesNotExist).map(user => user.identifier)) || [];
32
+ if (failedUsernames.length > 0) {
33
+ addAlert({
34
+ type: 'danger',
35
+ message: intl.formatMessage(messages.failedBetaTesters),
36
+ extraContent: (failedUsernames.map((learner) => (_jsxs("p", { className: "mb-0", children: ["\u2022 ", intl.formatMessage(messages.unknownLearner, { learner })] }, learner))))
37
+ });
38
+ }
39
+ handleChange('');
40
+ setAutoEnroll(true);
41
+ setEmailStudents(true);
42
+ onClose();
43
+ },
44
+ onError: (error) => {
45
+ var _a;
46
+ const notFound = isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404;
47
+ const errorMessage = notFound
48
+ ? intl.formatMessage(messages.enrollLearnerNotFoundError)
49
+ : intl.formatMessage(messages.enrollLearnerError);
50
+ showModal({
51
+ message: errorMessage,
52
+ variant: 'danger',
53
+ confirmText: intl.formatMessage(messages.closeButton),
54
+ });
55
+ }
56
+ });
57
+ };
58
+ return (_jsxs(ModalDialog, { isOpen: isOpen, onClose: onClose, isOverflowVisible: false, title: intl.formatMessage(messages.addBetaTesters), children: [_jsx(ModalDialog.Header, { className: "border-light-700 border-bottom", children: _jsx("h3", { className: "text-primary-500", children: intl.formatMessage(messages.addBetaTesters) }) }), _jsx("div", { className: "position-relative overflow-auto", children: _jsxs(ModalDialog.Body, { className: "py-4", children: [_jsx("p", { className: "text-gray-700 x-small mb-2", children: intl.formatMessage(messages.addBetaTestersInstructions) }), _jsx(FormControl, { name: "identifier", as: "textarea", rows: 4, placeholder: intl.formatMessage(messages.userIdentifierPlaceholder), onChange: handleInputChange, value: inputValue }), _jsxs("div", { className: "d-flex mt-3 text-primary-500", children: [_jsx(Form.Checkbox, { controlClassName: "border-primary-500", checked: autoEnroll, onChange: (e) => setAutoEnroll(e.target.checked), children: intl.formatMessage(messages.autoEnrollCheckbox) }), _jsx(Form.Checkbox, { controlClassName: "border-primary-500", className: "ml-4", checked: emailStudents, onChange: (e) => setEmailStudents(e.target.checked), children: intl.formatMessage(messages.notifyUsersCheckbox) })] })] }) }), _jsxs(ModalDialog.Footer, { className: "border-light-700 border-top", children: [_jsx(Button, { variant: "tertiary", onClick: onClose, children: intl.formatMessage(messages.cancelButton) }), _jsx(Button, { className: "ml-2", variant: "primary", onClick: handleSave, disabled: inputValue.trim().length === 0, children: intl.formatMessage(messages.saveButton) })] })] }));
59
+ };
60
+ export default AddBetaTestersModal;
61
+ //# sourceMappingURL=AddBetaTestersModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddBetaTestersModal.js","sourceRoot":"","sources":["../../../src/enrollments/components/AddBetaTestersModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { isAxiosError } from 'axios';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, FormControl, ModalDialog, Form } from '@openedx/paragon';\nimport { useUpdateBetaTesters } from '@src/enrollments/data/apiHook';\nimport messages from '@src/enrollments/messages';\nimport { useAlert } from '@src/providers/AlertProvider';\nimport { useDebouncedFilter } from '@src/hooks/useDebouncedFilter';\n\nexport interface AddBetaTestersModalProps {\n isOpen: boolean,\n onClose: () => void,\n}\n\nconst AddBetaTestersModal = ({\n isOpen,\n onClose\n}: AddBetaTestersModalProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [emails, setEmails] = useState('');\n const [autoEnroll, setAutoEnroll] = useState(true);\n const [emailStudents, setEmailStudents] = useState(true);\n const { mutate: addBetaTesters } = useUpdateBetaTesters(courseId);\n const { showModal, addAlert } = useAlert();\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue: emails,\n setFilter: setEmails,\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n handleChange(e.target.value);\n };\n\n const handleSave = () => {\n const identifier = inputValue.split(',').map(email => email.trim()).filter(email => email);\n addBetaTesters({ identifier, action: 'add', autoEnroll, emailStudents }, {\n onSuccess: (data) => {\n const failedUsernames = data.results?.filter(user => user.userDoesNotExist).map(user => user.identifier) || [];\n if (failedUsernames.length > 0) {\n addAlert({\n type: 'danger',\n message: intl.formatMessage(messages.failedBetaTesters),\n extraContent: (\n failedUsernames.map((learner: string) => (\n <p key={learner} className=\"mb-0\">• {intl.formatMessage(messages.unknownLearner, { learner })}</p>\n ))\n )\n });\n }\n handleChange('');\n setAutoEnroll(true);\n setEmailStudents(true);\n onClose();\n },\n onError: (error) => {\n const notFound = isAxiosError(error) && error.response?.status === 404;\n const errorMessage = notFound\n ? intl.formatMessage(messages.enrollLearnerNotFoundError)\n : intl.formatMessage(messages.enrollLearnerError);\n showModal({\n message: errorMessage,\n variant: 'danger',\n confirmText: intl.formatMessage(messages.closeButton),\n });\n }\n });\n };\n\n return (\n <ModalDialog isOpen={isOpen} onClose={onClose} isOverflowVisible={false} title={intl.formatMessage(messages.addBetaTesters)}>\n <ModalDialog.Header className=\"border-light-700 border-bottom\">\n <h3 className=\"text-primary-500\">{intl.formatMessage(messages.addBetaTesters)}</h3>\n </ModalDialog.Header>\n <div className=\"position-relative overflow-auto\">\n <ModalDialog.Body className=\"py-4\">\n <p className=\"text-gray-700 x-small mb-2\">{intl.formatMessage(messages.addBetaTestersInstructions)}</p>\n <FormControl\n name=\"identifier\"\n as=\"textarea\"\n rows={4}\n placeholder={intl.formatMessage(messages.userIdentifierPlaceholder)}\n onChange={handleInputChange}\n value={inputValue}\n />\n <div className=\"d-flex mt-3 text-primary-500\">\n <Form.Checkbox\n controlClassName=\"border-primary-500\"\n checked={autoEnroll}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setAutoEnroll(e.target.checked)}\n >{intl.formatMessage(messages.autoEnrollCheckbox)}\n </Form.Checkbox>\n <Form.Checkbox\n controlClassName=\"border-primary-500\"\n className=\"ml-4\"\n checked={emailStudents}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setEmailStudents(e.target.checked)}\n >{intl.formatMessage(messages.notifyUsersCheckbox)}\n </Form.Checkbox>\n </div>\n </ModalDialog.Body>\n </div>\n <ModalDialog.Footer className=\"border-light-700 border-top\">\n <Button variant=\"tertiary\" onClick={onClose}>\n {intl.formatMessage(messages.cancelButton)}\n </Button>\n <Button className=\"ml-2\" variant=\"primary\" onClick={handleSave} disabled={inputValue.trim().length === 0}>\n {intl.formatMessage(messages.saveButton)}\n </Button>\n </ModalDialog.Footer>\n </ModalDialog>\n );\n};\n\nexport default AddBetaTestersModal;\n"]}
@@ -0,0 +1,6 @@
1
+ export interface EnrollLearnersModalProps {
2
+ isOpen: boolean;
3
+ onClose: () => void;
4
+ }
5
+ declare const EnrollLearnersModal: ({ isOpen, onClose }: EnrollLearnersModalProps) => import("react/jsx-runtime").JSX.Element;
6
+ export default EnrollLearnersModal;