diff --git a/workspaces/frontend/src/app/pages/WorkspaceKinds/Form/WorkspaceKindForm.tsx b/workspaces/frontend/src/app/pages/WorkspaceKinds/Form/WorkspaceKindForm.tsx index 0972c68d..d99bdb8e 100644 --- a/workspaces/frontend/src/app/pages/WorkspaceKinds/Form/WorkspaceKindForm.tsx +++ b/workspaces/frontend/src/app/pages/WorkspaceKinds/Form/WorkspaceKindForm.tsx @@ -80,7 +80,7 @@ export const WorkspaceKindForm: React.FC = () => { // TODO: Complete handleCreate with API call to create a new WS kind try { if (mode === 'create') { - const newWorkspaceKind = await api.createWorkspaceKind({}, yamlValue); + const newWorkspaceKind = await api.createWorkspaceKind({ directYAML: true }, yamlValue); // TODO: alert user about success console.info('New workspace kind created:', JSON.stringify(newWorkspaceKind)); navigate('workspaceKinds'); diff --git a/workspaces/frontend/src/shared/api/apiUtils.ts b/workspaces/frontend/src/shared/api/apiUtils.ts index 8930f0dd..09c925e8 100644 --- a/workspaces/frontend/src/shared/api/apiUtils.ts +++ b/workspaces/frontend/src/shared/api/apiUtils.ts @@ -19,6 +19,7 @@ export const mergeRequestInit = ( type CallRestJSONOptions = { queryParams?: Record; parseJSON?: boolean; + directYAML?: boolean; } & EitherOrNone< { fileContents: string; @@ -32,7 +33,7 @@ const callRestJSON = ( host: string, path: string, requestInit: RequestInit, - { data, fileContents, queryParams, parseJSON = true }: CallRestJSONOptions, + { data, fileContents, queryParams, parseJSON = true, directYAML = false }: CallRestJSONOptions, ): Promise => { const { method, ...otherOptions } = requestInit; @@ -54,12 +55,17 @@ const callRestJSON = ( let contentType: string | undefined; let formData: FormData | undefined; if (fileContents) { - formData = new FormData(); - formData.append( - 'uploadfile', - new Blob([fileContents], { type: 'application/x-yaml' }), - 'uploadedFile.yml', - ); + if (directYAML) { + requestData = fileContents; + contentType = 'application/yaml'; + } else { + formData = new FormData(); + formData.append( + 'uploadfile', + new Blob([fileContents], { type: 'application/x-yaml' }), + 'uploadedFile.yml', + ); + } } else if (data) { // It's OK for contentType and requestData to BOTH be undefined for e.g. a GET request or POST with no body. contentType = 'application/json;charset=UTF-8'; @@ -122,6 +128,7 @@ export const restFILE = ( fileContents, queryParams, parseJSON: options?.parseJSON, + directYAML: options?.directYAML, }); /** POST -- but no body data -- targets simple endpoints */ @@ -173,48 +180,6 @@ export const restDELETE = ( parseJSON: options?.parseJSON, }); -/** POST -- but with YAML content directly in body */ -export const restYAML = ( - host: string, - path: string, - yamlContent: string, - queryParams?: Record, - options?: APIOptions, -): Promise => { - const { method, ...otherOptions } = mergeRequestInit(options, { method: 'POST' }); - - const sanitizedQueryParams = queryParams - ? Object.entries(queryParams).reduce((acc, [key, value]) => { - if (value) { - return { ...acc, [key]: value }; - } - return acc; - }, {}) - : null; - - const searchParams = sanitizedQueryParams - ? new URLSearchParams(sanitizedQueryParams).toString() - : null; - - return fetch(`${host}${path}${searchParams ? `?${searchParams}` : ''}`, { - ...otherOptions, - headers: { - ...otherOptions.headers, - ...(DEV_MODE && { [AUTH_HEADER]: localStorage.getItem(AUTH_HEADER) }), - 'Content-Type': 'application/vnd.kubeflow-notebooks.manifest+yaml', - }, - method, - body: yamlContent, - }).then((response) => - response.text().then((fetchedData) => { - if (options?.parseJSON !== false) { - return JSON.parse(fetchedData); - } - return fetchedData; - }), - ); -}; - export const isNotebookResponse = (response: unknown): response is ResponseBody => { if (typeof response === 'object' && response !== null) { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions diff --git a/workspaces/frontend/src/shared/api/notebookService.ts b/workspaces/frontend/src/shared/api/notebookService.ts index 5cdd91bb..8bdaeccc 100644 --- a/workspaces/frontend/src/shared/api/notebookService.ts +++ b/workspaces/frontend/src/shared/api/notebookService.ts @@ -1,10 +1,10 @@ import { restCREATE, restDELETE, + restFILE, restGET, restPATCH, restUPDATE, - restYAML, wrapRequest, } from '~/shared/api/apiUtils'; import { @@ -72,7 +72,7 @@ export const getWorkspaceKind: GetWorkspaceKindAPI = (hostPath) => (opts, kind) wrapRequest(restGET(hostPath, `/workspacekinds/${kind}`, {}, opts)); export const createWorkspaceKind: CreateWorkspaceKindAPI = (hostPath) => (opts, data) => - wrapRequest(restYAML(hostPath, `/workspacekinds`, data, {}, opts)); + wrapRequest(restFILE(hostPath, `/workspacekinds`, data, {}, opts)); export const updateWorkspaceKind: UpdateWorkspaceKindAPI = (hostPath) => (opts, kind, data) => wrapRequest(restUPDATE(hostPath, `/workspacekinds/${kind}`, data, {}, opts)); diff --git a/workspaces/frontend/src/shared/api/types.ts b/workspaces/frontend/src/shared/api/types.ts index 71389f36..7c2bad1a 100644 --- a/workspaces/frontend/src/shared/api/types.ts +++ b/workspaces/frontend/src/shared/api/types.ts @@ -3,6 +3,7 @@ export type APIOptions = { signal?: AbortSignal; parseJSON?: boolean; headers?: Record; + directYAML?: boolean; }; export type APIState = {