From 5256b6d23ef4d05ff3dce1d7d91711c1748c8d38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?=
Date: Mon, 12 Jul 2021 11:46:38 +0200
Subject: [PATCH 01/12] Accomodate height of the (#104882)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../sections/agent_policy/edit_package_policy_page/index.tsx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx
index b07d76dc6bd8e8..ee529b6865e565 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx
@@ -430,7 +430,9 @@ export const EditPackagePolicyForm = memo<{
/>
)}
{configurePackage}
-
+ {/* Extra space to accomodate the EuiBottomBar height */}
+
+
From b8dfcafe38e636ec88b2ca03253cf15cec844d27 Mon Sep 17 00:00:00 2001
From: Pete Harverson
Date: Mon, 12 Jul 2021 11:31:54 +0100
Subject: [PATCH 02/12] [ML] Fixes unnecessary too many buckets warning on
anomaly chart embeddable (#105043)
* [ML] Fixes unnecessary too many buckets warning on anomaly chart embeddable
* [ML] Update jest tests for number of axis ticks.
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../explorer_chart_distribution.js | 24 ++++++++++---------
.../explorer_chart_distribution.test.js | 2 +-
.../explorer_chart_single_metric.js | 24 ++++++++++---------
.../explorer_chart_single_metric.test.js | 2 +-
.../anomaly_explorer_charts_service.ts | 11 +++++++--
5 files changed, 37 insertions(+), 26 deletions(-)
diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js
index 7efd36bbe57c61..27a934fa841fe0 100644
--- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js
+++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js
@@ -270,12 +270,6 @@ export class ExplorerChartDistribution extends React.Component {
const tickValuesStart = Math.max(config.selectedEarliest, config.plotEarliest);
// +1 ms to account for the ms that was subtracted for query aggregations.
const interval = config.selectedLatest - config.selectedEarliest + 1;
- const tickValues = getTickValues(
- tickValuesStart,
- interval,
- config.plotEarliest,
- config.plotLatest
- );
const xAxis = d3.svg
.axis()
@@ -286,10 +280,18 @@ export class ExplorerChartDistribution extends React.Component {
.tickPadding(10)
.tickFormat((d) => moment(d).format(xAxisTickFormat));
- // With tooManyBuckets the chart would end up with no x-axis labels
- // because the ticks are based on the span of the emphasis section,
- // and the highlighted area spans the whole chart.
- if (tooManyBuckets === false) {
+ // With tooManyBuckets, or when the chart is used as an embeddable,
+ // the chart would end up with no x-axis labels because the ticks are based on the span of the
+ // emphasis section, and the selected area spans the whole chart.
+ const useAutoTicks =
+ tooManyBuckets === true || interval >= config.plotLatest - config.plotEarliest;
+ if (useAutoTicks === false) {
+ const tickValues = getTickValues(
+ tickValuesStart,
+ interval,
+ config.plotEarliest,
+ config.plotLatest
+ );
xAxis.tickValues(tickValues);
} else {
xAxis.ticks(numTicksForDateFormat(vizWidth, xAxisTickFormat));
@@ -327,7 +329,7 @@ export class ExplorerChartDistribution extends React.Component {
});
}
- if (tooManyBuckets === false) {
+ if (useAutoTicks === false) {
removeLabelOverlap(gAxis, tickValuesStart, interval, vizWidth);
}
}
diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.test.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.test.js
index 11a15b192fc520..8d2f66a870c75c 100644
--- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.test.js
+++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.test.js
@@ -139,7 +139,7 @@ describe('ExplorerChart', () => {
expect(+selectedInterval.getAttribute('height')).toBe(166);
const xAxisTicks = wrapper.getDOMNode().querySelector('.x').querySelectorAll('.tick');
- expect([...xAxisTicks]).toHaveLength(0);
+ expect([...xAxisTicks]).toHaveLength(1);
const yAxisTicks = wrapper.getDOMNode().querySelector('.y').querySelectorAll('.tick');
expect([...yAxisTicks]).toHaveLength(5);
const emphasizedAxisLabel = wrapper
diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js
index dd07a7d6cbdee0..19390017244a8c 100644
--- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js
+++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js
@@ -196,12 +196,6 @@ export class ExplorerChartSingleMetric extends React.Component {
const tickValuesStart = Math.max(config.selectedEarliest, config.plotEarliest);
// +1 ms to account for the ms that was subtracted for query aggregations.
const interval = config.selectedLatest - config.selectedEarliest + 1;
- const tickValues = getTickValues(
- tickValuesStart,
- interval,
- config.plotEarliest,
- config.plotLatest
- );
const xAxis = d3.svg
.axis()
@@ -212,10 +206,18 @@ export class ExplorerChartSingleMetric extends React.Component {
.tickPadding(10)
.tickFormat((d) => moment(d).format(xAxisTickFormat));
- // With tooManyBuckets the chart would end up with no x-axis labels
- // because the ticks are based on the span of the emphasis section,
- // and the highlighted area spans the whole chart.
- if (tooManyBuckets === false) {
+ // With tooManyBuckets, or when the chart is used as an embeddable,
+ // the chart would end up with no x-axis labels because the ticks are based on the span of the
+ // emphasis section, and the selected area spans the whole chart.
+ const useAutoTicks =
+ tooManyBuckets === true || interval >= config.plotLatest - config.plotEarliest;
+ if (useAutoTicks === false) {
+ const tickValues = getTickValues(
+ tickValuesStart,
+ interval,
+ config.plotEarliest,
+ config.plotLatest
+ );
xAxis.tickValues(tickValues);
} else {
xAxis.ticks(numTicksForDateFormat(vizWidth, xAxisTickFormat));
@@ -243,7 +245,7 @@ export class ExplorerChartSingleMetric extends React.Component {
axes.append('g').attr('class', 'y axis').call(yAxis);
- if (tooManyBuckets === false) {
+ if (useAutoTicks === false) {
removeLabelOverlap(gAxis, tickValuesStart, interval, vizWidth);
}
}
diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.test.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.test.js
index 981f7515d3d706..00172965bc2162 100644
--- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.test.js
+++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.test.js
@@ -144,7 +144,7 @@ describe('ExplorerChart', () => {
expect(+selectedInterval.getAttribute('height')).toBe(166);
const xAxisTicks = wrapper.getDOMNode().querySelector('.x').querySelectorAll('.tick');
- expect([...xAxisTicks]).toHaveLength(0);
+ expect([...xAxisTicks]).toHaveLength(1);
const yAxisTicks = wrapper.getDOMNode().querySelector('.y').querySelectorAll('.tick');
expect([...yAxisTicks]).toHaveLength(10);
diff --git a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts
index afad043fcc4d13..97ddefac860f2d 100644
--- a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts
+++ b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts
@@ -225,13 +225,20 @@ export class AnomalyExplorerChartsService {
chartRange.min = chartRange.min + maxBucketSpanMs;
}
+ // When used as an embeddable, selectedEarliestMs is the start date on the time picker,
+ // which may be earlier than the time of the first point plotted in the chart (as we plot
+ // the first full bucket with a start date no earlier than the start).
+ const selectedEarliestBucketCeil = boundsMin
+ ? Math.ceil(Math.max(selectedEarliestMs, boundsMin) / maxBucketSpanMs) * maxBucketSpanMs
+ : Math.ceil(selectedEarliestMs / maxBucketSpanMs) * maxBucketSpanMs;
+
const selectedLatestBucketStart = boundsMax
? Math.floor(Math.min(selectedLatestMs, boundsMax) / maxBucketSpanMs) * maxBucketSpanMs
: Math.floor(selectedLatestMs / maxBucketSpanMs) * maxBucketSpanMs;
if (
- (chartRange.min > selectedEarliestMs || chartRange.max < selectedLatestBucketStart) &&
- chartRange.max - chartRange.min < selectedLatestBucketStart - selectedEarliestMs
+ (chartRange.min > selectedEarliestBucketCeil || chartRange.max < selectedLatestBucketStart) &&
+ chartRange.max - chartRange.min < selectedLatestBucketStart - selectedEarliestBucketCeil
) {
tooManyBuckets = true;
}
From 216bb5e1b8c8406cd23503619972e5a3ea543790 Mon Sep 17 00:00:00 2001
From: Dzmitry Lemechko
Date: Mon, 12 Jul 2021 13:23:08 +0200
Subject: [PATCH 03/12] [load] run puppeteer script before gatling scenarios
(#104836)
* [load] puppeteer script before load testing
* install dependencies after metricbeat configuration
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
test/scripts/jenkins_build_load_testing.sh | 3 +++
x-pack/test/load/runner.ts | 10 ++++++++++
2 files changed, 13 insertions(+)
diff --git a/test/scripts/jenkins_build_load_testing.sh b/test/scripts/jenkins_build_load_testing.sh
index d7c7bda83c9ef2..667540515fc835 100755
--- a/test/scripts/jenkins_build_load_testing.sh
+++ b/test/scripts/jenkins_build_load_testing.sh
@@ -53,6 +53,9 @@ echo "cloud.auth: ${USER_FROM_VAULT}:${PASS_FROM_VAULT}" >> cfg/metricbeat/metri
cp cfg/metricbeat/metricbeat.yml $KIBANA_DIR/metricbeat-install/metricbeat.yml
# Disable system monitoring: enabled for now to have more data
#mv $KIBANA_DIR/metricbeat-install/modules.d/system.yml $KIBANA_DIR/metricbeat-install/modules.d/system.yml.disabled
+echo " -> Building puppeteer project"
+cd puppeteer
+yarn install && yarn build
popd
# doesn't persist, also set in kibanaPipeline.groovy
diff --git a/x-pack/test/load/runner.ts b/x-pack/test/load/runner.ts
index 2d379391b20897..0bea5992f55394 100644
--- a/x-pack/test/load/runner.ts
+++ b/x-pack/test/load/runner.ts
@@ -18,6 +18,7 @@ const simulationPackage = 'org.kibanaLoadTest.simulation';
const simulationFIleExtension = '.scala';
const gatlingProjectRootPath: string =
process.env.GATLING_PROJECT_PATH || resolve(REPO_ROOT, '../kibana-load-testing');
+const puppeteerProjectRootPath: string = resolve(gatlingProjectRootPath, 'puppeteer');
const simulationEntry: string = process.env.GATLING_SIMULATIONS || 'branch.DemoJourney';
if (!Fs.existsSync(gatlingProjectRootPath)) {
@@ -52,6 +53,15 @@ export async function GatlingTestRunner({ getService }: FtrProviderContext) {
const log = getService('log');
await withProcRunner(log, async (procs) => {
+ await procs.run('node build/index.js', {
+ cmd: 'node',
+ args: ['build/index.js'],
+ cwd: puppeteerProjectRootPath,
+ env: {
+ ...process.env,
+ },
+ wait: true,
+ });
for (let i = 0; i < simulationClasses.length; i++) {
await procs.run('gatling: test', {
cmd: 'mvn',
From 832d349930be1f8d4a7a47733f413b0ab75303e8 Mon Sep 17 00:00:00 2001
From: Joe Reuter
Date: Mon, 12 Jul 2021 14:13:42 +0200
Subject: [PATCH 04/12] [KibanaLegacy] Remove unused stuff and make things
async if it is easy (#104638)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* remove unused stuff and make things async if it is easy
* fix problems
* load bootstrap in monitoring
* load angular bootstrap for saved searches and in unit tests
* fix vis_type_table tests
* Update x-pack/plugins/monitoring/public/plugin.ts
Co-authored-by: Ester Martí Vilaseca
* Update x-pack/plugins/monitoring/public/plugin.ts
Co-authored-by: Ester Martí Vilaseca
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Stratoula Kalafateli
Co-authored-by: Ester Martí Vilaseca
---
.../doc_table/components/row_headers.test.js | 4 +
.../angular/doc_table/doc_table.test.js | 4 +
.../application/angular/get_inner_angular.ts | 4 +-
.../application/angular/helpers/index.ts | 1 +
.../angular/helpers}/promises.d.ts | 0
.../application/angular/helpers}/promises.js | 0
src/plugins/discover/public/plugin.tsx | 2 +
.../public/angular/angular_config.tsx | 7 +-
.../kibana_legacy/public/angular/index.ts | 2 -
src/plugins/kibana_legacy/public/index.ts | 1 -
src/plugins/kibana_legacy/public/mocks.ts | 1 +
.../kibana_legacy/public/notify/index.ts | 1 -
.../notify/toasts/TOAST_NOTIFICATIONS.md | 100 ------------------
.../public/notify/toasts/index.ts | 9 --
.../notify/toasts/toast_notifications.test.ts | 76 -------------
.../notify/toasts/toast_notifications.ts | 37 -------
src/plugins/kibana_legacy/public/plugin.ts | 8 ++
.../kibana_legacy/public/utils/index.ts | 1 -
.../kibana_legacy/public/utils/system_api.ts | 40 -------
src/plugins/timelion/public/plugin.ts | 5 +-
.../public/legacy/agg_table/agg_table.test.js | 6 +-
.../legacy/agg_table/agg_table_group.test.js | 6 +-
.../public/legacy/get_inner_angular.ts | 3 -
.../paginated_table/paginated_table.test.ts | 5 +
.../legacy/table_vis_controller.test.ts | 4 +
.../public/legacy/vis_controller.ts | 1 +
x-pack/plugins/graph/public/plugin.ts | 7 +-
x-pack/plugins/monitoring/public/plugin.ts | 5 +-
28 files changed, 54 insertions(+), 286 deletions(-)
rename src/plugins/{kibana_legacy/public/angular => discover/public/application/angular/helpers}/promises.d.ts (100%)
rename src/plugins/{kibana_legacy/public/angular => discover/public/application/angular/helpers}/promises.js (100%)
delete mode 100644 src/plugins/kibana_legacy/public/notify/toasts/TOAST_NOTIFICATIONS.md
delete mode 100644 src/plugins/kibana_legacy/public/notify/toasts/index.ts
delete mode 100644 src/plugins/kibana_legacy/public/notify/toasts/toast_notifications.test.ts
delete mode 100644 src/plugins/kibana_legacy/public/notify/toasts/toast_notifications.ts
delete mode 100644 src/plugins/kibana_legacy/public/utils/system_api.ts
diff --git a/src/plugins/discover/public/application/angular/doc_table/components/row_headers.test.js b/src/plugins/discover/public/application/angular/doc_table/components/row_headers.test.js
index a087ac86971838..1a3b34c45d05e2 100644
--- a/src/plugins/discover/public/application/angular/doc_table/components/row_headers.test.js
+++ b/src/plugins/discover/public/application/angular/doc_table/components/row_headers.test.js
@@ -19,6 +19,7 @@ import { setScopedHistory, setServices, setDocViewsRegistry } from '../../../../
import { coreMock } from '../../../../../../../core/public/mocks';
import { dataPluginMock } from '../../../../../../data/public/mocks';
import { navigationPluginMock } from '../../../../../../navigation/public/mocks';
+import { initAngularBootstrap } from '../../../../../../kibana_legacy/public/angular_bootstrap';
import { getInnerAngularModule } from '../../get_inner_angular';
import { createBrowserHistory } from 'history';
@@ -41,6 +42,9 @@ describe('Doc Table', () => {
// Stub out a minimal mapping of 4 fields
let mapping;
+ beforeAll(async () => {
+ await initAngularBootstrap();
+ });
beforeAll(() => setScopedHistory(createBrowserHistory()));
beforeEach(() => {
angular.element.prototype.slice = jest.fn(function (index) {
diff --git a/src/plugins/discover/public/application/angular/doc_table/doc_table.test.js b/src/plugins/discover/public/application/angular/doc_table/doc_table.test.js
index 1db35ddf18089e..097f32965b1413 100644
--- a/src/plugins/discover/public/application/angular/doc_table/doc_table.test.js
+++ b/src/plugins/discover/public/application/angular/doc_table/doc_table.test.js
@@ -17,6 +17,7 @@ import hits from '../../../__fixtures__/real_hits';
import { coreMock } from '../../../../../../core/public/mocks';
import { dataPluginMock } from '../../../../../data/public/mocks';
import { navigationPluginMock } from '../../../../../navigation/public/mocks';
+import { initAngularBootstrap } from '../../../../../kibana_legacy/public/angular_bootstrap';
import { setScopedHistory, setServices } from '../../../kibana_services';
import { getInnerAngularModule } from '../get_inner_angular';
@@ -54,6 +55,9 @@ describe('docTable', () => {
const core = coreMock.createStart();
let $elem;
+ beforeAll(async () => {
+ await initAngularBootstrap();
+ });
beforeAll(() => setScopedHistory(createBrowserHistory()));
beforeEach(() => {
angular.element.prototype.slice = jest.fn(() => {
diff --git a/src/plugins/discover/public/application/angular/get_inner_angular.ts b/src/plugins/discover/public/application/angular/get_inner_angular.ts
index 26d64d5adc8a33..992d82795302b9 100644
--- a/src/plugins/discover/public/application/angular/get_inner_angular.ts
+++ b/src/plugins/discover/public/application/angular/get_inner_angular.ts
@@ -33,13 +33,12 @@ import { createDocViewerDirective } from './doc_viewer';
import { createDiscoverGridDirective } from './create_discover_grid_directive';
import { createRenderCompleteDirective } from './directives/render_complete';
import {
- initAngularBootstrap,
configureAppAngularModule,
PrivateProvider,
- PromiseServiceCreator,
registerListenEventListener,
watchMultiDecorator,
} from '../../../../kibana_legacy/public';
+import { PromiseServiceCreator } from './helpers';
import { DiscoverStartPlugins } from '../../plugin';
import { getScopedHistory } from '../../kibana_services';
import { createDiscoverDirective } from './create_discover_directive';
@@ -54,7 +53,6 @@ export function getInnerAngularModule(
deps: DiscoverStartPlugins,
context: PluginInitializerContext
) {
- initAngularBootstrap();
const module = initializeInnerAngularModule(name, core, deps.navigation, deps.data);
configureAppAngularModule(module, { core, env: context.env }, true, getScopedHistory);
return module;
diff --git a/src/plugins/discover/public/application/angular/helpers/index.ts b/src/plugins/discover/public/application/angular/helpers/index.ts
index 3d2c0b1c63b332..6a7f75b7e81a20 100644
--- a/src/plugins/discover/public/application/angular/helpers/index.ts
+++ b/src/plugins/discover/public/application/angular/helpers/index.ts
@@ -8,3 +8,4 @@
export { formatRow, formatTopLevelObject } from './row_formatter';
export { handleSourceColumnState } from './state_helpers';
+export { PromiseServiceCreator } from './promises';
diff --git a/src/plugins/kibana_legacy/public/angular/promises.d.ts b/src/plugins/discover/public/application/angular/helpers/promises.d.ts
similarity index 100%
rename from src/plugins/kibana_legacy/public/angular/promises.d.ts
rename to src/plugins/discover/public/application/angular/helpers/promises.d.ts
diff --git a/src/plugins/kibana_legacy/public/angular/promises.js b/src/plugins/discover/public/application/angular/helpers/promises.js
similarity index 100%
rename from src/plugins/kibana_legacy/public/angular/promises.js
rename to src/plugins/discover/public/application/angular/helpers/promises.js
diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx
index 3e31fe1d46d459..1e8a5cdac95efe 100644
--- a/src/plugins/discover/public/plugin.tsx
+++ b/src/plugins/discover/public/plugin.tsx
@@ -403,6 +403,7 @@ export class DiscoverPlugin
}
// this is used by application mount and tests
const { getInnerAngularModule } = await import('./application/angular/get_inner_angular');
+ await plugins.kibanaLegacy.loadAngularBootstrap();
const module = getInnerAngularModule(
innerAngularName,
core,
@@ -473,6 +474,7 @@ export class DiscoverPlugin
throw Error('Discover plugin getEmbeddableInjector: initializeServices is undefined');
}
const { core, plugins } = await this.initializeServices();
+ await getServices().kibanaLegacy.loadAngularBootstrap();
getServices().kibanaLegacy.loadFontAwesome();
const { getInnerAngularModuleEmbeddable } = await import(
'./application/angular/get_inner_angular'
diff --git a/src/plugins/kibana_legacy/public/angular/angular_config.tsx b/src/plugins/kibana_legacy/public/angular/angular_config.tsx
index daecfbc57ea991..48ee6d2db269e6 100644
--- a/src/plugins/kibana_legacy/public/angular/angular_config.tsx
+++ b/src/plugins/kibana_legacy/public/angular/angular_config.tsx
@@ -13,6 +13,7 @@ import {
ILocationProvider,
IModule,
IRootScopeService,
+ IRequestConfig,
} from 'angular';
import $ from 'jquery';
import { set } from '@elastic/safer-lodash-set';
@@ -22,7 +23,6 @@ import { ChromeBreadcrumb, EnvironmentMode, PackageInfo } from 'kibana/public';
import { History } from 'history';
import { CoreStart } from 'kibana/public';
-import { isSystemApiRequest } from '../utils';
import { formatAngularHttpError, isAngularHttpError } from '../notify/lib';
export interface RouteConfiguration {
@@ -38,6 +38,11 @@ export interface RouteConfiguration {
requireUICapability?: string;
}
+function isSystemApiRequest(request: IRequestConfig) {
+ const { headers } = request;
+ return headers && !!headers['kbn-system-request'];
+}
+
/**
* Detects whether a given angular route is a dummy route that doesn't
* require any action. There are two ways this can happen:
diff --git a/src/plugins/kibana_legacy/public/angular/index.ts b/src/plugins/kibana_legacy/public/angular/index.ts
index d9d8c0c19eb7b1..369495698591d0 100644
--- a/src/plugins/kibana_legacy/public/angular/index.ts
+++ b/src/plugins/kibana_legacy/public/angular/index.ts
@@ -6,8 +6,6 @@
* Side Public License, v 1.
*/
-// @ts-ignore
-export { PromiseServiceCreator } from './promises';
// @ts-ignore
export { watchMultiDecorator } from './watch_multi';
export * from './angular_config';
diff --git a/src/plugins/kibana_legacy/public/index.ts b/src/plugins/kibana_legacy/public/index.ts
index 03adb768cde208..ea5172f78a68f3 100644
--- a/src/plugins/kibana_legacy/public/index.ts
+++ b/src/plugins/kibana_legacy/public/index.ts
@@ -14,7 +14,6 @@ export const plugin = (initializerContext: PluginInitializerContext) =>
export * from './plugin';
-export { initAngularBootstrap } from './angular_bootstrap';
export { PaginateDirectiveProvider, PaginateControlsDirectiveProvider } from './paginate/paginate';
export * from './angular';
export * from './notify';
diff --git a/src/plugins/kibana_legacy/public/mocks.ts b/src/plugins/kibana_legacy/public/mocks.ts
index 40834635cc5704..6116c0682cb3bb 100644
--- a/src/plugins/kibana_legacy/public/mocks.ts
+++ b/src/plugins/kibana_legacy/public/mocks.ts
@@ -22,6 +22,7 @@ const createStartContract = (): Start => ({
getHideWriteControls: jest.fn(),
},
loadFontAwesome: jest.fn(),
+ loadAngularBootstrap: jest.fn(),
});
export const kibanaLegacyPluginMock = {
diff --git a/src/plugins/kibana_legacy/public/notify/index.ts b/src/plugins/kibana_legacy/public/notify/index.ts
index a243059cb19183..d4dcaa77cc47ad 100644
--- a/src/plugins/kibana_legacy/public/notify/index.ts
+++ b/src/plugins/kibana_legacy/public/notify/index.ts
@@ -6,5 +6,4 @@
* Side Public License, v 1.
*/
-export * from './toasts';
export * from './lib';
diff --git a/src/plugins/kibana_legacy/public/notify/toasts/TOAST_NOTIFICATIONS.md b/src/plugins/kibana_legacy/public/notify/toasts/TOAST_NOTIFICATIONS.md
deleted file mode 100644
index de6a51f3927d17..00000000000000
--- a/src/plugins/kibana_legacy/public/notify/toasts/TOAST_NOTIFICATIONS.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# Toast notifications
-
-Use this service to surface toasts in the bottom-right corner of the screen. After a brief delay, they'll disappear. They're useful for notifying the user of state changes. See [the EUI docs](https://elastic.github.io/eui/) for more information on toasts and their role within the UI.
-
-## Importing the module
-
-```js
-import { toastNotifications } from 'ui/notify';
-```
-
-## Interface
-
-### Adding toasts
-
-For convenience, there are several methods which predefine the appearance of different types of toasts. Use these methods so that the same types of toasts look similar to the user.
-
-#### Default
-
-Neutral toast. Tell the user a change in state has occurred, which is not necessarily good or bad.
-
-```js
-toastNotifications.add('Copied to clipboard');
-```
-
-#### Success
-
-Let the user know that an action was successful, such as saving or deleting an object.
-
-```js
-toastNotifications.addSuccess('Your document was saved');
-```
-
-#### Warning
-
-If something OK or good happened, but perhaps wasn't perfect, show a warning toast.
-
-```js
-toastNotifications.addWarning('Your document was saved, but not its edit history');
-```
-
-#### Danger
-
-When the user initiated an action but the action failed, show them a danger toast.
-
-```js
-toastNotifications.addDanger('An error caused your document to be lost');
-```
-
-### Removing a toast
-
-Toasts will automatically be dismissed after a brief delay, but if for some reason you want to dismiss a toast, you can use the returned toast from one of the `add` methods and then pass it to `remove`.
-
-```js
-const toast = toastNotifications.add('Your document was saved');
-toastNotifications.remove(toast);
-```
-
-### Configuration options
-
-If you want to configure the toast further you can provide an object instead of a string. The properties of this object correspond to the `propTypes` accepted by the `EuiToast` component. Refer to [the EUI docs](https://elastic.github.io/eui/) for info on these `propTypes`.
-
-```js
-toastNotifications.add({
- title: 'Your document was saved',
- text: 'Only you have access to this document',
- color: 'success',
- iconType: 'check',
- 'data-test-subj': 'saveDocumentSuccess',
-});
-```
-
-Because the underlying components are React, you can use JSX to pass in React elements to the `text` prop. This gives you total flexibility over the content displayed within the toast.
-
-```js
-toastNotifications.add({
- title: 'Your document was saved',
- text: (
-
-
- Only you have access to this document. Edit permissions.
-
-
-
-
- ),
-});
-```
-
-## Use in functional tests
-
-Functional tests are commonly used to verify that a user action yielded a successful outcome. If you surface a toast to notify the user of this successful outcome, you can place a `data-test-subj` attribute on the toast and use it to check if the toast exists inside of your functional test. This acts as a proxy for verifying the successful outcome.
-
-```js
-toastNotifications.addSuccess({
- title: 'Your document was saved',
- 'data-test-subj': 'saveDocumentSuccess',
-});
-```
diff --git a/src/plugins/kibana_legacy/public/notify/toasts/index.ts b/src/plugins/kibana_legacy/public/notify/toasts/index.ts
deleted file mode 100644
index cdd7df04548fbb..00000000000000
--- a/src/plugins/kibana_legacy/public/notify/toasts/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-export { ToastNotifications } from './toast_notifications';
diff --git a/src/plugins/kibana_legacy/public/notify/toasts/toast_notifications.test.ts b/src/plugins/kibana_legacy/public/notify/toasts/toast_notifications.test.ts
deleted file mode 100644
index c2c5d9a4fc014a..00000000000000
--- a/src/plugins/kibana_legacy/public/notify/toasts/toast_notifications.test.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { notificationServiceMock } from '../../../../../core/public/mocks';
-import { ToastNotifications } from './toast_notifications';
-import { Toast } from 'kibana/public';
-import { BehaviorSubject } from 'rxjs';
-
-describe('ToastNotifications', () => {
- describe('interface', () => {
- function setup() {
- const toastsMock = notificationServiceMock.createStartContract().toasts;
- return { toastNotifications: new ToastNotifications(toastsMock), toastsMock };
- }
-
- describe('add method', () => {
- test('adds a toast', () => {
- const { toastNotifications, toastsMock } = setup();
- toastNotifications.add({});
- expect(toastsMock.add).toHaveBeenCalled();
- });
- });
-
- describe('remove method', () => {
- test('removes a toast', () => {
- const { toastNotifications, toastsMock } = setup();
- const fakeToast = {} as Toast;
- toastNotifications.remove(fakeToast);
- expect(toastsMock.remove).toHaveBeenCalledWith(fakeToast);
- });
- });
-
- describe('onChange method', () => {
- test('callback is called when observable changes', () => {
- const toastsMock = notificationServiceMock.createStartContract().toasts;
- const toasts$ = new BehaviorSubject([]);
- toastsMock.get$.mockReturnValue(toasts$);
- const toastNotifications = new ToastNotifications(toastsMock);
- const onChangeSpy = jest.fn();
- toastNotifications.onChange(onChangeSpy);
- toasts$.next([{ id: 'toast1' }]);
- toasts$.next([]);
- expect(onChangeSpy).toHaveBeenCalledTimes(2);
- });
- });
-
- describe('addSuccess method', () => {
- test('adds a success toast', () => {
- const { toastNotifications, toastsMock } = setup();
- toastNotifications.addSuccess({});
- expect(toastsMock.addSuccess).toHaveBeenCalled();
- });
- });
-
- describe('addWarning method', () => {
- test('adds a warning toast', () => {
- const { toastNotifications, toastsMock } = setup();
- toastNotifications.addWarning({});
- expect(toastsMock.addWarning).toHaveBeenCalled();
- });
- });
-
- describe('addDanger method', () => {
- test('adds a danger toast', () => {
- const { toastNotifications, toastsMock } = setup();
- toastNotifications.addWarning({});
- expect(toastsMock.addWarning).toHaveBeenCalled();
- });
- });
- });
-});
diff --git a/src/plugins/kibana_legacy/public/notify/toasts/toast_notifications.ts b/src/plugins/kibana_legacy/public/notify/toasts/toast_notifications.ts
deleted file mode 100644
index e7ccbbca07b734..00000000000000
--- a/src/plugins/kibana_legacy/public/notify/toasts/toast_notifications.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { NotificationsSetup, Toast, ToastInput, ErrorToastOptions } from 'kibana/public';
-
-export class ToastNotifications {
- public list: Toast[] = [];
-
- private onChangeCallback?: () => void;
-
- constructor(private readonly toasts: NotificationsSetup['toasts']) {
- toasts.get$().subscribe((list) => {
- this.list = list;
-
- if (this.onChangeCallback) {
- this.onChangeCallback();
- }
- });
- }
-
- public onChange = (callback: () => void) => {
- this.onChangeCallback = callback;
- };
-
- public add = (toastOrTitle: ToastInput) => this.toasts.add(toastOrTitle);
- public remove = (toast: Toast) => this.toasts.remove(toast);
- public addSuccess = (toastOrTitle: ToastInput) => this.toasts.addSuccess(toastOrTitle);
- public addWarning = (toastOrTitle: ToastInput) => this.toasts.addWarning(toastOrTitle);
- public addDanger = (toastOrTitle: ToastInput) => this.toasts.addDanger(toastOrTitle);
- public addError = (error: Error, options: ErrorToastOptions) =>
- this.toasts.addError(error, options);
-}
diff --git a/src/plugins/kibana_legacy/public/plugin.ts b/src/plugins/kibana_legacy/public/plugin.ts
index 337fdb80da7e45..f60130d367b584 100644
--- a/src/plugins/kibana_legacy/public/plugin.ts
+++ b/src/plugins/kibana_legacy/public/plugin.ts
@@ -33,6 +33,14 @@ export class KibanaLegacyPlugin {
loadFontAwesome: async () => {
await import('./font_awesome');
},
+ /**
+ * Loads angular bootstrap modules. Should be removed once the last consumer has migrated to EUI
+ * @deprecated
+ */
+ loadAngularBootstrap: async () => {
+ const { initAngularBootstrap } = await import('./angular_bootstrap');
+ initAngularBootstrap();
+ },
/**
* @deprecated
* Just exported for wiring up with dashboard mode, should not be used.
diff --git a/src/plugins/kibana_legacy/public/utils/index.ts b/src/plugins/kibana_legacy/public/utils/index.ts
index db3c0af6c8cb94..94233558b4627c 100644
--- a/src/plugins/kibana_legacy/public/utils/index.ts
+++ b/src/plugins/kibana_legacy/public/utils/index.ts
@@ -6,7 +6,6 @@
* Side Public License, v 1.
*/
-export * from './system_api';
// @ts-ignore
export { KbnAccessibleClickProvider } from './kbn_accessible_click';
// @ts-ignore
diff --git a/src/plugins/kibana_legacy/public/utils/system_api.ts b/src/plugins/kibana_legacy/public/utils/system_api.ts
deleted file mode 100644
index d0fe221935ba51..00000000000000
--- a/src/plugins/kibana_legacy/public/utils/system_api.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { IRequestConfig } from 'angular';
-
-const SYSTEM_REQUEST_HEADER_NAME = 'kbn-system-request';
-const LEGACY_SYSTEM_API_HEADER_NAME = 'kbn-system-api';
-
-/**
- * Adds a custom header designating request as system API
- * @param originalHeaders Object representing set of headers
- * @return Object representing set of headers, with system API header added in
- */
-export function addSystemApiHeader(originalHeaders: Record) {
- const systemApiHeaders = {
- [SYSTEM_REQUEST_HEADER_NAME]: true,
- };
- return {
- ...originalHeaders,
- ...systemApiHeaders,
- };
-}
-
-/**
- * Returns true if request is a system API request; false otherwise
- *
- * @param request Object Request object created by $http service
- * @return true if request is a system API request; false otherwise
- */
-export function isSystemApiRequest(request: IRequestConfig) {
- const { headers } = request;
- return (
- headers && (!!headers[SYSTEM_REQUEST_HEADER_NAME] || !!headers[LEGACY_SYSTEM_API_HEADER_NAME])
- );
-}
diff --git a/src/plugins/timelion/public/plugin.ts b/src/plugins/timelion/public/plugin.ts
index 6f8dbfdcc67041..63ea9a38e2795d 100644
--- a/src/plugins/timelion/public/plugin.ts
+++ b/src/plugins/timelion/public/plugin.ts
@@ -19,7 +19,7 @@ import {
AppNavLinkStatus,
} from '../../../core/public';
import { Panel } from './panels/panel';
-import { initAngularBootstrap } from '../../kibana_legacy/public';
+import { KibanaLegacyStart } from '../../kibana_legacy/public';
import { createKbnUrlTracker } from '../../kibana_utils/public';
import { DataPublicPluginStart, esFilters, DataPublicPluginSetup } from '../../data/public';
import { NavigationPublicPluginStart } from '../../navigation/public';
@@ -41,6 +41,7 @@ export interface TimelionPluginStartDependencies {
visualizations: VisualizationsStart;
visTypeTimelion: VisTypeTimelionPluginStart;
savedObjects: SavedObjectsStart;
+ kibanaLegacy: KibanaLegacyStart;
}
/** @internal */
@@ -91,7 +92,6 @@ export class TimelionPlugin
stopUrlTracker();
};
- initAngularBootstrap();
core.application.register({
id: 'timelion',
title: 'Timelion',
@@ -103,6 +103,7 @@ export class TimelionPlugin
visTypeTimelion.isUiEnabled === false ? AppNavLinkStatus.hidden : AppNavLinkStatus.default,
mount: async (params: AppMountParameters) => {
const [coreStart, pluginsStart] = await core.getStartServices();
+ await pluginsStart.kibanaLegacy.loadAngularBootstrap();
this.currentHistory = params.history;
appMounted();
diff --git a/src/plugins/vis_type_table/public/legacy/agg_table/agg_table.test.js b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table.test.js
index 65e26ddf6e03fd..cbc3db6585a7da 100644
--- a/src/plugins/vis_type_table/public/legacy/agg_table/agg_table.test.js
+++ b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table.test.js
@@ -15,7 +15,7 @@ import { round } from 'lodash';
import { getFieldFormatsRegistry } from '../../../../data/public/test_utils';
import { coreMock } from '../../../../../core/public/mocks';
-import { initAngularBootstrap } from '../../../../kibana_legacy/public';
+import { initAngularBootstrap } from '../../../../kibana_legacy/public/angular_bootstrap';
import { setUiSettings } from '../../../../data/public/services';
import { UI_SETTINGS } from '../../../../data/public/';
import { CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING } from '../../../../share/public';
@@ -60,10 +60,12 @@ describe('Table Vis - AggTable Directive', function () {
initTableVisLegacyModule(tableVisModule);
};
+ beforeAll(async () => {
+ await initAngularBootstrap();
+ });
beforeEach(() => {
setUiSettings(core.uiSettings);
setFormatService(getFieldFormatsRegistry(core));
- initAngularBootstrap();
initLocalAngular();
angular.mock.module('kibana/table_vis');
angular.mock.inject(($injector, config) => {
diff --git a/src/plugins/vis_type_table/public/legacy/agg_table/agg_table_group.test.js b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table_group.test.js
index 1c6630e30e5f73..ba04b2f449f6dd 100644
--- a/src/plugins/vis_type_table/public/legacy/agg_table/agg_table_group.test.js
+++ b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table_group.test.js
@@ -13,11 +13,11 @@ import expect from '@kbn/expect';
import { getFieldFormatsRegistry } from '../../../../data/public/test_utils';
import { coreMock } from '../../../../../core/public/mocks';
-import { initAngularBootstrap } from '../../../../kibana_legacy/public';
import { setUiSettings } from '../../../../data/public/services';
import { setFormatService } from '../../services';
import { getInnerAngular } from '../get_inner_angular';
import { initTableVisLegacyModule } from '../table_vis_legacy_module';
+import { initAngularBootstrap } from '../../../../kibana_legacy/public/angular_bootstrap';
import { tabifiedData } from './tabified_data';
const uiSettings = new Map();
@@ -40,10 +40,12 @@ describe('Table Vis - AggTableGroup Directive', function () {
initTableVisLegacyModule(tableVisModule);
};
+ beforeAll(async () => {
+ await initAngularBootstrap();
+ });
beforeEach(() => {
setUiSettings(core.uiSettings);
setFormatService(getFieldFormatsRegistry(core));
- initAngularBootstrap();
initLocalAngular();
angular.mock.module('kibana/table_vis');
angular.mock.inject(($injector) => {
diff --git a/src/plugins/vis_type_table/public/legacy/get_inner_angular.ts b/src/plugins/vis_type_table/public/legacy/get_inner_angular.ts
index 09fde318ee4dff..412dd904a5e872 100644
--- a/src/plugins/vis_type_table/public/legacy/get_inner_angular.ts
+++ b/src/plugins/vis_type_table/public/legacy/get_inner_angular.ts
@@ -16,7 +16,6 @@ import 'angular-recursion';
import { i18nDirective, i18nFilter, I18nProvider } from '@kbn/i18n/angular';
import { CoreStart, IUiSettingsClient, PluginInitializerContext } from 'kibana/public';
import {
- initAngularBootstrap,
PaginateDirectiveProvider,
PaginateControlsDirectiveProvider,
PrivateProvider,
@@ -24,8 +23,6 @@ import {
KbnAccessibleClickProvider,
} from '../../../kibana_legacy/public';
-initAngularBootstrap();
-
const thirdPartyAngularDependencies = ['ngSanitize', 'ui.bootstrap', 'RecursionHelper'];
export function getAngularModule(name: string, core: CoreStart, context: PluginInitializerContext) {
diff --git a/src/plugins/vis_type_table/public/legacy/paginated_table/paginated_table.test.ts b/src/plugins/vis_type_table/public/legacy/paginated_table/paginated_table.test.ts
index 77148803e7978b..3feff52f86792b 100644
--- a/src/plugins/vis_type_table/public/legacy/paginated_table/paginated_table.test.ts
+++ b/src/plugins/vis_type_table/public/legacy/paginated_table/paginated_table.test.ts
@@ -12,6 +12,7 @@ import $ from 'jquery';
import 'angular-sanitize';
import 'angular-mocks';
+import { initAngularBootstrap } from '../../../../kibana_legacy/public/angular_bootstrap';
import { getAngularModule } from '../get_inner_angular';
import { initTableVisLegacyModule } from '../table_vis_legacy_module';
import { coreMock } from '../../../../../core/public/mocks';
@@ -56,6 +57,10 @@ describe('Table Vis - Paginated table', () => {
const defaultPerPage = 10;
let paginatedTable: any;
+ beforeAll(async () => {
+ await initAngularBootstrap();
+ });
+
const initLocalAngular = () => {
const tableVisModule = getAngularModule(
'kibana/table_vis',
diff --git a/src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts b/src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts
index 36a9cc9cce77fe..f4a742ea16cb4f 100644
--- a/src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts
+++ b/src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts
@@ -13,6 +13,7 @@ import $ from 'jquery';
import { getAngularModule } from './get_inner_angular';
import { initTableVisLegacyModule } from './table_vis_legacy_module';
+import { initAngularBootstrap } from '../../../kibana_legacy/public/angular_bootstrap';
import { tableVisLegacyTypeDefinition } from './table_vis_legacy_type';
import { Vis } from '../../../visualizations/public';
import { stubFields } from '../../../data/public/stubs';
@@ -76,6 +77,9 @@ describe('Table Vis - Controller', () => {
initTableVisLegacyModule(tableVisModule);
};
+ beforeAll(async () => {
+ await initAngularBootstrap();
+ });
beforeEach(initLocalAngular);
beforeEach(angular.mock.module('kibana/table_vis'));
diff --git a/src/plugins/vis_type_table/public/legacy/vis_controller.ts b/src/plugins/vis_type_table/public/legacy/vis_controller.ts
index ee446c58c00139..ec198aa96f1f96 100644
--- a/src/plugins/vis_type_table/public/legacy/vis_controller.ts
+++ b/src/plugins/vis_type_table/public/legacy/vis_controller.ts
@@ -56,6 +56,7 @@ export function getTableVisualizationControllerClass(
async initLocalAngular() {
if (!this.tableVisModule) {
const [coreStart, { kibanaLegacy }] = await core.getStartServices();
+ await kibanaLegacy.loadAngularBootstrap();
this.tableVisModule = getAngularModule(innerAngularName, coreStart, context);
initTableVisLegacyModule(this.tableVisModule);
kibanaLegacy.loadFontAwesome();
diff --git a/x-pack/plugins/graph/public/plugin.ts b/x-pack/plugins/graph/public/plugin.ts
index 4525b42b3feb45..ec19e639b91c96 100644
--- a/x-pack/plugins/graph/public/plugin.ts
+++ b/x-pack/plugins/graph/public/plugin.ts
@@ -19,10 +19,7 @@ import {
} from '../../../../src/core/public';
import { Storage } from '../../../../src/plugins/kibana_utils/public';
-import {
- initAngularBootstrap,
- KibanaLegacyStart,
-} from '../../../../src/plugins/kibana_legacy/public';
+import { KibanaLegacyStart } from '../../../../src/plugins/kibana_legacy/public';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../src/plugins/navigation/public';
import { DataPublicPluginStart } from '../../../../src/plugins/data/public';
@@ -77,7 +74,6 @@ export class GraphPlugin
const config = this.initializerContext.config.get();
- initAngularBootstrap();
core.application.register({
id: 'graph',
title: 'Graph',
@@ -88,6 +84,7 @@ export class GraphPlugin
updater$: this.appUpdater$,
mount: async (params: AppMountParameters) => {
const [coreStart, pluginsStart] = await core.getStartServices();
+ await pluginsStart.kibanaLegacy.loadAngularBootstrap();
coreStart.chrome.docTitle.change(
i18n.translate('xpack.graph.pageTitle', { defaultMessage: 'Graph' })
);
diff --git a/x-pack/plugins/monitoring/public/plugin.ts b/x-pack/plugins/monitoring/public/plugin.ts
index a5b7d4906b5869..9f84165a27ba9f 100644
--- a/x-pack/plugins/monitoring/public/plugin.ts
+++ b/x-pack/plugins/monitoring/public/plugin.ts
@@ -93,7 +93,10 @@ export class MonitoringPlugin
category: DEFAULT_APP_CATEGORIES.management,
mount: async (params: AppMountParameters) => {
const [coreStart, pluginsStart] = await core.getStartServices();
- const { AngularApp } = await import('./angular');
+ const [, { AngularApp }] = await Promise.all([
+ pluginsStart.kibanaLegacy.loadAngularBootstrap(),
+ import('./angular'),
+ ]);
const deps: MonitoringStartPluginDependencies = {
navigation: pluginsStart.navigation,
kibanaLegacy: pluginsStart.kibanaLegacy,
From 87066e06b3cfe238b021f786896afdfd74b86303 Mon Sep 17 00:00:00 2001
From: Diana Derevyankina
<54894989+DziyanaDzeraviankina@users.noreply.github.com>
Date: Mon, 12 Jul 2021 17:25:52 +0300
Subject: [PATCH 05/12] [TSVB] Top_hit supports runtime fields (#103401)
* [TSVB] Refactor top-hit aggregation to work with fields instead of _source
* Allow select date strings for top_hit aggregation in table, metric, and markdown
* Fix agg_with handling for top_hit and add some tests
* Refactor get_agg_value and fix type check for _tsvb_chart
* Refactor top_hit.js
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../application/components/aggs/top_hit.js | 37 +++++--
.../components/lib/tick_formatter.js | 2 +-
.../lib/vis_data/helpers/bucket_transform.js | 2 +-
.../lib/vis_data/helpers/get_agg_value.js | 4 +-
.../vis_data/helpers/get_agg_value.test.js | 6 +-
test/functional/apps/visualize/_tsvb_chart.ts | 103 +++++++++++++++---
.../fixtures/kbn_archiver/visualize.json | 3 +-
.../page_objects/visual_builder_page.ts | 47 ++++++++
8 files changed, 168 insertions(+), 36 deletions(-)
diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/top_hit.js b/src/plugins/vis_type_timeseries/public/application/components/aggs/top_hit.js
index 546c09cdf34fd0..b9ef2d89135741 100644
--- a/src/plugins/vis_type_timeseries/public/application/components/aggs/top_hit.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/top_hit.js
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import React from 'react';
+import React, { useMemo, useEffect } from 'react';
import { AggRow } from './agg_row';
import { AggSelect } from './agg_select';
import { FieldSelect } from './field_select';
@@ -62,6 +62,7 @@ const getAggWithOptions = (field = {}, fieldTypesRestriction) => {
},
];
case KBN_FIELD_TYPES.STRING:
+ case KBN_FIELD_TYPES.DATE:
return [
{
label: i18n.translate('visTypeTimeseries.topHit.aggWithOptions.concatenate', {
@@ -91,16 +92,18 @@ const getOrderOptions = () => [
},
];
+const AGG_WITH_KEY = 'agg_with';
const ORDER_DATE_RESTRICT_FIELDS = [KBN_FIELD_TYPES.DATE];
+const getModelDefaults = () => ({
+ size: 1,
+ order: 'desc',
+ [AGG_WITH_KEY]: 'noop',
+});
+
const TopHitAggUi = (props) => {
const { fields, series, panel } = props;
- const defaults = {
- size: 1,
- agg_with: 'noop',
- order: 'desc',
- };
- const model = { ...defaults, ...props.model };
+ const model = useMemo(() => ({ ...getModelDefaults(), ...props.model }), [props.model]);
const indexPattern = series.override_index_pattern
? series.series_index_pattern
: panel.index_pattern;
@@ -110,7 +113,7 @@ const TopHitAggUi = (props) => {
PANEL_TYPES.METRIC,
PANEL_TYPES.MARKDOWN,
].includes(panel.type)
- ? [KBN_FIELD_TYPES.NUMBER, KBN_FIELD_TYPES.STRING]
+ ? [KBN_FIELD_TYPES.NUMBER, KBN_FIELD_TYPES.STRING, KBN_FIELD_TYPES.DATE]
: [KBN_FIELD_TYPES.NUMBER];
const handleChange = createChangeHandler(props.onChange, model);
@@ -124,13 +127,23 @@ const TopHitAggUi = (props) => {
const htmlId = htmlIdGenerator();
const selectedAggWithOption = aggWithOptions.find((option) => {
- return model.agg_with === option.value;
+ return model[AGG_WITH_KEY] === option.value;
});
const selectedOrderOption = orderOptions.find((option) => {
return model.order === option.value;
});
+ useEffect(() => {
+ const defaultFn = aggWithOptions?.[0]?.value;
+ const aggWith = model[AGG_WITH_KEY];
+ if (aggWith && defaultFn && aggWith !== defaultFn && !selectedAggWithOption) {
+ handleChange({
+ [AGG_WITH_KEY]: defaultFn,
+ });
+ }
+ }, [model, selectedAggWithOption, aggWithOptions, handleChange]);
+
return (
{
{
)}
options={aggWithOptions}
selectedOptions={selectedAggWithOption ? [selectedAggWithOption] : []}
- onChange={handleSelectChange('agg_with')}
+ onChange={handleSelectChange(AGG_WITH_KEY)}
singleSelection={{ asPlainText: true }}
+ data-test-subj="topHitAggregateWithComboBox"
/>
@@ -231,6 +245,7 @@ const TopHitAggUi = (props) => {
onChange={handleSelectChange('order_by')}
indexPattern={indexPattern}
fields={fields}
+ data-test-subj="topHitOrderByFieldSelect"
/>
diff --git a/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.js b/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.js
index c1d82a182e509b..9bccc13d192692 100644
--- a/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.js
+++ b/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.js
@@ -16,7 +16,7 @@ export const createTickFormatter = (format = '0,0.[00]', template, getConfig = n
const fieldFormats = getFieldFormats();
if (!template) template = '{{value}}';
- const render = handlebars.compile(template, { knownHelpersOnly: true });
+ const render = handlebars.compile(template, { noEscape: true, knownHelpersOnly: true });
let formatter;
if (isDuration(format)) {
diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/bucket_transform.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/bucket_transform.js
index 16e7b9d6072cba..13b890189325ce 100644
--- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/bucket_transform.js
+++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/bucket_transform.js
@@ -111,7 +111,7 @@ export const bucketTransform = {
docs: {
top_hits: {
size: bucket.size,
- _source: { includes: [bucket.field] },
+ fields: [bucket.field],
},
},
},
diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_agg_value.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_agg_value.js
index 32d17ef6d6cb73..90df3f26759599 100644
--- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_agg_value.js
+++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_agg_value.js
@@ -45,10 +45,10 @@ export const getAggValue = (row, metric) => {
}
const hits = get(row, [metric.id, 'docs', 'hits', 'hits'], []);
- const values = hits.map((doc) => get(doc, `_source.${metric.field}`));
+ const values = hits.map((doc) => doc.fields[metric.field]);
const aggWith = (metric.agg_with && aggFns[metric.agg_with]) || aggFns.noop;
- return aggWith(values);
+ return aggWith(values.flat());
case METRIC_TYPES.COUNT:
return get(row, 'doc_count', null);
default:
diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_agg_value.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_agg_value.test.js
index a23c57f5675633..ecbdd1563c3043 100644
--- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_agg_value.test.js
+++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_agg_value.test.js
@@ -67,11 +67,7 @@ describe('getAggValue', () => {
doc_count: 1,
docs: {
hits: {
- hits: [
- { _source: { example: { value: 25 } } },
- { _source: { example: { value: 25 } } },
- { _source: { example: { value: 25 } } },
- ],
+ hits: [{ fields: { 'example.value': [25, 25, 25] } }],
},
},
},
diff --git a/test/functional/apps/visualize/_tsvb_chart.ts b/test/functional/apps/visualize/_tsvb_chart.ts
index ca310493960f53..49b2ad8f9646a3 100644
--- a/test/functional/apps/visualize/_tsvb_chart.ts
+++ b/test/functional/apps/visualize/_tsvb_chart.ts
@@ -24,6 +24,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'timePicker',
'visChart',
'common',
+ 'settings',
]);
describe('visual builder', function describeIndexTests() {
@@ -44,14 +45,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
describe('metric', () => {
+ const { visualBuilder } = PageObjects;
+
beforeEach(async () => {
- await PageObjects.visualBuilder.resetPage();
- await PageObjects.visualBuilder.clickMetric();
- await PageObjects.visualBuilder.checkMetricTabIsPresent();
- await PageObjects.visualBuilder.clickPanelOptions('metric');
- await PageObjects.visualBuilder.setMetricsDataTimerangeMode('Last value');
- await PageObjects.visualBuilder.setDropLastBucket(true);
- await PageObjects.visualBuilder.clickDataTab('metric');
+ await visualBuilder.resetPage();
+ await visualBuilder.clickMetric();
+ await visualBuilder.checkMetricTabIsPresent();
+ await visualBuilder.clickPanelOptions('metric');
+ await visualBuilder.setMetricsDataTimerangeMode('Last value');
+ await visualBuilder.setDropLastBucket(true);
+ await visualBuilder.clickDataTab('metric');
});
it('should not have inspector enabled', async () => {
@@ -59,28 +62,98 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should show correct data', async () => {
- const value = await PageObjects.visualBuilder.getMetricValue();
+ const value = await visualBuilder.getMetricValue();
expect(value).to.eql('156');
});
it('should show correct data with Math Aggregation', async () => {
- await PageObjects.visualBuilder.createNewAgg();
- await PageObjects.visualBuilder.selectAggType('math', 1);
- await PageObjects.visualBuilder.fillInVariable();
- await PageObjects.visualBuilder.fillInExpression('params.test + 1');
- const value = await PageObjects.visualBuilder.getMetricValue();
+ await visualBuilder.createNewAgg();
+ await visualBuilder.selectAggType('math', 1);
+ await visualBuilder.fillInVariable();
+ await visualBuilder.fillInExpression('params.test + 1');
+ const value = await visualBuilder.getMetricValue();
expect(value).to.eql('157');
});
it('should populate fields for basic functions', async () => {
- const { visualBuilder } = PageObjects;
-
await visualBuilder.selectAggType('Average');
await visualBuilder.setFieldForAggregation('machine.ram');
const isFieldForAggregationValid = await visualBuilder.checkFieldForAggregationValidity();
expect(isFieldForAggregationValid).to.be(true);
});
+
+ it('should show correct data for Value Count with Entire time range mode', async () => {
+ await visualBuilder.selectAggType('Value Count');
+ await visualBuilder.setFieldForAggregation('machine.ram');
+
+ await visualBuilder.clickPanelOptions('metric');
+ await visualBuilder.setMetricsDataTimerangeMode('Entire time range');
+
+ const value = await visualBuilder.getMetricValue();
+ expect(value).to.eql('13,492');
+ });
+
+ it('should show same data for kibana and string index pattern modes', async () => {
+ await visualBuilder.selectAggType('Max');
+ await visualBuilder.setFieldForAggregation('machine.ram');
+ const kibanaIndexPatternModeValue = await visualBuilder.getMetricValue();
+
+ await visualBuilder.clickPanelOptions('metric');
+ await visualBuilder.switchIndexPatternSelectionMode(false);
+ const stringIndexPatternModeValue = await visualBuilder.getMetricValue();
+
+ expect(kibanaIndexPatternModeValue).to.eql(stringIndexPatternModeValue);
+ expect(kibanaIndexPatternModeValue).to.eql('32,212,254,720');
+ });
+
+ describe('Color rules', () => {
+ beforeEach(async () => {
+ await visualBuilder.selectAggType('Min');
+ await visualBuilder.setFieldForAggregation('machine.ram');
+
+ await visualBuilder.clickPanelOptions('metric');
+ await visualBuilder.setColorRuleOperator('>= greater than or equal');
+ await visualBuilder.setColorRuleValue(0);
+ });
+
+ it('should apply color rules to visualization background', async () => {
+ await visualBuilder.setColorPickerValue('#FFCFDF');
+
+ const backGroundStyle = await visualBuilder.getBackgroundStyle();
+ expect(backGroundStyle).to.eql('background-color: rgb(255, 207, 223);');
+ });
+
+ it('should apply color rules to metric value', async () => {
+ await visualBuilder.setColorPickerValue('#AD7DE6', 1);
+
+ const backGroundStyle = await visualBuilder.getMetricValueStyle();
+ expect(backGroundStyle).to.eql('color: rgb(173, 125, 230);');
+ });
+ });
+
+ describe('Top Hit aggregation', () => {
+ beforeEach(async () => {
+ await visualBuilder.selectAggType('Top Hit');
+ await visualBuilder.setTopHitOrderByField('@timestamp');
+ });
+
+ it('should show correct data for string type field', async () => {
+ await visualBuilder.setFieldForAggregation('machine.os.raw');
+ await visualBuilder.setTopHitAggregateWithOption('Concatenate');
+
+ const value = await visualBuilder.getMetricValue();
+ expect(value).to.eql('win 7');
+ });
+
+ it('should show correct data for runtime field', async () => {
+ await visualBuilder.setFieldForAggregation('hello_world_runtime_field');
+ await visualBuilder.setTopHitAggregateWithOption('Concatenate');
+
+ const value = await visualBuilder.getMetricValue();
+ expect(value).to.eql('hello world');
+ });
+ });
});
describe('gauge', () => {
diff --git a/test/functional/fixtures/kbn_archiver/visualize.json b/test/functional/fixtures/kbn_archiver/visualize.json
index 660da856964b44..225dc0592e87d5 100644
--- a/test/functional/fixtures/kbn_archiver/visualize.json
+++ b/test/functional/fixtures/kbn_archiver/visualize.json
@@ -3,6 +3,7 @@
"fieldAttrs": "{\"utc_time\":{\"customLabel\":\"UTC time\"}}",
"fieldFormatMap": "{\"bytes\":{\"id\":\"bytes\"}}",
"fields": "[{\"name\":\"referer\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"agent\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:image:width\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"xss.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"headings.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:description\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"meta.user.lastname\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.article:tag.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"geo.dest\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.twitter:image\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.article:section.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"utc_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.twitter:card\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"meta.char\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"clientip\",\"type\":\"ip\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:image:height\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"host\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"machine.ram\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"links\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"id\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"@tags.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"phpmemory\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.twitter:card.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"ip\",\"type\":\"ip\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:image\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.article:modified_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:site_name.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"request.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.article:tag\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"agent.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"spaces\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:site.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"headings\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"_source\",\"type\":\"_source\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"relatedContent.og:image.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"request\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"index.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"extension\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"memory\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"_index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"relatedContent.twitter:site\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:description\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"geo.coordinates\",\"type\":\"geo_point\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"meta.related\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:title.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:title.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"response.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"@message.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"machine.os\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.article:section\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"xss\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"links.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:title\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"geo.srcdest\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"extension.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"machine.os.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"@tags\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"host.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:type.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"geo.src\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"spaces.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:image:height.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:description.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:site_name\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:title\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"@message\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:image.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"@timestamp\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"bytes\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"response\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"meta.user.firstname\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:image:width.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:description.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.article:published_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"_type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false}]",
+ "runtimeFieldMap":"{\"hello_world_runtime_field\":{\"type\":\"keyword\",\"script\":{\"source\":\"emit('hello world')\"}}}",
"timeFieldName": "@timestamp",
"title": "logstash-*"
},
@@ -301,4 +302,4 @@
"references": [],
"type": "index-pattern",
"version": "WzE1LDFd"
-}
\ No newline at end of file
+}
diff --git a/test/functional/page_objects/visual_builder_page.ts b/test/functional/page_objects/visual_builder_page.ts
index 8e28ffab6c9c3d..fd89a88658b3a6 100644
--- a/test/functional/page_objects/visual_builder_page.ts
+++ b/test/functional/page_objects/visual_builder_page.ts
@@ -575,6 +575,42 @@ export class VisualBuilderPageObject extends FtrService {
await this.testSubjects.existOrFail('euiColorPickerPopover', { timeout: 5000 });
}
+ public async setColorPickerValue(colorHex: string, nth: number = 0): Promise {
+ const picker = await this.find.allByCssSelector('.tvbColorPicker button');
+ await picker[nth].clickMouseButton();
+ await this.checkColorPickerPopUpIsPresent();
+ await this.find.setValue('.euiColorPicker input', colorHex);
+ await this.visChart.waitForVisualizationRenderingStabilized();
+ }
+
+ public async setColorRuleOperator(condition: string): Promise {
+ await this.retry.try(async () => {
+ await this.comboBox.clearInputField('colorRuleOperator');
+ await this.comboBox.set('colorRuleOperator', condition);
+ });
+ }
+
+ public async setColorRuleValue(value: number): Promise {
+ await this.retry.try(async () => {
+ const colorRuleValueInput = await this.find.byCssSelector(
+ '[data-test-subj="colorRuleValue"]'
+ );
+ await colorRuleValueInput.type(value.toString());
+ });
+ }
+
+ public async getBackgroundStyle(): Promise {
+ await this.visChart.waitForVisualizationRenderingStabilized();
+ const visualization = await this.find.byClassName('tvbVis');
+ return await visualization.getAttribute('style');
+ }
+
+ public async getMetricValueStyle(): Promise {
+ await this.visChart.waitForVisualizationRenderingStabilized();
+ const metricValue = await this.find.byCssSelector('[data-test-subj="tsvbMetricValue"]');
+ return await metricValue.getAttribute('style');
+ }
+
public async changePanelPreview(nth: number = 0): Promise {
const prevRenderingCount = await this.visChart.getVisualizationRenderingCount();
const changePreviewBtnArray = await this.testSubjects.findAll('AddActivatePanelBtn');
@@ -680,4 +716,15 @@ export class VisualBuilderPageObject extends FtrService {
const dataTimeRangeMode = await this.testSubjects.find('dataTimeRangeMode');
return await this.comboBox.isOptionSelected(dataTimeRangeMode, value);
}
+
+ public async setTopHitAggregateWithOption(option: string): Promise {
+ await this.comboBox.set('topHitAggregateWithComboBox', option);
+ }
+
+ public async setTopHitOrderByField(timeField: string) {
+ await this.retry.try(async () => {
+ await this.comboBox.clearInputField('topHitOrderByFieldSelect');
+ await this.comboBox.set('topHitOrderByFieldSelect', timeField);
+ });
+ }
}
From a80791aa4ccc2902820591299ce8a89c364d2cd6 Mon Sep 17 00:00:00 2001
From: Jason Stoltzfus
Date: Mon, 12 Jul 2021 10:26:41 -0400
Subject: [PATCH 06/12] Pass locale to calendar (#105134)
---
.../components/analytics/components/analytics_filters.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_filters.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_filters.tsx
index 0c8455e986ae1d..dd99d368a0105d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_filters.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_filters.tsx
@@ -80,6 +80,7 @@ export const AnalyticsFilters: React.FC = () => {
'xpack.enterpriseSearch.appSearch.engine.analytics.filters.startDateAriaLabel',
{ defaultMessage: 'Filter by start date' }
)}
+ locale={i18n.getLocale()}
/>
}
endDateControl={
@@ -93,6 +94,7 @@ export const AnalyticsFilters: React.FC = () => {
'xpack.enterpriseSearch.appSearch.engine.analytics.filters.endDateAriaLabel',
{ defaultMessage: 'Filter by end date' }
)}
+ locale={i18n.getLocale()}
/>
}
fullWidth
From d6a36926008b000d006d012edafed5cad6a7f3f6 Mon Sep 17 00:00:00 2001
From: Kaarina Tungseth
Date: Mon, 12 Jul 2021 09:58:39 -0500
Subject: [PATCH 07/12] [DOCS] Adds how to create dashboard drilldowns for Top
N and Table TSVB panels (#104548)
---
docs/user/dashboard/tsvb.asciidoc | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/docs/user/dashboard/tsvb.asciidoc b/docs/user/dashboard/tsvb.asciidoc
index 89da3f7285924e..11fe71b7639bb5 100644
--- a/docs/user/dashboard/tsvb.asciidoc
+++ b/docs/user/dashboard/tsvb.asciidoc
@@ -148,6 +148,27 @@ The *Markdown* visualization supports Markdown with Handlebar (mustache) syntax
For answers to frequently asked *TSVB* question, review the following.
+[float]
+===== How do I create dashboard drilldowns for Top N and Table visualizations?
+
+You can create dashboard drilldowns that include the specified time range for *Top N* and *Table* visualizations.
+
+. Open the dashboard that you want to link to, then copy the URL.
+
+. Open the dashboard with the *Top N* and *Table* visualization panel, then click *Edit* in the toolbar.
+
+. Open the *Top N* or *Table* panel menu, then select *Edit visualization*.
+
+. Click *Panel options*.
+
+. In the *Item URL* field, enter the URL.
++
+For example `dashboards#/view/f193ca90-c9f4-11eb-b038-dd3270053a27`.
+
+. Click *Save and return*.
+
+. In the toolbar, cick *Save as*, then make sure *Store time with dashboard* is deselected.
+
[float]
===== Why is my TSVB visualization missing data?
From 1aa9459ba2d8c4e736fdae5c0f4f4a59f09c7973 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ece=20=C3=96zalp?=
Date: Mon, 12 Jul 2021 11:07:34 -0400
Subject: [PATCH 08/12] [CTI] converts disabled panel danger to warning
(#104989)
---
.../overview_cti_links/cti_disabled_module.tsx | 4 ++--
.../overview_cti_links/cti_inner_panel.tsx | 12 ++++--------
2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_disabled_module.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_disabled_module.tsx
index 21a4beca72f3b2..1600356882c36b 100644
--- a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_disabled_module.tsx
+++ b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_disabled_module.tsx
@@ -21,11 +21,11 @@ export const CtiDisabledModuleComponent = () => {
const danger = useMemo(
() => (
+
{i18n.DANGER_BUTTON}
}
diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_inner_panel.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_inner_panel.tsx
index 08bf0a432f9bb8..ddff78608dfb02 100644
--- a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_inner_panel.tsx
+++ b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_inner_panel.tsx
@@ -17,13 +17,9 @@ const ButtonContainer = styled(EuiFlexGroup)`
padding: ${({ theme }) => theme.eui.paddingSizes.s};
`;
-const Title = styled(EuiText)<{ textcolor: 'primary' | 'warning' | 'danger' }>`
+const Title = styled(EuiText)<{ textcolor: 'primary' | 'warning' }>`
color: ${({ theme, textcolor }) =>
- textcolor === 'primary'
- ? theme.eui.euiColorPrimary
- : textcolor === 'warning'
- ? theme.eui.euiColorWarningText
- : theme.eui.euiColorDangerText};
+ textcolor === 'primary' ? theme.eui.euiColorPrimary : theme.eui.euiColorWarningText};
margin-bottom: ${({ theme }) => theme.eui.paddingSizes.m};
`;
@@ -40,12 +36,12 @@ export const CtiInnerPanel = ({
body,
button,
}: {
- color: 'primary' | 'warning' | 'danger';
+ color: 'primary' | 'warning';
title: string;
body: string;
button?: JSX.Element;
}) => {
- const iconType = color === 'primary' ? 'iInCircle' : color === 'warning' ? 'help' : 'alert';
+ const iconType = color === 'primary' ? 'iInCircle' : 'help';
return (
From 0c9777c6020501b6c953b4bca97f41dd858549f1 Mon Sep 17 00:00:00 2001
From: Justin Kambic
Date: Mon, 12 Jul 2021 11:23:57 -0400
Subject: [PATCH 09/12] [Uptime] Refactor page headers to avoid invalid markup
(#104215)
* Refactor monitor and waterfall page headers to avoid rendering invalid markup.
* Update tests.
* Translate page titles.
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../components/monitor/monitor_title.test.tsx | 37 ++++++++++-------
.../components/monitor/monitor_title.tsx | 41 +++++++++----------
.../step_detail/step_detail_container.tsx | 9 ++--
.../step_detail/step_page_title.tsx | 13 ++----
x-pack/plugins/uptime/public/routes.tsx | 33 +++++++++++----
.../uptime/server/lib/requests/get_certs.ts | 1 -
6 files changed, 77 insertions(+), 57 deletions(-)
diff --git a/x-pack/plugins/uptime/public/components/monitor/monitor_title.test.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_title.test.tsx
index 4fd6335c3d3ca9..726ad235f7f49e 100644
--- a/x-pack/plugins/uptime/public/components/monitor/monitor_title.test.tsx
+++ b/x-pack/plugins/uptime/public/components/monitor/monitor_title.test.tsx
@@ -11,7 +11,7 @@ import { screen } from '@testing-library/react';
import { render } from '../../lib/helper/rtl_helpers';
import * as reactRouterDom from 'react-router-dom';
import { Ping } from '../../../common/runtime_types';
-import { MonitorPageTitle } from './monitor_title';
+import { MonitorPageTitle, MonitorPageTitleContent } from './monitor_title';
jest.mock('react-router-dom', () => {
const originalModule = jest.requireActual('react-router-dom');
@@ -77,11 +77,17 @@ describe('MonitorTitle component', () => {
});
it('renders the monitor heading and EnableMonitorAlert toggle', () => {
- render(, {
- state: { monitorStatus: { status: monitorStatusWithName, loading: false } },
- });
- expect(screen.getByRole('heading', { level: 1, name: monitorName })).toBeInTheDocument();
- expect(screen.getByTestId('uptimeDisplayDefineConnector')).toBeInTheDocument();
+ render(
+ <>
+
+
+ >,
+ {
+ state: { monitorStatus: { status: monitorStatusWithName, loading: false } },
+ }
+ );
+ expect(screen.getByText(monitorName));
+ expect(screen.getByRole('switch')).toBeInTheDocument();
});
it('renders the user provided monitorId when the name is not present', () => {
@@ -89,21 +95,24 @@ describe('MonitorTitle component', () => {
render(, {
state: { monitorStatus: { status: defaultMonitorStatus, loading: false } },
});
- expect(screen.getByRole('heading', { level: 1, name: defaultMonitorId })).toBeInTheDocument();
+ expect(screen.getByText(defaultMonitorId));
});
it('renders the url when the monitorId is auto generated and the monitor name is not present', () => {
mockReactRouterDomHooks({ useParamsResponse: { monitorId: autoGeneratedMonitorIdEncoded } });
- render(, {
- state: { monitorStatus: { status: defaultMonitorStatus, loading: false } },
- });
- expect(
- screen.getByRole('heading', { level: 1, name: defaultMonitorStatus.url?.full })
- ).toBeInTheDocument();
+ render(
+
+
+
,
+ {
+ state: { monitorStatus: { status: defaultMonitorStatus, loading: false } },
+ }
+ );
+ expect(screen.getByText(defaultMonitorStatus!.url!.full!));
});
it('renders beta disclaimer for synthetics monitors', () => {
- render(, {
+ render(, {
state: { monitorStatus: { status: defaultBrowserMonitorStatus, loading: false } },
});
const betaLink = screen.getByRole('link', {
diff --git a/x-pack/plugins/uptime/public/components/monitor/monitor_title.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_title.tsx
index 2112af06536695..aa68e2aa7fc4bc 100644
--- a/x-pack/plugins/uptime/public/components/monitor/monitor_title.tsx
+++ b/x-pack/plugins/uptime/public/components/monitor/monitor_title.tsx
@@ -5,15 +5,7 @@
* 2.0.
*/
-import {
- EuiBadge,
- EuiFlexGroup,
- EuiFlexItem,
- EuiSpacer,
- EuiTitle,
- EuiLink,
- EuiText,
-} from '@elastic/eui';
+import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiLink, EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import { useSelector } from 'react-redux';
@@ -40,18 +32,11 @@ const getPageTitle = (monitorId: string, selectedMonitor: Ping | null) => {
return monitorId;
};
-export const MonitorPageTitle: React.FC = () => {
+export const MonitorPageTitleContent: React.FC = () => {
const monitorId = useMonitorId();
-
const selectedMonitor = useSelector(monitorStatusSelector);
-
- const nameOrId = selectedMonitor?.monitor?.name || getPageTitle(monitorId, selectedMonitor);
-
const type = selectedMonitor?.monitor?.type;
const isBrowser = type === 'browser';
-
- useBreadcrumbs([{ text: nameOrId }]);
-
const renderMonitorType = (monitorType: string) => {
switch (monitorType) {
case 'http':
@@ -86,12 +71,13 @@ export const MonitorPageTitle: React.FC = () => {
return '';
}
};
-
return (
<>
-
- {nameOrId}
-
+
+
+
+
+
@@ -118,7 +104,18 @@ export const MonitorPageTitle: React.FC = () => {
)}
-
>
);
};
+
+export const MonitorPageTitle: React.FC = () => {
+ const monitorId = useMonitorId();
+
+ const selectedMonitor = useSelector(monitorStatusSelector);
+
+ const nameOrId = selectedMonitor?.monitor?.name || getPageTitle(monitorId, selectedMonitor);
+
+ useBreadcrumbs([{ text: nameOrId }]);
+
+ return {nameOrId};
+};
diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/step_detail_container.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/step_detail_container.tsx
index 610107f406306a..c24ecd91838659 100644
--- a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/step_detail_container.tsx
+++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_detail/step_detail_container.tsx
@@ -16,7 +16,7 @@ import { useUiSetting$ } from '../../../../../../../../src/plugins/kibana_react/
import { useMonitorBreadcrumb } from './use_monitor_breadcrumb';
import { ClientPluginsStart } from '../../../../apps/plugin';
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
-import { StepPageTitle } from './step_page_title';
+import { StepPageTitleContent } from './step_page_title';
import { StepPageNavigation } from './step_page_nav';
import { WaterfallChartContainer } from './waterfall/waterfall_chart_container';
@@ -78,10 +78,11 @@ export const StepDetailContainer: React.FC = ({ checkGroup, stepIndex })
return (
void;
handleNextStep: () => void;
}
-export const StepPageTitle = ({
- stepName,
+
+export const StepPageTitleContent = ({
stepIndex,
totalSteps,
handleNextStep,
@@ -29,11 +29,6 @@ export const StepPageTitle = ({
}: Props) => {
return (
-
-
- {stepName}
-
-
diff --git a/x-pack/plugins/uptime/public/routes.tsx b/x-pack/plugins/uptime/public/routes.tsx
index e3c558cee2c320..2b0cc4dc5e5c2b 100644
--- a/x-pack/plugins/uptime/public/routes.tsx
+++ b/x-pack/plugins/uptime/public/routes.tsx
@@ -23,7 +23,7 @@ import { UptimePage, useUptimeTelemetry } from './hooks';
import { OverviewPageComponent } from './pages/overview';
import { SyntheticsCheckSteps } from './pages/synthetics/synthetics_checks';
import { ClientPluginsStart } from './apps/plugin';
-import { MonitorPageTitle } from './components/monitor/monitor_title';
+import { MonitorPageTitle, MonitorPageTitleContent } from './components/monitor/monitor_title';
import { UptimeDatePicker } from './components/common/uptime_date_picker';
import { useKibana } from '../../../../src/plugins/kibana_react/public';
import { CertRefreshBtn } from './components/certificates/cert_refresh_btn';
@@ -36,10 +36,16 @@ interface RouteProps {
dataTestSubj: string;
title: string;
telemetryId: UptimePage;
- pageHeader?: { pageTitle: string | JSX.Element; rightSideItems?: JSX.Element[] };
+ pageHeader?: {
+ children?: JSX.Element;
+ pageTitle: string | JSX.Element;
+ rightSideItems?: JSX.Element[];
+ };
}
-const baseTitle = 'Uptime - Kibana';
+const baseTitle = i18n.translate('xpack.uptime.routes.baseTitle', {
+ defaultMessage: 'Uptime - Kibana',
+});
export const MONITORING_OVERVIEW_LABEL = i18n.translate('xpack.uptime.overview.heading', {
defaultMessage: 'Monitors',
@@ -47,18 +53,25 @@ export const MONITORING_OVERVIEW_LABEL = i18n.translate('xpack.uptime.overview.h
const Routes: RouteProps[] = [
{
- title: `Monitor | ${baseTitle}`,
+ title: i18n.translate('xpack.uptime.monitorRoute.title', {
+ defaultMessage: 'Monitor | {baseTitle}',
+ values: { baseTitle },
+ }),
path: MONITOR_ROUTE,
component: MonitorPage,
dataTestSubj: 'uptimeMonitorPage',
telemetryId: UptimePage.Monitor,
pageHeader: {
+ children: ,
pageTitle: ,
rightSideItems: [],
},
},
{
- title: `Settings | ${baseTitle}`,
+ title: i18n.translate('xpack.uptime.settingsRoute.title', {
+ defaultMessage: `Settings | {baseTitle}`,
+ values: { baseTitle },
+ }),
path: SETTINGS_ROUTE,
component: SettingsPage,
dataTestSubj: 'uptimeSettingsPage',
@@ -70,7 +83,10 @@ const Routes: RouteProps[] = [
},
},
{
- title: `Certificates | ${baseTitle}`,
+ title: i18n.translate('xpack.uptime.certificatesRoute.title', {
+ defaultMessage: `Certificates | {baseTitle}`,
+ values: { baseTitle },
+ }),
path: CERTIFICATES_ROUTE,
component: CertificatesPage,
dataTestSubj: 'uptimeCertificatesPage',
@@ -81,7 +97,10 @@ const Routes: RouteProps[] = [
},
},
{
- title: baseTitle,
+ title: i18n.translate('xpack.uptime.stepDetailRoute.title', {
+ defaultMessage: 'Synthetics detail | {baseTitle}',
+ values: { baseTitle },
+ }),
path: STEP_DETAIL_ROUTE,
component: StepDetailPage,
dataTestSubj: 'uptimeStepDetailPage',
diff --git a/x-pack/plugins/uptime/server/lib/requests/get_certs.ts b/x-pack/plugins/uptime/server/lib/requests/get_certs.ts
index 1b20ed9085fefc..7639484f517374 100644
--- a/x-pack/plugins/uptime/server/lib/requests/get_certs.ts
+++ b/x-pack/plugins/uptime/server/lib/requests/get_certs.ts
@@ -138,7 +138,6 @@ export const getCerts: UMElasticsearchQueryFn = asyn
searchBody.query.bool.filter.push(validityFilters);
}
- // console.log(JSON.stringify(params, null, 2));
const { body: result } = await uptimeEsClient.search({
body: searchBody,
});
From 3e5ed774700336657f25e8f0aef10e3bf17a93a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?=
Date: Mon, 12 Jul 2021 18:55:06 +0300
Subject: [PATCH 10/12] [Osquery] Fix 7.14 live query history view (#105211)
---
.../action_results/action_results_summary.tsx | 22 +------
.../osquery/public/actions/actions_table.tsx | 19 ++++++
.../public/agents/agent_id_to_name.tsx | 37 ++++++++++++
.../osquery/public/agents/agents_table.tsx | 24 ++++++--
.../public/agents/use_agent_details.ts | 36 +++++++++++
.../osquery/public/agents/use_all_agents.ts | 2 +-
.../public/live_queries/form/index.tsx | 2 +-
.../public/routes/live_queries/new/index.tsx | 10 +++-
.../routes/saved_queries/list/index.tsx | 60 ++++++++++---------
.../saved_queries/saved_queries_dropdown.tsx | 41 +++++++++----
.../scheduled_query_group_queries_table.tsx | 2 +-
.../actions/all/query.all_actions.dsl.ts | 23 +++++--
12 files changed, 207 insertions(+), 71 deletions(-)
create mode 100644 x-pack/plugins/osquery/public/agents/agent_id_to_name.tsx
create mode 100644 x-pack/plugins/osquery/public/agents/use_agent_details.ts
diff --git a/x-pack/plugins/osquery/public/action_results/action_results_summary.tsx b/x-pack/plugins/osquery/public/action_results/action_results_summary.tsx
index d3b0e38a5e033b..bf4c97d63d74ca 100644
--- a/x-pack/plugins/osquery/public/action_results/action_results_summary.tsx
+++ b/x-pack/plugins/osquery/public/action_results/action_results_summary.tsx
@@ -8,15 +8,13 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { i18n } from '@kbn/i18n';
-import { EuiLink, EuiInMemoryTable, EuiCodeBlock } from '@elastic/eui';
+import { EuiInMemoryTable, EuiCodeBlock } from '@elastic/eui';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
-import { PLUGIN_ID } from '../../../fleet/common';
-import { pagePathGetters } from '../../../fleet/public';
+import { AgentIdToName } from '../agents/agent_id_to_name';
import { useActionResults } from './use_action_results';
import { useAllResults } from '../results/use_all_results';
import { Direction } from '../../common/search_strategy';
-import { useKibana } from '../common/lib/kibana';
interface ActionResultsSummaryProps {
actionId: string;
@@ -35,7 +33,6 @@ const ActionResultsSummaryComponent: React.FC = ({
expirationDate,
agentIds,
}) => {
- const getUrlForApp = useKibana().services.application.getUrlForApp;
// @ts-expect-error update types
const [pageIndex, setPageIndex] = useState(0);
// @ts-expect-error update types
@@ -70,20 +67,7 @@ const ActionResultsSummaryComponent: React.FC = ({
isLive,
});
- const renderAgentIdColumn = useCallback(
- (agentId) => (
-
- {agentId}
-
- ),
- [getUrlForApp]
- );
+ const renderAgentIdColumn = useCallback((agentId) => , []);
const renderRowsColumn = useCallback(
(_, item) => {
diff --git a/x-pack/plugins/osquery/public/actions/actions_table.tsx b/x-pack/plugins/osquery/public/actions/actions_table.tsx
index 0ee928ad8aa147..045c1f67b070da 100644
--- a/x-pack/plugins/osquery/public/actions/actions_table.tsx
+++ b/x-pack/plugins/osquery/public/actions/actions_table.tsx
@@ -9,6 +9,7 @@ import { isArray } from 'lodash';
import { i18n } from '@kbn/i18n';
import { EuiBasicTable, EuiButtonIcon, EuiCodeBlock, formatDate } from '@elastic/eui';
import React, { useState, useCallback, useMemo } from 'react';
+import { useHistory } from 'react-router-dom';
import { useAllActions } from './use_all_actions';
import { Direction } from '../../common/search_strategy';
@@ -27,6 +28,7 @@ const ActionTableResultsButton = React.memo(({ ac
ActionTableResultsButton.displayName = 'ActionTableResultsButton';
const ActionsTableComponent = () => {
+ const { push } = useHistory();
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(20);
@@ -67,6 +69,16 @@ const ActionsTableComponent = () => {
[]
);
+ const handlePlayClick = useCallback(
+ (item) =>
+ push('/live_queries/new', {
+ form: {
+ query: item._source?.data?.query,
+ },
+ }),
+ [push]
+ );
+
const columns = useMemo(
() => [
{
@@ -106,6 +118,11 @@ const ActionsTableComponent = () => {
defaultMessage: 'View details',
}),
actions: [
+ {
+ type: 'icon',
+ icon: 'play',
+ onClick: handlePlayClick,
+ },
{
render: renderActionsColumn,
},
@@ -113,6 +130,7 @@ const ActionsTableComponent = () => {
},
],
[
+ handlePlayClick,
renderActionsColumn,
renderAgentsColumn,
renderCreatedByColumn,
@@ -135,6 +153,7 @@ const ActionsTableComponent = () => {
= ({ agentId }) => {
+ const getUrlForApp = useKibana().services.application.getUrlForApp;
+ const { data } = useAgentDetails({ agentId });
+
+ return (
+
+ {data?.item.local_metadata.host.name ?? agentId}
+
+ );
+};
+
+export const AgentIdToName = React.memo(AgentIdToNameComponent);
diff --git a/x-pack/plugins/osquery/public/agents/agents_table.tsx b/x-pack/plugins/osquery/public/agents/agents_table.tsx
index 7e8f49c051614d..53e2ce1d534204 100644
--- a/x-pack/plugins/osquery/public/agents/agents_table.tsx
+++ b/x-pack/plugins/osquery/public/agents/agents_table.tsx
@@ -21,7 +21,12 @@ import {
generateAgentSelection,
} from './helpers';
-import { SELECT_AGENT_LABEL, generateSelectedAgentsMessage } from './translations';
+import {
+ SELECT_AGENT_LABEL,
+ generateSelectedAgentsMessage,
+ ALL_AGENTS_LABEL,
+ AGENT_POLICY_LABEL,
+} from './translations';
import {
AGENT_GROUP_KEY,
@@ -72,8 +77,17 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh
useEffect(() => {
if (agentSelection && !defaultValueInitialized.current && options.length) {
- if (agentSelection.policiesSelected) {
- const policyOptions = find(['label', 'Policy'], options);
+ if (agentSelection.allAgentsSelected) {
+ const allAgentsOptions = find(['label', ALL_AGENTS_LABEL], options);
+
+ if (allAgentsOptions?.options) {
+ setSelectedOptions(allAgentsOptions.options);
+ defaultValueInitialized.current = true;
+ }
+ }
+
+ if (agentSelection.policiesSelected.length) {
+ const policyOptions = find(['label', AGENT_POLICY_LABEL], options);
if (policyOptions) {
const defaultOptions = policyOptions.options?.filter((option) =>
@@ -82,12 +96,12 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh
if (defaultOptions?.length) {
setSelectedOptions(defaultOptions);
+ defaultValueInitialized.current = true;
}
- defaultValueInitialized.current = true;
}
}
}
- }, [agentSelection, options]);
+ }, [agentSelection, options, selectedOptions]);
useEffect(() => {
// update the groups when groups or agents have changed
diff --git a/x-pack/plugins/osquery/public/agents/use_agent_details.ts b/x-pack/plugins/osquery/public/agents/use_agent_details.ts
new file mode 100644
index 00000000000000..1a0663812dec36
--- /dev/null
+++ b/x-pack/plugins/osquery/public/agents/use_agent_details.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { i18n } from '@kbn/i18n';
+import { useQuery } from 'react-query';
+
+import { GetOneAgentResponse, agentRouteService } from '../../../fleet/common';
+import { useErrorToast } from '../common/hooks/use_error_toast';
+import { useKibana } from '../common/lib/kibana';
+
+interface UseAgentDetails {
+ agentId: string;
+}
+
+export const useAgentDetails = ({ agentId }: UseAgentDetails) => {
+ const { http } = useKibana().services;
+ const setErrorToast = useErrorToast();
+ return useQuery(
+ ['agentDetails', agentId],
+ () => http.get(agentRouteService.getInfoPath(agentId)),
+ {
+ enabled: agentId.length > 0,
+ onSuccess: () => setErrorToast(),
+ onError: (error) =>
+ setErrorToast(error as Error, {
+ title: i18n.translate('xpack.osquery.agentDetails.fetchError', {
+ defaultMessage: 'Error while fetching agent details',
+ }),
+ }),
+ }
+ );
+};
diff --git a/x-pack/plugins/osquery/public/agents/use_all_agents.ts b/x-pack/plugins/osquery/public/agents/use_all_agents.ts
index 30ba4d2f579079..cda15cc8054371 100644
--- a/x-pack/plugins/osquery/public/agents/use_all_agents.ts
+++ b/x-pack/plugins/osquery/public/agents/use_all_agents.ts
@@ -38,7 +38,7 @@ export const useAllAgents = (
let kuery = `last_checkin_status: online and (${policyFragment})`;
if (searchValue) {
- kuery += `and (local_metadata.host.hostname:*${searchValue}* or local_metadata.elastic.agent.id:*${searchValue}*)`;
+ kuery += ` and (local_metadata.host.hostname:*${searchValue}* or local_metadata.elastic.agent.id:*${searchValue}*)`;
}
return http.get(agentRouteService.getListPath(), {
diff --git a/x-pack/plugins/osquery/public/live_queries/form/index.tsx b/x-pack/plugins/osquery/public/live_queries/form/index.tsx
index 8654a74fecfb40..658280042696ef 100644
--- a/x-pack/plugins/osquery/public/live_queries/form/index.tsx
+++ b/x-pack/plugins/osquery/public/live_queries/form/index.tsx
@@ -110,7 +110,7 @@ const LiveQueryFormComponent: React.FC = ({
{
agentSelection: {
agents: [],
- allAgentsSelected: false,
+ allAgentsSelected: true,
platformsSelected: [],
policiesSelected: [],
},
diff --git a/x-pack/plugins/osquery/public/routes/live_queries/new/index.tsx b/x-pack/plugins/osquery/public/routes/live_queries/new/index.tsx
index 9967eb97cddf22..40614c1f3e1b8e 100644
--- a/x-pack/plugins/osquery/public/routes/live_queries/new/index.tsx
+++ b/x-pack/plugins/osquery/public/routes/live_queries/new/index.tsx
@@ -8,7 +8,7 @@
import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import React, { useMemo } from 'react';
-import { useLocation } from 'react-router-dom';
+import { useHistory, useLocation } from 'react-router-dom';
import qs from 'query-string';
import { WithHeaderLayout } from '../../../components/layouts';
@@ -19,12 +19,18 @@ import { BetaBadge, BetaBadgeRowWrapper } from '../../../components/beta_badge';
const NewLiveQueryPageComponent = () => {
useBreadcrumbs('live_query_new');
+ const { replace } = useHistory();
const location = useLocation();
const liveQueryListProps = useRouterNavigate('live_queries');
const formDefaultValue = useMemo(() => {
const queryParams = qs.parse(location.search);
+ if (location.state?.form.query) {
+ replace({ state: null });
+ return { query: location.state?.form.query };
+ }
+
if (queryParams?.agentPolicyId) {
return {
agentSelection: {
@@ -37,7 +43,7 @@ const NewLiveQueryPageComponent = () => {
}
return undefined;
- }, [location.search]);
+ }, [location.search, location.state, replace]);
const LeftColumn = useMemo(
() => (
diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/list/index.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/list/index.tsx
index 7e8e8e543dfabf..8738c06d065979 100644
--- a/x-pack/plugins/osquery/public/routes/saved_queries/list/index.tsx
+++ b/x-pack/plugins/osquery/public/routes/saved_queries/list/index.tsx
@@ -16,6 +16,7 @@ import {
import React, { useCallback, useMemo, useState } from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
+import { useHistory } from 'react-router-dom';
import { SavedObject } from 'kibana/public';
import { WithHeaderLayout } from '../../../components/layouts';
@@ -51,6 +52,7 @@ const EditButton = React.memo(EditButtonComponent);
const SavedQueriesPageComponent = () => {
useBreadcrumbs('saved_queries');
+ const { push } = useHistory();
const newQueryLinkProps = useRouterNavigate('saved_queries/new');
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(10);
@@ -59,21 +61,15 @@ const SavedQueriesPageComponent = () => {
const { data } = useSavedQueries({ isLive: true });
- // const handlePlayClick = useCallback(
- // (item) =>
- // push({
- // search: qs.stringify({
- // tab: 'live_query',
- // }),
- // state: {
- // query: {
- // id: item.id,
- // query: item.attributes.query,
- // },
- // },
- // }),
- // [push]
- // );
+ const handlePlayClick = useCallback(
+ (item) =>
+ push('/live_queries/new', {
+ form: {
+ savedQueryId: item.id,
+ },
+ }),
+ [push]
+ );
const renderEditAction = useCallback(
(item: SavedObject<{ name: string }>) => (
@@ -96,45 +92,53 @@ const SavedQueriesPageComponent = () => {
() => [
{
field: 'attributes.id',
- name: 'Query ID',
+ name: i18n.translate('xpack.osquery.savedQueries.table.queryIdColumnTitle', {
+ defaultMessage: 'Query ID',
+ }),
sortable: true,
truncateText: true,
},
{
field: 'attributes.description',
- name: 'Description',
+ name: i18n.translate('xpack.osquery.savedQueries.table.descriptionColumnTitle', {
+ defaultMessage: 'Description',
+ }),
sortable: true,
truncateText: true,
},
{
field: 'attributes.created_by',
- name: 'Created by',
+ name: i18n.translate('xpack.osquery.savedQueries.table.createdByColumnTitle', {
+ defaultMessage: 'Created by',
+ }),
sortable: true,
truncateText: true,
},
{
field: 'attributes.updated_at',
- name: 'Last updated at',
+ name: i18n.translate('xpack.osquery.savedQueries.table.updatedAtColumnTitle', {
+ defaultMessage: 'Last updated at',
+ }),
sortable: (item: SavedObject<{ updated_at: string }>) =>
item.attributes.updated_at ? Date.parse(item.attributes.updated_at) : 0,
truncateText: true,
render: renderUpdatedAt,
},
{
- name: 'Actions',
+ name: i18n.translate('xpack.osquery.savedQueries.table.actionsColumnTitle', {
+ defaultMessage: 'Actions',
+ }),
actions: [
- // {
- // name: 'Live query',
- // description: 'Run live query',
- // type: 'icon',
- // icon: 'play',
- // onClick: handlePlayClick,
- // },
+ {
+ type: 'icon',
+ icon: 'play',
+ onClick: handlePlayClick,
+ },
{ render: renderEditAction },
],
},
],
- [renderEditAction, renderUpdatedAt]
+ [handlePlayClick, renderEditAction, renderUpdatedAt]
);
const onTableChange = useCallback(({ page = {}, sort = {} }) => {
diff --git a/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx b/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx
index e30954a695b2d9..073b56bfd1d4c8 100644
--- a/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx
+++ b/x-pack/plugins/osquery/public/saved_queries/saved_queries_dropdown.tsx
@@ -7,10 +7,11 @@
import { find } from 'lodash/fp';
import { EuiCodeBlock, EuiFormRow, EuiComboBox, EuiText } from '@elastic/eui';
-import React, { useCallback, useState } from 'react';
+import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { SimpleSavedObject } from 'kibana/public';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
+import { useHistory, useLocation } from 'react-router-dom';
import { useSavedQueries } from './use_saved_queries';
@@ -29,19 +30,25 @@ const SavedQueriesDropdownComponent: React.FC = ({
disabled,
onChange,
}) => {
+ const { replace } = useHistory();
+ const location = useLocation();
const [selectedOptions, setSelectedOptions] = useState([]);
const { data } = useSavedQueries({});
- const queryOptions =
- data?.savedObjects?.map((savedQuery) => ({
- label: savedQuery.attributes.id ?? '',
- value: {
- id: savedQuery.attributes.id,
- description: savedQuery.attributes.description,
- query: savedQuery.attributes.query,
- },
- })) ?? [];
+ const queryOptions = useMemo(
+ () =>
+ data?.savedObjects?.map((savedQuery) => ({
+ label: savedQuery.attributes.id ?? '',
+ value: {
+ savedObjectId: savedQuery.id,
+ id: savedQuery.attributes.id,
+ description: savedQuery.attributes.description,
+ query: savedQuery.attributes.query,
+ },
+ })) ?? [],
+ [data?.savedObjects]
+ );
const handleSavedQueryChange = useCallback(
(newSelectedOptions) => {
@@ -73,6 +80,20 @@ const SavedQueriesDropdownComponent: React.FC = ({
[]
);
+ useEffect(() => {
+ const savedQueryId = location.state?.form?.savedQueryId;
+
+ if (savedQueryId) {
+ const savedQueryOption = find(['value.savedObjectId', savedQueryId], queryOptions);
+
+ if (savedQueryOption) {
+ handleSavedQueryChange([savedQueryOption]);
+ }
+
+ replace({ state: null });
+ }
+ }, [handleSavedQueryChange, replace, location.state, queryOptions]);
+
return (
Date: Mon, 12 Jul 2021 11:56:43 -0400
Subject: [PATCH 11/12] [Fleet] Fix enrollment flyout with fleet server from
policy page (#104542)
* [Fleet] Fix enrollment flyout with fleet server from policy page
* Fix tests
* Show enrollment instructions for add agent from fleet server policy
* Fix conditions to show fleet server setup in flyout
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../agent_enrollment_flyout.test.mocks.ts | 1 +
.../agent_enrollment_flyout.test.tsx | 6 ++-
.../agent_enrollment_flyout/index.tsx | 39 ++++++++++++--
.../managed_instructions.tsx | 54 ++++++++++++-------
.../agent_enrollment_flyout/steps.tsx | 22 ++------
.../agent_enrollment_flyout/types.ts | 8 ++-
x-pack/plugins/fleet/public/types/index.ts | 1 +
7 files changed, 87 insertions(+), 44 deletions(-)
diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts
index d2e7c4089e88bd..5c292187982dc0 100644
--- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts
+++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts
@@ -11,6 +11,7 @@ jest.mock('../../hooks/use_request', () => {
...module,
useGetSettings: jest.fn(),
sendGetFleetStatus: jest.fn(),
+ sendGetOneAgentPolicy: jest.fn(),
};
});
diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx
index f68b1b878c51c0..18296134ee1a71 100644
--- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx
+++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx
@@ -16,7 +16,7 @@ import { coreMock } from 'src/core/public/mocks';
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
import type { AgentPolicy } from '../../../common';
-import { useGetSettings, sendGetFleetStatus } from '../../hooks/use_request';
+import { useGetSettings, sendGetFleetStatus, sendGetOneAgentPolicy } from '../../hooks/use_request';
import { FleetStatusProvider, ConfigContext } from '../../hooks';
import { useFleetServerInstructions } from '../../applications/fleet/sections/agents/agent_requirements_page/components';
@@ -79,6 +79,10 @@ describe('', () => {
data: { isReady: true },
});
+ (sendGetOneAgentPolicy as jest.Mock).mockResolvedValue({
+ data: { item: { package_policies: [] } },
+ });
+
(useFleetServerInstructions as jest.Mock).mockReturnValue({
serviceToken: 'test',
getServiceToken: jest.fn(),
diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/index.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/index.tsx
index 9b82b2a80b5e14..87911e5d6c2c78 100644
--- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/index.tsx
+++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/index.tsx
@@ -22,7 +22,9 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
-import { useGetSettings, useUrlModal } from '../../hooks';
+import { useGetSettings, useUrlModal, sendGetOneAgentPolicy, useFleetStatus } from '../../hooks';
+import { FLEET_SERVER_PACKAGE } from '../../constants';
+import type { PackagePolicy } from '../../types';
import { ManagedInstructions } from './managed_instructions';
import { StandaloneInstructions } from './standalone_instructions';
@@ -63,6 +65,30 @@ export const AgentEnrollmentFlyout: React.FunctionComponent = ({
}
}, [modal, lastModal, settings]);
+ const fleetStatus = useFleetStatus();
+ const [policyId, setSelectedPolicyId] = useState(agentPolicy?.id);
+ const [isFleetServerPolicySelected, setIsFleetServerPolicySelected] = useState(false);
+
+ useEffect(() => {
+ async function checkPolicyIsFleetServer() {
+ if (policyId && setIsFleetServerPolicySelected) {
+ const agentPolicyRequest = await sendGetOneAgentPolicy(policyId);
+ if (
+ agentPolicyRequest.data?.item &&
+ (agentPolicyRequest.data.item.package_policies as PackagePolicy[]).some(
+ (packagePolicy) => packagePolicy.package?.name === FLEET_SERVER_PACKAGE
+ )
+ ) {
+ setIsFleetServerPolicySelected(true);
+ } else {
+ setIsFleetServerPolicySelected(false);
+ }
+ }
+ }
+
+ checkPolicyIsFleetServer();
+ }, [policyId]);
+
const isLoadingInitialRequest = settings.isLoading && settings.isInitialRequest;
return (
@@ -110,16 +136,23 @@ export const AgentEnrollmentFlyout: React.FunctionComponent = ({
) : undefined
}
>
- {fleetServerHosts.length === 0 && mode === 'managed' ? null : mode === 'managed' ? (
+ {mode === 'managed' ? (
) : (
diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx
index 61f86335cd7f93..8054c48fbbaa80 100644
--- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx
+++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/managed_instructions.tsx
@@ -11,7 +11,7 @@ import type { EuiContainedStepProps } from '@elastic/eui/src/components/steps/st
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
-import { useGetOneEnrollmentAPIKey, useGetSettings, useLink, useFleetStatus } from '../../hooks';
+import { useGetOneEnrollmentAPIKey, useLink, useFleetStatus } from '../../hooks';
import { ManualInstructions } from '../../components/enrollment_instructions';
import {
@@ -56,14 +56,19 @@ const FleetServerMissingRequirements = () => {
};
export const ManagedInstructions = React.memo(
- ({ agentPolicy, agentPolicies, viewDataStep }) => {
+ ({
+ agentPolicy,
+ agentPolicies,
+ viewDataStep,
+ setSelectedPolicyId,
+ isFleetServerPolicySelected,
+ settings,
+ }) => {
const fleetStatus = useFleetStatus();
const [selectedApiKeyId, setSelectedAPIKeyId] = useState();
- const [isFleetServerPolicySelected, setIsFleetServerPolicySelected] = useState(false);
const apiKey = useGetOneEnrollmentAPIKey(selectedApiKeyId);
- const settings = useGetSettings();
const fleetServerInstructions = useFleetServerInstructions(apiKey?.data?.item?.policy_id);
const fleetServerSteps = useMemo(() => {
@@ -88,7 +93,7 @@ export const ManagedInstructions = React.memo(
}, [fleetServerInstructions]);
const steps = useMemo(() => {
- const fleetServerHosts = settings.data?.item?.fleet_server_hosts || [];
+ const fleetServerHosts = settings?.fleet_server_hosts || [];
const baseSteps: EuiContainedStepProps[] = [
DownloadStep(),
!agentPolicy
@@ -96,7 +101,7 @@ export const ManagedInstructions = React.memo(
agentPolicies,
selectedApiKeyId,
setSelectedAPIKeyId,
- setIsFleetServerPolicySelected,
+ setSelectedPolicyId,
})
: AgentEnrollmentKeySelectionStep({ agentPolicy, selectedApiKeyId, setSelectedAPIKeyId }),
];
@@ -121,30 +126,39 @@ export const ManagedInstructions = React.memo(
}, [
agentPolicy,
selectedApiKeyId,
+ setSelectedPolicyId,
setSelectedAPIKeyId,
agentPolicies,
apiKey.data,
fleetServerSteps,
isFleetServerPolicySelected,
- settings.data?.item?.fleet_server_hosts,
+ settings?.fleet_server_hosts,
viewDataStep,
]);
+ if (fleetStatus.isReady && settings?.fleet_server_hosts.length === 0) {
+ return null;
+ }
+
+ if (fleetStatus.isReady) {
+ return (
+ <>
+
+
+
+
+
+ >
+ );
+ }
+
return (
<>
- {fleetStatus.isReady ? (
- <>
-
-
-
-
-
- >
- ) : fleetStatus.missingRequirements?.length === 1 &&
- fleetStatus.missingRequirements[0] === 'fleet_server' ? (
+ {fleetStatus.missingRequirements?.length === 1 &&
+ fleetStatus.missingRequirements[0] === 'fleet_server' ? (
) : (
diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx
index 6cffa39628d923..1cfdc45fb7dba0 100644
--- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx
+++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx
@@ -11,9 +11,8 @@ import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import semver from 'semver';
-import type { AgentPolicy, PackagePolicy } from '../../types';
-import { sendGetOneAgentPolicy, useKibanaVersion } from '../../hooks';
-import { FLEET_SERVER_PACKAGE } from '../../constants';
+import type { AgentPolicy } from '../../types';
+import { useKibanaVersion } from '../../hooks';
import { EnrollmentStepAgentPolicy } from './agent_policy_selection';
import { AdvancedAgentAuthenticationSettings } from './advanced_agent_authentication_settings';
@@ -69,13 +68,11 @@ export const AgentPolicySelectionStep = ({
selectedApiKeyId,
setSelectedAPIKeyId,
excludeFleetServer,
- setIsFleetServerPolicySelected,
}: {
agentPolicies?: AgentPolicy[];
setSelectedPolicyId?: (policyId?: string) => void;
selectedApiKeyId?: string;
setSelectedAPIKeyId?: (key?: string) => void;
- setIsFleetServerPolicySelected?: (selected: boolean) => void;
excludeFleetServer?: boolean;
}) => {
const regularAgentPolicies = useMemo(() => {
@@ -92,21 +89,8 @@ export const AgentPolicySelectionStep = ({
if (setSelectedPolicyId) {
setSelectedPolicyId(policyId);
}
- if (policyId && setIsFleetServerPolicySelected) {
- const agentPolicyRequest = await sendGetOneAgentPolicy(policyId);
- if (
- agentPolicyRequest.data?.item &&
- (agentPolicyRequest.data.item.package_policies as PackagePolicy[]).some(
- (packagePolicy) => packagePolicy.package?.name === FLEET_SERVER_PACKAGE
- )
- ) {
- setIsFleetServerPolicySelected(true);
- } else {
- setIsFleetServerPolicySelected(false);
- }
- }
},
- [setIsFleetServerPolicySelected, setSelectedPolicyId]
+ [setSelectedPolicyId]
);
return {
diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/types.ts b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/types.ts
index 9ee514c634655f..282a5b243caed2 100644
--- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/types.ts
+++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/types.ts
@@ -7,7 +7,7 @@
import type { EuiStepProps } from '@elastic/eui';
-import type { AgentPolicy } from '../../types';
+import type { AgentPolicy, Settings } from '../../types';
export interface BaseProps {
/**
@@ -27,4 +27,10 @@ export interface BaseProps {
* in some way. This is an area for consumers to render a button and text explaining how data can be viewed.
*/
viewDataStep?: EuiStepProps;
+
+ settings?: Settings;
+
+ setSelectedPolicyId?: (policyId?: string) => void;
+
+ isFleetServerPolicySelected?: boolean;
}
diff --git a/x-pack/plugins/fleet/public/types/index.ts b/x-pack/plugins/fleet/public/types/index.ts
index f21552d68e77b6..c91ec42d3e5277 100644
--- a/x-pack/plugins/fleet/public/types/index.ts
+++ b/x-pack/plugins/fleet/public/types/index.ts
@@ -27,6 +27,7 @@ export {
PackagePolicyPackage,
Output,
DataStream,
+ Settings,
// API schema - misc setup, status
GetFleetStatusResponse,
// API schemas - Agent policy
From 42c743be8848e08761f76903c4aa1f0b5f8e899a Mon Sep 17 00:00:00 2001
From: Caroline Horn <549577+cchaos@users.noreply.github.com>
Date: Mon, 12 Jul 2021 12:50:41 -0400
Subject: [PATCH 12/12] [Top Menu] Increase size of top menu links to `s`
(#103144)
* Increased non-emphasized header links size from `xs` to `s`
* [Observability] Updating header links to use EuiHeaderLink
* [Spaces Menu] Larger spinner
* [Help Menu] Increase size of links
* [Canvas] Increase size to `s`
---
.../chrome/ui/header/header_help_menu.tsx | 12 +--
.../data/public/ui/filter_bar/filter_bar.tsx | 2 +-
.../index_pattern_table.tsx | 2 +-
.../public/top_nav_menu/top_nav_menu_item.tsx | 2 +-
.../app/RumDashboard/ActionMenu/index.tsx | 60 ++++++--------
.../alerting_popover_flyout.tsx | 1 -
.../anomaly_detection_setup_link.tsx | 1 -
.../shared/apm_header_action_menu/index.tsx | 2 +-
.../function_reference_generator.tsx | 2 +-
.../public/components/help_menu/help_menu.tsx | 4 +-
.../__snapshots__/edit_menu.stories.storyshot | 12 +--
.../edit_menu/edit_menu.component.tsx | 2 +-
.../share_menu.stories.storyshot | 4 +-
.../share_menu/share_menu.component.tsx | 2 +-
.../__snapshots__/view_menu.stories.storyshot | 8 +-
.../view_menu/view_menu.component.tsx | 2 +-
.../file_error_callouts.tsx | 2 +-
.../components/metrics_alert_dropdown.tsx | 7 +-
.../components/alert_dropdown.tsx | 7 +-
.../infra/public/pages/logs/page_content.tsx | 37 ++++-----
.../infra/public/pages/metrics/index.tsx | 43 ++++------
.../anomaly_detection_flyout.tsx | 7 +-
.../nav_control/nav_control_popover.tsx | 2 +-
.../common/header/action_menu_content.tsx | 82 +++++++++----------
.../alerts/toggle_alert_flyout_button.tsx | 7 +-
.../overview/synthetics_callout.test.tsx | 6 --
.../overview/synthetics_callout.tsx | 10 +--
27 files changed, 134 insertions(+), 194 deletions(-)
diff --git a/src/core/public/chrome/ui/header/header_help_menu.tsx b/src/core/public/chrome/ui/header/header_help_menu.tsx
index c6a09c1177a5e8..cbf89bba2ca443 100644
--- a/src/core/public/chrome/ui/header/header_help_menu.tsx
+++ b/src/core/public/chrome/ui/header/header_help_menu.tsx
@@ -211,7 +211,7 @@ export class HeaderHelpMenu extends Component {
return (
-
+
}>
-
- {ANALYZE_DATA}
-
-
-
-
-
+ {ANALYZE_MESSAGE}}>
+
- {i18n.translate('xpack.apm.addDataButtonLabel', {
- defaultMessage: 'Add data',
- })}
-
-
-
+ {ANALYZE_DATA}
+
+
+
+ {i18n.translate('xpack.apm.addDataButtonLabel', {
+ defaultMessage: 'Add data',
+ })}
+
+
);
}
diff --git a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/alerting_popover_flyout.tsx b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/alerting_popover_flyout.tsx
index ca73f6ddd05b34..4abd36a2773119 100644
--- a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/alerting_popover_flyout.tsx
+++ b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/alerting_popover_flyout.tsx
@@ -66,7 +66,6 @@ export function AlertingPopoverAndFlyout({
const button = (
-
+
{i18n.translate('xpack.apm.settingsLinkLabel', {
defaultMessage: 'Settings',
})}
diff --git a/x-pack/plugins/canvas/public/components/function_reference_generator/function_reference_generator.tsx b/x-pack/plugins/canvas/public/components/function_reference_generator/function_reference_generator.tsx
index 81532816d9c830..eb394801f549c4 100644
--- a/x-pack/plugins/canvas/public/components/function_reference_generator/function_reference_generator.tsx
+++ b/x-pack/plugins/canvas/public/components/function_reference_generator/function_reference_generator.tsx
@@ -29,7 +29,7 @@ export const FunctionReferenceGenerator: FC = ({ functionRegistry }) => {
};
return (
-
+
Generate function reference
);
diff --git a/x-pack/plugins/canvas/public/components/help_menu/help_menu.tsx b/x-pack/plugins/canvas/public/components/help_menu/help_menu.tsx
index 2877ccf41056df..af1850beb5290f 100644
--- a/x-pack/plugins/canvas/public/components/help_menu/help_menu.tsx
+++ b/x-pack/plugins/canvas/public/components/help_menu/help_menu.tsx
@@ -46,13 +46,13 @@ export const HelpMenu: FC = ({ functionRegistry }) => {
return (
<>
-
+
{strings.getKeyboardShortcutsLinkLabel()}
{FunctionReferenceGenerator ? (
-
+
) : null}
diff --git a/x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__stories__/__snapshots__/edit_menu.stories.storyshot b/x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__stories__/__snapshots__/edit_menu.stories.storyshot
index cc33ae3526c0c3..f2bc9c57cbcc66 100644
--- a/x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__stories__/__snapshots__/edit_menu.stories.storyshot
+++ b/x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__stories__/__snapshots__/edit_menu.stories.storyshot
@@ -9,7 +9,7 @@ exports[`Storyshots components/WorkpadHeader/EditMenu 2 elements selected 1`] =
>
}
isOpen={popoverOpen}
closePopover={closePopover}
diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx
index f3481cab733603..302de15db9f5a0 100644
--- a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx
+++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx
@@ -7,7 +7,7 @@
import React, { useState, useCallback, useMemo } from 'react';
import { i18n } from '@kbn/i18n';
-import { EuiPopover, EuiButtonEmpty, EuiContextMenuItem, EuiContextMenuPanel } from '@elastic/eui';
+import { EuiPopover, EuiContextMenuItem, EuiContextMenuPanel, EuiHeaderLink } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { AlertFlyout } from './alert_flyout';
import { useLinkProps } from '../../../hooks/use_link_props';
@@ -83,8 +83,7 @@ export const AlertDropdown = () => {
{
id="xpack.infra.alerting.logs.alertsButton"
defaultMessage="Alerts and rules"
/>
-
+
}
isOpen={popoverOpen}
closePopover={closePopover}
diff --git a/x-pack/plugins/infra/public/pages/logs/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/page_content.tsx
index 8175a95f6a0649..d8b5667e60d04c 100644
--- a/x-pack/plugins/infra/public/pages/logs/page_content.tsx
+++ b/x-pack/plugins/infra/public/pages/logs/page_content.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { EuiFlexGroup, EuiFlexItem, EuiButtonEmpty } from '@elastic/eui';
+import { EuiHeaderLinks, EuiHeaderLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useContext } from 'react';
import { Route, Switch } from 'react-router-dom';
@@ -78,28 +78,19 @@ export const LogsPageContent: React.FunctionComponent = () => {
{setHeaderActionMenu && (
-
-
-
- {settingsTabTitle}
-
-
-
-
-
-
-
- {ADD_DATA_LABEL}
-
-
-
+
+
+ {settingsTabTitle}
+
+
+
+ {ADD_DATA_LABEL}
+
+
)}
diff --git a/x-pack/plugins/infra/public/pages/metrics/index.tsx b/x-pack/plugins/infra/public/pages/metrics/index.tsx
index 045fcb57ae9436..d4845a4dd9e449 100644
--- a/x-pack/plugins/infra/public/pages/metrics/index.tsx
+++ b/x-pack/plugins/infra/public/pages/metrics/index.tsx
@@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
import React, { useContext } from 'react';
import { Route, RouteComponentProps, Switch } from 'react-router-dom';
-import { EuiErrorBoundary, EuiFlexItem, EuiFlexGroup, EuiButtonEmpty } from '@elastic/eui';
+import { EuiErrorBoundary, EuiHeaderLinks, EuiHeaderLink } from '@elastic/eui';
import { IIndexPattern } from 'src/plugins/data/common';
import { MetricsSourceConfigurationProperties } from '../../../common/metrics_sources';
import { DocumentTitle } from '../../components/document_title';
@@ -86,31 +86,22 @@ export const InfrastructurePage = ({ match }: RouteComponentProps) => {
{setHeaderActionMenu && (
-
-
-
- {settingsTabTitle}
-
-
-
-
-
-
-
-
-
-
- {ADD_DATA_LABEL}
-
-
-
+
+
+ {settingsTabTitle}
+
+
+
+
+ {ADD_DATA_LABEL}
+
+
)}
diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomaly_detection_flyout.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomaly_detection_flyout.tsx
index d2cd4f87a53422..4e28fb4202bdc2 100644
--- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomaly_detection_flyout.tsx
+++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomaly_detection_flyout.tsx
@@ -6,7 +6,7 @@
*/
import React, { useState, useCallback } from 'react';
-import { EuiButtonEmpty, EuiFlyout } from '@elastic/eui';
+import { EuiHeaderLink, EuiFlyout } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { FlyoutHome } from './flyout_home';
import { JobSetupScreen } from './job_setup_screen';
@@ -50,8 +50,7 @@ export const AnomalyDetectionFlyout = () => {
return (
<>
- {
id="xpack.infra.ml.anomalyDetectionButton"
defaultMessage="Anomaly detection"
/>
-
+
{showFlyout && (
{
}
return this.getButton(
- }>
+ }>
,
(activeSpace as Space).name
diff --git a/x-pack/plugins/uptime/public/components/common/header/action_menu_content.tsx b/x-pack/plugins/uptime/public/components/common/header/action_menu_content.tsx
index 479a512b7238a1..9f00dd2e8f0619 100644
--- a/x-pack/plugins/uptime/public/components/common/header/action_menu_content.tsx
+++ b/x-pack/plugins/uptime/public/components/common/header/action_menu_content.tsx
@@ -6,7 +6,7 @@
*/
import React from 'react';
-import { EuiButtonEmpty, EuiHeaderLinks, EuiHeaderSectionItem, EuiToolTip } from '@elastic/eui';
+import { EuiHeaderLinks, EuiToolTip, EuiHeaderLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { useHistory } from 'react-router-dom';
@@ -51,53 +51,45 @@ export function ActionMenuContent(): React.ReactElement {
return (
-
-
+
+
+
+
+
+ {ANALYZE_MESSAGE}}>
+
-
-
-
-
-
-
-
- {ANALYZE_MESSAGE}}>
-
- {ANALYZE_DATA}
-
-
-
-
-
- {ADD_DATA_LABEL}
-
-
+ {ANALYZE_DATA}
+
+
+
+
+ {ADD_DATA_LABEL}
+
);
}
diff --git a/x-pack/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx
index 278958bd1987bb..22193fe4623d68 100644
--- a/x-pack/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx
+++ b/x-pack/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx
@@ -6,7 +6,7 @@
*/
import {
- EuiButtonEmpty,
+ EuiHeaderLink,
EuiContextMenu,
EuiContextMenuPanelDescriptor,
EuiContextMenuPanelItemDescriptor,
@@ -123,8 +123,7 @@ export const ToggleAlertFlyoutButtonComponent: React.FC = ({
return (
= ({
id="xpack.uptime.alerts.toggleAlertFlyoutButtonText"
defaultMessage="Alerts and rules"
/>
-
+
}
closePopover={() => setIsOpen(false)}
isOpen={isOpen}
diff --git a/x-pack/plugins/uptime/public/components/overview/synthetics_callout.test.tsx b/x-pack/plugins/uptime/public/components/overview/synthetics_callout.test.tsx
index 5f6f9d7a7207ed..ec9e5f958ec3a5 100644
--- a/x-pack/plugins/uptime/public/components/overview/synthetics_callout.test.tsx
+++ b/x-pack/plugins/uptime/public/components/overview/synthetics_callout.test.tsx
@@ -67,9 +67,6 @@ describe('SyntheticsCallout', () => {
-
`);
});
@@ -128,9 +125,6 @@ describe('SyntheticsCallout', () => {
-
`);
wrapper.find('EuiButton').simulate('click');
diff --git a/x-pack/plugins/uptime/public/components/overview/synthetics_callout.tsx b/x-pack/plugins/uptime/public/components/overview/synthetics_callout.tsx
index fa28e42d7d0c14..4e9c3256f15781 100644
--- a/x-pack/plugins/uptime/public/components/overview/synthetics_callout.tsx
+++ b/x-pack/plugins/uptime/public/components/overview/synthetics_callout.tsx
@@ -5,14 +5,7 @@
* 2.0.
*/
-import {
- EuiButton,
- EuiButtonEmpty,
- EuiCallOut,
- EuiFlexGroup,
- EuiFlexItem,
- EuiSpacer,
-} from '@elastic/eui';
+import { EuiButton, EuiButtonEmpty, EuiCallOut, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import React, { useState } from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
@@ -74,7 +67,6 @@ export const SyntheticsCallout = () => {
-
>
);
};