@openedx/frontend-app-instructor-dashboard 1.0.0-alpha.4 → 1.0.0-alpha.41

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 (303) hide show
  1. package/dist/Main.d.ts +1 -1
  2. package/dist/Main.js +11 -18
  3. package/dist/Main.js.map +1 -1
  4. package/dist/app.js +0 -6
  5. package/dist/app.js.map +1 -1
  6. package/dist/certificates/CertificatesPage.d.ts +1 -0
  7. package/dist/certificates/CertificatesPage.js +315 -2
  8. package/dist/certificates/CertificatesPage.js.map +1 -1
  9. package/dist/certificates/CertificatesPage.scss +90 -0
  10. package/dist/certificates/components/CertificateTable.d.ts +14 -0
  11. package/dist/certificates/components/CertificateTable.js +88 -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 +11 -0
  17. package/dist/certificates/components/CertificatesToolbar.js +33 -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 +24 -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/GenerateCertificatesModal.d.ts +9 -0
  26. package/dist/certificates/components/GenerateCertificatesModal.js +19 -0
  27. package/dist/certificates/components/GenerateCertificatesModal.js.map +1 -0
  28. package/dist/certificates/components/GenerationHistoryTable.d.ts +11 -0
  29. package/dist/certificates/components/GenerationHistoryTable.js +25 -0
  30. package/dist/certificates/components/GenerationHistoryTable.js.map +1 -0
  31. package/dist/certificates/components/GrantExceptionsModal.d.ts +9 -0
  32. package/dist/certificates/components/GrantExceptionsModal.js +55 -0
  33. package/dist/certificates/components/GrantExceptionsModal.js.map +1 -0
  34. package/dist/certificates/components/InvalidateCertificateModal.d.ts +8 -0
  35. package/dist/certificates/components/InvalidateCertificateModal.js +26 -0
  36. package/dist/certificates/components/InvalidateCertificateModal.js.map +1 -0
  37. package/dist/certificates/components/IssuedCertificatesTab.d.ts +18 -0
  38. package/dist/certificates/components/IssuedCertificatesTab.js +6 -0
  39. package/dist/certificates/components/IssuedCertificatesTab.js.map +1 -0
  40. package/dist/certificates/components/LearnerActionModal.d.ts +16 -0
  41. package/dist/certificates/components/LearnerActionModal.js +27 -0
  42. package/dist/certificates/components/LearnerActionModal.js.map +1 -0
  43. package/dist/certificates/components/RegenerateCertificatesModal.d.ts +11 -0
  44. package/dist/certificates/components/RegenerateCertificatesModal.js +46 -0
  45. package/dist/certificates/components/RegenerateCertificatesModal.js.map +1 -0
  46. package/dist/certificates/components/RemoveExceptionModal.d.ts +9 -0
  47. package/dist/certificates/components/RemoveExceptionModal.js +10 -0
  48. package/dist/certificates/components/RemoveExceptionModal.js.map +1 -0
  49. package/dist/certificates/components/RemoveInvalidationModal.d.ts +9 -0
  50. package/dist/certificates/components/RemoveInvalidationModal.js +10 -0
  51. package/dist/certificates/components/RemoveInvalidationModal.js.map +1 -0
  52. package/dist/certificates/constants.d.ts +15 -0
  53. package/dist/certificates/constants.js +16 -0
  54. package/dist/certificates/constants.js.map +1 -0
  55. package/dist/certificates/data/api.d.ts +30 -0
  56. package/dist/certificates/data/api.js +126 -0
  57. package/dist/certificates/data/api.js.map +1 -0
  58. package/dist/certificates/data/apiHook.d.ts +63 -0
  59. package/dist/certificates/data/apiHook.js +133 -0
  60. package/dist/certificates/data/apiHook.js.map +1 -0
  61. package/dist/certificates/data/queryKeys.d.ts +9 -0
  62. package/dist/certificates/data/queryKeys.js +9 -0
  63. package/dist/certificates/data/queryKeys.js.map +1 -0
  64. package/dist/certificates/messages.d.ts +548 -0
  65. package/dist/certificates/messages.js +550 -0
  66. package/dist/certificates/messages.js.map +1 -0
  67. package/dist/certificates/types.d.ts +66 -0
  68. package/dist/certificates/types.js +26 -0
  69. package/dist/certificates/types.js.map +1 -0
  70. package/dist/certificates/utils/errorHandling.d.ts +12 -0
  71. package/dist/certificates/utils/errorHandling.js +24 -0
  72. package/dist/certificates/utils/errorHandling.js.map +1 -0
  73. package/dist/certificates/utils/filterUtils.d.ts +4 -0
  74. package/dist/certificates/utils/filterUtils.js +31 -0
  75. package/dist/certificates/utils/filterUtils.js.map +1 -0
  76. package/dist/certificates/utils/index.d.ts +2 -0
  77. package/dist/certificates/utils/index.js +2 -0
  78. package/dist/certificates/utils/index.js.map +1 -0
  79. package/dist/components/ActionCard.d.ts +2 -2
  80. package/dist/components/ActionCard.js +1 -1
  81. package/dist/components/ActionCard.js.map +1 -1
  82. package/dist/components/CodeEditor.d.ts +5 -0
  83. package/dist/components/CodeEditor.js +34 -0
  84. package/dist/components/CodeEditor.js.map +1 -0
  85. package/dist/components/PendingTasks.d.ts +3 -1
  86. package/dist/components/PendingTasks.js +3 -2
  87. package/dist/components/PendingTasks.js.map +1 -1
  88. package/dist/components/SpecifyLearnerField.d.ts +4 -1
  89. package/dist/components/SpecifyLearnerField.js +55 -15
  90. package/dist/components/SpecifyLearnerField.js.map +1 -1
  91. package/dist/components/SpecifyProblemField.d.ts +13 -0
  92. package/dist/components/SpecifyProblemField.js +52 -0
  93. package/dist/components/SpecifyProblemField.js.map +1 -0
  94. package/dist/components/UsernameFilter.d.ts +7 -0
  95. package/dist/components/UsernameFilter.js +19 -0
  96. package/dist/components/UsernameFilter.js.map +1 -0
  97. package/dist/components/messages.d.ts +45 -0
  98. package/dist/components/messages.js +45 -0
  99. package/dist/components/messages.js.map +1 -1
  100. package/dist/courseInfo/types.d.ts +5 -0
  101. package/dist/courseInfo/types.js.map +1 -1
  102. package/dist/courseTeam/CourseTeamPage.js +25 -2
  103. package/dist/courseTeam/CourseTeamPage.js.map +1 -1
  104. package/dist/courseTeam/components/AddTeamMemberModal.d.ts +6 -0
  105. package/dist/courseTeam/components/AddTeamMemberModal.js +61 -0
  106. package/dist/courseTeam/components/AddTeamMemberModal.js.map +1 -0
  107. package/dist/courseTeam/components/EditTeamMemberModal.d.ts +8 -0
  108. package/dist/courseTeam/components/EditTeamMemberModal.js +102 -0
  109. package/dist/courseTeam/components/EditTeamMemberModal.js.map +1 -0
  110. package/dist/courseTeam/components/MembersContent.d.ts +6 -0
  111. package/dist/courseTeam/components/MembersContent.js +48 -0
  112. package/dist/courseTeam/components/MembersContent.js.map +1 -0
  113. package/dist/courseTeam/components/RoleFilter.d.ts +7 -0
  114. package/dist/courseTeam/components/RoleFilter.js +22 -0
  115. package/dist/courseTeam/components/RoleFilter.js.map +1 -0
  116. package/dist/courseTeam/components/RolesContent.d.ts +3 -0
  117. package/dist/courseTeam/components/RolesContent.js +25 -0
  118. package/dist/courseTeam/components/RolesContent.js.map +1 -0
  119. package/dist/courseTeam/constants.d.ts +3 -0
  120. package/dist/courseTeam/constants.js +4 -0
  121. package/dist/courseTeam/constants.js.map +1 -0
  122. package/dist/courseTeam/data/api.d.ts +6 -0
  123. package/dist/courseTeam/data/api.js +38 -0
  124. package/dist/courseTeam/data/api.js.map +1 -0
  125. package/dist/courseTeam/data/apiHook.d.ts +8 -0
  126. package/dist/courseTeam/data/apiHook.js +32 -0
  127. package/dist/courseTeam/data/apiHook.js.map +1 -0
  128. package/dist/courseTeam/data/queryKeys.d.ts +7 -0
  129. package/dist/courseTeam/data/queryKeys.js +14 -0
  130. package/dist/courseTeam/data/queryKeys.js.map +1 -0
  131. package/dist/courseTeam/messages.d.ts +258 -0
  132. package/dist/courseTeam/messages.js +260 -0
  133. package/dist/courseTeam/messages.js.map +1 -0
  134. package/dist/courseTeam/types.d.ts +29 -0
  135. package/dist/courseTeam/types.js +3 -0
  136. package/dist/courseTeam/types.js.map +1 -0
  137. package/dist/data/api.d.ts +2 -1
  138. package/dist/data/api.js +9 -3
  139. package/dist/data/api.js.map +1 -1
  140. package/dist/data/apiHook.d.ts +1 -0
  141. package/dist/data/apiHook.js +11 -2
  142. package/dist/data/apiHook.js.map +1 -1
  143. package/dist/data/queryKeys.d.ts +4 -0
  144. package/dist/data/queryKeys.js +4 -0
  145. package/dist/data/queryKeys.js.map +1 -1
  146. package/dist/data/utils.d.ts +2 -0
  147. package/dist/data/utils.js +9 -0
  148. package/dist/data/utils.js.map +1 -0
  149. package/dist/dateExtensions/components/AddExtensionModal.d.ts +1 -1
  150. package/dist/dateExtensions/components/AddExtensionModal.js +6 -7
  151. package/dist/dateExtensions/components/AddExtensionModal.js.map +1 -1
  152. package/dist/dateExtensions/components/DateExtensionsList.js +3 -14
  153. package/dist/dateExtensions/components/DateExtensionsList.js.map +1 -1
  154. package/dist/dateExtensions/data/apiHook.d.ts +2 -2
  155. package/dist/dateExtensions/data/apiHook.js +4 -4
  156. package/dist/dateExtensions/data/apiHook.js.map +1 -1
  157. package/dist/dateExtensions/messages.d.ts +0 -5
  158. package/dist/dateExtensions/messages.js +1 -6
  159. package/dist/dateExtensions/messages.js.map +1 -1
  160. package/dist/enrollments/EnrollmentsPage.js +34 -7
  161. package/dist/enrollments/EnrollmentsPage.js.map +1 -1
  162. package/dist/enrollments/components/AddBetaTestersModal.d.ts +6 -0
  163. package/dist/enrollments/components/AddBetaTestersModal.js +69 -0
  164. package/dist/enrollments/components/AddBetaTestersModal.js.map +1 -0
  165. package/dist/enrollments/components/EnrollLearnersModal.d.ts +6 -0
  166. package/dist/enrollments/components/EnrollLearnersModal.js +53 -0
  167. package/dist/enrollments/components/EnrollLearnersModal.js.map +1 -0
  168. package/dist/enrollments/components/EnrollmentStatusModal.js +3 -3
  169. package/dist/enrollments/components/EnrollmentStatusModal.js.map +1 -1
  170. package/dist/enrollments/components/EnrollmentsList.d.ts +3 -2
  171. package/dist/enrollments/components/EnrollmentsList.js +13 -14
  172. package/dist/enrollments/components/EnrollmentsList.js.map +1 -1
  173. package/dist/enrollments/components/UnenrollModal.d.ts +1 -1
  174. package/dist/enrollments/components/UnenrollModal.js +29 -3
  175. package/dist/enrollments/components/UnenrollModal.js.map +1 -1
  176. package/dist/enrollments/components/UpdateBetaTesterModal.d.ts +8 -0
  177. package/dist/enrollments/components/UpdateBetaTesterModal.js +72 -0
  178. package/dist/enrollments/components/UpdateBetaTesterModal.js.map +1 -0
  179. package/dist/enrollments/data/api.d.ts +3 -1
  180. package/dist/enrollments/data/api.js +11 -1
  181. package/dist/enrollments/data/api.js.map +1 -1
  182. package/dist/enrollments/data/apiHook.d.ts +5 -3
  183. package/dist/enrollments/data/apiHook.js +21 -3
  184. package/dist/enrollments/data/apiHook.js.map +1 -1
  185. package/dist/enrollments/data/queryKeys.d.ts +1 -1
  186. package/dist/enrollments/data/queryKeys.js.map +1 -1
  187. package/dist/enrollments/messages.d.ts +131 -1
  188. package/dist/enrollments/messages.js +136 -6
  189. package/dist/enrollments/messages.js.map +1 -1
  190. package/dist/enrollments/types.d.ts +25 -0
  191. package/dist/enrollments/types.js.map +1 -1
  192. package/dist/grading/GradingPage.js +15 -2
  193. package/dist/grading/GradingPage.js.map +1 -1
  194. package/dist/grading/components/GradingActionRow.d.ts +2 -0
  195. package/dist/grading/components/GradingActionRow.js +20 -0
  196. package/dist/grading/components/GradingActionRow.js.map +1 -0
  197. package/dist/grading/components/GradingConfigurationModal.d.ts +6 -0
  198. package/dist/grading/components/GradingConfigurationModal.js +15 -0
  199. package/dist/grading/components/GradingConfigurationModal.js.map +1 -0
  200. package/dist/grading/components/GradingLearnerContent.d.ts +7 -0
  201. package/dist/grading/components/GradingLearnerContent.js +199 -0
  202. package/dist/grading/components/GradingLearnerContent.js.map +1 -0
  203. package/dist/grading/data/api.d.ts +6 -0
  204. package/dist/grading/data/api.js +59 -0
  205. package/dist/grading/data/api.js.map +1 -0
  206. package/dist/grading/data/apiHook.d.ts +6 -0
  207. package/dist/grading/data/apiHook.js +29 -0
  208. package/dist/grading/data/apiHook.js.map +1 -0
  209. package/dist/grading/data/queryKeys.d.ts +9 -0
  210. package/dist/grading/data/queryKeys.js +8 -0
  211. package/dist/grading/data/queryKeys.js.map +1 -0
  212. package/dist/grading/messages.d.ts +248 -0
  213. package/dist/grading/messages.js +250 -0
  214. package/dist/grading/messages.js.map +1 -0
  215. package/dist/grading/types.d.ts +11 -0
  216. package/dist/grading/types.js +2 -0
  217. package/dist/grading/types.js.map +1 -0
  218. package/dist/hooks/useDebouncedFilter.d.ts +1 -0
  219. package/dist/hooks/useDebouncedFilter.js +5 -0
  220. package/dist/hooks/useDebouncedFilter.js.map +1 -1
  221. package/dist/instructorNav/InstructorNav.js +16 -4
  222. package/dist/instructorNav/InstructorNav.js.map +1 -1
  223. package/dist/messages.d.ts +8 -0
  224. package/dist/messages.js +10 -0
  225. package/dist/messages.js.map +1 -0
  226. package/dist/pageWrapper/PageWrapper.js +3 -1
  227. package/dist/pageWrapper/PageWrapper.js.map +1 -1
  228. package/dist/providers/AccessErrorObserver.d.ts +9 -0
  229. package/dist/providers/AccessErrorObserver.js +35 -0
  230. package/dist/providers/AccessErrorObserver.js.map +1 -0
  231. package/dist/providers/AccessErrorProvider.d.ts +19 -0
  232. package/dist/providers/AccessErrorProvider.js +51 -0
  233. package/dist/providers/AccessErrorProvider.js.map +1 -0
  234. package/dist/providers/AlertProvider.js +1 -1
  235. package/dist/providers/AlertProvider.js.map +1 -1
  236. package/dist/providers/messages.d.ts +33 -0
  237. package/dist/providers/messages.js +35 -0
  238. package/dist/providers/messages.js.map +1 -0
  239. package/dist/provides.d.ts +2 -1
  240. package/dist/provides.js +3 -2
  241. package/dist/provides.js.map +1 -1
  242. package/dist/routes.d.ts +1 -1
  243. package/dist/routes.js +2 -2
  244. package/dist/routes.js.map +1 -1
  245. package/dist/slots/CourseInfoSlot/CourseInfoSlot.d.ts +2 -0
  246. package/dist/slots/CourseInfoSlot/CourseInfoSlot.js +14 -0
  247. package/dist/slots/CourseInfoSlot/CourseInfoSlot.js.map +1 -0
  248. package/dist/slots.js +13 -1
  249. package/dist/slots.js.map +1 -1
  250. package/dist/specialExams/SpecialExamsPage.js +14 -2
  251. package/dist/specialExams/SpecialExamsPage.js.map +1 -1
  252. package/dist/specialExams/components/AddAllowanceModal.d.ts +6 -0
  253. package/dist/specialExams/components/AddAllowanceModal.js +84 -0
  254. package/dist/specialExams/components/AddAllowanceModal.js.map +1 -0
  255. package/dist/specialExams/components/Allowances.d.ts +2 -0
  256. package/dist/specialExams/components/Allowances.js +89 -0
  257. package/dist/specialExams/components/Allowances.js.map +1 -0
  258. package/dist/specialExams/components/AllowancesList.d.ts +8 -0
  259. package/dist/specialExams/components/AllowancesList.js +63 -0
  260. package/dist/specialExams/components/AllowancesList.js.map +1 -0
  261. package/dist/specialExams/components/AttemptsList.d.ts +3 -0
  262. package/dist/specialExams/components/AttemptsList.js +50 -0
  263. package/dist/specialExams/components/AttemptsList.js.map +1 -0
  264. package/dist/specialExams/components/DeleteAllowanceModal.d.ts +8 -0
  265. package/dist/specialExams/components/DeleteAllowanceModal.js +29 -0
  266. package/dist/specialExams/components/DeleteAllowanceModal.js.map +1 -0
  267. package/dist/specialExams/components/EditAllowanceModal.d.ts +8 -0
  268. package/dist/specialExams/components/EditAllowanceModal.js +62 -0
  269. package/dist/specialExams/components/EditAllowanceModal.js.map +1 -0
  270. package/dist/specialExams/constants.d.ts +43 -0
  271. package/dist/specialExams/constants.js +19 -0
  272. package/dist/specialExams/constants.js.map +1 -0
  273. package/dist/specialExams/data/api.d.ts +7 -0
  274. package/dist/specialExams/data/api.js +55 -0
  275. package/dist/specialExams/data/api.js.map +1 -0
  276. package/dist/specialExams/data/apiHook.d.ts +6 -0
  277. package/dist/specialExams/data/apiHook.js +37 -0
  278. package/dist/specialExams/data/apiHook.js.map +1 -0
  279. package/dist/specialExams/data/queryKeys.d.ts +8 -0
  280. package/dist/specialExams/data/queryKeys.js +9 -0
  281. package/dist/specialExams/data/queryKeys.js.map +1 -0
  282. package/dist/specialExams/messages.d.ts +228 -0
  283. package/dist/specialExams/messages.js +230 -0
  284. package/dist/specialExams/messages.js.map +1 -0
  285. package/dist/specialExams/types.d.ts +65 -0
  286. package/dist/specialExams/types.js +2 -0
  287. package/dist/specialExams/types.js.map +1 -0
  288. package/dist/style.scss +16 -0
  289. package/dist/testUtils.js +2 -2
  290. package/dist/testUtils.js.map +1 -1
  291. package/dist/types/index.d.ts +15 -0
  292. package/dist/types/index.js.map +1 -1
  293. package/dist/utils/formatters.d.ts +5 -0
  294. package/dist/utils/formatters.js +10 -0
  295. package/dist/utils/formatters.js.map +1 -1
  296. package/package.json +6 -6
  297. package/dist/app.scss +0 -10
  298. package/dist/providers/QueryProvider.d.ts +0 -6
  299. package/dist/providers/QueryProvider.js +0 -16
  300. package/dist/providers/QueryProvider.js.map +0 -1
  301. package/dist/providers.d.ts +0 -3
  302. package/dist/providers.js +0 -8
  303. package/dist/providers.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AlertProvider.js","sourceRoot":"","sources":["../../src/providers/AlertProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import { createContext, useContext, useState, ReactNode, useCallback, useMemo, FC } from 'react';\nimport { Toast, AlertModal, ActionRow, Button, Alert } from '@openedx/paragon';\nimport { WarningFilled, Error as ErrorIcon, Info as InfoIcon, CheckCircle } from '@openedx/paragon/icons';\n\n// Toast Alert Types\ninterface ToastAlert {\n id: string,\n type: 'toast',\n message: string,\n visible: boolean,\n delay?: number,\n}\n\n// Modal Alert Types\ninterface ModalAlert {\n id: string,\n type: 'modal',\n title?: string,\n message: string,\n variant: 'default' | 'warning' | 'danger' | 'success',\n isOpen: boolean,\n confirmText?: string,\n cancelText?: string,\n onConfirm?: (id: string) => void,\n onCancel?: () => void,\n}\n\nexport type AlertType = 'success' | 'error' | 'info' | 'warning' | 'danger';\n\nexport interface AlertProps {\n id: string,\n type: AlertType,\n message: string,\n extraContent?: ReactNode,\n}\n\ninterface InlineAlert {\n id: string,\n type: 'inline',\n message: string,\n variant: 'success' | 'danger' | 'warning' | 'info',\n dismissible?: boolean,\n}\n\ninterface AlertContextType {\n showToast: (message: string, delay?: number) => void,\n showModal: (options: {\n title?: string,\n message: string,\n variant?: 'default' | 'warning' | 'danger' | 'success',\n confirmText?: string,\n cancelText?: string,\n onConfirm?: (id: string) => void,\n onCancel?: () => void,\n }) => void,\n showInlineAlert: (message: string, variant?: 'success' | 'danger' | 'warning' | 'info', dismissible?: boolean) => string,\n dismissInlineAlert: (id: string) => void,\n inlineAlerts: InlineAlert[],\n alerts: AlertProps[],\n addAlert: (alert: Omit<AlertProps, 'id'>) => void,\n removeAlert: (id: string) => void,\n clearAlerts: () => void,\n}\n\nconst AlertContext = createContext<AlertContextType | undefined>(undefined);\n\ninterface AlertProviderProps {\n children: ReactNode,\n}\n\nconst variantIcons: Record<string, any> = {\n success: CheckCircle,\n error: ErrorIcon,\n warning: WarningFilled,\n info: InfoIcon,\n danger: ErrorIcon,\n};\n\nexport const AlertProvider: FC<AlertProviderProps> = ({ children }) => {\n const [toasts, setToasts] = useState<ToastAlert[]>([]);\n const [modals, setModals] = useState<ModalAlert[]>([]);\n const [inlineAlerts, setInlineAlerts] = useState<InlineAlert[]>([]);\n const [alerts, setAlerts] = useState<AlertProps[]>([]); // PR #113 compatible state\n\n // Toast Methods\n const showToast = useCallback((message: string, delay?: number) => {\n const id = `toast-${Date.now()}`;\n const newToast: ToastAlert = { id, type: 'toast', message, visible: true, delay };\n setToasts(prev => [...prev, newToast]);\n }, []);\n\n const discardToast = useCallback((id: string) => {\n setToasts(prev => prev.map(t => (t.id === id ? { ...t, visible: false } : t)));\n setTimeout(() => {\n setToasts(prev => prev.filter(t => t.id !== id));\n }, 500);\n }, []);\n\n // Modal Methods\n const showModal = useCallback((options: {\n title?: string,\n message: string,\n variant?: 'default' | 'warning' | 'danger' | 'success',\n confirmText?: string,\n cancelText?: string,\n onConfirm?: (id: string) => void,\n onCancel?: () => void,\n }) => {\n const id = `modal-${Date.now()}-${Math.random()}`;\n const newModal: ModalAlert = {\n id,\n type: 'modal',\n title: options.title,\n message: options.message,\n variant: options.variant || 'default',\n isOpen: true,\n confirmText: options.confirmText,\n cancelText: options.cancelText,\n onConfirm: options.onConfirm,\n onCancel: options.onCancel,\n };\n setModals(prev => [...prev, newModal]);\n }, []);\n\n const closeModal = useCallback((id: string, callOnCancel?: boolean) => {\n setModals(prev => {\n const modal = prev.find(m => m.id === id);\n if (modal && callOnCancel && modal.onCancel) {\n modal.onCancel();\n }\n return prev.filter(m => m.id !== id);\n });\n }, []);\n\n const confirmModal = useCallback((id: string) => {\n setModals(prev => {\n const modal = prev.find(m => m.id === id);\n if (modal?.onConfirm) {\n modal.onConfirm(id);\n }\n return prev.filter(m => m.id !== id);\n });\n }, []);\n\n // Inline Alert Methods\n const showInlineAlert = useCallback((\n message: string,\n variant: 'success' | 'danger' | 'warning' | 'info' = 'info',\n dismissible = true\n ): string => {\n const id = `inline-${Date.now()}`;\n const newAlert: InlineAlert = { id, type: 'inline', message, variant, dismissible };\n setInlineAlerts(prev => [...prev, newAlert]);\n return id;\n }, []);\n\n const dismissInlineAlert = useCallback((id: string) => {\n setInlineAlerts(prev => prev.filter(a => a.id !== id));\n }, []);\n\n const addAlert = useCallback((alert: Omit<AlertProps, 'id'>) => {\n const id = `alert-${Date.now()}-${Math.random()}`;\n const newAlert: AlertProps = { ...alert, id };\n setAlerts(prev => [...prev, newAlert]);\n }, []);\n\n const removeAlert = useCallback((id: string) => {\n setAlerts(prev => prev.filter(a => a.id !== id));\n }, []);\n\n const clearAlerts = useCallback(() => {\n setToasts([]);\n setModals([]);\n setInlineAlerts([]);\n setAlerts([]);\n }, []);\n\n const value = useMemo(() => ({\n showToast,\n showModal,\n showInlineAlert,\n dismissInlineAlert,\n clearAlerts,\n inlineAlerts,\n alerts,\n addAlert,\n removeAlert,\n }), [showToast, showModal, showInlineAlert, dismissInlineAlert, clearAlerts, inlineAlerts, alerts, addAlert, removeAlert]);\n\n return (\n <AlertContext.Provider value={value}>\n {children}\n\n {/* Toast Container */}\n <div className=\"toast-container\">\n {toasts.map(toast => (\n <Toast\n key={toast.id}\n show={toast.visible}\n onClose={() => discardToast(toast.id)}\n delay={toast.delay}\n className=\"text-break\"\n >\n {toast.message}\n </Toast>\n ))}\n </div>\n\n {/* Modal Alerts - Only show the first modal in the queue */}\n {modals.length > 0 && (() => {\n const modal = modals[0];\n const icon = variantIcons[modal.variant];\n return (\n <AlertModal\n key={modal.id}\n title={modal.title}\n isOpen={modal.isOpen}\n onClose={() => closeModal(modal.id, true)}\n variant={modal.variant}\n {...(icon && { icon })}\n hasHeader={!!modal.title}\n footerNode={(\n <ActionRow>\n {modal.cancelText && (\n <Button variant=\"tertiary\" onClick={() => closeModal(modal.id, true)}>\n {modal.cancelText}\n </Button>\n )}\n {modal.confirmText && (\n <Button\n variant={modal.variant === 'danger' ? 'danger' : 'primary'}\n onClick={() => confirmModal(modal.id)}\n >\n {modal.confirmText}\n </Button>\n )}\n </ActionRow>\n )}\n >\n <p>{modal.message}</p>\n </AlertModal>\n );\n })()}\n </AlertContext.Provider>\n );\n};\n\nexport const AlertOutlet: FC = () => {\n const { alerts, removeAlert } = useAlert();\n\n return (\n <div className=\"alert-outlet\">\n {alerts.map(alert => (\n <Alert\n key={alert.id}\n className=\"mt-3\"\n icon={variantIcons[alert.type]}\n variant={alert.type === 'error' ? 'danger' : alert.type}\n dismissible\n onClose={() => removeAlert(alert.id)}\n >\n {alert.message}\n {alert.extraContent}\n </Alert>\n ))}\n </div>\n );\n};\n\nexport const useAlert = (): AlertContextType => {\n const context = useContext(AlertContext);\n if (context === undefined) {\n throw new Error('useAlert must be used within an AlertProvider');\n }\n return context;\n};\n"]}
