@datalayer/core 1.0.25 → 1.1.43

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 (359) hide show
  1. package/README.md +11 -134
  2. package/lib/api/index.d.ts +0 -9
  3. package/lib/api/index.js +0 -9
  4. package/lib/cli-login.js +167 -0
  5. package/lib/client/auth/AuthenticationManager.d.ts +3 -3
  6. package/lib/client/auth/AuthenticationManager.js +13 -13
  7. package/lib/client/auth/strategies.d.ts +2 -2
  8. package/lib/client/auth/strategies.js +6 -6
  9. package/lib/client/base.d.ts +9 -12
  10. package/lib/client/base.js +17 -19
  11. package/lib/client/index.d.ts +10 -98
  12. package/lib/client/index.js +12 -21
  13. package/lib/client/mixins/IAMMixin.js +26 -26
  14. package/lib/components/auth/Login.js +2 -2
  15. package/lib/components/avatars/UserAvatar.d.ts +16 -0
  16. package/lib/components/avatars/UserAvatar.js +47 -0
  17. package/lib/components/avatars/index.d.ts +1 -0
  18. package/lib/components/avatars/index.js +1 -0
  19. package/lib/components/billing/BillableAccountSelect.js +4 -0
  20. package/lib/components/billing/index.js +4 -0
  21. package/lib/components/context/index.d.ts +0 -1
  22. package/lib/components/context/index.js +0 -1
  23. package/lib/components/display/DisplayHandle.d.ts +12 -0
  24. package/lib/components/display/DisplayHandle.js +11 -0
  25. package/lib/components/display/LiveRelativeTime.js +4 -0
  26. package/lib/components/display/index.d.ts +1 -0
  27. package/lib/components/display/index.js +1 -0
  28. package/lib/components/flashes/index.d.ts +0 -1
  29. package/lib/components/flashes/index.js +0 -1
  30. package/lib/components/index.d.ts +0 -1
  31. package/lib/components/index.js +0 -1
  32. package/lib/components/principal/Principal.d.ts +7 -0
  33. package/lib/components/principal/Principal.js +153 -16
  34. package/lib/components/principal/PrincipalAvatar.d.ts +1 -1
  35. package/lib/components/principal/PrincipalAvatar.js +4 -28
  36. package/lib/components/principal/PrincipalBadge.js +4 -4
  37. package/lib/components/principal/PrincipalDetailsOverlay.d.ts +4 -2
  38. package/lib/components/principal/PrincipalDetailsOverlay.js +27 -7
  39. package/lib/components/principal/PrincipalSwitcherMenu.js +79 -42
  40. package/lib/components/progress/index.d.ts +0 -1
  41. package/lib/components/progress/index.js +0 -1
  42. package/lib/components/sharing/ShareAccessComponent.d.ts +3 -2
  43. package/lib/components/sharing/ShareAccessComponent.js +194 -147
  44. package/lib/components/sharing/SharingEditor.js +4 -0
  45. package/lib/components/snippets/index.d.ts +1 -1
  46. package/lib/components/snippets/index.js +1 -1
  47. package/lib/components/students/StudentResultCircle.d.ts +21 -0
  48. package/lib/components/students/StudentResultCircle.js +59 -0
  49. package/lib/components/students/index.d.ts +1 -1
  50. package/lib/components/students/index.js +1 -1
  51. package/lib/components/time/LiveRelativeTime.js +4 -0
  52. package/lib/components/time/index.js +4 -0
  53. package/lib/components/timeline/index.js +4 -0
  54. package/lib/components/tokens/index.d.ts +1 -1
  55. package/lib/components/tokens/index.js +1 -1
  56. package/lib/components/toolbars/index.d.ts +1 -3
  57. package/lib/components/toolbars/index.js +1 -3
  58. package/lib/config/Configuration.d.ts +13 -13
  59. package/lib/config/Configuration.js +5 -5
  60. package/lib/hooks/cacheConverters.d.ts +21 -0
  61. package/lib/hooks/cacheConverters.js +110 -0
  62. package/lib/hooks/index.d.ts +0 -2
  63. package/lib/hooks/index.js +0 -2
  64. package/lib/hooks/useCache.d.ts +64 -35
  65. package/lib/hooks/useCache.js +661 -306
  66. package/lib/hooks/useDatalayer.js +3 -1
  67. package/lib/hooks/useIAM.js +2 -4
  68. package/lib/hooks/useLocationHandles.d.ts +3 -1
  69. package/lib/hooks/useLocationHandles.js +2 -1
  70. package/lib/hooks/usePrincipalStore.d.ts +2 -2
  71. package/lib/hooks/usePrincipalStore.js +97 -14
  72. package/lib/hooks/useSelectedPrincipal.js +1 -1
  73. package/lib/hooks/useUser.js +19 -2
  74. package/lib/index.d.ts +1 -6
  75. package/lib/index.js +1 -13
  76. package/lib/main.js +3 -3
  77. package/lib/mocks/index.js +1 -1
  78. package/lib/mocks/models/index.d.ts +0 -1
  79. package/lib/mocks/models/index.js +0 -1
  80. package/lib/models/Datasource.d.ts +2 -2
  81. package/lib/models/IAM.d.ts +1 -1
  82. package/lib/models/School.d.ts +12 -3
  83. package/lib/models/Secret.d.ts +2 -2
  84. package/lib/models/Student.d.ts +13 -3
  85. package/lib/models/Usage.d.ts +11 -1
  86. package/lib/models/UserDTO.d.ts +2 -2
  87. package/lib/models/UserSettings.d.ts +1 -1
  88. package/lib/models/UserSettings.js +1 -1
  89. package/lib/models/index.d.ts +0 -30
  90. package/lib/models/index.js +0 -30
  91. package/lib/otel/client/OtelClient.d.ts +2 -2
  92. package/lib/otel/client/OtelClient.js +2 -2
  93. package/lib/otel/hooks/index.js +5 -5
  94. package/lib/otel/types.d.ts +1 -1
  95. package/lib/otel/views/OtelLive.js +1 -1
  96. package/lib/routes/index.d.ts +1 -0
  97. package/lib/routes/index.js +1 -0
  98. package/lib/routes/publicPaths.d.ts +23 -0
  99. package/lib/routes/publicPaths.js +74 -0
  100. package/lib/state/State.d.ts +0 -12
  101. package/lib/state/State.js +0 -12
  102. package/lib/state/substates/CoreState.js +13 -13
  103. package/lib/state/substates/IAMState.d.ts +1 -1
  104. package/lib/state/substates/IAMState.js +14 -14
  105. package/lib/state/substates/LayoutState.d.ts +12 -1
  106. package/lib/state/substates/SurveysState.d.ts +1 -1
  107. package/lib/state/substates/SurveysState.js +10 -10
  108. package/lib/state/substates/index.d.ts +0 -7
  109. package/lib/state/substates/index.js +0 -7
  110. package/lib/utils/Handles.js +3 -1
  111. package/lib/utils/index.d.ts +0 -1
  112. package/lib/utils/index.js +0 -1
  113. package/lib/views/api-keys/APIKeys.js +12 -3
  114. package/lib/views/datasources/DatasourceDetail.d.ts +1 -1
  115. package/lib/views/datasources/DatasourceNew.d.ts +1 -1
  116. package/lib/views/datasources/Datasources.d.ts +1 -1
  117. package/lib/views/datasources/Datasources.js +12 -3
  118. package/lib/views/iam/SignInSimple.d.ts +37 -1
  119. package/lib/views/iam/SignInSimple.js +111 -13
  120. package/package.json +5 -3
  121. package/lib/App.css +0 -47
  122. package/lib/App.d.ts +0 -3
  123. package/lib/App.js +0 -21
  124. package/lib/api/runtimes/checkpoints.d.ts +0 -122
  125. package/lib/api/runtimes/checkpoints.js +0 -118
  126. package/lib/api/runtimes/environments.d.ts +0 -9
  127. package/lib/api/runtimes/environments.js +0 -29
  128. package/lib/api/runtimes/healthz.d.ts +0 -15
  129. package/lib/api/runtimes/healthz.js +0 -44
  130. package/lib/api/runtimes/index.d.ts +0 -12
  131. package/lib/api/runtimes/index.js +0 -16
  132. package/lib/api/runtimes/runtimes.d.ts +0 -138
  133. package/lib/api/runtimes/runtimes.js +0 -230
  134. package/lib/api/runtimes/snapshots.d.ts +0 -38
  135. package/lib/api/runtimes/snapshots.js +0 -82
  136. package/lib/api/scheduler/index.d.ts +0 -6
  137. package/lib/api/scheduler/index.js +0 -10
  138. package/lib/api/scheduler/schedules.d.ts +0 -85
  139. package/lib/api/scheduler/schedules.js +0 -78
  140. package/lib/api/spacer/documents.d.ts +0 -12
  141. package/lib/api/spacer/documents.js +0 -43
  142. package/lib/api/spacer/healthz.d.ts +0 -15
  143. package/lib/api/spacer/healthz.js +0 -44
  144. package/lib/api/spacer/index.d.ts +0 -15
  145. package/lib/api/spacer/index.js +0 -19
  146. package/lib/api/spacer/items.d.ts +0 -25
  147. package/lib/api/spacer/items.js +0 -55
  148. package/lib/api/spacer/lexicals.d.ts +0 -34
  149. package/lib/api/spacer/lexicals.js +0 -89
  150. package/lib/api/spacer/notebooks.d.ts +0 -34
  151. package/lib/api/spacer/notebooks.js +0 -89
  152. package/lib/api/spacer/spaces.d.ts +0 -84
  153. package/lib/api/spacer/spaces.js +0 -170
  154. package/lib/api/spacer/users.d.ts +0 -9
  155. package/lib/api/spacer/users.js +0 -29
  156. package/lib/client/mixins/RuntimesMixin.d.ts +0 -93
  157. package/lib/client/mixins/RuntimesMixin.js +0 -229
  158. package/lib/client/mixins/SpacerMixin.d.ts +0 -210
  159. package/lib/client/mixins/SpacerMixin.js +0 -615
  160. package/lib/client/utils/spacerUtils.d.ts +0 -18
  161. package/lib/client/utils/spacerUtils.js +0 -32
  162. package/lib/collaboration/DatalayerCollaboration.d.ts +0 -13
  163. package/lib/collaboration/DatalayerCollaboration.js +0 -28
  164. package/lib/collaboration/DatalayerCollaborationProvider.d.ts +0 -60
  165. package/lib/collaboration/DatalayerCollaborationProvider.js +0 -163
  166. package/lib/collaboration/index.d.ts +0 -2
  167. package/lib/collaboration/index.js +0 -6
  168. package/lib/components/context/SpaceSelect.d.ts +0 -2
  169. package/lib/components/context/SpaceSelect.js +0 -42
  170. package/lib/components/flashes/FlashDisclaimer.d.ts +0 -2
  171. package/lib/components/flashes/FlashDisclaimer.js +0 -17
  172. package/lib/components/icons/ArtifactIcon.d.ts +0 -10
  173. package/lib/components/icons/ArtifactIcon.js +0 -58
  174. package/lib/components/icons/index.d.ts +0 -1
  175. package/lib/components/icons/index.js +0 -5
  176. package/lib/components/nbgrader/NbGradesDetails.d.ts +0 -5
  177. package/lib/components/nbgrader/NbGradesDetails.js +0 -14
  178. package/lib/components/nbgrader/index.d.ts +0 -1
  179. package/lib/components/nbgrader/index.js +0 -5
  180. package/lib/components/progress/CreditsIndicator.d.ts +0 -33
  181. package/lib/components/progress/CreditsIndicator.js +0 -23
  182. package/lib/components/runtimes/RuntimeCellVariables.d.ts +0 -39
  183. package/lib/components/runtimes/RuntimeCellVariables.js +0 -172
  184. package/lib/components/runtimes/RuntimeCellVariablesDialog.d.ts +0 -37
  185. package/lib/components/runtimes/RuntimeCellVariablesDialog.js +0 -101
  186. package/lib/components/runtimes/RuntimeLauncherDialog.d.ts +0 -57
  187. package/lib/components/runtimes/RuntimeLauncherDialog.js +0 -275
  188. package/lib/components/runtimes/RuntimePickerBase.d.ts +0 -69
  189. package/lib/components/runtimes/RuntimePickerBase.js +0 -122
  190. package/lib/components/runtimes/RuntimePickerCell.d.ts +0 -34
  191. package/lib/components/runtimes/RuntimePickerCell.js +0 -104
  192. package/lib/components/runtimes/RuntimePickerNotebook.d.ts +0 -42
  193. package/lib/components/runtimes/RuntimePickerNotebook.js +0 -232
  194. package/lib/components/runtimes/RuntimeReservationControl.d.ts +0 -47
  195. package/lib/components/runtimes/RuntimeReservationControl.js +0 -42
  196. package/lib/components/runtimes/RuntimeSimplePicker.d.ts +0 -38
  197. package/lib/components/runtimes/RuntimeSimplePicker.js +0 -155
  198. package/lib/components/runtimes/RuntimeTransfer.d.ts +0 -16
  199. package/lib/components/runtimes/RuntimeTransfer.js +0 -5
  200. package/lib/components/runtimes/RuntimeUtils.d.ts +0 -17
  201. package/lib/components/runtimes/RuntimeUtils.js +0 -178
  202. package/lib/components/runtimes/RuntimeVariables.d.ts +0 -38
  203. package/lib/components/runtimes/RuntimeVariables.js +0 -75
  204. package/lib/components/runtimes/index.d.ts +0 -11
  205. package/lib/components/runtimes/index.js +0 -15
  206. package/lib/components/scheduler/ScheduleMenu.d.ts +0 -54
  207. package/lib/components/scheduler/ScheduleMenu.js +0 -154
  208. package/lib/components/scheduler/index.d.ts +0 -1
  209. package/lib/components/scheduler/index.js +0 -5
  210. package/lib/components/snapshots/SandboxSnapshotMenu.d.ts +0 -33
  211. package/lib/components/snapshots/SandboxSnapshotMenu.js +0 -169
  212. package/lib/components/snapshots/index.d.ts +0 -1
  213. package/lib/components/snapshots/index.js +0 -5
  214. package/lib/components/snippets/SnippetDialog.d.ts +0 -42
  215. package/lib/components/snippets/SnippetDialog.js +0 -42
  216. package/lib/components/students/StudentItemStatus.d.ts +0 -7
  217. package/lib/components/students/StudentItemStatus.js +0 -66
  218. package/lib/components/tokens/SpaceVariantToken.d.ts +0 -5
  219. package/lib/components/tokens/SpaceVariantToken.js +0 -23
  220. package/lib/components/toolbars/AssignmentEditorToolbar.d.ts +0 -4
  221. package/lib/components/toolbars/AssignmentEditorToolbar.js +0 -18
  222. package/lib/components/toolbars/DocumentEditorToolbar.d.ts +0 -2
  223. package/lib/components/toolbars/DocumentEditorToolbar.js +0 -12
  224. package/lib/components/toolbars/NotebookEditorToolbar.d.ts +0 -29
  225. package/lib/components/toolbars/NotebookEditorToolbar.js +0 -30
  226. package/lib/examples/CellExample.d.ts +0 -6
  227. package/lib/examples/CellExample.js +0 -20
  228. package/lib/examples/NotebookExample.d.ts +0 -6
  229. package/lib/examples/NotebookExample.js +0 -19
  230. package/lib/examples/lexical-theme.css +0 -436
  231. package/lib/examples/notebooks/IPyWidgetsExample.ipynb.json +0 -101
  232. package/lib/examples/notebooks/IPyWidgetsExampleWithState.ipynb.json +0 -112
  233. package/lib/examples/notebooks/Lite.ipynb.json +0 -128
  234. package/lib/examples/notebooks/Matplotlib.ipynb.json +0 -137
  235. package/lib/examples/notebooks/NotebookExample1.ipynb.json +0 -126
  236. package/lib/examples/notebooks/NotebookExample2.ipynb.json +0 -48
  237. package/lib/examples/notebooks/NotebookOutputs.ipynb.json +0 -49
  238. package/lib/examples/notebooks/NotebookToCExample.ipynb.json +0 -102
  239. package/lib/examples/notebooks/PyGWalker.ipynb.json +0 -55
  240. package/lib/hooks/useCellOutputshot.d.ts +0 -4
  241. package/lib/hooks/useCellOutputshot.js +0 -25
  242. package/lib/hooks/useProjects.d.ts +0 -628
  243. package/lib/hooks/useProjects.js +0 -190
  244. package/lib/hooks/useRuntimes.d.ts +0 -5
  245. package/lib/hooks/useRuntimes.js +0 -34
  246. package/lib/mocks/jupyter/index.js +0 -5
  247. package/lib/mocks/models/CourseMock.d.ts +0 -6
  248. package/lib/mocks/models/CourseMock.js +0 -29
  249. package/lib/mocks/models/SpaceMock.d.ts +0 -6
  250. package/lib/mocks/models/SpaceMock.js +0 -25
  251. package/lib/models/Assignment.d.ts +0 -7
  252. package/lib/models/Assignment.js +0 -5
  253. package/lib/models/Cell.d.ts +0 -8
  254. package/lib/models/Cell.js +0 -5
  255. package/lib/models/CodeBlock.d.ts +0 -10
  256. package/lib/models/CodeBlock.js +0 -5
  257. package/lib/models/CodeSandboxSnapshot.d.ts +0 -92
  258. package/lib/models/CodeSandboxSnapshot.js +0 -13
  259. package/lib/models/CodeSandboxSnapshotDTO.d.ts +0 -173
  260. package/lib/models/CodeSandboxSnapshotDTO.js +0 -139
  261. package/lib/models/CodefeedBlocks.d.ts +0 -7
  262. package/lib/models/CodefeedBlocks.js +0 -5
  263. package/lib/models/Content.d.ts +0 -5
  264. package/lib/models/Content.js +0 -5
  265. package/lib/models/Course.d.ts +0 -17
  266. package/lib/models/Course.js +0 -5
  267. package/lib/models/Dataset.d.ts +0 -16
  268. package/lib/models/Dataset.js +0 -5
  269. package/lib/models/Document.d.ts +0 -8
  270. package/lib/models/Document.js +0 -5
  271. package/lib/models/Environment.d.ts +0 -86
  272. package/lib/models/Environment.js +0 -5
  273. package/lib/models/EnvironmentDTO.d.ts +0 -125
  274. package/lib/models/EnvironmentDTO.js +0 -88
  275. package/lib/models/Exercise.d.ts +0 -16
  276. package/lib/models/Exercise.js +0 -5
  277. package/lib/models/Item.d.ts +0 -20
  278. package/lib/models/Item.js +0 -5
  279. package/lib/models/ItemDTO.d.ts +0 -74
  280. package/lib/models/ItemDTO.js +0 -186
  281. package/lib/models/ItemType.d.ts +0 -2
  282. package/lib/models/ItemType.js +0 -5
  283. package/lib/models/Lesson.d.ts +0 -5
  284. package/lib/models/Lesson.js +0 -5
  285. package/lib/models/LexicalDTO.d.ts +0 -155
  286. package/lib/models/LexicalDTO.js +0 -157
  287. package/lib/models/Library.d.ts +0 -10
  288. package/lib/models/Library.js +0 -5
  289. package/lib/models/Notebook.d.ts +0 -11
  290. package/lib/models/Notebook.js +0 -5
  291. package/lib/models/NotebookDTO.d.ts +0 -96
  292. package/lib/models/NotebookDTO.js +0 -153
  293. package/lib/models/Page.d.ts +0 -41
  294. package/lib/models/Page.js +0 -25
  295. package/lib/models/PageTag.d.ts +0 -19
  296. package/lib/models/PageTag.js +0 -94
  297. package/lib/models/ProjectDTO.d.ts +0 -89
  298. package/lib/models/ProjectDTO.js +0 -131
  299. package/lib/models/Runtime.d.ts +0 -123
  300. package/lib/models/Runtime.js +0 -18
  301. package/lib/models/RuntimeDTO.d.ts +0 -191
  302. package/lib/models/RuntimeDTO.js +0 -204
  303. package/lib/models/Space.d.ts +0 -35
  304. package/lib/models/Space.js +0 -66
  305. package/lib/models/SpaceDTO.d.ts +0 -334
  306. package/lib/models/SpaceDTO.js +0 -244
  307. package/lib/models/SpaceItem.d.ts +0 -10
  308. package/lib/models/SpaceItem.js +0 -5
  309. package/lib/models/SpaceMember.d.ts +0 -6
  310. package/lib/models/SpaceMember.js +0 -5
  311. package/lib/models/StudentItem.d.ts +0 -21
  312. package/lib/models/StudentItem.js +0 -5
  313. package/lib/services/DatalayerServiceManager.d.ts +0 -22
  314. package/lib/services/DatalayerServiceManager.js +0 -69
  315. package/lib/services/index.d.ts +0 -4
  316. package/lib/services/index.js +0 -7
  317. package/lib/services/reconnectToRuntime.d.ts +0 -32
  318. package/lib/services/reconnectToRuntime.js +0 -59
  319. package/lib/state/substates/CellState.d.ts +0 -12
  320. package/lib/state/substates/CellState.js +0 -22
  321. package/lib/state/substates/DocumentState.d.ts +0 -10
  322. package/lib/state/substates/DocumentState.js +0 -14
  323. package/lib/state/substates/GradeState.d.ts +0 -10
  324. package/lib/state/substates/GradeState.js +0 -14
  325. package/lib/state/substates/JupyterLabState.d.ts +0 -16
  326. package/lib/state/substates/JupyterLabState.js +0 -17
  327. package/lib/state/substates/NbformatState.d.ts +0 -13
  328. package/lib/state/substates/NbformatState.js +0 -16
  329. package/lib/state/substates/RuntimesState.d.ts +0 -79
  330. package/lib/state/substates/RuntimesState.js +0 -180
  331. package/lib/state/substates/SpaceState.d.ts +0 -11
  332. package/lib/state/substates/SpaceState.js +0 -16
  333. package/lib/stateful/index.d.ts +0 -2
  334. package/lib/stateful/index.js +0 -6
  335. package/lib/stateful/jupyter/exec/Python.d.ts +0 -5
  336. package/lib/stateful/jupyter/exec/Python.js +0 -100
  337. package/lib/stateful/jupyter/exec/Snippets.d.ts +0 -105
  338. package/lib/stateful/jupyter/exec/Snippets.js +0 -101
  339. package/lib/stateful/jupyter/exec/index.d.ts +0 -2
  340. package/lib/stateful/jupyter/exec/index.js +0 -6
  341. package/lib/stateful/jupyter/index.d.ts +0 -2
  342. package/lib/stateful/jupyter/index.js +0 -6
  343. package/lib/stateful/jupyter/kernelsHandler.d.ts +0 -8
  344. package/lib/stateful/jupyter/kernelsHandler.js +0 -39
  345. package/lib/stateful/runtimes/actions.d.ts +0 -102
  346. package/lib/stateful/runtimes/actions.js +0 -249
  347. package/lib/stateful/runtimes/apis.d.ts +0 -273
  348. package/lib/stateful/runtimes/apis.js +0 -5
  349. package/lib/stateful/runtimes/index.d.ts +0 -5
  350. package/lib/stateful/runtimes/index.js +0 -9
  351. package/lib/stateful/runtimes/settings.d.ts +0 -15
  352. package/lib/stateful/runtimes/settings.js +0 -31
  353. package/lib/stateful/runtimes/snapshots.d.ts +0 -25
  354. package/lib/stateful/runtimes/snapshots.js +0 -150
  355. package/lib/stateful/runtimes/utils.d.ts +0 -7
  356. package/lib/stateful/runtimes/utils.js +0 -14
  357. package/lib/utils/Cells.d.ts +0 -2
  358. package/lib/utils/Cells.js +0 -28
  359. /package/lib/{mocks/jupyter/index.d.ts → cli-login.d.ts} +0 -0
