[ObsUX] [APM] Migrate APM from styled-components to @emotion (#204222)

Closes https://github.com/elastic/kibana/issues/202765

### Summary
While working on the visual refresh for the new EUI theme Borealis we
figured that was a good time to do the recommended migration from
`styled-components` to `@emotion`

### What has been done

- Migrate apm plugin from `styled-components` to `@emotion`
- Eui Visual Refresh for Borealis new theme
- All usage of color palette tokens and functions now pull from the
theme, and correctly update to use new colors when the theme changes
from Borealis to Amsterdam and vice versa
- All references to renamed tokens have been updated to use the new
token name
- Remove usage of deprecated `useEuiBackgroundColor`
- All usages of "success" colors have been updated to `accentSecondary`
and `textAccentSecondary` as needed

### Not this time

There are some color values on the server side, and the values are
static they would not update properly as dynamic tokens do. Eui guidance
right now is to keep these as they are for now (meaning to keep using
the JSON tokens).

### How to test
#### Running Kibana with the Borealis theme
In order to run Kibana with Borealis, you'll need to do the following:

- Set the following in kibana.dev.yml:
uiSettings.experimental.themeSwitcherEnabled: true
- Run Kibana with the following environment variable set:
KBN_OPTIMIZER_THEMES="borealislight,borealisdark,v8light,v8dark" yarn
start
- This will expose a toggle under Stack Management > Advanced Settings >
Theme version, which you can use to toggle between Amsterdam and
Borealis.
This commit is contained in:
Miriam 2024-12-18 17:13:24 +00:00 committed by GitHub
parent 639143ac59
commit fb0cb57b4f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
122 changed files with 852 additions and 945 deletions

View file

@ -16,8 +16,8 @@ module.exports = {
/packages[\/\\]kbn-ui-shared-deps-(npm|src)[\/\\]/,
/src[\/\\]plugins[\/\\](kibana_react)[\/\\]/,
/x-pack[\/\\]solutions[\/\\]observability[\/\\]plugins[\/\\](exploratory_view|investigate|investigate_app|observability|observability_ai_assistant_app|observability_ai_assistant_management|observability_solution|serverless_observability|streams|streams_app|synthetics|uptime|ux)[\/\\]/,
/x-pack[\/\\]plugins[\/\\](observability_solution\/apm|beats_management|fleet|observability_solution\/observability|observability_solution\/observability_shared|observability_solution\/exploratory_view|security_solution|timelines|observability_solution\/synthetics|observability_solution\/ux|observability_solution\/uptime)[\/\\]/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\](observability_solution\/apm|beats_management|fleet|observability_solution\/infra|lists|observability_solution\/observability|observability_solution\/observability_shared|observability_solution\/exploratory_view|security_solution|timelines|observability_solution\/synthetics|observability_solution\/ux|observability_solution\/uptime)[\/\\]/,
/x-pack[\/\\]plugins[\/\\](beats_management|fleet|observability_solution\/observability|observability_solution\/observability_shared|observability_solution\/exploratory_view|security_solution|timelines|observability_solution\/synthetics|observability_solution\/ux|observability_solution\/uptime)[\/\\]/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\](beats_management|fleet|lists|observability_solution\/observability|observability_solution\/observability_shared|observability_solution\/exploratory_view|security_solution|timelines|observability_solution\/synthetics|observability_solution\/ux|observability_solution\/uptime)[\/\\]/,
/x-pack[\/\\]test[\/\\]plugin_functional[\/\\]plugins[\/\\]resolver_test[\/\\]/,
/x-pack[\/\\]packages[\/\\]elastic_assistant[\/\\]/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]packages[\/\\]ecs_data_quality_dashboard[\/\\]/,

1
x-pack/.gitignore vendored
View file

@ -7,6 +7,7 @@
/test/reporting/configs/failure_debug/
/plugins/reporting/.chromium/
/platform/plugins/shared/screenshotting/chromium/
/plugins/screenshotting/chromium/
/plugins/reporting/.phantom/
/.aws-config.json
/.env

View file

