diff --git a/src/plugins/workspace/common/constants.ts b/src/plugins/workspace/common/constants.ts index 6ae89c0edad5..e60bb6aea0eb 100644 --- a/src/plugins/workspace/common/constants.ts +++ b/src/plugins/workspace/common/constants.ts @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -export const WORKSPACE_OVERVIEW_APP_ID = 'workspace_overview'; -export const WORKSPACE_FATAL_ERROR_APP_ID = 'workspace_fatal_error'; export const WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID = 'workspace'; export const WORKSPACE_CONFLICT_CONTROL_SAVED_OBJECTS_CLIENT_WRAPPER_ID = 'workspace_conflict_control'; diff --git a/src/plugins/workspace/opensearch_dashboards.json b/src/plugins/workspace/opensearch_dashboards.json index 4443b7e99834..f34106ab4fed 100644 --- a/src/plugins/workspace/opensearch_dashboards.json +++ b/src/plugins/workspace/opensearch_dashboards.json @@ -7,5 +7,5 @@ "savedObjects" ], "optionalPlugins": [], - "requiredBundles": ["opensearchDashboardsReact"] + "requiredBundles": [] } diff --git a/src/plugins/workspace/public/application.tsx b/src/plugins/workspace/public/application.tsx deleted file mode 100644 index a6f496304889..000000000000 --- a/src/plugins/workspace/public/application.tsx +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import React from 'react'; -import ReactDOM from 'react-dom'; -import { AppMountParameters, ScopedHistory } from '../../../core/public'; -import { OpenSearchDashboardsContextProvider } from '../../opensearch_dashboards_react/public'; -import { WorkspaceFatalError } from './components/workspace_fatal_error'; -import { Services } from './types'; - -export const renderFatalErrorApp = (params: AppMountParameters, services: Services) => { - const { element } = params; - const history = params.history as ScopedHistory<{ error?: string }>; - ReactDOM.render( - - - , - element - ); - - return () => { - ReactDOM.unmountComponentAtNode(element); - }; -}; diff --git a/src/plugins/workspace/public/components/workspace_fatal_error/__snapshots__/workspace_fatal_error.test.tsx.snap b/src/plugins/workspace/public/components/workspace_fatal_error/__snapshots__/workspace_fatal_error.test.tsx.snap deleted file mode 100644 index 594066e959f7..000000000000 --- a/src/plugins/workspace/public/components/workspace_fatal_error/__snapshots__/workspace_fatal_error.test.tsx.snap +++ /dev/null @@ -1,180 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` render error with callout 1`] = ` -
-
-
-
-
- -
-

- - Something went wrong - -

- -
-
-

- - The workspace you want to go can not be found, try go back to home. - -

-
- -
-
-
- -
-
-
-
-
-
-
-
-
-
-
-`; - -exports[` render normally 1`] = ` -
-
-
-
-
- -
-

- - Something went wrong - -

- -
-
-

- - The workspace you want to go can not be found, try go back to home. - -

-
- -
-
-
- -
-
-
-
-
-
-
-`; diff --git a/src/plugins/workspace/public/components/workspace_fatal_error/index.ts b/src/plugins/workspace/public/components/workspace_fatal_error/index.ts deleted file mode 100644 index afb34b10d913..000000000000 --- a/src/plugins/workspace/public/components/workspace_fatal_error/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -export { WorkspaceFatalError } from './workspace_fatal_error'; diff --git a/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.test.tsx b/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.test.tsx deleted file mode 100644 index d98e0063dcfa..000000000000 --- a/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.test.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import React from 'react'; -import { IntlProvider } from 'react-intl'; -import { fireEvent, render, waitFor } from '@testing-library/react'; -import { WorkspaceFatalError } from './workspace_fatal_error'; -import { context } from '../../../../opensearch_dashboards_react/public'; -import { coreMock } from '../../../../../core/public/mocks'; - -describe('', () => { - it('render normally', async () => { - const { findByText, container } = render( - - - - ); - await findByText('Something went wrong'); - expect(container).toMatchSnapshot(); - }); - - it('render error with callout', async () => { - const { findByText, container } = render( - - - - ); - await findByText('errorInCallout'); - expect(container).toMatchSnapshot(); - }); - - it('click go back to home', async () => { - const { location } = window; - const setHrefSpy = jest.fn((href) => href); - if (window.location) { - // @ts-ignore - delete window.location; - } - window.location = {} as Location; - Object.defineProperty(window.location, 'href', { - get: () => 'http://localhost/', - set: setHrefSpy, - }); - const coreStartMock = coreMock.createStart(); - const { getByText } = render( - - - - - - ); - fireEvent.click(getByText('Go back to home')); - await waitFor( - () => { - expect(setHrefSpy).toBeCalledTimes(1); - }, - { - container: document.body, - } - ); - window.location = location; - }); -}); diff --git a/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx b/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx deleted file mode 100644 index b1081e92237f..000000000000 --- a/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import { - EuiButton, - EuiEmptyPrompt, - EuiPage, - EuiPageBody, - EuiPageContent, - EuiCallOut, -} from '@elastic/eui'; -import React from 'react'; -import { FormattedMessage } from '@osd/i18n/react'; -import { IBasePath } from 'opensearch-dashboards/public'; -import { useOpenSearchDashboards } from '../../../../opensearch_dashboards_react/public'; -import { formatUrlWithWorkspaceId } from '../../../../../core/public/utils'; - -export function WorkspaceFatalError(props: { error?: string }) { - const { - services: { application, http }, - } = useOpenSearchDashboards(); - const goBackToHome = () => { - window.location.href = formatUrlWithWorkspaceId( - application?.getUrlForApp('home') || '', - '', - http?.basePath as IBasePath - ); - }; - return ( - - - - - - - } - body={ -

- -

- } - actions={[ - - - , - ]} - /> - {props.error ? : null} -
-
-
- ); -} diff --git a/src/plugins/workspace/public/plugin.test.ts b/src/plugins/workspace/public/plugin.test.ts index 370f60caab52..d2e82b6d37f8 100644 --- a/src/plugins/workspace/public/plugin.test.ts +++ b/src/plugins/workspace/public/plugin.test.ts @@ -3,25 +3,18 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { waitFor } from '@testing-library/dom'; -import { workspaceClientMock, WorkspaceClientMock } from './workspace_client.mock'; -import { applicationServiceMock, chromeServiceMock, coreMock } from '../../../core/public/mocks'; +import { chromeServiceMock, coreMock } from '../../../core/public/mocks'; import { WorkspacePlugin } from './plugin'; -import { WORKSPACE_FATAL_ERROR_APP_ID, WORKSPACE_OVERVIEW_APP_ID } from '../common/constants'; -import { Observable, Subscriber } from 'rxjs'; describe('Workspace plugin', () => { - beforeEach(() => { - WorkspaceClientMock.mockClear(); - Object.values(workspaceClientMock).forEach((item) => item.mockClear()); + const getSetupMock = () => ({ + ...coreMock.createSetup(), + chrome: chromeServiceMock.createSetupContract(), }); it('#setup', async () => { - const setupMock = coreMock.createSetup(); + const setupMock = getSetupMock(); const workspacePlugin = new WorkspacePlugin(); await workspacePlugin.setup(setupMock); - expect(setupMock.application.register).toBeCalledTimes(1); - expect(WorkspaceClientMock).toBeCalledTimes(1); - expect(workspaceClientMock.enterWorkspace).toBeCalledTimes(0); }); it('#setup when workspace id is in url and enterWorkspace return error', async () => { @@ -34,82 +27,11 @@ describe('Workspace plugin', () => { }, } as any) ); - workspaceClientMock.enterWorkspace.mockResolvedValue({ - success: false, - error: 'error', - }); - const setupMock = coreMock.createSetup(); - const applicationStartMock = applicationServiceMock.createStartContract(); - const chromeStartMock = chromeServiceMock.createStartContract(); - setupMock.getStartServices.mockImplementation(() => { - return Promise.resolve([ - { - application: applicationStartMock, - chrome: chromeStartMock, - }, - {}, - {}, - ]) as any; - }); + const setupMock = getSetupMock(); const workspacePlugin = new WorkspacePlugin(); await workspacePlugin.setup(setupMock); - expect(setupMock.application.register).toBeCalledTimes(1); - expect(WorkspaceClientMock).toBeCalledTimes(1); - expect(workspaceClientMock.enterWorkspace).toBeCalledWith('workspaceId'); - expect(setupMock.getStartServices).toBeCalledTimes(1); - await waitFor( - () => { - expect(applicationStartMock.navigateToApp).toBeCalledWith(WORKSPACE_FATAL_ERROR_APP_ID, { - replace: true, - state: { - error: 'error', - }, - }); - }, - { - container: document.body, - } - ); - windowSpy.mockRestore(); - }); - - it('#setup when workspace id is in url and enterWorkspace return success', async () => { - const windowSpy = jest.spyOn(window, 'window', 'get'); - windowSpy.mockImplementation( - () => - ({ - location: { - href: 'http://localhost/w/workspaceId/app', - }, - } as any) - ); - workspaceClientMock.enterWorkspace.mockResolvedValue({ - success: true, - error: 'error', - }); - const setupMock = coreMock.createSetup(); - const applicationStartMock = applicationServiceMock.createStartContract(); - let currentAppIdSubscriber: Subscriber | undefined; - setupMock.getStartServices.mockImplementation(() => { - return Promise.resolve([ - { - application: { - ...applicationStartMock, - currentAppId$: new Observable((subscriber) => { - currentAppIdSubscriber = subscriber; - }), - }, - }, - {}, - {}, - ]) as any; - }); - - const workspacePlugin = new WorkspacePlugin(); - await workspacePlugin.setup(setupMock); - currentAppIdSubscriber?.next(WORKSPACE_FATAL_ERROR_APP_ID); - expect(applicationStartMock.navigateToApp).toBeCalledWith(WORKSPACE_OVERVIEW_APP_ID); + expect(setupMock.workspaces.currentWorkspaceId$.getValue()).toEqual('workspaceId'); windowSpy.mockRestore(); }); }); diff --git a/src/plugins/workspace/public/plugin.ts b/src/plugins/workspace/public/plugin.ts index 5589299903d5..b4c154e01e96 100644 --- a/src/plugins/workspace/public/plugin.ts +++ b/src/plugins/workspace/public/plugin.ts @@ -3,82 +3,23 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { AppMountParameters, AppNavLinkStatus, CoreSetup, Plugin } from '../../../core/public'; -import { WORKSPACE_FATAL_ERROR_APP_ID, WORKSPACE_OVERVIEW_APP_ID } from '../common/constants'; +import { CoreSetup, Plugin } from '../../../core/public'; import { getWorkspaceIdFromUrl } from '../../../core/public/utils'; -import { Services } from './types'; -import { WorkspaceClient } from './workspace_client'; - -type WorkspaceAppType = (params: AppMountParameters, services: Services) => () => void; export class WorkspacePlugin implements Plugin<{}, {}> { private getWorkspaceIdFromURL(): string | null { return getWorkspaceIdFromUrl(window.location.href); } public async setup(core: CoreSetup) { - const workspaceClient = new WorkspaceClient(core.http, core.workspaces); - await workspaceClient.init(); - /** * Retrieve workspace id from url */ const workspaceId = this.getWorkspaceIdFromURL(); if (workspaceId) { - const result = await workspaceClient.enterWorkspace(workspaceId); - if (!result.success) { - /** - * Fatal error service does not support customized actions - * So we have to use a self-hosted page to show the errors and redirect. - */ - (async () => { - const [{ application, chrome }] = await core.getStartServices(); - chrome.setIsVisible(false); - application.navigateToApp(WORKSPACE_FATAL_ERROR_APP_ID, { - replace: true, - state: { - error: result.error, - }, - }); - })(); - } else { - /** - * If the workspace id is valid and user is currently on workspace_fatal_error page, - * we should redirect user to overview page of workspace. - */ - (async () => { - const [{ application }] = await core.getStartServices(); - const currentAppIdSubscription = application.currentAppId$.subscribe((currentAppId) => { - if (currentAppId === WORKSPACE_FATAL_ERROR_APP_ID) { - application.navigateToApp(WORKSPACE_OVERVIEW_APP_ID); - } - currentAppIdSubscription.unsubscribe(); - }); - })(); - } + core.workspaces.currentWorkspaceId$.next(workspaceId); } - const mountWorkspaceApp = async (params: AppMountParameters, renderApp: WorkspaceAppType) => { - const [coreStart] = await core.getStartServices(); - const services = { - ...coreStart, - workspaceClient, - }; - - return renderApp(params, services); - }; - - // workspace fatal error - core.application.register({ - id: WORKSPACE_FATAL_ERROR_APP_ID, - title: '', - navLinkStatus: AppNavLinkStatus.hidden, - async mount(params: AppMountParameters) { - const { renderFatalErrorApp } = await import('./application'); - return mountWorkspaceApp(params, renderFatalErrorApp); - }, - }); - return {}; } diff --git a/src/plugins/workspace/public/workspace_client.mock.ts b/src/plugins/workspace/public/workspace_client.mock.ts deleted file mode 100644 index 2ceeae5627d1..000000000000 --- a/src/plugins/workspace/public/workspace_client.mock.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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 deleted file mode 100644 index 7d05c3f22458..000000000000 --- a/src/plugins/workspace/public/workspace_client.test.ts +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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 deleted file mode 100644 index f9c219645d14..000000000000 --- a/src/plugins/workspace/public/workspace_client.ts +++ /dev/null @@ -1,262 +0,0 @@ -/* - * 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('/'); - } - - private async updateWorkspaceList(): Promise { - const result = await this.list({ - perPage: 999, - }); - - if (result?.success) { - this.workspaces.workspaceList$.next(result.result.workspaces); - } - } - - 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; - } - } - - 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, - }; - } - - public async getCurrentWorkspace(): Promise> { - const currentWorkspaceIdResp = await this.getCurrentWorkspaceId(); - if (currentWorkspaceIdResp.success) { - const currentWorkspaceResp = await this.get(currentWorkspaceIdResp.result); - return currentWorkspaceResp; - } else { - return currentWorkspaceIdResp; - } - } - - /** - * Persists 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 - * - * @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 - * - * @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(); - } -}