@openedx/frontend-app-gradebook 2.0.0-alpha.0

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 (350) hide show
  1. package/LICENSE +661 -0
  2. package/README.rst +279 -0
  3. package/dist/Main.d.ts +3 -0
  4. package/dist/Main.js +17 -0
  5. package/dist/Main.js.map +1 -0
  6. package/dist/app.d.ts +3 -0
  7. package/dist/app.js +10 -0
  8. package/dist/app.js.map +1 -0
  9. package/dist/components/BulkManagementHistoryView/BulkManagementAlerts.d.ts +5 -0
  10. package/dist/components/BulkManagementHistoryView/BulkManagementAlerts.js +20 -0
  11. package/dist/components/BulkManagementHistoryView/BulkManagementAlerts.js.map +1 -0
  12. package/dist/components/BulkManagementHistoryView/BulkManagementHistoryView.scss +6 -0
  13. package/dist/components/BulkManagementHistoryView/HistoryTable.d.ts +33 -0
  14. package/dist/components/BulkManagementHistoryView/HistoryTable.js +53 -0
  15. package/dist/components/BulkManagementHistoryView/HistoryTable.js.map +1 -0
  16. package/dist/components/BulkManagementHistoryView/ResultsSummary.d.ts +16 -0
  17. package/dist/components/BulkManagementHistoryView/ResultsSummary.js +19 -0
  18. package/dist/components/BulkManagementHistoryView/ResultsSummary.js.map +1 -0
  19. package/dist/components/BulkManagementHistoryView/data/api.d.ts +5 -0
  20. package/dist/components/BulkManagementHistoryView/data/api.js +16 -0
  21. package/dist/components/BulkManagementHistoryView/data/api.js.map +1 -0
  22. package/dist/components/BulkManagementHistoryView/data/apiHook.d.ts +16 -0
  23. package/dist/components/BulkManagementHistoryView/data/apiHook.js +34 -0
  24. package/dist/components/BulkManagementHistoryView/data/apiHook.js.map +1 -0
  25. package/dist/components/BulkManagementHistoryView/data/queryKeys.d.ts +5 -0
  26. package/dist/components/BulkManagementHistoryView/data/queryKeys.js +7 -0
  27. package/dist/components/BulkManagementHistoryView/data/queryKeys.js.map +1 -0
  28. package/dist/components/BulkManagementHistoryView/data/utils.d.ts +34 -0
  29. package/dist/components/BulkManagementHistoryView/data/utils.js +45 -0
  30. package/dist/components/BulkManagementHistoryView/data/utils.js.map +1 -0
  31. package/dist/components/BulkManagementHistoryView/index.d.ts +2 -0
  32. package/dist/components/BulkManagementHistoryView/index.js +12 -0
  33. package/dist/components/BulkManagementHistoryView/index.js.map +1 -0
  34. package/dist/components/BulkManagementHistoryView/messages.d.ts +24 -0
  35. package/dist/components/BulkManagementHistoryView/messages.js +20 -0
  36. package/dist/components/BulkManagementHistoryView/messages.js.map +1 -0
  37. package/dist/components/GradebookFilters/AssignmentFilter/index.d.ts +10 -0
  38. package/dist/components/GradebookFilters/AssignmentFilter/index.js +31 -0
  39. package/dist/components/GradebookFilters/AssignmentFilter/index.js.map +1 -0
  40. package/dist/components/GradebookFilters/AssignmentGradeFilter/hooks.d.ts +19 -0
  41. package/dist/components/GradebookFilters/AssignmentGradeFilter/hooks.js +31 -0
  42. package/dist/components/GradebookFilters/AssignmentGradeFilter/hooks.js.map +1 -0
  43. package/dist/components/GradebookFilters/AssignmentGradeFilter/index.d.ts +10 -0
  44. package/dist/components/GradebookFilters/AssignmentGradeFilter/index.js +17 -0
  45. package/dist/components/GradebookFilters/AssignmentGradeFilter/index.js.map +1 -0
  46. package/dist/components/GradebookFilters/AssignmentTypeFilter/index.d.ts +10 -0
  47. package/dist/components/GradebookFilters/AssignmentTypeFilter/index.js +38 -0
  48. package/dist/components/GradebookFilters/AssignmentTypeFilter/index.js.map +1 -0
  49. package/dist/components/GradebookFilters/CourseGradeFilter/hooks.d.ts +15 -0
  50. package/dist/components/GradebookFilters/CourseGradeFilter/hooks.js +34 -0
  51. package/dist/components/GradebookFilters/CourseGradeFilter/hooks.js.map +1 -0
  52. package/dist/components/GradebookFilters/CourseGradeFilter/index.d.ts +10 -0
  53. package/dist/components/GradebookFilters/CourseGradeFilter/index.js +17 -0
  54. package/dist/components/GradebookFilters/CourseGradeFilter/index.js.map +1 -0
  55. package/dist/components/GradebookFilters/GradebookFilters.scss +6 -0
  56. package/dist/components/GradebookFilters/PercentGroup.d.ts +22 -0
  57. package/dist/components/GradebookFilters/PercentGroup.js +16 -0
  58. package/dist/components/GradebookFilters/PercentGroup.js.map +1 -0
  59. package/dist/components/GradebookFilters/SelectGroup.d.ts +24 -0
  60. package/dist/components/GradebookFilters/SelectGroup.js +17 -0
  61. package/dist/components/GradebookFilters/SelectGroup.js.map +1 -0
  62. package/dist/components/GradebookFilters/StudentGroupsFilter/hooks.d.ts +16 -0
  63. package/dist/components/GradebookFilters/StudentGroupsFilter/hooks.js +46 -0
  64. package/dist/components/GradebookFilters/StudentGroupsFilter/hooks.js.map +1 -0
  65. package/dist/components/GradebookFilters/StudentGroupsFilter/index.d.ts +10 -0
  66. package/dist/components/GradebookFilters/StudentGroupsFilter/index.js +23 -0
  67. package/dist/components/GradebookFilters/StudentGroupsFilter/index.js.map +1 -0
  68. package/dist/components/GradebookFilters/data/api.d.ts +10 -0
  69. package/dist/components/GradebookFilters/data/api.js +27 -0
  70. package/dist/components/GradebookFilters/data/api.js.map +1 -0
  71. package/dist/components/GradebookFilters/data/apiHook.d.ts +16 -0
  72. package/dist/components/GradebookFilters/data/apiHook.js +24 -0
  73. package/dist/components/GradebookFilters/data/apiHook.js.map +1 -0
  74. package/dist/components/GradebookFilters/data/hooks.d.ts +7 -0
  75. package/dist/components/GradebookFilters/data/hooks.js +53 -0
  76. package/dist/components/GradebookFilters/data/hooks.js.map +1 -0
  77. package/dist/components/GradebookFilters/data/queryKeys.d.ts +10 -0
  78. package/dist/components/GradebookFilters/data/queryKeys.js +12 -0
  79. package/dist/components/GradebookFilters/data/queryKeys.js.map +1 -0
  80. package/dist/components/GradebookFilters/index.d.ts +10 -0
  81. package/dist/components/GradebookFilters/index.js +32 -0
  82. package/dist/components/GradebookFilters/index.js.map +1 -0
  83. package/dist/components/GradebookFilters/messages.d.ts +112 -0
  84. package/dist/components/GradebookFilters/messages.js +75 -0
  85. package/dist/components/GradebookFilters/messages.js.map +1 -0
  86. package/dist/components/GradebookHeader/hooks.d.ts +13 -0
  87. package/dist/components/GradebookHeader/hooks.js +28 -0
  88. package/dist/components/GradebookHeader/hooks.js.map +1 -0
  89. package/dist/components/GradebookHeader/index.d.ts +2 -0
  90. package/dist/components/GradebookHeader/index.js +14 -0
  91. package/dist/components/GradebookHeader/index.js.map +1 -0
  92. package/dist/components/GradebookHeader/messages.d.ts +48 -0
  93. package/dist/components/GradebookHeader/messages.js +35 -0
  94. package/dist/components/GradebookHeader/messages.js.map +1 -0
  95. package/dist/components/GradesView/BulkManagementControls/index.d.ts +2 -0
  96. package/dist/components/GradesView/BulkManagementControls/index.js +26 -0
  97. package/dist/components/GradesView/BulkManagementControls/index.js.map +1 -0
  98. package/dist/components/GradesView/BulkManagementControls/messages.d.ts +8 -0
  99. package/dist/components/GradesView/BulkManagementControls/messages.js +10 -0
  100. package/dist/components/GradesView/BulkManagementControls/messages.js.map +1 -0
  101. package/dist/components/GradesView/EditModal/HistoryHeader.d.ts +21 -0
  102. package/dist/components/GradesView/EditModal/HistoryHeader.js +20 -0
  103. package/dist/components/GradesView/EditModal/HistoryHeader.js.map +1 -0
  104. package/dist/components/GradesView/EditModal/ModalHeaders.d.ts +3 -0
  105. package/dist/components/GradesView/EditModal/ModalHeaders.js +26 -0
  106. package/dist/components/GradesView/EditModal/ModalHeaders.js.map +1 -0
  107. package/dist/components/GradesView/EditModal/OverrideTable/AdjustedGradeInput/index.d.ts +5 -0
  108. package/dist/components/GradesView/EditModal/OverrideTable/AdjustedGradeInput/index.js +23 -0
  109. package/dist/components/GradesView/EditModal/OverrideTable/AdjustedGradeInput/index.js.map +1 -0
  110. package/dist/components/GradesView/EditModal/OverrideTable/ReasonInput/index.d.ts +6 -0
  111. package/dist/components/GradesView/EditModal/OverrideTable/ReasonInput/index.js +25 -0
  112. package/dist/components/GradesView/EditModal/OverrideTable/ReasonInput/index.js.map +1 -0
  113. package/dist/components/GradesView/EditModal/OverrideTable/index.d.ts +5 -0
  114. package/dist/components/GradesView/EditModal/OverrideTable/index.js +39 -0
  115. package/dist/components/GradesView/EditModal/OverrideTable/index.js.map +1 -0
  116. package/dist/components/GradesView/EditModal/OverrideTable/messages.d.ts +32 -0
  117. package/dist/components/GradesView/EditModal/OverrideTable/messages.js +25 -0
  118. package/dist/components/GradesView/EditModal/OverrideTable/messages.js.map +1 -0
  119. package/dist/components/GradesView/EditModal/index.d.ts +2 -0
  120. package/dist/components/GradesView/EditModal/index.js +35 -0
  121. package/dist/components/GradesView/EditModal/index.js.map +1 -0
  122. package/dist/components/GradesView/EditModal/messages.d.ts +72 -0
  123. package/dist/components/GradesView/EditModal/messages.js +50 -0
  124. package/dist/components/GradesView/EditModal/messages.js.map +1 -0
  125. package/dist/components/GradesView/FilterBadges/FilterBadge.d.ts +9 -0
  126. package/dist/components/GradesView/FilterBadges/FilterBadge.js +27 -0
  127. package/dist/components/GradesView/FilterBadges/FilterBadge.js.map +1 -0
  128. package/dist/components/GradesView/FilterBadges/index.d.ts +8 -0
  129. package/dist/components/GradesView/FilterBadges/index.js +15 -0
  130. package/dist/components/GradesView/FilterBadges/index.js.map +1 -0
  131. package/dist/components/GradesView/FilterMenuToggle/index.d.ts +5 -0
  132. package/dist/components/GradesView/FilterMenuToggle/index.js +18 -0
  133. package/dist/components/GradesView/FilterMenuToggle/index.js.map +1 -0
  134. package/dist/components/GradesView/FilterMenuToggle/messages.d.ts +8 -0
  135. package/dist/components/GradesView/FilterMenuToggle/messages.js +10 -0
  136. package/dist/components/GradesView/FilterMenuToggle/messages.js.map +1 -0
  137. package/dist/components/GradesView/FilteredUsersLabel/index.d.ts +15 -0
  138. package/dist/components/GradesView/FilteredUsersLabel/index.js +27 -0
  139. package/dist/components/GradesView/FilteredUsersLabel/index.js.map +1 -0
  140. package/dist/components/GradesView/FilteredUsersLabel/messages.d.ts +8 -0
  141. package/dist/components/GradesView/FilteredUsersLabel/messages.js +10 -0
  142. package/dist/components/GradesView/FilteredUsersLabel/messages.js.map +1 -0
  143. package/dist/components/GradesView/GradebookTable/Fields.d.ts +2 -0
  144. package/dist/components/GradesView/GradebookTable/Fields.js +32 -0
  145. package/dist/components/GradesView/GradebookTable/Fields.js.map +1 -0
  146. package/dist/components/GradesView/GradebookTable/GradeButton.d.ts +26 -0
  147. package/dist/components/GradesView/GradebookTable/GradeButton.js +56 -0
  148. package/dist/components/GradesView/GradebookTable/GradeButton.js.map +1 -0
  149. package/dist/components/GradesView/GradebookTable/LabelReplacements.d.ts +3 -0
  150. package/dist/components/GradesView/GradebookTable/LabelReplacements.js +42 -0
  151. package/dist/components/GradesView/GradebookTable/LabelReplacements.js.map +1 -0
  152. package/dist/components/GradesView/GradebookTable/hooks.d.ts +11 -0
  153. package/dist/components/GradesView/GradebookTable/hooks.js +45 -0
  154. package/dist/components/GradesView/GradebookTable/hooks.js.map +1 -0
  155. package/dist/components/GradesView/GradebookTable/index.d.ts +5 -0
  156. package/dist/components/GradesView/GradebookTable/index.js +16 -0
  157. package/dist/components/GradesView/GradebookTable/index.js.map +1 -0
  158. package/dist/components/GradesView/GradebookTable/messages.d.ts +64 -0
  159. package/dist/components/GradesView/GradebookTable/messages.js +45 -0
  160. package/dist/components/GradesView/GradebookTable/messages.js.map +1 -0
  161. package/dist/components/GradesView/GradesView.scss +156 -0
  162. package/dist/components/GradesView/ImportGradesButton/index.d.ts +5 -0
  163. package/dist/components/GradesView/ImportGradesButton/index.js +38 -0
  164. package/dist/components/GradesView/ImportGradesButton/index.js.map +1 -0
  165. package/dist/components/GradesView/ImportGradesButton/messages.d.ts +16 -0
  166. package/dist/components/GradesView/ImportGradesButton/messages.js +15 -0
  167. package/dist/components/GradesView/ImportGradesButton/messages.js.map +1 -0
  168. package/dist/components/GradesView/ImportSuccessToast/hooks.d.ts +10 -0
  169. package/dist/components/GradesView/ImportSuccessToast/hooks.js +31 -0
  170. package/dist/components/GradesView/ImportSuccessToast/hooks.js.map +1 -0
  171. package/dist/components/GradesView/ImportSuccessToast/index.d.ts +5 -0
  172. package/dist/components/GradesView/ImportSuccessToast/index.js +15 -0
  173. package/dist/components/GradesView/ImportSuccessToast/index.js.map +1 -0
  174. package/dist/components/GradesView/ImportSuccessToast/messages.d.ts +17 -0
  175. package/dist/components/GradesView/ImportSuccessToast/messages.js +15 -0
  176. package/dist/components/GradesView/ImportSuccessToast/messages.js.map +1 -0
  177. package/dist/components/GradesView/InterventionsReport/index.d.ts +2 -0
  178. package/dist/components/GradesView/InterventionsReport/index.js +27 -0
  179. package/dist/components/GradesView/InterventionsReport/index.js.map +1 -0
  180. package/dist/components/GradesView/InterventionsReport/messages.d.ts +25 -0
  181. package/dist/components/GradesView/InterventionsReport/messages.js +20 -0
  182. package/dist/components/GradesView/InterventionsReport/messages.js.map +1 -0
  183. package/dist/components/GradesView/PageButtons/index.d.ts +5 -0
  184. package/dist/components/GradesView/PageButtons/index.js +14 -0
  185. package/dist/components/GradesView/PageButtons/index.js.map +1 -0
  186. package/dist/components/GradesView/PageButtons/messages.d.ts +16 -0
  187. package/dist/components/GradesView/PageButtons/messages.js +15 -0
  188. package/dist/components/GradesView/PageButtons/messages.js.map +1 -0
  189. package/dist/components/GradesView/ScoreViewInput/index.d.ts +5 -0
  190. package/dist/components/GradesView/ScoreViewInput/index.js +20 -0
  191. package/dist/components/GradesView/ScoreViewInput/index.js.map +1 -0
  192. package/dist/components/GradesView/ScoreViewInput/messages.d.ts +24 -0
  193. package/dist/components/GradesView/ScoreViewInput/messages.js +20 -0
  194. package/dist/components/GradesView/ScoreViewInput/messages.js.map +1 -0
  195. package/dist/components/GradesView/SearchControls/hooks.d.ts +9 -0
  196. package/dist/components/GradesView/SearchControls/hooks.js +34 -0
  197. package/dist/components/GradesView/SearchControls/hooks.js.map +1 -0
  198. package/dist/components/GradesView/SearchControls/index.d.ts +5 -0
  199. package/dist/components/GradesView/SearchControls/index.js +14 -0
  200. package/dist/components/GradesView/SearchControls/index.js.map +1 -0
  201. package/dist/components/GradesView/SearchControls/messages.d.ts +16 -0
  202. package/dist/components/GradesView/SearchControls/messages.js +15 -0
  203. package/dist/components/GradesView/SearchControls/messages.js.map +1 -0
  204. package/dist/components/GradesView/SpinnerIcon.d.ts +5 -0
  205. package/dist/components/GradesView/SpinnerIcon.js +15 -0
  206. package/dist/components/GradesView/SpinnerIcon.js.map +1 -0
  207. package/dist/components/GradesView/StatusAlerts/index.d.ts +5 -0
  208. package/dist/components/GradesView/StatusAlerts/index.js +16 -0
  209. package/dist/components/GradesView/StatusAlerts/index.js.map +1 -0
  210. package/dist/components/GradesView/StatusAlerts/messages.d.ts +24 -0
  211. package/dist/components/GradesView/StatusAlerts/messages.js +20 -0
  212. package/dist/components/GradesView/StatusAlerts/messages.js.map +1 -0
  213. package/dist/components/GradesView/data/api.d.ts +44 -0
  214. package/dist/components/GradesView/data/api.js +64 -0
  215. package/dist/components/GradesView/data/api.js.map +1 -0
  216. package/dist/components/GradesView/data/apiHook.d.ts +92 -0
  217. package/dist/components/GradesView/data/apiHook.js +191 -0
  218. package/dist/components/GradesView/data/apiHook.js.map +1 -0
  219. package/dist/components/GradesView/data/hooks.d.ts +32 -0
  220. package/dist/components/GradesView/data/hooks.js +242 -0
  221. package/dist/components/GradesView/data/hooks.js.map +1 -0
  222. package/dist/components/GradesView/data/queryKeys.d.ts +13 -0
  223. package/dist/components/GradesView/data/queryKeys.js +15 -0
  224. package/dist/components/GradesView/data/queryKeys.js.map +1 -0
  225. package/dist/components/GradesView/data/utils.d.ts +96 -0
  226. package/dist/components/GradesView/data/utils.js +103 -0
  227. package/dist/components/GradesView/data/utils.js.map +1 -0
  228. package/dist/components/GradesView/index.d.ts +10 -0
  229. package/dist/components/GradesView/index.js +35 -0
  230. package/dist/components/GradesView/index.js.map +1 -0
  231. package/dist/components/GradesView/messages.d.ts +24 -0
  232. package/dist/components/GradesView/messages.js +20 -0
  233. package/dist/components/GradesView/messages.js.map +1 -0
  234. package/dist/components/NetworkButton/index.d.ts +23 -0
  235. package/dist/components/NetworkButton/index.js +54 -0
  236. package/dist/components/NetworkButton/index.js.map +1 -0
  237. package/dist/components/WithSidebar/WithSidebar.scss +36 -0
  238. package/dist/components/WithSidebar/index.d.ts +9 -0
  239. package/dist/components/WithSidebar/index.js +34 -0
  240. package/dist/components/WithSidebar/index.js.map +1 -0
  241. package/dist/constants.d.ts +1 -0
  242. package/dist/constants.js +2 -0
  243. package/dist/constants.js.map +1 -0
  244. package/dist/containers/GradebookPage/GradebookDataLoader.d.ts +10 -0
  245. package/dist/containers/GradebookPage/GradebookDataLoader.js +19 -0
  246. package/dist/containers/GradebookPage/GradebookDataLoader.js.map +1 -0
  247. package/dist/containers/GradebookPage/index.d.ts +2 -0
  248. package/dist/containers/GradebookPage/index.js +40 -0
  249. package/dist/containers/GradebookPage/index.js.map +1 -0
  250. package/dist/data/api.d.ts +20 -0
  251. package/dist/data/api.js +36 -0
  252. package/dist/data/api.js.map +1 -0
  253. package/dist/data/apiHook.d.ts +40 -0
  254. package/dist/data/apiHook.js +65 -0
  255. package/dist/data/apiHook.js.map +1 -0
  256. package/dist/data/constants/app.d.ts +13 -0
  257. package/dist/data/constants/app.js +58 -0
  258. package/dist/data/constants/app.js.map +1 -0
  259. package/dist/data/constants/errors.d.ts +2 -0
  260. package/dist/data/constants/errors.js +3 -0
  261. package/dist/data/constants/errors.js.map +1 -0
  262. package/dist/data/constants/filters.d.ts +15 -0
  263. package/dist/data/constants/filters.js +71 -0
  264. package/dist/data/constants/filters.js.map +1 -0
  265. package/dist/data/constants/filters.messages.d.ts +56 -0
  266. package/dist/data/constants/filters.messages.js +40 -0
  267. package/dist/data/constants/filters.messages.js.map +1 -0
  268. package/dist/data/constants/grades.d.ts +6 -0
  269. package/dist/data/constants/grades.js +17 -0
  270. package/dist/data/constants/grades.js.map +1 -0
  271. package/dist/data/filtersContext.d.ts +60 -0
  272. package/dist/data/filtersContext.js +212 -0
  273. package/dist/data/filtersContext.js.map +1 -0
  274. package/dist/data/filtersSnapshot.d.ts +20 -0
  275. package/dist/data/filtersSnapshot.js +15 -0
  276. package/dist/data/filtersSnapshot.js.map +1 -0
  277. package/dist/data/formatUtils.d.ts +15 -0
  278. package/dist/data/formatUtils.js +35 -0
  279. package/dist/data/formatUtils.js.map +1 -0
  280. package/dist/data/gradebookUiContext.d.ts +99 -0
  281. package/dist/data/gradebookUiContext.js +143 -0
  282. package/dist/data/gradebookUiContext.js.map +1 -0
  283. package/dist/data/queryClient.d.ts +10 -0
  284. package/dist/data/queryClient.js +34 -0
  285. package/dist/data/queryClient.js.map +1 -0
  286. package/dist/data/queryKeys.d.ts +11 -0
  287. package/dist/data/queryKeys.js +21 -0
  288. package/dist/data/queryKeys.js.map +1 -0
  289. package/dist/data/services/lms/api.d.ts +2 -0
  290. package/dist/data/services/lms/api.js +104 -0
  291. package/dist/data/services/lms/api.js.map +1 -0
  292. package/dist/data/services/lms/constants.d.ts +3 -0
  293. package/dist/data/services/lms/constants.js +16 -0
  294. package/dist/data/services/lms/constants.js.map +1 -0
  295. package/dist/data/services/lms/index.d.ts +2 -0
  296. package/dist/data/services/lms/index.js +8 -0
  297. package/dist/data/services/lms/index.js.map +1 -0
  298. package/dist/data/services/lms/messages.d.ts +2 -0
  299. package/dist/data/services/lms/messages.js +8 -0
  300. package/dist/data/services/lms/messages.js.map +1 -0
  301. package/dist/data/services/lms/urls.d.ts +19 -0
  302. package/dist/data/services/lms/urls.js +47 -0
  303. package/dist/data/services/lms/urls.js.map +1 -0
  304. package/dist/data/services/lms/utils.d.ts +4 -0
  305. package/dist/data/services/lms/utils.js +34 -0
  306. package/dist/data/services/lms/utils.js.map +1 -0
  307. package/dist/data/services/segment/constants.d.ts +8 -0
  308. package/dist/data/services/segment/constants.js +26 -0
  309. package/dist/data/services/segment/constants.js.map +1 -0
  310. package/dist/data/services/segment/events.d.ts +14 -0
  311. package/dist/data/services/segment/events.js +32 -0
  312. package/dist/data/services/segment/events.js.map +1 -0
  313. package/dist/data/utils.d.ts +10 -0
  314. package/dist/data/utils.js +14 -0
  315. package/dist/data/utils.js.map +1 -0
  316. package/dist/i18n/index.d.ts +1 -0
  317. package/dist/i18n/index.js +2 -0
  318. package/dist/i18n/index.js.map +1 -0
  319. package/dist/i18n/utils.d.ts +2 -0
  320. package/dist/i18n/utils.js +21 -0
  321. package/dist/i18n/utils.js.map +1 -0
  322. package/dist/index.d.ts +3 -0
  323. package/dist/index.js +4 -0
  324. package/dist/index.js.map +1 -0
  325. package/dist/messages.d.ts +8 -0
  326. package/dist/messages.js +10 -0
  327. package/dist/messages.js.map +1 -0
  328. package/dist/providers.d.ts +3 -0
  329. package/dist/providers.js +13 -0
  330. package/dist/providers.js.map +1 -0
  331. package/dist/routes.d.ts +11 -0
  332. package/dist/routes.js +16 -0
  333. package/dist/routes.js.map +1 -0
  334. package/dist/style.scss +13 -0
  335. package/dist/utils/StrictDict.d.ts +2 -0
  336. package/dist/utils/StrictDict.js +19 -0
  337. package/dist/utils/StrictDict.js.map +1 -0
  338. package/dist/utils/formatDate.d.ts +15 -0
  339. package/dist/utils/formatDate.js +19 -0
  340. package/dist/utils/formatDate.js.map +1 -0
  341. package/dist/utils/hoc.d.ts +3 -0
  342. package/dist/utils/hoc.js +21 -0
  343. package/dist/utils/hoc.js.map +1 -0
  344. package/dist/utils/index.d.ts +3 -0
  345. package/dist/utils/index.js +4 -0
  346. package/dist/utils/index.js.map +1 -0
  347. package/dist/utils/keyStore.d.ts +2 -0
  348. package/dist/utils/keyStore.js +4 -0
  349. package/dist/utils/keyStore.js.map +1 -0
  350. package/package.json +89 -0