@ -6,7 +6,7 @@
*/
import { i18n } from '@kbn/i18n';
import { EuiTheme } from '@kbn/kibana-react-plugin/common';
import type { EuiThemeComputed } from '@elastic/eui';
import { ML_ANOMALY_SEVERITY } from '@kbn/ml-anomaly-utils/anomaly_severity';
export enum ServiceHealthStatus {
@ -34,29 +34,35 @@ export function getServiceHealthStatus({ severity }: { severity: ML_ANOMALY_SEVE
}
}
export function getServiceHealthStatusColor(theme: EuiTheme, status: ServiceHealthStatus) {
export function getServiceHealthStatusColor(
euiTheme: EuiThemeComputed,
status: ServiceHealthStatus
) {
switch (status) {
case ServiceHealthStatus.healthy:
return theme.eui.euiColorVis0;
return euiTheme.colors.success;
case ServiceHealthStatus.warning:
return theme.eui.euiColorVis5;
return euiTheme.colors.warning;
case ServiceHealthStatus.critical:
return theme.eui.euiColorVis9;
return euiTheme.colors.danger;
case ServiceHealthStatus.unknown:
return theme.eui.euiColorMediumShade;
return euiTheme.colors.mediumShade;
}
}
export function getServiceHealthStatusBadgeColor(theme: EuiTheme, status: ServiceHealthStatus) {
export function getServiceHealthStatusBadgeColor(
euiTheme: EuiThemeComputed,
status: ServiceHealthStatus
) {
switch (status) {
case ServiceHealthStatus.healthy:
return theme.eui.euiColorVis0_behindText;
return euiTheme.colors.success;
case ServiceHealthStatus.warning:
return theme.eui.euiColorVis5_behindText;
return euiTheme.colors.warning;
case ServiceHealthStatus.critical:
return theme.eui.euiColorVis9_behindText;
return euiTheme.colors.danger;
case ServiceHealthStatus.unknown:
return theme.eui.euiColorMediumShade;
return euiTheme.colors.mediumShade;
}
}

View file

@ -20,7 +20,6 @@ import type {
GetApmTimeseriesFunctionResponse,
} from '../../server/assistant_functions/get_apm_timeseries';
import { Coordinate, TimeSeries } from '../../typings/timeseries';
import { ApmThemeProvider } from '../components/routing/app_root';
import {
ChartType,
getTimeSeriesColor,
@ -54,101 +53,99 @@ export function registerGetApmTimeseriesFunction({
return (
<ChartPointerEventContextProvider>
<ApmThemeProvider>
<EuiFlexGroup direction="column">
{Object.values(groupedSeries).map((groupSeries) => {
const groupId = groupSeries[0].group;
<EuiFlexGroup direction="column">
{Object.values(groupedSeries).map((groupSeries) => {
const groupId = groupSeries[0].group;
const maxY = getMaxY(groupSeries);
const latencyFormatter = getDurationFormatter(maxY, 10, 1000);
const maxY = getMaxY(groupSeries);
const latencyFormatter = getDurationFormatter(maxY, 10, 1000);
let yLabelFormat: (value: number) => string;
let yLabelFormat: (value: number) => string;
const firstStat = groupSeries[0].stat;
const firstStat = groupSeries[0].stat;
switch (firstStat.timeseries.name) {
case 'transaction_throughput':
case 'exit_span_throughput':
case 'error_event_rate':
yLabelFormat = asTransactionRate;
break;
switch (firstStat.timeseries.name) {
case 'transaction_throughput':
case 'exit_span_throughput':
case 'error_event_rate':
yLabelFormat = asTransactionRate;
break;
case 'transaction_latency':
case 'exit_span_latency':
yLabelFormat = getResponseTimeTickFormatter(latencyFormatter);
break;
case 'transaction_latency':
case 'exit_span_latency':
yLabelFormat = getResponseTimeTickFormatter(latencyFormatter);
break;
case 'transaction_failure_rate':
case 'exit_span_failure_rate':
yLabelFormat = (y) => asPercent(y || 0, 100);
break;
}
case 'transaction_failure_rate':
case 'exit_span_failure_rate':
yLabelFormat = (y) => asPercent(y || 0, 100);
break;
}
const timeseries: Array<TimeSeries<Coordinate>> = groupSeries.map(
(series): TimeSeries<Coordinate> => {
let chartType: ChartType;
const timeseries: Array<TimeSeries<Coordinate>> = groupSeries.map(
(series): TimeSeries<Coordinate> => {
let chartType: ChartType;
const data = series.data;
const data = series.data;
switch (series.stat.timeseries.name) {
case 'transaction_throughput':
case 'exit_span_throughput':
chartType = ChartType.THROUGHPUT;
break;
switch (series.stat.timeseries.name) {
case 'transaction_throughput':
case 'exit_span_throughput':
chartType = ChartType.THROUGHPUT;
break;
case 'transaction_failure_rate':
case 'exit_span_failure_rate':
chartType = ChartType.FAILED_TRANSACTION_RATE;
break;
case 'transaction_failure_rate':
case 'exit_span_failure_rate':
chartType = ChartType.FAILED_TRANSACTION_RATE;
break;
case 'transaction_latency':
if (series.stat.timeseries.function === LatencyAggregationType.p99) {
chartType = ChartType.LATENCY_P99;
} else if (series.stat.timeseries.function === LatencyAggregationType.p95) {
chartType = ChartType.LATENCY_P95;
} else {
chartType = ChartType.LATENCY_AVG;
}
break;
case 'exit_span_latency':
case 'transaction_latency':
if (series.stat.timeseries.function === LatencyAggregationType.p99) {
chartType = ChartType.LATENCY_P99;
} else if (series.stat.timeseries.function === LatencyAggregationType.p95) {
chartType = ChartType.LATENCY_P95;
} else {
chartType = ChartType.LATENCY_AVG;
break;
}
break;
case 'error_event_rate':
chartType = ChartType.ERROR_OCCURRENCES;
break;
}
case 'exit_span_latency':
chartType = ChartType.LATENCY_AVG;
break;
return {
title: series.id,
type: 'line',
color: getTimeSeriesColor(chartType!).currentPeriodColor,
data,
};
case 'error_event_rate':
chartType = ChartType.ERROR_OCCURRENCES;
break;
}
);
return (
<EuiFlexItem grow={false} key={groupId}>
<EuiFlexGroup direction="column" gutterSize="s">
<EuiFlexItem>
<EuiText size="m">{groupId}</EuiText>
<TimeseriesChart
comparisonEnabled={false}
fetchStatus={FETCH_STATUS.SUCCESS}
id={groupId}
timeZone={timeZone}
timeseries={timeseries}
yLabelFormat={yLabelFormat!}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
);
})}
</EuiFlexGroup>
</ApmThemeProvider>
return {
title: series.id,
type: 'line',
color: getTimeSeriesColor(chartType!).currentPeriodColor,
data,
};
}
);
return (
<EuiFlexItem grow={false} key={groupId}>
<EuiFlexGroup direction="column" gutterSize="s">
<EuiFlexItem>
<EuiText size="m">{groupId}</EuiText>
<TimeseriesChart
comparisonEnabled={false}
fetchStatus={FETCH_STATUS.SUCCESS}
id={groupId}
timeZone={timeZone}
timeseries={timeseries}
yLabelFormat={yLabelFormat!}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
);
})}
</EuiFlexGroup>
</ChartPointerEventContextProvider>
);
});

View file

@ -10,6 +10,8 @@ import {
Axis,
BarSeries,
Chart,
LIGHT_THEME,
DARK_THEME,
LineAnnotation,
Position,
RectAnnotation,
@ -20,7 +22,7 @@ import {
Tooltip,
niceTimeFormatter,
} from '@elastic/charts';
import { EuiSpacer } from '@elastic/eui';
import { COLOR_MODES_STANDARD, EuiSpacer, useEuiTheme } from '@elastic/eui';
import React, { useMemo } from 'react';
import { IUiSettingsClient } from '@kbn/core/public';
import { TimeUnitChar } from '@kbn/observability-plugin/common';
@ -28,7 +30,6 @@ import { UI_SETTINGS } from '@kbn/data-plugin/public';
import moment from 'moment';
import { i18n } from '@kbn/i18n';
import { Coordinate } from '../../../../../typings/timeseries';
import { useTheme } from '../../../../hooks/use_theme';
import { getTimeZone } from '../../../shared/charts/helper/timezone';
import { TimeLabelForData, TIME_LABELS, getDomain } from './chart_preview_helper';
import { ALERT_PREVIEW_BUCKET_SIZE } from '../../utils/helper';
@ -52,15 +53,15 @@ export function ChartPreview({
timeUnit = 'm',
totalGroups,
}: ChartPreviewProps) {
const theme = useTheme();
const theme = useEuiTheme();
const thresholdOpacity = 0.3;
const DEFAULT_DATE_FORMAT = 'Y-MM-DD HH:mm:ss';
const style = {
fill: theme.eui.euiColorVis2,
fill: theme.euiTheme.colors.vis.euiColorVis2,
line: {
strokeWidth: 2,
stroke: theme.eui.euiColorVis2,
stroke: theme.euiTheme.colors.vis.euiColorVis2,
opacity: 1,
},
opacity: thresholdOpacity,
@ -121,6 +122,7 @@ export function ChartPreview({
legendPosition={'bottom'}
legendSize={legendSize}
locale={i18n.getLocale()}
theme={theme.colorMode === COLOR_MODES_STANDARD.dark ? DARK_THEME : LIGHT_THEME}
/>
<LineAnnotation
dataValues={[{ dataValue: threshold }]}

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { EuiButtonIcon, EuiToolTip } from '@elastic/eui';
import { EuiButtonIcon, EuiToolTip, useEuiTheme } from '@elastic/eui';
import React, { useCallback, useMemo, useState } from 'react';
import { i18n } from '@kbn/i18n';
import {
@ -29,6 +29,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query';
import numeral from '@elastic/numeral';
import { css } from '@emotion/react';
import { termQuery } from '../../../../../common/utils/term_query';
import {
SERVICE_NAME,
@ -40,7 +41,6 @@ import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plug
import { useFetchParams } from '../use_fetch_params';
import type { ApmPluginStartDeps } from '../../../../plugin';
import { useAdHocApmDataView } from '../../../../hooks/use_adhoc_apm_data_view';
import { useTheme } from '../../../../hooks/use_theme';
import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher';
const HIGHLIGHTED_BUCKET_PROPS = {
@ -205,7 +205,7 @@ export function FieldStatsPopover({
const field = dataView?.getFieldByName(fieldName);
const closePopover = useCallback(() => setInfoOpen(false), []);
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const params = useFetchParams();
@ -280,7 +280,9 @@ export function FieldStatsPopover({
}
)}
data-test-subj={'apmCorrelationsContextPopoverButton'}
style={{ marginLeft: theme.eui.euiSizeXS }}
css={css`
margin-left: ${euiTheme.size.xs};
`}
/>
</EuiToolTip>
);

View file

@ -7,13 +7,12 @@
import React, { useCallback, useMemo, useState } from 'react';
import { debounce } from 'lodash';
import { EuiBasicTable, EuiBasicTableColumn } from '@elastic/eui';
import { EuiBasicTable, EuiBasicTableColumn, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import type { EuiTableSortingType } from '@elastic/eui/src/components/basic_table/table_types';
import type { Criteria } from '@elastic/eui/src/components/basic_table/basic_table';
import { useUiTracker } from '@kbn/observability-shared-plugin/public';
import { FETCH_STATUS } from '../../../hooks/use_fetcher';
import { useTheme } from '../../../hooks/use_theme';
import type { FieldValuePair } from '../../../../common/correlations/types';
const PAGINATION_SIZE_OPTIONS = [5, 10, 20, 50];
@ -43,7 +42,7 @@ export function CorrelationsTable<T extends FieldValuePair>({
sorting,
rowHeader,
}: CorrelationsTableProps<T>) {
const euiTheme = useTheme();
const { euiTheme } = useEuiTheme();
const trackApmEvent = useUiTracker({ app: 'apm' });
const trackSelectSignificantCorrelationTerm = useCallback(
() => debounce(() => trackApmEvent({ metric: 'select_significant_term' }), 1000),
@ -105,7 +104,7 @@ export function CorrelationsTable<T extends FieldValuePair>({
selectedTerm.fieldValue === term.fieldValue &&
selectedTerm.fieldName === term.fieldName
? {
backgroundColor: euiTheme.eui.euiColorLightestShade,
backgroundColor: euiTheme.colors.lightestShade,
}
: null,
};

View file

@ -18,6 +18,7 @@ import {
EuiBadge,
EuiSwitch,
EuiIconTip,
useEuiTheme,
} from '@elastic/eui';
import type { EuiTableSortingType } from '@elastic/eui/src/components/basic_table/table_types';
import type { Direction } from '@elastic/eui/src/services/sort/sort_direction';
@ -34,7 +35,6 @@ import { FailedTransactionsCorrelation } from '../../../../common/correlations/f
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { useLocalStorage } from '../../../hooks/use_local_storage';
import { FETCH_STATUS } from '../../../hooks/use_fetcher';
import { useTheme } from '../../../hooks/use_theme';
import { push } from '../../shared/links/url_helpers';
import { CorrelationsTable } from './correlations_table';
@ -54,7 +54,7 @@ import { MIN_TAB_TITLE_HEIGHT } from '../../shared/charts/duration_distribution_
import { TotalDocCountLabel } from '../../shared/charts/duration_distribution_chart/total_doc_count_label';
export function FailedTransactionsCorrelations({ onFilter }: { onFilter: () => void }) {
const euiTheme = useTheme();
const { euiTheme } = useEuiTheme();
const {
core: { notifications },
@ -456,7 +456,7 @@ export function FailedTransactionsCorrelations({ onFilter }: { onFilter: () => v
style={{
display: 'flex',
flexDirection: 'row',
paddingLeft: euiTheme.eui.euiSizeS,
paddingLeft: euiTheme.size.s,
}}
>
<EuiSwitch
@ -473,7 +473,7 @@ export function FailedTransactionsCorrelations({ onFilter }: { onFilter: () => v
<EuiIconTip
size="m"
iconProps={{
style: { marginLeft: euiTheme.eui.euiSizeXS },
css: { marginLeft: euiTheme.size.xs },
}}
content={i18n.translate(
'xpack.apm.correlations.latencyCorrelations.advancedStatisticsTooltipContent',

View file

@ -6,7 +6,7 @@
*/
import { i18n } from '@kbn/i18n';
import { EuiTheme } from '@kbn/kibana-react-plugin/common';
import type { EuiThemeComputed } from '@elastic/eui';
import type { HistogramItem } from '../../../../common/correlations/types';
import { DurationDistributionChartData } from '../../shared/charts/duration_distribution_chart';
import { LatencyCorrelation } from '../../../../common/correlations/latency_correlations/types';
@ -18,7 +18,7 @@ export function getTransactionDistributionChartData({
failedTransactionsHistogram,
selectedTerm,
}: {
euiTheme: EuiTheme;
euiTheme: EuiThemeComputed;
allTransactionsHistogram?: HistogramItem[];
failedTransactionsHistogram?: HistogramItem[];
selectedTerm?: LatencyCorrelation | FailedTransactionsCorrelation | undefined;
@ -31,7 +31,7 @@ export function getTransactionDistributionChartData({
defaultMessage: 'All transactions',
}),
histogram: allTransactionsHistogram,
areaSeriesColor: euiTheme.eui.euiColorVis1,
areaSeriesColor: euiTheme.colors.vis.euiColorVis1,
});
}
@ -41,7 +41,7 @@ export function getTransactionDistributionChartData({
defaultMessage: 'Failed transactions',
}),
histogram: failedTransactionsHistogram,
areaSeriesColor: euiTheme.eui.euiColorVis7,
areaSeriesColor: euiTheme.colors.vis.euiColorVis7,
});
}
@ -49,7 +49,7 @@ export function getTransactionDistributionChartData({
transactionDistributionChartData.push({
id: `${selectedTerm.fieldName}:${selectedTerm.fieldValue}`,
histogram: selectedTerm.histogram,
areaSeriesColor: euiTheme.eui.euiColorVis2,
areaSeriesColor: euiTheme.colors.vis.euiColorVis2,
});
}

View file

@ -17,6 +17,7 @@ import {
EuiTitle,
EuiBadge,
EuiIconTip,
useEuiTheme,
} from '@elastic/eui';
import { Direction } from '@elastic/eui/src/services/sort/sort_direction';
import { EuiTableSortingType } from '@elastic/eui/src/components/basic_table/table_types';
@ -47,7 +48,6 @@ import { CorrelationsProgressControls } from './progress_controls';
import { OnAddFilter } from './context_popover/field_stats_popover';
import { useLatencyCorrelations } from './use_latency_correlations';
import { getTransactionDistributionChartData } from './get_transaction_distribution_chart_data';
import { useTheme } from '../../../hooks/use_theme';
import { ChartTitleToolTip } from './chart_title_tool_tip';
import { getLatencyCorrelationImpactLabel } from './utils/get_failed_transactions_correlation_impact_label';
import { MIN_TAB_TITLE_HEIGHT } from '../../shared/charts/duration_distribution_chart_with_scrubber';
@ -68,7 +68,7 @@ export function LatencyCorrelations({ onFilter }: { onFilter: () => void }) {
core: { notifications },
} = useApmPluginContext();
const euiTheme = useTheme();
const { euiTheme } = useEuiTheme();
const { progress, response, startFetch, cancelFetch } = useLatencyCorrelations();
const { overallHistogram, hasData, status } = getOverallHistogram(response, progress.isRunning);

View file

@ -7,11 +7,11 @@
import { i18n } from '@kbn/i18n';
import { ProcessorEvent } from '@kbn/observability-plugin/common';
import React from 'react';
import { useEuiTheme } from '@elastic/eui';
import { DEFAULT_PERCENTILE_THRESHOLD } from '../../../../common/correlations/constants';
import { useApmParams } from '../../../hooks/use_apm_params';
import { useFetcher } from '../../../hooks/use_fetcher';
import { useSampleChartSelection } from '../../../hooks/use_sample_chart_selection';
import { useTheme } from '../../../hooks/use_theme';
import { useTimeRange } from '../../../hooks/use_time_range';
import { DurationDistributionChartData } from '../../shared/charts/duration_distribution_chart';
import { DurationDistributionChartWithScrubber } from '../../shared/charts/duration_distribution_chart_with_scrubber';
@ -22,7 +22,7 @@ export function DependencyOperationDistributionChart() {
// there is no "current" event in the dependency operation detail view
const markerCurrentEvent = undefined;
const euiTheme = useTheme();
const { euiTheme } = useEuiTheme();
const {
query: {
@ -67,14 +67,14 @@ export function DependencyOperationDistributionChart() {
const chartData: DurationDistributionChartData[] = [
{
areaSeriesColor: euiTheme.eui.euiColorVis1,
areaSeriesColor: euiTheme.colors.vis.euiColorVis1,
histogram: data?.allSpansDistribution.overallHistogram ?? [],
id: i18n.translate('xpack.apm.dependencyOperationDistributionChart.allSpansLegendLabel', {
defaultMessage: 'All spans',
}),
},
{
areaSeriesColor: euiTheme.eui.euiColorVis7,
areaSeriesColor: euiTheme.colors.vis.euiColorVis7,
histogram: data?.failedSpansDistribution?.overallHistogram ?? [],
id: i18n.translate('xpack.apm.dependencyOperationDistributionChart.failedSpansLegendLabel', {
defaultMessage: 'Failed spans',

View file

@ -17,7 +17,6 @@ import { fromQuery } from '../../../shared/links/url_helpers';
import { APIReturnType } from '../../../../services/rest/create_call_apm_api';
import { Redirect } from 'react-router-dom';
import { ApmPluginContextValue } from '../../../../context/apm_plugin/apm_plugin_context';
import { ApmThemeProvider } from '../../../routing/app_root';
import * as useEntityCentricExperienceSetting from '../../../../hooks/use_entity_centric_experience_setting';
jest.mock('react-router-dom', () => ({
@ -85,9 +84,7 @@ const renderEntityLink = ({
} as unknown as ApmPluginContextValue
}
>
<ApmThemeProvider>
<EntityLink />
</ApmThemeProvider>
<EntityLink />
</MockApmPluginContextWrapper>
);
return { rerender, ...tools };

View file

@ -5,7 +5,14 @@
* 2.0.
*/
import { EuiButtonEmpty, EuiEmptyPrompt, EuiImage, EuiLink, EuiLoadingSpinner } from '@elastic/eui';
import {
EuiButtonEmpty,
EuiEmptyPrompt,
EuiImage,
EuiLink,
EuiLoadingSpinner,
useEuiTheme,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { useKibana } from '@kbn/kibana-react-plugin/public';
@ -18,7 +25,6 @@ import { useApmParams } from '../../../../hooks/use_apm_params';
import { useApmRouter } from '../../../../hooks/use_apm_router';
import { useEntityCentricExperienceSetting } from '../../../../hooks/use_entity_centric_experience_setting';
import { FETCH_STATUS, isPending, useFetcher } from '../../../../hooks/use_fetcher';
import { useTheme } from '../../../../hooks/use_theme';
import { ApmPluginStartDeps } from '../../../../plugin';
const pageHeader = {
@ -27,7 +33,7 @@ const pageHeader = {
export function EntityLink() {
const router = useApmRouter({ prependBasePath: false });
const theme = useTheme();
const { colorMode } = useEuiTheme();
const { services } = useKibana<ApmPluginStartDeps>();
const { observabilityShared, data } = services;
const timeRange = data.query.timefilter.timefilter.getTime();
@ -65,7 +71,7 @@ export function EntityLink() {
icon={
<EuiImage
size="fullWidth"
src={theme.darkMode ? dashboardsDark : dashboardsLight}
src={colorMode === 'DARK' ? dashboardsDark : dashboardsLight}
alt=""
/>
}

View file

@ -18,14 +18,13 @@ import {
DARK_THEME,
LegendValue,
} from '@elastic/charts';
import { EuiTitle } from '@elastic/eui';
import { EuiTitle, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
import { FETCH_STATUS } from '../../../../hooks/use_fetcher';
import { usePreviousPeriodLabel } from '../../../../hooks/use_previous_period_text';
import { useTheme } from '../../../../hooks/use_theme';
import { APIReturnType } from '../../../../services/rest/create_call_apm_api';
import { ChartContainer } from '../../../shared/charts/chart_container';
import { ChartType, getTimeSeriesColor } from '../../../shared/charts/helper/get_timeseries_color';
@ -42,7 +41,7 @@ interface Props {
export function ErrorDistribution({ distribution, title, fetchStatus }: Props) {
const { core } = useApmPluginContext();
const theme = useTheme();
const { colorMode } = useEuiTheme();
const { urlParams } = useLegacyUrlParams();
const { comparisonEnabled } = urlParams;
@ -97,7 +96,7 @@ export function ErrorDistribution({ distribution, title, fetchStatus }: Props) {
showLegend
legendValues={[LegendValue.CurrentAndLastValue]}
legendPosition={Position.Bottom}
theme={theme.darkMode ? DARK_THEME : LIGHT_THEME}
theme={colorMode === 'DARK' ? DARK_THEME : LIGHT_THEME}
locale={i18n.getLocale()}
/>
<Axis

View file

@ -22,7 +22,7 @@ import {
EuiToolTip,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { ObservabilityTriggerId } from '@kbn/observability-shared-plugin/common';
import { getContextMenuItemsFromActions } from '@kbn/observability-shared-plugin/public';
import { first } from 'lodash';
@ -56,8 +56,8 @@ import { ExceptionStacktrace } from './exception_stacktrace';
import { SampleSummary } from './sample_summary';
import { ErrorSampleContextualInsight } from './error_sample_contextual_insight';
const TransactionLinkName = euiStyled.div`
margin-left: ${({ theme }) => theme.eui.euiSizeS};
const TransactionLinkName = styled.div`
margin-left: ${({ theme }) => theme.euiTheme.size.s};
display: inline-block;
vertical-align: middle;
`;

View file

@ -8,6 +8,7 @@
import { composeStories } from '@storybook/testing-react';
import React from 'react';
import { mount } from 'enzyme';
import { EuiThemeProvider } from '@elastic/eui';
import * as stories from './exception_stacktrace.stories';
import { ExceptionStackTraceTitleProps } from './exception_stacktrace_title';
@ -17,10 +18,16 @@ describe('ExceptionStacktrace', () => {
describe('render', () => {
describe('with stacktraces', () => {
it('renders the stacktraces', () => {
expect(mount(<JavaWithLongLines />).find('Stacktrace')).toHaveLength(3);
expect(
mount(<JavaWithLongLines />, {
wrappingComponent: EuiThemeProvider,
}).find('Stacktrace')
).toHaveLength(3);
});
it('should have the title in a specific format', function () {
const wrapper = mount(<JavaWithLongLines />).find('ExceptionStacktraceTitle');
const wrapper = mount(<JavaWithLongLines />, {
wrappingComponent: EuiThemeProvider,
}).find('ExceptionStacktraceTitle');
expect(wrapper).toHaveLength(1);
const { type, message } = wrapper.props() as ExceptionStackTraceTitleProps;
expect(wrapper.text()).toContain(`${type}: ${message}`);
@ -29,7 +36,11 @@ describe('ExceptionStacktrace', () => {
describe('with more than one stack trace', () => {
it('renders cause stacktraces', () => {
expect(mount(<JavaWithLongLines />).find('CauseStacktrace')).toHaveLength(2);
expect(
mount(<JavaWithLongLines />, {
wrappingComponent: EuiThemeProvider,
}).find('CauseStacktrace')
).toHaveLength(2);
});
});
});

View file

@ -4,17 +4,17 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { EuiText, EuiSpacer, EuiCodeBlock } from '@elastic/eui';
import { EuiText, EuiSpacer, EuiCodeBlock, useEuiFontSize } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { APMError } from '../../../../../typings/es_schemas/ui/apm_error';
import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n';
const Label = euiStyled.div`
margin-bottom: ${({ theme }) => theme.eui.euiSizeXS};
font-size: ${({ theme }) => theme.eui.euiFontSizeS};
color: ${({ theme }) => theme.eui.euiColorDarkestShade};
const Label = styled.div`
margin-bottom: ${({ theme }) => theme.euiTheme.size.xs};
font-size: ${() => useEuiFontSize('s').fontSize};
color: ${({ theme }) => theme.euiTheme.colors.darkestShade};
`;
interface Props {

View file

@ -7,7 +7,7 @@
import { EuiBadge, EuiIconTip, EuiToolTip, RIGHT_ALIGNMENT } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import React, { useMemo, useState } from 'react';
import { apmEnableTableSearchBar } from '@kbn/observability-plugin/common';
import { isPending } from '../../../../hooks/use_fetcher';
@ -30,25 +30,25 @@ import { isTimeComparison } from '../../../shared/time_comparison/get_comparison
import { ErrorGroupItem, useErrorGroupListData } from './use_error_group_list_data';
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
const GroupIdLink = euiStyled(ErrorDetailLink)`
font-family: ${({ theme }) => theme.eui.euiCodeFontFamily};
const GroupIdLink = styled(ErrorDetailLink)`
font-family: ${({ theme }) => theme.euiTheme.font.familyCode};
`;
const MessageAndCulpritCell = euiStyled.div`
const MessageAndCulpritCell = styled.div`
${truncate('100%')};
`;
const ErrorLink = euiStyled(ErrorOverviewLink)`
const ErrorLink = styled(ErrorOverviewLink)`
${truncate('100%')};
`;
const MessageLink = euiStyled(ErrorDetailLink)`
font-family: ${({ theme }) => theme.eui.euiCodeFontFamily};
const MessageLink = styled(ErrorDetailLink)`
font-family: ${({ theme }) => theme.euiTheme.font.familyCode};
${truncate('100%')};
`;
const Culprit = euiStyled.div`
font-family: ${({ theme }) => theme.eui.euiCodeFontFamily};
const Culprit = styled.div`
font-family: ${({ theme }) => theme.euiTheme.font.familyCode};
`;
interface Props {

View file

@ -16,9 +16,9 @@ import {
EuiPopoverTitle,
EuiText,
} from '@elastic/eui';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
const PopoverContent = euiStyled(EuiText)`
const PopoverContent = styled(EuiText)`
max-width: 480px;
max-height: 40vh;
`;

View file

@ -11,12 +11,12 @@ import {
EuiDescriptionListTitle,
EuiEmptyPrompt,
EuiImage,
useEuiTheme,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import noResultsIllustrationDark from '../../../../assets/no_results_dark.svg';
import noResultsIllustrationLight from '../../../../assets/no_results_light.svg';
import { useTheme } from '../../../../hooks/use_theme';
export function EmptyPrompt() {
return (
@ -52,9 +52,10 @@ export function EmptyPrompt() {
}
function NoResultsIllustration() {
const theme = useTheme();
const { colorMode } = useEuiTheme();
const illustration = theme.darkMode ? noResultsIllustrationDark : noResultsIllustrationLight;
const illustration =
colorMode === 'DARK' ? noResultsIllustrationDark : noResultsIllustrationLight;
return (
<EuiImage alt={noResultsIllustrationAlternativeText} size="fullWidth" src={illustration} />

View file

@ -7,7 +7,7 @@
import { EuiToolTip, EuiIcon } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { getServiceNodeName, SERVICE_NODE_NAME_MISSING } from '../../../../../common/service_nodes';
import { asDynamicBytes, asInteger, asPercent } from '../../../../../common/utils/formatters';
import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context';
@ -21,7 +21,7 @@ import { ITableColumn, ManagedTable } from '../../../shared/managed_table';
const INITIAL_SORT_FIELD = 'cpu';
const INITIAL_SORT_DIRECTION = 'desc';
const ServiceNodeName = euiStyled.div`
const ServiceNodeName = styled.div`
${truncate(8 * unit)}
`;

View file

@ -5,14 +5,16 @@
* 2.0.
*/
import { EuiLink } from '@elastic/eui';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import React from 'react';
import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context';
import { useApmParams } from '../../../../hooks/use_apm_params';
import { useApmRouter } from '../../../../hooks/use_apm_router';
import { truncate } from '../../../../utils/style';
const StyledLink = euiStyled(EuiLink)`${truncate('100%')};`;
const StyledLink = styled(EuiLink)`
${truncate('100%')};
`;
interface Props {
serverlessFunctionName: string;

View file

@ -15,7 +15,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import styled from 'styled-components';
import styled from '@emotion/styled';
import { asMillisecondDuration, asPercent } from '../../../../../common/utils/formatters';
import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context';
import { useApmParams } from '../../../../hooks/use_apm_params';
@ -34,7 +34,7 @@ const CentralizedContainer = styled.div`
const Border = styled.div`
height: 55px;
border-right: 1px solid ${({ theme }) => theme.eui.euiColorLightShade};
border-right: ${({ theme }) => theme.euiTheme.border.thin};
`;
function VerticalRule() {

View file

@ -20,7 +20,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import React from 'react';
import { ApmDocumentType } from '../../../../../common/document_type';
import { getServiceNodeName, SERVICE_NODE_NAME_MISSING } from '../../../../../common/service_nodes';
@ -42,7 +42,7 @@ const INITIAL_DATA = {
containerId: '',
};
const Truncate = euiStyled.span`
const Truncate = styled.span`
display: block;
${truncate(unit * 12)}
`;

View file

@ -6,14 +6,14 @@
*/
import { composeStories } from '@storybook/testing-react';
import { render } from '@testing-library/react';
import React from 'react';
import * as stories from './crash_group_list.stories';
import { renderWithTheme } from '../../../../../utils/test_helpers';
const { Example } = composeStories(stories);
describe('MobileCrashGroupList', () => {
it('renders', () => {
expect(() => render(<Example />)).not.toThrowError();
expect(() => renderWithTheme(<Example />)).not.toThrowError();
});
});

View file

@ -7,7 +7,7 @@
import { EuiToolTip, RIGHT_ALIGNMENT, LEFT_ALIGNMENT, EuiIconTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import React, { useMemo } from 'react';
import { NOT_AVAILABLE_LABEL } from '../../../../../../common/i18n';
import { asInteger } from '../../../../../../common/utils/formatters';
@ -25,20 +25,20 @@ import { ITableColumn, ManagedTable } from '../../../../shared/managed_table';
import { TimestampTooltip } from '../../../../shared/timestamp_tooltip';
import { isTimeComparison } from '../../../../shared/time_comparison/get_comparison_options';
const MessageAndCulpritCell = euiStyled.div`
const MessageAndCulpritCell = styled.div`
${truncate('100%')};
`;
const ErrorLink = euiStyled(ErrorOverviewLink)`
const ErrorLink = styled(ErrorOverviewLink)`
${truncate('100%')};
`;
const GroupIdLink = euiStyled(CrashDetailLink)`
font-family: ${({ theme }) => theme.eui.euiCodeFontFamily};
const GroupIdLink = styled(CrashDetailLink)`
font-family: ${({ theme }) => theme.euiTheme.font.familyCode};
`;
const MessageLink = euiStyled(CrashDetailLink)`
font-family: ${({ theme }) => theme.eui.euiCodeFontFamily};
const MessageLink = styled(CrashDetailLink)`
font-family: ${({ theme }) => theme.euiTheme.font.familyCode};
${truncate('100%')};
`;

View file

@ -6,14 +6,14 @@
*/
import { composeStories } from '@storybook/testing-react';
import { render } from '@testing-library/react';
import React from 'react';
import * as stories from './error_group_list.stories';
import { renderWithTheme } from '../../../../../utils/test_helpers';
const { Example } = composeStories(stories);
describe('ErrorGroupList', () => {
it('renders', () => {
expect(() => render(<Example />)).not.toThrowError();
expect(() => renderWithTheme(<Example />)).not.toThrowError();
});
});

View file

@ -7,7 +7,7 @@
import { EuiBadge, EuiToolTip, RIGHT_ALIGNMENT, LEFT_ALIGNMENT, EuiIconTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import React, { useMemo } from 'react';
import { NOT_AVAILABLE_LABEL } from '../../../../../../common/i18n';
import { asInteger } from '../../../../../../common/utils/formatters';
@ -25,20 +25,20 @@ import { ITableColumn, ManagedTable } from '../../../../shared/managed_table';
import { TimestampTooltip } from '../../../../shared/timestamp_tooltip';
import { isTimeComparison } from '../../../../shared/time_comparison/get_comparison_options';
const GroupIdLink = euiStyled(ErrorDetailLink)`
font-family: ${({ theme }) => theme.eui.euiCodeFontFamily};
const GroupIdLink = styled(ErrorDetailLink)`
font-family: ${({ theme }) => theme.euiTheme.font.familyCode};
`;
const MessageAndCulpritCell = euiStyled.div`
const MessageAndCulpritCell = styled.div`
${truncate('100%')};
`;
const ErrorLink = euiStyled(ErrorOverviewLink)`
const ErrorLink = styled(ErrorOverviewLink)`
${truncate('100%')};
`;
const MessageLink = euiStyled(ErrorDetailLink)`
font-family: ${({ theme }) => theme.eui.euiCodeFontFamily};
const MessageLink = styled(ErrorDetailLink)`
font-family: ${({ theme }) => theme.euiTheme.font.familyCode};
${truncate('100%')};
`;

View file

@ -6,9 +6,8 @@
*/
import { MetricDatum, MetricTrendShape } from '@elastic/charts';
import { i18n } from '@kbn/i18n';
import { EuiIcon, EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui';
import { EuiIcon, EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, useEuiTheme } from '@elastic/eui';
import React, { useCallback } from 'react';
import { useTheme } from '@kbn/observability-shared-plugin/public';
import { useFetcher, isPending, FETCH_STATUS } from '../../../../../hooks/use_fetcher';
import { CLIENT_GEO_COUNTRY_NAME } from '../../../../../../common/es_fields/apm';
import { NOT_AVAILABLE_LABEL } from '../../../../../../common/i18n';
@ -45,7 +44,7 @@ export function MobileLocationStats({
environment: string;
comparisonEnabled: boolean;
}) {
const euiTheme = useTheme();
const { euiTheme } = useEuiTheme();
const previousPeriodLabel = usePreviousPeriodLabel();
@ -107,7 +106,7 @@ export function MobileLocationStats({
const metrics: MetricDatum[] = [
{
color: euiTheme.eui.euiColorLightestShade,
color: euiTheme.colors.lightestShade,
title: i18n.translate('xpack.apm.mobile.location.metrics.http.requests.title', {
defaultMessage: 'Most used in',
}),
@ -121,7 +120,7 @@ export function MobileLocationStats({
trendShape: MetricTrendShape.Area,
},
{
color: euiTheme.eui.euiColorLightestShade,
color: euiTheme.colors.lightestShade,
title: i18n.translate('xpack.apm.mobile.location.metrics.mostCrashes', {
defaultMessage: 'Most crashes',
}),
@ -135,7 +134,7 @@ export function MobileLocationStats({
trendShape: MetricTrendShape.Area,
},
{
color: euiTheme.eui.euiColorLightestShade,
color: euiTheme.colors.lightestShade,
title: i18n.translate('xpack.apm.mobile.location.metrics.sessions', {
defaultMessage: 'Most sessions',
}),
@ -149,7 +148,7 @@ export function MobileLocationStats({
trendShape: MetricTrendShape.Area,
},
{
color: euiTheme.eui.euiColorLightestShade,
color: euiTheme.colors.lightestShade,
title: i18n.translate('xpack.apm.mobile.location.metrics.launches', {
defaultMessage: 'Most launches',
}),

View file

@ -6,9 +6,8 @@
*/
import { MetricDatum, MetricTrendShape } from '@elastic/charts';
import { i18n } from '@kbn/i18n';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLoadingSpinner } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLoadingSpinner, useEuiTheme } from '@elastic/eui';
import React, { useCallback } from 'react';
import { useTheme } from '@kbn/observability-shared-plugin/public';
import { NOT_AVAILABLE_LABEL } from '../../../../../../common/i18n';
import { useAnyOfApmParams } from '../../../../../hooks/use_apm_params';
import { FETCH_STATUS, isPending, useFetcher } from '../../../../../hooks/use_fetcher';
@ -20,7 +19,7 @@ const valueFormatter = (value: number, suffix = '') => {
};
export function MobileStats({ start, end, kuery }: { start: string; end: string; kuery: string }) {
const euiTheme = useTheme();
const { euiTheme } = useEuiTheme();
const {
path: { serviceName },
@ -77,7 +76,7 @@ export function MobileStats({ start, end, kuery }: { start: string; end: string;
const metrics: MetricDatum[] = [
{
color: euiTheme.eui.euiColorLightestShade,
color: euiTheme.colors.lightestShade,
title: i18n.translate('xpack.apm.mobile.metrics.crash.rate', {
defaultMessage: 'Crash rate',
}),
@ -92,7 +91,7 @@ export function MobileStats({ start, end, kuery }: { start: string; end: string;
trendShape: MetricTrendShape.Area,
},
{
color: euiTheme.eui.euiColorLightestShade,
color: euiTheme.colors.lightestShade,
title: i18n.translate('xpack.apm.mobile.metrics.load.time', {
defaultMessage: 'Average app load time',
}),
@ -105,7 +104,7 @@ export function MobileStats({ start, end, kuery }: { start: string; end: string;
trendShape: MetricTrendShape.Area,
},
{
color: euiTheme.eui.euiColorLightestShade,
color: euiTheme.colors.lightestShade,
title: i18n.translate('xpack.apm.mobile.metrics.sessions', {
defaultMessage: 'Sessions',
}),
@ -118,7 +117,7 @@ export function MobileStats({ start, end, kuery }: { start: string; end: string;
trendShape: MetricTrendShape.Area,
},
{
color: euiTheme.eui.euiColorLightestShade,
color: euiTheme.colors.lightestShade,
title: i18n.translate('xpack.apm.mobile.metrics.http.requests', {
defaultMessage: 'HTTP requests',
}),

View file

@ -5,17 +5,16 @@
* 2.0.
*/
import React from 'react';
import { EuiEmptyPrompt, EuiImage } from '@elastic/eui';
import { EuiEmptyPrompt, EuiImage, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { dashboardsDark, dashboardsLight } from '@kbn/shared-svg';
import { useTheme } from '../../../hooks/use_theme';
interface Props {
actions: React.ReactNode;
}
export function EmptyDashboards({ actions }: Props) {
const theme = useTheme();
const { colorMode } = useEuiTheme();
return (
<>
@ -25,7 +24,7 @@ export function EmptyDashboards({ actions }: Props) {
icon={
<EuiImage
size="fullWidth"
src={theme.darkMode ? dashboardsDark : dashboardsLight}
src={colorMode === 'DARK' ? dashboardsDark : dashboardsLight}
alt=""
/>
}

View file

@ -23,7 +23,7 @@ import {
import { i18n } from '@kbn/i18n';
import { css } from '@emotion/react';
import React, { useEffect, useState, useMemo } from 'react';
import styled from 'styled-components';
import styled from '@emotion/styled';
import { isEmpty } from 'lodash';
import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher';
import { KueryBar } from '../../../shared/kuery_bar';

View file

@ -6,19 +6,18 @@
*/
import React from 'react';
import { EuiBadge } from '@elastic/eui';
import { EuiBadge, useEuiTheme } from '@elastic/eui';
import {
getServiceHealthStatusBadgeColor,
getServiceHealthStatusLabel,
ServiceHealthStatus,
} from '../../../../../common/service_health_status';
import { useTheme } from '../../../../hooks/use_theme';
export function HealthBadge({ healthStatus }: { healthStatus: ServiceHealthStatus }) {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
return (
<EuiBadge color={getServiceHealthStatusBadgeColor(theme, healthStatus)}>
<EuiBadge color={getServiceHealthStatusBadgeColor(euiTheme, healthStatus)}>
{getServiceHealthStatusLabel(healthStatus)}
</EuiBadge>
);

View file

@ -5,15 +5,13 @@
* 2.0.
*/
import { euiLightVars as lightTheme } from '@kbn/ui-theme';
import { render } from '@testing-library/react';
import cytoscape from 'cytoscape';
import React, { ReactNode } from 'react';
import { MemoryRouter } from 'react-router-dom';
import { ThemeContext } from 'styled-components';
import { MockApmPluginContextWrapper } from '../../../context/apm_plugin/mock_apm_plugin_context';
import { Controls } from './controls';
import { CytoscapeContext } from './cytoscape';
import { renderWithTheme } from '../../../utils/test_helpers';
const cy = cytoscape({
elements: [{ classes: 'primary', data: { id: 'test node' } }],
@ -27,11 +25,8 @@ function Wrapper({ children }: { children?: ReactNode }) {
'/service-map?rangeFrom=now-15m&rangeTo=now&environment=ENVIRONMENT_ALL&kuery=',
]}
>
<MockApmPluginContextWrapper>
<ThemeContext.Provider value={{ eui: lightTheme }}>{children}</ThemeContext.Provider>
</MockApmPluginContextWrapper>
<MockApmPluginContextWrapper>{children}</MockApmPluginContextWrapper>
</MemoryRouter>
s
</CytoscapeContext.Provider>
);
}
@ -39,7 +34,7 @@ function Wrapper({ children }: { children?: ReactNode }) {
describe('Controls', () => {
describe('with a primary node', () => {
it('links to the full map', async () => {
const result = render(<Controls />, { wrapper: Wrapper });
const result = renderWithTheme(<Controls />, { wrapper: Wrapper });
const { findByTestId } = result;
const button = await findByTestId('viewFullMapButton');

View file

@ -5,12 +5,11 @@
* 2.0.
*/
import { EuiButtonIcon, EuiPanel, EuiToolTip } from '@elastic/eui';
import { EuiButtonIcon, EuiPanel, EuiToolTip, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useContext, useEffect, useState } from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { useTheme } from '../../../hooks/use_theme';
import { getLegacyApmHref } from '../../shared/links/apm/apm_link';
import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params';
import { APMQueryParams } from '../../shared/links/url_helpers';
@ -18,24 +17,24 @@ import { CytoscapeContext } from './cytoscape';
import { getAnimationOptions, getNodeHeight } from './cytoscape_options';
import { useAnyOfApmParams } from '../../../hooks/use_apm_params';
const ControlsContainer = euiStyled('div')`
left: ${({ theme }) => theme.eui.euiSize};
const ControlsContainer = styled('div')`
left: ${({ theme }) => theme.euiTheme.size.base};
position: absolute;
top: ${({ theme }) => theme.eui.euiSizeS};
top: ${({ theme }) => theme.euiTheme.size.s};
z-index: 1; /* The element containing the cytoscape canvas has z-index = 0. */
`;
const Button = euiStyled(EuiButtonIcon)`
const Button = styled(EuiButtonIcon)`
display: block;
margin: ${({ theme }) => theme.eui.euiSizeXS};
margin: ${({ theme }) => theme.euiTheme.size.xs};
`;
const ZoomInButton = euiStyled(Button)`
margin-bottom: ${({ theme }) => theme.eui.euiSizeS};
const ZoomInButton = styled(Button)`
margin-bottom: ${({ theme }) => theme.euiTheme.size.s};
`;
const Panel = euiStyled(EuiPanel)`
margin-bottom: ${({ theme }) => theme.eui.euiSizeS};
const Panel = styled(EuiPanel)`
margin-bottom: ${({ theme }) => theme.euiTheme.size.s};
`;
const steps = 5;
@ -97,7 +96,7 @@ function useDebugDownloadUrl(cy?: cytoscape.Core) {
export function Controls() {
const { core } = useApmPluginContext();
const { basePath } = core.http;
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const cy = useContext(CytoscapeContext);
const { urlParams } = useLegacyUrlParams();
@ -110,7 +109,7 @@ export function Controls() {
);
const [zoom, setZoom] = useState((cy && cy.zoom()) || 1);
const duration = parseInt(theme.eui.euiAnimSpeedFast, 10);
const duration = euiTheme.animation.fast ? parseInt(euiTheme.animation.fast, 10) : 0;
const downloadUrl = useDebugDownloadUrl(cy);
const viewFullMapUrl = getLegacyApmHref({
basePath,
@ -140,9 +139,9 @@ export function Controls() {
if (cy) {
const eles = cy.nodes();
cy.animate({
...getAnimationOptions(theme),
...getAnimationOptions(euiTheme),
center: { eles },
fit: { eles, padding: getNodeHeight(theme) },
fit: { eles, padding: getNodeHeight(euiTheme) },
});
}
}

View file

@ -17,7 +17,7 @@ import React, {
useRef,
useState,
} from 'react';
import { useTheme } from '../../../hooks/use_theme';
import { useEuiTheme } from '@elastic/eui';
import { useTraceExplorerEnabledSetting } from '../../../hooks/use_trace_explorer_enabled_setting';
import { getCytoscapeOptions } from './cytoscape_options';
import { useCytoscapeEventHandlers } from './use_cytoscape_event_handlers';
@ -57,13 +57,13 @@ function useCytoscape(options: cytoscape.CytoscapeOptions) {
}
function CytoscapeComponent({ children, elements, height, serviceName, style }: CytoscapeProps) {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const isTraceExplorerEnabled = useTraceExplorerEnabledSetting();
const [ref, cy] = useCytoscape({
...getCytoscapeOptions(theme, isTraceExplorerEnabled),
...getCytoscapeOptions(euiTheme, isTraceExplorerEnabled),
elements,
});
useCytoscapeEventHandlers({ cy, serviceName, theme });
useCytoscapeEventHandlers({ cy, serviceName, euiTheme });
// Add items from the elements prop to the cytoscape collection and remove
// items that no longer are in the list, then trigger an event to notify

View file

@ -7,7 +7,7 @@
import cytoscape from 'cytoscape';
import { CSSProperties } from 'react';
import { EuiTheme } from '@kbn/kibana-react-plugin/common';
import type { EuiThemeComputed } from '@elastic/eui';
import { ServiceAnomalyStats } from '../../../../common/anomaly_detection';
import { SERVICE_NAME, SPAN_DESTINATION_SERVICE_RESOURCE } from '../../../../common/es_fields/apm';
import {
@ -26,21 +26,21 @@ function getServiceAnomalyStats(el: cytoscape.NodeSingular) {
}
function getBorderColorFn(
theme: EuiTheme
euiTheme: EuiThemeComputed
): cytoscape.Css.MapperFunction<cytoscape.NodeSingular, string> {
return (el: cytoscape.NodeSingular) => {
const hasAnomalyDetectionJob = el.data('serviceAnomalyStats') !== undefined;
const anomalyStats = getServiceAnomalyStats(el);
if (hasAnomalyDetectionJob) {
return getServiceHealthStatusColor(
theme,
euiTheme,
anomalyStats?.healthStatus ?? ServiceHealthStatus.unknown
);
}
if (el.hasClass('primary') || el.selected()) {
return theme.eui.euiColorPrimary;
return euiTheme.colors.primary;
}
return theme.eui.euiColorMediumShade;
return euiTheme.colors.mediumShade;
};
}
@ -79,10 +79,10 @@ function getBorderWidth(el: cytoscape.NodeSingular) {
// @ts-expect-error `documentMode` is not recognized as a valid property of `document`.
const isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
export const getAnimationOptions = (theme: EuiTheme): cytoscape.AnimationOptions => ({
duration: parseInt(theme.eui.euiAnimSpeedNormal, 10),
export const getAnimationOptions = (euiTheme: EuiThemeComputed): cytoscape.AnimationOptions => ({
duration: euiTheme.animation.normal ? parseInt(euiTheme.animation.normal, 10) : 0,
// @ts-expect-error The cubic-bezier options here are not recognized by the cytoscape types
easing: theme.eui.euiAnimSlightBounce,
easing: euiTheme.animation.bounce,
});
const zIndexNode = 200;
@ -90,14 +90,18 @@ const zIndexEdge = 100;
const zIndexEdgeHighlight = 110;
const zIndexEdgeHover = 120;
export const getNodeHeight = (theme: EuiTheme): number => parseInt(theme.eui.euiSizeXXL, 10);
export const getNodeHeight = (euiTheme: EuiThemeComputed): number =>
parseInt(euiTheme.size.xxl, 10);
function isService(el: cytoscape.NodeSingular) {
return el.data(SERVICE_NAME) !== undefined;
}
const getStyle = (theme: EuiTheme, isTraceExplorerEnabled: boolean): cytoscape.Stylesheet[] => {
const lineColor = theme.eui.euiColorMediumShade;
const getStyle = (
euiTheme: EuiThemeComputed,
isTraceExplorerEnabled: boolean
): cytoscape.Stylesheet[] => {
const lineColor = euiTheme.colors.mediumShade;
return [
{
selector: 'core',
@ -107,46 +111,46 @@ const getStyle = (theme: EuiTheme, isTraceExplorerEnabled: boolean): cytoscape.S
{
selector: 'node',
style: {
'background-color': theme.eui.euiColorGhost,
'background-color': euiTheme.colors.backgroundBasePlain,
// The DefinitelyTyped definitions don't specify that a function can be
// used here.
'background-image': (el: cytoscape.NodeSingular) => iconForNode(el),
'background-height': (el: cytoscape.NodeSingular) => (isService(el) ? '60%' : '40%'),
'background-width': (el: cytoscape.NodeSingular) => (isService(el) ? '60%' : '40%'),
'border-color': getBorderColorFn(theme),
'border-color': getBorderColorFn(euiTheme),
'border-style': getBorderStyle,
'border-width': getBorderWidth,
color: (el: cytoscape.NodeSingular) =>
el.hasClass('primary') || el.selected()
? theme.eui.euiColorPrimaryText
: theme.eui.euiTextColor,
? euiTheme.colors.textPrimary
: euiTheme.colors.textParagraph,
// theme.euiFontFamily doesn't work here for some reason, so we're just
// specifying a subset of the fonts for the label text.
'font-family': 'Inter UI, Segoe UI, Helvetica, Arial, sans-serif',
'font-size': theme.eui.euiFontSizeS,
'font-size': euiTheme.size.s,
ghost: 'yes',
'ghost-offset-x': 0,
'ghost-offset-y': 2,
'ghost-opacity': 0.15,
height: getNodeHeight(theme),
height: getNodeHeight(euiTheme),
label: (el: cytoscape.NodeSingular) =>
isService(el)
? el.data(SERVICE_NAME)
: el.data('label') || el.data(SPAN_DESTINATION_SERVICE_RESOURCE),
'min-zoomed-font-size': parseInt(theme.eui.euiSizeS, 10),
'min-zoomed-font-size': parseInt(euiTheme.size.s, 10),
'overlay-opacity': 0,
shape: (el: cytoscape.NodeSingular) =>
isService(el) ? (isIE11 ? 'rectangle' : 'ellipse') : 'diamond',
'text-background-color': theme.eui.euiColorPrimary,
'text-background-color': euiTheme.colors.primary,
'text-background-opacity': (el: cytoscape.NodeSingular) =>
el.hasClass('primary') || el.selected() ? 0.1 : 0,
'text-background-padding': theme.eui.euiSizeXS,
'text-background-padding': euiTheme.size.xs,
'text-background-shape': 'roundrectangle',
'text-margin-y': parseInt(theme.eui.euiSizeS, 10),
'text-margin-y': parseInt(euiTheme.size.s, 10),
'text-max-width': '200px',
'text-valign': 'bottom',
'text-wrap': 'ellipsis',
width: theme.eui.euiSizeXXL,
width: euiTheme.size.xxl,
'z-index': zIndexNode,
},
},
@ -162,7 +166,7 @@ const getStyle = (theme: EuiTheme, isTraceExplorerEnabled: boolean): cytoscape.S
// fairly new.
//
// @ts-expect-error
'target-distance-from-node': isIE11 ? undefined : theme.eui.euiSizeXS,
'target-distance-from-node': isIE11 ? undefined : euiTheme.size.xs,
width: 1,
'source-arrow-shape': 'none',
'z-index': zIndexEdge,
@ -175,8 +179,8 @@ const getStyle = (theme: EuiTheme, isTraceExplorerEnabled: boolean): cytoscape.S
'source-arrow-color': lineColor,
'target-arrow-shape': isIE11 ? 'none' : 'triangle',
// @ts-expect-error
'source-distance-from-node': isIE11 ? undefined : parseInt(theme.eui.euiSizeXS, 10),
'target-distance-from-node': isIE11 ? undefined : parseInt(theme.eui.euiSizeXS, 10),
'source-distance-from-node': isIE11 ? undefined : parseInt(euiTheme.size.xs, 10),
'target-distance-from-node': isIE11 ? undefined : parseInt(euiTheme.size.xs, 10),
},
},
{
@ -190,9 +194,9 @@ const getStyle = (theme: EuiTheme, isTraceExplorerEnabled: boolean): cytoscape.S
style: {
width: 4,
'z-index': zIndexEdgeHover,
'line-color': theme.eui.euiColorDarkShade,
'source-arrow-color': theme.eui.euiColorDarkShade,
'target-arrow-color': theme.eui.euiColorDarkShade,
'line-color': euiTheme.colors.darkShade,
'source-arrow-color': euiTheme.colors.darkShade,
'target-arrow-color': euiTheme.colors.darkShade,
},
},
...(isTraceExplorerEnabled
@ -202,9 +206,9 @@ const getStyle = (theme: EuiTheme, isTraceExplorerEnabled: boolean): cytoscape.S
style: {
width: 4,
'z-index': zIndexEdgeHover,
'line-color': theme.eui.euiColorDarkShade,
'source-arrow-color': theme.eui.euiColorDarkShade,
'target-arrow-color': theme.eui.euiColorDarkShade,
'line-color': euiTheme.colors.darkShade,
'source-arrow-color': euiTheme.colors.darkShade,
'target-arrow-color': euiTheme.colors.darkShade,
},
},
]
@ -219,9 +223,9 @@ const getStyle = (theme: EuiTheme, isTraceExplorerEnabled: boolean): cytoscape.S
selector: 'edge.highlight',
style: {
width: 4,
'line-color': theme.eui.euiColorPrimary,
'source-arrow-color': theme.eui.euiColorPrimary,
'target-arrow-color': theme.eui.euiColorPrimary,
'line-color': euiTheme.colors.primary,
'source-arrow-color': euiTheme.colors.primary,
'target-arrow-color': euiTheme.colors.primary,
'z-index': zIndexEdgeHighlight,
},
},
@ -230,32 +234,35 @@ const getStyle = (theme: EuiTheme, isTraceExplorerEnabled: boolean): cytoscape.S
// The CSS styles for the div containing the cytoscape element. Makes a
// background grid of dots.
export const getCytoscapeDivStyle = (theme: EuiTheme, status: FETCH_STATUS): CSSProperties => ({
export const getCytoscapeDivStyle = (
euiTheme: EuiThemeComputed,
status: FETCH_STATUS
): CSSProperties => ({
background: `linear-gradient(
90deg,
${theme.eui.euiPageBackgroundColor}
calc(${theme.eui.euiSizeL} - calc(${theme.eui.euiSizeXS} / 2)),
${euiTheme.colors.backgroundBasePlain}
calc(${euiTheme.size.l} - calc(${euiTheme.size.xs} / 2)),
transparent 1%
)
center,
linear-gradient(
${theme.eui.euiPageBackgroundColor}
calc(${theme.eui.euiSizeL} - calc(${theme.eui.euiSizeXS} / 2)),
${euiTheme.colors.backgroundBasePlain}
calc(${euiTheme.size.l} - calc(${euiTheme.size.xs} / 2)),
transparent 1%
)
center,
${theme.eui.euiColorLightShade}`,
backgroundSize: `${theme.eui.euiSizeL} ${theme.eui.euiSizeL}`,
${euiTheme.colors.lightShade}`,
backgroundSize: `${euiTheme.size.l} ${euiTheme.size.l}`,
cursor: `${status === FETCH_STATUS.LOADING ? 'wait' : 'grab'}`,
marginTop: 0,
});
export const getCytoscapeOptions = (
theme: EuiTheme,
euiTheme: EuiThemeComputed,
isTraceExplorerEnabled: boolean
): cytoscape.CytoscapeOptions => ({
boxSelectionEnabled: false,
maxZoom: 3,
minZoom: 0.2,
style: getStyle(theme, isTraceExplorerEnabled),
style: getStyle(euiTheme, isTraceExplorerEnabled),
});

View file

@ -6,26 +6,22 @@
*/
import React, { useContext, useEffect, useState } from 'react';
import { EuiCallOut, EuiLink } from '@elastic/eui';
import { EuiCallOut, EuiLink, useEuiTheme } from '@elastic/eui';
import styled from '@emotion/styled';
import { i18n } from '@kbn/i18n';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import { CytoscapeContext } from './cytoscape';
import { useTheme } from '../../../hooks/use_theme';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
const EmptyBannerContainer = euiStyled.div`
margin: ${({ theme }) => theme.eui.euiSizeS};
const EmptyBannerContainer = styled.div`
margin: ${({ theme }) => theme.euiTheme.size.s};
/* Add some extra margin so it displays to the right of the controls. */
left: calc(
${({ theme }) => theme.eui.euiSizeXXL} +
${({ theme }) => theme.eui.euiSizeS}
);
left: calc(${({ theme }) => theme.euiTheme.size.xxl} + ${({ theme }) => theme.euiTheme.size.s});
position: absolute;
z-index: 1;
`;
export function EmptyBanner() {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const cy = useContext(CytoscapeContext);
const [nodeCount, setNodeCount] = useState(0);
const { docLinks } = useApmPluginContext().core;
@ -51,7 +47,7 @@ export function EmptyBanner() {
// Since we're absolutely positioned, we need to get the full width and
// subtract the space for controls and margins.
const width = cy.width() - parseInt(theme.eui.euiSizeXXL, 10) - parseInt(theme.eui.euiSizeL, 10);
const width = cy.width() - parseInt(euiTheme.size.xxl, 10) - parseInt(euiTheme.size.l, 10);
return (
<EmptyBannerContainer style={{ width }}>

View file

@ -6,14 +6,13 @@
*/
import { usePerformanceContext } from '@kbn/ebt-tools';
import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, EuiPanel } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, EuiPanel, useEuiTheme } from '@elastic/eui';
import React, { ReactNode } from 'react';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { isActivePlatinumLicense } from '../../../../common/license_check';
import { invalidLicenseMessage, SERVICE_MAP_TIMEOUT_ERROR } from '../../../../common/service_map';
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
import { useLicenseContext } from '../../../context/license/use_license_context';
import { useTheme } from '../../../hooks/use_theme';
import { LicensePrompt } from '../../shared/license_prompt';
import { Controls } from './controls';
import { Cytoscape } from './cytoscape';
@ -103,7 +102,7 @@ export function ServiceMap({
end: string;
serviceGroupId?: string;
}) {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const license = useLicenseContext();
const serviceName = useServiceName();
const { config } = useApmPluginContext();
@ -200,7 +199,7 @@ export function ServiceMap({
elements={data.elements}
height={heightWithPadding}
serviceName={serviceName}
style={getCytoscapeDivStyle(theme, status)}
style={getCytoscapeDivStyle(euiTheme, status)}
>
<Controls />
{serviceName && <EmptyBanner />}

View file

@ -5,10 +5,18 @@
* 2.0.
*/
import { EuiFlexGroup, EuiFlexItem, EuiHealth, EuiIconTip, EuiTitle } from '@elastic/eui';
import {
EuiFlexGroup,
EuiFlexItem,
EuiHealth,
EuiIconTip,
EuiTitle,
useEuiFontSize,
useEuiTheme,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { getSeverity, ServiceAnomalyStats } from '../../../../../common/anomaly_detection';
import {
getServiceHealthStatus,
@ -16,32 +24,31 @@ import {
} from '../../../../../common/service_health_status';
import { TRANSACTION_REQUEST } from '../../../../../common/transaction_types';
import { asDuration, asInteger } from '../../../../../common/utils/formatters';
import { useTheme } from '../../../../hooks/use_theme';
import { MLSingleMetricLink } from '../../../shared/links/machine_learning_links/mlsingle_metric_link';
import { popoverWidth } from '../cytoscape_options';
const HealthStatusTitle = euiStyled(EuiTitle)`
const HealthStatusTitle = styled(EuiTitle)`
display: inline;
text-transform: uppercase;
`;
const VerticallyCentered = euiStyled.div`
const VerticallyCentered = styled.div`
display: flex;
align-items: center;
`;
const SubduedText = euiStyled.span`
color: ${({ theme }) => theme.eui.euiTextSubduedColor};
const SubduedText = styled.span`
color: ${({ theme }) => theme.euiTheme.colors.textSubdued};
`;
const EnableText = euiStyled.section`
color: ${({ theme }) => theme.eui.euiTextSubduedColor};
const EnableText = styled.section`
color: ${({ theme }) => theme.euiTheme.colors.textSubdued};
line-height: 1.4;
font-size: ${({ theme }) => theme.eui.euiFontSizeS};
font-size: ${() => useEuiFontSize('s').fontSize};
width: ${popoverWidth}px;
`;
export const ContentLine = euiStyled.section`
export const ContentLine = styled.section`
line-height: 2;
`;
@ -50,7 +57,7 @@ interface Props {
serviceAnomalyStats: ServiceAnomalyStats | undefined;
}
export function AnomalyDetection({ serviceName, serviceAnomalyStats }: Props) {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const anomalyScore = serviceAnomalyStats?.anomalyScore;
const severity = getSeverity(anomalyScore);
@ -76,7 +83,7 @@ export function AnomalyDetection({ serviceName, serviceAnomalyStats }: Props) {
<EuiFlexGroup>
<EuiFlexItem>
<VerticallyCentered>
<EuiHealth color={getServiceHealthStatusColor(theme, healthStatus)} />
<EuiHealth color={getServiceHealthStatusColor(euiTheme, healthStatus)} />
<SubduedText>{ANOMALY_DETECTION_SCORE_METRIC}</SubduedText>
</VerticallyCentered>
</EuiFlexItem>

View file

@ -12,7 +12,7 @@ import {
EuiFlexItem,
} from '@elastic/eui';
import React, { Fragment } from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { NodeDataDefinition } from 'cytoscape';
import { ContentsProps } from '.';
import {
@ -22,7 +22,7 @@ import {
} from '../../../../../common/es_fields/apm';
import { ExternalConnectionNode } from '../../../../../common/service_map';
const ExternalResourcesList = euiStyled.section`
const ExternalResourcesList = styled.section`
max-height: 360px;
overflow: auto;
`;

View file

@ -13,6 +13,7 @@ import {
EuiTitle,
EuiToolTip,
EuiIcon,
useEuiTheme,
} from '@elastic/eui';
import cytoscape from 'cytoscape';
import React, {
@ -27,7 +28,6 @@ import React, {
import { i18n } from '@kbn/i18n';
import { SERVICE_NAME, SPAN_TYPE } from '../../../../../common/es_fields/apm';
import { Environment } from '../../../../../common/environment_rt';
import { useTheme } from '../../../../hooks/use_theme';
import { useTraceExplorerEnabledSetting } from '../../../../hooks/use_trace_explorer_enabled_setting';
import { CytoscapeContext } from '../cytoscape';
import { getAnimationOptions, popoverWidth } from '../cytoscape_options';
@ -83,7 +83,7 @@ interface PopoverProps {
}
export function Popover({ focusedServiceName, environment, kuery, start, end }: PopoverProps) {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const cy = useContext(CytoscapeContext);
const [selectedElement, setSelectedElement] = useState<
cytoscape.NodeSingular | cytoscape.EdgeSingular | undefined
@ -164,12 +164,12 @@ export function Popover({ focusedServiceName, environment, kuery, start, end }:
event.preventDefault();
if (cy) {
cy.animate({
...getAnimationOptions(theme),
...getAnimationOptions(euiTheme),
center: { eles: cy.getElementById(selectedElementId) },
});
}
},
[cy, selectedElementId, theme]
[cy, selectedElementId, euiTheme]
);
const isAlreadyFocused = focusedServiceName === selectedElementId;

View file

@ -6,16 +6,17 @@
*/
import { composeStories } from '@storybook/testing-react';
import { render, screen, waitFor } from '@testing-library/react';
import { screen, waitFor } from '@testing-library/react';
import React from 'react';
import * as stories from './popover.stories';
import { renderWithTheme } from '../../../../utils/test_helpers';
const { Dependency, ExternalsList, Resource, Service } = composeStories(stories);
describe('Popover', () => {
describe('with dependency data', () => {
it('renders a dependency link', async () => {
render(<Dependency />);
renderWithTheme(<Dependency />);
await waitFor(() => {
expect(screen.getByRole('link', { name: /Dependency Details/i })).toBeInTheDocument();
@ -25,7 +26,7 @@ describe('Popover', () => {
describe('with externals list data', () => {
it('renders an externals list', async () => {
render(<ExternalsList />);
renderWithTheme(<ExternalsList />);
await waitFor(() => {
expect(screen.getByText(/813-mam-392.mktoresp.com:443/)).toBeInTheDocument();
@ -35,7 +36,7 @@ describe('Popover', () => {
describe('with resource data', () => {
it('renders with no buttons', async () => {
render(<Resource />);
renderWithTheme(<Resource />);
await waitFor(() => {
expect(screen.queryByRole('link')).not.toBeInTheDocument();
@ -45,7 +46,7 @@ describe('Popover', () => {
describe('with service data', () => {
it('renders contents for a service', async () => {
render(<Service />);
renderWithTheme(<Service />);
await waitFor(() => {
expect(screen.getByRole('link', { name: /service details/i })).toBeInTheDocument();

View file

@ -8,18 +8,18 @@
import { EuiDescriptionListDescription, EuiDescriptionListTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { NodeDataDefinition } from 'cytoscape';
import type { ContentsProps } from '.';
import { SPAN_SUBTYPE, SPAN_TYPE } from '../../../../../common/es_fields/apm';
const ItemRow = euiStyled.div`
const ItemRow = styled.div`
line-height: 2;
`;
const SubduedDescriptionListTitle = euiStyled(EuiDescriptionListTitle)`
const SubduedDescriptionListTitle = styled(EuiDescriptionListTitle)`
&&& {
color: ${({ theme }) => theme.eui.euiTextSubduedColor};
color: ${({ theme }) => theme.euiTheme.colors.textSubdued};
}
`;

View file

@ -8,24 +8,25 @@
import { renderHook } from '@testing-library/react';
import cytoscape from 'cytoscape';
import dagre from 'cytoscape-dagre';
import { EuiTheme } from '@kbn/kibana-react-plugin/common';
import { useUiTracker } from '@kbn/observability-shared-plugin/public';
import { useCytoscapeEventHandlers } from './use_cytoscape_event_handlers';
import lodash from 'lodash';
import type { EuiThemeComputed } from '@elastic/eui';
jest.mock('@kbn/observability-shared-plugin/public');
cytoscape.use(dagre);
const theme = {
eui: { avatarSizing: { l: { size: 10 } } },
} as unknown as EuiTheme;
const euiTheme = {
size: { avatarSizing: { l: { size: 10 } } },
animation: { normal: '1s' },
} as unknown as EuiThemeComputed;
describe('useCytoscapeEventHandlers', () => {
describe('when cytoscape is undefined', () => {
it('runs', () => {
expect(() => {
renderHook(() => useCytoscapeEventHandlers({ cy: undefined, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy: undefined, euiTheme }));
}).not.toThrowError();
});
});
@ -45,7 +46,7 @@ describe('useCytoscapeEventHandlers', () => {
} as unknown as cytoscape.CollectionReturnValue),
} as unknown as cytoscape.CollectionReturnValue);
renderHook(() => useCytoscapeEventHandlers({ serviceName: 'test', cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ serviceName: 'test', cy, euiTheme }));
cy.trigger('custom:data');
expect(cy.getElementById('test').hasClass('primary')).toEqual(true);
@ -66,7 +67,7 @@ describe('useCytoscapeEventHandlers', () => {
} as unknown as cytoscape.CollectionReturnValue),
} as unknown as cytoscape.CollectionReturnValue);
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.trigger('custom:data');
expect(run).toHaveBeenCalled();
@ -85,7 +86,7 @@ describe('useCytoscapeEventHandlers', () => {
const edge = cy.getElementById('test');
const style = jest.spyOn(edge, 'style');
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.trigger('layoutstop');
expect(style).toHaveBeenCalledWith('control-point-distances', [-0, 0]);
@ -97,7 +98,7 @@ describe('useCytoscapeEventHandlers', () => {
const cy = cytoscape({ elements: [{ data: { id: 'test' } }] });
const node = cy.getElementById('test');
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
node.trigger('drag');
expect(node.data('hasBeenDragged')).toEqual(true);
@ -110,7 +111,7 @@ describe('useCytoscapeEventHandlers', () => {
});
const node = cy.getElementById('test');
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
node.trigger('drag');
expect(node.data('hasBeenDragged')).toEqual(true);
@ -126,7 +127,7 @@ describe('useCytoscapeEventHandlers', () => {
} as unknown as HTMLElement;
jest.spyOn(cy, 'container').mockReturnValueOnce(container);
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.getElementById('test').trigger('dragfree');
expect(container.style.cursor).toEqual('pointer');
@ -140,7 +141,7 @@ describe('useCytoscapeEventHandlers', () => {
});
const node = cy.getElementById('test');
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
node.trigger('mouseover');
expect(node.hasClass('hover')).toEqual(true);
@ -153,7 +154,7 @@ describe('useCytoscapeEventHandlers', () => {
} as unknown as HTMLElement;
jest.spyOn(cy, 'container').mockReturnValueOnce(container);
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.getElementById('test').trigger('mouseover');
expect(container.style.cursor).toEqual('pointer');
@ -168,7 +169,7 @@ describe('useCytoscapeEventHandlers', () => {
return fn;
});
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.getElementById('test').trigger('mouseover');
expect(trackApmEvent).toHaveBeenCalledWith({
@ -184,7 +185,7 @@ describe('useCytoscapeEventHandlers', () => {
});
const node = cy.getElementById('test');
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
node.trigger('mouseout');
expect(node.hasClass('hover')).toEqual(false);
@ -197,7 +198,7 @@ describe('useCytoscapeEventHandlers', () => {
} as unknown as HTMLElement;
jest.spyOn(cy, 'container').mockReturnValueOnce(container);
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.getElementById('test').trigger('mouseout');
expect(container.style.cursor).toEqual('grab');
@ -218,7 +219,7 @@ describe('useCytoscapeEventHandlers', () => {
} as unknown as HTMLElement;
jest.spyOn(cy, 'container').mockReturnValueOnce(container);
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.getElementById('test').trigger('mouseover');
expect(container.style.cursor).toEqual('default');
@ -235,7 +236,7 @@ describe('useCytoscapeEventHandlers', () => {
return fn;
});
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.getElementById('test').trigger('select');
expect(trackApmEvent).toHaveBeenCalledWith({
@ -258,7 +259,7 @@ describe('useCytoscapeEventHandlers', () => {
useCytoscapeEventHandlers({
serviceName: 'test',
cy,
theme,
euiTheme,
})
);
cy.getElementById('test').trigger('unselect');
@ -275,7 +276,7 @@ describe('useCytoscapeEventHandlers', () => {
} as unknown as HTMLElement;
jest.spyOn(cy, 'container').mockReturnValueOnce(container);
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.trigger('tapstart');
expect(container.style.cursor).toEqual('grabbing');
@ -289,7 +290,7 @@ describe('useCytoscapeEventHandlers', () => {
} as unknown as HTMLElement;
jest.spyOn(cy, 'container').mockReturnValueOnce(container);
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.getElementById('test').trigger('tapstart');
expect(container.style.cursor).toEqual('grab');
@ -305,7 +306,7 @@ describe('useCytoscapeEventHandlers', () => {
} as unknown as HTMLElement;
jest.spyOn(cy, 'container').mockReturnValueOnce(container);
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.trigger('tapend');
expect(container.style.cursor).toEqual('grab');
@ -319,7 +320,7 @@ describe('useCytoscapeEventHandlers', () => {
} as unknown as HTMLElement;
jest.spyOn(cy, 'container').mockReturnValueOnce(container);
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.getElementById('test').trigger('tapend');
expect(container.style.cursor).toEqual('pointer');
@ -334,7 +335,7 @@ describe('useCytoscapeEventHandlers', () => {
jest.spyOn(Storage.prototype, 'getItem').mockReturnValueOnce('true');
const debug = jest.spyOn(window.console, 'debug').mockReturnValueOnce(undefined);
renderHook(() => useCytoscapeEventHandlers({ cy, theme }));
renderHook(() => useCytoscapeEventHandlers({ cy, euiTheme }));
cy.getElementById('test').trigger('select');
expect(debug).toHaveBeenCalled();

View file

@ -8,8 +8,8 @@
import cytoscape from 'cytoscape';
import { debounce } from 'lodash';
import { useEffect } from 'react';
import { EuiTheme } from '@kbn/kibana-react-plugin/common';
import { useUiTracker } from '@kbn/observability-shared-plugin/public';
import type { EuiThemeComputed } from '@elastic/eui';
import { getAnimationOptions, getNodeHeight } from './cytoscape_options';
/*
@ -39,13 +39,13 @@ function applyCubicBezierStyles(edges: cytoscape.EdgeCollection) {
function getLayoutOptions({
fit = false,
nodeHeight,
theme,
euiTheme,
}: {
fit?: boolean;
nodeHeight: number;
theme: EuiTheme;
euiTheme: EuiThemeComputed;
}): cytoscape.LayoutOptions {
const animationOptions = getAnimationOptions(theme);
const animationOptions = getAnimationOptions(euiTheme);
return {
animationDuration: animationOptions.duration,
@ -82,16 +82,16 @@ function resetConnectedEdgeStyle(cytoscapeInstance: cytoscape.Core, node?: cytos
export function useCytoscapeEventHandlers({
cy,
serviceName,
theme,
euiTheme,
}: {
cy?: cytoscape.Core;
serviceName?: string;
theme: EuiTheme;
euiTheme: EuiThemeComputed;
}) {
const trackApmEvent = useUiTracker({ app: 'apm' });
useEffect(() => {
const nodeHeight = getNodeHeight(theme);
const nodeHeight = getNodeHeight(euiTheme);
const dataHandler: cytoscape.EventHandler = (event, fit) => {
if (serviceName) {
@ -111,7 +111,7 @@ export function useCytoscapeEventHandlers({
event.cy
.elements('[!hasBeenDragged]')
.difference('node:selected')
.layout(getLayoutOptions({ fit, nodeHeight, theme }))
.layout(getLayoutOptions({ fit, nodeHeight, euiTheme }))
.run();
};
@ -216,5 +216,5 @@ export function useCytoscapeEventHandlers({
cy.removeListener('tapend', undefined, tapendHandler);
}
};
}, [cy, serviceName, trackApmEvent, theme]);
}, [cy, serviceName, trackApmEvent, euiTheme]);
}

View file

@ -6,10 +6,11 @@
*/
import { composeStories } from '@storybook/testing-react';
import { render, screen } from '@testing-library/react';
import { screen } from '@testing-library/react';
import React from 'react';
import * as stories from './service_overview.stories';
import * as useAdHocApmDataView from '../../../hooks/use_adhoc_apm_data_view';
import { renderWithTheme } from '../../../utils/test_helpers';
const { Example } = composeStories(stories);
@ -32,7 +33,7 @@ describe('ServiceOverview', () => {
jest.clearAllMocks();
});
it('renders', async () => {
render(<Example />);
renderWithTheme(<Example />);
expect(await screen.findByRole('heading', { name: 'Latency' })).toBeInTheDocument();
});

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { EuiFlexGroup, EuiFlexItem, EuiSkeletonText } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiSkeletonText, useEuiTheme } from '@elastic/eui';
import { CloudProvider, getAgentIcon, getCloudProviderIcon } from '@kbn/custom-icons';
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';
@ -35,7 +35,6 @@ import {
} from '../../../../../common/es_fields/infra_metrics';
import { isPending } from '../../../../hooks/use_fetcher';
import { useTheme } from '../../../../hooks/use_theme';
import { APIReturnType } from '../../../../services/rest/create_call_apm_api';
import { KeyValueFilterList } from '../../../shared/key_value_filter_list';
import { pushNewItemToKueryBar } from '../../../shared/kuery_bar/utils';
@ -89,7 +88,7 @@ const cloudDetailsKeys = [
];
export function InstanceDetails({ serviceName, serviceNodeName, kuery }: Props) {
const theme = useTheme();
const { colorMode } = useEuiTheme();
const history = useHistory();
const { data, status } = useInstanceDetailsFetcher({
@ -132,6 +131,8 @@ export function InstanceDetails({ serviceName, serviceNodeName, kuery }: Props)
});
const containerType = data.kubernetes?.pod?.name ? 'Kubernetes' : 'Docker';
const isDarkMode = colorMode === 'DARK';
return (
<EuiFlexGroup direction="column" responsive={false}>
<EuiFlexItem>
@ -140,7 +141,7 @@ export function InstanceDetails({ serviceName, serviceNodeName, kuery }: Props)
title={i18n.translate('xpack.apm.serviceOverview.instanceTable.details.serviceTitle', {
defaultMessage: 'Service',
})}
icon={getAgentIcon(data.agent?.name, theme.darkMode)}
icon={getAgentIcon(data.agent?.name, isDarkMode)}
keyValueList={serviceDetailsKeyValuePairs}
onClickFilter={addKueryBarFilter}
/>

View file

@ -13,6 +13,7 @@ import {
EuiHealth,
EuiToolTip,
RIGHT_ALIGNMENT,
useEuiTheme,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { isEmpty } from 'lodash';
@ -22,7 +23,6 @@ import { APIReturnType } from '../../../../../services/rest/create_call_apm_api'
import { getOptionLabel } from '../../../../../../common/agent_configuration/all_option';
import { useApmPluginContext } from '../../../../../context/apm_plugin/use_apm_plugin_context';
import { FETCH_STATUS } from '../../../../../hooks/use_fetcher';
import { useTheme } from '../../../../../hooks/use_theme';
import { LoadingStatePrompt } from '../../../../shared/loading_state_prompt';
import { ITableColumn, ManagedTable } from '../../../../shared/managed_table';
import { TimestampTooltip } from '../../../../shared/timestamp_tooltip';
@ -40,7 +40,7 @@ interface Props {
export function AgentConfigurationList({ status, configurations, refetch }: Props) {
const { core } = useApmPluginContext();
const canSave = core.application.capabilities.apm['settings:save'];
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const [configToBeDeleted, setConfigToBeDeleted] = useState<Config | null>(null);
const apmRouter = useApmRouter();
@ -110,7 +110,7 @@ export function AgentConfigurationList({ status, configurations, refetch }: Prop
{
field: 'applied_by_agent',
align: 'center',
width: theme.eui.euiSizeXL,
width: euiTheme.size.xl,
name: '',
sortable: true,
render: (_, { applied_by_agent: appliedByAgent }) => (
@ -125,7 +125,7 @@ export function AgentConfigurationList({ status, configurations, refetch }: Prop
})
}
>
<EuiHealth color={appliedByAgent ? 'success' : theme.eui.euiColorLightShade} />
<EuiHealth color={appliedByAgent ? 'success' : euiTheme.colors.lightShade} />
</EuiToolTip>
),
},
@ -172,12 +172,14 @@ export function AgentConfigurationList({ status, configurations, refetch }: Prop
...(canSave
? [
{
width: theme.eui.euiSizeXL,
width: euiTheme.size.xl,
name: '',
render: (config: Config) => (
<EuiButtonIcon
data-test-subj="apmColumnsButton"
aria-label="Edit"
aria-label={i18n.translate('xpack.apm.columns.euiButtonIcon.editLabel', {
defaultMessage: 'Edit',
})}
iconType="pencil"
href={apmRouter.link('/settings/agent-configuration/edit', {
query: {
@ -189,12 +191,14 @@ export function AgentConfigurationList({ status, configurations, refetch }: Prop
),
},
{
width: theme.eui.euiSizeXL,
width: euiTheme.size.xl,
name: '',
render: (config: Config) => (
<EuiButtonIcon
data-test-subj="apmColumnsButton"
aria-label="Delete"
aria-label={i18n.translate('xpack.apm.columns.euiButtonIcon.deleteLabel', {
defaultMessage: 'Delete',
})}
iconType="trash"
onClick={() => setConfigToBeDeleted(config)}
/>

View file

@ -5,13 +5,12 @@
* 2.0.
*/
import { EuiButtonEmpty } from '@elastic/eui';
import { EuiButtonEmpty, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { NotificationsStart } from '@kbn/core/public';
import React, { useState } from 'react';
import { callApmApi } from '../../../../../services/rest/create_call_apm_api';
import { useApmPluginContext } from '../../../../../context/apm_plugin/use_apm_plugin_context';
import { useTheme } from '../../../../../hooks/use_theme';
interface Props {
onDelete: () => void;
@ -21,7 +20,7 @@ interface Props {
export function DeleteButton({ onDelete, customLinkId }: Props) {
const [isDeleting, setIsDeleting] = useState(false);
const { toasts } = useApmPluginContext().core.notifications;
const theme = useTheme();
const { euiTheme } = useEuiTheme();
return (
<EuiButtonEmpty
@ -35,7 +34,7 @@ export function DeleteButton({ onDelete, customLinkId }: Props) {
setIsDeleting(false);
onDelete();
}}
style={{ marginRight: theme.eui.euiSize }}
style={{ marginRight: euiTheme.size.base }}
>
{i18n.translate('xpack.apm.settings.customLink.delete', {
defaultMessage: 'Delete',

View file

@ -204,7 +204,7 @@ function SummaryMetric({
css={css`
${xlFontSize}
font-weight: ${euiTheme.font.weight.bold};
color: ${euiTheme.colors.text};
color: ${euiTheme.colors.textParagraph};
`}
>
{value}

View file

@ -5,12 +5,12 @@
* 2.0.
*/
import { EuiIcon, EuiToolTip, RIGHT_ALIGNMENT } from '@elastic/eui';
import { EuiIcon, EuiToolTip, RIGHT_ALIGNMENT, useEuiFontSize } from '@elastic/eui';
import { usePerformanceContext } from '@kbn/ebt-tools';
import { TypeOf } from '@kbn/typed-react-router-config';
import { i18n } from '@kbn/i18n';
import React, { useEffect, useMemo } from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { ApmRoutes } from '../../routing/apm_route_config';
import { asMillisecondDuration, asTransactionRate } from '../../../../common/utils/formatters';
import { useApmParams } from '../../../hooks/use_apm_params';
@ -25,8 +25,8 @@ import { ServiceLink } from '../../shared/links/apm/service_link';
import { TruncateWithTooltip } from '../../shared/truncate_with_tooltip';
import { NOT_AVAILABLE_LABEL } from '../../../../common/i18n';
const StyledTransactionLink = euiStyled(TransactionDetailLink)`
font-size: ${({ theme }) => theme.eui.euiFontSizeS};
const StyledTransactionLink = styled(TransactionDetailLink)`
font-size: ${() => useEuiFontSize('s').fontSize};
${truncate('100%')};
`;

View file

@ -9,7 +9,7 @@ import { EuiEmptyPrompt } from '@elastic/eui';
import React from 'react';
import { i18n } from '@kbn/i18n';
import { Redirect } from 'react-router-dom';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
import { getRedirectToTransactionDetailPageUrl } from './get_redirect_to_transaction_detail_page_url';
@ -18,7 +18,7 @@ import { useApmParams } from '../../../hooks/use_apm_params';
import { useTimeRange } from '../../../hooks/use_time_range';
import { ApmPluginStartDeps } from '../../../plugin';
const CentralizedContainer = euiStyled.div`
const CentralizedContainer = styled.div`
height: 100%;
display: flex;
`;

View file

@ -7,6 +7,7 @@
import { useEffect } from 'react';
import { i18n } from '@kbn/i18n';
import { useEuiTheme } from '@elastic/eui';
import { DEFAULT_PERCENTILE_THRESHOLD } from '../../../../../common/correlations/constants';
import { EVENT_OUTCOME } from '../../../../../common/es_fields/apm';
import { EventOutcome } from '../../../../../common/event_outcome';
@ -16,11 +17,10 @@ import { useFetcher, FETCH_STATUS } from '../../../../hooks/use_fetcher';
import { isErrorMessage } from '../../correlations/utils/is_error_message';
import { useFetchParams } from '../../correlations/use_fetch_params';
import { getTransactionDistributionChartData } from '../../correlations/get_transaction_distribution_chart_data';
import { useTheme } from '../../../../hooks/use_theme';
export const useTransactionDistributionChartData = () => {
const params = useFetchParams();
const euiTheme = useTheme();
const { euiTheme } = useEuiTheme();
const {
core: { notifications },

View file

@ -7,20 +7,19 @@
import {
EuiAccordion,
EuiAccordionProps,
EuiFlexGroup,
EuiFlexItem,
EuiIcon,
EuiText,
EuiToolTip,
useEuiTheme,
} from '@elastic/eui';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import { transparentize } from 'polished';
import React, { useEffect, useRef } from 'react';
import { WindowScroller, AutoSizer } from 'react-virtualized';
import { areEqual, ListChildComponentProps, VariableSizeList as List } from 'react-window';
import { css } from '@emotion/react';
import { asBigNumber } from '../../../../../../../common/utils/formatters';
import { useTheme } from '../../../../../../hooks/use_theme';
import { Margins } from '../../../../../shared/charts/timeline';
import {
IWaterfallNodeFlatten,
@ -53,38 +52,6 @@ interface WaterfallNodeProps extends WaterfallProps {
const ACCORDION_HEIGHT = 48;
const StyledAccordion = euiStyled(EuiAccordion).withConfig({
shouldForwardProp: (prop) => !['marginLeftLevel', 'hasError'].includes(prop),
})<
EuiAccordionProps & {
marginLeftLevel: number;
hasError: boolean;
}
>`
border-top: 1px solid ${({ theme }) => theme.eui.euiColorLightShade};
${(props) => {
const borderLeft = props.hasError
? `2px solid ${props.theme.eui.euiColorDanger};`
: `1px solid ${props.theme.eui.euiColorLightShade};`;
return `.button_${props.id} {
width: 100%;
height: ${ACCORDION_HEIGHT}px;
margin-left: ${props.marginLeftLevel}px;
border-left: ${borderLeft}
&:hover {
background-color: ${props.theme.eui.euiColorLightestShade};
}
}`;
}}
.accordion__buttonContent {
width: 100%;
height: 100%;
}
`;
export function AccordionWaterfall({
maxLevelOpen,
showCriticalPath,
@ -176,7 +143,7 @@ const VirtualRow = React.memo(
);
const WaterfallNode = React.memo((props: WaterfallNodeProps) => {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const { duration, waterfallItemId, onClickWaterfallItem, timelineMargins, node } = props;
const { criticalPathSegmentsById, getErrorCount, updateTreeNode, showCriticalPath } =
useWaterfallContext();
@ -190,7 +157,7 @@ const WaterfallNode = React.memo((props: WaterfallNodeProps) => {
?.filter((segment) => segment.self)
.map((segment) => ({
id: segment.item.id,
color: theme.eui.euiColorAccent,
color: euiTheme.colors.accent,
left: (segment.offset - node.item.offset - node.item.skew) / node.item.duration,
width: segment.duration / node.item.duration,
}));
@ -203,14 +170,14 @@ const WaterfallNode = React.memo((props: WaterfallNodeProps) => {
onClickWaterfallItem(node.item, flyoutDetailTab);
};
const hasError = node.item.doc.event?.outcome === 'failure';
return (
<StyledAccordion
<EuiAccordion
data-test-subj="waterfallItem"
style={{ position: 'relative' }}
buttonClassName={`button_${node.item.id}`}
id={node.item.id}
hasError={node.item.doc.event?.outcome === 'failure'}
marginLeftLevel={marginLeftLevel}
buttonContentClassName="accordion__buttonContent"
buttonContent={
<EuiFlexGroup gutterSize="none" responsive={false}>
@ -243,6 +210,24 @@ const WaterfallNode = React.memo((props: WaterfallNodeProps) => {
initialIsOpen
forceState={node.expanded ? 'open' : 'closed'}
onToggle={toggleAccordion}
css={css`
border-top: ${euiTheme.border.thin};
.button_${node.item.id} {
width: 100%;
height: ${ACCORDION_HEIGHT}px;
margin-left: ${marginLeftLevel}px;
border-left: ${hasError
? `${euiTheme.border.width.thick} solid ${euiTheme.colors.danger};`
: `${euiTheme.border.thin};`};
&:hover {
background-color: ${euiTheme.colors.lightestShade};
}
}
.accordion__buttonContent {
width: 100%;
height: 100%;
}
`}
/>
);
});

View file

@ -6,18 +6,17 @@
*/
import React from 'react';
import { EuiBadge, EuiToolTip } from '@elastic/eui';
import { EuiBadge, EuiToolTip, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { EventOutcome } from '../../../../../../../typings/es_schemas/raw/fields/event_outcome';
import { useTheme } from '../../../../../../hooks/use_theme';
const ResetLineHeight = euiStyled.span`
const ResetLineHeight = styled.span`
line-height: initial;
`;
export function FailureBadge({ outcome }: { outcome?: EventOutcome }) {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
if (outcome !== 'failure') {
return null;
@ -30,7 +29,11 @@ export function FailureBadge({ outcome }: { outcome?: EventOutcome }) {
defaultMessage: 'event.outcome = failure',
})}
>
<EuiBadge color={theme.eui.euiColorDanger}>failure</EuiBadge>
<EuiBadge color={euiTheme.colors.danger}>
{i18n.translate('xpack.apm.failure_badge.label', {
defaultMessage: 'failure',
})}
</EuiBadge>
</EuiToolTip>
</ResetLineHeight>
);

View file

@ -5,14 +5,13 @@
* 2.0.
*/
import { EuiButtonEmpty, EuiCallOut } from '@elastic/eui';
import { EuiButtonEmpty, EuiCallOut, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { History } from 'history';
import React, { useMemo, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { css } from '@emotion/react';
import { useTheme } from '../../../../../../hooks/use_theme';
import {
VerticalLinesContainer,
TimelineAxisContainer,
@ -24,7 +23,7 @@ import { AccordionWaterfall } from './accordion_waterfall';
import { WaterfallFlyout } from './waterfall_flyout';
import { IWaterfall, IWaterfallItem } from './waterfall_helpers/waterfall_helpers';
const Container = euiStyled.div`
const Container = styled.div`
transition: 0.1s padding ease;
position: relative;
`;
@ -48,8 +47,8 @@ const toggleFlyout = ({
});
};
const WaterfallItemsContainer = euiStyled.div`
border-bottom: 1px solid ${({ theme }) => theme.eui.euiColorMediumShade};
const WaterfallItemsContainer = styled.div`
border-bottom: 1px solid ${({ theme }) => theme.euiTheme.colors.mediumShade};
`;
interface Props {
@ -90,7 +89,7 @@ const MAX_DEPTH_OPEN_LIMIT = 2;
export function Waterfall({ waterfall, waterfallItemId, showCriticalPath }: Props) {
const history = useHistory();
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const [isAccordionOpen, setIsAccordionOpen] = useState(true);
const { duration } = waterfall;
@ -134,16 +133,16 @@ export function Waterfall({ waterfall, waterfallItemId, showCriticalPath }: Prop
display: flex;
position: sticky;
top: var(--euiFixedHeadersOffset, 0);
z-index: ${theme.eui.euiZLevel2};
background-color: ${theme.eui.euiColorEmptyShade};
border-bottom: 1px solid ${theme.eui.euiColorMediumShade};
z-index: ${euiTheme.levels.content};
background-color: ${euiTheme.colors.emptyShade};
border-bottom: 1px solid ${euiTheme.colors.mediumShade};
`}
>
<EuiButtonEmpty
data-test-subj="apmWaterfallButton"
css={css`
position: absolute;
z-index: ${theme.eui.euiZLevel2};
z-index: ${euiTheme.levels.content};
`}
iconType={isAccordionOpen ? 'fold' : 'unfold'}
onClick={() => {

View file

@ -5,10 +5,21 @@
* 2.0.
*/
import { EuiFlyout } from '@elastic/eui';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import React from 'react';
import { EuiFlyout, EuiFlyoutProps } from '@elastic/eui';
import styled, { type StyledComponent } from '@emotion/styled';
export const ResponsiveFlyout = euiStyled(EuiFlyout)`
// The return type of this component needs to be specified because the inferred
// return type depends on types that are not exported from EUI. You get a TS4023
// error if the return type is not specified.
export const ResponsiveFlyout: StyledComponent<EuiFlyoutProps> = styled(
({
className,
...flyoutProps
}: {
className?: string;
} & EuiFlyoutProps) => <EuiFlyout {...flyoutProps} className={className} />
)`
width: 100%;
@media (min-width: 800px) {

View file

@ -21,7 +21,7 @@ import {
EuiToolTip,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { ProcessorEvent } from '@kbn/observability-plugin/common';
import { isEmpty } from 'lodash';
import React, { Fragment } from 'react';
@ -80,10 +80,10 @@ function getSpanTypes(span: Span) {
};
}
const ContainerWithMarginRight = euiStyled.div`
const ContainerWithMarginRight = styled.div`
/* add margin to all direct descendants */
& > * {
margin-right: ${({ theme }) => theme.eui.euiSizeXS};
margin-right: ${({ theme }) => theme.euiTheme.size.xs};
}
`;

View file

@ -8,10 +8,10 @@
import { EuiIcon, EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { Fragment, ReactNode, useEffect, useRef, useState } from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
const ToggleButtonContainer = euiStyled.div`
margin-top: ${({ theme }) => theme.eui.euiSizeS}
const ToggleButtonContainer = styled.div`
margin-top: ${({ theme }) => theme.euiTheme.size.s}
user-select: none;
`;

View file

@ -5,11 +5,10 @@
* 2.0.
*/
import { EuiBadge, EuiIcon, EuiText, EuiTitle, EuiToolTip } from '@elastic/eui';
import { EuiBadge, EuiIcon, EuiText, EuiTitle, EuiToolTip, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { ReactNode, useRef, useEffect, useState } from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import { useTheme } from '../../../../../../hooks/use_theme';
import styled from '@emotion/styled';
import { isMobileAgentName, isRumAgentName } from '../../../../../../../common/agent_name';
import { TRACE_ID, TRANSACTION_ID } from '../../../../../../../common/es_fields/apm';
import { asDuration } from '../../../../../../../common/utils/formatters';
@ -37,68 +36,68 @@ interface IBarStyleProps {
color: string;
}
const Container = euiStyled.div<IContainerStyleProps>`
const Container = styled.div<IContainerStyleProps>`
position: relative;
display: block;
user-select: none;
padding-top: ${({ theme }) => theme.eui.euiSizeS};
padding-bottom: ${({ theme }) => theme.eui.euiSizeM};
padding-top: ${({ theme }) => theme.euiTheme.size.s};
padding-bottom: ${({ theme }) => theme.euiTheme.size.m};
margin-right: ${(props) => props.timelineMargins.right}px;
margin-left: ${(props) =>
props.hasToggle
? props.timelineMargins.left - 30 // fix margin if there is a toggle
: props.timelineMargins.left}px ;
: props.timelineMargins.left}px;
background-color: ${({ isSelected, theme }) =>
isSelected ? theme.eui.euiColorLightestShade : 'initial'};
isSelected ? theme.euiTheme.colors.lightestShade : 'initial'};
cursor: pointer;
&:hover {
background-color: ${({ theme }) => theme.eui.euiColorLightestShade};
background-color: ${({ theme }) => theme.euiTheme.colors.lightestShade};
}
`;
const ItemBar = euiStyled.div<IBarStyleProps>`
const ItemBar = styled.div<IBarStyleProps>`
box-sizing: border-box;
position: relative;
height: ${({ theme }) => theme.eui.euiSize};
height: ${({ theme }) => theme.euiTheme.size.base};
min-width: 2px;
background-color: ${(props) => props.color};
`;
const ItemText = euiStyled.span`
const ItemText = styled.span`
position: absolute;
right: 0;
display: flex;
align-items: center;
height: ${({ theme }) => theme.eui.euiSizeL};
height: ${({ theme }) => theme.euiTheme.size.l};
max-width: 100%;
/* add margin to all direct descendants */
& > * {
margin-right: ${({ theme }) => theme.eui.euiSizeS};
margin-right: ${({ theme }) => theme.euiTheme.size.s};
white-space: nowrap;
}
`;
const CriticalPathItemBar = euiStyled.div`
const CriticalPathItemBar = styled.div`
box-sizing: border-box;
position: relative;
height: ${({ theme }) => theme.eui.euiSizeS};
top : ${({ theme }) => theme.eui.euiSizeS};
height: ${({ theme }) => theme.euiTheme.size.s};
top: ${({ theme }) => theme.euiTheme.size.s};
min-width: 2px;
background-color: transparent;
display: flex;
flex-direction: row;
`;
const CriticalPathItemSegment = euiStyled.div<{
const CriticalPathItemSegment = styled.div<{
left: number;
width: number;
color: string;
}>`
box-sizing: border-box;
position: absolute;
height: ${({ theme }) => theme.eui.euiSizeS};
height: ${({ theme }) => theme.euiTheme.size.s};
left: ${(props) => props.left * 100}%;
width: ${(props) => props.width * 100}%;
min-width: 2px;
@ -311,7 +310,7 @@ function RelatedErrors({
errorCount: number;
}) {
const apmRouter = useApmRouter();
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const { query } = useAnyOfApmParams(
'/services/{serviceName}/transactions/view',
'/mobile-services/{serviceName}/transactions/view',
@ -348,7 +347,7 @@ function RelatedErrors({
<div onClick={(e: React.MouseEvent) => e.stopPropagation()}>
<EuiBadge
href={isMobileAgentName(item.doc.agent.name) ? mobileHref : href}
color={theme.eui.euiColorDanger}
color={euiTheme.colors.danger}
iconType="arrowRight"
>
{i18n.translate('xpack.apm.waterfall.errorCount', {

View file

@ -6,9 +6,9 @@
*/
import { composeStories } from '@storybook/testing-react';
import { render, waitFor } from '@testing-library/react';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { disableConsoleWarning } from '../../../../../utils/test_helpers';
import { disableConsoleWarning, renderWithTheme } from '../../../../../utils/test_helpers';
import * as stories from './waterfall_container.stories';
const { Example } = composeStories(stories);
@ -25,7 +25,7 @@ describe('WaterfallContainer', () => {
});
it('expands and contracts the accordion', async () => {
const { getAllByRole } = render(<Example />);
const { getAllByRole } = renderWithTheme(<Example />);
const buttons = await waitFor(() => getAllByRole('button'));
const parentItem = buttons[1];
const childItem = buttons[2];

View file

@ -7,14 +7,15 @@
import { EuiEmptyPrompt } from '@elastic/eui';
import React from 'react';
import { i18n } from '@kbn/i18n';
import { Redirect } from 'react-router-dom';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
import { getRedirectToTransactionDetailPageUrl } from '../trace_link/get_redirect_to_transaction_detail_page_url';
import { useApmParams } from '../../../hooks/use_apm_params';
import { useTimeRange } from '../../../hooks/use_time_range';
const CentralizedContainer = euiStyled.div`
const CentralizedContainer = styled.div`
height: 100%;
display: flex;
`;
@ -67,7 +68,16 @@ export function TransactionLink() {
return (
<CentralizedContainer>
<EuiEmptyPrompt iconType="apmTrace" title={<h2>Fetching transaction...</h2>} />
<EuiEmptyPrompt
iconType="apmTrace"
title={
<h2>
{i18n.translate('xpack.apm.transactionLink.h2.fetchingTransactionLabel', {
defaultMessage: 'Fetching transaction...',
})}
</h2>
}
/>
</CentralizedContainer>
);
}

View file

@ -16,7 +16,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { ComponentType } from 'react';
import styled from 'styled-components';
import styled from '@emotion/styled';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { Markdown } from '@kbn/shared-ux-markdown';
import { AgentIcon } from '@kbn/custom-icons';

View file

@ -15,7 +15,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import styled from 'styled-components';
import styled from '@emotion/styled';
import { CodeEditor } from '@kbn/code-editor';
import { FormRowOnChange } from '.';
import { SettingsRow } from '../typings';

View file

@ -7,7 +7,7 @@
import { EuiLoadingSpinner } from '@elastic/eui';
import { IconType } from '@elastic/eui';
import { EuiHeaderLink, EuiIcon, EuiToolTip } from '@elastic/eui';
import { EuiHeaderLink, EuiIcon, EuiToolTip, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { AnomalyDetectionSetupState } from '../../../../../common/anomaly_detection/get_anomaly_detection_setup_state';
@ -18,7 +18,6 @@ import {
import { useAnomalyDetectionJobsContext } from '../../../../context/anomaly_detection_jobs/use_anomaly_detection_jobs_context';
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
import { useApmParams } from '../../../../hooks/use_apm_params';
import { useTheme } from '../../../../hooks/use_theme';
import { getLegacyApmHref } from '../../../shared/links/apm/apm_link';
export function AnomalyDetectionSetupLink() {
@ -29,12 +28,12 @@ export function AnomalyDetectionSetupLink() {
const { core } = useApmPluginContext();
const { basePath } = core.http;
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const { anomalyDetectionSetupState } = useAnomalyDetectionJobsContext();
let tooltipText: string = '';
let color: 'warning' | 'text' | 'success' | 'danger' = 'text';
let color: 'warning' | 'text' | 'accentSecondary' | 'danger' = 'text';
let icon: IconType | undefined;
if (anomalyDetectionSetupState === AnomalyDetectionSetupState.Failure) {
@ -51,7 +50,7 @@ export function AnomalyDetectionSetupLink() {
tooltipText = getNoJobsMessage(anomalyDetectionSetupState, environment);
icon = 'machineLearningApp';
} else if (anomalyDetectionSetupState === AnomalyDetectionSetupState.UpgradeableJobs) {
color = 'success';
color = 'accentSecondary';
tooltipText = i18n.translate('xpack.apm.anomalyDetectionSetup.upgradeableJobsText', {
defaultMessage: 'Updates available for existing anomaly detection jobs.',
});
@ -74,7 +73,7 @@ export function AnomalyDetectionSetupLink() {
data-test-subj="apmAnomalyDetectionHeaderLink"
>
{pre}
<span style={{ marginInlineStart: theme.eui.euiSizeS }}>{ANOMALY_DETECTION_LINK_LABEL}</span>
<span style={{ marginInlineStart: euiTheme.size.s }}>{ANOMALY_DETECTION_LINK_LABEL}</span>
</EuiHeaderLink>
);

View file

@ -7,7 +7,7 @@
import { PerformanceContextProvider } from '@kbn/ebt-tools';
import { APP_WRAPPER_CLASS } from '@kbn/core/public';
import { KibanaContextProvider, useDarkMode } from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import {
@ -16,9 +16,7 @@ import {
} from '@kbn/observability-shared-plugin/public';
import { Route } from '@kbn/shared-ux-router';
import { RouteRenderer, RouterProvider } from '@kbn/typed-react-router-config';
import { euiDarkVars, euiLightVars } from '@kbn/ui-theme';
import React from 'react';
import { DefaultTheme, ThemeProvider } from 'styled-components';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { KibanaEnvironmentContextProvider } from '../../../context/kibana_environment_context/kibana_environment_context';
import { AnomalyDetectionJobsContextProvider } from '../../../context/anomaly_detection_jobs/anomaly_detection_jobs_context';
@ -84,11 +82,9 @@ export function ApmAppRoot({
<LicenseProvider>
<AnomalyDetectionJobsContextProvider>
<InspectorContextProvider>
<ApmThemeProvider>
<MountApmHeaderActionMenu />
<Route component={ScrollToTopOnPathChange} />
<RouteRenderer />
</ApmThemeProvider>
<MountApmHeaderActionMenu />
<Route component={ScrollToTopOnPathChange} />
<RouteRenderer />
</InspectorContextProvider>
</AnomalyDetectionJobsContextProvider>
</LicenseProvider>
@ -128,19 +124,3 @@ function MountApmHeaderActionMenu() {
</HeaderMenuPortal>
);
}
export function ApmThemeProvider({ children }: { children: React.ReactNode }) {
const darkMode = useDarkMode(false);
return (
<ThemeProvider
theme={(outerTheme?: DefaultTheme) => ({
...outerTheme,
eui: darkMode ? euiDarkVars : euiLightVars,
darkMode,
})}
>
{children}
</ThemeProvider>
);
}

View file

@ -21,7 +21,7 @@ import {
Tooltip,
LegendValue,
} from '@elastic/charts';
import { EuiIcon } from '@elastic/eui';
import { EuiIcon, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import moment from 'moment';
import React from 'react';
@ -36,7 +36,6 @@ import {
import { Coordinate, TimeSeries } from '../../../../../typings/timeseries';
import { useChartPointerEventContext } from '../../../../context/chart_pointer_event/use_chart_pointer_event_context';
import { FETCH_STATUS } from '../../../../hooks/use_fetcher';
import { useTheme } from '../../../../hooks/use_theme';
import { unit } from '../../../../utils/style';
import { ChartContainer } from '../chart_container';
import { isTimeseriesEmpty, onBrushEnd } from '../helper/helper';
@ -74,7 +73,7 @@ export function BreakdownChart({
const {
query: { rangeFrom, rangeTo },
} = useAnyOfApmParams('/services/{serviceName}', '/mobile-services/{serviceName}');
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const { start, end } = useTimeRange({ rangeFrom, rangeTo });
const min = moment.utc(start).valueOf();
@ -82,7 +81,7 @@ export function BreakdownChart({
const xFormatter = niceTimeFormatter([min, max]);
const annotationColor = theme.eui.euiColorSuccess;
const annotationColor = euiTheme.colors.accentSecondary;
const isEmpty = isTimeseriesEmpty(timeseries);

View file

@ -25,7 +25,7 @@ import {
TickFormatter,
} from '@elastic/charts';
import { euiPaletteColorBlind } from '@elastic/eui';
import { euiPaletteColorBlind, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
@ -37,7 +37,6 @@ import type { HistogramItem } from '../../../../../common/correlations/types';
import { DEFAULT_PERCENTILE_THRESHOLD } from '../../../../../common/correlations/constants';
import { FETCH_STATUS } from '../../../../hooks/use_fetcher';
import { useTheme } from '../../../../hooks/use_theme';
import { ChartContainer } from '../chart_container';
@ -109,7 +108,7 @@ export function DurationDistributionChart({
eventType,
}: DurationDistributionChartProps) {
const chartThemes = useChartThemes();
const euiTheme = useTheme();
const { euiTheme } = useEuiTheme();
const markerPercentile = DEFAULT_PERCENTILE_THRESHOLD;
const annotationsDataValues: LineAnnotationDatum[] = [
@ -188,7 +187,7 @@ export function DurationDistributionChart({
},
tickLabel: {
fontSize: 10,
fill: euiTheme.eui.euiColorMediumShade,
fill: euiTheme.colors.mediumShade,
padding: 0,
},
},
@ -207,8 +206,8 @@ export function DurationDistributionChart({
id="rect_annotation_1"
style={{
strokeWidth: 1,
stroke: euiTheme.eui.euiColorLightShade,
fill: euiTheme.eui.euiColorLightShade,
stroke: euiTheme.colors.lightShade,
fill: euiTheme.colors.lightShade,
opacity: 0.9,
}}
hideTooltips={true}

View file

@ -7,11 +7,11 @@
import { i18n } from '@kbn/i18n';
import { rgba } from 'polished';
import { EuiTheme } from '@kbn/kibana-react-plugin/common';
import { getSeverity } from '@kbn/ml-anomaly-utils/get_severity';
import { ML_ANOMALY_SEVERITY } from '@kbn/ml-anomaly-utils/anomaly_severity';
import { ML_ANOMALY_THRESHOLD } from '@kbn/ml-anomaly-utils/anomaly_threshold';
import type { AreaSeriesStyle, RecursivePartial } from '@elastic/charts';
import type { EuiThemeComputed } from '@elastic/eui';
import { getSeverityColor } from '../../../../../common/anomaly_detection';
import { ServiceAnomalyTimeseries } from '../../../../../common/anomaly_detection/service_anomaly_timeseries';
import { APMChartSpec } from '../../../../../typings/timeseries';
@ -21,11 +21,11 @@ export const expectedBoundsTitle = i18n.translate('xpack.apm.comparison.expected
});
export function getChartAnomalyTimeseries({
anomalyTimeseries,
theme,
euiTheme,
anomalyTimeseriesColor,
}: {
anomalyTimeseries?: ServiceAnomalyTimeseries;
theme: EuiTheme;
euiTheme: EuiThemeComputed;
anomalyTimeseriesColor?: string;
}):
| {
@ -48,7 +48,7 @@ export function getChartAnomalyTimeseries({
opacity: 0,
},
},
color: anomalyTimeseriesColor ?? rgba(theme.eui.euiColorVis1, 0.5),
color: anomalyTimeseriesColor ?? rgba(euiTheme.colors.vis.euiColorVis1, 0.5),
yAccessors: ['y1'],
y0Accessors: ['y0'],
data: anomalyTimeseries.bounds,

View file

@ -6,13 +6,12 @@
*/
import { TooltipInfo } from '@elastic/charts';
import { EuiIcon } from '@elastic/eui';
import { EuiIcon, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { APIReturnType } from '../../../../services/rest/create_call_apm_api';
import { getServiceNodeName } from '../../../../../common/service_nodes';
import { asTransactionRate, TimeFormatter } from '../../../../../common/utils/formatters';
import { useTheme } from '../../../../hooks/use_theme';
type ServiceInstanceMainStatistics =
APIReturnType<'GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics'>;
@ -92,7 +91,7 @@ function MultipleInstanceCustomTooltip({
latencyFormatter,
values,
}: TooltipInfo & { latencyFormatter: TimeFormatter }) {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
return (
<>
@ -127,10 +126,7 @@ function MultipleInstanceCustomTooltip({
>
<div className="echTooltip__item--color" style={{ backgroundColor: color }} />
</div>
<div
className="echTooltip__item--container"
style={{ paddingLeft: theme.eui.euiSizeS }}
>
<div className="echTooltip__item--container" style={{ paddingLeft: euiTheme.size.s }}>
<span className="echTooltip__label">{latencyLabel}</span>
<span className="echTooltip__value">{latencyFormatter(latency).formatted}</span>
</div>
@ -142,10 +138,7 @@ function MultipleInstanceCustomTooltip({
>
<div className="echTooltip__item--color" style={{ backgroundColor: color }} />
</div>
<div
className="echTooltip__item--container"
style={{ paddingLeft: theme.eui.euiSizeS }}
>
<div className="echTooltip__item--container" style={{ paddingLeft: euiTheme.size.s }}>
<span className="echTooltip__label">{throughputLabel}</span>
<span className="echTooltip__value">{asTransactionRate(throughput)}</span>
</div>
@ -166,7 +159,7 @@ function MultipleInstanceCustomTooltip({
*/
export function CustomTooltip(props: TooltipInfo & { latencyFormatter: TimeFormatter }) {
const { values } = props;
const theme = useTheme();
const { euiTheme } = useEuiTheme();
return (
<div className="echTooltip">
@ -175,7 +168,7 @@ export function CustomTooltip(props: TooltipInfo & { latencyFormatter: TimeForma
) : (
<SingleInstanceCustomTooltip {...props} />
)}
<div style={{ padding: theme.eui.euiSizeXS }}>
<div style={{ padding: euiTheme.size.xs }}>
<EuiIcon type="filter" /> {clickToFilterDescription}
</div>
</div>

View file

@ -19,7 +19,7 @@ import {
TooltipType,
Tooltip,
} from '@elastic/charts';
import { EuiPanel, EuiTitle } from '@elastic/eui';
import { EuiPanel, EuiTitle, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { useHistory } from 'react-router-dom';
@ -28,7 +28,6 @@ import { usePreviousPeriodLabel } from '../../../../hooks/use_previous_period_te
import { SERVICE_NODE_NAME } from '../../../../../common/es_fields/apm';
import { asTransactionRate, getDurationFormatter } from '../../../../../common/utils/formatters';
import { FETCH_STATUS } from '../../../../hooks/use_fetcher';
import { useTheme } from '../../../../hooks/use_theme';
import { APIReturnType } from '../../../../services/rest/create_call_apm_api';
import * as urlHelpers from '../../links/url_helpers';
import { ChartContainer } from '../chart_container';
@ -54,7 +53,7 @@ export function InstancesLatencyDistributionChart({
const history = useHistory();
const hasData = items.length > 0;
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const chartThemes = useChartThemes();
const maxLatency = Math.max(...items.map((item) => item.latency ?? 0));
@ -130,7 +129,7 @@ export function InstancesLatencyDistributionChart({
locale={i18n.getLocale()}
/>
<BubbleSeries
color={theme.eui.euiColorVis0}
color={euiTheme.colors.vis.euiColorVis0}
data={items}
id={i18n.translate('xpack.apm.instancesLatencyDistributionChartLegend', {
defaultMessage: 'Instances',
@ -143,7 +142,7 @@ export function InstancesLatencyDistributionChart({
point: {
strokeWidth: 0,
radius: 4,
fill: theme.eui.euiColorVis0,
fill: euiTheme.colors.vis.euiColorVis0,
},
}}
/>
@ -156,13 +155,13 @@ export function InstancesLatencyDistributionChart({
xScaleType={ScaleType.Linear}
yAccessors={[(item) => item.latency]}
yScaleType={ScaleType.Linear}
color={theme.eui.euiColorMediumShade}
color={euiTheme.colors.mediumShade}
bubbleSeriesStyle={{
point: {
shape: 'square',
radius: 4,
fill: theme.eui.euiColorLightestShade,
stroke: theme.eui.euiColorMediumShade,
fill: euiTheme.colors.lightestShade,
stroke: euiTheme.colors.mediumShade,
strokeWidth: 2,
},
}}

View file

@ -16,12 +16,11 @@ import {
Settings,
Tooltip,
} from '@elastic/charts';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLoadingChart } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLoadingChart, useEuiTheme } from '@elastic/eui';
import React from 'react';
import { useChartThemes } from '@kbn/observability-shared-plugin/public';
import { i18n } from '@kbn/i18n';
import { Coordinate } from '../../../../../typings/timeseries';
import { useTheme } from '../../../../hooks/use_theme';
import { unit } from '../../../../utils/style';
import { getComparisonChartTheme } from '../../time_comparison/get_comparison_chart_theme';
@ -93,7 +92,7 @@ export function SparkPlotItem({
comparisonSeries?: Coordinate[];
comparisonSeriesColor?: string;
}) {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const defaultChartThemes = useChartThemes();
const comparisonChartTheme = getComparisonChartTheme();
const hasComparisonSeries = !!comparisonSeries?.length;
@ -110,7 +109,7 @@ export function SparkPlotItem({
};
const chartSize = {
height: theme.eui.euiSizeL,
height: euiTheme.size.l,
width: compact ? unit * 4 : unit * 5,
};
@ -201,7 +200,7 @@ export function SparkPlotItem({
justifyContent: 'center',
}}
>
<EuiIcon type="visLine" color={theme.eui.euiColorMediumShade} />
<EuiIcon type="visLine" color={euiTheme.colors.mediumShade} />
</div>
);
}

View file

@ -1,11 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Timeline TimelineAxisContainer should render with data 1`] = `
.c0 {
position: absolute;
bottom: 0;
}
<div
style={
Object {
@ -37,7 +32,7 @@ exports[`Timeline TimelineAxisContainer should render with data 1`] = `
transform="translate(0 80)"
>
<text
fill="#69707d"
fill="#69707D"
fontSize={11}
textAnchor="middle"
x={50}
@ -46,7 +41,7 @@ exports[`Timeline TimelineAxisContainer should render with data 1`] = `
0 μs
</text>
<text
fill="#69707d"
fill="#69707D"
fontSize={11}
textAnchor="middle"
x={30}
@ -55,7 +50,7 @@ exports[`Timeline TimelineAxisContainer should render with data 1`] = `
200 μs
</text>
<text
fill="#69707d"
fill="#69707D"
fontSize={11}
textAnchor="middle"
x={10}
@ -64,7 +59,7 @@ exports[`Timeline TimelineAxisContainer should render with data 1`] = `
400 μs
</text>
<text
fill="#69707d"
fill="#69707D"
fontSize={11}
textAnchor="middle"
x={-10}
@ -73,7 +68,7 @@ exports[`Timeline TimelineAxisContainer should render with data 1`] = `
600 μs
</text>
<text
fill="#69707d"
fill="#69707D"
fontSize={11}
textAnchor="middle"
x={-30}
@ -91,8 +86,9 @@ exports[`Timeline TimelineAxisContainer should render with data 1`] = `
</text>
</g>
</svg>
<div
className="c0"
className="css-cdm8xt"
style={
Object {
"left": -9955.5,
@ -100,55 +96,31 @@ exports[`Timeline TimelineAxisContainer should render with data 1`] = `
}
>
.c0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
font-size: 14px;
color: #69707d;
cursor: pointer;
opacity: 1;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.c1 {
width: 11px;
height: 11px;
margin-right: 0;
background: #98a2b3;
border-radius: 100%;
}
<span
<span
className="euiToolTipAnchor emotion-euiToolTipAnchor-inlineBlock"
onKeyDown={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
>
<div
className="c0"
className="css-dncsr3"
disabled={false}
onBlur={[Function]}
onFocus={[Function]}
>
<span
className="c1"
color="#98a2b3"
className="css-18bonuo"
color="#98A2B3"
shape="circle"
/>
</div>
</span>
</div>
<div
className="c0"
className="css-cdm8xt"
style={
Object {
"left": -10955.5,
@ -156,55 +128,31 @@ exports[`Timeline TimelineAxisContainer should render with data 1`] = `
}
>
.c0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
font-size: 14px;
color: #69707d;
cursor: pointer;
opacity: 1;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.c1 {
width: 11px;
height: 11px;
margin-right: 0;
background: #98a2b3;
border-radius: 100%;
}
<span
<span
className="euiToolTipAnchor emotion-euiToolTipAnchor-inlineBlock"
onKeyDown={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
>
<div
className="c0"
className="css-dncsr3"
disabled={false}
onBlur={[Function]}
onFocus={[Function]}
>
<span
className="c1"
color="#98a2b3"
className="css-18bonuo"
color="#98A2B3"
shape="circle"
/>
</div>
</span>
</div>
<div
className="c0"
className="css-cdm8xt"
style={
Object {
"left": -18955.5,
@ -212,48 +160,23 @@ exports[`Timeline TimelineAxisContainer should render with data 1`] = `
}
>
.c0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
font-size: 14px;
color: #69707d;
cursor: pointer;
opacity: 1;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.c1 {
width: 11px;
height: 11px;
margin-right: 0;
background: #98a2b3;
border-radius: 100%;
}
<span
<span
className="euiToolTipAnchor emotion-euiToolTipAnchor-inlineBlock"
onKeyDown={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
>
<div
className="c0"
className="css-dncsr3"
disabled={false}
onBlur={[Function]}
onFocus={[Function]}
>
<span
className="c1"
color="#98a2b3"
className="css-18bonuo"
color="#98A2B3"
shape="circle"
/>
</div>
@ -287,70 +210,70 @@ exports[`Timeline VerticalLinesContainer should render with data 1`] = `
transform="translate(0 100)"
>
<line
stroke="#f5f7fa"
stroke="#F1F4FA"
x1={50}
x2={50}
y1={0}
y2="100%"
/>
<line
stroke="#f5f7fa"
stroke="#F1F4FA"
x1={30}
x2={30}
y1={0}
y2="100%"
/>
<line
stroke="#f5f7fa"
stroke="#F1F4FA"
x1={10}
x2={10}
y1={0}
y2="100%"
/>
<line
stroke="#f5f7fa"
stroke="#F1F4FA"
x1={-10}
x2={-10}
y1={0}
y2="100%"
/>
<line
stroke="#f5f7fa"
stroke="#F1F4FA"
x1={-30}
x2={-30}
y1={0}
y2="100%"
/>
<line
stroke="#f5f7fa"
stroke="#F1F4FA"
x1={-50}
x2={-50}
y1={0}
y2="100%"
/>
<line
stroke="#98a2b3"
stroke="#98A2B3"
x1={-9950}
x2={-9950}
y1={0}
y2="100%"
/>
<line
stroke="#98a2b3"
stroke="#98A2B3"
x1={-10950}
x2={-10950}
y1={0}
y2="100%"
/>
<line
stroke="#98a2b3"
stroke="#98A2B3"
x1={-18950}
x2={-18950}
y1={0}
y2="100%"
/>
<line
stroke="#98a2b3"
stroke="#98A2B3"
x1={-50}
x2={-50}
y1={0}

View file

@ -6,8 +6,8 @@
*/
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import { useTheme } from '../../../../hooks/use_theme';
import styled from '@emotion/styled';
import { useEuiFontSize, useEuiTheme } from '@elastic/eui';
export enum Shape {
circle = 'circle',
@ -20,11 +20,11 @@ interface ContainerProps {
disabled: boolean;
}
const Container = euiStyled.div<ContainerProps>`
const Container = styled.div<ContainerProps>`
display: flex;
align-items: center;
font-size: ${({ theme }) => theme.eui.euiFontSizeS};
color: ${({ theme }) => theme.eui.euiColorDarkShade};
font-size: ${() => useEuiFontSize('s').fontSize};
color: ${({ theme }) => theme.euiTheme.colors.darkShade};
cursor: ${(props) => (props.clickable ? 'pointer' : 'initial')};
opacity: ${(props) => (props.disabled ? 0.4 : 1)};
user-select: none;
@ -38,7 +38,7 @@ interface IndicatorProps {
const radius = 11;
export const Indicator = euiStyled.span<IndicatorProps>`
export const Indicator = styled.span<IndicatorProps>`
width: ${radius}px;
height: ${radius}px;
margin-right: ${(props) => (props.withMargin ? `${radius / 2}px` : 0)};
@ -68,8 +68,8 @@ export function Legend({
indicator,
...rest
}: Props) {
const theme = useTheme();
const indicatorColor = color || theme.eui.euiColorVis1;
const { euiTheme } = useEuiTheme();
const indicatorColor = color || euiTheme.colors.vis.euiColorVis1;
return (
<Container

View file

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Marker renders agent marker 1`] = `
<styled.div
<Styled(div)
style={
Object {
"left": 4.5,
@ -18,11 +18,11 @@ exports[`Marker renders agent marker 1`] = `
}
}
/>
</styled.div>
</Styled(div)>
`;
exports[`Marker renders error marker 1`] = `
<styled.div
<Styled(div)
style={
Object {
"left": 4.5,
@ -54,5 +54,5 @@ exports[`Marker renders error marker 1`] = `
}
}
/>
</styled.div>
</Styled(div)>
`;

View file

@ -5,22 +5,21 @@
* 2.0.
*/
import { EuiToolTip } from '@elastic/eui';
import { EuiToolTip, useEuiTheme } from '@elastic/eui';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { asDuration } from '../../../../../../common/utils/formatters';
import { useTheme } from '../../../../../hooks/use_theme';
import { AgentMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_agent_marks';
import { Legend } from '../legend';
const NameContainer = euiStyled.div`
border-bottom: 1px solid ${({ theme }) => theme.eui.euiColorMediumShade};
padding-bottom: ${({ theme }) => theme.eui.euiSizeS};
const NameContainer = styled.div`
border-bottom: 1px solid ${({ theme }) => theme.euiTheme.colors.mediumShade};
padding-bottom: ${({ theme }) => theme.euiTheme.size.s};
`;
const TimeContainer = euiStyled.div`
color: ${({ theme }) => theme.eui.euiColorMediumShade};
padding-top: ${({ theme }) => theme.eui.euiSizeS};
const TimeContainer = styled.div`
color: ${({ theme }) => theme.euiTheme.colors.mediumShade};
padding-top: ${({ theme }) => theme.euiTheme.size.s};
`;
interface Props {
@ -28,7 +27,7 @@ interface Props {
}
export function AgentMarker({ mark }: Props) {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
return (
<>
@ -42,7 +41,7 @@ export function AgentMarker({ mark }: Props) {
</div>
}
>
<Legend clickable color={theme.eui.euiColorMediumShade} />
<Legend clickable color={euiTheme.colors.mediumShade} />
</EuiToolTip>
</>
);

View file

@ -5,13 +5,12 @@
* 2.0.
*/
import { EuiPopover, EuiText } from '@elastic/eui';
import { EuiPopover, EuiText, useEuiTheme } from '@elastic/eui';
import React, { useState } from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { TRACE_ID, TRANSACTION_ID } from '../../../../../../common/es_fields/apm';
import { asDuration } from '../../../../../../common/utils/formatters';
import { useLegacyUrlParams } from '../../../../../context/url_params_context/use_url_params';
import { useTheme } from '../../../../../hooks/use_theme';
import { ErrorMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks';
import { ErrorDetailLink } from '../../../links/apm/error_detail_link';
import { Legend, Shape } from '../legend';
@ -20,21 +19,21 @@ interface Props {
mark: ErrorMark;
}
const Popover = euiStyled.div`
const Popover = styled.div`
max-width: 280px;
`;
const TimeLegend = euiStyled(Legend)`
margin-bottom: ${({ theme }) => theme.eui.euiSize};
const TimeLegend = styled(Legend)`
margin-bottom: ${({ theme }) => theme.euiTheme.size.base};
`;
const ErrorLink = euiStyled(ErrorDetailLink)`
const ErrorLink = styled(ErrorDetailLink)`
display: block;
margin: ${({ theme }) => `${theme.eui.euiSizeS} 0 ${theme.eui.euiSizeS} 0`};
margin: ${({ theme }) => `${theme.euiTheme.size.s} 0 ${theme.euiTheme.size.s} 0`};
overflow-wrap: break-word;
`;
const Button = euiStyled(Legend)`
const Button = styled(Legend)`
height: 20px;
display: flex;
align-items: flex-end;
@ -51,7 +50,7 @@ function truncateMessage(errorMessage?: string) {
}
export function ErrorMarker({ mark }: Props) {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const { urlParams } = useLegacyUrlParams();
const [isPopoverOpen, showPopover] = useState(false);
@ -61,7 +60,7 @@ export function ErrorMarker({ mark }: Props) {
<Button
data-test-subj="popover"
clickable
color={theme.eui.euiColorDanger}
color={euiTheme.colors.danger}
shape={Shape.square}
onClick={togglePopover}
/>
@ -94,7 +93,7 @@ export function ErrorMarker({ mark }: Props) {
<Popover>
<TimeLegend
text={asDuration(mark.offset)}
indicator={<div style={{ marginRight: theme.eui.euiSizeXS }}>@</div>}
indicator={<div style={{ marginRight: euiTheme.size.xs }}>@</div>}
/>
<Legend
key={mark.serviceColor}

View file

@ -6,7 +6,7 @@
*/
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { AgentMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_agent_marks';
import { ErrorMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks';
import { AgentMarker } from './agent_marker';
@ -17,7 +17,7 @@ interface Props {
x: number;
}
const MarkerContainer = euiStyled.div`
const MarkerContainer = styled.div`
position: absolute;
bottom: 0;
`;

View file

@ -7,8 +7,8 @@
import { inRange } from 'lodash';
import React from 'react';
import { useEuiTheme } from '@elastic/eui';
import { getDurationFormatter } from '../../../../../common/utils/formatters';
import { useTheme } from '../../../../hooks/use_theme';
import { Mark } from '.';
import { Marker } from './marker';
import { PlotValues } from './plot_utils';
@ -36,7 +36,7 @@ interface TimelineAxisProps {
}
export function TimelineAxis({ plotValues, marks = [], topTraceDuration }: TimelineAxisProps) {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const { margins, tickValues, width, xMax, xScale } = plotValues;
const tickFormatter = getDurationFormatter(xMax);
@ -65,7 +65,7 @@ export function TimelineAxis({ plotValues, marks = [], topTraceDuration }: Timel
x={position}
y={0}
textAnchor="middle"
fill={theme.eui.euiColorDarkShade}
fill={euiTheme.colors.darkShade}
fontSize={11}
>
{label}
@ -76,7 +76,7 @@ export function TimelineAxis({ plotValues, marks = [], topTraceDuration }: Timel
key="topTrace"
x={topTraceDurationPosition}
y={0}
fill={theme.eui.euiTextColor}
fill={euiTheme.colors.textParagraph}
textAnchor="middle"
>
{tickFormatter(topTraceDuration).formatted}

View file

@ -6,7 +6,7 @@
*/
import React from 'react';
import { useTheme } from '../../../../hooks/use_theme';
import { useEuiTheme } from '@elastic/eui';
import { Mark } from '../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks';
import { PlotValues } from './plot_utils';
@ -21,7 +21,7 @@ export function VerticalLines({ topTraceDuration, plotValues, marks = [] }: Vert
const markTimes = marks.filter((mark) => mark.verticalLine).map(({ offset }) => offset);
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const tickPositions = tickValues.reduce<number[]>((positions, tick) => {
const position = xScale(tick);
@ -53,7 +53,7 @@ export function VerticalLines({ topTraceDuration, plotValues, marks = [] }: Vert
x2={position}
y1={0}
y2="100%"
stroke={theme.eui.euiColorLightestShade}
stroke={euiTheme.colors.lightestShade}
/>
))}
{markPositions.map((position) => (
@ -63,7 +63,7 @@ export function VerticalLines({ topTraceDuration, plotValues, marks = [] }: Vert
x2={position}
y1={0}
y2="100%"
stroke={theme.eui.euiColorMediumShade}
stroke={euiTheme.colors.mediumShade}
/>
))}
{Number.isFinite(topTraceDurationPosition) && (
@ -73,7 +73,7 @@ export function VerticalLines({ topTraceDuration, plotValues, marks = [] }: Vert
x2={topTraceDurationPosition}
y1={0}
y2="100%"
stroke={theme.eui.euiColorMediumShade}
stroke={euiTheme.colors.mediumShade}
/>
)}
</g>

View file

@ -25,7 +25,7 @@ import {
Tooltip,
SettingsSpec,
} from '@elastic/charts';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiSpacer } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiSpacer, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { ReactElement } from 'react';
import { useHistory } from 'react-router-dom';
@ -33,7 +33,6 @@ import { useChartThemes } from '@kbn/observability-shared-plugin/public';
import { isExpectedBoundsComparison } from '../time_comparison/get_comparison_options';
import { useChartPointerEventContext } from '../../../context/chart_pointer_event/use_chart_pointer_event_context';
import { useTheme } from '../../../hooks/use_theme';
import { unit } from '../../../utils/style';
import { ChartContainer } from './chart_container';
import {
@ -75,11 +74,11 @@ export function TimeseriesChart({
}: TimeseriesChartProps) {
const history = useHistory();
const { chartRef, updatePointerEvent } = useChartPointerEventContext();
const theme = useTheme();
const { euiTheme, colorMode } = useEuiTheme();
const chartThemes = useChartThemes();
const anomalyChartTimeseries = getChartAnomalyTimeseries({
anomalyTimeseries,
theme,
euiTheme,
anomalyTimeseriesColor: anomalyTimeseries?.color,
});
const isEmpty = isTimeseriesEmpty(timeseries);
@ -115,12 +114,13 @@ export function TimeseriesChart({
}
: undefined;
const endZoneColor = theme.darkMode ? theme.eui.euiColorLightShade : theme.eui.euiColorDarkShade;
const isDarkMode = colorMode === 'DARK';
const endZoneColor = isDarkMode ? euiTheme.colors.lightShade : euiTheme.colors.darkShade;
const endZoneRectAnnotationStyle: Partial<RectAnnotationStyle> = {
stroke: endZoneColor,
fill: endZoneColor,
strokeWidth: 0,
opacity: theme.darkMode ? 0.6 : 0.2,
opacity: isDarkMode ? 0.6 : 0.2,
};
function getChartType(type: string) {

View file

@ -13,7 +13,7 @@ import {
YDomainRange,
} from '@elastic/charts';
import React from 'react';
import { EuiIcon } from '@elastic/eui';
import { EuiIcon, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { asAbsoluteDateTime } from '../../../../common/utils/formatters';
import { useAnnotationsContext } from '../../../context/annotations/use_annotations_context';
@ -25,7 +25,6 @@ import { FETCH_STATUS } from '../../../hooks/use_fetcher';
import { unit } from '../../../utils/style';
import { getTimeZone } from './helper/timezone';
import { TimeseriesChart } from './timeseries_chart';
import { useTheme } from '../../../hooks/use_theme';
interface AnomalyTimeseries extends ServiceAnomalyTimeseries {
color?: string;
@ -69,8 +68,8 @@ export function TimeseriesChartWithContext({
} = useAnyOfApmParams('/services', '/dependencies/*', '/services/{serviceName}');
const { core } = useApmPluginContext();
const timeZone = getTimeZone(core.uiSettings);
const theme = useTheme();
const annotationColor = theme.eui.euiColorSuccess;
const { euiTheme } = useEuiTheme();
const annotationColor = euiTheme.colors.accentSecondary;
const { annotations } = useAnnotationsContext();
const timeseriesAnnotations = [

View file

@ -9,7 +9,7 @@ import { EuiFlexItem, EuiIconTip, EuiText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { isEmpty } from 'lodash';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context';
import { useAnyOfApmParams } from '../../../../hooks/use_apm_params';
import { MLSingleMetricLink } from '../../links/machine_learning_links/mlsingle_metric_link';
@ -19,14 +19,14 @@ interface Props {
mlJobId?: string;
}
const ShiftedIconWrapper = euiStyled.span`
const ShiftedIconWrapper = styled.span`
padding-right: 5px;
position: relative;
top: -1px;
display: inline-block;
`;
const ShiftedEuiText = euiStyled(EuiText)`
const ShiftedEuiText = styled(EuiText)`
position: relative;
top: 5px;
`;
@ -45,7 +45,9 @@ export function MLHeader({ hasValidMlLicense, mlJobId }: Props) {
const hasKuery = !isEmpty(kuery);
const icon = hasKuery ? (
<EuiIconTip
aria-label="Warning"
aria-label={i18n.translate('xpack.apm.mLHeader.euiIconTip.warningLabel', {
defaultMessage: 'Warning',
})}
type="warning"
color="warning"
content={i18n.translate(

View file

@ -5,7 +5,14 @@
* 2.0.
*/
import { EuiPanel, EuiTitle, EuiFlexGroup, EuiFlexItem, EuiIconTip } from '@elastic/eui';
import {
EuiPanel,
EuiTitle,
EuiFlexGroup,
EuiFlexItem,
EuiIconTip,
useEuiTheme,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { usePreviousPeriodLabel } from '../../../../hooks/use_previous_period_text';
@ -13,7 +20,6 @@ import { isTimeComparison } from '../../time_comparison/get_comparison_options';
import { APIReturnType } from '../../../../services/rest/create_call_apm_api';
import { asPercent } from '../../../../../common/utils/formatters';
import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher';
import { useTheme } from '../../../../hooks/use_theme';
import { TimeseriesChartWithContext } from '../timeseries_chart_with_context';
import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context';
import { getComparisonChartTheme } from '../../time_comparison/get_comparison_chart_theme';
@ -57,7 +63,7 @@ export function TransactionColdstartRateChart({
comparisonEnabled,
offset,
}: Props) {
const theme = useTheme();
const { euiTheme } = useEuiTheme();
const {
query: { rangeFrom, rangeTo },
@ -117,7 +123,7 @@ export function TransactionColdstartRateChart({
{
data: data?.currentPeriod?.transactionColdstartRate ?? [],
type: 'linemark',
color: theme.eui.euiColorVis5,
color: euiTheme.colors.vis.euiColorVis5,
title: i18n.translate('xpack.apm.coldstartRate.chart.coldstartRate', {
defaultMessage: 'Cold start rate (avg.)',
}),
@ -127,7 +133,7 @@ export function TransactionColdstartRateChart({
{
data: data?.previousPeriod?.transactionColdstartRate ?? [],
type: 'area',
color: theme.eui.euiColorMediumShade,
color: euiTheme.colors.mediumShade,
title: previousPeriodLabel,
},
]

View file

@ -9,7 +9,7 @@ import { EuiBasicTableColumn, RIGHT_ALIGNMENT, CENTER_ALIGNMENT } from '@elastic
import { i18n } from '@kbn/i18n';
import { TypeOf } from '@kbn/typed-react-router-config';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { isTimeComparison } from '../time_comparison/get_comparison_options';
import { asInteger } from '../../../../common/utils/formatters';
import { APIReturnType } from '../../../services/rest/create_call_apm_api';
@ -22,7 +22,7 @@ import { TruncateWithTooltip } from '../truncate_with_tooltip';
import { ChartType, getTimeSeriesColor } from '../charts/helper/get_timeseries_color';
import { ApmRoutes } from '../../routing/apm_route_config';
const ErrorLink = euiStyled(ErrorOverviewLink)`
const ErrorLink = styled(ErrorOverviewLink)`
${truncate('100%')};
`;

View file

@ -18,7 +18,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { Fragment } from 'react';
import styled from 'styled-components';
import styled from '@emotion/styled';
import { isEmpty } from 'lodash';
interface KeyValue {
@ -35,7 +35,8 @@ const StyledEuiAccordion = styled(EuiAccordion)`
`;
const StyledEuiDescriptionList = styled(EuiDescriptionList)`
margin: ${({ theme }) => `${theme.eui.euiSizeS} ${theme.eui.euiSizeS} 0 ${theme.eui.euiSizeS}`};
margin: ${({ theme }) =>
`${theme.euiTheme.size.s} ${theme.euiTheme.size.s} 0 ${theme.euiTheme.size.s}`};
.descriptionList__title,
.descriptionList__description {
margin-top: 0;

View file

@ -7,11 +7,11 @@
import { isBoolean, isNumber, isObject } from 'lodash';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { NOT_AVAILABLE_LABEL } from '../../../../common/i18n';
const EmptyValue = euiStyled.span`
color: ${({ theme }) => theme.eui.euiColorMediumShade};
const EmptyValue = styled.span`
color: ${({ theme }) => theme.euiTheme.colors.mediumShade};
text-align: left;
`;

View file

@ -7,72 +7,73 @@
import React from 'react';
import PropTypes from 'prop-types';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import { EuiIcon } from '@elastic/eui';
import styled from '@emotion/styled';
import { EuiIcon, useEuiFontSize } from '@elastic/eui';
import { unit } from '../../../../utils/style';
import { tint } from 'polished';
function getIconColor(type, theme) {
switch (type) {
case 'field':
return theme.eui.euiColorVis7;
return theme.euiTheme.colors.vis.euiColorVis7;
case 'value':
return theme.eui.euiColorVis0;
return theme.euiTheme.colors.vis.euiColorVis0;
case 'operator':
return theme.eui.euiColorVis1;
return theme.euiTheme.colors.vis.euiColorVis1;
case 'conjunction':
return theme.eui.euiColorVis3;
return theme.euiTheme.colors.vis.euiColorVis3;
case 'recentSearch':
return theme.eui.euiColorMediumShade;
return theme.euiTheme.colors.mediumShade;
}
}
const Description = euiStyled.div`
color: ${({ theme }) => theme.eui.euiColorDarkShade};
const Description = styled.div`
color: ${({ theme }) => theme.euiTheme.colors.darkShade};
p {
display: inline;
span {
font-family: ${({ theme }) => theme.eui.euiCodeFontFamily};
color: ${({ theme }) => theme.eui.euiColorFullShade};
padding: 0 ${({ theme }) => theme.eui.euiSizeXS};
font-family: ${({ theme }) => theme.euiTheme.font.familyCode};
color: ${({ theme }) => theme.euiTheme.colors.fullShade};
padding: 0 ${({ theme }) => theme.euiTheme.size.xs};
display: inline-block;
}
}
`;
const ListItem = euiStyled.li`
font-size: ${({ theme }) => theme.eui.euiFontSizeXS};
height: ${({ theme }) => theme.eui.euiSizeXL};
const ListItem = styled.li`
font-size: ${() => useEuiFontSize('xs').fontSize};
height: ${({ theme }) => theme.euiTheme.size.xl};
align-items: center;
display: flex;
background: ${({ selected, theme }) => (selected ? theme.eui.euiColorLightestShade : 'initial')};
background: ${({ selected, theme }) =>
selected ? theme.euiTheme.colors.lightestShade : 'initial'};
cursor: pointer;
border-radius: ${({ theme }) => theme.eui.euiBorderRadiusSmall};
border-radius: ${({ theme }) => theme.euiTheme.border.radius.small};
${Description} {
p span {
background: ${({ selected, theme }) =>
selected ? theme.eui.euiColorEmptyShade : theme.eui.euiColorLightestShade};
selected ? theme.euiTheme.colors.emptyShade : theme.euiTheme.colors.lightestShade};
}
}
`;
const Icon = euiStyled.div`
flex: 0 0 ${({ theme }) => theme.eui.euiSizeXL};
const Icon = styled.div`
flex: 0 0 ${({ theme }) => theme.euiTheme.size.xl};
background: ${({ type, theme }) => tint(0.9, getIconColor(type, theme))};
color: ${({ type, theme }) => getIconColor(type, theme)};
width: 100%;
height: 100%;
text-align: center;
line-height: ${({ theme }) => theme.eui.euiSizeXL};
line-height: ${({ theme }) => theme.euiTheme.size.xl};
`;
const TextValue = euiStyled.div`
const TextValue = styled.div`
flex: 0 0 ${unit * 16}px;
color: ${({ theme }) => theme.eui.euiColorDarkestShade};
padding: 0 ${({ theme }) => theme.eui.euiSizeS};
color: ${({ theme }) => theme.euiTheme.colors.darkestShade};
padding: 0 ${({ theme }) => theme.euiTheme.size.s};
`;
function getEuiIconType(type) {

View file

@ -9,18 +9,22 @@ import { isEmpty } from 'lodash';
import { tint } from 'polished';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { unit } from '../../../../utils/style';
import Suggestion from './suggestion';
const List = euiStyled.ul`
const List = styled.ul`
width: 100%;
border: 1px solid ${({ theme }) => theme.eui.euiColorLightShade};
border-radius: ${({ theme }) => theme.eui.euiBorderRadiusSmall};
box-shadow: 0 ${({ theme }) =>
`${theme.eui.euiSizeXS} ${theme.eui.euiSizeXL} ${tint(0.9, theme.eui.euiColorFullShade)}`};
border: 1px solid ${({ theme }) => theme.euiTheme.colors.lightShade};
border-radius: ${({ theme }) => theme.euiTheme.border.radius.small};
box-shadow: 0
${({ theme }) =>
`${theme.euiTheme.size.xs} ${theme.euiTheme.size.xl} ${tint(
0.9,
theme.euiTheme.colors.fullShade
)}`};
position: absolute;
background: ${({ theme }) => theme.eui.euiColorEmptyShade};
background: ${({ theme }) => theme.euiTheme.colors.emptyShade};
z-index: 10;
left: 0;
max-height: ${unit * 20}px;

View file

@ -8,7 +8,7 @@
import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiText } from '@elastic/eui';
import { AgentIcon } from '@kbn/custom-icons';
import { i18n } from '@kbn/i18n';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { TypeOf } from '@kbn/typed-react-router-config';
import React from 'react';
import { isMobileAgentName } from '../../../../../../common/agent_name';
@ -21,7 +21,9 @@ import { PopoverTooltip } from '../../../popover_tooltip';
import { TruncateWithTooltip } from '../../../truncate_with_tooltip';
import { MaxGroupsMessage, OTHER_SERVICE_NAME } from '../max_groups_message';
const StyledLink = euiStyled(EuiLink)`${truncate('100%')};`;
const StyledLink = styled(EuiLink)`
${truncate('100%')};
`;
function formatString(value?: string | null) {
return value || NOT_AVAILABLE_LABEL;

View file

@ -8,19 +8,21 @@
import { EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui';
import { TypeOf } from '@kbn/typed-react-router-config';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { useApmRouter } from '../../../hooks/use_apm_router';
import { truncate } from '../../../utils/style';
import { ApmRoutes } from '../../routing/apm_route_config';
import { SpanIcon } from '../span_icon';
const StyledLink = euiStyled(EuiLink)`${truncate('100%')};`;
const StyledLink = styled(EuiLink)`
${truncate('100%')};
`;
interface Props {
query: TypeOf<ApmRoutes, '/dependencies/overview'>['query'];
subtype?: string;
type?: string;
onClick?: React.ComponentProps<typeof EuiLink>['onClick'];
onClick?: React.MouseEventHandler<HTMLAnchorElement>;
}
export function DependencyLink({ query, subtype, type, onClick }: Props) {

View file

@ -6,7 +6,7 @@
*/
import React, { ReactNode } from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { useBreakpoints } from '../../../hooks/use_breakpoints';
/**
@ -24,7 +24,7 @@ const tableHeight = 282;
*
* Hide the empty message when we don't yet have any items and are still not initiated.
*/
const OverviewTableContainerDiv = euiStyled.div<{
const OverviewTableContainerDiv = styled.div<{
fixedHeight?: boolean;
isEmptyAndNotInitiated: boolean;
shouldUseMobileLayout: boolean;

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import {
CloudProvider,
@ -14,7 +14,6 @@ import {
getServerlessIcon,
} from '@kbn/custom-icons';
import React, { ReactChild, useState } from 'react';
import { useTheme } from '../../../hooks/use_theme';
import { ContainerType } from '../../../../common/service_metadata';
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
import { CloudDetails } from './cloud_details';
@ -81,7 +80,8 @@ export interface PopoverItem {
export function ServiceIcons({ start, end, serviceName, environment }: Props) {
const [selectedIconPopover, setSelectedIconPopover] = useState<Icons | null>();
const theme = useTheme();
const { colorMode } = useEuiTheme();
const isDarkMode = colorMode === 'DARK';
const { data: icons, status: iconsFetchStatus } = useFetcher(
(callApmApi) => {
@ -122,7 +122,7 @@ export function ServiceIcons({ start, end, serviceName, environment }: Props) {
{
key: 'service',
icon: {
type: getAgentIcon(icons?.agentName, theme.darkMode) || 'node',
type: getAgentIcon(icons?.agentName, isDarkMode) || 'node',
},
isVisible: !!icons?.agentName,
title: i18n.translate('xpack.apm.serviceIcons.service', {
@ -133,7 +133,7 @@ export function ServiceIcons({ start, end, serviceName, environment }: Props) {
{
key: 'opentelemetry',
icon: {
type: getAgentIcon('opentelemetry', theme.darkMode),
type: getAgentIcon('opentelemetry', isDarkMode),
},
isVisible: !!icons?.agentName && isOpenTelemetryAgentName(icons.agentName),
title: i18n.translate('xpack.apm.serviceIcons.opentelemetry', {

View file

@ -8,29 +8,29 @@
import { EuiAccordion, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { Stacktrace } from '.';
import { Stackframe } from '../../../../typings/es_schemas/raw/fields/stackframe';
const Accordion = euiStyled(EuiAccordion)`
border-top: ${({ theme }) => theme.eui.euiBorderThin};
margin-top: ${({ theme }) => theme.eui.euiSizeS};
const Accordion = styled(EuiAccordion)`
border-top: ${({ theme }) => theme.euiTheme.border.thin};
margin-top: ${({ theme }) => theme.euiTheme.size.s};
`;
const CausedByContainer = euiStyled('h5')`
padding: ${({ theme }) => theme.eui.euiSizeS} 0;
const CausedByContainer = styled('h5')`
padding: ${({ theme }) => theme.euiTheme.size.s} 0;
`;
const CausedByHeading = euiStyled('span')`
color: ${({ theme }) => theme.eui.euiTextSubduedColor};
const CausedByHeading = styled('span')`
color: ${({ theme }) => theme.euiTheme.colors.textSubdued};
display: block;
font-size: ${({ theme }) => theme.eui.euiFontSizeXS};
font-weight: ${({ theme }) => theme.eui.euiFontWeightBold};
font-size: ${({ theme }) => theme.euiTheme.size.xs};
font-weight: ${({ theme }) => theme.euiTheme.font.weight.bold};
text-transform: uppercase;
`;
const FramesContainer = euiStyled('div')`
padding-left: ${({ theme }) => theme.eui.euiSizeM};
const FramesContainer = styled('div')`
padding-left: ${({ theme }) => theme.euiTheme.size.m};
`;
function CausedBy({ message }: { message: string }) {

View file

@ -13,66 +13,66 @@ import javascript from 'react-syntax-highlighter/dist/cjs/languages/hljs/javascr
import python from 'react-syntax-highlighter/dist/cjs/languages/hljs/python';
import ruby from 'react-syntax-highlighter/dist/cjs/languages/hljs/ruby';
import xcode from 'react-syntax-highlighter/dist/cjs/styles/hljs/xcode';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { StackframeWithLineContext } from '../../../../typings/es_schemas/raw/fields/stackframe';
SyntaxHighlighter.registerLanguage('javascript', javascript);
SyntaxHighlighter.registerLanguage('python', python);
SyntaxHighlighter.registerLanguage('ruby', ruby);
const ContextContainer = euiStyled.div`
const ContextContainer = styled.div`
position: relative;
border-radius: ${({ theme }) => theme.eui.euiBorderRadiusSmall};
border-radius: ${({ theme }) => theme.euiTheme.border.radius.small};
`;
const LINE_HEIGHT = 18;
const LineHighlight = euiStyled.div<{ lineNumber: number }>`
const LineHighlight = styled.div<{ lineNumber: number }>`
position: absolute;
width: 100%;
height: ${LINE_HEIGHT}px;
top: ${(props) => props.lineNumber * LINE_HEIGHT}px;
pointer-events: none;
background-color: ${({ theme }) => tint(0.9, theme.eui.euiColorWarning)};
background-color: ${({ theme }) => tint(0.9, theme.euiTheme.colors.warning)};
`;
const LineNumberContainer = euiStyled.div<{ isLibraryFrame: boolean }>`
const LineNumberContainer = styled.div<{ isLibraryFrame: boolean }>`
position: absolute;
top: 0;
left: 0;
border-radius: ${({ theme }) => theme.eui.euiBorderRadiusSmall};
border-radius: ${({ theme }) => theme.euiTheme.border.radius.small};
background: ${({ isLibraryFrame, theme }) =>
isLibraryFrame ? theme.eui.euiColorEmptyShade : theme.eui.euiColorLightestShade};
isLibraryFrame ? theme.euiTheme.colors.emptyShade : theme.euiTheme.colors.lightestShade};
`;
const LineNumber = euiStyled.div<{ highlight: boolean }>`
const LineNumber = styled.div<{ highlight: boolean }>`
position: relative;
min-width: 42px;
padding-left: ${({ theme }) => theme.eui.euiSizeS};
padding-right: ${({ theme }) => theme.eui.euiSizeXS};
color: ${({ theme }) => theme.eui.euiColorMediumShade};
padding-left: ${({ theme }) => theme.euiTheme.size.s};
padding-right: ${({ theme }) => theme.euiTheme.size.xs};
color: ${({ theme }) => theme.euiTheme.colors.mediumShade};
line-height: ${LINE_HEIGHT}px;
text-align: right;
border-right: 1px solid ${({ theme }) => theme.eui.euiColorLightShade};
border-right: ${({ theme }) => theme.euiTheme.border.thin};
background-color: ${({ highlight, theme }) =>
highlight ? tint(0.9, theme.eui.euiColorWarning) : null};
highlight ? tint(0.9, theme.euiTheme.colors.warning) : null};
&:last-of-type {
border-radius: 0 0 0 ${({ theme }) => theme.eui.euiBorderRadiusSmall};
border-radius: 0 0 0 ${({ theme }) => theme.euiTheme.border.radius.small};
}
`;
const LineContainer = euiStyled.div`
const LineContainer = styled.div`
overflow: auto;
margin: 0 0 0 42px;
padding: 0;
background-color: ${({ theme }) => theme.eui.euiColorEmptyShade};
background-color: ${({ theme }) => theme.euiTheme.colors.emptyShade};
&:last-of-type {
border-radius: 0 0 ${({ theme }) => theme.eui.euiBorderRadiusSmall} 0;
border-radius: 0 0 ${({ theme }) => theme.euiTheme.border.radius.small} 0;
}
`;
const Line = euiStyled.pre`
const Line = styled.pre`
// Override all styles
margin: 0;
color: inherit;
@ -84,7 +84,7 @@ const Line = euiStyled.pre`
line-height: ${LINE_HEIGHT}px;
`;
const Code = euiStyled.code`
const Code = styled.code`
position: relative;
padding: 0;
margin: 0;

View file

@ -6,7 +6,8 @@
*/
import React, { ComponentType } from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { useEuiFontSize } from '@elastic/eui';
import { Stackframe } from '../../../../typings/es_schemas/raw/fields/stackframe';
import {
CSharpFrameHeadingRenderer,
@ -18,21 +19,21 @@ import {
PhpFrameHeadingRenderer,
} from './frame_heading_renderers';
const FileDetails = euiStyled.div`
color: ${({ theme }) => theme.eui.euiColorDarkShade};
const FileDetails = styled.div`
color: ${({ theme }) => theme.euiTheme.colors.darkShade};
line-height: 1.5; /* matches the line-hight of the accordion container button */
padding: 2px 0;
font-family: ${({ theme }) => theme.eui.euiCodeFontFamily};
font-size: ${({ theme }) => theme.eui.euiFontSizeS};
font-family: ${({ theme }) => theme.euiTheme.font.familyCode};
font-size: ${({ theme }) => useEuiFontSize('s').fontSize};
`;
const LibraryFrameFileDetail = euiStyled.span`
color: ${({ theme }) => theme.eui.euiColorDarkShade};
const LibraryFrameFileDetail = styled.span`
color: ${({ theme }) => theme.euiTheme.colors.darkShade};
word-break: break-word;
`;
const AppFrameFileDetail = euiStyled.span`
color: ${({ theme }) => theme.eui.euiColorFullShade};
const AppFrameFileDetail = styled.span`
color: ${({ theme }) => theme.euiTheme.colors.fullShade};
word-break: break-word;
`;

View file

@ -8,12 +8,12 @@
import { EuiAccordion } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { Stackframe } from '../../../../typings/es_schemas/raw/fields/stackframe';
import { Stackframe as StackframeComponent } from './stackframe';
const LibraryStacktraceAccordion = euiStyled(EuiAccordion)`
margin: ${({ theme }) => theme.eui.euiSizeXS} 0;
const LibraryStacktraceAccordion = styled(EuiAccordion)`
margin: ${({ theme }) => theme.euiTheme.size.xs} 0;
`;
interface Props {

View file

@ -7,7 +7,7 @@
import { EuiAccordion } from '@elastic/eui';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import {
Stackframe as StackframeType,
StackframeWithLineContext,
@ -16,18 +16,18 @@ import { Context } from './context';
import { FrameHeading } from './frame_heading';
import { Variables } from './variables';
const ContextContainer = euiStyled.div<{ isLibraryFrame: boolean }>`
const ContextContainer = styled.div<{ isLibraryFrame: boolean }>`
position: relative;
font-family: ${({ theme }) => theme.eui.euiCodeFontFamily};
font-size: ${({ theme }) => theme.eui.euiFontSizeS};
border: 1px solid ${({ theme }) => theme.eui.euiColorLightShade};
border-radius: ${({ theme }) => theme.eui.euiBorderRadiusSmall};
font-family: ${({ theme }) => theme.euiTheme.font.familyCode};
font-size: ${({ theme }) => theme.euiTheme.size.s};
border: 1px solid ${({ theme }) => theme.euiTheme.colors.lightShade};
border-radius: ${({ theme }) => theme.euiTheme.border.radius.small};
background: ${({ isLibraryFrame, theme }) =>
isLibraryFrame ? theme.eui.euiColorEmptyShade : theme.eui.euiColorLightestShade};
isLibraryFrame ? theme.euiTheme.colors.emptyShade : theme.euiTheme.colors.lightestShade};
`;
// Indent the non-context frames the same amount as the accordion control
const NoContextFrameHeadingWrapper = euiStyled.div`
const NoContextFrameHeadingWrapper = styled.div`
margin-left: 28px;
`;

View file

@ -8,16 +8,16 @@
import { EuiAccordion } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import styled from '@emotion/styled';
import { Stackframe } from '../../../../typings/es_schemas/raw/fields/stackframe';
import { KeyValueTable } from '../key_value_table';
import { flattenObject } from '../../../../common/utils/flatten_object';
const VariablesContainer = euiStyled.div`
background: ${({ theme }) => theme.eui.euiColorEmptyShade};
border-radius: 0 0 ${({ theme }) =>
`${theme.eui.euiBorderRadiusSmall} ${theme.eui.euiBorderRadiusSmall}`};
padding: ${({ theme }) => `${theme.eui.euiSizeS} ${theme.eui.euiSizeM}`};
const VariablesContainer = styled.div`
background: ${({ theme }) => theme.euiTheme.colors.emptyShade};
border-radius: 0 0
${({ theme }) => `${theme.euiTheme.border.radius.small} ${theme.euiTheme.border.radius.small}`};
padding: ${({ theme }) => `${theme.euiTheme.size.s} ${theme.euiTheme.size.m}`};
`;
interface Props {

Some files were not shown because too many files have changed in this diff Show more