@datalayer/core 1.0.24 → 1.1.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/README.md +35 -24
  2. package/lib/api/constants.d.ts +3 -0
  3. package/lib/api/constants.js +3 -0
  4. package/lib/api/index.d.ts +0 -8
  5. package/lib/api/index.js +0 -8
  6. package/lib/cli-login.js +167 -0
  7. package/lib/client/base.d.ts +0 -3
  8. package/lib/client/base.js +0 -2
  9. package/lib/client/index.d.ts +10 -98
  10. package/lib/client/index.js +12 -21
  11. package/lib/components/avatars/UserAvatar.d.ts +16 -0
  12. package/lib/components/avatars/UserAvatar.js +47 -0
  13. package/lib/components/avatars/index.d.ts +1 -0
  14. package/lib/components/avatars/index.js +1 -0
  15. package/lib/components/billing/BillableAccountSelect.js +4 -0
  16. package/lib/components/billing/index.js +4 -0
  17. package/lib/components/checkout/StripeCheckout.js +48 -2
  18. package/lib/components/context/index.d.ts +0 -1
  19. package/lib/components/context/index.js +0 -1
  20. package/lib/components/display/DisplayHandle.d.ts +12 -0
  21. package/lib/components/display/DisplayHandle.js +11 -0
  22. package/lib/components/display/LiveRelativeTime.d.ts +1 -10
  23. package/lib/components/display/LiveRelativeTime.js +5 -16
  24. package/lib/components/display/index.d.ts +1 -0
  25. package/lib/components/display/index.js +1 -0
  26. package/lib/components/flashes/index.d.ts +0 -1
  27. package/lib/components/flashes/index.js +0 -1
  28. package/lib/components/index.d.ts +2 -0
  29. package/lib/components/index.js +2 -0
  30. package/lib/components/principal/Principal.d.ts +7 -0
  31. package/lib/components/principal/Principal.js +153 -16
  32. package/lib/components/principal/PrincipalAvatar.d.ts +1 -1
  33. package/lib/components/principal/PrincipalAvatar.js +4 -28
  34. package/lib/components/principal/PrincipalBadge.js +4 -4
  35. package/lib/components/principal/PrincipalDetailsOverlay.d.ts +4 -2
  36. package/lib/components/principal/PrincipalDetailsOverlay.js +27 -7
  37. package/lib/components/principal/PrincipalSwitcherMenu.js +76 -39
  38. package/lib/components/progress/index.d.ts +0 -1
  39. package/lib/components/progress/index.js +0 -1
  40. package/lib/components/sharing/ShareAccessComponent.d.ts +3 -2
  41. package/lib/components/sharing/ShareAccessComponent.js +180 -133
  42. package/lib/components/sharing/SharingEditor.js +4 -0
  43. package/lib/components/snippets/index.d.ts +1 -1
  44. package/lib/components/snippets/index.js +1 -1
  45. package/lib/components/students/StudentResultCircle.d.ts +21 -0
  46. package/lib/components/students/StudentResultCircle.js +59 -0
  47. package/lib/components/students/index.d.ts +1 -1
  48. package/lib/components/students/index.js +1 -1
  49. package/lib/components/time/LiveRelativeTime.d.ts +14 -0
  50. package/lib/components/time/LiveRelativeTime.js +43 -0
  51. package/lib/components/time/index.d.ts +1 -0
  52. package/lib/components/time/index.js +9 -0
  53. package/lib/components/timeline/Timeline.d.ts +20 -0
  54. package/lib/components/timeline/Timeline.js +90 -0
  55. package/lib/components/timeline/index.d.ts +1 -0
  56. package/lib/components/timeline/index.js +9 -0
  57. package/lib/components/tokens/index.d.ts +1 -1
  58. package/lib/components/tokens/index.js +1 -1
  59. package/lib/components/toolbars/index.d.ts +1 -3
  60. package/lib/components/toolbars/index.js +1 -3
  61. package/lib/hooks/cacheConverters.d.ts +21 -0
  62. package/lib/hooks/cacheConverters.js +110 -0
  63. package/lib/hooks/index.d.ts +0 -2
  64. package/lib/hooks/index.js +0 -2
  65. package/lib/hooks/useCache.d.ts +65 -36
  66. package/lib/hooks/useCache.js +424 -65
  67. package/lib/hooks/useDatalayer.js +3 -1
  68. package/lib/hooks/useIAM.js +1 -3
  69. package/lib/hooks/useLocationHandles.d.ts +3 -1
  70. package/lib/hooks/useLocationHandles.js +2 -1
  71. package/lib/hooks/usePrincipalStore.d.ts +2 -2
  72. package/lib/hooks/usePrincipalStore.js +97 -14
  73. package/lib/hooks/useProjectStore.d.ts +1 -1
  74. package/lib/hooks/useSelectedPrincipal.js +1 -1
  75. package/lib/hooks/useUser.js +19 -2
  76. package/lib/index.d.ts +1 -6
  77. package/lib/index.js +1 -13
  78. package/lib/main.js +3 -3
  79. package/lib/mocks/index.js +1 -1
  80. package/lib/mocks/models/index.d.ts +0 -1
  81. package/lib/mocks/models/index.js +0 -1
  82. package/lib/models/Datasource.d.ts +2 -2
  83. package/lib/models/IAM.d.ts +1 -1
  84. package/lib/models/IAMToken.d.ts +1 -1
  85. package/lib/models/School.d.ts +12 -3
  86. package/lib/models/Secret.d.ts +2 -2
  87. package/lib/models/Student.d.ts +13 -3
  88. package/lib/models/Usage.d.ts +11 -1
  89. package/lib/models/UserDTO.d.ts +2 -2
  90. package/lib/models/index.d.ts +0 -30
  91. package/lib/models/index.js +0 -30
  92. package/lib/routes/index.d.ts +1 -0
  93. package/lib/routes/index.js +1 -0
  94. package/lib/routes/publicPaths.d.ts +23 -0
  95. package/lib/routes/publicPaths.js +74 -0
  96. package/lib/state/State.d.ts +0 -12
  97. package/lib/state/State.js +0 -12
  98. package/lib/state/substates/CoreState.js +1 -1
  99. package/lib/state/substates/LayoutState.d.ts +12 -1
  100. package/lib/state/substates/index.d.ts +0 -7
  101. package/lib/state/substates/index.js +0 -7
  102. package/lib/utils/Date.d.ts +7 -0
  103. package/lib/utils/Date.js +43 -10
  104. package/lib/utils/Handles.js +3 -1
  105. package/lib/utils/index.d.ts +1 -1
  106. package/lib/utils/index.js +1 -1
  107. package/lib/views/api-keys/APIKeyEdit.d.ts +8 -0
  108. package/lib/views/{iam-tokens/IAMTokenEdit.js → api-keys/APIKeyEdit.js} +31 -31
  109. package/lib/views/api-keys/APIKeyNew.d.ts +8 -0
  110. package/lib/views/api-keys/APIKeyNew.js +143 -0
  111. package/lib/views/api-keys/APIKeys.d.ts +12 -0
  112. package/lib/views/api-keys/APIKeys.js +128 -0
  113. package/lib/views/api-keys/APIKeysStandalone.d.ts +2 -0
  114. package/lib/views/api-keys/APIKeysStandalone.js +117 -0
  115. package/lib/views/api-keys/index.d.ts +3 -0
  116. package/lib/{mocks/jupyter → views/api-keys}/index.js +3 -1
  117. package/lib/views/datasources/DatasourceDetail.d.ts +1 -1
  118. package/lib/views/datasources/DatasourceNew.d.ts +1 -1
  119. package/lib/views/datasources/Datasources.d.ts +1 -1
  120. package/lib/views/datasources/Datasources.js +12 -3
  121. package/lib/views/iam/SignInSimple.d.ts +37 -1
  122. package/lib/views/iam/SignInSimple.js +110 -12
  123. package/package.json +5 -3
  124. package/lib/App.css +0 -47
  125. package/lib/App.d.ts +0 -3
  126. package/lib/App.js +0 -21
  127. package/lib/api/runtimes/checkpoints.d.ts +0 -122
  128. package/lib/api/runtimes/checkpoints.js +0 -118
  129. package/lib/api/runtimes/environments.d.ts +0 -9
  130. package/lib/api/runtimes/environments.js +0 -29
  131. package/lib/api/runtimes/healthz.d.ts +0 -15
  132. package/lib/api/runtimes/healthz.js +0 -44
  133. package/lib/api/runtimes/index.d.ts +0 -12
  134. package/lib/api/runtimes/index.js +0 -16
  135. package/lib/api/runtimes/runtimes.d.ts +0 -138
  136. package/lib/api/runtimes/runtimes.js +0 -230
  137. package/lib/api/runtimes/snapshots.d.ts +0 -38
  138. package/lib/api/runtimes/snapshots.js +0 -82
  139. package/lib/api/spacer/documents.d.ts +0 -12
  140. package/lib/api/spacer/documents.js +0 -43
  141. package/lib/api/spacer/healthz.d.ts +0 -15
  142. package/lib/api/spacer/healthz.js +0 -44
  143. package/lib/api/spacer/index.d.ts +0 -15
  144. package/lib/api/spacer/index.js +0 -19
  145. package/lib/api/spacer/items.d.ts +0 -25
  146. package/lib/api/spacer/items.js +0 -55
  147. package/lib/api/spacer/lexicals.d.ts +0 -34
  148. package/lib/api/spacer/lexicals.js +0 -89
  149. package/lib/api/spacer/notebooks.d.ts +0 -34
  150. package/lib/api/spacer/notebooks.js +0 -89
  151. package/lib/api/spacer/spaces.d.ts +0 -84
  152. package/lib/api/spacer/spaces.js +0 -170
  153. package/lib/api/spacer/users.d.ts +0 -9
  154. package/lib/api/spacer/users.js +0 -29
  155. package/lib/client/mixins/RuntimesMixin.d.ts +0 -93
  156. package/lib/client/mixins/RuntimesMixin.js +0 -229
  157. package/lib/client/mixins/SpacerMixin.d.ts +0 -210
  158. package/lib/client/mixins/SpacerMixin.js +0 -615
  159. package/lib/client/utils/spacerUtils.d.ts +0 -18
  160. package/lib/client/utils/spacerUtils.js +0 -32
  161. package/lib/collaboration/DatalayerCollaboration.d.ts +0 -13
  162. package/lib/collaboration/DatalayerCollaboration.js +0 -28
  163. package/lib/collaboration/DatalayerCollaborationProvider.d.ts +0 -60
  164. package/lib/collaboration/DatalayerCollaborationProvider.js +0 -163
  165. package/lib/collaboration/index.d.ts +0 -2
  166. package/lib/collaboration/index.js +0 -6
  167. package/lib/components/context/SpaceSelect.d.ts +0 -2
  168. package/lib/components/context/SpaceSelect.js +0 -42
  169. package/lib/components/flashes/FlashDisclaimer.d.ts +0 -2
  170. package/lib/components/flashes/FlashDisclaimer.js +0 -17
  171. package/lib/components/icons/ArtifactIcon.d.ts +0 -10
  172. package/lib/components/icons/ArtifactIcon.js +0 -58
  173. package/lib/components/icons/index.d.ts +0 -1
  174. package/lib/components/icons/index.js +0 -5
  175. package/lib/components/nbgrader/NbGradesDetails.d.ts +0 -5
  176. package/lib/components/nbgrader/NbGradesDetails.js +0 -14
  177. package/lib/components/nbgrader/index.d.ts +0 -1
  178. package/lib/components/nbgrader/index.js +0 -5
  179. package/lib/components/progress/CreditsIndicator.d.ts +0 -33
  180. package/lib/components/progress/CreditsIndicator.js +0 -23
  181. package/lib/components/runtimes/RuntimeCellVariables.d.ts +0 -39
  182. package/lib/components/runtimes/RuntimeCellVariables.js +0 -172
  183. package/lib/components/runtimes/RuntimeCellVariablesDialog.d.ts +0 -37
  184. package/lib/components/runtimes/RuntimeCellVariablesDialog.js +0 -101
  185. package/lib/components/runtimes/RuntimeLauncherDialog.d.ts +0 -57
  186. package/lib/components/runtimes/RuntimeLauncherDialog.js +0 -275
  187. package/lib/components/runtimes/RuntimePickerBase.d.ts +0 -69
  188. package/lib/components/runtimes/RuntimePickerBase.js +0 -122
  189. package/lib/components/runtimes/RuntimePickerCell.d.ts +0 -34
  190. package/lib/components/runtimes/RuntimePickerCell.js +0 -104
  191. package/lib/components/runtimes/RuntimePickerNotebook.d.ts +0 -42
  192. package/lib/components/runtimes/RuntimePickerNotebook.js +0 -232
  193. package/lib/components/runtimes/RuntimeReservationControl.d.ts +0 -47
  194. package/lib/components/runtimes/RuntimeReservationControl.js +0 -42
  195. package/lib/components/runtimes/RuntimeSimplePicker.d.ts +0 -38
  196. package/lib/components/runtimes/RuntimeSimplePicker.js +0 -155
  197. package/lib/components/runtimes/RuntimeTransfer.d.ts +0 -16
  198. package/lib/components/runtimes/RuntimeTransfer.js +0 -5
  199. package/lib/components/runtimes/RuntimeUtils.d.ts +0 -17
  200. package/lib/components/runtimes/RuntimeUtils.js +0 -178
  201. package/lib/components/runtimes/RuntimeVariables.d.ts +0 -38
  202. package/lib/components/runtimes/RuntimeVariables.js +0 -75
  203. package/lib/components/runtimes/index.d.ts +0 -11
  204. package/lib/components/runtimes/index.js +0 -15
  205. package/lib/components/snapshots/SandboxSnapshotMenu.d.ts +0 -33
  206. package/lib/components/snapshots/SandboxSnapshotMenu.js +0 -169
  207. package/lib/components/snapshots/index.d.ts +0 -1
  208. package/lib/components/snapshots/index.js +0 -5
  209. package/lib/components/snippets/SnippetDialog.d.ts +0 -42
  210. package/lib/components/snippets/SnippetDialog.js +0 -42
  211. package/lib/components/students/StudentItemStatus.d.ts +0 -7
  212. package/lib/components/students/StudentItemStatus.js +0 -66
  213. package/lib/components/tokens/SpaceVariantToken.d.ts +0 -5
  214. package/lib/components/tokens/SpaceVariantToken.js +0 -23
  215. package/lib/components/toolbars/AssignmentEditorToolbar.d.ts +0 -4
  216. package/lib/components/toolbars/AssignmentEditorToolbar.js +0 -18
  217. package/lib/components/toolbars/DocumentEditorToolbar.d.ts +0 -2
  218. package/lib/components/toolbars/DocumentEditorToolbar.js +0 -12
  219. package/lib/components/toolbars/NotebookEditorToolbar.d.ts +0 -29
  220. package/lib/components/toolbars/NotebookEditorToolbar.js +0 -30
  221. package/lib/examples/CellExample.d.ts +0 -6
  222. package/lib/examples/CellExample.js +0 -20
  223. package/lib/examples/NotebookExample.d.ts +0 -6
  224. package/lib/examples/NotebookExample.js +0 -19
  225. package/lib/examples/lexical-theme.css +0 -436
  226. package/lib/examples/notebooks/IPyWidgetsExample.ipynb.json +0 -101
  227. package/lib/examples/notebooks/IPyWidgetsExampleWithState.ipynb.json +0 -112
  228. package/lib/examples/notebooks/Lite.ipynb.json +0 -128
  229. package/lib/examples/notebooks/Matplotlib.ipynb.json +0 -137
  230. package/lib/examples/notebooks/NotebookExample1.ipynb.json +0 -126
  231. package/lib/examples/notebooks/NotebookExample2.ipynb.json +0 -48
  232. package/lib/examples/notebooks/NotebookOutputs.ipynb.json +0 -49
  233. package/lib/examples/notebooks/NotebookToCExample.ipynb.json +0 -102
  234. package/lib/examples/notebooks/PyGWalker.ipynb.json +0 -55
  235. package/lib/hooks/useCellOutputshot.d.ts +0 -4
  236. package/lib/hooks/useCellOutputshot.js +0 -25
  237. package/lib/hooks/useProjects.d.ts +0 -628
  238. package/lib/hooks/useProjects.js +0 -190
  239. package/lib/hooks/useRuntimes.d.ts +0 -5
  240. package/lib/hooks/useRuntimes.js +0 -34
  241. package/lib/mocks/models/CourseMock.d.ts +0 -6
  242. package/lib/mocks/models/CourseMock.js +0 -29
  243. package/lib/mocks/models/SpaceMock.d.ts +0 -6
  244. package/lib/mocks/models/SpaceMock.js +0 -25
  245. package/lib/models/Assignment.d.ts +0 -7
  246. package/lib/models/Assignment.js +0 -5
  247. package/lib/models/Cell.d.ts +0 -8
  248. package/lib/models/Cell.js +0 -5
  249. package/lib/models/CodeBlock.d.ts +0 -10
  250. package/lib/models/CodeBlock.js +0 -5
  251. package/lib/models/CodeSandboxSnapshot.d.ts +0 -92
  252. package/lib/models/CodeSandboxSnapshot.js +0 -13
  253. package/lib/models/CodeSandboxSnapshotDTO.d.ts +0 -173
  254. package/lib/models/CodeSandboxSnapshotDTO.js +0 -139
  255. package/lib/models/CodefeedBlocks.d.ts +0 -7
  256. package/lib/models/CodefeedBlocks.js +0 -5
  257. package/lib/models/Content.d.ts +0 -5
  258. package/lib/models/Content.js +0 -5
  259. package/lib/models/Course.d.ts +0 -17
  260. package/lib/models/Course.js +0 -5
  261. package/lib/models/Dataset.d.ts +0 -16
  262. package/lib/models/Dataset.js +0 -5
  263. package/lib/models/Document.d.ts +0 -8
  264. package/lib/models/Document.js +0 -5
  265. package/lib/models/Environment.d.ts +0 -86
  266. package/lib/models/Environment.js +0 -5
  267. package/lib/models/EnvironmentDTO.d.ts +0 -125
  268. package/lib/models/EnvironmentDTO.js +0 -88
  269. package/lib/models/Exercise.d.ts +0 -16
  270. package/lib/models/Exercise.js +0 -5
  271. package/lib/models/Item.d.ts +0 -20
  272. package/lib/models/Item.js +0 -5
  273. package/lib/models/ItemDTO.d.ts +0 -74
  274. package/lib/models/ItemDTO.js +0 -186
  275. package/lib/models/ItemType.d.ts +0 -2
  276. package/lib/models/ItemType.js +0 -5
  277. package/lib/models/Lesson.d.ts +0 -5
  278. package/lib/models/Lesson.js +0 -5
  279. package/lib/models/LexicalDTO.d.ts +0 -155
  280. package/lib/models/LexicalDTO.js +0 -157
  281. package/lib/models/Library.d.ts +0 -10
  282. package/lib/models/Library.js +0 -5
  283. package/lib/models/Notebook.d.ts +0 -11
  284. package/lib/models/Notebook.js +0 -5
  285. package/lib/models/NotebookDTO.d.ts +0 -96
  286. package/lib/models/NotebookDTO.js +0 -153
  287. package/lib/models/Page.d.ts +0 -41
  288. package/lib/models/Page.js +0 -25
  289. package/lib/models/PageTag.d.ts +0 -19
  290. package/lib/models/PageTag.js +0 -94
  291. package/lib/models/ProjectDTO.d.ts +0 -89
  292. package/lib/models/ProjectDTO.js +0 -131
  293. package/lib/models/Runtime.d.ts +0 -123
  294. package/lib/models/Runtime.js +0 -18
  295. package/lib/models/RuntimeDTO.d.ts +0 -191
  296. package/lib/models/RuntimeDTO.js +0 -204
  297. package/lib/models/Space.d.ts +0 -35
  298. package/lib/models/Space.js +0 -66
  299. package/lib/models/SpaceDTO.d.ts +0 -334
  300. package/lib/models/SpaceDTO.js +0 -244
  301. package/lib/models/SpaceItem.d.ts +0 -10
  302. package/lib/models/SpaceItem.js +0 -5
  303. package/lib/models/SpaceMember.d.ts +0 -6
  304. package/lib/models/SpaceMember.js +0 -5
  305. package/lib/models/StudentItem.d.ts +0 -21
  306. package/lib/models/StudentItem.js +0 -5
  307. package/lib/services/DatalayerServiceManager.d.ts +0 -22
  308. package/lib/services/DatalayerServiceManager.js +0 -69
  309. package/lib/services/index.d.ts +0 -4
  310. package/lib/services/index.js +0 -7
  311. package/lib/services/reconnectToRuntime.d.ts +0 -32
  312. package/lib/services/reconnectToRuntime.js +0 -59
  313. package/lib/state/substates/CellState.d.ts +0 -12
  314. package/lib/state/substates/CellState.js +0 -22
  315. package/lib/state/substates/DocumentState.d.ts +0 -10
  316. package/lib/state/substates/DocumentState.js +0 -14
  317. package/lib/state/substates/GradeState.d.ts +0 -10
  318. package/lib/state/substates/GradeState.js +0 -14
  319. package/lib/state/substates/JupyterLabState.d.ts +0 -16
  320. package/lib/state/substates/JupyterLabState.js +0 -17
  321. package/lib/state/substates/NbformatState.d.ts +0 -13
  322. package/lib/state/substates/NbformatState.js +0 -16
  323. package/lib/state/substates/RuntimesState.d.ts +0 -79
  324. package/lib/state/substates/RuntimesState.js +0 -180
  325. package/lib/state/substates/SpaceState.d.ts +0 -11
  326. package/lib/state/substates/SpaceState.js +0 -16
  327. package/lib/stateful/index.d.ts +0 -2
  328. package/lib/stateful/index.js +0 -6
  329. package/lib/stateful/jupyter/exec/Python.d.ts +0 -5
  330. package/lib/stateful/jupyter/exec/Python.js +0 -100
  331. package/lib/stateful/jupyter/exec/Snippets.d.ts +0 -105
  332. package/lib/stateful/jupyter/exec/Snippets.js +0 -101
  333. package/lib/stateful/jupyter/exec/index.d.ts +0 -2
  334. package/lib/stateful/jupyter/exec/index.js +0 -6
  335. package/lib/stateful/jupyter/index.d.ts +0 -2
  336. package/lib/stateful/jupyter/index.js +0 -6
  337. package/lib/stateful/jupyter/kernelsHandler.d.ts +0 -8
  338. package/lib/stateful/jupyter/kernelsHandler.js +0 -39
  339. package/lib/stateful/runtimes/actions.d.ts +0 -102
  340. package/lib/stateful/runtimes/actions.js +0 -249
  341. package/lib/stateful/runtimes/apis.d.ts +0 -273
  342. package/lib/stateful/runtimes/apis.js +0 -5
  343. package/lib/stateful/runtimes/index.d.ts +0 -5
  344. package/lib/stateful/runtimes/index.js +0 -9
  345. package/lib/stateful/runtimes/settings.d.ts +0 -15
  346. package/lib/stateful/runtimes/settings.js +0 -31
  347. package/lib/stateful/runtimes/snapshots.d.ts +0 -25
  348. package/lib/stateful/runtimes/snapshots.js +0 -150
  349. package/lib/stateful/runtimes/utils.d.ts +0 -7
  350. package/lib/stateful/runtimes/utils.js +0 -14
  351. package/lib/utils/Cells.d.ts +0 -2
  352. package/lib/utils/Cells.js +0 -28
  353. package/lib/views/iam-tokens/IAMTokenEdit.d.ts +0 -6
  354. package/lib/views/iam-tokens/IAMTokenNew.d.ts +0 -8
  355. package/lib/views/iam-tokens/IAMTokenNew.js +0 -118
  356. package/lib/views/iam-tokens/IAMTokens.d.ts +0 -12
  357. package/lib/views/iam-tokens/IAMTokens.js +0 -87
  358. package/lib/views/iam-tokens/Tokens.d.ts +0 -2
  359. package/lib/views/iam-tokens/Tokens.js +0 -85
  360. package/lib/views/iam-tokens/index.d.ts +0 -3
  361. package/lib/views/iam-tokens/index.js +0 -7
  362. /package/lib/{mocks/jupyter/index.d.ts → cli-login.d.ts} +0 -0
  363. /package/lib/utils/{logger.d.ts → Logger.d.ts} +0 -0
  364. /package/lib/utils/{logger.js → Logger.js} +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';