@@ -36,8 +36,9 @@
36
36
  * }
37
37
  * ```
38
38
  */
39
- import { useQuery, useMutation, useQueryClient, } from '@tanstack/react-query';
40
- import { BOOTSTRAP_USER_ONBOARDING, asContact, asDatasource, asInvite, asOrganization, asPage, asSecret, asSpace, asTeam, asToken, asUser, } from '../models/index.js';
39
+ import { useQuery, useQueries, useMutation, useQueryClient, } from '@tanstack/react-query';
40
+ import { BOOTSTRAP_USER_ONBOARDING, asContact, asDatasource, asInvite, asOrganization, asSecret, asTeam, asToken, asUser, } from '../models/index.js';
41
+ import { asPage, asSpace } from './cacheConverters.js';
41
42
  import { useCoreStore, useIAMStore } from '../state/index.js';
42
43
  import { asDisplayName, namesAsInitials, asArray } from '../utils/index.js';
43
44
  import { useDatalayer } from './useDatalayer.js';
@@ -348,9 +349,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
348
349
  const { requestDatalayer } = useDatalayer({ loginRoute });
349
350
  const { checkIsOrganizationMember } = useAuthorization();
350
351
  // Hook for notebook upload/creation
351
- const { isLoading: notebookUploadLoading, uploadAndSubmit: uploadNotebook, progress: notebookUploadProgress, reset: resetNotebookUpload, } = useUploadForm(`${coreStore.configuration.spacerRunUrl}/api/spacer/v1/notebooks`);
352
+ const { isLoading: notebookUploadLoading, uploadAndSubmit: uploadNotebook, progress: notebookUploadProgress, reset: resetNotebookUpload, } = useUploadForm(`${coreStore.configuration.spacerUrl}/api/spacer/v1/notebooks`);
352
353
  // Hook for document upload/creation
353
- const { isLoading: documentUploadLoading, uploadAndSubmit: uploadDocument, progress: documentUploadProgress, reset: resetDocumentUpload, } = useUploadForm(`${coreStore.configuration.spacerRunUrl}/api/spacer/v1/lexicals`);
354
+ const { isLoading: documentUploadLoading, uploadAndSubmit: uploadDocument, progress: documentUploadProgress, reset: resetDocumentUpload, } = useUploadForm(`${coreStore.configuration.spacerUrl}/api/spacer/v1/lexicals`);
354
355
  // ============================================================================
355
356
  // Transformation Functions (kept from original useCache)
356
357
  // Note: These functions use 'any' because they handle dynamic API responses
@@ -361,6 +362,85 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
361
362
  return asUser(u);
362
363
  }
363
364
  };
365
+ const toStudent = (rawStudent) => {
366
+ if (!rawStudent) {
367
+ return undefined;
368
+ }
369
+ const baseUser = asUser(rawStudent);
370
+ const studentItems = new Map();
371
+ const rawItemsSource = rawStudent.student_items ??
372
+ rawStudent.studentItems ??
373
+ rawStudent.items ??
374
+ rawStudent.course_items ??
375
+ rawStudent.student_items_by_uid ??
376
+ rawStudent.studentItemsByUid;
377
+ const rawItems = Array.isArray(rawItemsSource)
378
+ ? rawItemsSource
379
+ : rawItemsSource && typeof rawItemsSource === 'object'
380
+ ? Object.values(rawItemsSource)
381
+ : [];
382
+ rawItems.forEach((studentItem) => {
383
+ const itemId = String(studentItem.item_uid ??
384
+ studentItem.item_uid_s ??
385
+ studentItem.itemId ??
386
+ studentItem.item_id ??
387
+ studentItem.item_id_s ??
388
+ '').trim();
389
+ if (!itemId) {
390
+ return;
391
+ }
392
+ const completedRaw = studentItem.completed_b ??
393
+ studentItem.completed ??
394
+ studentItem.is_completed_b ??
395
+ studentItem.isCompleted ??
396
+ studentItem.done_b ??
397
+ studentItem.done;
398
+ const completed = typeof completedRaw === 'string'
399
+ ? ['true', '1', 'yes'].includes(completedRaw.toLowerCase())
400
+ : Boolean(completedRaw);
401
+ const passRaw = studentItem.pass_b ??
402
+ studentItem.pass ??
403
+ studentItem.passed_b ??
404
+ studentItem.passed;
405
+ const pass = typeof passRaw === 'string'
406
+ ? ['true', '1', 'yes'].includes(passRaw.toLowerCase())
407
+ : passRaw;
408
+ const mapped = {
409
+ id: studentItem.uid ?? studentItem.id,
410
+ type: 'student_item',
411
+ itemId,
412
+ itemType: studentItem.item_type_s ??
413
+ studentItem.itemType ??
414
+ studentItem.type_s ??
415
+ studentItem.type,
416
+ score: studentItem.score_i ??
417
+ studentItem.score_f ??
418
+ studentItem.score ??
419
+ studentItem.total_score_f,
420
+ codeStudent: studentItem.code_student_t ?? studentItem.codeStudent,
421
+ completed,
422
+ pass,
423
+ nbgrades: studentItem.nbgrades ??
424
+ studentItem.grades ??
425
+ [],
426
+ nbgradesTotalPoints: studentItem.nbgrades_total_points_f ??
427
+ studentItem.nbgradesTotalPoints ??
428
+ studentItem.total_points_f ??
429
+ ((studentItem.item_type_s ?? studentItem.itemType ?? studentItem.type_s ?? studentItem.type) === 'assignment'
430
+ ? 0
431
+ : undefined),
432
+ nbgradesTotalScore: studentItem.nbgrades_total_score_f ??
433
+ studentItem.nbgradesTotalScore ??
434
+ studentItem.total_score_f ??
435
+ ((studentItem.item_type_s ?? studentItem.itemType ?? studentItem.type_s ?? studentItem.type) === 'assignment'
436
+ ? 0
437
+ : undefined),
438
+ };
439
+ studentItems.set(itemId, mapped);
440
+ });
441
+ baseUser.studentItems = studentItems;
442
+ return baseUser;
443
+ };
364
444
  const toOrganization = (org) => {
365
445
  return asOrganization(org);
366
446
  };
@@ -447,7 +527,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
447
527
  path: raw_dataset.s3_path_s,
448
528
  cdnUrl: raw_dataset.cdn_url_s,
449
529
  creationDate: new Date(raw_dataset.creation_ts_dt),
450
- public: raw_dataset.public_b ?? false,
530
+ public: raw_dataset.is_public_b ?? false,
451
531
  lastPublicationDate: raw_dataset.creation_ts_dt
452
532
  ? new Date(raw_dataset.creation_ts_dt)
453
533
  : undefined,
@@ -470,7 +550,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
470
550
  description: cl.description_t,
471
551
  source: cl.source_t,
472
552
  creationDate: new Date(cl.creation_ts_dt),
473
- public: cl.public_b ?? false,
553
+ public: cl.is_public_b ?? false,
474
554
  lastPublicationDate: cl.last_publication_ts_dt
475
555
  ? new Date(cl.last_publication_ts_dt)
476
556
  : undefined,
@@ -496,7 +576,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
496
576
  nbformat: raw_notebook.model_s
497
577
  ? JSON.parse(raw_notebook.model_s)
498
578
  : undefined,
499
- public: raw_notebook.public_b ?? false,
579
+ public: raw_notebook.is_public_b ?? false,
500
580
  creationDate: new Date(raw_notebook.creation_ts_dt),
501
581
  lastUpdateDate: raw_notebook.last_update_ts_dt
502
582
  ? new Date(raw_notebook.last_update_ts_dt)
@@ -523,7 +603,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
523
603
  name: doc.name_t,
524
604
  description: doc.description_t,
525
605
  model: doc.model_s ? JSON.parse(doc.model_s) : undefined,
526
- public: doc.public_b ?? false,
606
+ public: doc.is_public_b ?? false,
527
607
  creationDate: new Date(doc.creation_ts_dt),
528
608
  lastUpdateDate: doc.last_update_ts_dt
529
609
  ? new Date(doc.last_update_ts_dt)
@@ -549,7 +629,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
549
629
  name: raw_lesson.name_t,
550
630
  description: raw_lesson.description_t,
551
631
  nbformat: raw_lesson.model_s ? JSON.parse(raw_lesson.model_s) : undefined,
552
- public: raw_lesson.public_b ?? false,
632
+ public: raw_lesson.is_public_b ?? false,
553
633
  creationDate: new Date(raw_lesson.creation_ts_dt),
554
634
  lastUpdateDate: raw_lesson.last_update_ts_dt
555
635
  ? new Date(raw_lesson.last_update_ts_dt)
@@ -580,7 +660,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
580
660
  codeQuestion: ex.code_question_t,
581
661
  codeSolution: ex.code_solution_t,
582
662
  codeTest: ex.code_test_t,
583
- public: ex.public_b ?? false,
663
+ public: ex.is_public_b ?? false,
584
664
  creationDate: new Date(ex.creation_ts_dt),
585
665
  lastUpdateDate: ex.last_update_ts_dt
586
666
  ? new Date(ex.last_update_ts_dt)
@@ -623,7 +703,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
623
703
  nbformat: raw_assignment.model_s
624
704
  ? JSON.parse(raw_assignment.model_s)
625
705
  : undefined,
626
- public: raw_assignment.public_b ?? false,
706
+ public: raw_assignment.is_public_b ?? false,
627
707
  creationDate: new Date(raw_assignment.creation_ts_dt),
628
708
  lastUpdateDate: raw_assignment.last_update_ts_dt
629
709
  ? new Date(raw_assignment.last_update_ts_dt)
@@ -665,6 +745,24 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
665
745
  },
666
746
  };
667
747
  };
748
+ const toEvalset = (raw_evalset) => {
749
+ const owner = toItemOwner(raw_evalset);
750
+ return {
751
+ id: raw_evalset.uid,
752
+ type: 'evalset',
753
+ name: raw_evalset.name_t,
754
+ description: raw_evalset.description_t,
755
+ public: raw_evalset.is_public_b ?? false,
756
+ creationDate: raw_evalset.creation_ts_dt
757
+ ? new Date(raw_evalset.creation_ts_dt)
758
+ : undefined,
759
+ lastUpdateDate: raw_evalset.last_update_ts_dt
760
+ ? new Date(raw_evalset.last_update_ts_dt)
761
+ : undefined,
762
+ tags: Array.isArray(raw_evalset.tags_ss) ? raw_evalset.tags_ss : [],
763
+ owner,
764
+ };
765
+ };
668
766
  const toItem = (item) => {
669
767
  if (!item.type_s) {
670
768
  console.error('No type_s found on item', item);
@@ -675,6 +773,45 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
675
773
  return toAssignment(item);
676
774
  case 'cell':
677
775
  return toCell(item);
776
+ case 'course':
777
+ return {
778
+ id: item.uid,
779
+ type: 'course',
780
+ name: item.name_t,
781
+ description: item.description_t,
782
+ tags: item.tags_ss ?? [],
783
+ handle: item.handle_s ?? item.handle,
784
+ handle_s: item.handle_s,
785
+ organization_handle_s: item.organization_handle_s,
786
+ owner_handle_s: item.owner_handle_s,
787
+ organization: {
788
+ handle: item.organization_handle_s,
789
+ },
790
+ owner: {
791
+ handle: item.owner_handle_s,
792
+ },
793
+ };
794
+ case 'space': {
795
+ const variant = (item.variant_s ?? item.variant ?? '').toLowerCase();
796
+ return {
797
+ id: item.uid,
798
+ type: variant === 'course' ? 'course' : 'space',
799
+ name: item.name_t,
800
+ description: item.description_t,
801
+ tags: item.tags_ss ?? [],
802
+ variant,
803
+ handle: item.handle_s ?? item.handle,
804
+ handle_s: item.handle_s,
805
+ organization_handle_s: item.organization_handle_s,
806
+ owner_handle_s: item.owner_handle_s,
807
+ organization: {
808
+ handle: item.organization_handle_s,
809
+ },
810
+ owner: {
811
+ handle: item.owner_handle_s,
812
+ },
813
+ };
814
+ }
678
815
  case 'dataset':
679
816
  return toDataset(item);
680
817
  case 'document':
@@ -687,6 +824,8 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
687
824
  return toNotebook(item);
688
825
  case 'page':
689
826
  return toPage(item);
827
+ case 'evalset':
828
+ return toEvalset(item);
690
829
  default:
691
830
  return {};
692
831
  }
@@ -721,17 +860,26 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
721
860
  if (raw_course.students) {
722
861
  students = new Map();
723
862
  raw_course.students.forEach((raw_stud) => {
724
- const student = toUser(raw_stud);
863
+ const student = toStudent(raw_stud);
725
864
  if (student && students) {
726
865
  students.set(student.id, student);
727
866
  }
728
867
  });
729
868
  }
730
869
  let itemIds = new Array();
731
- let raw_item_uids = raw_course.item_uids_s;
732
- if (raw_item_uids && raw_item_uids !== '()') {
733
- raw_item_uids = raw_item_uids.replace('(', '').replace(')', '');
734
- itemIds = raw_item_uids.split(' ');
870
+ const rawItemUids = raw_course.item_uids_s;
871
+ if (Array.isArray(rawItemUids)) {
872
+ itemIds = Array.from(new Set(rawItemUids
873
+ .map(uid => String(uid || '').trim())
874
+ .filter(Boolean)));
875
+ }
876
+ else if (typeof rawItemUids === 'string' && rawItemUids !== '()') {
877
+ itemIds = Array.from(new Set(rawItemUids
878
+ .replace('(', ' ')
879
+ .replace(')', ' ')
880
+ .split(/[\s,]+/g)
881
+ .map(uid => uid.trim())
882
+ .filter(Boolean)));
735
883
  }
736
884
  const items = new Array();
737
885
  if (raw_course.items) {
@@ -773,7 +921,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
773
921
  return useMutation({
774
922
  mutationFn: async ({ handle, password, }) => {
775
923
  return requestDatalayer({
776
- url: `${configuration.iamRunUrl}/api/iam/v1/login`,
924
+ url: `${configuration.iamUrl}/api/iam/v1/login`,
777
925
  method: 'POST',
778
926
  body: { handle, password },
779
927
  });
@@ -800,7 +948,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
800
948
  return useMutation({
801
949
  mutationFn: async () => {
802
950
  return requestDatalayer({
803
- url: `${configuration.iamRunUrl}/api/iam/v1/logout`,
951
+ url: `${configuration.iamUrl}/api/iam/v1/logout`,
804
952
  method: 'GET',
805
953
  });
806
954
  },
@@ -822,7 +970,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
822
970
  queryKey: queryKeys.auth.me(),
823
971
  queryFn: async () => {
824
972
  const resp = await requestDatalayer({
825
- url: `${configuration.iamRunUrl}/api/iam/v1/me`,
973
+ url: `${configuration.iamUrl}/api/iam/v1/me`,
826
974
  method: 'GET',
827
975
  token,
828
976
  });
@@ -841,7 +989,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
841
989
  return useMutation({
842
990
  mutationFn: async ({ email, firstName, lastName, }) => {
843
991
  return requestDatalayer({
844
- url: `${configuration.iamRunUrl}/api/iam/v1/me`,
992
+ url: `${configuration.iamUrl}/api/iam/v1/me`,
845
993
  method: 'PUT',
846
994
  body: { email, firstName, lastName },
847
995
  });
@@ -859,7 +1007,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
859
1007
  queryKey: queryKeys.auth.whoami(),
860
1008
  queryFn: async () => {
861
1009
  return requestDatalayer({
862
- url: `${configuration.iamRunUrl}/api/iam/v1/whoami`,
1010
+ url: `${configuration.iamUrl}/api/iam/v1/whoami`,
863
1011
  method: 'GET',
864
1012
  });
865
1013
  },
@@ -882,7 +1030,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
882
1030
  queryKey: queryKeys.users.detail(userId),
883
1031
  queryFn: async () => {
884
1032
  const resp = await requestDatalayer({
885
- url: `${configuration.iamRunUrl}/api/iam/v1/users/${userId}`,
1033
+ url: `${configuration.iamUrl}/api/iam/v1/users/${userId}`,
886
1034
  method: 'GET',
887
1035
  });
888
1036
  if (resp.success && resp.user) {
@@ -910,7 +1058,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
910
1058
  // Implementation depends on your API
911
1059
  // For now, using search as workaround
912
1060
  const resp = await requestDatalayer({
913
- url: `${configuration.iamRunUrl}/api/iam/v1/users/search`,
1061
+ url: `${configuration.iamUrl}/api/iam/v1/users/search`,
914
1062
  method: 'POST',
915
1063
  body: { namingPattern: handle },
916
1064
  });
@@ -942,7 +1090,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
942
1090
  return null;
943
1091
  }
944
1092
  const resp = await requestDatalayer({
945
- url: `${configuration.iamRunUrl}/api/iam/v1/users/public/${encodeURIComponent(normalizedHandle)}`,
1093
+ url: `${configuration.iamUrl}/api/iam/v1/users/public/${encodeURIComponent(normalizedHandle)}`,
946
1094
  method: 'GET',
947
1095
  });
948
1096
  if (resp.success) {
@@ -978,7 +1126,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
978
1126
  queryKey: queryKeys.users.search(namingPattern),
979
1127
  queryFn: async () => {
980
1128
  const resp = await requestDatalayer({
981
- url: `${configuration.iamRunUrl}/api/iam/v1/users/search`,
1129
+ url: `${configuration.iamUrl}/api/iam/v1/users/search`,
982
1130
  method: 'POST',
983
1131
  body: { namingPattern },
984
1132
  });
@@ -1015,7 +1163,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1015
1163
  return [];
1016
1164
  }
1017
1165
  const resp = await requestDatalayer({
1018
- url: `${configuration.iamRunUrl}/api/iam/v1/users/bulk`,
1166
+ url: `${configuration.iamUrl}/api/iam/v1/users/bulk`,
1019
1167
  method: 'POST',
1020
1168
  body: { userIds: normalizedUserIds },
1021
1169
  });
@@ -1045,7 +1193,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1045
1193
  return useMutation({
1046
1194
  mutationFn: async (onboarding) => {
1047
1195
  return requestDatalayer({
1048
- url: `${configuration.iamRunUrl}/api/iam/v1/onboardings`,
1196
+ url: `${configuration.iamUrl}/api/iam/v1/onboardings`,
1049
1197
  method: 'PUT',
1050
1198
  body: { onboarding },
1051
1199
  });
@@ -1062,10 +1210,10 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1062
1210
  return useMutation({
1063
1211
  mutationFn: async ({ userId, settings, }) => {
1064
1212
  return requestDatalayer({
1065
- url: `${configuration.iamRunUrl}/api/iam/v1/users/${userId}/settings`,
1213
+ url: `${configuration.iamUrl}/api/iam/v1/users/${userId}/settings`,
1066
1214
  method: 'PUT',
1067
1215
  body: {
1068
- aiagents_url_s: settings.aiAgentsUrl,
1216
+ aiAgents_url_s: settings.aiAgentsUrl,
1069
1217
  can_invite_b: settings.canInvite || false,
1070
1218
  },
1071
1219
  });
@@ -1088,7 +1236,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1088
1236
  queryKey: queryKeys.organizations.detail(organizationId),
1089
1237
  queryFn: async () => {
1090
1238
  const resp = await requestDatalayer({
1091
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations/${organizationId}`,
1239
+ url: `${configuration.iamUrl}/api/iam/v1/organizations/${organizationId}`,
1092
1240
  method: 'GET',