1
+ {"version":3,"file":"AlertProvider.js","sourceRoot":"","sources":["../../src/providers/AlertProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import { createContext, useContext, useState, ReactNode, useCallback, useMemo, FC } from 'react';\nimport { Toast, AlertModal, ActionRow, Button, Alert } from '@openedx/paragon';\nimport { WarningFilled, Error as ErrorIcon, Info as InfoIcon, CheckCircle } from '@openedx/paragon/icons';\n\n// Toast Alert Types\ninterface ToastAlert {\n id: string,\n type: 'toast',\n message: string,\n visible: boolean,\n delay?: number,\n}\n\n// Modal Alert Types\ninterface ModalAlert {\n id: string,\n type: 'modal',\n title?: string,\n message: string,\n variant: 'default' | 'warning' | 'danger' | 'success',\n isOpen: boolean,\n confirmText?: string,\n cancelText?: string,\n onConfirm?: (id: string) => void,\n onCancel?: () => void,\n}\n\nexport type AlertType = 'success' | 'error' | 'info' | 'warning' | 'danger';\n\nexport interface AlertProps {\n id: string,\n type: AlertType,\n message: string,\n extraContent?: ReactNode,\n}\n\ninterface InlineAlert {\n id: string,\n type: 'inline',\n message: string,\n variant: 'success' | 'danger' | 'warning' | 'info',\n dismissible?: boolean,\n}\n\ninterface AlertContextType {\n showToast: (message: string, delay?: number) => void,\n showModal: (options: {\n title?: string,\n message: string,\n variant?: 'default' | 'warning' | 'danger' | 'success',\n confirmText?: string,\n cancelText?: string,\n onConfirm?: (id: string) => void,\n onCancel?: () => void,\n }) => void,\n showInlineAlert: (message: string, variant?: 'success' | 'danger' | 'warning' | 'info', dismissible?: boolean) => string,\n dismissInlineAlert: (id: string) => void,\n inlineAlerts: InlineAlert[],\n alerts: AlertProps[],\n addAlert: (alert: Omit<AlertProps, 'id'>) => void,\n removeAlert: (id: string) => void,\n clearAlerts: () => void,\n}\n\nconst AlertContext = createContext<AlertContextType | undefined>(undefined);\n\ninterface AlertProviderProps {\n children: ReactNode,\n}\n\nconst variantIcons: Record<string, any> = {\n success: CheckCircle,\n error: ErrorIcon,\n warning: WarningFilled,\n info: InfoIcon,\n danger: ErrorIcon,\n};\n\nexport const AlertProvider: FC<AlertProviderProps> = ({ children }) => {\n const [toasts, setToasts] = useState<ToastAlert[]>([]);\n const [modals, setModals] = useState<ModalAlert[]>([]);\n const [inlineAlerts, setInlineAlerts] = useState<InlineAlert[]>([]);\n const [alerts, setAlerts] = useState<AlertProps[]>([]); // PR #113 compatible state\n\n // Toast Methods\n const showToast = useCallback((message: string, delay?: number) => {\n const id = `toast-${Date.now()}`;\n const newToast: ToastAlert = { id, type: 'toast', message, visible: true, delay };\n setToasts(prev => [...prev, newToast]);\n }, []);\n\n const discardToast = useCallback((id: string) => {\n setToasts(prev => prev.map(t => (t.id === id ? { ...t, visible: false } : t)));\n setTimeout(() => {\n setToasts(prev => prev.filter(t => t.id !== id));\n }, 500);\n }, []);\n\n // Modal Methods\n const showModal = useCallback((options: {\n title?: string,\n message: string,\n variant?: 'default' | 'warning' | 'danger' | 'success',\n confirmText?: string,\n cancelText?: string,\n onConfirm?: (id: string) => void,\n onCancel?: () => void,\n }) => {\n const id = `modal-${Date.now()}-${Math.random()}`;\n const newModal: ModalAlert = {\n id,\n type: 'modal',\n title: options.title,\n message: options.message,\n variant: options.variant || 'default',\n isOpen: true,\n confirmText: options.confirmText,\n cancelText: options.cancelText,\n onConfirm: options.onConfirm,\n onCancel: options.onCancel,\n };\n setModals(prev => [...prev, newModal]);\n }, []);\n\n const closeModal = useCallback((id: string, callOnCancel?: boolean) => {\n setModals(prev => {\n const modal = prev.find(m => m.id === id);\n if (modal && callOnCancel && modal.onCancel) {\n modal.onCancel();\n }\n return prev.filter(m => m.id !== id);\n });\n }, []);\n\n const confirmModal = useCallback((id: string) => {\n setModals(prev => {\n const modal = prev.find(m => m.id === id);\n if (modal?.onConfirm) {\n modal.onConfirm(id);\n }\n return prev.filter(m => m.id !== id);\n });\n }, []);\n\n // Inline Alert Methods\n const showInlineAlert = useCallback((\n message: string,\n variant: 'success' | 'danger' | 'warning' | 'info' = 'info',\n dismissible = true\n ): string => {\n const id = `inline-${Date.now()}`;\n const newAlert: InlineAlert = { id, type: 'inline', message, variant, dismissible };\n setInlineAlerts(prev => [...prev, newAlert]);\n return id;\n }, []);\n\n const dismissInlineAlert = useCallback((id: string) => {\n setInlineAlerts(prev => prev.filter(a => a.id !== id));\n }, []);\n\n const addAlert = useCallback((alert: Omit<AlertProps, 'id'>) => {\n const id = `alert-${Date.now()}-${Math.random()}`;\n const newAlert: AlertProps = { ...alert, id };\n setAlerts(prev => [...prev, newAlert]);\n }, []);\n\n const removeAlert = useCallback((id: string) => {\n setAlerts(prev => prev.filter(a => a.id !== id));\n }, []);\n\n const clearAlerts = useCallback(() => {\n setToasts([]);\n setModals([]);\n setInlineAlerts([]);\n setAlerts([]);\n }, []);\n\n const value = useMemo(() => ({\n showToast,\n showModal,\n showInlineAlert,\n dismissInlineAlert,\n clearAlerts,\n inlineAlerts,\n alerts,\n addAlert,\n removeAlert,\n }), [showToast, showModal, showInlineAlert, dismissInlineAlert, clearAlerts, inlineAlerts, alerts, addAlert, removeAlert]);\n\n return (\n <AlertContext.Provider value={value}>\n {children}\n\n {/* Toast Container */}\n <div className=\"toast-container\">\n {toasts.map(toast => (\n <Toast\n key={toast.id}\n show={toast.visible}\n onClose={() => discardToast(toast.id)}\n delay={toast.delay}\n className=\"text-break\"\n >\n {toast.message}\n </Toast>\n ))}\n </div>\n\n {/* Modal Alerts - Only show the first modal in the queue */}\n {modals.length > 0 && (() => {\n const modal = modals[0];\n const icon = variantIcons[modal.variant];\n return (\n <AlertModal\n key={modal.id}\n title={modal.title}\n isOpen={modal.isOpen}\n onClose={() => closeModal(modal.id, true)}\n variant={modal.variant}\n {...(icon && { icon })}\n hasHeader={!!modal.title}\n footerNode={(\n <ActionRow>\n {modal.cancelText && (\n <Button variant=\"tertiary\" onClick={() => closeModal(modal.id, true)}>\n {modal.cancelText}\n </Button>\n )}\n {modal.confirmText && (\n <Button\n variant={modal.variant === 'danger' ? 'danger' : 'primary'}\n onClick={() => modal.onConfirm ? confirmModal(modal.id) : closeModal(modal.id, false)}\n >\n {modal.confirmText}\n </Button>\n )}\n </ActionRow>\n )}\n >\n <p>{modal.message}</p>\n </AlertModal>\n );\n })()}\n </AlertContext.Provider>\n );\n};\n\nexport const AlertOutlet: FC = () => {\n const { alerts, removeAlert } = useAlert();\n\n return (\n <div className=\"alert-outlet\">\n {alerts.map(alert => (\n <Alert\n key={alert.id}\n className=\"mt-3\"\n icon={variantIcons[alert.type]}\n variant={alert.type === 'error' ? 'danger' : alert.type}\n dismissible\n onClose={() => removeAlert(alert.id)}\n >\n {alert.message}\n {alert.extraContent}\n </Alert>\n ))}\n </div>\n );\n};\n\nexport const useAlert = (): AlertContextType => {\n const context = useContext(AlertContext);\n if (context === undefined) {\n throw new Error('useAlert must be used within an AlertProvider');\n }\n return context;\n};\n"]}
@@ -0,0 +1,33 @@
1
+ declare const messages: {
2
+ forbiddenErrorHeading: {
3
+ id: string;
4
+ defaultMessage: string;
5
+ description: string;
6
+ };
7
+ forbiddenErrorMessage: {
8
+ id: string;
9
+ defaultMessage: string;
10
+ description: string;
11
+ };
12
+ unauthorizedErrorHeading: {
13
+ id: string;
14
+ defaultMessage: string;
15
+ description: string;
16
+ };
17
+ unauthorizedErrorMessage: {
18
+ id: string;
19
+ defaultMessage: string;
20
+ description: string;
21
+ };
22
+ genericErrorHeading: {
23
+ id: string;
24
+ defaultMessage: string;
25
+ description: string;
26
+ };
27
+ genericErrorMessage: {
28
+ id: string;
29
+ defaultMessage: string;
30
+ description: string;
31
+ };
32
+ };
33
+ export default messages;
@@ -0,0 +1,35 @@
1
+ import { defineMessages } from '@openedx/frontend-base';
2
+ const messages = defineMessages({
3
+ forbiddenErrorHeading: {
4
+ id: 'instructorDashboard.forbiddenError.heading',
5
+ defaultMessage: 'Access Denied',
6
+ description: 'Heading for the forbidden access error message',
7
+ },
8
+ forbiddenErrorMessage: {
9
+ id: 'instructorDashboard.forbiddenError.message',
10
+ defaultMessage: 'You do not have permission to access this content. Please contact the administrator if you believe this is an error.',
11
+ description: 'Message displayed when user lacks permission to access content',
12
+ },
13
+ unauthorizedErrorHeading: {
14
+ id: 'instructorDashboard.unauthorizedError.heading',
15
+ defaultMessage: 'Unauthorized',
16
+ description: 'Heading for the unauthorized access error message',
17
+ },
18
+ unauthorizedErrorMessage: {
19
+ id: 'instructorDashboard.unauthorizedError.message',
20
+ defaultMessage: 'You must be logged in and have instructor permissions to view this content.',
21
+ description: 'Message displayed when user is not authenticated or lacks instructor permissions',
22
+ },
23
+ genericErrorHeading: {
24
+ id: 'instructorDashboard.genericError.heading',
25
+ defaultMessage: 'Something went wrong',
26
+ description: 'Heading for a generic server error message',
27
+ },
28
+ genericErrorMessage: {
29
+ id: 'instructorDashboard.genericError.message',
30
+ defaultMessage: 'An unexpected error occurred. Please try again later.',
31
+ description: 'Message displayed when an unexpected server error occurs',
32
+ },
33
+ });
34
+ export default messages;
35
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/providers/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,qBAAqB,EAAE;QACrB,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,eAAe;QAC/B,WAAW,EAAE,gDAAgD;KAC9D;IACD,qBAAqB,EAAE;QACrB,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,sHAAsH;QACtI,WAAW,EAAE,gEAAgE;KAC9E;IACD,wBAAwB,EAAE;QACxB,EAAE,EAAE,+CAA+C;QACnD,cAAc,EAAE,cAAc;QAC9B,WAAW,EAAE,mDAAmD;KACjE;IACD,wBAAwB,EAAE;QACxB,EAAE,EAAE,+CAA+C;QACnD,cAAc,EAAE,6EAA6E;QAC7F,WAAW,EAAE,kFAAkF;KAChG;IACD,mBAAmB,EAAE;QACnB,EAAE,EAAE,0CAA0C;QAC9C,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,4CAA4C;KAC1D;IACD,mBAAmB,EAAE;QACnB,EAAE,EAAE,0CAA0C;QAC9C,cAAc,EAAE,uDAAuD;QACvE,WAAW,EAAE,0DAA0D;KACxE;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n forbiddenErrorHeading: {\n id: 'instructorDashboard.forbiddenError.heading',\n defaultMessage: 'Access Denied',\n description: 'Heading for the forbidden access error message',\n },\n forbiddenErrorMessage: {\n id: 'instructorDashboard.forbiddenError.message',\n defaultMessage: 'You do not have permission to access this content. Please contact the administrator if you believe this is an error.',\n description: 'Message displayed when user lacks permission to access content',\n },\n unauthorizedErrorHeading: {\n id: 'instructorDashboard.unauthorizedError.heading',\n defaultMessage: 'Unauthorized',\n description: 'Heading for the unauthorized access error message',\n },\n unauthorizedErrorMessage: {\n id: 'instructorDashboard.unauthorizedError.message',\n defaultMessage: 'You must be logged in and have instructor permissions to view this content.',\n description: 'Message displayed when user is not authenticated or lacks instructor permissions',\n },\n genericErrorHeading: {\n id: 'instructorDashboard.genericError.heading',\n defaultMessage: 'Something went wrong',\n description: 'Heading for a generic server error message',\n },\n genericErrorMessage: {\n id: 'instructorDashboard.genericError.message',\n defaultMessage: 'An unexpected error occurred. Please try again later.',\n description: 'Message displayed when an unexpected server error occurs',\n },\n});\n\nexport default messages;\n"]}
@@ -1,4 +1,5 @@
1
1
  declare const provides: {
2
- "org.openedx.frontend.provides.courseNavigationRoles.v1": string;
2
+ "org.openedx.frontend.provides.courseBarRoles.v1": string;
3
+ "org.openedx.frontend.provides.courseBarMasqueradeRoles.v1": string;
3
4
  };