@@ -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) {
@@ -1550,7 +1698,12 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
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(),
@@ -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);
@@ -2166,11 +2321,12 @@ 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/tokens`,
2324
+ url: `${configuration.iamRunUrl}/api/iam/v1/api-keys`,
2170
2325
  method: 'GET',
2171
2326
  });
2172
- if (resp.success && resp.tokens) {
2173
- const tokens = resp.tokens
2327
+ const tokenItems = asArray(resp?.apiKeys ?? resp?.api_keys ?? resp?.tokens);
2328
+ if (resp.success && tokenItems.length > 0) {
2329
+ const tokens = tokenItems
2174
2330
  .map((t) => {
2175
2331
  const token = toToken(t);
2176
2332
  if (token) {
@@ -2194,7 +2350,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2194
2350
  return useMutation({
2195
2351
  mutationFn: async (token) => {
2196
2352
  const resp = await requestDatalayer({
2197
- url: `${configuration.iamRunUrl}/api/iam/v1/tokens`,
2353
+ url: `${configuration.iamRunUrl}/api/iam/v1/api-keys`,
2198
2354
  method: 'POST',
2199
2355
  body: {
2200
2356
  ...token,
@@ -2202,8 +2358,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2202
2358
  },
2203
2359
  });
2204
2360
  // Transform the token in the response
2205
- if (resp.success && resp.token) {
2206
- resp.token = toToken(resp.token);
2361
+ const tokenPayload = resp?.apiKey ?? resp?.api_key ?? resp?.token;
2362
+ if (resp.success && tokenPayload) {
2363
+ resp.token = toToken(tokenPayload);
2207
2364
  }
2208
2365
  return resp;
2209
2366
  },
@@ -2515,11 +2672,12 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2515
2672
  queryKey: queryKeys.tokens.detail(tokenId),
2516
2673
  queryFn: async () => {
2517
2674
  const resp = await requestDatalayer({
2518
- url: `${configuration.iamRunUrl}/api/iam/v1/tokens/${tokenId}`,
2675
+ url: `${configuration.iamRunUrl}/api/iam/v1/api-keys/${tokenId}`,
2519
2676
  method: 'GET',
2520
2677
  });
2521
- if (resp.success && resp.token) {
2522
- return toToken(resp.token);
2678
+ const tokenPayload = resp?.apiKey ?? resp?.api_key ?? resp?.token;
2679
+ if (resp.success && tokenPayload) {
2680
+ return toToken(tokenPayload);
2523
2681
  }
2524
2682
  return null;
2525
2683
  },
@@ -2534,14 +2692,15 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2534
2692
  return useMutation({
2535
2693
  mutationFn: async (token) => {
2536
2694
  return requestDatalayer({
2537
- url: `${configuration.iamRunUrl}/api/iam/v1/tokens/${token.id}`,
2695
+ url: `${configuration.iamRunUrl}/api/iam/v1/api-keys/${token.id}`,
2538
2696
  method: 'PUT',
2539
2697
  body: { ...token },
2540
2698
  });
2541
2699
  },
2542
2700
  onSuccess: resp => {
2543
- if (resp.success && resp.token) {
2544
- const tok = toToken(resp.token);
2701
+ const tokenPayload = resp?.apiKey ?? resp?.api_key ?? resp?.token;
2702
+ if (resp.success && tokenPayload) {
2703
+ const tok = toToken(tokenPayload);
2545
2704
  if (tok) {
2546
2705
  queryClient.setQueryData(queryKeys.tokens.detail(tok.id), tok);
2547
2706
  }
@@ -2557,7 +2716,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2557
2716
  return useMutation({
2558
2717
  mutationFn: async (tokenId) => {
2559
2718
  return requestDatalayer({
2560
- url: `${configuration.iamRunUrl}/api/iam/v1/tokens/${tokenId}`,
2719
+ url: `${configuration.iamRunUrl}/api/iam/v1/api-keys/${tokenId}`,
2561
2720
  method: 'DELETE',
2562
2721
  });
2563
2722
  },
@@ -3453,9 +3612,29 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3453
3612
  method: 'POST',
3454
3613
  });
3455
3614
  },
3456
- 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
+ }
3457
3635
  queryClient.invalidateQueries({
3458
- queryKey: ['courses', 'detail', courseId],
3636
+ queryKey: detailKey,
3637
+ refetchType: 'none',
3459
3638
  });
3460
3639
  queryClient.invalidateQueries({
3461
3640
  queryKey: ['courses', 'enrollments'],
@@ -3474,9 +3653,25 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3474
3653
  method: 'DELETE',
3475
3654
  });
3476
3655
  },
3477
- 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
+ }
3478
3672
  queryClient.invalidateQueries({
3479
- queryKey: ['courses', 'detail', courseId],
3673
+ queryKey: detailKey,
3674
+ refetchType: 'none',
3480
3675
  });
3481
3676
  queryClient.invalidateQueries({
3482
3677
  queryKey: ['courses', 'enrollments'],
@@ -3537,7 +3732,8 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3537
3732
  mutationFn: async (itemId) => {
3538
3733
  return requestDatalayer({
3539
3734
  url: `${configuration.libraryRunUrl}/api/library/v1/items/${itemId}/public`,
3540
- method: 'PUT',
3735
+ method: 'PATCH',
3736
+ body: { is_public: true },
3541
3737
  });
3542
3738
  },
3543
3739
  onSuccess: () => {
@@ -3552,8 +3748,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3552
3748
  return useMutation({
3553
3749
  mutationFn: async (itemId) => {
3554
3750
  return requestDatalayer({
3555
- url: `${configuration.libraryRunUrl}/api/library/v1/items/${itemId}/private`,
3556
- method: 'PUT',
3751
+ url: `${configuration.libraryRunUrl}/api/library/v1/items/${itemId}/public`,
3752
+ method: 'PATCH',
3753
+ body: { is_public: false },
3557
3754
  });
3558
3755
  },
3559
3756
  onSuccess: () => {
@@ -3573,9 +3770,16 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3573
3770
  */
3574
3771
  const useRefreshLayout = () => {
3575
3772
  return useMutation({
3576
- 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
+ }
3577
3781
  return requestDatalayer({
3578
- url: `${configuration.spacerRunUrl}/api/spacer/v1/layouts/accounts/${accountHandle}${spaceHandle !== undefined ? '/spaces/' + spaceHandle : ''}`,
3782
+ url: `${configuration.spacerRunUrl}${path}`,
3579
3783
  method: 'GET',
3580
3784
  });
3581
3785
  },
@@ -3586,6 +3790,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3586
3790
  const transformedOrganization = resp.organization
3587
3791
  ? toOrganization(resp.organization)
3588
3792
  : undefined;
3793
+ const transformedTeam = resp.team && transformedOrganization
3794
+ ? toTeam(resp.team, transformedOrganization.id)
3795
+ : undefined;
3589
3796
  const transformedSpace = resp.space ? toSpace(resp.space) : undefined;
3590
3797
  // Set data directly into cache instead of just invalidating
3591
3798
  if (transformedUser) {
@@ -3598,6 +3805,15 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3598
3805
  queryKey: queryKeys.organizations.all(),
3599
3806
  });
3600
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
+ }
3601
3817
  if (transformedSpace) {
3602
3818
  // Set both user and org space queries based on which type it is
3603
3819
  if (transformedUser && variables.spaceHandle) {
@@ -3725,12 +3941,24 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3725
3941
  /**
3726
3942
  * Get dataset by ID
3727
3943
  */
3728
- const useDataset = (datasetId) => {
3944
+ const useDataset = (datasetId, scope) => {
3729
3945
  return useQuery({
3730
- queryKey: queryKeys.datasets.detail(datasetId),
3946
+ queryKey: [
3947
+ ...queryKeys.datasets.detail(datasetId),
3948
+ scope?.selectedPrincipalUid || '',
3949
+ scope?.selectedPrincipalKind || '',
3950
+ ],
3731
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();
3732
3960
  const resp = await requestDatalayer({
3733
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/items/${datasetId}`,
3961
+ url: `${configuration.runtimesRunUrl}/api/runtimes/v1/spaces/items/${datasetId}${query ? `?${query}` : ''}`,
3734
3962
  method: 'GET',
