@openedx/frontend-app-instructor-dashboard 1.0.0-alpha.33 → 1.0.0-alpha.35

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 (53) hide show
  1. package/dist/certificates/CertificatesPage.js +34 -8
  2. package/dist/certificates/CertificatesPage.js.map +1 -1
  3. package/dist/certificates/components/CertificatesPageHeader.d.ts +2 -2
  4. package/dist/certificates/components/CertificatesPageHeader.js +3 -3
  5. package/dist/certificates/components/CertificatesPageHeader.js.map +1 -1
  6. package/dist/certificates/components/DisableCertificatesModal.js +16 -8
  7. package/dist/certificates/components/DisableCertificatesModal.js.map +1 -1
  8. package/dist/certificates/components/GrantExceptionsModal.d.ts +2 -1
  9. package/dist/certificates/components/GrantExceptionsModal.js +49 -4
  10. package/dist/certificates/components/GrantExceptionsModal.js.map +1 -1
  11. package/dist/certificates/components/InvalidateCertificateModal.js +19 -3
  12. package/dist/certificates/components/InvalidateCertificateModal.js.map +1 -1
  13. package/dist/certificates/data/api.d.ts +7 -0
  14. package/dist/certificates/data/api.js +10 -0
  15. package/dist/certificates/data/api.js.map +1 -1
  16. package/dist/certificates/data/apiHook.d.ts +10 -0
  17. package/dist/certificates/data/apiHook.js +16 -1
  18. package/dist/certificates/data/apiHook.js.map +1 -1
  19. package/dist/certificates/messages.d.ts +100 -0
  20. package/dist/certificates/messages.js +104 -4
  21. package/dist/certificates/messages.js.map +1 -1
  22. package/dist/components/SpecifyLearnerField.js +25 -5
  23. package/dist/components/SpecifyLearnerField.js.map +1 -1
  24. package/dist/components/SpecifyProblemField.js +2 -2
  25. package/dist/components/SpecifyProblemField.js.map +1 -1
  26. package/dist/components/messages.d.ts +5 -0
  27. package/dist/components/messages.js +5 -0
  28. package/dist/components/messages.js.map +1 -1
  29. package/dist/enrollments/components/UpdateBetaTesterModal.js +9 -1
  30. package/dist/enrollments/components/UpdateBetaTesterModal.js.map +1 -1
  31. package/dist/grading/components/GradingLearnerContent.js +4 -0
  32. package/dist/grading/components/GradingLearnerContent.js.map +1 -1
  33. package/dist/slots/CourseInfoSlot/CourseInfoSlot.d.ts +2 -0
  34. package/dist/slots/CourseInfoSlot/CourseInfoSlot.js +14 -0
  35. package/dist/slots/CourseInfoSlot/CourseInfoSlot.js.map +1 -0
  36. package/dist/slots.js +9 -1
  37. package/dist/slots.js.map +1 -1
  38. package/dist/specialExams/components/AllowancesList.js +9 -4
  39. package/dist/specialExams/components/AllowancesList.js.map +1 -1
  40. package/dist/specialExams/components/AttemptsList.js +9 -4
  41. package/dist/specialExams/components/AttemptsList.js.map +1 -1
  42. package/dist/specialExams/components/EditAllowanceModal.js +1 -1
  43. package/dist/specialExams/components/EditAllowanceModal.js.map +1 -1
  44. package/dist/specialExams/data/api.js +6 -0
  45. package/dist/specialExams/data/api.js.map +1 -1
  46. package/dist/specialExams/data/queryKeys.d.ts +2 -2
  47. package/dist/specialExams/data/queryKeys.js +2 -2
  48. package/dist/specialExams/data/queryKeys.js.map +1 -1
  49. package/dist/specialExams/types.d.ts +1 -0
  50. package/dist/specialExams/types.js.map +1 -1
  51. package/dist/types/index.d.ts +4 -0
  52. package/dist/types/index.js.map +1 -1
  53. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/certificates/data/api.ts"],"names":[],"mappings":"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","sourcesContent":["import { camelCaseObject, getAuthenticatedHttpClient } from '@openedx/frontend-base';\nimport { getApiBaseUrl } from '@src/data/api';\nimport type { DataList, PaginationParams } from '@src/types';\nimport type {\n CertificateData,\n CertificateGenerationHistory,\n CertificateQueryParams,\n GrantExceptionRequest,\n InstructorTask,\n InvalidateCertificateRequest,\n RemoveExceptionRequest,\n RemoveInvalidationRequest,\n} from '@src/certificates/types';\n\nexport const getIssuedCertificates = async (\n courseId: string,\n params: CertificateQueryParams,\n): Promise<DataList<CertificateData>> => {\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/issued`,\n {\n params: {\n page: params.page + 1,\n page_size: params.pageSize,\n filter: params.filter,\n search: params.search,\n },\n },\n );\n return camelCaseObject(data);\n};\n\nexport const getInstructorTasks = async (\n courseId: string,\n params: PaginationParams,\n): Promise<DataList<InstructorTask>> => {\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/instructor_tasks`,\n {\n params: {\n page: params.page + 1,\n page_size: params.pageSize,\n },\n },\n );\n return camelCaseObject(data);\n};\n\nexport const grantBulkExceptions = async (\n courseId: string,\n request: GrantExceptionRequest,\n): Promise<{ success: string[], errors: { learner: string, message: string }[] }> => {\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/exceptions`,\n {\n learners: request.learners,\n notes: request.notes,\n },\n );\n return camelCaseObject(data);\n};\n\nexport const invalidateCertificate = async (\n courseId: string,\n request: InvalidateCertificateRequest,\n): Promise<{ success: string[], errors: { learner: string, message: string }[] }> => {\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/invalidations`,\n {\n learners: request.learners,\n notes: request.notes,\n },\n );\n return camelCaseObject(data);\n};\n\nexport const removeException = async (\n courseId: string,\n request: RemoveExceptionRequest,\n): Promise<void> => {\n await getAuthenticatedHttpClient().delete(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/exceptions`,\n {\n data: {\n username: request.username,\n },\n },\n );\n};\n\nexport const removeInvalidation = async (\n courseId: string,\n request: RemoveInvalidationRequest,\n): Promise<void> => {\n const httpClient = getAuthenticatedHttpClient();\n const url = `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/invalidations`;\n const payload = {\n username: request.username,\n };\n\n await httpClient.delete(url, {\n data: payload,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n};\n\nexport const toggleCertificateGeneration = async (\n courseId: string,\n enable: boolean,\n): Promise<void> => {\n await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/toggle_generation`,\n {\n enabled: enable,\n },\n );\n};\n\nexport const regenerateCertificates = async (\n courseId: string,\n filter: string,\n): Promise<void> => {\n const body: { statuses?: string[], student_set?: string } = {};\n\n // Map filter to backend parameters (must match backend filter logic)\n switch (filter) {\n case 'all':\n body.student_set = 'all';\n break;\n case 'received':\n body.statuses = ['downloadable'];\n break;\n case 'not_received':\n // Match backend filter: notpassing or unavailable\n body.statuses = ['notpassing', 'unavailable'];\n break;\n case 'audit_passing':\n body.statuses = ['audit_passing'];\n break;\n case 'audit_not_passing':\n body.statuses = ['audit_notpassing'];\n break;\n case 'error':\n body.statuses = ['error'];\n break;\n case 'granted_exceptions':\n body.student_set = 'allowlisted';\n break;\n case 'invalidated':\n // Invalidated certificates have unavailable status\n body.statuses = ['unavailable'];\n break;\n default:\n body.student_set = 'all';\n }\n\n await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/regenerate`,\n body,\n );\n};\n\nexport const getCertificateGenerationHistory = async (\n courseId: string,\n params: PaginationParams,\n): Promise<DataList<CertificateGenerationHistory>> => {\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/generation_history`,\n {\n params: {\n page: params.page + 1,\n page_size: params.pageSize,\n },\n },\n );\n return camelCaseObject(data);\n};\n"]}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/certificates/data/api.ts"],"names":[],"mappings":"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","sourcesContent":["import { camelCaseObject, getAuthenticatedHttpClient } from '@openedx/frontend-base';\nimport { getApiBaseUrl } from '@src/data/api';\nimport type { DataList, PaginationParams } from '@src/types';\nimport type {\n CertificateData,\n CertificateGenerationHistory,\n CertificateQueryParams,\n GrantExceptionRequest,\n InstructorTask,\n InvalidateCertificateRequest,\n RemoveExceptionRequest,\n RemoveInvalidationRequest,\n} from '@src/certificates/types';\n\nexport const getIssuedCertificates = async (\n courseId: string,\n params: CertificateQueryParams,\n): Promise<DataList<CertificateData>> => {\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/issued`,\n {\n params: {\n page: params.page + 1,\n page_size: params.pageSize,\n filter: params.filter,\n search: params.search,\n },\n },\n );\n return camelCaseObject(data);\n};\n\nexport const getInstructorTasks = async (\n courseId: string,\n params: PaginationParams,\n): Promise<DataList<InstructorTask>> => {\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/instructor_tasks`,\n {\n params: {\n page: params.page + 1,\n page_size: params.pageSize,\n },\n },\n );\n return camelCaseObject(data);\n};\n\nexport const grantBulkExceptions = async (\n courseId: string,\n request: GrantExceptionRequest,\n): Promise<{ success: string[], errors: { learner: string, message: string }[] }> => {\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/exceptions`,\n {\n learners: request.learners,\n notes: request.notes,\n },\n );\n return camelCaseObject(data);\n};\n\nexport const uploadBulkExceptionsCsv = async (\n courseId: string,\n file: File,\n): Promise<{ success: string[], errors: { learner: string, message: string }[] }> => {\n const formData = new FormData();\n formData.append('file', file);\n\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/exceptions/bulk`,\n formData,\n {\n headers: {\n 'Content-Type': 'multipart/form-data',\n },\n },\n );\n return camelCaseObject(data);\n};\n\nexport const invalidateCertificate = async (\n courseId: string,\n request: InvalidateCertificateRequest,\n): Promise<{ success: string[], errors: { learner: string, message: string }[] }> => {\n const { data } = await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/invalidations`,\n {\n learners: request.learners,\n notes: request.notes,\n },\n );\n return camelCaseObject(data);\n};\n\nexport const removeException = async (\n courseId: string,\n request: RemoveExceptionRequest,\n): Promise<void> => {\n await getAuthenticatedHttpClient().delete(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/exceptions`,\n {\n data: {\n username: request.username,\n },\n },\n );\n};\n\nexport const removeInvalidation = async (\n courseId: string,\n request: RemoveInvalidationRequest,\n): Promise<void> => {\n const httpClient = getAuthenticatedHttpClient();\n const url = `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/invalidations`;\n const payload = {\n username: request.username,\n };\n\n await httpClient.delete(url, {\n data: payload,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n};\n\nexport const toggleCertificateGeneration = async (\n courseId: string,\n enable: boolean,\n): Promise<void> => {\n await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/toggle_generation`,\n {\n enabled: enable,\n },\n );\n};\n\nexport const regenerateCertificates = async (\n courseId: string,\n filter: string,\n): Promise<void> => {\n const body: { statuses?: string[], student_set?: string } = {};\n\n // Map filter to backend parameters (must match backend filter logic)\n switch (filter) {\n case 'all':\n body.student_set = 'all';\n break;\n case 'received':\n body.statuses = ['downloadable'];\n break;\n case 'not_received':\n // Match backend filter: notpassing or unavailable\n body.statuses = ['notpassing', 'unavailable'];\n break;\n case 'audit_passing':\n body.statuses = ['audit_passing'];\n break;\n case 'audit_not_passing':\n body.statuses = ['audit_notpassing'];\n break;\n case 'error':\n body.statuses = ['error'];\n break;\n case 'granted_exceptions':\n body.student_set = 'allowlisted';\n break;\n case 'invalidated':\n // Invalidated certificates have unavailable status\n body.statuses = ['unavailable'];\n break;\n default:\n body.student_set = 'all';\n }\n\n await getAuthenticatedHttpClient().post(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/regenerate`,\n body,\n );\n};\n\nexport const getCertificateGenerationHistory = async (\n courseId: string,\n params: PaginationParams,\n): Promise<DataList<CertificateGenerationHistory>> => {\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/certificates/generation_history`,\n {\n params: {\n page: params.page + 1,\n page_size: params.pageSize,\n },\n },\n );\n return camelCaseObject(data);\n};\n"]}
@@ -22,6 +22,16 @@ export declare const useGrantBulkExceptions: (courseId: string) => import("@tans
22
22
  message: string;
23
23
  }[];
24
24
  }, Error, GrantExceptionRequest, unknown>;
