diff --git a/changelogs/fragments/7910.yml b/changelogs/fragments/7910.yml new file mode 100644 index 000000000000..bae53b3d1e62 --- /dev/null +++ b/changelogs/fragments/7910.yml @@ -0,0 +1,2 @@ +refactor: +- Update page header for edit object page ([#7910](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7910)) \ No newline at end of file diff --git a/src/plugins/advanced_settings/public/management_app/mount_management_section.tsx b/src/plugins/advanced_settings/public/management_app/mount_management_section.tsx index 383fc1eb3ccd..608324d0ecb2 100644 --- a/src/plugins/advanced_settings/public/management_app/mount_management_section.tsx +++ b/src/plugins/advanced_settings/public/management_app/mount_management_section.tsx @@ -103,10 +103,22 @@ export async function mountManagementSection( ); + const pagePaddingSize = useUpdatedUX + ? // When useUpdatedUX is enabled, page should align with header vertically. + { + paddingSize: 'm' as const, + } + : {}; + ReactDOM.render( {params.wrapInPage ? ( - + {content} ) : ( diff --git a/src/plugins/saved_objects_management/public/management_section/mount_section.tsx b/src/plugins/saved_objects_management/public/management_section/mount_section.tsx index e26956900627..60060a0d1992 100644 --- a/src/plugins/saved_objects_management/public/management_section/mount_section.tsx +++ b/src/plugins/saved_objects_management/public/management_section/mount_section.tsx @@ -103,6 +103,8 @@ export const mountManagementSection = async ({ serviceRegistry={serviceRegistry} setBreadcrumbs={setBreadcrumbs} history={history} + useUpdatedUX={useUpdatedUX} + navigation={navigation} /> @@ -131,10 +133,22 @@ export const mountManagementSection = async ({ ); + const pageContentPaddingSize = useUpdatedUX + ? // align with new header + { + paddingSize: 'm' as const, + } + : {}; + ReactDOM.render( {mountParams.wrapInPage ? ( - + {content} ) : ( diff --git a/src/plugins/saved_objects_management/public/management_section/object_view/components/__snapshots__/header.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/object_view/components/__snapshots__/header.test.tsx.snap index aa4d039c6ca5..84d7c8a6c078 100644 --- a/src/plugins/saved_objects_management/public/management_section/object_view/components/__snapshots__/header.test.tsx.snap +++ b/src/plugins/saved_objects_management/public/management_section/object_view/components/__snapshots__/header.test.tsx.snap @@ -2,11 +2,57 @@ exports[`Intro component renders correctly 1`] = `
@@ -227,3 +273,258 @@ exports[`Intro component renders correctly 1`] = `
`; + +exports[`Intro component renders correctly when use new UX 1`] = ` +
+ + Delete search + +
+`; + +exports[`Intro component renders correctly when use new UX and canDelete is true 1`] = ` +
+ + Delete search + +
+`; + +exports[`Intro component renders correctly when use new UX and canViewInApp is true 1`] = ` +
+ + Delete search + +
+`; diff --git a/src/plugins/saved_objects_management/public/management_section/object_view/components/header.test.tsx b/src/plugins/saved_objects_management/public/management_section/object_view/components/header.test.tsx index 54b5e6a9aaa8..eb38642b631a 100644 --- a/src/plugins/saved_objects_management/public/management_section/object_view/components/header.test.tsx +++ b/src/plugins/saved_objects_management/public/management_section/object_view/components/header.test.tsx @@ -32,6 +32,9 @@ import React from 'react'; import { mount } from 'enzyme'; import { I18nProvider } from '@osd/i18n/react'; import { Header } from './header'; +import { coreMock } from '../../../../../../core/public/mocks'; +import { ApplicationStart } from '../../../../../../core/public'; +import { NavigationPublicPluginStart } from '../../../../../navigation/public'; describe('Intro component', () => { const mountHeader = (props: { @@ -41,6 +44,9 @@ describe('Intro component', () => { type: string; viewUrl: string; onDeleteClick: () => void; + useUpdatedUX: boolean; + application: ApplicationStart; + navigationUI: NavigationPublicPluginStart['ui']; }) => mount( @@ -55,6 +61,13 @@ describe('Intro component', () => { canViewInApp: true, viewUrl: '/some-url', onDeleteClick: () => undefined, + useUpdatedUX: false, + navigationUI: ({ + HeaderControl: ({ controls }) => { + return controls?.[0].ariaLabel ?? controls?.[0].label ?? null; + }, + } as unknown) as NavigationPublicPluginStart['ui'], + application: coreMock.createStart().application, }; it('renders correctly', () => { @@ -133,4 +146,30 @@ describe('Intro component', () => { }); expect(mounted.exists(`a[data-test-subj='savedObjectEditViewInApp']`)).toBe(false); }); + + it('renders correctly when use new UX', () => { + const mounted = mountHeader({ + ...defaultProps, + useUpdatedUX: true, + }); + expect(mounted).toMatchSnapshot(); + }); + + it('renders correctly when use new UX and canViewInApp is true', () => { + const mounted = mountHeader({ + ...defaultProps, + useUpdatedUX: true, + canViewInApp: true, + }); + expect(mounted).toMatchSnapshot(); + }); + + it('renders correctly when use new UX and canDelete is true', () => { + const mounted = mountHeader({ + ...defaultProps, + useUpdatedUX: true, + canDelete: true, + }); + expect(mounted).toMatchSnapshot(); + }); }); diff --git a/src/plugins/saved_objects_management/public/management_section/object_view/components/header.tsx b/src/plugins/saved_objects_management/public/management_section/object_view/components/header.tsx index c17e1248c953..5f26c7a5b31c 100644 --- a/src/plugins/saved_objects_management/public/management_section/object_view/components/header.tsx +++ b/src/plugins/saved_objects_management/public/management_section/object_view/components/header.tsx @@ -38,6 +38,13 @@ import { EuiText, } from '@elastic/eui'; import { FormattedMessage } from '@osd/i18n/react'; +import { i18n } from '@osd/i18n'; +import { ApplicationStart } from '../../../../../../core/public'; +import { + NavigationPublicPluginStart, + TopNavControlButtonData, + TopNavControlIconData, +} from '../../../../../navigation/public'; interface HeaderProps { canEdit: boolean; @@ -46,6 +53,9 @@ interface HeaderProps { type: string; viewUrl: string; onDeleteClick: () => void; + useUpdatedUX: boolean; + navigationUI: NavigationPublicPluginStart['ui']; + application: ApplicationStart; } export const Header = ({ @@ -55,8 +65,49 @@ export const Header = ({ type, viewUrl, onDeleteClick, + useUpdatedUX, + navigationUI: { HeaderControl }, + application, }: HeaderProps) => { - return ( + return useUpdatedUX ? ( + + ) : ( diff --git a/src/plugins/saved_objects_management/public/management_section/object_view/saved_object_view.tsx b/src/plugins/saved_objects_management/public/management_section/object_view/saved_object_view.tsx index 30627e69084c..badeadfdd3a3 100644 --- a/src/plugins/saved_objects_management/public/management_section/object_view/saved_object_view.tsx +++ b/src/plugins/saved_objects_management/public/management_section/object_view/saved_object_view.tsx @@ -30,9 +30,9 @@ import React, { Component } from 'react'; import { i18n } from '@osd/i18n'; -import { EuiSpacer, EuiPageContent } from '@elastic/eui'; +import { EuiSpacer, EuiPageContent, EuiTitle } from '@elastic/eui'; import { - Capabilities, + ApplicationStart, SavedObjectsClientContract, OverlayStart, NotificationsStart, @@ -45,18 +45,21 @@ import { canViewInApp } from '../../lib'; import { SubmittedFormData } from '../types'; import { UiActionsStart } from '../../../../ui_actions/public'; import { SAVED_OBJECT_DELETE_TRIGGER } from '../../triggers'; +import { NavigationPublicPluginStart } from '../../../../navigation/public'; interface SavedObjectEditionProps { id: string; serviceName: string; serviceRegistry: ISavedObjectsManagementServiceRegistry; - capabilities: Capabilities; overlays: OverlayStart; notifications: NotificationsStart; uiActions: UiActionsStart; notFoundType?: string; savedObjectsClient: SavedObjectsClientContract; history: ScopedHistory; + useUpdatedUX: boolean; + navigationUI: NavigationPublicPluginStart['ui']; + application: ApplicationStart; } interface SavedObjectEditionState { @@ -92,21 +95,23 @@ export class SavedObjectEdition extends Component< render() { const { - capabilities, + application, notFoundType, serviceRegistry, id, serviceName, savedObjectsClient, + useUpdatedUX, + navigationUI, } = this.props; const { type } = this.state; const { object } = this.state; - const { edit: canEdit, delete: canDelete } = capabilities.savedObjectsManagement as Record< - string, - boolean - >; - const canView = canViewInApp(capabilities, type); + const { edit: canEdit, delete: canDelete } = application.capabilities + .savedObjectsManagement as Record; + const canView = canViewInApp(application.capabilities, type); const service = serviceRegistry.get(serviceName)!.service; + const { HeaderControl } = navigationUI; + const typeWithFirstLetterToUpperCase = type.charAt(0).toUpperCase() + type.slice(1); return ( @@ -117,22 +122,56 @@ export class SavedObjectEdition extends Component< type={type} onDeleteClick={() => this.delete()} viewUrl={service.urlFor(id)} + useUpdatedUX={useUpdatedUX} + navigationUI={navigationUI} + application={application} /> - {notFoundType && ( - <> - - - - )} - {canEdit && ( - <> - - - - )} + {notFoundType && + (useUpdatedUX ? ( + , + }, + ]} + setMountPoint={application.setAppBottomControls} + /> + ) : ( + <> + + + + ))} + {canEdit && + (useUpdatedUX ? ( + , + }, + ]} + setMountPoint={application.setAppBottomControls} + /> + ) : ( + <> + + + + ))} {object && ( <> - + {useUpdatedUX ? ( + +

+ {i18n.translate('savedObjectsManagement.view.form.title', { + defaultMessage: '{type} details', + values: { type: typeWithFirstLetterToUpperCase }, + })} +

+
+ ) : ( + + )}
void; history: ScopedHistory; + useUpdatedUX: boolean; + navigation: NavigationPublicPluginStart; }) => { const { service: serviceName, id } = useParams<{ service: string; id: string }>(); - const capabilities = coreStart.application.capabilities; const { search } = useLocation(); const query = parse(search); @@ -60,9 +64,13 @@ const SavedObjectsEditionPage = ({ useEffect(() => { setBreadcrumbs([ { - text: i18n.translate('savedObjectsManagement.breadcrumb.index', { - defaultMessage: 'Saved objects', - }), + text: useUpdatedUX + ? i18n.translate('savedObjectsManagement.breadcrumb.updatedUX.index', { + defaultMessage: 'Assets', + }) + : i18n.translate('savedObjectsManagement.breadcrumb.index', { + defaultMessage: 'Saved objects', + }), href: '/', }, { @@ -72,7 +80,7 @@ const SavedObjectsEditionPage = ({ }), }, ]); - }, [setBreadcrumbs, service]); + }, [setBreadcrumbs, service, useUpdatedUX]); return ( ); };