Skip to content

Commit

Permalink
replace default workspace with public workspace (#322)
Browse files Browse the repository at this point in the history
Signed-off-by: Hailong Cui <ihailong@amazon.com>
  • Loading branch information
Hailong-am authored Apr 12, 2024
1 parent 2d6ae9b commit bff1a06
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 32 deletions.
7 changes: 6 additions & 1 deletion src/core/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,11 @@ export { __osdBootstrap__ } from './osd_bootstrap';

export { WorkspacesStart, WorkspacesSetup, WorkspacesService } from './workspace';

export { WORKSPACE_TYPE, cleanWorkspaceId, DEFAULT_WORKSPACE_ID } from '../utils';
export {
WORKSPACE_TYPE,
cleanWorkspaceId,
PUBLIC_WORKSPACE_ID,
PUBLIC_WORKSPACE_NAME,
} from '../utils';

export { debounce } from './utils';
2 changes: 1 addition & 1 deletion src/core/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,8 @@ export { AppCategory, WorkspaceAttribute } from '../types';
export {
DEFAULT_APP_CATEGORIES,
PUBLIC_WORKSPACE_ID,
PUBLIC_WORKSPACE_NAME,
WORKSPACE_TYPE,
DEFAULT_WORKSPACE_ID,
} from '../utils';

export {
Expand Down
14 changes: 9 additions & 5 deletions src/core/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { i18n } from '@osd/i18n';

export const WORKSPACE_TYPE = 'workspace';

export const WORKSPACE_PATH_PREFIX = '/w';

export const PUBLIC_WORKSPACE_ID = 'public';

/**
* deafult workspace is a virtual workspace,
* saved objects without any workspaces are consider belongs to default workspace
* public workspace has parity with global tenant,
* it includes saved objects with `public` as its workspace or without any workspce info
*/
export const DEFAULT_WORKSPACE_ID = 'default';
export const PUBLIC_WORKSPACE_ID = 'public';

export const PUBLIC_WORKSPACE_NAME = i18n.translate('workspaces.public.workspace.default.name', {
defaultMessage: 'Global workspace',
});
2 changes: 1 addition & 1 deletion src/core/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ export { getWorkspaceIdFromUrl, formatUrlWithWorkspaceId, cleanWorkspaceId } fro
export {
WORKSPACE_PATH_PREFIX,
PUBLIC_WORKSPACE_ID,
PUBLIC_WORKSPACE_NAME,
WORKSPACE_TYPE,
DEFAULT_WORKSPACE_ID,
} from './constants';
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ import {
import { Flyout, Relationships } from './components';
import { SavedObjectWithMetadata } from '../../types';
import { WorkspaceObject } from 'opensearch-dashboards/public';
import { DEFAULT_WORKSPACE_ID } from '../../../../../core/public';
import { PUBLIC_WORKSPACE_ID } from '../../../../../core/public';
import { TableProps } from './components/table';

const allowedTypes = ['index-pattern', 'visualization', 'dashboard', 'search'];
Expand Down Expand Up @@ -696,7 +696,7 @@ describe('SavedObjectsTable', () => {
expect(filters[1].options.length).toBe(3);
expect(filters[1].options[0].value).toBe('foo');
expect(filters[1].options[1].value).toBe('bar');
expect(filters[1].options[2].value).toBe(DEFAULT_WORKSPACE_ID);
expect(filters[1].options[2].value).toBe(PUBLIC_WORKSPACE_ID);
});

it('show workspace filter when workspace turn on and enter a workspace', async () => {
Expand Down Expand Up @@ -832,7 +832,7 @@ describe('SavedObjectsTable', () => {
expect(findObjectsMock).toBeCalledWith(
http,
expect.objectContaining({
workspaces: expect.arrayContaining(['workspace1', 'default']),
workspaces: expect.arrayContaining(['workspace1', PUBLIC_WORKSPACE_ID]),
workspacesSearchOperator: expect.stringMatching('OR'),
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ import {
WorkspaceAttribute,
} from 'src/core/public';
import { Subscription } from 'rxjs';
import { DEFAULT_WORKSPACE_ID } from '../../../../../core/public';
import { PUBLIC_WORKSPACE_ID, PUBLIC_WORKSPACE_NAME } from '../../../../../core/public';
import { RedirectAppLinks } from '../../../../opensearch_dashboards_react/public';
import { IndexPatternsContract } from '../../../../data/public';
import {
Expand Down Expand Up @@ -193,21 +193,21 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb
} else {
// application home
if (!currentWorkspaceId) {
return availableWorkspaces?.map((ws) => ws.id).concat(DEFAULT_WORKSPACE_ID);
return availableWorkspaces?.map((ws) => ws.id).concat(PUBLIC_WORKSPACE_ID);
} else {
return [currentWorkspaceId];
}
}
}

private get wsNameIdLookup() {
private get workspaceNameIdLookup() {
const { availableWorkspaces } = this.state;
const workspaceNameIdMap = new Map<string, string>();
workspaceNameIdMap.set(DEFAULT_WORKSPACE_ID, DEFAULT_WORKSPACE_ID);
// Assumption: workspace name is unique across the system
availableWorkspaces?.reduce((map, ws) => {
return map.set(ws.name, ws.id);
}, workspaceNameIdMap);
workspaceNameIdMap.set(PUBLIC_WORKSPACE_NAME, PUBLIC_WORKSPACE_ID);
// workspace name is unique across the system
availableWorkspaces?.forEach((workspace) => {
workspaceNameIdMap.set(workspace.name, workspace.id);
});
return workspaceNameIdMap;
}

Expand Down Expand Up @@ -258,7 +258,7 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb
}
if (visibleWorkspaces?.length) {
filteredCountOptions.workspaces = visibleWorkspaces
.map((wsName) => this.wsNameIdLookup?.get(wsName) || '')
.map((wsName) => this.workspaceNameIdLookup?.get(wsName) || '')
.filter((wsId) => !!wsId);
}

Expand Down Expand Up @@ -351,13 +351,13 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb

if (visibleWorkspaces?.length) {
const workspaceIds: string[] = visibleWorkspaces.map(
(wsName) => this.wsNameIdLookup?.get(wsName) || ''
(wsName) => this.workspaceNameIdLookup?.get(wsName) || ''
);
findOptions.workspaces = workspaceIds;
}

if (findOptions.workspaces) {
if (findOptions.workspaces.indexOf(DEFAULT_WORKSPACE_ID) !== -1) {
if (findOptions.workspaces.indexOf(PUBLIC_WORKSPACE_ID) !== -1) {
// search both saved objects with workspace and without workspace
findOptions.workspacesSearchOperator = 'OR';
}
Expand Down Expand Up @@ -961,6 +961,8 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb
// Add workspace filter
if (workspaceEnabled && availableWorkspaces?.length) {
const wsCounts = savedObjectCounts.workspaces || {};
const publicWorkspaceExists =
availableWorkspaces.findIndex((workspace) => workspace.id === PUBLIC_WORKSPACE_ID) > -1;
const wsFilterOptions = availableWorkspaces
.filter((ws) => {
return this.workspaceIdQuery?.includes(ws.id);
Expand All @@ -973,11 +975,12 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb
};
});

if (!currentWorkspaceId) {
// add public workspace option only if we don't have it as real workspace
if (!currentWorkspaceId && !publicWorkspaceExists) {
wsFilterOptions.push({
name: DEFAULT_WORKSPACE_ID,
value: DEFAULT_WORKSPACE_ID,
view: `Default (${wsCounts[DEFAULT_WORKSPACE_ID] || 0})`,
name: PUBLIC_WORKSPACE_NAME,
value: PUBLIC_WORKSPACE_ID,
view: `${PUBLIC_WORKSPACE_NAME} (${wsCounts[PUBLIC_WORKSPACE_ID] || 0})`,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

import { schema } from '@osd/config-schema';
import { IRouter, SavedObjectsFindOptions } from 'src/core/server';
import { DEFAULT_WORKSPACE_ID } from '../../../../core/server';
import { PUBLIC_WORKSPACE_ID } from '../../../../core/server';
import { findAll } from '../lib';

export const registerScrollForCountRoute = (router: IRouter) => {
Expand Down Expand Up @@ -70,7 +70,7 @@ export const registerScrollForCountRoute = (router: IRouter) => {
if (requestHasWorkspaces) {
counts.workspaces = {};
findOptions.workspaces = req.body.workspaces;
if (findOptions.workspaces.indexOf(DEFAULT_WORKSPACE_ID) !== -1) {
if (findOptions.workspaces.indexOf(PUBLIC_WORKSPACE_ID) !== -1) {
// search both saved objects with workspace and without workspace
findOptions.workspacesSearchOperator = 'OR';
}
Expand All @@ -96,7 +96,7 @@ export const registerScrollForCountRoute = (router: IRouter) => {
});
}
if (requestHasWorkspaces) {
const resultWorkspaces = result.workspaces || [DEFAULT_WORKSPACE_ID];
const resultWorkspaces = result.workspaces || [PUBLIC_WORKSPACE_ID];
resultWorkspaces.forEach((ws) => {
counts.workspaces[ws] = counts.workspaces[ws] || 0;
counts.workspaces[ws]++;
Expand Down
5 changes: 2 additions & 3 deletions src/plugins/workspace/server/workspace_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import {
DEFAULT_APP_CATEGORIES,
PUBLIC_WORKSPACE_ID,
PUBLIC_WORKSPACE_NAME,
WORKSPACE_TYPE,
Logger,
} from '../../../core/server';
Expand Down Expand Up @@ -108,9 +109,7 @@ export class WorkspaceClient implements IWorkspaceClientImpl {
}
private async setupPublicWorkspace(savedObjectClient?: SavedObjectsClientContract) {
return this.checkAndCreateWorkspace(savedObjectClient, PUBLIC_WORKSPACE_ID, {
name: i18n.translate('workspaces.public.workspace.default.name', {
defaultMessage: 'Global workspace',
}),
name: PUBLIC_WORKSPACE_NAME,
features: ['*', `!@${DEFAULT_APP_CATEGORIES.management.id}`],
reserved: true,
});
Expand Down

0 comments on commit bff1a06

Please sign in to comment.