Reducing wrapping divs from RenderingService (#97017)

* Reducing wrapping divs from RenderingService

* Applying more styles to .kbnAppWrapper

Some being temporary and will need a better solution when introducing the page layout component

* Almost fixing tests for rendering service

Can’t figure out how to have a optional Observable
`Received: "kbnAppWrapper class-name”`

* Adding some comments

* [Dashboard] Using the APP_WRAPPER_CLASS

* fix test & ts types

* Fixin a few more tests that were using `.app-wrapper`

* Creating docs for new var and cleaning up some selectors

* Fixing reporting

* Fixing banner position and truncation

* Fixed CSS error in loading screen and jump in animation

* Fixing selectors in Canvas

* Remove unused var

* Added `APP_WRAPPER_CLASS` export from `server` and updated reporting to use it

* Fix monitoring icon clicks

* move APP_WRAPPER_CLASS definition to src/core/common

* Fixing Monitoring snapshots and wrapper class

* Moved `APP_WRAPPER_CLASS` utils but exported from `public` and `server`

* Remove old folder

* Fix dashboard test by only showing HR in edit mode

Co-authored-by: pgayvallet
Co-authored-by:  tsullivan
This commit is contained in:
Caroline Horn 2021-04-26 16:06:06 -04:00 committed by GitHub
parent 509d75bcfe
commit f07ebc822f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 239 additions and 200 deletions

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-public](./kibana-plugin-core-public.md) &gt; [APP\_WRAPPER\_CLASS](./kibana-plugin-core-public.app_wrapper_class.md)
## APP\_WRAPPER\_CLASS variable
The class name for top level \*and\* nested application wrappers to ensure proper layout
<b>Signature:</b>
```typescript
APP_WRAPPER_CLASS = "kbnAppWrapper"
```

View file

@ -138,6 +138,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| Variable | Description |
| --- | --- |
| [APP\_WRAPPER\_CLASS](./kibana-plugin-core-public.app_wrapper_class.md) | The class name for top level \*and\* nested application wrappers to ensure proper layout |
| [URL\_MAX\_LENGTH](./kibana-plugin-core-public.url_max_length.md) | The max URL length allowed by the current browser. Should be used to display warnings to users when query parameters cause URL to exceed this limit. |
## Type Aliases

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [APP\_WRAPPER\_CLASS](./kibana-plugin-core-server.app_wrapper_class.md)
## APP\_WRAPPER\_CLASS variable
The class name for top level \*and\* nested application wrappers to ensure proper layout
<b>Signature:</b>
```typescript
APP_WRAPPER_CLASS = "kbnAppWrapper"
```

View file

@ -230,6 +230,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| Variable | Description |
| --- | --- |
| [APP\_WRAPPER\_CLASS](./kibana-plugin-core-server.app_wrapper_class.md) | The class name for top level \*and\* nested application wrappers to ensure proper layout |
| [kibanaResponseFactory](./kibana-plugin-core-server.kibanaresponsefactory.md) | Set of helpers used to create <code>KibanaResponse</code> to form HTTP response on an incoming request. Should be returned as a result of [RequestHandler](./kibana-plugin-core-server.requesthandler.md) execution. |
| [ServiceStatusLevels](./kibana-plugin-core-server.servicestatuslevels.md) | The current "level" of availability of a service. |
| [validBodyOutput](./kibana-plugin-core-server.validbodyoutput.md) | The set of valid body.output |

View file

