From 2c770f4b4070defc05e1a217326012741ef211ee Mon Sep 17 00:00:00 2001 From: tygao Date: Tue, 13 Aug 2024 15:12:59 +0800 Subject: [PATCH 1/4] init page headers for workspace Signed-off-by: tygao --- .../management/opensearch_dashboards.json | 3 +- .../__snapshots__/feature_cards.test.tsx.snap | 16 - .../feature_cards/feature_cards.test.tsx | 24 +- .../feature_cards/feature_cards.tsx | 67 +-- .../public/landing_page_application.test.tsx | 5 + src/plugins/management/public/plugin.ts | 58 +- .../workspace/opensearch_dashboards.json | 3 +- .../workspace_creator.test.tsx | 3 + .../workspace_creator/workspace_creator.tsx | 22 +- .../components/workspace_creator_app.tsx | 11 +- .../workspace_detail.test.tsx.snap | 33 -- .../workspace_detail.test.tsx | 2 +- .../workspace_detail/workspace_detail.tsx | 19 +- .../components/workspace_detail_app.tsx | 4 +- .../__snapshots__/index.test.tsx.snap | 536 ++++++++++++++++-- .../components/workspace_list/index.test.tsx | 17 +- .../components/workspace_list/index.tsx | 100 ++-- src/plugins/workspace/public/plugin.ts | 10 +- src/plugins/workspace/public/types.ts | 2 + 19 files changed, 696 insertions(+), 239 deletions(-) diff --git a/src/plugins/management/opensearch_dashboards.json b/src/plugins/management/opensearch_dashboards.json index cf7d7d781f16..eb9a67c09296 100644 --- a/src/plugins/management/opensearch_dashboards.json +++ b/src/plugins/management/opensearch_dashboards.json @@ -4,5 +4,6 @@ "server": true, "ui": true, "optionalPlugins": ["home", "managementOverview"], - "requiredBundles": ["opensearchDashboardsReact", "opensearchDashboardsUtils"] + "requiredBundles": ["opensearchDashboardsReact", "opensearchDashboardsUtils"], + "requiredPlugins": ["navigation"] } diff --git a/src/plugins/management/public/components/feature_cards/__snapshots__/feature_cards.test.tsx.snap b/src/plugins/management/public/components/feature_cards/__snapshots__/feature_cards.test.tsx.snap index 0718fb98bf4f..c0963f0462aa 100644 --- a/src/plugins/management/public/components/feature_cards/__snapshots__/feature_cards.test.tsx.snap +++ b/src/plugins/management/public/components/feature_cards/__snapshots__/feature_cards.test.tsx.snap @@ -2,22 +2,6 @@ exports[` render with complex navLinks 1`] = `
-
-
-
-

-

-
-
null; + const navLinks: ChromeNavLink[] = [ { id: '1', @@ -85,7 +91,13 @@ const navLinks: ChromeNavLink[] = [ describe('', () => { it('render with empty navLinks', () => { const { container } = render( - + ); expect(container).toMatchSnapshot(); }); @@ -93,10 +105,11 @@ describe('', () => { it('render with complex navLinks', () => { const { container, getAllByTestId } = render( ); expect(container).toMatchSnapshot(); @@ -107,10 +120,11 @@ describe('', () => { const mockedNavigateToApp = jest.fn(); const { getByTestId } = render( ); fireEvent.click(getByTestId('landingPageFeature_1')); diff --git a/src/plugins/management/public/components/feature_cards/feature_cards.tsx b/src/plugins/management/public/components/feature_cards/feature_cards.tsx index 57d7e128c928..7c52e6a05fda 100644 --- a/src/plugins/management/public/components/feature_cards/feature_cards.tsx +++ b/src/plugins/management/public/components/feature_cards/feature_cards.tsx @@ -3,42 +3,32 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { i18n } from '@osd/i18n'; import { EuiCard, - EuiFlexGrid, EuiFlexGroup, EuiFlexItem, EuiPageContent, - EuiPageHeader, - EuiPageHeaderSection, - EuiPanel, EuiSpacer, EuiTitle, } from '@elastic/eui'; import { AppCategory, ChromeNavLink, CoreStart } from 'opensearch-dashboards/public'; import React, { useMemo } from 'react'; +import { NavigationPublicPluginStart } from '../../../../../../src/plugins/navigation/public'; export interface FeatureCardsProps { - pageTitle: string; + pageDescription: string; navLinks: ChromeNavLink[]; navigateToApp: CoreStart['application']['navigateToApp']; - getStartedCards: Array<{ - id: string; - title: string; - description: string; - }>; + setAppDescriptionControls: CoreStart['application']['setAppDescriptionControls']; + navigationUI: NavigationPublicPluginStart['ui']; } -const getStartedTitle = i18n.translate('management.gettingStarted.label', { - defaultMessage: 'Get started', -}); - export const FeatureCards = ({ navLinks, navigateToApp, - pageTitle, - getStartedCards, + setAppDescriptionControls, + pageDescription, + navigationUI: { HeaderControl }, }: FeatureCardsProps) => { const itemsPerRow = 4; const groupedCardForDisplay = useMemo(() => { @@ -65,41 +55,14 @@ export const FeatureCards = ({ } return ( <> - - - - -

{pageTitle}

-
-
-
- {getStartedCards.length ? ( - <> - - -

{getStartedTitle}

-
- - {getStartedCards.map((card) => { - return ( - - - navigateToApp(card.id)} - titleSize="xs" - /> - - - ); - })} - - - ) : null} -
+ {groupedCardForDisplay.map((group) => (
diff --git a/src/plugins/management/public/landing_page_application.test.tsx b/src/plugins/management/public/landing_page_application.test.tsx index 13d14ff34609..e8c6f994fff9 100644 --- a/src/plugins/management/public/landing_page_application.test.tsx +++ b/src/plugins/management/public/landing_page_application.test.tsx @@ -4,6 +4,8 @@ */ import { renderApp } from './landing_page_application'; +import { navigationPluginMock } from '../../navigation/public/mocks'; +import { coreMock } from '../../../../src/core/public/mocks'; describe('Landing page application', () => { it('renders and unmount without crashing', () => { @@ -13,6 +15,9 @@ describe('Landing page application', () => { props: { navigateToApp: jest.fn(), navLinks: [], + navigationUI: navigationPluginMock.createStartContract().ui, + setAppDescriptionControls: coreMock.createStart().application.setAppDescriptionControls, + pageDescription: '', }, }); diff --git a/src/plugins/management/public/plugin.ts b/src/plugins/management/public/plugin.ts index ef91e776a962..6242b87289a1 100644 --- a/src/plugins/management/public/plugin.ts +++ b/src/plugins/management/public/plugin.ts @@ -46,7 +46,6 @@ import { AppNavLinkStatus, DEFAULT_NAV_GROUPS, WorkspaceAvailability, - ChromeNavLink, } from '../../../core/public'; import { MANAGEMENT_APP_ID } from '../common/contants'; @@ -62,13 +61,17 @@ import { LinkItemType, getSortedNavLinks, } from '../../../core/public'; +import { NavigationPublicPluginStart } from '../../../../src/plugins/navigation/public'; interface ManagementSetupDependencies { home?: HomePublicPluginSetup; managementOverview?: ManagementOverViewPluginSetup; } - -export class ManagementPlugin implements Plugin { +interface ManagementStartDependencies { + navigation: NavigationPublicPluginStart; +} +export class ManagementPlugin + implements Plugin { private readonly managementSections = new ManagementSectionsService(); private readonly appUpdater = new BehaviorSubject(() => ({})); @@ -81,7 +84,10 @@ export class ManagementPlugin implements Plugin, + { home, managementOverview }: ManagementSetupDependencies + ) { const opensearchDashboardsVersion = this.initializerContext.env.packageInfo.version; core.application.register({ @@ -111,15 +117,30 @@ export class ManagementPlugin implements Plugin { const { renderApp } = await import('./landing_page_application'); - const [coreStart] = await core.getStartServices(); + const [coreStart, { navigation }] = await core.getStartServices(); const navLinks = ( await getNavLinksByNavGroupId(DEFAULT_NAV_GROUPS.settingsAndSetup.id) ).filter((navLink) => navLink.id !== settingsLandingPageId); + coreStart.chrome.setBreadcrumbs([ + { + text: settingsLandingPageTitle, + }, + ]); return renderApp({ mountElement: params.element, props: { navigateToApp: coreStart.application.navigateToApp, + setAppDescriptionControls: coreStart.application.setAppDescriptionControls, navLinks, - pageTitle: settingsLandingPageTitle, - getStartedCards: [], + pageDescription: settingsLandingPageDescription, + navigationUI: navigation.ui, }, }); }, @@ -213,18 +240,25 @@ export class ManagementPlugin implements Plugin { const { renderApp } = await import('./landing_page_application'); - const [coreStart] = await core.getStartServices(); + const [coreStart, { navigation }] = await core.getStartServices(); const navLinks = ( await getNavLinksByNavGroupId(DEFAULT_NAV_GROUPS.dataAdministration.id) ).filter((navLink) => navLink.id !== dataAdministrationLandingPageId); + coreStart.chrome.setBreadcrumbs([ + { + text: dataAdministrationPageTitle, + }, + ]); + return renderApp({ mountElement: params.element, props: { navigateToApp: coreStart.application.navigateToApp, navLinks, - pageTitle: dataAdministrationPageTitle, - getStartedCards: [], + pageDescription: dataAdministrationPageDescription, + navigationUI: navigation.ui, + setAppDescriptionControls: coreStart.application.setAppDescriptionControls, }, }); }, diff --git a/src/plugins/workspace/opensearch_dashboards.json b/src/plugins/workspace/opensearch_dashboards.json index d0b0e0b55ea8..ac24c20d712b 100644 --- a/src/plugins/workspace/opensearch_dashboards.json +++ b/src/plugins/workspace/opensearch_dashboards.json @@ -5,7 +5,8 @@ "ui": true, "requiredPlugins": [ "savedObjects", - "opensearchDashboardsReact" + "opensearchDashboardsReact", + "navigation" ], "optionalPlugins": ["savedObjectsManagement","management","dataSourceManagement","contentManagement"], "requiredBundles": ["opensearchDashboardsReact", "home","dataSource"] diff --git a/src/plugins/workspace/public/components/workspace_creator/workspace_creator.test.tsx b/src/plugins/workspace/public/components/workspace_creator/workspace_creator.test.tsx index 24692db47229..e3463bc7d9f5 100644 --- a/src/plugins/workspace/public/components/workspace_creator/workspace_creator.test.tsx +++ b/src/plugins/workspace/public/components/workspace_creator/workspace_creator.test.tsx @@ -91,6 +91,9 @@ const WorkspaceCreator = ({ }, }, dataSourceManagement: {}, + navigationUI: { + HeaderControl: () => null, + }, }, }); const registeredUseCases$ = new BehaviorSubject([ diff --git a/src/plugins/workspace/public/components/workspace_creator/workspace_creator.tsx b/src/plugins/workspace/public/components/workspace_creator/workspace_creator.tsx index c46d17b701ac..26bed213d142 100644 --- a/src/plugins/workspace/public/components/workspace_creator/workspace_creator.tsx +++ b/src/plugins/workspace/public/components/workspace_creator/workspace_creator.tsx @@ -4,13 +4,7 @@ */ import React, { useCallback } from 'react'; -import { - EuiPage, - EuiPageBody, - EuiPageHeader, - EuiPageContent, - euiPaletteColorBlind, -} from '@elastic/eui'; +import { EuiPage, EuiPageBody, EuiPageContent, euiPaletteColorBlind } from '@elastic/eui'; import { i18n } from '@osd/i18n'; import { useObservable } from 'react-use'; import { BehaviorSubject } from 'rxjs'; @@ -25,6 +19,7 @@ import { DataSource } from '../../../common/types'; import { DataSourceManagementPluginSetup } from '../../../../../plugins/data_source_management/public'; import { WorkspaceUseCase } from '../../types'; import { WorkspaceFormData } from '../workspace_form/types'; +import { NavigationPublicPluginStart } from '../../../../../plugins/navigation/public'; export interface WorkspaceCreatorProps { registeredUseCases$: BehaviorSubject; @@ -39,10 +34,12 @@ export const WorkspaceCreator = (props: WorkspaceCreatorProps) => { workspaceClient, savedObjects, dataSourceManagement, + navigationUI: { HeaderControl }, }, } = useOpenSearchDashboards<{ workspaceClient: WorkspaceClient; dataSourceManagement?: DataSourceManagementPluginSetup; + navigationUI: NavigationPublicPluginStart['ui']; }>(); const defaultWorkspaceFormValues: Partial = { @@ -102,8 +99,17 @@ export const WorkspaceCreator = (props: WorkspaceCreatorProps) => { return ( + - { const { - services: { chrome }, + services: { chrome, application }, } = useOpenSearchDashboards(); /** * set breadcrumbs to chrome */ useEffect(() => { + const homeBreadcrumb = { + text: i18n.translate('core.breadcrumbs.homeTitle', { defaultMessage: 'Home' }), + onClick: () => { + application?.navigateToApp('home'); + }, + }; chrome?.setBreadcrumbs([ + homeBreadcrumb, { text: i18n.translate('workspace.workspaceCreateTitle', { defaultMessage: 'Create a workspace', }), }, ]); - }, [chrome]); + }, [chrome, application]); return ( diff --git a/src/plugins/workspace/public/components/workspace_detail/__snapshots__/workspace_detail.test.tsx.snap b/src/plugins/workspace/public/components/workspace_detail/__snapshots__/workspace_detail.test.tsx.snap index 562eadabefd7..e6da2eebcf46 100644 --- a/src/plugins/workspace/public/components/workspace_detail/__snapshots__/workspace_detail.test.tsx.snap +++ b/src/plugins/workspace/public/components/workspace_detail/__snapshots__/workspace_detail.test.tsx.snap @@ -2,39 +2,6 @@ exports[`WorkspaceDetail render workspace detail page normally 1`] = `
-
-
-
-
-
-