3735
3963
  });
3736
3964
  if (resp.success && resp.item) {
@@ -3745,12 +3973,24 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3745
3973
  /**
3746
3974
  * Get datasets by space
3747
3975
  */
3748
- const useDatasetsBySpace = (spaceId) => {
3976
+ const useDatasetsBySpace = (spaceId, scope) => {
3749
3977
  return useQuery({
3750
- queryKey: queryKeys.datasets.bySpace(spaceId),
3978
+ queryKey: [
3979
+ ...queryKeys.datasets.bySpace(spaceId),
3980
+ scope?.selectedPrincipalUid || '',
3981
+ scope?.selectedPrincipalKind || '',
3982
+ ],
3751
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();
3752
3992
  const resp = await requestDatalayer({
3753
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/dataset`,
3993
+ url: `${configuration.runtimesRunUrl}/api/runtimes/v1/spaces/${spaceId}/items/types/dataset${query ? `?${query}` : ''}`,
3754
3994
  method: 'GET',
3755
3995
  });
3756
3996
  if (resp.success && resp.items) {
@@ -3767,9 +4007,17 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3767
4007
  */
3768
4008
  const useUpdateDataset = () => {
3769
4009
  return useMutation({
3770
- 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();
3771
4019
  return requestDatalayer({
3772
- url: `${configuration.spacerRunUrl}/api/spacer/v1/datasets/${id}`,
4020
+ url: `${configuration.runtimesRunUrl}/api/runtimes/v1/datasets/${id}${query ? `?${query}` : ''}`,
3773
4021
  method: 'PUT',
3774
4022
  body: { name, description },
3775
4023
  });
@@ -4158,6 +4406,12 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4158
4406
  queryClient.invalidateQueries({
4159
4407
  queryKey: ['assignments', assignmentId],
4160
4408
  });
4409
+ queryClient.invalidateQueries({
4410
+ queryKey: ['courses', 'detail', courseId],
4411
+ });
4412
+ queryClient.invalidateQueries({
4413
+ queryKey: ['courses', courseId, 'students'],
4414
+ });
4161
4415
  },
4162
4416
  });
4163
4417
  };
@@ -4181,6 +4435,12 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4181
4435
  queryClient.invalidateQueries({
4182
4436
  queryKey: ['assignments', assignmentId],
4183
4437
  });
4438
+ queryClient.invalidateQueries({
4439
+ queryKey: ['courses', 'detail', courseId],
4440
+ });
4441
+ queryClient.invalidateQueries({
4442
+ queryKey: ['courses', courseId, 'students'],
4443
+ });
4184
4444
  },
4185
4445
  });
4186
4446
  };
@@ -4204,16 +4464,16 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4204
4464
  // Exercise Grading
4205
4465
  // ============================================================================
4206
4466
  /**
4207
- * Grade an exercise by assigning points to student code
4467
+ * Grade an exercise by assigning a score to student code
4208
4468
  */
4209
- const useUpdateExercisePoints = () => {
4469
+ const useUpdateExerciseScore = () => {
4210
4470
  const queryClient = useQueryClient();
4211
4471
  return useMutation({
4212
- mutationFn: async ({ exerciseId, codeStudent, points, }) => {
4472
+ mutationFn: async ({ exerciseId, codeStudent, score, courseId, }) => {
4213
4473
  return requestDatalayer({
4214
- url: `${configuration.spacerRunUrl}/api/spacer/v1/exercises/${exerciseId}/points`,
4474
+ url: `${configuration.spacerRunUrl}/api/spacer/v1/exercises/${exerciseId}/score`,
4215
4475
  method: 'PUT',
4216
- body: { codeStudent, points },
4476
+ body: { codeStudent, score, courseId },
4217
4477
  });
4218
4478
  },
4219
4479
  onSuccess: (_, { exerciseId }) => {
@@ -4243,12 +4503,40 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4243
4503
  if (!resp.success) {
4244
4504
  throw new Error(resp.message || 'Failed to fetch student');
4245
4505
  }
4246
- return resp.student;
4506
+ return toStudent(resp.student);
4247
4507
  },
4248
4508
  enabled: !!courseId && !!studentId,
4249
4509
  ...options,
4250
4510
  });
4251
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.spacerRunUrl}/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
+ };
4252
4540
  /**
4253
4541
  * Mark a course item as completed
4254
4542
  */
@@ -4269,6 +4557,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4269
4557
  queryClient.invalidateQueries({
4270
4558
  queryKey: ['courses', courseId, 'items'],
4271
4559
  });
4560
+ queryClient.invalidateQueries({
4561
+ queryKey: ['courses', courseId, 'students'],
4562
+ });
4272
4563
  },
4273
4564
  });
4274
4565
  };
@@ -5627,12 +5918,19 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5627
5918
  */
5628
5919
  const useSearchPublicItems = () => {
5629
5920
  return useMutation({
5630
- 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))));
5631
5928
  const queryString = Object.entries({
5632
5929
  q: q || '*',
5633
- types: types.join(' '),
5930
+ types: (normalizedTypes.length > 0
5931
+ ? normalizedTypes
5932
+ : ['notebook', 'document', 'cell', 'lesson', 'evalset', 'course']).join(' '),
5634
5933
  max: max.toString(),
5635
- public: 'true',
5636
5934
  })
5637
5935
  .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
5638
5936
  .join('&');
@@ -6240,14 +6538,26 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6240
6538
  const useRefreshDataset = (options) => {
6241
6539
  const queryClient = useQueryClient();
6242
6540
  return useMutation({
6243
- 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();
6244
6553
  const resp = await requestDatalayer({
6245
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/items/${datasetId}`,
6554
+ url: `${configuration.runtimesRunUrl}/api/runtimes/v1/spaces/items/${datasetId}${query ? `?${query}` : ''}`,
6246
6555
  method: 'GET',
6247
6556
  });
6248
6557
  return resp;
6249
6558
  },
6250
- onSuccess: (data, datasetId) => {
6559
+ onSuccess: (data, variables) => {
6560
+ const datasetId = typeof variables === 'string' ? variables : variables.datasetId;
6251
6561
  queryClient.invalidateQueries({
6252
6562
  queryKey: queryKeys.datasets.detail(datasetId),
6253
6563
  });
@@ -6262,14 +6572,26 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6262
6572
  const useRefreshSpaceDatasets = (options) => {
6263
6573
  const queryClient = useQueryClient();
6264
6574
  return useMutation({
6265
- 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();
6266
6587
  const resp = await requestDatalayer({
6267
- url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${spaceId}/items/types/dataset`,
6588
+ url: `${configuration.runtimesRunUrl}/api/runtimes/v1/spaces/${spaceId}/items/types/dataset${query ? `?${query}` : ''}`,
6268
6589
  method: 'GET',
6269
6590
  });
6270
6591
  return resp;
6271
6592
  },
6272
- onSuccess: (data, spaceId) => {
6593
+ onSuccess: (data, variables) => {
6594
+ const spaceId = typeof variables === 'string' ? variables : variables.spaceId;
6273
6595
  queryClient.invalidateQueries({
6274
6596
  queryKey: queryKeys.datasets.bySpace(spaceId),
6275
6597
  });
@@ -6306,10 +6628,37 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6306
6628
  queryKey: queryKeys.items.public(),
6307
6629
  queryFn: async () => {
6308
6630
  const resp = await requestDatalayer({
6309
- url: `${configuration.libraryRunUrl}/api/library/v1/items/public`,
6631
+ url: `${configuration.libraryRunUrl}/api/library/v1/search?q=*&max=-1`,
6310
6632
  method: 'GET',
6311
6633
  });
6312
- 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.libraryRunUrl}/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
+ };
6313
6662
  },
6314
6663
  ...options,
6315
6664
  });
@@ -6323,10 +6672,15 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6323
6672
  return useMutation({
6324
6673
  mutationFn: async () => {
6325
6674
  const resp = await requestDatalayer({
6326
- url: `${configuration.libraryRunUrl}/api/library/v1/items/public`,
6675
+ url: `${configuration.libraryRunUrl}/api/library/v1/search?q=*&max=-1`,
6327
6676
  method: 'GET',
6328
6677
  });
6329
- return resp;
6678
+ return {
6679
+ ...resp,
6680
+ items: (resp.items || [])
6681
+ .map((item) => toItem(item))
6682
+ .filter(Boolean),
6683
+ };
6330
6684
  },
6331
6685
  onSuccess: () => {
6332
6686
  queryClient.invalidateQueries({ queryKey: queryKeys.items.public() });
@@ -6621,6 +6975,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6621
6975
  },
6622
6976
  onSuccess: () => {
6623
6977
  queryClient.invalidateQueries({ queryKey: queryKeys.items.public() });
6978
+ queryClient.invalidateQueries({
6979
+ queryKey: [...queryKeys.items.all(), 'publications'],
6980
+ });
6624
6981
  },
6625
6982
  ...options,
6626
6983
  });
@@ -7114,6 +7471,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
7114
7471
  useEnrollStudentToCourse,
7115
7472
  useRemoveStudentFromCourse,
7116
7473
  useStudent,
7474
+ useStudents,
7117
7475
  useConfirmCourseItemCompletion,
7118
7476
  useSetCourseItems,
7119
7477
  useRefreshCourse,
@@ -7168,7 +7526,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
7168
7526
  useExercisesBySpace,
7169
7527
  useUpdateExercise,
7170
7528
  useCloneExercise,
7171
- useUpdateExercisePoints,
7529
+ useUpdateExerciseScore,
7172
7530
  useRefreshExercise,
7173
7531
  useRefreshSpaceExercises,
7174
7532
  // Assignments
@@ -7190,6 +7548,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
7190
7548
  useMakeItemPrivate,
7191
7549
  useSearchPublicItems,
7192
7550
  usePublicItems,
7551
+ usePublications,
7193
7552
  useRefreshPublicItems,
7194
7553
  useRefreshSpaceItems,
7195
7554
  useClearCachedPublicItems,