@datalayer/core 0.0.3 → 0.0.4

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 (330) hide show
  1. package/README.md +114 -3
  2. package/lib/App.css +2 -2
  3. package/lib/App.d.ts +1 -1
  4. package/lib/App.js +9 -9
  5. package/lib/__tests__/index.test.js +5 -5
  6. package/lib/api/DatalayerApi.d.ts +1 -1
  7. package/lib/api/DatalayerApi.js +3 -3
  8. package/lib/api/index.d.ts +3 -3
  9. package/lib/api/index.js +3 -3
  10. package/lib/api/runtimes/actions.js +22 -23
  11. package/lib/api/runtimes/settings.js +3 -3
  12. package/lib/api/runtimes/snapshots.d.ts +1 -1
  13. package/lib/api/runtimes/snapshots.js +8 -8
  14. package/lib/api/runtimes/utils.js +1 -4
  15. package/lib/collaboration/DatalayerCollaboration.d.ts +9 -0
  16. package/lib/collaboration/DatalayerCollaboration.js +28 -0
  17. package/lib/collaboration/DatalayerCollaborationProvider.d.ts +54 -0
  18. package/lib/collaboration/DatalayerCollaborationProvider.js +162 -0
  19. package/lib/collaboration/index.d.ts +2 -0
  20. package/lib/collaboration/index.js +6 -0
  21. package/lib/components/avatars/BoringAvatar.d.ts +1 -1
  22. package/lib/components/avatars/BoringAvatar.js +2 -2
  23. package/lib/components/avatars/UserProfileAvatar.js +2 -9
  24. package/lib/components/banners/NoAutomationBanner.js +4 -4
  25. package/lib/components/buttons/DownloadCSVButton.js +1 -1
  26. package/lib/components/buttons/UploadButton.js +1 -1
  27. package/lib/components/checkout/StripeCheckout.d.ts +1 -1
  28. package/lib/components/checkout/StripeCheckout.js +6 -6
  29. package/lib/components/confetti/ConfettiSuccess.js +1 -1
  30. package/lib/components/context/OrganizationSelect.js +5 -5
  31. package/lib/components/context/SpaceSelect.js +7 -7
  32. package/lib/components/display/AvatarSkeleton.js +1 -1
  33. package/lib/components/display/CenteredSpinner.js +4 -4
  34. package/lib/components/display/CodePreview.js +4 -4
  35. package/lib/components/display/DatalayerBox.js +13 -14
  36. package/lib/components/display/HorizontalCenter.d.ts +1 -1
  37. package/lib/components/display/HorizontalCenter.js +1 -1
  38. package/lib/components/display/JupyterDialog.js +17 -15
  39. package/lib/components/display/NavLink.d.ts +4 -2
  40. package/lib/components/display/NavLink.js +6 -4
  41. package/lib/components/display/NotebookSkeleton.js +2 -2
  42. package/lib/components/display/Placeholder.js +1 -1
  43. package/lib/components/display/ToTopBranded.js +1 -1
  44. package/lib/components/echarts/EChartsReact.d.ts +1 -1
  45. package/lib/components/echarts/EChartsReact.js +1 -1
  46. package/lib/components/flashes/FlashClosable.js +11 -11
  47. package/lib/components/flashes/FlashDisclaimer.js +2 -3
  48. package/lib/components/flashes/FlashGuest.js +3 -4
  49. package/lib/components/flashes/FlashSurveys.js +3 -4
  50. package/lib/components/flashes/FlashUnauthorized.js +2 -2
  51. package/lib/components/flashes/surveys/Survey2025_1.d.ts +1 -1
  52. package/lib/components/flashes/surveys/Survey2025_1.js +62 -85
  53. package/lib/components/iam/ExternalTokenSilentLogin.js +6 -4
  54. package/lib/components/icons/ArtifactIcon.d.ts +2 -2
  55. package/lib/components/icons/ArtifactIcon.js +39 -39
  56. package/lib/components/labels/VisibilityLabel.js +2 -5
  57. package/lib/components/landings/StepBlock.d.ts +1 -1
  58. package/lib/components/landings/StepBlock.js +1 -1
  59. package/lib/components/navbar/NavigationVisbilityObserver.js +2 -2
  60. package/lib/components/navbar/SubdomainNavBar.js +45 -23
  61. package/lib/components/navbar/SubdomainNavBar.module.css +33 -14
  62. package/lib/components/nbgrader/NbGradesDetails.d.ts +1 -1
  63. package/lib/components/nbgrader/NbGradesDetails.js +5 -8
  64. package/lib/components/notebooks/JupyterNotebook.js +5 -5
  65. package/lib/components/notebooks/JupyterNotebookToolbar.js +3 -3
  66. package/lib/components/primer/Helper.d.ts +1 -1
  67. package/lib/components/primer/Helper.js +5 -3
  68. package/lib/components/primer/Portals.d.ts +1 -1
  69. package/lib/components/primer/Portals.js +2 -2
  70. package/lib/components/primer/Styles.js +1 -1
  71. package/lib/components/progress/ConsumptionBar.js +2 -2
  72. package/lib/components/progress/CreditsIndicator.d.ts +1 -1
  73. package/lib/components/progress/CreditsIndicator.js +4 -7
  74. package/lib/components/progress/ProgressRing.js +2 -2
  75. package/lib/components/runtimes/RuntimeCellVariables.js +9 -9
  76. package/lib/components/runtimes/RuntimeCellVariablesDialog.js +3 -3
  77. package/lib/components/runtimes/RuntimeLauncherDialog.js +30 -34
  78. package/lib/components/runtimes/RuntimePickerBase.js +42 -31
  79. package/lib/components/runtimes/RuntimePickerCell.js +9 -12
  80. package/lib/components/runtimes/RuntimePickerNotebook.js +44 -44
  81. package/lib/components/runtimes/RuntimeReservationControl.js +10 -15
  82. package/lib/components/runtimes/RuntimeSimplePicker.js +9 -12
  83. package/lib/components/runtimes/RuntimeUtils.js +22 -12
  84. package/lib/components/runtimes/RuntimeVariables.js +7 -7
  85. package/lib/components/screenshot/ScreenCapture.js +9 -13
  86. package/lib/components/screenshot/ScreenCaptureButton.d.ts +1 -1
  87. package/lib/components/screenshot/ScreenCaptureButton.js +14 -8
  88. package/lib/components/snapshots/RuntimeSnapshotMenu.js +19 -17
  89. package/lib/components/snippets/SnippetDialog.js +5 -5
  90. package/lib/components/storage/ContentsBrowser.js +63 -56
  91. package/lib/components/storage/ContentsItems.js +10 -8
  92. package/lib/components/students/StudentItemStatus.d.ts +1 -1
  93. package/lib/components/students/StudentItemStatus.js +35 -16
  94. package/lib/components/subnav/SubNav.d.ts +1 -1
  95. package/lib/components/subnav/SubNav.js +30 -15
  96. package/lib/components/subnav/SubNav.module.css +55 -21
  97. package/lib/components/tables/DataTable.js +1 -4
  98. package/lib/components/text-reveal/TextRevealAnimation.js +7 -2
  99. package/lib/components/text-reveal/TextRevealAnimation.module.css +4 -2
  100. package/lib/components/tokens/SpaceVariantToken.d.ts +1 -1
  101. package/lib/components/tokens/SpaceVariantToken.js +5 -5
  102. package/lib/components/toolbars/AssignmentEditorToolbar.js +1 -3
  103. package/lib/components/users/PeerIndicator.d.ts +1 -1
  104. package/lib/components/users/PeerIndicator.js +5 -5
  105. package/lib/config/Configuration.d.ts +48 -0
  106. package/lib/config/Configuration.js +42 -0
  107. package/lib/config/integrations/Loom.js +3 -3
  108. package/lib/examples/CellExample.d.ts +2 -2
  109. package/lib/examples/CellExample.js +34 -3
  110. package/lib/examples/DatalayerNotebookExample.d.ts +16 -0
  111. package/lib/examples/DatalayerNotebookExample.js +75 -0
  112. package/lib/examples/NativeNavigationExample.d.ts +8 -0
  113. package/lib/examples/NativeNavigationExample.js +97 -0
  114. package/lib/examples/NotebookExample.d.ts +1 -3
  115. package/lib/examples/NotebookExample.js +9 -7
  116. package/lib/examples/NotebookMutationsKernel.d.ts +2 -0
  117. package/lib/examples/NotebookMutationsKernel.js +115 -0
  118. package/lib/examples/NotebookMutationsServiceManager.d.ts +2 -0
  119. package/lib/examples/NotebookMutationsServiceManager.js +107 -0
  120. package/lib/examples/ReactRouterExample.d.ts +6 -0
  121. package/lib/examples/ReactRouterExample.js +175 -0
  122. package/lib/examples/example-selector.d.ts +22 -0
  123. package/lib/examples/example-selector.js +45 -0
  124. package/lib/examples/index.d.ts +2 -0
  125. package/lib/examples/index.js +6 -0
  126. package/lib/examples/main.js +153 -0
  127. package/lib/examples/notebooks/IPyWidgetsExample.ipynb.json +101 -0
  128. package/lib/examples/notebooks/IPyWidgetsExampleWithState.ipynb.json +112 -0
  129. package/lib/examples/{NotebookExample1.ipynb.json → notebooks/Lite.ipynb.json} +45 -53
  130. package/lib/examples/notebooks/Matplotlib.ipynb.json +137 -0
  131. package/lib/examples/notebooks/NotebookExample1.ipynb.json +126 -0
  132. package/lib/examples/notebooks/NotebookExample2.ipynb.json +48 -0
  133. package/lib/examples/notebooks/NotebookOutputs.ipynb.json +49 -0
  134. package/lib/examples/notebooks/NotebookToCExample.ipynb.json +102 -0
  135. package/lib/examples/notebooks/OutputIPyWidgetsExample.d.ts +145 -0
  136. package/lib/examples/notebooks/OutputIPyWidgetsExample.js +153 -0
  137. package/lib/examples/notebooks/PyGWalker.ipynb.json +55 -0
  138. package/lib/hooks/assets/OutputshotPlaceholders.d.ts +10 -10
  139. package/lib/hooks/assets/OutputshotPlaceholders.js +10 -10
  140. package/lib/hooks/index.d.ts +29 -28
  141. package/lib/hooks/index.js +29 -28
  142. package/lib/hooks/layouts/LayoutBackdrop.js +3 -6
  143. package/lib/hooks/layouts/LayoutScreenshot.css +1 -1
  144. package/lib/hooks/layouts/LayoutScreenshot.js +6 -6
  145. package/lib/hooks/useAIAgents.d.ts +1 -1
  146. package/lib/hooks/useAIAgents.js +6 -6
  147. package/lib/hooks/useAuthorization.js +4 -4
  148. package/lib/hooks/useBackdrop.js +7 -7
  149. package/lib/hooks/useBackdropJupyterLab.d.ts +1 -1
  150. package/lib/hooks/useBackdropJupyterLab.js +4 -4
  151. package/lib/hooks/useCache.d.ts +6 -2
  152. package/lib/hooks/useCache.js +233 -179
  153. package/lib/hooks/useCellOutputshot.js +3 -6
  154. package/lib/hooks/useContainsFocus.js +2 -1
  155. package/lib/hooks/useDatalayer.js +5 -3
  156. package/lib/hooks/useError.d.ts +1 -1
  157. package/lib/hooks/useError.js +2 -2
  158. package/lib/hooks/useExternalScript.js +4 -4
  159. package/lib/hooks/useFocusTrap.js +2 -1
  160. package/lib/hooks/useIAM.js +4 -5
  161. package/lib/hooks/useId.js +3 -3
  162. package/lib/hooks/useJupyterLabTheme.js +3 -1
  163. package/lib/hooks/useLocation.d.ts +22 -0
  164. package/lib/hooks/useLocation.js +149 -0
  165. package/lib/hooks/useLocationHandles.d.ts +2 -2
  166. package/lib/hooks/useLocationHandles.js +6 -4
  167. package/lib/hooks/useNavigate.d.ts +5 -1
  168. package/lib/hooks/useNavigate.js +62 -7
  169. package/lib/hooks/useNotebookAIAgent.js +3 -1
  170. package/lib/hooks/useParams.d.ts +5 -0
  171. package/lib/hooks/useParams.js +152 -0
  172. package/lib/hooks/useRuntimes.js +2 -2
  173. package/lib/hooks/useScreenshot.js +5 -5
  174. package/lib/hooks/useToast.js +15 -13
  175. package/lib/hooks/useUpload.js +9 -9
  176. package/lib/hooks/useUser.js +1 -1
  177. package/lib/index.css +1 -1
  178. package/lib/index.d.ts +6 -3
  179. package/lib/index.js +7 -3
  180. package/lib/mocks/components/FlashMock.js +4 -4
  181. package/lib/mocks/hooks/rests/rests.js +15 -18
  182. package/lib/mocks/hooks/useDatalayerMock.d.ts +2 -2
  183. package/lib/mocks/hooks/useDatalayerMock.js +7 -7
  184. package/lib/mocks/models/CodeBlockMock.js +1 -1
  185. package/lib/mocks/models/CodelineMock.js +1 -1
  186. package/lib/mocks/models/CourseMock.d.ts +1 -1
  187. package/lib/mocks/models/CourseMock.js +10 -10
  188. package/lib/mocks/models/InviteMock.d.ts +1 -1
  189. package/lib/mocks/models/InviteMock.js +21 -6
  190. package/lib/mocks/models/JupyterLabUserMock.js +2 -2
  191. package/lib/mocks/models/OrganisationMock.d.ts +1 -1
  192. package/lib/mocks/models/OrganisationMock.js +11 -7
  193. package/lib/mocks/models/SchoolMock.d.ts +1 -1
  194. package/lib/mocks/models/SchoolMock.js +6 -6
  195. package/lib/mocks/models/SpaceMock.d.ts +1 -1
  196. package/lib/mocks/models/SpaceMock.js +9 -9
  197. package/lib/mocks/models/TeamMock.d.ts +1 -1
  198. package/lib/mocks/models/TeamMock.js +6 -6
  199. package/lib/mocks/models/UserMock.d.ts +1 -1
  200. package/lib/mocks/models/UserMock.js +4 -6
  201. package/lib/mocks/views/ActionMenuMock.js +1 -1
  202. package/lib/mocks/views/ChartMock.js +3 -3
  203. package/lib/mocks/views/ChartMockOptions.js +24 -24
  204. package/lib/mocks/views/DashboardMock.js +74 -74
  205. package/lib/mocks/views/FormMock.js +1 -1
  206. package/lib/mocks/views/TableMock.js +1 -1
  207. package/lib/models/Account.d.ts +2 -2
  208. package/lib/models/Assignment.d.ts +2 -2
  209. package/lib/models/Cell.d.ts +1 -1
  210. package/lib/models/CodeBlock.d.ts +1 -1
  211. package/lib/models/CodefeedBlocks.d.ts +2 -2
  212. package/lib/models/Contact.d.ts +1 -1
  213. package/lib/models/Contact.js +14 -14
  214. package/lib/models/ContactIAMProvider.js +2 -2
  215. package/lib/models/Course.d.ts +7 -7
  216. package/lib/models/Dataset.d.ts +1 -1
  217. package/lib/models/Dean.d.ts +1 -1
  218. package/lib/models/Document.d.ts +1 -1
  219. package/lib/models/Environment.d.ts +2 -2
  220. package/lib/models/Exercise.d.ts +1 -1
  221. package/lib/models/IAMProviderLinked.js +1 -1
  222. package/lib/models/Instructor.d.ts +1 -1
  223. package/lib/models/Invite.d.ts +2 -2
  224. package/lib/models/Invite.js +1 -1
  225. package/lib/models/Item.d.ts +5 -5
  226. package/lib/models/LandingRoles.js +18 -18
  227. package/lib/models/Lesson.d.ts +1 -1
  228. package/lib/models/Member.d.ts +1 -1
  229. package/lib/models/Notebook.d.ts +1 -1
  230. package/lib/models/Organization.d.ts +4 -4
  231. package/lib/models/Organization.js +2 -2
  232. package/lib/models/OrganizationMember.d.ts +2 -2
  233. package/lib/models/Page.js +4 -2
  234. package/lib/models/PageTag.d.ts +1 -1
  235. package/lib/models/PageTag.js +56 -9
  236. package/lib/models/Profile.d.ts +1 -1
  237. package/lib/models/RolesOrganization.d.ts +1 -1
  238. package/lib/models/RolesOrganization.js +4 -12
  239. package/lib/models/RolesPlatform.d.ts +1 -1
  240. package/lib/models/RolesPlatform.js +12 -34
  241. package/lib/models/RolesTeam.d.ts +1 -1
  242. package/lib/models/RolesTeam.js +3 -10
  243. package/lib/models/Runtime.js +4 -4
  244. package/lib/models/RuntimeSnapshot.js +1 -1
  245. package/lib/models/School.d.ts +4 -4
  246. package/lib/models/Space.d.ts +5 -5
  247. package/lib/models/Space.js +3 -3
  248. package/lib/models/SpaceItem.d.ts +8 -8
  249. package/lib/models/SpaceMember.d.ts +2 -2
  250. package/lib/models/Student.d.ts +2 -2
  251. package/lib/models/StudentItem.d.ts +3 -3
  252. package/lib/models/Team.d.ts +3 -3
  253. package/lib/models/Team.js +2 -2
  254. package/lib/models/TeamMember.d.ts +2 -2
  255. package/lib/models/URN.js +1 -1
  256. package/lib/models/User.d.ts +2 -2
  257. package/lib/models/User.js +5 -3
  258. package/lib/models/UserOnboarding.d.ts +1 -1
  259. package/lib/models/UserOnboarding.js +7 -7
  260. package/lib/models/UserSettings.js +2 -2
  261. package/lib/models/index.d.ts +2 -2
  262. package/lib/models/index.js +2 -2
  263. package/lib/navigation/adapters/native.d.ts +11 -0
  264. package/lib/navigation/adapters/native.js +48 -0
  265. package/lib/navigation/adapters/nextjs.d.ts +9 -0
  266. package/lib/navigation/adapters/nextjs.js +35 -0
  267. package/lib/navigation/adapters/react-router.d.ts +4 -0
  268. package/lib/navigation/adapters/react-router.js +12 -0
  269. package/lib/navigation/components.d.ts +20 -0
  270. package/lib/navigation/components.js +36 -0
  271. package/lib/navigation/index.d.ts +4 -0
  272. package/lib/navigation/index.js +12 -0
  273. package/lib/routes/index.d.ts +1 -1
  274. package/lib/routes/index.js +1 -1
  275. package/lib/services/DatalayerServiceManager.d.ts +22 -0
  276. package/lib/services/DatalayerServiceManager.js +79 -0
  277. package/lib/services/index.d.ts +4 -0
  278. package/lib/services/index.js +7 -0
  279. package/lib/services/reconnectToRuntime.d.ts +32 -0
  280. package/lib/services/reconnectToRuntime.js +59 -0
  281. package/lib/state/State.d.ts +1 -1
  282. package/lib/state/State.js +1 -1
  283. package/lib/state/index.d.ts +1 -1
  284. package/lib/state/index.js +1 -1
  285. package/lib/state/storage/IAMStorage.js +14 -2
  286. package/lib/state/storage/index.d.ts +1 -1
  287. package/lib/state/storage/index.js +1 -1
  288. package/lib/state/substates/AIAgentState.js +4 -2
  289. package/lib/state/substates/CellState.js +6 -5
  290. package/lib/state/substates/CoreState.d.ts +1 -1
  291. package/lib/state/substates/CoreState.js +23 -15
  292. package/lib/state/substates/DatasourceState.js +1 -1
  293. package/lib/state/substates/IAMState.d.ts +4 -0
  294. package/lib/state/substates/IAMState.js +75 -56
  295. package/lib/state/substates/JupyterLabState.js +1 -1
  296. package/lib/state/substates/LayoutState.d.ts +2 -2
  297. package/lib/state/substates/LayoutState.js +41 -28
  298. package/lib/state/substates/OrganizationState.js +1 -1
  299. package/lib/state/substates/RuntimesState.js +6 -5
  300. package/lib/state/substates/SpaceState.js +1 -1
  301. package/lib/state/substates/SurveysState.js +4 -4
  302. package/lib/state/substates/TeamState.js +1 -1
  303. package/lib/test-setup.js +25 -3
  304. package/lib/theme/DatalayerTheme.js +1 -1
  305. package/lib/theme/DatalayerThemeProvider.js +17 -14
  306. package/lib/theme/Palette.js +1 -1
  307. package/lib/utils/Avatar.js +2 -2
  308. package/lib/utils/Browser.js +6 -6
  309. package/lib/utils/Cells.d.ts +1 -1
  310. package/lib/utils/Cookie.js +1 -1
  311. package/lib/utils/Date.js +2 -2
  312. package/lib/utils/Download.js +5 -3
  313. package/lib/utils/DownloadFile.js +4 -2
  314. package/lib/utils/Env.js +2 -1
  315. package/lib/utils/Lazy.d.ts +1 -1
  316. package/lib/utils/Lazy.js +2 -2
  317. package/lib/utils/Name.js +10 -8
  318. package/lib/utils/Notebook.d.ts +1 -1
  319. package/lib/utils/Notebook.js +3 -3
  320. package/lib/utils/Number.js +13 -9
  321. package/lib/utils/Plots.js +4 -4
  322. package/lib/utils/Screenshot.js +1 -1
  323. package/lib/utils/Sleep.js +1 -1
  324. package/lib/utils/Snapshot.js +2 -2
  325. package/lib/utils/String.js +2 -2
  326. package/lib/utils/Uri.js +1 -1
  327. package/lib/utils/WithSuspense.js +3 -6
  328. package/package.json +41 -5
  329. package/lib/__tests__/App.test.js +0 -17
  330. /package/lib/{__tests__/App.test.d.ts → examples/main.d.ts} +0 -0
