From 226cd21804bb91d58e7eb971eeb969a728db6fd1 Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Thu, 7 Mar 2024 18:04:45 +0800 Subject: [PATCH 1/7] feat: add comment Signed-off-by: SuZhou-Joe --- .../workspace/public/workspace_client.mock.ts | 25 ++ .../workspace/public/workspace_client.test.ts | 181 ++++++++++++ .../workspace/public/workspace_client.ts | 275 ++++++++++++++++++ 3 files changed, 481 insertions(+) create mode 100644 src/plugins/workspace/public/workspace_client.mock.ts create mode 100644 src/plugins/workspace/public/workspace_client.test.ts create mode 100644 src/plugins/workspace/public/workspace_client.ts diff --git a/src/plugins/workspace/public/workspace_client.mock.ts b/src/plugins/workspace/public/workspace_client.mock.ts new file mode 100644 index 000000000000..2ceeae5627d1 --- /dev/null +++ b/src/plugins/workspace/public/workspace_client.mock.ts @@ -0,0 +1,25 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export const workspaceClientMock = { + init: jest.fn(), + enterWorkspace: jest.fn(), + getCurrentWorkspaceId: jest.fn(), + getCurrentWorkspace: jest.fn(), + create: jest.fn(), + delete: jest.fn(), + list: jest.fn(), + get: jest.fn(), + update: jest.fn(), + stop: jest.fn(), +}; + +export const WorkspaceClientMock = jest.fn(function () { + return workspaceClientMock; +}); + +jest.doMock('./workspace_client', () => ({ + WorkspaceClient: WorkspaceClientMock, +})); diff --git a/src/plugins/workspace/public/workspace_client.test.ts b/src/plugins/workspace/public/workspace_client.test.ts new file mode 100644 index 000000000000..7d05c3f22458 --- /dev/null +++ b/src/plugins/workspace/public/workspace_client.test.ts @@ -0,0 +1,181 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { httpServiceMock, workspacesServiceMock } from '../../../core/public/mocks'; +import { WorkspaceClient } from './workspace_client'; + +const getWorkspaceClient = () => { + const httpSetupMock = httpServiceMock.createSetupContract(); + const workspaceMock = workspacesServiceMock.createSetupContract(); + return { + httpSetupMock, + workspaceMock, + workspaceClient: new WorkspaceClient(httpSetupMock, workspaceMock), + }; +}; + +describe('#WorkspaceClient', () => { + it('#init', async () => { + const { workspaceClient, httpSetupMock, workspaceMock } = getWorkspaceClient(); + await workspaceClient.init(); + expect(workspaceMock.initialized$.getValue()).toEqual(true); + expect(httpSetupMock.fetch).toBeCalledWith('/api/workspaces/_list', { + method: 'POST', + body: JSON.stringify({ + perPage: 999, + }), + }); + }); + + it('#enterWorkspace', async () => { + const { workspaceClient, httpSetupMock, workspaceMock } = getWorkspaceClient(); + httpSetupMock.fetch.mockResolvedValue({ + success: false, + }); + const result = await workspaceClient.enterWorkspace('foo'); + expect(result.success).toEqual(false); + httpSetupMock.fetch.mockResolvedValue({ + success: true, + }); + const successResult = await workspaceClient.enterWorkspace('foo'); + expect(workspaceMock.currentWorkspaceId$.getValue()).toEqual('foo'); + expect(httpSetupMock.fetch).toBeCalledWith('/api/workspaces/foo', { + method: 'GET', + }); + expect(successResult.success).toEqual(true); + }); + + it('#getCurrentWorkspaceId', async () => { + const { workspaceClient, httpSetupMock } = getWorkspaceClient(); + httpSetupMock.fetch.mockResolvedValue({ + success: true, + }); + await workspaceClient.enterWorkspace('foo'); + expect(await workspaceClient.getCurrentWorkspaceId()).toEqual({ + success: true, + result: 'foo', + }); + }); + + it('#getCurrentWorkspace', async () => { + const { workspaceClient, httpSetupMock } = getWorkspaceClient(); + httpSetupMock.fetch.mockResolvedValue({ + success: true, + result: { + name: 'foo', + }, + }); + await workspaceClient.enterWorkspace('foo'); + expect(await workspaceClient.getCurrentWorkspace()).toEqual({ + success: true, + result: { + name: 'foo', + }, + }); + }); + + it('#create', async () => { + const { workspaceClient, httpSetupMock } = getWorkspaceClient(); + httpSetupMock.fetch.mockResolvedValue({ + success: true, + result: { + name: 'foo', + workspaces: [], + }, + }); + await workspaceClient.create({ + name: 'foo', + }); + expect(httpSetupMock.fetch).toBeCalledWith('/api/workspaces', { + method: 'POST', + body: JSON.stringify({ + attributes: { + name: 'foo', + }, + }), + }); + expect(httpSetupMock.fetch).toBeCalledWith('/api/workspaces/_list', { + method: 'POST', + body: JSON.stringify({ + perPage: 999, + }), + }); + }); + + it('#delete', async () => { + const { workspaceClient, httpSetupMock } = getWorkspaceClient(); + httpSetupMock.fetch.mockResolvedValue({ + success: true, + result: { + name: 'foo', + workspaces: [], + }, + }); + await workspaceClient.delete('foo'); + expect(httpSetupMock.fetch).toBeCalledWith('/api/workspaces/foo', { + method: 'DELETE', + }); + expect(httpSetupMock.fetch).toBeCalledWith('/api/workspaces/_list', { + method: 'POST', + body: JSON.stringify({ + perPage: 999, + }), + }); + }); + + it('#list', async () => { + const { workspaceClient, httpSetupMock } = getWorkspaceClient(); + httpSetupMock.fetch.mockResolvedValue({ + success: true, + result: { + workspaces: [], + }, + }); + await workspaceClient.list({ + perPage: 999, + }); + expect(httpSetupMock.fetch).toBeCalledWith('/api/workspaces/_list', { + method: 'POST', + body: JSON.stringify({ + perPage: 999, + }), + }); + }); + + it('#get', async () => { + const { workspaceClient, httpSetupMock } = getWorkspaceClient(); + await workspaceClient.get('foo'); + expect(httpSetupMock.fetch).toBeCalledWith('/api/workspaces/foo', { + method: 'GET', + }); + }); + + it('#update', async () => { + const { workspaceClient, httpSetupMock } = getWorkspaceClient(); + httpSetupMock.fetch.mockResolvedValue({ + success: true, + result: { + workspaces: [], + }, + }); + await workspaceClient.update('foo', { + name: 'foo', + }); + expect(httpSetupMock.fetch).toBeCalledWith('/api/workspaces/foo', { + method: 'PUT', + body: JSON.stringify({ + attributes: { + name: 'foo', + }, + }), + }); + expect(httpSetupMock.fetch).toBeCalledWith('/api/workspaces/_list', { + method: 'POST', + body: JSON.stringify({ + perPage: 999, + }), + }); + }); +}); diff --git a/src/plugins/workspace/public/workspace_client.ts b/src/plugins/workspace/public/workspace_client.ts new file mode 100644 index 000000000000..a3985234d1ad --- /dev/null +++ b/src/plugins/workspace/public/workspace_client.ts @@ -0,0 +1,275 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + HttpFetchError, + HttpFetchOptions, + HttpSetup, + WorkspaceAttribute, + WorkspacesSetup, +} from '../../../core/public'; + +const WORKSPACES_API_BASE_URL = '/api/workspaces'; + +const join = (...uriComponents: Array) => + uriComponents + .filter((comp): comp is string => Boolean(comp)) + .map(encodeURIComponent) + .join('/'); + +type IResponse = + | { + result: T; + success: true; + } + | { + success: false; + error?: string; + }; + +interface WorkspaceFindOptions { + page?: number; + perPage?: number; + search?: string; + searchFields?: string[]; + sortField?: string; + sortOrder?: string; +} + +/** + * Workspaces is OpenSearchDashboards's visualize mechanism allowing admins to + * organize related features + * + * @public + */ +export class WorkspaceClient { + private http: HttpSetup; + private workspaces: WorkspacesSetup; + + constructor(http: HttpSetup, workspaces: WorkspacesSetup) { + this.http = http; + this.workspaces = workspaces; + } + + /** + * Initialize workspace list + */ + public async init() { + await this.updateWorkspaceList(); + this.workspaces.initialized$.next(true); + } + + /** + * Add a non-throw-error fetch method for internal use. + */ + private safeFetch = async ( + path: string, + options: HttpFetchOptions + ): Promise> => { + try { + return await this.http.fetch>(path, options); + } catch (error: unknown) { + if (error instanceof HttpFetchError) { + return { + success: false, + error: error.body?.message || error.body?.error || error.message, + }; + } + + if (error instanceof Error) { + return { + success: false, + error: error.message, + }; + } + + return { + success: false, + error: 'Unknown error', + }; + } + }; + + private getPath(...path: Array): string { + return [WORKSPACES_API_BASE_URL, join(...path)].filter((item) => item).join('/'); + } + + /** + * Fetch latest list of workspaces and update workspaceList$ to notify subscriptions + */ + private async updateWorkspaceList(): Promise { + const result = await this.list({ + perPage: 999, + }); + + if (result?.success) { + this.workspaces.workspaceList$.next(result.result.workspaces); + } + } + + /** + * Check if provided workspace id exists, + * update the currentWorkspaceId$ if it exists. + */ + public async enterWorkspace(id: string): Promise> { + const workspaceResp = await this.get(id); + if (workspaceResp.success) { + this.workspaces.currentWorkspaceId$.next(id); + return { + success: true, + result: null, + }; + } else { + return workspaceResp; + } + } + + /** + * A bypass layer to get current workspace id + */ + public async getCurrentWorkspaceId(): Promise> { + const currentWorkspaceId = this.workspaces.currentWorkspaceId$.getValue(); + if (!currentWorkspaceId) { + return { + success: false, + error: 'You are not in any workspace yet.', + }; + } + + return { + success: true, + result: currentWorkspaceId, + }; + } + + /** + * Do a find in the latest workspace list with current workspace id + */ + public async getCurrentWorkspace(): Promise> { + const currentWorkspaceIdResp = await this.getCurrentWorkspaceId(); + if (currentWorkspaceIdResp.success) { + const currentWorkspaceResp = await this.get(currentWorkspaceIdResp.result); + return currentWorkspaceResp; + } else { + return currentWorkspaceIdResp; + } + } + + /** + * Create an workspace + * + * @param attributes + * @returns + */ + public async create( + attributes: Omit + ): Promise> { + const path = this.getPath(); + + const result = await this.safeFetch(path, { + method: 'POST', + body: JSON.stringify({ + attributes, + }), + }); + + if (result.success) { + await this.updateWorkspaceList(); + } + + return result; + } + + /** + * Deletes a workspace by workspace id + * + * @param id + * @returns + */ + public async delete(id: string): Promise> { + const result = await this.safeFetch(this.getPath(id), { method: 'DELETE' }); + + if (result.success) { + await this.updateWorkspaceList(); + } + + return result; + } + + /** + * Search for workspaces + * + * @param {object} [options={}] + * @property {string} options.search + * @property {string} options.searchFields - see OpenSearch Simple Query String + * Query field argument for more information + * @property {integer} [options.page=1] + * @property {integer} [options.perPage=20] + * @property {array} options.fields + * @returns A find result with workspaces matching the specified search. + */ + public list( + options?: WorkspaceFindOptions + ): Promise< + IResponse<{ + workspaces: WorkspaceAttribute[]; + total: number; + per_page: number; + page: number; + }> + > { + const path = this.getPath('_list'); + return this.safeFetch(path, { + method: 'POST', + body: JSON.stringify(options || {}), + }); + } + + /** + * Fetches a single workspace by a workspace id + * + * @param {string} id + * @returns The workspace for the given id. + */ + public get(id: string): Promise> { + const path = this.getPath(id); + return this.safeFetch(path, { + method: 'GET', + }); + } + + /** + * Updates a workspace + * + * @param {string} id + * @param {object} attributes + * @returns + */ + public async update( + id: string, + attributes: Partial + ): Promise> { + const path = this.getPath(id); + const body = { + attributes, + }; + + const result = await this.safeFetch(path, { + method: 'PUT', + body: JSON.stringify(body), + }); + + if (result.success) { + await this.updateWorkspaceList(); + } + + return result; + } + + public stop() { + this.workspaces.workspaceList$.unsubscribe(); + this.workspaces.currentWorkspaceId$.unsubscribe(); + } +} From 39724888b43878a85ce9ed88586046d5155df94d Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Fri, 8 Mar 2024 10:18:12 +0800 Subject: [PATCH 2/7] feat: update unit test Signed-off-by: SuZhou-Joe --- src/plugins/workspace/public/plugin.test.ts | 18 +++++++++++++++++- src/plugins/workspace/public/plugin.ts | 7 +++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/plugins/workspace/public/plugin.test.ts b/src/plugins/workspace/public/plugin.test.ts index e1a45ee115ab..8c869415aede 100644 --- a/src/plugins/workspace/public/plugin.test.ts +++ b/src/plugins/workspace/public/plugin.test.ts @@ -3,10 +3,26 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { coreMock } from '../../../core/public/mocks'; +import { workspaceClientMock, WorkspaceClientMock } from './workspace_client.mock'; +import { chromeServiceMock, coreMock } from '../../../core/public/mocks'; import { WorkspacePlugin } from './plugin'; describe('Workspace plugin', () => { + const getSetupMock = () => ({ + ...coreMock.createSetup(), + chrome: chromeServiceMock.createSetupContract(), + }); + beforeEach(() => { + WorkspaceClientMock.mockClear(); + Object.values(workspaceClientMock).forEach((item) => item.mockClear()); + }); + it('#setup', async () => { + const setupMock = getSetupMock(); + const workspacePlugin = new WorkspacePlugin(); + await workspacePlugin.setup(setupMock); + expect(WorkspaceClientMock).toBeCalledTimes(1); + }); + it('#call savedObjectsClient.setCurrentWorkspace when current workspace id changed', () => { const workspacePlugin = new WorkspacePlugin(); const coreStart = coreMock.createStart(); diff --git a/src/plugins/workspace/public/plugin.ts b/src/plugins/workspace/public/plugin.ts index 3840066fcee3..6f604bcf5678 100644 --- a/src/plugins/workspace/public/plugin.ts +++ b/src/plugins/workspace/public/plugin.ts @@ -4,7 +4,8 @@ */ import type { Subscription } from 'rxjs'; -import { Plugin, CoreStart } from '../../../core/public'; +import { Plugin, CoreStart, CoreSetup } from '../../../core/public'; +import { WorkspaceClient } from './workspace_client'; export class WorkspacePlugin implements Plugin<{}, {}, {}> { private coreStart?: CoreStart; @@ -18,7 +19,9 @@ export class WorkspacePlugin implements Plugin<{}, {}, {}> { }); } } - public async setup() { + public async setup(core: CoreSetup) { + const workspaceClient = new WorkspaceClient(core.http, core.workspaces); + await workspaceClient.init(); return {}; } From ae2af7036d0c866d1d53814adfe7d2894a5161cd Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Fri, 8 Mar 2024 10:27:07 +0800 Subject: [PATCH 3/7] feat: add CHANGELOG Signed-off-by: SuZhou-Joe --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9bba980268a..2f5d5ee061f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,8 +32,8 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - [Multiple Datasource] Test connection schema validation for registered auth types ([#6109](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6109)) - [Workspace] Consume workspace id in saved object client ([#6014](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6014)) - [Multiple Datasource] Export DataSourcePluginRequestContext at top level for plugins to use ([#6108](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6108)) - - [Workspace] Add delete saved objects by workspace functionality([#6013](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6013)) +- [Workspace] Add a workspace client in workspace plugin ([#6094](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6094)) ### 🐛 Bug Fixes From 03bacb6d7eb97ff2ad13cfa3482a7377a4b78bd8 Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Sat, 9 Mar 2024 08:21:30 +0800 Subject: [PATCH 4/7] feat: optimize comment Signed-off-by: SuZhou-Joe --- src/plugins/workspace/public/workspace_client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/workspace/public/workspace_client.ts b/src/plugins/workspace/public/workspace_client.ts index a3985234d1ad..26b9cf7cbb8b 100644 --- a/src/plugins/workspace/public/workspace_client.ts +++ b/src/plugins/workspace/public/workspace_client.ts @@ -158,7 +158,7 @@ export class WorkspaceClient { } /** - * Create an workspace + * Create a workspace * * @param attributes * @returns From 43e00f4c4f0e975e14914b476e001b2a7160808d Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Sat, 9 Mar 2024 08:52:24 +0800 Subject: [PATCH 5/7] feat: optimize comment Signed-off-by: SuZhou-Joe --- .../workspace/public/workspace_client.ts | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/plugins/workspace/public/workspace_client.ts b/src/plugins/workspace/public/workspace_client.ts index 26b9cf7cbb8b..fb633cb16906 100644 --- a/src/plugins/workspace/public/workspace_client.ts +++ b/src/plugins/workspace/public/workspace_client.ts @@ -54,7 +54,9 @@ export class WorkspaceClient { } /** - * Initialize workspace list + * Initialize workspace list: + * 1. Retrieve the list of workspaces + * 2. Change the initialized flag to true */ public async init() { await this.updateWorkspaceList(); @@ -62,7 +64,10 @@ export class WorkspaceClient { } /** - * Add a non-throw-error fetch method for internal use. + * Add a non-throw-error fetch method, + * so that consumers only need to care about + * if the success is false instead of wrapping the call with a try catch + * and judge the error both in catch clause and if(!success) cluase. */ private safeFetch = async ( path: string, @@ -92,6 +97,12 @@ export class WorkspaceClient { } }; + /** + * Filter empty sub path and join all of the sub paths into a standard http path + * + * @param path + * @returns path + */ private getPath(...path: Array): string { return [WORKSPACES_API_BASE_URL, join(...path)].filter((item) => item).join('/'); } @@ -110,8 +121,11 @@ export class WorkspaceClient { } /** - * Check if provided workspace id exists, - * update the currentWorkspaceId$ if it exists. + * This method will check if a valid workspace can be found by the given workspace id, + * If so, perform a side effect of updating the core.workspace.currentWorkspaceId$. + * + * @param id workspace id + * @returns {Promise>} result for this operation */ public async enterWorkspace(id: string): Promise> { const workspaceResp = await this.get(id); @@ -161,11 +175,11 @@ export class WorkspaceClient { * Create a workspace * * @param attributes - * @returns + * @returns {Promise>>} id of the new created workspace */ public async create( attributes: Omit - ): Promise> { + ): Promise>> { const path = this.getPath(); const result = await this.safeFetch(path, { @@ -186,7 +200,7 @@ export class WorkspaceClient { * Deletes a workspace by workspace id * * @param id - * @returns + * @returns {Promise>} result for this operation */ public async delete(id: string): Promise> { const result = await this.safeFetch(this.getPath(id), { method: 'DELETE' }); @@ -231,7 +245,7 @@ export class WorkspaceClient { * Fetches a single workspace by a workspace id * * @param {string} id - * @returns The workspace for the given id. + * @returns {Promise>} The metadata of the workspace for the given id. */ public get(id: string): Promise> { const path = this.getPath(id); @@ -245,7 +259,7 @@ export class WorkspaceClient { * * @param {string} id * @param {object} attributes - * @returns + * @returns {Promise>} result for this operation */ public async update( id: string, From 9abb9c30175c0986ed0019a45e891cc3f756fc80 Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Sat, 9 Mar 2024 09:06:38 +0800 Subject: [PATCH 6/7] feat: optimize code Signed-off-by: SuZhou-Joe --- .../workspace/public/workspace_client.test.ts | 35 +++++++++++++++++-- .../workspace/public/workspace_client.ts | 2 ++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/plugins/workspace/public/workspace_client.test.ts b/src/plugins/workspace/public/workspace_client.test.ts index 7d05c3f22458..ef5ba154e94f 100644 --- a/src/plugins/workspace/public/workspace_client.test.ts +++ b/src/plugins/workspace/public/workspace_client.test.ts @@ -153,11 +153,15 @@ describe('#WorkspaceClient', () => { }); it('#update', async () => { - const { workspaceClient, httpSetupMock } = getWorkspaceClient(); + const { workspaceClient, httpSetupMock, workspaceMock } = getWorkspaceClient(); httpSetupMock.fetch.mockResolvedValue({ success: true, result: { - workspaces: [], + workspaces: [ + { + id: 'foo', + }, + ], }, }); await workspaceClient.update('foo', { @@ -171,6 +175,11 @@ describe('#WorkspaceClient', () => { }, }), }); + expect(workspaceMock.workspaceList$.getValue()).toEqual([ + { + id: 'foo', + }, + ]); expect(httpSetupMock.fetch).toBeCalledWith('/api/workspaces/_list', { method: 'POST', body: JSON.stringify({ @@ -178,4 +187,26 @@ describe('#WorkspaceClient', () => { }), }); }); + + it('#update with list gives error', async () => { + const { workspaceClient, httpSetupMock, workspaceMock } = getWorkspaceClient(); + let callTimes = 0; + httpSetupMock.fetch.mockImplementation(async () => { + callTimes++; + if (callTimes > 1) { + return { + success: false, + error: 'Something went wrong', + }; + } + + return { + success: true, + }; + }); + await workspaceClient.update('foo', { + name: 'foo', + }); + expect(workspaceMock.workspaceList$.getValue()).toEqual([]); + }); }); diff --git a/src/plugins/workspace/public/workspace_client.ts b/src/plugins/workspace/public/workspace_client.ts index fb633cb16906..31a7545db023 100644 --- a/src/plugins/workspace/public/workspace_client.ts +++ b/src/plugins/workspace/public/workspace_client.ts @@ -117,6 +117,8 @@ export class WorkspaceClient { if (result?.success) { this.workspaces.workspaceList$.next(result.result.workspaces); + } else { + this.workspaces.workspaceList$.next([]); } } From 65fc363651f492f1644b26efb6af15987dbec762 Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Mon, 11 Mar 2024 18:58:57 +0800 Subject: [PATCH 7/7] feat: optimize code Signed-off-by: SuZhou-Joe --- src/plugins/workspace/public/workspace_client.test.ts | 2 +- src/plugins/workspace/public/workspace_client.ts | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/plugins/workspace/public/workspace_client.test.ts b/src/plugins/workspace/public/workspace_client.test.ts index ef5ba154e94f..c18ed3db64e7 100644 --- a/src/plugins/workspace/public/workspace_client.test.ts +++ b/src/plugins/workspace/public/workspace_client.test.ts @@ -53,7 +53,7 @@ describe('#WorkspaceClient', () => { success: true, }); await workspaceClient.enterWorkspace('foo'); - expect(await workspaceClient.getCurrentWorkspaceId()).toEqual({ + expect(workspaceClient.getCurrentWorkspaceId()).toEqual({ success: true, result: 'foo', }); diff --git a/src/plugins/workspace/public/workspace_client.ts b/src/plugins/workspace/public/workspace_client.ts index 31a7545db023..3e988f38b265 100644 --- a/src/plugins/workspace/public/workspace_client.ts +++ b/src/plugins/workspace/public/workspace_client.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { i18n } from '@osd/i18n'; import { HttpFetchError, HttpFetchOptions, @@ -145,12 +146,14 @@ export class WorkspaceClient { /** * A bypass layer to get current workspace id */ - public async getCurrentWorkspaceId(): Promise> { + public getCurrentWorkspaceId(): IResponse { const currentWorkspaceId = this.workspaces.currentWorkspaceId$.getValue(); if (!currentWorkspaceId) { return { success: false, - error: 'You are not in any workspace yet.', + error: i18n.translate('workspace.error.notInWorkspace', { + defaultMessage: 'You are not in any workspace yet.', + }), }; } @@ -164,7 +167,7 @@ export class WorkspaceClient { * Do a find in the latest workspace list with current workspace id */ public async getCurrentWorkspace(): Promise> { - const currentWorkspaceIdResp = await this.getCurrentWorkspaceId(); + const currentWorkspaceIdResp = this.getCurrentWorkspaceId(); if (currentWorkspaceIdResp.success) { const currentWorkspaceResp = await this.get(currentWorkspaceIdResp.result); return currentWorkspaceResp;