Skip to content

Commit 744c3bb

Browse files
YosiEliasYossi Elias (EXT-Nokia)caponettosenanz
authored
feat(ws): add frontend hooks to call create WS backend (#217)
* feat(ws): Notebooks 2.0 // Frontend // Call To Create Workspace Signed-off-by: Yossi Elias (EXT-Nokia) <[email protected]> * Create types for WorkspacePodTemplate and adjust camelCase leftovers Signed-off-by: Guilherme Caponetto <[email protected]> --------- Signed-off-by: Yossi Elias (EXT-Nokia) <[email protected]> Signed-off-by: Guilherme Caponetto <[email protected]> Co-authored-by: Yossi Elias (EXT-Nokia) <[email protected]> Co-authored-by: Guilherme Caponetto <[email protected]> Co-authored-by: senanz <[email protected]>
1 parent 6123650 commit 744c3bb

File tree

6 files changed

+114
-5
lines changed

6 files changed

+114
-5
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,34 @@
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 = (
13+
namespace: string,
14+
formData: CreateWorkspaceData,
15+
): FetchState<Workspace | null> => {
16+
const { api, apiAvailable } = useNotebookAPI();
17+
18+
const call = React.useCallback<FetchStateCallbackPromise<Workspace | null>>(
19+
(opts: APIOptions) => {
20+
if (!apiAvailable) {
21+
return Promise.reject(new Error('API not yet available'));
22+
}
23+
if (!namespace) {
24+
return Promise.reject(new Error('namespace is not available yet'));
25+
}
26+
return createWorkspaceCall(opts, api, formData, namespace).then((result) => result.workspace);
27+
},
28+
[api, apiAvailable, namespace, formData],
29+
);
30+
31+
return useFetchState(call, null);
32+
};
33+
34+
export default useCreateWorkspace;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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+
formData: CreateWorkspaceData,
14+
namespace: string,
15+
): Promise<RegisterWorkspaceCreatedResources> => {
16+
const workspace = await api.createWorkspace(opts, formData, namespace);
17+
return { workspace };
18+
};

workspaces/frontend/src/app/types.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { APIOptions } from '~/shared/api/types';
2-
import { WorkspaceKind } from '~/shared/types';
2+
import { Workspace, WorkspaceKind, WorkspacePodTemplateMutate } from '~/shared/types';
33

44
export type ResponseBody<T> = {
55
data: T;
@@ -67,7 +67,24 @@ export type GetNamespaces = (opts: APIOptions) => Promise<NamespacesList>;
6767

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

70+
export type CreateWorkspace = (
71+
opts: APIOptions,
72+
data: CreateWorkspaceData,
73+
namespace: string,
74+
) => Promise<Workspace>;
75+
7076
export type NotebookAPIs = {
7177
getNamespaces: GetNamespaces;
7278
getWorkspaceKinds: GetWorkspaceKinds;
79+
createWorkspace: CreateWorkspace;
80+
};
81+
82+
export type CreateWorkspaceData = {
83+
data: {
84+
name: string;
85+
kind: string;
86+
paused: boolean;
87+
deferUpdates: boolean;
88+
podTemplate: WorkspacePodTemplateMutate;
89+
};
7390
};

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

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { NamespacesList } from '~/app/types';
2-
import { isNotebookResponse, restGET } from '~/shared/api/apiUtils';
1+
import { NamespacesList, CreateWorkspaceData } from '~/app/types';
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';
66

77
export const getNamespaces =
88
(hostPath: string) =>
@@ -23,3 +23,15 @@ export const getWorkspaceKinds =
2323
}
2424
throw new Error('Invalid response format');
2525
});
26+
27+
export const createWorkspace =
28+
(hostPath: string) =>
29+
(opts: APIOptions, data: CreateWorkspaceData, namespace = ''): Promise<Workspace> =>
30+
handleRestFailures(restCREATE(hostPath, `/workspaces/${namespace}`, data, opts)).then(
31+
(response) => {
32+
if (isNotebookResponse<Workspace>(response)) {
33+
return response.data;
34+
}
35+
throw new Error('Invalid response format');
36+
},
37+
);

workspaces/frontend/src/shared/types.ts

+27
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,33 @@ export interface WorkspaceStatus {
9393
stateMessage: string;
9494
}
9595

96+
export interface WorkspacePodMetadataMutate {
97+
labels: Record<string, string>;
98+
annotations: Record<string, string>;
99+
}
100+
101+
export interface WorkspacePodVolumeMount {
102+
pvcName: string;
103+
mountPath: string;
104+
readOnly?: boolean;
105+
}
106+
107+
export interface WorkspacePodVolumesMutate {
108+
home?: string;
109+
data: WorkspacePodVolumeMount[];
110+
}
111+
112+
export interface WorkspacePodTemplateOptionsMutate {
113+
imageConfig: string;
114+
podConfig: string;
115+
}
116+
117+
export interface WorkspacePodTemplateMutate {
118+
podMetadata: WorkspacePodMetadataMutate;
119+
volumes: WorkspacePodVolumesMutate;
120+
options: WorkspacePodTemplateOptionsMutate;
121+
}
122+
96123
export interface Workspace {
97124
name: string;
98125
namespace: string;

0 commit comments

Comments
 (0)