25
+ /**
26
+ * Hook to upload bulk certificate exceptions via CSV
27
+ */
28
+ export declare const useUploadBulkExceptionsCsv: (courseId: string) => import("@tanstack/react-query").UseMutationResult<{
29
+ success: string[];
30
+ errors: {
31
+ learner: string;
32
+ message: string;
33
+ }[];
34
+ }, Error, File, unknown>;
25
35
  /**
26
36
  * Hook to invalidate certificate
27
37
  */
@@ -1,5 +1,5 @@
1
1
  import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
2
- import { getCertificateGenerationHistory, getInstructorTasks, getIssuedCertificates, grantBulkExceptions, invalidateCertificate, regenerateCertificates, removeException, removeInvalidation, toggleCertificateGeneration, } from '../../certificates/data/api';
2
+ import { getCertificateGenerationHistory, getInstructorTasks, getIssuedCertificates, grantBulkExceptions, invalidateCertificate, regenerateCertificates, removeException, removeInvalidation, toggleCertificateGeneration, uploadBulkExceptionsCsv, } from '../../certificates/data/api';
3
3
  import { certificatesQueryKeys } from '../../certificates/data/queryKeys';
4
4
  /**
5
5
  * Hook to fetch issued certificates
@@ -40,6 +40,21 @@ export const useGrantBulkExceptions = (courseId) => {
40
40
  },
41
41
  });
42
42
  };
43
+ /**
44
+ * Hook to upload bulk certificate exceptions via CSV
45
+ */
46
+ export const useUploadBulkExceptionsCsv = (courseId) => {
47
+ const queryClient = useQueryClient();
48
+ return useMutation({
49
+ mutationFn: (file) => uploadBulkExceptionsCsv(courseId, file),
50
+ onSuccess: () => {
51
+ queryClient.invalidateQueries({
52
+ queryKey: certificatesQueryKeys.byCourse(courseId),
53
+ exact: false,
54
+ });
55
+ },
56
+ });
57
+ };
43
58
  /**
44
59
  * Hook to invalidate certificate
45
60
  */
