Skip to content

Commit 1efc32b

Browse files
author
Yossi Elias (EXT-Nokia)
committed
feat(ws): Notebooks 2.0 // Frontend // Call To Create Workspace
Signed-off-by: Yossi Elias (EXT-Nokia) <yossi.elias.ext@nokia.com>
1 parent e5d4e41 commit 1efc32b

File tree

5 files changed

+114
-3
lines changed

5 files changed

+114
-3
lines changed

workspaces/frontend/src/app/context/useNotebookAPIState.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { APIState } from '~/shared/api/types';
33
import { NotebookAPIs } from '~/app/types';
4-
import { getNamespaces, getWorkspaceKinds } from '~/shared/api/notebookService';
4+
import { getNamespaces, getWorkspaceKinds, createWorkspace } from '~/shared/api/notebookService';
55
import useAPIState from '~/shared/api/useAPIState';
66

77
export type NotebookAPIState = APIState<NotebookAPIs>;
@@ -13,6 +13,7 @@ const useNotebookAPIState = (
1313
(path: string) => ({
1414
getNamespaces: getNamespaces(path),
1515
getWorkspaceKinds: getWorkspaceKinds(path),
16+
createWorkspace: createWorkspace(path),
1617
}),
1718
[],
1819
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as React from 'react';
2+
import useFetchState, {
3+
FetchState,
4+
FetchStateCallbackPromise,
5+
} from '~/shared/utilities/useFetchState';
6+
import { CreateWorkspaceData } from '~/app/types';
7+
import { useNotebookAPI } from '~/app/hooks/useNotebookAPI';
8+
import { Workspace } from '~/shared/types';
9+
import { createWorkspaceCall } from '~/app/pages/Workspaces/utils';
10+
import { APIOptions } from '~/shared/api/types';
11+
12+
const useCreateWorkspace = (namespace: string, formData: CreateWorkspaceData):
13+
FetchState<Workspace | null> => {
14+
const { api, apiAvailable } = useNotebookAPI();
15+
16+
const call = React.useCallback<FetchStateCallbackPromise<Workspace | null>>(
17+
(opts: APIOptions) => {
18+
if (!apiAvailable) {
19+
return Promise.reject(new Error('API not yet available'));
20+
}
21+
if (!namespace) {
22+
return Promise.reject(new Error('namespace is not available yet'));
23+
}
24+
if (!formData) {
25+
return Promise.reject(new Error('formData is not available yet'));
26+
}
27+
return createWorkspaceCall(opts, api, namespace, formData).then(
28+
(result) => result.workspace
29+
);
30+
},
31+
[api, apiAvailable, namespace, formData],
32+
);
33+
34+
return useFetchState(call, null);
35+
};
36+
37+
export default useCreateWorkspace;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Workspace } from '~/shared/types';
2+
import { CreateWorkspaceData } from '~/app/types';
3+
import { NotebookAPIState } from '~/app/context/useNotebookAPIState';
4+
import { APIOptions } from '~/shared/api/types';
5+
6+
export type RegisterWorkspaceCreatedResources = {
7+
workspace: Workspace;
8+
};
9+
10+
export const createWorkspaceCall = async (
11+
opts: APIOptions,
12+
api: NotebookAPIState['api'],
13+
namespace: string,
14+
formData: CreateWorkspaceData,
15+
): Promise<RegisterWorkspaceCreatedResources> => {
16+
const workspace = await api.createWorkspace(
17+
opts,
18+
namespace,
19+
formData,
20+
);
21+
return { workspace };
22+
};

workspaces/frontend/src/app/types.ts

+32
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,39 @@ export type GetNamespaces = (opts: APIOptions) => Promise<NamespacesList>;
6767

6868
export type GetWorkspaceKinds = (opts: APIOptions) => Promise<WorkspaceKind[]>;
6969

70+
export type CreateWorkspace = (opts: APIOptions, namespace: string, data: CreateWorkspaceData) => Promise<Workspace>;
71+
7072
export type NotebookAPIs = {
7173
getNamespaces: GetNamespaces;
7274
getWorkspaceKinds: GetWorkspaceKinds;
75+
createWorkspace: CreateWorkspace;
76+
};
77+
78+
export type PodTemplate = {
79+
pod_metadata: {
80+
labels: Record<string, string>;
81+
annotations: Record<string, string>;
82+
};
83+
volumes: {
84+
home: string;
85+
data: {
86+
pvc_name: string;
87+
mount_path: string;
88+
read_only: boolean;
89+
}[];
90+
};
91+
options: {
92+
image_config: string;
93+
pod_config: string;
94+
};
7395
};
96+
97+
export type CreateWorkspaceData = {
98+
data: {
99+
name: string;
100+
kind: string;
101+
paused: boolean;
102+
defer_updates: boolean;
103+
pod_template: PodTemplate;
104+
};
105+
};

workspaces/frontend/src/shared/api/notebookService.ts

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { NamespacesList } from '~/app/types';
2-
import { isNotebookResponse, restGET } from '~/shared/api/apiUtils';
2+
import { isNotebookResponse, restGET, restCREATE } from '~/shared/api/apiUtils';
33
import { APIOptions } from '~/shared/api/types';
44
import { handleRestFailures } from '~/shared/api/errorUtils';
5-
import { WorkspaceKind } from '~/shared/types';
5+
import { Workspace, WorkspaceKind } from '~/shared/types';
6+
import { CreateWorkspaceData } from '~/app/types';
7+
68

79
export const getNamespaces =
810
(hostPath: string) =>
@@ -23,3 +25,20 @@ export const getWorkspaceKinds =
2325
}
2426
throw new Error('Invalid response format');
2527
});
28+
29+
export const createWorkspace =
30+
(hostPath: string) =>
31+
(opts: APIOptions, namespace: string = "" , data: CreateWorkspaceData): Promise<Workspace> =>
32+
handleRestFailures(
33+
restCREATE(
34+
hostPath,
35+
`/workspaces/${namespace}`,
36+
data,
37+
opts,
38+
),
39+
).then((response) => {
40+
if (isNotebookResponse<Workspace>(response)) {
41+
return response.data;
42+
}
43+
throw new Error('Invalid response format');
44+
});

0 commit comments

Comments
 (0)