-
-
- foo -
-
-

-
-
-
-
-
diff --git a/src/plugins/workspace/public/components/workspace_detail/workspace_detail.test.tsx b/src/plugins/workspace/public/components/workspace_detail/workspace_detail.test.tsx index 20f739273182..d27f0187e5b1 100644 --- a/src/plugins/workspace/public/components/workspace_detail/workspace_detail.test.tsx +++ b/src/plugins/workspace/public/components/workspace_detail/workspace_detail.test.tsx @@ -95,7 +95,7 @@ describe('WorkspaceDetail', () => { it('default selected tab is overview', async () => { const workspaceService = createWorkspacesSetupContractMockWithValue(workspaceObject); render(WorkspaceDetailPage({ workspacesService: workspaceService })); - expect(screen.queryByText('foo')).not.toBeNull(); + expect(screen.queryByTestId('workspaceTabs')).not.toBeNull(); expect(document.querySelector('#overview')).toHaveClass('euiTab-isSelected'); }); diff --git a/src/plugins/workspace/public/components/workspace_detail/workspace_detail.tsx b/src/plugins/workspace/public/components/workspace_detail/workspace_detail.tsx index 348414eba46d..59098a5e7219 100644 --- a/src/plugins/workspace/public/components/workspace_detail/workspace_detail.tsx +++ b/src/plugins/workspace/public/components/workspace_detail/workspace_detail.tsx @@ -4,15 +4,7 @@ */ import React from 'react'; -import { - EuiPage, - EuiPageBody, - EuiPageHeader, - EuiFlexItem, - EuiTabbedContent, - EuiFlexGroup, - EuiPanel, -} from '@elastic/eui'; +import { EuiPage, EuiPageBody, EuiTabbedContent } from '@elastic/eui'; import { useObservable } from 'react-use'; import { i18n } from '@osd/i18n'; @@ -40,12 +32,6 @@ export const WorkspaceDetail = (props: WorkspaceDetailProps) => { return null; } - const pageTitle = ( - - {currentWorkspace?.name} - - ); - const detailTabs = [ { id: DetailTab.Overview, @@ -86,9 +72,6 @@ export const WorkspaceDetail = (props: WorkspaceDetailProps) => { return ( <> - - - { text: currentWorkspace.name, }); breadcrumbs.push({ - text: i18n.translate('workspace.detail.breadcrumb', { defaultMessage: 'Workspace Detail' }), + text: `${currentWorkspace.name} ${i18n.translate('workspace.detail.title', { + defaultMessage: 'settings', + })}`, }); } chrome?.setBreadcrumbs(breadcrumbs); diff --git a/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap b/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap index 32283810c139..0e11d07cf53f 100644 --- a/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap +++ b/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap @@ -5,41 +5,30 @@ exports[`WorkspaceList should render title and table normally 1`] = `
-
-
-
+ -
-
-

- Workspaces -

-
-
-

- Workspace allow you to save and organize library items, such as index patterns, visualizations, dashboards, saved searches, and share them with other OpenSearch Dashboards users. You can control which features are visible in each workspace, and which users and groups have read and write access to the library items in the workspace. -

-
-
-
-
-
+ Create workspace + + + +
+ +
+ Name +
+
+ + + +
+ + +
+ ID +
+
+ + id1 + +
+ + +
+ Description +
+
+ +
+ + +
+ Use case +
+
+ Analytics (All) +
+ + +
+ + + + Edit + + + + + + Delete + + +
+ + + + +
+ Name +
+
+ + + +
+ + +
+ ID +
+
+ + id2 + +
+ + +
+ Description +
+
+ +
+ + +
+ Use case +
+
+ + +
+ + + + Edit + + + + + + Delete + + +
+ + + +
+ Name +
+
+ + + +
+ +
+ ID +
+
- No items found + id3 + +
+ + +
+ Description +
+
+ +
+ + +
+ Use case +
+
+ Observability +
+ + +
+ + + + Edit + + + + + + Delete +
@@ -273,6 +629,112 @@ exports[`WorkspaceList should render title and table normally 1`] = `
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
diff --git a/src/plugins/workspace/public/components/workspace_list/index.test.tsx b/src/plugins/workspace/public/components/workspace_list/index.test.tsx index bbff833da7b1..2284008d9d36 100644 --- a/src/plugins/workspace/public/components/workspace_list/index.test.tsx +++ b/src/plugins/workspace/public/components/workspace_list/index.test.tsx @@ -39,11 +39,18 @@ function getWrapWorkspaceListInContext( }, }; + const mockHeaderControl = ({ controls }) => { + return controls?.[0].description ?? controls?.[0].renderComponent ?? null; + }; + const services = { ...coreStartMock, workspaces: { workspaceList$: of(workspaceList), }, + navigationUI: { + HeaderControl: mockHeaderControl, + }, }; return ( @@ -59,12 +66,10 @@ function getWrapWorkspaceListInContext( describe('WorkspaceList', () => { it('should render title and table normally', () => { - const { getByText, getByRole, container } = render( - - ); - expect(getByText('Workspaces')).toBeInTheDocument(); + const { getByText, getByRole, container } = render(getWrapWorkspaceListInContext()); + expect( + getByText('Organize collaborative projects with use-case-specific workspaces.') + ).toBeInTheDocument(); expect(getByRole('table')).toBeInTheDocument(); expect(container).toMatchSnapshot(); }); diff --git a/src/plugins/workspace/public/components/workspace_list/index.tsx b/src/plugins/workspace/public/components/workspace_list/index.tsx index 3d6604122e48..6f0a4a38c81c 100644 --- a/src/plugins/workspace/public/components/workspace_list/index.tsx +++ b/src/plugins/workspace/public/components/workspace_list/index.tsx @@ -7,7 +7,6 @@ import React, { useState, useMemo, useCallback } from 'react'; import { EuiPage, EuiPageBody, - EuiPageHeader, EuiPageContent, EuiLink, EuiSmallButton, @@ -28,11 +27,7 @@ import { cleanWorkspaceId } from '../../../../../core/public'; import { DeleteWorkspaceModal } from '../delete_workspace_modal'; import { getFirstUseCaseOfFeatureConfigs } from '../../utils'; import { WorkspaceUseCase } from '../../types'; - -const WORKSPACE_LIST_PAGE_DESCRIPTION = i18n.translate('workspace.list.description', { - defaultMessage: - 'Workspace allow you to save and organize library items, such as index patterns, visualizations, dashboards, saved searches, and share them with other OpenSearch Dashboards users. You can control which features are visible in each workspace, and which users and groups have read and write access to the library items in the workspace.', -}); +import { NavigationPublicPluginStart } from '../../../../../plugins/navigation/public'; export interface WorkspaceListProps { registeredUseCases$: BehaviorSubject; @@ -40,8 +35,15 @@ export interface WorkspaceListProps { export const WorkspaceList = ({ registeredUseCases$ }: WorkspaceListProps) => { const { - services: { workspaces, application, http }, - } = useOpenSearchDashboards(); + services: { + workspaces, + application, + http, + navigationUI: { HeaderControl }, + }, + } = useOpenSearchDashboards<{ + navigationUI: NavigationPublicPluginStart['ui']; + }>(); const registeredUseCases = useObservable(registeredUseCases$); const isDashboardAdmin = application?.capabilities?.dashboards?.isDashboardAdmin; @@ -79,6 +81,41 @@ export const WorkspaceList = ({ registeredUseCases$ }: WorkspaceListProps) => { return workspaceList; }, [workspaceList, queryInput]); + const workspaceCreateUrl = useMemo(() => { + if (!application || !http) { + return ''; + } + + const appUrl = application.getUrlForApp(WORKSPACE_CREATE_APP_ID, { + absolute: false, + }); + if (!appUrl) return ''; + + return cleanWorkspaceId(appUrl); + }, [application, http]); + + const renderCreateWorkspaceButton = () => { + if (!isDashboardAdmin) return null; + const button = ( + + {i18n.translate('workspace.list.buttons.createWorkspace', { + defaultMessage: 'Create workspace', + })} + + ); + return ( + + ); + }; + const columns = [ { field: 'name', @@ -143,19 +180,6 @@ export const WorkspaceList = ({ registeredUseCases$ }: WorkspaceListProps) => { }, ]; - const workspaceCreateUrl = useMemo(() => { - if (!application || !http) { - return ''; - } - - const appUrl = application.getUrlForApp(WORKSPACE_CREATE_APP_ID, { - absolute: false, - }); - if (!appUrl) return ''; - - return cleanWorkspaceId(appUrl); - }, [application, http]); - const debouncedSetQueryInput = useMemo(() => { return debounce(setQueryInput, 300); }, [setQueryInput]); @@ -172,36 +196,26 @@ export const WorkspaceList = ({ registeredUseCases$ }: WorkspaceListProps) => { box: { incremental: true, }, - toolsRight: [ - ...(isDashboardAdmin - ? [ - - {i18n.translate('workspace.workspaceList.buttons.createWorkspace', { - defaultMessage: 'Create workspace', - })} - , - ] - : []), - ], }; return ( + + {renderCreateWorkspaceButton()} - , { savedObjectsManagement, management, dataSourceManagement }: WorkspacePluginSetupDeps ) { const workspaceClient = new WorkspaceClient(core.http, core.workspaces); @@ -295,11 +297,13 @@ export class WorkspacePlugin } const mountWorkspaceApp = async (params: AppMountParameters, renderApp: WorkspaceAppType) => { - const [coreStart] = await core.getStartServices(); + const [coreStart, { navigation }] = await core.getStartServices(); + const services = { ...coreStart, workspaceClient, dataSourceManagement, + navigationUI: navigation.ui, }; return renderApp(params, services, { @@ -431,7 +435,7 @@ export class WorkspacePlugin }); } - public start(core: CoreStart, { contentManagement }: WorkspacePluginStartDeps) { + public start(core: CoreStart, { contentManagement, navigation }: WorkspacePluginStartDeps) { this.coreStart = core; this.currentWorkspaceIdSubscription = this._changeSavedObjectCurrentWorkspace(); diff --git a/src/plugins/workspace/public/types.ts b/src/plugins/workspace/public/types.ts index 79fed7fa81ac..d5cfc224416f 100644 --- a/src/plugins/workspace/public/types.ts +++ b/src/plugins/workspace/public/types.ts @@ -6,10 +6,12 @@ import { CoreStart } from '../../../core/public'; import { WorkspaceClient } from './workspace_client'; import { DataSourceManagementPluginSetup } from '../../../plugins/data_source_management/public'; +import { NavigationPublicPluginStart } from '../../../plugins/navigation/public'; export type Services = CoreStart & { workspaceClient: WorkspaceClient; dataSourceManagement?: DataSourceManagementPluginSetup; + navigationUI?: NavigationPublicPluginStart['ui']; }; export interface WorkspaceUseCase { From 52a3e1d5347bb8ac515b2b075e760358c97f73c7 Mon Sep 17 00:00:00 2001 From: tygao Date: Wed, 14 Aug 2024 17:23:45 +0800 Subject: [PATCH 2/4] update Signed-off-by: tygao --- .../workspace/public/components/workspace_detail_app.tsx | 9 ++++++--- .../workspace/public/components/workspace_list/index.tsx | 7 +++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/plugins/workspace/public/components/workspace_detail_app.tsx b/src/plugins/workspace/public/components/workspace_detail_app.tsx index d1b6ad50c932..1185f0c66d8f 100644 --- a/src/plugins/workspace/public/components/workspace_detail_app.tsx +++ b/src/plugins/workspace/public/components/workspace_detail_app.tsx @@ -36,9 +36,12 @@ export const WorkspaceDetailApp = (props: WorkspaceDetailProps) => { text: currentWorkspace.name, }); breadcrumbs.push({ - text: `${currentWorkspace.name} ${i18n.translate('workspace.detail.title', { - defaultMessage: 'settings', - })}`, + text: i18n.translate('workspace.detail.title', { + defaultMessage: '{name} settings', + values: { + name: currentWorkspace.name, + }, + }), }); } chrome?.setBreadcrumbs(breadcrumbs); diff --git a/src/plugins/workspace/public/components/workspace_list/index.tsx b/src/plugins/workspace/public/components/workspace_list/index.tsx index 6f0a4a38c81c..af439ee891eb 100644 --- a/src/plugins/workspace/public/components/workspace_list/index.tsx +++ b/src/plugins/workspace/public/components/workspace_list/index.tsx @@ -82,7 +82,7 @@ export const WorkspaceList = ({ registeredUseCases$ }: WorkspaceListProps) => { }, [workspaceList, queryInput]); const workspaceCreateUrl = useMemo(() => { - if (!application || !http) { + if (!application) { return ''; } @@ -92,10 +92,9 @@ export const WorkspaceList = ({ registeredUseCases$ }: WorkspaceListProps) => { if (!appUrl) return ''; return cleanWorkspaceId(appUrl); - }, [application, http]); + }, [application]); const renderCreateWorkspaceButton = () => { - if (!isDashboardAdmin) return null; const button = ( { ]} setMountPoint={application?.setAppDescriptionControls} /> - {renderCreateWorkspaceButton()} + {isDashboardAdmin && renderCreateWorkspaceButton()} Date: Wed, 14 Aug 2024 17:54:32 +0800 Subject: [PATCH 3/4] update list page Signed-off-by: tygao --- .../__snapshots__/index.test.tsx.snap | 1147 ++++++++--------- .../components/workspace_list/index.tsx | 63 +- 2 files changed, 600 insertions(+), 610 deletions(-) diff --git a/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap b/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap index 0e11d07cf53f..86989c4bbf25 100644 --- a/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap +++ b/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap @@ -3,7 +3,7 @@ exports[`WorkspaceList should render title and table normally 1`] = `
Organize collaborative projects with use-case-specific workspaces.
-
-
+
+
+
- -
- -
+ aria-hidden="true" + class="euiFormControlLayoutCustomIcon__icon" + data-euiicon-type="search" + /> +
-
-
-
+
+
+
+
+
+
-
-
- -
+ +
- - - - - - + +
-
- - - - + + + + - + - + - - - - + + - + + + + + - + - - + + + - - - - + + + - + - + - + + - - - - + + + - + - - + + + - - -
+
+ + + + + - - Actions - + Description -
- -
- Name -
-
- - - -
-
+ + + + -
- ID -
-
+ +
+
+ Name +
+
+ - - id1 - -
-
+ + + +
-
- Description -
-
- -
-
+
-
- Use case -
-
- Analytics (All) -
-
+ + +
-
+
+ +
+
+
+ Use case +
+
+ Analytics (All) +
+
+
+ - - - Edit - - + aria-hidden="true" + class="euiButtonIcon__icon" + color="inherit" + data-euiicon-type="pencil" + /> + - - - Delete - + Edit -
-
-
- Name -
-
+ + - + Delete -
-
+ +
+
-
- ID -
-
+
+ - - id2 - -
-
+ + + +
-
- Description -
-
- -
-
+
-
- Use case -
-
+
+
+
+ Description +
+
+ -
+ +
-
+
+
+
+ - - - Edit - - + aria-hidden="true" + class="euiButtonIcon__icon" + color="inherit" + data-euiicon-type="pencil" + /> + - - - Delete - + Edit -
-
-
- Name -
-
+ + - + Delete -
-
+ +
+
-
- ID -
-
+
+ - - id3 - -
-
+ + + +
-
- Description -
-
- -
-
+
-
- Use case -
-
- Observability -
-
+ + +
-
+
+ +
+
+
+ Use case +
+
+ Observability +
+
+
+ - - - Edit - - + aria-hidden="true" + class="euiButtonIcon__icon" + color="inherit" + data-euiicon-type="pencil" + /> + + Edit + + + + - Delete - + aria-hidden="true" + class="euiButtonIcon__icon" + color="inherit" + data-euiicon-type="trash" + /> + + + Delete -
-
- -
-
+ +
+ +
+
+
+
+
-
- -
+ +
-
+
+
+ + + + + +
diff --git a/src/plugins/workspace/public/components/workspace_list/index.tsx b/src/plugins/workspace/public/components/workspace_list/index.tsx index af439ee891eb..931862b919a7 100644 --- a/src/plugins/workspace/public/components/workspace_list/index.tsx +++ b/src/plugins/workspace/public/components/workspace_list/index.tsx @@ -6,7 +6,6 @@ import React, { useState, useMemo, useCallback } from 'react'; import { EuiPage, - EuiPageBody, EuiPageContent, EuiLink, EuiSmallButton, @@ -23,7 +22,6 @@ import { navigateToWorkspaceDetail } from '../utils/workspace'; import { WORKSPACE_CREATE_APP_ID } from '../../../common/constants'; -import { cleanWorkspaceId } from '../../../../../core/public'; import { DeleteWorkspaceModal } from '../delete_workspace_modal'; import { getFirstUseCaseOfFeatureConfigs } from '../../utils'; import { WorkspaceUseCase } from '../../types'; @@ -91,7 +89,7 @@ export const WorkspaceList = ({ registeredUseCases$ }: WorkspaceListProps) => { }); if (!appUrl) return ''; - return cleanWorkspaceId(appUrl); + return appUrl; }, [application]); const renderCreateWorkspaceButton = () => { @@ -198,7 +196,7 @@ export const WorkspaceList = ({ registeredUseCases$ }: WorkspaceListProps) => { }; return ( - + { setMountPoint={application?.setAppDescriptionControls} /> {isDashboardAdmin && renderCreateWorkspaceButton()} - - - - setPagination((prev) => { - return { ...prev, pageIndex: index, pageSize: size }; - }) - } - pagination={pagination} - sorting={{ - sort: { - field: initialSortField, - direction: initialSortDirection, - }, - }} - isSelectable={true} - search={search} - /> - - + + + setPagination((prev) => { + return { ...prev, pageIndex: index, pageSize: size }; + }) + } + pagination={pagination} + sorting={{ + sort: { + field: initialSortField, + direction: initialSortDirection, + }, + }} + isSelectable={true} + search={search} + /> + {deletedWorkspace && ( Date: Wed, 14 Aug 2024 09:55:50 +0000 Subject: [PATCH 4/4] Changeset file for PR #7697 created/updated --- changelogs/fragments/7697.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/7697.yml diff --git a/changelogs/fragments/7697.yml b/changelogs/fragments/7697.yml new file mode 100644 index 000000000000..df490d5ed68a --- /dev/null +++ b/changelogs/fragments/7697.yml @@ -0,0 +1,2 @@ +feat: +- Integrate new page header for workspace pages ([#7697](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7697)) \ No newline at end of file