diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bf1e341c796fa..e54b7b56707e8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -170,7 +170,7 @@ /x-pack/legacy/plugins/index_lifecycle_management/ @elastic/es-ui /x-pack/legacy/plugins/index_management/ @elastic/es-ui /x-pack/legacy/plugins/license_management/ @elastic/es-ui -/x-pack/legacy/plugins/remote_clusters/ @elastic/es-ui +/x-pack/plugins/remote_clusters/ @elastic/es-ui /x-pack/legacy/plugins/rollup/ @elastic/es-ui /x-pack/plugins/searchprofiler/ @elastic/es-ui /x-pack/legacy/plugins/snapshot_restore/ @elastic/es-ui diff --git a/packages/kbn-test/package.json b/packages/kbn-test/package.json index 0cc54fa2a64c4..a01c4ebab8ad0 100644 --- a/packages/kbn-test/package.json +++ b/packages/kbn-test/package.json @@ -5,7 +5,7 @@ "license": "Apache-2.0", "private": true, "scripts": { - "build": "babel src --out-dir target --delete-dir-on-start --extensions .ts,.js,.tsx --ignore *.test.js,**/__tests__/**", + "build": "babel src --out-dir target --delete-dir-on-start --extensions .ts,.js,.tsx --ignore *.test.js,**/__tests__/** --source-maps=inline", "kbn:bootstrap": "yarn build", "kbn:watch": "yarn build --watch" }, diff --git a/packages/kbn-test/src/failed_tests_reporter/test_report.ts b/packages/kbn-test/src/failed_tests_reporter/test_report.ts index 6b759ef1d4c62..43d84163462d3 100644 --- a/packages/kbn-test/src/failed_tests_reporter/test_report.ts +++ b/packages/kbn-test/src/failed_tests_reporter/test_report.ts @@ -47,7 +47,7 @@ export interface TestSuite { /* number of skipped tests as a string */ skipped: string; }; - testcase: TestCase[]; + testcase?: TestCase[]; } export interface TestCase { @@ -89,7 +89,7 @@ export function* makeTestCaseIter(report: TestReport) { const testSuites = 'testsuites' in report ? report.testsuites.testsuite : [report.testsuite]; for (const testSuite of testSuites) { - for (const testCase of testSuite.testcase) { + for (const testCase of testSuite.testcase || []) { yield testCase; } } diff --git a/src/legacy/core_plugins/data/public/search/aggs/__tests__/buckets/_terms_other_bucket_helper.js b/src/legacy/core_plugins/data/public/search/aggs/__tests__/buckets/_terms_other_bucket_helper.js index 247290731df57..749dad377f2e2 100644 --- a/src/legacy/core_plugins/data/public/search/aggs/__tests__/buckets/_terms_other_bucket_helper.js +++ b/src/legacy/core_plugins/data/public/search/aggs/__tests__/buckets/_terms_other_bucket_helper.js @@ -24,7 +24,7 @@ import { mergeOtherBucketAggResponse, updateMissingBucket, } from '../../buckets/_terms_other_bucket_helper'; -import { Vis } from '../../../../../../../core_plugins/visualizations/public'; +import { start as visualizationsStart } from '../../../../../../../core_plugins/visualizations/public/np_ready/public/legacy'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; const visConfigSingleTerm = { @@ -191,7 +191,7 @@ describe('Terms Agg Other bucket helper', () => { ngMock.inject(Private => { const indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider); - vis = new Vis(indexPattern, aggConfig); + vis = new visualizationsStart.Vis(indexPattern, aggConfig); }); } diff --git a/src/legacy/core_plugins/kibana/public/discover/build_services.ts b/src/legacy/core_plugins/kibana/public/discover/build_services.ts index f9265323b2dcb..81f1c911f1cc9 100644 --- a/src/legacy/core_plugins/kibana/public/discover/build_services.ts +++ b/src/legacy/core_plugins/kibana/public/discover/build_services.ts @@ -36,6 +36,7 @@ import { SharePluginStart } from '../../../../../plugins/share/public'; import { SavedSearch } from './np_ready/types'; import { DocViewsRegistry } from './np_ready/doc_views/doc_views_registry'; import { ChartsPluginStart } from '../../../../../plugins/charts/public'; +import { VisualizationsStart } from '../../../visualizations/public'; export interface DiscoverServices { addBasePath: (path: string) => string; @@ -56,6 +57,7 @@ export interface DiscoverServices { getSavedSearchById: (id: string) => Promise; getSavedSearchUrlById: (id: string) => Promise; uiSettings: IUiSettingsClient; + visualizations: VisualizationsStart; } export async function buildServices( core: CoreStart, @@ -89,5 +91,6 @@ export async function buildServices( timefilter: plugins.data.query.timefilter.timefilter, toastNotifications: core.notifications.toasts, uiSettings: core.uiSettings, + visualizations: plugins.visualizations, }; } diff --git a/src/legacy/core_plugins/kibana/public/discover/legacy.ts b/src/legacy/core_plugins/kibana/public/discover/legacy.ts index ff44fbbe115d5..a1ef646f4fe85 100644 --- a/src/legacy/core_plugins/kibana/public/discover/legacy.ts +++ b/src/legacy/core_plugins/kibana/public/discover/legacy.ts @@ -20,10 +20,18 @@ import { PluginInitializerContext } from 'kibana/public'; import { npSetup, npStart } from 'ui/new_platform'; import { plugin } from './index'; +import { + setup as visualizationsSetup, + start as visualizationsStart, +} from '../../../../core_plugins/visualizations/public/np_ready/public/legacy'; // Legacy compatibility part - to be removed at cutover, replaced by a kibana.json file export const pluginInstance = plugin({} as PluginInitializerContext); export const setup = pluginInstance.setup(npSetup.core, { ...npSetup.plugins, + visualizations: visualizationsSetup, +}); +export const start = pluginInstance.start(npStart.core, { + ...npStart.plugins, + visualizations: visualizationsStart, }); -export const start = pluginInstance.start(npStart.core, npStart.plugins); diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js index 39a9ca6641fd1..bf5049cd976a3 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js @@ -60,7 +60,6 @@ import { ensureDefaultIndexPattern, registerTimefilterWithGlobalStateFactory, } from '../../kibana_services'; -import { Vis } from '../../../../../visualizations/public'; const { core, @@ -71,6 +70,7 @@ const { timefilter, toastNotifications, uiSettings, + visualizations, } = getServices(); import { getRootBreadcrumbs, getSavedSearchBreadcrumbs } from '../helpers/breadcrumbs'; @@ -990,7 +990,10 @@ function discoverController( }, }; - $scope.vis = new Vis($scope.searchSource.getField('index'), visSavedObject.visState); + $scope.vis = new visualizations.Vis( + $scope.searchSource.getField('index'), + visSavedObject.visState + ); visSavedObject.vis = $scope.vis; $scope.searchSource.onRequestStart((searchSource, options) => { diff --git a/src/legacy/core_plugins/kibana/public/discover/plugin.ts b/src/legacy/core_plugins/kibana/public/discover/plugin.ts index a495b56d5e9ea..565382313e369 100644 --- a/src/legacy/core_plugins/kibana/public/discover/plugin.ts +++ b/src/legacy/core_plugins/kibana/public/discover/plugin.ts @@ -36,6 +36,10 @@ import { DocViewInput, DocViewInputFn } from './np_ready/doc_views/doc_views_typ import { DocViewTable } from './np_ready/components/table/table'; import { JsonCodeBlock } from './np_ready/components/json_code_block/json_code_block'; import { HomePublicPluginSetup } from '../../../../../plugins/home/public'; +import { + VisualizationsStart, + VisualizationsSetup, +} from '../../../visualizations/public/np_ready/public'; /** * These are the interfaces with your public contracts. You should export these @@ -51,6 +55,7 @@ export interface DiscoverSetupPlugins { embeddable: IEmbeddableSetup; kibanaLegacy: KibanaLegacySetup; home: HomePublicPluginSetup; + visualizations: VisualizationsSetup; } export interface DiscoverStartPlugins { uiActions: UiActionsStart; @@ -60,6 +65,7 @@ export interface DiscoverStartPlugins { data: DataPublicPluginStart; share: SharePluginStart; inspector: any; + visualizations: VisualizationsStart; } const innerAngularName = 'app/discover'; const embeddableAngularName = 'app/discoverEmbeddable'; diff --git a/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js b/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js index 55447905e6421..f11aab9b9db88 100644 --- a/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js +++ b/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js @@ -38,8 +38,10 @@ import afterdatachangePng from './afterdatachange.png'; import afterdatachangeandresizePng from './afterdatachangeandresize.png'; import aftercolorchangePng from './aftercolorchange.png'; import changestartupPng from './changestartup.png'; -import { setup as visualizationsSetup } from '../../../visualizations/public/np_ready/public/legacy'; -import { Vis } from '../../../visualizations/public/np_ready/public/vis'; +import { + setup as visualizationsSetup, + start as visualizationsStart, +} from '../../../visualizations/public/np_ready/public/legacy'; import { createRegionMapVisualization } from '../region_map_visualization'; import { createRegionMapTypeDefinition } from '../region_map_type'; @@ -158,7 +160,7 @@ describe('RegionMapsVisualizationTests', function() { imageComparator = new ImageComparator(); - vis = new Vis(indexPattern, { + vis = new visualizationsStart.Vis(indexPattern, { type: 'region_map', }); diff --git a/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js b/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js index ef2ea831e84fd..27e9459c7e06c 100644 --- a/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js +++ b/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js @@ -32,8 +32,10 @@ import EMS_TILES from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_ import EMS_STYLE_ROAD_MAP_BRIGHT from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_bright'; import EMS_STYLE_ROAD_MAP_DESATURATED from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_desaturated'; import EMS_STYLE_DARK_MAP from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_dark'; -import { setup as visualizationsSetup } from '../../../visualizations/public/np_ready/public/legacy'; -import { Vis } from '../../../visualizations/public/np_ready/public/vis'; +import { + setup as visualizationsSetup, + start as visualizationsStart, +} from '../../../visualizations/public/np_ready/public/legacy'; import { createTileMapVisualization } from '../tile_map_visualization'; import { createTileMapTypeDefinition } from '../tile_map_type'; @@ -124,7 +126,7 @@ describe('CoordinateMapsVisualizationTest', function() { setupDOM('512px', '512px'); imageComparator = new ImageComparator(); - vis = new Vis(indexPattern, { + vis = new visualizationsStart.Vis(indexPattern, { type: 'tile_map', }); vis.params = { diff --git a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts index 15cd920b79e4a..67b5d018f4638 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts @@ -59,7 +59,7 @@ describe('metric_vis - createMetricVisTypeDefinition', () => { // TODO: remove when Vis is converted to typescript. Only importing Vis as type // @ts-ignore - vis = new Vis(stubIndexPattern, { + vis = new visualizationsStart.Vis(stubIndexPattern, { type: 'metric', aggs: [{ id: '1', type: 'top_hits', schema: 'metric', params: { field: 'ip' } }], }); diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js index fc5a24a66dab3..0dbff60613cb0 100644 --- a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js +++ b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js @@ -26,10 +26,11 @@ import sinon from 'sinon'; import { tabifyAggResponse, npStart } from '../../legacy_imports'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; import { round } from 'lodash'; - -import { Vis } from '../../../../visualizations/public'; import { tableVisTypeDefinition } from '../../table_vis_type'; -import { setup as visualizationsSetup } from '../../../../visualizations/public/np_ready/public/legacy'; +import { + setup as visualizationsSetup, + start as visualizationsStart, +} from '../../../../visualizations/public/np_ready/public/legacy'; import { getAngularModule } from '../../get_inner_angular'; import { initTableVisLegacyModule } from '../../table_vis_legacy_module'; import { tableVisResponseHandler } from '../../table_vis_response_handler'; @@ -42,10 +43,10 @@ describe('Table Vis - AggTable Directive', function() { const tabifiedData = {}; const init = () => { - const vis1 = new Vis(indexPattern, 'table'); + const vis1 = new visualizationsStart.Vis(indexPattern, 'table'); tabifiedData.metricOnly = tabifyAggResponse(vis1.aggs, fixtures.metricOnly); - const vis2 = new Vis(indexPattern, { + const vis2 = new visualizationsStart.Vis(indexPattern, { type: 'table', params: { showMetricsAtAllLevels: true, @@ -64,7 +65,7 @@ describe('Table Vis - AggTable Directive', function() { metricsAtAllLevels: true, }); - const vis3 = new Vis(indexPattern, { + const vis3 = new visualizationsStart.Vis(indexPattern, { type: 'table', aggs: [ { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js index 3c633f21cbabb..f6ae41b024b7d 100644 --- a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js +++ b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js @@ -23,10 +23,10 @@ import expect from '@kbn/expect'; import fixtures from 'fixtures/fake_hierarchical_data'; import { tabifyAggResponse, npStart } from '../../legacy_imports'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; -import { Vis } from '../../../../visualizations/public'; import { getAngularModule } from '../../get_inner_angular'; import { initTableVisLegacyModule } from '../../table_vis_legacy_module'; import { tableVisResponseHandler } from '../../table_vis_response_handler'; +import { start as visualizationsStart } from '../../../../visualizations/public/np_ready/public/legacy'; describe('Table Vis - AggTableGroup Directive', function() { let $rootScope; @@ -35,10 +35,10 @@ describe('Table Vis - AggTableGroup Directive', function() { const tabifiedData = {}; const init = () => { - const vis1 = new Vis(indexPattern, 'table'); + const vis1 = new visualizationsStart.Vis(indexPattern, 'table'); tabifiedData.metricOnly = tabifyAggResponse(vis1.aggs, fixtures.metricOnly); - const vis2 = new Vis(indexPattern, { + const vis2 = new visualizationsStart.Vis(indexPattern, { type: 'pie', aggs: [ { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js b/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js index 5f7d1ad90ecf8..55ecf98f994d2 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js @@ -20,7 +20,7 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; -import { Vis } from '../../../../visualizations/public/np_ready/public/vis'; +import { start as visualizationsStart } from '../../../../../core_plugins/visualizations/public/np_ready/public/legacy'; import { ImageComparator } from 'test_utils/image_comparator'; import { createTagCloudVisualization } from '../tag_cloud_visualization'; import basicdrawPng from './basicdraw.png'; @@ -76,7 +76,7 @@ describe('TagCloudVisualizationTest', function() { beforeEach(async function() { setupDOM('512px', '512px'); imageComparator = new ImageComparator(); - vis = new Vis(indexPattern, { + vis = new visualizationsStart.Vis(indexPattern, { type: 'tagcloud', params: { bucket: { accessor: 0, format: {} }, diff --git a/src/legacy/core_plugins/vis_type_vega/public/__tests__/vega_visualization.js b/src/legacy/core_plugins/vis_type_vega/public/__tests__/vega_visualization.js index 868e5729bd494..378590af29d3a 100644 --- a/src/legacy/core_plugins/vis_type_vega/public/__tests__/vega_visualization.js +++ b/src/legacy/core_plugins/vis_type_vega/public/__tests__/vega_visualization.js @@ -23,7 +23,6 @@ import ngMock from 'ng_mock'; import $ from 'jquery'; import { createVegaVisualization } from '../vega_visualization'; import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; -import { Vis } from '../../../visualizations/public/np_ready/public/vis'; import { ImageComparator } from 'test_utils/image_comparator'; import vegaliteGraph from '!!raw-loader!./vegalite_graph.hjson'; @@ -41,7 +40,10 @@ import vegaMapImage256 from './vega_map_image_256.png'; import { VegaParser } from '../data_model/vega_parser'; import { SearchCache } from '../data_model/search_cache'; -import { setup as visualizationsSetup } from '../../../visualizations/public/np_ready/public/legacy'; +import { + setup as visualizationsSetup, + start as visualizationsStart, +} from '../../../visualizations/public/np_ready/public/legacy'; import { createVegaTypeDefinition } from '../vega_type'; // TODO This is an integration test and thus requires a running platform. When moving to the new platform, // this test has to be migrated to the newly created integration test environment. @@ -106,7 +108,7 @@ describe('VegaVisualizations', () => { setupDOM('512px', '512px'); imageComparator = new ImageComparator(); - vis = new Vis(indexPattern, { type: 'vega' }); + vis = new visualizationsStart.Vis(indexPattern, { type: 'vega' }); }); afterEach(function() { diff --git a/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/pie_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/pie_chart.js index e4da572259b69..534a523103774 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/pie_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/pie_chart.js @@ -25,7 +25,7 @@ import expect from '@kbn/expect'; import fixtures from 'fixtures/fake_hierarchical_data'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; -import { Vis } from '../../../../../visualizations/public'; +import { start as visualizationsStart } from '../../../../../visualizations/public/np_ready/public/legacy'; import { getVis, getMockUiState } from '../lib/fixtures/_vis_fixture'; import { tabifyAggResponse } from '../../../legacy_imports'; import { vislibSlicesResponseHandler } from '../../response_handler'; @@ -133,7 +133,7 @@ describe('No global chart settings', function() { responseHandler = vislibSlicesResponseHandler; let id1 = 1; - stubVis1 = new Vis(indexPattern, { + stubVis1 = new visualizationsStart.Vis(indexPattern, { type: 'pie', aggs: rowAgg, }); @@ -222,7 +222,7 @@ describe('Vislib PieChart Class Test Suite', function() { responseHandler = vislibSlicesResponseHandler; let id = 1; - stubVis = new Vis(indexPattern, { + stubVis = new visualizationsStart.Vis(indexPattern, { type: 'pie', aggs: dataAgg, }); diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/__tests__/_vis.js b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/__tests__/_vis.js index d963315ef79db..8c75ba24051b0 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/__tests__/_vis.js +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/__tests__/_vis.js @@ -20,7 +20,6 @@ import _ from 'lodash'; import ngMock from 'ng_mock'; import expect from '@kbn/expect'; -import { Vis } from '../..'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; import { start as visualizations } from '../../legacy'; @@ -49,7 +48,7 @@ describe('Vis Class', function() { ); beforeEach(function() { - vis = new Vis(indexPattern, stateFixture); + vis = new visualizations.Vis(indexPattern, stateFixture); }); const verifyVis = function(vis) { @@ -85,7 +84,7 @@ describe('Vis Class', function() { describe('setState()', function() { it('should set the state to defaults', function() { - const vis = new Vis(indexPattern); + const vis = new visualizations.Vis(indexPattern); expect(vis).to.have.property('type'); expect(vis.type).to.eql(visTypes.get('histogram')); expect(vis).to.have.property('aggs'); @@ -101,7 +100,7 @@ describe('Vis Class', function() { expect(vis.isHierarchical()).to.be(true); }); it('should return false for non-hierarchical vis (like histogram)', function() { - const vis = new Vis(indexPattern); + const vis = new visualizations.Vis(indexPattern); expect(vis.isHierarchical()).to.be(false); }); }); diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/mocks.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/mocks.ts index 1063b1718b851..a948757d7bd83 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/mocks.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/mocks.ts @@ -49,6 +49,7 @@ const createStartContract = (): VisualizationsStart => ({ }, getSavedVisualizationsLoader: jest.fn(), showNewVisModal: jest.fn(), + Vis: jest.fn(), }); const createInstance = async () => { diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/plugin.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/plugin.ts index cbbeb7ff980a6..36c04923e3fd0 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/plugin.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/plugin.ts @@ -43,6 +43,7 @@ import { SavedObjectKibanaServicesWithVisualizations, } from '../../saved_visualizations'; import { SavedVisualizations } from '../../../../kibana/public/visualize/np_ready/types'; +import { VisImpl, VisImplConstructor } from './vis_impl'; import { showNewVisModal } from './wizard'; /** * Interface for this plugin's returned setup/start contracts. @@ -57,6 +58,7 @@ export interface VisualizationsStart { types: TypesStart; getSavedVisualizationsLoader: () => SavedVisualizations; showNewVisModal: typeof showNewVisModal; + Vis: VisImplConstructor; } export interface VisualizationsSetupDeps { @@ -131,6 +133,7 @@ export class VisualizationsPlugin types, getSavedVisualizationsLoader: () => this.getSavedVisualizationsLoader(), showNewVisModal, + Vis: VisImpl, }; } diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/vis.d.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis.ts similarity index 84% rename from src/legacy/core_plugins/visualizations/public/np_ready/public/vis.d.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/vis.ts index 71bf9bcf983ff..59a8013523ef6 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/vis.d.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis.ts @@ -42,9 +42,8 @@ export interface VisState { aggs: IAggConfigs; } -export declare class VisualizationController { - constructor(element: HTMLElement, vis: Vis); - public render(visData: any, visParams: any, update: { [key in Status]: boolean }): Promise; - public destroy(): void; - public isLoaded?(): Promise | void; +export interface VisualizationController { + render(visData: any, visParams: any, update: { [key in Status]: boolean }): Promise; + destroy(): void; + isLoaded?(): Promise | void; } diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_impl.d.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_impl.d.ts new file mode 100644 index 0000000000000..45d65efb5dcdf --- /dev/null +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_impl.d.ts @@ -0,0 +1,44 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Vis, VisState } from './vis'; +import { VisType } from './types'; +import { IIndexPattern } from '../../../../../../plugins/data/common'; + +type InitVisStateType = + | Partial + | Partial & { type: string }> + | string; + +export type VisImplConstructor = new ( + indexPattern: IIndexPattern, + visState?: InitVisStateType +) => VisImpl; + +export declare class VisImpl implements Vis { + constructor(indexPattern: IIndexPattern, visState?: InitVisStateType); + + type: VisType; + + // Since we haven't typed everything here yet, we basically "any" the rest + // of that interface. This should be removed as soon as this type definition + // has been completed. But that way we at least have typing for a couple of + // properties on that type. + [key: string]: any; +} diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/vis.js b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_impl.js similarity index 98% rename from src/legacy/core_plugins/visualizations/public/np_ready/public/vis.js rename to src/legacy/core_plugins/visualizations/public/np_ready/public/vis_impl.js index 0c2e5012df439..6f4ab6d708184 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/vis.js +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_impl.js @@ -33,7 +33,7 @@ import { AggConfigs, PersistedState } from '../../legacy_imports'; import { updateVisualizationConfig } from './legacy/vis_update'; import { getTypes } from './services'; -class Vis extends EventEmitter { +class VisImpl extends EventEmitter { constructor(indexPattern, visState) { super(); visState = visState || {}; @@ -203,6 +203,6 @@ class Vis extends EventEmitter { } } -Vis.prototype.type = 'histogram'; +VisImpl.prototype.type = 'histogram'; -export { Vis }; +export { VisImpl }; diff --git a/src/legacy/core_plugins/visualizations/public/saved_visualizations/_saved_vis.ts b/src/legacy/core_plugins/visualizations/public/saved_visualizations/_saved_vis.ts index ca2305a9cc91c..8b8c5fe94cc95 100644 --- a/src/legacy/core_plugins/visualizations/public/saved_visualizations/_saved_vis.ts +++ b/src/legacy/core_plugins/visualizations/public/saved_visualizations/_saved_vis.ts @@ -26,14 +26,14 @@ */ import { SavedObject, SavedObjectKibanaServices } from 'ui/saved_objects/types'; import { createSavedObjectClass } from 'ui/saved_objects/saved_object'; -// @ts-ignore -import { updateOldState, Vis } from '../index'; +import { updateOldState } from '../index'; import { extractReferences, injectReferences } from './saved_visualization_references'; import { IIndexPattern } from '../../../../../plugins/data/public'; import { VisSavedObject } from '../embeddable/visualize_embeddable'; import { createSavedSearchesLoader } from '../../../kibana/public/discover'; import { VisualizeConstants } from '../../../kibana/public/visualize'; +import { VisImpl } from '../np_ready/public/vis_impl'; async function _afterEsResp(savedVis: VisSavedObject, services: any) { await _getLinkedSavedSearch(savedVis, services); @@ -72,9 +72,8 @@ async function _createVis(savedVis: VisSavedObject) { if (savedVis.visState) { savedVis.visState.title = savedVis.title; } - // the typescript compiler is wrong here, will be right when vis.js -> vis.ts - // @ts-ignore - savedVis.vis = new Vis(savedVis.searchSource!.getField('index'), savedVis.visState); + + savedVis.vis = new VisImpl(savedVis.searchSource!.getField('index')!, savedVis.visState); savedVis.vis!.savedSearchId = savedVis.savedSearchId; diff --git a/src/legacy/ui/public/agg_response/tabify/__tests__/_get_columns.js b/src/legacy/ui/public/agg_response/tabify/__tests__/_get_columns.js index 56536a2e5b536..3eb41c03050d0 100644 --- a/src/legacy/ui/public/agg_response/tabify/__tests__/_get_columns.js +++ b/src/legacy/ui/public/agg_response/tabify/__tests__/_get_columns.js @@ -20,7 +20,7 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { tabifyGetColumns } from '../_get_columns'; -import { Vis } from '../../../../../core_plugins/visualizations/public'; +import { start as visualizationsStart } from '../../../../../core_plugins/visualizations/public/np_ready/public/legacy'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; describe('get columns', function() { let indexPattern; @@ -33,7 +33,7 @@ describe('get columns', function() { ); it('should inject a count metric if no aggs exist', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'pie', }); while (vis.aggs.length) vis.aggs.pop(); @@ -49,7 +49,7 @@ describe('get columns', function() { }); it('should inject a count metric if only buckets exist', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'pie', aggs: [ { @@ -68,7 +68,7 @@ describe('get columns', function() { }); it('should inject the metric after each bucket if the vis is hierarchical', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'pie', aggs: [ { @@ -104,7 +104,7 @@ describe('get columns', function() { }); it('should inject the multiple metrics after each bucket if the vis is hierarchical', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'pie', aggs: [ { @@ -156,7 +156,7 @@ describe('get columns', function() { }); it('should put all metrics at the end of the columns if the vis is not hierarchical', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { diff --git a/src/legacy/ui/public/agg_response/tabify/__tests__/_integration.js b/src/legacy/ui/public/agg_response/tabify/__tests__/_integration.js index c7c328000772b..f3f2e20149acf 100644 --- a/src/legacy/ui/public/agg_response/tabify/__tests__/_integration.js +++ b/src/legacy/ui/public/agg_response/tabify/__tests__/_integration.js @@ -22,7 +22,7 @@ import fixtures from 'fixtures/fake_hierarchical_data'; import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { tabifyAggResponse } from '../tabify'; -import { Vis } from '../../../../../core_plugins/visualizations/public'; +import { start as visualizationsStart } from '../../../../../core_plugins/visualizations/public/np_ready/public/legacy'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; describe('tabifyAggResponse Integration', function() { @@ -42,7 +42,7 @@ describe('tabifyAggResponse Integration', function() { } it('transforms a simple response properly', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [], }); @@ -73,7 +73,7 @@ describe('tabifyAggResponse Integration', function() { let esResp; beforeEach(function() { - vis = new Vis(indexPattern, { + vis = new visualizationsStart.Vis(indexPattern, { type: 'pie', aggs: [ { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, diff --git a/src/legacy/ui/public/agg_response/tabify/__tests__/_response_writer.js b/src/legacy/ui/public/agg_response/tabify/__tests__/_response_writer.js index ced495ef23c36..b0c0f2f3d9100 100644 --- a/src/legacy/ui/public/agg_response/tabify/__tests__/_response_writer.js +++ b/src/legacy/ui/public/agg_response/tabify/__tests__/_response_writer.js @@ -20,7 +20,7 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { TabbedAggResponseWriter } from '../_response_writer'; -import { Vis } from '../../../../../core_plugins/visualizations/public'; +import { start as visualizationsStart } from '../../../../../core_plugins/visualizations/public/np_ready/public/legacy'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; describe('TabbedAggResponseWriter class', function() { @@ -61,7 +61,7 @@ describe('TabbedAggResponseWriter class', function() { ]; const createResponseWritter = (aggs = [], opts = {}) => { - const vis = new Vis(indexPattern, { type: 'histogram', aggs: aggs }); + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: aggs }); return new TabbedAggResponseWriter(vis.getAggConfig(), opts); }; @@ -88,7 +88,7 @@ describe('TabbedAggResponseWriter class', function() { describe('sets timeRange', function() { it("to the first nested object's range", function() { - const vis = new Vis(indexPattern, { type: 'histogram', aggs: [] }); + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [] }); const range = { gte: 0, lte: 100, @@ -106,7 +106,7 @@ describe('TabbedAggResponseWriter class', function() { }); it('to undefined if no nested object', function() { - const vis = new Vis(indexPattern, { type: 'histogram', aggs: [] }); + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [] }); const writer = new TabbedAggResponseWriter(vis.getAggConfig(), { timeRange: {}, diff --git a/src/legacy/ui/public/vis/__tests__/_agg_config.js b/src/legacy/ui/public/vis/__tests__/_agg_config.js index 7dccf3eec18aa..9e53044f681ba 100644 --- a/src/legacy/ui/public/vis/__tests__/_agg_config.js +++ b/src/legacy/ui/public/vis/__tests__/_agg_config.js @@ -20,8 +20,8 @@ import sinon from 'sinon'; import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import { Vis } from '../../../../core_plugins/visualizations/public'; import { AggType, AggConfig } from '../../agg_types'; +import { start as visualizationsStart } from '../../../../core_plugins/visualizations/public/np_ready/public/legacy'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; @@ -37,7 +37,7 @@ describe('AggConfig', function() { describe('#toDsl', function() { it('calls #write()', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { @@ -55,7 +55,7 @@ describe('AggConfig', function() { }); it('uses the type name as the agg name', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { @@ -73,7 +73,7 @@ describe('AggConfig', function() { }); it('uses the params from #write() output as the agg params', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { @@ -93,7 +93,7 @@ describe('AggConfig', function() { }); it('includes subAggs from #write() output', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { @@ -219,8 +219,8 @@ describe('AggConfig', function() { testsIdentical.forEach((visConfig, index) => { it(`identical aggregations (${index})`, function() { - const vis1 = new Vis(indexPattern, visConfig); - const vis2 = new Vis(indexPattern, visConfig); + const vis1 = new visualizationsStart.Vis(indexPattern, visConfig); + const vis2 = new visualizationsStart.Vis(indexPattern, visConfig); expect(vis1.aggs.jsonDataEquals(vis2.aggs.aggs)).to.be(true); }); }); @@ -258,8 +258,8 @@ describe('AggConfig', function() { testsIdenticalDifferentOrder.forEach((test, index) => { it(`identical aggregations (${index}) - init json is in different order`, function() { - const vis1 = new Vis(indexPattern, test.config1); - const vis2 = new Vis(indexPattern, test.config2); + const vis1 = new visualizationsStart.Vis(indexPattern, test.config1); + const vis2 = new visualizationsStart.Vis(indexPattern, test.config2); expect(vis1.aggs.jsonDataEquals(vis2.aggs.aggs)).to.be(true); }); }); @@ -323,8 +323,8 @@ describe('AggConfig', function() { testsDifferent.forEach((test, index) => { it(`different aggregations (${index})`, function() { - const vis1 = new Vis(indexPattern, test.config1); - const vis2 = new Vis(indexPattern, test.config2); + const vis1 = new visualizationsStart.Vis(indexPattern, test.config1); + const vis2 = new visualizationsStart.Vis(indexPattern, test.config2); expect(vis1.aggs.jsonDataEquals(vis2.aggs.aggs)).to.be(false); }); }); @@ -332,7 +332,7 @@ describe('AggConfig', function() { describe('#toJSON', function() { it('includes the aggs id, params, type and schema', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { @@ -360,7 +360,7 @@ describe('AggConfig', function() { }); it('test serialization order is identical (for visual consistency)', function() { - const vis1 = new Vis(indexPattern, { + const vis1 = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { @@ -369,7 +369,7 @@ describe('AggConfig', function() { }, ], }); - const vis2 = new Vis(indexPattern, { + const vis2 = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { @@ -387,26 +387,26 @@ describe('AggConfig', function() { describe('#makeLabel', function() { it('uses the custom label if it is defined', function() { - const vis = new Vis(indexPattern, {}); + const vis = new visualizationsStart.Vis(indexPattern, {}); const aggConfig = vis.aggs.aggs[0]; aggConfig.params.customLabel = 'Custom label'; const label = aggConfig.makeLabel(); expect(label).to.be(aggConfig.params.customLabel); }); it('default label should be "Count"', function() { - const vis = new Vis(indexPattern, {}); + const vis = new visualizationsStart.Vis(indexPattern, {}); const aggConfig = vis.aggs.aggs[0]; const label = aggConfig.makeLabel(); expect(label).to.be('Count'); }); it('default label should be "Percentage of Count" when percentageMode is set to true', function() { - const vis = new Vis(indexPattern, {}); + const vis = new visualizationsStart.Vis(indexPattern, {}); const aggConfig = vis.aggs.aggs[0]; const label = aggConfig.makeLabel(true); expect(label).to.be('Percentage of Count'); }); - it('empty label if the Vis type is not defined', function() { - const vis = new Vis(indexPattern, {}); + it('empty label if the visualizationsStart.Vis type is not defined', function() { + const vis = new visualizationsStart.Vis(indexPattern, {}); const aggConfig = vis.aggs.aggs[0]; aggConfig.type = undefined; const label = aggConfig.makeLabel(); @@ -416,7 +416,7 @@ describe('AggConfig', function() { describe('#fieldFormatter - custom getFormat handler', function() { it('returns formatter from getFormat handler', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'metric', aggs: [ { @@ -447,7 +447,7 @@ describe('AggConfig', function() { let vis; beforeEach(function() { - vis = new Vis(indexPattern, visStateAggWithoutCustomGetFormat); + vis = new visualizationsStart.Vis(indexPattern, visStateAggWithoutCustomGetFormat); }); it("returns the field's formatter", function() { diff --git a/src/legacy/ui/public/vis/__tests__/_agg_configs.js b/src/legacy/ui/public/vis/__tests__/_agg_configs.js index 62ad9a40ad058..172523ec50c8b 100644 --- a/src/legacy/ui/public/vis/__tests__/_agg_configs.js +++ b/src/legacy/ui/public/vis/__tests__/_agg_configs.js @@ -22,7 +22,7 @@ import sinon from 'sinon'; import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { AggConfig, AggConfigs, AggGroupNames, Schemas } from '../../agg_types'; -import { Vis } from '../../../../core_plugins/visualizations/public'; +import { start as visualizationsStart } from '../../../../core_plugins/visualizations/public/np_ready/public/legacy'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; describe('AggConfigs', function() { @@ -38,7 +38,7 @@ describe('AggConfigs', function() { describe('constructor', function() { it('handles passing just a vis', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [], }); @@ -48,7 +48,7 @@ describe('AggConfigs', function() { }); it('converts configStates into AggConfig objects if they are not already', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [], }); @@ -72,7 +72,7 @@ describe('AggConfigs', function() { }); it('attempts to ensure that all states have an id', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [], }); @@ -154,7 +154,7 @@ describe('AggConfigs', function() { describe('#getRequestAggs', function() { it('performs a stable sort, but moves metrics to the bottom', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { type: 'avg', schema: 'metric' }, @@ -185,7 +185,7 @@ describe('AggConfigs', function() { describe('#getResponseAggs', function() { it('returns all request aggs for basic aggs', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { type: 'terms', schema: 'split' }, @@ -206,7 +206,7 @@ describe('AggConfigs', function() { }); it('expands aggs that have multiple responses', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { type: 'terms', schema: 'split' }, @@ -231,14 +231,14 @@ describe('AggConfigs', function() { describe('#toDsl', function() { it('uses the sorted aggs', function() { - const vis = new Vis(indexPattern, { type: 'histogram' }); + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram' }); sinon.spy(vis.aggs, 'getRequestAggs'); vis.aggs.toDsl(); expect(vis.aggs.getRequestAggs).to.have.property('callCount', 1); }); it('calls aggConfig#toDsl() on each aggConfig and compiles the nested output', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { type: 'date_histogram', schema: 'segment' }, @@ -272,7 +272,7 @@ describe('AggConfigs', function() { }); it("skips aggs that don't have a dsl representation", function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { @@ -295,7 +295,7 @@ describe('AggConfigs', function() { }); it('writes multiple metric aggregations at the same level', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { @@ -326,7 +326,7 @@ describe('AggConfigs', function() { }); it('writes multiple metric aggregations at every level if the vis is hierarchical', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { type: 'terms', schema: 'segment', params: { field: 'ip', orderBy: 1 } }, @@ -362,7 +362,7 @@ describe('AggConfigs', function() { }); it('adds the parent aggs of nested metrics at every level if the vis is hierarchical', function() { - const vis = new Vis(indexPattern, { + const vis = new visualizationsStart.Vis(indexPattern, { type: 'histogram', aggs: [ { diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index 27da54042594d..032efcee20afd 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -27,7 +27,7 @@ "xpack.maps": "legacy/plugins/maps", "xpack.ml": "legacy/plugins/ml", "xpack.monitoring": "legacy/plugins/monitoring", - "xpack.remoteClusters": ["plugins/remote_clusters", "legacy/plugins/remote_clusters"], + "xpack.remoteClusters": "plugins/remote_clusters", "xpack.reporting": ["plugins/reporting", "legacy/plugins/reporting"], "xpack.rollupJobs": "legacy/plugins/rollup", "xpack.searchProfiler": "plugins/searchprofiler", diff --git a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/setup_environment.js b/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/setup_environment.js deleted file mode 100644 index d2385dc900bb2..0000000000000 --- a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/setup_environment.js +++ /dev/null @@ -1,35 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import axios from 'axios'; -import axiosXhrAdapter from 'axios/lib/adapters/xhr'; -import chrome from 'ui/chrome'; // eslint-disable-line import/no-unresolved -import { MANAGEMENT_BREADCRUMB } from 'ui/management'; // eslint-disable-line import/no-unresolved -import { fatalError, toastNotifications } from 'ui/notify'; // eslint-disable-line import/no-unresolved - -import { init as initBreadcrumb } from '../../../public/app/services/breadcrumb'; -import { init as initHttp } from '../../../public/app/services/http'; -import { init as initNotification } from '../../../public/app/services/notification'; -import { init as initUiMetric } from '../../../public/app/services/ui_metric'; -import { init as initHttpRequests } from './http_requests'; - -export const setupEnvironment = () => { - chrome.breadcrumbs = { - set: () => {}, - }; - // axios has a $http like interface so using it to simulate $http - initHttp(axios.create({ adapter: axiosXhrAdapter }), path => path); - initBreadcrumb(() => {}, MANAGEMENT_BREADCRUMB); - initNotification(toastNotifications, fatalError); - initUiMetric(() => () => {}); - - const { server, httpRequestsMockHelpers } = initHttpRequests(); - - return { - server, - httpRequestsMockHelpers, - }; -}; diff --git a/x-pack/legacy/plugins/remote_clusters/common/cluster_serialization.test.ts b/x-pack/legacy/plugins/remote_clusters/common/cluster_serialization.test.ts deleted file mode 100644 index 476fbee7fb6a0..0000000000000 --- a/x-pack/legacy/plugins/remote_clusters/common/cluster_serialization.test.ts +++ /dev/null @@ -1,137 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { deserializeCluster, serializeCluster } from './cluster_serialization'; - -describe('cluster_serialization', () => { - describe('deserializeCluster()', () => { - it('should throw an error for invalid arguments', () => { - expect(() => deserializeCluster('foo', 'bar')).toThrowError(); - }); - - it('should deserialize a complete cluster object', () => { - expect( - deserializeCluster('test_cluster', { - seeds: ['localhost:9300'], - connected: true, - num_nodes_connected: 1, - max_connections_per_cluster: 3, - initial_connect_timeout: '30s', - skip_unavailable: false, - transport: { - ping_schedule: '-1', - compress: false, - }, - }) - ).toEqual({ - name: 'test_cluster', - seeds: ['localhost:9300'], - isConnected: true, - connectedNodesCount: 1, - maxConnectionsPerCluster: 3, - initialConnectTimeout: '30s', - skipUnavailable: false, - transportPingSchedule: '-1', - transportCompress: false, - }); - }); - - it('should deserialize a cluster object without transport information', () => { - expect( - deserializeCluster('test_cluster', { - seeds: ['localhost:9300'], - connected: true, - num_nodes_connected: 1, - max_connections_per_cluster: 3, - initial_connect_timeout: '30s', - skip_unavailable: false, - }) - ).toEqual({ - name: 'test_cluster', - seeds: ['localhost:9300'], - isConnected: true, - connectedNodesCount: 1, - maxConnectionsPerCluster: 3, - initialConnectTimeout: '30s', - skipUnavailable: false, - }); - }); - - it('should deserialize a cluster object with arbitrary missing properties', () => { - expect( - deserializeCluster('test_cluster', { - seeds: ['localhost:9300'], - connected: true, - num_nodes_connected: 1, - initial_connect_timeout: '30s', - transport: { - compress: false, - }, - }) - ).toEqual({ - name: 'test_cluster', - seeds: ['localhost:9300'], - isConnected: true, - connectedNodesCount: 1, - initialConnectTimeout: '30s', - transportCompress: false, - }); - }); - }); - - describe('serializeCluster()', () => { - it('should throw an error for invalid arguments', () => { - expect(() => serializeCluster('foo')).toThrowError(); - }); - - it('should serialize a complete cluster object to only dynamic properties', () => { - expect( - serializeCluster({ - name: 'test_cluster', - seeds: ['localhost:9300'], - isConnected: true, - connectedNodesCount: 1, - maxConnectionsPerCluster: 3, - initialConnectTimeout: '30s', - skipUnavailable: false, - transportPingSchedule: '-1', - transportCompress: false, - }) - ).toEqual({ - persistent: { - cluster: { - remote: { - test_cluster: { - seeds: ['localhost:9300'], - skip_unavailable: false, - }, - }, - }, - }, - }); - }); - - it('should serialize a cluster object with missing properties', () => { - expect( - serializeCluster({ - name: 'test_cluster', - seeds: ['localhost:9300'], - }) - ).toEqual({ - persistent: { - cluster: { - remote: { - test_cluster: { - seeds: ['localhost:9300'], - skip_unavailable: null, - }, - }, - }, - }, - }); - }); - }); -}); diff --git a/x-pack/legacy/plugins/remote_clusters/common/cluster_serialization.ts b/x-pack/legacy/plugins/remote_clusters/common/cluster_serialization.ts deleted file mode 100644 index 07ea79d42b800..0000000000000 --- a/x-pack/legacy/plugins/remote_clusters/common/cluster_serialization.ts +++ /dev/null @@ -1,71 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export function deserializeCluster(name: string, esClusterObject: any): any { - if (!name || !esClusterObject || typeof esClusterObject !== 'object') { - throw new Error('Unable to deserialize cluster'); - } - - const { - seeds, - connected: isConnected, - num_nodes_connected: connectedNodesCount, - max_connections_per_cluster: maxConnectionsPerCluster, - initial_connect_timeout: initialConnectTimeout, - skip_unavailable: skipUnavailable, - transport, - } = esClusterObject; - - let deserializedClusterObject: any = { - name, - seeds, - isConnected, - connectedNodesCount, - maxConnectionsPerCluster, - initialConnectTimeout, - skipUnavailable, - }; - - if (transport) { - const { ping_schedule: transportPingSchedule, compress: transportCompress } = transport; - - deserializedClusterObject = { - ...deserializedClusterObject, - transportPingSchedule, - transportCompress, - }; - } - - // It's unnecessary to send undefined values back to the client, so we can remove them. - Object.keys(deserializedClusterObject).forEach(key => { - if (deserializedClusterObject[key] === undefined) { - delete deserializedClusterObject[key]; - } - }); - - return deserializedClusterObject; -} - -export function serializeCluster(deserializedClusterObject: any): any { - if (!deserializedClusterObject || typeof deserializedClusterObject !== 'object') { - throw new Error('Unable to serialize cluster'); - } - - const { name, seeds, skipUnavailable } = deserializedClusterObject; - - return { - persistent: { - cluster: { - remote: { - [name]: { - seeds: seeds ? seeds : null, - skip_unavailable: skipUnavailable !== undefined ? skipUnavailable : null, - }, - }, - }, - }, - }; -} diff --git a/x-pack/legacy/plugins/remote_clusters/common/index.ts b/x-pack/legacy/plugins/remote_clusters/common/index.ts index 8f80b3b7dc6a3..c643f549cbfe1 100644 --- a/x-pack/legacy/plugins/remote_clusters/common/index.ts +++ b/x-pack/legacy/plugins/remote_clusters/common/index.ts @@ -4,20 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { i18n } from '@kbn/i18n'; -import { LICENSE_TYPE_BASIC, LicenseType } from '../../../common/constants'; - export const PLUGIN = { ID: 'remote_clusters', - // Remote Clusters are used in both CCS and CCR, and CCS is available for all licenses. - MINIMUM_LICENSE_REQUIRED: LICENSE_TYPE_BASIC as LicenseType, - getI18nName: (): string => { - return i18n.translate('xpack.remoteClusters.appName', { - defaultMessage: 'Remote Clusters', - }); - }, }; - -export const API_BASE_PATH = '/api/remote_clusters'; - -export { deserializeCluster, serializeCluster } from './cluster_serialization'; diff --git a/x-pack/legacy/plugins/remote_clusters/index.ts b/x-pack/legacy/plugins/remote_clusters/index.ts index 5dd823e09eb8b..37b2224f8d7c2 100644 --- a/x-pack/legacy/plugins/remote_clusters/index.ts +++ b/x-pack/legacy/plugins/remote_clusters/index.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Legacy } from 'kibana'; import { resolve } from 'path'; import { PLUGIN } from './common'; @@ -13,18 +12,11 @@ export function remoteClusters(kibana: any) { id: PLUGIN.ID, configPrefix: 'xpack.remote_clusters', publicDir: resolve(__dirname, 'public'), - // xpack_main is required for license checking. - require: ['kibana', 'elasticsearch', 'xpack_main', 'index_management'], + require: ['kibana'], uiExports: { styleSheetPaths: resolve(__dirname, 'public/index.scss'), - managementSections: ['plugins/remote_clusters'], - injectDefaultVars(server: Legacy.Server) { - const config = server.config(); - return { - remoteClustersUiEnabled: config.get('xpack.remote_clusters.ui.enabled'), - }; - }, }, + // TODO: Remove once CCR has migrated to NP config(Joi: any) { return Joi.object({ // display menu item @@ -41,6 +33,6 @@ export function remoteClusters(kibana: any) { config.get('xpack.remote_clusters.enabled') && config.get('xpack.index_management.enabled') ); }, - init(server: any) {}, + init() {}, }); } diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/connection_status/_index.scss b/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/connection_status/_index.scss deleted file mode 100644 index c85cb36c5dc5a..0000000000000 --- a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/connection_status/_index.scss +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 1. Prevent inherited flexbox layout from compressing this element on IE. - */ - .remoteClustersConnectionStatus__message { - flex-basis: auto !important; /* 1 */ -} diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/http.ts b/x-pack/legacy/plugins/remote_clusters/public/app/services/http.ts deleted file mode 100644 index 54dadf0ae3cb1..0000000000000 --- a/x-pack/legacy/plugins/remote_clusters/public/app/services/http.ts +++ /dev/null @@ -1,39 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -let _httpClient: any; -let _prependBasePath: any; - -export function init(httpClient: any, prependBasePath: any): void { - _httpClient = httpClient; - _prependBasePath = prependBasePath; -} - -export function getFullPath(path: string): string { - const apiPrefix = _prependBasePath('/api/remote_clusters'); - - if (path) { - return `${apiPrefix}/${path}`; - } - - return apiPrefix; -} - -export function sendPost(path: string, payload: any): any { - return _httpClient.post(getFullPath(path), payload); -} - -export function sendGet(path: string): any { - return _httpClient.get(getFullPath(path)); -} - -export function sendPut(path: string, payload: any): any { - return _httpClient.put(getFullPath(path), payload); -} - -export function sendDelete(path: string): any { - return _httpClient.delete(getFullPath(path)); -} diff --git a/x-pack/legacy/plugins/remote_clusters/public/index.html b/x-pack/legacy/plugins/remote_clusters/public/index.html deleted file mode 100644 index 4de600769fb40..0000000000000 --- a/x-pack/legacy/plugins/remote_clusters/public/index.html +++ /dev/null @@ -1,3 +0,0 @@ - -
-
diff --git a/x-pack/legacy/plugins/remote_clusters/public/index.js b/x-pack/legacy/plugins/remote_clusters/public/index.js deleted file mode 100644 index 0a08011dd71a0..0000000000000 --- a/x-pack/legacy/plugins/remote_clusters/public/index.js +++ /dev/null @@ -1,12 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { Plugin as RemoteClustersPlugin } from './plugin'; -import { createShim } from './shim'; - -const { coreStart, pluginsStart } = createShim(); -const remoteClustersPlugin = new RemoteClustersPlugin(); -remoteClustersPlugin.start(coreStart, pluginsStart); diff --git a/x-pack/legacy/plugins/remote_clusters/public/index.scss b/x-pack/legacy/plugins/remote_clusters/public/index.scss index 4618b005312a5..4ae11323642d8 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/index.scss +++ b/x-pack/legacy/plugins/remote_clusters/public/index.scss @@ -1,8 +1,7 @@ // Import the EUI global scope so we can use EUI constants @import 'src/legacy/ui/public/styles/_styling_constants'; -@import './app/sections/remote_cluster_list/components/connection_status/index'; -// Index management plugin styles +// Remote clusters plugin styles // Prefix all styles with "remoteClusters" to avoid conflicts. // Examples @@ -16,8 +15,14 @@ * as the 'Reset to defaults' link is added to and removed from the DOM. * 2. Fix the positioning. */ - .remoteClusterSkipIfUnavailableSwitch { justify-content: flex-start !important; /* 1 */ padding-top: $euiSizeS !important; } + +/** + * 1. Prevent inherited flexbox layout from compressing this element on IE. + */ + .remoteClustersConnectionStatus__message { + flex-basis: auto !important; /* 1 */ +} diff --git a/x-pack/legacy/plugins/remote_clusters/public/plugin.js b/x-pack/legacy/plugins/remote_clusters/public/plugin.js deleted file mode 100644 index 8dbcfb98859cd..0000000000000 --- a/x-pack/legacy/plugins/remote_clusters/public/plugin.js +++ /dev/null @@ -1,123 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { unmountComponentAtNode } from 'react-dom'; -import { i18n } from '@kbn/i18n'; -import routes from 'ui/routes'; - -import template from './index.html'; -import { renderReact } from './app'; -import { CRUD_APP_BASE_PATH } from './app/constants'; -import { setUserHasLeftApp, setRedirect } from './app/services'; -import { init as initBreadcrumbs } from './app/services/breadcrumb'; -import { init as initDocumentation } from './app/services/documentation'; -import { init as initHttp } from './app/services/http'; -import { init as initUiMetric } from './app/services/ui_metric'; -import { init as initNotification } from './app/services/notification'; - -const REACT_ROOT_ID = 'remoteClustersReactRoot'; - -export class Plugin { - start(coreStart, pluginsStart) { - const { - i18n: { Context }, - chrome: { setBreadcrumbs }, - notifications: { toasts }, - fatalError, - http: { - basePath: { prepend: prependBasePath }, - }, - injectedMetadata: { getInjectedVar }, - documentation: { elasticWebsiteUrl, docLinkVersion }, - } = coreStart; - - if (getInjectedVar('remoteClustersUiEnabled')) { - const { - management: { getSection, breadcrumb: managementBreadcrumb }, - uiMetric: { createUiStatsReporter }, - } = pluginsStart; - - const esSection = getSection('elasticsearch'); - esSection.register('remote_clusters', { - visible: true, - display: i18n.translate('xpack.remoteClusters.appTitle', { - defaultMessage: 'Remote Clusters', - }), - order: 5, - url: `#${CRUD_APP_BASE_PATH}/list`, - }); - - // Initialize services - initBreadcrumbs(setBreadcrumbs, managementBreadcrumb); - initDocumentation(`${elasticWebsiteUrl}guide/en/elasticsearch/reference/${docLinkVersion}/`); - initUiMetric(createUiStatsReporter); - initNotification(toasts, fatalError); - - const unmountReactApp = () => { - const appElement = document.getElementById(REACT_ROOT_ID); - if (appElement) { - unmountComponentAtNode(appElement); - } - }; - - // NOTE: The New Platform will implicitly handle much of this logic by mounting the app at - // the base route. - routes.when(`${CRUD_APP_BASE_PATH}/:view?/:id?`, { - template, - controllerAs: 'remoteClusters', - controller: class RemoteClustersController { - constructor($scope, $route, $http, kbnUrl) { - // NOTE: We depend upon Angular's $http service because it's decorated with interceptors, - // e.g. to check license status per request. - initHttp($http, prependBasePath); - - setRedirect(path => { - $scope.$evalAsync(() => { - kbnUrl.redirect(path); - }); - }); - - // If returning to the app, we'll need to reset this state. - setUserHasLeftApp(false); - - // React-router's will cause this controller to re-execute without the $destroy - // handler being called. This means the app will re-mount, so we need to unmount it first - // here. - unmountReactApp(); - - $scope.$$postDigest(() => { - const appElement = document.getElementById(REACT_ROOT_ID); - if (appElement) { - renderReact(appElement, Context); - } - - const appRoute = $route.current; - const stopListeningForLocationChange = $scope.$on('$locationChangeSuccess', () => { - const currentRoute = $route.current; - const isNavigationInApp = - currentRoute.$$route.template === appRoute.$$route.template; - - // When we navigate within the app, prevent Angular from re-matching the route and - // rebuilding the app. - if (isNavigationInApp) { - $route.current = appRoute; - } else { - // Set internal flag so we can prevent reacting to the route change internally. - setUserHasLeftApp(true); - } - }); - - $scope.$on('$destroy', () => { - stopListeningForLocationChange(); - unmountReactApp(); - }); - }); - } - }, - }); - } - } -} diff --git a/x-pack/legacy/plugins/remote_clusters/public/shim.ts b/x-pack/legacy/plugins/remote_clusters/public/shim.ts deleted file mode 100644 index 83975fa4bd0fe..0000000000000 --- a/x-pack/legacy/plugins/remote_clusters/public/shim.ts +++ /dev/null @@ -1,42 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { npStart } from 'ui/new_platform'; -import { management, MANAGEMENT_BREADCRUMB } from 'ui/management'; -import { fatalError } from 'ui/notify'; -import { DOC_LINK_VERSION, ELASTIC_WEBSITE_URL } from 'ui/documentation_links'; - -import { createUiStatsReporter } from '../../../../../src/legacy/core_plugins/ui_metric/public'; - -export function createShim() { - const { - core: { chrome, i18n, notifications, http, injectedMetadata }, - } = npStart; - - return { - coreStart: { - chrome, - i18n, - notifications, - fatalError, - injectedMetadata, - http, - documentation: { - elasticWebsiteUrl: ELASTIC_WEBSITE_URL, - docLinkVersion: DOC_LINK_VERSION, - }, - }, - pluginsStart: { - management: { - getSection: management.getSection.bind(management), - breadcrumb: MANAGEMENT_BREADCRUMB, - }, - uiMetric: { - createUiStatsReporter, - }, - }, - }; -} diff --git a/x-pack/legacy/plugins/security/public/services/auto_logout.js b/x-pack/legacy/plugins/security/public/services/auto_logout.js index eb00d62d0266c..fa4d149d1f2e6 100644 --- a/x-pack/legacy/plugins/security/public/services/auto_logout.js +++ b/x-pack/legacy/plugins/security/public/services/auto_logout.js @@ -8,12 +8,26 @@ import { uiModules } from 'ui/modules'; import chrome from 'ui/chrome'; const module = uiModules.get('security'); + +const getNextParameter = () => { + const { location } = window; + const next = encodeURIComponent(`${location.pathname}${location.search}${location.hash}`); + return `&next=${next}`; +}; + +const getProviderParameter = tenant => { + const key = `${tenant}/session_provider`; + const providerName = sessionStorage.getItem(key); + return providerName ? `&provider=${encodeURIComponent(providerName)}` : ''; +}; + module.service('autoLogout', ($window, Promise) => { return () => { - const next = chrome.removeBasePath(`${window.location.pathname}${window.location.hash}`); - $window.location.href = chrome.addBasePath( - `/logout?next=${encodeURIComponent(next)}&msg=SESSION_EXPIRED` - ); + const logoutUrl = chrome.getInjected('logoutUrl'); + const tenant = `${chrome.getInjected('session.tenant', '')}`; + const next = getNextParameter(); + const provider = getProviderParameter(tenant); + $window.location.href = `${logoutUrl}?msg=SESSION_EXPIRED${next}${provider}`; return Promise.halt(); }; }); diff --git a/x-pack/legacy/plugins/siem/public/components/alerts_viewer/translations.ts b/x-pack/legacy/plugins/siem/public/components/alerts_viewer/translations.ts index b0bc38bd3ebdc..79466251fc57b 100644 --- a/x-pack/legacy/plugins/siem/public/components/alerts_viewer/translations.ts +++ b/x-pack/legacy/plugins/siem/public/components/alerts_viewer/translations.ts @@ -19,7 +19,7 @@ export const ALERTS_TABLE_TITLE = i18n.translate('xpack.siem.alertsView.alertsTa }); export const ALERTS_GRAPH_TITLE = i18n.translate('xpack.siem.alertsView.alertsGraphTitle', { - defaultMessage: 'External alerts count', + defaultMessage: 'External alert count', }); export const ALERTS_STACK_BY_MODULE = i18n.translate( diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/errors_types/get_index_error.ts b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/errors_types/get_index_error.ts index e4f2a658b7362..4f45b480772f2 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/errors_types/get_index_error.ts +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/errors_types/get_index_error.ts @@ -8,13 +8,13 @@ import { MessageBody } from '../../../../components/ml/api/throw_if_not_ok'; export class SignalIndexError extends Error { message: string = ''; - statusCode: number = -1; + status_code: number = -1; error: string = ''; constructor(errObj: MessageBody) { super(errObj.message); this.message = errObj.message ?? ''; - this.statusCode = errObj.statusCode ?? -1; + this.status_code = errObj.status_code ?? -1; this.error = errObj.error ?? ''; this.name = 'SignalIndexError'; diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_signal_index.tsx b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_signal_index.tsx index 2635d6e5540f1..813bd2483689c 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_signal_index.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/signals/use_signal_index.tsx @@ -60,7 +60,7 @@ export const useSignalIndex = (): Return => { signalIndexName: null, createDeSignalIndex: createIndex, }); - if (error instanceof SignalIndexError && error.statusCode !== 404) { + if (error instanceof SignalIndexError && error.status_code !== 404) { errorToToaster({ title: i18n.SIGNAL_GET_NAME_FAILURE, error, dispatchToaster }); } } diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/translations.ts index 4cecf7376ca41..8c88fa4a5dae6 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/translations.ts +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/translations.ts @@ -86,7 +86,7 @@ export const STACK_BY_USERS = i18n.translate( export const HISTOGRAM_HEADER = i18n.translate( 'xpack.siem.detectionEngine.signals.histogram.headerTitle', { - defaultMessage: 'Signals count', + defaultMessage: 'Signal count', } ); diff --git a/x-pack/legacy/plugins/siem/public/pages/overview/translations.ts b/x-pack/legacy/plugins/siem/public/pages/overview/translations.ts index e20083bf51772..5ccd25984bc40 100644 --- a/x-pack/legacy/plugins/siem/public/pages/overview/translations.ts +++ b/x-pack/legacy/plugins/siem/public/pages/overview/translations.ts @@ -7,11 +7,11 @@ import { i18n } from '@kbn/i18n'; export const ALERTS_GRAPH_TITLE = i18n.translate('xpack.siem.overview.alertsGraphTitle', { - defaultMessage: 'External alerts count', + defaultMessage: 'External alert count', }); export const EVENTS = i18n.translate('xpack.siem.overview.eventsTitle', { - defaultMessage: 'Events count', + defaultMessage: 'Event count', }); export const NEWS_FEED_TITLE = i18n.translate('xpack.siem.overview.newsFeedSidebarTitle', { @@ -31,7 +31,7 @@ export const RECENT_TIMELINES = i18n.translate('xpack.siem.overview.recentTimeli }); export const SIGNAL_COUNT = i18n.translate('xpack.siem.overview.signalCountTitle', { - defaultMessage: 'Signals count', + defaultMessage: 'Signal count', }); export const VIEW_ALERTS = i18n.translate('xpack.siem.overview.viewAlertsButtonLabel', { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/open_close_signals_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/open_close_signals_route.ts index b2b938625180e..dd3b8d3c99e0c 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/open_close_signals_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/open_close_signals_route.ts @@ -54,6 +54,7 @@ export const setSignalsStatusRouteDef = ( }, query: queryObject, }, + ignoreUnavailable: true, }); } catch (exc) { // error while getting or updating signal with id: id in signal index .siem-signals diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/query_signals_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/query_signals_route.ts index a3602ffbded41..adb6e5f32921a 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/query_signals_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/query_signals_route.ts @@ -38,6 +38,7 @@ export const querySignalsRouteDef = ( return clusterClient.callAsCurrentUser('search', { index, body: { query, aggs, _source, track_total_hits, size }, + ignoreUnavailable: true, }); } catch (exc) { // error while getting or updating signal with id: id in signal index .siem-signals diff --git a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/constants.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/constants.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/constants.js rename to x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/constants.js diff --git a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/http_requests.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/http_requests.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/http_requests.js rename to x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/http_requests.js diff --git a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/index.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/index.js similarity index 96% rename from x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/index.js rename to x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/index.js index 084a370666e45..d70ba2a21e176 100644 --- a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/index.js +++ b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/index.js @@ -8,7 +8,7 @@ import { setup as remoteClustersAddSetup } from './remote_clusters_add.helpers'; import { setup as remoteClustersEditSetup } from './remote_clusters_edit.helpers'; import { setup as remoteClustersListSetup } from './remote_clusters_list.helpers'; -export { nextTick, getRandomString, findTestSubject } from '../../../../../../test_utils'; +export { nextTick, getRandomString, findTestSubject } from '../../../../../test_utils'; export { setupEnvironment } from './setup_environment'; diff --git a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_add.helpers.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_add.helpers.js similarity index 66% rename from x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_add.helpers.js rename to x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_add.helpers.js index e573a4ebcef92..dd1d5d2187176 100644 --- a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_add.helpers.js +++ b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_add.helpers.js @@ -4,10 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { registerTestBed } from '../../../../../../test_utils'; -import { RemoteClusterAdd } from '../../../public/app/sections/remote_cluster_add'; -import { createRemoteClustersStore } from '../../../public/app/store'; -import { registerRouter } from '../../../public/app/services/routing'; +import { registerTestBed } from '../../../../../test_utils'; + +/* eslint-disable @kbn/eslint/no-restricted-paths */ +import { RemoteClusterAdd } from '../../../public/application/sections/remote_cluster_add'; +import { createRemoteClustersStore } from '../../../public/application/store'; +import { registerRouter } from '../../../public/application/services/routing'; const testBedConfig = { store: createRemoteClustersStore, diff --git a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_edit.helpers.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_edit.helpers.js similarity index 68% rename from x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_edit.helpers.js rename to x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_edit.helpers.js index 6a90ed6657c78..426aea90e5a99 100644 --- a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_edit.helpers.js +++ b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_edit.helpers.js @@ -4,10 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { registerTestBed } from '../../../../../../test_utils'; -import { RemoteClusterEdit } from '../../../public/app/sections/remote_cluster_edit'; -import { createRemoteClustersStore } from '../../../public/app/store'; -import { registerRouter } from '../../../public/app/services/routing'; +import { registerTestBed } from '../../../../../test_utils'; + +/* eslint-disable @kbn/eslint/no-restricted-paths */ +import { RemoteClusterEdit } from '../../../public/application/sections/remote_cluster_edit'; +import { createRemoteClustersStore } from '../../../public/application/store'; +import { registerRouter } from '../../../public/application/services/routing'; import { REMOTE_CLUSTER_EDIT_NAME } from './constants'; diff --git a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_list.helpers.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_list.helpers.js similarity index 88% rename from x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_list.helpers.js rename to x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_list.helpers.js index 0009bd84ffa6a..dc9b22b40542a 100644 --- a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_list.helpers.js +++ b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_list.helpers.js @@ -4,10 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { registerTestBed, findTestSubject } from '../../../../../../test_utils'; -import { RemoteClusterList } from '../../../public/app/sections/remote_cluster_list'; -import { createRemoteClustersStore } from '../../../public/app/store'; -import { registerRouter } from '../../../public/app/services/routing'; +import { registerTestBed, findTestSubject } from '../../../../../test_utils'; + +/* eslint-disable @kbn/eslint/no-restricted-paths */ +import { RemoteClusterList } from '../../../public/application/sections/remote_cluster_list'; +import { createRemoteClustersStore } from '../../../public/application/store'; +import { registerRouter } from '../../../public/application/services/routing'; const testBedConfig = { store: createRemoteClustersStore, diff --git a/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/setup_environment.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/setup_environment.js new file mode 100644 index 0000000000000..c912a4ddabc9d --- /dev/null +++ b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/setup_environment.js @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + notificationServiceMock, + fatalErrorsServiceMock, + docLinksServiceMock, + injectedMetadataServiceMock, +} from '../../../../../../src/core/public/mocks'; + +import { usageCollectionPluginMock } from '../../../../../../src/plugins/usage_collection/public/mocks'; + +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { HttpService } from '../../../../../../src/core/public/http'; + +/* eslint-disable @kbn/eslint/no-restricted-paths */ +import { init as initBreadcrumb } from '../../../public/application/services/breadcrumb'; +import { init as initHttp } from '../../../public/application/services/http'; +import { init as initNotification } from '../../../public/application/services/notification'; +import { init as initUiMetric } from '../../../public/application/services/ui_metric'; +import { init as initDocumentation } from '../../../public/application/services/documentation'; +import { init as initHttpRequests } from './http_requests'; + +export const setupEnvironment = () => { + const httpServiceSetupMock = new HttpService().setup({ + injectedMetadata: injectedMetadataServiceMock.createSetupContract(), + fatalErrors: fatalErrorsServiceMock.createSetupContract(), + }); + + initBreadcrumb(() => {}); + initDocumentation(docLinksServiceMock.createStartContract()); + initUiMetric(usageCollectionPluginMock.createSetupContract()); + initNotification( + notificationServiceMock.createSetupContract().toasts, + fatalErrorsServiceMock.createSetupContract() + ); + initHttp(httpServiceSetupMock); + + const { server, httpRequestsMockHelpers } = initHttpRequests(); + + return { + server, + httpRequestsMockHelpers, + }; +}; diff --git a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/remote_clusters_add.test.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/remote_clusters_add.test.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/remote_clusters_add.test.js rename to x-pack/plugins/remote_clusters/__jest__/client_integration/remote_clusters_add.test.js diff --git a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/remote_clusters_edit.test.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/remote_clusters_edit.test.js similarity index 93% rename from x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/remote_clusters_edit.test.js rename to x-pack/plugins/remote_clusters/__jest__/client_integration/remote_clusters_edit.test.js index 95dc65a96e30a..cab91854a5114 100644 --- a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/remote_clusters_edit.test.js +++ b/x-pack/plugins/remote_clusters/__jest__/client_integration/remote_clusters_edit.test.js @@ -5,7 +5,7 @@ */ jest.mock('ui/new_platform'); -import { RemoteClusterForm } from '../../public/app/sections/components/remote_cluster_form'; +import { RemoteClusterForm } from '../../public/application/sections/components/remote_cluster_form'; import { pageHelpers, setupEnvironment, nextTick } from './helpers'; import { REMOTE_CLUSTER_EDIT, REMOTE_CLUSTER_EDIT_NAME } from './helpers/constants'; @@ -31,7 +31,7 @@ describe('Edit Remote cluster', () => { httpRequestsMockHelpers.setLoadRemoteClustersResponse([REMOTE_CLUSTER_EDIT]); ({ component, find, exists } = setup()); - await nextTick(); + await nextTick(100); // We need to wait next tick for the mock server response to kick in component.update(); }); diff --git a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/remote_clusters_list.test.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/remote_clusters_list.test.js similarity index 96% rename from x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/remote_clusters_list.test.js rename to x-pack/plugins/remote_clusters/__jest__/client_integration/remote_clusters_list.test.js index 699c00e450a1f..1b7c600218cee 100644 --- a/x-pack/legacy/plugins/remote_clusters/__jest__/client_integration/remote_clusters_list.test.js +++ b/x-pack/plugins/remote_clusters/__jest__/client_integration/remote_clusters_list.test.js @@ -12,7 +12,7 @@ import { findTestSubject, } from './helpers'; -import { getRouter } from '../../public/app/services'; +import { getRouter } from '../../public/application/services'; import { getRemoteClusterMock } from '../../fixtures/remote_cluster'; jest.mock('ui/new_platform'); @@ -39,11 +39,11 @@ describe('', () => { describe('on component mount', () => { let exists; - beforeEach(async () => { + beforeEach(() => { ({ exists } = setup()); }); - test('should show a "loading remote clusters" indicator', async () => { + test('should show a "loading remote clusters" indicator', () => { expect(exists('remoteClustersTableLoading')).toBe(true); }); }); @@ -55,7 +55,7 @@ describe('', () => { beforeEach(async () => { ({ exists, component } = setup()); - await nextTick(); // We need to wait next tick for the mock server response to kick in + await nextTick(100); // We need to wait next tick for the mock server response to kick in component.update(); }); @@ -97,7 +97,7 @@ describe('', () => { // Mount the component ({ component, find, exists, table, actions } = setup()); - await nextTick(); // Make sure that the Http request is fulfilled + await nextTick(100); // Make sure that the Http request is fulfilled component.update(); // Read the remote clusters list table @@ -206,7 +206,7 @@ describe('', () => { actions.clickBulkDeleteButton(); actions.clickConfirmModalDeleteRemoteCluster(); - await nextTick(550); // there is a 500ms timeout in the api action + await nextTick(600); // there is a 500ms timeout in the api action component.update(); ({ rows } = table.getMetaData('remoteClusterListTable')); diff --git a/x-pack/legacy/plugins/remote_clusters/fixtures/remote_cluster.js b/x-pack/plugins/remote_clusters/fixtures/remote_cluster.js similarity index 91% rename from x-pack/legacy/plugins/remote_clusters/fixtures/remote_cluster.js rename to x-pack/plugins/remote_clusters/fixtures/remote_cluster.js index 248e2b8232cad..e3e087548cf00 100644 --- a/x-pack/legacy/plugins/remote_clusters/fixtures/remote_cluster.js +++ b/x-pack/plugins/remote_clusters/fixtures/remote_cluster.js @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { getRandomString } from '../../../../test_utils'; +import { getRandomString } from '../../../test_utils'; export const getRemoteClusterMock = ({ name = getRandomString(), diff --git a/x-pack/plugins/remote_clusters/kibana.json b/x-pack/plugins/remote_clusters/kibana.json index de1e3d1e26865..27ae6802966dd 100644 --- a/x-pack/plugins/remote_clusters/kibana.json +++ b/x-pack/plugins/remote_clusters/kibana.json @@ -1,9 +1,17 @@ { "id": "remote_clusters", "version": "kibana", + "configPath": [ + "xpack", + "remote_clusters" + ], "requiredPlugins": [ - "licensing" + "licensing", + "management" + ], + "optionalPlugins": [ + "usageCollection" ], "server": true, - "ui": false + "ui": true } diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/app.js b/x-pack/plugins/remote_clusters/public/application/app.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/app.js rename to x-pack/plugins/remote_clusters/public/application/app.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/constants/index.ts b/x-pack/plugins/remote_clusters/public/application/constants/index.ts similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/constants/index.ts rename to x-pack/plugins/remote_clusters/public/application/constants/index.ts diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/constants/paths.ts b/x-pack/plugins/remote_clusters/public/application/constants/paths.ts similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/constants/paths.ts rename to x-pack/plugins/remote_clusters/public/application/constants/paths.ts diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/constants/ui_metric.ts b/x-pack/plugins/remote_clusters/public/application/constants/ui_metric.ts similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/constants/ui_metric.ts rename to x-pack/plugins/remote_clusters/public/application/constants/ui_metric.ts diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/redirect.js b/x-pack/plugins/remote_clusters/public/application/index.d.ts similarity index 50% rename from x-pack/legacy/plugins/remote_clusters/public/app/services/redirect.js rename to x-pack/plugins/remote_clusters/public/application/index.d.ts index ec77c2a2bfe99..b5c5ad5522134 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/services/redirect.js +++ b/x-pack/plugins/remote_clusters/public/application/index.d.ts @@ -4,14 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -// This depends upon Angular, which is why we use this provider pattern to access it within -// our React app. -let _redirect; +import { RegisterManagementAppArgs, I18nStart } from '../types'; -export function setRedirect(redirect) { - _redirect = redirect; -} - -export function redirect(path) { - _redirect(path); -} +export declare const renderApp: ( + elem: HTMLElement | null, + I18nContext: I18nStart['Context'] +) => ReturnType; diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/index.js b/x-pack/plugins/remote_clusters/public/application/index.js similarity index 80% rename from x-pack/legacy/plugins/remote_clusters/public/app/index.js rename to x-pack/plugins/remote_clusters/public/application/index.js index 2de59f4590553..0b8b26ace5daa 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/index.js +++ b/x-pack/plugins/remote_clusters/public/application/index.js @@ -5,14 +5,14 @@ */ import React from 'react'; -import { render } from 'react-dom'; +import { render, unmountComponentAtNode } from 'react-dom'; import { HashRouter } from 'react-router-dom'; import { Provider } from 'react-redux'; import { App } from './app'; import { remoteClustersStore } from './store'; -export const renderReact = async (elem, I18nContext) => { +export const renderApp = (elem, I18nContext) => { render( @@ -23,4 +23,5 @@ export const renderReact = async (elem, I18nContext) => { , elem ); + return () => unmountComponentAtNode(elem); }; diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/configured_by_node_warning/configured_by_node_warning.js b/x-pack/plugins/remote_clusters/public/application/sections/components/configured_by_node_warning/configured_by_node_warning.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/configured_by_node_warning/configured_by_node_warning.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/configured_by_node_warning/configured_by_node_warning.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/configured_by_node_warning/index.js b/x-pack/plugins/remote_clusters/public/application/sections/components/configured_by_node_warning/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/configured_by_node_warning/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/configured_by_node_warning/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/index.js b/x-pack/plugins/remote_clusters/public/application/sections/components/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/__snapshots__/remote_cluster_form.test.js.snap b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/__snapshots__/remote_cluster_form.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/__snapshots__/remote_cluster_form.test.js.snap rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/__snapshots__/remote_cluster_form.test.js.snap diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/index.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/remote_cluster_form.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/remote_cluster_form.js similarity index 99% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/remote_cluster_form.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/remote_cluster_form.js index f070bb218be42..08cd01496a8b9 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/remote_cluster_form.js +++ b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/remote_cluster_form.js @@ -491,7 +491,7 @@ export class RemoteClusterForm extends Component { let errorBody; - if (cause) { + if (cause && Array.isArray(cause)) { if (cause.length === 1) { errorBody =

{cause[0]}

; } else { diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/remote_cluster_form.test.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/remote_cluster_form.test.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/remote_cluster_form.test.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/remote_cluster_form.test.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/request_flyout.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/request_flyout.js similarity index 97% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/request_flyout.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/request_flyout.js index deec26129abe5..70e2267001e3c 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/request_flyout.js +++ b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/request_flyout.js @@ -26,7 +26,7 @@ import { EuiTitle, } from '@elastic/eui'; -import { serializeCluster } from '../../../../../common'; +import { serializeCluster } from '../../../../../common/constants'; export class RequestFlyout extends PureComponent { static propTypes = { diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/__snapshots__/validate_name.test.js.snap b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/__snapshots__/validate_name.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/__snapshots__/validate_name.test.js.snap rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/__snapshots__/validate_name.test.js.snap diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/__snapshots__/validate_seeds.test.js.snap b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/__snapshots__/validate_seeds.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/__snapshots__/validate_seeds.test.js.snap rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/__snapshots__/validate_seeds.test.js.snap diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/index.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/validate_name.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/validate_name.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/validate_name.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/validate_name.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/validate_name.test.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/validate_name.test.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/validate_name.test.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/validate_name.test.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/validate_seed.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/validate_seed.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/validate_seed.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/validate_seed.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/validate_seed.test.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/validate_seed.test.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/validate_seed.test.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/validate_seed.test.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/validate_seeds.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/validate_seeds.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/validate_seeds.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/validate_seeds.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/validate_seeds.test.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/validate_seeds.test.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_form/validators/validate_seeds.test.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_form/validators/validate_seeds.test.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_page_title/index.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_page_title/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_page_title/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_page_title/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_page_title/remote_cluster_page_title.js b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_page_title/remote_cluster_page_title.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/components/remote_cluster_page_title/remote_cluster_page_title.js rename to x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_page_title/remote_cluster_page_title.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/index.js b/x-pack/plugins/remote_clusters/public/application/sections/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_add/index.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_add/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_add/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_add/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_add/remote_cluster_add.container.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_add/remote_cluster_add.container.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_add/remote_cluster_add.container.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_add/remote_cluster_add.container.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_add/remote_cluster_add.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_add/remote_cluster_add.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_add/remote_cluster_add.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_add/remote_cluster_add.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_edit/index.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_edit/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_edit/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_edit/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_edit/remote_cluster_edit.container.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_edit/remote_cluster_edit.container.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_edit/remote_cluster_edit.container.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_edit/remote_cluster_edit.container.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_edit/remote_cluster_edit.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_edit/remote_cluster_edit.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_edit/remote_cluster_edit.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_edit/remote_cluster_edit.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/connection_status/connection_status.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/components/connection_status/connection_status.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/connection_status/connection_status.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/components/connection_status/connection_status.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/connection_status/index.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/components/connection_status/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/connection_status/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/components/connection_status/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/index.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/components/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/components/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/remove_cluster_button_provider/index.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/components/remove_cluster_button_provider/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/remove_cluster_button_provider/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/components/remove_cluster_button_provider/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/remove_cluster_button_provider/remove_cluster_button_provider.container.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/components/remove_cluster_button_provider/remove_cluster_button_provider.container.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/remove_cluster_button_provider/remove_cluster_button_provider.container.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/components/remove_cluster_button_provider/remove_cluster_button_provider.container.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/remove_cluster_button_provider/remove_cluster_button_provider.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/components/remove_cluster_button_provider/remove_cluster_button_provider.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/components/remove_cluster_button_provider/remove_cluster_button_provider.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/components/remove_cluster_button_provider/remove_cluster_button_provider.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/detail_panel/detail_panel.container.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/detail_panel/detail_panel.container.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/detail_panel/detail_panel.container.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/detail_panel/detail_panel.container.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/detail_panel/detail_panel.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/detail_panel/detail_panel.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/detail_panel/detail_panel.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/detail_panel/detail_panel.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/detail_panel/index.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/detail_panel/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/detail_panel/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/detail_panel/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/index.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/remote_cluster_list.container.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_list.container.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/remote_cluster_list.container.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_list.container.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/remote_cluster_list.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_list.js similarity index 98% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/remote_cluster_list.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_list.js index dea6bc7627cc1..207aa8045c011 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/remote_cluster_list.js +++ b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_list.js @@ -145,9 +145,9 @@ export class RemoteClusterList extends Component { } renderError(error) { - // We can safely depend upon the shape of this error coming from Angular $http, because we + // We can safely depend upon the shape of this error coming from http service, because we // handle unexpected error shapes in the API action. - const { statusCode, error: errorString } = error.data; + const { statusCode, error: errorString } = error.body; const title = i18n.translate('xpack.remoteClusters.remoteClusterList.loadingErrorTitle', { defaultMessage: 'Error loading remote clusters', diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/remote_cluster_table/index.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_table/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/remote_cluster_table/index.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_table/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/remote_cluster_table/remote_cluster_table.container.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_table/remote_cluster_table.container.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/remote_cluster_table/remote_cluster_table.container.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_table/remote_cluster_table.container.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/remote_cluster_table/remote_cluster_table.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_table/remote_cluster_table.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/sections/remote_cluster_list/remote_cluster_table/remote_cluster_table.js rename to x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_table/remote_cluster_table.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/api.js b/x-pack/plugins/remote_clusters/public/application/services/api.js similarity index 93% rename from x-pack/legacy/plugins/remote_clusters/public/app/services/api.js rename to x-pack/plugins/remote_clusters/public/application/services/api.js index 8631bc5af12a8..72d5e3f9c3f9e 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/services/api.js +++ b/x-pack/plugins/remote_clusters/public/application/services/api.js @@ -9,19 +9,19 @@ import { trackUserRequest } from './ui_metric'; import { sendGet, sendPost, sendPut, sendDelete } from './http'; export async function loadClusters() { - const response = await sendGet(); - return response.data; + return await sendGet(); } export async function addCluster(cluster) { const request = sendPost('', cluster); + return await trackUserRequest(request, UIM_CLUSTER_ADD); } export async function editCluster(cluster) { const { name, ...rest } = cluster; - const request = sendPut(name, rest); + return await trackUserRequest(request, UIM_CLUSTER_UPDATE); } diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/api_errors.js b/x-pack/plugins/remote_clusters/public/application/services/api_errors.js similarity index 77% rename from x-pack/legacy/plugins/remote_clusters/public/app/services/api_errors.js rename to x-pack/plugins/remote_clusters/public/application/services/api_errors.js index c50ad92532071..8376f37f36f49 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/services/api_errors.js +++ b/x-pack/plugins/remote_clusters/public/application/services/api_errors.js @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fatalError, toasts } from './notification'; +import { toasts, fatalError } from './notification'; function createToastConfig(error, errorTitle) { - // Expect an error in the shape provided by Angular's $http service. - if (error && error.data) { - const { error: errorString, statusCode, message } = error.data; + // Expect an error in the shape provided by http service. + if (error && error.body) { + const { error: errorString, statusCode, message } = error.body; return { title: errorTitle, text: `${statusCode}: ${errorString}. ${message}`, @@ -26,7 +26,7 @@ export function showApiWarning(error, errorTitle) { // This error isn't an HTTP error, so let the fatal error screen tell the user something // unexpected happened. - return fatalError(error, errorTitle); + return fatalError.add(error, errorTitle); } export function showApiError(error, errorTitle) { @@ -38,5 +38,5 @@ export function showApiError(error, errorTitle) { // This error isn't an HTTP error, so let the fatal error screen tell the user something // unexpected happened. - fatalError(error, errorTitle); + fatalError.add(error, errorTitle); } diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/breadcrumb.ts b/x-pack/plugins/remote_clusters/public/application/services/breadcrumb.ts similarity index 68% rename from x-pack/legacy/plugins/remote_clusters/public/app/services/breadcrumb.ts rename to x-pack/plugins/remote_clusters/public/application/services/breadcrumb.ts index 68d34cc2a17d4..f90a0d3456166 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/services/breadcrumb.ts +++ b/x-pack/plugins/remote_clusters/public/application/services/breadcrumb.ts @@ -8,13 +8,22 @@ import { i18n } from '@kbn/i18n'; import { CRUD_APP_BASE_PATH } from '../constants'; -let _setBreadcrumbs: any; -let _breadcrumbs: any; +interface Breadcrumb { + text: string; + href?: string; +} +interface Breadcrumbs { + home: Breadcrumb; + add: Breadcrumb; + edit: Breadcrumb; +} + +let _setBreadcrumbs: (breadcrumbs: Breadcrumb[]) => void; +let _breadcrumbs: Breadcrumbs; -export function init(setGlobalBreadcrumbs: any, managementBreadcrumb: any): void { +export function init(setGlobalBreadcrumbs: (breadcrumbs: Breadcrumb[]) => void): void { _setBreadcrumbs = setGlobalBreadcrumbs; _breadcrumbs = { - management: managementBreadcrumb, home: { text: i18n.translate('xpack.remoteClusters.listBreadcrumbTitle', { defaultMessage: 'Remote Clusters', @@ -34,13 +43,13 @@ export function init(setGlobalBreadcrumbs: any, managementBreadcrumb: any): void }; } -export function setBreadcrumbs(type: string, queryParams?: string): void { +export function setBreadcrumbs(type: 'home' | 'add' | 'edit', queryParams?: string): void { if (!_breadcrumbs[type]) { return; } if (type === 'home') { - _setBreadcrumbs([_breadcrumbs.management, _breadcrumbs.home]); + _setBreadcrumbs([_breadcrumbs.home]); } else { // Support deep-linking back to a remote cluster in the detail panel. const homeBreadcrumb = { @@ -48,6 +57,6 @@ export function setBreadcrumbs(type: string, queryParams?: string): void { href: `${_breadcrumbs.home.href}${queryParams}`, }; - _setBreadcrumbs([_breadcrumbs.management, homeBreadcrumb, _breadcrumbs[type]]); + _setBreadcrumbs([homeBreadcrumb, _breadcrumbs[type]]); } } diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/documentation.ts b/x-pack/plugins/remote_clusters/public/application/services/documentation.ts similarity index 70% rename from x-pack/legacy/plugins/remote_clusters/public/app/services/documentation.ts rename to x-pack/plugins/remote_clusters/public/application/services/documentation.ts index 4d04aa6fad74d..38cf2223a313b 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/services/documentation.ts +++ b/x-pack/plugins/remote_clusters/public/application/services/documentation.ts @@ -4,11 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ +import { DocLinksStart } from 'kibana/public'; + export let skippingDisconnectedClustersUrl: string; export let remoteClustersUrl: string; export let transportPortUrl: string; -export function init(esDocBasePath: string): void { +export function init(docLinks: DocLinksStart): void { + const { DOC_LINK_VERSION, ELASTIC_WEBSITE_URL } = docLinks; + const esDocBasePath = `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}`; + skippingDisconnectedClustersUrl = `${esDocBasePath}/modules-cross-cluster-search.html#_skipping_disconnected_clusters`; remoteClustersUrl = `${esDocBasePath}/modules-remote-clusters.html`; transportPortUrl = `${esDocBasePath}/modules-transport.html`; diff --git a/x-pack/plugins/remote_clusters/public/application/services/http.ts b/x-pack/plugins/remote_clusters/public/application/services/http.ts new file mode 100644 index 0000000000000..b49e95f3a5c65 --- /dev/null +++ b/x-pack/plugins/remote_clusters/public/application/services/http.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { HttpSetup, HttpResponse } from 'kibana/public'; +import { API_BASE_PATH } from '../../../common/constants'; + +let _httpClient: HttpSetup; + +export function init(httpClient: HttpSetup): void { + _httpClient = httpClient; +} + +export function getFullPath(path: string): string { + if (path) { + return `${API_BASE_PATH}/${path}`; + } + + return API_BASE_PATH; +} + +export function sendPost( + path: string, + payload: { + name: string; + seeds: string[]; + skipUnavailable: boolean; + } +): Promise { + return _httpClient.post(getFullPath(path), { + body: JSON.stringify(payload), + }); +} + +export function sendGet(path: string): Promise { + return _httpClient.get(getFullPath(path)); +} + +export function sendPut( + path: string, + payload: { + seeds: string[]; + skipUnavailable: boolean; + } +): Promise { + return _httpClient.put(getFullPath(path), { + body: JSON.stringify(payload), + }); +} + +export function sendDelete(path: string): Promise { + return _httpClient.delete(getFullPath(path)); +} diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/index.js b/x-pack/plugins/remote_clusters/public/application/services/index.js similarity index 93% rename from x-pack/legacy/plugins/remote_clusters/public/app/services/index.js rename to x-pack/plugins/remote_clusters/public/application/services/index.js index 69679e55dfef5..031770d9500ed 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/services/index.js +++ b/x-pack/plugins/remote_clusters/public/application/services/index.js @@ -8,7 +8,7 @@ export { loadClusters, addCluster, editCluster, removeClusterRequest } from './a export { showApiError, showApiWarning } from './api_errors'; -export { setRedirect, redirect } from './redirect'; +export { initRedirect, redirect } from './redirect'; export { isSeedNodeValid, isSeedNodePortValid } from './validate_seed_node'; diff --git a/x-pack/plugins/remote_clusters/public/application/services/notification.ts b/x-pack/plugins/remote_clusters/public/application/services/notification.ts new file mode 100644 index 0000000000000..1c9173e519b48 --- /dev/null +++ b/x-pack/plugins/remote_clusters/public/application/services/notification.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { NotificationsSetup, FatalErrorsSetup } from 'src/core/public'; + +export let toasts: NotificationsSetup['toasts']; +export let fatalError: FatalErrorsSetup; + +export function init(_toasts: NotificationsSetup['toasts'], _fatalError: FatalErrorsSetup): void { + toasts = _toasts; + fatalError = _fatalError; +} diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/query_params.js b/x-pack/plugins/remote_clusters/public/application/services/query_params.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/services/query_params.js rename to x-pack/plugins/remote_clusters/public/application/services/query_params.js diff --git a/x-pack/plugins/remote_clusters/public/application/services/redirect.ts b/x-pack/plugins/remote_clusters/public/application/services/redirect.ts new file mode 100644 index 0000000000000..00a97fa74c5ce --- /dev/null +++ b/x-pack/plugins/remote_clusters/public/application/services/redirect.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CoreStart } from 'kibana/public'; + +let navigateToApp: CoreStart['application']['navigateToApp']; + +export function init(_navigateToApp: CoreStart['application']['navigateToApp']) { + navigateToApp = _navigateToApp; +} + +export function redirect(path: string) { + navigateToApp('kibana', { path: `#${path}` }); +} diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/routing.js b/x-pack/plugins/remote_clusters/public/application/services/routing.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/services/routing.js rename to x-pack/plugins/remote_clusters/public/application/services/routing.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/ui_metric.ts b/x-pack/plugins/remote_clusters/public/application/services/ui_metric.ts similarity index 62% rename from x-pack/legacy/plugins/remote_clusters/public/app/services/ui_metric.ts rename to x-pack/plugins/remote_clusters/public/application/services/ui_metric.ts index 36a23476c1873..91354155cacb0 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/services/ui_metric.ts +++ b/x-pack/plugins/remote_clusters/public/application/services/ui_metric.ts @@ -4,17 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ +import { UsageCollectionSetup } from 'src/plugins/usage_collection/public'; +import { UiStatsMetricType } from '@kbn/analytics'; import { UIM_APP_NAME } from '../constants'; -import { - createUiStatsReporter, - METRIC_TYPE, -} from '../../../../../../../src/legacy/core_plugins/ui_metric/public'; -export let trackUiMetric: ReturnType; -export { METRIC_TYPE }; +export let trackUiMetric: (metricType: UiStatsMetricType, eventName: string) => void; +export let METRIC_TYPE: UsageCollectionSetup['METRIC_TYPE']; -export function init(getReporter: typeof createUiStatsReporter): void { - trackUiMetric = getReporter(UIM_APP_NAME); +export function init(usageCollection: UsageCollectionSetup): void { + trackUiMetric = usageCollection.reportUiStats.bind(usageCollection, UIM_APP_NAME); + METRIC_TYPE = usageCollection.METRIC_TYPE; } /** diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/validate_seed_node.js b/x-pack/plugins/remote_clusters/public/application/services/validate_seed_node.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/services/validate_seed_node.js rename to x-pack/plugins/remote_clusters/public/application/services/validate_seed_node.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/validate_seed_node.test.js b/x-pack/plugins/remote_clusters/public/application/services/validate_seed_node.test.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/services/validate_seed_node.test.js rename to x-pack/plugins/remote_clusters/public/application/services/validate_seed_node.test.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/action_types.js b/x-pack/plugins/remote_clusters/public/application/store/action_types.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/action_types.js rename to x-pack/plugins/remote_clusters/public/application/store/action_types.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/actions/add_cluster.js b/x-pack/plugins/remote_clusters/public/application/store/actions/add_cluster.js similarity index 88% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/actions/add_cluster.js rename to x-pack/plugins/remote_clusters/public/application/store/actions/add_cluster.js index 726bc56b08f12..0b7838f48b137 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/store/actions/add_cluster.js +++ b/x-pack/plugins/remote_clusters/public/application/store/actions/add_cluster.js @@ -35,12 +35,12 @@ export const addCluster = cluster => async dispatch => { ]); } catch (error) { if (error) { - const { statusCode, data } = error; + const { body } = error; - // Expect an error in the shape provided by Angular's $http service. - if (data) { - // Some errors have statusCode directly available but some are under a data property. - if ((statusCode || (data && data.statusCode)) === 409) { + // Expect an error in the shape provided by http service. + if (body) { + const { statusCode, message } = body; + if (statusCode && statusCode === 409) { return dispatch({ type: ADD_CLUSTER_FAILURE, payload: { @@ -63,9 +63,8 @@ export const addCluster = cluster => async dispatch => { error: { message: i18n.translate('xpack.remoteClusters.addAction.failedDefaultErrorMessage', { defaultMessage: 'Request failed with a {statusCode} error. {message}', - values: { statusCode, message: data.message }, + values: { statusCode, message }, }), - cause: data.cause, }, }, }); @@ -74,7 +73,7 @@ export const addCluster = cluster => async dispatch => { // This error isn't an HTTP error, so let the fatal error screen tell the user something // unexpected happened. - return fatalError( + return fatalError.add( error, i18n.translate('xpack.remoteClusters.addAction.errorTitle', { defaultMessage: 'Error adding cluster', diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/actions/detail_panel.js b/x-pack/plugins/remote_clusters/public/application/store/actions/detail_panel.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/actions/detail_panel.js rename to x-pack/plugins/remote_clusters/public/application/store/actions/detail_panel.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/actions/edit_cluster.js b/x-pack/plugins/remote_clusters/public/application/store/actions/edit_cluster.js similarity index 90% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/actions/edit_cluster.js rename to x-pack/plugins/remote_clusters/public/application/store/actions/edit_cluster.js index 3ed481aa0f8ea..062704472521e 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/store/actions/edit_cluster.js +++ b/x-pack/plugins/remote_clusters/public/application/store/actions/edit_cluster.js @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; -import { fatalError, toasts } from '../../services/notification'; +import { toasts, fatalError } from '../../services/notification'; import { CRUD_APP_BASE_PATH } from '../../constants'; import { loadClusters } from './load_clusters'; @@ -39,19 +39,19 @@ export const editCluster = cluster => async dispatch => { ]); } catch (error) { if (error) { - const { statusCode, data } = error; + const { body } = error; - // Expect an error in the shape provided by Angular's $http service. - if (data) { + // Expect an error in the shape provided by http service. + if (body) { + const { statusCode, message } = body; return dispatch({ type: EDIT_CLUSTER_FAILURE, payload: { error: { message: i18n.translate('xpack.remoteClusters.editAction.failedDefaultErrorMessage', { defaultMessage: 'Request failed with a {statusCode} error. {message}', - values: { statusCode, message: data.message }, + values: { statusCode, message }, }), - cause: data.cause, }, }, }); @@ -60,7 +60,7 @@ export const editCluster = cluster => async dispatch => { // This error isn't an HTTP error, so let the fatal error screen tell the user something // unexpected happened. - return fatalError( + return fatalError.add( error, i18n.translate('xpack.remoteClusters.editAction.errorTitle', { defaultMessage: 'Error editing cluster', diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/actions/index.js b/x-pack/plugins/remote_clusters/public/application/store/actions/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/actions/index.js rename to x-pack/plugins/remote_clusters/public/application/store/actions/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/actions/load_clusters.js b/x-pack/plugins/remote_clusters/public/application/store/actions/load_clusters.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/actions/load_clusters.js rename to x-pack/plugins/remote_clusters/public/application/store/actions/load_clusters.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/actions/refresh_clusters.js b/x-pack/plugins/remote_clusters/public/application/store/actions/refresh_clusters.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/actions/refresh_clusters.js rename to x-pack/plugins/remote_clusters/public/application/store/actions/refresh_clusters.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/actions/remove_clusters.js b/x-pack/plugins/remote_clusters/public/application/store/actions/remove_clusters.js similarity index 95% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/actions/remove_clusters.js rename to x-pack/plugins/remote_clusters/public/application/store/actions/remove_clusters.js index 4086a91e29021..8e22eac8b292b 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/store/actions/remove_clusters.js +++ b/x-pack/plugins/remote_clusters/public/application/store/actions/remove_clusters.js @@ -30,7 +30,7 @@ function getErrorTitle(count, name = null) { } } else { return i18n.translate('xpack.remoteClusters.removeAction.errorMultipleNotificationTitle', { - defaultMessage: `Error removing '{count}' remote clusters`, + defaultMessage: `Error removing {count} remote clusters`, values: { count }, }); } @@ -46,7 +46,7 @@ export const removeClusters = names => async (dispatch, getState) => { await Promise.all([ sendRemoveClusterRequest(names.join(',')).then(response => { - ({ itemsDeleted, errors } = response.data); + ({ itemsDeleted, errors } = response); }), // Wait at least half a second to avoid a weird flicker of the saving feedback (only visible // when requests resolve very quickly). @@ -55,7 +55,7 @@ export const removeClusters = names => async (dispatch, getState) => { const errorTitle = getErrorTitle(names.length, names[0]); toasts.addDanger({ title: errorTitle, - text: error.data.message, + text: error.body?.message, }); }); diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/index.js b/x-pack/plugins/remote_clusters/public/application/store/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/index.js rename to x-pack/plugins/remote_clusters/public/application/store/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/middleware/detail_panel.js b/x-pack/plugins/remote_clusters/public/application/store/middleware/detail_panel.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/middleware/detail_panel.js rename to x-pack/plugins/remote_clusters/public/application/store/middleware/detail_panel.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/middleware/index.js b/x-pack/plugins/remote_clusters/public/application/store/middleware/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/middleware/index.js rename to x-pack/plugins/remote_clusters/public/application/store/middleware/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/reducers/add_cluster.js b/x-pack/plugins/remote_clusters/public/application/store/reducers/add_cluster.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/reducers/add_cluster.js rename to x-pack/plugins/remote_clusters/public/application/store/reducers/add_cluster.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/reducers/clusters.js b/x-pack/plugins/remote_clusters/public/application/store/reducers/clusters.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/reducers/clusters.js rename to x-pack/plugins/remote_clusters/public/application/store/reducers/clusters.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/reducers/detail_panel.js b/x-pack/plugins/remote_clusters/public/application/store/reducers/detail_panel.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/reducers/detail_panel.js rename to x-pack/plugins/remote_clusters/public/application/store/reducers/detail_panel.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/reducers/edit_cluster.js b/x-pack/plugins/remote_clusters/public/application/store/reducers/edit_cluster.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/reducers/edit_cluster.js rename to x-pack/plugins/remote_clusters/public/application/store/reducers/edit_cluster.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/reducers/index.js b/x-pack/plugins/remote_clusters/public/application/store/reducers/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/reducers/index.js rename to x-pack/plugins/remote_clusters/public/application/store/reducers/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/reducers/remove_cluster.js b/x-pack/plugins/remote_clusters/public/application/store/reducers/remove_cluster.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/reducers/remove_cluster.js rename to x-pack/plugins/remote_clusters/public/application/store/reducers/remove_cluster.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/selectors/index.js b/x-pack/plugins/remote_clusters/public/application/store/selectors/index.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/selectors/index.js rename to x-pack/plugins/remote_clusters/public/application/store/selectors/index.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/store/store.js b/x-pack/plugins/remote_clusters/public/application/store/store.js similarity index 100% rename from x-pack/legacy/plugins/remote_clusters/public/app/store/store.js rename to x-pack/plugins/remote_clusters/public/application/store/store.js diff --git a/x-pack/legacy/plugins/remote_clusters/public/app/services/notification.ts b/x-pack/plugins/remote_clusters/public/index.ts similarity index 59% rename from x-pack/legacy/plugins/remote_clusters/public/app/services/notification.ts rename to x-pack/plugins/remote_clusters/public/index.ts index 1ac329253cddb..dbe22b71b48df 100644 --- a/x-pack/legacy/plugins/remote_clusters/public/app/services/notification.ts +++ b/x-pack/plugins/remote_clusters/public/index.ts @@ -3,11 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { RemoteClustersUIPlugin } from './plugin'; -export let toasts: any; -export let fatalError: any; - -export function init(_toasts: any, _fatalError: any): void { - toasts = _toasts; - fatalError = _fatalError; -} +export const plugin = () => new RemoteClustersUIPlugin(); diff --git a/x-pack/plugins/remote_clusters/public/plugin.ts b/x-pack/plugins/remote_clusters/public/plugin.ts new file mode 100644 index 0000000000000..5b84fa1fde369 --- /dev/null +++ b/x-pack/plugins/remote_clusters/public/plugin.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { CoreSetup, Plugin, CoreStart } from 'kibana/public'; +import { init as initBreadcrumbs } from './application/services/breadcrumb'; +import { init as initDocumentation } from './application/services/documentation'; +import { init as initHttp } from './application/services/http'; +import { init as initUiMetric } from './application/services/ui_metric'; +import { init as initNotification } from './application/services/notification'; +import { init as initRedirect } from './application/services/redirect'; +import { Dependencies } from './types'; + +export class RemoteClustersUIPlugin implements Plugin { + setup( + { notifications: { toasts }, http, getStartServices }: CoreSetup, + { management, usageCollection }: Dependencies + ) { + const esSection = management.sections.getSection('elasticsearch'); + + esSection!.registerApp({ + id: 'remote_clusters', + title: i18n.translate('xpack.remoteClusters.appTitle', { + defaultMessage: 'Remote Clusters', + }), + mount: async ({ element, setBreadcrumbs }) => { + const [core] = await getStartServices(); + const { + i18n: { Context: i18nContext }, + docLinks, + fatalErrors, + } = core; + + // Initialize services + initBreadcrumbs(setBreadcrumbs); + initDocumentation(docLinks); + initUiMetric(usageCollection); + initNotification(toasts, fatalErrors); + initHttp(http); + + const { renderApp } = await import('./application'); + return renderApp(element, i18nContext); + }, + }); + } + + start({ application }: CoreStart) { + initRedirect(application.navigateToApp); + } + + stop() {} +} diff --git a/x-pack/plugins/remote_clusters/public/types.ts b/x-pack/plugins/remote_clusters/public/types.ts new file mode 100644 index 0000000000000..45ae90f91587a --- /dev/null +++ b/x-pack/plugins/remote_clusters/public/types.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ManagementSetup } from 'src/plugins/management/public'; +import { UsageCollectionSetup } from 'src/plugins/usage_collection/public'; +import { RegisterManagementAppArgs } from 'src/plugins/management/public'; +import { I18nStart } from 'kibana/public'; + +export interface Dependencies { + management: ManagementSetup; + usageCollection: UsageCollectionSetup; +} + +export { RegisterManagementAppArgs }; + +export { I18nStart }; diff --git a/x-pack/plugins/remote_clusters/server/config.ts b/x-pack/plugins/remote_clusters/server/config.ts new file mode 100644 index 0000000000000..9525fe1e2a0db --- /dev/null +++ b/x-pack/plugins/remote_clusters/server/config.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { PluginConfigDescriptor } from 'kibana/server'; + +export const configSchema = schema.object({ + enabled: schema.boolean({ defaultValue: true }), +}); + +export type ConfigType = TypeOf; + +export const config: PluginConfigDescriptor = { + schema: configSchema, + exposeToBrowser: { + enabled: true, + }, +}; diff --git a/x-pack/plugins/remote_clusters/server/index.ts b/x-pack/plugins/remote_clusters/server/index.ts index 896161d82919b..927fa768fc9fd 100644 --- a/x-pack/plugins/remote_clusters/server/index.ts +++ b/x-pack/plugins/remote_clusters/server/index.ts @@ -6,4 +6,6 @@ import { PluginInitializerContext } from 'kibana/server'; import { RemoteClustersServerPlugin } from './plugin'; +export { config } from './config'; + export const plugin = (ctx: PluginInitializerContext) => new RemoteClustersServerPlugin(ctx); diff --git a/x-pack/plugins/remote_clusters/server/plugin.ts b/x-pack/plugins/remote_clusters/server/plugin.ts index dd0bb536d2695..d15ae44c8d5db 100644 --- a/x-pack/plugins/remote_clusters/server/plugin.ts +++ b/x-pack/plugins/remote_clusters/server/plugin.ts @@ -6,10 +6,12 @@ import { i18n } from '@kbn/i18n'; import { CoreSetup, Logger, Plugin, PluginInitializerContext } from 'src/core/server'; -import { PLUGIN } from '../common/constants'; +import { Observable } from 'rxjs'; import { LICENSE_CHECK_STATE } from '../../licensing/common/types'; -import { Dependencies, LicenseStatus, RouteDependencies } from './types'; +import { PLUGIN } from '../common/constants'; +import { Dependencies, LicenseStatus, RouteDependencies } from './types'; +import { ConfigType } from './config'; import { registerGetRoute, registerAddRoute, @@ -20,9 +22,11 @@ import { export class RemoteClustersServerPlugin implements Plugin { licenseStatus: LicenseStatus; log: Logger; + config: Observable; - constructor({ logger }: PluginInitializerContext) { + constructor({ logger, config }: PluginInitializerContext) { this.log = logger.get(); + this.config = config.create(); this.licenseStatus = { valid: false }; } diff --git a/x-pack/plugins/remote_clusters/server/routes/api/add_route.ts b/x-pack/plugins/remote_clusters/server/routes/api/add_route.ts index aa09b6bf45667..e4ede01ca23ea 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/add_route.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/add_route.ts @@ -38,8 +38,7 @@ export const register = (deps: RouteDependencies): void => { // Check if cluster already exists. const existingCluster = await doesClusterExist(callAsCurrentUser, name); if (existingCluster) { - return response.customError({ - statusCode: 409, + return response.conflict({ body: { message: i18n.translate( 'xpack.remoteClusters.addRemoteCluster.existingRemoteClusterErrorMessage', diff --git a/x-pack/plugins/remote_clusters/server/routes/api/update_route.ts b/x-pack/plugins/remote_clusters/server/routes/api/update_route.ts index fd707f15ad11e..ed584307d84c1 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/update_route.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/update_route.ts @@ -44,8 +44,7 @@ export const register = (deps: RouteDependencies): void => { // Check if cluster does exist. const existingCluster = await doesClusterExist(callAsCurrentUser, name); if (!existingCluster) { - return response.customError({ - statusCode: 404, + return response.notFound({ body: { message: i18n.translate( 'xpack.remoteClusters.updateRemoteCluster.noRemoteClusterErrorMessage', diff --git a/x-pack/plugins/security/public/plugin.tsx b/x-pack/plugins/security/public/plugin.tsx index f1ac2e2ecc3e2..467f86bd1ac69 100644 --- a/x-pack/plugins/security/public/plugin.tsx +++ b/x-pack/plugins/security/public/plugin.tsx @@ -57,13 +57,14 @@ export class SecurityPlugin { home, licensing, management }: PluginSetupDependencies ) { const { http, notifications, injectedMetadata } = core; - const { basePath, anonymousPaths } = http; + const { anonymousPaths } = http; anonymousPaths.register('/login'); anonymousPaths.register('/logout'); anonymousPaths.register('/logged_out'); - const tenant = `${injectedMetadata.getInjectedVar('session.tenant', '')}`; - const sessionExpired = new SessionExpired(basePath, tenant); + const tenant = injectedMetadata.getInjectedVar('session.tenant', '') as string; + const logoutUrl = injectedMetadata.getInjectedVar('logoutUrl') as string; + const sessionExpired = new SessionExpired(logoutUrl, tenant); http.intercept(new UnauthorizedResponseHttpInterceptor(sessionExpired, anonymousPaths)); this.sessionTimeout = new SessionTimeout(notifications, sessionExpired, http, tenant); http.intercept(new SessionTimeoutHttpInterceptor(this.sessionTimeout, anonymousPaths)); diff --git a/x-pack/plugins/security/public/session/session_expired.test.ts b/x-pack/plugins/security/public/session/session_expired.test.ts index 678c397dfbc64..f5ad9cb464e3e 100644 --- a/x-pack/plugins/security/public/session/session_expired.test.ts +++ b/x-pack/plugins/security/public/session/session_expired.test.ts @@ -4,11 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { coreMock } from 'src/core/public/mocks'; import { SessionExpired } from './session_expired'; -describe('Session Expiration', () => { +describe('#logout', () => { const mockGetItem = jest.fn().mockReturnValue(null); + const CURRENT_URL = '/foo/bar?baz=quz#quuz'; + const LOGOUT_URL = '/logout'; + const TENANT = '/some-basepath'; + + let newUrlPromise: Promise; beforeAll(() => { Object.defineProperty(window, 'sessionStorage', { @@ -19,69 +23,42 @@ describe('Session Expiration', () => { }); }); + beforeEach(() => { + window.history.pushState({}, '', CURRENT_URL); + mockGetItem.mockReset(); + newUrlPromise = new Promise(resolve => { + jest.spyOn(window.location, 'assign').mockImplementation(url => { + resolve(url); + }); + }); + }); + afterAll(() => { delete (window as any).sessionStorage; }); - describe('logout', () => { - const mockCurrentUrl = (url: string) => window.history.pushState({}, '', url); - const tenant = ''; - - it('redirects user to "/logout" when there is no basePath', async () => { - const { basePath } = coreMock.createSetup().http; - mockCurrentUrl('/foo/bar?baz=quz#quuz'); - const sessionExpired = new SessionExpired(basePath, tenant); - const newUrlPromise = new Promise(resolve => { - jest.spyOn(window.location, 'assign').mockImplementation(url => { - resolve(url); - }); - }); - - sessionExpired.logout(); + it(`redirects user to the logout URL with 'msg' and 'next' parameters`, async () => { + const sessionExpired = new SessionExpired(LOGOUT_URL, TENANT); + sessionExpired.logout(); - const url = await newUrlPromise; - expect(url).toBe( - `/logout?next=${encodeURIComponent('/foo/bar?baz=quz#quuz')}&msg=SESSION_EXPIRED` - ); - }); - - it('adds a provider parameter when an auth provider is saved in sessionStorage', async () => { - const { basePath } = coreMock.createSetup().http; - mockCurrentUrl('/foo/bar?baz=quz#quuz'); - const sessionExpired = new SessionExpired(basePath, tenant); - const newUrlPromise = new Promise(resolve => { - jest.spyOn(window.location, 'assign').mockImplementation(url => { - resolve(url); - }); - }); - mockGetItem.mockReturnValueOnce('basic'); - - sessionExpired.logout(); + const next = `&next=${encodeURIComponent(CURRENT_URL)}`; + await expect(newUrlPromise).resolves.toBe(`${LOGOUT_URL}?msg=SESSION_EXPIRED${next}`); + }); - const url = await newUrlPromise; - expect(url).toBe( - `/logout?next=${encodeURIComponent( - '/foo/bar?baz=quz#quuz' - )}&msg=SESSION_EXPIRED&provider=basic` - ); - }); + it(`adds 'provider' parameter when sessionStorage contains the provider name for this tenant`, async () => { + const providerName = 'basic'; + mockGetItem.mockReturnValueOnce(providerName); - it('redirects user to "/${basePath}/logout" and removes basePath from next parameter when there is a basePath', async () => { - const { basePath } = coreMock.createSetup({ basePath: '/foo' }).http; - mockCurrentUrl('/foo/bar?baz=quz#quuz'); - const sessionExpired = new SessionExpired(basePath, tenant); - const newUrlPromise = new Promise(resolve => { - jest.spyOn(window.location, 'assign').mockImplementation(url => { - resolve(url); - }); - }); + const sessionExpired = new SessionExpired(LOGOUT_URL, TENANT); + sessionExpired.logout(); - sessionExpired.logout(); + expect(mockGetItem).toHaveBeenCalledTimes(1); + expect(mockGetItem).toHaveBeenCalledWith(`${TENANT}/session_provider`); - const url = await newUrlPromise; - expect(url).toBe( - `/foo/logout?next=${encodeURIComponent('/bar?baz=quz#quuz')}&msg=SESSION_EXPIRED` - ); - }); + const next = `&next=${encodeURIComponent(CURRENT_URL)}`; + const provider = `&provider=${providerName}`; + await expect(newUrlPromise).resolves.toBe( + `${LOGOUT_URL}?msg=SESSION_EXPIRED${next}${provider}` + ); }); }); diff --git a/x-pack/plugins/security/public/session/session_expired.ts b/x-pack/plugins/security/public/session/session_expired.ts index a43da85526757..5866526b8851e 100644 --- a/x-pack/plugins/security/public/session/session_expired.ts +++ b/x-pack/plugins/security/public/session/session_expired.ts @@ -4,26 +4,28 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HttpSetup } from 'src/core/public'; - export interface ISessionExpired { logout(): void; } +const getNextParameter = () => { + const { location } = window; + const next = encodeURIComponent(`${location.pathname}${location.search}${location.hash}`); + return `&next=${next}`; +}; + +const getProviderParameter = (tenant: string) => { + const key = `${tenant}/session_provider`; + const providerName = sessionStorage.getItem(key); + return providerName ? `&provider=${encodeURIComponent(providerName)}` : ''; +}; + export class SessionExpired { - constructor(private basePath: HttpSetup['basePath'], private tenant: string) {} + constructor(private logoutUrl: string, private tenant: string) {} logout() { - const next = this.basePath.remove( - `${window.location.pathname}${window.location.search}${window.location.hash}` - ); - const key = `${this.tenant}/session_provider`; - const providerName = sessionStorage.getItem(key); - const provider = providerName ? `&provider=${encodeURIComponent(providerName)}` : ''; - window.location.assign( - this.basePath.prepend( - `/logout?next=${encodeURIComponent(next)}&msg=SESSION_EXPIRED${provider}` - ) - ); + const next = getNextParameter(); + const provider = getProviderParameter(this.tenant); + window.location.assign(`${this.logoutUrl}?msg=SESSION_EXPIRED${next}${provider}`); } } diff --git a/x-pack/plugins/security/public/session/unauthorized_response_http_interceptor.test.ts b/x-pack/plugins/security/public/session/unauthorized_response_http_interceptor.test.ts index ff2db01cb6c58..fba2a2ec98146 100644 --- a/x-pack/plugins/security/public/session/unauthorized_response_http_interceptor.test.ts +++ b/x-pack/plugins/security/public/session/unauthorized_response_http_interceptor.test.ts @@ -33,7 +33,7 @@ afterEach(() => { it(`logs out 401 responses`, async () => { const http = setupHttp('/foo'); - const sessionExpired = new SessionExpired(http.basePath, tenant); + const sessionExpired = new SessionExpired(`${http.basePath}/logout`, tenant); const logoutPromise = new Promise(resolve => { jest.spyOn(sessionExpired, 'logout').mockImplementation(() => resolve()); }); @@ -59,7 +59,7 @@ it(`ignores anonymous paths`, async () => { const http = setupHttp('/foo'); const { anonymousPaths } = http; anonymousPaths.register('/bar'); - const sessionExpired = new SessionExpired(http.basePath, tenant); + const sessionExpired = new SessionExpired(`${http.basePath}/logout`, tenant); const interceptor = new UnauthorizedResponseHttpInterceptor(sessionExpired, anonymousPaths); http.intercept(interceptor); fetchMock.mock('*', 401); @@ -70,7 +70,7 @@ it(`ignores anonymous paths`, async () => { it(`ignores errors which don't have a response, for example network connectivity issues`, async () => { const http = setupHttp('/foo'); - const sessionExpired = new SessionExpired(http.basePath, tenant); + const sessionExpired = new SessionExpired(`${http.basePath}/logout`, tenant); const interceptor = new UnauthorizedResponseHttpInterceptor(sessionExpired, http.anonymousPaths); http.intercept(interceptor); fetchMock.mock('*', new Promise((resolve, reject) => reject(new Error('Network is down')))); @@ -81,7 +81,7 @@ it(`ignores errors which don't have a response, for example network connectivity it(`ignores requests which omit credentials`, async () => { const http = setupHttp('/foo'); - const sessionExpired = new SessionExpired(http.basePath, tenant); + const sessionExpired = new SessionExpired(`${http.basePath}/logout`, tenant); const interceptor = new UnauthorizedResponseHttpInterceptor(sessionExpired, http.anonymousPaths); http.intercept(interceptor); fetchMock.mock('*', 401); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts index ca6ef5b6cede9..b8034fd92e988 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/index.ts @@ -25,5 +25,7 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./update_rules_bulk')); loadTestFile(require.resolve('./patch_rules_bulk')); loadTestFile(require.resolve('./patch_rules')); + loadTestFile(require.resolve('./query_signals')); + loadTestFile(require.resolve('./open_close_signals')); }); }; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/open_close_signals.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/open_close_signals.ts new file mode 100644 index 0000000000000..e9e3e4299d108 --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/open_close_signals.ts @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { DETECTION_ENGINE_SIGNALS_STATUS_URL } from '../../../../legacy/plugins/siem/common/constants'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { + createSignalsIndex, + deleteSignalsIndex, + setSignalStatus, + getSignalStatusEmptyResponse, +} from './utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + + describe('open_close_signals', () => { + describe('validation checks', () => { + it('should not give errors when querying and the signals index does not exist yet', async () => { + const { body } = await supertest + .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) + .set('kbn-xsrf', 'true') + .send(setSignalStatus({ signalIds: ['123'], status: 'open' })) + .expect(200); + + // remove any server generated items that are indeterministic + delete body.took; + + expect(body).to.eql(getSignalStatusEmptyResponse()); + }); + + it('should not give errors when querying and the signals index does exist and is empty', async () => { + await createSignalsIndex(supertest); + const { body } = await supertest + .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) + .set('kbn-xsrf', 'true') + .send(setSignalStatus({ signalIds: ['123'], status: 'open' })) + .expect(200); + + // remove any server generated items that are indeterministic + delete body.took; + + expect(body).to.eql(getSignalStatusEmptyResponse()); + + await deleteSignalsIndex(supertest); + }); + }); + }); +}; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/query_signals.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/query_signals.ts new file mode 100644 index 0000000000000..6fa62412ed467 --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/query_signals.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { DETECTION_ENGINE_QUERY_SIGNALS_URL } from '../../../../legacy/plugins/siem/common/constants'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { getSignalStatus, createSignalsIndex, deleteSignalsIndex } from './utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + + describe('query_signals_route', () => { + describe('validation checks', () => { + it('should not give errors when querying and the signals index does not exist yet', async () => { + const { body } = await supertest + .post(DETECTION_ENGINE_QUERY_SIGNALS_URL) + .set('kbn-xsrf', 'true') + .send(getSignalStatus()) + .expect(200); + + // remove any server generated items that are indeterministic + delete body.took; + + expect(body).to.eql({ + timed_out: false, + _shards: { total: 0, successful: 0, skipped: 0, failed: 0 }, + hits: { total: { value: 0, relation: 'eq' }, max_score: 0, hits: [] }, + }); + }); + + it('should not give errors when querying and the signals index does exist and is empty', async () => { + await createSignalsIndex(supertest); + const { body } = await supertest + .post(DETECTION_ENGINE_QUERY_SIGNALS_URL) + .set('kbn-xsrf', 'true') + .send(getSignalStatus()) + .expect(200); + + // remove any server generated items that are indeterministic + delete body.took; + + expect(body).to.eql({ + timed_out: false, + _shards: { total: 1, successful: 1, skipped: 0, failed: 0 }, + hits: { total: { value: 0, relation: 'eq' }, max_score: null, hits: [] }, + aggregations: { + statuses: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, + }, + }); + + await deleteSignalsIndex(supertest); + }); + }); + }); +}; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/utils.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/utils.ts index b78073c0e737b..bef700d0409a5 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/utils.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/utils.ts @@ -53,6 +53,36 @@ export const getSimpleRule = (ruleId = 'rule-1'): Partial = query: 'user.name: root or user.name: admin', }); +export const getSignalStatus = () => ({ + aggs: { statuses: { terms: { field: 'signal.status', size: 10 } } }, +}); + +export const setSignalStatus = ({ + signalIds, + status, +}: { + signalIds: string[]; + status: 'open' | 'closed'; +}) => ({ + signal_ids: signalIds, + status, +}); + +export const getSignalStatusEmptyResponse = () => ({ + timed_out: false, + total: 0, + updated: 0, + deleted: 0, + batches: 0, + version_conflicts: 0, + noops: 0, + retries: { bulk: 0, search: 0 }, + throttled_millis: 0, + requests_per_second: -1, + throttled_until_millis: 0, + failures: [], +}); + /** * This is a typical simple rule for testing that is easy for most basic testing */ diff --git a/x-pack/test/functional/apps/visualize/feature_controls/visualize_spaces.ts b/x-pack/test/functional/apps/visualize/feature_controls/visualize_spaces.ts index 066042896c122..b24c537d25085 100644 --- a/x-pack/test/functional/apps/visualize/feature_controls/visualize_spaces.ts +++ b/x-pack/test/functional/apps/visualize/feature_controls/visualize_spaces.ts @@ -20,7 +20,8 @@ export default function({ getPageObjects, getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const appsMenu = getService('appsMenu'); - describe('visualize', () => { + // FLAKY: https://github.com/elastic/kibana/issues/45244 + describe.skip('visualize', () => { before(async () => { await esArchiver.loadIfNeeded('logstash_functional'); });