@@ -3,13 +3,14 @@
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
5
  import { URLExt } from '@jupyterlab/coreutils';
6
- import { BOOTSTRAP_USER_ONBOARDING, LinkedInUser, asContact, asDatasource, asInbound, asInvite, asOrganization, asOutbound, asPage, asSecret, asSpace, asSurvey, asTeam, asToken, asUsage, asUser, } from "../models";
6
+ import { BOOTSTRAP_USER_ONBOARDING, LinkedInUser, asContact, asDatasource, asInbound, asInvite, asOrganization, asOutbound, asPage, asSecret, asSpace, asSurvey, asTeam, asToken, asUsage, asUser, } from '../models';
7
7
  import { useCoreStore, useIAMStore } from '../state';
8
- import { asDisplayName, namesAsInitials, asArray } from "../utils";
8
+ import { asDisplayName, namesAsInitials, asArray } from '../utils';
9
9
  import { IAMProvidersSpecs } from '../models';
10
10
  import { newUserMock } from './../mocks';
11
- import { useDatalayer } from "./useDatalayer";
12
- import { useAuthorization } from "./useAuthorization";
11
+ import { useDatalayer } from './useDatalayer';
12
+ import { useAuthorization } from './useAuthorization';
13
+ import { useUploadForm } from './useUpload';
13
14
  import { OUTPUTSHOT_PLACEHOLDER_DEFAULT_SVG } from './assets';
