From b95211bc50fef3d26d13d2609a68643f9c063436 Mon Sep 17 00:00:00 2001 From: Weronika Olejniczak <32842468+weronikaolejniczak@users.noreply.github.com> Date: Mon, 6 Jan 2025 21:57:07 +0100 Subject: [PATCH] [Stack Monitoring] Visual refresh changes (#204258) ## Summary This PR introduces changes to `x-pack/plugins/monitoring` necessary for the Visual Refresh project (https://github.com/elastic/kibana/issues/199715): - replacing `euiThemeVars` with `euiTheme` context - replacing old tokens with `euiTheme` - making sure all color palette functions are run within the context of the `EuiProvider` Additionally: - I migrated Sass to `@emotion/react` - I migrated `euiStyled` to `@emotion/react` - I extended `emotion.d.ts` in `tsconfig.json` for typing of the EUI theme closes [#8228](https://github.com/elastic/eui/issues/8228) ### QA We need to test the critical paths in the Stack monitoring, paying close attention to: - [ ] color palette, visibility and contrast ratio of elements in Amsterdam / Borealis Specific paths: - [ ] Monitoring time-series "Zoom out" button hover behavior - `x-pack/plugins/monitoring/public/components/chart/monitoring_timeseries_container.tsx` - [ ] Shard allocation (especially color mapping with shard type and status): - [ ] `x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/components/assigned.js` - [ ] `x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/components/shard.js` - [ ] Kuery bar suggestions and autocomplete field: - [ ] `x-pack/plugins/monitoring/public/components/kuery_bar/autocomplete_field.tsx` - [ ] `x-pack/plugins/monitoring/public/components/kuery_bar/suggestion_item.tsx` ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Elastic Machine --- .github/CODEOWNERS | 1 - .../pages/logstash/node_pipelines.tsx | 2 +- .../application/pages/logstash/pipelines.tsx | 2 +- .../components/apm/instances/instances.tsx | 16 +- .../components/beats/listing/listing.js | 16 +- .../components/chart/horizontal_legend.scss | 30 ---- ...zontal_legend.js => horizontal_legend.tsx} | 95 +++++++--- .../public/components/chart/info_tooltip.scss | 12 -- .../{info_tooltip.js => info_tooltip.tsx} | 38 +++- .../monitoring_timeseries_container.scss | 8 - .../chart/monitoring_timeseries_container.tsx | 32 +++- .../chart/timeseries_visualization.js | 51 ++++-- .../chart/timeseries_visualization.scss | 39 ---- .../public/components/chart/types.ts | 18 ++ .../components/cluster/listing/listing.js | 37 ++-- .../components/cluster/listing/listing.scss | 41 ----- .../ccr/__snapshots__/ccr.test.js.snap | 14 +- .../components/elasticsearch/ccr/ccr.js | 16 +- .../components/elasticsearch/ccr/ccr.scss | 7 - .../elasticsearch/indices/indices.js | 25 ++- .../elasticsearch/indices/indices.scss | 4 - .../elasticsearch/ml_jobs/ml_jobs.tsx | 2 +- .../nodes/__snapshots__/cells.test.js.snap | 4 +- .../components/elasticsearch/nodes/cells.js | 11 +- .../components/elasticsearch/nodes/nodes.js | 39 ++-- .../shard_activity/shard_activity.js | 2 +- .../shard_allocation/components/assigned.js | 85 ++++++--- .../shard_allocation/components/shard.js | 16 +- .../shard_allocation/components/unassigned.js | 28 ++- .../shard_allocation/shard_allocation.js | 16 +- .../shard_allocation/shard_allocation.scss | 71 -------- .../kibana/cluster_status/index.tsx | 17 +- .../components/kibana/detail_status/index.js | 19 +- .../components/kibana/instances/instances.tsx | 35 ++-- .../kuery_bar/autocomplete_field.tsx | 32 ++-- .../components/kuery_bar/suggestion_item.tsx | 109 +++++------ .../__snapshots__/listing.test.js.snap | 4 +- .../components/logstash/listing/listing.js | 16 +- .../pipeline_listing/pipeline_listing.js | 21 ++- .../collapsible_statement.test.js.snap | 2 +- .../__snapshots__/detail_drawer.test.js.snap | 116 +++++++++--- .../views/__snapshots__/metric.test.js.snap | 7 +- .../pipeline_viewer.test.js.snap | 4 +- .../plugin_statement.test.js.snap | 42 ++--- .../views/__snapshots__/queue.test.js.snap | 2 +- .../__snapshots__/statement.test.js.snap | 18 +- .../views/collapsible_statement.scss | 3 - ...statement.js => collapsible_statement.tsx} | 42 +++-- .../pipeline_viewer/views/detail_drawer.js | 21 ++- .../pipeline_viewer/views/detail_drawer.scss | 4 - .../logstash/pipeline_viewer/views/metric.js | 42 ----- .../pipeline_viewer/views/metric.scss | 27 --- .../logstash/pipeline_viewer/views/metric.tsx | 74 ++++++++ .../pipeline_viewer/views/pipeline_viewer.js | 2 +- .../views/plugin_statement.scss | 7 - ...ugin_statement.js => plugin_statement.tsx} | 78 ++++---- .../logstash/pipeline_viewer/views/queue.scss | 4 - .../views/{queue.js => queue.tsx} | 15 +- .../pipeline_viewer/views/statement.js | 113 ------------ .../pipeline_viewer/views/statement.scss | 47 ----- .../pipeline_viewer/views/statement.tsx | 170 ++++++++++++++++++ .../logstash/pipeline_viewer/views/types.ts | 14 ++ .../__snapshots__/index.test.js.snap | 22 ++- .../public/components/sparkline/index.js | 60 +++++-- .../components/sparkline/sparkline.scss | 36 ---- .../components/status_icon/_status_icon.scss | 25 --- .../public/components/status_icon/index.tsx | 1 + .../__snapshots__/summary_status.test.js.snap | 28 ++- .../summary_status/summary_status.scss | 10 -- .../summary_status/summary_status.tsx | 32 +++- .../public/components/table/eui_table.tsx | 8 +- .../public/components/table/eui_table_ssp.js | 2 +- .../private/monitoring/public/index.scss | 8 - .../plugins/private/monitoring/tsconfig.json | 17 +- .../monitoring/logstash_pipeline_viewer.js | 2 +- 75 files changed, 1168 insertions(+), 968 deletions(-) delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/chart/horizontal_legend.scss rename x-pack/platform/plugins/private/monitoring/public/components/chart/{horizontal_legend.js => horizontal_legend.tsx} (54%) delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/chart/info_tooltip.scss rename x-pack/platform/plugins/private/monitoring/public/components/chart/{info_tooltip.js => info_tooltip.tsx} (51%) delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/chart/monitoring_timeseries_container.scss delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/chart/timeseries_visualization.scss create mode 100644 x-pack/platform/plugins/private/monitoring/public/components/chart/types.ts delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/cluster/listing/listing.scss delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/ccr/ccr.scss delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/indices/indices.scss delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.scss delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.scss rename x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/{collapsible_statement.js => collapsible_statement.tsx} (56%) delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/detail_drawer.scss delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/metric.js delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/metric.scss create mode 100644 x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/metric.tsx delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/plugin_statement.scss rename x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/{plugin_statement.js => plugin_statement.tsx} (68%) delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/queue.scss rename x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/{queue.js => queue.tsx} (70%) delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/statement.js delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/statement.scss create mode 100644 x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/statement.tsx create mode 100644 x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/types.ts delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/sparkline/sparkline.scss delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/status_icon/_status_icon.scss delete mode 100644 x-pack/platform/plugins/private/monitoring/public/components/summary_status/summary_status.scss delete mode 100644 x-pack/platform/plugins/private/monitoring/public/index.scss diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 20c1749b15087..0df52424548b0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2543,7 +2543,6 @@ x-pack/solutions/security/plugins/security_solution/server/lib/security_integrat # Observability design /x-pack/platform/plugins/shared/fleet/**/*.scss @elastic/observability-design -/x-pack/platform/plugins/private/monitoring/**/*.scss @elastic/observability-design # Ent. Search design /x-pack/solutions/search/plugins/enterprise_search/**/*.scss @elastic/search-design diff --git a/x-pack/platform/plugins/private/monitoring/public/application/pages/logstash/node_pipelines.tsx b/x-pack/platform/plugins/private/monitoring/public/application/pages/logstash/node_pipelines.tsx index 5a15843d37989..57e3ba53d7260 100644 --- a/x-pack/platform/plugins/private/monitoring/public/application/pages/logstash/node_pipelines.tsx +++ b/x-pack/platform/plugins/private/monitoring/public/application/pages/logstash/node_pipelines.tsx @@ -99,7 +99,7 @@ export const LogStashNodePipelinesPage: React.FC = ({ clusters } {data.pipelines && (
= ({ clusters }) => const upgradeMessage = pageData ? makeUpgradeMessage(clusterStatus.versions) : null; return ( onBrush({ xaxis })} stats={clusterStatus} data={pipelines} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/apm/instances/instances.tsx b/x-pack/platform/plugins/private/monitoring/public/components/apm/instances/instances.tsx index 30d4ea223a64f..c1c3d091a68e3 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/apm/instances/instances.tsx +++ b/x-pack/platform/plugins/private/monitoring/public/components/apm/instances/instances.tsx @@ -65,14 +65,12 @@ function getColumns(setupMode: SetupMode, cgroup: unknown) { }; setupModeStatus = ( -
- -
+ ); } @@ -187,7 +185,7 @@ export function ApmServerInstances({ apms, setupMode, alerts }: Props) { {setupModeCallout} - -
+ ); } @@ -161,7 +159,7 @@ export class Listing extends PureComponent { {setupModeCallOut} (theme: UseEuiTheme) => + css` + display: flex; + font-size: ${euiFontSize(theme, 'xs').fontSize}; + cursor: pointer; + color: ${theme.euiTheme.colors.textParagraph}; + display: flex; + flex-direction: row; + align-items: center; + ${isDisabled ? 'opacity: 0.5;' : ''} + `; + +const legendHorizontalStyle = ({ euiTheme }: UseEuiTheme) => css` + ${logicalCSS('margin-top', euiTheme.size.xs)} +`; + +const legendLabelStyle = css` + overflow: hidden; + white-space: nowrap; + display: flex; + flex-direction: row; + align-items: center; +`; + +const legendValueStyle = ({ euiTheme }: UseEuiTheme) => css` + overflow: hidden; + white-space: nowrap; + ${logicalCSS('margin-left', euiTheme.size.xs)} +`; + +interface Row { + id: string; + label: string; + legend?: boolean; + color?: string; + tickFormatter?: (arg: number) => number; +} + +interface Props { + series: Row[]; + seriesValues: { [key: string]: number }; + seriesFilter: string[]; + onToggle: (event: MouseEvent, id: string) => void; + legendFormatter?: (value: number) => number; + tickFormatter?: (value: number) => number; +} + +export class HorizontalLegend extends React.Component { + constructor(props: Props) { + super(props); this.formatter = this.formatter.bind(this); this.createSeries = this.createSeries.bind(this); } @@ -22,14 +77,14 @@ export class HorizontalLegend extends React.Component { /** * @param {Number} value Final value to display */ - displayValue(value) { - return {value}; + displayValue(value: number) { + return {value}; } /** * @param {Number} value True if value is falsy and/or not a number */ - validValue(value) { + validValue(value: number) { return value !== null && value !== undefined && (typeof value === 'string' || !isNaN(value)); } @@ -38,7 +93,7 @@ export class HorizontalLegend extends React.Component { * A null means no data for the time bucket and will be formatted as 'N/A' * @param {Object} row Props passed form a parent by row index */ - formatter(value, row) { + formatter(value: number, row: Row) { if (!this.validValue(value)) { return ( ; } @@ -73,12 +123,11 @@ export class HorizontalLegend extends React.Component { return ( @@ -99,8 +148,8 @@ export class HorizontalLegend extends React.Component { const rows = this.props.series.map(this.createSeries); return ( -
- +
+ {rows}
diff --git a/x-pack/platform/plugins/private/monitoring/public/components/chart/info_tooltip.scss b/x-pack/platform/plugins/private/monitoring/public/components/chart/info_tooltip.scss deleted file mode 100644 index 7798951ce23fc..0000000000000 --- a/x-pack/platform/plugins/private/monitoring/public/components/chart/info_tooltip.scss +++ /dev/null @@ -1,12 +0,0 @@ -.monChart__tooltipLabel, -.monChart__tooltipValue { - text-align: left; - font-size: $euiFontSizeXS; - padding: $euiSizeXS; - word-wrap: break-word; - white-space: normal; -} - -.monChart__tooltipLabel { - font-weight: $euiFontWeightBold; -} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/chart/info_tooltip.js b/x-pack/platform/plugins/private/monitoring/public/components/chart/info_tooltip.tsx similarity index 51% rename from x-pack/platform/plugins/private/monitoring/public/components/chart/info_tooltip.js rename to x-pack/platform/plugins/private/monitoring/public/components/chart/info_tooltip.tsx index 35d7cdaf9da19..7391fadd9b14e 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/chart/info_tooltip.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/chart/info_tooltip.tsx @@ -6,10 +6,36 @@ */ import React from 'react'; +import { css } from '@emotion/react'; +import { euiFontSize, UseEuiTheme } from '@elastic/eui'; + import { FormattedMessage } from '@kbn/i18n-react'; -import './info_tooltip.scss'; -export function InfoTooltip({ series, bucketSize }) { +import { Series } from './types'; + +const tooltipLabelStyle = (theme: UseEuiTheme) => css` + text-align: left; + font-size: ${euiFontSize(theme, 'xs').fontSize}; + padding: ${theme.euiTheme.size.xs}; + word-wrap: break-word; + white-space: normal; + font-weight: ${theme.euiTheme.font.weight.bold}; +`; + +const tooltipValueStyle = (theme: UseEuiTheme) => css` + text-align: left; + font-size: ${euiFontSize(theme, 'xs').fontSize}; + padding: ${theme.euiTheme.size.xs}; + word-wrap: break-word; + white-space: normal; +`; + +interface Props { + series: Series[]; + bucketSize?: string; +} + +export function InfoTooltip({ series, bucketSize }: Props) { const tableRows = series.map((item, index) => { return ( - {item.metric.label} - {item.metric.description} + {item.metric.label} + {item.metric.description} ); }); @@ -29,13 +55,13 @@ export function InfoTooltip({ series, bucketSize }) { - - + {tableRows} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/chart/monitoring_timeseries_container.scss b/x-pack/platform/plugins/private/monitoring/public/components/chart/monitoring_timeseries_container.scss deleted file mode 100644 index 0da89b55e69e4..0000000000000 --- a/x-pack/platform/plugins/private/monitoring/public/components/chart/monitoring_timeseries_container.scss +++ /dev/null @@ -1,8 +0,0 @@ -.monRhythmChart__wrapper .monRhythmChart__zoom { - visibility: hidden; - padding-right: $euiSizeM; -} - -.monRhythmChart__wrapper:hover .monRhythmChart__zoom { - visibility: visible; -} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/chart/monitoring_timeseries_container.tsx b/x-pack/platform/plugins/private/monitoring/public/components/chart/monitoring_timeseries_container.tsx index b8d4ba2f64868..beb86f595c662 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/chart/monitoring_timeseries_container.tsx +++ b/x-pack/platform/plugins/private/monitoring/public/components/chart/monitoring_timeseries_container.tsx @@ -6,9 +6,8 @@ */ import React, { Fragment } from 'react'; +import { css } from '@emotion/react'; import { get, first } from 'lodash'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; import { EuiBadge, EuiIconTip, @@ -18,7 +17,13 @@ import { EuiScreenReaderOnly, EuiTextAlign, EuiButtonEmpty, + UseEuiTheme, + logicalCSS, } from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + import { getTechnicalPreview } from './get_technical_preview'; import { getTitle } from './get_title'; import { getUnits } from './get_units'; @@ -26,8 +31,18 @@ import { MonitoringTimeseries } from './monitoring_timeseries'; import { InfoTooltip } from './info_tooltip'; import { AlertsBadge } from '../../alerts/badge'; import type { AlertsByName } from '../../alerts/types'; +import { Series } from './types'; -import './monitoring_timeseries_container.scss'; +const zoomStyle = ({ euiTheme }: UseEuiTheme) => css` + visibility: hidden; + ${logicalCSS('padding-right', euiTheme.size.m)} +`; + +const wrapperStyle = css` + &:hover .rhythmChart__zoom { + visibility: visible; + } +`; interface ZoomInfo { showZoomOutBtn: () => boolean; @@ -37,9 +52,7 @@ interface ZoomInfo { interface SeriesAlert { alerts: AlertsByName; } -interface Series { - metric: { title: string; label: string; description: string }; -} + interface Props { series?: Series[] | SeriesAlert; onBrush?: ({ xaxis }: any) => void; @@ -56,7 +69,7 @@ const zoomOutBtn = (zoomInfo?: ZoomInfo) => { } return ( - + @@ -123,7 +137,7 @@ export function MonitoringTimeseriesContainer({ series, onBrush, zoomInfo }: Pro } return ( - + @@ -147,7 +161,7 @@ export function MonitoringTimeseriesContainer({ series, onBrush, zoomInfo }: Pro } diff --git a/x-pack/platform/plugins/private/monitoring/public/components/chart/timeseries_visualization.js b/x-pack/platform/plugins/private/monitoring/public/components/chart/timeseries_visualization.js index 18e785874052b..8dcfb8047ae35 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/chart/timeseries_visualization.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/chart/timeseries_visualization.js @@ -5,14 +5,50 @@ * 2.0. */ -import { debounce, keys, has, includes, isFunction, difference, assign } from 'lodash'; import React from 'react'; +import { css } from '@emotion/react'; +import { debounce, keys, has, includes, isFunction, difference, assign } from 'lodash'; + import { getLastValue } from './get_last_value'; import { TimeseriesContainer } from './timeseries_container'; import { HorizontalLegend } from './horizontal_legend'; import { getValuesForSeriesIndex, getValuesByX } from './get_values_for_legend'; import { DEBOUNCE_SLOW_MS } from '../../../common/constants'; -import './timeseries_visualization.scss'; + +const rhythmChartStyle = css` + position: relative; + display: flex; + flex-direction: column; + flex: 1 0 auto; +`; + +const rhythmChartContentStyle = css` + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: flex; + flex: 1 0 auto; + flex-direction: column; +`; + +const rhythmChartVisualizationStyle = css` + position: relative; + display: flex; + flex-direction: column; + flex: 1 0 auto; + + & > div { + min-width: 1px; + width: 100%; + height: 100%; + } + + div { + user-select: none; + } +`; export class TimeseriesVisualization extends React.Component { constructor(props) { @@ -116,11 +152,6 @@ export class TimeseriesVisualization extends React.Component { } render() { - const className = 'monRhythmChart'; - const style = { - flexDirection: 'column', // for legend position = bottom - }; - const legend = this.props.hasLegend ? ( -
-
+
+
+
div { - min-width: 1px; - width: 100%; - height: 100%; - } - - // SASSTODO: generic selector - div { - @include monitoringNoUserSelect; - } -} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/chart/types.ts b/x-pack/platform/plugins/private/monitoring/public/components/chart/types.ts new file mode 100644 index 0000000000000..62035e7565313 --- /dev/null +++ b/x-pack/platform/plugins/private/monitoring/public/components/chart/types.ts @@ -0,0 +1,18 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface Series { + metric: { + description: string; + field: any; + hasCalculation: any; + isDerivative: any; + label: string; + metricAgg: any; + title: string; + }; +} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/cluster/listing/listing.js b/x-pack/platform/plugins/private/monitoring/public/components/cluster/listing/listing.js index a10dbd1fd2198..ff2f4efabdf7c 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/cluster/listing/listing.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/cluster/listing/listing.js @@ -6,9 +6,9 @@ */ import React, { Fragment } from 'react'; -import { Legacy } from '../../../legacy_shims'; import moment from 'moment'; import numeral from '@elastic/numeral'; +import { css } from '@emotion/react'; import { capitalize, partial } from 'lodash'; import { EuiHealth, @@ -20,17 +20,32 @@ import { EuiSpacer, EuiIcon, EuiToolTip, + euiFontSize, } from '@elastic/eui'; -import { EuiMonitoringTable } from '../../table'; + import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; + +import { Legacy } from '../../../legacy_shims'; +import { EuiMonitoringTable } from '../../table'; import { AlertsStatus } from '../../../alerts/status'; import { STANDALONE_CLUSTER_CLUSTER_UUID } from '../../../../common/constants'; import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link'; -import './listing.scss'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { toMountPoint } from '@kbn/react-kibana-mount'; +const clusterCellExpiredStyle = ({ euiTheme }) => css` + color: ${euiTheme.colors.textParagraph}; +`; + +const clusterCellLicenseStyle = (theme) => css` + font-size: ${euiFontSize(theme, 'm').fontSize}; +`; + +const clusterCellExpirationStyle = ({ euiTheme }) => css` + color: ${euiTheme.colors.darkShade}; +`; + const IsClusterSupported = ({ isSupported, children }) => { return isSupported ? children : '-'; }; @@ -64,7 +79,7 @@ const STANDALONE_CLUSTER_STORAGE_KEY = 'viewedStandaloneCluster'; const getColumns = ( showLicenseExpiration, - changeCluster, + _changeCluster, handleClickIncompatibleLicense, handleClickInvalidLicense ) => { @@ -193,18 +208,14 @@ const getColumns = ( const license = cluster.license; if (!licenseType) { - return ( -
-
N/A
-
- ); + return
N/A
; } if (license) { const licenseExpiry = () => { if (license.expiry_date_in_millis < moment().valueOf()) { // license is expired - return Expired; + return Expired; } // license is fine @@ -213,8 +224,8 @@ const getColumns = ( return (
-
{capitalize(licenseType)}
-
+
{capitalize(licenseType)}
+
{showLicenseExpiration ? licenseExpiry() : null}
@@ -419,7 +430,7 @@ export const Listing = ({ angular, clusters, sorting, pagination, onTableChange ) : null} .euiTableRowCell > .euiTableCellContent { + padding: 0; + } +", + "toString": [Function], + } + } executeQueryOptions={ Object { "defaultFields": Array [ diff --git a/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/ccr/ccr.js b/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/ccr/ccr.js index 18474238d468d..80cac2953f1c7 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/ccr/ccr.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/ccr/ccr.js @@ -6,6 +6,7 @@ */ import React, { Fragment, useState } from 'react'; +import { css } from '@emotion/react'; import { EuiInMemoryTable, EuiLink, @@ -17,11 +18,22 @@ import { EuiTextColor, EuiScreenReaderOnly, } from '@elastic/eui'; + import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; + import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link'; import { AlertsStatus } from '../../../alerts/status'; -import './ccr.scss'; + +/** + * We want the collapsed table (that shows the shard data) to be inline + * with the columns from the main table so we need to remove the padding + */ +const ccrListingTableStyle = css` + .euiTableRow-isExpandedRow > .euiTableRowCell > .euiTableCellContent { + padding: 0; + } +`; function toSeconds(ms) { return Math.floor(ms / 1000) + 's'; @@ -194,7 +206,7 @@ export const Ccr = (props) => { return ( .euiTableRowCell > .euiTableCellContent { - padding: 0; /* [1] */ -} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/indices/indices.js b/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/indices/indices.js index 1c47aa17638de..bd8784254bc75 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/indices/indices.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/indices/indices.js @@ -7,12 +7,7 @@ import React from 'react'; import { capitalize } from 'lodash'; -import { LARGE_FLOAT, LARGE_BYTES, LARGE_ABBREVIATED } from '../../../../common/formatting'; -import { formatMetric } from '../../../lib/format_number'; -import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link'; -import { ElasticsearchStatusIcon } from '../status_icon'; -import { ClusterStatus } from '../cluster_status'; -import { EuiMonitoringTable } from '../../table'; +import { css } from '@emotion/react'; import { EuiLink, EuiPage, @@ -22,10 +17,22 @@ import { EuiSpacer, EuiScreenReaderOnly, } from '@elastic/eui'; + import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; + import { AlertsStatus } from '../../../alerts/status'; -import './indices.scss'; +import { ClusterStatus } from '../cluster_status'; +import { ElasticsearchStatusIcon } from '../status_icon'; +import { EuiMonitoringTable } from '../../table'; +import { LARGE_FLOAT, LARGE_BYTES, LARGE_ABBREVIATED } from '../../../../common/formatting'; +import { formatMetric } from '../../../lib/format_number'; +import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link'; + +const statusStyle = css` + display: flex; + align-items: center; +`; const getColumns = (alerts) => { return [ @@ -70,7 +77,7 @@ const getColumns = (alerts) => { field: 'status', sortable: true, render: (value) => ( -
+
  {capitalize(value)} @@ -183,7 +190,7 @@ export const ElasticsearchIndices = ({ /> +
N/A
`; diff --git a/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/nodes/cells.js b/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/nodes/cells.js index 1b6121f278496..b900880486eb6 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/nodes/cells.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/nodes/cells.js @@ -7,7 +7,7 @@ import React, { useState } from 'react'; import { get } from 'lodash'; -import { formatMetric } from '../../../lib/format_number'; +import { css } from '@emotion/react'; import { EuiText, EuiPopover, @@ -17,8 +17,15 @@ import { EuiFlexGroup, EuiFlexItem, } from '@elastic/eui'; + import { i18n } from '@kbn/i18n'; +import { formatMetric } from '../../../lib/format_number'; + +const offlineStyle = ({ euiTheme }) => css` + color: ${euiTheme.colors.textParagraph}; +`; + const TRENDING_DOWN = i18n.translate('xpack.monitoring.elasticsearch.node.cells.trendingDownText', { defaultMessage: 'down', }); @@ -27,7 +34,7 @@ const TRENDING_UP = i18n.translate('xpack.monitoring.elasticsearch.node.cells.tr }); function OfflineCell() { - return
N/A
; + return
N/A
; } const getDirection = (slope) => { diff --git a/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/nodes/nodes.js b/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/nodes/nodes.js index 5a407d09230e1..e40edf1d24109 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/nodes/nodes.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/nodes/nodes.js @@ -5,6 +5,9 @@ * 2.0. */ +import React, { Fragment } from 'react'; +import { css } from '@emotion/react'; +import { get } from 'lodash'; import { EuiBadge, EuiBadgeGroup, @@ -20,11 +23,12 @@ import { EuiSpacer, EuiText, EuiToolTip, + euiFontSize, } from '@elastic/eui'; + import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { get } from 'lodash'; -import React, { Fragment } from 'react'; + import { ELASTICSEARCH_SYSTEM_ID } from '../../../../common/constants'; import { SetupModeFeature } from '../../../../common/enums'; import { AlertsStatus } from '../../../alerts/status'; @@ -37,6 +41,15 @@ import { EuiMonitoringSSPTable } from '../../table'; import { ClusterStatus } from '../cluster_status'; import { MetricCell, OfflineCell } from './cells'; +const tableCellNameStyle = (theme) => css` + ${euiFontSize(theme, 'm')} +`; + +const tableCellTransportAddressStyle = (theme) => css` + ${euiFontSize(theme, 's')} + color: ${theme.euiTheme.colors.darkShade}; +`; + const getNodeTooltip = (node) => { const { nodeTypeLabel, nodeTypeClass } = node; @@ -97,15 +110,13 @@ const getColumns = (showCgroupMetricsElasticsearch, setupMode, clusterUuid, aler }; setupModeStatus = ( -
- -
+ ); if (status.isNetNewUser) { nameLink = value; @@ -114,13 +125,13 @@ const getColumns = (showCgroupMetricsElasticsearch, setupMode, clusterUuid, aler return (
-
+
{getNodeTooltip(node)} {nameLink}
-
{extractIp(node.transport_address)}
+
{extractIp(node.transport_address)}
{setupModeStatus}
); @@ -502,7 +513,7 @@ export function ElasticsearchNodes({ clusterStatus, showCgroupMetricsElasticsear {setupModeCallout} { /> css` + ${logicalCSS('padding-top', euiTheme.size.l)} +`; + +const childTitleStyle = (theme) => css` + ${logicalCSS('padding', `${theme.euiTheme.size.l} ${theme.euiTheme.size.s}`)} + text-align: center; + font-size: ${euiFontSize(theme, 'xs').fontSize}; + color: ${theme.euiTheme.colors.ghost}; + display: flex; + flex-direction: row; + align-items: center; +`; + +const shardStyle = (theme) => css` + align-self: center; + ${logicalCSS('padding', `${theme.euiTheme.size.xs} ${theme.euiTheme.size.s}`)} + font-size: ${euiFontSize(theme, 'xs').fontSize}; + position: relative; + display: inline-block; +`; + +const childStyle = (data, shardStats) => (theme) => + css` + float: left; + align-self: center; + background-color: ${theme.euiTheme.colors.lightestShade}; + margin: ${theme.euiTheme.size.s}; + border: 1px solid ${theme.euiTheme.colors.mediumShade}; + border-radius: ${theme.euiTheme.size.xs}; + ${logicalCSS('padding', `calc(${theme.euiTheme.size.xs} / 2) 0`)} + + ${data.type === 'index' && + logicalCSS( + 'border-left', + `${theme.euiTheme.size.xs} solid ${theme.euiTheme.colors.borderStrongSuccess}` + )} + + ${shardStats?.status === 'red' && + logicalCSS( + 'border-left', + `${theme.euiTheme.size.xs} solid ${theme.euiTheme.colors.borderStrongDanger}` + )} + + ${shardStats?.status === 'yellow' && + logicalCSS( + 'border-left', + `${theme.euiTheme.size.xs} solid ${theme.euiTheme.colors.borderStrongWarning}` + )} + + ${data.type === 'shard' && shardStyle(theme)} + `; + const generateQueryAndLink = (data) => { let type = 'indices'; let ident = data.name; @@ -46,21 +100,7 @@ export class Assigned extends React.Component { createChild = (data) => { const key = data.id; - const initialClasses = ['monChild']; - if (data.type === 'index') { - initialClasses.push('monChild--index'); - } const shardStats = get(this.props.shardStats.indices, key); - if (shardStats) { - switch (shardStats.status) { - case 'red': - initialClasses.push('monChild--danger'); - break; - case 'yellow': - initialClasses.push('monChild--warning'); - break; - } - } // TODO: redesign for shard allocation const name = {data.name}; @@ -71,13 +111,13 @@ export class Assigned extends React.Component { return ( - + {name} {master} @@ -93,9 +133,10 @@ export class Assigned extends React.Component { render() { const data = sortBy(this.props.data, sortByName).map(this.createChild); + return ( -
diff --git a/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/shard_allocation/components/shard.js b/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/shard_allocation/components/shard.js index 6676b71b4bf13..67d780fd54be5 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/shard_allocation/components/shard.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/shard_allocation/components/shard.js @@ -6,11 +6,22 @@ */ import React from 'react'; +import { css } from '@emotion/react'; import { get } from 'lodash'; +import { EuiToolTip, EuiBadge, euiFontSize, logicalCSS } from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + import { calculateClass } from '../lib/calculate_class'; import { vents } from '../lib/vents'; -import { i18n } from '@kbn/i18n'; -import { EuiToolTip, EuiBadge } from '@elastic/eui'; + +const shardStyle = (theme) => css` + ${logicalCSS('padding', `${theme.euiTheme.size.xs} ${theme.euiTheme.size.s}`)} + align-self: center; + font-size: ${euiFontSize(theme, 'xs').fontSize}; + position: relative; + display: inline-block; +`; function getColor(classes) { const classList = classes.split(' '); @@ -117,6 +128,7 @@ export class Shard extends React.Component {
css` + vertical-align: middle; + width: calc(${euiTheme.size.l} * 10); +`; + +export const unassignedChildrenStyle = ({ euiTheme }) => css` + ${logicalCSS('padding-top', euiTheme.size.l)} +`; export class Unassigned extends React.Component { static displayName = i18n.translate( 'xpack.monitoring.elasticsearch.shardAllocation.unassignedDisplayName', - { - defaultMessage: 'Unassigned', - } + { defaultMessage: 'Unassigned' } ); createShard = (shard) => { @@ -33,14 +43,16 @@ export class Unassigned extends React.Component { '.' + shard.shard + additionId; + return ; }; render() { const shards = sortBy(this.props.shards, 'shard').map(this.createShard); + return ( -
diff --git a/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.js b/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.js index 1ac8a66fba75c..85d76647a24a9 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.js @@ -6,12 +6,24 @@ */ import React from 'react'; +import { css } from '@emotion/react'; import { EuiTitle, EuiBadge, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; + import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; -import './shard_allocation.scss'; + import { ClusterView } from './components/cluster_view'; +const clusterStyle = ({ euiTheme }) => css` + th { + text-align: left; + } + + td:first-child { + width: calc(${euiTheme.base} * 12.5); + } +`; + export const ShardAllocation = (props) => { const types = [ { @@ -59,7 +71,7 @@ export const ShardAllocation = (props) => { ]; return ( -
+

); } @@ -187,7 +196,7 @@ function InstancesPageStatusIndicator({ staleMessage }: IndicatorProps) { title={title} titleSize="xxxs" textAlign="left" - className="monSummaryStatusNoWrap__stat" + css={summaryStatusNoWrapStatStyle} /> ); } diff --git a/x-pack/platform/plugins/private/monitoring/public/components/kibana/detail_status/index.js b/x-pack/platform/plugins/private/monitoring/public/components/kibana/detail_status/index.js index 5f82968177c5c..d841f8a452f08 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/kibana/detail_status/index.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/kibana/detail_status/index.js @@ -5,17 +5,26 @@ * 2.0. */ -import { EuiBadge, EuiStat, EuiToolTip } from '@elastic/eui'; +import React from 'react'; +import { capitalize } from 'lodash'; +import { css } from '@emotion/react'; +import { EuiBadge, EuiStat, EuiToolTip, euiTextTruncate } from '@elastic/eui'; + import { i18n } from '@kbn/i18n'; import { useUiSetting } from '@kbn/kibana-react-plugin/public'; -import { capitalize } from 'lodash'; -import React from 'react'; + import { ExternalConfigContext } from '../../../application/contexts/external_config_context'; import { formatMetric } from '../../../lib/format_number'; import { DefaultStatusIndicator, SummaryStatus } from '../../summary_status'; import { formatLastSeenTimestamp } from '../format_last_seen_timestamp'; import { KibanaStatusIcon } from '../status_icon'; +const summaryStatusNoWrapStatStyle = css` + p { + ${euiTextTruncate()} + } +`; + export function DetailStatus({ stats }) { const { transport_address: transportAddress, @@ -77,12 +86,12 @@ export function DetailStatus({ stats }) { return ( ); }; diff --git a/x-pack/platform/plugins/private/monitoring/public/components/kibana/instances/instances.tsx b/x-pack/platform/plugins/private/monitoring/public/components/kibana/instances/instances.tsx index 1daebd5898e0a..121beddf66644 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/kibana/instances/instances.tsx +++ b/x-pack/platform/plugins/private/monitoring/public/components/kibana/instances/instances.tsx @@ -5,6 +5,9 @@ * 2.0. */ +import React, { Fragment } from 'react'; +import { css } from '@emotion/react'; +import { capitalize, get } from 'lodash'; import { EuiCallOut, EuiHealth, @@ -16,12 +19,14 @@ import { EuiScreenReaderOnly, EuiSpacer, EuiToolTip, + UseEuiTheme, + euiFontSize, } from '@elastic/eui'; + import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { useUiSetting } from '@kbn/kibana-react-plugin/public'; -import { capitalize, get } from 'lodash'; -import React, { Fragment } from 'react'; + import type { TableChange, Sorting, Pagination } from '../../../application/hooks/use_table'; import type { AlertsByName } from '../../../alerts/types'; import { KIBANA_SYSTEM_ID } from '../../../../common/constants'; @@ -40,6 +45,10 @@ import { ClusterStatus } from '../cluster_status'; import { formatLastSeenTimestamp } from '../format_last_seen_timestamp'; import type { SetupMode } from '../../setup_mode/types'; +const tableCellSplitNumber = (theme: UseEuiTheme) => css` + font-size: ${euiFontSize(theme, 'm').fontSize}; +`; + const getColumns = ( setupMode: SetupMode, alerts: AlertsByName, @@ -64,14 +73,12 @@ const getColumns = ( }; setupModeStatus = ( -
- -
+ ); if (status.isNetNewUser) { return ( @@ -188,10 +195,8 @@ const getColumns = ( return (
-
- {formatNumber(value, 'int_commas') + ' ms avg'} -
-
+
{formatNumber(value, 'int_commas') + ' ms avg'}
+
{formatNumber(kibana?.response_times?.max, 'int_commas')} ms max
@@ -319,7 +324,7 @@ export const KibanaInstances: React.FC = (props: Props) => { {setupModeCallOut} - +
{areSuggestionsVisible && !isLoadingSuggestions && suggestions.length > 0 ? ( - + {suggestions.map((suggestion, suggestionIndex) => ( ))} - + ) : null} - +
); } @@ -299,19 +306,16 @@ const withUnfocused = (state: AutocompleteFieldState) => ({ isFocused: false, }); -const AutocompleteContainer = euiStyled.div` +const autocompleteContainerCss = css` position: relative; `; -const SuggestionsPanel = euiStyled(EuiPanel).attrs(() => ({ - paddingSize: 'none', - hasShadow: true, -}))` +const suggestionsPanelCss = ({ euiTheme }: UseEuiTheme) => css` position: absolute; width: 100%; - margin-top: 2px; + ${logicalCSS('margin-top', euiTheme.size.xxs)} overflow-x: hidden; overflow-y: scroll; - z-index: ${euiThemeVars.euiZLevel1}; + z-index: ${euiTheme.levels.maskBelowHeader}; max-height: 322px; `; diff --git a/x-pack/platform/plugins/private/monitoring/public/components/kuery_bar/suggestion_item.tsx b/x-pack/platform/plugins/private/monitoring/public/components/kuery_bar/suggestion_item.tsx index 687ba1ebc5e63..5fd1d5fd7fa2a 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/kuery_bar/suggestion_item.tsx +++ b/x-pack/platform/plugins/private/monitoring/public/components/kuery_bar/suggestion_item.tsx @@ -5,11 +5,12 @@ * 2.0. */ -import { EuiIcon } from '@elastic/eui'; -import { transparentize } from 'polished'; import React from 'react'; +import { EuiIcon, UseEuiTheme, euiFontSize } from '@elastic/eui'; +import { css } from '@emotion/react'; +import { transparentize } from 'polished'; + import { QuerySuggestion, QuerySuggestionTypes } from '@kbn/unified-search-plugin/public'; -import { euiStyled } from '@kbn/kibana-react-plugin/common'; interface Props { isSelected?: boolean; @@ -18,69 +19,74 @@ interface Props { suggestion: QuerySuggestion; } -export const SuggestionItem: React.FC = (props) => { - const { isSelected, onClick, onMouseEnter, suggestion } = props; - +export const SuggestionItem: React.FC = ({ + isSelected = false, + onClick, + onMouseEnter, + suggestion, +}) => { return ( - - + // TODO: should be focusable and have relevant key events; try using an existing component from EUI + // eslint-disable-next-line jsx-a11y/click-events-have-key-events +
+
- - {suggestion.text} - {suggestion.description} - +
+
{suggestion.text}
+
{suggestion.description}
+
); }; -SuggestionItem.defaultProps = { - isSelected: false, -}; +const suggestionItemContainerStyle = (isSelected?: boolean) => (theme: UseEuiTheme) => + css` + display: flex; + flex-direction: row; + font-size: ${euiFontSize(theme, 's').fontSize}; + height: ${theme.euiTheme.size.xl}; + white-space: nowrap; + background-color: ${isSelected ? theme.euiTheme.colors.lightestShade : 'transparent'}; + `; -const SuggestionItemContainer = euiStyled.div<{ - isSelected?: boolean; -}>` - display: flex; - flex-direction: row; - font-size: ${(props) => props.theme.eui.euiFontSizeS}; - height: ${(props) => props.theme.eui.euiSizeXL}; - white-space: nowrap; - background-color: ${(props) => - props.isSelected ? props.theme.eui.euiColorLightestShade : 'transparent'}; -`; - -const SuggestionItemField = euiStyled.div` +const suggestionItemFieldStyle = ({ euiTheme }: UseEuiTheme) => css` align-items: center; cursor: pointer; display: flex; flex-direction: row; - height: ${(props) => props.theme.eui.euiSizeXL}; - padding: ${(props) => props.theme.eui.euiSizeXS}; + height: ${euiTheme.size.xl}; + padding: ${euiTheme.size.xs}; `; -const SuggestionItemIconField = euiStyled(SuggestionItemField)<{ - suggestionType: QuerySuggestionTypes; -}>` - background-color: ${(props) => - transparentize(0.9, getEuiIconColor(props.theme, props.suggestionType))}; - color: ${(props) => getEuiIconColor(props.theme, props.suggestionType)}; - flex: 0 0 auto; - justify-content: center; - width: ${(props) => props.theme.eui.euiSizeXL}; -`; +const suggestionItemIconFieldStyle = + (suggestionType: QuerySuggestionTypes) => (theme: UseEuiTheme) => + css` + ${suggestionItemFieldStyle(theme)}; + background-color: ${transparentize(0.9, getEuiIconColor(theme, suggestionType))}; + color: ${getEuiIconColor(theme, suggestionType)}; + flex: 0 0 auto; + justify-content: center; + width: ${theme.euiTheme.size.xl}; + `; -const SuggestionItemTextField = euiStyled(SuggestionItemField)` +const suggestionItemTextFieldStyle = (theme: UseEuiTheme) => css` + ${suggestionItemFieldStyle(theme)}; flex: 2 0 0; - font-family: ${(props) => props.theme.eui.euiCodeFontFamily}; + font-family: ${theme.euiTheme.font.familyCode}; `; -const SuggestionItemDescriptionField = euiStyled(SuggestionItemField)` +const suggestionItemDescriptionFieldStyle = (theme: UseEuiTheme) => css` + ${suggestionItemFieldStyle(theme)}; flex: 3 0 0; p { display: inline; span { - font-family: ${(props) => props.theme.eui.euiCodeFontFamily}; + font-family: ${theme.euiTheme.font.familyCode}; } } `; @@ -102,18 +108,21 @@ const getEuiIconType = (suggestionType: QuerySuggestionTypes) => { } }; -const getEuiIconColor = (theme: any, suggestionType: QuerySuggestionTypes): string => { +const getEuiIconColor = ( + { euiTheme }: UseEuiTheme, + suggestionType: QuerySuggestionTypes +): string => { switch (suggestionType) { case QuerySuggestionTypes.Field: - return theme?.eui.euiColorVis7; + return euiTheme.colors.vis.euiColorVis7; case QuerySuggestionTypes.Value: - return theme?.eui.euiColorVis0; + return euiTheme.colors.vis.euiColorVis0; case QuerySuggestionTypes.Operator: - return theme?.eui.euiColorVis1; + return euiTheme.colors.vis.euiColorVis1; case QuerySuggestionTypes.Conjunction: - return theme?.eui.euiColorVis2; + return euiTheme.colors.vis.euiColorVis2; case QuerySuggestionTypes.RecentSearch: default: - return theme?.eui.euiColorMediumShade; + return euiTheme.colors.mediumShade; } }; diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/listing/__snapshots__/listing.test.js.snap b/x-pack/platform/plugins/private/monitoring/public/components/logstash/listing/__snapshots__/listing.test.js.snap index 2e01fce7247dc..bc6cd4649a048 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/listing/__snapshots__/listing.test.js.snap +++ b/x-pack/platform/plugins/private/monitoring/public/components/logstash/listing/__snapshots__/listing.test.js.snap @@ -2,7 +2,6 @@ exports[`Listing should render with certain data pieces missing 1`] = ` - -
+ ); } @@ -202,7 +200,7 @@ export class Listing extends PureComponent { {setupModeCallOut} css` + font-size: ${euiFontSize(theme, 'l').fontSize}; +`; + export class PipelineListing extends Component { tooltipXValueFormatter(xValue, dateFormat) { return moment(xValue).format(dateFormat); @@ -76,7 +84,7 @@ export class PipelineListing extends Component { options={{ xaxis: throughput.timeRange }} /> - + {formatMetric(value, '0.[0]a', throughput.metric.units)} @@ -108,7 +116,7 @@ export class PipelineListing extends Component { options={{ xaxis: nodesCount.timeRange }} /> - + {formatMetric(value, '0a')} @@ -128,8 +136,7 @@ export class PipelineListing extends Component { } render() { - const { data, sorting, pagination, onTableChange, upgradeMessage, className, ...props } = - this.props; + const { data, sorting, pagination, onTableChange, upgradeMessage, ...props } = this.props; const sortingOptions = sorting || { field: 'id', direction: 'asc' }; if (sortingOptions.field === 'name') { @@ -152,7 +159,7 @@ export class PipelineListing extends Component { diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/detail_drawer.test.js.snap b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/detail_drawer.test.js.snap index 7bf74a1d57791..63ef44025ad2e 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/detail_drawer.test.js.snap +++ b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/detail_drawer.test.js.snap @@ -13,9 +13,7 @@ exports[`DetailDrawer component If vertices shows basic info and no stats for if - + @@ -66,9 +64,7 @@ exports[`DetailDrawer component Plugin vertices Plugin does not have explicit ID - + @@ -114,7 +110,17 @@ exports[`DetailDrawer component Plugin vertices Plugin does not have explicit ID
- + @@ -357,7 +391,17 @@ exports[`DetailDrawer component Plugin vertices Plugin has explicit ID shows bas
- + @@ -603,9 +675,7 @@ exports[`DetailDrawer component shows vertex title 1`] = ` - + diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/metric.test.js.snap b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/metric.test.js.snap index b9a4e1db36f68..26fd05f6d57b0 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/metric.test.js.snap +++ b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/metric.test.js.snap @@ -2,12 +2,12 @@ exports[`Metric component does not render warning badge when no warning present 1`] = ` @@ -19,11 +19,10 @@ exports[`Metric component does not render warning badge when no warning present exports[`Metric component renders warning badge 1`] = ` 220 diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/pipeline_viewer.test.js.snap b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/pipeline_viewer.test.js.snap index e6ef946a8108c..8df1ace748e43 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/pipeline_viewer.test.js.snap +++ b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/pipeline_viewer.test.js.snap @@ -13,7 +13,7 @@ exports[`PipelineViewer component passes expected props 1`] = ` @@ -20,8 +20,8 @@ exports[`PluginStatement component adds warning highlight for cpu time 1`] = ` > @@ -75,7 +75,7 @@ exports[`PluginStatement component adds warning highlight for cpu time 1`] = ` exports[`PluginStatement component adds warning highlight for event millis 1`] = ` @@ -92,8 +92,8 @@ exports[`PluginStatement component adds warning highlight for event millis 1`] = > @@ -147,7 +147,7 @@ exports[`PluginStatement component adds warning highlight for event millis 1`] = exports[`PluginStatement component does not render explicit id field if no id is specified 1`] = ` @@ -164,8 +164,8 @@ exports[`PluginStatement component does not render explicit id field if no id is > @@ -197,7 +197,7 @@ exports[`PluginStatement component does not render explicit id field if no id is exports[`PluginStatement component renders input metrics and explicit id fields 1`] = ` @@ -214,8 +214,8 @@ exports[`PluginStatement component renders input metrics and explicit id fields > @@ -257,7 +257,7 @@ exports[`PluginStatement component renders input metrics and explicit id fields exports[`PluginStatement component renders processor statement metrics 1`] = ` @@ -274,8 +274,8 @@ exports[`PluginStatement component renders processor statement metrics 1`] = ` > diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/queue.test.js.snap b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/queue.test.js.snap index 6f80a5b70f629..be23f040fe9b8 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/queue.test.js.snap +++ b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/__snapshots__/queue.test.js.snap @@ -10,7 +10,7 @@ exports[`Queue component renders default elements 1`] = ` size="s" />
else @@ -40,7 +40,7 @@ exports[`Statement component renders a CollapsibleStatement with if body for bra className="monPipelineViewer__listItem" >
if @@ -85,7 +85,7 @@ exports[`Statement component renders a PluginStatement component for plugin mode className="monPipelineViewer__listItem" >
0 1`] = ` className="monPipelineViewer__listItem" >
@@ -146,7 +146,7 @@ exports[`Statement component renders spacers for element with depth > 0 1`] = ` size="xs" > else diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.scss b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.scss deleted file mode 100644 index 0f5e5bd0d081f..0000000000000 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.scss +++ /dev/null @@ -1,3 +0,0 @@ -.monPipelineViewer__collapsibleStatement { - padding-left: $euiSizeM; -} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.js b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.tsx similarity index 56% rename from x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.js rename to x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.tsx index 458eefdebfbab..430801133be42 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.tsx @@ -6,18 +6,33 @@ */ import React from 'react'; -import PropTypes from 'prop-types'; +import { css } from '@emotion/react'; -import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import './collapsible_statement.scss'; +import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, logicalCSS, UseEuiTheme } from '@elastic/eui'; -function getToggleIconType(isCollapsed) { +const collapsibleStatementStyle = ({ euiTheme }: UseEuiTheme) => css` + ${logicalCSS('padding-left', euiTheme.size.m)} +`; + +function getToggleIconType(isCollapsed: boolean) { return isCollapsed ? 'arrowRight' : 'arrowDown'; } -export function CollapsibleStatement(props) { - const { collapse, expand, id, isCollapsed } = props; +interface CollapsibleStatementProps { + children: React.ReactNode; + collapse: (id: string) => void; + expand: (id: string) => void; + id: string; + isCollapsed: boolean; +} +export function CollapsibleStatement({ + children, + collapse, + expand, + id, + isCollapsed, +}: CollapsibleStatementProps) { const toggleClicked = () => { if (isCollapsed) { expand(id); @@ -28,10 +43,10 @@ export function CollapsibleStatement(props) { return ( - {props.children} + {children} ); } - -CollapsibleStatement.propTypes = { - collapse: PropTypes.func.isRequired, - expand: PropTypes.func.isRequired, - id: PropTypes.string.isRequired, - isCollapsed: PropTypes.bool.isRequired, -}; diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/detail_drawer.js b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/detail_drawer.js index 3141c633424f4..e1048b93e2d77 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/detail_drawer.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/detail_drawer.js @@ -7,6 +7,7 @@ import React from 'react'; import { last } from 'lodash'; +import { css } from '@emotion/react'; import { EuiBadge, EuiCodeBlock, @@ -24,13 +25,19 @@ import { EuiText, EuiTitle, } from '@elastic/eui'; + +import { FormattedMessage } from '@kbn/i18n-react'; + import { Sparkline } from '../../../sparkline'; import { formatMetric } from '../../../../lib/format_number'; -import { FormattedMessage } from '@kbn/i18n-react'; -import './detail_drawer.scss'; + +// TODO: Why is this width here? +const lspvDetailDrawerSparklineContainerStyle = css` + width: 7vw; +`; function renderIcon(vertex) { - return ; + return ; } function renderPluginBasicStats(vertex, timeseriesTooltipXValueFormatter) { @@ -50,7 +57,7 @@ function renderPluginBasicStats(vertex, timeseriesTooltipXValueFormatter) { /> -
+
-
+
-
+
-
+
- {value} - - ); - } else { - stylizedValue = ( - - {value} - - ); - } - return ( - - {stylizedValue} - - ); -} - -Metric.propTypes = { - className: PropTypes.string.isRequired, - value: PropTypes.string.isRequired, - warning: PropTypes.bool, -}; diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/metric.scss b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/metric.scss deleted file mode 100644 index 71b16cdaf3ff4..0000000000000 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/metric.scss +++ /dev/null @@ -1,27 +0,0 @@ -.monPipelineViewer__metric { - text-align: right; - - &--cpuTime { - width: $euiSizeXXL; - } - - &--events, - &--eventsEmitted { - width: $euiSizeXXL * 4; - } - - &--eventMillis { - width: $euiSizeXXL * 2; - } -} - -@include euiBreakpoint('m') { - .monPipelineViewer__metricFlexItem { - margin-bottom: $euiSizeXS !important; // sass-lint:disable-line no-important - } - - .monPipelineViewer__metric { - text-align: left; - padding-left: $euiSizeXL; - } -} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/metric.tsx b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/metric.tsx new file mode 100644 index 0000000000000..244c33f275a4e --- /dev/null +++ b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/metric.tsx @@ -0,0 +1,74 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { css } from '@emotion/react'; +import { EuiFlexItem, EuiBadge, EuiText, UseEuiTheme, logicalCSS } from '@elastic/eui'; + +type Type = 'cpuTime' | 'events' | 'eventsEmitted' | 'eventMillis'; + +const metricStyle = + (type: Type) => + ({ euiTheme }: UseEuiTheme) => { + let width: string; + + switch (type) { + case 'cpuTime': + width = euiTheme.size.xxl; + break; + case 'events': + case 'eventsEmitted': + width = `calc(${euiTheme.size.xxl} * 4)`; + break; + case 'eventMillis': + width = `calc(${euiTheme.size.xxl} * 2)`; + break; + default: + width = 'auto'; + } + + return css` + text-align: right; + width: ${width}; + + @media (min-width: ${euiTheme.breakpoint.m}) { + text-align: left; + ${logicalCSS('padding-left', euiTheme.size.xl)} + } + `; + }; + +const metricFlexItemStyle = ({ euiTheme }: UseEuiTheme) => css` + @media (min-width: ${euiTheme.breakpoint.m}) { + ${logicalCSS('margin-bottom', euiTheme.size.xs)} + } +`; + +interface MetricProps { + type: Type; + value: string; + warning?: boolean; +} + +export function Metric({ type, warning, value }: MetricProps) { + let stylizedValue; + + if (warning) { + stylizedValue = {value}; + } else { + stylizedValue = ( + + {value} + + ); + } + return ( + + {stylizedValue} + + ); +} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/pipeline_viewer.js b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/pipeline_viewer.js index 8ca913d34a8ea..7e09e7da854e4 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/pipeline_viewer.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/pipeline_viewer.js @@ -52,7 +52,7 @@ export class PipelineViewer extends React.Component { />

- + css` + ${logicalCSS('margin-left', euiTheme.size.xs)} +`; + +const pluginStatementStyle = ({ euiTheme }: UseEuiTheme) => css` + ${logicalCSS('padding-left', euiTheme.size.m)} +`; -function getInputStatementMetrics({ latestEventsPerSecond }) { +function getInputStatementMetrics({ latestEventsPerSecond }: Vertex) { return [ , ]; } -function getProcessorStatementMetrics(processorVertex) { +function getProcessorStatementMetrics(processorVertex: Vertex) { const { latestMillisPerEvent, latestEventsPerSecond, percentOfTotalProcessorTime } = processorVertex; return [ , , , ]; } -function renderPluginStatementMetrics(pluginType, vertex) { +function renderPluginStatementMetrics(pluginType: string, vertex: Vertex) { return pluginType === 'input' ? getInputStatementMetrics(vertex) : getProcessorStatementMetrics(vertex); } +interface Statement { + hasExplicitId: boolean; + id: string; + name: string; + pluginType: string; + vertex: Vertex; +} + +interface PluginStatementProps { + onShowVertexDetails: (vertex: Vertex) => void; + statement: Statement; +} + export function PluginStatement({ statement: { hasExplicitId, id, name, pluginType, vertex }, onShowVertexDetails, -}) { +}: PluginStatementProps) { const statementMetrics = renderPluginStatementMetrics(pluginType, vertex); + const onNameButtonClick = () => { onShowVertexDetails(vertex); }; @@ -68,7 +99,7 @@ export function PluginStatement({ return ( @@ -77,8 +108,8 @@ export function PluginStatement({ {id} @@ -112,18 +141,3 @@ export function PluginStatement({ ); } - -PluginStatement.propTypes = { - onShowVertexDetails: PropTypes.func.isRequired, - statement: PropTypes.shape({ - hasExplicitId: PropTypes.bool.isRequired, - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - pluginType: PropTypes.string.isRequired, - vertex: PropTypes.shape({ - latestEventsPerSecond: PropTypes.number.isRequired, - latestMillisPerEvent: PropTypes.number, - percentOfTotalProcessorTime: PropTypes.number, - }).isRequired, - }).isRequired, -}; diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/queue.scss b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/queue.scss deleted file mode 100644 index 60bac9f41b991..0000000000000 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/queue.scss +++ /dev/null @@ -1,4 +0,0 @@ -.monPipelineViewer__queueMessage { - margin-left: $euiSizeL; - color: $euiColorDarkShade; -} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/queue.js b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/queue.tsx similarity index 70% rename from x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/queue.js rename to x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/queue.tsx index 8b138da7dd012..5b98f67545090 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/queue.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/queue.tsx @@ -6,17 +6,24 @@ */ import React from 'react'; -import { StatementListHeading } from './statement_list_heading'; -import { EuiSpacer, EuiText } from '@elastic/eui'; +import { css } from '@emotion/react'; +import { EuiSpacer, EuiText, UseEuiTheme, logicalCSS } from '@elastic/eui'; + import { FormattedMessage } from '@kbn/i18n-react'; -import './queue.scss'; + +import { StatementListHeading } from './statement_list_heading'; + +const queueMessageStyle = ({ euiTheme }: UseEuiTheme) => css` + ${logicalCSS('margin-left', euiTheme.size.l)} + color: ${euiTheme.colors.darkShade}; +`; export function Queue() { return (
- + - - {name} - - - ); -} - -function renderIfStatement({ condition }, onVertexSelected) { - return [ - renderStatementName('if', onVertexSelected), - - - {condition} - - , - ]; -} - -function getStatementBody(isIf, statement, vertex, onShowVertexDetails) { - const showVertexDetailsClicked = () => { - onShowVertexDetails(vertex); - }; - - return isIf - ? renderIfStatement(statement, showVertexDetailsClicked) - : renderStatementName('else', showVertexDetailsClicked); -} - -function renderNestingSpacers(depth) { - const spacers = []; - for (let i = 0; i < depth; i += 1) { - spacers.push(
); - } - return spacers; -} - -function renderStatement({ - collapse, - element, - element: { - id, - statement, - statement: { vertex }, - }, - expand, - isCollapsed, - onShowVertexDetails, -}) { - if (statement instanceof PluginStatementModel) { - return ; - } - - const statementBody = getStatementBody( - element instanceof IfElement, - statement, - vertex, - onShowVertexDetails - ); - - return ( - - {statementBody} - - ); -} - -export function Statement(props) { - const { depth } = props.element; - - return ( -
  • -
    {renderNestingSpacers(depth)}
    - {renderStatement(props)} -
  • - ); -} - -Statement.propTypes = { - collapse: PropTypes.func.isRequired, - element: PropTypes.shape({ - depth: PropTypes.number.isRequired, - id: PropTypes.string.isRequired, - statement: PropTypes.object.isRequired, - }).isRequired, - expand: PropTypes.func.isRequired, - isCollapsed: PropTypes.bool.isRequired, - onShowVertexDetails: PropTypes.func.isRequired, -}; diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/statement.scss b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/statement.scss deleted file mode 100644 index 00d139463af50..0000000000000 --- a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/statement.scss +++ /dev/null @@ -1,47 +0,0 @@ -.monPipelineViewer__spaceContainer { - background-color: $euiColorEmptyShade; - align-self: stretch; - display: flex; - // Separates the left border spaces properly - border-bottom: solid 2px $euiColorEmptyShade; -} - -.monPipelineViewer__spacer { - width: $euiSizeM; - align-self: stretch; - margin-left: $euiSizeM; - border-left: 1px $euiBorderColor dashed; - - // This allows the border to be flush - &:last-child { - width: 0; - } - - &:first-child { - // Odd number is because of the single pixel border. - margin-left: $euiSizeL - 1px; - } -} - -.monPipelineViewer__list { - .monPipelineViewer__listItem { - display: flex; - min-height: $euiSizeXL; - align-items: center; - padding-right: $euiSizeM; - - &:nth-child(2n + 1) { - background: tintOrShade($euiColorLightestShade, 2%, 2%); - } - } -} - -.monPipelineViewer__conditional { - font-weight: bold; -} - -@include euiBreakpoint('m') { - .monPipelineViewer__spacer { - border: none; - } -} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/statement.tsx b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/statement.tsx new file mode 100644 index 0000000000000..718603b06ef63 --- /dev/null +++ b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/statement.tsx @@ -0,0 +1,170 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { MouseEventHandler } from 'react'; +import { css } from '@emotion/react'; +import { EuiButtonEmpty, EuiCodeBlock, EuiFlexItem, logicalCSS, UseEuiTheme } from '@elastic/eui'; + +import { PluginStatement as PluginStatementModel } from '../models/pipeline/plugin_statement'; +import { CollapsibleStatement } from './collapsible_statement'; +import { IfElement } from '../models/list/if_element'; +import { PluginStatement } from './plugin_statement'; +import { Vertex } from './types'; + +const spaceContainerStyle = ({ euiTheme }: UseEuiTheme) => css` + background-color: ${euiTheme.colors.backgroundBasePlain}; + align-self: stretch; + display: flex; + // Separates the left border spaces properly + ${logicalCSS('border-bottom', `solid 2px ${euiTheme.colors.emptyShade}`)} +`; + +const spacerStyle = ({ euiTheme }: UseEuiTheme) => css` + width: ${euiTheme.size.m}; + align-self: stretch; + ${logicalCSS('margin-left', euiTheme.size.m)} + ${logicalCSS('border-left', `1px ${euiTheme.border.color} dashed`)} + + // This allows the border to be flush + &:last-child { + width: 0; + } + + &:first-child { + // Odd number is because of the single pixel border + ${logicalCSS('margin-left', `calc(${euiTheme.size.l}) - 1px)`)} + } + + @media (min-width: var(${euiTheme.breakpoint.m})) { + border: none; + } +`; + +const listItemStyle = ({ euiTheme }: UseEuiTheme) => css` + display: flex; + min-height: ${euiTheme.size.xl}; + align-items: center; + ${logicalCSS('padding-right', euiTheme.size.m)} + + &:nth-child(2n + 1) { + background: ${euiTheme.colors.lightestShade}; + } +`; + +const conditionalStyle = ({ euiTheme }: UseEuiTheme) => css` + font-weight: ${euiTheme.font.weight.bold}; +`; + +function renderStatementName(name: string, onVertexSelected: MouseEventHandler) { + return ( + + + {name} + + + ); +} + +function renderIfStatement( + { condition }: { vertex?: Vertex; condition?: string }, + onVertexSelected: MouseEventHandler +) { + return [ + renderStatementName('if', onVertexSelected), + + + {condition} + + , + ]; +} + +function getStatementBody( + isIf: boolean, + statement: { vertex?: Vertex; condition?: string }, + vertex: Vertex, + onShowVertexDetails: (vertex: Vertex) => void +) { + const showVertexDetailsClicked = () => { + onShowVertexDetails(vertex); + }; + + return isIf + ? renderIfStatement(statement, showVertexDetailsClicked) + : renderStatementName('else', showVertexDetailsClicked); +} + +function renderNestingSpacers(depth: number) { + const spacers = []; + + for (let i = 0; i < depth; i += 1) { + spacers.push(
    ); + } + + return spacers; +} + +interface StatementProps { + collapse: () => void; + element: { + depth: number; + id: string; + statement: { + vertex: Vertex; + }; + }; + expand: () => void; + isCollapsed: boolean; + onShowVertexDetails: (vertex: Vertex) => void; +} + +function renderStatement({ + collapse, + element, + element: { + id, + statement, + statement: { vertex }, + }, + expand, + isCollapsed, + onShowVertexDetails, +}: StatementProps) { + if (statement instanceof PluginStatementModel) { + return ; + } + + const statementBody = getStatementBody( + element instanceof IfElement, + statement, + vertex, + onShowVertexDetails + ); + + return ( + + {statementBody} + + ); +} + +export function Statement(props: StatementProps) { + const { depth } = props.element; + + return ( +
  • +
    {renderNestingSpacers(depth)}
    + {renderStatement(props)} +
  • + ); +} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/types.ts b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/types.ts new file mode 100644 index 0000000000000..6721b78ed1dfe --- /dev/null +++ b/x-pack/platform/plugins/private/monitoring/public/components/logstash/pipeline_viewer/views/types.ts @@ -0,0 +1,14 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface Vertex { + latestEventsPerSecond: number; + latestMillisPerEvent?: number; + percentOfTotalProcessorTime?: number; + isTimeConsuming: () => boolean; + isSlow: () => boolean; +} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/sparkline/__snapshots__/index.test.js.snap b/x-pack/platform/plugins/private/monitoring/public/components/sparkline/__snapshots__/index.test.js.snap index f52e00b4432c0..31d8fe985f96b 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/sparkline/__snapshots__/index.test.js.snap +++ b/x-pack/platform/plugins/private/monitoring/public/components/sparkline/__snapshots__/index.test.js.snap @@ -3,7 +3,11 @@ exports[`Sparkline component does not show tooltip initially 1`] = `
    `; @@ -11,7 +15,11 @@ exports[`Sparkline component does not show tooltip initially 1`] = ` exports[`Sparkline component shows tooltip on hover 1`] = `
    1513814914
    25
    css` + font-weight: ${theme.euiTheme.font.weight.regular}; + background: ${transparentize(0.3, theme.euiTheme.colors.darkestShade)}; + font-size: ${euiFontSize(theme, 'xs').fontSize}; + padding: ${theme.euiTheme.size.xs}; + border-radius: ${theme.euiTheme.border.radius.medium}; + pointer-events: none; +`; + +const tooltipXValueStyle = ({ euiTheme }) => css` + color: ${transparentize(0.3, euiTheme.colors.ghost)}; +`; + +const tooltipYValueStyle = ({ euiTheme }) => css` + color: ${euiTheme.colors.ghost}; +`; + +const tooltipContainerStyle = ({ euiTheme }) => css` + position: fixed; + z-index: ${euiTheme.levels.menu}; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; +`; + +const tooltipCaretStyle = (theme) => css` + font-size: ${euiFontSize(theme, 'l').fontSize}; + color: ${transparentize(0.3, theme.euiTheme.colors.darkestShade)}; + display: none; +`; export class Sparkline extends React.Component { constructor(props) { @@ -97,17 +133,21 @@ export class Sparkline extends React.Component { } return ( -
    - -
    -
    +
    + +
    +
    {this.props.tooltip.yValueFormatter(this.state.tooltip.yValue)}
    -
    +
    {this.props.tooltip.xValueFormatter(this.state.tooltip.xValue)}
    - +
    ); } @@ -124,7 +164,7 @@ export class Sparkline extends React.Component { render() { return (
    -
    +
    {this.renderTooltip()}
    ); diff --git a/x-pack/platform/plugins/private/monitoring/public/components/sparkline/sparkline.scss b/x-pack/platform/plugins/private/monitoring/public/components/sparkline/sparkline.scss deleted file mode 100644 index 2873b9ff444d7..0000000000000 --- a/x-pack/platform/plugins/private/monitoring/public/components/sparkline/sparkline.scss +++ /dev/null @@ -1,36 +0,0 @@ -.monSparkline { - height: 2em; -} - -// SASSTODO: Replace with EUI tooltip -.monSparklineTooltip { - font-weight: normal; - background: transparentize($euiColorDarkestShade, .3); - font-size: $euiFontSizeXS; - padding: $euiSizeXS; - border-radius: $euiBorderRadius; - pointer-events: none; -} - -.monSparklineTooltip__xValue { - color: transparentize($euiColorGhost, .3); -} - -.monSparklineTooltip__yValue { - color: $euiColorGhost; -} - -.monSparklineTooltip__caret { - font-size: $euiFontSizeL; - color: transparentize($euiColorDarkestShade, .3); - display: none; -} - -.monSparklineTooltip__container { - position: fixed; - z-index: $euiZContentMenu; - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; -} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/status_icon/_status_icon.scss b/x-pack/platform/plugins/private/monitoring/public/components/status_icon/_status_icon.scss deleted file mode 100644 index 50c705f80650e..0000000000000 --- a/x-pack/platform/plugins/private/monitoring/public/components/status_icon/_status_icon.scss +++ /dev/null @@ -1,25 +0,0 @@ -.monStatusIcon { - display: inline-block; - margin-left: $euiSizeXS; - padding: calc($euiSizeXS / 2) $euiSizeS; - border-radius: $euiBorderRadius; - color: $euiColorGhost; - min-width: 1.9em; - text-align: center; -} - -.monStatusIcon--green { - background-color: $euiColorSuccess; -} - -.monStatusIcon--red { - background-color: $euiColorDanger; -} - -.monStatusIcon--yellow { - background-color: $euiColorWarning; -} - -.monStatusIcon--gray { - background-color: $euiTextColor; -} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/status_icon/index.tsx b/x-pack/platform/plugins/private/monitoring/public/components/status_icon/index.tsx index 59c87866d57d3..01065c7eb9afc 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/status_icon/index.tsx +++ b/x-pack/platform/plugins/private/monitoring/public/components/status_icon/index.tsx @@ -26,6 +26,7 @@ export interface StatusIconProps { type: keyof typeof STATUS_ICON_TYPES; label: string; } + export const StatusIcon: React.FunctionComponent = ({ type, label }) => { const icon = typeToIconMap[type]; diff --git a/x-pack/platform/plugins/private/monitoring/public/components/summary_status/__snapshots__/summary_status.test.js.snap b/x-pack/platform/plugins/private/monitoring/public/components/summary_status/__snapshots__/summary_status.test.js.snap index 8c6dc9bd29ee5..c1fa59647e064 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/summary_status/__snapshots__/summary_status.test.js.snap +++ b/x-pack/platform/plugins/private/monitoring/public/components/summary_status/__snapshots__/summary_status.test.js.snap @@ -1,9 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Summary Status Component should allow label to be optional 1`] = ` -
    +
    @@ -12,7 +10,7 @@ exports[`Summary Status Component should allow label to be optional 1`] = ` style="max-width:200px" >
    +
    @@ -99,7 +95,7 @@ exports[`Summary Status Component should allow status to be optional 1`] = ` style="max-width:200px" >
    +
    @@ -153,7 +147,7 @@ exports[`Summary Status Component should render metrics in a summary bar 1`] = ` style="max-width:200px" >
    css` + ${logicalCSS('margin-left', euiTheme.size.m)} + ${logicalCSS('margin-right', euiTheme.size.m)} +`; + +const summaryStatusNoWrapStatStyle = css` + p { + ${euiTextTruncate()} + } +`; interface Metrics { label: string; @@ -46,7 +66,7 @@ const wrapChild = ({ label, value, ...props }: Metrics, index: number) => ( > +
    } titleSize="xxxs" textAlign="left" - className="monSummaryStatusNoWrap__stat" + css={summaryStatusNoWrapStatStyle} description={i18n.translate('xpack.monitoring.summaryStatus.alertsDescription', { defaultMessage: 'Alerts', })} diff --git a/x-pack/platform/plugins/private/monitoring/public/components/table/eui_table.tsx b/x-pack/platform/plugins/private/monitoring/public/components/table/eui_table.tsx index a383fcf1cd666..4f4f17c425a29 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/table/eui_table.tsx +++ b/x-pack/platform/plugins/private/monitoring/public/components/table/eui_table.tsx @@ -67,15 +67,15 @@ export const EuiMonitoringTable: FunctionComponent> = ({ } return ( -
    +
    {footerContent}
    diff --git a/x-pack/platform/plugins/private/monitoring/public/components/table/eui_table_ssp.js b/x-pack/platform/plugins/private/monitoring/public/components/table/eui_table_ssp.js index 0c12e91512bd4..5fb8bb581bf2e 100644 --- a/x-pack/platform/plugins/private/monitoring/public/components/table/eui_table_ssp.js +++ b/x-pack/platform/plugins/private/monitoring/public/components/table/eui_table_ssp.js @@ -100,7 +100,7 @@ export function EuiMonitoringSSPTable({ }; return ( -
    +
    + {bucketSize}{bucketSize}
    - + + {data} - + + {shards}