4
5
  export default provides;
package/dist/provides.js CHANGED
@@ -1,7 +1,8 @@
1
- import { providesCourseNavigationRolesId } from '@openedx/frontend-base';
1
+ import { providesCourseBarMasqueradeRolesId, providesCourseBarRolesId } from '@openedx/frontend-base';
2
2
  import { instructorDashboardRole } from './constants';
3
3
  const provides = {
4
- [providesCourseNavigationRolesId]: instructorDashboardRole
4
+ [providesCourseBarRolesId]: instructorDashboardRole,
5
+ [providesCourseBarMasqueradeRolesId]: instructorDashboardRole,
5
6
  };
6
7
  export default provides;
7
8
  //# sourceMappingURL=provides.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provides.js","sourceRoot":"","sources":["../src/provides.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,QAAQ,GAAG;IACf,CAAC,+BAA+B,CAAC,EAAE,uBAAuB;CAC3D,CAAC;AAEF,eAAe,QAAQ,CAAC","sourcesContent":["import { providesCourseNavigationRolesId } from '@openedx/frontend-base';\nimport { instructorDashboardRole } from './constants';\n\nconst provides = {\n [providesCourseNavigationRolesId]: instructorDashboardRole\n};\n\nexport default provides;\n"]}
1
+ {"version":3,"file":"provides.js","sourceRoot":"","sources":["../src/provides.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kCAAkC,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AACtG,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,QAAQ,GAAG;IACf,CAAC,wBAAwB,CAAC,EAAE,uBAAuB;IACnD,CAAC,kCAAkC,CAAC,EAAE,uBAAuB;CAC9D,CAAC;AAEF,eAAe,QAAQ,CAAC","sourcesContent":["import { providesCourseBarMasqueradeRolesId, providesCourseBarRolesId } from '@openedx/frontend-base';\nimport { instructorDashboardRole } from './constants';\n\nconst provides = {\n [providesCourseBarRolesId]: instructorDashboardRole,\n [providesCourseBarMasqueradeRolesId]: instructorDashboardRole,\n};\n\nexport default provides;\n"]}
package/dist/routes.d.ts CHANGED
@@ -2,7 +2,7 @@ declare const routes: {
2
2
  id: string;
3
3
  path: string;
4
4
  handle: {
5
- role: string;
5
+ roles: string[];
6
6
  };
7
7
  lazy(): Promise<{
8
8
  Component: () => import("react/jsx-runtime").JSX.Element;
package/dist/routes.js CHANGED
@@ -49,11 +49,11 @@ const routes = [
49
49
  id: 'org.openedx.frontend.route.instructorDashboard.main',
50
50
  path: 'instructor-dashboard/:courseId',
51
51
  handle: {
52
- role: instructorDashboardRole
52
+ roles: [instructorDashboardRole]
53
53
  },
54
54
  lazy() {
55
55
  return __awaiter(this, void 0, void 0, function* () {
56
- const module = yield import('./Main');
56
+ const module = yield import(/* webpackChunkName: "instructor-dashboard-main" */ './Main');
57
57
  return { Component: module.default };
58
58
  });
59
59
  },
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.tsx"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,WAAW,MAAM,0BAA0B,CAAC;AACnD,OAAO,cAAc,MAAM,gCAAgC,CAAC;AAC5D,OAAO,gBAAgB,MAAM,oCAAoC,CAAC;AAClE,OAAO,cAAc,MAAM,gCAAgC,CAAC;AAC5D,OAAO,iBAAiB,MAAM,sCAAsC,CAAC;AACrE,OAAO,kBAAkB,MAAM,wCAAwC,CAAC;AACxE,OAAO,eAAe,MAAM,kCAAkC,CAAC;AAC/D,OAAO,WAAW,MAAM,0BAA0B,CAAC;AACnD,OAAO,iBAAiB,MAAM,sCAAsC,CAAC;AACrE,OAAO,gBAAgB,MAAM,oCAAoC,CAAC;AAClE,OAAO,YAAY,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAOtD,MAAM,WAAW,GAA2B;IAC1C,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,KAAC,cAAc,KAAG,EAAE;IACrD,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,KAAC,eAAe,KAAG,EAAE;IACtD,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,KAAC,cAAc,KAAG,EAAE;IACrD,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAC,WAAW,KAAG,EAAE;IAC9C,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,KAAC,kBAAkB,KAAG,EAAE;IAC7D,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAC,WAAW,KAAG,EAAE;IAC9C,EAAE,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,KAAC,iBAAiB,KAAG,EAAE;IAC3D,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,KAAC,gBAAgB,KAAG,EAAE;IACzD,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,KAAC,gBAAgB,KAAG,EAAE;IACxD,EAAE,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,KAAC,iBAAiB,KAAG,EAAE;CAC5D,CAAC;AAEF,MAAM,UAAU,GAAG,GAAG,EAAE;IACtB,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,EAAqB,CAAC;IACjD,MAAM,YAAY,GAAG,cAAc,CAAC,yDAAyD,CAA2B,CAAC;IAEzH,MAAM,SAAS,GAAG;QAChB,GAAG,WAAW,CAAC,MAAM,CACnB,UAAU,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC,CAChF;QACD,GAAG,YAAY;KAChB,CAAC;IAEF,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;IAE5D,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,KAAC,YAAY,KAAG,CAAC;AACxD,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG;IACb;QACE,EAAE,EAAE,qDAAqD;QACzD,IAAI,EAAE,gCAAgC;QACtC,MAAM,EAAE;YACN,IAAI,EAAE,uBAAuB;SAC9B;QACK,IAAI;;gBACR,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACtC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YACvC,CAAC;SAAA;QACD,QAAQ,EAAE;YACR;gBACE,KAAK,EAAE,IAAI;gBACX,OAAO,EAAE,KAAC,QAAQ,IAAC,EAAE,EAAC,aAAa,EAAC,OAAO,SAAG;aAC/C;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,KAAC,UAAU,KAAG;aACxB;SACF;KACF;CACF,CAAC;AAEF,eAAe,MAAM,CAAC","sourcesContent":["import { useParams, Navigate } from 'react-router-dom';\nimport CohortsPage from '@src/cohorts/CohortsPage';\nimport CourseInfoPage from '@src/courseInfo/CourseInfoPage';\nimport CertificatesPage from '@src/certificates/CertificatesPage';\nimport CourseTeamPage from '@src/courseTeam/CourseTeamPage';\nimport DataDownloadsPage from '@src/dataDownloads/DataDownloadsPage';\nimport DateExtensionsPage from '@src/dateExtensions/DateExtensionsPage';\nimport EnrollmentsPage from '@src/enrollments/EnrollmentsPage';\nimport GradingPage from '@src/grading/GradingPage';\nimport OpenResponsesPage from '@src/openResponses/OpenResponsesPage';\nimport SpecialExamsPage from '@src/specialExams/SpecialExamsPage';\nimport PageNotFound from '@src/components/PageNotFound';\nimport { useWidgetProps } from './slots/SlotUtils';\nimport { instructorDashboardRole } from './constants';\n\ninterface InstructorRouteProps {\n tabId: string,\n content: React.ReactNode,\n}\n\nconst defaultTabs: InstructorRouteProps[] = [\n { tabId: 'course_info', content: <CourseInfoPage /> },\n { tabId: 'enrollments', content: <EnrollmentsPage /> },\n { tabId: 'course_team', content: <CourseTeamPage /> },\n { tabId: 'cohorts', content: <CohortsPage /> },\n { tabId: 'date_extensions', content: <DateExtensionsPage /> },\n { tabId: 'grading', content: <GradingPage /> },\n { tabId: 'data_downloads', content: <DataDownloadsPage /> },\n { tabId: 'special_exams', content: <SpecialExamsPage /> },\n { tabId: 'certificates', content: <CertificatesPage /> },\n { tabId: 'open_responses', content: <OpenResponsesPage /> },\n];\n\nconst TabContent = () => {\n const { tabId } = useParams<{ tabId: string }>();\n const routeWidgets = useWidgetProps('org.openedx.frontend.slot.instructorDashboard.routes.v1') as InstructorRouteProps[];\n\n const tabRoutes = [\n ...defaultTabs.filter(\n defaultTab => !routeWidgets.some(slotTab => slotTab.tabId === defaultTab.tabId)\n ),\n ...routeWidgets\n ];\n\n const foundTab = tabRoutes.find(tab => tab.tabId === tabId);\n\n return foundTab ? foundTab.content : <PageNotFound />;\n};\n\nconst routes = [\n {\n id: 'org.openedx.frontend.route.instructorDashboard.main',\n path: 'instructor-dashboard/:courseId',\n handle: {\n role: instructorDashboardRole\n },\n async lazy() {\n const module = await import('./Main');\n return { Component: module.default };\n },\n children: [\n {\n index: true,\n element: <Navigate to=\"course_info\" replace />\n },\n {\n path: ':tabId',\n element: <TabContent />\n },\n ]\n }\n];\n\nexport default routes;\n"]}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.tsx"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,WAAW,MAAM,0BAA0B,CAAC;AACnD,OAAO,cAAc,MAAM,gCAAgC,CAAC;AAC5D,OAAO,gBAAgB,MAAM,oCAAoC,CAAC;AAClE,OAAO,cAAc,MAAM,gCAAgC,CAAC;AAC5D,OAAO,iBAAiB,MAAM,sCAAsC,CAAC;AACrE,OAAO,kBAAkB,MAAM,wCAAwC,CAAC;AACxE,OAAO,eAAe,MAAM,kCAAkC,CAAC;AAC/D,OAAO,WAAW,MAAM,0BAA0B,CAAC;AACnD,OAAO,iBAAiB,MAAM,sCAAsC,CAAC;AACrE,OAAO,gBAAgB,MAAM,oCAAoC,CAAC;AAClE,OAAO,YAAY,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAOtD,MAAM,WAAW,GAA2B;IAC1C,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,KAAC,cAAc,KAAG,EAAE;IACrD,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,KAAC,eAAe,KAAG,EAAE;IACtD,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,KAAC,cAAc,KAAG,EAAE;IACrD,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAC,WAAW,KAAG,EAAE;IAC9C,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,KAAC,kBAAkB,KAAG,EAAE;IAC7D,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAC,WAAW,KAAG,EAAE;IAC9C,EAAE,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,KAAC,iBAAiB,KAAG,EAAE;IAC3D,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,KAAC,gBAAgB,KAAG,EAAE;IACzD,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,KAAC,gBAAgB,KAAG,EAAE;IACxD,EAAE,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,KAAC,iBAAiB,KAAG,EAAE;CAC5D,CAAC;AAEF,MAAM,UAAU,GAAG,GAAG,EAAE;IACtB,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,EAAqB,CAAC;IACjD,MAAM,YAAY,GAAG,cAAc,CAAC,yDAAyD,CAA2B,CAAC;IAEzH,MAAM,SAAS,GAAG;QAChB,GAAG,WAAW,CAAC,MAAM,CACnB,UAAU,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC,CAChF;QACD,GAAG,YAAY;KAChB,CAAC;IAEF,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;IAE5D,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,KAAC,YAAY,KAAG,CAAC;AACxD,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG;IACb;QACE,EAAE,EAAE,qDAAqD;QACzD,IAAI,EAAE,gCAAgC;QACtC,MAAM,EAAE;YACN,KAAK,EAAE,CAAC,uBAAuB,CAAC;SACjC;QACK,IAAI;;gBACR,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,mDAAmD,CAAC,QAAQ,CAAC,CAAC;gBAC1F,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YACvC,CAAC;SAAA;QACD,QAAQ,EAAE;YACR;gBACE,KAAK,EAAE,IAAI;gBACX,OAAO,EAAE,KAAC,QAAQ,IAAC,EAAE,EAAC,aAAa,EAAC,OAAO,SAAG;aAC/C;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,KAAC,UAAU,KAAG;aACxB;SACF;KACF;CACF,CAAC;AAEF,eAAe,MAAM,CAAC","sourcesContent":["import { useParams, Navigate } from 'react-router-dom';\nimport CohortsPage from '@src/cohorts/CohortsPage';\nimport CourseInfoPage from '@src/courseInfo/CourseInfoPage';\nimport CertificatesPage from '@src/certificates/CertificatesPage';\nimport CourseTeamPage from '@src/courseTeam/CourseTeamPage';\nimport DataDownloadsPage from '@src/dataDownloads/DataDownloadsPage';\nimport DateExtensionsPage from '@src/dateExtensions/DateExtensionsPage';\nimport EnrollmentsPage from '@src/enrollments/EnrollmentsPage';\nimport GradingPage from '@src/grading/GradingPage';\nimport OpenResponsesPage from '@src/openResponses/OpenResponsesPage';\nimport SpecialExamsPage from '@src/specialExams/SpecialExamsPage';\nimport PageNotFound from '@src/components/PageNotFound';\nimport { useWidgetProps } from './slots/SlotUtils';\nimport { instructorDashboardRole } from './constants';\n\ninterface InstructorRouteProps {\n tabId: string,\n content: React.ReactNode,\n}\n\nconst defaultTabs: InstructorRouteProps[] = [\n { tabId: 'course_info', content: <CourseInfoPage /> },\n { tabId: 'enrollments', content: <EnrollmentsPage /> },\n { tabId: 'course_team', content: <CourseTeamPage /> },\n { tabId: 'cohorts', content: <CohortsPage /> },\n { tabId: 'date_extensions', content: <DateExtensionsPage /> },\n { tabId: 'grading', content: <GradingPage /> },\n { tabId: 'data_downloads', content: <DataDownloadsPage /> },\n { tabId: 'special_exams', content: <SpecialExamsPage /> },\n { tabId: 'certificates', content: <CertificatesPage /> },\n { tabId: 'open_responses', content: <OpenResponsesPage /> },\n];\n\nconst TabContent = () => {\n const { tabId } = useParams<{ tabId: string }>();\n const routeWidgets = useWidgetProps('org.openedx.frontend.slot.instructorDashboard.routes.v1') as InstructorRouteProps[];\n\n const tabRoutes = [\n ...defaultTabs.filter(\n defaultTab => !routeWidgets.some(slotTab => slotTab.tabId === defaultTab.tabId)\n ),\n ...routeWidgets\n ];\n\n const foundTab = tabRoutes.find(tab => tab.tabId === tabId);\n\n return foundTab ? foundTab.content : <PageNotFound />;\n};\n\nconst routes = [\n {\n id: 'org.openedx.frontend.route.instructorDashboard.main',\n path: 'instructor-dashboard/:courseId',\n handle: {\n roles: [instructorDashboardRole]\n },\n async lazy() {\n const module = await import(/* webpackChunkName: \"instructor-dashboard-main\" */ './Main');\n return { Component: module.default };\n },\n children: [\n {\n index: true,\n element: <Navigate to=\"course_info\" replace />\n },\n {\n path: ':tabId',\n element: <TabContent />\n },\n ]\n }\n];\n\nexport default routes;\n"]}
@@ -0,0 +1,2 @@
1
+ declare const CourseInfoSlot: () => import("react/jsx-runtime").JSX.Element | null;
2
+ export default CourseInfoSlot;
@@ -0,0 +1,14 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useParams } from 'react-router-dom';
3
+ import { useCourseInfo } from '../../data/apiHook';
4
+ const CourseInfoSlot = () => {
5
+ const { courseId = '' } = useParams();
6
+ const { data } = useCourseInfo(courseId);
7
+ if (!data) {
8
+ return null;
9
+ }
10
+ const { org = '', courseNumber = '', displayName = '' } = data;
11
+ return (_jsxs("div", { style: { minWidth: 0, lineHeight: '1' }, children: [_jsxs("span", { className: "d-block small m-0", children: [org, " ", courseNumber] }), _jsx("span", { className: "d-block m-0 font-weight-bold course-title", children: displayName })] }));
12
+ };
13
+ export default CourseInfoSlot;
14
+ //# sourceMappingURL=CourseInfoSlot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CourseInfoSlot.js","sourceRoot":"","sources":["../../../src/slots/CourseInfoSlot/CourseInfoSlot.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,cAAc,GAAG,GAAG,EAAE;IAC1B,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,SAAS,EAAE,CAAC;IACtC,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAEzC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,GAAG,GAAG,EAAE,EAAE,YAAY,GAAG,EAAE,EAAE,WAAW,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;IAE/D,OAAO,CACL,eAAK,KAAK,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,aAC1C,gBAAM,SAAS,EAAC,mBAAmB,aAAE,GAAG,OAAG,YAAY,IAAQ,EAC/D,eAAM,SAAS,EAAC,2CAA2C,YAAE,WAAW,GAAQ,IAC5E,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC","sourcesContent":["import { useParams } from 'react-router-dom';\nimport { useCourseInfo } from '@src/data/apiHook';\n\nconst CourseInfoSlot = () => {\n const { courseId = '' } = useParams();\n const { data } = useCourseInfo(courseId);\n\n if (!data) {\n return null;\n }\n\n const { org = '', courseNumber = '', displayName = '' } = data;\n\n return (\n <div style={{ minWidth: 0, lineHeight: '1' }}>\n <span className=\"d-block small m-0\">{org} {courseNumber}</span>\n <span className=\"d-block m-0 font-weight-bold course-title\">{displayName}</span>\n </div>\n );\n};\n\nexport default CourseInfoSlot;\n"]}
package/dist/slots.js CHANGED
@@ -1,3 +1,15 @@
1
- const slots = [];
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { helpButtonSlotOperation, WidgetOperationTypes } from '@openedx/frontend-base';
3
+ import CourseInfoSlot from './slots/CourseInfoSlot/CourseInfoSlot';
4
+ import { appId, instructorDashboardRole } from './constants';
5
+ const slots = [
6
+ helpButtonSlotOperation({ appId, role: instructorDashboardRole }),
7
+ {
8
+ slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',
9
+ id: 'org.openedx.frontend.widget.slotShowcase.headerLink',
10
+ op: WidgetOperationTypes.APPEND,
11
+ element: _jsx(CourseInfoSlot, {}),
12
+ },
13
+ ];
2
14
  export default slots;
3
15
  //# sourceMappingURL=slots.js.map
package/dist/slots.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"slots.js","sourceRoot":"","sources":["../src/slots.tsx"],"names":[],"mappings":"AAEA,MAAM,KAAK,GAAoB,EAAE,CAAC;AAElC,eAAe,KAAK,CAAC","sourcesContent":["import { SlotOperation } from '@openedx/frontend-base';\n\nconst slots: SlotOperation[] = [];\n\nexport default slots;\n"]}
1
+ {"version":3,"file":"slots.js","sourceRoot":"","sources":["../src/slots.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,uBAAuB,EAAiB,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACtG,OAAO,cAAc,MAAM,0CAA0C,CAAC;AACtE,OAAO,EAAE,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEhE,MAAM,KAAK,GAAoB;IAC7B,uBAAuB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC;IACjE;QACE,MAAM,EAAE,kDAAkD;QAC1D,EAAE,EAAE,qDAAqD;QACzD,EAAE,EAAE,oBAAoB,CAAC,MAAM;QAC/B,OAAO,EAAE,KAAC,cAAc,KAAG;KAC5B;CACF,CAAC;AAEF,eAAe,KAAK,CAAC","sourcesContent":["import { helpButtonSlotOperation, SlotOperation, WidgetOperationTypes } from '@openedx/frontend-base';\nimport CourseInfoSlot from '@src/slots/CourseInfoSlot/CourseInfoSlot';\nimport { appId, instructorDashboardRole } from '@src/constants';\n\nconst slots: SlotOperation[] = [\n helpButtonSlotOperation({ appId, role: instructorDashboardRole }),\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',\n id: 'org.openedx.frontend.widget.slotShowcase.headerLink',\n op: WidgetOperationTypes.APPEND,\n element: <CourseInfoSlot />,\n },\n];\n\nexport default slots;\n"]}
@@ -1,6 +1,18 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { useIntl } from '@openedx/frontend-base';
4
+ import { Button, ButtonGroup, Card } from '@openedx/paragon';
5
+ import messages from './messages';
6
+ import Allowances from './components/Allowances';
7
+ import AttemptsList from './components/AttemptsList';
8
+ const SPECIAL_EXAMS_TAB = {
9
+ ATTEMPTS: 'attempts',
10
+ ALLOWANCES: 'allowances',
11
+ };
2
12
  const SpecialExamsPage = () => {
3
- return (_jsx("div", { children: _jsx("h3", { children: "Special Exams" }) }));
13
+ const intl = useIntl();
14
+ const [selectedTab, setSelectedTab] = useState(SPECIAL_EXAMS_TAB.ATTEMPTS);
15
+ return (_jsxs(_Fragment, { children: [_jsx("h3", { className: "text-primary-700", children: intl.formatMessage(messages.specialExamsTitle) }), _jsxs(Card, { className: "bg-light-200 mt-4.5", children: [_jsxs(ButtonGroup, { className: "d-block mx-4 mt-4", children: [_jsx(Button, { variant: selectedTab === SPECIAL_EXAMS_TAB.ATTEMPTS ? 'primary' : 'outline-primary', onClick: () => setSelectedTab(SPECIAL_EXAMS_TAB.ATTEMPTS), children: intl.formatMessage(messages.examAttempts) }), _jsx(Button, { variant: selectedTab === SPECIAL_EXAMS_TAB.ALLOWANCES ? 'primary' : 'outline-primary', onClick: () => setSelectedTab(SPECIAL_EXAMS_TAB.ALLOWANCES), children: intl.formatMessage(messages.allowances) })] }), selectedTab === SPECIAL_EXAMS_TAB.ATTEMPTS ? _jsx(AttemptsList, {}) : _jsx(Allowances, {})] })] }));
4
16
  };
5
17
  export default SpecialExamsPage;
6
18
  //# sourceMappingURL=SpecialExamsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SpecialExamsPage.js","sourceRoot":"","sources":["../../src/specialExams/SpecialExamsPage.tsx"],"names":[],"mappings":";AAAA,MAAM,gBAAgB,GAAG,GAAG,EAAE;IAC5B,OAAO,CACL,wBACE,yCAAsB,GAClB,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["const SpecialExamsPage = () => {\n return (\n <div>\n <h3>Special Exams</h3>\n </div>\n );\n};\n\nexport default SpecialExamsPage;\n"]}
1
+ {"version":3,"file":"SpecialExamsPage.js","sourceRoot":"","sources":["../../src/specialExams/SpecialExamsPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,UAAU,MAAM,yBAAyB,CAAC;AACjD,OAAO,YAAY,MAAM,2BAA2B,CAAC;AAErD,MAAM,iBAAiB,GAAG;IACxB,QAAQ,EAAE,UAAU;IACpB,UAAU,EAAE,YAAY;CACzB,CAAC;AAEF,MAAM,gBAAgB,GAAG,GAAG,EAAE;IAC5B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAA6D,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAEvI,OAAO,CACL,8BACE,aAAI,SAAS,EAAC,kBAAkB,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,GAAM,EACtF,MAAC,IAAI,IAAC,SAAS,EAAC,qBAAqB,aACnC,MAAC,WAAW,IAAC,SAAS,EAAC,mBAAmB,aACxC,KAAC,MAAM,IACL,OAAO,EAAE,WAAW,KAAK,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,EACnF,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,iBAAiB,CAAC,QAAQ,CAAC,YACzD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,GAClC,EACT,KAAC,MAAM,IACL,OAAO,EAAE,WAAW,KAAK,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,EACrF,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,iBAAiB,CAAC,UAAU,CAAC,YAC3D,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,GAChC,IACG,EAEZ,WAAW,KAAK,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAC,YAAY,KAAG,CAAC,CAAC,CAAC,KAAC,UAAU,KAAG,IAE3E,IACN,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import { useState } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, ButtonGroup, Card } from '@openedx/paragon';\nimport messages from './messages';\nimport Allowances from './components/Allowances';\nimport AttemptsList from './components/AttemptsList';\n\nconst SPECIAL_EXAMS_TAB = {\n ATTEMPTS: 'attempts',\n ALLOWANCES: 'allowances',\n};\n\nconst SpecialExamsPage = () => {\n const intl = useIntl();\n const [selectedTab, setSelectedTab] = useState<(typeof SPECIAL_EXAMS_TAB)[keyof typeof SPECIAL_EXAMS_TAB]>(SPECIAL_EXAMS_TAB.ATTEMPTS);\n\n return (\n <>\n <h3 className=\"text-primary-700\">{intl.formatMessage(messages.specialExamsTitle)}</h3>\n <Card className=\"bg-light-200 mt-4.5\">\n <ButtonGroup className=\"d-block mx-4 mt-4\">\n <Button\n variant={selectedTab === SPECIAL_EXAMS_TAB.ATTEMPTS ? 'primary' : 'outline-primary'}\n onClick={() => setSelectedTab(SPECIAL_EXAMS_TAB.ATTEMPTS)}\n >{intl.formatMessage(messages.examAttempts)}\n </Button>\n <Button\n variant={selectedTab === SPECIAL_EXAMS_TAB.ALLOWANCES ? 'primary' : 'outline-primary'}\n onClick={() => setSelectedTab(SPECIAL_EXAMS_TAB.ALLOWANCES)}\n >{intl.formatMessage(messages.allowances)}\n </Button>\n </ButtonGroup>\n {\n selectedTab === SPECIAL_EXAMS_TAB.ATTEMPTS ? <AttemptsList /> : <Allowances />\n }\n </Card>\n </>\n );\n};\n\nexport default SpecialExamsPage;\n"]}
@@ -0,0 +1,6 @@
1
+ interface AddAllowanceModalProps {
2
+ isOpen: boolean;
3
+ onClose: () => void;
4
+ }
5
+ declare const AddAllowanceModal: ({ isOpen, onClose }: AddAllowanceModalProps) => import("react/jsx-runtime").JSX.Element;
6
+ export default AddAllowanceModal;
@@ -0,0 +1,84 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import { useParams } from 'react-router-dom';
4
+ import { useIntl } from '@openedx/frontend-base';
5
+ import { ActionRow, Button, Form, ModalDialog } from '@openedx/paragon';
6
+ import { addLabel, addPlaceholder, allowanceTypesOptions } from '../../specialExams/constants';
7
+ import { useAddAllowance, useSpecialExams } from '../../specialExams/data/apiHook';
8
+ import messages from '../../specialExams/messages';
9
+ import { useAlert } from '../../providers/AlertProvider';
10
+ const examTypeOptions = [
11
+ { value: '', label: messages.selectExamType },
12
+ { value: 'proctored', label: messages.proctored },
13
+ { value: 'timed', label: messages.timed },
14
+ ];
15
+ const emptyAllowanceData = {
16
+ examType: '',
17
+ examIds: [],
18
+ allowanceType: '',
19
+ value: '',
20
+ users: ''
21
+ };
22
+ const AddAllowanceModal = ({ isOpen, onClose }) => {
23
+ const intl = useIntl();
24
+ const { courseId = '' } = useParams();
25
+ const [newAllowance, setNewAllowance] = useState(emptyAllowanceData);
26
+ const { data: specialExams, refetch } = useSpecialExams(courseId, newAllowance.examType);
27
+ const { mutate: addAllowance } = useAddAllowance(courseId);
28
+ const { showModal } = useAlert();
29
+ const enableSubmitButton = useMemo(() => (allowanceData) => {
30
+ const { examType, allowanceType, value, users, examIds } = allowanceData;
31
+ if (!examType || !allowanceType || !value || !users || examIds.length === 0) {
32
+ return false;
33
+ }
34
+ const userIds = users.split(',').map(user => user.trim()).filter(user => user);
35
+ return userIds.length > 0;
36
+ }, []);
37
+ useEffect(() => {
38
+ if (isOpen && newAllowance.examType) {
39
+ refetch();
40
+ }
41
+ }, [isOpen, newAllowance.examType, refetch]);
42
+ const handleClose = () => {
43
+ setNewAllowance(emptyAllowanceData);
44
+ onClose();
45
+ };
46
+ const handleAdd = (e) => {
47
+ e.preventDefault();
48
+ const userIds = newAllowance.users.split(',').map(user => user.trim()).filter(user => user);
49
+ const allowanceData = {
50
+ userIds,
51
+ examType: newAllowance.examType,
52
+ examIds: newAllowance.examIds,
53
+ allowanceType: newAllowance.allowanceType,
54
+ value: newAllowance.value,
55
+ };
56
+ addAllowance(allowanceData, {
57
+ onSuccess: () => {
58
+ handleClose();
59
+ },
60
+ onError: () => {
61
+ showModal({
62
+ message: intl.formatMessage(messages.addAllowanceError),
63
+ variant: 'danger',
64
+ });
65
+ }
66
+ });
67
+ };
68
+ const handleChanges = (e) => {
69
+ const { value, name } = e.target;
70
+ setNewAllowance(prev => (Object.assign(Object.assign({}, prev), { [name]: value })));
71
+ };
72
+ const handleToggleExam = (value) => {
73
+ setNewAllowance(prev => {
74
+ const examIds = prev.examIds.includes(value)
75
+ ? prev.examIds.filter(id => id !== value)
76
+ : [...prev.examIds, value];
77
+ return Object.assign(Object.assign({}, prev), { examIds });
78
+ });
79
+ };
80
+ return (_jsxs(ModalDialog, { isOpen: isOpen, onClose: handleClose, title: intl.formatMessage(messages.addAllowance), isOverflowVisible: false, size: "lg", children: [_jsx(ModalDialog.Header, { className: "border-bottom border-light-700", children: _jsx(ModalDialog.Title, { className: "text-primary-700", children: intl.formatMessage(messages.addAllowance) }) }), _jsxs(Form, { className: "position-relative overflow-auto", onSubmit: handleAdd, children: [_jsxs(ModalDialog.Body, { children: [_jsxs(Form.Group, { controlId: "specify-learners", children: [_jsxs(Form.Label, { className: "text-primary-500 x-small", children: [intl.formatMessage(messages.specifyLearners), ":"] }), _jsx(Form.Control, { as: "textarea", rows: 3, placeholder: intl.formatMessage(messages.specifyLearnersPlaceholder), name: "users", onChange: handleChanges })] }), _jsxs(Form.Group, { controlId: "select-exam-type", children: [_jsxs(Form.Label, { className: "text-primary-500 x-small", children: [intl.formatMessage(messages.selectExamType), ":"] }), _jsx(Form.Control, { as: "select", name: "examType", onChange: handleChanges, children: examTypeOptions.map(option => (_jsx("option", { value: option.value, children: intl.formatMessage(option.label) }, option.value))) })] }), _jsxs(Form.Group, { controlId: "select-exams", children: [_jsxs(Form.Label, { className: "text-primary-500 x-small", children: [intl.formatMessage(messages.selectExams), ":"] }), newAllowance.examType && (_jsx(Form.CheckboxSet, { onChange: (e) => handleToggleExam(Number(e.target.value)), name: "examIds", children: (specialExams || [])
81
+ .map((exam) => (_jsx(Form.Checkbox, { className: "mt-2", value: exam.id, children: exam.examName }, exam.id))) }))] }), _jsxs(Form.Group, { controlId: "select-allowance-type", children: [_jsxs(Form.Label, { className: "text-primary-500 x-small", children: [intl.formatMessage(messages.selectAllowanceType), ":"] }), _jsx(Form.Control, { as: "select", name: "allowanceType", onChange: handleChanges, children: allowanceTypesOptions.map(option => (_jsx("option", { value: option.value, children: intl.formatMessage(option.label) }, option.value))) })] }), _jsxs(Form.Group, { controlId: "allowance-value", children: [_jsxs(Form.Label, { className: "text-primary-500 x-small", children: [intl.formatMessage(addLabel[newAllowance.allowanceType || 'additional_time_granted']), ":"] }), _jsx(Form.Control, { type: newAllowance.allowanceType === 'review_policy_exception' ? 'text' : 'number', placeholder: intl.formatMessage(addPlaceholder[newAllowance.allowanceType || 'additional_time_granted']), name: "value", onChange: handleChanges })] })] }), _jsx(ModalDialog.Footer, { className: "border-top border-light-700", children: _jsxs(ActionRow, { children: [_jsx(Button, { variant: "tertiary", onClick: handleClose, children: intl.formatMessage(messages.cancel) }), _jsx(Button, { disabled: !enableSubmitButton(newAllowance), variant: "primary", type: "submit", children: intl.formatMessage(messages.createAllowance) })] }) })] })] }));
82
+ };
83
+ export default AddAllowanceModal;
84
+ //# sourceMappingURL=AddAllowanceModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddAllowanceModal.js","sourceRoot":"","sources":["../../../src/specialExams/components/AddAllowanceModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { ActionRow, Button, Form, ModalDialog } from '@openedx/paragon';\nimport { addLabel, addPlaceholder, allowanceTypesOptions } from '@src/specialExams/constants';\nimport { useAddAllowance, useSpecialExams } from '@src/specialExams/data/apiHook';\nimport messages from '@src/specialExams/messages';\nimport { AddAllowanceForm, AddAllowanceParams } from '@src/specialExams/types';\nimport { useAlert } from '@src/providers/AlertProvider';\n\ninterface AddAllowanceModalProps {\n isOpen: boolean,\n onClose: () => void,\n}\n\nconst examTypeOptions = [\n { value: '', label: messages.selectExamType },\n { value: 'proctored', label: messages.proctored },\n { value: 'timed', label: messages.timed },\n];\n\nconst emptyAllowanceData = {\n examType: '',\n examIds: [],\n allowanceType: '',\n value: '',\n users: ''\n};\n\nconst AddAllowanceModal = ({ isOpen, onClose }: AddAllowanceModalProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams();\n const [newAllowance, setNewAllowance] = useState<AddAllowanceForm>(emptyAllowanceData);\n const { data: specialExams, refetch } = useSpecialExams(courseId, newAllowance.examType);\n const { mutate: addAllowance } = useAddAllowance(courseId);\n const { showModal } = useAlert();\n\n const enableSubmitButton = useMemo(() => (allowanceData: AddAllowanceForm) => {\n const { examType, allowanceType, value, users, examIds } = allowanceData;\n if (!examType || !allowanceType || !value || !users || examIds.length === 0) {\n return false;\n }\n const userIds = users.split(',').map(user => user.trim()).filter(user => user);\n return userIds.length > 0;\n }, []);\n\n useEffect(() => {\n if (isOpen && newAllowance.examType) {\n refetch();\n }\n }, [isOpen, newAllowance.examType, refetch]);\n\n const handleClose = () => {\n setNewAllowance(emptyAllowanceData);\n onClose();\n };\n\n const handleAdd = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const userIds = newAllowance.users.split(',').map(user => user.trim()).filter(user => user);\n const allowanceData: AddAllowanceParams = {\n userIds,\n examType: newAllowance.examType,\n examIds: newAllowance.examIds,\n allowanceType: newAllowance.allowanceType,\n value: newAllowance.value,\n };\n\n addAllowance(allowanceData, {\n onSuccess: () => {\n handleClose();\n },\n onError: () => {\n showModal({\n message: intl.formatMessage(messages.addAllowanceError),\n variant: 'danger',\n });\n }\n });\n };\n\n const handleChanges = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const { value, name } = e.target;\n setNewAllowance(prev => ({\n ...prev,\n [name]: value,\n }));\n };\n\n const handleToggleExam = (value: number) => {\n setNewAllowance(prev => {\n const examIds = prev.examIds.includes(value)\n ? prev.examIds.filter(id => id !== value)\n : [...prev.examIds, value];\n return {\n ...prev,\n examIds,\n };\n });\n };\n\n return (\n <ModalDialog isOpen={isOpen} onClose={handleClose} title={intl.formatMessage(messages.addAllowance)} isOverflowVisible={false} size=\"lg\">\n <ModalDialog.Header className=\"border-bottom border-light-700\">\n <ModalDialog.Title className=\"text-primary-700\">{intl.formatMessage(messages.addAllowance)}</ModalDialog.Title>\n </ModalDialog.Header>\n <Form className=\"position-relative overflow-auto\" onSubmit={handleAdd}>\n <ModalDialog.Body>\n <Form.Group controlId=\"specify-learners\">\n <Form.Label className=\"text-primary-500 x-small\">{intl.formatMessage(messages.specifyLearners)}:</Form.Label>\n <Form.Control\n as=\"textarea\"\n rows={3}\n placeholder={intl.formatMessage(messages.specifyLearnersPlaceholder)}\n name=\"users\"\n onChange={handleChanges}\n />\n </Form.Group>\n <Form.Group controlId=\"select-exam-type\">\n <Form.Label className=\"text-primary-500 x-small\">{intl.formatMessage(messages.selectExamType)}:</Form.Label>\n <Form.Control as=\"select\" name=\"examType\" onChange={handleChanges}>\n {examTypeOptions.map(option => (\n <option key={option.value} value={option.value}>{intl.formatMessage(option.label)}</option>\n ))}\n </Form.Control>\n </Form.Group>\n <Form.Group controlId=\"select-exams\">\n <Form.Label className=\"text-primary-500 x-small\">{intl.formatMessage(messages.selectExams)}:</Form.Label>\n {newAllowance.examType && (\n <Form.CheckboxSet onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleToggleExam(Number(e.target.value))} name=\"examIds\">\n {\n (specialExams || [])\n .map((exam) => (\n <Form.Checkbox className=\"mt-2\" key={exam.id} value={exam.id}>\n {exam.examName}\n </Form.Checkbox>\n ))\n }\n </Form.CheckboxSet>\n )}\n </Form.Group>\n <Form.Group controlId=\"select-allowance-type\">\n <Form.Label className=\"text-primary-500 x-small\">{intl.formatMessage(messages.selectAllowanceType)}:</Form.Label>\n <Form.Control as=\"select\" name=\"allowanceType\" onChange={handleChanges}>\n {allowanceTypesOptions.map(option => (\n <option key={option.value} value={option.value}>{intl.formatMessage(option.label)}</option>\n ))}\n </Form.Control>\n </Form.Group>\n <Form.Group controlId=\"allowance-value\">\n <Form.Label className=\"text-primary-500 x-small\">{intl.formatMessage(addLabel[newAllowance.allowanceType || 'additional_time_granted'])}:</Form.Label>\n <Form.Control\n type={newAllowance.allowanceType === 'review_policy_exception' ? 'text' : 'number'}\n placeholder={intl.formatMessage(addPlaceholder[newAllowance.allowanceType || 'additional_time_granted'])}\n name=\"value\"\n onChange={handleChanges}\n />\n </Form.Group>\n </ModalDialog.Body>\n <ModalDialog.Footer className=\"border-top border-light-700\">\n <ActionRow>\n <Button variant=\"tertiary\" onClick={handleClose}>{intl.formatMessage(messages.cancel)}</Button>\n <Button disabled={!enableSubmitButton(newAllowance)} variant=\"primary\" type=\"submit\">{intl.formatMessage(messages.createAllowance)}</Button>\n </ActionRow>\n </ModalDialog.Footer>\n </Form>\n </ModalDialog>\n );\n};\n\nexport default AddAllowanceModal;\n"]}
@@ -0,0 +1,2 @@
1
+ declare const Allowances: () => import("react/jsx-runtime").JSX.Element;
2
+ export default Allowances;
@@ -0,0 +1,89 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
11
+ import { useState, useEffect } from 'react';
12
+ import { useParams } from 'react-router-dom';
13
+ import { useIntl } from '@openedx/frontend-base';
14
+ import { useToggle } from '@openedx/paragon';
15
+ import AddAllowanceModal from '../../specialExams/components/AddAllowanceModal';
16
+ import AllowancesList from '../../specialExams/components/AllowancesList';
17
+ import EditAllowanceModal from '../../specialExams/components/EditAllowanceModal';
18
+ import DeleteAllowanceModal from '../../specialExams/components/DeleteAllowanceModal';
19
+ import { useAttempts } from '../../specialExams/data/apiHook';
20
+ import messages from '../../specialExams/messages';
21
+ import { useAlert } from '../../providers/AlertProvider';
22
+ const Allowances = () => {
23
+ var _a;
24
+ const intl = useIntl();
25
+ const { courseId = '' } = useParams();
26
+ const { showModal } = useAlert();
27
+ const [isAddModalOpen, openAddModal, closeAddModal] = useToggle(false);
28
+ const [isEditModalOpen, openEditModal, closeEditModal] = useToggle(false);
29
+ const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useToggle(false);
30
+ const [selectedAllowance, setSelectedAllowance] = useState(null);
31
+ const [pendingAction, setPendingAction] = useState(null);
32
+ const { refetch } = useAttempts(courseId, {
33
+ page: 0,
34
+ pageSize: 100,
35
+ emailOrUsername: (_a = selectedAllowance === null || selectedAllowance === void 0 ? void 0 : selectedAllowance.user.username) !== null && _a !== void 0 ? _a : '',
36
+ ordering: '',
37
+ }, false); // disabled by default — only runs on refetch
38
+ // Handle the attempt check after selectedAllowance and pendingAction are set
39
+ useEffect(() => {
40
+ if (!selectedAllowance || !pendingAction) {
41
+ return;
42
+ }
43
+ const checkAttempt = () => __awaiter(void 0, void 0, void 0, function* () {
44
+ const { data } = yield refetch();
45
+ const hasAttempt = data === null || data === void 0 ? void 0 : data.results.some((attempt) => attempt.examId === selectedAllowance.proctoredExam.id);
46
+ if (hasAttempt) {
47
+ showModal({
48
+ message: intl.formatMessage(messages.cannotModifyAllowance, {
49
+ action: pendingAction,
50
+ username: selectedAllowance.user.username,
51
+ }),
52
+ variant: 'warning',
53
+ });
54
+ setSelectedAllowance(null);
55
+ setPendingAction(null);
56
+ }
57
+ else if (pendingAction === 'edit') {
58
+ openEditModal();
59
+ setPendingAction(null);
60
+ }
61
+ else {
62
+ openDeleteModal();
63
+ setPendingAction(null);
64
+ }
65
+ });
66
+ checkAttempt();
67
+ }, [selectedAllowance, pendingAction, refetch, showModal, intl, openEditModal, openDeleteModal]);
68
+ const handleEditAllowance = (allowance) => {
69
+ setSelectedAllowance(allowance);
70
+ setPendingAction('edit');
71
+ };
72
+ const handleDeleteAllowance = (allowance) => {
73
+ setSelectedAllowance(allowance);
74
+ setPendingAction('delete');
75
+ };
76
+ const handleCloseEditModal = () => {
77
+ setSelectedAllowance(null);
78
+ setPendingAction(null);
79
+ closeEditModal();
80
+ };
81
+ const handleCloseDeleteModal = () => {
82
+ setSelectedAllowance(null);
83
+ setPendingAction(null);
84
+ closeDeleteModal();
85
+ };
86
+ return (_jsxs(_Fragment, { children: [_jsx(AllowancesList, { onClickAdd: openAddModal, onEdit: handleEditAllowance, onDelete: handleDeleteAllowance }), _jsx(AddAllowanceModal, { isOpen: isAddModalOpen, onClose: closeAddModal }), selectedAllowance && _jsx(EditAllowanceModal, { isOpen: isEditModalOpen, onClose: handleCloseEditModal, allowance: selectedAllowance }), selectedAllowance && _jsx(DeleteAllowanceModal, { isOpen: isDeleteModalOpen, onClose: handleCloseDeleteModal, allowance: selectedAllowance })] }));
87
+ };
88
+ export default Allowances;
89
+ //# sourceMappingURL=Allowances.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Allowances.js","sourceRoot":"","sources":["../../../src/specialExams/components/Allowances.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState, useEffect } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { useToggle } from '@openedx/paragon';\nimport AddAllowanceModal from '@src/specialExams/components/AddAllowanceModal';\nimport AllowancesList from '@src/specialExams/components/AllowancesList';\nimport EditAllowanceModal from '@src/specialExams/components/EditAllowanceModal';\nimport DeleteAllowanceModal from '@src/specialExams/components/DeleteAllowanceModal';\nimport { useAttempts } from '@src/specialExams/data/apiHook';\nimport messages from '@src/specialExams/messages';\nimport { Allowance } from '@src/specialExams/types';\nimport { useAlert } from '@src/providers/AlertProvider';\n\nconst Allowances = () => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const { showModal } = useAlert();\n const [isAddModalOpen, openAddModal, closeAddModal] = useToggle(false);\n const [isEditModalOpen, openEditModal, closeEditModal] = useToggle(false);\n const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useToggle(false);\n const [selectedAllowance, setSelectedAllowance] = useState<Allowance | null>(null);\n const [pendingAction, setPendingAction] = useState<'edit' | 'delete' | null>(null);\n\n const { refetch } = useAttempts(courseId, {\n page: 0,\n pageSize: 100,\n emailOrUsername: selectedAllowance?.user.username ?? '',\n ordering: '',\n }, false); // disabled by default — only runs on refetch\n\n // Handle the attempt check after selectedAllowance and pendingAction are set\n useEffect(() => {\n if (!selectedAllowance || !pendingAction) {\n return;\n }\n\n const checkAttempt = async () => {\n const { data } = await refetch();\n const hasAttempt = data?.results.some(\n (attempt) => attempt.examId === selectedAllowance.proctoredExam.id\n );\n\n if (hasAttempt) {\n showModal({\n message: intl.formatMessage(messages.cannotModifyAllowance, {\n action: pendingAction,\n username: selectedAllowance.user.username,\n }),\n variant: 'warning',\n });\n setSelectedAllowance(null);\n setPendingAction(null);\n } else if (pendingAction === 'edit') {\n openEditModal();\n setPendingAction(null);\n } else {\n openDeleteModal();\n setPendingAction(null);\n }\n };\n\n checkAttempt();\n }, [selectedAllowance, pendingAction, refetch, showModal, intl, openEditModal, openDeleteModal]);\n\n const handleEditAllowance = (allowance: Allowance) => {\n setSelectedAllowance(allowance);\n setPendingAction('edit');\n };\n\n const handleDeleteAllowance = (allowance: Allowance) => {\n setSelectedAllowance(allowance);\n setPendingAction('delete');\n };\n\n const handleCloseEditModal = () => {\n setSelectedAllowance(null);\n setPendingAction(null);\n closeEditModal();\n };\n\n const handleCloseDeleteModal = () => {\n setSelectedAllowance(null);\n setPendingAction(null);\n closeDeleteModal();\n };\n\n return (\n <>\n <AllowancesList onClickAdd={openAddModal} onEdit={handleEditAllowance} onDelete={handleDeleteAllowance} />\n <AddAllowanceModal isOpen={isAddModalOpen} onClose={closeAddModal} />\n {selectedAllowance && <EditAllowanceModal isOpen={isEditModalOpen} onClose={handleCloseEditModal} allowance={selectedAllowance} />}\n {selectedAllowance && <DeleteAllowanceModal isOpen={isDeleteModalOpen} onClose={handleCloseDeleteModal} allowance={selectedAllowance} />}\n </>\n );\n};\n\nexport default Allowances;\n"]}
@@ -0,0 +1,8 @@
1
+ import { Allowance } from '../../specialExams/types';
2
+ interface AllowanceList {
3
+ onClickAdd: () => void;
4
+ onEdit: (allowance: Allowance) => void;
5
+ onDelete: (allowance: Allowance) => void;
6
+ }
7
+ declare const AllowancesList: ({ onClickAdd, onEdit, onDelete }: AllowanceList) => import("react/jsx-runtime").JSX.Element;
8
+ export default AllowancesList;