@@ -1 +1 @@
1
- {"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/certificates/data/apiHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAS9E,OAAO,EACL,+BAA+B,EAC/B,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAEzE;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,QAAgB,EAAE,MAA8B,EAAE,EAAE,CACxF,QAAQ,CAAC;IACP,QAAQ,EAAE,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC;IACxD,OAAO,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC;IACtD,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CAAC;AAEL;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAAgB,EAAE,MAAwB,EAAE,EAAE,CAC/E,QAAQ,CAAC;IACP,QAAQ,EAAE,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC;IACvD,OAAO,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC;IACnD,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CAAC;AAEL;;GAEG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,QAAgB,EAAE,MAAwB,EAAE,EAAE,CAC5F,QAAQ,CAAC;IACP,QAAQ,EAAE,qBAAqB,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC;IACnE,OAAO,EAAE,GAAG,EAAE,CAAC,+BAA+B,CAAC,QAAQ,EAAE,MAAM,CAAC;IAChE,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CAAC;AAEL;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACzD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,CAAC,OAA8B,EAAE,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC;QACtF,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC;gBAC5B,QAAQ,EAAE,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAClD,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,QAAgB,EAAE,EAAE;IAC3D,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,CAAC,OAAqC,EAAE,EAAE,CAAC,qBAAqB,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC/F,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC;gBAC5B,QAAQ,EAAE,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAClD,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACrD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,CAAC,OAA+B,EAAE,EAAE,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC;QACnF,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC;gBAC5B,QAAQ,EAAE,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAClD,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACxD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,CAAC,OAAkC,EAAE,EAAE,CAAC,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC;QACzF,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC;gBAC5B,QAAQ,EAAE,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAClD,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,QAAgB,EAAE,EAAE;IACjE,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,CAAC,MAAe,EAAE,EAAE,CAAC,2BAA2B,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC9E,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC;gBAC5B,QAAQ,EAAE,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAClD,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,QAAgB,EAAE,EAAE;IAC5D,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,UAAU,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,sBAAsB,CAAC,QAAQ,EAAE,MAAM,CAAC;QACxE,SAAS,EAAE,GAAG,EAAE;YACd,WAAW,CAAC,iBAAiB,CAAC;gBAC5B,QAAQ,EAAE,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAClD,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport type { PaginationParams } from '@src/types';\nimport type {\n CertificateQueryParams,\n GrantExceptionRequest,\n InvalidateCertificateRequest,\n RemoveExceptionRequest,\n RemoveInvalidationRequest,\n} from '@src/certificates/types';\nimport {\n getCertificateGenerationHistory,\n getInstructorTasks,\n getIssuedCertificates,\n grantBulkExceptions,\n invalidateCertificate,\n regenerateCertificates,\n removeException,\n removeInvalidation,\n toggleCertificateGeneration,\n} from '@src/certificates/data/api';\nimport { certificatesQueryKeys } from '@src/certificates/data/queryKeys';\n\n/**\n * Hook to fetch issued certificates\n */\nexport const useIssuedCertificates = (courseId: string, params: CertificateQueryParams) =>\n useQuery({\n queryKey: certificatesQueryKeys.issued(courseId, params),\n queryFn: () => getIssuedCertificates(courseId, params),\n enabled: !!courseId,\n });\n\n/**\n * Hook to fetch instructor tasks\n */\nexport const useInstructorTasks = (courseId: string, params: PaginationParams) =>\n useQuery({\n queryKey: certificatesQueryKeys.tasks(courseId, params),\n queryFn: () => getInstructorTasks(courseId, params),\n enabled: !!courseId,\n });\n\n/**\n * Hook to fetch certificate generation history\n */\nexport const useCertificateGenerationHistory = (courseId: string, params: PaginationParams) =>\n useQuery({\n queryKey: certificatesQueryKeys.generationHistory(courseId, params),\n queryFn: () => getCertificateGenerationHistory(courseId, params),\n enabled: !!courseId,\n });\n\n/**\n * Hook to grant bulk certificate exceptions\n */\nexport const useGrantBulkExceptions = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (request: GrantExceptionRequest) => grantBulkExceptions(courseId, request),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n\n/**\n * Hook to invalidate certificate\n */\nexport const useInvalidateCertificate = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (request: InvalidateCertificateRequest) => invalidateCertificate(courseId, request),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n\n/**\n * Hook to remove certificate exception\n */\nexport const useRemoveException = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (request: RemoveExceptionRequest) => removeException(courseId, request),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n\n/**\n * Hook to remove certificate invalidation\n */\nexport const useRemoveInvalidation = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (request: RemoveInvalidationRequest) => removeInvalidation(courseId, request),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n\n/**\n * Hook to toggle certificate generation\n */\nexport const useToggleCertificateGeneration = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (enable: boolean) => toggleCertificateGeneration(courseId, enable),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n\n/**\n * Hook to regenerate certificates\n */\nexport const useRegenerateCertificates = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (filter: string) => regenerateCertificates(courseId, filter),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n"]}
1
+ {"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/certificates/data/apiHook.ts"],"names":[],"mappings":"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","sourcesContent":["import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport type { PaginationParams } from '@src/types';\nimport type {\n CertificateQueryParams,\n GrantExceptionRequest,\n InvalidateCertificateRequest,\n RemoveExceptionRequest,\n RemoveInvalidationRequest,\n} from '@src/certificates/types';\nimport {\n getCertificateGenerationHistory,\n getInstructorTasks,\n getIssuedCertificates,\n grantBulkExceptions,\n invalidateCertificate,\n regenerateCertificates,\n removeException,\n removeInvalidation,\n toggleCertificateGeneration,\n uploadBulkExceptionsCsv,\n} from '@src/certificates/data/api';\nimport { certificatesQueryKeys } from '@src/certificates/data/queryKeys';\n\n/**\n * Hook to fetch issued certificates\n */\nexport const useIssuedCertificates = (courseId: string, params: CertificateQueryParams) =>\n useQuery({\n queryKey: certificatesQueryKeys.issued(courseId, params),\n queryFn: () => getIssuedCertificates(courseId, params),\n enabled: !!courseId,\n });\n\n/**\n * Hook to fetch instructor tasks\n */\nexport const useInstructorTasks = (courseId: string, params: PaginationParams) =>\n useQuery({\n queryKey: certificatesQueryKeys.tasks(courseId, params),\n queryFn: () => getInstructorTasks(courseId, params),\n enabled: !!courseId,\n });\n\n/**\n * Hook to fetch certificate generation history\n */\nexport const useCertificateGenerationHistory = (courseId: string, params: PaginationParams) =>\n useQuery({\n queryKey: certificatesQueryKeys.generationHistory(courseId, params),\n queryFn: () => getCertificateGenerationHistory(courseId, params),\n enabled: !!courseId,\n });\n\n/**\n * Hook to grant bulk certificate exceptions\n */\nexport const useGrantBulkExceptions = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (request: GrantExceptionRequest) => grantBulkExceptions(courseId, request),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n\n/**\n * Hook to upload bulk certificate exceptions via CSV\n */\nexport const useUploadBulkExceptionsCsv = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (file: File) => uploadBulkExceptionsCsv(courseId, file),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n\n/**\n * Hook to invalidate certificate\n */\nexport const useInvalidateCertificate = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (request: InvalidateCertificateRequest) => invalidateCertificate(courseId, request),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n\n/**\n * Hook to remove certificate exception\n */\nexport const useRemoveException = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (request: RemoveExceptionRequest) => removeException(courseId, request),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n\n/**\n * Hook to remove certificate invalidation\n */\nexport const useRemoveInvalidation = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (request: RemoveInvalidationRequest) => removeInvalidation(courseId, request),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n\n/**\n * Hook to toggle certificate generation\n */\nexport const useToggleCertificateGeneration = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (enable: boolean) => toggleCertificateGeneration(courseId, enable),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n\n/**\n * Hook to regenerate certificates\n */\nexport const useRegenerateCertificates = (courseId: string) => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (filter: string) => regenerateCertificates(courseId, filter),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: certificatesQueryKeys.byCourse(courseId),\n exact: false,\n });\n },\n });\n};\n"]}
@@ -249,6 +249,96 @@ declare const messages: {
249
249
  defaultMessage: string;
250
250
  description: string;
251
251
  };
