Skip to content

Commit

Permalink
Merge pull request #4 from SuZhou-Joe/feature/workspace-service
Browse files Browse the repository at this point in the history
Add interfaces and partial implement for public core.workspaces
  • Loading branch information
SuZhou-Joe authored Jun 12, 2023
2 parents 99fc9eb + 02f73fa commit 3c5df9d
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/core/public/application/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { IUiSettingsClient } from '../ui_settings';
import { SavedObjectsStart } from '../saved_objects';
import { AppCategory, WorkspaceTemplate } from '../../types';
import { ScopedHistory } from './scoped_history';
import { WorkspacesStart } from '../workspace';

/**
* Accessibility status of an application.
Expand Down Expand Up @@ -340,6 +341,8 @@ export interface AppMountContext {
injectedMetadata: {
getInjectedVar: (name: string, defaultValue?: any) => unknown;
};
/** {@link WorkspacesService} */
workspaces: WorkspacesStart;
};
}

Expand Down
6 changes: 6 additions & 0 deletions src/core/public/core_system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import { ContextService } from './context';
import { IntegrationsService } from './integrations';
import { CoreApp } from './core_app';
import type { InternalApplicationSetup, InternalApplicationStart } from './application/types';
import { WorkspacesService } from './workspace';

interface Params {
rootDomElement: HTMLElement;
Expand Down Expand Up @@ -110,6 +111,7 @@ export class CoreSystem {

private readonly rootDomElement: HTMLElement;
private readonly coreContext: CoreContext;
private readonly workspaces: WorkspacesService;
private fatalErrorsSetup: FatalErrorsSetup | null = null;

constructor(params: Params) {
Expand Down Expand Up @@ -138,6 +140,7 @@ export class CoreSystem {
this.rendering = new RenderingService();
this.application = new ApplicationService();
this.integrations = new IntegrationsService();
this.workspaces = new WorkspacesService();

this.coreContext = { coreId: Symbol('core'), env: injectedMetadata.env };

Expand Down Expand Up @@ -199,6 +202,7 @@ export class CoreSystem {
const uiSettings = await this.uiSettings.start();
const docLinks = this.docLinks.start({ injectedMetadata });
const http = await this.http.start();
const workspaces = await this.workspaces.start({ http });
const savedObjects = await this.savedObjects.start({ http });
const i18n = await this.i18n.start();
const fatalErrors = await this.fatalErrors.start();
Expand Down Expand Up @@ -242,6 +246,7 @@ export class CoreSystem {
overlays,
savedObjects,
uiSettings,
workspaces,
}));

const core: InternalCoreStart = {
Expand All @@ -256,6 +261,7 @@ export class CoreSystem {
overlays,
uiSettings,
fatalErrors,
workspaces,
};

await this.plugins.start(core);
Expand Down
3 changes: 3 additions & 0 deletions src/core/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ import {
HandlerParameters,
} from './context';
import { Branding } from '../types';
import { WorkspacesStart } from './workspace';

export { PackageInfo, EnvironmentMode } from '../server/types';
/** @interal */
Expand Down Expand Up @@ -294,6 +295,8 @@ export interface CoreStart {
getInjectedVar: (name: string, defaultValue?: any) => unknown;
getBranding: () => Branding;
};
/** {@link WorkspacesStart} */
workspaces: WorkspacesStart;
}

export {
Expand Down
1 change: 1 addition & 0 deletions src/core/public/plugins/plugin_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,5 +168,6 @@ export function createPluginStartContext<
getBranding: deps.injectedMetadata.getBranding,
},
fatalErrors: deps.fatalErrors,
workspaces: deps.workspaces,
};
}
7 changes: 7 additions & 0 deletions src/core/public/workspace/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
export { WorkspacesClientContract, WorkspacesClient } from './workspaces_client';
export { WorkspacesStart, WorkspacesService } from './workspaces_service';
export { WorkspaceAttribute, WorkspaceFindOptions } from '../../server/types';
191 changes: 191 additions & 0 deletions src/core/public/workspace/workspaces_client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
import { resolve as resolveUrl } from 'url';
import type { PublicMethodsOf } from '@osd/utility-types';
import { WORKSPACES_API_BASE_URL } from '../../server/types';
import { HttpStart } from '../http';
import { WorkspaceAttribute, WorkspaceFindOptions } from '.';

/**
* WorkspacesClientContract as implemented by the {@link WorkspacesClient}
*
* @public
*/
export type WorkspacesClientContract = PublicMethodsOf<WorkspacesClient>;

const join = (...uriComponents: Array<string | undefined>) =>
uriComponents
.filter((comp): comp is string => Boolean(comp))
.map(encodeURIComponent)
.join('/');

type IResponse<T> =
| {
result: T;
success: true;
}
| {
success: false;
error?: string;
};

/**
* Workspaces is OpenSearchDashboards's visualize mechanism allowing admins to
* organize related features
*
* @public
*/
export class WorkspacesClient {
private http: HttpStart;
constructor(http: HttpStart) {
this.http = http;
}

private getPath(path: Array<string | undefined>): string {
return resolveUrl(`${WORKSPACES_API_BASE_URL}/`, join(...path));
}

public async enterWorkspace(id: string): Promise<IResponse<null>> {
return {
success: false,
error: 'Unimplement',
};
}

public async exitWorkspace(): Promise<IResponse<null>> {
return {
success: false,
error: 'Unimplement',
};
}

public async getCurrentWorkspaceId(): Promise<IResponse<WorkspaceAttribute['id']>> {
return {
success: false,
error: 'Unimplement',
};
}

public async getCurrentWorkspace(): Promise<IResponse<WorkspaceAttribute>> {
return {
success: false,
error: 'Unimplement',
};
}

/**
* Persists an workspace
*
* @param attributes
* @returns
*/
public create = (
attributes: Omit<WorkspaceAttribute, 'id'>
): Promise<IResponse<WorkspaceAttribute>> => {
if (!attributes) {
return Promise.reject(new Error('requires attributes'));
}

const path = this.getPath([]);

return this.http.fetch(path, {
method: 'POST',
body: JSON.stringify({
attributes,
}),
});
};

/**
* Deletes a workspace
*
* @param id
* @returns
*/
public delete = (id: string): Promise<IResponse<null>> => {
if (!id) {
return Promise.reject(new Error('requires id'));
}

return this.http.delete(this.getPath([id]), { method: 'DELETE' });
};

/**
* Search for workspaces
*
* @param {object} [options={}]
* @property {string} options.search
* @property {string} options.search_fields - see OpenSearch Simple Query String
* Query field argument for more information
* @property {integer} [options.page=1]
* @property {integer} [options.per_page=20]
* @property {array} options.fields
* @returns A find result with workspaces matching the specified search.
*/
public list = (
options?: WorkspaceFindOptions
): Promise<
IResponse<
WorkspaceAttribute & {
total: number;
perPage: number;
page: number;
}
>
> => {
const path = this.getPath(['_list']);
return this.http.fetch(path, {
method: 'GET',
query: options,
});
};

/**
* Fetches a single workspace
*
* @param {string} id
* @returns The workspace for the given id.
*/
public get = (id: string): Promise<IResponse<WorkspaceAttribute>> => {
if (!id) {
return Promise.reject(new Error('requires id'));
}

const path = this.getPath([id]);
return this.http.fetch(path, {
method: 'GET',
});
};

/**
* Updates a workspace
*
* @param {string} id
* @param {object} attributes
* @returns
*/
public update(id: string, attributes: Partial<WorkspaceAttribute>): Promise<IResponse<boolean>> {
if (!id || !attributes) {
return Promise.reject(new Error('requires id and attributes'));
}

const path = this.getPath([id]);
const body = {
attributes,
};

return this.http
.fetch(path, {
method: 'PUT',
body: JSON.stringify(body),
})
.then((resp: WorkspaceAttribute) => {
return {
result: true,
success: true,
};
});
}
}
22 changes: 22 additions & 0 deletions src/core/public/workspace/workspaces_service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
import { CoreService } from 'src/core/types';
import { WorkspacesClient, WorkspacesClientContract } from './workspaces_client';
import { HttpStart } from '..';

/**
* @public
*/
export interface WorkspacesStart {
client: WorkspacesClientContract;
}

export class WorkspacesService implements CoreService<void, WorkspacesStart> {
public async setup() {}
public async start({ http }: { http: HttpStart }): Promise<WorkspacesStart> {
return { client: new WorkspacesClient(http) };
}
public async stop() {}
}

0 comments on commit 3c5df9d

Please sign in to comment.