@ -1,6 +1,7 @@
.header__topBanner {
position: fixed;
top: 0;
left: 0;
height: $kbnHeaderBannerHeight;
width: 100%;
z-index: $euiZHeader;

View file

@ -199,7 +199,7 @@ describe('#start()', () => {
root.innerHTML = '<p>foo bar</p>';
await startCore(root);
expect(root.innerHTML).toMatchInlineSnapshot(
`"<div id=\\"kibana-body\\"></div><div></div><div></div>"`
`"<div id=\\"kibana-body\\" data-test-subj=\\"kibanaChrome\\"></div><div></div><div></div>"`
);
});

View file

@ -176,6 +176,7 @@ export class CoreSystem {
const coreUiTargetDomElement = document.createElement('div');
coreUiTargetDomElement.id = 'kibana-body';
coreUiTargetDomElement.dataset.testSubj = 'kibanaChrome';
const notificationsTargetDomElement = document.createElement('div');
const overlayTargetDomElement = document.createElement('div');

View file

@ -74,7 +74,7 @@ export type {
DomainDeprecationDetails,
} from '../server/types';
export type { CoreContext, CoreSystem } from './core_system';
export { DEFAULT_APP_CATEGORIES } from '../utils';
export { DEFAULT_APP_CATEGORIES, APP_WRAPPER_CLASS } from '../utils';
export type {
AppCategory,
UiSettingsParams,

View file

@ -1,7 +1,3 @@
.kbnGlobalBannerList {
padding: $euiSize;
}
.kbnGlobalBannerList__item + .kbnGlobalBannerList__item {
margin-top: $euiSizeS;
}

View file

@ -73,6 +73,9 @@ export interface App<HistoryLocationState = unknown> {
updater$?: Observable<AppUpdater>;
}
// @public
export const APP_WRAPPER_CLASS = "kbnAppWrapper";
// @public
export interface AppCategory {
ariaLabel?: string;

View file

@ -1,16 +1,20 @@
@import '../mixins';
/**
* stretch the root element of the Kibana application to set the base-size that
* Stretch the root element of the Kibana application to set the base-size that
* flexed children should keep. Only works when paired with root styles applied
* by core service from new platform
*/
// SASSTODO: Naming here is too embedded and high up that changing them could cause major breaks
#kibana-body {
overflow-x: hidden;
// DO NOT ADD ANY OVERFLOW BEHAVIORS HERE
// It will break the sticky navigation
min-height: 100%;
display: flex;
flex-direction: column;
}
// Affixes a div to restrict the position of charts tooltip to the visible viewport minus the header
#app-fixed-viewport {
pointer-events: none;
visibility: hidden;
@ -21,26 +25,17 @@
left: 0;
}
.app-wrapper {
.kbnAppWrapper {
// DO NOT ADD ANY OTHER STYLES TO THIS SELECTOR
// This a very nested dependency happnening in "all" apps
display: flex;
flex-flow: column nowrap;
margin: 0 auto;
@include kibanaFullBodyMinHeight();
}
.app-wrapper-panel {
display: flex;
flex-grow: 1;
flex-shrink: 0;
flex-basis: auto;
flex-direction: column;
> * {
flex-shrink: 0;
}
z-index: 0; // This effectively puts every high z-index inside the scope of this wrapper to it doesn't interfere with the header and/or overlay mask
position: relative; // This is temporary for apps that relied on this being present on `.application`
}
// TODO: This is problematic because it doesn't stay in line with EUI:
// adapted from euiHeaderAffordForFixed as we need to handle the top banner
@mixin kbnAffordForHeader($headerHeight) {
padding-top: $headerHeight;

View file

@ -6,21 +6,25 @@
* Side Public License, v 1.
*/
import { BehaviorSubject } from 'rxjs';
import { BehaviorSubject, of } from 'rxjs';
import { act } from 'react-dom/test-utils';
import { mount } from 'enzyme';
import React from 'react';
import { AppWrapper, AppContainer } from './app_containers';
import { AppWrapper } from './app_containers';
describe('AppWrapper', () => {
it('toggles the `hidden-chrome` class depending on the chrome visibility state', () => {
const chromeVisible$ = new BehaviorSubject<boolean>(true);
const component = mount(<AppWrapper chromeVisible$={chromeVisible$}>app-content</AppWrapper>);
const component = mount(
<AppWrapper chromeVisible$={chromeVisible$} classes$={of([])}>
app-content
</AppWrapper>
);
expect(component.getDOMNode()).toMatchInlineSnapshot(`
<div
class="app-wrapper"
class="kbnAppWrapper"
>
app-content
</div>
@ -30,7 +34,7 @@ describe('AppWrapper', () => {
component.update();
expect(component.getDOMNode()).toMatchInlineSnapshot(`
<div
class="app-wrapper hidden-chrome"
class="kbnAppWrapper kbnAppWrapper--hiddenChrome"
>
app-content
</div>
@ -40,22 +44,25 @@ describe('AppWrapper', () => {
component.update();
expect(component.getDOMNode()).toMatchInlineSnapshot(`
<div
class="app-wrapper"
class="kbnAppWrapper"
>
app-content
</div>
`);
});
});
describe('AppContainer', () => {
it('adds classes supplied by chrome', () => {
const chromeVisible$ = new BehaviorSubject<boolean>(true);
const appClasses$ = new BehaviorSubject<string[]>([]);
const component = mount(<AppContainer classes$={appClasses$}>app-content</AppContainer>);
const component = mount(
<AppWrapper chromeVisible$={chromeVisible$} classes$={appClasses$}>
app-content
</AppWrapper>
);
expect(component.getDOMNode()).toMatchInlineSnapshot(`
<div
class="application"
class="kbnAppWrapper"
>
app-content
</div>
@ -65,7 +72,7 @@ describe('AppContainer', () => {
component.update();
expect(component.getDOMNode()).toMatchInlineSnapshot(`
<div
class="application classA classB"
class="kbnAppWrapper classA classB"
>
app-content
</div>
@ -75,7 +82,7 @@ describe('AppContainer', () => {
component.update();
expect(component.getDOMNode()).toMatchInlineSnapshot(`
<div
class="application classC"
class="kbnAppWrapper classC"
>
app-content
</div>
@ -85,7 +92,7 @@ describe('AppContainer', () => {
component.update();
expect(component.getDOMNode()).toMatchInlineSnapshot(`
<div
class="application"
class="kbnAppWrapper"
>
app-content
</div>

View file

@ -10,17 +10,23 @@ import React from 'react';
import { Observable } from 'rxjs';
import useObservable from 'react-use/lib/useObservable';
import classNames from 'classnames';
import { APP_WRAPPER_CLASS } from '../../utils';
export const AppWrapper: React.FunctionComponent<{
chromeVisible$: Observable<boolean>;
}> = ({ chromeVisible$, children }) => {
const visible = useObservable(chromeVisible$);
return <div className={classNames('app-wrapper', { 'hidden-chrome': !visible })}>{children}</div>;
};
export const AppContainer: React.FunctionComponent<{
classes$: Observable<string[]>;
}> = ({ classes$, children }) => {
const classes = useObservable(classes$);
return <div className={classNames('application', classes)}>{children}</div>;
}> = ({ chromeVisible$, classes$, children }) => {
const visible = useObservable(chromeVisible$);
const classes = useObservable(classes$, ['']);
return (
<div
className={classNames(
APP_WRAPPER_CLASS,
{ 'kbnAppWrapper--hiddenChrome': !visible },
classes
)}
>
{children}
</div>
);
};

View file

@ -13,7 +13,7 @@ import { RenderingService } from './rendering_service';
import { applicationServiceMock } from '../application/application_service.mock';
import { chromeServiceMock } from '../chrome/chrome_service.mock';
import { overlayServiceMock } from '../overlays/overlay_service.mock';
import { BehaviorSubject } from 'rxjs';
import { BehaviorSubject, of } from 'rxjs';
describe('RenderingService#start', () => {
let application: ReturnType<typeof applicationServiceMock.createInternalStartContract>;
@ -28,6 +28,7 @@ describe('RenderingService#start', () => {
chrome = chromeServiceMock.createStartContract();
chrome.getHeaderComponent.mockReturnValue(<div>Hello chrome!</div>);
chrome.getApplicationClasses$.mockReturnValue(of([]));
overlays = overlayServiceMock.createStartContract();
overlays.banners.getComponent.mockReturnValue(<div>I&apos;m a banner!</div>);
@ -48,54 +49,58 @@ describe('RenderingService#start', () => {
it('renders application service into provided DOM element', () => {
startService();
expect(targetDomElement.querySelector('div.application')).toMatchInlineSnapshot(`
<div
class="application class-name"
>
<div>
Hello application!
</div>
</div>
`);
expect(targetDomElement.querySelector('div.kbnAppWrapper')).toMatchInlineSnapshot(`
<div
class="kbnAppWrapper kbnAppWrapper--hiddenChrome"
>
<div
id="app-fixed-viewport"
/>
<div>
Hello application!
</div>
</div>
`);
});
it('adds the `chrome-hidden` class to the AppWrapper when chrome is hidden', () => {
it('adds the `kbnAppWrapper--hiddenChrome` class to the AppWrapper when chrome is hidden', () => {
const isVisible$ = new BehaviorSubject(true);
chrome.getIsVisible$.mockReturnValue(isVisible$);
startService();
const appWrapper = targetDomElement.querySelector('div.app-wrapper')!;
expect(appWrapper.className).toEqual('app-wrapper');
const appWrapper = targetDomElement.querySelector('div.kbnAppWrapper')!;
expect(appWrapper.className).toEqual('kbnAppWrapper');
act(() => isVisible$.next(false));
expect(appWrapper.className).toEqual('app-wrapper hidden-chrome');
expect(appWrapper.className).toEqual('kbnAppWrapper kbnAppWrapper--hiddenChrome');
act(() => isVisible$.next(true));
expect(appWrapper.className).toEqual('app-wrapper');
expect(appWrapper.className).toEqual('kbnAppWrapper');
});
it('adds the application classes to the AppContainer', () => {
it('adds the application classes to the AppWrapper', () => {
const applicationClasses$ = new BehaviorSubject<string[]>([]);
const isVisible$ = new BehaviorSubject(true);
chrome.getIsVisible$.mockReturnValue(isVisible$);
chrome.getApplicationClasses$.mockReturnValue(applicationClasses$);
startService();
const appContainer = targetDomElement.querySelector('div.application')!;
expect(appContainer.className).toEqual('application');
const appContainer = targetDomElement.querySelector('div.kbnAppWrapper')!;
expect(appContainer.className).toEqual('kbnAppWrapper');
act(() => applicationClasses$.next(['classA', 'classB']));
expect(appContainer.className).toEqual('application classA classB');
expect(appContainer.className).toEqual('kbnAppWrapper classA classB');
act(() => applicationClasses$.next(['classC']));
expect(appContainer.className).toEqual('application classC');
expect(appContainer.className).toEqual('kbnAppWrapper classC');
act(() => applicationClasses$.next([]));
expect(appContainer.className).toEqual('application');
expect(appContainer.className).toEqual('kbnAppWrapper');
});
it('contains wrapper divs', () => {
startService();
expect(targetDomElement.querySelector('div.app-wrapper')).toBeDefined();
expect(targetDomElement.querySelector('div.app-wrapper-pannel')).toBeDefined();
expect(targetDomElement.querySelector('div.kbnAppWrapper')).toBeDefined();
});
it('renders the banner UI', () => {

View file

@ -14,7 +14,7 @@ import { pairwise, startWith } from 'rxjs/operators';
import { InternalChromeStart } from '../chrome';
import { InternalApplicationStart } from '../application';
import { OverlayStart } from '../overlays';
import { AppWrapper, AppContainer } from './app_containers';
import { AppWrapper } from './app_containers';
interface StartDeps {
application: InternalApplicationStart;
@ -48,16 +48,25 @@ export class RenderingService {
ReactDOM.render(
<I18nProvider>
<div className="content" data-test-subj="kibanaChrome">
<>
{/* Fixed headers */}
{chromeHeader}
<AppWrapper chromeVisible$={chrome.getIsVisible$()}>
<div className="app-wrapper-panel">
<div id="app-fixed-viewport" />
<div id="globalBannerList">{bannerComponent}</div>
<AppContainer classes$={chrome.getApplicationClasses$()}>{appComponent}</AppContainer>
</div>
{/* banners$.subscribe() for things like the No data banner */}
<div id="globalBannerList">{bannerComponent}</div>
{/* The App Wrapper outside of the fixed headers that accepts custom class names from apps */}
<AppWrapper
chromeVisible$={chrome.getIsVisible$()}
classes$={chrome.getApplicationClasses$()}
>
{/* Affixes a div to restrict the position of charts tooltip to the visible viewport minus the header */}
<div id="app-fixed-viewport" />
{/* The actual plugin/app */}
{appComponent}
</AppWrapper>
</div>
</>
</I18nProvider>,
targetDomElement
);

View file

@ -6,7 +6,7 @@
// In order to override the TM (Textmate) theme of Ace/Brace, everywhere,
// it is being scoped by a known outer selector
.application {
.kbnBody {
.ace-tm {
$aceBackground: tintOrShade($euiColorLightShade, 50%, 0);

View file

@ -5,29 +5,6 @@
// Grab some nav-specific EUI vars
@import '@elastic/eui/src/components/collapsible_nav/variables';
// Application Layout
.application,
.app-container {
> * {
position: relative;
}
}
.application {
position: relative;
z-index: 0;
display: flex;
flex-grow: 1;
flex-shrink: 0;
flex-basis: auto;
flex-direction: column;
> * {
flex-shrink: 0;
}
}
// We apply brute force focus states to anything not coming from Eui
// which has focus states designed at the component level.
// You can also use "kbn-resetFocusState" to not apply the default focus

View file

@ -397,7 +397,7 @@ export type {
} from './deprecations';
export type { AppCategory } from '../types';
export { DEFAULT_APP_CATEGORIES } from '../utils';
export { DEFAULT_APP_CATEGORIES, APP_WRAPPER_CLASS } from '../utils';
export type {
SavedObject,

View file

@ -89,8 +89,7 @@ const InlineStyles: FC<{ darkMode: boolean }> = ({ darkMode }) => {
}
.kbnWelcomeText {
font-family:
display: inline-block;
display: block;
font-size: 14px;
font-family: sans-serif;
line-height: 40px !important;
@ -103,7 +102,7 @@ const InlineStyles: FC<{ darkMode: boolean }> = ({ darkMode }) => {
text-align: center;
line-height: 1;
text-align: center;
font-faimily: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial !important;
font-family: sans-serif;
letter-spacing: -.005em;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;

View file

@ -175,6 +175,9 @@ import { URL } from 'url';
export { AddConfigDeprecation }
// @public
export const APP_WRAPPER_CLASS = "kbnAppWrapper";
// @public
export interface AppCategory {
ariaLabel?: string;

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
/**
* The class name for top level *and* nested application wrappers to ensure proper layout
* @public
*/
export const APP_WRAPPER_CLASS = 'kbnAppWrapper';

View file

@ -7,3 +7,4 @@
*/
export { DEFAULT_APP_CATEGORIES } from './default_app_categories';
export { APP_WRAPPER_CLASS } from './app_wrapper_class';

View file

@ -1,9 +1,3 @@
.dshAppContainer {
display: flex;
flex-direction: column;
flex: 1;
}
.dashboardViewport {
flex: 1;
display: flex;

View file

@ -303,7 +303,7 @@ export function DashboardApp({
}, [data.search.session]);
return (
<div className="app-container dshAppContainer">
<>
{savedDashboard && dashboardStateManager && dashboardContainer && viewMode && (
<>
<DashboardTopNav
@ -334,6 +334,6 @@ export function DashboardApp({
</div>
</>
)}
</div>
</>
);
}

View file

@ -620,36 +620,38 @@ export function DashboardTopNav({
return (
<>
<TopNavMenu {...getNavBarProps()} />
<EuiHorizontalRule margin="none" />
{viewMode !== ViewMode.VIEW ? (
<SolutionToolbar isDarkModeEnabled={IS_DARK_THEME}>
{{
primaryActionButton: (
<PrimaryActionButton
isDarkModeEnabled={IS_DARK_THEME}
label={i18n.translate('dashboard.solutionToolbar.addPanelButtonLabel', {
defaultMessage: 'Create visualization',
})}
onClick={createNewVisType(lensAlias)}
iconType="lensApp"
data-test-subj="dashboardAddNewPanelButton"
/>
),
quickButtonGroup: <QuickButtonGroup buttons={quickButtons} />,
addFromLibraryButton: (
<AddFromLibraryButton
onClick={addFromLibrary}
data-test-subj="dashboardAddPanelButton"
/>
),
extraButtons: [
<EditorMenu
createNewVisType={createNewVisType}
dashboardContainer={dashboardContainer}
/>,
],
}}
</SolutionToolbar>
<>
<EuiHorizontalRule margin="none" />
<SolutionToolbar isDarkModeEnabled={IS_DARK_THEME}>
{{
primaryActionButton: (
<PrimaryActionButton
isDarkModeEnabled={IS_DARK_THEME}
label={i18n.translate('dashboard.solutionToolbar.addPanelButtonLabel', {
defaultMessage: 'Create visualization',
})}
onClick={createNewVisType(lensAlias)}
iconType="lensApp"
data-test-subj="dashboardAddNewPanelButton"
/>
),
quickButtonGroup: <QuickButtonGroup buttons={quickButtons} />,
addFromLibraryButton: (
<AddFromLibraryButton
onClick={addFromLibrary}
data-test-subj="dashboardAddPanelButton"
/>
),
extraButtons: [
<EditorMenu
createNewVisType={createNewVisType}
dashboardContainer={dashboardContainer}
/>,
],
}}
</SolutionToolbar>
</>
) : null}
</>
);

View file

@ -12,6 +12,7 @@ import { filter, map } from 'rxjs/operators';
import { Start as InspectorStartContract } from 'src/plugins/inspector/public';
import { UrlForwardingSetup, UrlForwardingStart } from 'src/plugins/url_forwarding/public';
import { APP_WRAPPER_CLASS } from '../../../core/public';
import {
App,
Plugin,
@ -292,7 +293,7 @@ export class DashboardPlugin
category: DEFAULT_APP_CATEGORIES.kibana,
mount: async (params: AppMountParameters) => {
this.currentHistory = params.history;
params.element.classList.add('dshAppContainer');
params.element.classList.add(APP_WRAPPER_CLASS);
const { mountApp } = await import('./application/dashboard_router');
appMounted();
return mountApp({

View file

@ -25,7 +25,7 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
expect(await testSubjects.exists('kbnLoadingMessage')).to.be(false);
const getAppWrapperHeight = async () => {
const wrapper = await find.byClassName('app-wrapper');
const wrapper = await find.byClassName('kbnAppWrapper');
return (await wrapper.getSize()).height;
};

View file

@ -25,7 +25,7 @@ export const Banner: FC<BannerProps> = ({ bannerConfig }) => {
color: textColor,
}}
>
<div data-test-subj="bannerInnerWrapper">
<div className="eui-textTruncate" data-test-subj="bannerInnerWrapper">
<Markdown markdown={textContent} openLinksInNewTab={true} />
</div>
</div>

View file

@ -5,10 +5,6 @@ body.canvas-isFullscreen {
padding-top: 0;
}
.headerWrapper ~ .app-wrapper {
min-height: 100vh;
}
// following rule is for docked navigation
&.euiBody--collapsibleNavIsDocked {
padding-left: 0 !important; // sass-lint:disable-line no-important

View file

@ -86,7 +86,7 @@ export class Popover extends Component<Props, State> {
return button(handleClick);
};
const appWrapper = document.querySelector('.app-wrapper');
const appWrapper = document.querySelector('.kbnAppWrapper');
const EuiPopoverAny = (EuiPopover as any) as React.FC<any>;
return (

View file

@ -10,10 +10,10 @@ import { uiRoutes } from './helpers/routes';
import { Legacy } from '../legacy_shims';
import { configureAppAngularModule } from '../../../../../src/plugins/kibana_legacy/public';
import { localAppModule, appModuleName } from './app_modules';
import { APP_WRAPPER_CLASS } from '../../../../../src/core/public';
import { MonitoringStartPluginDependencies } from '../types';
const APP_WRAPPER_CLASS = 'monApplicationWrapper';
export class AngularApp {
private injector?: angular.auto.IInjectorService;

View file

@ -31,13 +31,19 @@ exports[`Node Listing Metric Cell should format a non-percentage metric 1`] = `
<div
class="euiPopover__anchor"
>
<span
data-euiicon-type="arrowDown"
<button
aria-label="More information about this metric"
class="euiButtonIcon euiButtonIcon--text euiButtonIcon--empty euiButtonIcon--xSmall"
data-test-subj="monitoringCellIcon-testCell2"
role="button"
tabindex="0"
title="More information about this metric"
/>
type="button"
>
<span
aria-hidden="true"
class="euiButtonIcon__icon"
data-euiicon-type="sortDown"
/>
</button>
</div>
</div>
</div>
@ -78,13 +84,19 @@ exports[`Node Listing Metric Cell should format a percentage metric 1`] = `
<div
class="euiPopover__anchor"
>
<span
data-euiicon-type="arrowDown"
<button
aria-label="More information about this metric"
class="euiButtonIcon euiButtonIcon--text euiButtonIcon--empty euiButtonIcon--xSmall"
data-test-subj="monitoringCellIcon-testCell"
role="button"
tabindex="0"
title="More information about this metric"
/>
type="button"
>
<span
aria-hidden="true"
class="euiButtonIcon__icon"
data-euiicon-type="sortDown"
/>
</button>
</div>
</div>
</div>

View file

@ -11,10 +11,9 @@ import { formatMetric } from '../../../lib/format_number';
import {
EuiText,
EuiPopover,
EuiIcon,
EuiButtonIcon,
EuiDescriptionList,
EuiSpacer,
EuiKeyboardAccessible,
EuiFlexGroup,
EuiFlexItem,
} from '@elastic/eui';
@ -40,7 +39,7 @@ const getDirection = (slope) => {
const getIcon = (slope) => {
if (slope || slope === 0) {
return slope > 0 ? 'arrowUp' : 'arrowDown';
return slope > 0 ? 'sortUp' : 'sortDown';
}
return null;
};
@ -83,17 +82,22 @@ function MetricCell({ isOnline, metric = {}, isPercent, ...props }) {
},
];
const iconLabel = i18n.translate(
'xpack.monitoring.elasticsearch.node.cells.tooltip.iconLabel',
{
defaultMessage: 'More information about this metric',
}
);
const button = (
<EuiKeyboardAccessible>
<EuiIcon
onClick={onButtonClick}
type={getIcon(slope)}
data-test-subj={`monitoringCellIcon-${props['data-test-subj']}`}
title={i18n.translate('xpack.monitoring.elasticsearch.node.cells.tooltip.iconLabel', {
defaultMessage: 'More information about this metric',
})}
/>
</EuiKeyboardAccessible>
<EuiButtonIcon
color="text"
onClick={onButtonClick}
iconType={getIcon(slope)}
data-test-subj={`monitoringCellIcon-${props['data-test-subj']}`}
title={iconLabel}
aria-label={iconLabel}
/>
);
return (

View file

@ -6,9 +6,3 @@
// monChart__legend
// monChart__legend--small
// monChart__legend-isLoading
.monApplicationWrapper {
display: flex;
flex-direction: column;
flex-grow: 1;
}

View file

@ -23,11 +23,6 @@ filter-bar,
display: none !important;
}
/* override open/closed positioning of the app wrapper/nav */
.app-wrapper {
left: 0px !important;
}
/**
* Discover Tweaks
*/

View file

@ -23,11 +23,6 @@ filter-bar,
display: none !important;
}
/* override open/closed positioning of the app wrapper/nav */
.app-wrapper {
left: 0px !important;
}
/**
* Discover Tweaks
*/

View file

@ -5,7 +5,8 @@
* 2.0.
*/
export const DEFAULT_PAGELOAD_SELECTOR = '.application';
import { APP_WRAPPER_CLASS } from '../../../../../../src/core/server';
export const DEFAULT_PAGELOAD_SELECTOR = `.${APP_WRAPPER_CLASS}`;
export const CONTEXT_GETNUMBEROFITEMS = 'GetNumberOfItems';
export const CONTEXT_GETBROWSERDIMENSIONS = 'GetBrowserDimensions';

View file

@ -204,7 +204,7 @@ describe('Screenshot Observable Pipeline', () => {
expect(mockOpen.mock.calls.length).toBe(2);
const firstSelector = mockOpen.mock.calls[0][1].waitForSelector;
expect(firstSelector).toBe('.application');
expect(firstSelector).toBe('.kbnAppWrapper');
const secondSelector = mockOpen.mock.calls[1][1].waitForSelector;
expect(secondSelector).toBe('[data-shared-page="2"]');

View file

@ -7,6 +7,7 @@
import { i18n } from '@kbn/i18n';
import { ReportingCore } from '../..';
import { APP_WRAPPER_CLASS } from '../../../../../../src/core/server';
import { API_DIAGNOSE_URL } from '../../../common/constants';
import { omitBlockedHeaders } from '../../export_types/common';
import { getAbsoluteUrlFactory } from '../../export_types/common/get_absolute_url';
@ -47,8 +48,8 @@ export const registerDiagnoseScreenshot = (reporting: ReportingCore, logger: Log
height: 2024,
},
selectors: {
screenshot: '.application',
renderComplete: '.application',
screenshot: `.${APP_WRAPPER_CLASS}`,
renderComplete: `.${APP_WRAPPER_CLASS}`,
itemsCountAttribute: 'data-test-subj="kibanaChrome"',
timefilterDurationAttribute: 'data-test-subj="kibanaChrome"',
},

View file

@ -32,7 +32,7 @@ export const AppGlobalStyle = createGlobalStyle<{ theme: { eui: { euiColorPrimar
overflow: hidden;
}
div.app-wrapper {
div.kbnAppWrapper {
background-color: rgba(0,0,0,0);
}

View file

@ -118,7 +118,7 @@ const Application = (props: UptimeAppProps) => {
<UptimeSettingsContextProvider {...props}>
<UptimeThemeContextProvider darkMode={darkMode}>
<UptimeStartupPluginsContextProvider {...startPlugins}>
<EuiPage className="app-wrapper-panel " data-test-subj="uptimeApp">
<EuiPage data-test-subj="uptimeApp">
<RedirectAppLinks application={core.application}>
<main>
<UptimeAlertsFlyoutWrapper />

View file

@ -108,7 +108,7 @@ export function SecurityPageProvider({ getService, getPageObjects }: FtrProvider
if (expectedResult === 'chrome') {
await find.byCssSelector(
'[data-test-subj="kibanaChrome"] .app-wrapper:not(.hidden-chrome)',
'[data-test-subj="kibanaChrome"] .kbnAppWrapper:not(.kbnAppWrapper--hiddenChrome)',
20000
);
log.debug(`Finished login process currentUrl = ${await browser.getCurrentUrl()}`);

View file

@ -43,7 +43,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
await find.byCssSelector(
'[data-test-subj="kibanaChrome"] .app-wrapper:not(.hidden-chrome)',
'[data-test-subj="kibanaChrome"] .kbnAppWrapper:not(.kbnAppWrapper--hiddenChrome)',
20000
);

View file

@ -43,7 +43,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
await find.byCssSelector(
'[data-test-subj="kibanaChrome"] .app-wrapper:not(.hidden-chrome)',
'[data-test-subj="kibanaChrome"] .kbnAppWrapper:not(.kbnAppWrapper--hiddenChrome)',
20000
);