14
15
  const CONTACTS_BY_HANDLE = new Map();
15
16
  const CONTACTS_BY_ID = new Map();
@@ -64,10 +65,13 @@ const DEFAULT_SEARCH_OPTS = {
64
65
  * instead of redirecting to the login page).
65
66
  */
66
67
  export const useCache = ({ loginRoute = '/login' } = {}) => {
67
- const { configuration } = useCoreStore();
68
+ const coreStore = useCoreStore();
69
+ const { configuration } = coreStore;
68
70
  const { user } = useIAMStore();
69
71
  const { requestDatalayer } = useDatalayer({ loginRoute });
70
72
  const { checkIsOrganizationMember } = useAuthorization();
73
+ // Hook for notebook upload/creation
74
+ const { isLoading: notebookUploadLoading, uploadAndSubmit: uploadNotebook, progress: notebookUploadProgress, reset: resetNotebookUpload, } = useUploadForm(`${coreStore.configuration.spacerRunUrl}/api/spacer/v1/notebooks`);
71
75
  // Caches -------------------------------------------------------------------
72
76
  const clearAllCaches = () => {
73
77
  CONTACTS_BY_HANDLE.clear();
@@ -129,7 +133,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
129
133
  body: {
130
134
  handle,
131
135
  password,
132
- }
136
+ },
133
137
  });
134
138
  };
135
139
  const logout = () => {
@@ -151,7 +155,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
151
155
  lastName,
152
156
  password,
153
157
  passwordConfirm,
154
- }
158
+ },
155
159
  });
156
160
  };
157
161
  const requestJoinToken = (handle, email, firstName, lastName, password, passwordConfirm) => {
@@ -165,7 +169,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
165
169
  lastName,
166
170
  password,
167
171
  passwordConfirm,
168
- }
172
+ },
169
173
  });
170
174
  };
171
175
  const joinWithInvite = (formValues, token) => {
@@ -193,7 +197,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
193
197
  handle,
194
198
  password,
195
199
  passwordConfirm,
196
- }
200
+ },
197
201
  });
198
202
  };
199
203
  const createTokenForPasswordChange = (handle, password, passwordConfirm) => {
@@ -204,7 +208,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
204
208
  handle,
205
209
  password,
206
210
  passwordConfirm,
207
- }
211
+ },
208
212
  });
209
213
  };
210
214
  const confirmPassworkWithToken = (userHandle, token) => {
@@ -216,7 +220,8 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
216
220
  // OAuth2 -------------------------------------------------------------------
217
221
  const getOAuth2AuthorizationURL = async (queryArgs) => {
218
222
  return requestDatalayer({
219
- url: URLExt.join(configuration.iamRunUrl, 'api/iam/v1/oauth2/authz/url') + URLExt.objectToQueryString(queryArgs),
223
+ url: URLExt.join(configuration.iamRunUrl, 'api/iam/v1/oauth2/authz/url') +
224
+ URLExt.objectToQueryString(queryArgs),
220
225
  notifyOnError: false,
221
226
  });
222
227
  };
@@ -230,8 +235,8 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
230
235
  return fetch(IAMProvidersSpecs.GitHub.userInfoURL, {
231
236
  method: 'GET',
232
237
  headers: {
233
- 'Accept': 'application/vnd.github+json',
234
- 'Authorization': `Bearer ${accessToken}`,
238
+ Accept: 'application/vnd.github+json',
239
+ Authorization: `Bearer ${accessToken}`,
235
240
  'X-GitHub-Api-Version': '2022-11-28',
236
241
  },
237
242
  }).then(resp => resp.json());
@@ -246,53 +251,50 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
246
251
  };
