diff --git a/src/core/public/rendering/_base.scss b/src/core/public/rendering/_base.scss
index e59008f08259..1333e48f6ca5 100644
--- a/src/core/public/rendering/_base.scss
+++ b/src/core/public/rendering/_base.scss
@@ -5,7 +5,6 @@
*/
// SASSTODO: Naming here is too embedded and high up that changing them could cause major breaks
#opensearch-dashboards-body {
- overflow-x: hidden;
min-height: 100%;
}
diff --git a/src/core/public/rendering/app_containers.test.tsx b/src/core/public/rendering/app_containers.test.tsx
index fd43c79514c1..157253f5f757 100644
--- a/src/core/public/rendering/app_containers.test.tsx
+++ b/src/core/public/rendering/app_containers.test.tsx
@@ -43,6 +43,7 @@ describe('AppWrapper', () => {
expect(component.getDOMNode()).toMatchInlineSnapshot(`
app-content
@@ -53,6 +54,7 @@ describe('AppWrapper', () => {
expect(component.getDOMNode()).toMatchInlineSnapshot(`
app-content
@@ -63,6 +65,7 @@ describe('AppWrapper', () => {
expect(component.getDOMNode()).toMatchInlineSnapshot(`
app-content
diff --git a/src/core/public/rendering/app_containers.tsx b/src/core/public/rendering/app_containers.tsx
index dab85769bd0b..8ccf795f8dcf 100644
--- a/src/core/public/rendering/app_containers.tsx
+++ b/src/core/public/rendering/app_containers.tsx
@@ -37,7 +37,11 @@ export const AppWrapper: React.FunctionComponent<{
chromeVisible$: Observable;
}> = ({ chromeVisible$, children }) => {
const visible = useObservable(chromeVisible$);
- return {children}
;
+ return (
+
+ {children}
+
+ );
};
export const AppContainer: React.FunctionComponent<{
diff --git a/src/plugins/advanced_settings/public/management_app/_advanced_settings.scss b/src/plugins/advanced_settings/public/management_app/_advanced_settings.scss
index 82704fc93062..a33082c3ef64 100644
--- a/src/plugins/advanced_settings/public/management_app/_advanced_settings.scss
+++ b/src/plugins/advanced_settings/public/management_app/_advanced_settings.scss
@@ -76,7 +76,3 @@
.mgtAdvancedSettingsForm__button {
width: 100%;
}
-
-.osdBody--mgtAdvancedSettingsHasBottomBar .mgtPage__body {
- padding-bottom: $euiSizeXL * 2;
-}
diff --git a/src/plugins/advanced_settings/public/management_app/components/form/form.test.tsx b/src/plugins/advanced_settings/public/management_app/components/form/form.test.tsx
index 650d8b259f0c..09e9d642977c 100644
--- a/src/plugins/advanced_settings/public/management_app/components/form/form.test.tsx
+++ b/src/plugins/advanced_settings/public/management_app/components/form/form.test.tsx
@@ -29,6 +29,7 @@
*/
import React from 'react';
+import ReactDOM from 'react-dom';
import { shallowWithI18nProvider, mountWithI18nProvider } from 'test_utils/enzyme_helpers';
import { UiSettingsType } from '../../../../../../core/public';
@@ -38,6 +39,11 @@ import { notificationServiceMock } from '../../../../../../core/public/mocks';
import { SettingsChanges } from '../../types';
import { Form } from './form';
+jest.mock('react-dom', () => ({
+ ...jest.requireActual('react-dom'),
+ createPortal: jest.fn((element) => element),
+}));
+
jest.mock('../field', () => ({
Field: () => {
return 'field';
@@ -45,6 +51,8 @@ jest.mock('../field', () => ({
}));
beforeAll(() => {
+ ReactDOM.createPortal = jest.fn((children: any) => children);
+
const localStorage: Record = {
'core.chrome.isLocked': true,
};
@@ -60,6 +68,7 @@ beforeAll(() => {
});
afterAll(() => {
+ (ReactDOM.createPortal as jest.Mock).mockClear();
delete (window as any).localStorage;
});
diff --git a/src/plugins/advanced_settings/public/management_app/components/form/form.tsx b/src/plugins/advanced_settings/public/management_app/components/form/form.tsx
index 92b7a792d2d2..a74199771d2a 100644
--- a/src/plugins/advanced_settings/public/management_app/components/form/form.tsx
+++ b/src/plugins/advanced_settings/public/management_app/components/form/form.tsx
@@ -47,8 +47,9 @@ import {
import { FormattedMessage } from '@osd/i18n/react';
import { isEmpty } from 'lodash';
import { i18n } from '@osd/i18n';
+import { DocLinksStart, ToastsStart } from 'opensearch-dashboards/public';
+import { createPortal } from 'react-dom';
import { toMountPoint } from '../../../../../opensearch_dashboards_react/public';
-import { DocLinksStart, ToastsStart } from '../../../../../../core/public';
import { getCategoryName } from '../../lib';
import { Field, getEditableValue } from '../field';
@@ -336,63 +337,69 @@ export class Form extends PureComponent {
};
renderBottomBar = () => {
- const areChangesInvalid = this.areChangesInvalid();
- return (
-
-
-
- {this.renderCountOfUnsaved()}
-
-
-
-
- {i18n.translate('advancedSettings.form.cancelButtonLabel', {
- defaultMessage: 'Cancel changes',
- })}
-
-
-
-
-
+
+
+ {this.renderCountOfUnsaved()}
+
+
+
+
- {i18n.translate('advancedSettings.form.saveButtonLabel', {
- defaultMessage: 'Save changes',
+ {i18n.translate('advancedSettings.form.cancelButtonLabel', {
+ defaultMessage: 'Cancel changes',
})}
-
-
-
-
-
- );
+
+
+
+
+
+ {i18n.translate('advancedSettings.form.saveButtonLabel', {
+ defaultMessage: 'Save changes',
+ })}
+
+
+
+
+
+ );
+
+ return createPortal(bottomBar, document.getElementById('app-wrapper')!);
+ } catch (e) {
+ return null;
+ }
};
render() {
@@ -401,12 +408,6 @@ export class Form extends PureComponent {
const currentCategories: Category[] = [];
const hasUnsavedChanges = !isEmpty(unsavedChanges);
- if (hasUnsavedChanges) {
- document.body.classList.add('osdBody--mgtAdvancedSettingsHasBottomBar');
- } else {
- document.body.classList.remove('osdBody--mgtAdvancedSettingsHasBottomBar');
- }
-
categories.forEach((category) => {
if (visibleSettings[category] && visibleSettings[category].length) {
currentCategories.push(category);