@openedx/frontend-app-instructor-dashboard 1.0.0-alpha.3 → 1.0.0-alpha.31

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 (270) 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 +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 +214 -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 +32 -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 +25 -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 +27 -0
  39. package/dist/certificates/components/LearnerActionModal.js.map +1 -0
  40. package/dist/certificates/components/RemoveExceptionModal.d.ts +9 -0
  41. package/dist/certificates/components/RemoveExceptionModal.js +10 -0
  42. package/dist/certificates/components/RemoveExceptionModal.js.map +1 -0
  43. package/dist/certificates/components/RemoveInvalidationModal.d.ts +9 -0
  44. package/dist/certificates/components/RemoveInvalidationModal.js +10 -0
  45. package/dist/certificates/components/RemoveInvalidationModal.js.map +1 -0
  46. package/dist/certificates/constants.d.ts +15 -0
  47. package/dist/certificates/constants.js +16 -0
  48. package/dist/certificates/constants.js.map +1 -0
  49. package/dist/certificates/data/api.d.ts +23 -0
  50. package/dist/certificates/data/api.js +115 -0
  51. package/dist/certificates/data/api.js.map +1 -0
  52. package/dist/certificates/data/apiHook.d.ts +50 -0
  53. package/dist/certificates/data/apiHook.js +118 -0
  54. package/dist/certificates/data/apiHook.js.map +1 -0
  55. package/dist/certificates/data/queryKeys.d.ts +9 -0
  56. package/dist/certificates/data/queryKeys.js +9 -0
  57. package/dist/certificates/data/queryKeys.js.map +1 -0
  58. package/dist/certificates/messages.d.ts +343 -0
  59. package/dist/certificates/messages.js +345 -0
  60. package/dist/certificates/messages.js.map +1 -0
  61. package/dist/certificates/types.d.ts +66 -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/components/ActionCard.d.ts +2 -2
  74. package/dist/components/ActionCard.js +1 -1
  75. package/dist/components/ActionCard.js.map +1 -1
  76. package/dist/components/CodeEditor.d.ts +5 -0
  77. package/dist/components/CodeEditor.js +34 -0
  78. package/dist/components/CodeEditor.js.map +1 -0
  79. package/dist/components/PendingTasks.d.ts +3 -1
  80. package/dist/components/PendingTasks.js +3 -2
  81. package/dist/components/PendingTasks.js.map +1 -1
  82. package/dist/components/SpecifyLearnerField.d.ts +4 -1
  83. package/dist/components/SpecifyLearnerField.js +33 -13
  84. package/dist/components/SpecifyLearnerField.js.map +1 -1
  85. package/dist/components/SpecifyProblemField.d.ts +13 -0
  86. package/dist/components/SpecifyProblemField.js +52 -0
  87. package/dist/components/SpecifyProblemField.js.map +1 -0
  88. package/dist/components/UsernameFilter.d.ts +7 -0
  89. package/dist/components/UsernameFilter.js +19 -0
  90. package/dist/components/UsernameFilter.js.map +1 -0
  91. package/dist/components/messages.d.ts +40 -0
  92. package/dist/components/messages.js +40 -0
  93. package/dist/components/messages.js.map +1 -1
  94. package/dist/courseInfo/types.d.ts +5 -0
  95. package/dist/courseInfo/types.js.map +1 -1
  96. package/dist/courseTeam/CourseTeamPage.js +25 -2
  97. package/dist/courseTeam/CourseTeamPage.js.map +1 -1
  98. package/dist/courseTeam/components/AddTeamMemberModal.d.ts +6 -0
  99. package/dist/courseTeam/components/AddTeamMemberModal.js +61 -0
  100. package/dist/courseTeam/components/AddTeamMemberModal.js.map +1 -0
  101. package/dist/courseTeam/components/EditTeamMemberModal.d.ts +8 -0
  102. package/dist/courseTeam/components/EditTeamMemberModal.js +102 -0
  103. package/dist/courseTeam/components/EditTeamMemberModal.js.map +1 -0
  104. package/dist/courseTeam/components/MembersContent.d.ts +6 -0
  105. package/dist/courseTeam/components/MembersContent.js +48 -0
  106. package/dist/courseTeam/components/MembersContent.js.map +1 -0
  107. package/dist/courseTeam/components/RoleFilter.d.ts +7 -0
  108. package/dist/courseTeam/components/RoleFilter.js +22 -0
  109. package/dist/courseTeam/components/RoleFilter.js.map +1 -0
  110. package/dist/courseTeam/components/RolesContent.d.ts +3 -0
  111. package/dist/courseTeam/components/RolesContent.js +25 -0
  112. package/dist/courseTeam/components/RolesContent.js.map +1 -0
  113. package/dist/courseTeam/constants.d.ts +3 -0
  114. package/dist/courseTeam/constants.js +4 -0
  115. package/dist/courseTeam/constants.js.map +1 -0
  116. package/dist/courseTeam/data/api.d.ts +6 -0
  117. package/dist/courseTeam/data/api.js +38 -0
  118. package/dist/courseTeam/data/api.js.map +1 -0
  119. package/dist/courseTeam/data/apiHook.d.ts +8 -0
  120. package/dist/courseTeam/data/apiHook.js +32 -0
  121. package/dist/courseTeam/data/apiHook.js.map +1 -0
  122. package/dist/courseTeam/data/queryKeys.d.ts +7 -0
  123. package/dist/courseTeam/data/queryKeys.js +14 -0
  124. package/dist/courseTeam/data/queryKeys.js.map +1 -0
  125. package/dist/courseTeam/messages.d.ts +258 -0
  126. package/dist/courseTeam/messages.js +260 -0
  127. package/dist/courseTeam/messages.js.map +1 -0
  128. package/dist/courseTeam/types.d.ts +29 -0
  129. package/dist/courseTeam/types.js +3 -0
  130. package/dist/courseTeam/types.js.map +1 -0
  131. package/dist/data/api.d.ts +2 -1
  132. package/dist/data/api.js +9 -3
  133. package/dist/data/api.js.map +1 -1
  134. package/dist/data/apiHook.d.ts +1 -0
  135. package/dist/data/apiHook.js +10 -2
  136. package/dist/data/apiHook.js.map +1 -1
  137. package/dist/data/queryKeys.d.ts +4 -0
  138. package/dist/data/queryKeys.js +4 -0
  139. package/dist/data/queryKeys.js.map +1 -1
  140. package/dist/dateExtensions/components/AddExtensionModal.d.ts +1 -1
  141. package/dist/dateExtensions/components/AddExtensionModal.js +6 -7
  142. package/dist/dateExtensions/components/AddExtensionModal.js.map +1 -1
  143. package/dist/dateExtensions/components/DateExtensionsList.js +3 -14
  144. package/dist/dateExtensions/components/DateExtensionsList.js.map +1 -1
  145. package/dist/dateExtensions/data/apiHook.d.ts +2 -2
  146. package/dist/dateExtensions/data/apiHook.js +4 -4
  147. package/dist/dateExtensions/data/apiHook.js.map +1 -1
  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 +69 -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 +1 -1
  177. package/dist/enrollments/data/queryKeys.js.map +1 -1
  178. package/dist/enrollments/messages.d.ts +131 -1
  179. package/dist/enrollments/messages.js +136 -6
  180. package/dist/enrollments/messages.js.map +1 -1
  181. package/dist/enrollments/types.d.ts +25 -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 +15 -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/instructorNav/InstructorNav.js +6 -1
  213. package/dist/instructorNav/InstructorNav.js.map +1 -1
  214. package/dist/routes.d.ts +1 -1
  215. package/dist/routes.js +2 -2
  216. package/dist/routes.js.map +1 -1
  217. package/dist/specialExams/SpecialExamsPage.js +14 -2
  218. package/dist/specialExams/SpecialExamsPage.js.map +1 -1
  219. package/dist/specialExams/components/AddAllowanceModal.d.ts +6 -0
  220. package/dist/specialExams/components/AddAllowanceModal.js +84 -0
  221. package/dist/specialExams/components/AddAllowanceModal.js.map +1 -0
  222. package/dist/specialExams/components/Allowances.d.ts +2 -0
  223. package/dist/specialExams/components/Allowances.js +32 -0
  224. package/dist/specialExams/components/Allowances.js.map +1 -0
  225. package/dist/specialExams/components/AllowancesList.d.ts +8 -0
  226. package/dist/specialExams/components/AllowancesList.js +58 -0
  227. package/dist/specialExams/components/AllowancesList.js.map +1 -0
  228. package/dist/specialExams/components/AttemptsList.d.ts +3 -0
  229. package/dist/specialExams/components/AttemptsList.js +45 -0
  230. package/dist/specialExams/components/AttemptsList.js.map +1 -0
  231. package/dist/specialExams/components/DeleteAllowanceModal.d.ts +8 -0
  232. package/dist/specialExams/components/DeleteAllowanceModal.js +29 -0
  233. package/dist/specialExams/components/DeleteAllowanceModal.js.map +1 -0
  234. package/dist/specialExams/components/EditAllowanceModal.d.ts +8 -0
  235. package/dist/specialExams/components/EditAllowanceModal.js +62 -0
  236. package/dist/specialExams/components/EditAllowanceModal.js.map +1 -0
  237. package/dist/specialExams/constants.d.ts +43 -0
  238. package/dist/specialExams/constants.js +19 -0
  239. package/dist/specialExams/constants.js.map +1 -0
  240. package/dist/specialExams/data/api.d.ts +7 -0
  241. package/dist/specialExams/data/api.js +49 -0
  242. package/dist/specialExams/data/api.js.map +1 -0
  243. package/dist/specialExams/data/apiHook.d.ts +6 -0
  244. package/dist/specialExams/data/apiHook.js +37 -0
  245. package/dist/specialExams/data/apiHook.js.map +1 -0
  246. package/dist/specialExams/data/queryKeys.d.ts +8 -0
  247. package/dist/specialExams/data/queryKeys.js +9 -0
  248. package/dist/specialExams/data/queryKeys.js.map +1 -0
  249. package/dist/specialExams/messages.d.ts +223 -0
  250. package/dist/specialExams/messages.js +225 -0
  251. package/dist/specialExams/messages.js.map +1 -0
  252. package/dist/specialExams/types.d.ts +64 -0
  253. package/dist/specialExams/types.js +2 -0
  254. package/dist/specialExams/types.js.map +1 -0
  255. package/dist/style.scss +16 -0
  256. package/dist/testUtils.js +2 -2
  257. package/dist/testUtils.js.map +1 -1
  258. package/dist/types/index.d.ts +1 -0
  259. package/dist/types/index.js.map +1 -1
  260. package/dist/utils/formatters.d.ts +5 -0
  261. package/dist/utils/formatters.js +10 -0
  262. package/dist/utils/formatters.js.map +1 -1
  263. package/package.json +4 -5
  264. package/dist/app.scss +0 -10
  265. package/dist/providers/QueryProvider.d.ts +0 -6
  266. package/dist/providers/QueryProvider.js +0 -16
  267. package/dist/providers/QueryProvider.js.map +0 -1
  268. package/dist/providers.d.ts +0 -3
  269. package/dist/providers.js +0 -8
  270. package/dist/providers.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/certificates/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n pageTitle: {\n id: 'instruct.certificates.pageTitle',\n defaultMessage: 'Certificates',\n description: 'Title for certificates page',\n },\n grantExceptionsButton: {\n id: 'instruct.certificates.grantExceptionsButton',\n defaultMessage: 'Grant Exception(s)',\n description: 'Button to grant certificate exceptions',\n },\n invalidateCertificateButton: {\n id: 'instruct.certificates.invalidateCertificateButton',\n defaultMessage: 'Invalidate Certificate',\n description: 'Button to invalidate certificates',\n },\n disableCertificatesButton: {\n id: 'instruct.certificates.disableCertificatesButton',\n defaultMessage: 'Disable Certificates',\n description: 'Button to disable certificate generation',\n },\n regenerateCertificatesButton: {\n id: 'instruct.certificates.regenerateCertificatesButton',\n defaultMessage: 'Regenerate Certificates',\n description: 'Button to regenerate certificates',\n },\n issuedCertificatesTab: {\n id: 'instruct.certificates.issuedCertificatesTab',\n defaultMessage: 'Issued Certificates',\n description: 'Tab label for issued certificates',\n },\n generationHistoryTab: {\n id: 'instruct.certificates.generationHistoryTab',\n defaultMessage: 'Certificate Generation History',\n description: 'Tab label for certificate generation history',\n },\n searchPlaceholder: {\n id: 'instruct.certificates.searchPlaceholder',\n defaultMessage: 'Search by username or email',\n description: 'Placeholder text for search input',\n },\n filterAllLearners: {\n id: 'instruct.certificates.filterAllLearners',\n defaultMessage: 'All Learners',\n description: 'Filter option for all learners',\n },\n filterReceived: {\n id: 'instruct.certificates.filterReceived',\n defaultMessage: 'Received',\n description: 'Filter option for learners who received certificates',\n },\n filterNotReceived: {\n id: 'instruct.certificates.filterNotReceived',\n defaultMessage: 'Not Received',\n description: 'Filter option for learners who did not receive certificates',\n },\n filterAuditPassing: {\n id: 'instruct.certificates.filterAuditPassing',\n defaultMessage: 'Audit - Passing',\n description: 'Filter option for audit learners who are passing',\n },\n filterAuditNotPassing: {\n id: 'instruct.certificates.filterAuditNotPassing',\n defaultMessage: 'Audit - Not Passing',\n description: 'Filter option for audit learners who are not passing',\n },\n filterErrorState: {\n id: 'instruct.certificates.filterErrorState',\n defaultMessage: 'Error State',\n description: 'Filter option for error states',\n },\n filterGrantedExceptions: {\n id: 'instruct.certificates.filterGrantedExceptions',\n defaultMessage: 'Granted Exceptions',\n description: 'Filter option for granted exceptions',\n },\n filterInvalidated: {\n id: 'instruct.certificates.filterInvalidated',\n defaultMessage: 'Invalidated',\n description: 'Filter option for invalidated certificates',\n },\n columnUsername: {\n id: 'instruct.certificates.columnUsername',\n defaultMessage: 'Username',\n description: 'Table column header for username',\n },\n columnEmail: {\n id: 'instruct.certificates.columnEmail',\n defaultMessage: 'Email',\n description: 'Table column header for email',\n },\n columnEnrollmentTrack: {\n id: 'instruct.certificates.columnEnrollmentTrack',\n defaultMessage: 'Enrollment Track',\n description: 'Table column header for enrollment track',\n },\n columnCertificateStatus: {\n id: 'instruct.certificates.columnCertificateStatus',\n defaultMessage: 'Certificate Status',\n description: 'Table column header for certificate status',\n },\n columnSpecialCase: {\n id: 'instruct.certificates.columnSpecialCase',\n defaultMessage: 'Special Case',\n description: 'Table column header for special case',\n },\n columnExceptionGranted: {\n id: 'instruct.certificates.columnExceptionGranted',\n defaultMessage: 'Exception Granted',\n description: 'Table column header for exception granted',\n },\n columnExceptionNotes: {\n id: 'instruct.certificates.columnExceptionNotes',\n defaultMessage: 'Exception Notes',\n description: 'Table column header for exception notes',\n },\n columnInvalidatedBy: {\n id: 'instruct.certificates.columnInvalidatedBy',\n defaultMessage: 'Invalidated By',\n description: 'Table column header for invalidated by',\n },\n columnInvalidationDate: {\n id: 'instruct.certificates.columnInvalidationDate',\n defaultMessage: 'Invalidation Date',\n description: 'Table column header for invalidation date',\n },\n columnInvalidationNote: {\n id: 'instruct.certificates.columnInvalidationNote',\n defaultMessage: 'Invalidation Note',\n description: 'Table column header for invalidation note',\n },\n columnActions: {\n id: 'instruct.certificates.columnActions',\n defaultMessage: 'Actions',\n description: 'Table column header for actions',\n },\n removeExceptionAction: {\n id: 'instruct.certificates.removeExceptionAction',\n defaultMessage: 'Remove Exception',\n description: 'Action menu item to remove exception',\n },\n removeInvalidationAction: {\n id: 'instruct.certificates.removeInvalidationAction',\n defaultMessage: 'Remove Invalidation',\n description: 'Action menu item to remove invalidation',\n },\n noDataMessage: {\n id: 'instruct.certificates.noDataMessage',\n defaultMessage: 'No certificates found',\n description: 'Message when no certificates are found',\n },\n exceptionRemovedToast: {\n id: 'instruct.certificates.exceptionRemovedToast',\n defaultMessage: 'Exception removed for {email}',\n description: 'Toast message when exception is removed',\n },\n invalidationRemovedToast: {\n id: 'instruct.certificates.invalidationRemovedToast',\n defaultMessage: 'The certificate for {email} has been re-validated and the system is re-running the grade for this learner.',\n description: 'Toast message when invalidation is removed',\n },\n exceptionsGrantedToast: {\n id: 'instruct.certificates.exceptionsGrantedToast',\n defaultMessage: 'Exceptions granted for {count} learner(s)',\n description: 'Toast message when exceptions are granted',\n },\n certificatesInvalidatedToast: {\n id: 'instruct.certificates.certificatesInvalidatedToast',\n defaultMessage: 'Certificates invalidated for {count} learner(s)',\n description: 'Toast message when certificates are invalidated',\n },\n grantExceptionsModalTitle: {\n id: 'instruct.certificates.grantExceptionsModalTitle',\n defaultMessage: 'Grant Certificate Exceptions',\n description: 'Title for grant exceptions modal',\n },\n grantExceptionsModalDescription: {\n id: 'instruct.certificates.grantExceptionsModalDescription',\n defaultMessage: 'Enter usernames or emails, or upload a CSV file to grant certificate exceptions.',\n description: 'Description for grant exceptions modal',\n },\n invalidateCertificateModalTitle: {\n id: 'instruct.certificates.invalidateCertificateModalTitle',\n defaultMessage: 'Invalidate Certificates',\n description: 'Title for invalidate certificate modal',\n },\n invalidateCertificateModalDescription: {\n id: 'instruct.certificates.invalidateCertificateModalDescription',\n defaultMessage: 'Enter usernames or emails, or upload a CSV file to invalidate certificates.',\n description: 'Description for invalidate certificate modal',\n },\n removeExceptionModalTitle: {\n id: 'instruct.certificates.removeExceptionModalTitle',\n defaultMessage: 'Remove Exception',\n description: 'Title for remove exception modal',\n },\n removeExceptionModalMessage: {\n id: 'instruct.certificates.removeExceptionModalMessage',\n defaultMessage: 'Are you sure you want to remove the certificate exception for {email}?',\n description: 'Message for remove exception confirmation modal',\n },\n removeInvalidationModalTitle: {\n id: 'instruct.certificates.removeInvalidationModalTitle',\n defaultMessage: 'Remove Invalidation',\n description: 'Title for remove invalidation modal',\n },\n removeInvalidationModalMessage: {\n id: 'instruct.certificates.removeInvalidationModalMessage',\n defaultMessage: 'Are you sure you want to remove invalidation for {email}?',\n description: 'Message for remove invalidation confirmation modal',\n },\n disableCertificatesModalTitle: {\n id: 'instruct.certificates.disableCertificatesModalTitle',\n defaultMessage: 'Disable Certificate Generation',\n description: 'Title for disable certificates modal',\n },\n disableCertificatesModalMessage: {\n id: 'instruct.certificates.disableCertificatesModalMessage',\n defaultMessage: 'Students will not be able to receive certificates until certificate generation is re-enabled. Are you sure you want to disable certificate generation?',\n description: 'Message for disable certificates modal',\n },\n enableCertificatesModalTitle: {\n id: 'instruct.certificates.enableCertificatesModalTitle',\n defaultMessage: 'Enable Certificate Generation',\n description: 'Title for enable certificates modal',\n },\n enableCertificatesModalMessage: {\n id: 'instruct.certificates.enableCertificatesModalMessage',\n defaultMessage: 'Are you sure you want to enable certificate generation for this course?',\n description: 'Message for enable certificates modal',\n },\n notesLabel: {\n id: 'instruct.certificates.notesLabel',\n defaultMessage: 'Notes (Optional)',\n description: 'Label for notes field',\n },\n notesPlaceholder: {\n id: 'instruct.certificates.notesPlaceholder',\n defaultMessage: 'Enter notes...',\n description: 'Placeholder for notes field',\n },\n learnersLabel: {\n id: 'instruct.certificates.learnersLabel',\n defaultMessage: 'Username or Email',\n description: 'Label for learners field',\n },\n learnersPlaceholder: {\n id: 'instruct.certificates.learnersPlaceholder',\n defaultMessage: 'Enter usernames or emails (one per line)',\n description: 'Placeholder for learners field',\n },\n cancel: {\n id: 'instruct.certificates.cancel',\n defaultMessage: 'Cancel',\n description: 'Cancel button text',\n },\n confirm: {\n id: 'instruct.certificates.confirm',\n defaultMessage: 'Confirm',\n description: 'Confirm button text',\n },\n submit: {\n id: 'instruct.certificates.submit',\n defaultMessage: 'Submit',\n description: 'Submit button text',\n },\n columnTaskName: {\n id: 'instruct.certificates.columnTaskName',\n defaultMessage: 'Task Name',\n description: 'Table column header for task name',\n },\n columnDate: {\n id: 'instruct.certificates.columnDate',\n defaultMessage: 'Date',\n description: 'Table column header for date',\n },\n columnDetails: {\n id: 'instruct.certificates.columnDetails',\n defaultMessage: 'Details',\n description: 'Table column header for details',\n },\n noTasksMessage: {\n id: 'instruct.certificates.noTasksMessage',\n defaultMessage: 'No certificate generation tasks found',\n description: 'Message when no tasks are found',\n },\n errorGrantException: {\n id: 'instruct.certificates.errorGrantException',\n defaultMessage: 'Failed to grant exceptions',\n description: 'Error message when granting exceptions fails',\n },\n errorInvalidateCertificate: {\n id: 'instruct.certificates.errorInvalidateCertificate',\n defaultMessage: 'Failed to invalidate certificates',\n description: 'Error message when invalidating certificates fails',\n },\n errorRemoveException: {\n id: 'instruct.certificates.errorRemoveException',\n defaultMessage: 'Failed to remove exception',\n description: 'Error message when removing exception fails',\n },\n errorRemoveInvalidation: {\n id: 'instruct.certificates.errorRemoveInvalidation',\n defaultMessage: 'Failed to remove invalidation',\n description: 'Error message when removing invalidation fails',\n },\n errorToggleCertificateGeneration: {\n id: 'instruct.certificates.errorToggleCertificateGeneration',\n defaultMessage: 'Failed to toggle certificate generation',\n description: 'Error message when toggling certificate generation fails',\n },\n successEnableCertificates: {\n id: 'instruct.certificates.successEnableCertificates',\n defaultMessage: 'Certificate generation enabled',\n description: 'Success message when certificate generation is enabled',\n },\n successDisableCertificates: {\n id: 'instruct.certificates.successDisableCertificates',\n defaultMessage: 'Certificate generation disabled',\n description: 'Success message when certificate generation is disabled',\n },\n certificatesDisabledMessage: {\n id: 'instruct.certificates.certificatesDisabledMessage',\n defaultMessage: 'Certificate management features are not enabled for this course. Please contact your system administrator to enable certificate generation.',\n description: 'Message displayed when certificate features are disabled',\n },\n certificatesRegeneratedToast: {\n id: 'instruct.certificates.certificatesRegeneratedToast',\n defaultMessage: 'Certificate regeneration started successfully',\n description: 'Success message when certificates are regenerated',\n },\n errorRegenerateCertificates: {\n id: 'instruct.certificates.errorRegenerateCertificates',\n defaultMessage: 'Failed to regenerate certificates',\n description: 'Error message when certificate regeneration fails',\n },\n regenerateCertificatesButtonWithFilter: {\n id: 'instruct.certificates.regenerateCertificatesButtonWithFilter',\n defaultMessage: 'Regenerate Certificates: {filter}',\n description: 'Button to regenerate certificates with filter applied',\n },\n});\n\nexport default messages;\n"]}