252
+ learnerLabel: {
253
+ id: string;
254
+ defaultMessage: string;
255
+ description: string;
256
+ };
257
+ learnerPlaceholder: {
258
+ id: string;
259
+ defaultMessage: string;
260
+ description: string;
261
+ };
262
+ bulkUploadTab: {
263
+ id: string;
264
+ defaultMessage: string;
265
+ description: string;
266
+ };
267
+ singleLearnerTab: {
268
+ id: string;
269
+ defaultMessage: string;
270
+ description: string;
271
+ };
272
+ csvFileLabel: {
273
+ id: string;
274
+ defaultMessage: string;
275
+ description: string;
276
+ };
277
+ csvInstructions: {
278
+ id: string;
279
+ defaultMessage: string;
280
+ description: string;
281
+ };
282
+ csvInstructionsTooltip: {
283
+ id: string;
284
+ defaultMessage: string;
285
+ description: string;
286
+ };
287
+ csvFileSelected: {
288
+ id: string;
289
+ defaultMessage: string;
290
+ description: string;
291
+ };
292
+ csvUploadPending: {
293
+ id: string;
294
+ defaultMessage: string;
295
+ description: string;
296
+ };
297
+ studentGeneratedCertificatesMenuItem: {
298
+ id: string;
299
+ defaultMessage: string;
300
+ description: string;
301
+ };
302
+ moreActionsButton: {
303
+ id: string;
304
+ defaultMessage: string;
305
+ description: string;
306
+ };
307
+ studentGeneratedCertificatesModalTitle: {
308
+ id: string;
309
+ defaultMessage: string;
310
+ description: string;
311
+ };
312
+ enableStudentGeneratedCertificates: {
313
+ id: string;
314
+ defaultMessage: string;
315
+ description: string;
316
+ };
317
+ studentGeneratedCertificatesDescription: {
318
+ id: string;
319
+ defaultMessage: string;
320
+ description: string;
321
+ };
322
+ close: {
323
+ id: string;
324
+ defaultMessage: string;
325
+ description: string;
326
+ };
327
+ studentEmailUsername: {
328
+ id: string;
329
+ defaultMessage: string;
330
+ description: string;
331
+ };
332
+ notesOptional: {
333
+ id: string;
334
+ defaultMessage: string;
335
+ description: string;
336
+ };
337
+ individualTabDescription: {
338
+ id: string;
339
+ defaultMessage: string;
340
+ description: string;
341
+ };
252
342
  cancel: {
253
343
  id: string;
254
344
  defaultMessage: string;
@@ -264,6 +354,11 @@ declare const messages: {
264
354
  defaultMessage: string;
265
355
  description: string;
266
356
  };
357
+ save: {
358
+ id: string;
359
+ defaultMessage: string;
360
+ description: string;
361
+ };
267
362
  columnTaskName: {
268
363
  id: string;
269
364
  defaultMessage: string;
@@ -339,5 +434,10 @@ declare const messages: {
339
434
  defaultMessage: string;
340
435
  description: string;
341
436
  };
437
+ errorModalTitle: {
438
+ id: string;
439
+ defaultMessage: string;
440
+ description: string;
441
+ };
342
442
  };
343
443
  export default messages;
@@ -172,22 +172,22 @@ const messages = defineMessages({
172
172
  },
173
173
  grantExceptionsModalTitle: {
174
174
  id: 'instruct.certificates.grantExceptionsModalTitle',
175
- defaultMessage: 'Grant Certificate Exceptions',
175
+ defaultMessage: 'Add to Exceptions List',
176
176
  description: 'Title for grant exceptions modal',
177
177
  },
178
178
  grantExceptionsModalDescription: {
179
179
  id: 'instruct.certificates.grantExceptionsModalDescription',
180
- defaultMessage: 'Enter usernames or emails, or upload a CSV file to grant certificate exceptions.',
180
+ defaultMessage: 'Set exceptions to generate certificates for learners who did not qualify for a certificate but have been given an exception by the course team. After you add learners to the exception list, you must Generate Exception Certificates.',
181
181
  description: 'Description for grant exceptions modal',
182
182
  },
183
183
  invalidateCertificateModalTitle: {
184
184
  id: 'instruct.certificates.invalidateCertificateModalTitle',
185
- defaultMessage: 'Invalidate Certificates',
185
+ defaultMessage: 'Invalidate Certificate',
186
186
  description: 'Title for invalidate certificate modal',
187
187
  },
188
188
  invalidateCertificateModalDescription: {
189
189
  id: 'instruct.certificates.invalidateCertificateModalDescription',
190
- defaultMessage: 'Enter usernames or emails, or upload a CSV file to invalidate certificates.',
190
+ defaultMessage: 'Enter username or email to invalidate a certificate.',
191
191
  description: 'Description for invalidate certificate modal',
192
192
  },
193
193
  removeExceptionModalTitle: {
@@ -250,6 +250,96 @@ const messages = defineMessages({
250
250
  defaultMessage: 'Enter usernames or emails (one per line)',
251
251
  description: 'Placeholder for learners field',
252
252
  },
253
+ learnerLabel: {
254
+ id: 'instruct.certificates.learnerLabel',
255
+ defaultMessage: 'Username or Email',
256
+ description: 'Label for single learner field',
257
+ },
258
+ learnerPlaceholder: {
259
+ id: 'instruct.certificates.learnerPlaceholder',
260
+ defaultMessage: 'Enter username or email',
261
+ description: 'Placeholder for single learner field',
262
+ },
263
+ bulkUploadTab: {
264
+ id: 'instruct.certificates.bulkUploadTab',
265
+ defaultMessage: 'Bulk',
266
+ description: 'Tab label for bulk CSV upload',
267
+ },
268
+ singleLearnerTab: {
269
+ id: 'instruct.certificates.singleLearnerTab',
270
+ defaultMessage: 'Individual',
271
+ description: 'Tab label for single learner input',
272
+ },
273
+ csvFileLabel: {
274
+ id: 'instruct.certificates.csvFileLabel',
275
+ defaultMessage: 'Upload CSV',
276
+ description: 'Label for CSV file upload',
277
+ },
278
+ csvInstructions: {
279
+ id: 'instruct.certificates.csvInstructions',
280
+ defaultMessage: 'CSV Instructions',
281
+ description: 'Link text for CSV instructions',
282
+ },
283
+ csvInstructionsTooltip: {
284
+ id: 'instruct.certificates.csvInstructionsTooltip',
285
+ defaultMessage: 'CSV file should contain the usernames or email addresses of learners who will receive exceptions. Include the username or email address in the first comma separated field. You can include an optional note describing the reason for the exception in the second comma separated field.',
286
+ description: 'Tooltip text for CSV instructions',
287
+ },
288
+ csvFileSelected: {
289
+ id: 'instruct.certificates.csvFileSelected',
290
+ defaultMessage: 'File selected: {fileName}',
291
+ description: 'Message shown when CSV file is selected',
292
+ },
293
+ csvUploadPending: {
294
+ id: 'instruct.certificates.csvUploadPending',
295
+ defaultMessage: 'CSV file "{fileName}" is ready. Bulk upload will be processed when the backend API is available.',
296
+ description: 'Message shown when CSV upload is pending backend implementation',
297
+ },
298
+ studentGeneratedCertificatesMenuItem: {
299
+ id: 'instruct.certificates.studentGeneratedCertificatesMenuItem',
300
+ defaultMessage: 'Student Generated Certificates',
301
+ description: 'Menu item for student generated certificates',
302
+ },
303
+ moreActionsButton: {
304
+ id: 'instruct.certificates.moreActionsButton',
305
+ defaultMessage: 'More actions',
306
+ description: 'Button for more actions menu',
307
+ },
308
+ studentGeneratedCertificatesModalTitle: {
309
+ id: 'instruct.certificates.studentGeneratedCertificatesModalTitle',
310
+ defaultMessage: 'Student Generated Certificates',
311
+ description: 'Title for student generated certificates modal',
312
+ },
313
+ enableStudentGeneratedCertificates: {
314
+ id: 'instruct.certificates.enableStudentGeneratedCertificates',
315
+ defaultMessage: 'Enable Student Generated Certificates',
316
+ description: 'Checkbox label for enabling student generated certificates',
317
+ },
318
+ studentGeneratedCertificatesDescription: {
319
+ id: 'instruct.certificates.studentGeneratedCertificatesDescription',
320
+ defaultMessage: 'This functionality is enabled by default',
321
+ description: 'Description text for student generated certificates',
322
+ },
323
+ close: {
324
+ id: 'instruct.certificates.close',
325
+ defaultMessage: 'Close',
326
+ description: 'Close button text',
327
+ },
328
+ studentEmailUsername: {
329
+ id: 'instruct.certificates.studentEmailUsername',
330
+ defaultMessage: 'Student Email/Username',
331
+ description: 'Placeholder for student email or username field',
332
+ },
333
+ notesOptional: {
334
+ id: 'instruct.certificates.notesOptional',
335
+ defaultMessage: 'Notes (optional)',
336
+ description: 'Placeholder for optional notes field',
337
+ },
338
+ individualTabDescription: {
339
+ id: 'instruct.certificates.individualTabDescription',
340
+ defaultMessage: 'Enter the username or email address of each learner that you want to add as an exception.',
341
+ description: 'Description for individual tab',
342
+ },
253
343
  cancel: {
254
344
  id: 'instruct.certificates.cancel',
255
345
  defaultMessage: 'Cancel',
@@ -265,6 +355,11 @@ const messages = defineMessages({
265
355
  defaultMessage: 'Submit',
266
356
  description: 'Submit button text',
267
357
  },
358
+ save: {
359
+ id: 'instruct.certificates.save',
360
+ defaultMessage: 'Save',
361
+ description: 'Save button text',
362
+ },
268
363
  columnTaskName: {
269
364
  id: 'instruct.certificates.columnTaskName',
270
365
  defaultMessage: 'Task Name',
@@ -340,6 +435,11 @@ const messages = defineMessages({
340
435
  defaultMessage: 'Regenerate Certificates: {filter}',
341
436
  description: 'Button to regenerate certificates with filter applied',
342
437
  },
438
+ errorModalTitle: {
439
+ id: 'instruct.certificates.errorModalTitle',
440
+ defaultMessage: 'Error',
441
+ description: 'Title for error modal',
442
+ },
343
443
  });
344
444
  export default messages;
345
445
  //# sourceMappingURL=messages.js.map
@@ -1 +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"]}
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: 'Add to Exceptions List',\n description: 'Title for grant exceptions modal',\n },\n grantExceptionsModalDescription: {\n id: 'instruct.certificates.grantExceptionsModalDescription',\n defaultMessage: 'Set exceptions to generate certificates for learners who did not qualify for a certificate but have been given an exception by the course team. After you add learners to the exception list, you must Generate Exception Certificates.',\n description: 'Description for grant exceptions modal',\n },\n invalidateCertificateModalTitle: {\n id: 'instruct.certificates.invalidateCertificateModalTitle',\n defaultMessage: 'Invalidate Certificate',\n description: 'Title for invalidate certificate modal',\n },\n invalidateCertificateModalDescription: {\n id: 'instruct.certificates.invalidateCertificateModalDescription',\n defaultMessage: 'Enter username or email to invalidate a certificate.',\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 learnerLabel: {\n id: 'instruct.certificates.learnerLabel',\n defaultMessage: 'Username or Email',\n description: 'Label for single learner field',\n },\n learnerPlaceholder: {\n id: 'instruct.certificates.learnerPlaceholder',\n defaultMessage: 'Enter username or email',\n description: 'Placeholder for single learner field',\n },\n bulkUploadTab: {\n id: 'instruct.certificates.bulkUploadTab',\n defaultMessage: 'Bulk',\n description: 'Tab label for bulk CSV upload',\n },\n singleLearnerTab: {\n id: 'instruct.certificates.singleLearnerTab',\n defaultMessage: 'Individual',\n description: 'Tab label for single learner input',\n },\n csvFileLabel: {\n id: 'instruct.certificates.csvFileLabel',\n defaultMessage: 'Upload CSV',\n description: 'Label for CSV file upload',\n },\n csvInstructions: {\n id: 'instruct.certificates.csvInstructions',\n defaultMessage: 'CSV Instructions',\n description: 'Link text for CSV instructions',\n },\n csvInstructionsTooltip: {\n id: 'instruct.certificates.csvInstructionsTooltip',\n defaultMessage: 'CSV file should contain the usernames or email addresses of learners who will receive exceptions. Include the username or email address in the first comma separated field. You can include an optional note describing the reason for the exception in the second comma separated field.',\n description: 'Tooltip text for CSV instructions',\n },\n csvFileSelected: {\n id: 'instruct.certificates.csvFileSelected',\n defaultMessage: 'File selected: {fileName}',\n description: 'Message shown when CSV file is selected',\n },\n csvUploadPending: {\n id: 'instruct.certificates.csvUploadPending',\n defaultMessage: 'CSV file \"{fileName}\" is ready. Bulk upload will be processed when the backend API is available.',\n description: 'Message shown when CSV upload is pending backend implementation',\n },\n studentGeneratedCertificatesMenuItem: {\n id: 'instruct.certificates.studentGeneratedCertificatesMenuItem',\n defaultMessage: 'Student Generated Certificates',\n description: 'Menu item for student generated certificates',\n },\n moreActionsButton: {\n id: 'instruct.certificates.moreActionsButton',\n defaultMessage: 'More actions',\n description: 'Button for more actions menu',\n },\n studentGeneratedCertificatesModalTitle: {\n id: 'instruct.certificates.studentGeneratedCertificatesModalTitle',\n defaultMessage: 'Student Generated Certificates',\n description: 'Title for student generated certificates modal',\n },\n enableStudentGeneratedCertificates: {\n id: 'instruct.certificates.enableStudentGeneratedCertificates',\n defaultMessage: 'Enable Student Generated Certificates',\n description: 'Checkbox label for enabling student generated certificates',\n },\n studentGeneratedCertificatesDescription: {\n id: 'instruct.certificates.studentGeneratedCertificatesDescription',\n defaultMessage: 'This functionality is enabled by default',\n description: 'Description text for student generated certificates',\n },\n close: {\n id: 'instruct.certificates.close',\n defaultMessage: 'Close',\n description: 'Close button text',\n },\n studentEmailUsername: {\n id: 'instruct.certificates.studentEmailUsername',\n defaultMessage: 'Student Email/Username',\n description: 'Placeholder for student email or username field',\n },\n notesOptional: {\n id: 'instruct.certificates.notesOptional',\n defaultMessage: 'Notes (optional)',\n description: 'Placeholder for optional notes field',\n },\n individualTabDescription: {\n id: 'instruct.certificates.individualTabDescription',\n defaultMessage: 'Enter the username or email address of each learner that you want to add as an exception.',\n description: 'Description for individual tab',\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 save: {\n id: 'instruct.certificates.save',\n defaultMessage: 'Save',\n description: 'Save 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 errorModalTitle: {\n id: 'instruct.certificates.errorModalTitle',\n defaultMessage: 'Error',\n description: 'Title for error modal',\n },\n});\n\nexport default messages;\n"]}
@@ -8,6 +8,23 @@ 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 errorMessages = {
12
+ not_found: messages.learnerNotFound,
13
+ generic_error: messages.learnerGenericError,
14
+ not_enrolled: messages.learnerNotEnrolled,
15
+ };
16
+ const getErrorState = (error, data) => {
17
+ var _a, _b;
18
+ const isNotFoundError = isAxiosError(error)
19
+ && (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404 || ((_b = error.response) === null || _b === void 0 ? void 0 : _b.status) === 400);
20
+ if (isNotFoundError)
21
+ return 'not_found';
22
+ if (data && !data.isEnrolled)
23
+ return 'not_enrolled';
24
+ if (error && !isNotFoundError)
25
+ return 'generic_error';
26
+ return null;
27
+ };
11
28
  const initialLearnerState = {
12
29
  username: '',
13
30
  fullName: '',
@@ -15,22 +32,23 @@ const initialLearnerState = {
15
32
  isEnrolled: false,
16
33
  };
17
34
  const SpecifyLearnerField = forwardRef(({ learner, onClickSelect }, ref) => {
18
- var _a;
19
35
  const intl = useIntl();
20
36
  const { courseId = '' } = useParams();
21
37
  const [identifier, setIdentifier] = useState('');
22
38
  const [showLearner, enableShowLearner, disableShowLearner] = useToggle(!!learner);
39
+ const [errorState, setErrorState] = useState(null);
23
40
  const { data: courseInfo } = useCourseInfo(courseId);
24
41
  const permissions = (courseInfo === null || courseInfo === void 0 ? void 0 : courseInfo.permissions) || { admin: false, dataResearcher: false };
25
42
  const { inputValue, handleChange, resetFilter } = useDebouncedFilter({
26
43
  filterValue: identifier,
27
44
  setFilter: setIdentifier,
28
45
  });
29
- const { data, refetch, error } = useLearner(courseId, inputValue);
46
+ const { data, refetch } = useLearner(courseId, inputValue);
30
47
  const resetState = () => {
31
48
  resetFilter();
32
49
  onClickSelect('');
33
50
  disableShowLearner();
51
+ setErrorState(null);
34
52
  };
35
53
  useImperativeHandle(ref, () => ({
36
54
  reset: resetState,
@@ -38,6 +56,9 @@ const SpecifyLearnerField = forwardRef(({ learner, onClickSelect }, ref) => {
38
56
  const selectedLearner = learner || data || initialLearnerState;
39
57
  const handleInputChange = (event) => {
40
58
  handleChange(event.target.value);
59
+ if (errorState) {
60
+ setErrorState(null);
61
+ }
41
62
  if (showLearner) {
42
63
  disableShowLearner();
43
64
  }
@@ -49,15 +70,14 @@ const SpecifyLearnerField = forwardRef(({ learner, onClickSelect }, ref) => {
49
70
  // Need to pass empty value if learner is not valid to clear out any previously selected learner
50
71
  // We could have other conditions/fields depending on valid learner
51
72
  const formValue = !result.error && ((_a = result.data) === null || _a === void 0 ? void 0 : _a.isEnrolled) ? inputValue : '';
73
+ setErrorState(getErrorState(result.error, result === null || result === void 0 ? void 0 : result.data));
52
74
  onClickSelect(formValue);
53
75
  enableShowLearner();
54
76
  });
55
77
  }
56
78
  };
57
79
  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
59
- && isAxiosError(error)
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 }) }))] }));
80
+ && (_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 && errorState && (_jsx("p", { className: "text-danger-500 mb-0 x-small mt-2", children: intl.formatMessage(errorMessages[errorState], { identifier: inputValue }) }))] }));
61
81
  });
62
82
  SpecifyLearnerField.displayName = 'SpecifyLearnerField';
63
83
  export default SpecifyLearnerField;