247
252
  const postLinkedinShare = async (linkedinUser, postText, accessToken) => {
248
253
  const POST_SHARE_REQUEST = {
249
- "author": linkedinUser.getUrn(),
250
- "lifecycleState": "PUBLISHED",
251
- "specificContent": {
252
- "com.linkedin.ugc.ShareContent": {
253
- "shareCommentary": {
254
- "text": postText
254
+ author: linkedinUser.getUrn(),
255
+ lifecycleState: 'PUBLISHED',
256
+ specificContent: {
257
+ 'com.linkedin.ugc.ShareContent': {
258
+ shareCommentary: {
259
+ text: postText,
255
260
  },
256
- "shareMediaCategory": "NONE"
257
- }
261
+ shareMediaCategory: 'NONE',
262
+ },
263
+ },
264
+ visibility: {
265
+ 'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC',
258
266
  },
259
- "visibility": {
260
- "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
261
- }
262
267
  };
263
268
  return proxyPOST(IAMProvidersSpecs.LinkedIn.postShareURL, POST_SHARE_REQUEST, accessToken);
264
269
  };
265
270
  const postLinkedinShareWithUpload = async (linkedinUser, postText, uploadObject, accessToken) => {
266
271
  const REGISTER_UPLOAD_REQUEST = {
267
- "registerUploadRequest": {
268
- "recipes": [
269
- "urn:li:digitalmediaRecipe:feedshare-image"
270
- ],
271
- "owner": linkedinUser.getUrn(),
272
- "serviceRelationships": [
272
+ registerUploadRequest: {
273
+ recipes: ['urn:li:digitalmediaRecipe:feedshare-image'],
274
+ owner: linkedinUser.getUrn(),
275
+ serviceRelationships: [
273
276
  {
274
- "relationshipType": "OWNER",
275
- "identifier": "urn:li:userGeneratedContent"
276
- }
277
- ]
278
- }
277
+ relationshipType: 'OWNER',
278
+ identifier: 'urn:li:userGeneratedContent',
279
+ },
280
+ ],
281
+ },
279
282
  };
280
- return proxyPOST(IAMProvidersSpecs.LinkedIn.registerUploadURL, REGISTER_UPLOAD_REQUEST, accessToken)
281
- .then(registerUploadReponse => {
283
+ return proxyPOST(IAMProvidersSpecs.LinkedIn.registerUploadURL, REGISTER_UPLOAD_REQUEST, accessToken).then(registerUploadReponse => {
282
284
  /*
283
- {
284
- "value": {
285
- "uploadMechanism": {
286
- "com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest": {
287
- "headers": {},
288
- "uploadUrl": "https://api.linkedin.com/mediaUpload/C5522AQGTYER3k3ByHQ/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&m=AQJbrN86Zm265gAAAWemyz2pxPSgONtBiZdchrgG872QltnfYjnMdb2j3A&app=1953784&sync=0&v=beta&ut=2H-IhpbfXrRow1"
289
- }
290
- },
291
- "mediaArtifact": "urn:li:digitalmediaMediaArtifact:(urn:li:digitalmediaAsset:C5522AQGTYER3k3ByHQ,urn:li:digitalmediaMediaArtifactClass:feedshare-uploadedImage)",
292
- "asset": "urn:li:digitalmediaAsset:C5522AQGTYER3k3ByHQ"
285
+ {
286
+ "value": {
287
+ "uploadMechanism": {
288
+ "com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest": {
289
+ "headers": {},
290
+ "uploadUrl": "https://api.linkedin.com/mediaUpload/C5522AQGTYER3k3ByHQ/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&m=AQJbrN86Zm265gAAAWemyz2pxPSgONtBiZdchrgG872QltnfYjnMdb2j3A&app=1953784&sync=0&v=beta&ut=2H-IhpbfXrRow1"
291
+ }
292
+ },
293
+ "mediaArtifact": "urn:li:digitalmediaMediaArtifact:(urn:li:digitalmediaAsset:C5522AQGTYER3k3ByHQ,urn:li:digitalmediaMediaArtifactClass:feedshare-uploadedImage)",
294
+ "asset": "urn:li:digitalmediaAsset:C5522AQGTYER3k3ByHQ"
295
+ }
293
296
  }
294
- }
295
- */
297
+ */
296
298
  const asset = registerUploadReponse.response.value.asset;
297
299
  const uploadURL = registerUploadReponse.response.value.uploadMechanism['com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest'].uploadUrl;
298
300
  const UPLOAD_OBJECT_REQUEST = {
@@ -300,34 +302,33 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
300
302
  content: uploadObject,
301
303
  userURN: linkedinUser.getUrn(),
302
304
  };
303
- return proxyPUT(uploadURL, UPLOAD_OBJECT_REQUEST, accessToken)
304
- .then(resp => {
305
+ return proxyPUT(uploadURL, UPLOAD_OBJECT_REQUEST, accessToken).then(resp => {
305
306
  const share = {
306
- "author": linkedinUser.getUrn(),
307
- "lifecycleState": "PUBLISHED",
308
- "specificContent": {
309
- "com.linkedin.ugc.ShareContent": {
310
- "shareCommentary": {
311
- "text": postText
307
+ author: linkedinUser.getUrn(),
308
+ lifecycleState: 'PUBLISHED',
309
+ specificContent: {
310
+ 'com.linkedin.ugc.ShareContent': {
311
+ shareCommentary: {
312
+ text: postText,
312
313
  },
313
- "shareMediaCategory": "IMAGE",
314
- "media": [
314
+ shareMediaCategory: 'IMAGE',
315
+ media: [
315
316
  {
316
- "status": "READY",
317
- "description": {
318
- "text": "Datalayer Notebook"
317
+ status: 'READY',
318
+ description: {
319
+ text: 'Datalayer Notebook',
319
320
  },
320
- "media": asset,
321
- "title": {
322
- "text": "Datalayer Notebook"
323
- }
324
- }
325
- ]
326
- }
321
+ media: asset,
322
+ title: {
323
+ text: 'Datalayer Notebook',
324
+ },
325
+ },
326
+ ],
327
+ },
328
+ },
329
+ visibility: {
330
+ 'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC',
327
331
  },
328
- "visibility": {
329
- "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
330
- }
331
332
  };
332
333
  return proxyPOST(IAMProvidersSpecs.LinkedIn.postShareURL, share, accessToken);
333
334
  });
@@ -342,7 +343,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
342
343
  request_method: 'GET',
343
344
  request_url: url,
344
345
  request_token: token,
345
- }
346
+ },
346
347
  });
347
348
  };
348
349
  const proxyPOST = async (url, body, token) => {
@@ -354,7 +355,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
354
355
  request_url: url,
355
356
  request_token: token,
356
357
  request_body: body,
357
- }
358
+ },
358
359
  });
359
360
  };
360
361
  const proxyPUT = async (url, body, token) => {
@@ -366,7 +367,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
366
367
  request_url: url,
367
368
  request_token: token,
368
369
  request_body: body,
369
- }
370
+ },
370
371
  });
371
372
  };
372
373
  // Waiting List -------------------------------------------------------------
@@ -378,8 +379,8 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
378
379
  firstName: formData.firstName,
379
380
  lastName: formData.lastName,
380
381
  email: formData.email,
381
- affiliation: formData.affiliation || ''
382
- }
382
+ affiliation: formData.affiliation || '',
383
+ },
383
384
  })
384
385
  .then(resp => {
385
386
  // Special case, make the error very explicit to the user...
@@ -398,7 +399,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
398
399
  const resp = await requestDatalayer({
399
400
  url: `${configuration.iamRunUrl}/api/iam/v1/me`,
400
401
  method: 'GET',
401
- token
402
+ token,
402
403
  });
403
404
  const me = resp.me;
404
405
  if (me) {
@@ -415,7 +416,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
415
416
  email,
416
417
  firstName,
417
418
  lastName,
418
- }
419
+ },
419
420
  });
420
421
  };
421
422
  const whoami = () => {
@@ -424,22 +425,22 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
424
425
  method: 'GET',
425
426
  });
426
427
  };