@@ -0,0 +1,66 @@
1
+ import type { PaginationParams } from '../types';
2
+ export declare enum CertificateFilter {
3
+ ALL_LEARNERS = "all",
4
+ RECEIVED = "received",
5
+ NOT_RECEIVED = "not_received",
6
+ AUDIT_PASSING = "audit_passing",
7
+ AUDIT_NOT_PASSING = "audit_not_passing",
8
+ ERROR_STATE = "error",
9
+ GRANTED_EXCEPTIONS = "granted_exceptions",
10
+ INVALIDATED = "invalidated"
11
+ }
12
+ export declare enum CertificateStatus {
13
+ RECEIVED = "downloadable",
14
+ NOT_RECEIVED = "notpassing",
15
+ AUDIT_PASSING = "audit_passing",
16
+ AUDIT_NOT_PASSING = "audit_notpassing",
17
+ ERROR_STATE = "error"
18
+ }
19
+ export declare enum SpecialCase {
20
+ NONE = "",
21
+ INVALIDATION = "invalidated",
22
+ EXCEPTION = "exception"
23
+ }
24
+ export interface CertificateData {
25
+ username: string;
26
+ email: string;
27
+ enrollmentTrack: string;
28
+ certificateStatus: CertificateStatus;
29
+ specialCase: SpecialCase;
30
+ exceptionGranted?: string;
31
+ exceptionNotes?: string;
32
+ invalidatedBy?: string;
33
+ invalidationDate?: string;
34
+ invalidationNote?: string;
35
+ }
36
+ export interface InstructorTask {
37
+ taskId: string;
38
+ taskName: string;
39
+ taskState: string;
40
+ taskOutput?: string;
41
+ created: string;
42
+ updated: string;
43
+ }
44
+ export interface CertificateGenerationHistory {
45
+ taskName: string;
46
+ date: string;
47
+ details: string;
48
+ }
49
+ export interface CertificateQueryParams extends PaginationParams {
50
+ filter: CertificateFilter;
51
+ search: string;
52
+ }
53
+ export interface GrantExceptionRequest {
54
+ learners: string[];
55
+ notes?: string;
56
+ }
57
+ export interface InvalidateCertificateRequest {
58
+ learners: string[];
59
+ notes?: string;
60
+ }
61
+ export interface RemoveExceptionRequest {
62
+ username: string;
63
+ }
64
+ export interface RemoveInvalidationRequest {
65
+ username: string;
66
+ }
@@ -0,0 +1,26 @@
1
+ export var CertificateFilter;
2
+ (function (CertificateFilter) {
3
+ CertificateFilter["ALL_LEARNERS"] = "all";
4
+ CertificateFilter["RECEIVED"] = "received";
5
+ CertificateFilter["NOT_RECEIVED"] = "not_received";
6
+ CertificateFilter["AUDIT_PASSING"] = "audit_passing";
7
+ CertificateFilter["AUDIT_NOT_PASSING"] = "audit_not_passing";
8
+ CertificateFilter["ERROR_STATE"] = "error";
9
+ CertificateFilter["GRANTED_EXCEPTIONS"] = "granted_exceptions";
10
+ CertificateFilter["INVALIDATED"] = "invalidated";
11
+ })(CertificateFilter || (CertificateFilter = {}));
12
+ export var CertificateStatus;
13
+ (function (CertificateStatus) {
14
+ CertificateStatus["RECEIVED"] = "downloadable";
15
+ CertificateStatus["NOT_RECEIVED"] = "notpassing";
16
+ CertificateStatus["AUDIT_PASSING"] = "audit_passing";
17
+ CertificateStatus["AUDIT_NOT_PASSING"] = "audit_notpassing";
18
+ CertificateStatus["ERROR_STATE"] = "error";
19
+ })(CertificateStatus || (CertificateStatus = {}));
20
+ export var SpecialCase;
21
+ (function (SpecialCase) {
22
+ SpecialCase["NONE"] = "";
23
+ SpecialCase["INVALIDATION"] = "invalidated";
24
+ SpecialCase["EXCEPTION"] = "exception";
25
+ })(SpecialCase || (SpecialCase = {}));
26
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/certificates/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,iBASX;AATD,WAAY,iBAAiB;IAC3B,yCAAoB,CAAA;IACpB,0CAAqB,CAAA;IACrB,kDAA6B,CAAA;IAC7B,oDAA+B,CAAA;IAC/B,4DAAuC,CAAA;IACvC,0CAAqB,CAAA;IACrB,8DAAyC,CAAA;IACzC,gDAA2B,CAAA;AAC7B,CAAC,EATW,iBAAiB,KAAjB,iBAAiB,QAS5B;AAED,MAAM,CAAN,IAAY,iBAMX;AAND,WAAY,iBAAiB;IAC3B,8CAAyB,CAAA;IACzB,gDAA2B,CAAA;IAC3B,oDAA+B,CAAA;IAC/B,2DAAsC,CAAA;IACtC,0CAAqB,CAAA;AACvB,CAAC,EANW,iBAAiB,KAAjB,iBAAiB,QAM5B;AAED,MAAM,CAAN,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,wBAAS,CAAA;IACT,2CAA4B,CAAA;IAC5B,sCAAuB,CAAA;AACzB,CAAC,EAJW,WAAW,KAAX,WAAW,QAItB","sourcesContent":["import type { PaginationParams } from '@src/types';\n\nexport enum CertificateFilter {\n ALL_LEARNERS = 'all',\n RECEIVED = 'received',\n NOT_RECEIVED = 'not_received',\n AUDIT_PASSING = 'audit_passing',\n AUDIT_NOT_PASSING = 'audit_not_passing',\n ERROR_STATE = 'error',\n GRANTED_EXCEPTIONS = 'granted_exceptions',\n INVALIDATED = 'invalidated',\n}\n\nexport enum CertificateStatus {\n RECEIVED = 'downloadable',\n NOT_RECEIVED = 'notpassing',\n AUDIT_PASSING = 'audit_passing',\n AUDIT_NOT_PASSING = 'audit_notpassing',\n ERROR_STATE = 'error',\n}\n\nexport enum SpecialCase {\n NONE = '',\n INVALIDATION = 'invalidated',\n EXCEPTION = 'exception',\n}\n\nexport interface CertificateData {\n username: string,\n email: string,\n enrollmentTrack: string,\n certificateStatus: CertificateStatus,\n specialCase: SpecialCase,\n exceptionGranted?: string,\n exceptionNotes?: string,\n invalidatedBy?: string,\n invalidationDate?: string,\n invalidationNote?: string,\n}\n\nexport interface InstructorTask {\n taskId: string,\n taskName: string,\n taskState: string,\n taskOutput?: string,\n created: string,\n updated: string,\n}\n\nexport interface CertificateGenerationHistory {\n taskName: string,\n date: string,\n details: string,\n}\n\nexport interface CertificateQueryParams extends PaginationParams {\n filter: CertificateFilter,\n search: string,\n}\n\nexport interface GrantExceptionRequest {\n learners: string[],\n notes?: string,\n}\n\nexport interface InvalidateCertificateRequest {\n learners: string[],\n notes?: string,\n}\n\nexport interface RemoveExceptionRequest {\n username: string,\n}\n\nexport interface RemoveInvalidationRequest {\n username: string,\n}\n"]}
@@ -0,0 +1,10 @@
1
+ export interface ApiError {
2
+ response?: {
3
+ data?: {
4
+ error?: string;
5
+ };
6
+ };
7
+ message?: string;
8
+ }
9
+ export declare const getErrorMessage: (error: ApiError, fallbackMessage: string) => string;
10
+ export declare const parseLearnersCount: (learners: string) => number;
@@ -0,0 +1,3 @@
1
+ export const getErrorMessage = (error, fallbackMessage) => { var _a, _b; return ((_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) || (error === null || error === void 0 ? void 0 : error.message) || fallbackMessage; };
2
+ export const parseLearnersCount = (learners) => learners.split(/[\n,]/).filter((l) => l.trim()).length;
3
+ //# sourceMappingURL=errorHandling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorHandling.js","sourceRoot":"","sources":["../../../src/certificates/utils/errorHandling.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAe,EAAE,eAAuB,EAAU,EAAE,eAClF,OAAA,CAAA,MAAA,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,QAAQ,0CAAE,IAAI,0CAAE,KAAK,MAAI,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,CAAA,IAAI,eAAe,CAAA,EAAA,CAAC;AAEpE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAAgB,EAAU,EAAE,CAC7D,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC","sourcesContent":["export interface ApiError {\n response?: {\n data?: {\n error?: string,\n },\n },\n message?: string,\n}\n\nexport const getErrorMessage = (error: ApiError, fallbackMessage: string): string =>\n error?.response?.data?.error || error?.message || fallbackMessage;\n\nexport const parseLearnersCount = (learners: string): number =>\n learners.split(/[\\n,]/).filter((l) => l.trim()).length;\n"]}
@@ -0,0 +1,4 @@
1
+ import { CertificateData, CertificateFilter } from '../../certificates/types';
2
+ export declare const matchesFilter: (item: CertificateData, filter: CertificateFilter) => boolean;
3
+ export declare const matchesSearch: (item: CertificateData, search: string) => boolean;
4
+ export declare const filterCertificates: (data: CertificateData[], filter: CertificateFilter, search: string) => CertificateData[];
@@ -0,0 +1,31 @@
1
+ import { CertificateFilter, CertificateStatus, SpecialCase } from '../../certificates/types';
2
+ export const matchesFilter = (item, filter) => {
3
+ switch (filter) {
4
+ case CertificateFilter.RECEIVED:
5
+ return item.certificateStatus === CertificateStatus.RECEIVED;
6
+ case CertificateFilter.NOT_RECEIVED:
7
+ return item.certificateStatus === CertificateStatus.NOT_RECEIVED;
8
+ case CertificateFilter.AUDIT_PASSING:
9
+ return item.certificateStatus === CertificateStatus.AUDIT_PASSING;
10
+ case CertificateFilter.AUDIT_NOT_PASSING:
11
+ return item.certificateStatus === CertificateStatus.AUDIT_NOT_PASSING;
12
+ case CertificateFilter.ERROR_STATE:
13
+ return item.certificateStatus === CertificateStatus.ERROR_STATE;
14
+ case CertificateFilter.GRANTED_EXCEPTIONS:
15
+ return item.specialCase === SpecialCase.EXCEPTION;
16
+ case CertificateFilter.INVALIDATED:
17
+ return item.specialCase === SpecialCase.INVALIDATION;
18
+ case CertificateFilter.ALL_LEARNERS:
19
+ default:
20
+ return true;
21
+ }
22
+ };
23
+ export const matchesSearch = (item, search) => {
24
+ if (!search)
25
+ return true;
26
+ const searchLower = search.toLowerCase();
27
+ return (item.username.toLowerCase().includes(searchLower)
28
+ || item.email.toLowerCase().includes(searchLower));
29
+ };
30
+ export const filterCertificates = (data, filter, search) => data.filter((item) => matchesFilter(item, filter) && matchesSearch(item, search));
31
+ //# sourceMappingURL=filterUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filterUtils.js","sourceRoot":"","sources":["../../../src/certificates/utils/filterUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,iBAAiB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE7G,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAqB,EAAE,MAAyB,EAAW,EAAE;IACzF,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,iBAAiB,CAAC,QAAQ;YAC7B,OAAO,IAAI,CAAC,iBAAiB,KAAK,iBAAiB,CAAC,QAAQ,CAAC;QAC/D,KAAK,iBAAiB,CAAC,YAAY;YACjC,OAAO,IAAI,CAAC,iBAAiB,KAAK,iBAAiB,CAAC,YAAY,CAAC;QACnE,KAAK,iBAAiB,CAAC,aAAa;YAClC,OAAO,IAAI,CAAC,iBAAiB,KAAK,iBAAiB,CAAC,aAAa,CAAC;QACpE,KAAK,iBAAiB,CAAC,iBAAiB;YACtC,OAAO,IAAI,CAAC,iBAAiB,KAAK,iBAAiB,CAAC,iBAAiB,CAAC;QACxE,KAAK,iBAAiB,CAAC,WAAW;YAChC,OAAO,IAAI,CAAC,iBAAiB,KAAK,iBAAiB,CAAC,WAAW,CAAC;QAClE,KAAK,iBAAiB,CAAC,kBAAkB;YACvC,OAAO,IAAI,CAAC,WAAW,KAAK,WAAW,CAAC,SAAS,CAAC;QACpD,KAAK,iBAAiB,CAAC,WAAW;YAChC,OAAO,IAAI,CAAC,WAAW,KAAK,WAAW,CAAC,YAAY,CAAC;QACvD,KAAK,iBAAiB,CAAC,YAAY,CAAC;QACpC;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAqB,EAAE,MAAc,EAAW,EAAE;IAC9E,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACzC,OAAO,CACL,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;WAC9C,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAClD,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,IAAuB,EACvB,MAAyB,EACzB,MAAc,EACK,EAAE,CACrB,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC","sourcesContent":["import { CertificateData, CertificateFilter, CertificateStatus, SpecialCase } from '@src/certificates/types';\n\nexport const matchesFilter = (item: CertificateData, filter: CertificateFilter): boolean => {\n switch (filter) {\n case CertificateFilter.RECEIVED:\n return item.certificateStatus === CertificateStatus.RECEIVED;\n case CertificateFilter.NOT_RECEIVED:\n return item.certificateStatus === CertificateStatus.NOT_RECEIVED;\n case CertificateFilter.AUDIT_PASSING:\n return item.certificateStatus === CertificateStatus.AUDIT_PASSING;\n case CertificateFilter.AUDIT_NOT_PASSING:\n return item.certificateStatus === CertificateStatus.AUDIT_NOT_PASSING;\n case CertificateFilter.ERROR_STATE:\n return item.certificateStatus === CertificateStatus.ERROR_STATE;\n case CertificateFilter.GRANTED_EXCEPTIONS:\n return item.specialCase === SpecialCase.EXCEPTION;\n case CertificateFilter.INVALIDATED:\n return item.specialCase === SpecialCase.INVALIDATION;\n case CertificateFilter.ALL_LEARNERS:\n default:\n return true;\n }\n};\n\nexport const matchesSearch = (item: CertificateData, search: string): boolean => {\n if (!search) return true;\n const searchLower = search.toLowerCase();\n return (\n item.username.toLowerCase().includes(searchLower)\n || item.email.toLowerCase().includes(searchLower)\n );\n};\n\nexport const filterCertificates = (\n data: CertificateData[],\n filter: CertificateFilter,\n search: string,\n): CertificateData[] =>\n data.filter((item) => matchesFilter(item, filter) && matchesSearch(item, search));\n"]}
@@ -0,0 +1,2 @@
1
+ export { getErrorMessage } from '../../certificates/utils/errorHandling';
2
+ export type { ApiError } from '../../certificates/utils/errorHandling';
@@ -0,0 +1,2 @@
1
+ export { getErrorMessage } from '../../certificates/utils/errorHandling';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/certificates/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC","sourcesContent":["export { getErrorMessage } from '@src/certificates/utils/errorHandling';\nexport type { ApiError } from '@src/certificates/utils/errorHandling';\n"]}
@@ -1,5 +1,5 @@
1
- interface ActionCardProps {
2
- buttonLabel: string;
1
+ export interface ActionCardProps {
2
+ buttonLabel?: string;
3
3
  customAction?: React.ReactNode;
4
4
  description: string;
5
5
  hasBorderBottom?: boolean;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Button, Card } from '@openedx/paragon';
3
3
  const ActionCard = ({ buttonLabel, customAction, description, hasBorderBottom = true, isLoading = false, title, onButtonClick, }) => {
4
- return (_jsxs(Card, { className: `bg-light-200 py-2 border-gray-500 rounded-0 shadow-none ${hasBorderBottom ? 'border-bottom' : ''}`, orientation: "horizontal", children: [_jsx(Card.Body, { className: "flex-grow-1", children: _jsxs(Card.Section, { children: [_jsx("h4", { className: "mb-2", children: title }), _jsx("p", { className: "text-muted mb-0", children: description })] }) }), _jsx(Card.Footer, { className: "d-flex align-items-center justify-content-end", children: customAction !== null && customAction !== void 0 ? customAction : (_jsx(Button, { onClick: onButtonClick, disabled: isLoading, variant: "primary", children: buttonLabel })) })] }));
4
+ return (_jsxs(Card, { className: `bg-light-200 pb-2 mt-2 border-gray-500 rounded-0 shadow-none ${hasBorderBottom ? 'border-bottom' : ''}`, orientation: "horizontal", children: [_jsx(Card.Body, { className: "flex-grow-1", children: _jsxs(Card.Section, { className: "pl-0", children: [_jsx("h4", { className: "text-primary-700 mb-2", children: title }), _jsx("p", { className: "text-primary-500 mb-0", children: description })] }) }), _jsx(Card.Footer, { className: "d-flex align-items-center justify-content-end", children: customAction !== null && customAction !== void 0 ? customAction : (buttonLabel && onButtonClick && (_jsx(Button, { onClick: onButtonClick, disabled: isLoading, variant: "primary", children: buttonLabel }))) })] }));
5
5
  };
6
6
  export default ActionCard;
7
7
  //# sourceMappingURL=ActionCard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ActionCard.js","sourceRoot":"","sources":["../../src/components/ActionCard.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAYhD,MAAM,UAAU,GAAG,CAAC,EAClB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,eAAe,GAAG,IAAI,EACtB,SAAS,GAAG,KAAK,EACjB,KAAK,EACL,aAAa,GACG,EAAE,EAAE;IACpB,OAAO,CACL,MAAC,IAAI,IAAC,SAAS,EAAE,2DAA2D,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,WAAW,EAAC,YAAY,aAC5I,KAAC,IAAI,CAAC,IAAI,IAAC,SAAS,EAAC,aAAa,YAChC,MAAC,IAAI,CAAC,OAAO,eACX,aAAI,SAAS,EAAC,MAAM,YAAE,KAAK,GAAM,EACjC,YAAG,SAAS,EAAC,iBAAiB,YAAE,WAAW,GAAK,IACnC,GACL,EACZ,KAAC,IAAI,CAAC,MAAM,IAAC,SAAS,EAAC,+CAA+C,YACnE,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,CACf,KAAC,MAAM,IACL,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,SAAS,EACnB,OAAO,EAAC,SAAS,YAEhB,WAAW,GACL,CACV,GACW,IACT,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC","sourcesContent":["import { Button, Card } from '@openedx/paragon';\n\ninterface ActionCardProps {\n buttonLabel: string,\n customAction?: React.ReactNode,\n description: string,\n hasBorderBottom?: boolean,\n isLoading?: boolean,\n title: string,\n onButtonClick?: () => void,\n}\n\nconst ActionCard = ({\n buttonLabel,\n customAction,\n description,\n hasBorderBottom = true,\n isLoading = false,\n title,\n onButtonClick,\n}: ActionCardProps) => {\n return (\n <Card className={`bg-light-200 py-2 border-gray-500 rounded-0 shadow-none ${hasBorderBottom ? 'border-bottom' : ''}`} orientation=\"horizontal\">\n <Card.Body className=\"flex-grow-1\">\n <Card.Section>\n <h4 className=\"mb-2\">{title}</h4>\n <p className=\"text-muted mb-0\">{description}</p>\n </Card.Section>\n </Card.Body>\n <Card.Footer className=\"d-flex align-items-center justify-content-end\">\n {customAction ?? (\n <Button\n onClick={onButtonClick}\n disabled={isLoading}\n variant=\"primary\"\n >\n {buttonLabel}\n </Button>\n )}\n </Card.Footer>\n </Card>\n );\n};\n\nexport default ActionCard;\n"]}
1
+ {"version":3,"file":"ActionCard.js","sourceRoot":"","sources":["../../src/components/ActionCard.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAYhD,MAAM,UAAU,GAAG,CAAC,EAClB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,eAAe,GAAG,IAAI,EACtB,SAAS,GAAG,KAAK,EACjB,KAAK,EACL,aAAa,GACG,EAAE,EAAE;IACpB,OAAO,CACL,MAAC,IAAI,IAAC,SAAS,EAAE,gEAAgE,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,WAAW,EAAC,YAAY,aACjJ,KAAC,IAAI,CAAC,IAAI,IAAC,SAAS,EAAC,aAAa,YAChC,MAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,MAAM,aAC5B,aAAI,SAAS,EAAC,uBAAuB,YAAE,KAAK,GAAM,EAClD,YAAG,SAAS,EAAC,uBAAuB,YAAE,WAAW,GAAK,IACzC,GACL,EACZ,KAAC,IAAI,CAAC,MAAM,IAAC,SAAS,EAAC,+CAA+C,YACnE,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,CAAC,WAAW,IAAI,aAAa,IAAI,CAChD,KAAC,MAAM,IACL,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,SAAS,EACnB,OAAO,EAAC,SAAS,YAEhB,WAAW,GACL,CACV,CAAC,GACU,IACT,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC","sourcesContent":["import { Button, Card } from '@openedx/paragon';\n\nexport interface ActionCardProps {\n buttonLabel?: string,\n customAction?: React.ReactNode,\n description: string,\n hasBorderBottom?: boolean,\n isLoading?: boolean,\n title: string,\n onButtonClick?: () => void,\n}\n\nconst ActionCard = ({\n buttonLabel,\n customAction,\n description,\n hasBorderBottom = true,\n isLoading = false,\n title,\n onButtonClick,\n}: ActionCardProps) => {\n return (\n <Card className={`bg-light-200 pb-2 mt-2 border-gray-500 rounded-0 shadow-none ${hasBorderBottom ? 'border-bottom' : ''}`} orientation=\"horizontal\">\n <Card.Body className=\"flex-grow-1\">\n <Card.Section className=\"pl-0\">\n <h4 className=\"text-primary-700 mb-2\">{title}</h4>\n <p className=\"text-primary-500 mb-0\">{description}</p>\n </Card.Section>\n </Card.Body>\n <Card.Footer className=\"d-flex align-items-center justify-content-end\">\n {customAction ?? (buttonLabel && onButtonClick && (\n <Button\n onClick={onButtonClick}\n disabled={isLoading}\n variant=\"primary\"\n >\n {buttonLabel}\n </Button>\n ))}\n </Card.Footer>\n </Card>\n );\n};\n\nexport default ActionCard;\n"]}
@@ -0,0 +1,5 @@
1
+ interface CodeEditorProps {
2
+ data: string;
3
+ }
4
+ declare const CodeEditor: ({ data }: CodeEditorProps) => import("react/jsx-runtime").JSX.Element;
5
+ export default CodeEditor;
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useCallback, useRef } from 'react';
3
+ import { EditorView, basicSetup } from 'codemirror';
4
+ import { EditorState } from '@codemirror/state';
5
+ const decodeHtml = (raw) => {
6
+ const parser = new DOMParser();
7
+ const doc = parser.parseFromString(raw, 'text/html');
8
+ return doc.documentElement.textContent || '';
9
+ };
10
+ const CodeEditor = ({ data }) => {
11
+ const editorRef = useRef(null);
12
+ const containerRef = useCallback((node) => {
13
+ if (editorRef.current) {
14
+ editorRef.current.destroy();
15
+ editorRef.current = null;
16
+ }
17
+ if (node && data) {
18
+ editorRef.current = new EditorView({
19
+ state: EditorState.create({
20
+ doc: decodeHtml(data),
21
+ extensions: [
22
+ basicSetup,
23
+ EditorState.readOnly.of(true),
24
+ EditorView.editable.of(false),
25
+ ],
26
+ }),
27
+ parent: node,
28
+ });
29
+ }
30
+ }, [data]);
31
+ return _jsx("div", { ref: containerRef });
32
+ };
33
+ export default CodeEditor;
34
+ //# sourceMappingURL=CodeEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeEditor.js","sourceRoot":"","sources":["../../src/components/CodeEditor.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMhD,MAAM,UAAU,GAAG,CAAC,GAAW,EAAU,EAAE;IACzC,MAAM,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;IAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACrD,OAAO,GAAG,CAAC,eAAe,CAAC,WAAW,IAAI,EAAE,CAAC;AAC/C,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,EAAE,IAAI,EAAmB,EAAE,EAAE;IAC/C,MAAM,SAAS,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IAElD,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,IAA2B,EAAE,EAAE;QAC/D,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACtB,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC5B,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC;QAC3B,CAAC;QACD,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,SAAS,CAAC,OAAO,GAAG,IAAI,UAAU,CAAC;gBACjC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;oBACxB,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC;oBACrB,UAAU,EAAE;wBACV,UAAU;wBACV,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC;wBAC7B,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC;qBAC9B;iBACF,CAAC;gBACF,MAAM,EAAE,IAAI;aACb,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO,cAAK,GAAG,EAAE,YAAY,GAAI,CAAC;AACpC,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC","sourcesContent":["import { useCallback, useRef } from 'react';\nimport { EditorView, basicSetup } from 'codemirror';\nimport { EditorState } from '@codemirror/state';\n\ninterface CodeEditorProps {\n data: string,\n}\n\nconst decodeHtml = (raw: string): string => {\n const parser = new DOMParser();\n const doc = parser.parseFromString(raw, 'text/html');\n return doc.documentElement.textContent || '';\n};\n\nconst CodeEditor = ({ data }: CodeEditorProps) => {\n const editorRef = useRef<EditorView | null>(null);\n\n const containerRef = useCallback((node: HTMLDivElement | null) => {\n if (editorRef.current) {\n editorRef.current.destroy();\n editorRef.current = null;\n }\n if (node && data) {\n editorRef.current = new EditorView({\n state: EditorState.create({\n doc: decodeHtml(data),\n extensions: [\n basicSetup,\n EditorState.readOnly.of(true),\n EditorView.editable.of(false),\n ],\n }),\n parent: node,\n });\n }\n }, [data]);\n\n return <div ref={containerRef} />;\n};\n\nexport default CodeEditor;\n"]}
@@ -1,5 +1,7 @@
1
1
  interface PendingTasksProps {
2
2
  isPolling?: boolean;
3
+ isOpen?: boolean;
4
+ onToggle?: () => void;
3
5
  }
4
- declare const PendingTasks: ({ isPolling }: PendingTasksProps) => import("react/jsx-runtime").JSX.Element;
6
+ declare const PendingTasks: ({ isPolling, isOpen, onToggle }: PendingTasksProps) => import("react/jsx-runtime").JSX.Element;
5
7
  export { PendingTasks };
@@ -7,7 +7,7 @@ import { ExpandLess, ExpandMore } from '@openedx/paragon/icons';
7
7
  import { usePendingTasks } from '../data/apiHook';
8
8
  import { useParams } from 'react-router';
9
9
  import { ObjectCell } from './ObjectCell';
10
- const PendingTasks = ({ isPolling = false }) => {
10
+ const PendingTasks = ({ isPolling = false, isOpen = false, onToggle }) => {
11
11
  const intl = useIntl();
12
12
  const { courseId = '' } = useParams();
13
13
  const { data: tasks, isLoading } = usePendingTasks(courseId, { enablePolling: isPolling });
@@ -32,7 +32,8 @@ const PendingTasks = ({ isPolling = false }) => {
32
32
  }
33
33
  return (_jsx(DataTable, { columns: tableColumns, data: tasks, RowStatusComponent: () => null }));
34
34
  };
35
- return (_jsxs(Collapsible.Advanced, { className: "mt-4 pt-4 border-top", styling: "basic", children: [_jsxs(Collapsible.Trigger, { className: "collapsible-trigger d-flex border-0 align-items-center text-decoration-none", children: [_jsx("div", { className: "d-flex", children: _jsx("h3", { className: "text-primary-700", children: intl.formatMessage(messages.pendingTasksTitle) }) }), _jsx(Collapsible.Visible, { whenClosed: true, children: _jsx("div", { className: "pl-2 d-flex", children: _jsx(Icon, { className: "text-primary-500", src: ExpandMore }) }) }), _jsx(Collapsible.Visible, { whenOpen: true, children: _jsx("div", { className: "pl-2 d-flex", children: _jsx(Icon, { className: "text-primary-500", src: ExpandLess }) }) })] }), _jsx(Collapsible.Body, { children: renderContent() })] }));
35
+ const collapsibleProps = onToggle ? { open: isOpen, onToggle } : {};
36
+ return (_jsxs(Collapsible.Advanced, Object.assign({ className: "mt-4 pt-4 border-top", styling: "basic" }, collapsibleProps, { children: [_jsxs(Collapsible.Trigger, { className: "collapsible-trigger d-flex border-0 align-items-center text-decoration-none", children: [_jsx("div", { className: "d-flex", children: _jsx("h3", { className: "text-primary-700", children: intl.formatMessage(messages.pendingTasksTitle) }) }), _jsx(Collapsible.Visible, { whenClosed: true, children: _jsx("div", { className: "pl-2 d-flex", children: _jsx(Icon, { className: "text-primary-500", src: ExpandMore }) }) }), _jsx(Collapsible.Visible, { whenOpen: true, children: _jsx("div", { className: "pl-2 d-flex", children: _jsx(Icon, { className: "text-primary-500", src: ExpandLess }) }) })] }), _jsx(Collapsible.Body, { children: renderContent() })] })));
36
37
  };
37
38
  export { PendingTasks };
38
39
  //# sourceMappingURL=PendingTasks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PendingTasks.js","sourceRoot":"","sources":["../../src/components/PendingTasks.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport { Collapsible, DataTable, Icon, Skeleton } from '@openedx/paragon';\nimport { useMemo } from 'react';\nimport messages from './messages';\nimport { ExpandLess, ExpandMore } from '@openedx/paragon/icons';\nimport { usePendingTasks } from '@src/data/apiHook';\nimport { useParams } from 'react-router';\nimport { ObjectCell } from './ObjectCell';\nimport { PendingTask, TableCellValue } from '@src/types';\n\ninterface PendingTasksProps {\n isPolling?: boolean,\n}\n\nconst PendingTasks = ({ isPolling = false }: PendingTasksProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams();\n const { data: tasks, isLoading } = usePendingTasks(courseId, { enablePolling: isPolling });\n\n const tableColumns = useMemo(() => [\n { accessor: 'taskType', Header: intl.formatMessage(messages.taskTypeColumnName) },\n { accessor: 'taskInput', Header: intl.formatMessage(messages.taskInputColumnName), Cell: ({ row }: TableCellValue<PendingTask>) => <ObjectCell value={row.original.taskInput} /> },\n { accessor: 'taskId', Header: intl.formatMessage(messages.taskIdColumnName) },\n { accessor: 'requester', Header: intl.formatMessage(messages.requesterColumnName) },\n { accessor: 'taskState', Header: intl.formatMessage(messages.taskStateColumnName) },\n { accessor: 'created', Header: intl.formatMessage(messages.createdColumnName) },\n { accessor: 'taskOutput', Header: intl.formatMessage(messages.taskOutputColumnName), Cell: ({ row }: TableCellValue<PendingTask>) => <ObjectCell value={row.original.taskOutput} /> },\n { accessor: 'durationSec', Header: intl.formatMessage(messages.durationColumnName) },\n { accessor: 'status', Header: intl.formatMessage(messages.statusColumnName) },\n { accessor: 'taskMessage', Header: intl.formatMessage(messages.taskMessageColumnName) },\n ], [intl]);\n\n const renderContent = () => {\n if (isLoading) {\n return <Skeleton count={3} />;\n }\n\n if (!tasks || tasks?.length === 0) {\n return <div className=\"my-3\">{intl.formatMessage(messages.noTasksMessage)}</div>;\n }\n\n return (\n <DataTable\n columns={tableColumns}\n data={tasks}\n RowStatusComponent={() => null}\n />\n );\n };\n\n return (\n <Collapsible.Advanced\n className=\"mt-4 pt-4 border-top\"\n styling=\"basic\"\n >\n <Collapsible.Trigger\n className=\"collapsible-trigger d-flex border-0 align-items-center text-decoration-none\"\n >\n <div className=\"d-flex\">\n <h3 className=\"text-primary-700\">{intl.formatMessage(messages.pendingTasksTitle)}</h3>\n </div>\n\n <Collapsible.Visible whenClosed>\n <div className=\"pl-2 d-flex\">\n <Icon className=\"text-primary-500\" src={ExpandMore} />\n </div>\n </Collapsible.Visible>\n <Collapsible.Visible whenOpen>\n <div className=\"pl-2 d-flex\">\n <Icon className=\"text-primary-500\" src={ExpandLess} />\n </div>\n </Collapsible.Visible>\n </Collapsible.Trigger>\n <Collapsible.Body>\n {renderContent() }\n </Collapsible.Body>\n </Collapsible.Advanced>\n );\n};\n\nexport { PendingTasks };\n"]}
1
+ {"version":3,"file":"PendingTasks.js","sourceRoot":"","sources":["../../src/components/PendingTasks.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAS1C,MAAM,YAAY,GAAG,CAAC,EAAE,SAAS,GAAG,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,QAAQ,EAAqB,EAAE,EAAE;IAC1F,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,SAAS,EAAE,CAAC;IACtC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,eAAe,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC;IAE3F,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QACjC,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE;QACjF,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAA+B,EAAE,EAAE,CAAC,KAAC,UAAU,IAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,SAAS,GAAI,EAAE;QAClL,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;QAC7E,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE;QACnF,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE;QACnF,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE;QAC/E,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAA+B,EAAE,EAAE,CAAC,KAAC,UAAU,IAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,UAAU,GAAI,EAAE;QACrL,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE;QACpF,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;QAC7E,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE;KACxF,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,KAAC,QAAQ,IAAC,KAAK,EAAE,CAAC,GAAI,CAAC;QAChC,CAAC;QAED,IAAI,CAAC,KAAK,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,MAAM,MAAK,CAAC,EAAE,CAAC;YAClC,OAAO,cAAK,SAAS,EAAC,MAAM,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAO,CAAC;QACnF,CAAC;QAED,OAAO,CACL,KAAC,SAAS,IACR,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,KAAK,EACX,kBAAkB,EAAE,GAAG,EAAE,CAAC,IAAI,GAC9B,CACH,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAEpE,OAAO,CACL,MAAC,WAAW,CAAC,QAAQ,kBACnB,SAAS,EAAC,sBAAsB,EAChC,OAAO,EAAC,OAAO,IACX,gBAAgB,eAEpB,MAAC,WAAW,CAAC,OAAO,IAClB,SAAS,EAAC,6EAA6E,aAEvF,cAAK,SAAS,EAAC,QAAQ,YACrB,aAAI,SAAS,EAAC,kBAAkB,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,GAAM,GAClF,EAEN,KAAC,WAAW,CAAC,OAAO,IAAC,UAAU,kBAC7B,cAAK,SAAS,EAAC,aAAa,YAC1B,KAAC,IAAI,IAAC,SAAS,EAAC,kBAAkB,EAAC,GAAG,EAAE,UAAU,GAAI,GAClD,GACc,EACtB,KAAC,WAAW,CAAC,OAAO,IAAC,QAAQ,kBAC3B,cAAK,SAAS,EAAC,aAAa,YAC1B,KAAC,IAAI,IAAC,SAAS,EAAC,kBAAkB,EAAC,GAAG,EAAE,UAAU,GAAI,GAClD,GACc,IACF,EACtB,KAAC,WAAW,CAAC,IAAI,cACd,aAAa,EAAE,GACC,KACE,CACxB,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport { Collapsible, DataTable, Icon, Skeleton } from '@openedx/paragon';\nimport { useMemo } from 'react';\nimport messages from './messages';\nimport { ExpandLess, ExpandMore } from '@openedx/paragon/icons';\nimport { usePendingTasks } from '@src/data/apiHook';\nimport { useParams } from 'react-router';\nimport { ObjectCell } from './ObjectCell';\nimport { PendingTask, TableCellValue } from '@src/types';\n\ninterface PendingTasksProps {\n isPolling?: boolean,\n isOpen?: boolean,\n onToggle?: () => void,\n}\n\nconst PendingTasks = ({ isPolling = false, isOpen = false, onToggle }: PendingTasksProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams();\n const { data: tasks, isLoading } = usePendingTasks(courseId, { enablePolling: isPolling });\n\n const tableColumns = useMemo(() => [\n { accessor: 'taskType', Header: intl.formatMessage(messages.taskTypeColumnName) },\n { accessor: 'taskInput', Header: intl.formatMessage(messages.taskInputColumnName), Cell: ({ row }: TableCellValue<PendingTask>) => <ObjectCell value={row.original.taskInput} /> },\n { accessor: 'taskId', Header: intl.formatMessage(messages.taskIdColumnName) },\n { accessor: 'requester', Header: intl.formatMessage(messages.requesterColumnName) },\n { accessor: 'taskState', Header: intl.formatMessage(messages.taskStateColumnName) },\n { accessor: 'created', Header: intl.formatMessage(messages.createdColumnName) },\n { accessor: 'taskOutput', Header: intl.formatMessage(messages.taskOutputColumnName), Cell: ({ row }: TableCellValue<PendingTask>) => <ObjectCell value={row.original.taskOutput} /> },\n { accessor: 'durationSec', Header: intl.formatMessage(messages.durationColumnName) },\n { accessor: 'status', Header: intl.formatMessage(messages.statusColumnName) },\n { accessor: 'taskMessage', Header: intl.formatMessage(messages.taskMessageColumnName) },\n ], [intl]);\n\n const renderContent = () => {\n if (isLoading) {\n return <Skeleton count={3} />;\n }\n\n if (!tasks || tasks?.length === 0) {\n return <div className=\"my-3\">{intl.formatMessage(messages.noTasksMessage)}</div>;\n }\n\n return (\n <DataTable\n columns={tableColumns}\n data={tasks}\n RowStatusComponent={() => null}\n />\n );\n };\n\n const collapsibleProps = onToggle ? { open: isOpen, onToggle } : {};\n\n return (\n <Collapsible.Advanced\n className=\"mt-4 pt-4 border-top\"\n styling=\"basic\"\n {...collapsibleProps}\n >\n <Collapsible.Trigger\n className=\"collapsible-trigger d-flex border-0 align-items-center text-decoration-none\"\n >\n <div className=\"d-flex\">\n <h3 className=\"text-primary-700\">{intl.formatMessage(messages.pendingTasksTitle)}</h3>\n </div>\n\n <Collapsible.Visible whenClosed>\n <div className=\"pl-2 d-flex\">\n <Icon className=\"text-primary-500\" src={ExpandMore} />\n </div>\n </Collapsible.Visible>\n <Collapsible.Visible whenOpen>\n <div className=\"pl-2 d-flex\">\n <Icon className=\"text-primary-500\" src={ExpandLess} />\n </div>\n </Collapsible.Visible>\n </Collapsible.Trigger>\n <Collapsible.Body>\n {renderContent() }\n </Collapsible.Body>\n </Collapsible.Advanced>\n );\n};\n\nexport { PendingTasks };\n"]}
@@ -3,5 +3,8 @@ interface SpecifyLearnerFieldProps {
3
3
  learner?: SelectedLearner;
4
4
  onClickSelect: (emailOrUsername: string) => void;
5
5
  }
6
- declare const SpecifyLearnerField: ({ learner, onClickSelect }: SpecifyLearnerFieldProps) => import("react/jsx-runtime").JSX.Element;
6
+ interface SpecifyLearnerFieldRef {
7
+ reset: () => void;
8
+ }
9
+ declare const SpecifyLearnerField: import("react").ForwardRefExoticComponent<SpecifyLearnerFieldProps & import("react").RefAttributes<SpecifyLearnerFieldRef>>;
7
10
  export default SpecifyLearnerField;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useState } from 'react';
2
+ import { useState, useImperativeHandle, forwardRef } from 'react';
3
3
  import { isAxiosError } from 'axios';
4
4
  import { useParams } from 'react-router-dom';
5
5
  import { Avatar, Button, FormControl, FormGroup, FormLabel, useToggle } from '@openedx/paragon';
@@ -8,20 +8,34 @@ import { SpinnerIcon } from '@openedx/paragon/icons';
8
8
  import { useDebouncedFilter } from '../hooks/useDebouncedFilter';
9
9
  import { useCourseInfo, useLearner } from '../data/apiHook';
10
10
  import messages from './messages';
11
- const SpecifyLearnerField = ({ learner, onClickSelect }) => {
11
+ const initialLearnerState = {
12
+ username: '',
13
+ fullName: '',
14
+ email: '',
15
+ isEnrolled: false,
16
+ };
17
+ const SpecifyLearnerField = forwardRef(({ learner, onClickSelect }, ref) => {
12
18
  var _a;
13
19
  const intl = useIntl();
14
20
  const { courseId = '' } = useParams();
15
21
  const [identifier, setIdentifier] = useState('');
16
- const [showLearner, enableShowLearner, disableShowLearner] = useToggle(false);
22
+ const [showLearner, enableShowLearner, disableShowLearner] = useToggle(!!learner);
17
23
  const { data: courseInfo } = useCourseInfo(courseId);
18
24
  const permissions = (courseInfo === null || courseInfo === void 0 ? void 0 : courseInfo.permissions) || { admin: false, dataResearcher: false };
19
- const { inputValue, handleChange } = useDebouncedFilter({
25
+ const { inputValue, handleChange, resetFilter } = useDebouncedFilter({
20
26
  filterValue: identifier,
21
27
  setFilter: setIdentifier,
22
28
  });
23
- const { data = { email: '', fullName: '', username: '' }, refetch, error } = useLearner(courseId, inputValue);
24
- const selectedLearner = learner || data;
29
+ const { data, refetch, error } = useLearner(courseId, inputValue);
30
+ const resetState = () => {
31
+ resetFilter();
32
+ onClickSelect('');
33
+ disableShowLearner();
34
+ };
35
+ useImperativeHandle(ref, () => ({
36
+ reset: resetState,
37
+ }));
38
+ const selectedLearner = learner || data || initialLearnerState;
25
39
  const handleInputChange = (event) => {
26
40
  handleChange(event.target.value);
27
41
  if (showLearner) {
@@ -30,15 +44,21 @@ const SpecifyLearnerField = ({ learner, onClickSelect }) => {
30
44
  };
31
45
  const handleClickSelect = () => {
32
46
  if (inputValue) {
33
- onClickSelect(inputValue);
34
- refetch();
35
- enableShowLearner();
47
+ refetch().then((result) => {
48
+ var _a;
49
+ // Need to pass empty value if learner is not valid to clear out any previously selected learner
50
+ // We could have other conditions/fields depending on valid learner
51
+ const formValue = !result.error && ((_a = result.data) === null || _a === void 0 ? void 0 : _a.isEnrolled) ? inputValue : '';
52
+ onClickSelect(formValue);
53
+ enableShowLearner();
54
+ });
36
55
  }
37
56
  };
38
- return (_jsxs(FormGroup, { className: "mb-0", size: "sm", children: [_jsx(FormLabel, { className: "text-primary-500 d-flex", children: intl.formatMessage(messages.specifyLearner) }), _jsxs("div", { className: "d-flex align-items-center", children: [_jsx(FormControl, { className: `mr-2 ${selectedLearner.username && showLearner ? 'd-none' : ''}`, name: "emailOrUsername", placeholder: intl.formatMessage(messages.specifyLearnerPlaceholder), size: "md", autoResize: true, value: inputValue, onChange: handleInputChange }), selectedLearner.username && showLearner ? (_jsxs(_Fragment, { children: [_jsx(Avatar, { className: "mr-2.5", size: "sm" }), _jsxs("div", { className: "d-flex flex-column mr-3 text-primary-500", children: [_jsx("p", { className: "mb-0", children: selectedLearner.username }), (permissions.admin || permissions.dataResearcher)
39
- && (_jsxs("div", { className: "d-flex x-small", children: [_jsx("p", { className: "mr-3 mb-0", children: selectedLearner.fullName }), _jsx("p", { className: "mb-0", children: selectedLearner.email })] }))] }), !learner && _jsx(Button, { iconBefore: SpinnerIcon, onClick: disableShowLearner, children: intl.formatMessage(messages.change) })] })) : (_jsx(Button, { onClick: handleClickSelect, disabled: !inputValue, children: intl.formatMessage(messages.select) }))] }), showLearner && error
57
+ return (_jsxs(FormGroup, { className: "mb-0", size: "sm", children: [_jsx(FormLabel, { className: "text-primary-500 d-flex", children: selectedLearner.username ? intl.formatMessage(messages.selectedLearner) : intl.formatMessage(messages.specifyLearner) }), _jsxs("div", { className: "d-flex align-items-center", children: [_jsx(FormControl, { className: `mr-2 ${selectedLearner.username && showLearner ? 'd-none' : ''}`, name: "emailOrUsername", placeholder: intl.formatMessage(messages.specifyLearnerPlaceholder), size: "md", autoResize: true, value: inputValue, onChange: handleInputChange }), selectedLearner.username && showLearner ? (_jsxs(_Fragment, { children: [_jsx(Avatar, { className: "mr-2.5", size: "sm" }), _jsxs("div", { className: "d-flex flex-column mr-3 text-primary-500", children: [_jsx("p", { className: "mb-0", children: selectedLearner.username }), (permissions.admin || permissions.dataResearcher)
58
+ && (_jsxs("div", { className: "d-flex x-small", children: [_jsx("p", { className: "mr-3 mb-0", children: selectedLearner.fullName }), _jsx("p", { className: "mb-0", children: selectedLearner.email })] }))] }), !learner && _jsx(Button, { iconBefore: SpinnerIcon, onClick: resetState, children: intl.formatMessage(messages.change) })] })) : (_jsx(Button, { onClick: handleClickSelect, disabled: !inputValue, children: intl.formatMessage(messages.select) }))] }), showLearner && error
40
59
  && isAxiosError(error)
41
- && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404 && (_jsx("p", { className: "text-danger-500 mb-0 x-small mt-2", children: intl.formatMessage(messages.learnerNotFound, { identifier }) }))] }));
42
- };
60
+ && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404 && (_jsx("p", { className: "text-danger-500 mb-0 x-small mt-2", children: intl.formatMessage(messages.learnerNotFound, { identifier }) })), showLearner && !error && !(selectedLearner === null || selectedLearner === void 0 ? void 0 : selectedLearner.isEnrolled) && (_jsx("p", { className: "text-danger-500 mb-0 x-small mt-2", children: intl.formatMessage(messages.learnerNotEnrolled, { identifier }) }))] }));
61
+ });
62
+ SpecifyLearnerField.displayName = 'SpecifyLearnerField';
43
63
  export default SpecifyLearnerField;
44
64
  //# sourceMappingURL=SpecifyLearnerField.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SpecifyLearnerField.js","sourceRoot":"","sources":["../../src/components/SpecifyLearnerField.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState, ChangeEvent } from 'react';\nimport { isAxiosError } from 'axios';\nimport { useParams } from 'react-router-dom';\nimport { Avatar, Button, FormControl, FormGroup, FormLabel, useToggle } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport { SpinnerIcon } from '@openedx/paragon/icons';\nimport { useDebouncedFilter } from '@src/hooks/useDebouncedFilter';\nimport { useCourseInfo, useLearner } from '@src/data/apiHook';\nimport { SelectedLearner } from '@src/types';\nimport messages from './messages';\n\ninterface SpecifyLearnerFieldProps {\n learner?: SelectedLearner,\n onClickSelect: (emailOrUsername: string) => void,\n}\n\nconst SpecifyLearnerField = ({ learner, onClickSelect }: SpecifyLearnerFieldProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [identifier, setIdentifier] = useState('');\n const [showLearner, enableShowLearner, disableShowLearner] = useToggle(false);\n const { data: courseInfo } = useCourseInfo(courseId);\n const permissions = courseInfo?.permissions || { admin: false, dataResearcher: false };\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue: identifier,\n setFilter: setIdentifier,\n });\n const { data = { email: '', fullName: '', username: '' }, refetch, error } = useLearner(courseId, inputValue);\n\n const selectedLearner = learner || data;\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n handleChange(event.target.value);\n\n if (showLearner) {\n disableShowLearner();\n }\n };\n\n const handleClickSelect = () => {\n if (inputValue) {\n onClickSelect(inputValue);\n refetch();\n enableShowLearner();\n }\n };\n\n return (\n <FormGroup className=\"mb-0\" size=\"sm\">\n <FormLabel className=\"text-primary-500 d-flex\">{intl.formatMessage(messages.specifyLearner)}</FormLabel>\n <div className=\"d-flex align-items-center\">\n <FormControl\n className={`mr-2 ${selectedLearner.username && showLearner ? 'd-none' : ''}`}\n name=\"emailOrUsername\"\n placeholder={intl.formatMessage(messages.specifyLearnerPlaceholder)}\n size=\"md\"\n autoResize\n value={inputValue}\n onChange={handleInputChange}\n />\n {selectedLearner.username && showLearner ? (\n <>\n <Avatar className=\"mr-2.5\" size=\"sm\" />\n <div className=\"d-flex flex-column mr-3 text-primary-500\">\n <p className=\"mb-0\">{selectedLearner.username}</p>\n {(permissions.admin || permissions.dataResearcher)\n && (\n <div className=\"d-flex x-small\">\n <p className=\"mr-3 mb-0\">{selectedLearner.fullName}</p>\n <p className=\"mb-0\">{selectedLearner.email}</p>\n </div>\n )}\n </div>\n {!learner && <Button iconBefore={SpinnerIcon} onClick={disableShowLearner}>{intl.formatMessage(messages.change)}</Button>}\n </>\n ) : (\n <Button onClick={handleClickSelect} disabled={!inputValue}>{intl.formatMessage(messages.select)}</Button>\n )}\n </div>\n {showLearner && error\n && isAxiosError(error)\n && error.response?.status === 404 && (\n <p className=\"text-danger-500 mb-0 x-small mt-2\">\n {intl.formatMessage(messages.learnerNotFound, { identifier })}\n </p>\n )}\n </FormGroup>\n );\n};\n\nexport default SpecifyLearnerField;\n"]}
1
+ {"version":3,"file":"SpecifyLearnerField.js","sourceRoot":"","sources":["../../src/components/SpecifyLearnerField.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState, ChangeEvent, useImperativeHandle, forwardRef } from 'react';\nimport { isAxiosError } from 'axios';\nimport { useParams } from 'react-router-dom';\nimport { Avatar, Button, FormControl, FormGroup, FormLabel, useToggle } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport { SpinnerIcon } from '@openedx/paragon/icons';\nimport { useDebouncedFilter } from '@src/hooks/useDebouncedFilter';\nimport { useCourseInfo, useLearner } from '@src/data/apiHook';\nimport { SelectedLearner } from '@src/types';\nimport messages from './messages';\n\ninterface SpecifyLearnerFieldProps {\n learner?: SelectedLearner,\n onClickSelect: (emailOrUsername: string) => void,\n}\n\ninterface SpecifyLearnerFieldRef {\n reset: () => void,\n}\n\nconst initialLearnerState = {\n username: '',\n fullName: '',\n email: '',\n isEnrolled: false,\n};\n\nconst SpecifyLearnerField = forwardRef<SpecifyLearnerFieldRef, SpecifyLearnerFieldProps>(({ learner, onClickSelect }, ref) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [identifier, setIdentifier] = useState('');\n const [showLearner, enableShowLearner, disableShowLearner] = useToggle(!!learner);\n const { data: courseInfo } = useCourseInfo(courseId);\n const permissions = courseInfo?.permissions || { admin: false, dataResearcher: false };\n const { inputValue, handleChange, resetFilter } = useDebouncedFilter({\n filterValue: identifier,\n setFilter: setIdentifier,\n });\n const { data, refetch, error } = useLearner(courseId, inputValue);\n\n const resetState = () => {\n resetFilter();\n onClickSelect('');\n disableShowLearner();\n };\n\n useImperativeHandle(ref, () => ({\n reset: resetState,\n }));\n\n const selectedLearner = learner || data || initialLearnerState;\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n handleChange(event.target.value);\n\n if (showLearner) {\n disableShowLearner();\n }\n };\n\n const handleClickSelect = () => {\n if (inputValue) {\n refetch().then((result) => {\n // Need to pass empty value if learner is not valid to clear out any previously selected learner\n // We could have other conditions/fields depending on valid learner\n const formValue = !result.error && result.data?.isEnrolled ? inputValue : '';\n onClickSelect(formValue);\n enableShowLearner();\n });\n }\n };\n\n return (\n <FormGroup className=\"mb-0\" size=\"sm\">\n <FormLabel className=\"text-primary-500 d-flex\">{selectedLearner.username ? intl.formatMessage(messages.selectedLearner) : intl.formatMessage(messages.specifyLearner)}</FormLabel>\n <div className=\"d-flex align-items-center\">\n <FormControl\n className={`mr-2 ${selectedLearner.username && showLearner ? 'd-none' : ''}`}\n name=\"emailOrUsername\"\n placeholder={intl.formatMessage(messages.specifyLearnerPlaceholder)}\n size=\"md\"\n autoResize\n value={inputValue}\n onChange={handleInputChange}\n />\n {selectedLearner.username && showLearner ? (\n <>\n <Avatar className=\"mr-2.5\" size=\"sm\" />\n <div className=\"d-flex flex-column mr-3 text-primary-500\">\n <p className=\"mb-0\">{selectedLearner.username}</p>\n {(permissions.admin || permissions.dataResearcher)\n && (\n <div className=\"d-flex x-small\">\n <p className=\"mr-3 mb-0\">{selectedLearner.fullName}</p>\n <p className=\"mb-0\">{selectedLearner.email}</p>\n </div>\n )}\n </div>\n {!learner && <Button iconBefore={SpinnerIcon} onClick={resetState}>{intl.formatMessage(messages.change)}</Button>}\n </>\n ) : (\n <Button onClick={handleClickSelect} disabled={!inputValue}>{intl.formatMessage(messages.select)}</Button>\n )}\n </div>\n {showLearner && error\n && isAxiosError(error)\n && error.response?.status === 404 && (\n <p className=\"text-danger-500 mb-0 x-small mt-2\">\n {intl.formatMessage(messages.learnerNotFound, { identifier })}\n </p>\n )}\n {\n showLearner && !error && !selectedLearner?.isEnrolled && (\n <p className=\"text-danger-500 mb-0 x-small mt-2\">\n {intl.formatMessage(messages.learnerNotEnrolled, { identifier })}\n </p>\n )\n }\n </FormGroup>\n );\n});\n\nSpecifyLearnerField.displayName = 'SpecifyLearnerField';\n\nexport default SpecifyLearnerField;\n"]}
@@ -0,0 +1,13 @@
1
+ interface SpecifyProblemFieldProps {
2
+ buttonLabel: string;
3
+ disabled?: boolean;
4
+ fieldLabel: string;
5
+ problemResponsesError?: string;
6
+ usernameOrEmail?: string;
7
+ onClickSelect: (problemLocation: string, event: React.MouseEvent<HTMLButtonElement>) => void;
8
+ }
9
+ interface SpecifyProblemFieldRef {
10
+ reset: () => void;
11
+ }
12
+ declare const SpecifyProblemField: import("react").ForwardRefExoticComponent<SpecifyProblemFieldProps & import("react").RefAttributes<SpecifyProblemFieldRef>>;
13
+ export default SpecifyProblemField;
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useImperativeHandle, forwardRef } from 'react';
3
+ import { isAxiosError } from 'axios';
4
+ import { useParams } from 'react-router-dom';
5
+ import { Button, Form, Icon, OverlayTrigger, Tooltip, useToggle } from '@openedx/paragon';
6
+ import { InfoOutline, SpinnerIcon } from '@openedx/paragon/icons';
7
+ import { useIntl } from '@openedx/frontend-base';
8
+ import messages from './messages';
9
+ import { useDebouncedFilter } from '../hooks/useDebouncedFilter';
10
+ import { useProblemDetails } from '../data/apiHook';
11
+ const SpecifyProblemField = forwardRef(({ buttonLabel, disabled, fieldLabel, problemResponsesError, usernameOrEmail = '', onClickSelect, }, ref) => {
12
+ var _a;
13
+ const intl = useIntl();
14
+ const { courseId = '' } = useParams();
15
+ const [problemLocation, setProblemLocation] = useState('');
16
+ const [showSelectedLocation, enableShowSelectedLocation, disableShowSelectedLocation] = useToggle(false);
17
+ const { inputValue, handleChange, resetFilter } = useDebouncedFilter({
18
+ filterValue: problemLocation,
19
+ setFilter: setProblemLocation,
20
+ });
21
+ const { data = { breadcrumbs: [], name: '', id: '' }, refetch, error } = useProblemDetails(courseId, inputValue, usernameOrEmail);
22
+ useImperativeHandle(ref, () => ({
23
+ reset: () => {
24
+ resetFilter();
25
+ disableShowSelectedLocation();
26
+ }
27
+ }));
28
+ const handleInputChange = (e) => {
29
+ handleChange(e.target.value);
30
+ if (showSelectedLocation) {
31
+ disableShowSelectedLocation();
32
+ }
33
+ };
34
+ const handleClick = (event) => {
35
+ if (inputValue) {
36
+ refetch().then(() => {
37
+ onClickSelect(inputValue, event);
38
+ enableShowSelectedLocation();
39
+ });
40
+ }
41
+ };
42
+ return (_jsxs(Form.Group, { className: "mb-0", isInvalid: !!problemResponsesError, size: "sm", children: [_jsx(Form.Label, { className: "d-flex align-content-end align-items-center gap-2 text-primary-500", children: showSelectedLocation ? intl.formatMessage(messages.selectedProblem)
43
+ : (_jsxs(_Fragment, { children: [fieldLabel, _jsx(OverlayTrigger, { placement: "top", overlay: (_jsx(Tooltip, { id: "problem-location-tooltip", className: "info-tooltip", children: intl.formatMessage(messages.problemLocationTooltip) })), children: _jsx(Icon, { src: InfoOutline, size: "sm", "aria-label": intl.formatMessage(messages.problemLocationInfoIconLabel) }) })] })) }), _jsx("div", { className: "d-flex align-items-center", children: showSelectedLocation && data && !error ? (_jsxs("div", { className: "d-flex gap-3 align-items-center col-8 p-0", children: [_jsxs("div", { className: "d-block w-100", children: [_jsx("p", { className: "x-small mb-0 text-primary-500 text-truncate", children: data.breadcrumbs
44
+ .slice(1, -1)
45
+ .map(breadcrumb => breadcrumb.displayName)
46
+ .join(' > ') }), _jsx("p", { className: "text-primary-500 mb-0", children: data.name }), _jsx("p", { className: "x-small text-gray-700 text-truncate mb-0", children: data.id })] }), _jsx(Button, { iconBefore: SpinnerIcon, onClick: disableShowSelectedLocation, children: intl.formatMessage(messages.change) })] })) : (_jsxs(_Fragment, { children: [_jsx(Form.Control, { type: "text", placeholder: intl.formatMessage(messages.problemLocationPlaceholder), value: inputValue, onChange: handleInputChange, className: "flex-grow-1", size: "md" }), problemResponsesError && (_jsx(Form.Control.Feedback, { type: "invalid", children: problemResponsesError })), _jsx(Button, { variant: "primary", onClick: handleClick, disabled: disabled || !inputValue, className: "text-nowrap", children: buttonLabel })] })) }), showSelectedLocation && error
47
+ && isAxiosError(error)
48
+ && (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 400) && (_jsx("p", { className: "text-danger-500 mb-0 x-small mt-2", children: intl.formatMessage(messages.problemNotFound, { identifier: inputValue }) }))] }));
49
+ });
50
+ SpecifyProblemField.displayName = 'SpecifyProblemField';
51
+ export default SpecifyProblemField;
52
+ //# sourceMappingURL=SpecifyProblemField.js.map