1093
1241
  });
1094
1242
  if (resp.success && resp.organization) {
@@ -1112,7 +1260,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1112
1260
  queryFn: async () => {
1113
1261
  // Fetch via account endpoint
1114
1262
  const resp = await requestDatalayer({
1115
- url: `${configuration.iamRunUrl}/api/iam/v1/accounts/${handle}`,
1263
+ url: `${configuration.iamUrl}/api/iam/v1/accounts/${handle}`,
1116
1264
  method: 'GET',
1117
1265
  });
1118
1266
  if (resp.success && resp.organization) {
@@ -1139,7 +1287,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1139
1287
  return null;
1140
1288
  }
1141
1289
  const resp = await requestDatalayer({
1142
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations/public/${encodeURIComponent(normalizedHandle)}`,
1290
+ url: `${configuration.iamUrl}/api/iam/v1/organizations/public/${encodeURIComponent(normalizedHandle)}`,
1143
1291
  method: 'GET',
1144
1292
  });
1145
1293
  if (resp.success) {
@@ -1159,7 +1307,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1159
1307
  queryKey: queryKeys.organizations.userOrgs(),
1160
1308
  queryFn: async () => {
1161
1309
  const resp = await requestDatalayer({
1162
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations`,
1310
+ url: `${configuration.iamUrl}/api/iam/v1/organizations`,
1163
1311
  method: 'GET',
1164
1312
  });
1165
1313
  if (resp.success && resp.organizations) {
@@ -1185,7 +1333,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1185
1333
  return useMutation({
1186
1334
  mutationFn: async (organization) => {
1187
1335
  return requestDatalayer({
1188
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations`,
1336
+ url: `${configuration.iamUrl}/api/iam/v1/organizations`,
1189
1337
  method: 'POST',
1190
1338
  body: {
1191
1339
  handle: organization.handle,
@@ -1214,7 +1362,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1214
1362
  return useMutation({
1215
1363
  mutationFn: async (organization) => {
1216
1364
  return requestDatalayer({
1217
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations/${organization.id}`,
1365
+ url: `${configuration.iamUrl}/api/iam/v1/organizations/${organization.id}`,
1218
1366
  method: 'PUT',
1219
1367
  body: {
1220
1368
  name: organization.name,
@@ -1246,7 +1394,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1246
1394
  queryKey: queryKeys.teams.detail(teamId),
1247
1395
  queryFn: async () => {
1248
1396
  const resp = await requestDatalayer({
1249
- url: `${configuration.iamRunUrl}/api/iam/v1/teams/${teamId}`,
1397
+ url: `${configuration.iamUrl}/api/iam/v1/teams/${teamId}`,
1250
1398
  method: 'GET',
1251
1399
  });
1252
1400
  if (resp.success && resp.team) {
@@ -1268,7 +1416,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1268
1416
  queryKey: queryKeys.teams.byOrganization(organizationId),
1269
1417
  queryFn: async () => {
1270
1418
  const resp = await requestDatalayer({
1271
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations/${organizationId}/teams`,
1419
+ url: `${configuration.iamUrl}/api/iam/v1/organizations/${organizationId}/teams`,
1272
1420
  method: 'GET',
1273
1421
  });
1274
1422
  if (resp.success && resp.teams) {
@@ -1294,7 +1442,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1294
1442
  return useMutation({
1295
1443
  mutationFn: async ({ team, organization, }) => {
1296
1444
  return requestDatalayer({
1297
- url: `${configuration.iamRunUrl}/api/iam/v1/teams`,
1445
+ url: `${configuration.iamUrl}/api/iam/v1/teams`,
1298
1446
  method: 'POST',
1299
1447
  body: {
1300
1448
  handle: team.handle,
@@ -1324,7 +1472,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1324
1472
  return useMutation({
1325
1473
  mutationFn: async (team) => {
1326
1474
  return requestDatalayer({
1327
- url: `${configuration.iamRunUrl}/api/iam/v1/teams/${team.id}`,
1475
+ url: `${configuration.iamUrl}/api/iam/v1/teams/${team.id}`,
1328
1476
  method: 'PUT',
1329
1477
  body: {
1330
1478
  name: team.name,
@@ -1356,7 +1504,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1356
1504
  queryFn: async () => {
1357
1505
  // Note: This might need organization context
1358
1506
  const resp = await requestDatalayer({
1359
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}`,
1507
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}`,
1360
1508
  method: 'GET',
1361
1509
  });
1362
1510
  if (resp.success && resp.space) {
@@ -1381,7 +1529,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1381
1529
  queryKey: queryKeys.spaces.detail(spaceId),
1382
1530
  queryFn: async () => {
1383
1531
  const resp = await requestDatalayer({
1384
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/organizations/${organizationId}`,
1532
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/organizations/${organizationId}`,
1385
1533
  method: 'GET',
1386
1534
  });
1387
1535
  if (resp.success && resp.space) {
@@ -1404,7 +1552,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1404
1552
  queryKey: queryKeys.spaces.byOrganization(organizationId),
1405
1553
  queryFn: async () => {
1406
1554
  const resp = await requestDatalayer({
1407
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/organizations/${organizationId}`,
1555
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/organizations/${organizationId}`,
1408
1556
  method: 'GET',
1409
1557
  });
1410
1558
  if (resp.success && resp.spaces) {
@@ -1441,7 +1589,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1441
1589
  }
1442
1590
  const query = params.toString();
1443
1591
  const resp = await requestDatalayer({
1444
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/users/me${query ? `?${query}` : ''}`,
1592
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/users/me${query ? `?${query}` : ''}`,
1445
1593
  method: 'GET',
1446
1594
  });
1447
1595
  if (resp.success && resp.spaces) {
@@ -1469,7 +1617,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1469
1617
  ? space.seedSpace?.id
1470
1618
  : undefined;
1471
1619
  const resp = await requestDatalayer({
1472
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces`,
1620
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces`,
1473
1621
  method: 'POST',
1474
1622
  body: {
1475
1623
  name: space.name,
@@ -1517,7 +1665,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1517
1665
  return requestDatalayer({
1518
1666
  // Use the canonical space update route. This keeps project runtime
1519
1667
  // assignment cleanup resilient when stale runtime links must be cleared.
1520
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${id}`,
1668
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${id}`,
1521
1669
  method: 'PUT',
1522
1670
  body: {
1523
1671
  name,
@@ -1546,11 +1694,16 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1546
1694
  return useMutation({
1547
1695
  mutationFn: async (spaceUid) => {
1548
1696
  return requestDatalayer({
1549
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceUid}`,
1697
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceUid}`,
1550
1698
  method: 'DELETE',
1551
1699
  });
1552
1700
  },
1553
- onSuccess: () => {
1701
+ onSuccess: (_resp, deletedSpaceUid) => {
1702
+ const deletedUid = String(deletedSpaceUid || '').trim();
1703
+ // Invalidate deleted space detail cache and all list queries.
1704
+ queryClient.removeQueries({
1705
+ queryKey: queryKeys.spaces.detail(deletedUid),
1706
+ });
1554
1707
  // Invalidate all space queries
1555
1708
  queryClient.invalidateQueries({
1556
1709
  queryKey: queryKeys.spaces.all(),
@@ -1569,7 +1722,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1569
1722
  queryKey: queryKeys.notebooks.detail(notebookId),
1570
1723
  queryFn: async () => {
1571
1724
  const resp = await requestDatalayer({
1572
- url: `${configuration.spacerRunUrl}/api/spacer/v1/notebooks/${notebookId}`,
1725
+ url: `${configuration.spacerUrl}/api/spacer/v1/notebooks/${notebookId}`,
1573
1726
  method: 'GET',
1574
1727
  });
1575
1728
  if (resp.success && resp.notebook) {
@@ -1592,7 +1745,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1592
1745
  queryKey: queryKeys.notebooks.bySpace(spaceId),
1593
1746
  queryFn: async () => {
1594
1747
  const resp = await requestDatalayer({
1595
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/notebook`,
1748
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/notebook`,
1596
1749
  method: 'GET',
1597
1750
  });
1598
1751
  if (resp.success && resp.items) {
@@ -1616,6 +1769,8 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1616
1769
  return useMutation({
1617
1770
  mutationFn: async ({ spaceId, name, description, notebookType = 'notebook', file, }) => {
1618
1771
  const formData = new FormData();
1772
+ formData.append('space_id', spaceId);
1773
+ // Backward compatibility for endpoints still expecting camelCase.
1619
1774
  formData.append('spaceId', spaceId);
1620
1775
  formData.append('notebookType', notebookType);
1621
1776
  formData.append('name', name);
@@ -1648,7 +1803,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1648
1803
  return useMutation({
1649
1804
  mutationFn: async ({ id, name, description, }) => {
1650
1805
  return requestDatalayer({
1651
- url: `${configuration.spacerRunUrl}/api/spacer/v1/notebooks/${id}`,
1806
+ url: `${configuration.spacerUrl}/api/spacer/v1/notebooks/${id}`,
1652
1807
  method: 'PUT',
1653
1808
  body: { name, description },
1654
1809
  });
@@ -1674,7 +1829,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1674
1829
  return useMutation({
1675
1830
  mutationFn: async ({ notebookId, nbformat, }) => {
1676
1831
  return requestDatalayer({
1677
- url: `${configuration.spacerRunUrl}/api/spacer/v1/notebooks/${notebookId}/model`,
1832
+ url: `${configuration.spacerUrl}/api/spacer/v1/notebooks/${notebookId}/model`,
1678
1833
  method: 'PUT',
1679
1834
  body: { nbformat },
1680
1835
  });
@@ -1699,7 +1854,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1699
1854
  return useMutation({
1700
1855
  mutationFn: async (notebookId) => {
1701
1856
  return requestDatalayer({
1702
- url: `${configuration.spacerRunUrl}/api/spacer/v1/notebooks/${notebookId}/clone`,
1857
+ url: `${configuration.spacerUrl}/api/spacer/v1/notebooks/${notebookId}/clone`,
1703
1858
  method: 'POST',
1704
1859
  });
1705
1860
  },
@@ -1729,7 +1884,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1729
1884
  queryKey: queryKeys.documents.detail(documentId),
1730
1885
  queryFn: async () => {
1731
1886
  const resp = await requestDatalayer({
1732
- url: `${configuration.spacerRunUrl}/api/spacer/v1/lexicals/${documentId}`,
1887
+ url: `${configuration.spacerUrl}/api/spacer/v1/lexicals/${documentId}`,
1733
1888
  method: 'GET',
1734
1889
  });
1735
1890
  if (resp.success && resp.document) {
@@ -1755,7 +1910,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1755
1910
  return [];
1756
1911
  }
1757
1912
  const resp = await requestDatalayer({
1758
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/document`,
1913
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/document`,
1759
1914
  method: 'GET',
1760
1915
  });
1761
1916
  if (resp.success && resp.items) {
@@ -1779,7 +1934,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1779
1934
  return useMutation({
1780
1935
  mutationFn: async ({ id, name, description, }) => {
1781
1936
  return requestDatalayer({
1782
- url: `${configuration.spacerRunUrl}/api/spacer/v1/lexicals/${id}`,
1937
+ url: `${configuration.spacerUrl}/api/spacer/v1/lexicals/${id}`,
1783
1938
  method: 'PUT',
1784
1939
  body: { name, description },
1785
1940
  });
@@ -1805,7 +1960,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1805
1960
  return useMutation({
1806
1961
  mutationFn: async ({ id, model }) => {
1807
1962
  return requestDatalayer({
1808
- url: `${configuration.spacerRunUrl}/api/spacer/v1/lexicals/${id}/model`,
1963
+ url: `${configuration.spacerUrl}/api/spacer/v1/lexicals/${id}/model`,
1809
1964
  method: 'PUT',
1810
1965
  body: { model },
1811
1966
  });
@@ -1859,7 +2014,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1859
2014
  return useMutation({
1860
2015
  mutationFn: async (documentId) => {
1861
2016
  return requestDatalayer({
1862
- url: `${configuration.spacerRunUrl}/api/spacer/v1/lexicals/${documentId}/clone`,
2017
+ url: `${configuration.spacerUrl}/api/spacer/v1/lexicals/${documentId}/clone`,
1863
2018
  method: 'POST',
1864
2019
  });
1865
2020
  },
@@ -1889,7 +2044,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1889
2044
  queryKey: queryKeys.pages.detail(pageId),
1890
2045
  queryFn: async () => {
1891
2046
  const resp = await requestDatalayer({
1892
- url: `${configuration.libraryRunUrl}/api/library/v1/pages/${pageId}`,
2047
+ url: `${configuration.libraryUrl}/api/library/v1/pages/${pageId}`,
1893
2048
  method: 'GET',
1894
2049
  });
1895
2050
  if (resp.success && resp.page) {
@@ -1921,7 +2076,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1921
2076
  }
1922
2077
  const query = params.toString();
1923
2078
  const resp = await requestDatalayer({
1924
- url: `${configuration.libraryRunUrl}/api/library/v1/pages${query ? `?${query}` : ''}`,
2079
+ url: `${configuration.libraryUrl}/api/library/v1/pages${query ? `?${query}` : ''}`,
1925
2080
  method: 'GET',
1926
2081
  });
1927
2082
  if (resp.success && resp.pages) {
@@ -1948,7 +2103,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1948
2103
  return useMutation({
1949
2104
  mutationFn: async (page) => {
1950
2105
  return requestDatalayer({
1951
- url: `${configuration.libraryRunUrl}/api/library/v1/pages`,
2106
+ url: `${configuration.libraryUrl}/api/library/v1/pages`,
1952
2107
  method: 'POST',
1953
2108
  body: { ...page },
1954
2109
  });
@@ -1975,7 +2130,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1975
2130
  return useMutation({
1976
2131
  mutationFn: async (page) => {
1977
2132
  return requestDatalayer({
1978
- url: `${configuration.libraryRunUrl}/api/library/v1/pages/${page.id}`,
2133
+ url: `${configuration.libraryUrl}/api/library/v1/pages/${page.id}`,
1979
2134
  method: 'PUT',
1980
2135
  body: {
1981
2136
  name: page.name,
@@ -2004,7 +2159,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2004
2159
  return useMutation({
2005
2160
  mutationFn: async (pageId) => {
2006
2161
  return requestDatalayer({
2007
- url: `${configuration.libraryRunUrl}/api/library/v1/pages/${pageId}`,
2162
+ url: `${configuration.libraryUrl}/api/library/v1/pages/${pageId}`,
2008
2163
  method: 'DELETE',
2009
2164
  });
2010
2165
  },
@@ -2032,7 +2187,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2032
2187
  ],
2033
2188
  queryFn: async () => {
2034
2189
  const resp = await requestDatalayer({
2035
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/datasources`, principalUid, principalKind),
2190
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/datasources`, principalUid, principalKind),
2036
2191
  method: 'GET',
2037
2192
  });
2038
2193
  if (resp.success && resp.datasources) {
@@ -2061,7 +2216,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2061
2216
  return useMutation({
2062
2217
  mutationFn: async (datasource) => {
2063
2218
  return requestDatalayer({
2064
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/datasources`, principalUid, principalKind),
2219
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/datasources`, principalUid, principalKind),
2065
2220
  method: 'POST',
2066
2221
  body: { ...datasource },
2067
2222
  });
@@ -2097,7 +2252,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2097
2252
  ],
2098
2253
  queryFn: async () => {
2099
2254
  const resp = await requestDatalayer({
2100
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/secrets`, principalUid, principalKind),
2255
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/secrets`, principalUid, principalKind),
2101
2256
  method: 'GET',
2102
2257
  });
2103
2258
  if (resp.success && resp.secrets) {
@@ -2121,7 +2276,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2121
2276
  return useMutation({
2122
2277
  mutationFn: async (secret) => {
2123
2278
  return requestDatalayer({
2124
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/secrets`, principalUid, principalKind),
2279
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/secrets`, principalUid, principalKind),
2125
2280
  method: 'POST',
2126
2281
  body: { ...secret },
2127
2282
  });
@@ -2146,7 +2301,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2146
2301
  return useMutation({
2147
2302
  mutationFn: async (secretId) => {
2148
2303
  return requestDatalayer({
2149
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/secrets/${secretId}`, principalUid, principalKind),
2304
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/secrets/${secretId}`, principalUid, principalKind),
2150
2305
  method: 'DELETE',
2151
2306
  });
2152
2307
  },
@@ -2166,7 +2321,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2166
2321
  queryKey: queryKeys.tokens.all(),
2167
2322
  queryFn: async () => {
2168
2323
  const resp = await requestDatalayer({
2169
- url: `${configuration.iamRunUrl}/api/iam/v1/api-keys`,
2324
+ url: `${configuration.iamUrl}/api/iam/v1/api-keys`,
2170
2325
  method: 'GET',
2171
2326
  });
2172
2327
  const tokenItems = asArray(resp?.apiKeys ?? resp?.api_keys ?? resp?.tokens);
@@ -2195,7 +2350,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2195
2350
  return useMutation({
2196
2351
  mutationFn: async (token) => {
2197
2352
  const resp = await requestDatalayer({
2198
- url: `${configuration.iamRunUrl}/api/iam/v1/api-keys`,
2353
+ url: `${configuration.iamUrl}/api/iam/v1/api-keys`,
2199
2354
  method: 'POST',
2200
2355
  body: {
2201
2356
  ...token,
@@ -2228,7 +2383,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2228
2383
  queryKey: queryKeys.contacts.detail(contactId),
2229
2384
  queryFn: async () => {
2230
2385
  const resp = await requestDatalayer({
2231
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/${contactId}`,
2386
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/${contactId}`,
2232
2387
  method: 'GET',
2233
2388
  });
2234
2389
  if (resp.success && resp.contact) {
@@ -2252,7 +2407,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2252
2407
  queryKey: queryKeys.contacts.search(query),
2253
2408
  queryFn: async () => {
2254
2409
  const resp = await requestDatalayer({
2255
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/search`,
2410
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/search`,
2256
2411
  method: 'POST',
2257
2412
  body: { query },
2258
2413
  });
@@ -2282,7 +2437,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2282
2437
  return useMutation({
2283
2438
  mutationFn: async (contact) => {
2284
2439
  return requestDatalayer({
2285
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts`,
2440
+ url: `${configuration.growthUrl}/api/growth/v1/contacts`,
2286
2441
  method: 'POST',
2287
2442
  body: { contact },
2288
2443
  });
@@ -2309,7 +2464,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2309
2464
  return useMutation({
2310
2465
  mutationFn: async ({ contactId, contact, }) => {
2311
2466
  return requestDatalayer({
2312
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/${contactId}`,
2467
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/${contactId}`,
2313
2468
  method: 'PUT',
2314
2469
  body: { contact },
2315
2470
  });
@@ -2333,7 +2488,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2333
2488
  return useMutation({
2334
2489
  mutationFn: async (contactId) => {
2335
2490
  return requestDatalayer({
2336
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/${contactId}`,
2491
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/${contactId}`,
2337
2492
  method: 'DELETE',
2338
2493
  });
2339
2494
  },
@@ -2359,7 +2514,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2359
2514
  return useMutation({
2360
2515
  mutationFn: async (itemId) => {
2361
2516
  return requestDatalayer({
2362
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/items/${itemId}`,
2517
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/items/${itemId}`,
2363
2518
  method: 'DELETE',
2364
2519
  });
2365
2520
  },
@@ -2416,7 +2571,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2416
2571
  ],
2417
2572
  queryFn: async () => {
2418
2573
  const resp = await requestDatalayer({
2419
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/datasources/${datasourceId}`, principalUid, principalKind),
2574
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/datasources/${datasourceId}`, principalUid, principalKind),
2420
2575
  method: 'GET',
2421
2576
  });
2422
2577
  if (resp.success && resp.datasource) {
@@ -2437,7 +2592,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2437
2592
  return useMutation({
2438
2593
  mutationFn: async (datasource) => {
2439
2594
  return requestDatalayer({
2440
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/datasources/${datasource.id}`, principalUid, principalKind),
2595
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/datasources/${datasource.id}`, principalUid, principalKind),
2441
2596
  method: 'PUT',
2442
2597
  body: { ...datasource },
2443
2598
  });
@@ -2469,7 +2624,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2469
2624
  ],
2470
2625
  queryFn: async () => {
2471
2626
  const resp = await requestDatalayer({
2472
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/secrets/${secretId}`, principalUid, principalKind),
2627
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/secrets/${secretId}`, principalUid, principalKind),
2473
2628
  method: 'GET',
2474
2629
  });
2475
2630
  if (resp.success && resp.secret) {
@@ -2493,7 +2648,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2493
2648
  return useMutation({
2494
2649
  mutationFn: async (secret) => {
2495
2650
  return requestDatalayer({
2496
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/secrets/${secret.id}`, principalUid, principalKind),
2651
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/secrets/${secret.id}`, principalUid, principalKind),
2497
2652
  method: 'PUT',
2498
2653
  body: { ...secret },
2499
2654
  });
@@ -2517,7 +2672,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2517
2672
  queryKey: queryKeys.tokens.detail(tokenId),
2518
2673
  queryFn: async () => {
2519
2674
  const resp = await requestDatalayer({
2520
- url: `${configuration.iamRunUrl}/api/iam/v1/api-keys/${tokenId}`,
2675
+ url: `${configuration.iamUrl}/api/iam/v1/api-keys/${tokenId}`,
2521
2676
  method: 'GET',
2522
2677
  });
2523
2678
  const tokenPayload = resp?.apiKey ?? resp?.api_key ?? resp?.token;
@@ -2537,7 +2692,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2537
2692
  return useMutation({
2538
2693
  mutationFn: async (token) => {
2539
2694
  return requestDatalayer({
2540
- url: `${configuration.iamRunUrl}/api/iam/v1/api-keys/${token.id}`,
2695
+ url: `${configuration.iamUrl}/api/iam/v1/api-keys/${token.id}`,
2541
2696
  method: 'PUT',
2542
2697
  body: { ...token },
2543
2698
  });
@@ -2561,7 +2716,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2561
2716
  return useMutation({
2562
2717
  mutationFn: async (tokenId) => {
2563
2718
  return requestDatalayer({
2564
- url: `${configuration.iamRunUrl}/api/iam/v1/api-keys/${tokenId}`,
2719
+ url: `${configuration.iamUrl}/api/iam/v1/api-keys/${tokenId}`,
2565
2720
  method: 'DELETE',
2566
2721
  });
2567
2722
  },
@@ -2581,7 +2736,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2581
2736
  queryKey: queryKeys.contacts.byHandle(handle),
2582
2737
  queryFn: async () => {
2583
2738
  const resp = await requestDatalayer({
2584
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/handle/${handle}`,
2739
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/handle/${handle}`,
2585
2740
  method: 'GET',
2586
2741
  });
2587
2742
  if (resp.success && resp.contact) {
@@ -2605,7 +2760,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2605
2760
  queryKey: queryKeys.teams.byHandle(handle),
2606
2761
  queryFn: async () => {
2607
2762
  const resp = await requestDatalayer({
2608
- url: `${configuration.iamRunUrl}/api/iam/v1/teams/handle/${handle}`,
2763
+ url: `${configuration.iamUrl}/api/iam/v1/teams/handle/${handle}`,
2609
2764
  method: 'GET',
2610
2765
  });
2611
2766
  if (resp.success && resp.team) {
@@ -2629,7 +2784,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2629
2784
  queryKey: queryKeys.spaces.orgSpaceByHandle(organizationId, handle),
2630
2785
  queryFn: async () => {
2631
2786
  const resp = await requestDatalayer({
2632
- url: `${configuration.spacerRunUrl}/api/spacer/v1/organizations/${organizationId}/spaces/handle/${handle}`,
2787
+ url: `${configuration.spacerUrl}/api/spacer/v1/organizations/${organizationId}/spaces/handle/${handle}`,
2633
2788
  method: 'GET',
2634
2789
  });
2635
2790
  if (resp.success && resp.space) {
@@ -2656,7 +2811,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2656
2811
  queryKey: queryKeys.spaces.detail(spaceId),
2657
2812
  queryFn: async () => {
2658
2813
  const resp = await requestDatalayer({
2659
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}`,
2814
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}`,
2660
2815
  method: 'GET',
2661
2816
  });
2662
2817
  if (resp.success && resp.space) {
@@ -2683,7 +2838,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2683
2838
  }
2684
2839
  // If not in cache, fetch all user spaces which will populate it
2685
2840
  const resp = await requestDatalayer({
2686
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/users/me`,
2841
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/users/me`,
2687
2842
  method: 'GET',
2688
2843
  });
2689
2844
  if (resp.success && resp.spaces) {
@@ -2716,7 +2871,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2716
2871
  return useMutation({
2717
2872
  mutationFn: async ({ organizationId, spaceId, updates, }) => {
2718
2873
  return requestDatalayer({
2719
- url: `${configuration.spacerRunUrl}/api/spacer/v1/organizations/${organizationId}/spaces/${spaceId}`,
2874
+ url: `${configuration.spacerUrl}/api/spacer/v1/organizations/${organizationId}/spaces/${spaceId}`,
2720
2875
  method: 'PUT',
2721
2876
  body: updates,
2722
2877
  });
@@ -2741,7 +2896,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2741
2896
  return useMutation({
2742
2897
  mutationFn: async (userId) => {
2743
2898
  return requestDatalayer({
2744
- url: `${configuration.iamRunUrl}/api/iam/v1/users/${userId}`,
2899
+ url: `${configuration.iamUrl}/api/iam/v1/users/${userId}`,
2745
2900
  method: 'GET',
2746
2901
  });
2747
2902
  },
@@ -2767,7 +2922,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2767
2922
  queryKey: [...queryKeys.users.detail(userId), 'credits'],
2768
2923
  queryFn: async () => {
2769
2924
  const resp = await requestDatalayer({
2770
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits/users/${userId}`,
2925
+ url: `${configuration.iamUrl}/api/iam/v1/usage/credits/users/${userId}`,
2771
2926
  method: 'GET',
2772
2927
  });
2773
2928
  if (resp.success) {
@@ -2786,7 +2941,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2786
2941
  return useMutation({
2787
2942
  mutationFn: async ({ userId, credits, brand, }) => {
2788
2943
  return requestDatalayer({
2789
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits/users/${userId}`,
2944
+ url: `${configuration.iamUrl}/api/iam/v1/usage/credits/users/${userId}`,
2790
2945
  method: 'PUT',
2791
2946
  body: { credits, brand },
2792
2947
  });
@@ -2805,7 +2960,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2805
2960
  return useMutation({
2806
2961
  mutationFn: async ({ organizationId, userId, }) => {
2807
2962
  return requestDatalayer({
2808
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations/${organizationId}/members/${userId}`,
2963
+ url: `${configuration.iamUrl}/api/iam/v1/organizations/${organizationId}/members/${userId}`,
2809
2964
  method: 'POST',
2810
2965
  });
2811
2966
  },
@@ -2826,7 +2981,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2826
2981
  return useMutation({
2827
2982
  mutationFn: async ({ organizationId, userId, }) => {
2828
2983
  return requestDatalayer({
2829
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations/${organizationId}/members/${userId}`,
2984
+ url: `${configuration.iamUrl}/api/iam/v1/organizations/${organizationId}/members/${userId}`,
2830
2985
  method: 'DELETE',
2831
2986
  });
2832
2987
  },
@@ -2847,7 +3002,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2847
3002
  return useMutation({
2848
3003
  mutationFn: async ({ organizationId, userId, roleName, }) => {
2849
3004
  return requestDatalayer({
2850
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations/${organizationId}/members/${userId}/roles/${roleName}`,
3005
+ url: `${configuration.iamUrl}/api/iam/v1/organizations/${organizationId}/members/${userId}/roles/${roleName}`,
2851
3006
  method: 'POST',
2852
3007
  });
2853
3008
  },
@@ -2865,7 +3020,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2865
3020
  return useMutation({
2866
3021
  mutationFn: async ({ organizationId, userId, roleName, }) => {
2867
3022
  return requestDatalayer({
2868
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations/${organizationId}/members/${userId}/roles/${roleName}`,
3023
+ url: `${configuration.iamUrl}/api/iam/v1/organizations/${organizationId}/members/${userId}/roles/${roleName}`,
2869
3024
  method: 'DELETE',
2870
3025
  });
2871
3026
  },
@@ -2883,7 +3038,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2883
3038
  return useMutation({
2884
3039
  mutationFn: async ({ teamId, userId, }) => {
2885
3040
  return requestDatalayer({
2886
- url: `${configuration.iamRunUrl}/api/iam/v1/teams/${teamId}/members/${userId}`,
3041
+ url: `${configuration.iamUrl}/api/iam/v1/teams/${teamId}/members/${userId}`,
2887
3042
  method: 'POST',
2888
3043
  });
2889
3044
  },
@@ -2904,7 +3059,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2904
3059
  return useMutation({
2905
3060
  mutationFn: async ({ teamId, userId, }) => {
2906
3061
  return requestDatalayer({
2907
- url: `${configuration.iamRunUrl}/api/iam/v1/teams/${teamId}/members/${userId}`,
3062
+ url: `${configuration.iamUrl}/api/iam/v1/teams/${teamId}/members/${userId}`,
2908
3063
  method: 'DELETE',
2909
3064
  });
2910
3065
  },
@@ -2925,7 +3080,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2925
3080
  return useMutation({
2926
3081
  mutationFn: async ({ teamId, userId, roleName, }) => {
2927
3082
  return requestDatalayer({
2928
- url: `${configuration.iamRunUrl}/api/iam/v1/teams/${teamId}/members/${userId}/roles/${roleName}`,
3083
+ url: `${configuration.iamUrl}/api/iam/v1/teams/${teamId}/members/${userId}/roles/${roleName}`,
2929
3084
  method: 'POST',
2930
3085
  });
2931
3086
  },
@@ -2943,7 +3098,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2943
3098
  return useMutation({
2944
3099
  mutationFn: async ({ teamId, userId, roleName, }) => {
2945
3100
  return requestDatalayer({
2946
- url: `${configuration.iamRunUrl}/api/iam/v1/teams/${teamId}/members/${userId}/roles/${roleName}`,
3101
+ url: `${configuration.iamUrl}/api/iam/v1/teams/${teamId}/members/${userId}/roles/${roleName}`,
2947
3102
  method: 'DELETE',
2948
3103
  });
2949
3104
  },
@@ -2961,7 +3116,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2961
3116
  return useMutation({
2962
3117
  mutationFn: async ({ organizationId, spaceId, accountId, }) => {
2963
3118
  return requestDatalayer({
2964
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/organizations/${organizationId}/members/${accountId}`,
3119
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/organizations/${organizationId}/members/${accountId}`,
2965
3120
  method: 'POST',
2966
3121
  });
2967
3122
  },
@@ -2982,7 +3137,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2982
3137
  return useMutation({
2983
3138
  mutationFn: async ({ organizationId, spaceId, accountId, }) => {
2984
3139
  return requestDatalayer({
2985
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/organizations/${organizationId}/members/${accountId}`,
3140
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/organizations/${organizationId}/members/${accountId}`,
2986
3141
  method: 'DELETE',
2987
3142
  });
2988
3143
  },
@@ -3003,7 +3158,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3003
3158
  return useMutation({
3004
3159
  mutationFn: async (spaceId) => {
3005
3160
  return requestDatalayer({
3006
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/public`,
3161
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/public`,
3007
3162
  method: 'PUT',
3008
3163
  });
3009
3164
  },
@@ -3021,7 +3176,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3021
3176
  return useMutation({
3022
3177
  mutationFn: async (spaceId) => {
3023
3178
  return requestDatalayer({
3024
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/private`,
3179
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/private`,
3025
3180
  method: 'PUT',
3026
3181
  });
3027
3182
  },
@@ -3042,7 +3197,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3042
3197
  return useMutation({
3043
3198
  mutationFn: async ({ handle, password, passwordConfirm, }) => {
3044
3199
  return requestDatalayer({
3045
- url: `${configuration.iamRunUrl}/api/iam/v1/password`,
3200
+ url: `${configuration.iamUrl}/api/iam/v1/password`,
3046
3201
  method: 'PUT',
3047
3202
  body: { handle, password, passwordConfirm },
3048
3203
  });
@@ -3056,7 +3211,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3056
3211
  return useMutation({
3057
3212
  mutationFn: async (email) => {
3058
3213
  return requestDatalayer({
3059
- url: `${configuration.iamRunUrl}/api/iam/v1/me/email`,
3214
+ url: `${configuration.iamUrl}/api/iam/v1/me/email`,
3060
3215
  method: 'PUT',
3061
3216
  body: { email },
3062
3217
  });
@@ -3070,7 +3225,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3070
3225
  return useMutation({
3071
3226
  mutationFn: async (token) => {
3072
3227
  return requestDatalayer({
3073
- url: `${configuration.iamRunUrl}/api/iam/v1/me/email`,
3228
+ url: `${configuration.iamUrl}/api/iam/v1/me/email`,
3074
3229
  method: 'POST',
3075
3230
  body: { token },
3076
3231
  });
@@ -3088,7 +3243,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3088
3243
  return useMutation({
3089
3244
  mutationFn: async ({ userId, roleName, }) => {
3090
3245
  return requestDatalayer({
3091
- url: `${configuration.iamRunUrl}/api/iam/v1/users/${userId}/roles/${roleName}`,
3246
+ url: `${configuration.iamUrl}/api/iam/v1/users/${userId}/roles/${roleName}`,
3092
3247
  method: 'POST',
3093
3248
  });
3094
3249
  },
@@ -3106,7 +3261,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3106
3261
  return useMutation({
3107
3262
  mutationFn: async ({ userId, roleName, }) => {
3108
3263
  return requestDatalayer({
3109
- url: `${configuration.iamRunUrl}/api/iam/v1/users/${userId}/roles/${roleName}`,
3264
+ url: `${configuration.iamUrl}/api/iam/v1/users/${userId}/roles/${roleName}`,
3110
3265
  method: 'DELETE',
3111
3266
  });
3112
3267
  },
@@ -3125,7 +3280,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3125
3280
  queryKey: ['schools'],
3126
3281
  queryFn: async () => {
3127
3282
  const resp = await requestDatalayer({
3128
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations/schools`,
3283
+ url: `${configuration.iamUrl}/api/iam/v1/organizations/schools`,
3129
3284
  method: 'GET',
3130
3285
  });
3131
3286
  if (resp.success && resp.orgs) {
@@ -3160,7 +3315,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3160
3315
  return useMutation({
3161
3316
  mutationFn: async (organizationId) => {
3162
3317
  return requestDatalayer({
3163
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations/${organizationId}`,
3318
+ url: `${configuration.iamUrl}/api/iam/v1/organizations/${organizationId}`,
3164
3319
  method: 'GET',
3165
3320
  });
3166
3321
  },
@@ -3187,7 +3342,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3187
3342
  return useMutation({
3188
3343
  mutationFn: async () => {
3189
3344
  return requestDatalayer({
3190
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations`,
3345
+ url: `${configuration.iamUrl}/api/iam/v1/organizations`,
3191
3346
  method: 'GET',
3192
3347
  });
3193
3348
  },
@@ -3216,7 +3371,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3216
3371
  return useMutation({
3217
3372
  mutationFn: async ({ teamId, organizationId: _organizationId, }) => {
3218
3373
  return requestDatalayer({
3219
- url: `${configuration.iamRunUrl}/api/iam/v1/teams/${teamId}`,
3374
+ url: `${configuration.iamUrl}/api/iam/v1/teams/${teamId}`,
3220
3375
  method: 'GET',
3221
3376
  });
3222
3377
  },
@@ -3243,7 +3398,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3243
3398
  return useMutation({
3244
3399
  mutationFn: async (organizationId) => {
3245
3400
  return requestDatalayer({
3246
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations/${organizationId}/teams`,
3401
+ url: `${configuration.iamUrl}/api/iam/v1/organizations/${organizationId}/teams`,
3247
3402
  method: 'GET',
3248
3403
  });
3249
3404
  },
@@ -3272,7 +3427,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3272
3427
  return useMutation({
3273
3428
  mutationFn: async ({ organizationId, spaceId, }) => {
3274
3429
  return requestDatalayer({
3275
- url: `${configuration.spacerRunUrl}/api/spacer/v1/organizations/${organizationId}/spaces/${spaceId}`,
3430
+ url: `${configuration.spacerUrl}/api/spacer/v1/organizations/${organizationId}/spaces/${spaceId}`,
3276
3431
  method: 'GET',
3277
3432
  });
3278
3433
  },
@@ -3296,7 +3451,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3296
3451
  return useMutation({
3297
3452
  mutationFn: async (organizationId) => {
3298
3453
  return requestDatalayer({
3299
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/organizations/${organizationId}`,
3454
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/organizations/${organizationId}`,
3300
3455
  method: 'GET',
3301
3456
  });
3302
3457
  },
@@ -3322,7 +3477,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3322
3477
  return useMutation({
3323
3478
  mutationFn: async () => {
3324
3479
  return requestDatalayer({
3325
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/users/me`,
3480
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/users/me`,
3326
3481
  method: 'GET',
3327
3482
  });
3328
3483
  },
@@ -3352,7 +3507,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3352
3507
  queryKey: ['courses', 'detail', courseId],
3353
3508
  queryFn: async () => {
3354
3509
  const resp = await requestDatalayer({
3355
- url: `${configuration.spacerRunUrl}/api/spacer/v1/courses/${courseId}`,
3510
+ url: `${configuration.spacerUrl}/api/spacer/v1/courses/${courseId}`,
3356
3511
  method: 'GET',
3357
3512
  });
3358
3513
  if (resp.success && resp.course) {
@@ -3371,7 +3526,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3371
3526
  return useMutation({
3372
3527
  mutationFn: async ({ courseId, name, description, }) => {
3373
3528
  return requestDatalayer({
3374
- url: `${configuration.spacerRunUrl}/api/spacer/v1/courses/${courseId}`,
3529
+ url: `${configuration.spacerUrl}/api/spacer/v1/courses/${courseId}`,
3375
3530
  method: 'PUT',
3376
3531
  body: { name, description },
3377
3532
  });
@@ -3396,7 +3551,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3396
3551
  queryKey: ['courses', 'public'],
3397
3552
  queryFn: async () => {
3398
3553
  const resp = await requestDatalayer({
3399
- url: `${configuration.libraryRunUrl}/api/library/v1/courses/public`,
3554
+ url: `${configuration.libraryUrl}/api/library/v1/courses/public`,
3400
3555
  method: 'GET',
3401
3556
  });
3402
3557
  if (resp.success && resp.courses) {
@@ -3415,7 +3570,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3415
3570
  queryKey: ['courses', 'instructor', userId],
3416
3571
  queryFn: async () => {
3417
3572
  const resp = await requestDatalayer({
3418
- url: `${configuration.spacerRunUrl}/api/spacer/v1/instructors/${userId}/courses`,
3573
+ url: `${configuration.spacerUrl}/api/spacer/v1/instructors/${userId}/courses`,
3419
3574
  method: 'GET',
3420
3575
  });
3421
3576
  if (resp.success && resp.courses) {
@@ -3435,7 +3590,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3435
3590
  queryKey: ['courses', 'enrollments', 'me'],
3436
3591
  queryFn: async () => {
3437
3592
  const resp = await requestDatalayer({
3438
- url: `${configuration.spacerRunUrl}/api/spacer/v1/courses/enrollments/me`,
3593
+ url: `${configuration.spacerUrl}/api/spacer/v1/courses/enrollments/me`,
3439
3594
  method: 'GET',
3440
3595
  });
3441
3596
  if (resp.success && resp.enrollments) {
@@ -3453,13 +3608,33 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3453
3608
  return useMutation({
3454
3609
  mutationFn: async ({ courseId, studentId, }) => {
3455
3610
  return requestDatalayer({
3456
- url: `${configuration.spacerRunUrl}/api/spacer/v1/courses/${courseId}/enrollments/students/${studentId}`,
3611
+ url: `${configuration.spacerUrl}/api/spacer/v1/courses/${courseId}/enrollments/students/${studentId}`,
3457
3612
  method: 'POST',
3458
3613
  });
3459
3614
  },
3460
- onSuccess: (_, { courseId }) => {
3615
+ onSuccess: (_, { courseId, studentId }) => {
3616
+ // Optimistically add the student to the cached course so enrollment
3617
+ // dependent UI (e.g. the Progress tab) updates immediately. The Solr
3618
+ // read model is eventually consistent, so an immediate refetch would
3619
+ // return stale data; mark the detail query stale without refetching and
3620
+ // let it reconcile on the next natural fetch.
3621
+ const detailKey = ['courses', 'detail', courseId];
3622
+ const cached = queryClient.getQueryData(detailKey);
3623
+ if (cached) {
3624
+ const nextStudents = cached.students instanceof Map
3625
+ ? new Map(cached.students)
3626
+ : new Map();
3627
+ if (!nextStudents.has(studentId)) {
3628
+ nextStudents.set(studentId, { id: studentId });
3629
+ }
3630
+ queryClient.setQueryData(detailKey, {
3631
+ ...cached,
3632
+ students: nextStudents,
3633
+ });
3634
+ }
3461
3635
  queryClient.invalidateQueries({
3462
- queryKey: ['courses', 'detail', courseId],
3636
+ queryKey: detailKey,
3637
+ refetchType: 'none',
3463
3638
  });
3464
3639
  queryClient.invalidateQueries({
3465
3640
  queryKey: ['courses', 'enrollments'],
@@ -3474,13 +3649,29 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3474
3649
  return useMutation({
3475
3650
  mutationFn: async ({ courseId, studentId, }) => {
3476
3651
  return requestDatalayer({
3477
- url: `${configuration.spacerRunUrl}/api/spacer/v1/courses/${courseId}/enrollments/students/${studentId}`,
3652
+ url: `${configuration.spacerUrl}/api/spacer/v1/courses/${courseId}/enrollments/students/${studentId}`,
3478
3653
  method: 'DELETE',
3479
3654
  });
3480
3655
  },
3481
- onSuccess: (_, { courseId }) => {
3656
+ onSuccess: (_, { courseId, studentId }) => {
3657
+ // Optimistically remove the student from the cached course so
3658
+ // enrollment dependent UI (e.g. the Progress tab) updates immediately.
3659
+ // The Solr read model is eventually consistent, so an immediate refetch
3660
+ // would return stale data; mark the detail query stale without
3661
+ // refetching and let it reconcile on the next natural fetch.
3662
+ const detailKey = ['courses', 'detail', courseId];
3663
+ const cached = queryClient.getQueryData(detailKey);
3664
+ if (cached && cached.students instanceof Map) {
3665
+ const nextStudents = new Map(cached.students);
3666
+ nextStudents.delete(studentId);
3667
+ queryClient.setQueryData(detailKey, {
3668
+ ...cached,
3669
+ students: nextStudents,
3670
+ });
3671
+ }
3482
3672
  queryClient.invalidateQueries({
3483
- queryKey: ['courses', 'detail', courseId],
3673
+ queryKey: detailKey,
3674
+ refetchType: 'none',
3484
3675
  });
3485
3676
  queryClient.invalidateQueries({
3486
3677
  queryKey: ['courses', 'enrollments'],
@@ -3496,7 +3687,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3496
3687
  queryKey: ['spaces', spaceId, 'items'],
3497
3688
  queryFn: async () => {
3498
3689
  const resp = await requestDatalayer({
3499
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items`,
3690
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items`,
3500
3691
  method: 'GET',
3501
3692
  });
3502
3693
  if (resp.success && resp.items) {
@@ -3518,7 +3709,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3518
3709
  queryKey: ['spaces', spaceId, 'default-items'],
3519
3710
  queryFn: async () => {
3520
3711
  const resp = await requestDatalayer({
3521
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/default-items`,
3712
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/default-items`,
3522
3713
  method: 'GET',
3523
3714
  });
3524
3715
  if (resp.success) {
@@ -3540,8 +3731,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3540
3731
  return useMutation({
3541
3732
  mutationFn: async (itemId) => {
3542
3733
  return requestDatalayer({
3543
- url: `${configuration.libraryRunUrl}/api/library/v1/items/${itemId}/public`,
3544
- method: 'PUT',
3734
+ url: `${configuration.libraryUrl}/api/library/v1/items/${itemId}/public`,
3735
+ method: 'PATCH',
3736
+ body: { is_public: true },
3545
3737
  });
3546
3738
  },
3547
3739
  onSuccess: () => {
@@ -3556,8 +3748,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3556
3748
  return useMutation({
3557
3749
  mutationFn: async (itemId) => {
3558
3750
  return requestDatalayer({
3559
- url: `${configuration.libraryRunUrl}/api/library/v1/items/${itemId}/private`,
3560
- method: 'PUT',
3751
+ url: `${configuration.libraryUrl}/api/library/v1/items/${itemId}/public`,
3752
+ method: 'PATCH',
3753
+ body: { is_public: false },
3561
3754
  });
3562
3755
  },
3563
3756
  onSuccess: () => {
@@ -3577,9 +3770,16 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3577
3770
  */
3578
3771
  const useRefreshLayout = () => {
3579
3772
  return useMutation({
3580
- mutationFn: async ({ accountHandle, spaceHandle, }) => {
3773
+ mutationFn: async ({ accountHandle, teamHandle, spaceHandle, }) => {
3774
+ let path = `/api/spacer/v1/layouts/accounts/${accountHandle}`;
3775
+ if (teamHandle !== undefined && spaceHandle !== undefined) {
3776
+ path += `/teams/${teamHandle}/spaces/${spaceHandle}`;
3777
+ }
3778
+ else if (spaceHandle !== undefined) {
3779
+ path += `/spaces/${spaceHandle}`;
3780
+ }
3581
3781
  return requestDatalayer({
3582
- url: `${configuration.spacerRunUrl}/api/spacer/v1/layouts/accounts/${accountHandle}${spaceHandle !== undefined ? '/spaces/' + spaceHandle : ''}`,
3782
+ url: `${configuration.spacerUrl}${path}`,
3583
3783
  method: 'GET',
3584
3784
  });
3585
3785
  },
@@ -3590,6 +3790,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3590
3790
  const transformedOrganization = resp.organization
3591
3791
  ? toOrganization(resp.organization)
3592
3792
  : undefined;
3793
+ const transformedTeam = resp.team && transformedOrganization
3794
+ ? toTeam(resp.team, transformedOrganization.id)
3795
+ : undefined;
3593
3796
  const transformedSpace = resp.space ? toSpace(resp.space) : undefined;
3594
3797
  // Set data directly into cache instead of just invalidating
3595
3798
  if (transformedUser) {
@@ -3602,6 +3805,15 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3602
3805
  queryKey: queryKeys.organizations.all(),
3603
3806
  });
3604
3807
  }
3808
+ if (transformedTeam) {
3809
+ if (transformedTeam.id) {
3810
+ queryClient.setQueryData(queryKeys.teams.detail(transformedTeam.id), transformedTeam);
3811
+ }
3812
+ if (variables.teamHandle) {
3813
+ queryClient.setQueryData(queryKeys.teams.byHandle(variables.teamHandle), transformedTeam);
3814
+ }
3815
+ queryClient.invalidateQueries({ queryKey: queryKeys.teams.all() });
3816
+ }
3605
3817
  if (transformedSpace) {
3606
3818
  // Set both user and org space queries based on which type it is
3607
3819
  if (transformedUser && variables.spaceHandle) {
@@ -3623,7 +3835,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3623
3835
  return useMutation({
3624
3836
  mutationFn: async (spaceId) => {
3625
3837
  return requestDatalayer({
3626
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/export`,
3838
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/export`,
3627
3839
  method: 'GET',
3628
3840
  });
3629
3841
  },
@@ -3640,7 +3852,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3640
3852
  queryKey: queryKeys.cells.detail(cellId),
3641
3853
  queryFn: async () => {
3642
3854
  const resp = await requestDatalayer({
3643
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/items/${cellId}`,
3855
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/items/${cellId}`,
3644
3856
  method: 'GET',
3645
3857
  });
3646
3858
  if (resp.success && resp.item) {
@@ -3663,7 +3875,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3663
3875
  queryKey: queryKeys.cells.bySpace(spaceId),
3664
3876
  queryFn: async () => {
3665
3877
  const resp = await requestDatalayer({
3666
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/cell`,
3878
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/cell`,
3667
3879
  method: 'GET',
3668
3880
  });
3669
3881
  if (resp.success && resp.items) {
@@ -3682,7 +3894,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3682
3894
  return useMutation({
3683
3895
  mutationFn: async (cell) => {
3684
3896
  return requestDatalayer({
3685
- url: `${configuration.spacerRunUrl}/api/spacer/v1/cells/${cell.id}`,
3897
+ url: `${configuration.spacerUrl}/api/spacer/v1/cells/${cell.id}`,
3686
3898
  method: 'PUT',
3687
3899
  body: cell,
3688
3900
  });
@@ -3707,7 +3919,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3707
3919
  return useMutation({
3708
3920
  mutationFn: async (cellId) => {
3709
3921
  return requestDatalayer({
3710
- url: `${configuration.spacerRunUrl}/api/spacer/v1/cells/${cellId}/clone`,
3922
+ url: `${configuration.spacerUrl}/api/spacer/v1/cells/${cellId}/clone`,
3711
3923
  method: 'POST',
3712
3924
  });
3713
3925
  },
@@ -3729,12 +3941,24 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3729
3941
  /**
3730
3942
  * Get dataset by ID
3731
3943
  */
3732
- const useDataset = (datasetId) => {
3944
+ const useDataset = (datasetId, scope) => {
3733
3945
  return useQuery({
3734
- queryKey: queryKeys.datasets.detail(datasetId),
3946
+ queryKey: [
3947
+ ...queryKeys.datasets.detail(datasetId),
3948
+ scope?.selectedPrincipalUid || '',
3949
+ scope?.selectedPrincipalKind || '',
3950
+ ],
3735
3951
  queryFn: async () => {
3952
+ const params = new URLSearchParams();
3953
+ if (scope?.selectedPrincipalUid) {
3954
+ params.set('selected_principal_uid', scope.selectedPrincipalUid);
3955
+ }
3956
+ if (scope?.selectedPrincipalKind) {
3957
+ params.set('selected_principal_kind', scope.selectedPrincipalKind);
3958
+ }
3959
+ const query = params.toString();
3736
3960
  const resp = await requestDatalayer({
3737
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/items/${datasetId}`,
3961
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/spaces/items/${datasetId}${query ? `?${query}` : ''}`,
3738
3962
  method: 'GET',
3739
3963
  });
3740
3964
  if (resp.success && resp.item) {
@@ -3749,12 +3973,24 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3749
3973
  /**
3750
3974
  * Get datasets by space
3751
3975
  */
3752
- const useDatasetsBySpace = (spaceId) => {
3976
+ const useDatasetsBySpace = (spaceId, scope) => {
3753
3977
  return useQuery({
3754
- queryKey: queryKeys.datasets.bySpace(spaceId),
3978
+ queryKey: [
3979
+ ...queryKeys.datasets.bySpace(spaceId),
3980
+ scope?.selectedPrincipalUid || '',
3981
+ scope?.selectedPrincipalKind || '',
3982
+ ],
3755
3983
  queryFn: async () => {
3984
+ const params = new URLSearchParams();
3985
+ if (scope?.selectedPrincipalUid) {
3986
+ params.set('selected_principal_uid', scope.selectedPrincipalUid);
3987
+ }
3988
+ if (scope?.selectedPrincipalKind) {
3989
+ params.set('selected_principal_kind', scope.selectedPrincipalKind);
3990
+ }
3991
+ const query = params.toString();
3756
3992
  const resp = await requestDatalayer({
3757
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/dataset`,
3993
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/spaces/${spaceId}/items/types/dataset${query ? `?${query}` : ''}`,
3758
3994
  method: 'GET',
3759
3995
  });
3760
3996
  if (resp.success && resp.items) {
@@ -3771,9 +4007,17 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3771
4007
  */
3772
4008
  const useUpdateDataset = () => {
3773
4009
  return useMutation({
3774
- mutationFn: async ({ id, name, description, }) => {
4010
+ mutationFn: async ({ id, name, description, selectedPrincipalUid, selectedPrincipalKind, }) => {
4011
+ const params = new URLSearchParams();
4012
+ if (selectedPrincipalUid) {
4013
+ params.set('selected_principal_uid', selectedPrincipalUid);
4014
+ }
4015
+ if (selectedPrincipalKind) {
4016
+ params.set('selected_principal_kind', selectedPrincipalKind);
4017
+ }
4018
+ const query = params.toString();
3775
4019
  return requestDatalayer({
3776
- url: `${configuration.spacerRunUrl}/api/spacer/v1/datasets/${id}`,
4020
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/datasets/${id}${query ? `?${query}` : ''}`,
3777
4021
  method: 'PUT',
3778
4022
  body: { name, description },
3779
4023
  });
@@ -3801,7 +4045,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3801
4045
  queryKey: queryKeys.environments.detail(environmentId),
3802
4046
  queryFn: async () => {
3803
4047
  const resp = await requestDatalayer({
3804
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/items/${environmentId}`,
4048
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/items/${environmentId}`,
3805
4049
  method: 'GET',
3806
4050
  });
3807
4051
  if (resp.success && resp.item) {
@@ -3821,7 +4065,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3821
4065
  queryKey: queryKeys.environments.bySpace(spaceId),
3822
4066
  queryFn: async () => {
3823
4067
  const resp = await requestDatalayer({
3824
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/environment`,
4068
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/environment`,
3825
4069
  method: 'GET',
3826
4070
  });
3827
4071
  if (resp.success && resp.items) {
@@ -3841,7 +4085,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3841
4085
  queryKey: queryKeys.lessons.detail(lessonId),
3842
4086
  queryFn: async () => {
3843
4087
  const resp = await requestDatalayer({
3844
- url: `${configuration.spacerRunUrl}/api/spacer/v1/lessons/${lessonId}`,
4088
+ url: `${configuration.spacerUrl}/api/spacer/v1/lessons/${lessonId}`,
3845
4089
  method: 'GET',
3846
4090
  });
3847
4091
  if (resp.success && resp.lesson) {
@@ -3861,7 +4105,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3861
4105
  queryKey: queryKeys.lessons.bySpace(spaceId),
3862
4106
  queryFn: async () => {
3863
4107
  const resp = await requestDatalayer({
3864
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/lesson`,
4108
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/lesson`,
3865
4109
  method: 'GET',
3866
4110
  });
3867
4111
  if (resp.success && resp.items) {
@@ -3880,7 +4124,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3880
4124
  return useMutation({
3881
4125
  mutationFn: async (lessonId) => {
3882
4126
  return requestDatalayer({
3883
- url: `${configuration.spacerRunUrl}/api/spacer/v1/notebooks/${lessonId}/clone`,
4127
+ url: `${configuration.spacerUrl}/api/spacer/v1/notebooks/${lessonId}/clone`,
3884
4128
  method: 'POST',
3885
4129
  });
3886
4130
  },
@@ -3910,7 +4154,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3910
4154
  queryKey: queryKeys.exercises.detail(exerciseId),
3911
4155
  queryFn: async () => {
3912
4156
  const resp = await requestDatalayer({
3913
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/items/${exerciseId}`,
4157
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/items/${exerciseId}`,
3914
4158
  method: 'GET',
3915
4159
  });
3916
4160
  if (resp.success && resp.item) {
@@ -3930,7 +4174,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3930
4174
  queryKey: queryKeys.exercises.bySpace(spaceId),
3931
4175
  queryFn: async () => {
3932
4176
  const resp = await requestDatalayer({
3933
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/exercise`,
4177
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/exercise`,
3934
4178
  method: 'GET',
3935
4179
  });
3936
4180
  if (resp.success && resp.items) {
@@ -3949,7 +4193,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3949
4193
  return useMutation({
3950
4194
  mutationFn: async ({ id, name, description, help, codePre, codeSolution, codeQuestion, codeTest, }) => {
3951
4195
  return requestDatalayer({
3952
- url: `${configuration.spacerRunUrl}/api/spacer/v1/exercises/${id}`,
4196
+ url: `${configuration.spacerUrl}/api/spacer/v1/exercises/${id}`,
3953
4197
  method: 'PUT',
3954
4198
  body: {
3955
4199
  name,
@@ -3977,7 +4221,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3977
4221
  return useMutation({
3978
4222
  mutationFn: async (exerciseId) => {
3979
4223
  return requestDatalayer({
3980
- url: `${configuration.spacerRunUrl}/api/spacer/v1/exercises/${exerciseId}/clone`,
4224
+ url: `${configuration.spacerUrl}/api/spacer/v1/exercises/${exerciseId}/clone`,
3981
4225
  method: 'POST',
3982
4226
  });
3983
4227
  },
@@ -4004,7 +4248,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4004
4248
  queryKey: queryKeys.assignments.detail(assignmentId),
4005
4249
  queryFn: async () => {
4006
4250
  const resp = await requestDatalayer({
4007
- url: `${configuration.spacerRunUrl}/api/spacer/v1/assignments/${assignmentId}`,
4251
+ url: `${configuration.spacerUrl}/api/spacer/v1/assignments/${assignmentId}`,
4008
4252
  method: 'GET',
4009
4253
  });
4010
4254
  if (resp.success && resp.assignment) {
@@ -4024,7 +4268,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4024
4268
  queryKey: queryKeys.assignments.bySpace(spaceId),
4025
4269
  queryFn: async () => {
4026
4270
  const resp = await requestDatalayer({
4027
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/assignment`,
4271
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/assignment`,
4028
4272
  method: 'GET',
4029
4273
  });
4030
4274
  if (resp.success && resp.items) {
@@ -4043,7 +4287,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4043
4287
  return useMutation({
4044
4288
  mutationFn: async (assignmentId) => {
4045
4289
  return requestDatalayer({
4046
- url: `${configuration.spacerRunUrl}/api/spacer/v1/notebooks/${assignmentId}/clone`,
4290
+ url: `${configuration.spacerUrl}/api/spacer/v1/notebooks/${assignmentId}/clone`,
4047
4291
  method: 'POST',
4048
4292
  });
4049
4293
  },
@@ -4070,7 +4314,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4070
4314
  queryKey: ['invites', 'token', token],
4071
4315
  queryFn: async () => {
4072
4316
  const resp = await requestDatalayer({
4073
- url: `${configuration.growthRunUrl}/api/growth/v1/invites/tokens/${token}`,
4317
+ url: `${configuration.growthUrl}/api/growth/v1/invites/tokens/${token}`,
4074
4318
  method: 'GET',
4075
4319
  });
4076
4320
  if (resp.success && resp.invite) {
@@ -4090,7 +4334,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4090
4334
  queryKey: ['invites', 'user', accountId],
4091
4335
  queryFn: async () => {
4092
4336
  const resp = await requestDatalayer({
4093
- url: `${configuration.growthRunUrl}/api/growth/v1/invites/users/${accountId}`,
4337
+ url: `${configuration.growthUrl}/api/growth/v1/invites/users/${accountId}`,
4094
4338
  method: 'GET',
4095
4339
  });
4096
4340
  if (resp.success && resp.invites) {
@@ -4109,7 +4353,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4109
4353
  return useMutation({
4110
4354
  mutationFn: async (token) => {
4111
4355
  return requestDatalayer({
4112
- url: `${configuration.growthRunUrl}/api/growth/v1/invites/tokens/${token}`,
4356
+ url: `${configuration.growthUrl}/api/growth/v1/invites/tokens/${token}`,
4113
4357
  method: 'PUT',
4114
4358
  });
4115
4359
  },
@@ -4132,7 +4376,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4132
4376
  queryKey: ['assignments', 'student', assignmentId, courseId, userId],
4133
4377
  queryFn: async () => {
4134
4378
  const resp = await requestDatalayer({
4135
- url: `${configuration.spacerRunUrl}/api/spacer/v1/assignments/${assignmentId}/courses/${courseId}/students/${userId}`,
4379
+ url: `${configuration.spacerUrl}/api/spacer/v1/assignments/${assignmentId}/courses/${courseId}/students/${userId}`,
4136
4380
  method: 'GET',
4137
4381
  });
4138
4382
  if (!resp.success) {
@@ -4151,7 +4395,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4151
4395
  return useMutation({
4152
4396
  mutationFn: async ({ assignmentId, courseId: _courseId, userId: _userId, }) => {
4153
4397
  return requestDatalayer({
4154
- url: `${configuration.spacerRunUrl}/api/spacer/v1/assignments/${assignmentId}/reset`,
4398
+ url: `${configuration.spacerUrl}/api/spacer/v1/assignments/${assignmentId}/reset`,
4155
4399
  method: 'POST',
4156
4400
  });
4157
4401
  },
@@ -4162,6 +4406,12 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4162
4406
  queryClient.invalidateQueries({
4163
4407
  queryKey: ['assignments', assignmentId],
4164
4408
  });
4409
+ queryClient.invalidateQueries({
4410
+ queryKey: ['courses', 'detail', courseId],
4411
+ });
4412
+ queryClient.invalidateQueries({
4413
+ queryKey: ['courses', courseId, 'students'],
4414
+ });
4165
4415
  },
4166
4416
  });
4167
4417
  };
@@ -4173,7 +4423,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4173
4423
  return useMutation({
4174
4424
  mutationFn: async ({ assignmentId, courseId: _courseId, userId, model, }) => {
4175
4425
  return requestDatalayer({
4176
- url: `${configuration.spacerRunUrl}/api/spacer/v1/assignments/${assignmentId}/students/${userId}/grade`,
4426
+ url: `${configuration.spacerUrl}/api/spacer/v1/assignments/${assignmentId}/students/${userId}/grade`,
4177
4427
  method: 'PUT',
4178
4428
  body: { model },
4179
4429
  });
@@ -4185,6 +4435,12 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4185
4435
  queryClient.invalidateQueries({
4186
4436
  queryKey: ['assignments', assignmentId],
4187
4437
  });
4438
+ queryClient.invalidateQueries({
4439
+ queryKey: ['courses', 'detail', courseId],
4440
+ });
4441
+ queryClient.invalidateQueries({
4442
+ queryKey: ['courses', courseId, 'students'],
4443
+ });
4188
4444
  },
4189
4445
  });
4190
4446
  };
@@ -4196,7 +4452,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4196
4452
  queryKey: ['assignments', 'studentVersion', assignmentId],
4197
4453
  queryFn: async () => {
4198
4454
  const resp = await requestDatalayer({
4199
- url: `${configuration.spacerRunUrl}/api/spacer/v1/assignments/${assignmentId}/student_version`,
4455
+ url: `${configuration.spacerUrl}/api/spacer/v1/assignments/${assignmentId}/student_version`,
4200
4456
  method: 'GET',
4201
4457
  });
4202
4458
  return resp;
@@ -4208,16 +4464,16 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4208
4464
  // Exercise Grading
4209
4465
  // ============================================================================
4210
4466
  /**
4211
- * Grade an exercise by assigning points to student code
4467
+ * Grade an exercise by assigning a score to student code
4212
4468
  */
4213
- const useUpdateExercisePoints = () => {
4469
+ const useUpdateExerciseScore = () => {
4214
4470
  const queryClient = useQueryClient();
4215
4471
  return useMutation({
4216
- mutationFn: async ({ exerciseId, codeStudent, points, }) => {
4472
+ mutationFn: async ({ exerciseId, codeStudent, score, courseId, }) => {
4217
4473
  return requestDatalayer({
4218
- url: `${configuration.spacerRunUrl}/api/spacer/v1/exercises/${exerciseId}/points`,
4474
+ url: `${configuration.spacerUrl}/api/spacer/v1/exercises/${exerciseId}/score`,
4219
4475
  method: 'PUT',
4220
- body: { codeStudent, points },
4476
+ body: { codeStudent, score, courseId },
4221
4477
  });
4222
4478
  },
4223
4479
  onSuccess: (_, { exerciseId }) => {
@@ -4241,18 +4497,46 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4241
4497
  queryKey: ['courses', courseId, 'students', studentId],
4242
4498
  queryFn: async () => {
4243
4499
  const resp = await requestDatalayer({
4244
- url: `${configuration.spacerRunUrl}/api/spacer/v1/courses/${courseId}/enrollments/students/${studentId}`,
4500
+ url: `${configuration.spacerUrl}/api/spacer/v1/courses/${courseId}/enrollments/students/${studentId}`,
4245
4501
  method: 'GET',
4246
4502
  });
4247
4503
  if (!resp.success) {
4248
4504
  throw new Error(resp.message || 'Failed to fetch student');
4249
4505
  }
4250
- return resp.student;
4506
+ return toStudent(resp.student);
4251
4507
  },
4252
4508
  enabled: !!courseId && !!studentId,
4253
4509
  ...options,
4254
4510
  });
4255
4511
  };
4512
+ /**
4513
+ * Hydrate multiple students (with their student items) for a course.
4514
+ *
4515
+ * The course payload only carries the public member projection of each
4516
+ * student (uid/handle/name) and intentionally omits the nested
4517
+ * `student_items`. To compute per-item progress (e.g. in the course report)
4518
+ * each student must be fetched individually through the enrollment endpoint,
4519
+ * which returns the deep student document including its items.
4520
+ */
4521
+ const useStudents = (courseId, studentIds) => {
4522
+ const uniqueStudentIds = Array.from(new Set((studentIds || []).map(id => String(id || '').trim()).filter(Boolean)));
4523
+ return useQueries({
4524
+ queries: uniqueStudentIds.map(studentId => ({
4525
+ queryKey: ['courses', courseId, 'students', studentId],
4526
+ queryFn: async () => {
4527
+ const resp = await requestDatalayer({
4528
+ url: `${configuration.spacerUrl}/api/spacer/v1/courses/${courseId}/enrollments/students/${studentId}`,
4529
+ method: 'GET',
4530
+ });
4531
+ if (!resp.success) {
4532
+ throw new Error(resp.message || 'Failed to fetch student');
4533
+ }
4534
+ return toStudent(resp.student);
4535
+ },
4536
+ enabled: !!courseId && !!studentId,
4537
+ })),
4538
+ });
4539
+ };
4256
4540
  /**
4257
4541
  * Mark a course item as completed
4258
4542
  */
@@ -4261,7 +4545,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4261
4545
  return useMutation({
4262
4546
  mutationFn: async ({ courseId, itemType, itemId, completed, }) => {
4263
4547
  return requestDatalayer({
4264
- url: `${configuration.spacerRunUrl}/api/spacer/v1/assignments/${courseId}/types/${itemType}/items/${itemId}/complete`,
4548
+ url: `${configuration.spacerUrl}/api/spacer/v1/assignments/${courseId}/types/${itemType}/items/${itemId}/complete`,
4265
4549
  method: 'PUT',
4266
4550
  body: { completed },
4267
4551
  });
@@ -4273,6 +4557,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4273
4557
  queryClient.invalidateQueries({
4274
4558
  queryKey: ['courses', courseId, 'items'],
4275
4559
  });
4560
+ queryClient.invalidateQueries({
4561
+ queryKey: ['courses', courseId, 'students'],
4562
+ });
4276
4563
  },
4277
4564
  });
4278
4565
  };
@@ -4284,7 +4571,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4284
4571
  return useMutation({
4285
4572
  mutationFn: async ({ courseId, itemIds, }) => {
4286
4573
  return requestDatalayer({
4287
- url: `${configuration.spacerRunUrl}/api/spacer/v1/courses/${courseId}/items`,
4574
+ url: `${configuration.spacerUrl}/api/spacer/v1/courses/${courseId}/items`,
4288
4575
  method: 'PUT',
4289
4576
  body: { itemIds },
4290
4577
  });
@@ -4310,7 +4597,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4310
4597
  queryKey: ['inbounds'],
4311
4598
  queryFn: async () => {
4312
4599
  const resp = await requestDatalayer({
4313
- url: `${configuration.inboundsRunUrl}/api/inbounds/v1/inbounds`,
4600
+ url: `${configuration.inboundsUrl}/api/inbounds/v1/inbounds`,
4314
4601
  method: 'GET',
4315
4602
  });
4316
4603
  if (!resp.success) {
@@ -4329,7 +4616,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4329
4616
  queryKey: ['outbounds', outboundId],
4330
4617
  queryFn: async () => {
4331
4618
  const resp = await requestDatalayer({
4332
- url: `${configuration.growthRunUrl}/api/growth/v1/outbounds/${outboundId}`,
4619
+ url: `${configuration.growthUrl}/api/growth/v1/outbounds/${outboundId}`,
4333
4620
  method: 'GET',
4334
4621
  });
4335
4622
  if (!resp.success) {
@@ -4349,7 +4636,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4349
4636
  queryKey: ['outbounds'],
4350
4637
  queryFn: async () => {
4351
4638
  const resp = await requestDatalayer({
4352
- url: `${configuration.growthRunUrl}/api/growth/v1/outbounds`,
4639
+ url: `${configuration.growthUrl}/api/growth/v1/outbounds`,
4353
4640
  method: 'GET',
4354
4641
  });
4355
4642
  if (!resp.success) {
@@ -4368,7 +4655,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4368
4655
  return useMutation({
4369
4656
  mutationFn: async (params) => {
4370
4657
  return requestDatalayer({
4371
- url: `${configuration.growthRunUrl}/api/growth/v1/outbounds/emails/bulk/draft`,
4658
+ url: `${configuration.growthUrl}/api/growth/v1/outbounds/emails/bulk/draft`,
4372
4659
  method: 'POST',
4373
4660
  body: params,
4374
4661
  });
@@ -4392,7 +4679,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4392
4679
  return useMutation({
4393
4680
  mutationFn: async (outboundId) => {
4394
4681
  return requestDatalayer({
4395
- url: `${configuration.growthRunUrl}/api/growth/v1/outbounds/${outboundId}/try`,
4682
+ url: `${configuration.growthUrl}/api/growth/v1/outbounds/${outboundId}/try`,
4396
4683
  method: 'POST',
4397
4684
  body: {},
4398
4685
  });
@@ -4413,7 +4700,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4413
4700
  return useMutation({
4414
4701
  mutationFn: async (outboundId) => {
4415
4702
  return requestDatalayer({
4416
- url: `${configuration.growthRunUrl}/api/growth/v1/outbounds/${outboundId}/launch`,
4703
+ url: `${configuration.growthUrl}/api/growth/v1/outbounds/${outboundId}/launch`,
4417
4704
  method: 'POST',
4418
4705
  body: {},
4419
4706
  });
@@ -4436,7 +4723,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4436
4723
  return useMutation({
4437
4724
  mutationFn: async ({ userId, recipient, subject, content, }) => {
4438
4725
  return requestDatalayer({
4439
- url: `${configuration.growthRunUrl}/api/growth/v1/outbounds/email`,
4726
+ url: `${configuration.growthUrl}/api/growth/v1/outbounds/email`,
4440
4727
  method: 'POST',
4441
4728
  body: { userId, recipient, subject, content },
4442
4729
  });
@@ -4451,7 +4738,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4451
4738
  return useMutation({
4452
4739
  mutationFn: async (outboundId) => {
4453
4740
  return requestDatalayer({
4454
- url: `${configuration.growthRunUrl}/api/growth/v1/outbounds/${outboundId}`,
4741
+ url: `${configuration.growthUrl}/api/growth/v1/outbounds/${outboundId}`,
4455
4742
  method: 'DELETE',
4456
4743
  });
4457
4744
  },
@@ -4476,7 +4763,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4476
4763
  return useMutation({
4477
4764
  mutationFn: async (userId) => {
4478
4765
  return requestDatalayer({
4479
- url: `${configuration.iamRunUrl}/api/iam/v1/outbounds/users/${userId}`,
4766
+ url: `${configuration.iamUrl}/api/iam/v1/outbounds/users/${userId}`,
4480
4767
  method: 'PUT',
4481
4768
  });
4482
4769
  },
@@ -4489,7 +4776,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4489
4776
  return useMutation({
4490
4777
  mutationFn: async (userId) => {
4491
4778
  return requestDatalayer({
4492
- url: `${configuration.iamRunUrl}/api/iam/v1/outbounds/users/${userId}`,
4779
+ url: `${configuration.iamUrl}/api/iam/v1/outbounds/users/${userId}`,
4493
4780
  method: 'DELETE',
4494
4781
  });
4495
4782
  },
@@ -4502,7 +4789,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4502
4789
  return useMutation({
4503
4790
  mutationFn: async (contactId) => {
4504
4791
  return requestDatalayer({
4505
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/unsubscribe/${contactId}`,
4792
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/unsubscribe/${contactId}`,
4506
4793
  method: 'GET',
4507
4794
  });
4508
4795
  },
@@ -4515,7 +4802,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4515
4802
  return useMutation({
4516
4803
  mutationFn: async (token) => {
4517
4804
  return requestDatalayer({
4518
- url: `${configuration.growthRunUrl}/api/growth/v1/outbounds/unsubscribe/${token}`,
4805
+ url: `${configuration.growthUrl}/api/growth/v1/outbounds/unsubscribe/${token}`,
4519
4806
  method: 'GET',
4520
4807
  });
4521
4808
  },
@@ -4532,7 +4819,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4532
4819
  return useMutation({
4533
4820
  mutationFn: async () => {
4534
4821
  return requestDatalayer({
4535
- url: `${configuration.iamRunUrl}/api/iam/v1/mfa`,
4822
+ url: `${configuration.iamUrl}/api/iam/v1/mfa`,
4536
4823
  method: 'PUT',
4537
4824
  });
4538
4825
  },
@@ -4549,7 +4836,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4549
4836
  return useMutation({
4550
4837
  mutationFn: async () => {
4551
4838
  return requestDatalayer({
4552
- url: `${configuration.iamRunUrl}/api/iam/v1/mfa`,
4839
+ url: `${configuration.iamUrl}/api/iam/v1/mfa`,
4553
4840
  method: 'DELETE',
4554
4841
  });
4555
4842
  },
@@ -4565,7 +4852,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4565
4852
  return useMutation({
4566
4853
  mutationFn: async ({ userUid, code, }) => {
4567
4854
  return requestDatalayer({
4568
- url: `${configuration.iamRunUrl}/api/iam/v1/mfa`,
4855
+ url: `${configuration.iamUrl}/api/iam/v1/mfa`,
4569
4856
  method: 'POST',
4570
4857
  body: { userUid, code },
4571
4858
  });
@@ -4617,7 +4904,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4617
4904
  }));
4618
4905
  };
4619
4906
  const resp = await requestDatalayer({
4620
- url: `${configuration.iamRunUrl}/api/iam/stripe/v1/plans/prices`,
4907
+ url: `${configuration.iamUrl}/api/iam/stripe/v1/plans/prices`,
4621
4908
  method: 'GET',
4622
4909
  });
4623
4910
  if (resp?.success === false) {
@@ -4644,7 +4931,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4644
4931
  return useMutation({
4645
4932
  mutationFn: async ({ product, }) => {
4646
4933
  const resp = await requestDatalayer({
4647
- url: `${configuration.iamRunUrl}/api/iam/stripe/v1/topup/payment-intent`,
4934
+ url: `${configuration.iamUrl}/api/iam/stripe/v1/topup/payment-intent`,
4648
4935
  method: 'POST',
4649
4936
  body: {
4650
4937
  price_id: product?.id,
@@ -4663,7 +4950,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4663
4950
  queryKey: ['subscription', 'plans', scope?.accountUid ?? 'self'],
4664
4951
  queryFn: async () => {
4665
4952
  const resp = await requestDatalayer({
4666
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/plans/catalog`, scope?.accountUid),
4953
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/plans/catalog`, scope?.accountUid),
4667
4954
  method: 'GET',
4668
4955
  });
4669
4956
  return resp.plans || [];
@@ -4678,7 +4965,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4678
4965
  return useMutation({
4679
4966
  mutationFn: async ({ plan, }) => {
4680
4967
  const resp = await requestDatalayer({
4681
- url: `${configuration.iamRunUrl}/api/iam/stripe/v1/subscription/payment-intent`,
4968
+ url: `${configuration.iamUrl}/api/iam/stripe/v1/subscription/payment-intent`,
4682
4969
  method: 'POST',
4683
4970
  body: {
4684
4971
  price_id: plan?.id,
@@ -4696,7 +4983,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4696
4983
  return useMutation({
4697
4984
  mutationFn: async () => {
4698
4985
  const resp = await requestDatalayer({
4699
- url: `${configuration.iamRunUrl}/api/iam/stripe/v1/subscription/resume/setup-intent`,
4986
+ url: `${configuration.iamUrl}/api/iam/stripe/v1/subscription/resume/setup-intent`,
4700
4987
  method: 'POST',
4701
4988
  body: scope?.accountUid ? { account_uid: scope.accountUid } : {},
4702
4989
  });
@@ -4712,7 +4999,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4712
4999
  queryKey: ['subscription', 'status', scope?.accountUid ?? 'self'],
4713
5000
  queryFn: async () => {
4714
5001
  return requestDatalayer({
4715
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/plans`, scope?.accountUid),
5002
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/plans`, scope?.accountUid),
4716
5003
  method: 'GET',
4717
5004
  });
4718
5005
  },
@@ -4727,7 +5014,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4727
5014
  queryKey: ['subscription', 'eligible-accounts'],
4728
5015
  queryFn: async () => {
4729
5016
  const resp = await requestDatalayer({
4730
- url: `${configuration.iamRunUrl}/api/iam/v1/plans/eligible-accounts`,
5017
+ url: `${configuration.iamUrl}/api/iam/v1/plans/eligible-accounts`,
4731
5018
  method: 'GET',
4732
5019
  });
4733
5020
  return resp.accounts || [];
@@ -4746,7 +5033,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4746
5033
  queryKey: ['subscription', 'accounts-details', normalizedAccountUids],
4747
5034
  queryFn: async () => {
4748
5035
  const resp = await requestDatalayer({
4749
- url: `${configuration.iamRunUrl}/api/iam/v1/plans/accounts/details`,
5036
+ url: `${configuration.iamUrl}/api/iam/v1/plans/accounts/details`,
4750
5037
  method: 'POST',
4751
5038
  body: {
4752
5039
  account_uids: normalizedAccountUids,
@@ -4766,7 +5053,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4766
5053
  return useMutation({
4767
5054
  mutationFn: async () => {
4768
5055
  return requestDatalayer({
4769
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/plans/cancel`, scope?.accountUid),
5056
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/plans/cancel`, scope?.accountUid),
4770
5057
  method: 'POST',
4771
5058
  });
4772
5059
  },
@@ -4785,7 +5072,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4785
5072
  return useMutation({
4786
5073
  mutationFn: async () => {
4787
5074
  return requestDatalayer({
4788
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/plans/resume`, scope?.accountUid),
5075
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/plans/resume`, scope?.accountUid),
4789
5076
  method: 'POST',
4790
5077
  });
4791
5078
  },
@@ -4804,7 +5091,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4804
5091
  queryKey: ['subscription', 'admin', userId],
4805
5092
  queryFn: async () => {
4806
5093
  return requestDatalayer({
4807
- url: `${configuration.iamRunUrl}/api/iam/v1/plans/admin/${userId}`,
5094
+ url: `${configuration.iamUrl}/api/iam/v1/plans/admin/${userId}`,
4808
5095
  method: 'GET',
4809
5096
  });
4810
5097
  },
@@ -4820,7 +5107,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4820
5107
  return useMutation({
4821
5108
  mutationFn: async (userId) => {
4822
5109
  return requestDatalayer({
4823
- url: `${configuration.iamRunUrl}/api/iam/v1/plans/admin/${userId}/reset`,
5110
+ url: `${configuration.iamUrl}/api/iam/v1/plans/admin/${userId}/reset`,
4824
5111
  method: 'POST',
4825
5112
  });
4826
5113
  },
@@ -4839,7 +5126,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4839
5126
  return useMutation({
4840
5127
  mutationFn: async (credits) => {
4841
5128
  return requestDatalayer({
4842
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits`,
5129
+ url: `${configuration.iamUrl}/api/iam/v1/usage/credits`,
4843
5130
  method: 'DELETE',
4844
5131
  body: { credits },
4845
5132
  });
@@ -4859,7 +5146,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4859
5146
  return useMutation({
4860
5147
  mutationFn: async ({ subject, message, email, brand, }) => {
4861
5148
  return requestDatalayer({
4862
- url: `${configuration.supportRunUrl}/api/support/v1/support/request`,
5149
+ url: `${configuration.supportUrl}/api/support/v1/support/request`,
4863
5150
  method: 'POST',
4864
5151
  body: { subject, message, email, brand },
4865
5152
  });
@@ -4873,7 +5160,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4873
5160
  return useMutation({
4874
5161
  mutationFn: async ({ accountHandle, firstName, lastName, email, message, }) => {
4875
5162
  return requestDatalayer({
4876
- url: `${configuration.supportRunUrl}/api/support/v1/support/request2`,
5163
+ url: `${configuration.supportUrl}/api/support/v1/support/request2`,
4877
5164
  method: 'POST',
4878
5165
  body: { accountHandle, firstName, lastName, email, message },
4879
5166
  });
@@ -4888,7 +5175,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4888
5175
  queryKey: ['users', userId, 'surveys'],
4889
5176
  queryFn: async () => {
4890
5177
  const resp = await requestDatalayer({
4891
- url: `${configuration.growthRunUrl}/api/growth/v1/surveys/users/${userId}`,
5178
+ url: `${configuration.growthUrl}/api/growth/v1/surveys/users/${userId}`,
4892
5179
  method: 'GET',
4893
5180
  });
4894
5181
  if (!resp.success) {
@@ -4913,7 +5200,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4913
5200
  return useMutation({
4914
5201
  mutationFn: async ({ handle, email, firstName, lastName, password, passwordConfirm, }) => {
4915
5202
  return requestDatalayer({
4916
- url: `${configuration.iamRunUrl}/api/iam/v1/join/request`,
5203
+ url: `${configuration.iamUrl}/api/iam/v1/join/request`,
4917
5204
  method: 'POST',
4918
5205
  body: {
4919
5206
  handle,
@@ -4934,7 +5221,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4934
5221
  return useMutation({
4935
5222
  mutationFn: async ({ handle, email, firstName, lastName, password, passwordConfirm, }) => {
4936
5223
  return requestDatalayer({
4937
- url: `${configuration.iamRunUrl}/api/iam/v1/join/request/token`,
5224
+ url: `${configuration.iamUrl}/api/iam/v1/join/request/token`,
4938
5225
  method: 'POST',
4939
5226
  body: {
4940
5227
  handle,
@@ -4955,7 +5242,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4955
5242
  return useMutation({
4956
5243
  mutationFn: async ({ formValues, token, }) => {
4957
5244
  return requestDatalayer({
4958
- url: `${configuration.iamRunUrl}/api/iam/v1/join/invites/token`,
5245
+ url: `${configuration.iamUrl}/api/iam/v1/join/invites/token`,
4959
5246
  method: 'POST',
4960
5247
  body: { ...formValues, token },
4961
5248
  });
@@ -4969,7 +5256,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4969
5256
  return useMutation({
4970
5257
  mutationFn: async ({ userHandle, token, }) => {
4971
5258
  return requestDatalayer({
4972
- url: `${configuration.iamRunUrl}/api/iam/v1/join/users/${userHandle}/tokens/${token}`,
5259
+ url: `${configuration.iamUrl}/api/iam/v1/join/users/${userHandle}/tokens/${token}`,
4973
5260
  method: 'GET',
4974
5261
  });
4975
5262
  },
@@ -4985,7 +5272,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4985
5272
  return useMutation({
4986
5273
  mutationFn: async ({ handle, password, passwordConfirm, }) => {
4987
5274
  return requestDatalayer({
4988
- url: `${configuration.iamRunUrl}/api/iam/v1/password/token`,
5275
+ url: `${configuration.iamUrl}/api/iam/v1/password/token`,
4989
5276
  method: 'POST',
4990
5277
  body: { handle, password, passwordConfirm },
4991
5278
  });
@@ -4999,7 +5286,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4999
5286
  return useMutation({
5000
5287
  mutationFn: async ({ handle, password, passwordConfirm, }) => {
5001
5288
  return requestDatalayer({
5002
- url: `${configuration.iamRunUrl}/api/iam/v1/password`,
5289
+ url: `${configuration.iamUrl}/api/iam/v1/password`,
5003
5290
  method: 'PUT',
5004
5291
  body: { handle, password, passwordConfirm },
5005
5292
  });
@@ -5013,7 +5300,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5013
5300
  return useMutation({
5014
5301
  mutationFn: async ({ userHandle, token, }) => {
5015
5302
  return requestDatalayer({
5016
- url: `${configuration.iamRunUrl}/api/iam/v1/password/confirm/users/${userHandle}/tokens/${token}`,
5303
+ url: `${configuration.iamUrl}/api/iam/v1/password/confirm/users/${userHandle}/tokens/${token}`,
5017
5304
  method: 'PUT',
5018
5305
  });
5019
5306
  },
@@ -5032,7 +5319,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5032
5319
  .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
5033
5320
  .join('&');
5034
5321
  const resp = await requestDatalayer({
5035
- url: `${configuration.iamRunUrl}/api/iam/v1/oauth2/authz/url?${queryString}`,
5322
+ url: `${configuration.iamUrl}/api/iam/v1/oauth2/authz/url?${queryString}`,
5036
5323
  notifyOnError: false,
5037
5324
  });
5038
5325
  return resp.autorization_url;
@@ -5049,7 +5336,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5049
5336
  .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
5050
5337
  .join('&');
5051
5338
  const resp = await requestDatalayer({
5052
- url: `${configuration.iamRunUrl}/api/iam/v1/oauth2/authz/url/link?${queryString}`,
5339
+ url: `${configuration.iamUrl}/api/iam/v1/oauth2/authz/url/link?${queryString}`,
5053
5340
  });
5054
5341
  return resp;
5055
5342
  },
@@ -5066,7 +5353,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5066
5353
  return useMutation({
5067
5354
  mutationFn: async ({ contactId, tagName, }) => {
5068
5355
  return requestDatalayer({
5069
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/${contactId}/tags/${tagName}`,
5356
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/${contactId}/tags/${tagName}`,
5070
5357
  method: 'POST',
5071
5358
  });
5072
5359
  },
@@ -5086,7 +5373,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5086
5373
  return useMutation({
5087
5374
  mutationFn: async ({ contactId, tagName, }) => {
5088
5375
  return requestDatalayer({
5089
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/${contactId}/tags/${tagName}`,
5376
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/${contactId}/tags/${tagName}`,
5090
5377
  method: 'DELETE',
5091
5378
  });
5092
5379
  },
@@ -5105,7 +5392,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5105
5392
  return useMutation({
5106
5393
  mutationFn: async ({ contactId, message, }) => {
5107
5394
  return requestDatalayer({
5108
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/invites`,
5395
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/invites`,
5109
5396
  method: 'POST',
5110
5397
  body: { contactId, message },
5111
5398
  });
@@ -5120,7 +5407,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5120
5407
  return useMutation({
5121
5408
  mutationFn: async ({ contactId, useDomain, }) => {
5122
5409
  return requestDatalayer({
5123
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/${contactId}/enrich/email?useDomain=${useDomain}`,
5410
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/${contactId}/enrich/email?useDomain=${useDomain}`,
5124
5411
  method: 'GET',
5125
5412
  });
5126
5413
  },
@@ -5139,7 +5426,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5139
5426
  return useMutation({
5140
5427
  mutationFn: async (contactId) => {
5141
5428
  return requestDatalayer({
5142
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/${contactId}/enrich/linkedin`,
5429
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/${contactId}/enrich/linkedin`,
5143
5430
  method: 'GET',
5144
5431
  });
5145
5432
  },
@@ -5158,7 +5445,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5158
5445
  return useMutation({
5159
5446
  mutationFn: async ({ contactId, message, }) => {
5160
5447
  return requestDatalayer({
5161
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/${contactId}/connect/linkedin`,
5448
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/${contactId}/connect/linkedin`,
5162
5449
  method: 'POST',
5163
5450
  body: { message },
5164
5451
  });
@@ -5181,7 +5468,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5181
5468
  return useMutation({
5182
5469
  mutationFn: async ({ userId, contactId, }) => {
5183
5470
  return requestDatalayer({
5184
- url: `${configuration.growthRunUrl}/api/growth/v1/users/${userId}/contacts/${contactId}/link`,
5471
+ url: `${configuration.growthUrl}/api/growth/v1/users/${userId}/contacts/${contactId}/link`,
5185
5472
  method: 'POST',
5186
5473
  });
5187
5474
  },
@@ -5203,7 +5490,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5203
5490
  return useMutation({
5204
5491
  mutationFn: async ({ userId, contactId, }) => {
5205
5492
  return requestDatalayer({
5206
- url: `${configuration.growthRunUrl}/api/growth/v1/users/${userId}/contacts/${contactId}/link`,
5493
+ url: `${configuration.growthUrl}/api/growth/v1/users/${userId}/contacts/${contactId}/link`,
5207
5494
  method: 'DELETE',
5208
5495
  });
5209
5496
  },
@@ -5228,7 +5515,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5228
5515
  queryKey: queryKeys.credits.organizationOverview(organizationUid),
5229
5516
  queryFn: async () => {
5230
5517
  const resp = await requestDatalayer({
5231
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits/allocations/organizations/${organizationUid}/overview`,
5518
+ url: `${configuration.iamUrl}/api/iam/v1/usage/credits/allocations/organizations/${organizationUid}/overview`,
5232
5519
  method: 'GET',
5233
5520
  });
5234
5521
  return resp.overview ?? { organization: null, teams: [] };
@@ -5245,7 +5532,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5245
5532
  queryKey: queryKeys.credits.teamOverview(teamUid),
5246
5533
  queryFn: async () => {
5247
5534
  const resp = await requestDatalayer({
5248
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits/allocations/teams/${teamUid}/overview`,
5535
+ url: `${configuration.iamUrl}/api/iam/v1/usage/credits/allocations/teams/${teamUid}/overview`,
5249
5536
  method: 'GET',
5250
5537
  });
5251
5538
  return resp.overview ?? { team: null, members: [] };
@@ -5262,7 +5549,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5262
5549
  queryKey: queryKeys.credits.organizationHistory(organizationUid),
5263
5550
  queryFn: async () => {
5264
5551
  const resp = await requestDatalayer({
5265
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits/allocations/organizations/${organizationUid}/history`,
5552
+ url: `${configuration.iamUrl}/api/iam/v1/usage/credits/allocations/organizations/${organizationUid}/history`,
5266
5553
  method: 'GET',
5267
5554
  });
5268
5555
  return (resp.history ?? { organization_uid: organizationUid, events: [] });
@@ -5279,7 +5566,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5279
5566
  queryKey: queryKeys.credits.teamHistory(teamUid),
5280
5567
  queryFn: async () => {
5281
5568
  const resp = await requestDatalayer({
5282
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits/allocations/teams/${teamUid}/history`,
5569
+ url: `${configuration.iamUrl}/api/iam/v1/usage/credits/allocations/teams/${teamUid}/history`,
5283
5570
  method: 'GET',
5284
5571
  });
5285
5572
  return resp.history ?? { team_uid: teamUid, events: [] };
@@ -5295,7 +5582,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5295
5582
  return useMutation({
5296
5583
  mutationFn: async ({ organizationUid, teamUid, amount, }) => {
5297
5584
  return requestDatalayer({
5298
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits/allocations/organizations/${organizationUid}/teams/${teamUid}`,
5585
+ url: `${configuration.iamUrl}/api/iam/v1/usage/credits/allocations/organizations/${organizationUid}/teams/${teamUid}`,
5299
5586
  method: 'POST',
5300
5587
  body: { amount },
5301
5588
  });
@@ -5323,7 +5610,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5323
5610
  return useMutation({
5324
5611
  mutationFn: async ({ teamUid, memberUid, amount, }) => {
5325
5612
  return requestDatalayer({
5326
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits/allocations/teams/${teamUid}/members/${memberUid}`,
5613
+ url: `${configuration.iamUrl}/api/iam/v1/usage/credits/allocations/teams/${teamUid}/members/${memberUid}`,
5327
5614
  method: 'POST',
5328
5615
  body: { amount },
5329
5616
  });
@@ -5345,7 +5632,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5345
5632
  return useMutation({
5346
5633
  mutationFn: async ({ organizationUid, teamUid, amount, }) => {
5347
5634
  return requestDatalayer({
5348
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits/allocations/organizations/${organizationUid}/teams/${teamUid}/revoke`,
5635
+ url: `${configuration.iamUrl}/api/iam/v1/usage/credits/allocations/organizations/${organizationUid}/teams/${teamUid}/revoke`,
5349
5636
  method: 'POST',
5350
5637
  body: { amount },
5351
5638
  });
@@ -5373,7 +5660,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5373
5660
  return useMutation({
5374
5661
  mutationFn: async ({ teamUid, memberUid, amount, }) => {
5375
5662
  return requestDatalayer({
5376
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits/allocations/teams/${teamUid}/members/${memberUid}/revoke`,
5663
+ url: `${configuration.iamUrl}/api/iam/v1/usage/credits/allocations/teams/${teamUid}/members/${memberUid}/revoke`,
5377
5664
  method: 'POST',
5378
5665
  body: { amount },
5379
5666
  });
@@ -5396,7 +5683,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5396
5683
  return useMutation({
5397
5684
  mutationFn: async ({ userId, quota, }) => {
5398
5685
  return requestDatalayer({
5399
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/quota`,
5686
+ url: `${configuration.iamUrl}/api/iam/v1/usage/quota`,
5400
5687
  method: 'PUT',
5401
5688
  body: {
5402
5689
  user_uid: userId,
@@ -5478,7 +5765,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5478
5765
  };
5479
5766
  };
5480
5767
  const resp = await requestDatalayer({
5481
- url: withAccountUidQuery(`${configuration.iamRunUrl}/api/iam/v1/usage/user`, scope?.accountUid),
5768
+ url: withAccountUidQuery(`${configuration.iamUrl}/api/iam/v1/usage/user`, scope?.accountUid),
5482
5769
  method: 'GET',
5483
5770
  });
5484
5771
  // Transform snake_case API response to camelCase IUsage interface
@@ -5545,7 +5832,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5545
5832
  };
5546
5833
  };
5547
5834
  const resp = await requestDatalayer({
5548
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/users/${userId}`,
5835
+ url: `${configuration.iamUrl}/api/iam/v1/usage/users/${userId}`,
5549
5836
  method: 'GET',
5550
5837
  });
5551
5838
  // Transform snake_case API response to camelCase IUsage interface
@@ -5613,7 +5900,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5613
5900
  };
5614
5901
  };
5615
5902
  const resp = await requestDatalayer({
5616
- url: `${configuration.iamRunUrl}/api/iam/v1/usage/platform`,
5903
+ url: `${configuration.iamUrl}/api/iam/v1/usage/platform`,
5617
5904
  method: 'GET',
5618
5905
  });
5619
5906
  // Transform snake_case API response to camelCase IUsage interface
@@ -5631,17 +5918,24 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5631
5918
  */
5632
5919
  const useSearchPublicItems = () => {
5633
5920
  return useMutation({
5634
- mutationFn: async ({ q, types = ['notebook', 'document', 'lesson'], max = 100, }) => {
5921
+ mutationFn: async ({ q, types = ['notebook', 'document', 'cell', 'lesson', 'evalset', 'course'], max = 100, }) => {
5922
+ const normalizedTypes = Array.from(new Set((types || [])
5923
+ .map(type => String(type || '')
5924
+ .trim()
5925
+ .toLowerCase())
5926
+ .filter(Boolean)
5927
+ .map(type => (type === 'eval' ? 'evalset' : type))));
5635
5928
  const queryString = Object.entries({
5636
5929
  q: q || '*',
5637
- types: types.join(' '),
5930
+ types: (normalizedTypes.length > 0
5931
+ ? normalizedTypes
5932
+ : ['notebook', 'document', 'cell', 'lesson', 'evalset', 'course']).join(' '),
5638
5933
  max: max.toString(),
5639
- public: 'true',
5640
5934
  })
5641
5935
  .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
5642
5936
  .join('&');
5643
5937
  const resp = await requestDatalayer({
5644
- url: `${configuration.libraryRunUrl}/api/library/v1/search?${queryString}`,
5938
+ url: `${configuration.libraryUrl}/api/library/v1/search?${queryString}`,
5645
5939
  method: 'GET',
5646
5940
  });
5647
5941
  if (!resp.success) {
@@ -5698,7 +5992,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5698
5992
  return useMutation({
5699
5993
  mutationFn: async (accessToken) => {
5700
5994
  return requestDatalayer({
5701
- url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
5995
+ url: `${configuration.iamUrl}/api/iam/v1/proxy/request`,
5702
5996
  method: 'POST',
5703
5997
  body: {
5704
5998
  request_method: 'GET',
@@ -5729,7 +6023,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5729
6023
  },
5730
6024
  };
5731
6025
  return requestDatalayer({
5732
- url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
6026
+ url: `${configuration.iamUrl}/api/iam/v1/proxy/request`,
5733
6027
  method: 'POST',
5734
6028
  body: {
5735
6029
  request_method: 'POST',
@@ -5763,7 +6057,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5763
6057
  },
5764
6058
  };
5765
6059
  const registerResp = await requestDatalayer({
5766
- url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
6060
+ url: `${configuration.iamUrl}/api/iam/v1/proxy/request`,
5767
6061
  method: 'POST',
5768
6062
  body: {
5769
6063
  request_method: 'POST',
@@ -5776,7 +6070,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5776
6070
  const uploadUrl = registerResp.response.value.uploadMechanism['com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest'].uploadUrl;
5777
6071
  // Step 2: Upload image
5778
6072
  await requestDatalayer({
5779
- url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
6073
+ url: `${configuration.iamUrl}/api/iam/v1/proxy/request`,
5780
6074
  method: 'POST',
5781
6075
  body: {
5782
6076
  request_method: 'PUT',
@@ -5829,7 +6123,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5829
6123
  };
5830
6124
  }
5831
6125
  return requestDatalayer({
5832
- url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
6126
+ url: `${configuration.iamUrl}/api/iam/v1/proxy/request`,
5833
6127
  method: 'POST',
5834
6128
  body: {
5835
6129
  request_method: 'POST',
@@ -5851,7 +6145,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5851
6145
  return useMutation({
5852
6146
  mutationFn: async ({ url, token }) => {
5853
6147
  return requestDatalayer({
5854
- url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
6148
+ url: `${configuration.iamUrl}/api/iam/v1/proxy/request`,
5855
6149
  method: 'POST',
5856
6150
  body: {
5857
6151
  request_method: 'GET',
@@ -5869,7 +6163,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5869
6163
  return useMutation({
5870
6164
  mutationFn: async ({ url, body, token, }) => {
5871
6165
  return requestDatalayer({
5872
- url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
6166
+ url: `${configuration.iamUrl}/api/iam/v1/proxy/request`,
5873
6167
  method: 'POST',
5874
6168
  body: {
5875
6169
  request_method: 'POST',
@@ -5888,7 +6182,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5888
6182
  return useMutation({
5889
6183
  mutationFn: async ({ url, body, token, }) => {
5890
6184
  return requestDatalayer({
5891
- url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
6185
+ url: `${configuration.iamUrl}/api/iam/v1/proxy/request`,
5892
6186
  method: 'POST',
5893
6187
  body: {
5894
6188
  request_method: 'PUT',
@@ -5910,7 +6204,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5910
6204
  return useMutation({
5911
6205
  mutationFn: async ({ firstName, lastName, email, affiliation, }) => {
5912
6206
  return requestDatalayer({
5913
- url: `${configuration.growthRunUrl}/api/growth/v1/waitinglist/register`,
6207
+ url: `${configuration.growthUrl}/api/growth/v1/waitinglist/register`,
5914
6208
  method: 'POST',
5915
6209
  body: {
5916
6210
  firstName,
@@ -5930,7 +6224,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5930
6224
  queryKey: ['growth', 'kpi'],
5931
6225
  queryFn: async () => {
5932
6226
  const resp = await requestDatalayer({
5933
- url: `${configuration.growthRunUrl}/api/growth/v1/kpis`,
6227
+ url: `${configuration.growthUrl}/api/growth/v1/kpis`,
5934
6228
  method: 'GET',
5935
6229
  });
5936
6230
  return resp;
@@ -5946,7 +6240,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5946
6240
  queryKey: ['growth', 'contacts-kpi'],
5947
6241
  queryFn: async () => {
5948
6242
  const resp = await requestDatalayer({
5949
- url: `${configuration.growthRunUrl}/api/growth/v1/kpis/contacts`,
6243
+ url: `${configuration.growthUrl}/api/growth/v1/kpis/contacts`,
5950
6244
  method: 'GET',
5951
6245
  });
5952
6246
  return resp;
@@ -5968,7 +6262,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5968
6262
  return useMutation({
5969
6263
  mutationFn: async ({ userId, spaceId, }) => {
5970
6264
  const resp = await requestDatalayer({
5971
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/users/${userId}`,
6265
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/users/${userId}`,
5972
6266
  method: 'GET',
5973
6267
  });
5974
6268
  return resp;
@@ -5994,7 +6288,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5994
6288
  return useMutation({
5995
6289
  mutationFn: async (courseId) => {
5996
6290
  const resp = await requestDatalayer({
5997
- url: `${configuration.spacerRunUrl}/api/spacer/v1/courses/${courseId}`,
6291
+ url: `${configuration.spacerUrl}/api/spacer/v1/courses/${courseId}`,
5998
6292
  method: 'GET',
5999
6293
  });
6000
6294
  return resp;
@@ -6016,7 +6310,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6016
6310
  return useMutation({
6017
6311
  mutationFn: async () => {
6018
6312
  const resp = await requestDatalayer({
6019
- url: `${configuration.libraryRunUrl}/api/library/v1/courses/public`,
6313
+ url: `${configuration.libraryUrl}/api/library/v1/courses/public`,
6020
6314
  method: 'GET',
6021
6315
  });
6022
6316
  return resp;
@@ -6038,7 +6332,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6038
6332
  return useMutation({
6039
6333
  mutationFn: async () => {
6040
6334
  const resp = await requestDatalayer({
6041
- url: `${configuration.spacerRunUrl}/api/spacer/v1/instructors/${user?.id}/courses`,
6335
+ url: `${configuration.spacerUrl}/api/spacer/v1/instructors/${user?.id}/courses`,
6042
6336
  method: 'GET',
6043
6337
  });
6044
6338
  return resp;
@@ -6060,7 +6354,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6060
6354
  return useMutation({
6061
6355
  mutationFn: async () => {
6062
6356
  const resp = await requestDatalayer({
6063
- url: `${configuration.spacerRunUrl}/api/spacer/v1/courses/enrollments/me`,
6357
+ url: `${configuration.spacerUrl}/api/spacer/v1/courses/enrollments/me`,
6064
6358
  method: 'GET',
6065
6359
  });
6066
6360
  return resp;
@@ -6082,7 +6376,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6082
6376
  return useMutation({
6083
6377
  mutationFn: async ({ courseId, studentHandle, }) => {
6084
6378
  const resp = await requestDatalayer({
6085
- url: `${configuration.spacerRunUrl}/api/spacer/v1/courses/${courseId}/enrollments/students/${studentHandle}`,
6379
+ url: `${configuration.spacerUrl}/api/spacer/v1/courses/${courseId}/enrollments/students/${studentHandle}`,
6086
6380
  method: 'GET',
6087
6381
  });
6088
6382
  return resp;
@@ -6104,7 +6398,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6104
6398
  return useMutation({
6105
6399
  mutationFn: async (notebookId) => {
6106
6400
  const resp = await requestDatalayer({
6107
- url: `${configuration.spacerRunUrl}/api/spacer/v1/notebooks/${notebookId}`,
6401
+ url: `${configuration.spacerUrl}/api/spacer/v1/notebooks/${notebookId}`,
6108
6402
  method: 'GET',
6109
6403
  });
6110
6404
  return resp;
@@ -6126,7 +6420,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6126
6420
  return useMutation({
6127
6421
  mutationFn: async (spaceId) => {
6128
6422
  const resp = await requestDatalayer({
6129
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/notebook`,
6423
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/notebook`,
6130
6424
  method: 'GET',
6131
6425
  });
6132
6426
  return resp;
@@ -6158,7 +6452,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6158
6452
  return useMutation({
6159
6453
  mutationFn: async (documentId) => {
6160
6454
  const resp = await requestDatalayer({
6161
- url: `${configuration.spacerRunUrl}/api/spacer/v1/lexicals/${documentId}`,
6455
+ url: `${configuration.spacerUrl}/api/spacer/v1/lexicals/${documentId}`,
6162
6456
  method: 'GET',
6163
6457
  });
6164
6458
  return resp;
@@ -6180,7 +6474,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6180
6474
  return useMutation({
6181
6475
  mutationFn: async (spaceId) => {
6182
6476
  const resp = await requestDatalayer({
6183
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/document`,
6477
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/document`,
6184
6478
  method: 'GET',
6185
6479
  });
6186
6480
  return resp;
@@ -6202,7 +6496,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6202
6496
  return useMutation({
6203
6497
  mutationFn: async (cellId) => {
6204
6498
  const resp = await requestDatalayer({
6205
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/items/${cellId}`,
6499
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/items/${cellId}`,
6206
6500
  method: 'GET',
6207
6501
  });
6208
6502
  return resp;
@@ -6224,7 +6518,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6224
6518
  return useMutation({
6225
6519
  mutationFn: async (spaceId) => {
6226
6520
  const resp = await requestDatalayer({
6227
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/cell`,
6521
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/cell`,
6228
6522
  method: 'GET',
6229
6523
  });
6230
6524
  return resp;
@@ -6244,14 +6538,26 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6244
6538
  const useRefreshDataset = (options) => {
6245
6539
  const queryClient = useQueryClient();
6246
6540
  return useMutation({
6247
- mutationFn: async (datasetId) => {
6541
+ mutationFn: async (variables) => {
6542
+ const datasetId = typeof variables === 'string' ? variables : variables.datasetId;
6543
+ const selectedPrincipalUid = typeof variables === 'string' ? undefined : variables.selectedPrincipalUid;
6544
+ const selectedPrincipalKind = typeof variables === 'string' ? undefined : variables.selectedPrincipalKind;
6545
+ const params = new URLSearchParams();
6546
+ if (selectedPrincipalUid) {
6547
+ params.set('selected_principal_uid', selectedPrincipalUid);
6548
+ }
6549
+ if (selectedPrincipalKind) {
6550
+ params.set('selected_principal_kind', selectedPrincipalKind);
6551
+ }
6552
+ const query = params.toString();
6248
6553
  const resp = await requestDatalayer({
6249
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/items/${datasetId}`,
6554
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/spaces/items/${datasetId}${query ? `?${query}` : ''}`,
6250
6555
  method: 'GET',
6251
6556
  });
6252
6557
  return resp;
6253
6558
  },
6254
- onSuccess: (data, datasetId) => {
6559
+ onSuccess: (data, variables) => {
6560
+ const datasetId = typeof variables === 'string' ? variables : variables.datasetId;
6255
6561
  queryClient.invalidateQueries({
6256
6562
  queryKey: queryKeys.datasets.detail(datasetId),
6257
6563
  });
@@ -6266,14 +6572,26 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6266
6572
  const useRefreshSpaceDatasets = (options) => {
6267
6573
  const queryClient = useQueryClient();
6268
6574
  return useMutation({
6269
- mutationFn: async (spaceId) => {
6575
+ mutationFn: async (variables) => {
6576
+ const spaceId = typeof variables === 'string' ? variables : variables.spaceId;
6577
+ const selectedPrincipalUid = typeof variables === 'string' ? undefined : variables.selectedPrincipalUid;
6578
+ const selectedPrincipalKind = typeof variables === 'string' ? undefined : variables.selectedPrincipalKind;
6579
+ const params = new URLSearchParams();
6580
+ if (selectedPrincipalUid) {
6581
+ params.set('selected_principal_uid', selectedPrincipalUid);
6582
+ }
6583
+ if (selectedPrincipalKind) {
6584
+ params.set('selected_principal_kind', selectedPrincipalKind);
6585
+ }
6586
+ const query = params.toString();
6270
6587
  const resp = await requestDatalayer({
6271
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/dataset`,
6588
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/spaces/${spaceId}/items/types/dataset${query ? `?${query}` : ''}`,
6272
6589
  method: 'GET',
6273
6590
  });
6274
6591
  return resp;
6275
6592
  },
6276
- onSuccess: (data, spaceId) => {
6593
+ onSuccess: (data, variables) => {
6594
+ const spaceId = typeof variables === 'string' ? variables : variables.spaceId;
6277
6595
  queryClient.invalidateQueries({
6278
6596
  queryKey: queryKeys.datasets.bySpace(spaceId),
6279
6597
  });
@@ -6290,7 +6608,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6290
6608
  return useMutation({
6291
6609
  mutationFn: async () => {
6292
6610
  const resp = await requestDatalayer({
6293
- url: `${configuration.iamRunUrl}/api/iam/v1/organizations/schools`,
6611
+ url: `${configuration.iamUrl}/api/iam/v1/organizations/schools`,
6294
6612
  method: 'GET',
6295
6613
  });
6296
6614
  return resp;
@@ -6310,10 +6628,37 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6310
6628
  queryKey: queryKeys.items.public(),
6311
6629
  queryFn: async () => {
6312
6630
  const resp = await requestDatalayer({
6313
- url: `${configuration.libraryRunUrl}/api/library/v1/items/public`,
6631
+ url: `${configuration.libraryUrl}/api/library/v1/search?q=*&max=-1`,
6314
6632
  method: 'GET',
6315
6633
  });
6316
- return resp;
6634
+ return {
6635
+ ...resp,
6636
+ items: (resp.items || [])
6637
+ .map((item) => toItem(item))
6638
+ .filter(Boolean),
6639
+ };
6640
+ },
6641
+ ...options,
6642
+ });
6643
+ };
6644
+ /**
6645
+ * Get the current user's own public items (publications).
6646
+ * @param options - Query options
6647
+ */
6648
+ const usePublications = (options) => {
6649
+ return useQuery({
6650
+ queryKey: [...queryKeys.items.all(), 'publications'],
6651
+ queryFn: async () => {
6652
+ const resp = await requestDatalayer({
6653
+ url: `${configuration.libraryUrl}/api/library/v1/publications`,
6654
+ method: 'GET',
6655
+ });
6656
+ return {
6657
+ ...resp,
6658
+ items: (resp.items || [])
6659
+ .map((item) => toItem(item))
6660
+ .filter(Boolean),
6661
+ };
6317
6662
  },
6318
6663
  ...options,
6319
6664
  });
@@ -6327,10 +6672,15 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6327
6672
  return useMutation({
6328
6673
  mutationFn: async () => {
6329
6674
  const resp = await requestDatalayer({
6330
- url: `${configuration.libraryRunUrl}/api/library/v1/items/public`,
6675
+ url: `${configuration.libraryUrl}/api/library/v1/search?q=*&max=-1`,
6331
6676
  method: 'GET',
6332
6677
  });
6333
- return resp;
6678
+ return {
6679
+ ...resp,
6680
+ items: (resp.items || [])
6681
+ .map((item) => toItem(item))
6682
+ .filter(Boolean),
6683
+ };
6334
6684
  },
6335
6685
  onSuccess: () => {
6336
6686
  queryClient.invalidateQueries({ queryKey: queryKeys.items.public() });
@@ -6347,7 +6697,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6347
6697
  return useMutation({
6348
6698
  mutationFn: async (spaceId) => {
6349
6699
  const resp = await requestDatalayer({
6350
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items`,
6700
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items`,
6351
6701
  method: 'GET',
6352
6702
  });
6353
6703
  return resp;
@@ -6406,7 +6756,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6406
6756
  return useMutation({
6407
6757
  mutationFn: async (environmentId) => {
6408
6758
  const resp = await requestDatalayer({
6409
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/items/${environmentId}`,
6759
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/items/${environmentId}`,
6410
6760
  method: 'GET',
6411
6761
  });
6412
6762
  return resp;
@@ -6428,7 +6778,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6428
6778
  return useMutation({
6429
6779
  mutationFn: async (spaceId) => {
6430
6780
  const resp = await requestDatalayer({
6431
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/environment`,
6781
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/environment`,
6432
6782
  method: 'GET',
6433
6783
  });
6434
6784
  return resp;
@@ -6450,7 +6800,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6450
6800
  return useMutation({
6451
6801
  mutationFn: async (lessonId) => {
6452
6802
  const resp = await requestDatalayer({
6453
- url: `${configuration.spacerRunUrl}/api/spacer/v1/lessons/${lessonId}`,
6803
+ url: `${configuration.spacerUrl}/api/spacer/v1/lessons/${lessonId}`,
6454
6804
  method: 'GET',
6455
6805
  });
6456
6806
  return resp;
@@ -6472,7 +6822,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6472
6822
  return useMutation({
6473
6823
  mutationFn: async (spaceId) => {
6474
6824
  const resp = await requestDatalayer({
6475
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/lesson`,
6825
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/lesson`,
6476
6826
  method: 'GET',
6477
6827
  });
6478
6828
  return resp;
@@ -6494,7 +6844,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6494
6844
  return useMutation({
6495
6845
  mutationFn: async (exerciseId) => {
6496
6846
  const resp = await requestDatalayer({
6497
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/items/${exerciseId}`,
6847
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/items/${exerciseId}`,
6498
6848
  method: 'GET',
6499
6849
  });
6500
6850
  return resp;
@@ -6516,7 +6866,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6516
6866
  return useMutation({
6517
6867
  mutationFn: async (spaceId) => {
6518
6868
  const resp = await requestDatalayer({
6519
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/exercise`,
6869
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/exercise`,
6520
6870
  method: 'GET',
6521
6871
  });
6522
6872
  return resp;
@@ -6538,7 +6888,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6538
6888
  return useMutation({
6539
6889
  mutationFn: async (assignmentId) => {
6540
6890
  const resp = await requestDatalayer({
6541
- url: `${configuration.spacerRunUrl}/api/spacer/v1/assignments/${assignmentId}`,
6891
+ url: `${configuration.spacerUrl}/api/spacer/v1/assignments/${assignmentId}`,
6542
6892
  method: 'GET',
6543
6893
  });
6544
6894
  return resp;
@@ -6560,7 +6910,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6560
6910
  return useMutation({
6561
6911
  mutationFn: async ({ courseId, userId, assignmentId, }) => {
6562
6912
  const resp = await requestDatalayer({
6563
- url: `${configuration.spacerRunUrl}/api/spacer/v1/assignments/${assignmentId}/courses/${courseId}/students/${userId}`,
6913
+ url: `${configuration.spacerUrl}/api/spacer/v1/assignments/${assignmentId}/courses/${courseId}/students/${userId}`,
6564
6914
  method: 'GET',
6565
6915
  });
6566
6916
  return resp;
@@ -6582,7 +6932,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6582
6932
  return useMutation({
6583
6933
  mutationFn: async (spaceId) => {
6584
6934
  const resp = await requestDatalayer({
6585
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/assignment`,
6935
+ url: `${configuration.spacerUrl}/api/spacer/v1/spaces/${spaceId}/items/types/assignment`,
6586
6936
  method: 'GET',
6587
6937
  });
6588
6938
  return resp;
@@ -6625,6 +6975,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6625
6975
  },
6626
6976
  onSuccess: () => {
6627
6977
  queryClient.invalidateQueries({ queryKey: queryKeys.items.public() });
6978
+ queryClient.invalidateQueries({
6979
+ queryKey: [...queryKeys.items.all(), 'publications'],
6980
+ });
6628
6981
  },
6629
6982
  ...options,
6630
6983
  });
@@ -6640,7 +6993,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6640
6993
  return useMutation({
6641
6994
  mutationFn: async ({ firstName, lastName, email, socialUrl, }) => {
6642
6995
  const resp = await requestDatalayer({
6643
- url: `${configuration.growthRunUrl}/api/growth/v1/invites/request`,
6996
+ url: `${configuration.growthUrl}/api/growth/v1/invites/request`,
6644
6997
  method: 'POST',
6645
6998
  body: {
6646
6999
  first_name: firstName,
@@ -6663,7 +7016,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6663
7016
  return useMutation({
6664
7017
  mutationFn: async ({ email, firstName, lastName, message, brand, }) => {
6665
7018
  const resp = await requestDatalayer({
6666
- url: `${configuration.growthRunUrl}/api/growth/v1/invites`,
7019
+ url: `${configuration.growthUrl}/api/growth/v1/invites`,
6667
7020
  method: 'POST',
6668
7021
  body: {
6669
7022
  email,
@@ -6690,7 +7043,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6690
7043
  return useMutation({
6691
7044
  mutationFn: async (token) => {
6692
7045
  const resp = await requestDatalayer({
6693
- url: `${configuration.growthRunUrl}/api/growth/v1/invites/tokens/${token}`,
7046
+ url: `${configuration.growthUrl}/api/growth/v1/invites/tokens/${token}`,
6694
7047
  method: 'GET',
6695
7048
  });
6696
7049
  return resp;
@@ -6710,7 +7063,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6710
7063
  return useMutation({
6711
7064
  mutationFn: async (accountId) => {
6712
7065
  const resp = await requestDatalayer({
6713
- url: `${configuration.growthRunUrl}/api/growth/v1/invites/users/${accountId}`,
7066
+ url: `${configuration.growthUrl}/api/growth/v1/invites/users/${accountId}`,
6714
7067
  method: 'GET',
6715
7068
  });
6716
7069
  return resp;
@@ -6747,7 +7100,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6747
7100
  return useMutation({
6748
7101
  mutationFn: async (contactId) => {
6749
7102
  const resp = await requestDatalayer({
6750
- url: `${configuration.growthRunUrl}/api/growth/v1/contacts/${contactId}`,
7103
+ url: `${configuration.growthUrl}/api/growth/v1/contacts/${contactId}`,
6751
7104
  method: 'GET',
6752
7105
  });
6753
7106
  return resp;
@@ -6770,7 +7123,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6770
7123
  queryKey: ['inbounds', id],
6771
7124
  queryFn: async () => {
6772
7125
  const resp = await requestDatalayer({
6773
- url: `${configuration.inboundsRunUrl}/api/inbounds/v1/inbounds/${id}`,
7126
+ url: `${configuration.inboundsUrl}/api/inbounds/v1/inbounds/${id}`,
6774
7127
  method: 'GET',
6775
7128
  });
6776
7129
  return resp;
@@ -6788,7 +7141,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6788
7141
  queryKey: ['inbounds', 'handle', handle],
6789
7142
  queryFn: async () => {
6790
7143
  const resp = await requestDatalayer({
6791
- url: `${configuration.inboundsRunUrl}/api/inbounds/v1/inbounds/handles/${handle}`,
7144
+ url: `${configuration.inboundsUrl}/api/inbounds/v1/inbounds/handles/${handle}`,
6792
7145
  method: 'GET',
6793
7146
  });
6794
7147
  return resp;
@@ -6805,7 +7158,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6805
7158
  return useMutation({
6806
7159
  mutationFn: async (userId) => {
6807
7160
  const resp = await requestDatalayer({
6808
- url: `${configuration.inboundsRunUrl}/api/inbounds/v1/inbounds/${userId}`,
7161
+ url: `${configuration.inboundsUrl}/api/inbounds/v1/inbounds/${userId}`,
6809
7162
  method: 'GET',
6810
7163
  });
6811
7164
  return resp;
@@ -6826,7 +7179,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6826
7179
  return useMutation({
6827
7180
  mutationFn: async (outboundId) => {
6828
7181
  const resp = await requestDatalayer({
6829
- url: `${configuration.growthRunUrl}/api/growth/v1/outbounds/${outboundId}`,
7182
+ url: `${configuration.growthUrl}/api/growth/v1/outbounds/${outboundId}`,
6830
7183
  method: 'GET',
6831
7184
  });
6832
7185
  return resp;
@@ -6846,7 +7199,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6846
7199
  queryKey: queryKeys.ray.clusters(),
6847
7200
  queryFn: async () => {
6848
7201
  const resp = await requestDatalayer({
6849
- url: `${configuration.runtimesRunUrl}/api/runtimes/v1/ray/clusters`,
7202
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/ray/clusters`,
6850
7203
  method: 'GET',
6851
7204
  });
6852
7205
  if (!resp.success) {
@@ -6861,7 +7214,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6861
7214
  },
6862
7215
  ...DEFAULT_QUERY_OPTIONS,
6863
7216
  refetchOnMount: true,
6864
- enabled: Boolean(configuration.runtimesRunUrl),
7217
+ enabled: Boolean(configuration.runtimesUrl),
6865
7218
  });
6866
7219
  };
6867
7220
  const useRayCluster = (namespace = 'default', clusterName = '') => {
@@ -6869,7 +7222,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6869
7222
  queryKey: queryKeys.ray.cluster(namespace, clusterName),
6870
7223
  queryFn: async () => {
6871
7224
  const resp = await requestDatalayer({
6872
- url: `${configuration.runtimesRunUrl}/api/runtimes/v1/ray/clusters/${encodeURIComponent(clusterName)}?namespace=${encodeURIComponent(namespace)}`,
7225
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/ray/clusters/${encodeURIComponent(clusterName)}?namespace=${encodeURIComponent(namespace)}`,
6873
7226
  method: 'GET',
6874
7227
  });
6875
7228
  if (!resp.success) {
@@ -6878,7 +7231,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6878
7231
  return resp.cluster || null;
6879
7232
  },
6880
7233
  ...DEFAULT_QUERY_OPTIONS,
6881
- enabled: Boolean(configuration.runtimesRunUrl) &&
7234
+ enabled: Boolean(configuration.runtimesUrl) &&
6882
7235
  Boolean(namespace) &&
6883
7236
  Boolean(clusterName),
6884
7237
  });
@@ -6887,7 +7240,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6887
7240
  return useMutation({
6888
7241
  mutationFn: async (payload) => {
6889
7242
  const resp = await requestDatalayer({
6890
- url: `${configuration.runtimesRunUrl}/api/runtimes/v1/ray/clusters`,
7243
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/ray/clusters`,
6891
7244
  method: 'POST',
6892
7245
  body: payload,
6893
7246
  });
@@ -6905,7 +7258,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6905
7258
  return useMutation({
6906
7259
  mutationFn: async (clusterName) => {
6907
7260
  return requestDatalayer({
6908
- url: `${configuration.runtimesRunUrl}/api/runtimes/v1/ray/clusters/${encodeURIComponent(clusterName)}?namespace=${encodeURIComponent(namespace)}`,
7261
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/ray/clusters/${encodeURIComponent(clusterName)}?namespace=${encodeURIComponent(namespace)}`,
6909
7262
  method: 'DELETE',
6910
7263
  });
6911
7264
  },
@@ -6924,7 +7277,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6924
7277
  params.set('cluster_name', clusterName);
6925
7278
  }
6926
7279
  const resp = await requestDatalayer({
6927
- url: `${configuration.runtimesRunUrl}/api/runtimes/v1/ray/jobs?${params.toString()}`,
7280
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/ray/jobs?${params.toString()}`,
6928
7281
  method: 'GET',
6929
7282
  });
6930
7283
  if (!resp.success) {
@@ -6933,14 +7286,14 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6933
7286
  return asArray(resp.jobs);
6934
7287
  },
6935
7288
  ...DEFAULT_QUERY_OPTIONS,
6936
- enabled: Boolean(configuration.runtimesRunUrl),
7289
+ enabled: Boolean(configuration.runtimesUrl),
6937
7290
  });
6938
7291
  };
6939
7292
  const useSubmitRayJob = (clusterName) => {
6940
7293
  return useMutation({
6941
7294
  mutationFn: async (payload) => {
6942
7295
  return requestDatalayer({
6943
- url: `${configuration.runtimesRunUrl}/api/runtimes/v1/ray/clusters/${encodeURIComponent(clusterName)}/jobs`,
7296
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/ray/clusters/${encodeURIComponent(clusterName)}/jobs`,
6944
7297
  method: 'POST',
6945
7298
  body: payload,
6946
7299
  });
@@ -6954,7 +7307,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6954
7307
  return useMutation({
6955
7308
  mutationFn: async (jobName) => {
6956
7309
  return requestDatalayer({
6957
- url: `${configuration.runtimesRunUrl}/api/runtimes/v1/ray/jobs/${encodeURIComponent(jobName)}?namespace=${encodeURIComponent(namespace)}`,
7310
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/ray/jobs/${encodeURIComponent(jobName)}?namespace=${encodeURIComponent(namespace)}`,
6958
7311
  method: 'DELETE',
6959
7312
  });
6960
7313
  },
@@ -6971,7 +7324,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6971
7324
  params.set('namespace', namespace);
6972
7325
  params.set('tail_lines', String(tailLines));
6973
7326
  const resp = await requestDatalayer({
6974
- url: `${configuration.runtimesRunUrl}/api/runtimes/v1/ray/jobs/${encodeURIComponent(jobName)}/logs?${params.toString()}`,
7327
+ url: `${configuration.runtimesUrl}/api/runtimes/v1/ray/jobs/${encodeURIComponent(jobName)}/logs?${params.toString()}`,
6975
7328
  method: 'GET',
6976
7329
  // Logs naturally 404 once a job is deleted; never surface a toast.
6977
7330
  notifyOnError: false,
@@ -6985,7 +7338,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6985
7338
  };
6986
7339
  },
6987
7340
  ...DEFAULT_QUERY_OPTIONS,
6988
- enabled: Boolean(configuration.runtimesRunUrl) && Boolean(jobName) && enabled,
7341
+ enabled: Boolean(configuration.runtimesUrl) && Boolean(jobName) && enabled,
6989
7342
  refetchOnMount: 'always',
6990
7343
  refetchInterval: query => {
6991
7344
  const status = String(query.state.data?.status || '').toLowerCase();
@@ -7118,6 +7471,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
7118
7471
  useEnrollStudentToCourse,
7119
7472
  useRemoveStudentFromCourse,
7120
7473
  useStudent,
7474
+ useStudents,
7121
7475
  useConfirmCourseItemCompletion,
7122
7476
  useSetCourseItems,
7123
7477
  useRefreshCourse,
@@ -7172,7 +7526,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
7172
7526
  useExercisesBySpace,
7173
7527
  useUpdateExercise,
7174
7528
  useCloneExercise,
7175
- useUpdateExercisePoints,
7529
+ useUpdateExerciseScore,
7176
7530
  useRefreshExercise,
7177
7531
  useRefreshSpaceExercises,
7178
7532
  // Assignments
@@ -7194,6 +7548,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
7194
7548
  useMakeItemPrivate,
7195
7549
  useSearchPublicItems,
7196
7550
  usePublicItems,
7551
+ usePublications,
7197
7552
  useRefreshPublicItems,
7198
7553
  useRefreshSpaceItems,
7199
7554
  useClearCachedPublicItems,