@@ -0,0 +1,191 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { useMemo } from 'react';
11
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
12
+ import { useParams } from 'react-router-dom';
13
+ import lms from '../../../data/services/lms';
14
+ import { sortAlphaAsc } from '../../../data/formatUtils';
15
+ import { filtersSnapshot } from '../../../data/filtersSnapshot';
16
+ import { useGradebookUi } from '../../../data/gradebookUiContext';
17
+ import { useCourseIdWithGate } from '../../../data/apiHook';
18
+ import { trackGradesDisplayed, trackGradeOverrideSucceeded, trackGradeOverrideFailed, trackUploadOverrideSucceeded, trackUploadOverrideFailed, } from '../../../data/services/segment/events';
19
+ // Cross-feature invalidation: a successful CSV upload refreshes the bulk-operation
20
+ // history owned by the BulkManagementHistoryView feature.
21
+ import { bulkOperationHistoryQueryKeys } from '../../BulkManagementHistoryView/data/queryKeys';
22
+ import { getGradeOverrideHistory, getGrades, getGradesPage } from './api';
23
+ import { gradeOverrideHistoryQueryKeys, gradesQueryKeys } from './queryKeys';
24
+ import { buildGradesFetchParams } from './utils';
25
+ /**
26
+ * Builds the `getGrades` params from the live `filtersSnapshot`. Reads at fetch
27
+ * time (not from the query key) so imperative refetches pick up the latest
28
+ * filter values — the FiltersProvider keeps `filtersSnapshot` in sync.
29
+ */
30
+ const buildGradebookDataParams = () => buildGradesFetchParams(filtersSnapshot);
31
+ /**
32
+ * useGrades()
33
+ * Single-responsibility query for the main gradebook rows. Caller supplies
34
+ * `courseId`, the current pagination cursor (`gradesPageEndpoint` from
35
+ * `GradebookUi`, or `null` for the base/unpaged page), and decides when it may
36
+ * run via `enabled`. The base grades key is a prefix of the paged key, so
37
+ * invalidating `byCourse(courseId)` still refetches any page. The first
38
+ * (unpaged) page reads the current filter params at fetch time (so an
39
+ * imperative `invalidateQueries` on filter apply / search refetches with the
40
+ * latest values); a non-null cursor fetches that opaque prev/next URL —
41
+ * replacing the legacy `fetchPrevNextGrades` thunk.
42
+ */
43
+ export const useGrades = (courseId, gradesPageEndpoint, { enabled = true } = {}) => useQuery({
44
+ queryKey: [...gradesQueryKeys.byCourse(courseId), gradesPageEndpoint !== null && gradesPageEndpoint !== void 0 ? gradesPageEndpoint : 'base'],
45
+ queryFn: () => __awaiter(void 0, void 0, void 0, function* () {
46
+ const data = gradesPageEndpoint
47
+ ? yield getGradesPage(gradesPageEndpoint)
48
+ : yield getGrades(buildGradebookDataParams());
49
+ // Mirrors the legacy `receivedGrades` redux-beacon trigger: one event per
50
+ // actual fetch, with the filters it ran under and the resulting cursors.
51
+ trackGradesDisplayed({
52
+ assignmentType: filtersSnapshot.assignmentType,
53
+ cohort: filtersSnapshot.cohort,
54
+ track: filtersSnapshot.track,
55
+ prev: data.previous,
56
+ next: data.next,
57
+ });
58
+ return data;
59
+ }),
60
+ enabled: !!courseId && enabled,
61
+ });
62
+ /**
63
+ * useGradesData()
64
+ * Shapes the `useGrades` query into the read-model the grades table / counts /
65
+ * pagination consume — the React Query equivalent of the Redux `grades` slice
66
+ * fields that `useGradebookData` used to mirror. Results are sorted by username
67
+ * (matching the legacy `fetching.received` handling).
68
+ */
69
+ export const useGradesData = () => {
70
+ var _a, _b, _c, _d;
71
+ const { courseId, enabled } = useCourseIdWithGate();
72
+ const { gradesPageEndpoint } = useGradebookUi();
73
+ const query = useGrades(courseId, gradesPageEndpoint, { enabled });
74
+ const data = query.data;
75
+ const results = useMemo(() => { var _a; return [...((_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [])].sort(sortAlphaAsc); }, [data]);
76
+ return {
77
+ results,
78
+ prevPage: (_a = data === null || data === void 0 ? void 0 : data.previous) !== null && _a !== void 0 ? _a : null,
79
+ nextPage: (_b = data === null || data === void 0 ? void 0 : data.next) !== null && _b !== void 0 ? _b : null,
80
+ totalUsersCount: (_c = data === null || data === void 0 ? void 0 : data.total_users_count) !== null && _c !== void 0 ? _c : 0,
81
+ filteredUsersCount: (_d = data === null || data === void 0 ? void 0 : data.filtered_users_count) !== null && _d !== void 0 ? _d : 0,
82
+ isFetching: query.isFetching,
83
+ isError: query.isError,
84
+ isSuccess: query.isSuccess,
85
+ };
86
+ };
87
+ /**
88
+ * useGradeOverrideHistory(subsectionId, userId)
89
+ * Grade-override history for a single learner/subsection, used by the edit modal.
90
+ * Enabled only once both identifiers are present (i.e. the modal has been opened
91
+ * for a specific cell). `retry: false` because a `success: false` business error
92
+ * is not worth retrying.
93
+ */
94
+ export const useGradeOverrideHistory = (subsectionId, userId) => (useQuery({
95
+ queryKey: gradeOverrideHistoryQueryKeys.byCell(subsectionId !== null && subsectionId !== void 0 ? subsectionId : null, userId !== null && userId !== void 0 ? userId : null),
96
+ queryFn: () => getGradeOverrideHistory(subsectionId, userId),
97
+ enabled: !!subsectionId && userId !== undefined && userId !== null,
98
+ retry: false,
99
+ }));
100
+ /**
101
+ * useUpdateGrades()
102
+ * Grade-override save from the edit modal. The HTTP call runs through React Query;
103
+ * success emits the Segment `update.*` event, shows the success banner, resets to
104
+ * the first grades page, and invalidates the grades query (so the table reflects
105
+ * the override) and the edited cell's override history (so reopening the modal
106
+ * shows the new entry).
107
+ *
108
+ * The payload is captured as mutation variables when the trigger is called (same
109
+ * shape as the old `selectors.app.editUpdateData`): the caller closes the modal
110
+ * right after triggering the save, and a pending mutation picks up re-rendered
111
+ * options, so a closure over `modalState` would read the reset (empty) state.
112
+ *
113
+ * Returns a no-arg trigger to match the legacy `useUpdateGrades()` call site.
114
+ */
115
+ export const useUpdateGrades = () => {
116
+ const queryClient = useQueryClient();
117
+ const { courseId = '' } = useParams();
118
+ const { setShowSuccess, setGradesPageEndpoint, modalState } = useGradebookUi();
119
+ const mutation = useMutation({
120
+ mutationFn: (updateData) => lms.api.updateGradebookData(updateData),
121
+ onSuccess: ({ data }, updateData) => {
122
+ trackGradeOverrideSucceeded(data);
123
+ setShowSuccess(true);
124
+ setGradesPageEndpoint(null);
125
+ queryClient.invalidateQueries({
126
+ queryKey: gradesQueryKeys.byCourse(courseId),
127
+ });
128
+ updateData.forEach(({ usage_id: usageId, user_id: userId }) => {
129
+ queryClient.invalidateQueries({
130
+ queryKey: gradeOverrideHistoryQueryKeys.byCell(usageId, userId),
131
+ });
132
+ });
133
+ },
134
+ onError: (error) => {
135
+ trackGradeOverrideFailed(error);
136
+ },
137
+ });
138
+ return () => {
139
+ mutation.mutate([{
140
+ grade: {
141
+ comment: modalState.reasonForChange,
142
+ earned_graded_override: modalState.adjustedGradeValue,
143
+ },
144
+ usage_id: modalState.updateModuleId,
145
+ user_id: modalState.updateUserId,
146
+ }]);
147
+ };
148
+ };
149
+ /**
150
+ * useSubmitImportGradesButtonData()
151
+ * Bulk grade-override CSV upload. The upload runs through React Query and, on
152
+ * success, invalidates the bulk-operation-history query so the new upload shows up.
153
+ * CSV progress/results/toast are React UI state (GradebookUi context) and success/
154
+ * failure emit the Segment `uploadOverride.*` events.
155
+ *
156
+ * Returns `(formData) => Promise` whose promise always resolves (errors are handled
157
+ * inside `onError`), matching the legacy thunk so the caller's `.then(clearInput)`
158
+ * still runs on both success and failure.
159
+ */
160
+ export const useSubmitImportGradesButtonData = () => {
161
+ const queryClient = useQueryClient();
162
+ const { courseId = '' } = useParams();
163
+ const { setShowImportSuccessToast, resetCsvUpload, markCsvUploadSuccess, setCsvUploadErrors, } = useGradebookUi();
164
+ const mutation = useMutation({
165
+ mutationFn: (formData) => lms.api.uploadGradeCsv(formData),
166
+ onMutate: () => {
167
+ resetCsvUpload();
168
+ },
169
+ onSuccess: () => {
170
+ markCsvUploadSuccess();
171
+ setShowImportSuccessToast(true);
172
+ trackUploadOverrideSucceeded();
173
+ queryClient.invalidateQueries({
174
+ queryKey: bulkOperationHistoryQueryKeys.byCourse(courseId),
175
+ });
176
+ },
177
+ onError: (error) => {
178
+ var _a, _b;
179
+ trackUploadOverrideFailed(error);
180
+ if ((error === null || error === void 0 ? void 0 : error.status) === 200 && ((_b = (_a = error === null || error === void 0 ? void 0 : error.data) === null || _a === void 0 ? void 0 : _a.error_messages) === null || _b === void 0 ? void 0 : _b.length)) {
181
+ const { error_messages: errorMessages } = error.data;
182
+ setCsvUploadErrors(errorMessages);
183
+ }
184
+ else {
185
+ setCsvUploadErrors(['Unknown error.']);
186
+ }
187
+ },
188
+ });
189
+ return (formData) => mutation.mutateAsync(formData).catch(() => { });
190
+ };
191
+ //# sourceMappingURL=apiHook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../../src/components/GradesView/data/apiHook.ts"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from 'react';\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { useParams } from 'react-router-dom';\n\nimport lms from '@src/data/services/lms';\nimport { sortAlphaAsc } from '@src/data/formatUtils';\nimport { filtersSnapshot } from '@src/data/filtersSnapshot';\nimport { useGradebookUi } from '@src/data/gradebookUiContext';\nimport { useCourseIdWithGate } from '@src/data/apiHook';\nimport {\n trackGradesDisplayed,\n trackGradeOverrideSucceeded,\n trackGradeOverrideFailed,\n trackUploadOverrideSucceeded,\n trackUploadOverrideFailed,\n} from '@src/data/services/segment/events';\n// Cross-feature invalidation: a successful CSV upload refreshes the bulk-operation\n// history owned by the BulkManagementHistoryView feature.\nimport { bulkOperationHistoryQueryKeys } from '@src/components/BulkManagementHistoryView/data/queryKeys';\n\nimport { getGradeOverrideHistory, getGrades, getGradesPage } from './api';\nimport { gradeOverrideHistoryQueryKeys, gradesQueryKeys } from './queryKeys';\nimport { buildGradesFetchParams } from './utils';\n\n/**\n * Builds the `getGrades` params from the live `filtersSnapshot`. Reads at fetch\n * time (not from the query key) so imperative refetches pick up the latest\n * filter values — the FiltersProvider keeps `filtersSnapshot` in sync.\n */\nconst buildGradebookDataParams = () => buildGradesFetchParams(filtersSnapshot);\n\n/**\n * useGrades()\n * Single-responsibility query for the main gradebook rows. Caller supplies\n * `courseId`, the current pagination cursor (`gradesPageEndpoint` from\n * `GradebookUi`, or `null` for the base/unpaged page), and decides when it may\n * run via `enabled`. The base grades key is a prefix of the paged key, so\n * invalidating `byCourse(courseId)` still refetches any page. The first\n * (unpaged) page reads the current filter params at fetch time (so an\n * imperative `invalidateQueries` on filter apply / search refetches with the\n * latest values); a non-null cursor fetches that opaque prev/next URL —\n * replacing the legacy `fetchPrevNextGrades` thunk.\n */\nexport const useGrades = (\n courseId: string,\n gradesPageEndpoint: string | null,\n { enabled = true }: { enabled?: boolean } = {},\n) => useQuery({\n queryKey: [...gradesQueryKeys.byCourse(courseId), gradesPageEndpoint ?? 'base'],\n queryFn: async () => {\n const data = gradesPageEndpoint\n ? await getGradesPage(gradesPageEndpoint)\n : await getGrades(buildGradebookDataParams());\n // Mirrors the legacy `receivedGrades` redux-beacon trigger: one event per\n // actual fetch, with the filters it ran under and the resulting cursors.\n trackGradesDisplayed({\n assignmentType: filtersSnapshot.assignmentType,\n cohort: filtersSnapshot.cohort,\n track: filtersSnapshot.track,\n prev: data.previous,\n next: data.next,\n });\n return data;\n },\n enabled: !!courseId && enabled,\n});\n\n/** One subsection cell within a learner's grade row. */\nexport interface SubsectionBreakdown {\n label: string;\n category?: string;\n subsection_name?: string;\n module_id?: string;\n score_possible?: number;\n score_earned?: number;\n percent?: number;\n attempted?: boolean;\n [key: string]: unknown;\n}\n\n/** One learner's grade row from the gradebook response. */\nexport interface GradeEntry {\n user_id?: number;\n username?: string;\n external_user_key?: string;\n email?: string;\n percent?: number;\n section_breakdown: SubsectionBreakdown[];\n [key: string]: unknown;\n}\n\n/** Shaped grades read-model derived from the `useGrades` query. */\nexport interface GradesData {\n results: GradeEntry[];\n prevPage: string | null;\n nextPage: string | null;\n totalUsersCount: number;\n filteredUsersCount: number;\n isFetching: boolean;\n isError: boolean;\n isSuccess: boolean;\n}\n\n/**\n * useGradesData()\n * Shapes the `useGrades` query into the read-model the grades table / counts /\n * pagination consume — the React Query equivalent of the Redux `grades` slice\n * fields that `useGradebookData` used to mirror. Results are sorted by username\n * (matching the legacy `fetching.received` handling).\n */\nexport const useGradesData = (): GradesData => {\n const { courseId, enabled } = useCourseIdWithGate();\n const { gradesPageEndpoint } = useGradebookUi();\n const query = useGrades(courseId, gradesPageEndpoint, { enabled });\n const data = query.data as {\n results?: GradeEntry[];\n previous?: string | null;\n next?: string | null;\n total_users_count?: number;\n filtered_users_count?: number;\n } | undefined;\n const results = useMemo(\n () => [...(data?.results ?? [])].sort(sortAlphaAsc),\n [data],\n );\n return {\n results,\n prevPage: data?.previous ?? null,\n nextPage: data?.next ?? null,\n totalUsersCount: data?.total_users_count ?? 0,\n filteredUsersCount: data?.filtered_users_count ?? 0,\n isFetching: query.isFetching,\n isError: query.isError,\n isSuccess: query.isSuccess,\n };\n};\n\n/**\n * useGradeOverrideHistory(subsectionId, userId)\n * Grade-override history for a single learner/subsection, used by the edit modal.\n * Enabled only once both identifiers are present (i.e. the modal has been opened\n * for a specific cell). `retry: false` because a `success: false` business error\n * is not worth retrying.\n */\nexport const useGradeOverrideHistory = (subsectionId?: string, userId?: string | number) => (\n useQuery({\n queryKey: gradeOverrideHistoryQueryKeys.byCell(subsectionId ?? null, userId ?? null),\n queryFn: () => getGradeOverrideHistory(subsectionId as string, userId as string | number),\n enabled: !!subsectionId && userId !== undefined && userId !== null,\n retry: false,\n })\n);\n\n/** Shape of the rejection thrown by `uploadGradeCsv` (an HTTP response, not an Error). */\ninterface CsvUploadError {\n status?: number;\n data?: { error_messages?: string[]; saved?: number; total?: number };\n}\n\n/** One grade-override entry sent to the gradebook bulk-update endpoint. */\ninterface GradeOverrideUpdate {\n grade: {\n comment: string;\n earned_graded_override: string | number;\n };\n usage_id: string | null;\n user_id: number | null;\n}\n\n/**\n * useUpdateGrades()\n * Grade-override save from the edit modal. The HTTP call runs through React Query;\n * success emits the Segment `update.*` event, shows the success banner, resets to\n * the first grades page, and invalidates the grades query (so the table reflects\n * the override) and the edited cell's override history (so reopening the modal\n * shows the new entry).\n *\n * The payload is captured as mutation variables when the trigger is called (same\n * shape as the old `selectors.app.editUpdateData`): the caller closes the modal\n * right after triggering the save, and a pending mutation picks up re-rendered\n * options, so a closure over `modalState` would read the reset (empty) state.\n *\n * Returns a no-arg trigger to match the legacy `useUpdateGrades()` call site.\n */\nexport const useUpdateGrades = () => {\n const queryClient = useQueryClient();\n const { courseId = '' } = useParams();\n const { setShowSuccess, setGradesPageEndpoint, modalState } = useGradebookUi();\n const mutation = useMutation({\n mutationFn: (updateData: GradeOverrideUpdate[]) => lms.api.updateGradebookData(updateData),\n onSuccess: ({ data }, updateData) => {\n trackGradeOverrideSucceeded(data);\n setShowSuccess(true);\n setGradesPageEndpoint(null);\n queryClient.invalidateQueries({\n queryKey: gradesQueryKeys.byCourse(courseId),\n });\n updateData.forEach(({ usage_id: usageId, user_id: userId }) => {\n queryClient.invalidateQueries({\n queryKey: gradeOverrideHistoryQueryKeys.byCell(usageId, userId),\n });\n });\n },\n onError: (error) => {\n trackGradeOverrideFailed(error);\n },\n });\n return () => {\n mutation.mutate([{\n grade: {\n comment: modalState.reasonForChange,\n earned_graded_override: modalState.adjustedGradeValue,\n },\n usage_id: modalState.updateModuleId,\n user_id: modalState.updateUserId,\n }]);\n };\n};\n\n/**\n * useSubmitImportGradesButtonData()\n * Bulk grade-override CSV upload. The upload runs through React Query and, on\n * success, invalidates the bulk-operation-history query so the new upload shows up.\n * CSV progress/results/toast are React UI state (GradebookUi context) and success/\n * failure emit the Segment `uploadOverride.*` events.\n *\n * Returns `(formData) => Promise` whose promise always resolves (errors are handled\n * inside `onError`), matching the legacy thunk so the caller's `.then(clearInput)`\n * still runs on both success and failure.\n */\nexport const useSubmitImportGradesButtonData = () => {\n const queryClient = useQueryClient();\n const { courseId = '' } = useParams();\n const {\n setShowImportSuccessToast,\n resetCsvUpload,\n markCsvUploadSuccess,\n setCsvUploadErrors,\n } = useGradebookUi();\n const mutation = useMutation<unknown, CsvUploadError, FormData>({\n mutationFn: (formData) => lms.api.uploadGradeCsv(formData),\n onMutate: () => {\n resetCsvUpload();\n },\n onSuccess: () => {\n markCsvUploadSuccess();\n setShowImportSuccessToast(true);\n trackUploadOverrideSucceeded();\n queryClient.invalidateQueries({\n queryKey: bulkOperationHistoryQueryKeys.byCourse(courseId),\n });\n },\n onError: (error) => {\n trackUploadOverrideFailed(error);\n if (error?.status === 200 && error?.data?.error_messages?.length) {\n const { error_messages: errorMessages } = error.data;\n setCsvUploadErrors(errorMessages);\n } else {\n setCsvUploadErrors(['Unknown error.']);\n }\n },\n });\n return (formData: FormData) => mutation.mutateAsync(formData).catch(() => {});\n};\n"]}
@@ -0,0 +1,32 @@
1
+ export function useGradesHeadings(): (string | undefined)[];
2
+ export function useSelectableAssignmentLabels(): import("./utils").AssignmentSummary[];
3
+ export function useSelectedAssignmentData(): import("./utils").AssignmentSummary | undefined;
4
+ export function useSelectedAssignmentLabel(): string | undefined;
5
+ export function useShouldShowSpinner(): boolean;
6
+ export function useAllGrades(): import("./apiHook").GradeEntry[];
7
+ export function useUserCounts(): {
8
+ filteredUsersCount: number;
9
+ totalUsersCount: number;
10
+ };
11
+ export function useGradeData(): {
12
+ nextPage: string | null;
13
+ prevPage: string | null;
14
+ totalUsersCount: number;
15
+ filteredUsersCount: number;
16
+ gradeFormat: string;
17
+ };
18
+ export function useGradeExportUrl(): any;
19
+ export function useInterventionExportUrl(): any;
20
+ export function useFilterBadgeConfig(filterName: any): any;
21
+ export function useGradeOverrideData(): {
22
+ gradeOverrideHistoryResults: any[];
23
+ gradeOverrideCurrentEarnedGradedOverride: number | null;
24
+ gradeOriginalEarnedGraded: number | null;
25
+ gradeOriginalPossibleGraded: number | null;
26
+ gradeOverrideHistoryError: string;
27
+ hasOverrideErrors: boolean;
28
+ };
29
+ export function useEditModalPossibleGrade(): string | number | null;
30
+ export function useRefetchGrades(): () => void;
31
+ export function useFetchGradesIfAssignmentGradeFiltersSet(): () => void;
32
+ export function useFetchPrevNextGrades(): (endpoint: any) => void;
@@ -0,0 +1,242 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { useMemo } from 'react';
13
+ import { useIsMutating, useQueryClient } from '@tanstack/react-query';
14
+ import { useParams } from 'react-router-dom';
15
+ import lms from '../../../data/services/lms';
16
+ import initialFilters, { filterConfig, filters as filterNames } from '../../../data/constants/filters';
17
+ import { useFilters } from '../../../data/filtersContext';
18
+ import { useGradebookUi } from '../../../data/gradebookUiContext';
19
+ import { useCanViewGradebook } from '../../../data/apiHook';
20
+ import { useSelectedCohortEntry, useSelectedTrackEntry, } from '../../GradebookFilters/data/hooks';
21
+ import { useGradesData, useGradeOverrideHistory } from './apiHook';
22
+ import { gradesQueryKeys } from './queryKeys';
23
+ import { chooseRelevantAssignmentData, formatMaxAssignmentGrade, formatMaxCourseGrade, formatMinAssignmentGrade, formatMinCourseGrade, getAssignmentsFromResultsSubstate, headingMapper, isDefault, relevantAssignmentDataFromResults, } from './utils';
24
+ // Stable empty reference so read hooks don't return a fresh array each render.
25
+ const EMPTY_ARRAY = [];
26
+ /**
27
+ * useGradesHeadings()
28
+ * The gradebook table headings for the current assignment-type / assignment
29
+ * filters, derived from the grades query's section breakdown.
30
+ */
31
+ export const useGradesHeadings = () => {
32
+ const { results } = useGradesData();
33
+ const { assignmentType, assignment: assignmentId } = useFilters();
34
+ return useMemo(() => {
35
+ var _a;
36
+ const selectedAssignmentLabel = (_a = relevantAssignmentDataFromResults(results, assignmentId)) === null || _a === void 0 ? void 0 : _a.label;
37
+ const sectionBreakdown = getAssignmentsFromResultsSubstate(results);
38
+ return headingMapper(assignmentType || 'All', selectedAssignmentLabel || 'All')(sectionBreakdown);
39
+ }, [results, assignmentType, assignmentId]);
40
+ };
41
+ /**
42
+ * useSelectableAssignmentLabels()
43
+ * The assignment options for the assignment dropdown, derived from the grades
44
+ * results and filtered by the current assignment-type.
45
+ */
46
+ export const useSelectableAssignmentLabels = () => {
47
+ const { results } = useGradesData();
48
+ const { assignmentType } = useFilters();
49
+ return useMemo(() => {
50
+ const all = getAssignmentsFromResultsSubstate(results)
51
+ .map(chooseRelevantAssignmentData);
52
+ return (assignmentType && assignmentType !== 'All')
53
+ ? all.filter((assignment) => assignment.type === assignmentType)
54
+ : all;
55
+ }, [results, assignmentType]);
56
+ };
57
+ /**
58
+ * useSelectedAssignmentData()
59
+ * The currently-selected assignment's data (label/type/id, from the grades
60
+ * results), or undefined when no assignment is selected.
61
+ */
62
+ export const useSelectedAssignmentData = () => {
63
+ const { results } = useGradesData();
64
+ const { assignment: assignmentId } = useFilters();
65
+ return useMemo(() => relevantAssignmentDataFromResults(results, assignmentId), [results, assignmentId]);
66
+ };
67
+ /**
68
+ * useSelectedAssignmentLabel()
69
+ * The label of the currently-selected assignment (from the grades results).
70
+ */
71
+ export const useSelectedAssignmentLabel = () => { var _a; return (_a = useSelectedAssignmentData()) === null || _a === void 0 ? void 0 : _a.label; };
72
+ /**
73
+ * useShouldShowSpinner()
74
+ * The busy indicator: the roles gate combined with the grades query fetching or
75
+ * any in-flight mutation (grade override save / CSV upload).
76
+ */
77
+ export const useShouldShowSpinner = () => {
78
+ const canViewGradebook = useCanViewGradebook();
79
+ const { isFetching } = useGradesData();
80
+ const mutatingCount = useIsMutating();
81
+ return canViewGradebook && (isFetching || mutatingCount > 0);
82
+ };
83
+ /**
84
+ * useAllGrades()
85
+ * The (sorted) grades rows for the table.
86
+ */
87
+ export const useAllGrades = () => useGradesData().results;
88
+ /**
89
+ * useUserCounts()
90
+ * Filtered/total user counts from the grades query.
91
+ */
92
+ export const useUserCounts = () => {
93
+ const { filteredUsersCount, totalUsersCount } = useGradesData();
94
+ return { filteredUsersCount, totalUsersCount };
95
+ };
96
+ /**
97
+ * useGradeData()
98
+ * The pagination cursors + counts (from the grades query) plus the current
99
+ * `gradeFormat` (from the GradebookUi context).
100
+ */
101
+ export const useGradeData = () => {
102
+ const { nextPage, prevPage, totalUsersCount, filteredUsersCount, } = useGradesData();
103
+ const { gradeFormat } = useGradebookUi();
104
+ return {
105
+ nextPage, prevPage, totalUsersCount, filteredUsersCount, gradeFormat,
106
+ };
107
+ };
108
+ // Export URL args, built from the FiltersProvider (applied grade limits + the
109
+ // immediate filters) and the selected cohort name. Reuses the pure
110
+ // `format*` helpers so the CSV/intervention URL formatting is unchanged.
111
+ const useLmsApiServiceArgs = () => {
112
+ const { assignment, assignmentType, track, includeCourseRoleMembers, appliedAssignmentGradeMin, appliedAssignmentGradeMax, appliedCourseGradeMin, appliedCourseGradeMax, } = useFilters();
113
+ const selectedCohort = useSelectedCohortEntry();
114
+ const assignmentId = assignment || undefined;
115
+ const opts = { assignmentId };
116
+ return {
117
+ cohort: selectedCohort ? selectedCohort.name : undefined,
118
+ track,
119
+ assignment: assignmentId,
120
+ assignmentType,
121
+ assignmentGradeMin: formatMinAssignmentGrade(appliedAssignmentGradeMin, opts),
122
+ assignmentGradeMax: formatMaxAssignmentGrade(appliedAssignmentGradeMax, opts),
123
+ courseGradeMin: formatMinCourseGrade(appliedCourseGradeMin),
124
+ courseGradeMax: formatMaxCourseGrade(appliedCourseGradeMax),
125
+ excludedCourseRoles: includeCourseRoleMembers ? '' : 'all',
126
+ };
127
+ };
128
+ export const useGradeExportUrl = () => lms.urls.gradeCsvUrl(useLmsApiServiceArgs());
129
+ export const useInterventionExportUrl = () => lms.urls.interventionExportCsvUrl(useLmsApiServiceArgs());
130
+ /**
131
+ * useFilterBadgeConfig(filterName)
132
+ * The badge config (value + isDefault) for a given filter, built from the
133
+ * FiltersProvider (immediate filters + applied grade limits + query-derived
134
+ * assignment label) and the selected cohort/track names. Reuses `filterConfig` +
135
+ * the pure `selectors.filters.isDefault` so formatting is unchanged.
136
+ */
137
+ export const useFilterBadgeConfig = (filterName) => {
138
+ const selectedCohort = useSelectedCohortEntry();
139
+ const selectedTrack = useSelectedTrackEntry();
140
+ const selectedAssignmentLabel = useSelectedAssignmentLabel();
141
+ const { assignmentType, includeCourseRoleMembers, appliedAssignmentGradeMin, appliedAssignmentGradeMax, appliedCourseGradeMin, appliedCourseGradeMax, } = useFilters();
142
+ if (filterName === filterNames.cohort || filterName === filterNames.track) {
143
+ const entry = filterName === filterNames.cohort ? selectedCohort : selectedTrack;
144
+ const value = entry ? entry.name : '';
145
+ return Object.assign(Object.assign({}, filterConfig[filterName]), { value, isDefault: value === initialFilters[filterName] });
146
+ }
147
+ const _a = filterConfig[filterName], { filterOrder } = _a, config = __rest(_a, ["filterOrder"]);
148
+ if (filterOrder) {
149
+ const [min, max] = filterName === filterNames.assignmentGrade
150
+ ? [appliedAssignmentGradeMin, appliedAssignmentGradeMax]
151
+ : [appliedCourseGradeMin, appliedCourseGradeMax];
152
+ return Object.assign(Object.assign({}, config), { value: `${min} - ${max}`, isDefault: isDefault(filterOrder[0], min) && isDefault(filterOrder[1], max) });
153
+ }
154
+ const singleValues = {
155
+ [filterNames.assignmentType]: assignmentType,
156
+ [filterNames.assignment]: selectedAssignmentLabel || '',
157
+ [filterNames.includeCourseRoleMembers]: includeCourseRoleMembers,
158
+ };
159
+ const value = singleValues[filterName];
160
+ return Object.assign(Object.assign({}, config), { value, isDefault: isDefault(filterName, value) });
161
+ };
162
+ /**
163
+ * useGradeOverrideData()
164
+ * The edit-modal override read-model, sourced from the override-history query
165
+ * gated on the modal's subsection/user ids (from the GradebookUi context).
166
+ */
167
+ export const useGradeOverrideData = () => {
168
+ var _a, _b, _c, _d, _e;
169
+ const { modalState } = useGradebookUi();
170
+ const query = useGradeOverrideHistory(modalState.updateModuleId, modalState.updateUserId);
171
+ const { data } = query;
172
+ return {
173
+ gradeOverrideHistoryResults: (_a = data === null || data === void 0 ? void 0 : data.overrideHistory) !== null && _a !== void 0 ? _a : EMPTY_ARRAY,
174
+ gradeOverrideCurrentEarnedGradedOverride: (_b = data === null || data === void 0 ? void 0 : data.currentEarnedGradedOverride) !== null && _b !== void 0 ? _b : null,
175
+ gradeOriginalEarnedGraded: (_c = data === null || data === void 0 ? void 0 : data.originalGradeEarnedGraded) !== null && _c !== void 0 ? _c : null,
176
+ gradeOriginalPossibleGraded: (_d = data === null || data === void 0 ? void 0 : data.originalGradePossibleGraded) !== null && _d !== void 0 ? _d : null,
177
+ gradeOverrideHistoryError: query.isError ? (((_e = query.error) === null || _e === void 0 ? void 0 : _e.message) || '') : '',
178
+ hasOverrideErrors: query.isError,
179
+ };
180
+ };
181
+ /**
182
+ * useEditModalPossibleGrade()
183
+ * The edit-modal "possible" grade: the context `adjustedGradePossible` or, as a
184
+ * fallback, the override query's original possible-graded value.
185
+ */
186
+ export const useEditModalPossibleGrade = () => {
187
+ const { modalState } = useGradebookUi();
188
+ const { gradeOriginalPossibleGraded } = useGradeOverrideData();
189
+ return modalState.adjustedGradePossible || gradeOriginalPossibleGraded;
190
+ };
191
+ // Invalidate the main grades query, causing the mounted `useGrades` observer to
192
+ // refetch with the current filters.
193
+ const useInvalidateGrades = () => {
194
+ const queryClient = useQueryClient();
195
+ const { courseId = '' } = useParams();
196
+ return () => queryClient.invalidateQueries({ queryKey: gradesQueryKeys.byCourse(courseId) });
197
+ };
198
+ /**
199
+ * useRefetchGrades()
200
+ * Refetches the grades query from the first (unpaged) page with the latest
201
+ * filters. Always invalidates (the base-page cache entry may still be fresh, and
202
+ * a fresh entry is served as-is when the key flips back to it); when on a
203
+ * prev/next page, also clears the pagination cursor.
204
+ */
205
+ export const useRefetchGrades = () => {
206
+ const invalidateGrades = useInvalidateGrades();
207
+ const { gradesPageEndpoint, setGradesPageEndpoint } = useGradebookUi();
208
+ return () => {
209
+ if (gradesPageEndpoint !== null) {
210
+ setGradesPageEndpoint(null);
211
+ }
212
+ invalidateGrades();
213
+ };
214
+ };
215
+ /**
216
+ * useFetchGradesIfAssignmentGradeFiltersSet()
217
+ * Refetches from the start only when a non-default applied assignment-grade limit
218
+ * is set (mirrors the legacy `areAssignmentGradeFiltersSet` gate).
219
+ */
220
+ export const useFetchGradesIfAssignmentGradeFiltersSet = () => {
221
+ const refetchFromStart = useRefetchGrades();
222
+ const { appliedAssignmentGradeMin, appliedAssignmentGradeMax } = useFilters();
223
+ return () => {
224
+ const isSet = appliedAssignmentGradeMin !== initialFilters.assignmentGradeMin
225
+ || appliedAssignmentGradeMax !== initialFilters.assignmentGradeMax;
226
+ if (isSet) {
227
+ refetchFromStart();
228
+ }
229
+ };
230
+ };
231
+ /**
232
+ * useFetchPrevNextGrades()
233
+ * Pagination trigger: sets the page cursor in the GradebookUi context (the
234
+ * `useGrades` query keys off it and fetches that opaque prev/next URL).
235
+ */
236
+ export const useFetchPrevNextGrades = () => {
237
+ const { setGradesPageEndpoint } = useGradebookUi();
238
+ return (endpoint) => {
239
+ setGradesPageEndpoint(endpoint);
240
+ };
241
+ };
242
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../../src/components/GradesView/data/hooks.js"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from 'react';\nimport { useIsMutating, useQueryClient } from '@tanstack/react-query';\nimport { useParams } from 'react-router-dom';\n\nimport lms from '@src/data/services/lms';\nimport initialFilters, { filterConfig, filters as filterNames } from '@src/data/constants/filters';\nimport { useFilters } from '@src/data/filtersContext';\nimport { useGradebookUi } from '@src/data/gradebookUiContext';\nimport { useCanViewGradebook } from '@src/data/apiHook';\nimport {\n useSelectedCohortEntry,\n useSelectedTrackEntry,\n} from '@src/components/GradebookFilters/data/hooks';\n\nimport { useGradesData, useGradeOverrideHistory } from './apiHook';\nimport { gradesQueryKeys } from './queryKeys';\nimport {\n chooseRelevantAssignmentData,\n formatMaxAssignmentGrade,\n formatMaxCourseGrade,\n formatMinAssignmentGrade,\n formatMinCourseGrade,\n getAssignmentsFromResultsSubstate,\n headingMapper,\n isDefault,\n relevantAssignmentDataFromResults,\n} from './utils';\n\n// Stable empty reference so read hooks don't return a fresh array each render.\nconst EMPTY_ARRAY = [];\n\n/**\n * useGradesHeadings()\n * The gradebook table headings for the current assignment-type / assignment\n * filters, derived from the grades query's section breakdown.\n */\nexport const useGradesHeadings = () => {\n const { results } = useGradesData();\n const { assignmentType, assignment: assignmentId } = useFilters();\n return useMemo(() => {\n const selectedAssignmentLabel = relevantAssignmentDataFromResults(results, assignmentId)?.label;\n const sectionBreakdown = getAssignmentsFromResultsSubstate(results);\n return headingMapper(\n assignmentType || 'All',\n selectedAssignmentLabel || 'All',\n )(sectionBreakdown);\n }, [results, assignmentType, assignmentId]);\n};\n\n/**\n * useSelectableAssignmentLabels()\n * The assignment options for the assignment dropdown, derived from the grades\n * results and filtered by the current assignment-type.\n */\nexport const useSelectableAssignmentLabels = () => {\n const { results } = useGradesData();\n const { assignmentType } = useFilters();\n return useMemo(() => {\n const all = getAssignmentsFromResultsSubstate(results)\n .map(chooseRelevantAssignmentData);\n return (assignmentType && assignmentType !== 'All')\n ? all.filter((assignment) => assignment.type === assignmentType)\n : all;\n }, [results, assignmentType]);\n};\n\n/**\n * useSelectedAssignmentData()\n * The currently-selected assignment's data (label/type/id, from the grades\n * results), or undefined when no assignment is selected.\n */\nexport const useSelectedAssignmentData = () => {\n const { results } = useGradesData();\n const { assignment: assignmentId } = useFilters();\n return useMemo(\n () => relevantAssignmentDataFromResults(results, assignmentId),\n [results, assignmentId],\n );\n};\n\n/**\n * useSelectedAssignmentLabel()\n * The label of the currently-selected assignment (from the grades results).\n */\nexport const useSelectedAssignmentLabel = () => useSelectedAssignmentData()?.label;\n\n/**\n * useShouldShowSpinner()\n * The busy indicator: the roles gate combined with the grades query fetching or\n * any in-flight mutation (grade override save / CSV upload).\n */\nexport const useShouldShowSpinner = () => {\n const canViewGradebook = useCanViewGradebook();\n const { isFetching } = useGradesData();\n const mutatingCount = useIsMutating();\n return canViewGradebook && (isFetching || mutatingCount > 0);\n};\n\n/**\n * useAllGrades()\n * The (sorted) grades rows for the table.\n */\nexport const useAllGrades = () => useGradesData().results;\n\n/**\n * useUserCounts()\n * Filtered/total user counts from the grades query.\n */\nexport const useUserCounts = () => {\n const { filteredUsersCount, totalUsersCount } = useGradesData();\n return { filteredUsersCount, totalUsersCount };\n};\n\n/**\n * useGradeData()\n * The pagination cursors + counts (from the grades query) plus the current\n * `gradeFormat` (from the GradebookUi context).\n */\nexport const useGradeData = () => {\n const {\n nextPage, prevPage, totalUsersCount, filteredUsersCount,\n } = useGradesData();\n const { gradeFormat } = useGradebookUi();\n return {\n nextPage, prevPage, totalUsersCount, filteredUsersCount, gradeFormat,\n };\n};\n\n// Export URL args, built from the FiltersProvider (applied grade limits + the\n// immediate filters) and the selected cohort name. Reuses the pure\n// `format*` helpers so the CSV/intervention URL formatting is unchanged.\nconst useLmsApiServiceArgs = () => {\n const {\n assignment, assignmentType, track, includeCourseRoleMembers,\n appliedAssignmentGradeMin, appliedAssignmentGradeMax,\n appliedCourseGradeMin, appliedCourseGradeMax,\n } = useFilters();\n const selectedCohort = useSelectedCohortEntry();\n const assignmentId = assignment || undefined;\n const opts = { assignmentId };\n return {\n cohort: selectedCohort ? selectedCohort.name : undefined,\n track,\n assignment: assignmentId,\n assignmentType,\n assignmentGradeMin: formatMinAssignmentGrade(appliedAssignmentGradeMin, opts),\n assignmentGradeMax: formatMaxAssignmentGrade(appliedAssignmentGradeMax, opts),\n courseGradeMin: formatMinCourseGrade(appliedCourseGradeMin),\n courseGradeMax: formatMaxCourseGrade(appliedCourseGradeMax),\n excludedCourseRoles: includeCourseRoleMembers ? '' : 'all',\n };\n};\n\nexport const useGradeExportUrl = () => lms.urls.gradeCsvUrl(useLmsApiServiceArgs());\nexport const useInterventionExportUrl = () => lms.urls.interventionExportCsvUrl(useLmsApiServiceArgs());\n\n/**\n * useFilterBadgeConfig(filterName)\n * The badge config (value + isDefault) for a given filter, built from the\n * FiltersProvider (immediate filters + applied grade limits + query-derived\n * assignment label) and the selected cohort/track names. Reuses `filterConfig` +\n * the pure `selectors.filters.isDefault` so formatting is unchanged.\n */\nexport const useFilterBadgeConfig = (filterName) => {\n const selectedCohort = useSelectedCohortEntry();\n const selectedTrack = useSelectedTrackEntry();\n const selectedAssignmentLabel = useSelectedAssignmentLabel();\n const {\n assignmentType, includeCourseRoleMembers,\n appliedAssignmentGradeMin, appliedAssignmentGradeMax,\n appliedCourseGradeMin, appliedCourseGradeMax,\n } = useFilters();\n\n if (filterName === filterNames.cohort || filterName === filterNames.track) {\n const entry = filterName === filterNames.cohort ? selectedCohort : selectedTrack;\n const value = entry ? entry.name : '';\n return {\n ...filterConfig[filterName],\n value,\n isDefault: value === initialFilters[filterName],\n };\n }\n\n const { filterOrder, ...config } = filterConfig[filterName];\n\n if (filterOrder) {\n const [min, max] = filterName === filterNames.assignmentGrade\n ? [appliedAssignmentGradeMin, appliedAssignmentGradeMax]\n : [appliedCourseGradeMin, appliedCourseGradeMax];\n return {\n ...config,\n value: `${min} - ${max}`,\n isDefault: isDefault(filterOrder[0], min) && isDefault(filterOrder[1], max),\n };\n }\n\n const singleValues = {\n [filterNames.assignmentType]: assignmentType,\n [filterNames.assignment]: selectedAssignmentLabel || '',\n [filterNames.includeCourseRoleMembers]: includeCourseRoleMembers,\n };\n const value = singleValues[filterName];\n return { ...config, value, isDefault: isDefault(filterName, value) };\n};\n\n/**\n * useGradeOverrideData()\n * The edit-modal override read-model, sourced from the override-history query\n * gated on the modal's subsection/user ids (from the GradebookUi context).\n */\nexport const useGradeOverrideData = () => {\n const { modalState } = useGradebookUi();\n const query = useGradeOverrideHistory(modalState.updateModuleId, modalState.updateUserId);\n const { data } = query;\n return {\n gradeOverrideHistoryResults: data?.overrideHistory ?? EMPTY_ARRAY,\n gradeOverrideCurrentEarnedGradedOverride: data?.currentEarnedGradedOverride ?? null,\n gradeOriginalEarnedGraded: data?.originalGradeEarnedGraded ?? null,\n gradeOriginalPossibleGraded: data?.originalGradePossibleGraded ?? null,\n gradeOverrideHistoryError: query.isError ? (query.error?.message || '') : '',\n hasOverrideErrors: query.isError,\n };\n};\n\n/**\n * useEditModalPossibleGrade()\n * The edit-modal \"possible\" grade: the context `adjustedGradePossible` or, as a\n * fallback, the override query's original possible-graded value.\n */\nexport const useEditModalPossibleGrade = () => {\n const { modalState } = useGradebookUi();\n const { gradeOriginalPossibleGraded } = useGradeOverrideData();\n return modalState.adjustedGradePossible || gradeOriginalPossibleGraded;\n};\n\n// Invalidate the main grades query, causing the mounted `useGrades` observer to\n// refetch with the current filters.\nconst useInvalidateGrades = () => {\n const queryClient = useQueryClient();\n const { courseId = '' } = useParams();\n return () => queryClient.invalidateQueries({ queryKey: gradesQueryKeys.byCourse(courseId) });\n};\n\n/**\n * useRefetchGrades()\n * Refetches the grades query from the first (unpaged) page with the latest\n * filters. Always invalidates (the base-page cache entry may still be fresh, and\n * a fresh entry is served as-is when the key flips back to it); when on a\n * prev/next page, also clears the pagination cursor.\n */\nexport const useRefetchGrades = () => {\n const invalidateGrades = useInvalidateGrades();\n const { gradesPageEndpoint, setGradesPageEndpoint } = useGradebookUi();\n return () => {\n if (gradesPageEndpoint !== null) {\n setGradesPageEndpoint(null);\n }\n invalidateGrades();\n };\n};\n\n/**\n * useFetchGradesIfAssignmentGradeFiltersSet()\n * Refetches from the start only when a non-default applied assignment-grade limit\n * is set (mirrors the legacy `areAssignmentGradeFiltersSet` gate).\n */\nexport const useFetchGradesIfAssignmentGradeFiltersSet = () => {\n const refetchFromStart = useRefetchGrades();\n const { appliedAssignmentGradeMin, appliedAssignmentGradeMax } = useFilters();\n return () => {\n const isSet = appliedAssignmentGradeMin !== initialFilters.assignmentGradeMin\n || appliedAssignmentGradeMax !== initialFilters.assignmentGradeMax;\n if (isSet) {\n refetchFromStart();\n }\n };\n};\n\n/**\n * useFetchPrevNextGrades()\n * Pagination trigger: sets the page cursor in the GradebookUi context (the\n * `useGrades` query keys off it and fetches that opaque prev/next URL).\n */\nexport const useFetchPrevNextGrades = () => {\n const { setGradesPageEndpoint } = useGradebookUi();\n return (endpoint) => {\n setGradesPageEndpoint(endpoint);\n };\n};\n"]}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The main gradebook rows. The base key is a prefix of each paged key (see
3
+ * `useGrades`), so invalidating `byCourse(courseId)` refetches any page.
4
+ */
5
+ export declare const gradesQueryKeys: {
6
+ all: readonly ["gradebook"];
7
+ byCourse: (courseId: string) => readonly ["gradebook", string, "grades"];
8
+ };
9
+ /** Grade-override history for one learner on one subsection (edit modal). */
10
+ export declare const gradeOverrideHistoryQueryKeys: {
11
+ all: readonly ["gradebook", "gradeOverrideHistory"];
12
+ byCell: (subsectionId: string | null, userId: string | number | null) => readonly ["gradebook", "gradeOverrideHistory", string | null, string | number | null];
13
+ };
@@ -0,0 +1,15 @@
1
+ import { BASE_KEY } from '../../../data/queryKeys';
2
+ /**
3
+ * The main gradebook rows. The base key is a prefix of each paged key (see
4
+ * `useGrades`), so invalidating `byCourse(courseId)` refetches any page.
5
+ */
6
+ export const gradesQueryKeys = {
7
+ all: BASE_KEY,
8
+ byCourse: (courseId) => [...BASE_KEY, courseId, 'grades'],
9
+ };
10
+ /** Grade-override history for one learner on one subsection (edit modal). */
11
+ export const gradeOverrideHistoryQueryKeys = {
12
+ all: [...BASE_KEY, 'gradeOverrideHistory'],
13
+ byCell: (subsectionId, userId) => [...BASE_KEY, 'gradeOverrideHistory', subsectionId, userId],
14
+ };
15
+ //# sourceMappingURL=queryKeys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../../../src/components/GradesView/data/queryKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,GAAG,EAAE,QAAQ;IACb,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAU;CAC3E,CAAC;AAEF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,GAAG,EAAE,CAAC,GAAG,QAAQ,EAAE,sBAAsB,CAAU;IACnD,MAAM,EAAE,CACN,YAA2B,EAC3B,MAA8B,EAC9B,EAAE,CAAC,CAAC,GAAG,QAAQ,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,CAAU;CAC1E,CAAC","sourcesContent":["import { BASE_KEY } from '@src/data/queryKeys';\n\n/**\n * The main gradebook rows. The base key is a prefix of each paged key (see\n * `useGrades`), so invalidating `byCourse(courseId)` refetches any page.\n */\nexport const gradesQueryKeys = {\n all: BASE_KEY,\n byCourse: (courseId: string) => [...BASE_KEY, courseId, 'grades'] as const,\n};\n\n/** Grade-override history for one learner on one subsection (edit modal). */\nexport const gradeOverrideHistoryQueryKeys = {\n all: [...BASE_KEY, 'gradeOverrideHistory'] as const,\n byCell: (\n subsectionId: string | null,\n userId: string | number | null,\n ) => [...BASE_KEY, 'gradeOverrideHistory', subsectionId, userId] as const,\n};\n"]}