diff --git a/src/core/public/utils/index.ts b/src/core/public/utils/index.ts index 7676b9482aac..9b6cf8c652c0 100644 --- a/src/core/public/utils/index.ts +++ b/src/core/public/utils/index.ts @@ -31,3 +31,4 @@ export { shareWeakReplay } from './share_weak_replay'; export { Sha256 } from './crypto'; export { MountWrapper, mountReactNode } from './mount'; +export { WORKSPACE_PATH_PREFIX, WORKSPACE_TYPE } from '../../utils'; diff --git a/src/core/types/saved_objects.ts b/src/core/types/saved_objects.ts index fa4f5ab97fdf..fb952484073d 100644 --- a/src/core/types/saved_objects.ts +++ b/src/core/types/saved_objects.ts @@ -115,6 +115,7 @@ export interface SavedObject { originId?: string; /** Workspaces that this saved object exists in. */ workspaces?: string[]; + permissions?: Permissions; } export interface SavedObjectError { diff --git a/src/core/utils/constants.ts b/src/core/utils/constants.ts index 73c2d6010846..ecc1b7e863c4 100644 --- a/src/core/utils/constants.ts +++ b/src/core/utils/constants.ts @@ -4,3 +4,5 @@ */ export const WORKSPACE_TYPE = 'workspace'; + +export const WORKSPACE_PATH_PREFIX = '/w'; diff --git a/src/core/utils/index.ts b/src/core/utils/index.ts index af4f9a17ae58..46de7181cf17 100644 --- a/src/core/utils/index.ts +++ b/src/core/utils/index.ts @@ -37,4 +37,4 @@ export { IContextProvider, } from './context'; export { DEFAULT_APP_CATEGORIES } from './default_app_categories'; -export { WORKSPACE_TYPE } from './constants'; +export { WORKSPACE_TYPE, WORKSPACE_PATH_PREFIX } from './constants'; diff --git a/src/plugins/saved_objects_management/public/lib/get_saved_object_counts.ts b/src/plugins/saved_objects_management/public/lib/get_saved_object_counts.ts index 6eaaac7d35f2..374f2720b537 100644 --- a/src/plugins/saved_objects_management/public/lib/get_saved_object_counts.ts +++ b/src/plugins/saved_objects_management/public/lib/get_saved_object_counts.ts @@ -34,13 +34,14 @@ export interface SavedObjectCountOptions { typesToInclude: string[]; namespacesToInclude?: string[]; searchString?: string; + workspaces?: string[]; } export async function getSavedObjectCounts( http: HttpStart, options: SavedObjectCountOptions -): Promise> { - return await http.post>( +): Promise>> { + return await http.post>>( `/api/opensearch-dashboards/management/saved_objects/scroll/counts`, { body: JSON.stringify(options) } ); diff --git a/src/plugins/saved_objects_management/public/lib/parse_query.test.ts b/src/plugins/saved_objects_management/public/lib/parse_query.test.ts index a940cf3ebbca..731bb73a4d70 100644 --- a/src/plugins/saved_objects_management/public/lib/parse_query.test.ts +++ b/src/plugins/saved_objects_management/public/lib/parse_query.test.ts @@ -39,6 +39,8 @@ describe('getQueryText', () => { return [{ value: 'lala' }, { value: 'lolo' }]; } else if (field === 'namespaces') { return [{ value: 'default' }]; + } else if (field === 'workspaces') { + return [{ value: 'workspaces' }]; } return []; }, @@ -47,6 +49,7 @@ describe('getQueryText', () => { queryText: 'foo bar', visibleTypes: 'lala', visibleNamespaces: 'default', + visibleWorkspaces: 'workspaces', }); }); }); diff --git a/src/plugins/saved_objects_management/public/lib/parse_query.ts b/src/plugins/saved_objects_management/public/lib/parse_query.ts index 24c35d500aaa..3db3f7fcee1c 100644 --- a/src/plugins/saved_objects_management/public/lib/parse_query.ts +++ b/src/plugins/saved_objects_management/public/lib/parse_query.ts @@ -33,12 +33,15 @@ import { Query } from '@elastic/eui'; interface ParsedQuery { queryText?: string; visibleTypes?: string[]; + visibleNamespaces?: string[]; + visibleWorkspaces?: string[]; } export function parseQuery(query: Query): ParsedQuery { let queryText: string | undefined; let visibleTypes: string[] | undefined; let visibleNamespaces: string[] | undefined; + let visibleWorkspaces: string[] | undefined; if (query) { if (query.ast.getTermClauses().length) { @@ -53,11 +56,15 @@ export function parseQuery(query: Query): ParsedQuery { if (query.ast.getFieldClauses('namespaces')) { visibleNamespaces = query.ast.getFieldClauses('namespaces')[0].value as string[]; } + if (query.ast.getFieldClauses('workspaces')) { + visibleWorkspaces = query.ast.getFieldClauses('workspaces')[0].value as string[]; + } } return { queryText, visibleTypes, visibleNamespaces, + visibleWorkspaces, }; } diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap index d18762f4912f..58cf4a992693 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap @@ -203,6 +203,7 @@ exports[`SavedObjectsTable should render normally 1`] = ` >
{ onRefresh: () => {}, totalCount: 4, filteredCount: 2, + hideImport: false, }; const component = shallow(
); @@ -47,3 +48,20 @@ describe('Header', () => { expect(component).toMatchSnapshot(); }); }); + +describe('Header - workspace enabled', () => { + it('should hide `Import` button for application home state', () => { + const props = { + onExportAll: () => {}, + onImport: () => {}, + onRefresh: () => {}, + totalCount: 4, + filteredCount: 2, + hideImport: true, + }; + + const component = shallow(
); + + expect(component.find('EuiButtonEmpty[data-test-subj="importObjects"]').exists()).toBe(false); + }); +}); diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/header.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/header.tsx index a22e349d5240..957950935d3f 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/header.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/header.tsx @@ -45,11 +45,13 @@ export const Header = ({ onImport, onRefresh, filteredCount, + hideImport = false, }: { onExportAll: () => void; onImport: () => void; onRefresh: () => void; filteredCount: number; + hideImport: boolean; }) => ( @@ -82,19 +84,21 @@ export const Header = ({ /> - - - - - + {!hideImport && ( + + + + + + )} { expect(component).toMatchSnapshot(); }); + it('should render gotoApp link correctly for workspace', () => { + const item = { + id: 'dashboard-1', + type: 'dashboard', + workspaces: ['ws-1'], + attributes: {}, + references: [], + meta: { + title: `My-Dashboard-test`, + icon: 'indexPatternApp', + editUrl: '/management/opensearch-dashboards/objects/savedDashboards/dashboard-1', + inAppUrl: { + path: '/app/dashboards#/view/dashboard-1', + uiCapabilitiesPath: 'dashboard.show', + }, + }, + }; + const props = { + ...defaultProps, + availableWorkspaces: [{ id: 'ws-1', name: 'My workspace' } as WorkspaceAttribute], + items: [item], + }; + const component = shallowWithI18nProvider(); + + const table = component.find('EuiBasicTable'); + const columns = table.prop('columns') as any[]; + const content = columns[1].render('My-Dashboard-test', item); + expect(content.props.href).toEqual('/w/ws-1/app/dashboards#/view/dashboard-1'); + }); + it('should handle query parse error', () => { const onQueryChangeMock = jest.fn(); const customizedProps = { diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/table.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/table.tsx index 636933d449df..a80c0a0fd15d 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/table.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/table.tsx @@ -28,7 +28,7 @@ * under the License. */ -import { IBasePath } from 'src/core/public'; +import { IBasePath, WorkspaceAttribute } from 'src/core/public'; import React, { PureComponent, Fragment } from 'react'; import moment from 'moment'; import { @@ -56,6 +56,7 @@ import { SavedObjectsManagementAction, SavedObjectsManagementColumnServiceStart, } from '../../../services'; +import { WORKSPACE_PATH_PREFIX } from '../../../../../../core/public/utils'; export interface TableProps { basePath: IBasePath; @@ -83,6 +84,7 @@ export interface TableProps { onShowRelationships: (object: SavedObjectWithMetadata) => void; canGoInApp: (obj: SavedObjectWithMetadata) => boolean; dateFormat: string; + availableWorkspaces?: WorkspaceAttribute[]; } interface TableState { @@ -177,8 +179,11 @@ export class Table extends PureComponent { columnRegistry, namespaceRegistry, dateFormat, + availableWorkspaces, } = this.props; + const visibleWsIds = availableWorkspaces?.map((ws) => ws.id) || []; + const pagination = { pageIndex, pageSize, @@ -226,13 +231,20 @@ export class Table extends PureComponent { sortable: false, 'data-test-subj': 'savedObjectsTableRowTitle', render: (title: string, object: SavedObjectWithMetadata) => { - const { path = '' } = object.meta.inAppUrl || {}; + let { path = '' } = object.meta.inAppUrl || {}; const canGoInApp = this.props.canGoInApp(object); if (!canGoInApp) { return {title || getDefaultTitle(object)}; } + if (object.workspaces?.length) { + // first workspace login user have permission + const [workspaceId] = object.workspaces.filter((wsId) => visibleWsIds.includes(wsId)); + path = workspaceId ? `${WORKSPACE_PATH_PREFIX}/${workspaceId}${path}` : path; + } return ( - {title || getDefaultTitle(object)} + + {title || getDefaultTitle(object)} + ); }, } as EuiTableFieldDataColumnType>, diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx index 5a6bf0713d95..455ca884098b 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx @@ -48,6 +48,7 @@ import { notificationServiceMock, savedObjectsServiceMock, applicationServiceMock, + workspacesServiceMock, } from '../../../../../core/public/mocks'; import { dataPluginMock } from '../../../../data/public/mocks'; import { serviceRegistryMock } from '../../services/service_registry.mock'; @@ -102,6 +103,7 @@ describe('SavedObjectsTable', () => { let notifications: ReturnType; let savedObjects: ReturnType; let search: ReturnType['search']; + let workspaces: ReturnType; const shallowRender = (overrides: Partial = {}) => { return (shallowWithI18nProvider( @@ -121,6 +123,7 @@ describe('SavedObjectsTable', () => { notifications = notificationServiceMock.createStartContract(); savedObjects = savedObjectsServiceMock.createStartContract(); search = dataPluginMock.createStartContract().search; + workspaces = workspacesServiceMock.createStartContract(); const applications = applicationServiceMock.createStartContract(); applications.capabilities = { @@ -154,6 +157,7 @@ describe('SavedObjectsTable', () => { savedObjectsClient: savedObjects.client, indexPatterns: dataPluginMock.createStartContract().indexPatterns, http, + workspaces, overlays, notifications, applications, diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx index 2f78f307d165..ce2792486b6b 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx @@ -61,11 +61,14 @@ import { FormattedMessage } from '@osd/i18n/react'; import { SavedObjectsClientContract, SavedObjectsFindOptions, + WorkspacesStart, HttpStart, OverlayStart, NotificationsStart, ApplicationStart, + WorkspaceAttribute, } from 'src/core/public'; +import { Subscription } from 'rxjs'; import { RedirectAppLinks } from '../../../../opensearch_dashboards_react/public'; import { IndexPatternsContract } from '../../../../data/public'; import { @@ -106,6 +109,7 @@ export interface SavedObjectsTableProps { savedObjectsClient: SavedObjectsClientContract; indexPatterns: IndexPatternsContract; http: HttpStart; + workspaces: WorkspacesStart; search: DataPublicPluginStart['search']; overlays: OverlayStart; notifications: NotificationsStart; @@ -121,7 +125,7 @@ export interface SavedObjectsTableState { page: number; perPage: number; savedObjects: SavedObjectWithMetadata[]; - savedObjectCounts: Record; + savedObjectCounts: Record>; activeQuery: Query; selectedSavedObjects: SavedObjectWithMetadata[]; isShowingImportFlyout: boolean; @@ -135,23 +139,31 @@ export interface SavedObjectsTableState { exportAllOptions: ExportAllOption[]; exportAllSelectedOptions: Record; isIncludeReferencesDeepChecked: boolean; + currentWorkspaceId: string | null; + availableWorkspaces?: WorkspaceAttribute[]; + workspaceEnabled: boolean; } export class SavedObjectsTable extends Component { private _isMounted = false; + private currentWorkspaceIdSubscription?: Subscription; + private workspacesSubscription?: Subscription; + private workspacesEnabledSubscription?: Subscription; constructor(props: SavedObjectsTableProps) { super(props); + const typeCounts = props.allowedTypes.reduce((typeToCountMap, type) => { + typeToCountMap[type] = 0; + return typeToCountMap; + }, {} as Record); + this.state = { totalCount: 0, page: 0, perPage: props.perPageConfig || 50, savedObjects: [], - savedObjectCounts: props.allowedTypes.reduce((typeToCountMap, type) => { - typeToCountMap[type] = 0; - return typeToCountMap; - }, {} as Record), + savedObjectCounts: { type: typeCounts } as Record>, activeQuery: Query.parse(''), selectedSavedObjects: [], isShowingImportFlyout: false, @@ -165,11 +177,49 @@ export class SavedObjectsTable extends Component ws.id); + } else { + return [currentWorkspaceId]; + } + } + } + + private get wsNameIdLookup() { + const { availableWorkspaces } = this.state; + // Assumption: workspace name is unique across the system + return availableWorkspaces?.reduce((map, ws) => { + return map.set(ws.name, ws.id); + }, new Map()); + } + + private formatWorkspaceIdParams( + obj: T + ): T | Omit { + const { workspaces, ...others } = obj; + if (workspaces) { + return obj; + } + return others; + } + componentDidMount() { this._isMounted = true; + + this.fetchWorkspace(); this.fetchSavedObjects(); this.fetchCounts(); } @@ -177,25 +227,36 @@ export class SavedObjectsTable extends Component { const { allowedTypes, namespaceRegistry } = this.props; - const { queryText, visibleTypes, visibleNamespaces } = parseQuery(this.state.activeQuery); + const { queryText, visibleTypes, visibleNamespaces, visibleWorkspaces } = parseQuery( + this.state.activeQuery + ); const filteredTypes = filterQuery(allowedTypes, visibleTypes); const availableNamespaces = namespaceRegistry.getAll()?.map((ns) => ns.id) || []; - const filteredCountOptions: SavedObjectCountOptions = { + const filteredCountOptions: SavedObjectCountOptions = this.formatWorkspaceIdParams({ typesToInclude: filteredTypes, searchString: queryText, - }; + workspaces: this.workspaceIdQuery, + }); if (availableNamespaces.length) { const filteredNamespaces = filterQuery(availableNamespaces, visibleNamespaces); filteredCountOptions.namespacesToInclude = filteredNamespaces; } + if (visibleWorkspaces?.length) { + filteredCountOptions.workspaces = visibleWorkspaces.map( + (wsName) => this.wsNameIdLookup?.get(wsName) || '' + ); + } // These are the saved objects visible in the table. const filteredSavedObjectCounts = await getSavedObjectCounts( @@ -244,6 +305,23 @@ export class SavedObjectsTable extends Component { + const workspace = this.props.workspaces; + this.currentWorkspaceIdSubscription = workspace.currentWorkspaceId$.subscribe((workspaceId) => + this.setState({ + currentWorkspaceId: workspaceId, + }) + ); + + this.workspacesSubscription = workspace.workspaceList$.subscribe((workspaceList) => { + this.setState({ availableWorkspaces: workspaceList }); + }); + + this.workspacesEnabledSubscription = workspace.workspaceEnabled$.subscribe((enabled) => { + this.setState({ workspaceEnabled: enabled }); + }); + }; + fetchSavedObject = (type: string, id: string) => { this.setState({ isSearching: true }, () => this.debouncedFetchObject(type, id)); }; @@ -251,17 +329,18 @@ export class SavedObjectsTable extends Component { const { activeQuery: query, page, perPage } = this.state; const { notifications, http, allowedTypes, namespaceRegistry } = this.props; - const { queryText, visibleTypes, visibleNamespaces } = parseQuery(query); + const { queryText, visibleTypes, visibleNamespaces, visibleWorkspaces } = parseQuery(query); const filteredTypes = filterQuery(allowedTypes, visibleTypes); // "searchFields" is missing from the "findOptions" but gets injected via the API. // The API extracts the fields from each uiExports.savedObjectsManagement "defaultSearchField" attribute - const findOptions: SavedObjectsFindOptions = { + const findOptions: SavedObjectsFindOptions = this.formatWorkspaceIdParams({ search: queryText ? `${queryText}*` : undefined, perPage, page: page + 1, fields: ['id'], type: filteredTypes, - }; + workspaces: this.workspaceIdQuery, + }); const availableNamespaces = namespaceRegistry.getAll()?.map((ns) => ns.id) || []; if (availableNamespaces.length) { @@ -269,6 +348,13 @@ export class SavedObjectsTable extends Component this.wsNameIdLookup?.get(wsName) || '' + ); + findOptions.workspaces = workspaceIds; + } + if (findOptions.type.length > 1) { findOptions.sortField = 'type'; } @@ -796,6 +882,9 @@ export class SavedObjectsTable extends Component { + return this.workspaceIdQuery?.includes(ws.id); + }) + .map((ws) => { + return { + name: ws.name, + value: ws.name, + view: `${ws.name} (${wsCounts[ws.id] || 0})`, + }; + }); + + filters.push({ + type: 'field_value_selection', + field: 'workspaces', + name: + namespaceRegistry.getAlias() || + i18n.translate('savedObjectsManagement.objectsTable.table.workspaceFilterName', { + defaultMessage: 'Workspaces', + }), + multiSelect: 'or', + options: wsFilterOptions, + }); + } + + // workspace enable and no workspace is selected + const hideImport = workspaceEnabled && !workspaceId; + return ( {this.renderFlyout()} @@ -857,6 +977,7 @@ export class SavedObjectsTable extends Component @@ -871,7 +992,7 @@ export class SavedObjectsTable extends Component diff --git a/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx b/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx index 09937388ba57..8796605d9d1d 100644 --- a/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx +++ b/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx @@ -85,6 +85,7 @@ const SavedObjectsTablePage = ({ indexPatterns={dataStart.indexPatterns} search={dataStart.search} http={coreStart.http} + workspaces={coreStart.workspaces} overlays={coreStart.overlays} notifications={coreStart.notifications} applications={coreStart.application} diff --git a/src/plugins/saved_objects_management/server/routes/scroll_count.ts b/src/plugins/saved_objects_management/server/routes/scroll_count.ts index 63233748a896..fc5237805378 100644 --- a/src/plugins/saved_objects_management/server/routes/scroll_count.ts +++ b/src/plugins/saved_objects_management/server/routes/scroll_count.ts @@ -41,12 +41,13 @@ export const registerScrollForCountRoute = (router: IRouter) => { typesToInclude: schema.arrayOf(schema.string()), namespacesToInclude: schema.maybe(schema.arrayOf(schema.string())), searchString: schema.maybe(schema.string()), + workspaces: schema.maybe(schema.arrayOf(schema.string())), }), }, }, router.handleLegacyErrors(async (context, req, res) => { const { client } = context.core.savedObjects; - const counts = { + const counts: Record> = { type: {}, }; @@ -58,11 +59,18 @@ export const registerScrollForCountRoute = (router: IRouter) => { const requestHasNamespaces = Array.isArray(req.body.namespacesToInclude) && req.body.namespacesToInclude.length; + const requestHasWorkspaces = Array.isArray(req.body.workspaces) && req.body.workspaces.length; + if (requestHasNamespaces) { counts.namespaces = {}; findOptions.namespaces = req.body.namespacesToInclude; } + if (requestHasWorkspaces) { + counts.workspaces = {}; + findOptions.workspaces = req.body.workspaces; + } + if (req.body.searchString) { findOptions.search = `${req.body.searchString}*`; findOptions.searchFields = ['title']; @@ -82,6 +90,13 @@ export const registerScrollForCountRoute = (router: IRouter) => { counts.namespaces[ns]++; }); } + if (requestHasWorkspaces) { + const resultWorkspaces = result.workspaces || []; + resultWorkspaces.forEach((ws) => { + counts.workspaces[ws] = counts.workspaces[ws] || 0; + counts.workspaces[ws]++; + }); + } counts.type[type] = counts.type[type] || 0; counts.type[type]++; }); @@ -99,6 +114,13 @@ export const registerScrollForCountRoute = (router: IRouter) => { } } + const workspacesToInclude = req.body.workspaces || []; + for (const ws of workspacesToInclude) { + if (!counts.workspaces[ws]) { + counts.workspaces[ws] = 0; + } + } + return res.ok({ body: counts, }); diff --git a/src/plugins/workspace/opensearch_dashboards.json b/src/plugins/workspace/opensearch_dashboards.json index ea2fe1cbed49..8f015fd55fe4 100644 --- a/src/plugins/workspace/opensearch_dashboards.json +++ b/src/plugins/workspace/opensearch_dashboards.json @@ -4,6 +4,6 @@ "server": true, "ui": true, "requiredPlugins": [], - "optionalPlugins": [], + "optionalPlugins": ["savedObjectsManagement"], "requiredBundles": [] } diff --git a/src/plugins/workspace/public/components/utils/workspace_column.tsx b/src/plugins/workspace/public/components/utils/workspace_column.tsx new file mode 100644 index 000000000000..0d1899959cfe --- /dev/null +++ b/src/plugins/workspace/public/components/utils/workspace_column.tsx @@ -0,0 +1,53 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { EuiText } from '@elastic/eui'; +import useObservable from 'react-use/lib/useObservable'; +import { i18n } from '@osd/i18n'; +import { WorkspaceAttribute, CoreSetup } from '../../../../../core/public'; +import { + SavedObjectsManagementColumn, + SavedObjectsManagementRecord, +} from '../../../../saved_objects_management/public'; + +interface WorkspaceColumnProps { + coreSetup: CoreSetup; + workspaces?: string[]; + record: SavedObjectsManagementRecord; +} + +function WorkspaceColumn({ coreSetup, workspaces, record }: WorkspaceColumnProps) { + const workspaceList = useObservable(coreSetup.workspaces.workspaceList$); + + const wsLookUp = workspaceList?.reduce((map, ws) => { + return map.set(ws.id, ws.name); + }, new Map()); + + const workspaceNames = workspaces?.map((wsId) => wsLookUp?.get(wsId)).join(' | '); + + return {workspaceNames}; +} + +export function getWorkspaceColumn( + coreSetup: CoreSetup +): SavedObjectsManagementColumn { + return { + id: 'workspace_column', + euiColumn: { + align: 'left', + field: 'workspaces', + name: i18n.translate('savedObjectsManagement.objectsTable.table.columnWorkspacesName', { + defaultMessage: 'Workspaces', + }), + render: (workspaces: string[], record: SavedObjectsManagementRecord) => { + return ; + }, + }, + loadData: () => { + return Promise.resolve(undefined); + }, + }; +} diff --git a/src/plugins/workspace/public/plugin.ts b/src/plugins/workspace/public/plugin.ts index 933afa5858be..b9839aa04621 100644 --- a/src/plugins/workspace/public/plugin.ts +++ b/src/plugins/workspace/public/plugin.ts @@ -2,10 +2,22 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ -import { Plugin } from '../../../core/public'; +import { SavedObjectsManagementPluginSetup } from 'src/plugins/saved_objects_management/public'; +import { CoreSetup, Plugin } from '../../../core/public'; +import { getWorkspaceColumn } from './components/utils/workspace_column'; + +interface WorkspacePluginSetupDeps { + savedObjectsManagement?: SavedObjectsManagementPluginSetup; +} export class WorkspacePlugin implements Plugin<{}, {}, {}> { - public async setup() { + public async setup(core: CoreSetup, { savedObjectsManagement }: WorkspacePluginSetupDeps) { + core.workspaces.workspaceEnabled$.next(true); + /** + * register workspace column into saved objects table + */ + savedObjectsManagement?.columns.register(getWorkspaceColumn(core)); + return {}; }