427
- const requestEmailUpdate = (email) => {
428
+ const requestEmailUpdate = email => {
428
429
  return requestDatalayer({
429
430
  url: `${configuration.iamRunUrl}/api/iam/v1/me/email`,
430
431
  method: 'PUT',
431
432
  body: {
432
433
  email,
433
- }
434
+ },
434
435
  });
435
436
  };
436
- const confirmEmailUpdate = (token) => {
437
+ const confirmEmailUpdate = token => {
437
438
  return requestDatalayer({
438
439
  url: `${configuration.iamRunUrl}/api/iam/v1/me/email`,
439
440
  method: 'POST',
440
441
  body: {
441
442
  token,
442
- }
443
+ },
443
444
  });
444
445
  };
445
446
  // Onboarding ---------------------------------------------------------------
@@ -449,7 +450,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
449
450
  method: 'PUT',
450
451
  body: {
451
452
  onboarding,
452
- }
453
+ },
453
454
  });
454
455
  };
455
456
  // Settings -----------------------------------------------------------------
@@ -475,7 +476,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
475
476
  return requestDatalayer({
476
477
  url: `${configuration.libraryRunUrl}/api/library/v1/pages`,
477
478
  method: 'POST',
478
- body: { ...page }
479
+ body: { ...page },
479
480
  }).then(resp => {
480
481
  if (resp.success) {
481
482
  if (resp.page) {
@@ -560,7 +561,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
560
561
  return requestDatalayer({
561
562
  url: `${configuration.iamRunUrl}/api/iam/v1/datasources`,
562
563
  method: 'POST',
563
- body: { ...datasource }
564
+ body: { ...datasource },
564
565
  }).then(resp => {
565
566
  if (resp.success) {
566
567
  if (resp.datasource) {
@@ -574,7 +575,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
574
575
  return requestDatalayer({
575
576
  url: `${configuration.iamRunUrl}/api/iam/v1/datasources/${datasource.id}`,
576
577
  method: 'PUT',
577
- body: { ...datasource }
578
+ body: { ...datasource },
578
579
  }).then(resp => {
579
580
  if (resp.success) {
580
581
  if (resp.datasource) {
@@ -631,7 +632,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
631
632
  return requestDatalayer({
632
633
  url: `${configuration.iamRunUrl}/api/iam/v1/secrets`,
633
634
  method: 'POST',
634
- body: { ...secret }
635
+ body: { ...secret },
635
636
  }).then(resp => {
636
637
  if (resp.success) {
637
638
  if (resp.secret) {
@@ -645,7 +646,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
645
646
  return requestDatalayer({
646
647
  url: `${configuration.iamRunUrl}/api/iam/v1/secrets/${secret.id}`,
647
648
  method: 'PUT',
648
- body: { ...secret }
649
+ body: { ...secret },
649
650
  }).then(resp => {
650
651
  if (resp.success) {
651
652
  if (resp.secret) {
@@ -711,7 +712,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
711
712
  body: {
712
713
  ...token,
713
714
  expirationDate: token.expirationDate.getTime(),
714
- }
715
+ },
715
716
  }).then(resp => {
716
717
  if (resp.success) {
717
718
  if (resp.token) {
@@ -725,7 +726,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
725
726
  return requestDatalayer({
726
727
  url: `${configuration.iamRunUrl}/api/iam/v1/tokens/${token.id}`,
727
728
  method: 'PUT',
728
- body: { ...token }
729
+ body: { ...token },
729
730
  }).then(resp => {
730
731
  if (resp.success) {
731
732
  if (resp.token) {
@@ -822,7 +823,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
822
823
  last_name: lastName,
823
824
  email: email,
824
825
  social_url: socialUrl,
825
- }
826
+ },
826
827
  });
827
828
  };
828
829
  const sendInvite = (invite) => {
@@ -835,7 +836,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
835
836
  lastName: invite.to.lastName,
836
837
  message: invite.message,
837
838
  brand: invite.brand,
838
- }
839
+ },
839
840
  });
840
841
  };
841
842
  const getInvite = (token) => INVITES_BY_TOKEN.get(token);
@@ -916,7 +917,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
916
917
  method: 'POST',
917
918
  body: {
918
919
  contact,
919
- }
920
+ },
920
921
  }).then(resp => {
921
922
  if (resp.success) {
922
923
  toContact(resp.contact);
@@ -930,7 +931,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
930
931
  method: 'PUT',
931
932
  body: {
932
933
  contact,
933
- }
934
+ },
934
935
  }).then(resp => {
935
936
  if (resp.success) {
936
937
  toContact(resp.contact);
@@ -955,7 +956,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
955
956
  method: 'POST',
956
957
  body: {
957
958
  query,
958
- }
959
+ },
959
960
  }).then(resp => {
960
961
  if (resp.success) {
961
962
  const contacts = resp.contacts.map(contact => toContact(contact));
@@ -989,7 +990,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
989
990
  body: {
990
991
  contactId: contact.id,
991
992
  message,
992
- }
993
+ },
993
994
  });
994
995
  };
995
996
  // Contacts Enrich ----------------------------------------------------------
@@ -999,7 +1000,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
999
1000
  method: 'GET',
1000
1001
  });
1001
1002
  };
1002
- const enrichContactLinkedin = (contactId) => {
1003
+ const enrichContactLinkedin = contactId => {
1003
1004
  return requestDatalayer({
1004
1005
  url: `${configuration.growthRunUrl}/api/growth/v1/contacts/${contactId}/enrich/linkedin`,
1005
1006
  method: 'GET',
@@ -1011,7 +1012,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1011
1012
  method: 'POST',
1012
1013
  body: {
1013
1014
  message,
1014
- }
1015
+ },
1015
1016
  }).then(resp => {
1016
1017
  if (resp.success) {
1017
1018
  toContact(resp.contact);
@@ -1059,8 +1060,8 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1059
1060
  url: `${configuration.iamRunUrl}/api/iam/v1/users/search`,
1060
1061
  method: 'POST',
1061
1062
  body: {
1062
- namingPattern
1063
- }
1063
+ namingPattern,
1064
+ },
1064
1065
  }).then(resp => {
1065
1066
  if (resp.success) {
1066
1067
  const users = resp.users.map(user => toUser(user));
@@ -1097,7 +1098,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1097
1098
  handle: organization.handle,
1098
1099
  name: organization.name,
1099
1100
  description: organization.description,
1100
- }
1101
+ },
1101
1102
  }).then(resp => {
1102
1103
  const organization = toOrganization(resp.organization);
1103
1104
  ORGANISATIONS_FOR_USER_BY_ID.set(organization.id, organization);
@@ -1135,7 +1136,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1135
1136
  body: {
1136
1137
  name: organization.name,
1137
1138
  description: organization.description,
1138
- }
1139
+ },
1139
1140
  }).then(resp => {
1140
1141
  if (resp.success) {
1141
1142
  const org = getOrganizationById(organization.id);
@@ -1205,7 +1206,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1205
1206
  name: team.name,
1206
1207
  description: team.description,
1207
1208
  organizationId: organization.id,
1208
- }
1209
+ },
1209
1210
  }).then(resp => {
1210
1211
  const team = toTeam(resp.team, organization.id);
1211
1212
  TEAMS_BY_HANDLE.set(team.handle, team);
@@ -1242,7 +1243,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1242
1243
  body: {
1243
1244
  name: team.name,
1244
1245
  description: team.description,
1245
- }
1246
+ },
1246
1247
  }).then(resp => {
1247
1248
  if (resp.success) {
1248
1249
  const t = resp.team;
@@ -1326,7 +1327,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1326
1327
  creationDate: new Date(s.creation_ts_dt),
1327
1328
  setMembers(members) {
1328
1329
  this.members = members;
1329
- }
1330
+ },
1330
1331
  };
1331
1332
  SCHOOLS_BY_ID.set(school.id, school);
1332
1333
  });
@@ -1340,9 +1341,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1340
1341
  return space;
1341
1342
  };
1342
1343
  const createSpace = (space, organization) => {
1343
- const seedSpaceId = (space.variant === 'course')
1344
- ? space.seedSpace?.id
1345
- : undefined;
1344
+ const seedSpaceId = space.variant === 'course' ? space.seedSpace?.id : undefined;
1346
1345
  return requestDatalayer({
1347
1346
  url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces`,
1348
1347
  method: 'POST',
@@ -1354,7 +1353,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1354
1353
  spaceHandle: space.handle,
1355
1354
  organizationId: organization?.id,
1356
1355
  seedSpaceId,
1357
- }
1356
+ },
1358
1357
  }).then(resp => {
1359
1358
  const spc = resp.space;
1360
1359
  if (spc) {
@@ -1416,7 +1415,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1416
1415
  body: {
1417
1416
  name: space.name,
1418
1417
  description: space.description,
1419
- }
1418
+ },
1420
1419
  }).then(resp => {
1421
1420
  if (resp.success) {
1422
1421
  const spc = getOrganizationSpace(organization.id, space.id);
@@ -1495,7 +1494,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1495
1494
  body: {
1496
1495
  name: space.name,
1497
1496
  description: space.description,
1498
- }
1497
+ },
1499
1498
  }).then(resp => {
1500
1499
  if (resp.success) {
1501
1500
  const spc = getUserSpace(space.id);
@@ -1603,7 +1602,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1603
1602
  onboarding: BOOTSTRAP_USER_ONBOARDING,
1604
1603
  linkedContactId: undefined,
1605
1604
  events: [],
1606
- settings: {}
1605
+ settings: {},
1607
1606
  };
1608
1607
  USERS_BY_ID.set(instructor.id, instructor);
1609
1608
  }
@@ -1634,7 +1633,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1634
1633
  id: raw_course.uid,
1635
1634
  handle: raw_course.handle_s,
1636
1635
  type: 'space',
1637
- variant: "course",
1636
+ variant: 'course',
1638
1637
  name: raw_course.name_t,
1639
1638
  description: raw_course.description_t,
1640
1639
  creationDate: new Date(raw_course.creation_ts_dt),
@@ -1656,7 +1655,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1656
1655
  body: {
1657
1656
  name,
1658
1657
  description,
1659
- }
1658
+ },
1660
1659
  });
1661
1660
  };
1662
1661
  const refreshCourse = (courseId) => {
@@ -1750,7 +1749,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1750
1749
  method: 'PUT',
1751
1750
  body: {
1752
1751
  completed,
1753
- }
1752
+ },
1754
1753
  });
1755
1754
  };
1756
1755
  const setCourseItems = (courseId, itemIds) => {
@@ -1759,7 +1758,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1759
1758
  method: 'PUT',
1760
1759
  body: {
1761
1760
  itemIds,
1762
- }
1761
+ },
1763
1762
  });
1764
1763
  };
1765
1764
  // Surveys ---------------------------------------------------------------------
@@ -1933,7 +1932,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1933
1932
  // Items --------------------------------------------------------------
1934
1933
  const toItem = (item) => {
1935
1934
  if (!item.type_s) {
1936
- console.error("No type_s found on item", item);
1935
+ console.error('No type_s found on item', item);
1937
1936
  return {};
1938
1937
  }
1939
1938
  switch (item.type_s) {
@@ -2046,7 +2045,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2046
2045
  });
2047
2046
  };
2048
2047
  // Datasets ------------------------------------------------------------------
2049
- const toDataset = (raw_dataset) => {
2048
+ const toDataset = raw_dataset => {
2050
2049
  const owner = newUserMock();
2051
2050
  USERS_BY_ID.set(owner.id, owner);
2052
2051
  const dataset = {
@@ -2063,19 +2062,21 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2063
2062
  cdnUrl: raw_dataset.cdn_url_s,
2064
2063
  creationDate: new Date(raw_dataset.creation_ts_dt),
2065
2064
  public: raw_dataset.public_b ?? false,
2066
- lastPublicationDate: raw_dataset.creation_ts_dt ? new Date(raw_dataset.creation_ts_dt) : undefined,
2065
+ lastPublicationDate: raw_dataset.creation_ts_dt
2066
+ ? new Date(raw_dataset.creation_ts_dt)
2067
+ : undefined,
2067
2068
  owner,
2068
2069
  space: {
2069
2070
  handle: raw_dataset.handle_s,
2070
2071
  },
2071
2072
  organization: {
2072
2073
  handle: raw_dataset.handle_s,
2073
- }
2074
+ },
2074
2075
  };
2075
2076
  SPACE_DATASETS_BY_ID.set(dataset.id, dataset);
2076
2077
  return dataset;
2077
2078
  };
2078
- const getDataset = (id) => SPACE_DATASETS_BY_ID.get(id);
2079
+ const getDataset = id => SPACE_DATASETS_BY_ID.get(id);
2079
2080
  const refreshDataset = (id) => {
2080
2081
  return requestDatalayer({
2081
2082
  url: `${configuration.spacerRunUrl}/api/spacer/v1/spaces/items/${id}`,
@@ -2112,11 +2113,11 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2112
2113
  body: {
2113
2114
  name,
2114
2115
  description,
2115
- }
2116
+ },
2116
2117
  });
2117
2118
  };
2118
2119
  // Cells ------------------------------------------------------------------
2119
- const toCell = (cl) => {
2120
+ const toCell = cl => {
2120
2121
  const owner = newUserMock();
2121
2122
  USERS_BY_ID.set(owner.id, owner);
2122
2123
  const cell = {
@@ -2127,7 +2128,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2127
2128
  source: cl.source_t,
2128
2129
  creationDate: new Date(cl.creation_ts_dt),
2129
2130
  public: cl.public_b ?? false,
2130
- lastPublicationDate: cl.last_publication_ts_dt ? new Date(cl.last_publication_ts_dt) : undefined,
2131
+ lastPublicationDate: cl.last_publication_ts_dt
2132
+ ? new Date(cl.last_publication_ts_dt)
2133
+ : undefined,
2131
2134
  outputshotUrl: cl.outputshot_url_s || '',
2132
2135
  outputshotData: OUTPUTSHOT_PLACEHOLDER_DEFAULT_SVG,
2133
2136
  owner,
@@ -2175,7 +2178,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2175
2178
  return requestDatalayer({
2176
2179
  url: `${configuration.spacerRunUrl}/api/spacer/v1/cells/${cell.id}`,
2177
2180
  method: 'PUT',
2178
- body: cell
2181
+ body: cell,
2179
2182
  });
2180
2183
  };
2181
2184
  const cloneCell = (cellId) => {
@@ -2190,7 +2193,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2190
2193
  });
2191
2194
  };
2192
2195
  // Notebooks ------------------------------------------------------------------
2193
- const toNotebook = (raw_notebook) => {
2196
+ const toNotebook = raw_notebook => {
2194
2197
  const owner = newUserMock();
2195
2198
  USERS_BY_ID.set(owner.id, owner);
2196
2199
  const notebook = {
@@ -2198,11 +2201,17 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2198
2201
  type: 'notebook',
2199
2202
  name: raw_notebook.name_t,
2200
2203
  description: raw_notebook.description_t,
2201
- nbformat: raw_notebook.model_s ? JSON.parse(raw_notebook.model_s) : undefined,
2204
+ nbformat: raw_notebook.model_s
2205
+ ? JSON.parse(raw_notebook.model_s)
2206
+ : undefined,
2202
2207
  public: raw_notebook.public_b ?? false,
2203
2208
  creationDate: new Date(raw_notebook.creation_ts_dt),
2204
- lastUpdateDate: raw_notebook.last_update_ts_dt ? new Date(raw_notebook.last_update_ts_dt) : undefined,
2205
- lastPublicationDate: raw_notebook.creation_ts_dt ? new Date(raw_notebook.creation_ts_dt) : undefined,
2209
+ lastUpdateDate: raw_notebook.last_update_ts_dt
2210
+ ? new Date(raw_notebook.last_update_ts_dt)
2211
+ : undefined,
2212
+ lastPublicationDate: raw_notebook.creation_ts_dt
2213
+ ? new Date(raw_notebook.creation_ts_dt)
2214
+ : undefined,
2206
2215
  datasets: [],
2207
2216
  owner,
2208
2217
  space: {
@@ -2210,12 +2219,12 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2210
2219
  },
2211
2220
  organization: {
2212
2221
  handle: raw_notebook.handle_s,
2213
- }
2222
+ },
2214
2223
  };
2215
2224
  SPACE_NOTEBOOKS_BY_ID.set(notebook.id, notebook);
2216
2225
  return notebook;
2217
2226
  };
2218
- const getNotebook = (notebookId) => SPACE_NOTEBOOKS_BY_ID.get(notebookId);
2227
+ const getNotebook = notebookId => SPACE_NOTEBOOKS_BY_ID.get(notebookId);
2219
2228
  const refreshNotebook = (notebookId) => {
2220
2229
  return requestDatalayer({
2221
2230
  url: `${configuration.spacerRunUrl}/api/spacer/v1/notebooks/${notebookId}`,
@@ -2231,7 +2240,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2231
2240
  });
2232
2241
  };
2233
2242
  const getSpaceNotebooks = () => Array.from(SPACE_NOTEBOOKS_BY_ID.values());
2234
- const getSpaceNotebook = (id) => SPACE_NOTEBOOKS_BY_ID.get(id);
2243
+ const getSpaceNotebook = id => SPACE_NOTEBOOKS_BY_ID.get(id);
2235
2244
  const refreshSpaceNotebooks = (space, organization) => {
2236
2245
  const url = `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${space.id}/items/types/notebook`;
2237
2246
  return requestDatalayer({
@@ -2257,6 +2266,27 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2257
2266
  return resp;
2258
2267
  });
2259
2268
  };
2269
+ const createNotebook = async (spaceId, name, description, notebookType = 'notebook') => {
2270
+ // Create FormData for the upload
2271
+ const formData = new FormData();
2272
+ formData.append('spaceId', spaceId);
2273
+ formData.append('notebookType', notebookType);
2274
+ formData.append('name', name);
2275
+ formData.append('description', description || '');
2276
+ try {
2277
+ const resp = await uploadNotebook(formData);
2278
+ if (resp.success) {
2279
+ if (resp.notebook) {
2280
+ toNotebook(resp.notebook);
2281
+ }
2282
+ }
2283
+ return resp;
2284
+ }
2285
+ catch (error) {
2286
+ console.error('Failed to create notebook:', error);
2287
+ return { success: false, error };
2288
+ }
2289
+ };
2260
2290
  const updateNotebook = (id, name, description) => {
2261
2291
  return requestDatalayer({
2262
2292
  url: `${configuration.spacerRunUrl}/api/spacer/v1/notebooks/${id}`,
@@ -2264,7 +2294,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2264
2294
  body: {
2265
2295
  name,
2266
2296
  description,
2267
- }
2297
+ },
2268
2298
  });
2269
2299
  };
2270
2300
  const updateNotebookModel = (notebookId, nbformat) => {
@@ -2273,11 +2303,11 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2273
2303
  method: 'PUT',
2274
2304
  body: {
2275
2305
  nbformat,
2276
- }
2306
+ },
2277
2307
  });
2278
2308
  };
2279
2309
  // Documents ------------------------------------------------------------------
2280
- const toDocument = (doc) => {
2310
+ const toDocument = doc => {
2281
2311
  const owner = newUserMock();
2282
2312
  USERS_BY_ID.set(owner.id, owner);
2283
2313
  const document = {
@@ -2288,20 +2318,24 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2288
2318
  model: doc.model_s ? JSON.parse(doc.model_s) : undefined,
2289
2319
  public: doc.public_b ?? false,
2290
2320
  creationDate: new Date(doc.creation_ts_dt),
2291
- lastUpdateDate: doc.last_update_ts_dt ? new Date(doc.last_update_ts_dt) : undefined,
2292
- lastPublicationDate: doc.creation_ts_dt ? new Date(doc.creation_ts_dt) : undefined,
2321
+ lastUpdateDate: doc.last_update_ts_dt
2322
+ ? new Date(doc.last_update_ts_dt)
2323
+ : undefined,
2324
+ lastPublicationDate: doc.creation_ts_dt
2325
+ ? new Date(doc.creation_ts_dt)
2326
+ : undefined,
2293
2327
  owner,
2294
2328
  space: {
2295
2329
  handle: doc.handle_s,
2296
2330
  },
2297
2331
  organization: {
2298
2332
  handle: doc.handle_s,
2299
- }
2333
+ },
2300
2334
  };
2301
2335
  SPACE_DOCUMENTS_BY_ID.set(document.id, document);
2302
2336
  return document;
2303
2337
  };
2304
- const getDocument = (id) => SPACE_DOCUMENTS_BY_ID.get(id);
2338
+ const getDocument = id => SPACE_DOCUMENTS_BY_ID.get(id);
2305
2339
  const refreshDocument = (id) => {
2306
2340
  return requestDatalayer({
2307
2341
  url: `${configuration.spacerRunUrl}/api/spacer/v1/lexicals/${id}`,
@@ -2317,7 +2351,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2317
2351
  });
2318
2352
  };
2319
2353
  const getSpaceDocuments = () => Array.from(SPACE_DOCUMENTS_BY_ID.values());
2320
- const getSpaceDocument = (id) => SPACE_DOCUMENTS_BY_ID.get(id);
2354
+ const getSpaceDocument = id => SPACE_DOCUMENTS_BY_ID.get(id);
2321
2355
  const refreshSpaceDocuments = (space, organization) => {
2322
2356
  const url = `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${space.id}/items/types/document`;
2323
2357
  return requestDatalayer({
@@ -2350,7 +2384,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2350
2384
  body: {
2351
2385
  name,
2352
2386
  description,
2353
- }
2387
+ },
2354
2388
  });
2355
2389
  };
2356
2390
  const updateDocumentModel = (id, model) => {
@@ -2359,7 +2393,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2359
2393
  method: 'PUT',
2360
2394
  body: {
2361
2395
  model,
2362
- }
2396
+ },
2363
2397
  });
2364
2398
  };
2365
2399
  // Environments ------------------------------------------------------------------
@@ -2373,14 +2407,16 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2373
2407
  description: env.description_t,
2374
2408
  creationDate: new Date(env.creation_ts_dt),
2375
2409
  public: env.public_b ?? false,
2376
- lastPublicationDate: env.creation_ts_dt ? new Date(env.creation_ts_dt) : undefined,
2410
+ lastPublicationDate: env.creation_ts_dt
2411
+ ? new Date(env.creation_ts_dt)
2412
+ : undefined,
2377
2413
  owner,
2378
2414
  space: {
2379
2415
  handle: env.handle_s,
2380
2416
  },
2381
2417
  organization: {
2382
2418
  handle: env.handle_s,
2383
- }
2419
+ },
2384
2420
  };
2385
2421
  cache.set(environment.id, environment);
2386
2422
  return environment;
@@ -2416,7 +2452,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2416
2452
  });
2417
2453
  };
2418
2454
  // Lessons ------------------------------------------------------------------
2419
- const toLesson = (raw_lesson) => {
2455
+ const toLesson = raw_lesson => {
2420
2456
  const owner = newUserMock();
2421
2457
  USERS_BY_ID.set(owner.id, owner);
2422
2458
  const lesson = {
@@ -2427,8 +2463,12 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2427
2463
  nbformat: raw_lesson.model_s ? JSON.parse(raw_lesson.model_s) : undefined,
2428
2464
  public: raw_lesson.public_b ?? false,
2429
2465
  creationDate: new Date(raw_lesson.creation_ts_dt),
2430
- lastUpdateDate: raw_lesson.last_update_ts_dt ? new Date(raw_lesson.last_update_ts_dt) : undefined,
2431
- lastPublicationDate: raw_lesson.creation_ts_dt ? new Date(raw_lesson.creation_ts_dt) : undefined,
2466
+ lastUpdateDate: raw_lesson.last_update_ts_dt
2467
+ ? new Date(raw_lesson.last_update_ts_dt)
2468
+ : undefined,
2469
+ lastPublicationDate: raw_lesson.creation_ts_dt
2470
+ ? new Date(raw_lesson.creation_ts_dt)
2471
+ : undefined,
2432
2472
  owner,
2433
2473
  space: {
2434
2474
  handle: raw_lesson.handle_s,
@@ -2441,7 +2481,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2441
2481
  SPACE_LESSONS_BY_ID.set(lesson.id, lesson);
2442
2482
  return lesson;
2443
2483
  };
2444
- const getLesson = (id) => SPACE_LESSONS_BY_ID.get(id);
2484
+ const getLesson = id => SPACE_LESSONS_BY_ID.get(id);
2445
2485
  const refreshLesson = (id) => {
2446
2486
  return requestDatalayer({
2447
2487
  url: `${configuration.spacerRunUrl}/api/spacer/v1/lessons/${id}`,
@@ -2457,7 +2497,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2457
2497
  });
2458
2498
  };
2459
2499
  const getSpaceLessons = () => Array.from(SPACE_LESSONS_BY_ID.values());
2460
- const getSpaceLesson = (id) => SPACE_LESSONS_BY_ID.get(id);
2500
+ const getSpaceLesson = id => SPACE_LESSONS_BY_ID.get(id);
2461
2501
  const refreshSpaceLessons = (space, organization) => {
2462
2502
  const url = `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${space.id}/items/types/lesson`;
2463
2503
  return requestDatalayer({
@@ -2499,8 +2539,12 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2499
2539
  codeTest: ex.code_test_t,
2500
2540
  public: ex.public_b ?? false,
2501
2541
  creationDate: new Date(ex.creation_ts_dt),
2502
- lastUpdateDate: ex.last_update_ts_dt ? new Date(ex.last_update_ts_dt) : undefined,
2503
- lastPublicationDate: ex.creation_ts_dt ? new Date(ex.creation_ts_dt) : undefined,
2542
+ lastUpdateDate: ex.last_update_ts_dt
2543
+ ? new Date(ex.last_update_ts_dt)
2544
+ : undefined,
2545
+ lastPublicationDate: ex.creation_ts_dt
2546
+ ? new Date(ex.creation_ts_dt)
2547
+ : undefined,
2504
2548
  owner,
2505
2549
  space: {
2506
2550
  handle: ex.handle_s,
@@ -2568,7 +2612,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2568
2612
  codeSolution,
2569
2613
  codeQuestion,
2570
2614
  codeTest,
2571
- }
2615
+ },
2572
2616
  });
2573
2617
  };
2574
2618
  const updateExercisePoints = (id, codeStudent, points) => {
@@ -2578,7 +2622,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2578
2622
  body: {
2579
2623
  codeStudent,
2580
2624
  points,
2581
- }
2625
+ },
2582
2626
  });
2583
2627
  };
2584
2628
  // Assignments ------------------------------------------------------------------
@@ -2590,7 +2634,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2590
2634
  raw_assignment.student_items.forEach(student_item => {
2591
2635
  studentItem = {
2592
2636
  id: student_item.uid,
2593
- type: "student_item",
2637
+ type: 'student_item',
2594
2638
  itemId: student_item.item_uid,
2595
2639
  itemType: student_item.item_type_s,
2596
2640
  nbgrades: student_item.nbgrades,
@@ -2605,11 +2649,17 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2605
2649
  type: 'assignment',
2606
2650
  name: raw_assignment.name_t,
2607
2651
  description: raw_assignment.description_t,
2608
- nbformat: raw_assignment.model_s ? JSON.parse(raw_assignment.model_s) : undefined,
2652
+ nbformat: raw_assignment.model_s
2653
+ ? JSON.parse(raw_assignment.model_s)
2654
+ : undefined,
2609
2655
  public: raw_assignment.public_b ?? false,
2610
2656
  creationDate: new Date(raw_assignment.creation_ts_dt),
2611
- lastUpdateDate: raw_assignment.last_update_ts_dt ? new Date(raw_assignment.last_update_ts_dt) : undefined,
2612
- lastPublicationDate: raw_assignment.creation_ts_dt ? new Date(raw_assignment.creation_ts_dt) : undefined,
2657
+ lastUpdateDate: raw_assignment.last_update_ts_dt
2658
+ ? new Date(raw_assignment.last_update_ts_dt)
2659
+ : undefined,
2660
+ lastPublicationDate: raw_assignment.creation_ts_dt
2661
+ ? new Date(raw_assignment.creation_ts_dt)
2662
+ : undefined,
2613
2663
  studentItem,
2614
2664
  datasets: [],
2615
2665
  owner,
@@ -2624,7 +2674,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2624
2674
  STUDENT_ASSIGNMENTS_BY_ID.set(assignment.id, assignment);
2625
2675
  return assignment;
2626
2676
  };
2627
- const getAssignment = (assignmentId) => SPACE_ASSIGNMENTS_BY_ID.get(assignmentId);
2677
+ const getAssignment = assignmentId => SPACE_ASSIGNMENTS_BY_ID.get(assignmentId);
2628
2678
  const refreshAssignment = (assignmentId) => {
2629
2679
  return requestDatalayer({
2630
2680
  url: `${configuration.spacerRunUrl}/api/spacer/v1/assignments/${assignmentId}`,
@@ -2674,7 +2724,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2674
2724
  method: 'PUT',
2675
2725
  body: {
2676
2726
  model,
2677
- }
2727
+ },
2678
2728
  }).then(resp => {
2679
2729
  if (resp.success) {
2680
2730
  const assignment = resp.assignment;
@@ -2686,7 +2736,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2686
2736
  });
2687
2737
  };
2688
2738
  const getSpaceAssignments = () => Array.from(SPACE_ASSIGNMENTS_BY_ID.values());
2689
- const getSpaceAssignment = (id) => SPACE_ASSIGNMENTS_BY_ID.get(id);
2739
+ const getSpaceAssignment = id => SPACE_ASSIGNMENTS_BY_ID.get(id);
2690
2740
  const refreshSpaceAssignments = (space, organization) => {
2691
2741
  const url = `${configuration.spacerRunUrl}/api/spacer/v1/spaces/${space.id}/items/types/assignment`;
2692
2742
  return requestDatalayer({
@@ -2712,7 +2762,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2712
2762
  return resp;
2713
2763
  });
2714
2764
  };
2715
- const getAssignmentStudentVersion = (assignmentId) => {
2765
+ const getAssignmentStudentVersion = assignmentId => {
2716
2766
  return requestDatalayer({
2717
2767
  url: `${configuration.spacerRunUrl}/api/spacer/v1/assignments/${assignmentId}/student_version`,
2718
2768
  method: 'GET',
@@ -2732,8 +2782,8 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2732
2782
  method: 'POST',
2733
2783
  body: {
2734
2784
  price_id: product?.id,
2735
- return_url: `${location.protocol}//${location.host}${location.pathname.split('/').slice(0, -1).join('/')}`
2736
- }
2785
+ return_url: `${location.protocol}//${location.host}${location.pathname.split('/').slice(0, -1).join('/')}`,
2786
+ },
2737
2787
  })
2738
2788
  .then(data => data.client_secret)
2739
2789
  .catch(error => {
@@ -2741,40 +2791,40 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2741
2791
  });
2742
2792
  };
2743
2793
  // Credits -------------------------------------------------------------------
2744
- const burnCredit = (credits) => {
2794
+ const burnCredit = credits => {
2745
2795
  return requestDatalayer({
2746
2796
  url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits`,
2747
- method: "DELETE",
2797
+ method: 'DELETE',
2748
2798
  body: {
2749
2799
  credits,
2750
- }
2800
+ },
2751
2801
  });
2752
2802
  };
2753
- const getUserCredits = (userId) => {
2803
+ const getUserCredits = userId => {
2754
2804
  return requestDatalayer({
2755
2805
  url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits/users/${userId}`,
2756
- method: "GET",
2806
+ method: 'GET',
2757
2807
  });
2758
2808
  };
2759
2809
  const updateUserCredits = (userId, credits, brand) => {
2760
2810
  return requestDatalayer({
2761
2811
  url: `${configuration.iamRunUrl}/api/iam/v1/usage/credits/users/${userId}`,
2762
- method: "PUT",
2812
+ method: 'PUT',
2763
2813
  body: {
2764
2814
  credits,
2765
2815
  brand,
2766
- }
2816
+ },
2767
2817
  });
2768
2818
  };
2769
2819
  const updateUserCreditsQuota = (userId, quota) => {
2770
2820
  return requestDatalayer({
2771
2821
  url: `${configuration.iamRunUrl}/api/iam/v1/usage/quota`,
2772
- method: "PUT",
2822
+ method: 'PUT',
2773
2823
  body: {
2774
2824
  user_uid: userId,
2775
2825
  quota,
2776
- reset: "0",
2777
- }
2826
+ reset: '0',
2827
+ },
2778
2828
  });
2779
2829
  };
2780
2830
  // Usages -------------------------------------------------------------------
@@ -2784,7 +2834,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2784
2834
  const getUsages = async () => {
2785
2835
  const data = await requestDatalayer({
2786
2836
  url: `${configuration.iamRunUrl}/api/iam/v1/usage/user`,
2787
- method: "GET",
2837
+ method: 'GET',
2788
2838
  });
2789
2839
  data.usages = (data.usages ?? []).map(u => asUsage(u));
2790
2840
  return data;
@@ -2795,7 +2845,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2795
2845
  const getUsagesForUser = async (userId) => {
2796
2846
  const data = await requestDatalayer({
2797
2847
  url: `${configuration.iamRunUrl}/api/iam/v1/usage/users/${userId}`,
2798
- method: "GET",
2848
+ method: 'GET',
2799
2849
  });
2800
2850
  data.usages = (data.usages ?? []).map(u => asUsage(u));
2801
2851
  return data;
@@ -2806,7 +2856,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2806
2856
  const getPlatformUsages = async () => {
2807
2857
  const data = await requestDatalayer({
2808
2858
  url: `${configuration.iamRunUrl}/api/iam/v1/usage/platform`,
2809
- method: "GET",
2859
+ method: 'GET',
2810
2860
  });
2811
2861
  data.usages = (data.usages ?? []).map(u => asUsage(u));
2812
2862
  return data;
@@ -2821,7 +2871,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2821
2871
  message,
2822
2872
  email,
2823
2873
  brand,
2824
- }
2874
+ },
2825
2875
  });
2826
2876
  };
2827
2877
  const requestPlatformSupport2 = (accountHandle, firstName, lastName, email, message) => {
@@ -2834,7 +2884,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2834
2884
  lastName,
2835
2885
  email,
2836
2886
  message,
2837
- }
2887
+ },
2838
2888
  });
2839
2889
  };
2840
2890
  // Growth ------------------------------------------------------------------
@@ -2871,6 +2921,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2871
2921
  cloneExercise,
2872
2922
  cloneLesson,
2873
2923
  cloneNotebook,
2924
+ createNotebook,
2874
2925
  confirmCourseItemCompletion,
2875
2926
  confirmEmailUpdate,
2876
2927
  confirmJoinWithToken,
@@ -3093,6 +3144,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
3093
3144
  updateUserSettings,
3094
3145
  validateUserMFACode,
3095
3146
  whoami,
3147
+ notebookUploadLoading,
3148
+ notebookUploadProgress,
3149
+ resetNotebookUpload,
3096
3150
  };
3097
3151
  };
3098
3152
  export default useCache;