diff --git a/.eslintignore b/.eslintignore index 90155ca9cb681e..e5b17567b562cf 100644 --- a/.eslintignore +++ b/.eslintignore @@ -9,7 +9,7 @@ bower_components /built_assets /html_docs /src/plugins/data/common/es_query/kuery/ast/_generated_/** -/src/fixtures/vislib/mock_data +src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data /src/legacy/ui/public/angular-bootstrap /src/legacy/ui/public/flot-charts /test/fixtures/scenarios diff --git a/.eslintrc.js b/.eslintrc.js index a7bb204da47751..2c5804da053a6b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -77,7 +77,7 @@ module.exports = { }, }, { - files: ['src/legacy/core_plugins/kbn_vislib_vis_types/**/*.{js,ts,tsx}'], + files: ['src/legacy/core_plugins/vis_type_vislib/**/*.{js,ts,tsx}'], rules: { 'react-hooks/exhaustive-deps': 'off', }, diff --git a/.i18nrc.json b/.i18nrc.json index 4bc0f773ee8b5f..6986d36e8e94f5 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -21,7 +21,7 @@ "interpreter": "src/legacy/core_plugins/interpreter", "kbn": "src/legacy/core_plugins/kibana", "kbnDocViews": "src/legacy/core_plugins/kbn_doc_views", - "kbnVislibVisTypes": "src/legacy/core_plugins/kbn_vislib_vis_types", + "kbnVislibVisTypes": "src/legacy/core_plugins/vis_type_vislib", "management": ["src/legacy/core_plugins/management", "src/plugins/management"], "kibana_react": "src/legacy/core_plugins/kibana_react", "kibana-react": "src/plugins/kibana_react", diff --git a/.sass-lint.yml b/.sass-lint.yml index f6c0f5bb83fcb2..fba2c003484f6a 100644 --- a/.sass-lint.yml +++ b/.sass-lint.yml @@ -2,7 +2,7 @@ files: include: - 'src/legacy/core_plugins/metrics/**/*.s+(a|c)ss' - 'src/legacy/core_plugins/timelion/**/*.s+(a|c)ss' - - 'src/legacy/ui/public/vislib/**/*.s+(a|c)ss' + - 'src/legacy/core_plugins/vis_type_vislib/**/*.s+(a|c)ss' - 'x-pack/legacy/plugins/rollup/**/*.s+(a|c)ss' - 'x-pack/legacy/plugins/security/**/*.s+(a|c)ss' - 'x-pack/legacy/plugins/canvas/**/*.s+(a|c)ss' diff --git a/docs/maps/images/gs_add_cloropeth_layer.png b/docs/maps/images/gs_add_cloropeth_layer.png index b2ee35f025b6f4..2800a5a2d25846 100644 Binary files a/docs/maps/images/gs_add_cloropeth_layer.png and b/docs/maps/images/gs_add_cloropeth_layer.png differ diff --git a/docs/maps/images/gs_add_es_layer.png b/docs/maps/images/gs_add_es_layer.png deleted file mode 100644 index b80ddc47d7e5d1..00000000000000 Binary files a/docs/maps/images/gs_add_es_layer.png and /dev/null differ diff --git a/docs/maps/images/sample_data_web_logs.png b/docs/maps/images/sample_data_web_logs.png index dda0926a07dfe4..3b0c2ba3f12c04 100644 Binary files a/docs/maps/images/sample_data_web_logs.png and b/docs/maps/images/sample_data_web_logs.png differ diff --git a/docs/maps/maps-getting-started.asciidoc b/docs/maps/maps-getting-started.asciidoc index e6908ca773a2f6..34ed79c736b2e7 100644 --- a/docs/maps/maps-getting-started.asciidoc +++ b/docs/maps/maps-getting-started.asciidoc @@ -68,14 +68,16 @@ and lighter shades symbolize countries with less traffic. . Click the *EMS Boundaries* data source. . From the *Layer* dropdown menu, select *World Countries*. . Click the *Add layer* button. -. Set *Layer name* to `Total Requests by Country`. -. Set *Layer transparency* to 0.5. +. Set *Name* to `Total Requests by Country`. +. Set *Opacity* to 50%. +. Click *Add* under *Tooltip fields*. +. In the popover, select *ISO 3166-1 alpha-2 code* and *name* and click *Add*. ===== Join the vector layer with the sample web log index You now have a vector layer containing the world countries. To symbolize countries by web traffic, you'll need to augment the world country features with the count of Elasticsearch weblog documents originating from each country. -To do this, you'll create a <> to link the vector source *World Countries* to +To do this, you'll create a <> to link the vector source *World Countries* to the {es} index `kibana_sample_data_logs` on the shared key iso2 = geo.src. . Click plus image:maps/images/gs_plus_icon.png[] to the right of *Term Joins* label. @@ -83,15 +85,18 @@ the {es} index `kibana_sample_data_logs` on the shared key iso2 = geo.src. . Set *Left field* to *ISO 3166-1 alpha-2 code*. . Set *Right source* to *kibana_sample_data_logs*. . Set *Right field* to *geo.src*. +. Click *and use metric count*. +. Set *Custom label* to *web logs count*. ===== Set the layer style All of the world countries are still a single color because the layer is using <>. To shade the world countries based on which country is sending the most requests, you'll need to use <>. -. Click image:maps/images/gs_link_icon.png[] to the right of *Fill color*. +. Under *Fill color*, change the selected value from *Solid* to *By value*. +. In the field select input, select *web logs count*. . Select the grey color ramp. -. In the field select input, select *count of kibana_sample_data_logs:geo.src*. +. Under *Border color*, change the selected color to *white*. . Click *Save & close*. + Your map now looks like this: @@ -119,9 +124,11 @@ The layer is only visible when users zoom in the map past zoom level 9. . Click the *Documents* data source. . Set *Index pattern* to *kibana_sample_data_logs*. . Click the *Add layer* button. -. Set *Layer name* to `Actual Requests`. -. Set *Zoom range for layer visibility* to the range [9, 24]. -. Set *Layer transparency* to 1. +. Set *Name* to `Actual Requests`. +. Set *Visibilty* to the range [9, 24]. +. Set *Opacity* to 100%. +. Click *Add* under *Tooltip fields*. +. In the popover, select *clientip*, *timestamp*, *host*, *request*, *response*, *machine.os*, *agent*, and *bytes* and click *Add*. . Set *Fill color* to *#2200ff*. . Click *Save & close*. + @@ -152,28 +159,28 @@ image::maps/images/grid_metrics_both.png[] . Set *Index pattern* to *kibana_sample_data_logs*. . Set *Show as* to *points*. . Click the *Add layer* button. -. Set *Layer name* to `Total Requests and Bytes`. -. Set *Zoom range for layer visibility* to the range [0, 9]. -. Set *Layer transparency* to 1. +. Set *Name* to `Total Requests and Bytes`. +. Set *Visibility* to the range [0, 9]. +. Set *Opacity* to 100%. ===== Configure the aggregation metrics -. Click plus image:maps/images/gs_plus_icon.png[] to the right of *Metrics* label. +. Click *Add metric* under of *Metrics* label. . Select *Sum* in the aggregation select. . Select *bytes* in the field select. ===== Set the layer style . In *Layer style*, change *Symbol size*: - .. Set *Min size* to 1. + .. Set *Min size* to 7. .. Set *Max size* to 25. - .. In the field select, select *sum of bytes*. + .. Change the field select from *count* to *sum of bytes*. . Click *Save & close* button. + Your map now looks like this between zoom levels 0 and 9: + [role="screenshot"] -image::maps/images/gs_add_es_layer.png[] +image::maps/images/sample_data_web_logs.png[] [role="xpack"] [[maps-save]] diff --git a/package.json b/package.json index 365f597fe04fee..7915c0ed32baf3 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "kbn:bootstrap": "yarn build:types && node scripts/register_git_hook", "spec_to_console": "node scripts/spec_to_console", "backport-skip-ci": "backport --prDescription \"[skip-ci]\"", + "storybook": "node scripts/storybook", "cover:report": "nyc report --temp-dir target/kibana-coverage/functional --report-dir target/coverage/report --reporter=lcov && open ./target/coverage/report/lcov-report/index.html" }, "repository": { @@ -460,10 +461,13 @@ "postcss-url": "^8.0.0", "prettier": "^1.19.1", "proxyquire": "1.8.0", + "react-popper-tooltip": "^2.10.1", + "react-textarea-autosize": "^7.1.2", "regenerate": "^1.4.0", "sass-lint": "^1.12.1", "selenium-webdriver": "^4.0.0-alpha.5", "simple-git": "1.116.0", + "simplebar-react": "^2.1.0", "sinon": "^7.4.2", "strip-ansi": "^3.0.1", "supertest": "^3.1.0", diff --git a/packages/kbn-dev-utils/src/index.ts b/packages/kbn-dev-utils/src/index.ts index 2fc29b71b262ec..714ed56ac47033 100644 --- a/packages/kbn-dev-utils/src/index.ts +++ b/packages/kbn-dev-utils/src/index.ts @@ -17,7 +17,7 @@ * under the License. */ -export { withProcRunner } from './proc_runner'; +export { withProcRunner, ProcRunner } from './proc_runner'; export { ToolingLog, ToolingLogTextWriter, diff --git a/packages/kbn-dev-utils/src/proc_runner/index.ts b/packages/kbn-dev-utils/src/proc_runner/index.ts index ad5e7c8ee946e5..af9dc5c65a3a3a 100644 --- a/packages/kbn-dev-utils/src/proc_runner/index.ts +++ b/packages/kbn-dev-utils/src/proc_runner/index.ts @@ -18,3 +18,4 @@ */ export { withProcRunner } from './with_proc_runner'; +export { ProcRunner } from './proc_runner'; diff --git a/packages/kbn-dev-utils/src/run/run.ts b/packages/kbn-dev-utils/src/run/run.ts index 1d28d435757297..e185f86cc3bf79 100644 --- a/packages/kbn-dev-utils/src/run/run.ts +++ b/packages/kbn-dev-utils/src/run/run.ts @@ -23,11 +23,13 @@ import exitHook from 'exit-hook'; import { pickLevelFromFlags, ToolingLog } from '../tooling_log'; import { createFlagError, isFailError } from './fail'; import { Flags, getFlags, getHelp } from './flags'; +import { ProcRunner, withProcRunner } from '../proc_runner'; type CleanupTask = () => void; type RunFn = (args: { log: ToolingLog; flags: Flags; + procRunner: ProcRunner; addCleanupTask: (task: CleanupTask) => void; }) => Promise | void; @@ -102,10 +104,13 @@ export async function run(fn: RunFn, options: Options = {}) { } try { - await fn({ - log, - flags, - addCleanupTask: (task: CleanupTask) => cleanupTasks.push(task), + await withProcRunner(log, async procRunner => { + await fn({ + log, + flags, + procRunner, + addCleanupTask: (task: CleanupTask) => cleanupTasks.push(task), + }); }); } finally { doCleanup(); diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index a3debf78fb8c86..8bded9d403c215 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -4489,6 +4489,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = __webpack_require__(36); var proc_runner_1 = __webpack_require__(37); exports.withProcRunner = proc_runner_1.withProcRunner; +exports.ProcRunner = proc_runner_1.ProcRunner; var tooling_log_1 = __webpack_require__(415); exports.ToolingLog = tooling_log_1.ToolingLog; exports.ToolingLogTextWriter = tooling_log_1.ToolingLogTextWriter; @@ -4761,6 +4762,8 @@ function __importDefault(mod) { Object.defineProperty(exports, "__esModule", { value: true }); var with_proc_runner_1 = __webpack_require__(38); exports.withProcRunner = with_proc_runner_1.withProcRunner; +var proc_runner_1 = __webpack_require__(39); +exports.ProcRunner = proc_runner_1.ProcRunner; /***/ }), @@ -37069,6 +37072,7 @@ const exit_hook_1 = tslib_1.__importDefault(__webpack_require__(348)); const tooling_log_1 = __webpack_require__(415); const fail_1 = __webpack_require__(425); const flags_1 = __webpack_require__(426); +const proc_runner_1 = __webpack_require__(37); async function run(fn, options = {}) { var _a; const flags = flags_1.getFlags(process.argv.slice(2), options); @@ -37118,10 +37122,13 @@ async function run(fn, options = {}) { throw fail_1.createFlagError(`Unknown flag(s) "${flags.unexpected.join('", "')}"`); } try { - await fn({ - log, - flags, - addCleanupTask: (task) => cleanupTasks.push(task), + await proc_runner_1.withProcRunner(log, async (procRunner) => { + await fn({ + log, + flags, + procRunner, + addCleanupTask: (task) => cleanupTasks.push(task), + }); }); } finally { diff --git a/packages/kbn-storybook/README.md b/packages/kbn-storybook/README.md new file mode 100644 index 00000000000000..c9195f41ebf26b --- /dev/null +++ b/packages/kbn-storybook/README.md @@ -0,0 +1,33 @@ +# Kibana Storybook + +This package provides ability to add [Storybook](https://storybook.js.org/) to any Kibana plugin. + +- [Setup Instructions](#setup-instructions) + + +## Setup Instructions + +1. Add `storybook.js` launcher file to your plugin. For example, create a file at + `src/plugins//scripts/storybook.js`, with the following contents: + + ```js + import { join } from 'path'; + + // eslint-disable-next-line + require('@kbn/storybook').runStorybookCli({ + name: '', + storyGlobs: [join(__dirname, '..', 'public', 'components', '**', '*.examples.tsx')], + }); + ``` +2. Add your plugin alias to `src/dev/storybook/aliases.ts` config. +3. Create sample Storybook stories. For example, in your plugin create create a file at + `src/plugins//public/components/hello_world/__examples__/hello_world.examples.tsx` with + the following contents: + + ```jsx + import * as React from 'react'; + import { storiesOf } from '@storybook/react'; + + storiesOf('Hello world', module).add('default', () =>
Hello world!
); + ``` +4. Launch Storybook with `yarn storybook `. diff --git a/packages/kbn-storybook/index.js b/packages/kbn-storybook/index.js new file mode 100644 index 00000000000000..78e2cf7f5073b3 --- /dev/null +++ b/packages/kbn-storybook/index.js @@ -0,0 +1,86 @@ +/* + * 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. + */ + +const fs = require('fs'); +const { join } = require('path'); +const Rx = require('rxjs'); +const { first } = require('rxjs/operators'); +const storybook = require('@storybook/react/standalone'); +const { run } = require('@kbn/dev-utils'); +const { generateStorybookEntry } = require('./lib/storybook_entry'); +const { REPO_ROOT, CURRENT_CONFIG } = require('./lib/constants'); +const { buildDll } = require('./lib/dll'); + +exports.runStorybookCli = config => { + const { name, storyGlobs } = config; + run( + async ({ flags, log, procRunner }) => { + log.debug('Global config:\n', require('./lib/constants')); + + const currentConfig = JSON.stringify(config, null, 2); + const currentConfigDir = join(CURRENT_CONFIG, '..'); + await fs.promises.mkdir(currentConfigDir, { recursive: true }); + log.debug('Writing currentConfig:\n', CURRENT_CONFIG + '\n', currentConfig); + await fs.promises.writeFile(CURRENT_CONFIG, `exports.currentConfig = ${currentConfig};`); + + await buildDll({ + rebuildDll: flags.rebuildDll, + log, + procRunner, + }); + + // Build sass and continue when initial build complete + await procRunner.run('watch sass', { + cmd: process.execPath, + args: ['scripts/build_sass', '--watch'], + cwd: REPO_ROOT, + wait: /scss bundles created/, + }); + + const subj = new Rx.ReplaySubject(1); + generateStorybookEntry({ log, storyGlobs }).subscribe(subj); + + await subj.pipe(first()).toPromise(); + + await Promise.all([ + // route errors + subj.toPromise(), + + new Promise(() => { + // storybook never completes, so neither will this promise + const configDir = join(__dirname, 'storybook_config'); + log.debug('Config dir:', configDir); + storybook({ + mode: 'dev', + port: 9001, + configDir, + }); + }), + ]); + }, + { + flags: { + boolean: ['rebuildDll'], + }, + description: ` + Run the storybook examples for ${name} + `, + } + ); +}; diff --git a/packages/kbn-storybook/lib/constants.js b/packages/kbn-storybook/lib/constants.js new file mode 100644 index 00000000000000..9d216d347eada9 --- /dev/null +++ b/packages/kbn-storybook/lib/constants.js @@ -0,0 +1,27 @@ +/* + * 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. + */ + +const { resolve, dirname } = require('path'); + +exports.REPO_ROOT = dirname(require.resolve('../../../package.json')); +exports.ASSET_DIR = resolve(exports.REPO_ROOT, 'built_assets/storybook'); +exports.CURRENT_CONFIG = resolve(exports.ASSET_DIR, 'current.config.js'); +exports.STORY_ENTRY_PATH = resolve(exports.ASSET_DIR, 'stories.entry.js'); +exports.DLL_DIST_DIR = resolve(exports.ASSET_DIR, 'dll'); +exports.DLL_NAME = 'storybook_dll'; diff --git a/packages/kbn-storybook/lib/dll.js b/packages/kbn-storybook/lib/dll.js new file mode 100644 index 00000000000000..a9154ca972120c --- /dev/null +++ b/packages/kbn-storybook/lib/dll.js @@ -0,0 +1,41 @@ +/* + * 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. + */ + +const { resolve } = require('path'); +const { existsSync } = require('fs'); + +const { REPO_ROOT, DLL_DIST_DIR } = require('./constants'); + +exports.buildDll = async ({ rebuildDll, log, procRunner }) => { + if (rebuildDll) { + log.info('rebuilding dll'); + } else if (!existsSync(resolve(DLL_DIST_DIR, 'dll.js'))) { + log.info('dll missing, rebuilding'); + } else { + log.info('dll exists'); + return; + } + + await procRunner.run('build dll ', { + cmd: require.resolve('webpack/bin/webpack'), + args: ['--config', require.resolve('./webpack.dll.config.js')], + cwd: REPO_ROOT, + wait: true, + }); +}; diff --git a/packages/kbn-storybook/lib/storybook_entry.js b/packages/kbn-storybook/lib/storybook_entry.js new file mode 100644 index 00000000000000..dececef47f40e4 --- /dev/null +++ b/packages/kbn-storybook/lib/storybook_entry.js @@ -0,0 +1,89 @@ +/* + * 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. + */ + +const { resolve, relative, dirname } = require('path'); +const Fs = require('fs'); +const Rx = require('rxjs'); +const { mergeMap, map, debounceTime } = require('rxjs/operators'); +const normalize = require('normalize-path'); +const { promisify } = require('util'); + +const watch = require('glob-watcher'); +const mkdirp = require('mkdirp'); // eslint-disable-line +const glob = require('fast-glob'); + +const mkdirpAsync = promisify(mkdirp); +const writeFileAsync = promisify(Fs.writeFile); + +const { REPO_ROOT, STORY_ENTRY_PATH } = require('./constants'); +const STORE_ENTRY_DIR = dirname(STORY_ENTRY_PATH); + +exports.generateStorybookEntry = ({ log, storyGlobs }) => { + const globs = ['built_assets/css/**/*.light.css', ...storyGlobs]; + log.info('Storybook globs:\n', globs); + const norm = p => normalize(relative(STORE_ENTRY_DIR, p)); + + return Rx.defer(() => + glob(globs, { + absolute: true, + cwd: REPO_ROOT, + onlyFiles: true, + }) + ).pipe( + map(paths => { + log.info('Discovered Storybook entry points:\n', paths); + return new Set(paths.map(norm)); + }), + mergeMap( + paths => + new Rx.Observable(observer => { + observer.next(paths); + + const chokidar = watch(globs, { cwd: REPO_ROOT }) + .on('add', path => { + observer.next(paths.add(norm(resolve(REPO_ROOT, path)))); + }) + .on('unlink', path => { + observer.next(paths.delete(norm(resolve(REPO_ROOT, path)))); + }); + + return () => { + chokidar.close(); + }; + }) + ), + debounceTime(200), + mergeMap(async (paths, i) => { + await mkdirpAsync(STORE_ENTRY_DIR); + + let content = ''; + for (const path of paths) { + content += `require('${path}');\n`; + } + + await writeFileAsync(STORY_ENTRY_PATH, content); + + if (i === 0) { + log.info('%d paths written to entry file', paths.size); + } else { + log.info('entry file updated'); + } + }) + ); +}; diff --git a/packages/kbn-storybook/lib/webpack.dll.config.js b/packages/kbn-storybook/lib/webpack.dll.config.js new file mode 100644 index 00000000000000..bc871fab471b28 --- /dev/null +++ b/packages/kbn-storybook/lib/webpack.dll.config.js @@ -0,0 +1,149 @@ +/* + * 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. + */ + +const webpack = require('webpack'); +const path = require('path'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); + +const { DLL_NAME, REPO_ROOT, DLL_DIST_DIR } = require('./constants'); + +// This is the Webpack config for the DLL of CSS and JS assets that are +// not expected to change during development. This saves compile and run +// times considerably. +module.exports = { + context: REPO_ROOT, + mode: 'development', + + // This is a (potentially growing) list of modules that can be safely + // included in the DLL. Only add to this list modules or other code + // which Storybook stories and their components would require, but don't + // change during development. + entry: [ + '@elastic/eui/dist/eui_theme_light.css', + '@kbn/ui-framework/dist/kui_light.css', + '@storybook/addon-info', + '@storybook/addon-knobs', + '@storybook/addon-knobs/react', + '@storybook/addon-knobs/register', + '@storybook/addon-options', + '@storybook/addon-options/register', + '@storybook/core', + '@storybook/core/dist/server/common/polyfills.js', + '@storybook/react', + '@storybook/theming', + 'angular-mocks', + 'angular', + 'brace', + 'chroma-js', + 'highlight.js', + 'html-entities', + 'jquery', + 'lodash.clone', + 'lodash', + 'markdown-it', + 'mocha', + 'prop-types', + 'react-ace', + 'react-beautiful-dnd', + 'react-dom', + 'react-focus-lock', + 'react-markdown', + 'react-resize-detector', + 'react-virtualized', + 'react', + 'recompose', + 'redux-actions', + 'remark-parse', + 'rxjs', + 'sinon', + 'tinycolor2', + './src/legacy/ui/public/styles/font_awesome.less', + './src/legacy/ui/public/styles/bootstrap/bootstrap_light.less', + ], + plugins: [ + // Produce the DLL and its manifest + new webpack.DllPlugin({ + name: DLL_NAME, + path: path.resolve(DLL_DIST_DIR, 'manifest.json'), + }), + // Produce the DLL CSS file + new MiniCssExtractPlugin({ + filename: 'dll.css', + }), + ], + // Output the DLL JS file + output: { + path: DLL_DIST_DIR, + filename: 'dll.js', + library: DLL_NAME, + }, + // Include a require alias for legacy UI code and styles + resolve: { + alias: { + ui: path.resolve(REPO_ROOT, 'src/legacy/ui/public'), + }, + mainFields: ['browser', 'main'], + }, + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: MiniCssExtractPlugin.loader, + options: {}, + }, + { loader: 'css-loader' }, + { + loader: 'string-replace-loader', + options: { + search: '__REPLACE_WITH_PUBLIC_PATH__', + replace: '/', + flags: 'g', + }, + }, + ], + }, + { + test: /\.less$/, + use: [ + { loader: 'style-loader' }, + { loader: 'css-loader', options: { importLoaders: 2 } }, + { + loader: 'postcss-loader', + options: { + config: { + path: path.resolve(REPO_ROOT, 'src/optimize/postcss.config.js'), + }, + }, + }, + { loader: 'less-loader' }, + ], + }, + { + test: /\.(woff|woff2|ttf|eot|svg|ico)(\?|$)/, + loader: 'file-loader', + }, + ], + }, + node: { + fs: 'empty', + child_process: 'empty', + }, +}; diff --git a/packages/kbn-storybook/package.json b/packages/kbn-storybook/package.json new file mode 100644 index 00000000000000..6948ae81806eb1 --- /dev/null +++ b/packages/kbn-storybook/package.json @@ -0,0 +1,32 @@ +{ + "name": "@kbn/storybook", + "version": "1.0.0", + "private": true, + "license": "Apache-2.0", + "dependencies": { + "@kbn/babel-preset": "1.0.0", + "@kbn/dev-utils": "1.0.0", + "@storybook/addon-actions": "^5.2.8", + "@storybook/addon-console": "^1.2.1", + "@storybook/addon-info": "^5.2.8", + "@storybook/addon-knobs": "^5.2.8", + "@storybook/addon-options": "^5.2.8", + "@storybook/addon-storyshots": "^5.2.8", + "@storybook/react": "^5.2.8", + "@storybook/theming": "^5.2.8", + "copy-webpack-plugin": "5.0.3", + "execa": "1.0.0", + "fast-glob": "2.2.7", + "glob-watcher": "5.0.3", + "jest-specific-snapshot": "2.0.0", + "jest-styled-components": "6.3.1", + "mkdirp": "0.5.1", + "mini-css-extract-plugin": "0.7.0", + "normalize-path": "3.0.0", + "react-docgen-typescript-loader": "3.1.0", + "rxjs": "6.5.2", + "serve-static": "1.14.1", + "styled-components": "^3", + "webpack": "4.34.0" + } +} \ No newline at end of file diff --git a/packages/kbn-storybook/storybook_config/addons.js b/packages/kbn-storybook/storybook_config/addons.js new file mode 100644 index 00000000000000..f439d1d8892f89 --- /dev/null +++ b/packages/kbn-storybook/storybook_config/addons.js @@ -0,0 +1,23 @@ +/* + * 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 '@storybook/addon-options/register'; +import '@storybook/addon-actions/register'; +import '@storybook/addon-knobs/register'; +import '@storybook/addon-console'; diff --git a/packages/kbn-storybook/storybook_config/config.js b/packages/kbn-storybook/storybook_config/config.js new file mode 100644 index 00000000000000..a7975773e675be --- /dev/null +++ b/packages/kbn-storybook/storybook_config/config.js @@ -0,0 +1,68 @@ +/* + * 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 { configure, addDecorator, addParameters } from '@storybook/react'; +import { withKnobs } from '@storybook/addon-knobs/react'; +import { withInfo } from '@storybook/addon-info'; +import { create } from '@storybook/theming'; + +// If we're running Storyshots, be sure to register the require context hook. +// Otherwise, add the other decorators. +if (process.env.NODE_ENV === 'test') { + // eslint-disable-next-line + require('babel-plugin-require-context-hook/register')(); +} else { + // Customize the info for each story. + addDecorator( + withInfo({ + inline: true, + styles: { + infoBody: { + margin: 20, + }, + infoStory: { + margin: '40px 60px', + }, + }, + }) + ); + + // Add optional knobs to customize each story. + addDecorator(withKnobs); +} + +// Set up the Storybook environment with custom settings. +addParameters({ + options: { + theme: create({ + base: 'light', + brandTitle: 'Kibana Storybook', + brandUrl: 'https://github.com/elastic/kibana/tree/master/packages/kbn-storybook', + }), + showPanel: true, + isFullscreen: false, + panelPosition: 'bottom', + isToolshown: true, + }, +}); + +configure(() => { + // eslint-disable-next-line + require('../../../built_assets/storybook/stories.entry.js'); +}, module); diff --git a/src/legacy/core_plugins/visualizations/public/expressions/boot.ts b/packages/kbn-storybook/storybook_config/middleware.js similarity index 69% rename from src/legacy/core_plugins/visualizations/public/expressions/boot.ts rename to packages/kbn-storybook/storybook_config/middleware.js index c30493e7d4c366..f517477b405bd1 100644 --- a/src/legacy/core_plugins/visualizations/public/expressions/boot.ts +++ b/packages/kbn-storybook/storybook_config/middleware.js @@ -17,9 +17,10 @@ * under the License. */ -import { npSetup } from 'ui/new_platform'; -import { visualization as visualizationFunction } from './visualization_function'; -import { visualization as visualizationRenderer } from './visualization_renderer'; +const serve = require('serve-static'); +const path = require('path'); -npSetup.plugins.expressions.registerFunction(visualizationFunction); -npSetup.plugins.expressions.registerRenderer(visualizationRenderer); +// Extend the Storybook Middleware to include a route to access Legacy UI assets +module.exports = function(router) { + router.get('/ui', serve(path.resolve(__dirname, '../../../../src/legacy/ui/public/assets'))); +}; diff --git a/packages/kbn-storybook/storybook_config/mocks/absolute_to_parsed_url.js b/packages/kbn-storybook/storybook_config/mocks/absolute_to_parsed_url.js new file mode 100644 index 00000000000000..65a27b095f84e1 --- /dev/null +++ b/packages/kbn-storybook/storybook_config/mocks/absolute_to_parsed_url.js @@ -0,0 +1,23 @@ +/* + * 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. + */ + +export const absoluteToParsedUrl = () => { + getAbsoluteUrl: () => + 'http://localhost:5601/kbp/app/canvas#/workpad/workpad-24d56dad-ae70-42b8-9ef1-c5350ecd426c/page/1'; +}; // noop diff --git a/packages/kbn-storybook/storybook_config/mocks/noop.js b/packages/kbn-storybook/storybook_config/mocks/noop.js new file mode 100755 index 00000000000000..aaddfb2ed8ac31 --- /dev/null +++ b/packages/kbn-storybook/storybook_config/mocks/noop.js @@ -0,0 +1,20 @@ +/* + * 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. + */ + +export default function() {} diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/pie.d.ts b/packages/kbn-storybook/storybook_config/mocks/state_store.js similarity index 75% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/pie.d.ts rename to packages/kbn-storybook/storybook_config/mocks/state_store.js index bf55abfe8161a1..11bdf6632321d1 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/pie.d.ts +++ b/packages/kbn-storybook/storybook_config/mocks/state_store.js @@ -17,16 +17,10 @@ * under the License. */ -import { CommonVislibParams } from './types'; - -export interface PieVisParams extends CommonVislibParams { - type: 'pie'; - addLegend: boolean; - isDonut: boolean; - labels: { - show: boolean; - values: boolean; - last_level: boolean; - truncate: number | null; +export function getState() { + return { + assets: { + yay: { value: 'here is your image' }, + }, }; } diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/index.js b/packages/kbn-storybook/storybook_config/mocks/ui_storage.js similarity index 73% rename from src/legacy/core_plugins/kbn_vislib_vis_types/index.js rename to packages/kbn-storybook/storybook_config/mocks/ui_storage.js index 6e1f17c941ece3..4bd8cdeddfc220 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/index.js +++ b/packages/kbn-storybook/storybook_config/mocks/ui_storage.js @@ -17,14 +17,12 @@ * under the License. */ -export default function(kibana) { - return new kibana.Plugin({ - uiExports: { - visTypes: ['plugins/kbn_vislib_vis_types/kbn_vislib_vis_types'], - interpreter: [ - 'plugins/kbn_vislib_vis_types/pie_fn', - 'plugins/kbn_vislib_vis_types/vislib_fn', - ], - }, - }); +export class Storage { + get(key) { + return this[key]; + } + + set(key, value) { + this[key] = value; + } } diff --git a/packages/kbn-storybook/storybook_config/preview-head.html b/packages/kbn-storybook/storybook_config/preview-head.html new file mode 100644 index 00000000000000..bef08a5120a36b --- /dev/null +++ b/packages/kbn-storybook/storybook_config/preview-head.html @@ -0,0 +1,6 @@ + + + diff --git a/packages/kbn-storybook/storybook_config/webpack.config.js b/packages/kbn-storybook/storybook_config/webpack.config.js new file mode 100644 index 00000000000000..72ff9162ffe6c9 --- /dev/null +++ b/packages/kbn-storybook/storybook_config/webpack.config.js @@ -0,0 +1,108 @@ +/* + * 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. + */ + +const { resolve } = require('path'); +const webpack = require('webpack'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const { REPO_ROOT, DLL_DIST_DIR } = require('../lib/constants'); +// eslint-disable-next-line import/no-unresolved +const { currentConfig } = require('../../../built_assets/storybook/current.config'); + +// Extend the Storybook Webpack config with some customizations +module.exports = async ({ config }) => { + // Find and alter the CSS rule to replace the Kibana public path string with a path + // to the route we've added in middleware.js + const cssRule = config.module.rules.find(rule => rule.test.source.includes('.css$')); + cssRule.use.push({ + loader: 'string-replace-loader', + options: { + search: '__REPLACE_WITH_PUBLIC_PATH__', + replace: '/', + flags: 'g', + }, + }); + + // Include the React preset from Kibana for Storybook JS files. + config.module.rules.push({ + test: /\.js$/, + exclude: /node_modules/, + loaders: 'babel-loader', + options: { + presets: [require.resolve('@kbn/babel-preset/webpack_preset')], + }, + }); + + // Handle Typescript files + config.module.rules.push({ + test: /\.tsx?$/, + use: [ + { + loader: 'babel-loader', + options: { + presets: [require.resolve('@kbn/babel-preset/webpack_preset')], + }, + }, + ], + }); + + // Parse props data for .tsx files + config.module.rules.push({ + test: /\.tsx$/, + // Exclude example files, as we don't display props info for them + exclude: /\.examples.tsx$/, + use: [ + // Parse TS comments to create Props tables in the UI + require.resolve('react-docgen-typescript-loader'), + ], + }); + + // Reference the built DLL file of static(ish) dependencies, which are removed + // during kbn:bootstrap and rebuilt if missing. + config.plugins.push( + new webpack.DllReferencePlugin({ + manifest: resolve(DLL_DIST_DIR, 'manifest.json'), + context: REPO_ROOT, + }) + ); + + // Copy the DLL files to the Webpack build for use in the Storybook UI + config.plugins.push( + new CopyWebpackPlugin([ + { + from: resolve(DLL_DIST_DIR, 'dll.js'), + to: 'dll.js', + }, + { + from: resolve(DLL_DIST_DIR, 'dll.css'), + to: 'dll.css', + }, + ]) + ); + + // Tell Webpack about the ts/x extensions + config.resolve.extensions.push('.ts', '.tsx'); + + // Load custom Webpack config specified by a plugin. + if (currentConfig.webpackHook) { + // eslint-disable-next-line import/no-dynamic-require + config = await require(currentConfig.webpackHook)({ config }); + } + + return config; +}; diff --git a/scripts/storybook.js b/scripts/storybook.js new file mode 100644 index 00000000000000..cc517bd5a4a323 --- /dev/null +++ b/scripts/storybook.js @@ -0,0 +1,21 @@ +/* + * 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. + */ + +require('../src/setup_node_env'); +require('../src/dev/storybook/run_storybook_cli'); diff --git a/src/core/CONVENTIONS.md b/src/core/CONVENTIONS.md index 18f82766bdbc16..61c5d5b076a446 100644 --- a/src/core/CONVENTIONS.md +++ b/src/core/CONVENTIONS.md @@ -1,6 +1,12 @@ # Kibana Conventions -- [Plugin Structure](#plugin-structure) +- [Kibana Conventions](#kibana-conventions) + - [Plugin Structure](#plugin-structure) + - [The PluginInitializer](#the-plugininitializer) + - [The Plugin class](#the-plugin-class) + - [Applications](#applications) + - [Services](#services) + - [Usage Collection](#usage-collection) ## Plugin Structure diff --git a/src/core/CORE_CONVENTIONS.md b/src/core/CORE_CONVENTIONS.md new file mode 100644 index 00000000000000..76f3be1595258d --- /dev/null +++ b/src/core/CORE_CONVENTIONS.md @@ -0,0 +1,140 @@ +- [Core Conventions](#core-conventions) + - [1. Exposing API Types](#1-exposing-api-types) + - [2. API Structure and nesting](#2-api-structure-and-nesting) + - [3. Tests and mocks](#3-tests-and-mocks) + +# Core Conventions + +This document contains conventions for development inside `src/core`. Although +many of these might be more widely applicable, adoption within the rest of +Kibana is not the primary objective. + +## 1. Exposing API Types +The following section applies to the types that describe the entire surface +area of Core API's and does not apply to internal types. + + - 1.1 All API types must be exported from the top-level `server` or `public` + directories. + + ```ts + // -- good -- + import { IRouter } from 'src/core/server'; + + // -- bad -- + import { IRouter } from 'src/core/server/http/router.ts'; + ``` + + > Why? This is required for generating documentation from our inline + > typescript doc comments, makes it easier for API consumers to find the + > relevant types and creates a clear distinction between external and + > internal types. + + - 1.2 Classes must not be exposed directly. Instead, use a separate type, + prefixed with an 'I', to describe the public contract of the class. + + ```ts + // -- good (alternative 1) -- + /** + * @public + * {@link UiSettingsClient} + */ + export type IUiSettingsClient = PublicContractOf; + + /** internal only */ + export class UiSettingsClient { + constructor(private setting: string) {} + /** Retrieve all settings */ + public getSettings(): { return this.settings; } + }; + + // -- good (alternative 2) -- + export interface IUiSettingsClient { + /** Retrieve all settings */ + public getSettings(): string; + } + + export class UiSettingsClient implements IUiSettingsClient { + public getSettings(): string; + } + + // -- bad -- + /** external */ + export class UiSettingsClient { + constructor(private setting: string) {} + public getSettings(): { return this.settings; } + } + ``` + + > Why? Classes' private members form part of their type signature making it + > impossible to mock a dependency typed as a `class`. + > + > Until we can use ES private field support in Typescript 3.8 + > https://github.com/elastic/kibana/issues/54906 we have two alternatives + > each with their own pro's and cons: + > + > #### Using a derived class (alternative 1) + > + > Pro's: + > - TSDoc comments are located with the source code + > - The class acts as a single source of type information + > + > Con's: + > - "Go to definition" first takes you to where the type gets derived + > requiring a second "Go to definition" to navigate to the type source. + > + > #### Using a separate interface (alternative 2) + > Pro's: + > - Creates an explicit external API contract + > - "Go to definition" will take you directly to the type definition. + > + > Con's: + > - TSDoc comments are located with the interface not next to the + > implementation source code. + > - Creates duplicate type information between the interface and + > implementation class. + +## 2. API Structure and nesting + - 2.1 Nest API methods into their own namespace only if we expect we will be + adding additional methods to that namespace. + + ```ts + // good + core.overlays.openFlyout(...); + core.overlays.openModal(...); + core.overlays.banners.add(...); + core.overlays.banners.remove(...); + core.overlays.banners.replace(...); + + // bad + core.overlays.flyouts.open(...); + core.overlays.modals.open(...); + ``` + + > Why? Nested namespaces should facilitate discovery and navigation for + > consumers of the API. Having namespaces with a single method, effectively + > hides the method under an additional layer without improving the + > organization. However, introducing namespaces early on can avoid API + > churn when we know related API methods will be introduced. + +## 3. Tests and mocks + - 3.1 Declare Jest mocks with a temporary variable to ensure types are + correctly inferred. + + ```ts + // -- good -- + const createMock => { + const mocked: jest.Mocked = { + start: jest.fn(), + }; + mocked.start.mockReturnValue(createStartContractMock()); + return mocked; + }; + // -- bad -- + const createMock = (): jest.Mocked => ({ + start: jest.fn().mockReturnValue(createSetupContractMock()), + }); + ``` + + > Why? Without the temporary variable, Jest types the `start` function as + > `jest` and, as a result, doesn't typecheck the mock return + > value. diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index bd084767a723f0..8dccb9830526c7 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -101,9 +101,6 @@ export const LICENSE_OVERRIDES = { // TODO can be removed if the PR#9 is accepted on the source 'pause-stream@0.0.11': ['MIT'], - // TODO can be removed once we upgrade past or equal pdf-image@2.0.1 - 'pdf-image@1.1.0': ['MIT'], - // TODO can be removed once we upgrade the use of walk dependency past or equal to v2.3.14 'walk@2.3.9': ['MIT'], }; diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index e18852e353b00c..e5493df0aecf70 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -52,6 +52,9 @@ export const IGNORE_FILE_GLOBS = [ // filename must match language code which requires capital letters '**/translations/*.json', + + // filename is required by storybook + 'packages/kbn-storybook/storybook_config/preview-head.html', ]; /** @@ -117,7 +120,7 @@ export const TEMPORARILY_IGNORED_PATHS = [ 'src/legacy/core_plugins/timelion/server/series_functions/__tests__/fixtures/seriesList.js', 'src/legacy/core_plugins/timelion/server/series_functions/__tests__/fixtures/tlConfig.js', 'src/fixtures/config_upgrade_from_4.0.0_to_4.0.1-snapshot.json', - 'src/fixtures/vislib/mock_data/terms/_seriesMultiple.js', + 'src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/terms/_seriesMultiple.js', 'src/legacy/ui/public/angular-bootstrap/bindHtml/bindHtml.js', 'src/legacy/ui/public/angular-bootstrap/tooltip/tooltip-html-unsafe-popup.html', 'src/legacy/ui/public/angular-bootstrap/tooltip/tooltip-popup.html', diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts new file mode 100644 index 00000000000000..8213bdeeea2da8 --- /dev/null +++ b/src/dev/storybook/aliases.ts @@ -0,0 +1,25 @@ +/* + * 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. + */ + +export const storybookAliases = { + canvas: 'x-pack/legacy/plugins/canvas/scripts/storybook_new.js', + embeddable: 'src/plugins/embeddable/scripts/storybook.js', + infra: 'x-pack/legacy/plugins/infra/scripts/storybook.js', + siem: 'x-pack/legacy/plugins/siem/scripts/storybook.js', +}; diff --git a/src/dev/storybook/commands/clean.ts b/src/dev/storybook/commands/clean.ts new file mode 100644 index 00000000000000..328c4d9e2c23c2 --- /dev/null +++ b/src/dev/storybook/commands/clean.ts @@ -0,0 +1,32 @@ +/* + * 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 { ToolingLog } from '@kbn/dev-utils'; +import { REPO_ROOT } from '@kbn/dev-utils'; +import { join } from 'path'; +import del from 'del'; + +export const clean = async ({ log }: { log: ToolingLog }) => { + log.info('Cleaning Storybook build folder'); + + const dir = join(REPO_ROOT, 'built_assets', 'storybook'); + log.info('Deleting folder:', dir); + await del([join(dir, '*')]); + await del([dir]); +}; diff --git a/src/dev/storybook/run_storybook_cli.ts b/src/dev/storybook/run_storybook_cli.ts new file mode 100644 index 00000000000000..0f7dc40ceef0b3 --- /dev/null +++ b/src/dev/storybook/run_storybook_cli.ts @@ -0,0 +1,78 @@ +/* + * 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 { join } from 'path'; +import { run, createFlagError } from '@kbn/dev-utils'; +import { REPO_ROOT } from '@kbn/dev-utils'; +import { storybookAliases } from './aliases'; +import { clean } from './commands/clean'; + +run( + async params => { + const { flags, log } = params; + const { + _: [alias], + } = flags; + + if (flags.verbose) { + log.verbose('Flags:', flags); + } + + if (flags.clean) { + await clean({ log }); + return; + } + + if (!alias) { + throw createFlagError('missing alias'); + } + + if (!storybookAliases.hasOwnProperty(alias)) { + throw createFlagError(`unknown alias [${alias}]`); + } + + const relative = (storybookAliases as any)[alias]; + const absolute = join(REPO_ROOT, relative); + + log.verbose('Loading Storybook:', absolute); + process.chdir(join(absolute, '..', '..')); + require(absolute); + }, + { + usage: `node scripts/storybook `, + description: ` + Start a 📕 Storybook for a plugin + + Available aliases: + ${Object.keys(storybookAliases) + .map(alias => `📕 ${alias}`) + .join('\n ')} + + Add your alias in src/dev/storybook/aliases.ts + `, + flags: { + default: {}, + string: [], + boolean: ['clean'], + help: ` + --clean Clean Storybook build folder. + `, + }, + } +); diff --git a/src/legacy/core_plugins/console/common/text_object.ts b/src/legacy/core_plugins/console/common/text_object.ts new file mode 100644 index 00000000000000..3b3464a77ac4e9 --- /dev/null +++ b/src/legacy/core_plugins/console/common/text_object.ts @@ -0,0 +1,48 @@ +/* + * 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. + */ + +export const textObjectTypeName = 'text-object'; + +/** + * Describes the shape of persisted objects that contain information about the current text in the + * text editor. + */ +export interface TextObject { + /** + * An ID that uniquely identifies this object. + */ + id: string; + + /** + * UNIX timestamp of when the object was created. + */ + createdAt: number; + + /** + * UNIX timestamp of when the object was last updated. + */ + updatedAt: number; + + /** + * Text value input by the user. + * + * Used to re-populate a text editor buffer. + */ + text: string; +} diff --git a/src/legacy/core_plugins/console/common/types.ts b/src/legacy/core_plugins/console/common/types.ts new file mode 100644 index 00000000000000..33d6907ff60b88 --- /dev/null +++ b/src/legacy/core_plugins/console/common/types.ts @@ -0,0 +1,49 @@ +/* + * 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 { TextObject } from './text_object'; + +export interface IdObject { + id: string; +} + +export interface ObjectStorage { + /** + * Creates a new object in the underlying persistance layer. + * + * @remarks Does not accept an ID, a new ID is generated and returned with the newly created object. + */ + create(obj: Omit): Promise; + + /** + * This method should update specific object in the persistance layer. + */ + update(obj: O): Promise; + + /** + * A function that will return all of the objects in the persistance layer. + * + * @remarks Unless an error is thrown this function should always return an array (empty if there are not objects present). + */ + findAll(): Promise; +} + +export interface ObjectStorageClient { + text: ObjectStorage; +} diff --git a/src/legacy/core_plugins/console/public/np_ready/application/components/editor_content_spinner.tsx b/src/legacy/core_plugins/console/public/np_ready/application/components/editor_content_spinner.tsx new file mode 100644 index 00000000000000..2ae4545ad24ef7 --- /dev/null +++ b/src/legacy/core_plugins/console/public/np_ready/application/components/editor_content_spinner.tsx @@ -0,0 +1,29 @@ +/* + * 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 React, { FunctionComponent } from 'react'; +import { EuiLoadingContent, EuiPageContent } from '@elastic/eui'; + +export const EditorContentSpinner: FunctionComponent = () => { + return ( + + + + ); +}; diff --git a/src/legacy/core_plugins/console/public/np_ready/application/components/index.ts b/src/legacy/core_plugins/console/public/np_ready/application/components/index.ts index 0f109e99b0b39f..4669e210e7c2d8 100644 --- a/src/legacy/core_plugins/console/public/np_ready/application/components/index.ts +++ b/src/legacy/core_plugins/console/public/np_ready/application/components/index.ts @@ -18,8 +18,10 @@ */ export * from './split_panel'; +export { SomethingWentWrongCallout } from './something_went_wrong_callout'; export { TopNavMenuItem, TopNavMenu } from './top_nav_menu'; export { ConsoleMenu } from './console_menu'; export { WelcomePanel } from './welcome_panel'; export { AutocompleteOptions, DevToolsSettingsModal } from './settings_modal'; export { HelpPanel } from './help_panel'; +export { EditorContentSpinner } from './editor_content_spinner'; diff --git a/src/legacy/core_plugins/console/public/np_ready/application/components/something_went_wrong_callout.tsx b/src/legacy/core_plugins/console/public/np_ready/application/components/something_went_wrong_callout.tsx new file mode 100644 index 00000000000000..7b643bc84dd348 --- /dev/null +++ b/src/legacy/core_plugins/console/public/np_ready/application/components/something_went_wrong_callout.tsx @@ -0,0 +1,58 @@ +/* + * 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 React, { FunctionComponent, useEffect } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { EuiCallOut, EuiText, EuiButton, EuiSpacer } from '@elastic/eui'; + +interface Props { + error: Error; + onButtonClick: () => void; +} + +export const SomethingWentWrongCallout: FunctionComponent = ({ error, onButtonClick }) => { + useEffect(() => { + // eslint-disable-next-line no-console + console.error(error); + }, [error]); + + return ( + + +

+ +

+
+ + onButtonClick()}> + + +
+ ); +}; diff --git a/src/legacy/core_plugins/console/public/np_ready/application/components/top_nav_menu.tsx b/src/legacy/core_plugins/console/public/np_ready/application/components/top_nav_menu.tsx index c83237c52febd2..92f3f32da9a4e7 100644 --- a/src/legacy/core_plugins/console/public/np_ready/application/components/top_nav_menu.tsx +++ b/src/legacy/core_plugins/console/public/np_ready/application/components/top_nav_menu.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React from 'react'; +import React, { FunctionComponent } from 'react'; import { EuiTabs, EuiTab } from '@elastic/eui'; export interface TopNavMenuItem { @@ -29,19 +29,26 @@ export interface TopNavMenuItem { } interface Props { + disabled?: boolean; items: TopNavMenuItem[]; } -export function TopNavMenu({ items }: Props) { +export const TopNavMenu: FunctionComponent = ({ items, disabled }) => { return ( {items.map((item, idx) => { return ( - + {item.label} ); })} ); -} +}; diff --git a/src/legacy/core_plugins/console/public/np_ready/application/containers/editor/editor.tsx b/src/legacy/core_plugins/console/public/np_ready/application/containers/editor/editor.tsx index 07b48c083bf617..56449bfb454174 100644 --- a/src/legacy/core_plugins/console/public/np_ready/application/containers/editor/editor.tsx +++ b/src/legacy/core_plugins/console/public/np_ready/application/containers/editor/editor.tsx @@ -20,19 +20,26 @@ import React, { useCallback } from 'react'; import { debounce } from 'lodash'; +import { EditorContentSpinner } from '../../components'; import { Panel, PanelsContainer } from '../../components/split_panel'; import { Editor as EditorUI, EditorOutput } from './legacy/console_editor'; import { StorageKeys } from '../../../services'; -import { useServicesContext } from '../../contexts'; +import { useEditorReadContext, useServicesContext } from '../../contexts'; const INITIAL_PANEL_WIDTH = 50; const PANEL_MIN_WIDTH = '100px'; -export const Editor = () => { +interface Props { + loading: boolean; +} + +export const Editor = ({ loading }: Props) => { const { services: { storage }, } = useServicesContext(); + const { currentTextObject } = useEditorReadContext(); + const [firstPanelWidth, secondPanelWidth] = storage.get(StorageKeys.WIDTH, [ INITIAL_PANEL_WIDTH, INITIAL_PANEL_WIDTH, @@ -45,19 +52,25 @@ export const Editor = () => { [] ); + if (!currentTextObject) return null; + return ( - + {loading ? ( + + ) : ( + + )} - + {loading ? : } ); diff --git a/src/legacy/core_plugins/console/public/np_ready/application/containers/editor/legacy/console_editor/editor.test.tsx b/src/legacy/core_plugins/console/public/np_ready/application/containers/editor/legacy/console_editor/editor.test.tsx index 73ee6d160613f8..d4079fcea33f87 100644 --- a/src/legacy/core_plugins/console/public/np_ready/application/containers/editor/legacy/console_editor/editor.test.tsx +++ b/src/legacy/core_plugins/console/public/np_ready/application/containers/editor/legacy/console_editor/editor.test.tsx @@ -52,7 +52,7 @@ describe('Legacy (Ace) Console Editor Component Smoke Test', () => { - + @@ -72,6 +72,7 @@ describe('Legacy (Ace) Console Editor Component Smoke Test', () => { updateCurrentState: jest.fn(), } as any, notifications: notificationServiceMock.createSetupContract(), + objectStorageClient: {} as any, }, docLinkVersion: 'NA', }; diff --git a/src/legacy/core_plugins/console/public/np_ready/application/containers/editor/legacy/console_editor/editor.tsx b/src/legacy/core_plugins/console/public/np_ready/application/containers/editor/legacy/console_editor/editor.tsx index 761a252b56a877..759e3dbafb39ce 100644 --- a/src/legacy/core_plugins/console/public/np_ready/application/containers/editor/legacy/console_editor/editor.tsx +++ b/src/legacy/core_plugins/console/public/np_ready/application/containers/editor/legacy/console_editor/editor.tsx @@ -35,7 +35,11 @@ import { autoIndent, getDocumentation } from '../console_menu_actions'; import { registerCommands } from './keyboard_shortcuts'; import { applyCurrentSettings } from './apply_editor_settings'; -import { useSendCurrentRequestToES, useSetInputEditor } from '../../../../hooks'; +import { + useSendCurrentRequestToES, + useSetInputEditor, + useSaveCurrentTextObject, +} from '../../../../hooks'; import * as senseEditor from '../../../../models/sense_editor'; // @ts-ignore @@ -43,6 +47,10 @@ import mappings from '../../../../../lib/mappings/mappings'; import { subscribeResizeChecker } from '../subscribe_console_resize_checker'; +export interface EditorProps { + initialTextValue: string; +} + const abs: CSSProperties = { position: 'absolute', top: '0', @@ -58,7 +66,7 @@ const DEFAULT_INPUT_VALUE = `GET _search } }`; -function EditorUI() { +function EditorUI({ initialTextValue }: EditorProps) { const { services: { history, notifications }, docLinkVersion, @@ -68,6 +76,7 @@ function EditorUI() { const { settings } = useEditorReadContext(); const setInputEditor = useSetInputEditor(); const sendCurrentRequestToES = useSendCurrentRequestToES(); + const saveCurrentTextObject = useSaveCurrentTextObject(); const editorRef = useRef(null); const editorInstanceRef = useRef(null); @@ -132,10 +141,7 @@ function EditorUI() { if (initialQueryParams.load_from) { loadBufferFromRemote(initialQueryParams.load_from); } else { - const { content: text } = history.getSavedEditorState() || { - content: DEFAULT_INPUT_VALUE, - }; - editor.update(text); + editor.update(initialTextValue || DEFAULT_INPUT_VALUE); } function setupAutosave() { @@ -153,7 +159,7 @@ function EditorUI() { function saveCurrentState() { try { const content = editor.getCoreEditor().getValue(); - history.updateCurrentState(content); + saveCurrentTextObject(content); } catch (e) { // Ignoring saving error } @@ -172,7 +178,7 @@ function EditorUI() { mappings.clearSubscriptions(); window.removeEventListener('hashchange', onHashChange); }; - }, [history, setInputEditor]); + }, [saveCurrentTextObject, initialTextValue, history, setInputEditor]); useEffect(() => { const { current: editor } = editorInstanceRef; diff --git a/src/legacy/core_plugins/console/public/np_ready/application/containers/main/main.tsx b/src/legacy/core_plugins/console/public/np_ready/application/containers/main/main.tsx index 764c4b8e87100e..902d800b3e56b3 100644 --- a/src/legacy/core_plugins/console/public/np_ready/application/containers/main/main.tsx +++ b/src/legacy/core_plugins/console/public/np_ready/application/containers/main/main.tsx @@ -19,14 +19,15 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiPageContent } from '@elastic/eui'; import { ConsoleHistory } from '../console_history'; import { Editor } from '../editor'; import { Settings } from '../settings'; -import { TopNavMenu, WelcomePanel, HelpPanel } from '../../components'; +import { TopNavMenu, WelcomePanel, HelpPanel, SomethingWentWrongCallout } from '../../components'; import { useServicesContext, useEditorReadContext } from '../../contexts'; +import { useDataInit } from '../../hooks'; import { getTopNavConfig } from './get_top_nav'; @@ -48,6 +49,15 @@ export function Main() { const renderConsoleHistory = () => { return editorsReady ? setShowHistory(false)} /> : null; }; + const { done, error, retry } = useDataInit(); + + if (error) { + return ( + + + + ); + } return (
@@ -66,6 +76,7 @@ export function Main() { setShowHistory(!showingHistory), onClickSettings: () => setShowSettings(true), @@ -75,11 +86,11 @@ export function Main() { {showingHistory ? {renderConsoleHistory()} : null} - + - {showWelcome ? ( + {done && showWelcome ? ( { storage.set('version_welcome_shown', '@@SENSE_REVISION'); diff --git a/src/legacy/core_plugins/console/public/np_ready/application/contexts/services_context.tsx b/src/legacy/core_plugins/console/public/np_ready/application/contexts/services_context.tsx index f14685ecd4ac74..d7f036e1aecb61 100644 --- a/src/legacy/core_plugins/console/public/np_ready/application/contexts/services_context.tsx +++ b/src/legacy/core_plugins/console/public/np_ready/application/contexts/services_context.tsx @@ -20,6 +20,7 @@ import React, { createContext, useContext } from 'react'; import { NotificationsSetup } from 'kibana/public'; import { History, Storage, Settings } from '../../services'; +import { ObjectStorageClient } from '../../../../common/types'; import { MetricsTracker } from '../../types'; export interface ContextValue { @@ -28,6 +29,7 @@ export interface ContextValue { storage: Storage; settings: Settings; notifications: NotificationsSetup; + objectStorageClient: ObjectStorageClient; trackUiMetric: MetricsTracker; }; elasticsearchUrl: string; diff --git a/src/legacy/core_plugins/console/public/np_ready/application/hooks/index.ts b/src/legacy/core_plugins/console/public/np_ready/application/hooks/index.ts index 8c5a8d599a0df7..72e83e883553d9 100644 --- a/src/legacy/core_plugins/console/public/np_ready/application/hooks/index.ts +++ b/src/legacy/core_plugins/console/public/np_ready/application/hooks/index.ts @@ -20,3 +20,5 @@ export { useSetInputEditor } from './use_set_input_editor'; export { useRestoreRequestFromHistory } from './use_restore_request_from_history'; export { useSendCurrentRequestToES } from './use_send_current_request_to_es'; +export { useSaveCurrentTextObject } from './use_save_current_text_object'; +export { useDataInit } from './use_data_init'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/heatmap.d.ts b/src/legacy/core_plugins/console/public/np_ready/application/hooks/use_data_init/data_migration.ts similarity index 53% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/heatmap.d.ts rename to src/legacy/core_plugins/console/public/np_ready/application/hooks/use_data_init/data_migration.ts index 13c676854ead29..08acd78ba2b8a0 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/heatmap.d.ts +++ b/src/legacy/core_plugins/console/public/np_ready/application/hooks/use_data_init/data_migration.ts @@ -17,20 +17,30 @@ * under the License. */ -import { ColorSchemas } from 'ui/vislib/components/color/colormaps'; -import { RangeValues } from 'ui/vis/editors/default/controls/ranges'; -import { TimeMarker } from 'ui/vislib/visualizations/time_marker'; -import { CommonVislibParams, ColorSchemaVislibParams, ValueAxis } from './types'; -import { Positions } from './utils/collections'; +import { History } from '../../../services'; +import { ObjectStorageClient } from '../../../../../common/types'; -export interface HeatmapVisParams extends CommonVislibParams, ColorSchemaVislibParams { - type: 'heatmap'; - addLegend: boolean; - enableHover: boolean; - colorsNumber: number | ''; - colorsRange: RangeValues[]; - valueAxes: ValueAxis[]; - setColorRange: boolean; - percentageMode: boolean; - times: TimeMarker[]; +export interface Dependencies { + history: History; + objectStorageClient: ObjectStorageClient; +} + +/** + * Once off migration to new text object data structure + */ +export async function migrateToTextObjects({ + history, + objectStorageClient: objectStorageClient, +}: Dependencies): Promise { + const legacyTextContent = history.getLegacySavedEditorState(); + + if (!legacyTextContent) return; + + await objectStorageClient.text.create({ + createdAt: Date.now(), + updatedAt: Date.now(), + text: legacyTextContent.content, + }); + + history.deleteLegacySavedEditorState(); } diff --git a/src/legacy/core_plugins/console/public/np_ready/application/hooks/use_data_init/index.ts b/src/legacy/core_plugins/console/public/np_ready/application/hooks/use_data_init/index.ts new file mode 100644 index 00000000000000..582aa047f7d408 --- /dev/null +++ b/src/legacy/core_plugins/console/public/np_ready/application/hooks/use_data_init/index.ts @@ -0,0 +1,19 @@ +/* + * 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. + */ +export { useDataInit } from './use_data_init'; diff --git a/src/legacy/core_plugins/console/public/np_ready/application/hooks/use_data_init/use_data_init.ts b/src/legacy/core_plugins/console/public/np_ready/application/hooks/use_data_init/use_data_init.ts new file mode 100644 index 00000000000000..2212827c1f5980 --- /dev/null +++ b/src/legacy/core_plugins/console/public/np_ready/application/hooks/use_data_init/use_data_init.ts @@ -0,0 +1,72 @@ +/* + * 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 { useCallback, useEffect, useState } from 'react'; +import { migrateToTextObjects } from './data_migration'; +import { useEditorActionContext, useServicesContext } from '../../contexts'; + +export const useDataInit = () => { + const [error, setError] = useState(null); + const [done, setDone] = useState(false); + const [retryToken, setRetryToken] = useState({}); + + const retry = useCallback(() => { + setRetryToken({}); + setDone(false); + setError(null); + }, []); + + const { + services: { objectStorageClient, history }, + } = useServicesContext(); + + const dispatch = useEditorActionContext(); + + useEffect(() => { + const load = async () => { + try { + await migrateToTextObjects({ history, objectStorageClient }); + const results = await objectStorageClient.text.findAll(); + if (!results.length) { + const newObject = await objectStorageClient.text.create({ + createdAt: Date.now(), + updatedAt: Date.now(), + text: '', + }); + dispatch({ type: 'setCurrentTextObject', payload: newObject }); + } else { + // For now, we always take the first text object returned. + dispatch({ type: 'setCurrentTextObject', payload: results[0] }); + } + } catch (e) { + setError(e); + } finally { + setDone(true); + } + }; + + load(); + }, [dispatch, objectStorageClient, history, retryToken]); + + return { + error, + done, + retry, + }; +}; diff --git a/src/legacy/core_plugins/console/public/np_ready/application/hooks/use_save_current_text_object.ts b/src/legacy/core_plugins/console/public/np_ready/application/hooks/use_save_current_text_object.ts new file mode 100644 index 00000000000000..ab517ba1bfdd13 --- /dev/null +++ b/src/legacy/core_plugins/console/public/np_ready/application/hooks/use_save_current_text_object.ts @@ -0,0 +1,49 @@ +/* + * 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 { useRef, useCallback } from 'react'; +import { throttle } from 'lodash'; +import { useEditorReadContext, useServicesContext } from '../contexts'; + +const WAIT_MS = 500; + +export const useSaveCurrentTextObject = () => { + const promiseChainRef = useRef(Promise.resolve()); + + const { + services: { objectStorageClient }, + } = useServicesContext(); + + const { currentTextObject } = useEditorReadContext(); + + return useCallback( + throttle( + (text: string) => { + const { current: promise } = promiseChainRef; + if (!currentTextObject) return; + promise.finally(() => + objectStorageClient.text.update({ ...currentTextObject, text, updatedAt: Date.now() }) + ); + }, + WAIT_MS, + { trailing: true } + ), + [objectStorageClient, currentTextObject] + ); +}; diff --git a/src/legacy/core_plugins/console/public/np_ready/application/index.tsx b/src/legacy/core_plugins/console/public/np_ready/application/index.tsx index 89756513b2b22c..efd0f2ba860240 100644 --- a/src/legacy/core_plugins/console/public/np_ready/application/index.tsx +++ b/src/legacy/core_plugins/console/public/np_ready/application/index.tsx @@ -18,10 +18,11 @@ */ import React from 'react'; -import { NotificationsSetup } from 'kibana/public'; +import { NotificationsSetup } from 'src/core/public'; import { ServicesContextProvider, EditorContextProvider, RequestContextProvider } from './contexts'; import { Main } from './containers'; import { createStorage, createHistory, createSettings, Settings } from '../services'; +import * as localStorageObjectClient from '../lib/local_storage_object_client'; import { createUsageTracker } from '../services/tracker'; let settingsRef: Settings; @@ -46,6 +47,7 @@ export function boot(deps: { }); const history = createHistory({ storage }); const settings = createSettings({ storage }); + const objectStorageClient = localStorageObjectClient.create(storage); settingsRef = settings; return ( @@ -60,6 +62,7 @@ export function boot(deps: { settings, notifications, trackUiMetric, + objectStorageClient, }, }} > diff --git a/src/legacy/core_plugins/console/public/np_ready/application/stores/editor.ts b/src/legacy/core_plugins/console/public/np_ready/application/stores/editor.ts index 339a2f7a2c4af5..844eacd9b91a8c 100644 --- a/src/legacy/core_plugins/console/public/np_ready/application/stores/editor.ts +++ b/src/legacy/core_plugins/console/public/np_ready/application/stores/editor.ts @@ -21,22 +21,26 @@ import { Reducer } from 'react'; import { produce } from 'immer'; import { identity } from 'fp-ts/lib/function'; import { DevToolsSettings } from '../../services'; +import { TextObject } from '../../../../common/text_object'; export interface Store { ready: boolean; settings: DevToolsSettings; + currentTextObject: TextObject | null; } export const initialValue: Store = produce( { ready: false, settings: null as any, + currentTextObject: null, }, identity ); export type Action = | { type: 'setInputEditor'; payload: any } + | { type: 'setCurrentTextObject'; payload: any } | { type: 'updateSettings'; payload: DevToolsSettings }; export const reducer: Reducer = (state, action) => @@ -53,5 +57,10 @@ export const reducer: Reducer = (state, action) => return; } + if (action.type === 'setCurrentTextObject') { + draft.currentTextObject = action.payload; + return; + } + return draft; }); diff --git a/src/legacy/core_plugins/console/public/np_ready/application/styles/_app.scss b/src/legacy/core_plugins/console/public/np_ready/application/styles/_app.scss index 159e9f9e8a1730..c69440225236b0 100644 --- a/src/legacy/core_plugins/console/public/np_ready/application/styles/_app.scss +++ b/src/legacy/core_plugins/console/public/np_ready/application/styles/_app.scss @@ -26,6 +26,10 @@ // Required on IE11 to render ace editor correctly after first input. position: relative; + + &__spinner { + width: 100%; + } } .conApp__output { diff --git a/src/legacy/core_plugins/console/public/np_ready/lib/local_storage_object_client/create.ts b/src/legacy/core_plugins/console/public/np_ready/lib/local_storage_object_client/create.ts new file mode 100644 index 00000000000000..36948b9acb9626 --- /dev/null +++ b/src/legacy/core_plugins/console/public/np_ready/lib/local_storage_object_client/create.ts @@ -0,0 +1,29 @@ +/* + * 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 { Storage } from '../../services'; +import { ObjectStorageClient } from '../../../../common/types'; +import { TextObject, textObjectTypeName } from '../../../../common/text_object'; +import { LocalObjectStorage } from './local_storage_object_client'; + +export const create = (storage: Storage): ObjectStorageClient => { + return { + text: new LocalObjectStorage(storage, textObjectTypeName), + }; +}; diff --git a/src/legacy/core_plugins/console/public/np_ready/lib/local_storage_object_client/index.ts b/src/legacy/core_plugins/console/public/np_ready/lib/local_storage_object_client/index.ts new file mode 100644 index 00000000000000..c170b8721a04dd --- /dev/null +++ b/src/legacy/core_plugins/console/public/np_ready/lib/local_storage_object_client/index.ts @@ -0,0 +1,21 @@ +/* + * 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. + */ + +export { create } from './create'; +export { LocalObjectStorage } from './local_storage_object_client'; diff --git a/src/legacy/core_plugins/console/public/np_ready/lib/local_storage_object_client/local_storage_object_client.ts b/src/legacy/core_plugins/console/public/np_ready/lib/local_storage_object_client/local_storage_object_client.ts new file mode 100644 index 00000000000000..41c88d23b2533d --- /dev/null +++ b/src/legacy/core_plugins/console/public/np_ready/lib/local_storage_object_client/local_storage_object_client.ts @@ -0,0 +1,53 @@ +/* + * 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 uuid from 'uuid'; +import { ObjectStorage, IdObject } from '../../../../common/types'; +import { Storage } from '../../services'; + +export class LocalObjectStorage implements ObjectStorage { + private readonly prefix: string; + + constructor(private readonly client: Storage, type: string) { + this.prefix = `console_local_${type}`; + } + + async create(obj: Omit): Promise { + const id = uuid.v4(); + const newObj = { id, ...obj } as O; + this.client.set(`${this.prefix}_${id}`, newObj); + return newObj; + } + + async update(obj: O): Promise { + this.client.set(`${this.prefix}_${obj.id}`, obj); + } + + async findAll(): Promise { + const allLocalKeys = this.client.keys().filter(key => { + return key.includes(this.prefix); + }); + + const result = []; + for (const key of allLocalKeys) { + result.push(this.client.get(key)); + } + return result; + } +} diff --git a/src/legacy/core_plugins/console/public/np_ready/plugin.ts b/src/legacy/core_plugins/console/public/np_ready/plugin.ts index cbe262b1246772..22351ae95ba872 100644 --- a/src/legacy/core_plugins/console/public/np_ready/plugin.ts +++ b/src/legacy/core_plugins/console/public/np_ready/plugin.ts @@ -55,11 +55,11 @@ export class ConsoleUIPlugin implements Plugin { defaultMessage: 'Console', }), enableRouting: false, - async mount(ctx, { element }) { + async mount({ core: { docLinks } }, { element }) { const { boot } = await import('./application'); render( boot({ - docLinkVersion: ctx.core.docLinks.DOC_LINK_VERSION, + docLinkVersion: docLinks.DOC_LINK_VERSION, I18nContext, notifications, elasticsearchUrl, diff --git a/src/legacy/core_plugins/console/public/np_ready/services/history.ts b/src/legacy/core_plugins/console/public/np_ready/services/history.ts index 6cb6f7ba35cd44..04dae0beacefee 100644 --- a/src/legacy/core_plugins/console/public/np_ready/services/history.ts +++ b/src/legacy/core_plugins/console/public/np_ready/services/history.ts @@ -74,13 +74,20 @@ export class History { }); } - getSavedEditorState() { + getLegacySavedEditorState() { const saved = this.storage.get('editor_state'); if (!saved) return; const { time, content } = saved; return { time, content }; } + /** + * This function should only ever be called once for a user if they had legacy state. + */ + deleteLegacySavedEditorState() { + this.storage.delete('editor_state'); + } + clearHistory() { this.getHistoryKeys().forEach(key => this.storage.delete(key)); } diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/package.json b/src/legacy/core_plugins/kbn_vislib_vis_types/package.json deleted file mode 100644 index b6df6eb794de8b..00000000000000 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "kbn_vislib_vis_types", - "version": "kibana" -} diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controller.js b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controller.js deleted file mode 100644 index 46f2376cb03eb7..00000000000000 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controller.js +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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 $ from 'jquery'; -import React from 'react'; - -import { - CUSTOM_LEGEND_VIS_TYPES, - VisLegend, -} from '../../../ui/public/vis/vis_types/vislib_vis_legend'; -import { VislibVisProvider } from '../../../ui/public/vislib/vis'; -import chrome from '../../../ui/public/chrome'; -import { mountReactNode } from '../../../../core/public/utils'; - -const legendClassName = { - top: 'visLib--legend-top', - bottom: 'visLib--legend-bottom', - left: 'visLib--legend-left', - right: 'visLib--legend-right', -}; - -export class vislibVisController { - constructor(el, vis) { - this.el = el; - this.vis = vis; - this.unmount = null; - this.legendRef = React.createRef(); - - // vis mount point - this.container = document.createElement('div'); - this.container.className = 'visLib'; - this.el.appendChild(this.container); - - // chart mount point - this.chartEl = document.createElement('div'); - this.chartEl.className = 'visLib__chart'; - this.container.appendChild(this.chartEl); - // legend mount point - this.legendEl = document.createElement('div'); - this.legendEl.className = 'visLib__legend'; - this.container.appendChild(this.legendEl); - } - - render(esResponse, visParams) { - if (this.vislibVis) { - this.destroy(); - } - - return new Promise(async resolve => { - if (!this.vislib) { - const $injector = await chrome.dangerouslyGetActiveInjector(); - const Private = $injector.get('Private'); - this.Vislib = Private(VislibVisProvider); - } - - if (this.el.clientWidth === 0 || this.el.clientHeight === 0) { - return resolve(); - } - - this.vislibVis = new this.Vislib(this.chartEl, visParams); - this.vislibVis.on('brush', this.vis.API.events.brush); - this.vislibVis.on('click', this.vis.API.events.filter); - this.vislibVis.on('renderComplete', resolve); - - this.vislibVis.initVisConfig(esResponse, this.vis.getUiState()); - - if (visParams.addLegend) { - $(this.container) - .attr('class', (i, cls) => { - return cls.replace(/visLib--legend-\S+/g, ''); - }) - .addClass(legendClassName[visParams.legendPosition]); - - this.mountLegend(esResponse, visParams.legendPosition); - } - - this.vislibVis.render(esResponse, this.vis.getUiState()); - - // refreshing the legend after the chart is rendered. - // this is necessary because some visualizations - // provide data necessary for the legend only after a render cycle. - if ( - visParams.addLegend && - CUSTOM_LEGEND_VIS_TYPES.includes(this.vislibVis.visConfigArgs.type) - ) { - this.unmountLegend(); - this.mountLegend(esResponse, visParams.legendPosition); - this.vislibVis.render(esResponse, this.vis.getUiState()); - } - }); - } - - mountLegend(visData, position) { - this.unmount = mountReactNode( - - )(this.legendEl); - } - - unmountLegend() { - if (this.unmount) { - this.unmount(); - } - } - - destroy() { - if (this.unmount) { - this.unmount(); - } - - if (this.vislibVis) { - this.vislibVis.off('brush', this.vis.API.events.brush); - this.vislibVis.off('click', this.vis.API.events.filter); - this.vislibVis.destroy(); - delete this.vislibVis; - } - } -} diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/kbn_vislib_vis_types.js b/src/legacy/core_plugins/kbn_vislib_vis_types/public/kbn_vislib_vis_types.js deleted file mode 100644 index c82073ff582b8c..00000000000000 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/kbn_vislib_vis_types.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 { setup as visualizations } from '../../visualizations/public/np_ready/public/legacy'; - -import { histogramDefinition } from './histogram'; -import { lineDefinition } from './line'; -import { pieDefinition } from './pie'; -import { areaDefinition } from './area'; -import { heatmapDefinition } from './heatmap'; -import { horizontalBarDefinition } from './horizontal_bar'; -import { gaugeDefinition } from './gauge'; -import { goalDefinition } from './goal'; - -visualizations.types.createBaseVisualization(histogramDefinition); -visualizations.types.createBaseVisualization(lineDefinition); -visualizations.types.createBaseVisualization(pieDefinition); -visualizations.types.createBaseVisualization(areaDefinition); -visualizations.types.createBaseVisualization(heatmapDefinition); -visualizations.types.createBaseVisualization(horizontalBarDefinition); -visualizations.types.createBaseVisualization(gaugeDefinition); -visualizations.types.createBaseVisualization(goalDefinition); diff --git a/src/legacy/core_plugins/kibana/index.js b/src/legacy/core_plugins/kibana/index.js index 111b74d8aa6af9..e6a0420534ef25 100644 --- a/src/legacy/core_plugins/kibana/index.js +++ b/src/legacy/core_plugins/kibana/index.js @@ -61,10 +61,7 @@ export default function(kibana) { uiExports: { hacks: ['plugins/kibana/discover', 'plugins/kibana/dev_tools', 'plugins/kibana/visualize'], - savedObjectTypes: [ - 'plugins/kibana/visualize/saved_visualizations/saved_visualization_register', - 'plugins/kibana/dashboard/saved_dashboard/saved_dashboard_register', - ], + savedObjectTypes: ['plugins/kibana/dashboard/saved_dashboard/saved_dashboard_register'], app: { id: 'kibana', title: 'Kibana', diff --git a/src/legacy/core_plugins/kibana/public/dashboard/legacy_imports.ts b/src/legacy/core_plugins/kibana/public/dashboard/legacy_imports.ts index ba019194310807..b44d1993db23a4 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/legacy_imports.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/legacy_imports.ts @@ -65,6 +65,6 @@ export { ensureDefaultIndexPattern } from 'ui/legacy_compat'; export { unhashUrl } from '../../../../../plugins/kibana_utils/public'; export { IInjector } from 'ui/chrome'; export { SavedObjectLoader } from 'ui/saved_objects'; -export { VISUALIZE_EMBEDDABLE_TYPE } from '../visualize_embeddable'; +export { VISUALIZE_EMBEDDABLE_TYPE } from '../../../visualizations/public/embeddable'; export { registerTimefilterWithGlobalStateFactory } from 'ui/timefilter/setup_router'; export { absoluteToParsedUrl } from 'ui/url/absolute_to_parsed_url'; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/url_helper.ts b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/url_helper.ts index 2e360567c4653f..73383f2ff3f68b 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/url_helper.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/url_helper.ts @@ -25,11 +25,9 @@ import { DashboardConstants } from './dashboard_constants'; */ export function getUrlVars(url: string): Record { const vars: Record = {}; - // @ts-ignore - url.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(_, key, value) { - // @ts-ignore + for (const [, key, value] of url.matchAll(/[?&]+([^=&]+)=([^&]*)/gi)) { vars[key] = decodeURIComponent(value); - }); + } return vars; } diff --git a/src/legacy/core_plugins/kibana/public/index.scss b/src/legacy/core_plugins/kibana/public/index.scss index dfe4aa1fd3b9f9..324458c0814d9f 100644 --- a/src/legacy/core_plugins/kibana/public/index.scss +++ b/src/legacy/core_plugins/kibana/public/index.scss @@ -7,6 +7,9 @@ // Public UI styles @import 'src/legacy/ui/public/index'; +// vis_type_vislib UI styles +@import 'src/legacy/core_plugins/vis_type_vislib/public/index'; + // Dev tools styles @import './dev_tools/index'; @@ -18,7 +21,6 @@ // Visualize styles @import './visualize/index'; -@import './visualize_embeddable/index'; // Has to come after visualize because of some // bad cascading in the Editor layout @import 'src/legacy/ui/public/vis/index'; diff --git a/src/legacy/core_plugins/kibana/public/kibana.js b/src/legacy/core_plugins/kibana/public/kibana.js index 334397c479a1d2..4100ae72058699 100644 --- a/src/legacy/core_plugins/kibana/public/kibana.js +++ b/src/legacy/core_plugins/kibana/public/kibana.js @@ -52,7 +52,7 @@ import './visualize'; import './dashboard'; import './management'; import './dev_tools'; -import 'ui/vislib'; +import 'ui/color_maps'; import 'ui/agg_response'; import 'ui/agg_types'; import { showAppRedirectNotification } from 'ui/notify'; diff --git a/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts b/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts index 141063adcbd6ab..189624fdbb2b3e 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts @@ -72,6 +72,5 @@ export { VisType } from 'ui/vis'; export { wrapInI18nContext } from 'ui/i18n'; export { DashboardConstants } from '../dashboard/np_ready/dashboard_constants'; -export { VisSavedObject } from '../visualize_embeddable/visualize_embeddable'; -export { VISUALIZE_EMBEDDABLE_TYPE } from '../visualize_embeddable'; -export { VisualizeEmbeddableFactory } from '../visualize_embeddable/visualize_embeddable_factory'; +export { VisSavedObject } from '../../../visualizations/public/embeddable/visualize_embeddable'; +export { VISUALIZE_EMBEDDABLE_TYPE } from '../../../visualizations/public/embeddable'; diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js index 64653730473cdd..a80aed5302d1ff 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js @@ -357,7 +357,10 @@ function VisualizeAppController( }; $scope.showQueryBarTimePicker = () => { - return vis.type.options.showTimePicker; + // tsvb loads without an indexPattern initially (TODO investigate). + // hide timefilter only if timeFieldName is explicitly undefined. + const hasTimeField = $scope.indexPattern ? !!$scope.indexPattern.timeFieldName : true; + return vis.type.options.showTimePicker && hasTimeField; }; $scope.timeRange = timefilter.getTime(); diff --git a/src/legacy/core_plugins/kibana/public/visualize/plugin.ts b/src/legacy/core_plugins/kibana/public/visualize/plugin.ts index 9ea26f129895ce..660e8169664c4d 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/plugin.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/plugin.ts @@ -27,6 +27,9 @@ import { SavedObjectsClientContract, } from 'kibana/public'; +// @ts-ignore +import { uiModules } from 'ui/modules'; + import { Storage } from '../../../../../plugins/kibana_utils/public'; import { DataPublicPluginStart } from '../../../../../plugins/data/public'; import { IEmbeddableStart } from '../../../../../plugins/embeddable/public'; @@ -40,14 +43,11 @@ import { FeatureCatalogueCategory, HomePublicPluginSetup, } from '../../../../../plugins/home/public'; -import { - defaultEditor, - VisEditorTypesRegistryProvider, - VisualizeEmbeddableFactory, - VISUALIZE_EMBEDDABLE_TYPE, -} from './legacy_imports'; +import { defaultEditor, VisEditorTypesRegistryProvider } from './legacy_imports'; import { UsageCollectionSetup } from '../../../../../plugins/usage_collection/public'; import { createSavedVisLoader } from './saved_visualizations/saved_visualizations'; +// @ts-ignore +import { savedObjectManagementRegistry } from '../management/saved_object_registry'; export interface LegacyAngularInjectedDependencies { legacyChrome: any; @@ -113,6 +113,7 @@ export class VisualizePlugin implements Plugin { indexPatterns: data.indexPatterns, chrome: contextCore.chrome, overlays: contextCore.overlays, + visualizations, }); const deps: VisualizeKibanaServices = { ...angularDependencies, @@ -159,19 +160,32 @@ export class VisualizePlugin implements Plugin { } public start( - { savedObjects: { client: savedObjectsClient } }: CoreStart, + core: CoreStart, { embeddables, navigation, data, share, visualizations }: VisualizePluginStartDependencies ) { this.startDependencies = { data, embeddables, navigation, - savedObjectsClient, + savedObjectsClient: core.savedObjects.client, share, visualizations, }; - const embeddableFactory = new VisualizeEmbeddableFactory(visualizations.types); - embeddables.registerEmbeddableFactory(VISUALIZE_EMBEDDABLE_TYPE, embeddableFactory); + const savedVisualizations = createSavedVisLoader({ + savedObjectsClient: core.savedObjects.client, + indexPatterns: data.indexPatterns, + chrome: core.chrome, + overlays: core.overlays, + visualizations, + }); + + // TODO: remove once savedobjectregistry is refactored + savedObjectManagementRegistry.register({ + service: 'savedVisualizations', + title: 'visualizations', + }); + + uiModules.get('app/visualize').service('savedVisualizations', () => savedVisualizations); } } diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.ts b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.ts index 9f7ba342d803f5..a0a6f8ea1c8a24 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.ts @@ -34,7 +34,7 @@ import { IIndexPattern } from '../../../../../../plugins/data/public'; import { VisSavedObject } from '../legacy_imports'; import { createSavedSearchesService } from '../../discover'; -import { VisualizeConstants } from '..'; +import { VisualizeConstants } from '../np_ready/visualize_constants'; async function _afterEsResp(savedVis: VisSavedObject, services: any) { await _getLinkedSavedSearch(savedVis, services); diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.ts b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.ts index b71a10ab000d89..98f5458d5eecc2 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.ts @@ -18,7 +18,7 @@ */ import { extractReferences, injectReferences } from './saved_visualization_references'; -import { VisSavedObject } from '../../visualize_embeddable/visualize_embeddable'; +import { VisSavedObject } from '../../../../visualizations/public/embeddable/visualize_embeddable'; describe('extractReferences', () => { test('extracts nothing if savedSearchId is empty', () => { diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.ts b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.ts index 0c76aaff4345d8..403e9c5a8172d6 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.ts @@ -17,7 +17,7 @@ * under the License. */ import { SavedObjectAttributes, SavedObjectReference } from 'kibana/server'; -import { VisSavedObject } from '../../visualize_embeddable/visualize_embeddable'; +import { VisSavedObject } from '../../../../visualizations/public/embeddable/visualize_embeddable'; export function extractReferences({ attributes, diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_register.ts b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_register.ts deleted file mode 100644 index cbf72339804ce9..00000000000000 --- a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_register.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 { npStart } from 'ui/new_platform'; -// @ts-ignore -import { uiModules } from 'ui/modules'; -// @ts-ignore -import { savedObjectManagementRegistry } from '../../management/saved_object_registry'; -import './saved_visualizations'; -import { createSavedVisLoader } from './saved_visualizations'; - -const services = { - savedObjectsClient: npStart.core.savedObjects.client, - indexPatterns: npStart.plugins.data.indexPatterns, - chrome: npStart.core.chrome, - overlays: npStart.core.overlays, -}; - -const savedObjectLoaderVisualize = createSavedVisLoader(services); - -// Register this service with the saved object registry so it can be -// edited by the object editor. -savedObjectManagementRegistry.register({ - service: 'savedVisualizations', - title: 'visualizations', -}); - -uiModules.get('app/visualize').service('savedVisualizations', () => savedObjectLoaderVisualize); diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualizations.ts b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualizations.ts index c19c7818c1fbda..d51fae74289391 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualizations.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualizations.ts @@ -19,14 +19,18 @@ import { SavedObjectLoader } from 'ui/saved_objects'; import { SavedObjectKibanaServices } from 'ui/saved_objects/types'; -import { start as visualizations } from '../../../../visualizations/public/np_ready/public/legacy'; // @ts-ignore import { findListItems } from './find_list_items'; import { createSavedVisClass } from './_saved_vis'; -import { createVisualizeEditUrl } from '..'; +import { createVisualizeEditUrl } from '../np_ready/visualize_constants'; +import { VisualizationsStart } from '../../../../visualizations/public/np_ready/public'; -export function createSavedVisLoader(services: SavedObjectKibanaServices) { - const { savedObjectsClient } = services; +interface SavedObjectKibanaServicesWithVisualizations extends SavedObjectKibanaServices { + visualizations: VisualizationsStart; +} + +export function createSavedVisLoader(services: SavedObjectKibanaServicesWithVisualizations) { + const { savedObjectsClient, visualizations } = services; class SavedObjectLoaderVisualize extends SavedObjectLoader { mapHitSource = (source: Record, id: string) => { diff --git a/src/legacy/core_plugins/region_map/public/choropleth_layer.js b/src/legacy/core_plugins/region_map/public/choropleth_layer.js index f4c6bfd6bedf5b..8132976fcbc69b 100644 --- a/src/legacy/core_plugins/region_map/public/choropleth_layer.js +++ b/src/legacy/core_plugins/region_map/public/choropleth_layer.js @@ -23,7 +23,7 @@ import _ from 'lodash'; import d3 from 'd3'; import { i18n } from '@kbn/i18n'; import { KibanaMapLayer } from 'ui/vis/map/kibana_map_layer'; -import { truncatedColorMaps } from 'ui/vislib/components/color/truncated_colormaps'; +import { truncatedColorMaps } from 'ui/color_maps'; import * as topojson from 'topojson-client'; import { toastNotifications } from 'ui/notify'; import * as colorUtil from 'ui/vis/map/color_util'; diff --git a/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx b/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx index 8306b3274a9144..73fe07ec60102d 100644 --- a/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx +++ b/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx @@ -28,7 +28,7 @@ import { NumberInputOption, SelectOption, SwitchOption, -} from '../../../kbn_vislib_vis_types/public/components'; +} from '../../../vis_type_vislib/public/components'; import { WmsOptions } from '../../../tile_map/public/components/wms_options'; import { RegionMapVisParams } from '../types'; diff --git a/src/legacy/core_plugins/region_map/public/region_map_type.js b/src/legacy/core_plugins/region_map/public/region_map_type.js index 6f83ae912e1842..39353a379ce52d 100644 --- a/src/legacy/core_plugins/region_map/public/region_map_type.js +++ b/src/legacy/core_plugins/region_map/public/region_map_type.js @@ -19,7 +19,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { Schemas } from 'ui/vis/editors/default/schemas'; -import { colorSchemas } from 'ui/vislib/components/color/truncated_colormaps'; +import { truncatedColorSchemas as colorSchemas } from 'ui/color_maps'; import { mapToLayerWithId } from './util'; import { createRegionMapVisualization } from './region_map_visualization'; import { Status } from '../../visualizations/public'; diff --git a/src/legacy/core_plugins/region_map/public/region_map_visualization.js b/src/legacy/core_plugins/region_map/public/region_map_visualization.js index b58de5d9c6ab71..f9a5793ca8137d 100644 --- a/src/legacy/core_plugins/region_map/public/region_map_visualization.js +++ b/src/legacy/core_plugins/region_map/public/region_map_visualization.js @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; import ChoroplethLayer from './choropleth_layer'; -import { truncatedColorMaps } from 'ui/vislib/components/color/truncated_colormaps'; +import { truncatedColorMaps } from 'ui/color_maps'; import { getFormat } from 'ui/visualize/loader/pipeline_helpers/utilities'; import { toastNotifications } from 'ui/notify'; diff --git a/src/legacy/core_plugins/tile_map/public/components/tile_map_options.tsx b/src/legacy/core_plugins/tile_map/public/components/tile_map_options.tsx index 15c92f4617497a..e57cea8467d124 100644 --- a/src/legacy/core_plugins/tile_map/public/components/tile_map_options.tsx +++ b/src/legacy/core_plugins/tile_map/public/components/tile_map_options.tsx @@ -27,7 +27,7 @@ import { RangeOption, SelectOption, SwitchOption, -} from '../../../kbn_vislib_vis_types/public/components'; +} from '../../../vis_type_vislib/public/components'; import { WmsOptions } from './wms_options'; import { TileMapVisParams } from '../types'; import { MapTypes } from '../map_types'; diff --git a/src/legacy/core_plugins/tile_map/public/components/wms_internal_options.tsx b/src/legacy/core_plugins/tile_map/public/components/wms_internal_options.tsx index f2cf69bb63ba43..2989f6ce7ebd58 100644 --- a/src/legacy/core_plugins/tile_map/public/components/wms_internal_options.tsx +++ b/src/legacy/core_plugins/tile_map/public/components/wms_internal_options.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { EuiLink, EuiSpacer, EuiText, EuiScreenReaderOnly } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { TextInputOption } from '../../../kbn_vislib_vis_types/public/components'; +import { TextInputOption } from '../../../vis_type_vislib/public/components'; import { WMSOptions } from '../types'; interface WmsInternalOptions { diff --git a/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx b/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx index c5ccc3acba6104..d9dca5afd73776 100644 --- a/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx +++ b/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx @@ -25,7 +25,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { TmsLayer } from 'ui/vis/map/service_settings'; import { Vis } from 'ui/vis'; import { RegionMapVisParams } from '../../../region_map/public/types'; -import { SelectOption, SwitchOption } from '../../../kbn_vislib_vis_types/public/components'; +import { SelectOption, SwitchOption } from '../../../vis_type_vislib/public/components'; import { WmsInternalOptions } from './wms_internal_options'; import { WMSOptions, TileMapVisParams } from '../types'; diff --git a/src/legacy/core_plugins/tile_map/public/markers/scaled_circles.js b/src/legacy/core_plugins/tile_map/public/markers/scaled_circles.js index e9334ff91def9a..fe29d9b6aad21b 100644 --- a/src/legacy/core_plugins/tile_map/public/markers/scaled_circles.js +++ b/src/legacy/core_plugins/tile_map/public/markers/scaled_circles.js @@ -22,7 +22,7 @@ import _ from 'lodash'; import d3 from 'd3'; import $ from 'jquery'; import { EventEmitter } from 'events'; -import { truncatedColorMaps } from 'ui/vislib/components/color/truncated_colormaps'; +import { truncatedColorMaps } from 'ui/color_maps'; import * as colorUtil from 'ui/vis/map/color_util'; export class ScaledCirclesMarkers extends EventEmitter { diff --git a/src/legacy/core_plugins/tile_map/public/tile_map_type.js b/src/legacy/core_plugins/tile_map/public/tile_map_type.js index f2e6469e768e7e..c58c226f0aba0e 100644 --- a/src/legacy/core_plugins/tile_map/public/tile_map_type.js +++ b/src/legacy/core_plugins/tile_map/public/tile_map_type.js @@ -21,7 +21,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { Schemas } from 'ui/vis/editors/default/schemas'; -import { colorSchemas } from 'ui/vislib/components/color/truncated_colormaps'; +import { truncatedColorSchemas as colorSchemas } from 'ui/color_maps'; import { convertToGeoJson } from 'ui/vis/map/convert_to_geojson'; import { createTileMapVisualization } from './tile_map_visualization'; diff --git a/src/legacy/core_plugins/vis_type_markdown/public/settings_options.tsx b/src/legacy/core_plugins/vis_type_markdown/public/settings_options.tsx index cce92a08f2c2b2..125577815c207b 100644 --- a/src/legacy/core_plugins/vis_type_markdown/public/settings_options.tsx +++ b/src/legacy/core_plugins/vis_type_markdown/public/settings_options.tsx @@ -22,7 +22,7 @@ import { EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { VisOptionsProps } from 'ui/vis/editors/default'; -import { RangeOption, SwitchOption } from '../../kbn_vislib_vis_types/public/components'; +import { RangeOption, SwitchOption } from '../../vis_type_vislib/public/components'; import { MarkdownVisParams } from './types'; function SettingsOptions({ stateParams, setValue }: VisOptionsProps) { diff --git a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_controller.js b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_controller.js index ecaf6b5d70d362..17dad6a4cd8cb1 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_controller.js +++ b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_controller.js @@ -20,7 +20,7 @@ import { last, findIndex, isNaN } from 'lodash'; import React, { Component } from 'react'; import { isColorDark } from '@elastic/eui'; -import { getHeatmapColors } from 'ui/vislib/components/color/heatmap_color'; +import { getHeatmapColors } from 'ui/color_maps'; import { getFormat } from 'ui/visualize/loader/pipeline_helpers/utilities'; import { MetricVisValue } from './metric_vis_value'; diff --git a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_options.tsx b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_options.tsx index 9649588976c0d1..566618c5270197 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_options.tsx +++ b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_options.tsx @@ -36,8 +36,8 @@ import { SwitchOption, RangeOption, SetColorSchemaOptionsValue, -} from '../../../kbn_vislib_vis_types/public/components'; -import { ColorModes } from '../../../kbn_vislib_vis_types/public/utils/collections'; +} from '../../../vis_type_vislib/public/components'; +import { ColorModes } from '../../../vis_type_vislib/public/utils/collections'; import { MetricVisParam, VisParams } from '../types'; function MetricVisOptions({ diff --git a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_fn.ts b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_fn.ts index b64361f17c4703..04bff5ccb46557 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_fn.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_fn.ts @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; -import { vislibColorMaps, ColorSchemas } from 'ui/vislib/components/color/colormaps'; +import { vislibColorMaps, ColorSchemas } from 'ui/color_maps'; import { ExpressionFunction, KibanaDatatable, @@ -27,7 +27,7 @@ import { Render, Style, } from '../../../../plugins/expressions/public'; -import { ColorModes } from '../../kbn_vislib_vis_types/public/utils/collections'; +import { ColorModes } from '../../vis_type_vislib/public/utils/collections'; import { visType, DimensionsVisParam, VisParams } from './types'; type Context = KibanaDatatable; diff --git a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.ts b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.ts index ceab5dafe1f064..9b22423012b366 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.ts @@ -23,13 +23,13 @@ import { i18n } from '@kbn/i18n'; import { Schemas } from 'ui/vis/editors/default/schemas'; import { AggGroupNames } from 'ui/vis/editors/default'; -import { colorSchemas, ColorSchemas } from 'ui/vislib/components/color/colormaps'; +import { colorSchemas, ColorSchemas } from 'ui/color_maps'; // @ts-ignore import { MetricVisComponent } from './components/metric_vis_controller'; import { MetricVisOptions } from './components/metric_vis_options'; -import { ColorModes } from '../../kbn_vislib_vis_types/public/utils/collections'; +import { ColorModes } from '../../vis_type_vislib/public/utils/collections'; export const metricVisDefinition = { name: 'metric', diff --git a/src/legacy/core_plugins/vis_type_metric/public/types.ts b/src/legacy/core_plugins/vis_type_metric/public/types.ts index ce0e78140a86a4..06ec509f8c4d36 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/types.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/types.ts @@ -17,11 +17,11 @@ * under the License. */ -import { ColorSchemas } from 'ui/vislib/components/color/colormaps'; +import { ColorSchemas } from 'ui/color_maps'; import { RangeValues } from 'ui/vis/editors/default/controls/ranges'; import { SchemaConfig } from '../../visualizations/public'; -import { ColorModes } from '../../kbn_vislib_vis_types/public/utils/collections'; -import { Labels, Style } from '../../kbn_vislib_vis_types/public/types'; +import { ColorModes } from '../../vis_type_vislib/public/utils/collections'; +import { Labels, Style } from '../../vis_type_vislib/public/types'; export const visType = 'metric'; diff --git a/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx b/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx index 4d69af59b0c99f..be82b52dee0fc3 100644 --- a/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx +++ b/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx @@ -28,7 +28,7 @@ import { NumberInputOption, SwitchOption, SelectOption, -} from '../../../kbn_vislib_vis_types/public/components/common'; +} from '../../../vis_type_vislib/public/components/common'; import { TableVisParams } from '../types'; import { totalAggregations, isAggConfigNumeric } from './utils'; diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx index 9e6a2d1a24a85d..c500b5d888b053 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx @@ -23,7 +23,7 @@ import { i18n } from '@kbn/i18n'; import { ValidatedDualRange } from 'ui/validated_range'; import { VisOptionsProps } from 'ui/vis/editors/default'; -import { SelectOption, SwitchOption } from '../../../kbn_vislib_vis_types/public/components'; +import { SelectOption, SwitchOption } from '../../../vis_type_vislib/public/components'; import { TagCloudVisParams } from '../types'; function TagCloudOptions({ stateParams, setValue, vis }: VisOptionsProps) { diff --git a/src/legacy/core_plugins/vis_type_vislib/index.ts b/src/legacy/core_plugins/vis_type_vislib/index.ts new file mode 100644 index 00000000000000..8c24368f43ab18 --- /dev/null +++ b/src/legacy/core_plugins/vis_type_vislib/index.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 { resolve } from 'path'; +import { Legacy } from 'kibana'; + +import { LegacyPluginApi, LegacyPluginInitializer } from '../../types'; + +const kbnVislibVisTypesPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) => + new Plugin({ + id: 'vis_type_vislib', + require: ['kibana', 'elasticsearch', 'visualizations', 'interpreter', 'data'], + publicDir: resolve(__dirname, 'public'), + styleSheetPaths: resolve(__dirname, 'public/index.scss'), + uiExports: { + hacks: [resolve(__dirname, 'public/legacy')], + injectDefaultVars: server => ({}), + }, + init: (server: Legacy.Server) => ({}), + config(Joi: any) { + return Joi.object({ + enabled: Joi.boolean().default(true), + }).default(); + }, + } as Legacy.PluginSpecOptions); + +// eslint-disable-next-line import/no-default-export +export default kbnVislibVisTypesPluginInitializer; diff --git a/src/legacy/core_plugins/vis_type_vislib/package.json b/src/legacy/core_plugins/vis_type_vislib/package.json new file mode 100644 index 00000000000000..e30a9e2b358342 --- /dev/null +++ b/src/legacy/core_plugins/vis_type_vislib/package.json @@ -0,0 +1,4 @@ +{ + "name": "vis_type_vislib", + "version": "kibana" +} diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/__snapshots__/pie_fn.test.js.snap b/src/legacy/core_plugins/vis_type_vislib/public/__snapshots__/pie_fn.test.ts.snap similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/__snapshots__/pie_fn.test.js.snap rename to src/legacy/core_plugins/vis_type_vislib/public/__snapshots__/pie_fn.test.ts.snap diff --git a/src/legacy/core_plugins/vis_type_vislib/public/_index.scss b/src/legacy/core_plugins/vis_type_vislib/public/_index.scss new file mode 100644 index 00000000000000..64445648ba84a8 --- /dev/null +++ b/src/legacy/core_plugins/vis_type_vislib/public/_index.scss @@ -0,0 +1 @@ +@import './vislib/index' diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/area.js b/src/legacy/core_plugins/vis_type_vislib/public/area.ts similarity index 89% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/area.js rename to src/legacy/core_plugins/vis_type_vislib/public/area.ts index fd13067c84cc00..9484ddc16fe625 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/area.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/area.ts @@ -18,8 +18,12 @@ */ import { i18n } from '@kbn/i18n'; -import { Schemas } from 'ui/vis/editors/default/schemas'; -import { AggGroupNames } from 'ui/vis/editors/default'; +// @ts-ignore +import { palettes } from '@elastic/eui/lib/services'; +// @ts-ignore +import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; + +import { Schemas, AggGroupNames } from './legacy_imports'; import { Positions, ChartTypes, @@ -33,17 +37,17 @@ import { getConfigCollections, } from './utils/collections'; import { getAreaOptionTabs, countLabel } from './utils/common_config'; -import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; -import { vislibVisController } from './controller'; +import { createVislibVisController } from './vis_controller'; +import { KbnVislibVisTypesDependencies } from './plugin'; -export const areaDefinition = { +export const createAreaVisTypeDefinition = (deps: KbnVislibVisTypesDependencies) => ({ name: 'area', title: i18n.translate('kbnVislibVisTypes.area.areaTitle', { defaultMessage: 'Area' }), icon: 'visArea', description: i18n.translate('kbnVislibVisTypes.area.areaDescription', { defaultMessage: 'Emphasize the quantity beneath a line chart', }), - visualization: vislibVisController, + visualization: createVislibVisController(deps), visConfig: { defaults: { type: 'area', @@ -132,7 +136,9 @@ export const areaDefinition = { { group: AggGroupNames.Metrics, name: 'metric', - title: i18n.translate('kbnVislibVisTypes.area.metricsTitle', { defaultMessage: 'Y-axis' }), + title: i18n.translate('kbnVislibVisTypes.area.metricsTitle', { + defaultMessage: 'Y-axis', + }), aggFilter: ['!geo_centroid', '!geo_bounds'], min: 1, defaults: [{ schema: 'metric', type: 'count' }], @@ -140,7 +146,9 @@ export const areaDefinition = { { group: AggGroupNames.Metrics, name: 'radius', - title: i18n.translate('kbnVislibVisTypes.area.radiusTitle', { defaultMessage: 'Dot size' }), + title: i18n.translate('kbnVislibVisTypes.area.radiusTitle', { + defaultMessage: 'Dot size', + }), min: 0, max: 1, aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality'], @@ -148,7 +156,9 @@ export const areaDefinition = { { group: AggGroupNames.Buckets, name: 'segment', - title: i18n.translate('kbnVislibVisTypes.area.segmentTitle', { defaultMessage: 'X-axis' }), + title: i18n.translate('kbnVislibVisTypes.area.segmentTitle', { + defaultMessage: 'X-axis', + }), min: 0, max: 1, aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], @@ -175,4 +185,4 @@ export const areaDefinition = { }, ]), }, -}; +}); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/basic_options.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/basic_options.tsx similarity index 96% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/basic_options.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/basic_options.tsx index 2bffcb383dde3f..81174d63060e5c 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/basic_options.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/common/basic_options.tsx @@ -20,7 +20,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { VisOptionsProps } from 'ui/vis/editors/default'; +import { VisOptionsProps } from '../../legacy_imports'; import { SwitchOption } from './switch'; import { SelectOption } from './select'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/color_ranges.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/color_ranges.tsx similarity index 96% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/color_ranges.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/color_ranges.tsx index 947c7ae7e6e362..2bf58de2f93edf 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/color_ranges.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/common/color_ranges.tsx @@ -19,9 +19,10 @@ import React, { useCallback } from 'react'; import { last } from 'lodash'; + import { i18n } from '@kbn/i18n'; -import { RangeValues, RangesParamEditor } from 'ui/vis/editors/default/controls/ranges'; +import { RangeValues, RangesParamEditor } from '../../legacy_imports'; interface ColorRangesProps { 'data-test-subj'?: string; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/color_schema.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/color_schema.tsx similarity index 96% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/color_schema.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/color_schema.tsx index 44837c514d4cfa..7b4679ba25e8fe 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/color_schema.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/common/color_schema.tsx @@ -22,8 +22,7 @@ import { i18n } from '@kbn/i18n'; import { EuiLink, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from 'ui/vis/editors/default'; -import { ColorSchema } from 'ui/vislib/components/color/colormaps'; +import { VisOptionsProps, ColorSchema } from '../../legacy_imports'; import { SelectOption } from './select'; import { SwitchOption } from './switch'; import { ColorSchemaVislibParams } from '../../types'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/index.ts b/src/legacy/core_plugins/vis_type_vislib/public/components/common/index.ts similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/index.ts rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/index.ts diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/number_input.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/number_input.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/number_input.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/number_input.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/range.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/range.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/range.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/range.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/required_number_input.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/required_number_input.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/required_number_input.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/required_number_input.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/select.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/select.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/select.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/select.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/switch.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/switch.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/switch.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/switch.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/text_input.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/text_input.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/text_input.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/text_input.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/truncate_labels.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/truncate_labels.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/truncate_labels.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/truncate_labels.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/utils.ts b/src/legacy/core_plugins/vis_type_vislib/public/components/common/utils.ts similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/utils.ts rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/utils.ts diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/validation_wrapper.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/validation_wrapper.tsx similarity index 96% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/validation_wrapper.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/common/validation_wrapper.tsx index 1dd1ab49d9a47d..b38c65d086823f 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/validation_wrapper.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/common/validation_wrapper.tsx @@ -18,7 +18,8 @@ */ import React, { useEffect, useState, useCallback } from 'react'; -import { VisOptionsProps } from 'ui/vis/editors/default'; + +import { VisOptionsProps } from '../../legacy_imports'; export interface ValidationVisOptionsProps extends VisOptionsProps { setMultipleValidity(paramName: string, isValid: boolean): void; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/index.ts b/src/legacy/core_plugins/vis_type_vislib/public/components/index.ts similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/index.ts rename to src/legacy/core_plugins/vis_type_vislib/public/components/index.ts diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/index.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/index.tsx similarity index 97% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/index.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/index.tsx index e3805027d658c5..2ba4319a82a957 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/index.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/index.tsx @@ -20,7 +20,7 @@ import React, { useCallback } from 'react'; import { EuiSpacer } from '@elastic/eui'; -import { VisOptionsProps } from 'ui/vis/editors/default'; +import { VisOptionsProps } from '../../../legacy_imports'; import { GaugeVisParams } from '../../../gauge'; import { RangesPanel } from './ranges_panel'; import { StylePanel } from './style_panel'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/labels_panel.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/labels_panel.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/labels_panel.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/labels_panel.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/ranges_panel.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/ranges_panel.tsx similarity index 98% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/ranges_panel.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/ranges_panel.tsx index 1045543512c6b6..71ffb22243a0f0 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/ranges_panel.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/ranges_panel.tsx @@ -22,7 +22,7 @@ import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { ColorSchemas } from 'ui/vislib/components/color/colormaps'; +import { ColorSchemas } from '../../../legacy_imports'; import { ColorRanges, ColorSchemaOptions, SwitchOption } from '../../common'; import { GaugeOptionsInternalProps } from '.'; import { ColorSchemaVislibParams } from '../../../types'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/style_panel.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/style_panel.tsx similarity index 97% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/style_panel.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/style_panel.tsx index a76171673d9a82..0b4986ae8ad806 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/style_panel.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/style_panel.tsx @@ -22,7 +22,7 @@ import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { AggGroupNames } from 'ui/vis/editors/default'; +import { AggGroupNames } from '../../../legacy_imports'; import { SelectOption } from '../../common'; import { GaugeOptionsInternalProps } from '.'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/heatmap/index.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/index.tsx similarity index 99% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/heatmap/index.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/index.tsx index 659bcf47f7a0b1..7ce38fdcda1c8c 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/heatmap/index.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/index.tsx @@ -18,11 +18,12 @@ */ import React, { useCallback, useEffect, useState } from 'react'; + import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from 'ui/vis/editors/default'; +import { VisOptionsProps } from '../../../legacy_imports'; import { BasicOptions, ColorRanges, diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/heatmap/labels_panel.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/labels_panel.tsx similarity index 98% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/heatmap/labels_panel.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/labels_panel.tsx index c0e9a70e8b11e7..6ca0bb26ef5358 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/heatmap/labels_panel.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/labels_panel.tsx @@ -18,11 +18,12 @@ */ import React, { useCallback } from 'react'; + import { EuiColorPicker, EuiFormRow, EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from 'ui/vis/editors/default'; +import { VisOptionsProps } from '../../../legacy_imports'; import { ValueAxis } from '../../../types'; import { HeatmapVisParams } from '../../../heatmap'; import { SwitchOption } from '../../common'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/index.ts b/src/legacy/core_plugins/vis_type_vislib/public/components/options/index.ts similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/index.ts rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/index.ts diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/category_axis_panel.test.tsx.snap b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/category_axis_panel.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/category_axis_panel.test.tsx.snap rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/category_axis_panel.test.tsx.snap diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/chart_options.test.tsx.snap b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/chart_options.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/chart_options.test.tsx.snap rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/chart_options.test.tsx.snap diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/custom_extents_options.test.tsx.snap b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/custom_extents_options.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/custom_extents_options.test.tsx.snap rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/custom_extents_options.test.tsx.snap diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/index.test.tsx.snap b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/index.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/index.test.tsx.snap rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/index.test.tsx.snap diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/label_options.test.tsx.snap b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/label_options.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/label_options.test.tsx.snap rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/label_options.test.tsx.snap diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/line_options.test.tsx.snap b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/line_options.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/line_options.test.tsx.snap rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/line_options.test.tsx.snap diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/value_axes_panel.test.tsx.snap b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/value_axes_panel.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/value_axes_panel.test.tsx.snap rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/value_axes_panel.test.tsx.snap diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/value_axis_options.test.tsx.snap b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/value_axis_options.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/value_axis_options.test.tsx.snap rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/value_axis_options.test.tsx.snap diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/y_extents.test.tsx.snap b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/y_extents.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/__snapshots__/y_extents.test.tsx.snap rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/y_extents.test.tsx.snap diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/category_axis_panel.test.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/category_axis_panel.test.tsx similarity index 98% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/category_axis_panel.test.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/category_axis_panel.test.tsx index a32e48baf4588c..69622bb3666a63 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/category_axis_panel.test.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/category_axis_panel.test.tsx @@ -25,6 +25,8 @@ import { Positions, getPositions } from '../../../utils/collections'; import { LabelOptions } from './label_options'; import { categoryAxis } from './mocks'; +jest.mock('ui/new_platform'); + const positions = getPositions(); describe('CategoryAxisPanel component', () => { diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/category_axis_panel.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/category_axis_panel.tsx similarity index 98% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/category_axis_panel.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/category_axis_panel.tsx index 11946a5a6bccd6..b83508f3f08964 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/category_axis_panel.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/category_axis_panel.tsx @@ -18,11 +18,12 @@ */ import React, { useCallback } from 'react'; + import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from 'ui/vis/editors/default'; +import { VisOptionsProps } from '../../../legacy_imports'; import { BasicVislibParams, Axis } from '../../../types'; import { SelectOption, SwitchOption } from '../../common'; import { LabelOptions } from './label_options'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/chart_options.test.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/chart_options.test.tsx similarity index 99% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/chart_options.test.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/chart_options.test.tsx index ba1a46ba7d89e7..9679728a2a3d18 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/chart_options.test.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/chart_options.test.tsx @@ -31,6 +31,8 @@ import { } from '../../../utils/collections'; import { valueAxis, seriesParam } from './mocks'; +jest.mock('ui/new_platform'); + const interpolationModes = getInterpolationModes(); const chartTypes = getChartTypes(); const chartModes = getChartModes(); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/chart_options.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/chart_options.tsx similarity index 98% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/chart_options.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/chart_options.tsx index 1c9357c67c2f08..8830c9164c7511 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/chart_options.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/chart_options.tsx @@ -18,10 +18,11 @@ */ import React, { useMemo, useCallback } from 'react'; + import { i18n } from '@kbn/i18n'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; -import { VisOptionsProps } from 'ui/vis/editors/default'; +import { VisOptionsProps } from '../../../legacy_imports'; import { BasicVislibParams, SeriesParam, ValueAxis } from '../../../types'; import { ChartTypes } from '../../../utils/collections'; import { SelectOption } from '../../common'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.test.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/custom_extents_options.test.tsx similarity index 99% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.test.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/custom_extents_options.test.tsx index 5f1779ad353040..a112b9a3db708f 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.test.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/custom_extents_options.test.tsx @@ -28,6 +28,8 @@ const DEFAULT_Y_EXTENTS = 'defaultYExtents'; const SCALE = 'scale'; const SET_Y_EXTENTS = 'setYExtents'; +jest.mock('ui/new_platform'); + describe('CustomExtentsOptions component', () => { let setValueAxis: jest.Mock; let setValueAxisScale: jest.Mock; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/custom_extents_options.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/custom_extents_options.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/custom_extents_options.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.test.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.test.tsx similarity index 99% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.test.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.test.tsx index dc5cf422776034..df1920bd4013c9 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.test.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.test.tsx @@ -19,6 +19,7 @@ import React from 'react'; import { mount, shallow } from 'enzyme'; + import { MetricsAxisOptions } from './index'; import { BasicVislibParams, SeriesParam, ValueAxis } from '../../../types'; import { ValidationVisOptionsProps } from '../../common'; @@ -26,10 +27,10 @@ import { Positions } from '../../../utils/collections'; import { ValueAxesPanel } from './value_axes_panel'; import { CategoryAxisPanel } from './category_axis_panel'; import { ChartTypes } from '../../../utils/collections'; -import { AggConfig } from 'ui/vis'; -import { AggType } from 'ui/agg_types'; +import { AggConfig, AggType } from '../../../legacy_imports'; import { defaultValueAxisId, valueAxis, seriesParam, categoryAxis } from './mocks'; +jest.mock('ui/new_platform'); jest.mock('./series_panel', () => ({ SeriesPanel: () => 'SeriesPanel', })); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.tsx similarity index 99% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.tsx index 2ca4ed1e2343d0..85077ed4923310 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.tsx @@ -21,7 +21,7 @@ import React, { useState, useEffect, useCallback, useMemo } from 'react'; import { cloneDeep, uniq, get } from 'lodash'; import { EuiSpacer } from '@elastic/eui'; -import { AggConfig } from 'ui/vis'; +import { AggConfig } from '../../../legacy_imports'; import { BasicVislibParams, ValueAxis, SeriesParam, Axis } from '../../../types'; import { ValidationVisOptionsProps } from '../../common'; import { SeriesPanel } from './series_panel'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/label_options.test.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/label_options.test.tsx similarity index 99% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/label_options.test.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/label_options.test.tsx index abb3a2455f9f9e..91d9987c77f3bd 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/label_options.test.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/label_options.test.tsx @@ -23,6 +23,8 @@ import { LabelOptions, LabelOptionsProps } from './label_options'; import { TruncateLabelsOption } from '../../common'; import { valueAxis, categoryAxis } from './mocks'; +jest.mock('ui/new_platform'); + const FILTER = 'filter'; const ROTATE = 'rotate'; const DISABLED = 'disabled'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/label_options.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/label_options.tsx similarity index 98% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/label_options.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/label_options.tsx index 427d43e18cca6d..6a94eabe252432 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/label_options.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/label_options.tsx @@ -18,11 +18,12 @@ */ import React, { useCallback, useMemo } from 'react'; + import { EuiTitle, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from 'ui/vis/editors/default'; +import { VisOptionsProps } from '../../../legacy_imports'; import { BasicVislibParams, Axis } from '../../../types'; import { SelectOption, SwitchOption, TruncateLabelsOption } from '../../common'; import { getRotateOptions } from '../../../utils/collections'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/line_options.test.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/line_options.test.tsx similarity index 98% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/line_options.test.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/line_options.test.tsx index 0e603814493fa5..98ef8a094a2600 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/line_options.test.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/line_options.test.tsx @@ -24,6 +24,8 @@ import { NumberInputOption } from '../../common'; import { getInterpolationModes } from '../../../utils/collections'; import { seriesParam } from './mocks'; +jest.mock('ui/new_platform'); + const LINE_WIDTH = 'lineWidth'; const DRAW_LINES = 'drawLinesBetweenPoints'; const interpolationModes = getInterpolationModes(); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/line_options.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/line_options.tsx similarity index 98% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/line_options.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/line_options.tsx index 9514b69a20b04e..0848b708b90949 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/line_options.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/line_options.tsx @@ -18,10 +18,11 @@ */ import React, { useCallback } from 'react'; + import { i18n } from '@kbn/i18n'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; -import { Vis } from 'ui/vis'; +import { Vis } from '../../../legacy_imports'; import { SeriesParam } from '../../../types'; import { NumberInputOption, SelectOption, SwitchOption } from '../../common'; import { SetChart } from './chart_options'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/mocks.ts b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/mocks.ts similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/mocks.ts rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/mocks.ts diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/series_panel.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/series_panel.tsx similarity index 97% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/series_panel.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/series_panel.tsx index 5a455f4adde31f..4d87cc61797fca 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/series_panel.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/series_panel.tsx @@ -18,11 +18,12 @@ */ import React from 'react'; + import { EuiPanel, EuiTitle, EuiSpacer, EuiAccordion } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from 'ui/vis/editors/default'; +import { VisOptionsProps } from '../../../legacy_imports'; import { BasicVislibParams } from '../../../types'; import { ChartOptions } from './chart_options'; import { SetParamByIndex, ChangeValueAxis } from './'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/utils.ts b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/utils.ts similarity index 98% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/utils.ts rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/utils.ts index 7144b0ad4902e2..7c4f3b3ec8843d 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/utils.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/utils.ts @@ -44,7 +44,7 @@ const makeSerie = ( }; const isAxisHorizontal = (position: Positions) => - [Positions.TOP, Positions.BOTTOM].includes(position); + [Positions.TOP, Positions.BOTTOM].includes(position as any); const RADIX = 10; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/value_axes_panel.test.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/value_axes_panel.test.tsx similarity index 99% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/value_axes_panel.test.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/value_axes_panel.test.tsx index 080c64db7ff851..7524c7a13435b5 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/value_axes_panel.test.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/value_axes_panel.test.tsx @@ -25,6 +25,8 @@ import { Positions, getScaleTypes, getAxisModes, getPositions } from '../../../u import { mountWithIntl } from 'test_utils/enzyme_helpers'; import { valueAxis, seriesParam } from './mocks'; +jest.mock('ui/new_platform'); + const positions = getPositions(); const axisModes = getAxisModes(); const scaleTypes = getScaleTypes(); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/value_axes_panel.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/value_axes_panel.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/value_axes_panel.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/value_axes_panel.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/value_axis_options.test.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/value_axis_options.test.tsx similarity index 99% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/value_axis_options.test.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/value_axis_options.test.tsx index 8cb476508c78b1..bd512e9365783b 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/value_axis_options.test.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/value_axis_options.test.tsx @@ -32,6 +32,8 @@ import { } from '../../../utils/collections'; import { valueAxis, categoryAxis } from './mocks'; +jest.mock('ui/new_platform'); + const POSITION = 'position'; const positions = getPositions(); const axisModes = getAxisModes(); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/value_axis_options.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/value_axis_options.tsx similarity index 99% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/value_axis_options.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/value_axis_options.tsx index 243950b7623903..b4ea4cb42ee60c 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/value_axis_options.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/value_axis_options.tsx @@ -100,7 +100,7 @@ function ValueAxisOptions(props: ValueAxisOptionsParams) { if (isCategoryAxisHorizontal) { return isAxisHorizontal(position); } - return [Positions.LEFT, Positions.RIGHT].includes(position); + return [Positions.LEFT, Positions.RIGHT].includes(position as any); }, [isCategoryAxisHorizontal] ); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/y_extents.test.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/y_extents.test.tsx similarity index 99% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/y_extents.test.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/y_extents.test.tsx index 2df17b6e349852..17c47b35b20dca 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/y_extents.test.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/y_extents.test.tsx @@ -23,6 +23,8 @@ import { YExtents, YExtentsProps } from './y_extents'; import { ScaleTypes } from '../../../utils/collections'; import { NumberInputOption } from '../../common'; +jest.mock('ui/new_platform'); + describe('YExtents component', () => { let setMultipleValidity: jest.Mock; let setScale: jest.Mock; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/y_extents.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/y_extents.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/y_extents.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/y_extents.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/pie.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/pie.tsx similarity index 98% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/pie.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/pie.tsx index 53dde185ec09fe..056eb70cb256bb 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/pie.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/pie.tsx @@ -17,11 +17,12 @@ * under the License. */ import React from 'react'; + import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from 'ui/vis/editors/default'; +import { VisOptionsProps } from '../../legacy_imports'; import { BasicOptions, TruncateLabelsOption, SwitchOption } from '../common'; import { PieVisParams } from '../../pie'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/point_series/grid_panel.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/grid_panel.tsx similarity index 98% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/point_series/grid_panel.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/grid_panel.tsx index 63b2449b823d53..bdb4d3f39c12b0 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/point_series/grid_panel.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/grid_panel.tsx @@ -17,11 +17,12 @@ * under the License. */ import React, { useMemo, useEffect, useCallback } from 'react'; + import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from 'ui/vis/editors/default'; +import { VisOptionsProps } from '../../../legacy_imports'; import { SelectOption, SwitchOption } from '../../common'; import { BasicVislibParams, ValueAxis } from '../../../types'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/point_series/index.ts b/src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/index.ts similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/point_series/index.ts rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/index.ts diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/point_series/point_series.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/point_series.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/point_series/point_series.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/point_series.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/point_series/threshold_panel.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/threshold_panel.tsx similarity index 100% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/point_series/threshold_panel.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/threshold_panel.tsx diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/gauge.js b/src/legacy/core_plugins/vis_type_vislib/public/gauge.ts similarity index 77% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/gauge.js rename to src/legacy/core_plugins/vis_type_vislib/public/gauge.ts index a472d20e072247..5dcc8ad16918d0 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/gauge.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/gauge.ts @@ -18,14 +18,43 @@ */ import { i18n } from '@kbn/i18n'; -import { Schemas } from 'ui/vis/editors/default/schemas'; -import { AggGroupNames } from 'ui/vis/editors/default'; -import { ColorSchemas } from 'ui/vislib/components/color/colormaps'; + +import { Schemas, AggGroupNames, ColorSchemas, RangeValues } from './legacy_imports'; import { GaugeOptions } from './components/options'; import { getGaugeCollections, Alignments, ColorModes, GaugeTypes } from './utils/collections'; -import { vislibVisController } from './controller'; +import { createVislibVisController } from './vis_controller'; +import { ColorSchemaVislibParams, Labels, Style } from './types'; +import { KbnVislibVisTypesDependencies } from './plugin'; + +export interface Gauge extends ColorSchemaVislibParams { + backStyle: 'Full'; + gaugeStyle: 'Full'; + orientation: 'vertical'; + type: 'meter'; + alignment: Alignments; + colorsRange: RangeValues[]; + extendRange: boolean; + gaugeType: GaugeTypes; + labels: Labels; + percentageMode: boolean; + outline?: boolean; + scale: { + show: boolean; + labels: false; + color: 'rgba(105,112,125,0.2)'; + }; + style: Style; +} + +export interface GaugeVisParams { + type: 'gauge'; + addTooltip: boolean; + addLegend: boolean; + isDisplayWarning: boolean; + gauge: Gauge; +} -export const gaugeDefinition = { +export const createGaugeVisTypeDefinition = (deps: KbnVislibVisTypesDependencies) => ({ name: 'gauge', title: i18n.translate('kbnVislibVisTypes.gauge.gaugeTitle', { defaultMessage: 'Gauge' }), icon: 'visGauge', @@ -79,7 +108,7 @@ export const gaugeDefinition = { }, }, }, - visualization: vislibVisController, + visualization: createVislibVisController(deps), editorConfig: { collections: getGaugeCollections(), optionsTemplate: GaugeOptions, @@ -115,4 +144,4 @@ export const gaugeDefinition = { ]), }, useCustomNoDataScreen: true, -}; +}); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/goal.js b/src/legacy/core_plugins/vis_type_vislib/public/goal.ts similarity index 90% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/goal.js rename to src/legacy/core_plugins/vis_type_vislib/public/goal.ts index 71fcd6593e72cc..302d5f6393ef90 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/goal.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/goal.ts @@ -18,21 +18,21 @@ */ import { i18n } from '@kbn/i18n'; -import { Schemas } from 'ui/vis/editors/default/schemas'; -import { AggGroupNames } from 'ui/vis/editors/default'; -import { ColorSchemas } from 'ui/vislib/components/color/colormaps'; + +import { Schemas, AggGroupNames, ColorSchemas } from './legacy_imports'; import { GaugeOptions } from './components/options'; import { getGaugeCollections, GaugeTypes, ColorModes } from './utils/collections'; -import { vislibVisController } from './controller'; +import { createVislibVisController } from './vis_controller'; +import { KbnVislibVisTypesDependencies } from './plugin'; -export const goalDefinition = { +export const createGoalVisTypeDefinition = (deps: KbnVislibVisTypesDependencies) => ({ name: 'goal', title: i18n.translate('kbnVislibVisTypes.goal.goalTitle', { defaultMessage: 'Goal' }), icon: 'visGoal', description: i18n.translate('kbnVislibVisTypes.goal.goalDescription', { defaultMessage: 'A goal chart indicates how close you are to your final goal.', }), - visualization: vislibVisController, + visualization: createVislibVisController(deps), visConfig: { defaults: { addTooltip: true, @@ -108,4 +108,4 @@ export const goalDefinition = { ]), }, useCustomNoDataScreen: true, -}; +}); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/heatmap.js b/src/legacy/core_plugins/vis_type_vislib/public/heatmap.ts similarity index 81% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/heatmap.js rename to src/legacy/core_plugins/vis_type_vislib/public/heatmap.ts index 292e108053598b..eb5f84b409838a 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/heatmap.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/heatmap.ts @@ -18,21 +18,35 @@ */ import { i18n } from '@kbn/i18n'; -import { Schemas } from 'ui/vis/editors/default/schemas'; -import { AggGroupNames } from 'ui/vis/editors/default'; -import { ColorSchemas } from 'ui/vislib/components/color/colormaps'; + +import { Schemas, AggGroupNames, ColorSchemas, RangeValues } from './legacy_imports'; import { AxisTypes, getHeatmapCollections, Positions, ScaleTypes } from './utils/collections'; import { HeatmapOptions } from './components/options'; -import { vislibVisController } from './controller'; +import { createVislibVisController } from './vis_controller'; +import { TimeMarker } from './vislib/visualizations/time_marker'; +import { CommonVislibParams, ColorSchemaVislibParams, ValueAxis } from './types'; +import { KbnVislibVisTypesDependencies } from './plugin'; + +export interface HeatmapVisParams extends CommonVislibParams, ColorSchemaVislibParams { + type: 'heatmap'; + addLegend: boolean; + enableHover: boolean; + colorsNumber: number | ''; + colorsRange: RangeValues[]; + valueAxes: ValueAxis[]; + setColorRange: boolean; + percentageMode: boolean; + times: TimeMarker[]; +} -export const heatmapDefinition = { +export const createHeatmapVisTypeDefinition = (deps: KbnVislibVisTypesDependencies) => ({ name: 'heatmap', title: i18n.translate('kbnVislibVisTypes.heatmap.heatmapTitle', { defaultMessage: 'Heat Map' }), icon: 'visHeatmap', description: i18n.translate('kbnVislibVisTypes.heatmap.heatmapDescription', { defaultMessage: 'Shade cells within a matrix', }), - visualization: vislibVisController, + visualization: createVislibVisController(deps), visConfig: { defaults: { type: 'heatmap', @@ -122,4 +136,4 @@ export const heatmapDefinition = { }, ]), }, -}; +}); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/histogram.js b/src/legacy/core_plugins/vis_type_vislib/public/histogram.ts similarity index 92% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/histogram.js rename to src/legacy/core_plugins/vis_type_vislib/public/histogram.ts index bc017b5a1a871d..f92875a62cfd7d 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/histogram.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/histogram.ts @@ -18,8 +18,13 @@ */ import { i18n } from '@kbn/i18n'; -import { Schemas } from 'ui/vis/editors/default/schemas'; -import { AggGroupNames } from 'ui/vis/editors/default'; +// @ts-ignore +import { palettes } from '@elastic/eui/lib/services'; +// @ts-ignore +import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; + +import { Schemas, AggGroupNames } from './legacy_imports'; + import { Positions, ChartTypes, @@ -32,10 +37,10 @@ import { getConfigCollections, } from './utils/collections'; import { getAreaOptionTabs, countLabel } from './utils/common_config'; -import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; -import { vislibVisController } from './controller'; +import { createVislibVisController } from './vis_controller'; +import { KbnVislibVisTypesDependencies } from './plugin'; -export const histogramDefinition = { +export const createHistogramVisTypeDefinition = (deps: KbnVislibVisTypesDependencies) => ({ name: 'histogram', title: i18n.translate('kbnVislibVisTypes.histogram.histogramTitle', { defaultMessage: 'Vertical Bar', @@ -44,7 +49,7 @@ export const histogramDefinition = { description: i18n.translate('kbnVislibVisTypes.histogram.histogramDescription', { defaultMessage: 'Assign a continuous variable to each axis', }), - visualization: vislibVisController, + visualization: createVislibVisController(deps), visConfig: { defaults: { type: 'histogram', @@ -183,4 +188,4 @@ export const histogramDefinition = { }, ]), }, -}; +}); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js b/src/legacy/core_plugins/vis_type_vislib/public/horizontal_bar.ts similarity index 92% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js rename to src/legacy/core_plugins/vis_type_vislib/public/horizontal_bar.ts index ee3570314618ab..ada0c6b44ff701 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/horizontal_bar.ts @@ -18,8 +18,13 @@ */ import { i18n } from '@kbn/i18n'; -import { Schemas } from 'ui/vis/editors/default/schemas'; -import { AggGroupNames } from 'ui/vis/editors/default'; +// @ts-ignore +import { palettes } from '@elastic/eui/lib/services'; +// @ts-ignore +import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; + +import { Schemas, AggGroupNames } from './legacy_imports'; + import { Positions, ChartTypes, @@ -32,10 +37,10 @@ import { getConfigCollections, } from './utils/collections'; import { getAreaOptionTabs, countLabel } from './utils/common_config'; -import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; -import { vislibVisController } from './controller'; +import { createVislibVisController } from './vis_controller'; +import { KbnVislibVisTypesDependencies } from './plugin'; -export const horizontalBarDefinition = { +export const createHorizontalBarVisTypeDefinition = (deps: KbnVislibVisTypesDependencies) => ({ name: 'horizontal_bar', title: i18n.translate('kbnVislibVisTypes.horizontalBar.horizontalBarTitle', { defaultMessage: 'Horizontal Bar', @@ -44,7 +49,7 @@ export const horizontalBarDefinition = { description: i18n.translate('kbnVislibVisTypes.horizontalBar.horizontalBarDescription', { defaultMessage: 'Assign a continuous variable to each axis', }), - visualization: vislibVisController, + visualization: createVislibVisController(deps), visConfig: { defaults: { type: 'histogram', @@ -182,4 +187,4 @@ export const horizontalBarDefinition = { }, ]), }, -}; +}); diff --git a/src/legacy/ui/public/vis/editors/default/schemas.d.ts b/src/legacy/core_plugins/vis_type_vislib/public/index.ts similarity index 62% rename from src/legacy/ui/public/vis/editors/default/schemas.d.ts rename to src/legacy/core_plugins/vis_type_vislib/public/index.ts index 236421f30fb09d..5abe79daf11faf 100644 --- a/src/legacy/ui/public/vis/editors/default/schemas.d.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/index.ts @@ -17,21 +17,9 @@ * under the License. */ -import { AggParam } from '../../../agg_types'; -import { AggGroupNames } from './agg_groups'; -import { AggControlProps } from './controls/agg_control_props'; +import { PluginInitializerContext } from '../../../../core/public'; +import { KbnVislibVisTypesPlugin as Plugin } from './plugin'; -export interface Schema { - aggFilter: string | string[]; - editor: boolean | string; - group: AggGroupNames; - max: number; - min: number; - name: string; - params: AggParam[]; - title: string; - defaults: unknown; - hideCustomLabel?: boolean; - mustBeFirst?: boolean; - editorComponent?: React.ComponentType; +export function plugin(initializerContext: PluginInitializerContext) { + return new Plugin(initializerContext); } diff --git a/src/legacy/core_plugins/vis_type_vislib/public/legacy.ts b/src/legacy/core_plugins/vis_type_vislib/public/legacy.ts new file mode 100644 index 00000000000000..3d4cf55adc5e0c --- /dev/null +++ b/src/legacy/core_plugins/vis_type_vislib/public/legacy.ts @@ -0,0 +1,74 @@ +/* + * 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 { npSetup, npStart } from 'ui/new_platform'; +import { PluginInitializerContext } from 'kibana/public'; + +/* eslint-disable prettier/prettier */ +import { + initializeHierarchicalTooltipFormatter, + getHierarchicalTooltipFormatter, + // @ts-ignore +} from 'ui/vis/components/tooltip/_hierarchical_tooltip_formatter'; +import { + initializePointSeriesTooltipFormatter, + getPointSeriesTooltipFormatter, + // @ts-ignore +} from 'ui/vis/components/tooltip/_pointseries_tooltip_formatter'; +import { + vislibSeriesResponseHandlerProvider, + vislibSlicesResponseHandlerProvider, + // @ts-ignore +} from 'ui/vis/response_handlers/vislib'; +// @ts-ignore +import { vislibColor } from 'ui/vis/components/color/color'; + +import { plugin } from '.'; +import { + KbnVislibVisTypesPluginSetupDependencies, + KbnVislibVisTypesPluginStartDependencies, +} from './plugin'; +import { + setup as visualizationsSetup, + start as visualizationsStart, +} from '../../visualizations/public/np_ready/public/legacy'; + +const setupPlugins: Readonly = { + expressions: npSetup.plugins.expressions, + visualizations: visualizationsSetup, + __LEGACY: { + initializeHierarchicalTooltipFormatter, + getHierarchicalTooltipFormatter, + initializePointSeriesTooltipFormatter, + getPointSeriesTooltipFormatter, + vislibSeriesResponseHandlerProvider, + vislibSlicesResponseHandlerProvider, + vislibColor, + }, +}; + +const startPlugins: Readonly = { + expressions: npStart.plugins.expressions, + visualizations: visualizationsStart, +}; + +const pluginInstance = plugin({} as PluginInitializerContext); + +export const setup = pluginInstance.setup(npSetup.core, setupPlugins); +export const start = pluginInstance.start(npStart.core, startPlugins); diff --git a/src/legacy/core_plugins/vis_type_vislib/public/legacy_imports.ts b/src/legacy/core_plugins/vis_type_vislib/public/legacy_imports.ts new file mode 100644 index 00000000000000..2970942f221e80 --- /dev/null +++ b/src/legacy/core_plugins/vis_type_vislib/public/legacy_imports.ts @@ -0,0 +1,35 @@ +/* + * 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. + */ + +export { AggGroupNames, VisOptionsProps } from 'ui/vis/editors/default'; +export { Schemas } from 'ui/vis/editors/default/schemas'; +export { RangeValues, RangesParamEditor } from 'ui/vis/editors/default/controls/ranges'; +export { ColorSchema, ColorSchemas, colorSchemas, getHeatmapColors } from 'ui/color_maps'; +export { AggConfig, Vis, VisParams } from 'ui/vis'; +export { AggType } from 'ui/agg_types'; +export { CUSTOM_LEGEND_VIS_TYPES, VisLegend } from 'ui/vis/vis_types/vislib_vis_legend'; +// @ts-ignore +export { Tooltip } from 'ui/vis/components/tooltip'; +// @ts-ignore +export { SimpleEmitter } from 'ui/utils/simple_emitter'; +// @ts-ignore +export { Binder } from 'ui/binder'; +export { getFormat } from 'ui/visualize/loader/pipeline_helpers/utilities'; +// @ts-ignore +export { tabifyAggResponse } from 'ui/agg_response/tabify'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/line.js b/src/legacy/core_plugins/vis_type_vislib/public/line.ts similarity index 92% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/line.js rename to src/legacy/core_plugins/vis_type_vislib/public/line.ts index d6d075f452fed4..35a059fadddcb9 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/line.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/line.ts @@ -18,8 +18,12 @@ */ import { i18n } from '@kbn/i18n'; -import { Schemas } from 'ui/vis/editors/default/schemas'; -import { AggGroupNames } from 'ui/vis/editors/default'; +// @ts-ignore +import { palettes } from '@elastic/eui/lib/services'; +// @ts-ignore +import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; + +import { Schemas, AggGroupNames } from './legacy_imports'; import { Positions, ChartTypes, @@ -32,18 +36,18 @@ import { InterpolationModes, getConfigCollections, } from './utils/collections'; -import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; import { getAreaOptionTabs, countLabel } from './utils/common_config'; -import { vislibVisController } from './controller'; +import { createVislibVisController } from './vis_controller'; +import { KbnVislibVisTypesDependencies } from './plugin'; -export const lineDefinition = { +export const createLineVisTypeDefinition = (deps: KbnVislibVisTypesDependencies) => ({ name: 'line', title: i18n.translate('kbnVislibVisTypes.line.lineTitle', { defaultMessage: 'Line' }), icon: 'visLine', description: i18n.translate('kbnVislibVisTypes.line.lineDescription', { defaultMessage: 'Emphasize trends', }), - visualization: vislibVisController, + visualization: createVislibVisController(deps), visConfig: { defaults: { type: 'line', @@ -175,4 +179,4 @@ export const lineDefinition = { }, ]), }, -}; +}); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/pie.js b/src/legacy/core_plugins/vis_type_vislib/public/pie.ts similarity index 81% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/pie.js rename to src/legacy/core_plugins/vis_type_vislib/public/pie.ts index 1cef3114f047d7..32307b7a117a1c 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/pie.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/pie.ts @@ -18,20 +18,34 @@ */ import { i18n } from '@kbn/i18n'; -import { Schemas } from 'ui/vis/editors/default/schemas'; -import { AggGroupNames } from 'ui/vis/editors/default'; + +import { Schemas, AggGroupNames } from './legacy_imports'; import { PieOptions } from './components/options'; import { getPositions, Positions } from './utils/collections'; -import { vislibVisController } from './controller'; +import { createVislibVisController } from './vis_controller'; +import { CommonVislibParams } from './types'; +import { KbnVislibVisTypesDependencies } from './plugin'; + +export interface PieVisParams extends CommonVislibParams { + type: 'pie'; + addLegend: boolean; + isDonut: boolean; + labels: { + show: boolean; + values: boolean; + last_level: boolean; + truncate: number | null; + }; +} -export const pieDefinition = { +export const createPieVisTypeDefinition = (deps: KbnVislibVisTypesDependencies) => ({ name: 'pie', title: i18n.translate('kbnVislibVisTypes.pie.pieTitle', { defaultMessage: 'Pie' }), icon: 'visPie', description: i18n.translate('kbnVislibVisTypes.pie.pieDescription', { defaultMessage: 'Compare parts of a whole', }), - visualization: vislibVisController, + visualization: createVislibVisController(deps), visConfig: { defaults: { type: 'pie', @@ -89,4 +103,4 @@ export const pieDefinition = { }, hierarchicalData: true, responseHandler: 'vislib_slices', -}; +}); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/pie_fn.test.js b/src/legacy/core_plugins/vis_type_vislib/public/pie_fn.test.ts similarity index 92% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/pie_fn.test.js rename to src/legacy/core_plugins/vis_type_vislib/public/pie_fn.test.ts index 4d932e6e9518e0..786de0cc79b86d 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/pie_fn.test.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/pie_fn.test.ts @@ -19,10 +19,14 @@ // eslint-disable-next-line import { functionWrapper } from '../../../../plugins/expressions/public/functions/tests/utils'; -import { kibanaPie } from './pie_fn'; +import { createPieVisFn } from './pie_fn'; +import { KbnVislibVisTypesDependencies } from './plugin'; jest.mock('ui/new_platform'); +const deps: KbnVislibVisTypesDependencies = { + vislibSlicesResponseHandlerProvider: () => ({ handler: mockResponseHandler }), +} as any; const mockResponseHandler = jest.fn().mockReturnValue( Promise.resolve({ hits: 1, @@ -39,20 +43,15 @@ const mockResponseHandler = jest.fn().mockReturnValue( }, }) ); -jest.mock('ui/vis/response_handlers/vislib', () => ({ - vislibSlicesResponseHandlerProvider: () => ({ handler: mockResponseHandler }), -})); describe('interpreter/functions#pie', () => { - const fn = functionWrapper(kibanaPie); + const fn = functionWrapper(createPieVisFn(deps)); const context = { type: 'kibana_datatable', rows: [{ 'col-0-1': 0 }], columns: [{ id: 'col-0-1', name: 'Count' }], }; const visConfig = { - addTooltip: true, - addLegend: false, type: 'pie', addTooltip: true, addLegend: true, diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/pie_fn.js b/src/legacy/core_plugins/vis_type_vislib/public/pie_fn.ts similarity index 68% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/pie_fn.js rename to src/legacy/core_plugins/vis_type_vislib/public/pie_fn.ts index f66fd53e59efe5..4b536caedb1212 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/pie_fn.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/pie_fn.ts @@ -17,11 +17,37 @@ * under the License. */ -import { functionsRegistry } from 'plugins/interpreter/registries'; -import { vislibSlicesResponseHandlerProvider as vislibSlicesResponseHandler } from 'ui/vis/response_handlers/vislib'; import { i18n } from '@kbn/i18n'; -export const kibanaPie = () => ({ +import { + ExpressionFunction, + KibanaDatatable, + Render, +} from '../../../../plugins/expressions/public'; +import { KbnVislibVisTypesDependencies } from './plugin'; + +const name = 'kibana_pie'; + +type Context = KibanaDatatable; + +interface Arguments { + visConfig: string; +} + +type VisParams = Required; + +interface RenderValue { + visConfig: VisParams; +} + +type Return = Promise>; + +export const createPieVisFn = (deps: KbnVislibVisTypesDependencies) => (): ExpressionFunction< + typeof name, + Context, + Arguments, + Return +> => ({ name: 'kibana_pie', type: 'render', context: { @@ -32,14 +58,15 @@ export const kibanaPie = () => ({ }), args: { visConfig: { - types: ['string', 'null'], + types: ['string'], default: '"{}"', + help: '', }, }, async fn(context, args) { const visConfig = JSON.parse(args.visConfig); - const responseHandler = vislibSlicesResponseHandler().handler; + const responseHandler = deps.vislibSlicesResponseHandlerProvider().handler; const convertedData = await responseHandler(context, visConfig.dimensions); return { @@ -56,5 +83,3 @@ export const kibanaPie = () => ({ }; }, }); - -functionsRegistry.register(kibanaPie); diff --git a/src/legacy/core_plugins/vis_type_vislib/public/plugin.ts b/src/legacy/core_plugins/vis_type_vislib/public/plugin.ts new file mode 100644 index 00000000000000..a2e8512b2201b2 --- /dev/null +++ b/src/legacy/core_plugins/vis_type_vislib/public/plugin.ts @@ -0,0 +1,106 @@ +/* + * 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 { + CoreSetup, + CoreStart, + Plugin, + IUiSettingsClient, + PluginInitializerContext, +} from 'kibana/public'; + +import { Plugin as ExpressionsPublicPlugin } from '../../../../plugins/expressions/public'; +import { VisualizationsSetup, VisualizationsStart } from '../../visualizations/public'; +import { createKbnVislibVisTypesFn } from './vis_type_vislib_vis_fn'; +import { createPieVisFn } from './pie_fn'; +import { + createHistogramVisTypeDefinition, + createLineVisTypeDefinition, + createPieVisTypeDefinition, + createAreaVisTypeDefinition, + createHeatmapVisTypeDefinition, + createHorizontalBarVisTypeDefinition, + createGaugeVisTypeDefinition, + createGoalVisTypeDefinition, +} from './vis_type_vislib_vis_types'; + +type ResponseHandlerProvider = () => { + name: string; + handler: (response: any, dimensions: any) => Promise; +}; +type KbnVislibVisTypesCoreSetup = CoreSetup; + +export interface LegacyDependencies { + initializeHierarchicalTooltipFormatter: () => Promise; + getHierarchicalTooltipFormatter: () => Promise; + initializePointSeriesTooltipFormatter: () => void; + getPointSeriesTooltipFormatter: () => void; + vislibSeriesResponseHandlerProvider: ResponseHandlerProvider; + vislibSlicesResponseHandlerProvider: ResponseHandlerProvider; + vislibColor: (colors: Array, mappings: any) => (value: any) => any; +} + +export type KbnVislibVisTypesDependencies = LegacyDependencies & { + uiSettings: IUiSettingsClient; +}; + +/** @internal */ +export interface KbnVislibVisTypesPluginSetupDependencies { + expressions: ReturnType; + visualizations: VisualizationsSetup; + __LEGACY: LegacyDependencies; +} + +/** @internal */ +export interface KbnVislibVisTypesPluginStartDependencies { + expressions: ReturnType; + visualizations: VisualizationsStart; +} + +/** @internal */ +export class KbnVislibVisTypesPlugin implements Plugin, void> { + constructor(public initializerContext: PluginInitializerContext) {} + + public async setup( + core: KbnVislibVisTypesCoreSetup, + { expressions, visualizations, __LEGACY }: KbnVislibVisTypesPluginSetupDependencies + ) { + const visualizationDependencies: Readonly = { + ...__LEGACY, + uiSettings: core.uiSettings, + }; + + expressions.registerFunction(createKbnVislibVisTypesFn(visualizationDependencies)); + expressions.registerFunction(createPieVisFn(visualizationDependencies)); + + [ + createHistogramVisTypeDefinition, + createLineVisTypeDefinition, + createPieVisTypeDefinition, + createAreaVisTypeDefinition, + createHeatmapVisTypeDefinition, + createHorizontalBarVisTypeDefinition, + createGaugeVisTypeDefinition, + createGoalVisTypeDefinition, + ].forEach(vis => visualizations.types.createBaseVisualization(vis(visualizationDependencies))); + } + + public start(core: CoreStart, deps: KbnVislibVisTypesPluginStartDependencies) { + // nothing to do here + } +} diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/types.ts b/src/legacy/core_plugins/vis_type_vislib/public/types.ts similarity index 95% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/types.ts rename to src/legacy/core_plugins/vis_type_vislib/public/types.ts index b023eb54f72954..b6928be89f6488 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/types.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/types.ts @@ -17,8 +17,8 @@ * under the License. */ -import { ColorSchemas } from 'ui/vislib/components/color/colormaps'; -import { TimeMarker } from 'ui/vislib/visualizations/time_marker'; +import { ColorSchemas } from './legacy_imports'; +import { TimeMarker } from './vislib/visualizations/time_marker'; import { Positions, ChartModes, diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/utils/collections.ts b/src/legacy/core_plugins/vis_type_vislib/public/utils/collections.ts similarity index 73% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/utils/collections.ts rename to src/legacy/core_plugins/vis_type_vislib/public/utils/collections.ts index 6fe30483a32e89..810ddeea738341 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/utils/collections.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/utils/collections.ts @@ -18,14 +18,16 @@ */ import { i18n } from '@kbn/i18n'; -import { colorSchemas } from 'ui/vislib/components/color/colormaps'; +import { $Values } from '@kbn/utility-types'; +import { colorSchemas } from '../legacy_imports'; -export enum Positions { - RIGHT = 'right', - LEFT = 'left', - TOP = 'top', - BOTTOM = 'bottom', -} +export const Positions = Object.freeze({ + RIGHT: 'right' as 'right', + LEFT: 'left' as 'left', + TOP: 'top' as 'top', + BOTTOM: 'bottom' as 'bottom', +}); +export type Positions = $Values; const getPositions = () => [ { @@ -54,11 +56,12 @@ const getPositions = () => [ }, ]; -export enum ChartTypes { - LINE = 'line', - AREA = 'area', - HISTOGRAM = 'histogram', -} +export const ChartTypes = Object.freeze({ + LINE: 'line' as 'line', + AREA: 'area' as 'area', + HISTOGRAM: 'histogram' as 'histogram', +}); +export type ChartTypes = $Values; const getChartTypes = () => [ { @@ -81,10 +84,11 @@ const getChartTypes = () => [ }, ]; -export enum ChartModes { - NORMAL = 'normal', - STACKED = 'stacked', -} +export const ChartModes = Object.freeze({ + NORMAL: 'normal' as 'normal', + STACKED: 'stacked' as 'stacked', +}); +export type ChartModes = $Values; const getChartModes = () => [ { @@ -101,11 +105,12 @@ const getChartModes = () => [ }, ]; -export enum InterpolationModes { - LINEAR = 'linear', - CARDINAL = 'cardinal', - STEP_AFTER = 'step-after', -} +export const InterpolationModes = Object.freeze({ + LINEAR: 'linear' as 'linear', + CARDINAL: 'cardinal' as 'cardinal', + STEP_AFTER: 'step-after' as 'step-after', +}); +export type InterpolationModes = $Values; const getInterpolationModes = () => [ { @@ -128,16 +133,18 @@ const getInterpolationModes = () => [ }, ]; -export enum AxisTypes { - CATEGORY = 'category', - VALUE = 'value', -} +export const AxisTypes = Object.freeze({ + CATEGORY: 'category' as 'category', + VALUE: 'value' as 'value', +}); +export type AxisTypes = $Values; -export enum ScaleTypes { - LINEAR = 'linear', - LOG = 'log', - SQUARE_ROOT = 'square root', -} +export const ScaleTypes = Object.freeze({ + LINEAR: 'linear' as 'linear', + LOG: 'log' as 'log', + SQUARE_ROOT: 'square root' as 'square root', +}); +export type ScaleTypes = $Values; const getScaleTypes = () => [ { @@ -160,12 +167,13 @@ const getScaleTypes = () => [ }, ]; -export enum AxisModes { - NORMAL = 'normal', - PERCENTAGE = 'percentage', - WIGGLE = 'wiggle', - SILHOUETTE = 'silhouette', -} +export const AxisModes = Object.freeze({ + NORMAL: 'normal' as 'normal', + PERCENTAGE: 'percentage' as 'percentage', + WIGGLE: 'wiggle' as 'wiggle', + SILHOUETTE: 'silhouette' as 'silhouette', +}); +export type AxisModes = $Values; const getAxisModes = () => [ { @@ -194,17 +202,19 @@ const getAxisModes = () => [ }, ]; -export enum Rotates { - HORIZONTAL = 0, - VERTICAL = 90, - ANGLED = 75, -} +export const Rotates = Object.freeze({ + HORIZONTAL: 0, + VERTICAL: 90, + ANGLED: 75, +}); +export type Rotates = $Values; -export enum ThresholdLineStyles { - FULL = 'full', - DASHED = 'dashed', - DOT_DASHED = 'dot-dashed', -} +export const ThresholdLineStyles = Object.freeze({ + FULL: 'full' as 'full', + DASHED: 'dashed' as 'dashed', + DOT_DASHED: 'dot-dashed' as 'dot-dashed', +}); +export type ThresholdLineStyles = $Values; const getThresholdLineStyles = () => [ { @@ -248,16 +258,18 @@ const getRotateOptions = () => [ }, ]; -export enum GaugeTypes { - ARC = 'Arc', - CIRCLE = 'Circle', -} +export const GaugeTypes = Object.freeze({ + ARC: 'Arc' as 'Arc', + CIRCLE: 'Circle' as 'Circle', +}); +export type GaugeTypes = $Values; -export enum ColorModes { - BACKGROUND = 'Background', - LABELS = 'Labels', - NONE = 'None', -} +export const ColorModes = Object.freeze({ + BACKGROUND: 'Background' as 'Background', + LABELS: 'Labels' as 'Labels', + NONE: 'None' as 'None', +}); +export type ColorModes = $Values; const getGaugeTypes = () => [ { @@ -274,11 +286,12 @@ const getGaugeTypes = () => [ }, ]; -export enum Alignments { - AUTOMATIC = 'automatic', - HORIZONTAL = 'horizontal', - VERTICAL = 'vertical', -} +export const Alignments = Object.freeze({ + AUTOMATIC: 'automatic' as 'automatic', + HORIZONTAL: 'horizontal' as 'horizontal', + VERTICAL: 'vertical' as 'vertical', +}); +export type Alignments = $Values; const getAlignments = () => [ { diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/utils/common_config.tsx b/src/legacy/core_plugins/vis_type_vislib/public/utils/common_config.tsx similarity index 96% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/utils/common_config.tsx rename to src/legacy/core_plugins/vis_type_vislib/public/utils/common_config.tsx index 7e4140606762fe..adb93ca8011b2e 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/utils/common_config.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/utils/common_config.tsx @@ -18,8 +18,9 @@ */ import React from 'react'; -import { VisOptionsProps } from 'ui/vis/editors/default'; import { i18n } from '@kbn/i18n'; + +import { VisOptionsProps } from '../legacy_imports'; import { PointSeriesOptions, MetricsAxisOptions } from '../components/options'; import { ValidationWrapper } from '../components/common'; import { BasicVislibParams } from '../types'; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/vis_controller.tsx b/src/legacy/core_plugins/vis_type_vislib/public/vis_controller.tsx new file mode 100644 index 00000000000000..cff9a0a2e85519 --- /dev/null +++ b/src/legacy/core_plugins/vis_type_vislib/public/vis_controller.tsx @@ -0,0 +1,147 @@ +/* + * 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 $ from 'jquery'; +import React, { RefObject } from 'react'; + +import { CUSTOM_LEGEND_VIS_TYPES, VisLegend, Vis, VisParams } from './legacy_imports'; +// @ts-ignore +import { Vis as Vislib } from './vislib/vis'; +import { Positions } from './utils/collections'; +import { KbnVislibVisTypesDependencies } from './plugin'; +import { mountReactNode } from '../../../../core/public/utils'; + +const legendClassName = { + top: 'visLib--legend-top', + bottom: 'visLib--legend-bottom', + left: 'visLib--legend-left', + right: 'visLib--legend-right', +}; + +export const createVislibVisController = (deps: KbnVislibVisTypesDependencies) => { + return class VislibVisController { + unmount: (() => void) | null = null; + visParams?: VisParams; + legendRef: RefObject; + container: HTMLDivElement; + chartEl: HTMLDivElement; + legendEl: HTMLDivElement; + vislibVis: any; + + constructor(public el: Element, public vis: Vis) { + this.el = el; + this.vis = vis; + this.unmount = null; + this.legendRef = React.createRef(); + + // vis mount point + this.container = document.createElement('div'); + this.container.className = 'visLib'; + this.el.appendChild(this.container); + + // chart mount point + this.chartEl = document.createElement('div'); + this.chartEl.className = 'visLib__chart'; + this.container.appendChild(this.chartEl); + + // legend mount point + this.legendEl = document.createElement('div'); + this.legendEl.className = 'visLib__legend'; + this.container.appendChild(this.legendEl); + } + + render(esResponse: any, visParams: VisParams) { + if (this.vislibVis) { + this.destroy(); + } + + return new Promise(async resolve => { + if (this.el.clientWidth === 0 || this.el.clientHeight === 0) { + return resolve(); + } + + await deps.initializeHierarchicalTooltipFormatter(); + await deps.initializePointSeriesTooltipFormatter(); + + this.vislibVis = new Vislib(this.chartEl, visParams, deps); + this.vislibVis.on('brush', this.vis.API.events.brush); + this.vislibVis.on('click', this.vis.API.events.filter); + this.vislibVis.on('renderComplete', resolve); + + this.vislibVis.initVisConfig(esResponse, this.vis.getUiState()); + + if (visParams.addLegend) { + $(this.container) + .attr('class', (i, cls) => { + return cls.replace(/visLib--legend-\S+/g, ''); + }) + .addClass((legendClassName as any)[visParams.legendPosition]); + + this.mountLegend(esResponse, visParams.legendPosition); + } + + this.vislibVis.render(esResponse, this.vis.getUiState()); + + // refreshing the legend after the chart is rendered. + // this is necessary because some visualizations + // provide data necessary for the legend only after a render cycle. + if ( + visParams.addLegend && + CUSTOM_LEGEND_VIS_TYPES.includes(this.vislibVis.visConfigArgs.type) + ) { + this.unmountLegend(); + this.mountLegend(esResponse, visParams.legendPosition); + this.vislibVis.render(esResponse, this.vis.getUiState()); + } + }); + } + + mountLegend(visData: any, position: Positions) { + this.unmount = mountReactNode( + + )(this.legendEl); + } + + unmountLegend() { + if (this.unmount) { + this.unmount(); + } + } + + destroy() { + if (this.unmount) { + this.unmount(); + } + + if (this.vislibVis) { + this.vislibVis.off('brush', this.vis.API.events.brush); + this.vislibVis.off('click', this.vis.API.events.filter); + this.vislibVis.destroy(); + delete this.vislibVis; + } + } + }; +}; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/vislib_fn.js b/src/legacy/core_plugins/vis_type_vislib/public/vis_type_vislib_vis_fn.ts similarity index 68% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/vislib_fn.js rename to src/legacy/core_plugins/vis_type_vislib/public/vis_type_vislib_vis_fn.ts index 85ea5994548d6b..0a685cd70e0895 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/vislib_fn.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vis_type_vislib_vis_fn.ts @@ -17,11 +17,36 @@ * under the License. */ -import { functionsRegistry } from 'plugins/interpreter/registries'; import { i18n } from '@kbn/i18n'; -import { vislibSeriesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib'; -export const vislib = () => ({ +import { + ExpressionFunction, + KibanaDatatable, + Render, +} from '../../../../plugins/expressions/public'; +import { KbnVislibVisTypesDependencies } from './plugin'; + +const name = 'vislib'; + +type Context = KibanaDatatable; + +interface Arguments { + type: string; + visConfig: string; +} + +type VisParams = Required; + +interface RenderValue { + visType: string; + visConfig: VisParams; +} + +type Return = Promise>; + +export const createKbnVislibVisTypesFn = ( + deps: KbnVislibVisTypesDependencies +) => (): ExpressionFunction => ({ name: 'vislib', type: 'render', context: { @@ -34,14 +59,16 @@ export const vislib = () => ({ type: { types: ['string'], default: '""', + help: 'vislib vis type', }, visConfig: { - types: ['string', 'null'], + types: ['string'], default: '"{}"', + help: '', }, }, async fn(context, args) { - const responseHandler = vislibSeriesResponseHandlerProvider().handler; + const responseHandler = deps.vislibSeriesResponseHandlerProvider().handler; const visConfigParams = JSON.parse(args.visConfig); const convertedData = await responseHandler(context, visConfigParams.dimensions); @@ -60,5 +87,3 @@ export const vislib = () => ({ }; }, }); - -functionsRegistry.register(vislib); diff --git a/src/legacy/core_plugins/vis_type_vislib/public/vis_type_vislib_vis_types.ts b/src/legacy/core_plugins/vis_type_vislib/public/vis_type_vislib_vis_types.ts new file mode 100644 index 00000000000000..f44d5038954839 --- /dev/null +++ b/src/legacy/core_plugins/vis_type_vislib/public/vis_type_vislib_vis_types.ts @@ -0,0 +1,27 @@ +/* + * 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. + */ + +export { createHistogramVisTypeDefinition } from './histogram'; +export { createLineVisTypeDefinition } from './line'; +export { createPieVisTypeDefinition } from './pie'; +export { createAreaVisTypeDefinition } from './area'; +export { createHeatmapVisTypeDefinition } from './heatmap'; +export { createHorizontalBarVisTypeDefinition } from './horizontal_bar'; +export { createGaugeVisTypeDefinition } from './gauge'; +export { createGoalVisTypeDefinition } from './goal'; diff --git a/src/legacy/ui/public/vislib/VISLIB.md b/src/legacy/core_plugins/vis_type_vislib/public/vislib/VISLIB.md similarity index 100% rename from src/legacy/ui/public/vislib/VISLIB.md rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/VISLIB.md diff --git a/src/legacy/ui/public/vislib/__tests__/components/heatmap_color.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/components/heatmap_color.js similarity index 97% rename from src/legacy/ui/public/vislib/__tests__/components/heatmap_color.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/components/heatmap_color.js index 1cafbadcff655b..36c5b60abf5c6b 100644 --- a/src/legacy/ui/public/vislib/__tests__/components/heatmap_color.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/components/heatmap_color.js @@ -19,7 +19,8 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import { getHeatmapColors } from '../../components/color/heatmap_color'; + +import { getHeatmapColors } from '../../../legacy_imports'; describe('Vislib Heatmap Color Module Test Suite', function() { const emptyObject = {}; diff --git a/src/legacy/ui/public/vislib/__tests__/components/labels.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/components/labels.js similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/components/labels.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/components/labels.js diff --git a/src/legacy/ui/public/vislib/__tests__/index.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/index.js similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/index.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/index.js diff --git a/src/legacy/ui/public/vislib/__tests__/lib/__snapshots__/dispatch_heatmap.test.js.snap b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/__snapshots__/dispatch_heatmap.test.js.snap similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/__snapshots__/dispatch_heatmap.test.js.snap rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/__snapshots__/dispatch_heatmap.test.js.snap diff --git a/src/legacy/ui/public/vislib/__tests__/lib/axis/axis.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/axis/axis.js similarity index 98% rename from src/legacy/ui/public/vislib/__tests__/lib/axis/axis.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/axis/axis.js index 8b32943b64ea89..3081c124150765 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/axis/axis.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/axis/axis.js @@ -20,9 +20,11 @@ import d3 from 'd3'; import _ from 'lodash'; import ngMock from 'ng_mock'; +import 'ui/persisted_state'; + import expect from '@kbn/expect'; import $ from 'jquery'; -import '../../../../persisted_state'; + import { Axis } from '../../../lib/axis'; import { VisConfig } from '../../../lib/vis_config'; @@ -119,7 +121,8 @@ describe('Vislib Axis Class Test Suite', function() { }, data, persistedState, - $('.x-axis-div')[0] + $('.x-axis-div')[0], + () => undefined ); yAxis = new Axis(visConfig, { type: 'value', diff --git a/src/legacy/ui/public/vislib/__tests__/lib/axis_title.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/axis_title.js similarity index 97% rename from src/legacy/ui/public/vislib/__tests__/lib/axis_title.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/axis_title.js index d71184fdc1223d..cbb294c3b44e4e 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/axis_title.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/axis_title.js @@ -21,12 +21,14 @@ import d3 from 'd3'; import _ from 'lodash'; import $ from 'jquery'; import ngMock from 'ng_mock'; + import expect from '@kbn/expect'; +import 'ui/persisted_state'; + import { AxisTitle } from '../../lib/axis/axis_title'; import { AxisConfig } from '../../lib/axis/axis_config'; import { VisConfig } from '../../lib/vis_config'; import { Data } from '../../lib/data'; -import '../../../persisted_state'; describe('Vislib AxisTitle Class Test Suite', function() { let PersistedState; @@ -118,14 +120,15 @@ describe('Vislib AxisTitle Class Test Suite', function() { .style('height', '20px') .style('width', '20px'); - dataObj = new Data(data, new PersistedState()); + dataObj = new Data(data, new PersistedState(), () => undefined); visConfig = new VisConfig( { type: 'histogram', }, data, new PersistedState(), - el.node() + el.node(), + () => undefined ); const xAxisConfig = new AxisConfig(visConfig, { position: 'bottom', diff --git a/src/legacy/ui/public/vislib/__tests__/lib/chart_title.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/chart_title.js similarity index 98% rename from src/legacy/ui/public/vislib/__tests__/lib/chart_title.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/chart_title.js index e64999e7bd3295..b2086d0749a419 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/chart_title.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/chart_title.js @@ -21,9 +21,9 @@ import d3 from 'd3'; import _ from 'lodash'; import ngMock from 'ng_mock'; import expect from '@kbn/expect'; + import { ChartTitle } from '../../lib/chart_title'; import { VisConfig } from '../../lib/vis_config'; -import '../../../persisted_state'; describe('Vislib ChartTitle Class Test Suite', function() { let persistedState; @@ -112,7 +112,8 @@ describe('Vislib ChartTitle Class Test Suite', function() { }, data, persistedState, - el.node() + el.node(), + () => undefined ); chartTitle = new ChartTitle(visConfig); }) diff --git a/src/legacy/ui/public/vislib/__tests__/lib/data.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/data.js similarity index 92% rename from src/legacy/ui/public/vislib/__tests__/lib/data.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/data.js index c12259ee55a5a4..5811b1d238163a 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/data.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/data.js @@ -20,9 +20,9 @@ import _ from 'lodash'; import ngMock from 'ng_mock'; import expect from '@kbn/expect'; +import 'ui/persisted_state'; import { Data } from '../../lib/data'; -import '../../../persisted_state'; const seriesData = { label: '', @@ -168,7 +168,7 @@ describe('Vislib Data Class Test Suite', function() { }); it('should return an object', function() { - const rowIn = new Data(rowsData, persistedState); + const rowIn = new Data(rowsData, persistedState, () => undefined); expect(_.isObject(rowIn)).to.be(true); }); }); @@ -182,7 +182,7 @@ describe('Vislib Data Class Test Suite', function() { }; beforeEach(function() { - data = new Data(pieData, persistedState); + data = new Data(pieData, persistedState, () => undefined); }); it('should remove zero values', function() { @@ -196,7 +196,7 @@ describe('Vislib Data Class Test Suite', function() { let serOut; beforeEach(function() { - serIn = new Data(seriesData, persistedState); + serIn = new Data(seriesData, persistedState, () => undefined); serOut = serIn.flatten(); }); @@ -210,7 +210,7 @@ describe('Vislib Data Class Test Suite', function() { function testLength(inputData) { return function() { - const data = new Data(inputData, persistedState); + const data = new Data(inputData, persistedState, () => undefined); const len = _.reduce( data.chartData(), function(sum, chart) { @@ -266,7 +266,7 @@ describe('Vislib Data Class Test Suite', function() { }; beforeEach(function() { - data = new Data(geohashGridData, persistedState); + data = new Data(geohashGridData, persistedState, () => undefined); }); describe('getVisData', function() { @@ -287,7 +287,7 @@ describe('Vislib Data Class Test Suite', function() { describe('null value check', function() { it('should return false', function() { - const data = new Data(rowsData, persistedState); + const data = new Data(rowsData, persistedState, () => undefined); expect(data.hasNullValues()).to.be(false); }); @@ -307,7 +307,7 @@ describe('Vislib Data Class Test Suite', function() { ], }); - const data = new Data(nullRowData, persistedState); + const data = new Data(nullRowData, persistedState, () => undefined); expect(data.hasNullValues()).to.be(true); }); }); diff --git a/src/legacy/ui/public/vislib/__tests__/lib/dispatch.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/dispatch.js similarity index 90% rename from src/legacy/ui/public/vislib/__tests__/lib/dispatch.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/dispatch.js index f2d2e7d05a34d4..a93db5637c89d9 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/dispatch.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/dispatch.js @@ -20,22 +20,23 @@ import _ from 'lodash'; import d3 from 'd3'; import ngMock from 'ng_mock'; + import expect from '@kbn/expect'; +import 'ui/persisted_state'; // Data -import data from 'fixtures/vislib/mock_data/date_histogram/_series'; -import FixturesVislibVisFixtureProvider from 'fixtures/vislib/_vis_fixture'; -import '../../../persisted_state'; -import { SimpleEmitter } from '../../../utils/simple_emitter'; +import data from './fixtures/mock_data/date_histogram/_series'; +import getFixturesVislibVisFixtureProvider from './fixtures/_vis_fixture'; +import { SimpleEmitter } from '../../../legacy_imports'; describe('Vislib Dispatch Class Test Suite', function() { function destroyVis(vis) { vis.destroy(); } - function getEls(el, n, type) { + function getEls(element, n, type) { return d3 - .select(el) + .select(element) .data(new Array(n)) .enter() .append(type); @@ -48,7 +49,8 @@ describe('Vislib Dispatch Class Test Suite', function() { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(); + const getVis = getFixturesVislibVisFixtureProvider(Private); + vis = getVis(); persistedState = new ($injector.get('PersistedState'))(); vis.render(data, persistedState); }) @@ -74,8 +76,9 @@ describe('Vislib Dispatch Class Test Suite', function() { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(); + const getVis = getFixturesVislibVisFixtureProvider(Private); persistedState = new ($injector.get('PersistedState'))(); + vis = getVis(); vis.on('brush', _.noop); vis.render(data, persistedState); }) @@ -91,7 +94,7 @@ describe('Vislib Dispatch Class Test Suite', function() { const apply = chart.events.addEvent('event', _.noop); expect(apply).to.be.a('function'); - const els = getEls(vis.el, 3, 'div'); + const els = getEls(vis.element, 3, 'div'); apply(els); els.each(function() { expect(d3.select(this).on('event')).to.be(_.noop); @@ -114,7 +117,7 @@ describe('Vislib Dispatch Class Test Suite', function() { const apply = chart.events[name](chart.series[0].chartEl); expect(apply).to.be.a('function'); - const els = getEls(vis.el, 3, 'div'); + const els = getEls(vis.element, 3, 'div'); apply(els); els.each(function() { expect(d3.select(this).on(event)).to.be.a('function'); @@ -188,7 +191,8 @@ describe('Vislib Dispatch Class Test Suite', function() { let persistedState; ngMock.module('kibana'); ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(); + const getVis = getFixturesVislibVisFixtureProvider(Private); + vis = getVis(); persistedState = new ($injector.get('PersistedState'))(); vis.on('someEvent', _.noop); vis.render(data, persistedState); @@ -207,7 +211,8 @@ describe('Vislib Dispatch Class Test Suite', function() { let persistedState; ngMock.module('kibana'); ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(); + const getVis = getFixturesVislibVisFixtureProvider(Private); + vis = getVis(); persistedState = new ($injector.get('PersistedState'))(); vis.render(data, persistedState); vis.on('someEvent', _.noop); diff --git a/src/legacy/ui/public/vislib/__tests__/lib/dispatch_heatmap.test.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/dispatch_heatmap.test.js similarity index 88% rename from src/legacy/ui/public/vislib/__tests__/lib/dispatch_heatmap.test.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/dispatch_heatmap.test.js index 19e78ef4f30c27..e22f19ea643fd3 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/dispatch_heatmap.test.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/dispatch_heatmap.test.js @@ -16,7 +16,13 @@ * specific language governing permissions and limitations * under the License. */ + import mockDispatchDataD3 from './fixtures/dispatch_heatmap_d3.json'; +import { Dispatch } from '../../lib/dispatch'; +import mockdataPoint from './fixtures/dispatch_heatmap_data_point.json'; +import mockConfigPercentage from './fixtures/dispatch_heatmap_config.json'; + +jest.mock('ui/new_platform'); jest.mock('d3', () => ({ event: { target: { @@ -26,16 +32,14 @@ jest.mock('d3', () => ({ }, }, })); - -import { Dispatch } from '../../lib/dispatch'; -import mockdataPoint from './fixtures/dispatch_heatmap_data_point.json'; -import mockConfigPercentage from './fixtures/dispatch_heatmap_config.json'; - -jest.mock('ui/chrome', () => ({ - getUiSettingsClient: () => ({ - get: () => '', - }), - addBasePath: () => {}, +jest.mock('../../../legacy_imports.ts', () => ({ + ...jest.requireActual('../../../legacy_imports.ts'), + chrome: { + getUiSettingsClient: () => ({ + get: () => '', + }), + addBasePath: () => {}, + }, })); function getHandlerMock(config = {}, data = {}) { diff --git a/src/legacy/ui/public/vislib/__tests__/lib/dispatch_vertical_bar_chart.test.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/dispatch_vertical_bar_chart.test.js similarity index 90% rename from src/legacy/ui/public/vislib/__tests__/lib/dispatch_vertical_bar_chart.test.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/dispatch_vertical_bar_chart.test.js index e196c1bde0737e..8fe9ac24db77b5 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/dispatch_vertical_bar_chart.test.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/dispatch_vertical_bar_chart.test.js @@ -16,7 +16,14 @@ * specific language governing permissions and limitations * under the License. */ + import mockDispatchDataD3 from './fixtures/dispatch_bar_chart_d3.json'; +import { Dispatch } from '../../lib/dispatch'; +import mockdataPoint from './fixtures/dispatch_bar_chart_data_point.json'; +import mockConfigPercentage from './fixtures/dispatch_bar_chart_config_percentage.json'; +import mockConfigNormal from './fixtures/dispatch_bar_chart_config_normal.json'; + +jest.mock('ui/new_platform'); jest.mock('d3', () => ({ event: { target: { @@ -26,17 +33,14 @@ jest.mock('d3', () => ({ }, }, })); - -import { Dispatch } from '../../lib/dispatch'; -import mockdataPoint from './fixtures/dispatch_bar_chart_data_point.json'; -import mockConfigPercentage from './fixtures/dispatch_bar_chart_config_percentage.json'; -import mockConfigNormal from './fixtures/dispatch_bar_chart_config_normal.json'; - -jest.mock('ui/chrome', () => ({ - getUiSettingsClient: () => ({ - get: () => '', - }), - addBasePath: () => {}, +jest.mock('../../../legacy_imports.ts', () => ({ + ...jest.requireActual('../../../legacy_imports.ts'), + chrome: { + getUiSettingsClient: () => ({ + get: () => '', + }), + addBasePath: () => {}, + }, })); function getHandlerMock(config = {}, data = {}) { diff --git a/src/legacy/ui/public/vislib/__tests__/lib/error_handler.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/error_handler.js similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/error_handler.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/error_handler.js diff --git a/src/fixtures/vislib/_vis_fixture.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/_vis_fixture.js similarity index 61% rename from src/fixtures/vislib/_vis_fixture.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/_vis_fixture.js index d71c76a1fd99e1..c49ca732f09159 100644 --- a/src/fixtures/vislib/_vis_fixture.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/_vis_fixture.js @@ -19,7 +19,23 @@ import _ from 'lodash'; import $ from 'jquery'; -import { VislibVisProvider } from 'ui/vislib/vis'; + +import { Vis } from '../../../vis'; + +// TODO: remove legacy imports when/of converting tests to jest +import { + setHierarchicalTooltipFormatter, + getHierarchicalTooltipFormatter, +} from 'ui/vis/components/tooltip/_hierarchical_tooltip_formatter'; +import { + setPointSeriesTooltipFormatter, + getPointSeriesTooltipFormatter, +} from 'ui/vis/components/tooltip/_pointseries_tooltip_formatter'; +import { + vislibSeriesResponseHandlerProvider, + vislibSlicesResponseHandlerProvider, +} from 'ui/vis/response_handlers/vislib'; +import { vislibColor } from 'ui/vis/components/color/color'; const $visCanvas = $('
') .attr('id', 'vislib-vis-fixtures') @@ -52,11 +68,25 @@ afterEach(function() { count = 0; }); -export default function VislibFixtures(Private) { - return function(visLibParams) { - const Vis = Private(VislibVisProvider); +const getDeps = () => { + const uiSettings = new Map(); + return { + uiSettings, + vislibColor, + getHierarchicalTooltipFormatter, + getPointSeriesTooltipFormatter, + vislibSeriesResponseHandlerProvider, + vislibSlicesResponseHandlerProvider, + }; +}; + +export default function getVislibFixtures(Private) { + setHierarchicalTooltipFormatter(Private); + setPointSeriesTooltipFormatter(Private); + + return function(visLibParams, element) { return new Vis( - $visCanvas.new(), + element || $visCanvas.new(), _.defaults({}, visLibParams || {}, { addTooltip: true, addLegend: true, @@ -64,7 +94,8 @@ export default function VislibFixtures(Private) { setYExtents: false, yAxis: {}, type: 'histogram', - }) + }), + getDeps() ); }; } diff --git a/src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_config_normal.json b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_config_normal.json similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_config_normal.json rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_config_normal.json diff --git a/src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_config_percentage.json b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_config_percentage.json similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_config_percentage.json rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_config_percentage.json diff --git a/src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_d3.json b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_d3.json similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_d3.json rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_d3.json diff --git a/src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_data_point.json b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_data_point.json similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_data_point.json rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_bar_chart_data_point.json diff --git a/src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_heatmap_config.json b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_heatmap_config.json similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_heatmap_config.json rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_heatmap_config.json diff --git a/src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_heatmap_d3.json b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_heatmap_d3.json similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_heatmap_d3.json rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_heatmap_d3.json diff --git a/src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_heatmap_data_point.json b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_heatmap_data_point.json similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/fixtures/dispatch_heatmap_data_point.json rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/dispatch_heatmap_data_point.json diff --git a/src/fixtures/vislib/mock_data/date_histogram/_columns.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_columns.js similarity index 100% rename from src/fixtures/vislib/mock_data/date_histogram/_columns.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_columns.js diff --git a/src/fixtures/vislib/mock_data/date_histogram/_rows.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_rows.js similarity index 100% rename from src/fixtures/vislib/mock_data/date_histogram/_rows.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_rows.js diff --git a/src/fixtures/vislib/mock_data/date_histogram/_rows_series_with_holes.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_rows_series_with_holes.js similarity index 100% rename from src/fixtures/vislib/mock_data/date_histogram/_rows_series_with_holes.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_rows_series_with_holes.js diff --git a/src/fixtures/vislib/mock_data/date_histogram/_series.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_series.js similarity index 100% rename from src/fixtures/vislib/mock_data/date_histogram/_series.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_series.js diff --git a/src/fixtures/vislib/mock_data/date_histogram/_series_monthly_interval.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_series_monthly_interval.js similarity index 100% rename from src/fixtures/vislib/mock_data/date_histogram/_series_monthly_interval.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_series_monthly_interval.js diff --git a/src/fixtures/vislib/mock_data/date_histogram/_series_neg.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_series_neg.js similarity index 100% rename from src/fixtures/vislib/mock_data/date_histogram/_series_neg.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_series_neg.js diff --git a/src/fixtures/vislib/mock_data/date_histogram/_series_pos_neg.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_series_pos_neg.js similarity index 100% rename from src/fixtures/vislib/mock_data/date_histogram/_series_pos_neg.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_series_pos_neg.js diff --git a/src/fixtures/vislib/mock_data/date_histogram/_stacked_series.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_stacked_series.js similarity index 100% rename from src/fixtures/vislib/mock_data/date_histogram/_stacked_series.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/date_histogram/_stacked_series.js diff --git a/src/fixtures/vislib/mock_data/filters/_columns.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/filters/_columns.js similarity index 100% rename from src/fixtures/vislib/mock_data/filters/_columns.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/filters/_columns.js diff --git a/src/fixtures/vislib/mock_data/filters/_rows.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/filters/_rows.js similarity index 100% rename from src/fixtures/vislib/mock_data/filters/_rows.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/filters/_rows.js diff --git a/src/fixtures/vislib/mock_data/filters/_series.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/filters/_series.js similarity index 100% rename from src/fixtures/vislib/mock_data/filters/_series.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/filters/_series.js diff --git a/src/fixtures/vislib/mock_data/geohash/_columns.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/geohash/_columns.js similarity index 100% rename from src/fixtures/vislib/mock_data/geohash/_columns.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/geohash/_columns.js diff --git a/src/fixtures/vislib/mock_data/geohash/_geo_json.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/geohash/_geo_json.js similarity index 100% rename from src/fixtures/vislib/mock_data/geohash/_geo_json.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/geohash/_geo_json.js diff --git a/src/fixtures/vislib/mock_data/geohash/_rows.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/geohash/_rows.js similarity index 100% rename from src/fixtures/vislib/mock_data/geohash/_rows.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/geohash/_rows.js diff --git a/src/fixtures/vislib/mock_data/histogram/_columns.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/histogram/_columns.js similarity index 100% rename from src/fixtures/vislib/mock_data/histogram/_columns.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/histogram/_columns.js diff --git a/src/fixtures/vislib/mock_data/histogram/_rows.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/histogram/_rows.js similarity index 100% rename from src/fixtures/vislib/mock_data/histogram/_rows.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/histogram/_rows.js diff --git a/src/fixtures/vislib/mock_data/histogram/_series.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/histogram/_series.js similarity index 100% rename from src/fixtures/vislib/mock_data/histogram/_series.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/histogram/_series.js diff --git a/src/fixtures/vislib/mock_data/histogram/_slices.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/histogram/_slices.js similarity index 100% rename from src/fixtures/vislib/mock_data/histogram/_slices.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/histogram/_slices.js diff --git a/src/fixtures/vislib/mock_data/not_enough_data/_one_point.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/not_enough_data/_one_point.js similarity index 100% rename from src/fixtures/vislib/mock_data/not_enough_data/_one_point.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/not_enough_data/_one_point.js diff --git a/src/fixtures/vislib/mock_data/range/_columns.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/range/_columns.js similarity index 100% rename from src/fixtures/vislib/mock_data/range/_columns.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/range/_columns.js diff --git a/src/fixtures/vislib/mock_data/range/_rows.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/range/_rows.js similarity index 100% rename from src/fixtures/vislib/mock_data/range/_rows.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/range/_rows.js diff --git a/src/fixtures/vislib/mock_data/range/_series.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/range/_series.js similarity index 100% rename from src/fixtures/vislib/mock_data/range/_series.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/range/_series.js diff --git a/src/fixtures/vislib/mock_data/significant_terms/_columns.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/significant_terms/_columns.js similarity index 100% rename from src/fixtures/vislib/mock_data/significant_terms/_columns.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/significant_terms/_columns.js diff --git a/src/fixtures/vislib/mock_data/significant_terms/_rows.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/significant_terms/_rows.js similarity index 100% rename from src/fixtures/vislib/mock_data/significant_terms/_rows.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/significant_terms/_rows.js diff --git a/src/fixtures/vislib/mock_data/significant_terms/_series.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/significant_terms/_series.js similarity index 100% rename from src/fixtures/vislib/mock_data/significant_terms/_series.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/significant_terms/_series.js diff --git a/src/fixtures/vislib/mock_data/stacked/_stacked.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/stacked/_stacked.js similarity index 100% rename from src/fixtures/vislib/mock_data/stacked/_stacked.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/stacked/_stacked.js diff --git a/src/fixtures/vislib/mock_data/terms/_columns.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/terms/_columns.js similarity index 100% rename from src/fixtures/vislib/mock_data/terms/_columns.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/terms/_columns.js diff --git a/src/fixtures/vislib/mock_data/terms/_rows.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/terms/_rows.js similarity index 100% rename from src/fixtures/vislib/mock_data/terms/_rows.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/terms/_rows.js diff --git a/src/fixtures/vislib/mock_data/terms/_series.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/terms/_series.js similarity index 100% rename from src/fixtures/vislib/mock_data/terms/_series.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/terms/_series.js diff --git a/src/fixtures/vislib/mock_data/terms/_seriesMultiple.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/terms/_seriesMultiple.js similarity index 100% rename from src/fixtures/vislib/mock_data/terms/_seriesMultiple.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/terms/_seriesMultiple.js diff --git a/src/legacy/ui/public/vislib/__tests__/lib/handler/handler.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/handler/handler.js similarity index 87% rename from src/legacy/ui/public/vislib/__tests__/lib/handler/handler.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/handler/handler.js index d37d67567e8a52..b309c97d240006 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/handler/handler.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/handler/handler.js @@ -21,13 +21,14 @@ import ngMock from 'ng_mock'; import expect from '@kbn/expect'; // Data -import series from 'fixtures/vislib/mock_data/date_histogram/_series'; -import columns from 'fixtures/vislib/mock_data/date_histogram/_columns'; -import rows from 'fixtures/vislib/mock_data/date_histogram/_rows'; -import stackedSeries from 'fixtures/vislib/mock_data/date_histogram/_stacked_series'; +import series from '../fixtures/mock_data/date_histogram/_series'; +import columns from '../fixtures/mock_data/date_histogram/_columns'; +import rows from '../fixtures/mock_data/date_histogram/_rows'; +import stackedSeries from '../fixtures/mock_data/date_histogram/_stacked_series'; import $ from 'jquery'; -import FixturesVislibVisFixtureProvider from 'fixtures/vislib/_vis_fixture'; -import '../../../../persisted_state'; +import 'ui/persisted_state'; + +import getFixturesVislibVisFixtureProvider from '../fixtures/_vis_fixture'; const dateHistogramArray = [series, columns, rows, stackedSeries]; const names = ['series', 'columns', 'rows', 'stackedSeries']; @@ -40,7 +41,8 @@ dateHistogramArray.forEach(function(data, i) { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(); + const getVis = getFixturesVislibVisFixtureProvider(Private); + vis = getVis(); persistedState = new ($injector.get('PersistedState'))(); vis.render(data, persistedState); }) @@ -106,12 +108,12 @@ dateHistogramArray.forEach(function(data, i) { describe('removeAll Method', function() { beforeEach(function() { ngMock.inject(function() { - vis.handler.removeAll(vis.el); + vis.handler.removeAll(vis.element); }); }); it('should remove all DOM elements from the el', function() { - expect($(vis.el).children().length).to.be(0); + expect($(vis.element).children().length).to.be(0); }); }); @@ -121,7 +123,7 @@ dateHistogramArray.forEach(function(data, i) { }); it('should return an error classed DOM element with a text message', function() { - expect($(vis.el).find('.error').length).to.be(1); + expect($(vis.element).find('.error').length).to.be(1); expect($('.error h4').html()).to.be('This is an error!'); }); }); diff --git a/src/legacy/ui/public/vislib/__tests__/lib/layout/layout.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/layout/layout.js similarity index 65% rename from src/legacy/ui/public/vislib/__tests__/lib/layout/layout.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/layout/layout.js index 853a00d035a076..c8636f34ce6f8f 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/layout/layout.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/layout/layout.js @@ -20,16 +20,16 @@ import d3 from 'd3'; import ngMock from 'ng_mock'; import expect from '@kbn/expect'; +import 'ui/persisted_state'; // Data -import series from 'fixtures/vislib/mock_data/date_histogram/_series'; -import columns from 'fixtures/vislib/mock_data/date_histogram/_columns'; -import rows from 'fixtures/vislib/mock_data/date_histogram/_rows'; -import stackedSeries from 'fixtures/vislib/mock_data/date_histogram/_stacked_series'; +import series from '../fixtures/mock_data/date_histogram/_series'; +import columns from '../fixtures/mock_data/date_histogram/_columns'; +import rows from '../fixtures/mock_data/date_histogram/_rows'; +import stackedSeries from '../fixtures/mock_data/date_histogram/_stacked_series'; import $ from 'jquery'; import { Layout } from '../../../lib/layout/layout'; -import FixturesVislibVisFixtureProvider from 'fixtures/vislib/_vis_fixture'; -import '../../../../persisted_state'; +import getFixturesVislibVisFixtureProvider from '../fixtures/_vis_fixture'; import { VisConfig } from '../../../lib/vis_config'; const dateHistogramArray = [series, columns, rows, stackedSeries]; @@ -46,7 +46,8 @@ dateHistogramArray.forEach(function(data, i) { beforeEach(function() { ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(); + const getVis = getFixturesVislibVisFixtureProvider(Private); + vis = getVis(); persistedState = new ($injector.get('PersistedState'))(); vis.render(data, persistedState); numberOfCharts = vis.handler.charts.length; @@ -59,17 +60,17 @@ dateHistogramArray.forEach(function(data, i) { describe('createLayout Method', function() { it('should append all the divs', function() { - expect($(vis.el).find('.visWrapper').length).to.be(1); - expect($(vis.el).find('.visAxis--y').length).to.be(2); - expect($(vis.el).find('.visWrapper__column').length).to.be(1); - expect($(vis.el).find('.visAxis__column--y').length).to.be(2); - expect($(vis.el).find('.y-axis-title').length).to.be.above(0); - expect($(vis.el).find('.visAxis__splitAxes--y').length).to.be(2); - expect($(vis.el).find('.visAxis__spacer--y').length).to.be(4); - expect($(vis.el).find('.visWrapper__chart').length).to.be(numberOfCharts); - expect($(vis.el).find('.visAxis--x').length).to.be(2); - expect($(vis.el).find('.visAxis__splitAxes--x').length).to.be(2); - expect($(vis.el).find('.x-axis-title').length).to.be.above(0); + expect($(vis.element).find('.visWrapper').length).to.be(1); + expect($(vis.element).find('.visAxis--y').length).to.be(2); + expect($(vis.element).find('.visWrapper__column').length).to.be(1); + expect($(vis.element).find('.visAxis__column--y').length).to.be(2); + expect($(vis.element).find('.y-axis-title').length).to.be.above(0); + expect($(vis.element).find('.visAxis__splitAxes--y').length).to.be(2); + expect($(vis.element).find('.visAxis__spacer--y').length).to.be(4); + expect($(vis.element).find('.visWrapper__chart').length).to.be(numberOfCharts); + expect($(vis.element).find('.visAxis--x').length).to.be(2); + expect($(vis.element).find('.visAxis__splitAxes--x').length).to.be(2); + expect($(vis.element).find('.x-axis-title').length).to.be.above(0); }); }); @@ -81,35 +82,36 @@ dateHistogramArray.forEach(function(data, i) { }, data, persistedState, - vis.el + vis.element, + () => undefined ); testLayout = new Layout(visConfig); }); it('should append a div with the correct class name', function() { - expect($(vis.el).find('.chart').length).to.be(numberOfCharts); + expect($(vis.element).find('.chart').length).to.be(numberOfCharts); }); it('should bind data to the DOM element', function() { expect( - !!$(vis.el) + !!$(vis.element) .find('.chart') .data() ).to.be(true); }); it('should create children', function() { - expect(typeof $(vis.el).find('.x-axis-div')).to.be('object'); + expect(typeof $(vis.element).find('.x-axis-div')).to.be('object'); }); it('should call split function when provided', function() { - expect(typeof $(vis.el).find('.x-axis-div')).to.be('object'); + expect(typeof $(vis.element).find('.x-axis-div')).to.be('object'); }); it('should throw errors when incorrect arguments provided', function() { expect(function() { testLayout.layout({ - parent: vis.el, + parent: vis.element, type: undefined, class: 'chart', }); @@ -131,7 +133,7 @@ dateHistogramArray.forEach(function(data, i) { expect(function() { testLayout.layout({ - parent: vis.el, + parent: vis.element, type: function(d) { return d; }, @@ -143,26 +145,26 @@ dateHistogramArray.forEach(function(data, i) { describe('appendElem Method', function() { beforeEach(function() { - vis.handler.layout.appendElem(vis.el, 'svg', 'column'); + vis.handler.layout.appendElem(vis.element, 'svg', 'column'); vis.handler.layout.appendElem('.visChart', 'div', 'test'); }); it('should append DOM element to el with a class name', function() { - expect(typeof $(vis.el).find('.column')).to.be('object'); - expect(typeof $(vis.el).find('.test')).to.be('object'); + expect(typeof $(vis.element).find('.column')).to.be('object'); + expect(typeof $(vis.element).find('.test')).to.be('object'); }); }); describe('removeAll Method', function() { beforeEach(function() { - d3.select(vis.el) + d3.select(vis.element) .append('div') .attr('class', 'visualize'); - vis.handler.layout.removeAll(vis.el); + vis.handler.layout.removeAll(vis.element); }); it('should remove all DOM elements from the el', function() { - expect($(vis.el).children().length).to.be(0); + expect($(vis.element).children().length).to.be(0); }); }); }); diff --git a/src/legacy/ui/public/vislib/__tests__/lib/layout/layout_types.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/layout/layout_types.js similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/layout/layout_types.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/layout/layout_types.js diff --git a/src/legacy/ui/public/vislib/__tests__/lib/layout/splits/column_chart/splits.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/layout/splits/column_chart/splits.js similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/layout/splits/column_chart/splits.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/layout/splits/column_chart/splits.js diff --git a/src/legacy/ui/public/vislib/__tests__/lib/layout/splits/gauge_chart/splits.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/layout/splits/gauge_chart/splits.js similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/layout/splits/gauge_chart/splits.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/layout/splits/gauge_chart/splits.js diff --git a/src/legacy/ui/public/vislib/__tests__/lib/layout/types/column_layout.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/layout/types/column_layout.js similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/layout/types/column_layout.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/layout/types/column_layout.js diff --git a/src/legacy/ui/public/vislib/__tests__/lib/types/point_series.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/types/point_series.js similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/types/point_series.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/types/point_series.js diff --git a/src/legacy/ui/public/vislib/__tests__/lib/types/testdata_linechart_percentile.json b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/types/testdata_linechart_percentile.json similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/types/testdata_linechart_percentile.json rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/types/testdata_linechart_percentile.json diff --git a/src/legacy/ui/public/vislib/__tests__/lib/types/testdata_linechart_percentile_result.json b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/types/testdata_linechart_percentile_result.json similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/lib/types/testdata_linechart_percentile_result.json rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/types/testdata_linechart_percentile_result.json diff --git a/src/legacy/ui/public/vislib/__tests__/lib/vis_config.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/vis_config.js similarity index 98% rename from src/legacy/ui/public/vislib/__tests__/lib/vis_config.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/vis_config.js index c9dcd4737b51a8..3f0253b4a46702 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/vis_config.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/vis_config.js @@ -20,8 +20,8 @@ import d3 from 'd3'; import ngMock from 'ng_mock'; import expect from '@kbn/expect'; +import 'ui/persisted_state'; import { VisConfig } from '../../lib/vis_config'; -import '../../../persisted_state'; describe('Vislib VisConfig Class Test Suite', function() { let el; @@ -101,7 +101,8 @@ describe('Vislib VisConfig Class Test Suite', function() { }, data, new PersistedState(), - el + el, + () => undefined ); }) ); diff --git a/src/legacy/ui/public/vislib/__tests__/lib/x_axis.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/x_axis.js similarity index 98% rename from src/legacy/ui/public/vislib/__tests__/lib/x_axis.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/x_axis.js index 2fb7763756975c..09fe067537c7f7 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/x_axis.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/x_axis.js @@ -21,8 +21,8 @@ import d3 from 'd3'; import _ from 'lodash'; import ngMock from 'ng_mock'; import expect from '@kbn/expect'; +import 'ui/persisted_state'; import $ from 'jquery'; -import '../../../persisted_state'; import { Axis } from '../../lib/axis'; import { VisConfig } from '../../lib/vis_config'; @@ -124,7 +124,8 @@ describe('Vislib xAxis Class Test Suite', function() { }, data, persistedState, - $('.x-axis-div')[0] + $('.x-axis-div')[0], + () => undefined ); xAxis = new Axis(visConfig, { type: 'category', diff --git a/src/legacy/ui/public/vislib/__tests__/lib/y_axis.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/y_axis.js similarity index 99% rename from src/legacy/ui/public/vislib/__tests__/lib/y_axis.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/y_axis.js index 0189b8b960d326..e857aca3bf3edc 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/y_axis.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/y_axis.js @@ -21,8 +21,8 @@ import _ from 'lodash'; import d3 from 'd3'; import ngMock from 'ng_mock'; import expect from '@kbn/expect'; +import 'ui/persisted_state'; import $ from 'jquery'; -import '../../../persisted_state'; import { Axis } from '../../lib/axis'; import { VisConfig } from '../../lib/vis_config'; @@ -97,7 +97,8 @@ function createData(seriesData) { }, data, persistedState, - node + node, + () => undefined ); return new YAxis( visConfig, diff --git a/src/legacy/ui/public/vislib/__tests__/vis.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/vis.js similarity index 92% rename from src/legacy/ui/public/vislib/__tests__/vis.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/vis.js index f10f44b7100d82..a6d1c4daf5d2cf 100644 --- a/src/legacy/ui/public/vislib/__tests__/vis.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/vis.js @@ -18,16 +18,17 @@ */ import _ from 'lodash'; -import expect from '@kbn/expect'; +import $ from 'jquery'; import ngMock from 'ng_mock'; -import series from 'fixtures/vislib/mock_data/date_histogram/_series'; -import columns from 'fixtures/vislib/mock_data/date_histogram/_columns'; -import rows from 'fixtures/vislib/mock_data/date_histogram/_rows'; -import stackedSeries from 'fixtures/vislib/mock_data/date_histogram/_stacked_series'; -import $ from 'jquery'; -import FixturesVislibVisFixtureProvider from 'fixtures/vislib/_vis_fixture'; -import '../../persisted_state'; +import expect from '@kbn/expect'; +import 'ui/persisted_state'; + +import series from './lib/fixtures/mock_data/date_histogram/_series'; +import columns from './lib/fixtures/mock_data/date_histogram/_columns'; +import rows from './lib/fixtures/mock_data/date_histogram/_rows'; +import stackedSeries from './lib/fixtures/mock_data/date_histogram/_stacked_series'; +import getFixturesVislibVisFixtureProvider from './lib/fixtures/_vis_fixture'; const dataArray = [series, columns, rows, stackedSeries]; @@ -45,9 +46,10 @@ dataArray.forEach(function(data, i) { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(); + const getVis = getFixturesVislibVisFixtureProvider(Private); + vis = getVis(); persistedState = new ($injector.get('PersistedState'))(); - secondVis = Private(FixturesVislibVisFixtureProvider)(); + secondVis = getVis(); }) ); @@ -99,7 +101,7 @@ dataArray.forEach(function(data, i) { }); it('should not remove visualizations that have not been destroyed', function() { - expect($(vis.el).find('.visWrapper').length).to.be(1); + expect($(vis.element).find('.visWrapper').length).to.be(1); }); }); diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/area_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/area_chart.js similarity index 93% rename from src/legacy/ui/public/vislib/__tests__/visualizations/area_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/area_chart.js index d81fd66f1e1110..7fe350bd85e052 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/area_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/area_chart.js @@ -18,20 +18,22 @@ */ import d3 from 'd3'; -import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; - import $ from 'jquery'; -import FixturesVislibVisFixtureProvider from 'fixtures/vislib/_vis_fixture'; -import '../../../persisted_state'; + +import expect from '@kbn/expect'; +import 'ui/persisted_state'; + +import getFixturesVislibVisFixtureProvider from '../lib/fixtures/_vis_fixture'; + const dataTypesArray = { - 'series pos': require('fixtures/vislib/mock_data/date_histogram/_series'), - 'series pos neg': require('fixtures/vislib/mock_data/date_histogram/_series_pos_neg'), - 'series neg': require('fixtures/vislib/mock_data/date_histogram/_series_neg'), - 'term columns': require('fixtures/vislib/mock_data/terms/_columns'), - 'range rows': require('fixtures/vislib/mock_data/range/_rows'), - stackedSeries: require('fixtures/vislib/mock_data/date_histogram/_stacked_series'), + 'series pos': require('../lib/fixtures/mock_data/date_histogram/_series'), + 'series pos neg': require('../lib/fixtures/mock_data/date_histogram/_series_pos_neg'), + 'series neg': require('../lib/fixtures/mock_data/date_histogram/_series_neg'), + 'term columns': require('../lib/fixtures/mock_data/terms/_columns'), + 'range rows': require('../lib/fixtures/mock_data/range/_rows'), + stackedSeries: require('../lib/fixtures/mock_data/date_histogram/_stacked_series'), }; const visLibParams = { @@ -49,7 +51,8 @@ _.forOwn(dataTypesArray, function(dataType, dataTypeName) { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(visLibParams); + const getVis = getFixturesVislibVisFixtureProvider(Private); + vis = getVis(visLibParams); persistedState = new ($injector.get('PersistedState'))(); vis.on('brush', _.noop); vis.render(dataType, persistedState); diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/chart.js similarity index 93% rename from src/legacy/ui/public/vislib/__tests__/visualizations/chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/chart.js index f876db0aa6b226..088d3377af4dd5 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/chart.js @@ -18,15 +18,16 @@ */ import d3 from 'd3'; -import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import { VislibVisProvider } from '../../vis'; -import '../../../persisted_state'; + +import expect from '@kbn/expect'; +import 'ui/persisted_state'; + import { Chart } from '../../visualizations/_chart'; +import getFixturesVislibVisFixtureProvider from '../lib/fixtures/_vis_fixture'; describe('Vislib _chart Test Suite', function() { let persistedState; - let Vis; let vis; let el; let myChart; @@ -111,7 +112,7 @@ describe('Vislib _chart Test Suite', function() { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - Vis = Private(VislibVisProvider); + const getVis = getFixturesVislibVisFixtureProvider(Private); persistedState = new ($injector.get('PersistedState'))(); el = d3 @@ -126,7 +127,7 @@ describe('Vislib _chart Test Suite', function() { zeroFill: true, }; - vis = new Vis(el[0][0], config); + vis = getVis(config, el[0][0]); vis.render(data, persistedState); myChart = vis.handler.charts[0]; diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/column_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/column_chart.js similarity index 91% rename from src/legacy/ui/public/vislib/__tests__/visualizations/column_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/column_chart.js index 2253783e7e6446..d02060ef29bdd4 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/column_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/column_chart.js @@ -17,24 +17,25 @@ * under the License. */ -import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; import d3 from 'd3'; +import expect from '@kbn/expect'; +import 'ui/persisted_state'; + // Data -import series from 'fixtures/vislib/mock_data/date_histogram/_series'; -import seriesPosNeg from 'fixtures/vislib/mock_data/date_histogram/_series_pos_neg'; -import seriesNeg from 'fixtures/vislib/mock_data/date_histogram/_series_neg'; -import termsColumns from 'fixtures/vislib/mock_data/terms/_columns'; -import histogramRows from 'fixtures/vislib/mock_data/histogram/_rows'; -import stackedSeries from 'fixtures/vislib/mock_data/date_histogram/_stacked_series'; -import { seriesMonthlyInterval } from 'fixtures/vislib/mock_data/date_histogram/_series_monthly_interval'; -import { rowsSeriesWithHoles } from 'fixtures/vislib/mock_data/date_histogram/_rows_series_with_holes'; -import rowsWithZeros from 'fixtures/vislib/mock_data/date_histogram/_rows'; +import series from '../lib/fixtures/mock_data/date_histogram/_series'; +import seriesPosNeg from '../lib/fixtures/mock_data/date_histogram/_series_pos_neg'; +import seriesNeg from '../lib/fixtures/mock_data/date_histogram/_series_neg'; +import termsColumns from '../lib/fixtures/mock_data/terms/_columns'; +import histogramRows from '../lib/fixtures/mock_data/histogram/_rows'; +import stackedSeries from '../lib/fixtures/mock_data/date_histogram/_stacked_series'; +import { seriesMonthlyInterval } from '../lib/fixtures/mock_data/date_histogram/_series_monthly_interval'; +import { rowsSeriesWithHoles } from '../lib/fixtures/mock_data/date_histogram/_rows_series_with_holes'; +import rowsWithZeros from '../lib/fixtures/mock_data/date_histogram/_rows'; import $ from 'jquery'; -import FixturesVislibVisFixtureProvider from 'fixtures/vislib/_vis_fixture'; -import '../../../persisted_state'; +import getFixturesVislibVisFixtureProvider from '../lib/fixtures/_vis_fixture'; // tuple, with the format [description, mode, data] const dataTypesArray = [ @@ -69,7 +70,8 @@ dataTypesArray.forEach(function(dataType) { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(visLibParams); + const getVis = getFixturesVislibVisFixtureProvider(Private); + vis = getVis(visLibParams); persistedState = new ($injector.get('PersistedState'))(); vis.on('brush', _.noop); vis.render(data, persistedState); @@ -257,7 +259,8 @@ describe('stackData method - data set with zeros in percentage mode', function() beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(visLibParams); + const getVis = getFixturesVislibVisFixtureProvider(Private); + vis = getVis(visLibParams); persistedState = new ($injector.get('PersistedState'))(); vis.on('brush', _.noop); }) @@ -307,7 +310,8 @@ describe('datumWidth - split chart data set with holes', function() { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(visLibParams); + const getVis = getFixturesVislibVisFixtureProvider(Private); + vis = getVis(visLibParams); persistedState = new ($injector.get('PersistedState'))(); vis.on('brush', _.noop); vis.render(rowsSeriesWithHoles, persistedState); @@ -344,7 +348,8 @@ describe('datumWidth - monthly interval', function() { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(visLibParams); + const getVis = getFixturesVislibVisFixtureProvider(Private); + vis = getVis(visLibParams); persistedState = new ($injector.get('PersistedState'))(); vis.on('brush', _.noop); vis.render(seriesMonthlyInterval, persistedState); diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/gauge_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/gauge_chart.js similarity index 94% rename from src/legacy/ui/public/vislib/__tests__/visualizations/gauge_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/gauge_chart.js index 45d9d4a2e374bd..074b34e1c03c43 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/gauge_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/gauge_chart.js @@ -17,13 +17,15 @@ * under the License. */ -import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import $ from 'jquery'; import _ from 'lodash'; -import data from 'fixtures/vislib/mock_data/terms/_seriesMultiple'; -import FixturesVislibVisFixtureProvider from 'fixtures/vislib/_vis_fixture'; -import '../../../persisted_state'; + +import expect from '@kbn/expect'; +import 'ui/persisted_state'; + +import data from '../lib/fixtures/mock_data/terms/_seriesMultiple'; +import getFixturesVislibVisFixtureProvider from '../lib/fixtures/_vis_fixture'; describe('Vislib Gauge Chart Test Suite', function() { let PersistedState; @@ -89,7 +91,7 @@ describe('Vislib Gauge Chart Test Suite', function() { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - vislibVis = Private(FixturesVislibVisFixtureProvider); + vislibVis = getFixturesVislibVisFixtureProvider(Private); PersistedState = $injector.get('PersistedState'); generateVis(); }) diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/heatmap_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/heatmap_chart.js similarity index 92% rename from src/legacy/ui/public/vislib/__tests__/visualizations/heatmap_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/heatmap_chart.js index f1dc4bf07ee31c..bf1dbad0b44cf1 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/heatmap_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/heatmap_chart.js @@ -17,20 +17,21 @@ * under the License. */ -import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; import d3 from 'd3'; +import expect from '@kbn/expect'; +import 'ui/persisted_state'; + // Data -import series from 'fixtures/vislib/mock_data/date_histogram/_series'; -import seriesPosNeg from 'fixtures/vislib/mock_data/date_histogram/_series_pos_neg'; -import seriesNeg from 'fixtures/vislib/mock_data/date_histogram/_series_neg'; -import termsColumns from 'fixtures/vislib/mock_data/terms/_columns'; -import stackedSeries from 'fixtures/vislib/mock_data/date_histogram/_stacked_series'; +import series from '../lib/fixtures/mock_data/date_histogram/_series'; +import seriesPosNeg from '../lib/fixtures/mock_data/date_histogram/_series_pos_neg'; +import seriesNeg from '../lib/fixtures/mock_data/date_histogram/_series_neg'; +import termsColumns from '../lib/fixtures/mock_data/terms/_columns'; +import stackedSeries from '../lib/fixtures/mock_data/date_histogram/_stacked_series'; import $ from 'jquery'; -import FixturesVislibVisFixtureProvider from 'fixtures/vislib/_vis_fixture'; -import '../../../persisted_state'; +import getFixturesVislibVisFixtureProvider from '../lib/fixtures/_vis_fixture'; // tuple, with the format [description, mode, data] const dataTypesArray = [ @@ -74,7 +75,7 @@ describe('Vislib Heatmap Chart Test Suite', function() { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - vislibVis = Private(FixturesVislibVisFixtureProvider); + vislibVis = getFixturesVislibVisFixtureProvider(Private); PersistedState = $injector.get('PersistedState'); generateVis(); }) diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/line_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/line_chart.js similarity index 92% rename from src/legacy/ui/public/vislib/__tests__/visualizations/line_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/line_chart.js index 354be1f0ced0f5..d010944a19e47d 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/line_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/line_chart.js @@ -20,18 +20,19 @@ import d3 from 'd3'; import expect from '@kbn/expect'; import ngMock from 'ng_mock'; +import $ from 'jquery'; import _ from 'lodash'; +import 'ui/persisted_state'; + // Data -import seriesPos from 'fixtures/vislib/mock_data/date_histogram/_series'; -import seriesPosNeg from 'fixtures/vislib/mock_data/date_histogram/_series_pos_neg'; -import seriesNeg from 'fixtures/vislib/mock_data/date_histogram/_series_neg'; -import histogramColumns from 'fixtures/vislib/mock_data/histogram/_columns'; -import rangeRows from 'fixtures/vislib/mock_data/range/_rows'; -import termSeries from 'fixtures/vislib/mock_data/terms/_series'; -import $ from 'jquery'; -import FixturesVislibVisFixtureProvider from 'fixtures/vislib/_vis_fixture'; -import '../../../persisted_state'; +import seriesPos from '../lib/fixtures/mock_data/date_histogram/_series'; +import seriesPosNeg from '../lib/fixtures/mock_data/date_histogram/_series_pos_neg'; +import seriesNeg from '../lib/fixtures/mock_data/date_histogram/_series_neg'; +import histogramColumns from '../lib/fixtures/mock_data/histogram/_columns'; +import rangeRows from '../lib/fixtures/mock_data/range/_rows'; +import termSeries from '../lib/fixtures/mock_data/terms/_series'; +import getFixturesVislibVisFixtureProvider from '../lib/fixtures/_vis_fixture'; const dataTypes = [ ['series pos', seriesPos], @@ -54,6 +55,7 @@ describe('Vislib Line Chart', function() { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { + const getVis = getFixturesVislibVisFixtureProvider(Private); const visLibParams = { type: 'line', addLegend: true, @@ -61,10 +63,10 @@ describe('Vislib Line Chart', function() { drawLinesBetweenPoints: true, }; - vis = Private(FixturesVislibVisFixtureProvider)(visLibParams); + vis = getVis(visLibParams); persistedState = new ($injector.get('PersistedState'))(); - vis.on('brush', _.noop); vis.render(data, persistedState); + vis.on('brush', _.noop); }) ); diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/pie_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/pie_chart.js similarity index 94% rename from src/legacy/ui/public/vislib/__tests__/visualizations/pie_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/pie_chart.js index 9d299c4d3a5dff..381dfcd387cc20 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/pie_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/pie_chart.js @@ -18,17 +18,20 @@ */ import d3 from 'd3'; -import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; -import fixtures from 'fixtures/fake_hierarchical_data'; import $ from 'jquery'; -import FixturesVislibVisFixtureProvider from 'fixtures/vislib/_vis_fixture'; -import { Vis } from '../../../vis'; -import '../../../persisted_state'; + +import expect from '@kbn/expect'; +// TODO: Remove ui imports once converting to jest +import 'ui/persisted_state'; +import { vislibSlicesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib'; + +import fixtures from 'fixtures/fake_hierarchical_data'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; -import { vislibSlicesResponseHandlerProvider } from '../../../vis/response_handlers/vislib'; -import { tabifyAggResponse } from '../../../agg_response/tabify'; + +import getFixturesVislibVisFixtureProvider from '../lib/fixtures/_vis_fixture'; +import { Vis, tabifyAggResponse } from '../../../legacy_imports'; const rowAgg = [ { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, @@ -129,7 +132,8 @@ describe('No global chart settings', function() { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - chart1 = Private(FixturesVislibVisFixtureProvider)(visLibParams1); + const getVis = getFixturesVislibVisFixtureProvider(Private); + chart1 = getVis(visLibParams1); persistedState = new ($injector.get('PersistedState'))(); indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider); responseHandler = vislibSlicesResponseHandlerProvider().handler; @@ -163,7 +167,7 @@ describe('No global chart settings', function() { }); it('should render chart titles for all charts', function() { - expect($(chart1.el).find('.visAxis__splitTitles--y').length).to.be(1); + expect($(chart1.element).find('.visAxis__splitTitles--y').length).to.be(1); }); describe('_validatePieData method', function() { @@ -221,7 +225,8 @@ describe('Vislib PieChart Class Test Suite', function() { beforeEach(ngMock.module('kibana')); beforeEach( ngMock.inject(function(Private, $injector) { - vis = Private(FixturesVislibVisFixtureProvider)(visLibParams); + const getVis = getFixturesVislibVisFixtureProvider(Private); + vis = getVis(visLibParams); persistedState = new ($injector.get('PersistedState'))(); indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider); responseHandler = vislibSlicesResponseHandlerProvider().handler; diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/time_marker.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/time_marker.js similarity index 97% rename from src/legacy/ui/public/vislib/__tests__/visualizations/time_marker.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/time_marker.js index cfe61d6f35198f..ec22d43c08cb2b 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/time_marker.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/time_marker.js @@ -20,8 +20,8 @@ import d3 from 'd3'; import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import series from 'fixtures/vislib/mock_data/date_histogram/_series'; -import terms from 'fixtures/vislib/mock_data/terms/_columns'; +import series from '../lib/fixtures/mock_data/date_histogram/_series'; +import terms from '../lib/fixtures/mock_data/terms/_columns'; import $ from 'jquery'; import { TimeMarker } from '../../visualizations/time_marker'; diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/vis_types.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/vis_types.js similarity index 100% rename from src/legacy/ui/public/vislib/__tests__/visualizations/vis_types.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/visualizations/vis_types.js diff --git a/src/legacy/ui/public/vislib/_index.scss b/src/legacy/core_plugins/vis_type_vislib/public/vislib/_index.scss similarity index 100% rename from src/legacy/ui/public/vislib/_index.scss rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/_index.scss diff --git a/src/legacy/ui/public/vislib/_variables.scss b/src/legacy/core_plugins/vis_type_vislib/public/vislib/_variables.scss similarity index 100% rename from src/legacy/ui/public/vislib/_variables.scss rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/_variables.scss diff --git a/src/legacy/ui/public/vislib/components/labels/data_array.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/data_array.js similarity index 100% rename from src/legacy/ui/public/vislib/components/labels/data_array.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/data_array.js diff --git a/src/legacy/ui/public/vislib/components/labels/flatten_series.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/flatten_series.js similarity index 100% rename from src/legacy/ui/public/vislib/components/labels/flatten_series.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/flatten_series.js diff --git a/src/legacy/ui/public/vislib/components/labels/index.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/index.js similarity index 100% rename from src/legacy/ui/public/vislib/components/labels/index.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/index.js diff --git a/src/legacy/ui/public/vislib/components/labels/labels.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/labels.js similarity index 100% rename from src/legacy/ui/public/vislib/components/labels/labels.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/labels.js diff --git a/src/legacy/ui/public/vislib/components/labels/truncate_labels.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/truncate_labels.js similarity index 100% rename from src/legacy/ui/public/vislib/components/labels/truncate_labels.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/truncate_labels.js diff --git a/src/legacy/ui/public/vislib/components/labels/uniq_labels.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/uniq_labels.js similarity index 100% rename from src/legacy/ui/public/vislib/components/labels/uniq_labels.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/labels/uniq_labels.js diff --git a/src/legacy/ui/public/vislib/components/zero_injection/flatten_data.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/flatten_data.js similarity index 100% rename from src/legacy/ui/public/vislib/components/zero_injection/flatten_data.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/flatten_data.js diff --git a/src/legacy/ui/public/vislib/components/zero_injection/inject_zeros.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/inject_zeros.js similarity index 100% rename from src/legacy/ui/public/vislib/components/zero_injection/inject_zeros.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/inject_zeros.js diff --git a/src/legacy/ui/public/vislib/components/zero_injection/ordered_x_keys.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/ordered_x_keys.js similarity index 100% rename from src/legacy/ui/public/vislib/components/zero_injection/ordered_x_keys.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/ordered_x_keys.js diff --git a/src/legacy/ui/public/vislib/components/zero_injection/uniq_keys.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/uniq_keys.js similarity index 100% rename from src/legacy/ui/public/vislib/components/zero_injection/uniq_keys.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/uniq_keys.js diff --git a/src/legacy/ui/public/vislib/components/zero_injection/zero_fill_data_array.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/zero_fill_data_array.js similarity index 100% rename from src/legacy/ui/public/vislib/components/zero_injection/zero_fill_data_array.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/zero_fill_data_array.js diff --git a/src/legacy/ui/public/vislib/components/zero_injection/zero_filled_array.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/zero_filled_array.js similarity index 100% rename from src/legacy/ui/public/vislib/components/zero_injection/zero_filled_array.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/zero_filled_array.js diff --git a/src/legacy/ui/public/vislib/components/zero_injection/zero_injection.test.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/zero_injection.test.js similarity index 100% rename from src/legacy/ui/public/vislib/components/zero_injection/zero_injection.test.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/components/zero_injection/zero_injection.test.js diff --git a/src/legacy/ui/public/vislib/errors.ts b/src/legacy/core_plugins/vis_type_vislib/public/vislib/errors.ts similarity index 95% rename from src/legacy/ui/public/vislib/errors.ts rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/errors.ts index 0c6e720f0ef323..9014349c38d253 100644 --- a/src/legacy/ui/public/vislib/errors.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/errors.ts @@ -19,7 +19,7 @@ /* eslint-disable max-classes-per-file */ -import { KbnError } from '../../../../plugins/kibana_utils/public'; +import { KbnError } from '../../../../../plugins/kibana_utils/public'; export class VislibError extends KbnError { constructor(message: string) { diff --git a/src/legacy/ui/public/vislib/index.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/index.js similarity index 100% rename from src/legacy/ui/public/vislib/index.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/index.js diff --git a/src/legacy/ui/public/vislib/lib/_alerts.scss b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_alerts.scss similarity index 100% rename from src/legacy/ui/public/vislib/lib/_alerts.scss rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_alerts.scss diff --git a/src/legacy/ui/public/vislib/lib/_data_label.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_data_label.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/_data_label.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_data_label.js diff --git a/src/legacy/ui/public/vislib/lib/_error_handler.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_error_handler.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/_error_handler.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_error_handler.js diff --git a/src/legacy/ui/public/vislib/lib/_handler.scss b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_handler.scss similarity index 100% rename from src/legacy/ui/public/vislib/lib/_handler.scss rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_handler.scss diff --git a/src/legacy/ui/public/vislib/lib/_index.scss b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_index.scss similarity index 100% rename from src/legacy/ui/public/vislib/lib/_index.scss rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/_index.scss diff --git a/src/legacy/ui/public/vislib/lib/alerts.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/alerts.js similarity index 97% rename from src/legacy/ui/public/vislib/lib/alerts.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/alerts.js index cf79dabf1b07e0..086b4e31be1a3e 100644 --- a/src/legacy/ui/public/vislib/lib/alerts.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/alerts.js @@ -71,11 +71,11 @@ export class Alerts { const alerts = this.alerts; const vis = this.vis; - $(vis.el) + $(vis.element) .find('.visWrapper__alerts') .append($('
').addClass('visAlerts__tray')); if (!alerts.size()) return; - $(vis.el) + $(vis.element) .find('.visAlerts__tray') .append(alerts.value()); } @@ -89,13 +89,13 @@ export class Alerts { }; if (this.alertDefs.find(alertDef => alertDef.msg === alert.msg)) return; this.alertDefs.push(alert); - $(vis.el) + $(vis.element) .find('.visAlerts__tray') .append(this._addAlert(alert)); } destroy() { - $(this.vis.el) + $(this.vis.element) .find('.visWrapper__alerts') .remove(); } diff --git a/src/legacy/ui/public/vislib/lib/axis/axis.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/axis/axis.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis.js diff --git a/src/legacy/ui/public/vislib/lib/axis/axis_config.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_config.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/axis/axis_config.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_config.js diff --git a/src/legacy/ui/public/vislib/lib/axis/axis_labels.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_labels.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/axis/axis_labels.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_labels.js diff --git a/src/legacy/ui/public/vislib/lib/axis/axis_scale.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_scale.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/axis/axis_scale.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_scale.js diff --git a/src/legacy/ui/public/vislib/lib/axis/axis_title.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_title.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/axis/axis_title.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_title.js diff --git a/src/legacy/ui/public/vislib/lib/axis/index.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/index.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/axis/index.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/index.js diff --git a/src/legacy/ui/public/vislib/lib/axis/scale_modes.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/scale_modes.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/axis/scale_modes.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/scale_modes.js diff --git a/src/legacy/ui/public/vislib/lib/axis/time_ticks.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/time_ticks.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/axis/time_ticks.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/time_ticks.js diff --git a/src/legacy/ui/public/vislib/lib/axis/time_ticks.test.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/time_ticks.test.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/axis/time_ticks.test.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/time_ticks.test.js diff --git a/src/legacy/ui/public/vislib/lib/chart_grid.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/chart_grid.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/chart_grid.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/chart_grid.js diff --git a/src/legacy/ui/public/vislib/lib/chart_title.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/chart_title.js similarity index 98% rename from src/legacy/ui/public/vislib/lib/chart_title.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/chart_title.js index f79d14a3deaa67..1c84f98614b05b 100644 --- a/src/legacy/ui/public/vislib/lib/chart_title.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/chart_title.js @@ -19,8 +19,9 @@ import d3 from 'd3'; import _ from 'lodash'; + import { ErrorHandler } from './_error_handler'; -import { Tooltip } from '../../vis/components/tooltip'; +import { Tooltip } from '../../legacy_imports'; export class ChartTitle extends ErrorHandler { constructor(visConfig) { diff --git a/src/legacy/ui/public/vislib/lib/data.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/data.js similarity index 98% rename from src/legacy/ui/public/vislib/lib/data.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/data.js index c10449c681a3cb..c7824c43eeec58 100644 --- a/src/legacy/ui/public/vislib/lib/data.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/data.js @@ -19,11 +19,11 @@ import d3 from 'd3'; import _ from 'lodash'; + import { injectZeros } from '../components/zero_injection/inject_zeros'; import { orderXValues } from '../components/zero_injection/ordered_x_keys'; import { labels } from '../components/labels/labels'; -import { vislibColor } from '../../vis/components/color/color'; -import { getFormat } from '../../visualize/loader/pipeline_helpers/utilities'; +import { getFormat } from '../../legacy_imports'; /** * Provides an API for pulling values off the data @@ -35,8 +35,9 @@ import { getFormat } from '../../visualize/loader/pipeline_helpers/utilities'; * @param attr {Object|*} Visualization options */ export class Data { - constructor(data, uiState) { + constructor(data, uiState, vislibColor) { this.uiState = uiState; + this.vislibColor = vislibColor; this.data = this.copyDataObj(data); this.type = this.getDataType(); this._cleanVisData(); @@ -472,7 +473,7 @@ export class Data { const defaultColors = this.uiState.get('vis.defaultColors'); const overwriteColors = this.uiState.get('vis.colors'); const colors = defaultColors ? _.defaults({}, overwriteColors, defaultColors) : overwriteColors; - return vislibColor(this.getLabels(), colors); + return this.vislibColor(this.getLabels(), colors); } /** @@ -482,7 +483,7 @@ export class Data { * @returns {Function} Performs lookup on string and returns hex color */ getPieColorFunc() { - return vislibColor( + return this.vislibColor( this.pieNames(this.getVisData()).map(function(d) { return d.label; }), diff --git a/src/legacy/ui/public/vislib/lib/dispatch.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/dispatch.js similarity index 92% rename from src/legacy/ui/public/vislib/lib/dispatch.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/dispatch.js index fb5cc127c27fd8..404f7ef82d97f9 100644 --- a/src/legacy/ui/public/vislib/lib/dispatch.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/dispatch.js @@ -20,10 +20,8 @@ import d3 from 'd3'; import { get } from 'lodash'; import $ from 'jquery'; -import { SimpleEmitter } from '../../utils/simple_emitter'; -import chrome from 'ui/chrome'; -const config = chrome.getUiSettingsClient(); +import { SimpleEmitter } from '../../legacy_imports'; /** * Handles event responses @@ -33,9 +31,10 @@ const config = chrome.getUiSettingsClient(); * @param handler {Object} Reference to Handler Class Object */ export class Dispatch extends SimpleEmitter { - constructor(handler) { + constructor(handler, uiSettings) { super(); this.handler = handler; + this.uiSettings = uiSettings; this._listeners = {}; } @@ -196,7 +195,7 @@ export class Dispatch extends SimpleEmitter { const addEvent = this.addEvent; const $el = this.handler.el; if (!this.handler.highlight) { - this.handler.highlight = self.highlight; + this.handler.highlight = self.getHighlighter(self.uiSettings); } function hover(d, i) { @@ -289,21 +288,23 @@ export class Dispatch extends SimpleEmitter { } /** - * Highlight the element that is under the cursor + * return function to Highlight the element that is under the cursor * by reducing the opacity of all the elements on the graph. - * @param element {d3.Selection} - * @method highlight + * @param uiSettings + * @method getHighlighter */ - highlight(element) { - const label = this.getAttribute('data-label'); - if (!label) return; - const dimming = config.get('visualization:dimmingOpacity'); - $(element) - .parent() - .find('[data-label]') - .css('opacity', 1) //Opacity 1 is needed to avoid the css application - .not((els, el) => String($(el).data('label')) === label) - .css('opacity', justifyOpacity(dimming)); + getHighlighter(uiSettings) { + return function highlight(element) { + const label = this.getAttribute('data-label'); + if (!label) return; + const dimming = uiSettings.get('visualization:dimmingOpacity'); + $(element) + .parent() + .find('[data-label]') + .css('opacity', 1) //Opacity 1 is needed to avoid the css application + .not((els, el) => String($(el).data('label')) === label) + .css('opacity', justifyOpacity(dimming)); + }; } /** diff --git a/src/legacy/ui/public/vislib/lib/handler.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/handler.js similarity index 96% rename from src/legacy/ui/public/vislib/lib/handler.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/handler.js index 6047faa0c6b15b..b887b61578cc41 100644 --- a/src/legacy/ui/public/vislib/lib/handler.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/handler.js @@ -20,15 +20,16 @@ import d3 from 'd3'; import _ from 'lodash'; import MarkdownIt from 'markdown-it'; + import { NoResults } from '../errors'; -import { Binder } from '../../binder'; import { Layout } from './layout/layout'; import { ChartTitle } from './chart_title'; import { Alerts } from './alerts'; import { Axis } from './axis/axis'; import { ChartGrid as Grid } from './chart_grid'; import { visTypes as chartTypes } from '../visualizations/vis_types'; -import { dispatchRenderComplete } from '../../../../../plugins/kibana_utils/public'; +import { Binder } from '../../legacy_imports'; +import { dispatchRenderComplete } from '../../../../../../plugins/kibana_utils/public'; const markdownIt = new MarkdownIt({ html: false, @@ -45,9 +46,10 @@ const markdownIt = new MarkdownIt({ * create the visualization */ export class Handler { - constructor(vis, visConfig) { + constructor(vis, visConfig, deps) { this.el = visConfig.get('el'); this.ChartClass = chartTypes[visConfig.get('type')]; + this.deps = deps; this.charts = []; this.vis = vis; @@ -151,7 +153,7 @@ export class Handler { let loadedCount = 0; const chartSelection = selection.selectAll('.chart'); chartSelection.each(function(chartData) { - const chart = new self.ChartClass(self, this, chartData); + const chart = new self.ChartClass(self, this, chartData, self.deps); self.vis.eventNames().forEach(function(event) { self.enable(event, chart); diff --git a/src/legacy/ui/public/vislib/lib/layout/_index.scss b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/_index.scss similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/_index.scss rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/_index.scss diff --git a/src/legacy/ui/public/vislib/lib/layout/_layout.scss b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/_layout.scss similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/_layout.scss rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/_layout.scss diff --git a/src/legacy/ui/public/vislib/lib/layout/index.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/index.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/index.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/index.js diff --git a/src/legacy/ui/public/vislib/lib/layout/layout.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/layout.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/layout.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/layout.js diff --git a/src/legacy/ui/public/vislib/lib/layout/layout_types.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/layout_types.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/layout_types.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/layout_types.js diff --git a/src/legacy/ui/public/vislib/lib/layout/splits/column_chart/chart_split.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/chart_split.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/splits/column_chart/chart_split.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/chart_split.js diff --git a/src/legacy/ui/public/vislib/lib/layout/splits/column_chart/chart_title_split.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/chart_title_split.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/splits/column_chart/chart_title_split.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/chart_title_split.js diff --git a/src/legacy/ui/public/vislib/lib/layout/splits/column_chart/x_axis_split.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/x_axis_split.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/splits/column_chart/x_axis_split.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/x_axis_split.js diff --git a/src/legacy/ui/public/vislib/lib/layout/splits/column_chart/y_axis_split.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/y_axis_split.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/splits/column_chart/y_axis_split.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/column_chart/y_axis_split.js diff --git a/src/legacy/ui/public/vislib/lib/layout/splits/gauge_chart/chart_split.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/gauge_chart/chart_split.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/splits/gauge_chart/chart_split.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/gauge_chart/chart_split.js diff --git a/src/legacy/ui/public/vislib/lib/layout/splits/gauge_chart/chart_title_split.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/gauge_chart/chart_title_split.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/splits/gauge_chart/chart_title_split.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/gauge_chart/chart_title_split.js diff --git a/src/legacy/ui/public/vislib/lib/layout/splits/pie_chart/chart_split.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/pie_chart/chart_split.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/splits/pie_chart/chart_split.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/pie_chart/chart_split.js diff --git a/src/legacy/ui/public/vislib/lib/layout/splits/pie_chart/chart_title_split.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/pie_chart/chart_title_split.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/splits/pie_chart/chart_title_split.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/splits/pie_chart/chart_title_split.js diff --git a/src/legacy/ui/public/vislib/lib/layout/types/column_layout.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/types/column_layout.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/types/column_layout.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/types/column_layout.js diff --git a/src/legacy/ui/public/vislib/lib/layout/types/gauge_layout.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/types/gauge_layout.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/types/gauge_layout.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/types/gauge_layout.js diff --git a/src/legacy/ui/public/vislib/lib/layout/types/pie_layout.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/types/pie_layout.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/layout/types/pie_layout.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/layout/types/pie_layout.js diff --git a/src/legacy/ui/public/vislib/lib/types/gauge.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/gauge.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/types/gauge.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/gauge.js diff --git a/src/legacy/ui/public/vislib/lib/types/index.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/index.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/types/index.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/index.js diff --git a/src/legacy/ui/public/vislib/lib/types/pie.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/pie.js similarity index 100% rename from src/legacy/ui/public/vislib/lib/types/pie.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/pie.js diff --git a/src/legacy/ui/public/vislib/lib/types/point_series.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/point_series.js similarity index 98% rename from src/legacy/ui/public/vislib/lib/types/point_series.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/point_series.js index 332f7408ebc667..eab3bc02f4eec9 100644 --- a/src/legacy/ui/public/vislib/lib/types/point_series.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/point_series.js @@ -202,7 +202,7 @@ export const vislibPointSeriesTypes = { 'Positive and negative values are not accurately represented by stacked ' + 'area charts. Either changing the chart mode to "overlap" or using a ' + 'bar chart is recommended.', - test: function(vis, data) { + test: function(_, data) { if (!data.shouldBeStacked() || data.maxNumberOfSeries() < 2) return; const hasPos = data.getYMax(data._getY) > 0; @@ -216,7 +216,7 @@ export const vislibPointSeriesTypes = { 'Parts of or the entire area chart might not be displayed due to null ' + 'values in the data. A line chart is recommended when displaying data ' + 'with null values.', - test: function(vis, data) { + test: function(_, data) { return data.hasNullValues(); }, }, @@ -229,7 +229,7 @@ export const vislibPointSeriesTypes = { const tooManySeries = defaults.charts.length && defaults.charts[0].series.length > cfg.heatmapMaxBuckets; if (hasCharts && tooManySeries) { - defaults.error = i18n.translate('common.ui.vislib.heatmap.maxBucketsText', { + defaults.error = i18n.translate('kbnVislibVisTypes.vislib.heatmap.maxBucketsText', { defaultMessage: 'There are too many series defined ({nr}). The configured maximum is {max}.', values: { diff --git a/src/legacy/ui/public/vislib/lib/types/point_series.test.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/point_series.test.js similarity index 98% rename from src/legacy/ui/public/vislib/lib/types/point_series.test.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/point_series.test.js index cada6127282d8e..38a6be548594f3 100644 --- a/src/legacy/ui/public/vislib/lib/types/point_series.test.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/types/point_series.test.js @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import stackedSeries from '../../../../../../fixtures/vislib/mock_data/date_histogram/_stacked_series'; +import stackedSeries from '../../__tests__/lib/fixtures/mock_data/date_histogram/_stacked_series'; import { vislibPointSeriesTypes } from './point_series'; describe('vislibPointSeriesTypes', () => { diff --git a/src/legacy/ui/public/vislib/lib/vis_config.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/vis_config.js similarity index 93% rename from src/legacy/ui/public/vislib/lib/vis_config.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/vis_config.js index 5f10e89474809c..091e6b1752d8dd 100644 --- a/src/legacy/ui/public/vislib/lib/vis_config.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/vis_config.js @@ -35,8 +35,8 @@ const DEFAULT_VIS_CONFIG = { }; export class VisConfig { - constructor(visConfigArgs, data, uiState, el) { - this.data = new Data(data, uiState); + constructor(visConfigArgs, data, uiState, el, vislibColor) { + this.data = new Data(data, uiState, vislibColor); const visType = visTypes[visConfigArgs.type]; const typeDefaults = visType(visConfigArgs, this.data); diff --git a/src/legacy/ui/public/vislib/partials/touchdown.tmpl.html b/src/legacy/core_plugins/vis_type_vislib/public/vislib/partials/touchdown.tmpl.html similarity index 100% rename from src/legacy/ui/public/vislib/partials/touchdown.tmpl.html rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/partials/touchdown.tmpl.html diff --git a/src/legacy/core_plugins/vis_type_vislib/public/vislib/vis.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/vis.js new file mode 100644 index 00000000000000..32afb6a008b618 --- /dev/null +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/vis.js @@ -0,0 +1,184 @@ +/* + * 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 _ from 'lodash'; +import d3 from 'd3'; +import { EventEmitter } from 'events'; + +import { VislibError } from './errors'; +import { VisConfig } from './lib/vis_config'; +import { Handler } from './lib/handler'; + +/** + * Creates the visualizations. + * + * @class Vis + * @constructor + * @param element {HTMLElement} jQuery selected HTML element + * @param config {Object} Parameters that define the chart type and chart options + */ +export class Vis extends EventEmitter { + constructor(element, visConfigArgs, deps) { + super(); + this.element = element.get ? element.get(0) : element; + this.visConfigArgs = _.cloneDeep(visConfigArgs); + this.visConfigArgs.dimmingOpacity = deps.uiSettings.get('visualization:dimmingOpacity'); + this.visConfigArgs.heatmapMaxBuckets = deps.uiSettings.get('visualization:heatmap:maxBuckets'); + this.deps = deps; + } + + hasLegend() { + return this.visConfigArgs.addLegend; + } + + initVisConfig(data, uiState) { + this.data = data; + this.uiState = uiState; + this.visConfig = new VisConfig( + this.visConfigArgs, + this.data, + this.uiState, + this.element, + this.deps.vislibColor + ); + } + + /** + * Renders the visualization + * + * @method render + * @param data {Object} Elasticsearch query results + */ + render(data, uiState) { + if (!data) { + throw new Error('No valid data!'); + } + + if (this.handler) { + this.data = null; + this._runOnHandler('destroy'); + } + + this.initVisConfig(data, uiState); + + this.handler = new Handler(this, this.visConfig, this.deps); + this._runOnHandler('render'); + } + + getLegendLabels() { + return this.visConfig ? this.visConfig.get('legend.labels', null) : null; + } + + getLegendColors() { + return this.visConfig ? this.visConfig.get('legend.colors', null) : null; + } + + _runOnHandler(method) { + try { + this.handler[method](); + } catch (error) { + if (error instanceof VislibError) { + error.displayToScreen(this.handler); + } else { + throw error; + } + } + } + + /** + * Destroys the visualization + * Removes chart and all elements associated with it. + * Removes chart and all elements associated with it. + * Remove event listeners and pass destroy call down to owned objects. + * + * @method destroy + */ + destroy() { + const selection = d3.select(this.element).select('.visWrapper'); + + if (this.handler) this._runOnHandler('destroy'); + + selection.remove(); + } + + /** + * Sets attributes on the visualization + * + * @method set + * @param name {String} An attribute name + * @param val {*} Value to which the attribute name is set + */ + set(name, val) { + this.visConfigArgs[name] = val; + this.render(this.data, this.uiState); + } + + /** + * Gets attributes from the visualization + * + * @method get + * @param name {String} An attribute name + * @returns {*} The value of the attribute name + */ + get(name) { + return this.visConfig.get(name); + } + + /** + * Turns on event listeners. + * + * @param event {String} + * @param listener{Function} + * @returns {*} + */ + on(event, listener) { + const first = this.listenerCount(event) === 0; + const ret = EventEmitter.prototype.on.call(this, event, listener); + const added = this.listenerCount(event) > 0; + + // if this is the first listener added for the event + // enable the event in the handler + if (first && added && this.handler) this.handler.enable(event); + + return ret; + } + + /** + * Turns off event listeners. + * + * @param event {String} + * @param listener{Function} + * @returns {*} + */ + off(event, listener) { + const last = this.listenerCount(event) === 1; + const ret = EventEmitter.prototype.off.call(this, event, listener); + const removed = this.listenerCount(event) === 0; + + // Once all listeners are removed, disable the events in the handler + if (last && removed && this.handler) this.handler.disable(event); + return ret; + } + + removeAllListeners(event) { + const ret = EventEmitter.prototype.removeAllListeners.call(this, event); + this.handler.disable(event); + return ret; + } +} diff --git a/src/legacy/ui/public/vislib/vislib.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/vislib.js similarity index 82% rename from src/legacy/ui/public/vislib/vislib.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/vislib.js index 847deb8273a736..024dee60ef2bf4 100644 --- a/src/legacy/ui/public/vislib/vislib.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/vislib.js @@ -23,8 +23,7 @@ import './lib/types'; import './lib/layout/layout_types'; import './lib/data'; import './visualizations/vis_types'; -import { mappedColors } from '../vis/components/color/mapped_colors'; -import { VislibVisProvider } from './vis'; +import { Vis } from './vis'; // prefetched for faster optimization runs // end prefetching @@ -36,11 +35,9 @@ import { VislibVisProvider } from './vis'; * @main vislib * @return {Object} Contains the version number and the Vis Class for creating visualizations */ -export function VislibProvider(Private, $rootScope) { - $rootScope.$on('$routeChangeStart', () => mappedColors.purge()); - +export function VislibProvider() { return { version: '0.0.0', - Vis: Private(VislibVisProvider), + Vis, }; } diff --git a/src/legacy/ui/public/vislib/visualizations/_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/_chart.js similarity index 81% rename from src/legacy/ui/public/vislib/visualizations/_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/_chart.js index 2fbd96d6a070aa..ac6e8130a846ad 100644 --- a/src/legacy/ui/public/vislib/visualizations/_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/_chart.js @@ -19,12 +19,10 @@ import d3 from 'd3'; import _ from 'lodash'; + import { dataLabel } from '../lib/_data_label'; import { Dispatch } from '../lib/dispatch'; -import { Tooltip } from '../../vis/components/tooltip'; -import { getFormat } from '../../visualize/loader/pipeline_helpers/utilities'; -import { getHierarchicalTooltipFormatter } from '../../vis/components/tooltip/_hierarchical_tooltip_formatter'; -import { getPointSeriesTooltipFormatter } from '../../vis/components/tooltip/_pointseries_tooltip_formatter'; +import { Tooltip, getFormat } from '../../legacy_imports'; /** * The Base Class for all visualizations. @@ -36,26 +34,26 @@ import { getPointSeriesTooltipFormatter } from '../../vis/components/tooltip/_po * @param chartData {Object} Elasticsearch query results for this specific chart */ export class Chart { - constructor(handler, el, chartData) { + constructor(handler, element, chartData, deps) { this.handler = handler; - this.chartEl = el; + this.chartEl = element; this.chartData = chartData; this.tooltips = []; - const events = (this.events = new Dispatch(handler)); + const events = (this.events = new Dispatch(handler, deps.uiSettings)); const fieldFormatter = getFormat(this.handler.data.get('tooltipFormatter')); const tooltipFormatterProvider = this.handler.visConfig.get('type') === 'pie' - ? getHierarchicalTooltipFormatter() - : getPointSeriesTooltipFormatter(); + ? deps.getHierarchicalTooltipFormatter() + : deps.getPointSeriesTooltipFormatter(); const tooltipFormatter = tooltipFormatterProvider(fieldFormatter); if (this.handler.visConfig && this.handler.visConfig.get('addTooltip', false)) { - const $el = this.handler.el; + const element = this.handler.el; // Add tooltip - this.tooltip = new Tooltip('chart', $el, tooltipFormatter, events); + this.tooltip = new Tooltip('chart', element, tooltipFormatter, events); this.tooltips.push(this.tooltip); } diff --git a/src/legacy/ui/public/vislib/visualizations/gauge_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauge_chart.js similarity index 97% rename from src/legacy/ui/public/vislib/visualizations/gauge_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauge_chart.js index c67b1b8881d694..729c6640326030 100644 --- a/src/legacy/ui/public/vislib/visualizations/gauge_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauge_chart.js @@ -22,8 +22,8 @@ import { Chart } from './_chart'; import { gaugeTypes } from './gauges/gauge_types'; export class GaugeChart extends Chart { - constructor(handler, chartEl, chartData) { - super(handler, chartEl, chartData); + constructor(handler, chartEl, chartData, deps) { + super(handler, chartEl, chartData, deps); this.gaugeConfig = handler.visConfig.get('gauge', {}); this.gauge = new gaugeTypes[this.gaugeConfig.type](this); } diff --git a/src/legacy/ui/public/vislib/visualizations/gauges/_index.scss b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/_index.scss similarity index 100% rename from src/legacy/ui/public/vislib/visualizations/gauges/_index.scss rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/_index.scss diff --git a/src/legacy/ui/public/vislib/visualizations/gauges/_meter.scss b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/_meter.scss similarity index 100% rename from src/legacy/ui/public/vislib/visualizations/gauges/_meter.scss rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/_meter.scss diff --git a/src/legacy/ui/public/vislib/visualizations/gauges/gauge_types.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/gauge_types.js similarity index 100% rename from src/legacy/ui/public/vislib/visualizations/gauges/gauge_types.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/gauge_types.js diff --git a/src/legacy/ui/public/vislib/visualizations/gauges/meter.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/meter.js similarity index 99% rename from src/legacy/ui/public/vislib/visualizations/gauges/meter.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/meter.js index 25da3ba9571816..f5199146622517 100644 --- a/src/legacy/ui/public/vislib/visualizations/gauges/meter.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/gauges/meter.js @@ -19,7 +19,8 @@ import d3 from 'd3'; import _ from 'lodash'; -import { getHeatmapColors } from '../../components/color/heatmap_color'; + +import { getHeatmapColors } from '../../../legacy_imports'; const arcAngles = { angleFactor: 0.75, diff --git a/src/legacy/ui/public/vislib/visualizations/pie_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.js similarity index 99% rename from src/legacy/ui/public/vislib/visualizations/pie_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.js index 6d51c69892bc09..a2cbf0fe295ce9 100644 --- a/src/legacy/ui/public/vislib/visualizations/pie_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.js @@ -42,8 +42,8 @@ const defaults = { * @param chartData {Object} Elasticsearch query results for this specific chart */ export class PieChart extends Chart { - constructor(handler, chartEl, chartData) { - super(handler, chartEl, chartData); + constructor(handler, chartEl, chartData, deps) { + super(handler, chartEl, chartData, deps); const charts = this.handler.data.getVisData(); this._validatePieData(charts); this._attr = _.defaults(handler.visConfig.get('chart', {}), defaults); diff --git a/src/legacy/ui/public/vislib/visualizations/point_series.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series.js similarity index 97% rename from src/legacy/ui/public/vislib/visualizations/point_series.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series.js index 84dbea2ccc823f..c838c51d34bf5a 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series.js @@ -20,7 +20,8 @@ import d3 from 'd3'; import _ from 'lodash'; import $ from 'jquery'; -import { Tooltip } from '../../vis/components/tooltip'; + +import { Tooltip } from '../../legacy_imports'; import { Chart } from './_chart'; import { TimeMarker } from './time_marker'; import { seriesTypes } from './point_series/series_types'; @@ -39,9 +40,10 @@ const touchdownTmpl = _.template(touchdownTmplHtml); * @param chartData {Object} Elasticsearch query results for this specific chart */ export class PointSeries extends Chart { - constructor(handler, chartEl, chartData) { - super(handler, chartEl, chartData); + constructor(handler, chartEl, chartData, deps) { + super(handler, chartEl, chartData, deps); + this.deps = deps; this.handler = handler; this.chartData = chartData; this.chartEl = chartEl; @@ -255,7 +257,7 @@ export class PointSeries extends Chart { if (!seriArgs.show) return; const SeriClass = seriTypes[seriArgs.type || self.handler.visConfig.get('chart.type')] || seriTypes.line; - const series = new SeriClass(self.handler, svg, data.series[i], seriArgs); + const series = new SeriClass(self.handler, svg, data.series[i], seriArgs, this.deps); series.events = self.events; svg.call(series.draw()); self.series.push(series); diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/_index.scss b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/_index.scss similarity index 100% rename from src/legacy/ui/public/vislib/visualizations/point_series/_index.scss rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/_index.scss diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/_labels.scss b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/_labels.scss similarity index 100% rename from src/legacy/ui/public/vislib/visualizations/point_series/_labels.scss rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/_labels.scss diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/_point_series.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/_point_series.js similarity index 100% rename from src/legacy/ui/public/vislib/visualizations/point_series/_point_series.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/_point_series.js diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/area_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.js similarity index 98% rename from src/legacy/ui/public/vislib/visualizations/point_series/area_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.js index 08147bacdcc981..274ae82271e965 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series/area_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.js @@ -43,8 +43,8 @@ const defaults = { * chart */ export class AreaChart extends PointSeries { - constructor(handler, chartEl, chartData, seriesConfigArgs) { - super(handler, chartEl, chartData, seriesConfigArgs); + constructor(handler, chartEl, chartData, seriesConfigArgs, deps) { + super(handler, chartEl, chartData, seriesConfigArgs, deps); this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults); this.isOverlapping = this.seriesConfig.mode !== 'stacked'; diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.js similarity index 98% rename from src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.js index 1f18141d862999..4b422d9b1419fc 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.js @@ -57,8 +57,8 @@ function datumWidth(defaultWidth, datum, nextDatum, scale, gutterWidth, groupCou * @param chartData {Object} Elasticsearch query results for this specific chart */ export class ColumnChart extends PointSeries { - constructor(handler, chartEl, chartData, seriesConfigArgs) { - super(handler, chartEl, chartData, seriesConfigArgs); + constructor(handler, chartEl, chartData, seriesConfigArgs, deps) { + super(handler, chartEl, chartData, seriesConfigArgs, deps); this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults); this.labelOptions = _.defaults(handler.visConfig.get('labels', {}), defaults.showLabel); } diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/heatmap_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/heatmap_chart.js similarity index 98% rename from src/legacy/ui/public/vislib/visualizations/point_series/heatmap_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/heatmap_chart.js index 1bc33bd5bbadef..948cf98a643525 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series/heatmap_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/heatmap_chart.js @@ -19,10 +19,12 @@ import _ from 'lodash'; import moment from 'moment'; -import { PointSeries } from './_point_series'; -import { getHeatmapColors } from '../../components/color/heatmap_color'; + import { isColorDark } from '@elastic/eui'; +import { PointSeries } from './_point_series'; +import { getHeatmapColors } from '../../../legacy_imports'; + const defaults = { color: undefined, // todo fillColor: undefined, // todo @@ -38,8 +40,8 @@ const defaults = { * @param chartData {Object} Elasticsearch query results for this specific chart */ export class HeatmapChart extends PointSeries { - constructor(handler, chartEl, chartData, seriesConfigArgs) { - super(handler, chartEl, chartData, seriesConfigArgs); + constructor(handler, chartEl, chartData, seriesConfigArgs, deps) { + super(handler, chartEl, chartData, seriesConfigArgs, deps); this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults); this.handler.visConfig.set('legend', { diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/line_chart.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.js similarity index 98% rename from src/legacy/ui/public/vislib/visualizations/point_series/line_chart.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.js index 57090b5424f93e..0038b4401b3024 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series/line_chart.js +++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.js @@ -42,8 +42,8 @@ const defaults = { * @param chartData {Object} Elasticsearch query results for this specific chart */ export class LineChart extends PointSeries { - constructor(handler, chartEl, chartData, seriesConfigArgs) { - super(handler, chartEl, chartData, seriesConfigArgs); + constructor(handler, chartEl, chartData, seriesConfigArgs, deps) { + super(handler, chartEl, chartData, seriesConfigArgs, deps); this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults); } diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/series_types.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/series_types.js similarity index 100% rename from src/legacy/ui/public/vislib/visualizations/point_series/series_types.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/point_series/series_types.js diff --git a/src/legacy/ui/public/vislib/visualizations/time_marker.d.ts b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/time_marker.d.ts similarity index 100% rename from src/legacy/ui/public/vislib/visualizations/time_marker.d.ts rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/time_marker.d.ts diff --git a/src/legacy/ui/public/vislib/visualizations/time_marker.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/time_marker.js similarity index 100% rename from src/legacy/ui/public/vislib/visualizations/time_marker.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/time_marker.js diff --git a/src/legacy/ui/public/vislib/visualizations/vis_types.js b/src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/vis_types.js similarity index 100% rename from src/legacy/ui/public/vislib/visualizations/vis_types.js rename to src/legacy/core_plugins/vis_type_vislib/public/vislib/visualizations/vis_types.js diff --git a/src/legacy/core_plugins/visualizations/index.ts b/src/legacy/core_plugins/visualizations/index.ts index cf2d123d8f1841..a2779cfe4346df 100644 --- a/src/legacy/core_plugins/visualizations/index.ts +++ b/src/legacy/core_plugins/visualizations/index.ts @@ -26,7 +26,7 @@ export const visualizations: LegacyPluginInitializer = kibana => publicDir: resolve(__dirname, 'public'), require: [], uiExports: { - interpreter: ['plugins/visualizations/expressions/boot'], + styleSheetPaths: resolve(__dirname, 'public/index.scss'), }, }); diff --git a/src/legacy/core_plugins/kibana/public/visualize_embeddable/_embeddables.scss b/src/legacy/core_plugins/visualizations/public/embeddable/_embeddables.scss similarity index 100% rename from src/legacy/core_plugins/kibana/public/visualize_embeddable/_embeddables.scss rename to src/legacy/core_plugins/visualizations/public/embeddable/_embeddables.scss diff --git a/src/legacy/core_plugins/kibana/public/visualize_embeddable/_index.scss b/src/legacy/core_plugins/visualizations/public/embeddable/_index.scss similarity index 100% rename from src/legacy/core_plugins/kibana/public/visualize_embeddable/_index.scss rename to src/legacy/core_plugins/visualizations/public/embeddable/_index.scss diff --git a/src/legacy/core_plugins/kibana/public/visualize_embeddable/_visualize_lab_disabled.scss b/src/legacy/core_plugins/visualizations/public/embeddable/_visualize_lab_disabled.scss similarity index 100% rename from src/legacy/core_plugins/kibana/public/visualize_embeddable/_visualize_lab_disabled.scss rename to src/legacy/core_plugins/visualizations/public/embeddable/_visualize_lab_disabled.scss diff --git a/src/legacy/core_plugins/kibana/public/visualize_embeddable/constants.ts b/src/legacy/core_plugins/visualizations/public/embeddable/constants.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/visualize_embeddable/constants.ts rename to src/legacy/core_plugins/visualizations/public/embeddable/constants.ts diff --git a/src/legacy/core_plugins/kibana/public/visualize_embeddable/disabled_lab_embeddable.tsx b/src/legacy/core_plugins/visualizations/public/embeddable/disabled_lab_embeddable.tsx similarity index 100% rename from src/legacy/core_plugins/kibana/public/visualize_embeddable/disabled_lab_embeddable.tsx rename to src/legacy/core_plugins/visualizations/public/embeddable/disabled_lab_embeddable.tsx diff --git a/src/legacy/core_plugins/kibana/public/visualize_embeddable/disabled_lab_visualization.tsx b/src/legacy/core_plugins/visualizations/public/embeddable/disabled_lab_visualization.tsx similarity index 92% rename from src/legacy/core_plugins/kibana/public/visualize_embeddable/disabled_lab_visualization.tsx rename to src/legacy/core_plugins/visualizations/public/embeddable/disabled_lab_visualization.tsx index 52fa937bbe0470..3d2af2c591a3ce 100644 --- a/src/legacy/core_plugins/kibana/public/visualize_embeddable/disabled_lab_visualization.tsx +++ b/src/legacy/core_plugins/visualizations/public/embeddable/disabled_lab_visualization.tsx @@ -29,14 +29,14 @@ export function DisabledLabVisualization({ title }: { title: string }) { />
{title} }} />
diff --git a/src/legacy/core_plugins/kibana/public/visualize_embeddable/get_index_pattern.ts b/src/legacy/core_plugins/visualizations/public/embeddable/get_index_pattern.ts similarity index 89% rename from src/legacy/core_plugins/kibana/public/visualize_embeddable/get_index_pattern.ts rename to src/legacy/core_plugins/visualizations/public/embeddable/get_index_pattern.ts index 36efc4b86d0d31..25aa77ec735792 100644 --- a/src/legacy/core_plugins/kibana/public/visualize_embeddable/get_index_pattern.ts +++ b/src/legacy/core_plugins/visualizations/public/embeddable/get_index_pattern.ts @@ -17,10 +17,9 @@ * under the License. */ -import { npStart } from 'ui/new_platform'; - import { VisSavedObject } from './visualize_embeddable'; import { indexPatterns, IIndexPattern } from '../../../../../plugins/data/public'; +import { getUISettings, getSavedObjects } from '../np_ready/public/services'; export async function getIndexPattern( savedVis: VisSavedObject @@ -29,8 +28,8 @@ export async function getIndexPattern( return savedVis.vis.indexPattern; } - const savedObjectsClient = npStart.core.savedObjects.client; - const defaultIndex = npStart.core.uiSettings.get('defaultIndex'); + const savedObjectsClient = getSavedObjects().client; + const defaultIndex = getUISettings().get('defaultIndex'); if (savedVis.vis.params.index_pattern) { const indexPatternObjects = await savedObjectsClient.find({ diff --git a/src/legacy/core_plugins/kibana/public/visualize_embeddable/index.ts b/src/legacy/core_plugins/visualizations/public/embeddable/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/visualize_embeddable/index.ts rename to src/legacy/core_plugins/visualizations/public/embeddable/index.ts diff --git a/src/legacy/core_plugins/kibana/public/visualize_embeddable/visualize_embeddable.ts b/src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable.ts similarity index 99% rename from src/legacy/core_plugins/kibana/public/visualize_embeddable/visualize_embeddable.ts rename to src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable.ts index b7a3a0f000d720..c1b049ab5e969f 100644 --- a/src/legacy/core_plugins/kibana/public/visualize_embeddable/visualize_embeddable.ts +++ b/src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable.ts @@ -47,7 +47,7 @@ import { APPLY_FILTER_TRIGGER, } from '../../../../../plugins/embeddable/public'; import { dispatchRenderComplete } from '../../../../../plugins/kibana_utils/public'; -import { SavedSearch } from '../discover/np_ready/types'; +import { SavedSearch } from '../../../kibana/public/discover/np_ready/types'; const getKeys = (o: T): Array => Object.keys(o) as Array; diff --git a/src/legacy/core_plugins/kibana/public/visualize_embeddable/visualize_embeddable_factory.tsx b/src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx similarity index 67% rename from src/legacy/core_plugins/kibana/public/visualize_embeddable/visualize_embeddable_factory.tsx rename to src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx index ebb9ce2cfdf6b2..3f29f97afee489 100644 --- a/src/legacy/core_plugins/kibana/public/visualize_embeddable/visualize_embeddable_factory.tsx +++ b/src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx @@ -17,26 +17,9 @@ * under the License. */ -import 'uiExports/contextMenuActions'; -import 'uiExports/devTools'; -import 'uiExports/docViews'; -import 'uiExports/embeddableActions'; -import 'uiExports/fieldFormatEditors'; -import 'uiExports/fieldFormats'; -import 'uiExports/indexManagement'; -import 'uiExports/inspectorViews'; -import 'uiExports/savedObjectTypes'; -import 'uiExports/search'; -import 'uiExports/shareContextMenuExtensions'; -import 'uiExports/visTypes'; -import 'uiExports/visualize'; - import { i18n } from '@kbn/i18n'; import chrome from 'ui/chrome'; -import { npSetup, npStart } from 'ui/new_platform'; - -import { Legacy } from 'kibana'; import { SavedObjectAttributes } from 'kibana/server'; import { @@ -45,9 +28,8 @@ import { Container, EmbeddableOutput, } from '../../../../../plugins/embeddable/public'; -import { start as visualizations } from '../../../visualizations/public/np_ready/public/legacy'; -import { showNewVisModal } from '../visualize'; -import { SavedVisualizations } from '../visualize/np_ready/types'; +import { showNewVisModal } from '../../../kibana/public/visualize/np_ready/wizard/show_new_vis'; +import { SavedVisualizations } from '../../../kibana/public/visualize/np_ready/types'; import { DisabledLabEmbeddable } from './disabled_lab_embeddable'; import { getIndexPattern } from './get_index_pattern'; import { @@ -57,7 +39,15 @@ import { VisSavedObject, } from './visualize_embeddable'; import { VISUALIZE_EMBEDDABLE_TYPE } from './constants'; -import { TypesStart } from '../../../visualizations/public/np_ready/public/types'; + +import { + getUISettings, + getCapabilities, + getHttp, + getTypes, + getSavedObjects, + getUsageCollector, +} from '../np_ready/public/services'; interface VisualizationAttributes extends SavedObjectAttributes { visState: string; @@ -70,60 +60,48 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory< VisualizationAttributes > { public readonly type = VISUALIZE_EMBEDDABLE_TYPE; - private readonly visTypes: TypesStart; static async createVisualizeEmbeddableFactory(): Promise { - return new VisualizeEmbeddableFactory(visualizations.types); + return new VisualizeEmbeddableFactory(); } - constructor(visTypes: TypesStart) { + constructor() { super({ savedObjectMetaData: { - name: i18n.translate('kbn.visualize.savedObjectName', { defaultMessage: 'Visualization' }), + name: i18n.translate('visualizations.savedObjectName', { defaultMessage: 'Visualization' }), includeFields: ['visState'], type: 'visualization', getIconForSavedObject: savedObject => { - if (!visTypes) { - return 'visualizeApp'; - } return ( - visTypes.get(JSON.parse(savedObject.attributes.visState).type).icon || 'visualizeApp' + getTypes().get(JSON.parse(savedObject.attributes.visState).type).icon || 'visualizeApp' ); }, getTooltipForSavedObject: savedObject => { - if (!visTypes) { - return ''; - } return `${savedObject.attributes.title} (${ - visTypes.get(JSON.parse(savedObject.attributes.visState).type).title + getTypes().get(JSON.parse(savedObject.attributes.visState).type).title })`; }, showSavedObject: savedObject => { - if (!visTypes) { - return false; - } const typeName: string = JSON.parse(savedObject.attributes.visState).type; - const visType = visTypes.get(typeName); + const visType = getTypes().get(typeName); if (!visType) { return false; } - if (npStart.core.uiSettings.get('visualize:enableLabs')) { + if (getUISettings().get('visualize:enableLabs')) { return true; } return visType.stage !== 'experimental'; }, }, }); - - this.visTypes = visTypes; } public isEditable() { - return npStart.core.application.capabilities.visualize.save as boolean; + return getCapabilities().visualize.save as boolean; } public getDisplayName() { - return i18n.translate('kbn.embeddable.visualizations.displayName', { + return i18n.translate('visualizations.displayName', { defaultMessage: 'visualization', }); } @@ -134,16 +112,15 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory< parent?: Container ): Promise { const $injector = await chrome.dangerouslyGetActiveInjector(); - const config = $injector.get('config'); const savedVisualizations = $injector.get('savedVisualizations'); try { const visId = savedObject.id as string; const editUrl = visId - ? npStart.core.http.basePath.prepend(`/app/kibana${savedVisualizations.urlFor(visId)}`) + ? getHttp().basePath.prepend(`/app/kibana${savedVisualizations.urlFor(visId)}`) : ''; - const isLabsEnabled = config.get('visualize:enableLabs'); + const isLabsEnabled = getUISettings().get('visualize:enableLabs'); if (!isLabsEnabled && savedObject.vis.type.stage === 'experimental') { return new DisabledLabEmbeddable(savedObject.title, input); @@ -191,18 +168,16 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory< public async create() { // TODO: This is a bit of a hack to preserve the original functionality. Ideally we will clean this up // to allow for in place creation of visualizations without having to navigate away to a new URL. - if (this.visTypes) { - showNewVisModal( - this.visTypes, - { - editorParams: ['addToDashboard'], - }, - npStart.core.http.basePath.prepend, - npStart.core.uiSettings, - npStart.core.savedObjects, - npSetup.plugins.usageCollection - ); - } + showNewVisModal( + getTypes(), + { + editorParams: ['addToDashboard'], + }, + getHttp().basePath.prepend, + getUISettings(), + getSavedObjects(), + getUsageCollector() + ); return undefined; } } diff --git a/src/legacy/ui/public/visualize/loader/vis.js b/src/legacy/core_plugins/visualizations/public/expressions/vis.js similarity index 93% rename from src/legacy/ui/public/visualize/loader/vis.js rename to src/legacy/core_plugins/visualizations/public/expressions/vis.js index ad946aa1212ff3..cbadfd9da37888 100644 --- a/src/legacy/ui/public/visualize/loader/vis.js +++ b/src/legacy/core_plugins/visualizations/public/expressions/vis.js @@ -29,11 +29,8 @@ import { EventEmitter } from 'events'; import _ from 'lodash'; -import { PersistedState } from '../../persisted_state'; - -import { start as visualizations } from '../../../../core_plugins/visualizations/public/np_ready/public/legacy'; - -const visTypes = visualizations.types; +import { PersistedState } from '../../../../ui/public/persisted_state'; +import { getTypes } from '../np_ready/public/services'; export class Vis extends EventEmitter { constructor(visState = { type: 'histogram' }) { @@ -64,7 +61,7 @@ export class Vis extends EventEmitter { this.title = state.title || ''; const type = state.type || this.type; if (_.isString(type)) { - this.type = visTypes.get(type); + this.type = getTypes().get(type); if (!this.type) { throw new Error(`Invalid type "${type}"`); } diff --git a/src/legacy/core_plugins/visualizations/public/expressions/visualization_function.ts b/src/legacy/core_plugins/visualizations/public/expressions/visualization_function.ts index ddf1b11945422c..37b437c1c2dd6d 100644 --- a/src/legacy/core_plugins/visualizations/public/expressions/visualization_function.ts +++ b/src/legacy/core_plugins/visualizations/public/expressions/visualization_function.ts @@ -25,7 +25,7 @@ import { PersistedState } from 'ui/persisted_state'; import { VisResponseValue } from 'src/plugins/visualizations/public'; import { ExpressionFunction, Render } from 'src/plugins/expressions/public'; import { npStart } from 'ui/new_platform'; -import { start as visualizations } from '../np_ready/public/legacy'; +import { getTypes } from '../np_ready/public/services'; interface Arguments { index?: string | null; @@ -97,7 +97,7 @@ export const visualization = (): ExpressionFunctionVisualization => ({ const visConfigParams = args.visConfig ? JSON.parse(args.visConfig) : {}; const schemas = args.schemas ? JSON.parse(args.schemas) : {}; - const visType = visualizations.types.get(args.type || 'histogram') as any; + const visType = getTypes().get(args.type || 'histogram') as any; const indexPattern = args.index ? await indexPatterns.get(args.index) : null; const uiStateParams = args.uiState ? JSON.parse(args.uiState) : {}; diff --git a/src/legacy/core_plugins/visualizations/public/expressions/visualization_renderer.tsx b/src/legacy/core_plugins/visualizations/public/expressions/visualization_renderer.tsx index 40648a137c1415..5f894c7eb60e33 100644 --- a/src/legacy/core_plugins/visualizations/public/expressions/visualization_renderer.tsx +++ b/src/legacy/core_plugins/visualizations/public/expressions/visualization_renderer.tsx @@ -21,8 +21,8 @@ import chrome from 'ui/chrome'; import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; // @ts-ignore -import { Vis } from '../../../../ui/public/visualize/loader/vis'; -import { Visualization } from '../../../visualizations/public/np_ready/public/components'; +import { Vis } from './vis'; +import { Visualization } from '../np_ready/public/components'; export const visualization = () => ({ name: 'visualization', diff --git a/src/legacy/core_plugins/visualizations/public/index.scss b/src/legacy/core_plugins/visualizations/public/index.scss new file mode 100644 index 00000000000000..957d06be4daf0d --- /dev/null +++ b/src/legacy/core_plugins/visualizations/public/index.scss @@ -0,0 +1,3 @@ +@import 'src/legacy/ui/public/styles/styling_constants'; + +@import './embeddable/_index'; diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy.ts index 1e86aa64d1fa85..41b23b276e88d7 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy.ts @@ -27,5 +27,5 @@ import { plugin } from '.'; const pluginInstance = plugin({} as PluginInitializerContext); -export const setup = pluginInstance.setup(npSetup.core); -export const start = pluginInstance.start(npStart.core); +export const setup = pluginInstance.setup(npSetup.core, npSetup.plugins); +export const start = pluginInstance.start(npStart.core, npStart.plugins); 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 88c5768a0b4e43..2fa85d86a794ea 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 @@ -28,6 +28,10 @@ import { PluginInitializerContext } from 'src/core/public'; import { VisualizationsSetup, VisualizationsStart } from './'; import { VisualizationsPlugin } from './plugin'; import { coreMock } from '../../../../../../core/public/mocks'; +import { embeddablePluginMock } from '../../../../../../plugins/embeddable/public/mocks'; +import { expressionsPluginMock } from '../../../../../../plugins/expressions/public/mocks'; +import { dataPluginMock } from '../../../../../../plugins/data/public/mocks'; +import { usageCollectionPluginMock } from '../../../../../../plugins/usage_collection/public/mocks'; const createSetupContract = (): VisualizationsSetup => ({ types: { @@ -49,8 +53,15 @@ const createStartContract = (): VisualizationsStart => ({ const createInstance = async () => { const plugin = new VisualizationsPlugin({} as PluginInitializerContext); - const setup = plugin.setup(coreMock.createSetup()); - const doStart = () => plugin.start(coreMock.createStart()); + const setup = plugin.setup(coreMock.createSetup(), { + expressions: expressionsPluginMock.createSetupContract(), + embeddable: embeddablePluginMock.createStartContract(), + usageCollection: usageCollectionPluginMock.createSetupContract(), + }); + const doStart = () => + plugin.start(coreMock.createStart(), { + data: dataPluginMock.createStartContract(), + }); return { plugin, 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 ccf6aaf152ea4b..7584556324e8bf 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 @@ -18,8 +18,24 @@ */ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public'; import { TypesService, TypesSetup, TypesStart } from './types'; -import { setUISettings, setTypes, setI18n } from './services'; - +import { + setUISettings, + setTypes, + setI18n, + setCapabilities, + setHttp, + setIndexPatterns, + setSavedObjects, + setUsageCollector, +} from './services'; +import { VisualizeEmbeddableFactory } from '../../embeddable/visualize_embeddable_factory'; +import { VISUALIZE_EMBEDDABLE_TYPE } from '../../embeddable'; +import { ExpressionsSetup } from '../../../../../../plugins/expressions/public'; +import { IEmbeddableSetup } from '../../../../../../plugins/embeddable/public'; +import { visualization as visualizationFunction } from '../../expressions/visualization_function'; +import { visualization as visualizationRenderer } from '../../expressions/visualization_renderer'; +import { DataPublicPluginStart } from '../../../../../../plugins/data/public'; +import { UsageCollectionSetup } from '../../../../../../plugins/usage_collection/public'; /** * Interface for this plugin's returned setup/start contracts. * @@ -34,6 +50,16 @@ export interface VisualizationsStart { types: TypesStart; } +export interface VisualizationsSetupDeps { + expressions: ExpressionsSetup; + embeddable: IEmbeddableSetup; + usageCollection: UsageCollectionSetup; +} + +export interface VisualizationsStartDeps { + data: DataPublicPluginStart; +} + /** * Visualizations Plugin - public * @@ -42,22 +68,45 @@ export interface VisualizationsStart { * * @internal */ -export class VisualizationsPlugin implements Plugin { +export class VisualizationsPlugin + implements + Plugin< + VisualizationsSetup, + VisualizationsStart, + VisualizationsSetupDeps, + VisualizationsStartDeps + > { private readonly types: TypesService = new TypesService(); constructor(initializerContext: PluginInitializerContext) {} - public setup(core: CoreSetup) { + public setup( + core: CoreSetup, + { expressions, embeddable, usageCollection }: VisualizationsSetupDeps + ) { setUISettings(core.uiSettings); + setUsageCollector(usageCollection); + + expressions.registerFunction(visualizationFunction); + expressions.registerRenderer(visualizationRenderer); + + const embeddableFactory = new VisualizeEmbeddableFactory(); + embeddable.registerEmbeddableFactory(VISUALIZE_EMBEDDABLE_TYPE, embeddableFactory); + return { types: this.types.setup(), }; } - public start(core: CoreStart) { - setI18n(core.i18n); + public start(core: CoreStart, { data }: VisualizationsStartDeps) { const types = this.types.start(); + setI18n(core.i18n); setTypes(types); + setCapabilities(core.application.capabilities); + setHttp(core.http); + setSavedObjects(core.savedObjects); + setIndexPatterns(data.indexPatterns); + return { types, }; diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/services.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/services.ts index 434612d11b28aa..4b426fee6c7daa 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/services.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/services.ts @@ -17,12 +17,36 @@ * under the License. */ -import { I18nStart, IUiSettingsClient } from 'src/core/public'; +import { + Capabilities, + HttpStart, + I18nStart, + IUiSettingsClient, + SavedObjectsStart, +} from 'src/core/public'; import { TypesStart } from './types'; import { createGetterSetter } from '../../../../../../plugins/kibana_utils/public'; +import { IndexPatternsContract } from '../../../../../../plugins/data/public'; +import { UsageCollectionSetup } from '../../../../../../plugins/usage_collection/public'; export const [getUISettings, setUISettings] = createGetterSetter('UISettings'); +export const [getCapabilities, setCapabilities] = createGetterSetter('Capabilities'); + +export const [getHttp, setHttp] = createGetterSetter('Http'); + +export const [getSavedObjects, setSavedObjects] = createGetterSetter( + 'SavedObjects' +); + export const [getTypes, setTypes] = createGetterSetter('Types'); export const [getI18n, setI18n] = createGetterSetter('I18n'); + +export const [getIndexPatterns, setIndexPatterns] = createGetterSetter( + 'IndexPatterns' +); + +export const [getUsageCollector, setUsageCollector] = createGetterSetter( + 'UsageCollection' +); diff --git a/src/legacy/ui/public/UI_SYSTEMS.md b/src/legacy/ui/public/UI_SYSTEMS.md index 63fd602075653d..37bfbcf92f6404 100644 --- a/src/legacy/ui/public/UI_SYSTEMS.md +++ b/src/legacy/ui/public/UI_SYSTEMS.md @@ -6,7 +6,3 @@ In this directory you'll find various UI systems you can use to craft effective * [banners](notify/banners/BANNERS.md) * [toastNotifications](notify/toasts/TOAST_NOTIFICATIONS.md) - -## ui/vislib - -* [VisLib](vislib/VISLIB.md) \ No newline at end of file diff --git a/src/legacy/ui/public/_index.scss b/src/legacy/ui/public/_index.scss index 747ad025ef691d..f5a1d0a7922a74 100644 --- a/src/legacy/ui/public/_index.scss +++ b/src/legacy/ui/public/_index.scss @@ -26,5 +26,4 @@ // Can't import vis folder here because of cascading issues, it's imported in core_plugins/kibana // @import './vis/index'; -@import './vislib/index'; @import './visualize/index'; diff --git a/src/legacy/ui/public/vislib/components/color/colormaps.ts b/src/legacy/ui/public/color_maps/color_maps.ts similarity index 100% rename from src/legacy/ui/public/vislib/components/color/colormaps.ts rename to src/legacy/ui/public/color_maps/color_maps.ts diff --git a/src/legacy/ui/public/vislib/components/color/heatmap_color.js b/src/legacy/ui/public/color_maps/heatmap_color.js similarity index 98% rename from src/legacy/ui/public/vislib/components/color/heatmap_color.js rename to src/legacy/ui/public/color_maps/heatmap_color.js index 5e788cd1f33451..06d754235f88b5 100644 --- a/src/legacy/ui/public/vislib/components/color/heatmap_color.js +++ b/src/legacy/ui/public/color_maps/heatmap_color.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import { vislibColorMaps } from './colormaps'; +import { vislibColorMaps } from './color_maps'; function enforceBounds(x) { if (x < 0) { diff --git a/src/legacy/ui/public/color_maps/index.ts b/src/legacy/ui/public/color_maps/index.ts new file mode 100644 index 00000000000000..50dfe682f44188 --- /dev/null +++ b/src/legacy/ui/public/color_maps/index.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ + +export * from './color_maps'; +// @ts-ignore +export { getHeatmapColors } from './heatmap_color'; +// @ts-ignore +export * from './truncated_color_maps'; diff --git a/src/legacy/ui/public/vislib/components/color/truncated_colormaps.js b/src/legacy/ui/public/color_maps/truncated_color_maps.js similarity index 86% rename from src/legacy/ui/public/vislib/components/color/truncated_colormaps.js rename to src/legacy/ui/public/color_maps/truncated_color_maps.js index ccf005b3726a88..cb7772c875e48c 100644 --- a/src/legacy/ui/public/vislib/components/color/truncated_colormaps.js +++ b/src/legacy/ui/public/color_maps/truncated_color_maps.js @@ -17,14 +17,14 @@ * under the License. */ -import { vislibColorMaps } from './colormaps'; +import { vislibColorMaps } from './color_maps'; export const truncatedColorMaps = {}; const colormaps = vislibColorMaps; for (const key in colormaps) { if (colormaps.hasOwnProperty(key)) { - //slice off lightest colors + // slice off lightest colors truncatedColorMaps[key] = { ...colormaps[key], value: colormaps[key].value.slice(Math.floor(colormaps[key].value.length / 4)), @@ -32,7 +32,7 @@ for (const key in colormaps) { } } -export const colorSchemas = Object.values(truncatedColorMaps).map(({ id, label }) => ({ +export const truncatedColorSchemas = Object.values(truncatedColorMaps).map(({ id, label }) => ({ value: id, text: label, })); diff --git a/src/legacy/ui/public/vis/components/tooltip/_hierarchical_tooltip_formatter.js b/src/legacy/ui/public/vis/components/tooltip/_hierarchical_tooltip_formatter.js index 26a9c5b008f700..aef7bc3913a49c 100644 --- a/src/legacy/ui/public/vis/components/tooltip/_hierarchical_tooltip_formatter.js +++ b/src/legacy/ui/public/vis/components/tooltip/_hierarchical_tooltip_formatter.js @@ -19,6 +19,9 @@ import _ from 'lodash'; import $ from 'jquery'; + +import chrome from 'ui/chrome'; + import { collectBranch } from './_collect_branch'; import numeral from 'numeral'; import template from './_hierarchical_tooltip.html'; @@ -68,6 +71,12 @@ export const getHierarchicalTooltipFormatter = () => { return _tooltipFormatter; }; +export const initializeHierarchicalTooltipFormatter = async () => { + const $injector = await chrome.dangerouslyGetActiveInjector(); + const Private = $injector.get('Private'); + _tooltipFormatter = Private(HierarchicalTooltipFormatterProvider); +}; + export const setHierarchicalTooltipFormatter = Private => { _tooltipFormatter = Private(HierarchicalTooltipFormatterProvider); }; diff --git a/src/legacy/ui/public/vis/components/tooltip/_pointseries_tooltip_formatter.js b/src/legacy/ui/public/vis/components/tooltip/_pointseries_tooltip_formatter.js index fa0b030c736c16..88c9e3d67b4a93 100644 --- a/src/legacy/ui/public/vis/components/tooltip/_pointseries_tooltip_formatter.js +++ b/src/legacy/ui/public/vis/components/tooltip/_pointseries_tooltip_formatter.js @@ -18,6 +18,9 @@ */ import $ from 'jquery'; + +import chrome from 'ui/chrome'; + import template from './_pointseries_tooltip.html'; export function PointSeriesTooltipFormatterProvider($compile, $rootScope) { @@ -75,6 +78,12 @@ export const getPointSeriesTooltipFormatter = () => { return _tooltipFormatter; }; +export const initializePointSeriesTooltipFormatter = async () => { + const $injector = await chrome.dangerouslyGetActiveInjector(); + const Private = $injector.get('Private'); + _tooltipFormatter = Private(PointSeriesTooltipFormatterProvider); +}; + export const setPointSeriesTooltipFormatter = Private => { _tooltipFormatter = Private(PointSeriesTooltipFormatterProvider); }; diff --git a/src/legacy/ui/public/vis/editors/default/agg_groups.ts b/src/legacy/ui/public/vis/editors/default/agg_groups.ts index f55e6ecd79155d..e84306144fa632 100644 --- a/src/legacy/ui/public/vis/editors/default/agg_groups.ts +++ b/src/legacy/ui/public/vis/editors/default/agg_groups.ts @@ -18,11 +18,14 @@ */ import { i18n } from '@kbn/i18n'; +import { $Values } from '@kbn/utility-types'; -export enum AggGroupNames { - Buckets = 'buckets', - Metrics = 'metrics', -} +export const AggGroupNames = Object.freeze({ + Buckets: 'buckets' as 'buckets', + Metrics: 'metrics' as 'metrics', + None: 'none' as 'none', +}); +export type AggGroupNames = $Values; export const aggGroupNamesMap = () => ({ [AggGroupNames.Metrics]: i18n.translate('common.ui.vis.editors.aggGroups.metricsText', { diff --git a/src/legacy/ui/public/vis/editors/default/components/agg_group.tsx b/src/legacy/ui/public/vis/editors/default/components/agg_group.tsx index 528914f4fd006b..1c8690f6deb795 100644 --- a/src/legacy/ui/public/vis/editors/default/components/agg_group.tsx +++ b/src/legacy/ui/public/vis/editors/default/components/agg_group.tsx @@ -66,7 +66,7 @@ function DefaultEditorAggGroup({ setTouched, setValidity, }: DefaultEditorAggGroupProps) { - const groupNameLabel = aggGroupNamesMap()[groupName]; + const groupNameLabel = (aggGroupNamesMap() as any)[groupName]; // e.g. buckets can have no aggs const group: AggConfig[] = state.aggs.aggs.filter((agg: AggConfig) => agg.schema.group === groupName) || []; diff --git a/src/legacy/ui/public/vis/editors/default/schemas.js b/src/legacy/ui/public/vis/editors/default/schemas.ts similarity index 70% rename from src/legacy/ui/public/vis/editors/default/schemas.js rename to src/legacy/ui/public/vis/editors/default/schemas.ts index 69449dc8504a89..e86a73732c3f4c 100644 --- a/src/legacy/ui/public/vis/editors/default/schemas.js +++ b/src/legacy/ui/public/vis/editors/default/schemas.ts @@ -18,13 +18,44 @@ */ import _ from 'lodash'; + +import { Optional } from '@kbn/utility-types'; + +import { AggParam } from '../../../agg_types'; import { IndexedArray } from '../../../indexed_array'; import { RowsOrColumnsControl } from './controls/rows_or_columns'; import { RadiusRatioOptionControl } from './controls/radius_ratio_option'; import { AggGroupNames } from './agg_groups'; +import { AggControlProps } from './controls/agg_control_props'; + +export interface Schema { + aggFilter: string | string[]; + editor: boolean | string; + group: AggGroupNames; + max: number; + min: number; + name: string; + params: AggParam[]; + title: string; + defaults: unknown; + hideCustomLabel?: boolean; + mustBeFirst?: boolean; + aggSettings?: any; + editorComponent?: React.ComponentType; +} class Schemas { - constructor(schemas) { + // @ts-ignore + all: IndexedArray; + + constructor( + schemas: Array< + Optional< + Schema, + 'min' | 'max' | 'group' | 'title' | 'aggFilter' | 'editor' | 'params' | 'defaults' + > + > + ) { _(schemas || []) .map(schema => { if (!schema.name) throw new Error('all schema must have a unique name'); @@ -35,7 +66,7 @@ class Schemas { name: 'row', default: true, }, - ]; + ] as AggParam[]; schema.editorComponent = RowsOrColumnsControl; } else if (schema.name === 'radius') { schema.editorComponent = RadiusRatioOptionControl; @@ -51,21 +82,23 @@ class Schemas { params: [], }); - return schema; + return schema as Schema; }) - .tap(schemas => { + .tap((fullSchemas: Schema[]) => { this.all = new IndexedArray({ index: ['name'], group: ['group'], immutable: true, - initialSet: schemas, + initialSet: fullSchemas, }); }) .groupBy('group') .forOwn((group, groupName) => { + // @ts-ignore this[groupName] = new IndexedArray({ index: ['name'], immutable: true, + // @ts-ignore initialSet: group, }); }) diff --git a/src/legacy/ui/public/vis/vis_types/_vislib_vis_legend.scss b/src/legacy/ui/public/vis/vis_types/_vislib_vis_legend.scss index 4d7c0e2bdcadb4..62050ce4e99fd3 100644 --- a/src/legacy/ui/public/vis/vis_types/_vislib_vis_legend.scss +++ b/src/legacy/ui/public/vis/vis_types/_vislib_vis_legend.scss @@ -1,4 +1,4 @@ -@import '../../vislib/variables'; +@import '../../../../core_plugins/vis_type_vislib/public/vislib/variables'; // NOTE: Some of the styles attempt to align with the TSVB legend diff --git a/src/legacy/ui/public/vis/vis_types/vislib_vis_legend/pie_utils.ts b/src/legacy/ui/public/vis/vis_types/vislib_vis_legend/pie_utils.ts new file mode 100644 index 00000000000000..d9eea83d40b48c --- /dev/null +++ b/src/legacy/ui/public/vis/vis_types/vislib_vis_legend/pie_utils.ts @@ -0,0 +1,103 @@ +/* + * 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 _ from 'lodash'; + +/** + * Returns an array of names ordered by appearance in the nested array + * of objects + * + * > Duplicated utilty method from vislib Data class to decouple `vislib_vis_legend` from `vislib` + * + * @see src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/data.js + * + * @returns {Array} Array of unique names (strings) + */ +export function getPieNames(data: any[]): string[] { + const names: string[] = []; + + _.forEach(data, function(obj) { + const columns = obj.raw ? obj.raw.columns : undefined; + _.forEach(getNames(obj, columns), function(name) { + names.push(name); + }); + }); + + return _.uniq(names, 'label'); +} + +/** + * Flattens hierarchical data into an array of objects with a name and index value. + * The indexed value determines the order of nesting in the data. + * Returns an array with names sorted by the index value. + * + * @param data {Object} Chart data object + * @param columns {Object} Contains formatter information + * @returns {Array} Array of names (strings) + */ +function getNames(data: any, columns: any): string[] { + const slices = data.slices; + + if (slices.children) { + const namedObj = returnNames(slices.children, 0, columns); + + return _(namedObj) + .sortBy(function(obj) { + return obj.index; + }) + .unique(function(d) { + return d.label; + }) + .value(); + } + + return []; +} + +/** + * Helper function for getNames + * Returns an array of objects with a name (key) value and an index value. + * The index value allows us to sort the names in the correct nested order. + * + * @param array {Array} Array of data objects + * @param index {Number} Number of times the object is nested + * @param columns {Object} Contains name formatter information + * @returns {Array} Array of labels (strings) + */ +function returnNames(array: any[], index: number, columns: any): any[] { + const names: any[] = []; + + _.forEach(array, function(obj) { + names.push({ + label: obj.name, + values: [obj.rawData], + index, + }); + + if (obj.children) { + const plusIndex = index + 1; + + _.forEach(returnNames(obj.children, plusIndex, columns), function(namedObj) { + names.push(namedObj); + }); + } + }); + + return names; +} diff --git a/src/legacy/ui/public/vis/vis_types/vislib_vis_legend/vislib_vis_legend.tsx b/src/legacy/ui/public/vis/vis_types/vislib_vis_legend/vislib_vis_legend.tsx index f0100e369f0507..d98590f9885b9d 100644 --- a/src/legacy/ui/public/vis/vis_types/vislib_vis_legend/vislib_vis_legend.tsx +++ b/src/legacy/ui/public/vis/vis_types/vislib_vis_legend/vislib_vis_legend.tsx @@ -23,12 +23,11 @@ import { compact, uniq, map } from 'lodash'; import { i18n } from '@kbn/i18n'; import { EuiPopoverProps, EuiIcon, keyCodes, htmlIdGenerator } from '@elastic/eui'; -// @ts-ignore -import { Data } from '../../../vislib/lib/data'; // @ts-ignore import { createFiltersFromEvent } from '../../../../../core_plugins/visualizations/public'; import { CUSTOM_LEGEND_VIS_TYPES, LegendItem } from './models'; import { VisLegendItem } from './vislib_vis_legend_item'; +import { getPieNames } from './pie_utils'; import { getTableAggs } from '../../../visualize/loader/pipeline_helpers/utilities'; export interface VisLegendProps { @@ -128,7 +127,7 @@ export class VisLegend extends PureComponent { if (!data) return []; data = data.columns || data.rows || [data]; - if (type === 'pie') return Data.prototype.pieNames(data); + if (type === 'pie') return getPieNames(data); return this.getSeriesLabels(data); }; diff --git a/src/legacy/ui/public/vislib/vis.js b/src/legacy/ui/public/vislib/vis.js deleted file mode 100644 index 6ce58c1f5b23b2..00000000000000 --- a/src/legacy/ui/public/vislib/vis.js +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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 _ from 'lodash'; -import d3 from 'd3'; -import { EventEmitter } from 'events'; -import chrome from '../chrome'; -import { VislibError } from './errors'; -import { VisConfig } from './lib/vis_config'; -import { Handler } from './lib/handler'; -import { setHierarchicalTooltipFormatter } from '../vis/components/tooltip/_hierarchical_tooltip_formatter'; -import { setPointSeriesTooltipFormatter } from '../vis/components/tooltip/_pointseries_tooltip_formatter'; - -const config = chrome.getUiSettingsClient(); - -export function VislibVisProvider(Private) { - setHierarchicalTooltipFormatter(Private); - setPointSeriesTooltipFormatter(Private); - - /** - * Creates the visualizations. - * - * @class Vis - * @constructor - * @param $el {HTMLElement} jQuery selected HTML element - * @param config {Object} Parameters that define the chart type and chart options - */ - class Vis extends EventEmitter { - constructor($el, visConfigArgs) { - super(); - this.el = $el.get ? $el.get(0) : $el; - this.visConfigArgs = _.cloneDeep(visConfigArgs); - this.visConfigArgs.dimmingOpacity = config.get('visualization:dimmingOpacity'); - this.visConfigArgs.heatmapMaxBuckets = config.get('visualization:heatmap:maxBuckets'); - } - - hasLegend() { - return this.visConfigArgs.addLegend; - } - - initVisConfig(data, uiState) { - this.data = data; - - this.uiState = uiState; - - this.visConfig = new VisConfig(this.visConfigArgs, this.data, this.uiState, this.el); - } - - /** - * Renders the visualization - * - * @method render - * @param data {Object} Elasticsearch query results - */ - render(data, uiState) { - if (!data) { - throw new Error('No valid data!'); - } - - if (this.handler) { - this.data = null; - this._runOnHandler('destroy'); - } - - this.initVisConfig(data, uiState); - - this.handler = new Handler(this, this.visConfig); - this._runOnHandler('render'); - } - - getLegendLabels() { - return this.visConfig ? this.visConfig.get('legend.labels', null) : null; - } - - getLegendColors() { - return this.visConfig ? this.visConfig.get('legend.colors', null) : null; - } - - _runOnHandler(method) { - try { - this.handler[method](); - } catch (error) { - if (error instanceof VislibError) { - error.displayToScreen(this.handler); - } else { - throw error; - } - } - } - - /** - * Destroys the visualization - * Removes chart and all elements associated with it. - * Removes chart and all elements associated with it. - * Remove event listeners and pass destroy call down to owned objects. - * - * @method destroy - */ - destroy() { - const selection = d3.select(this.el).select('.visWrapper'); - - if (this.handler) this._runOnHandler('destroy'); - - selection.remove(); - } - - /** - * Sets attributes on the visualization - * - * @method set - * @param name {String} An attribute name - * @param val {*} Value to which the attribute name is set - */ - set(name, val) { - this.visConfigArgs[name] = val; - this.render(this.data, this.uiState); - } - - /** - * Gets attributes from the visualization - * - * @method get - * @param name {String} An attribute name - * @returns {*} The value of the attribute name - */ - get(name) { - return this.visConfig.get(name); - } - - /** - * Turns on event listeners. - * - * @param event {String} - * @param listener{Function} - * @returns {*} - */ - on(event, listener) { - const first = this.listenerCount(event) === 0; - const ret = EventEmitter.prototype.on.call(this, event, listener); - const added = this.listenerCount(event) > 0; - - // if this is the first listener added for the event - // enable the event in the handler - if (first && added && this.handler) this.handler.enable(event); - - return ret; - } - - /** - * Turns off event listeners. - * - * @param event {String} - * @param listener{Function} - * @returns {*} - */ - off(event, listener) { - const last = this.listenerCount(event) === 1; - const ret = EventEmitter.prototype.off.call(this, event, listener); - const removed = this.listenerCount(event) === 0; - - // Once all listeners are removed, disable the events in the handler - if (last && removed && this.handler) this.handler.disable(event); - return ret; - } - - removeAllListeners(event) { - const ret = EventEmitter.prototype.removeAllListeners.call(this, event); - this.handler.disable(event); - return ret; - } - } - - return Vis; -} diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_operators.ts b/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_operators.ts index bb15cffa67b599..13542710eac08c 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_operators.ts +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_operators.ts @@ -18,11 +18,11 @@ */ import { i18n } from '@kbn/i18n'; -import { esFilters } from '../../../..'; +import { FILTERS } from '../../../../../common/es_query/filters'; export interface Operator { message: string; - type: esFilters.FILTERS; + type: FILTERS; negate: boolean; fieldTypes?: string[]; } @@ -31,7 +31,7 @@ export const isOperator = { message: i18n.translate('data.filter.filterEditor.isOperatorOptionLabel', { defaultMessage: 'is', }), - type: esFilters.FILTERS.PHRASE, + type: FILTERS.PHRASE, negate: false, }; @@ -39,7 +39,7 @@ export const isNotOperator = { message: i18n.translate('data.filter.filterEditor.isNotOperatorOptionLabel', { defaultMessage: 'is not', }), - type: esFilters.FILTERS.PHRASE, + type: FILTERS.PHRASE, negate: true, }; @@ -47,7 +47,7 @@ export const isOneOfOperator = { message: i18n.translate('data.filter.filterEditor.isOneOfOperatorOptionLabel', { defaultMessage: 'is one of', }), - type: esFilters.FILTERS.PHRASES, + type: FILTERS.PHRASES, negate: false, fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape'], }; @@ -56,7 +56,7 @@ export const isNotOneOfOperator = { message: i18n.translate('data.filter.filterEditor.isNotOneOfOperatorOptionLabel', { defaultMessage: 'is not one of', }), - type: esFilters.FILTERS.PHRASES, + type: FILTERS.PHRASES, negate: true, fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape'], }; @@ -65,7 +65,7 @@ export const isBetweenOperator = { message: i18n.translate('data.filter.filterEditor.isBetweenOperatorOptionLabel', { defaultMessage: 'is between', }), - type: esFilters.FILTERS.RANGE, + type: FILTERS.RANGE, negate: false, fieldTypes: ['number', 'date', 'ip'], }; @@ -74,7 +74,7 @@ export const isNotBetweenOperator = { message: i18n.translate('data.filter.filterEditor.isNotBetweenOperatorOptionLabel', { defaultMessage: 'is not between', }), - type: esFilters.FILTERS.RANGE, + type: FILTERS.RANGE, negate: true, fieldTypes: ['number', 'date', 'ip'], }; @@ -83,7 +83,7 @@ export const existsOperator = { message: i18n.translate('data.filter.filterEditor.existsOperatorOptionLabel', { defaultMessage: 'exists', }), - type: esFilters.FILTERS.EXISTS, + type: FILTERS.EXISTS, negate: false, }; @@ -91,7 +91,7 @@ export const doesNotExistOperator = { message: i18n.translate('data.filter.filterEditor.doesNotExistOperatorOptionLabel', { defaultMessage: 'does not exist', }), - type: esFilters.FILTERS.EXISTS, + type: FILTERS.EXISTS, negate: true, }; diff --git a/src/plugins/embeddable/public/components/embeddable_panel/__examples__/embeddable_panel.examples.tsx b/src/plugins/embeddable/public/components/embeddable_panel/__examples__/embeddable_panel.examples.tsx new file mode 100644 index 00000000000000..7ec8848b8cebdd --- /dev/null +++ b/src/plugins/embeddable/public/components/embeddable_panel/__examples__/embeddable_panel.examples.tsx @@ -0,0 +1,24 @@ +/* + * 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 * as React from 'react'; +import { storiesOf } from '@storybook/react'; +import { EmbeddablePanel } from '..'; + +storiesOf('components/EmbeddablePanel', module).add('default', () => ); diff --git a/src/plugins/embeddable/public/components/embeddable_panel/index.tsx b/src/plugins/embeddable/public/components/embeddable_panel/index.tsx new file mode 100644 index 00000000000000..7089efa4bca88f --- /dev/null +++ b/src/plugins/embeddable/public/components/embeddable_panel/index.tsx @@ -0,0 +1,29 @@ +/* + * 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 { EuiPanel } from '@elastic/eui'; +import * as React from 'react'; + +export const EmbeddablePanel = () => { + return ( + + Hello world + + ); +}; diff --git a/src/plugins/embeddable/scripts/storybook.js b/src/plugins/embeddable/scripts/storybook.js new file mode 100644 index 00000000000000..0d7712fe973f48 --- /dev/null +++ b/src/plugins/embeddable/scripts/storybook.js @@ -0,0 +1,26 @@ +/* + * 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 { join } from 'path'; + +// eslint-disable-next-line +require('@kbn/storybook').runStorybookCli({ + name: 'embeddable', + storyGlobs: [join(__dirname, '..', 'public', 'components', '**', '*.examples.tsx')], +}); diff --git a/src/plugins/expressions/public/execute.ts b/src/plugins/expressions/public/execute.ts index 12e84f677ce3e5..89ef272a0d023a 100644 --- a/src/plugins/expressions/public/execute.ts +++ b/src/plugins/expressions/public/execute.ts @@ -65,6 +65,7 @@ export class ExpressionDataHandler { getInitialContext, inspectorAdapters: this.inspectorAdapters, abortSignal: this.abortController.signal, + variables: params.variables, }) .then( (v: IInterpreterResult) => { diff --git a/src/plugins/expressions/public/functions/tests/var.test.ts b/src/plugins/expressions/public/functions/tests/var.test.ts new file mode 100644 index 00000000000000..fe5963ec8c5099 --- /dev/null +++ b/src/plugins/expressions/public/functions/tests/var.test.ts @@ -0,0 +1,63 @@ +/* + * 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 { functionWrapper } from './utils'; +import { variable } from '../var'; +import { FunctionHandlers } from '../../../common/types'; +import { KibanaContext } from '../../../common/expression_types/kibana_context'; + +describe('interpreter/functions#var', () => { + const fn = functionWrapper(variable); + let context: Partial; + let initialContext: KibanaContext; + let handlers: FunctionHandlers; + + beforeEach(() => { + context = { timeRange: { from: '0', to: '1' } }; + initialContext = { + type: 'kibana_context', + query: { language: 'lucene', query: 'geo.src:US' }, + filters: [ + { + meta: { + disabled: false, + negate: false, + alias: null, + }, + query: { match: {} }, + }, + ], + timeRange: { from: '2', to: '3' }, + }; + handlers = { + getInitialContext: () => initialContext, + variables: { test: 1 } as any, + }; + }); + + it('returns the selected variable', () => { + const actual = fn(context, { name: 'test' }, handlers); + expect(actual).toEqual(1); + }); + + it('returns undefined if variable does not exist', () => { + const actual = fn(context, { name: 'unknown' }, handlers); + expect(actual).toEqual(undefined); + }); +}); diff --git a/src/plugins/expressions/public/functions/tests/var_set.test.ts b/src/plugins/expressions/public/functions/tests/var_set.test.ts new file mode 100644 index 00000000000000..7efa8ebc0dd3fd --- /dev/null +++ b/src/plugins/expressions/public/functions/tests/var_set.test.ts @@ -0,0 +1,74 @@ +/* + * 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 { functionWrapper } from './utils'; +import { variableSet } from '../var_set'; +import { FunctionHandlers } from '../../../common/types'; +import { KibanaContext } from '../../../common/expression_types/kibana_context'; + +describe('interpreter/functions#varset', () => { + const fn = functionWrapper(variableSet); + let context: Partial; + let initialContext: KibanaContext; + let handlers: FunctionHandlers; + let variables: Record; + + beforeEach(() => { + context = { timeRange: { from: '0', to: '1' } }; + initialContext = { + type: 'kibana_context', + query: { language: 'lucene', query: 'geo.src:US' }, + filters: [ + { + meta: { + disabled: false, + negate: false, + alias: null, + }, + query: { match: {} }, + }, + ], + timeRange: { from: '2', to: '3' }, + }; + handlers = { + getInitialContext: () => initialContext, + variables: { test: 1 } as any, + }; + + variables = handlers.variables; + }); + + it('updates a variable', () => { + const actual = fn(context, { name: 'test', value: 2 }, handlers); + expect(variables.test).toEqual(2); + expect(actual).toEqual(context); + }); + + it('sets a new variable', () => { + const actual = fn(context, { name: 'new', value: 3 }, handlers); + expect(variables.new).toEqual(3); + expect(actual).toEqual(context); + }); + + it('stores context if value is not set', () => { + const actual = fn(context, { name: 'test' }, handlers); + expect(variables.test).toEqual(context); + expect(actual).toEqual(context); + }); +}); diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/gauge.d.ts b/src/plugins/expressions/public/functions/var.ts similarity index 50% rename from src/legacy/core_plugins/kbn_vislib_vis_types/public/gauge.d.ts rename to src/plugins/expressions/public/functions/var.ts index ff8345e9a5b257..9410149060216b 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/gauge.d.ts +++ b/src/plugins/expressions/public/functions/var.ts @@ -17,34 +17,33 @@ * under the License. */ -import { RangeValues } from 'ui/vis/editors/default/controls/ranges'; -import { Alignments, GaugeTypes } from './utils/collections'; -import { ColorSchemaVislibParams, Labels, Style } from './types'; +import { i18n } from '@kbn/i18n'; +import { ExpressionFunction } from '../../common/types'; -interface Gauge extends ColorSchemaVislibParams { - backStyle: 'Full'; - gaugeStyle: 'Full'; - orientation: 'vertical'; - type: 'meter'; - alignment: Alignments; - colorsRange: RangeValues[]; - extendRange: boolean; - gaugeType: GaugeTypes; - labels: Labels; - percentageMode: boolean; - outline?: boolean; - scale: { - show: boolean; - labels: false; - color: 'rgba(105,112,125,0.2)'; - }; - style: Style; +interface Arguments { + name: string; } -export interface GaugeVisParams { - type: 'gauge'; - addTooltip: boolean; - addLegend: boolean; - isDisplayWarning: boolean; - gauge: Gauge; -} +type Context = any; +type ExpressionFunctionVar = ExpressionFunction<'var', Context, Arguments, any>; + +export const variable = (): ExpressionFunctionVar => ({ + name: 'var', + help: i18n.translate('expressions.functions.var.help', { + defaultMessage: 'Updates kibana global context', + }), + args: { + name: { + types: ['string'], + aliases: ['_'], + required: true, + help: i18n.translate('expressions.functions.var.name.help', { + defaultMessage: 'Specify name of the variable', + }), + }, + }, + fn(context, args, handlers) { + const variables: Record = handlers.variables; + return variables[args.name]; + }, +}); diff --git a/src/plugins/expressions/public/functions/var_set.ts b/src/plugins/expressions/public/functions/var_set.ts new file mode 100644 index 00000000000000..a10ee7a00814fb --- /dev/null +++ b/src/plugins/expressions/public/functions/var_set.ts @@ -0,0 +1,58 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { ExpressionFunction } from '../../common/types'; + +interface Arguments { + name: string; + value?: any; +} + +type Context = any; +type ExpressionFunctionVarSet = ExpressionFunction<'var_set', Context, Arguments, Context>; + +export const variableSet = (): ExpressionFunctionVarSet => ({ + name: 'var_set', + help: i18n.translate('expressions.functions.varset.help', { + defaultMessage: 'Updates kibana global context', + }), + args: { + name: { + types: ['string'], + aliases: ['_'], + required: true, + help: i18n.translate('expressions.functions.varset.name.help', { + defaultMessage: 'Specify name of the variable', + }), + }, + value: { + aliases: ['val'], + help: i18n.translate('expressions.functions.varset.val.help', { + defaultMessage: + 'Specify value for the variable. If not provided input context will be used', + }), + }, + }, + fn(context, args, handlers) { + const variables: Record = handlers.variables; + variables[args.name] = args.value === undefined ? context : args.value; + return context; + }, +}); diff --git a/src/plugins/expressions/public/loader.ts b/src/plugins/expressions/public/loader.ts index 0342713f7627b1..d714282360f716 100644 --- a/src/plugins/expressions/public/loader.ts +++ b/src/plugins/expressions/public/loader.ts @@ -178,6 +178,9 @@ export class ExpressionLoader { if (params.extraHandlers && this.params) { this.params.extraHandlers = params.extraHandlers; } + if (params.variables && this.params) { + this.params.variables = params.variables; + } } } diff --git a/src/plugins/expressions/public/plugin.ts b/src/plugins/expressions/public/plugin.ts index 7471326cdd749e..11f804464704ec 100644 --- a/src/plugins/expressions/public/plugin.ts +++ b/src/plugins/expressions/public/plugin.ts @@ -32,6 +32,8 @@ import { clog as clogFunction } from './functions/clog'; import { font as fontFunction } from './functions/font'; import { kibana as kibanaFunction } from './functions/kibana'; import { kibanaContext as kibanaContextFunction } from './functions/kibana_context'; +import { variable } from './functions/var'; +import { variableSet } from './functions/var_set'; import { boolean as booleanType, datatable as datatableType, @@ -109,6 +111,8 @@ export class ExpressionsPublicPlugin registerFunction(fontFunction); registerFunction(kibanaFunction); registerFunction(kibanaContextFunction); + registerFunction(variable); + registerFunction(variableSet); types.register(booleanType); types.register(datatableType); diff --git a/src/plugins/expressions/public/types/index.ts b/src/plugins/expressions/public/types/index.ts index 66a3da48dbee9c..e094e5e91d0068 100644 --- a/src/plugins/expressions/public/types/index.ts +++ b/src/plugins/expressions/public/types/index.ts @@ -65,6 +65,7 @@ export interface IExpressionLoaderParams { export interface IInterpreterHandlers { getInitialContext: IGetInitialContext; inspectorAdapters?: Adapters; + variables?: Record; abortSignal?: AbortSignal; } diff --git a/src/plugins/kibana_react/public/saved_objects/saved_object_save_modal.tsx b/src/plugins/kibana_react/public/saved_objects/saved_object_save_modal.tsx index 33d4dcfd6606a3..cdbc2bb9b54735 100644 --- a/src/plugins/kibana_react/public/saved_objects/saved_object_save_modal.tsx +++ b/src/plugins/kibana_react/public/saved_objects/saved_object_save_modal.tsx @@ -39,7 +39,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; import { EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { VISUALIZE_EMBEDDABLE_TYPE } from '../../../../legacy/core_plugins/kibana/public/visualize_embeddable/constants'; +import { VISUALIZE_EMBEDDABLE_TYPE } from '../../../../legacy/core_plugins/visualizations/public/embeddable/constants'; export interface OnSaveProps { newTitle: string; diff --git a/test/functional/apps/visualize/_data_table_notimeindex_filters.ts b/test/functional/apps/visualize/_data_table_notimeindex_filters.ts new file mode 100644 index 00000000000000..eb83e80e2bbe13 --- /dev/null +++ b/test/functional/apps/visualize/_data_table_notimeindex_filters.ts @@ -0,0 +1,90 @@ +/* + * 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 expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function({ getService, getPageObjects }: FtrProviderContext) { + const log = getService('log'); + const filterBar = getService('filterBar'); + const renderable = getService('renderable'); + const dashboardAddPanel = getService('dashboardAddPanel'); + const PageObjects = getPageObjects([ + 'common', + 'visualize', + 'header', + 'dashboard', + 'timePicker', + 'visEditor', + 'visChart', + ]); + + describe('data table with index without time filter filters', function indexPatternCreation() { + const vizName1 = 'Visualization DataTable w/o time filter'; + + before(async function() { + log.debug('navigateToApp visualize'); + await PageObjects.visualize.navigateToNewVisualization(); + log.debug('clickDataTable'); + await PageObjects.visualize.clickDataTable(); + log.debug('clickNewSearch'); + await PageObjects.visualize.clickNewSearch( + PageObjects.visualize.index.LOGSTASH_NON_TIME_BASED + ); + log.debug('Bucket = Split Rows'); + await PageObjects.visEditor.clickBucket('Split rows'); + log.debug('Aggregation = Histogram'); + await PageObjects.visEditor.selectAggregation('Histogram'); + log.debug('Field = bytes'); + await PageObjects.visEditor.selectField('bytes'); + log.debug('Interval = 2000'); + await PageObjects.visEditor.setInterval('2000', { type: 'numeric' }); + await PageObjects.visEditor.clickGo(); + }); + + it('should be able to save and load', async function() { + await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName1); + + await PageObjects.visualize.loadSavedVisualization(vizName1); + await PageObjects.visChart.waitForVisualization(); + }); + + it('timefilter should be disabled', async () => { + const isOff = await PageObjects.timePicker.isOff(); + expect(isOff).to.be(true); + }); + + // test to cover bug #54548 - add this visualization to a dashboard and filter + it('should add to dashboard and allow filtering', async function() { + await PageObjects.common.navigateToApp('dashboard'); + await PageObjects.dashboard.clickNewDashboard(); + await dashboardAddPanel.addVisualization(vizName1); + + // hover and click on cell to filter + await PageObjects.visChart.filterOnTableCell('1', '2'); + + await PageObjects.header.waitUntilLoadingHasFinished(); + await renderable.waitForRender(); + const filterCount = await filterBar.getFilterCount(); + expect(filterCount).to.be(1); + + await filterBar.removeAllFilters(); + }); + }); +} diff --git a/test/functional/apps/visualize/index.ts b/test/functional/apps/visualize/index.ts index 2a13b6fea91581..68285971e5c4a0 100644 --- a/test/functional/apps/visualize/index.ts +++ b/test/functional/apps/visualize/index.ts @@ -47,6 +47,7 @@ export default function({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./_area_chart')); loadTestFile(require.resolve('./_data_table')); loadTestFile(require.resolve('./_data_table_nontimeindex')); + loadTestFile(require.resolve('./_data_table_notimeindex_filters')); }); describe('', function() { diff --git a/test/functional/page_objects/common_page.ts b/test/functional/page_objects/common_page.ts index 75a15cc16db2eb..347923670c4135 100644 --- a/test/functional/page_objects/common_page.ts +++ b/test/functional/page_objects/common_page.ts @@ -371,6 +371,12 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo await browser.pressKeys(browser.keys.ENTER); } + // Pause the browser at a certain place for debugging + // Not meant for usage in CI, only for dev-usage + async pause() { + return browser.pause(); + } + /** * Clicks cancel button on modal * @param overlayWillStay pass in true if your test will show multiple modals in succession diff --git a/test/functional/page_objects/time_picker.js b/test/functional/page_objects/time_picker.js index 7c676784294784..2394abc9c21854 100644 --- a/test/functional/page_objects/time_picker.js +++ b/test/functional/page_objects/time_picker.js @@ -124,6 +124,11 @@ export function TimePickerPageProvider({ getService, getPageObjects }) { await this.setAbsoluteRange(this.defaultStartTime, this.defaultEndTime); } + async isOff() { + const element = await find.byClassName('euiDatePickerRange--readOnly'); + return !!element; + } + async isQuickSelectMenuOpen() { return await testSubjects.exists('superDatePickerQuickMenu'); } diff --git a/test/functional/services/browser.ts b/test/functional/services/browser.ts index 72bcc07ab98cfa..6a689e85de214c 100644 --- a/test/functional/services/browser.ts +++ b/test/functional/services/browser.ts @@ -199,6 +199,14 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { return await driver.get(url); } + /** + * Pauses the execution in the browser, similar to setting a breakpoint for debugging. + * @return {Promise} + */ + public async pause() { + await driver.executeAsyncScript(`(async () => { debugger; return Promise.resolve(); })()`); + } + /** * Moves the remote environment’s mouse cursor to the specified point {x, y} which is * offset to browser page top left corner. diff --git a/test/functional/services/dashboard/add_panel.js b/test/functional/services/dashboard/add_panel.js index 7a26f8d4479819..e390fd918eaee2 100644 --- a/test/functional/services/dashboard/add_panel.js +++ b/test/functional/services/dashboard/add_panel.js @@ -28,6 +28,8 @@ export function DashboardAddPanelProvider({ getService, getPageObjects }) { async clickOpenAddPanel() { log.debug('DashboardAddPanel.clickOpenAddPanel'); await testSubjects.click('dashboardAddPanelButton'); + // Give some time for the animation to complete + await PageObjects.common.sleep(500); } async clickAddNewEmbeddableLink(type) { @@ -96,8 +98,8 @@ export function DashboardAddPanelProvider({ getService, getPageObjects }) { if (!isOpen) { await retry.try(async () => { await this.clickOpenAddPanel(); - const isOpen = await this.isAddPanelOpen(); - if (!isOpen) { + const isNowOpen = await this.isAddPanelOpen(); + if (!isNowOpen) { throw new Error('Add panel still not open, trying again.'); } }); diff --git a/test/functional/services/remote/webdriver.ts b/test/functional/services/remote/webdriver.ts index 1a7abc63170753..1bd6358749e11d 100644 --- a/test/functional/services/remote/webdriver.ts +++ b/test/functional/services/remote/webdriver.ts @@ -43,6 +43,7 @@ import { Browsers } from './browsers'; const throttleOption: string = process.env.TEST_THROTTLE_NETWORK as string; const headlessBrowser: string = process.env.TEST_BROWSER_HEADLESS as string; +const remoteDebug: string = process.env.TEST_REMOTE_DEBUG as string; const SECOND = 1000; const MINUTE = 60 * SECOND; const NO_QUEUE_COMMANDS = ['getLog', 'getStatus', 'newSession', 'quit']; @@ -97,6 +98,10 @@ async function attemptToCreateCommand( // See: https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md chromeOptions.push('headless', 'disable-gpu'); } + if (remoteDebug === '1') { + // Visit chrome://inspect in chrome to remotely view/debug + chromeOptions.push('headless', 'disable-gpu', 'remote-debugging-port=9222'); + } chromeCapabilities.set('goog:chromeOptions', { w3c: false, args: chromeOptions, diff --git a/test/functional/services/test_subjects.ts b/test/functional/services/test_subjects.ts index 8ef008d5dee50e..d47b838c8d72a5 100644 --- a/test/functional/services/test_subjects.ts +++ b/test/functional/services/test_subjects.ts @@ -169,10 +169,14 @@ export function TestSubjectsProvider({ getService }: FtrProviderContext) { }); } - public async getAttribute(selector: string, attribute: string): Promise { + public async getAttribute( + selector: string, + attribute: string, + timeout?: number + ): Promise { return await retry.try(async () => { log.debug(`TestSubjects.getAttribute(${selector}, ${attribute})`); - const element = await this.find(selector); + const element = await this.find(selector, timeout); return await element.getAttribute(attribute); }); } diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/legacy.ts b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/legacy.ts index 57b5ad086e6a78..6d125bc3002e00 100644 --- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/legacy.ts +++ b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/np_ready/public/legacy.ts @@ -22,6 +22,20 @@ import 'ui/autoload/all'; import 'uiExports/interpreter'; import 'uiExports/embeddableFactories'; import 'uiExports/embeddableActions'; +import 'uiExports/contextMenuActions'; +import 'uiExports/devTools'; +import 'uiExports/docViews'; +import 'uiExports/embeddableActions'; +import 'uiExports/fieldFormatEditors'; +import 'uiExports/fieldFormats'; +import 'uiExports/home'; +import 'uiExports/indexManagement'; +import 'uiExports/inspectorViews'; +import 'uiExports/savedObjectTypes'; +import 'uiExports/search'; +import 'uiExports/shareContextMenuExtensions'; +import 'uiExports/visTypes'; +import 'uiExports/visualize'; import { npSetup, npStart } from 'ui/new_platform'; import { ExitFullScreenButton } from 'ui/exit_full_screen'; diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/index.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/index.ts index e0568a36f87437..33f2b217998148 100644 --- a/x-pack/legacy/plugins/actions/server/builtin_action_types/index.ts +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/index.ts @@ -8,26 +8,28 @@ import { ActionTypeRegistry } from '../action_type_registry'; import { ActionsConfigurationUtilities } from '../actions_config'; import { Logger } from '../../../../../../src/core/server'; -import { getActionType as getServerLogActionType } from './server_log'; -import { getActionType as getSlackActionType } from './slack'; import { getActionType as getEmailActionType } from './email'; import { getActionType as getIndexActionType } from './es_index'; import { getActionType as getPagerDutyActionType } from './pagerduty'; +import { getActionType as getServerLogActionType } from './server_log'; +import { getActionType as getServiceNowActionType } from './servicenow'; +import { getActionType as getSlackActionType } from './slack'; import { getActionType as getWebhookActionType } from './webhook'; export function registerBuiltInActionTypes({ - logger, - actionTypeRegistry, actionsConfigUtils: configurationUtilities, + actionTypeRegistry, + logger, }: { - logger: Logger; - actionTypeRegistry: ActionTypeRegistry; actionsConfigUtils: ActionsConfigurationUtilities; + actionTypeRegistry: ActionTypeRegistry; + logger: Logger; }) { - actionTypeRegistry.register(getServerLogActionType({ logger })); - actionTypeRegistry.register(getSlackActionType({ configurationUtilities })); actionTypeRegistry.register(getEmailActionType({ logger, configurationUtilities })); actionTypeRegistry.register(getIndexActionType({ logger })); actionTypeRegistry.register(getPagerDutyActionType({ logger, configurationUtilities })); + actionTypeRegistry.register(getServerLogActionType({ logger })); + actionTypeRegistry.register(getServiceNowActionType({ configurationUtilities })); + actionTypeRegistry.register(getSlackActionType({ configurationUtilities })); actionTypeRegistry.register(getWebhookActionType({ logger, configurationUtilities })); } diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/lib/post_servicenow.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/lib/post_servicenow.ts new file mode 100644 index 00000000000000..cfd3a9d70dc932 --- /dev/null +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/lib/post_servicenow.ts @@ -0,0 +1,28 @@ +/* + * 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, { AxiosResponse } from 'axios'; +import { Services } from '../../types'; +import { ParamsType, SecretsType } from '../servicenow'; + +interface PostServiceNowOptions { + apiUrl: string; + data: ParamsType; + headers: Record; + services?: Services; + secrets: SecretsType; +} + +// post an event to serviceNow +export async function postServiceNow(options: PostServiceNowOptions): Promise { + const { apiUrl, data, headers, secrets } = options; + const axiosOptions = { + headers, + validateStatus: () => true, + auth: secrets, + }; + return axios.post(`${apiUrl}/api/now/v1/table/incident`, data, axiosOptions); +} diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/servicenow.test.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/servicenow.test.ts new file mode 100644 index 00000000000000..a445c6afde4d50 --- /dev/null +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/servicenow.test.ts @@ -0,0 +1,279 @@ +/* + * 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. + */ + +jest.mock('./lib/post_servicenow', () => ({ + postServiceNow: jest.fn(), +})); + +import { getActionType } from './servicenow'; +import { ActionType, Services, ActionTypeExecutorOptions } from '../types'; +import { validateConfig, validateSecrets, validateParams } from '../lib'; +import { savedObjectsClientMock } from '../../../../../../src/core/server/mocks'; +import { postServiceNow } from './lib/post_servicenow'; +import { createActionTypeRegistry } from './index.test'; +import { configUtilsMock } from '../actions_config.mock'; + +const postServiceNowMock = postServiceNow as jest.Mock; + +const ACTION_TYPE_ID = '.servicenow'; + +const services: Services = { + callCluster: async (path: string, opts: any) => {}, + savedObjectsClient: savedObjectsClientMock.create(), +}; + +let actionType: ActionType; + +const mockServiceNow = { + config: { + apiUrl: 'www.servicenowisinkibanaactions.com', + }, + secrets: { + password: 'secret-password', + username: 'secret-username', + }, + params: { + comments: 'hello cool service now incident', + short_description: 'this is a cool service now incident', + }, +}; + +beforeAll(() => { + const { actionTypeRegistry } = createActionTypeRegistry(); + actionType = actionTypeRegistry.get(ACTION_TYPE_ID); +}); + +describe('get()', () => { + test('should return correct action type', () => { + expect(actionType.id).toEqual(ACTION_TYPE_ID); + expect(actionType.name).toEqual('servicenow'); + }); +}); + +describe('validateConfig()', () => { + test('should validate and pass when config is valid', () => { + const { config } = mockServiceNow; + expect(validateConfig(actionType, config)).toEqual(config); + }); + + test('should validate and throw error when config is invalid', () => { + expect(() => { + validateConfig(actionType, { shouldNotBeHere: true }); + }).toThrowErrorMatchingInlineSnapshot( + `"error validating action type config: [apiUrl]: expected value of type [string] but got [undefined]"` + ); + }); + + test('should validate and pass when the servicenow url is whitelisted', () => { + actionType = getActionType({ + configurationUtilities: { + ...configUtilsMock, + ensureWhitelistedUri: url => { + expect(url).toEqual('https://events.servicenow.com/v2/enqueue'); + }, + }, + }); + + expect( + validateConfig(actionType, { apiUrl: 'https://events.servicenow.com/v2/enqueue' }) + ).toEqual({ apiUrl: 'https://events.servicenow.com/v2/enqueue' }); + }); + + test('config validation returns an error if the specified URL isnt whitelisted', () => { + actionType = getActionType({ + configurationUtilities: { + ...configUtilsMock, + ensureWhitelistedUri: _ => { + throw new Error(`target url is not whitelisted`); + }, + }, + }); + + expect(() => { + validateConfig(actionType, { apiUrl: 'https://events.servicenow.com/v2/enqueue' }); + }).toThrowErrorMatchingInlineSnapshot( + `"error validating action type config: error configuring servicenow action: target url is not whitelisted"` + ); + }); +}); + +describe('validateSecrets()', () => { + test('should validate and pass when secrets is valid', () => { + const { secrets } = mockServiceNow; + expect(validateSecrets(actionType, secrets)).toEqual(secrets); + }); + + test('should validate and throw error when secrets is invalid', () => { + expect(() => { + validateSecrets(actionType, { username: false }); + }).toThrowErrorMatchingInlineSnapshot( + `"error validating action type secrets: [password]: expected value of type [string] but got [undefined]"` + ); + + expect(() => { + validateSecrets(actionType, { username: false, password: 'hello' }); + }).toThrowErrorMatchingInlineSnapshot( + `"error validating action type secrets: [username]: expected value of type [string] but got [boolean]"` + ); + }); +}); + +describe('validateParams()', () => { + test('should validate and pass when params is valid', () => { + const { params } = mockServiceNow; + expect(validateParams(actionType, params)).toEqual(params); + }); + + test('should validate and throw error when params is invalid', () => { + expect(() => { + validateParams(actionType, { eventAction: 'ackynollage' }); + }).toThrowErrorMatchingInlineSnapshot( + `"error validating action params: [short_description]: expected value of type [string] but got [undefined]"` + ); + }); +}); + +describe('execute()', () => { + beforeEach(() => { + postServiceNowMock.mockReset(); + }); + const { config, params, secrets } = mockServiceNow; + test('should succeed with valid params', async () => { + postServiceNowMock.mockImplementation(() => { + return { status: 201, data: 'data-here' }; + }); + + const actionId = 'some-action-id'; + const executorOptions: ActionTypeExecutorOptions = { + actionId, + config, + params, + secrets, + services, + }; + const actionResponse = await actionType.executor(executorOptions); + const { apiUrl, data, headers } = postServiceNowMock.mock.calls[0][0]; + expect({ apiUrl, data, headers, secrets }).toMatchInlineSnapshot(` + Object { + "apiUrl": "www.servicenowisinkibanaactions.com", + "data": Object { + "comments": "hello cool service now incident", + "short_description": "this is a cool service now incident", + }, + "headers": Object { + "Accept": "application/json", + "Content-Type": "application/json", + }, + "secrets": Object { + "password": "secret-password", + "username": "secret-username", + }, + } + `); + expect(actionResponse).toMatchInlineSnapshot(` + Object { + "actionId": "some-action-id", + "data": "data-here", + "status": "ok", + } + `); + }); + + test('should fail when postServiceNow throws', async () => { + postServiceNowMock.mockImplementation(() => { + throw new Error('doing some testing'); + }); + + const actionId = 'some-action-id'; + const executorOptions: ActionTypeExecutorOptions = { + actionId, + config, + params, + secrets, + services, + }; + const actionResponse = await actionType.executor(executorOptions); + expect(actionResponse).toMatchInlineSnapshot(` + Object { + "actionId": "some-action-id", + "message": "error posting servicenow event", + "serviceMessage": "doing some testing", + "status": "error", + } + `); + }); + + test('should fail when postServiceNow returns 429', async () => { + postServiceNowMock.mockImplementation(() => { + return { status: 429, data: 'data-here' }; + }); + + const actionId = 'some-action-id'; + const executorOptions: ActionTypeExecutorOptions = { + actionId, + config, + params, + secrets, + services, + }; + const actionResponse = await actionType.executor(executorOptions); + expect(actionResponse).toMatchInlineSnapshot(` + Object { + "actionId": "some-action-id", + "message": "error posting servicenow event: http status 429, retry later", + "retry": true, + "status": "error", + } + `); + }); + + test('should fail when postServiceNow returns 501', async () => { + postServiceNowMock.mockImplementation(() => { + return { status: 501, data: 'data-here' }; + }); + + const actionId = 'some-action-id'; + const executorOptions: ActionTypeExecutorOptions = { + actionId, + config, + params, + secrets, + services, + }; + const actionResponse = await actionType.executor(executorOptions); + expect(actionResponse).toMatchInlineSnapshot(` + Object { + "actionId": "some-action-id", + "message": "error posting servicenow event: http status 501, retry later", + "retry": true, + "status": "error", + } + `); + }); + + test('should fail when postServiceNow returns 418', async () => { + postServiceNowMock.mockImplementation(() => { + return { status: 418, data: 'data-here' }; + }); + + const actionId = 'some-action-id'; + const executorOptions: ActionTypeExecutorOptions = { + actionId, + config, + params, + secrets, + services, + }; + const actionResponse = await actionType.executor(executorOptions); + expect(actionResponse).toMatchInlineSnapshot(` + Object { + "actionId": "some-action-id", + "message": "error posting servicenow event: unexpected status 418", + "status": "error", + } + `); + }); +}); diff --git a/x-pack/legacy/plugins/actions/server/builtin_action_types/servicenow.ts b/x-pack/legacy/plugins/actions/server/builtin_action_types/servicenow.ts new file mode 100644 index 00000000000000..2d5c18207def3f --- /dev/null +++ b/x-pack/legacy/plugins/actions/server/builtin_action_types/servicenow.ts @@ -0,0 +1,169 @@ +/* + * 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 { curry } from 'lodash'; +import { i18n } from '@kbn/i18n'; +import { schema, TypeOf } from '@kbn/config-schema'; +import { + ActionType, + ActionTypeExecutorOptions, + ActionTypeExecutorResult, + ExecutorType, +} from '../types'; +import { ActionsConfigurationUtilities } from '../actions_config'; +import { postServiceNow } from './lib/post_servicenow'; + +// config definition +export type ConfigType = TypeOf; + +const ConfigSchemaProps = { + apiUrl: schema.string(), +}; + +const ConfigSchema = schema.object(ConfigSchemaProps); + +function validateConfig( + configurationUtilities: ActionsConfigurationUtilities, + configObject: ConfigType +) { + if (configObject.apiUrl == null) { + return i18n.translate('xpack.actions.builtin.servicenow.servicenowApiNullError', { + defaultMessage: 'ServiceNow [apiUrl] is required', + }); + } + try { + configurationUtilities.ensureWhitelistedUri(configObject.apiUrl); + } catch (whitelistError) { + return i18n.translate('xpack.actions.builtin.servicenow.servicenowApiWhitelistError', { + defaultMessage: 'error configuring servicenow action: {message}', + values: { + message: whitelistError.message, + }, + }); + } +} +// secrets definition +export type SecretsType = TypeOf; +const SecretsSchemaProps = { + password: schema.string(), + username: schema.string(), +}; + +const SecretsSchema = schema.object(SecretsSchemaProps); + +function validateSecrets( + configurationUtilities: ActionsConfigurationUtilities, + secrets: SecretsType +) { + if (secrets.username == null) { + return i18n.translate('xpack.actions.builtin.servicenow.servicenowApiUserError', { + defaultMessage: 'error configuring servicenow action: no secrets [username] provided', + }); + } + if (secrets.password == null) { + return i18n.translate('xpack.actions.builtin.servicenow.servicenowApiPasswordError', { + defaultMessage: 'error configuring servicenow action: no secrets [password] provided', + }); + } +} + +// params definition + +export type ParamsType = TypeOf; + +const ParamsSchema = schema.object({ + comments: schema.maybe(schema.string()), + short_description: schema.string(), +}); + +// action type definition +export function getActionType({ + configurationUtilities, + executor = serviceNowExecutor, +}: { + configurationUtilities: ActionsConfigurationUtilities; + executor?: ExecutorType; +}): ActionType { + return { + id: '.servicenow', + name: 'servicenow', + validate: { + config: schema.object(ConfigSchemaProps, { + validate: curry(validateConfig)(configurationUtilities), + }), + secrets: schema.object(SecretsSchemaProps, { + validate: curry(validateSecrets)(configurationUtilities), + }), + params: ParamsSchema, + }, + executor, + }; +} + +// action executor + +async function serviceNowExecutor( + execOptions: ActionTypeExecutorOptions +): Promise { + const actionId = execOptions.actionId; + const config = execOptions.config as ConfigType; + const secrets = execOptions.secrets as SecretsType; + const params = execOptions.params as ParamsType; + const headers = { + Accept: 'application/json', + 'Content-Type': 'application/json', + }; + let response; + try { + response = await postServiceNow({ apiUrl: config.apiUrl, data: params, headers, secrets }); + } catch (err) { + const message = i18n.translate('xpack.actions.builtin.servicenow.postingErrorMessage', { + defaultMessage: 'error posting servicenow event', + }); + return { + status: 'error', + actionId, + message, + serviceMessage: err.message, + }; + } + if (response.status === 200 || response.status === 201 || response.status === 204) { + return { + status: 'ok', + actionId, + data: response.data, + }; + } + + if (response.status === 429 || response.status >= 500) { + const message = i18n.translate('xpack.actions.builtin.servicenow.postingRetryErrorMessage', { + defaultMessage: 'error posting servicenow event: http status {status}, retry later', + values: { + status: response.status, + }, + }); + + return { + status: 'error', + actionId, + message, + retry: true, + }; + } + + const message = i18n.translate('xpack.actions.builtin.servicenow.postingUnexpectedErrorMessage', { + defaultMessage: 'error posting servicenow event: unexpected status {status}', + values: { + status: response.status, + }, + }); + + return { + status: 'error', + actionId, + message, + }; +} diff --git a/x-pack/legacy/plugins/apm/public/components/app/TraceOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/TraceOverview/index.tsx index 1ecf72f6fa3fc5..cf701d02aa5cb6 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/TraceOverview/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/TraceOverview/index.tsx @@ -49,7 +49,7 @@ export function TraceOverview() { return ( - + diff --git a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/__snapshots__/fetcher.test.ts.snap b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/__snapshots__/fetcher.test.ts.snap index 18ce29982b6167..580cafff95e0cd 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/__snapshots__/fetcher.test.ts.snap +++ b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/__snapshots__/fetcher.test.ts.snap @@ -6,7 +6,7 @@ Array [ Object { "body": Object { "aggs": Object { - "transactions": Object { + "transaction_groups": Object { "aggs": Object { "avg": Object { "avg": Object { @@ -42,12 +42,24 @@ Array [ }, }, }, - "terms": Object { - "field": "transaction.name", - "order": Object { - "sum": "desc", - }, - "size": 100, + "composite": Object { + "size": 10000, + "sources": Array [ + Object { + "service": Object { + "terms": Object { + "field": "service.name", + }, + }, + }, + Object { + "transaction": Object { + "terms": Object { + "field": "transaction.name", + }, + }, + }, + ], }, }, }, @@ -104,7 +116,7 @@ Array [ Object { "body": Object { "aggs": Object { - "transactions": Object { + "transaction_groups": Object { "aggs": Object { "avg": Object { "avg": Object { @@ -140,12 +152,22 @@ Array [ }, }, }, + "composite": Object { + "size": 10000, + "sources": Array [ + Object { + "transaction": Object { + "terms": Object { + "field": "transaction.name", + }, + }, + }, + ], + }, + }, + "transactions": Object { "terms": Object { "field": "transaction.name", - "order": Object { - "sum": "desc", - }, - "size": 100, }, }, }, diff --git a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/__snapshots__/queries.test.ts.snap b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/__snapshots__/queries.test.ts.snap index e33255b5baa554..58fbe664cccab0 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/__snapshots__/queries.test.ts.snap +++ b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/__snapshots__/queries.test.ts.snap @@ -4,7 +4,7 @@ exports[`transaction group queries fetches top traces 1`] = ` Object { "body": Object { "aggs": Object { - "transactions": Object { + "transaction_groups": Object { "aggs": Object { "avg": Object { "avg": Object { @@ -40,12 +40,24 @@ Object { }, }, }, - "terms": Object { - "field": "transaction.name", - "order": Object { - "sum": "desc", - }, - "size": "myIndex", + "composite": Object { + "size": 10000, + "sources": Array [ + Object { + "service": Object { + "terms": Object { + "field": "service.name", + }, + }, + }, + Object { + "transaction": Object { + "terms": Object { + "field": "transaction.name", + }, + }, + }, + ], }, }, }, @@ -98,7 +110,7 @@ exports[`transaction group queries fetches top transactions 1`] = ` Object { "body": Object { "aggs": Object { - "transactions": Object { + "transaction_groups": Object { "aggs": Object { "avg": Object { "avg": Object { @@ -134,12 +146,22 @@ Object { }, }, }, + "composite": Object { + "size": 10000, + "sources": Array [ + Object { + "transaction": Object { + "terms": Object { + "field": "transaction.name", + }, + }, + }, + ], + }, + }, + "transactions": Object { "terms": Object { "field": "transaction.name", - "order": Object { - "sum": "desc", - }, - "size": "myIndex", }, }, }, diff --git a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/__snapshots__/transform.test.ts.snap b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/__snapshots__/transform.test.ts.snap index 2d8b16e95f7694..66b805ab2efc15 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/__snapshots__/transform.test.ts.snap +++ b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/__snapshots__/transform.test.ts.snap @@ -3,12 +3,12 @@ exports[`transactionGroupsTransformer should match snapshot 1`] = ` Array [ Object { - "averageResponseTime": 255966.30555555556, - "impact": 4.3693406535517445, - "name": "POST /api/orders", - "p95": 320238.5, + "averageResponseTime": 48021.972616494, + "impact": 100, + "name": "GET /api", + "p95": 67138.18364917398, "sample": Object { - "@timestamp": "2018-11-18T20:43:32.010Z", + "@timestamp": "2018-11-18T20:53:44.070Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -16,52 +16,50 @@ Array [ }, "context": Object { "custom": Object { - "containerId": 4669, + "containerId": 5176, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 2413, + "pid": 3756, "ppid": 1, "title": "node /app/server.js", }, "request": Object { - "body": "[REDACTED]", "headers": Object { - "accept": "application/json", - "connection": "close", - "content-length": "129", - "content-type": "application/json", + "accept": "*/*", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "elastic-apm-traceparent": "00-86c68779d8a65b06fb78e770ffc436a5-4aaea53dc1791183-01", "host": "opbeans-node:3000", - "user-agent": "workload/2.4.3", + "user-agent": "python-requests/2.20.0", }, "http_version": "1.1", - "method": "POST", + "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.10", + "remote_address": "::ffff:172.18.0.6", }, "url": Object { - "full": "http://opbeans-node:3000/api/orders", + "full": "http://opbeans-node:3000/api/types/3", "hostname": "opbeans-node", - "pathname": "/api/orders", + "pathname": "/api/types/3", "port": "3000", "protocol": "http:", - "raw": "/api/orders", + "raw": "/api/types/3", }, }, "response": Object { "headers": Object { "connection": "close", - "content-length": "13", - "content-type": "application/json; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:43:32 GMT", - "etag": "W/\\"d-g9K2iK4ordyN88lGL4LmPlYNfhc\\"", + "content-type": "application/json;charset=UTF-8", + "date": "Sun, 18 Nov 2018 20:53:43 GMT", + "transfer-encoding": "chunked", "x-powered-by": "Express", }, - "status_code": 200, + "status_code": 404, }, "service": Object { "agent": Object { @@ -101,48 +99,48 @@ baz", "host": Object { "name": "b359e3afece8", }, + "parent": Object { + "id": "4aaea53dc1791183", + }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542573812010006, + "us": 1542574424070007, }, "trace": Object { - "id": "2b1252a338249daeecf6afb0c236e31b", + "id": "86c68779d8a65b06fb78e770ffc436a5", }, "transaction": Object { "duration": Object { - "us": 291572, + "us": 8684, }, - "id": "2c9f39e9ec4a0111", - "name": "POST /api/orders", - "result": "HTTP 2xx", + "id": "a78bca581dcd8ff8", + "name": "GET /api", + "result": "HTTP 4xx", "sampled": true, "span_count": Object { - "started": 16, + "started": 1, }, "type": "request", }, }, - "transactionsPerMinute": 5684.210526315789, + "transactionsPerMinute": 691926.3157894736, }, Object { - "averageResponseTime": 48021.972616494, - "impact": 100, - "name": "GET /api", - "p95": 67138.18364917398, + "averageResponseTime": 2651.8784461553205, + "impact": 15.770246496477105, + "name": "GET static file", + "p95": 6140.579335038363, "sample": Object { - "@timestamp": "2018-11-18T20:53:44.070Z", + "@timestamp": "2018-11-18T20:53:43.304Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", "version": "7.0.0-alpha1", }, "context": Object { - "custom": Object { - "containerId": 5176, - }, "process": Object { "argv": Array [ "/usr/local/bin/node", @@ -155,36 +153,37 @@ baz", "request": Object { "headers": Object { "accept": "*/*", - "accept-encoding": "gzip, deflate", - "connection": "keep-alive", - "elastic-apm-traceparent": "00-86c68779d8a65b06fb78e770ffc436a5-4aaea53dc1791183-01", "host": "opbeans-node:3000", - "user-agent": "python-requests/2.20.0", + "user-agent": "curl/7.38.0", }, "http_version": "1.1", "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.6", + "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://opbeans-node:3000/api/types/3", + "full": "http://opbeans-node:3000/", "hostname": "opbeans-node", - "pathname": "/api/types/3", + "pathname": "/", "port": "3000", "protocol": "http:", - "raw": "/api/types/3", + "raw": "/", }, }, "response": Object { "headers": Object { - "connection": "close", - "content-type": "application/json;charset=UTF-8", + "accept-ranges": "bytes", + "cache-control": "public, max-age=0", + "connection": "keep-alive", + "content-length": "640", + "content-type": "text/html; charset=UTF-8", "date": "Sun, 18 Nov 2018 20:53:43 GMT", - "transfer-encoding": "chunked", + "etag": "W/\\"280-1670775e878\\"", + "last-modified": "Mon, 12 Nov 2018 10:27:07 GMT", "x-powered-by": "Express", }, - "status_code": 404, + "status_code": 200, }, "service": Object { "agent": Object { @@ -207,59 +206,43 @@ baz", "ip": "172.18.0.10", "platform": "linux", }, - "tags": Object { - "foo": "bar", - "lorem": "ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus, ipsum id scelerisque consequat, enim leo vulputate massa, vel ultricies ante neque ac risus. Curabitur tincidunt vitae sapien id pulvinar. Mauris eu vestibulum tortor. Integer sit amet lorem fringilla, egestas tellus vitae, vulputate purus. Nulla feugiat blandit nunc et semper. Morbi purus libero, mattis sed mauris non, euismod iaculis lacus. Curabitur eleifend ante eros, non faucibus velit lacinia id. Duis posuere libero augue, at dignissim urna consectetur eget. Praesent eu congue est, iaculis finibus augue.", - "multi-line": "foo -bar -baz", - "this-is-a-very-long-tag-name-without-any-spaces": "test", - }, - "user": Object { - "email": "kimchy@elastic.co", - "id": "42", - "username": "kimchy", - }, }, "host": Object { "name": "b359e3afece8", }, - "parent": Object { - "id": "4aaea53dc1791183", - }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542574424070007, + "us": 1542574423304006, }, "trace": Object { - "id": "86c68779d8a65b06fb78e770ffc436a5", + "id": "b303d2a4a007946b63b9db7fafe639a0", }, "transaction": Object { "duration": Object { - "us": 8684, + "us": 1801, }, - "id": "a78bca581dcd8ff8", - "name": "GET /api", - "result": "HTTP 4xx", + "id": "2869c13633534be5", + "name": "GET static file", + "result": "HTTP 2xx", "sampled": true, "span_count": Object { - "started": 1, + "started": 0, }, "type": "request", }, }, - "transactionsPerMinute": 691926.3157894736, + "transactionsPerMinute": 1977031.5789473683, }, Object { - "averageResponseTime": 33265.03326147213, - "impact": 10.256357027376065, - "name": "GET /api/orders", - "p95": 58827.489999999976, + "averageResponseTime": 32554.36257814184, + "impact": 14.344171563678346, + "name": "GET /api/stats", + "p95": 59356.73611111111, "sample": Object { - "@timestamp": "2018-11-18T20:53:40.973Z", + "@timestamp": "2018-11-18T20:53:42.560Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -267,7 +250,7 @@ baz", }, "context": Object { "custom": Object { - "containerId": 408, + "containerId": 207, }, "process": Object { "argv": Array [ @@ -280,35 +263,38 @@ baz", }, "request": Object { "headers": Object { - "connection": "close", + "accept": "*/*", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "elastic-apm-traceparent": "00-63ccc3b0929dafb7f2fbcabdc7f7af25-821a787e73ab1563-01", "host": "opbeans-node:3000", - "user-agent": "workload/2.4.3", + "if-none-match": "W/\\"77-uxKJrX5GSMJJWTKh3orUFAEVxSs\\"", + "referer": "http://opbeans-node:3000/dashboard", + "user-agent": "Chromeless 1.4.0", }, "http_version": "1.1", "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.10", + "remote_address": "::ffff:172.18.0.7", }, "url": Object { - "full": "http://opbeans-node:3000/api/orders", + "full": "http://opbeans-node:3000/api/stats", "hostname": "opbeans-node", - "pathname": "/api/orders", + "pathname": "/api/stats", "port": "3000", "protocol": "http:", - "raw": "/api/orders", + "raw": "/api/stats", }, }, "response": Object { "headers": Object { - "connection": "close", - "content-length": "103612", - "content-type": "application/json; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:53:40 GMT", - "etag": "W/\\"194bc-cOw6+iRf7XCeqMXHrle3IOig7tY\\"", + "connection": "keep-alive", + "date": "Sun, 18 Nov 2018 20:53:42 GMT", + "etag": "W/\\"77-uxKJrX5GSMJJWTKh3orUFAEVxSs\\"", "x-powered-by": "Express", }, - "status_code": 200, + "status_code": 304, }, "service": Object { "agent": Object { @@ -348,39 +334,42 @@ baz", "host": Object { "name": "b359e3afece8", }, + "parent": Object { + "id": "821a787e73ab1563", + }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542574420973006, + "us": 1542574422560002, }, "trace": Object { - "id": "0afce85f593cbbdd09949936fe964f0f", + "id": "63ccc3b0929dafb7f2fbcabdc7f7af25", }, "transaction": Object { "duration": Object { - "us": 23040, + "us": 28753, }, - "id": "89f200353eb50539", - "name": "GET /api/orders", - "result": "HTTP 2xx", + "id": "fb754e7628da2fb5", + "name": "GET /api/stats", + "result": "HTTP 3xx", "sampled": true, "span_count": Object { - "started": 2, + "started": 7, }, "type": "request", }, }, - "transactionsPerMinute": 102536.84210526315, + "transactionsPerMinute": 146494.73684210525, }, Object { - "averageResponseTime": 32900.72714285714, - "impact": 2.1791207411745854, - "name": "GET /log-message", - "p95": 40444, + "averageResponseTime": 32159.926322043968, + "impact": 10.27904952170656, + "name": "GET /api/customers", + "p95": 59845.85714285714, "sample": Object { - "@timestamp": "2018-11-18T20:49:09.225Z", + "@timestamp": "2018-11-18T20:53:21.180Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -388,48 +377,51 @@ baz", }, "context": Object { "custom": Object { - "containerId": 321, + "containerId": 2531, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3142, + "pid": 3710, "ppid": 1, "title": "node /app/server.js", }, "request": Object { "headers": Object { - "connection": "close", + "accept": "*/*", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "elastic-apm-traceparent": "00-541025da8ecc2f51f21c1a4ad6992b77-ca18d9d4c3879519-01", "host": "opbeans-node:3000", - "user-agent": "workload/2.4.3", + "user-agent": "python-requests/2.20.0", }, "http_version": "1.1", "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.10", + "remote_address": "::ffff:172.18.0.6", }, "url": Object { - "full": "http://opbeans-node:3000/log-message", + "full": "http://opbeans-node:3000/api/customers", "hostname": "opbeans-node", - "pathname": "/log-message", + "pathname": "/api/customers", "port": "3000", "protocol": "http:", - "raw": "/log-message", + "raw": "/api/customers", }, }, "response": Object { "headers": Object { - "connection": "close", - "content-length": "24", - "content-type": "text/html; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:49:09 GMT", - "etag": "W/\\"18-MS3VbhH7auHMzO0fUuNF6v14N/M\\"", + "connection": "keep-alive", + "content-length": "186769", + "content-type": "application/json; charset=utf-8", + "date": "Sun, 18 Nov 2018 20:53:21 GMT", + "etag": "W/\\"2d991-yG3J8W/roH7fSxXTudZrO27Ax9s\\"", "x-powered-by": "Express", }, - "status_code": 500, + "status_code": 200, }, "service": Object { "agent": Object { @@ -469,39 +461,42 @@ baz", "host": Object { "name": "b359e3afece8", }, + "parent": Object { + "id": "ca18d9d4c3879519", + }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542574149225004, + "us": 1542574401180002, }, "trace": Object { - "id": "ba18b741cdd3ac83eca89a5fede47577", + "id": "541025da8ecc2f51f21c1a4ad6992b77", }, "transaction": Object { "duration": Object { - "us": 32381, + "us": 18077, }, - "id": "b9a8f96d7554d09f", - "name": "GET /log-message", - "result": "HTTP 5xx", + "id": "94852b9dd1075982", + "name": "GET /api/customers", + "result": "HTTP 2xx", "sampled": true, "span_count": Object { - "started": 0, + "started": 2, }, "type": "request", }, }, - "transactionsPerMinute": 22105.263157894737, + "transactionsPerMinute": 106294.73684210525, }, Object { - "averageResponseTime": 32554.36257814184, - "impact": 14.344171563678346, - "name": "GET /api/stats", - "p95": 59356.73611111111, + "averageResponseTime": 33265.03326147213, + "impact": 10.256357027376065, + "name": "GET /api/orders", + "p95": 58827.489999999976, "sample": Object { - "@timestamp": "2018-11-18T20:53:42.560Z", + "@timestamp": "2018-11-18T20:53:40.973Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -509,7 +504,7 @@ baz", }, "context": Object { "custom": Object { - "containerId": 207, + "containerId": 408, }, "process": Object { "argv": Array [ @@ -522,38 +517,35 @@ baz", }, "request": Object { "headers": Object { - "accept": "*/*", - "accept-encoding": "gzip, deflate", - "connection": "keep-alive", - "elastic-apm-traceparent": "00-63ccc3b0929dafb7f2fbcabdc7f7af25-821a787e73ab1563-01", + "connection": "close", "host": "opbeans-node:3000", - "if-none-match": "W/\\"77-uxKJrX5GSMJJWTKh3orUFAEVxSs\\"", - "referer": "http://opbeans-node:3000/dashboard", - "user-agent": "Chromeless 1.4.0", + "user-agent": "workload/2.4.3", }, "http_version": "1.1", "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.7", + "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://opbeans-node:3000/api/stats", + "full": "http://opbeans-node:3000/api/orders", "hostname": "opbeans-node", - "pathname": "/api/stats", + "pathname": "/api/orders", "port": "3000", "protocol": "http:", - "raw": "/api/stats", + "raw": "/api/orders", }, }, "response": Object { "headers": Object { - "connection": "keep-alive", - "date": "Sun, 18 Nov 2018 20:53:42 GMT", - "etag": "W/\\"77-uxKJrX5GSMJJWTKh3orUFAEVxSs\\"", + "connection": "close", + "content-length": "103612", + "content-type": "application/json; charset=utf-8", + "date": "Sun, 18 Nov 2018 20:53:40 GMT", + "etag": "W/\\"194bc-cOw6+iRf7XCeqMXHrle3IOig7tY\\"", "x-powered-by": "Express", }, - "status_code": 304, + "status_code": 200, }, "service": Object { "agent": Object { @@ -593,42 +585,39 @@ baz", "host": Object { "name": "b359e3afece8", }, - "parent": Object { - "id": "821a787e73ab1563", - }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542574422560002, + "us": 1542574420973006, }, "trace": Object { - "id": "63ccc3b0929dafb7f2fbcabdc7f7af25", + "id": "0afce85f593cbbdd09949936fe964f0f", }, "transaction": Object { "duration": Object { - "us": 28753, - }, - "id": "fb754e7628da2fb5", - "name": "GET /api/stats", - "result": "HTTP 3xx", + "us": 23040, + }, + "id": "89f200353eb50539", + "name": "GET /api/orders", + "result": "HTTP 2xx", "sampled": true, "span_count": Object { - "started": 7, + "started": 2, }, "type": "request", }, }, - "transactionsPerMinute": 146494.73684210525, + "transactionsPerMinute": 102536.84210526315, }, Object { - "averageResponseTime": 32387.73641304348, - "impact": 2.2558112380477584, - "name": "GET /log-error", - "p95": 40061.1, + "averageResponseTime": 27516.89144558744, + "impact": 9.651458992731666, + "name": "GET /api/products/top", + "p95": 56064.679999999986, "sample": Object { - "@timestamp": "2018-11-18T20:52:51.462Z", + "@timestamp": "2018-11-18T20:52:57.316Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -636,48 +625,52 @@ baz", }, "context": Object { "custom": Object { - "containerId": 4877, + "containerId": 5113, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3659, + "pid": 3686, "ppid": 1, "title": "node /app/server.js", }, "request": Object { "headers": Object { - "connection": "close", + "accept": "*/*", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "elastic-apm-traceparent": "00-74f12e705936d66350f4741ebeb55189-fcebe94cd2136215-01", "host": "opbeans-node:3000", - "user-agent": "workload/2.4.3", + "referer": "http://opbeans-node:3000/dashboard", + "user-agent": "Chromeless 1.4.0", }, "http_version": "1.1", "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.10", + "remote_address": "::ffff:172.18.0.7", }, "url": Object { - "full": "http://opbeans-node:3000/log-error", + "full": "http://opbeans-node:3000/api/products/top", "hostname": "opbeans-node", - "pathname": "/log-error", + "pathname": "/api/products/top", "port": "3000", "protocol": "http:", - "raw": "/log-error", + "raw": "/api/products/top", }, }, "response": Object { "headers": Object { - "connection": "close", - "content-length": "24", - "content-type": "text/html; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:52:51 GMT", - "etag": "W/\\"18-MS3VbhH7auHMzO0fUuNF6v14N/M\\"", + "connection": "keep-alive", + "content-length": "282", + "content-type": "application/json; charset=utf-8", + "date": "Sun, 18 Nov 2018 20:52:57 GMT", + "etag": "W/\\"11a-lcI9zuMZYYsDRpEZgYqDYr96cKM\\"", "x-powered-by": "Express", }, - "status_code": 500, + "status_code": 200, }, "service": Object { "agent": Object { @@ -717,39 +710,42 @@ baz", "host": Object { "name": "b359e3afece8", }, + "parent": Object { + "id": "fcebe94cd2136215", + }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542574371462005, + "us": 1542574377316005, }, "trace": Object { - "id": "15366d65659b5fc8f67ff127391b3aff", + "id": "74f12e705936d66350f4741ebeb55189", }, "transaction": Object { "duration": Object { - "us": 33367, + "us": 48781, }, - "id": "ec9c465c5042ded8", - "name": "GET /log-error", - "result": "HTTP 5xx", + "id": "be4bd5475d5d9e6f", + "name": "GET /api/products/top", + "result": "HTTP 2xx", "sampled": true, "span_count": Object { - "started": 0, + "started": 4, }, "type": "request", }, }, - "transactionsPerMinute": 23242.105263157893, + "transactionsPerMinute": 116652.63157894736, }, Object { - "averageResponseTime": 32159.926322043968, - "impact": 10.27904952170656, - "name": "GET /api/customers", - "p95": 59845.85714285714, + "averageResponseTime": 12683.190864600327, + "impact": 4.4239778504968, + "name": "GET /api/products", + "p95": 35009.67999999999, "sample": Object { - "@timestamp": "2018-11-18T20:53:21.180Z", + "@timestamp": "2018-11-18T20:53:43.477Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -757,48 +753,45 @@ baz", }, "context": Object { "custom": Object { - "containerId": 2531, + "containerId": 2857, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3710, + "pid": 3756, "ppid": 1, "title": "node /app/server.js", }, "request": Object { "headers": Object { - "accept": "*/*", - "accept-encoding": "gzip, deflate", - "connection": "keep-alive", - "elastic-apm-traceparent": "00-541025da8ecc2f51f21c1a4ad6992b77-ca18d9d4c3879519-01", + "connection": "close", "host": "opbeans-node:3000", - "user-agent": "python-requests/2.20.0", + "user-agent": "workload/2.4.3", }, "http_version": "1.1", "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.6", + "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://opbeans-node:3000/api/customers", + "full": "http://opbeans-node:3000/api/products", "hostname": "opbeans-node", - "pathname": "/api/customers", + "pathname": "/api/products", "port": "3000", "protocol": "http:", - "raw": "/api/customers", + "raw": "/api/products", }, }, "response": Object { "headers": Object { - "connection": "keep-alive", - "content-length": "186769", + "connection": "close", + "content-length": "1023", "content-type": "application/json; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:53:21 GMT", - "etag": "W/\\"2d991-yG3J8W/roH7fSxXTudZrO27Ax9s\\"", + "date": "Sun, 18 Nov 2018 20:53:43 GMT", + "etag": "W/\\"3ff-VyOxcDApb+a/lnjkm9FeTOGSDrs\\"", "x-powered-by": "Express", }, "status_code": 200, @@ -841,25 +834,22 @@ baz", "host": Object { "name": "b359e3afece8", }, - "parent": Object { - "id": "ca18d9d4c3879519", - }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542574401180002, + "us": 1542574423477006, }, "trace": Object { - "id": "541025da8ecc2f51f21c1a4ad6992b77", + "id": "bee00a8efb523ca4b72adad57f7caba3", }, "transaction": Object { "duration": Object { - "us": 18077, + "us": 6915, }, - "id": "94852b9dd1075982", - "name": "GET /api/customers", + "id": "d8fc6d3b8707b64c", + "name": "GET /api/products", "result": "HTTP 2xx", "sampled": true, "span_count": Object { @@ -868,15 +858,15 @@ baz", "type": "request", }, }, - "transactionsPerMinute": 106294.73684210525, + "transactionsPerMinute": 116147.36842105263, }, Object { - "averageResponseTime": 27516.89144558744, - "impact": 9.651458992731666, - "name": "GET /api/products/top", - "p95": 56064.679999999986, + "averageResponseTime": 255966.30555555556, + "impact": 4.3693406535517445, + "name": "POST /api/orders", + "p95": 320238.5, "sample": Object { - "@timestamp": "2018-11-18T20:52:57.316Z", + "@timestamp": "2018-11-18T20:43:32.010Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -884,49 +874,49 @@ baz", }, "context": Object { "custom": Object { - "containerId": 5113, + "containerId": 4669, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3686, + "pid": 2413, "ppid": 1, "title": "node /app/server.js", }, "request": Object { + "body": "[REDACTED]", "headers": Object { - "accept": "*/*", - "accept-encoding": "gzip, deflate", - "connection": "keep-alive", - "elastic-apm-traceparent": "00-74f12e705936d66350f4741ebeb55189-fcebe94cd2136215-01", + "accept": "application/json", + "connection": "close", + "content-length": "129", + "content-type": "application/json", "host": "opbeans-node:3000", - "referer": "http://opbeans-node:3000/dashboard", - "user-agent": "Chromeless 1.4.0", + "user-agent": "workload/2.4.3", }, "http_version": "1.1", - "method": "GET", + "method": "POST", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.7", + "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://opbeans-node:3000/api/products/top", + "full": "http://opbeans-node:3000/api/orders", "hostname": "opbeans-node", - "pathname": "/api/products/top", + "pathname": "/api/orders", "port": "3000", "protocol": "http:", - "raw": "/api/products/top", + "raw": "/api/orders", }, }, "response": Object { "headers": Object { - "connection": "keep-alive", - "content-length": "282", + "connection": "close", + "content-length": "13", "content-type": "application/json; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:52:57 GMT", - "etag": "W/\\"11a-lcI9zuMZYYsDRpEZgYqDYr96cKM\\"", + "date": "Sun, 18 Nov 2018 20:43:32 GMT", + "etag": "W/\\"d-g9K2iK4ordyN88lGL4LmPlYNfhc\\"", "x-powered-by": "Express", }, "status_code": 200, @@ -969,42 +959,39 @@ baz", "host": Object { "name": "b359e3afece8", }, - "parent": Object { - "id": "fcebe94cd2136215", - }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542574377316005, + "us": 1542573812010006, }, "trace": Object { - "id": "74f12e705936d66350f4741ebeb55189", + "id": "2b1252a338249daeecf6afb0c236e31b", }, "transaction": Object { "duration": Object { - "us": 48781, + "us": 291572, }, - "id": "be4bd5475d5d9e6f", - "name": "GET /api/products/top", + "id": "2c9f39e9ec4a0111", + "name": "POST /api/orders", "result": "HTTP 2xx", "sampled": true, "span_count": Object { - "started": 4, + "started": 16, }, "type": "request", }, }, - "transactionsPerMinute": 116652.63157894736, + "transactionsPerMinute": 5684.210526315789, }, Object { - "averageResponseTime": 21331.714285714286, - "impact": 0.28817487960409877, - "name": "POST /api", - "p95": 30938, + "averageResponseTime": 17189.329210275926, + "impact": 3.424381787142002, + "name": "GET /api/products/:id/customers", + "p95": 39284.79999999999, "sample": Object { - "@timestamp": "2018-11-18T20:29:42.751Z", + "@timestamp": "2018-11-18T20:48:24.769Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -1012,50 +999,51 @@ baz", }, "context": Object { "custom": Object { - "containerId": 2927, + "containerId": 1735, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 546, + "pid": 3100, "ppid": 1, "title": "node /app/server.js", }, "request": Object { - "body": "[REDACTED]", "headers": Object { - "accept": "application/json", - "connection": "close", - "content-length": "129", - "content-type": "application/json", + "accept": "*/*", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "elastic-apm-traceparent": "00-28f178c354d17f400dea04bc4a7b3c57-68f5d1607cac7779-01", "host": "opbeans-node:3000", - "user-agent": "workload/2.4.3", + "user-agent": "python-requests/2.20.0", }, "http_version": "1.1", - "method": "POST", + "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.10", + "remote_address": "::ffff:172.18.0.6", }, "url": Object { - "full": "http://opbeans-node:3000/api/orders", + "full": "http://opbeans-node:3000/api/products/2/customers", "hostname": "opbeans-node", - "pathname": "/api/orders", + "pathname": "/api/products/2/customers", "port": "3000", "protocol": "http:", - "raw": "/api/orders", + "raw": "/api/products/2/customers", }, }, "response": Object { "headers": Object { - "connection": "close", - "content-length": "0", - "date": "Sun, 18 Nov 2018 20:29:42 GMT", + "connection": "keep-alive", + "content-length": "186570", + "content-type": "application/json; charset=utf-8", + "date": "Sun, 18 Nov 2018 20:48:24 GMT", + "etag": "W/\\"2d8ca-Z9NzuHyGyxwtzpOkcIxBvzm24iw\\"", "x-powered-by": "Express", }, - "status_code": 400, + "status_code": 200, }, "service": Object { "agent": Object { @@ -1095,23 +1083,26 @@ baz", "host": Object { "name": "b359e3afece8", }, + "parent": Object { + "id": "68f5d1607cac7779", + }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542572982751005, + "us": 1542574104769029, }, "trace": Object { - "id": "8ed4d94ec8fc11b1ea1b0aa59c2320ff", + "id": "28f178c354d17f400dea04bc4a7b3c57", }, "transaction": Object { "duration": Object { - "us": 21083, + "us": 49338, }, - "id": "d67c2f7aa897110c", - "name": "POST /api", - "result": "HTTP 4xx", + "id": "2a87ae20ad04ee0c", + "name": "GET /api/products/:id/customers", + "result": "HTTP 2xx", "sampled": true, "span_count": Object { "started": 1, @@ -1119,15 +1110,15 @@ baz", "type": "request", }, }, - "transactionsPerMinute": 4642.105263157894, + "transactionsPerMinute": 66378.94736842105, }, Object { - "averageResponseTime": 17189.329210275926, - "impact": 3.424381787142002, - "name": "GET /api/products/:id/customers", - "p95": 39284.79999999999, + "averageResponseTime": 11257.757916666667, + "impact": 2.558180605569336, + "name": "GET /api/types", + "p95": 35222.944444444445, "sample": Object { - "@timestamp": "2018-11-18T20:48:24.769Z", + "@timestamp": "2018-11-18T20:53:44.978Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -1135,48 +1126,45 @@ baz", }, "context": Object { "custom": Object { - "containerId": 1735, + "containerId": 2193, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3100, + "pid": 3756, "ppid": 1, "title": "node /app/server.js", }, "request": Object { "headers": Object { - "accept": "*/*", - "accept-encoding": "gzip, deflate", - "connection": "keep-alive", - "elastic-apm-traceparent": "00-28f178c354d17f400dea04bc4a7b3c57-68f5d1607cac7779-01", + "connection": "close", "host": "opbeans-node:3000", - "user-agent": "python-requests/2.20.0", + "user-agent": "workload/2.4.3", }, "http_version": "1.1", "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.6", + "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://opbeans-node:3000/api/products/2/customers", + "full": "http://opbeans-node:3000/api/types", "hostname": "opbeans-node", - "pathname": "/api/products/2/customers", + "pathname": "/api/types", "port": "3000", "protocol": "http:", - "raw": "/api/products/2/customers", + "raw": "/api/types", }, }, "response": Object { "headers": Object { - "connection": "keep-alive", - "content-length": "186570", + "connection": "close", + "content-length": "112", "content-type": "application/json; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:48:24 GMT", - "etag": "W/\\"2d8ca-Z9NzuHyGyxwtzpOkcIxBvzm24iw\\"", + "date": "Sun, 18 Nov 2018 20:53:44 GMT", + "etag": "W/\\"70-1z6hT7P1WHgBgS/BeUEVeHhOCQU\\"", "x-powered-by": "Express", }, "status_code": 200, @@ -1219,42 +1207,39 @@ baz", "host": Object { "name": "b359e3afece8", }, - "parent": Object { - "id": "68f5d1607cac7779", - }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542574104769029, + "us": 1542574424978005, }, "trace": Object { - "id": "28f178c354d17f400dea04bc4a7b3c57", + "id": "0d84126973411c19b470f2d9eea958d3", }, "transaction": Object { "duration": Object { - "us": 49338, + "us": 7891, }, - "id": "2a87ae20ad04ee0c", - "name": "GET /api/products/:id/customers", + "id": "0f10668e4fb3adc7", + "name": "GET /api/types", "result": "HTTP 2xx", "sampled": true, "span_count": Object { - "started": 1, + "started": 2, }, "type": "request", }, }, - "transactionsPerMinute": 66378.94736842105, + "transactionsPerMinute": 75789.47368421052, }, Object { - "averageResponseTime": 12763.68806073154, - "impact": 1.7479924334286208, - "name": "GET /api/types/:id", - "p95": 30576.749999999996, + "averageResponseTime": 3504.5108924806746, + "impact": 2.3600993453143766, + "name": "GET *", + "p95": 11431.738095238095, "sample": Object { - "@timestamp": "2018-11-18T20:53:35.967Z", + "@timestamp": "2018-11-18T20:53:42.493Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -1262,7 +1247,7 @@ baz", }, "context": Object { "custom": Object { - "containerId": 5345, + "containerId": 6446, }, "process": Object { "argv": Array [ @@ -1275,35 +1260,41 @@ baz", }, "request": Object { "headers": Object { - "connection": "close", + "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", "host": "opbeans-node:3000", - "user-agent": "workload/2.4.3", + "if-modified-since": "Mon, 12 Nov 2018 10:27:07 GMT", + "if-none-match": "W/\\"280-1670775e878\\"", + "upgrade-insecure-requests": "1", + "user-agent": "Chromeless 1.4.0", }, "http_version": "1.1", "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.10", + "remote_address": "::ffff:172.18.0.7", }, "url": Object { - "full": "http://opbeans-node:3000/api/types/1", + "full": "http://opbeans-node:3000/dashboard", "hostname": "opbeans-node", - "pathname": "/api/types/1", + "pathname": "/dashboard", "port": "3000", "protocol": "http:", - "raw": "/api/types/1", + "raw": "/dashboard", }, }, "response": Object { "headers": Object { - "connection": "close", - "content-length": "217", - "content-type": "application/json; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:53:35 GMT", - "etag": "W/\\"d9-cebOOHODBQMZd1wt+ZZBaSPgQLQ\\"", + "accept-ranges": "bytes", + "cache-control": "public, max-age=0", + "connection": "keep-alive", + "date": "Sun, 18 Nov 2018 20:53:42 GMT", + "etag": "W/\\"280-1670775e878\\"", + "last-modified": "Mon, 12 Nov 2018 10:27:07 GMT", "x-powered-by": "Express", }, - "status_code": 200, + "status_code": 304, }, "service": Object { "agent": Object { @@ -1348,34 +1339,34 @@ baz", "name": "transaction", }, "timestamp": Object { - "us": 1542574415967005, + "us": 1542574422493006, }, "trace": Object { - "id": "2223b30b5cbaf2e221fcf70ac6d9abbe", + "id": "7efb6ade88cdea20cd96ca482681cde7", }, "transaction": Object { "duration": Object { - "us": 13064, + "us": 1901, }, - "id": "053436abacdec0a4", - "name": "GET /api/types/:id", - "result": "HTTP 2xx", + "id": "f5fc4621949b63fb", + "name": "GET *", + "result": "HTTP 3xx", "sampled": true, "span_count": Object { - "started": 2, + "started": 0, }, "type": "request", }, }, - "transactionsPerMinute": 45757.8947368421, + "transactionsPerMinute": 224684.21052631576, }, Object { - "averageResponseTime": 12683.190864600327, - "impact": 4.4239778504968, - "name": "GET /api/products", - "p95": 35009.67999999999, + "averageResponseTime": 32387.73641304348, + "impact": 2.2558112380477584, + "name": "GET /log-error", + "p95": 40061.1, "sample": Object { - "@timestamp": "2018-11-18T20:53:43.477Z", + "@timestamp": "2018-11-18T20:52:51.462Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -1383,14 +1374,14 @@ baz", }, "context": Object { "custom": Object { - "containerId": 2857, + "containerId": 4877, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3756, + "pid": 3659, "ppid": 1, "title": "node /app/server.js", }, @@ -1407,24 +1398,24 @@ baz", "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://opbeans-node:3000/api/products", + "full": "http://opbeans-node:3000/log-error", "hostname": "opbeans-node", - "pathname": "/api/products", + "pathname": "/log-error", "port": "3000", "protocol": "http:", - "raw": "/api/products", + "raw": "/log-error", }, }, "response": Object { "headers": Object { "connection": "close", - "content-length": "1023", - "content-type": "application/json; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:53:43 GMT", - "etag": "W/\\"3ff-VyOxcDApb+a/lnjkm9FeTOGSDrs\\"", + "content-length": "24", + "content-type": "text/html; charset=utf-8", + "date": "Sun, 18 Nov 2018 20:52:51 GMT", + "etag": "W/\\"18-MS3VbhH7auHMzO0fUuNF6v14N/M\\"", "x-powered-by": "Express", }, - "status_code": 200, + "status_code": 500, }, "service": Object { "agent": Object { @@ -1469,34 +1460,34 @@ baz", "name": "transaction", }, "timestamp": Object { - "us": 1542574423477006, + "us": 1542574371462005, }, "trace": Object { - "id": "bee00a8efb523ca4b72adad57f7caba3", + "id": "15366d65659b5fc8f67ff127391b3aff", }, "transaction": Object { "duration": Object { - "us": 6915, + "us": 33367, }, - "id": "d8fc6d3b8707b64c", - "name": "GET /api/products", - "result": "HTTP 2xx", + "id": "ec9c465c5042ded8", + "name": "GET /log-error", + "result": "HTTP 5xx", "sampled": true, "span_count": Object { - "started": 2, + "started": 0, }, "type": "request", }, }, - "transactionsPerMinute": 116147.36842105263, + "transactionsPerMinute": 23242.105263157893, }, Object { - "averageResponseTime": 11257.757916666667, - "impact": 2.558180605569336, - "name": "GET /api/types", - "p95": 35222.944444444445, + "averageResponseTime": 32900.72714285714, + "impact": 2.1791207411745854, + "name": "GET /log-message", + "p95": 40444, "sample": Object { - "@timestamp": "2018-11-18T20:53:44.978Z", + "@timestamp": "2018-11-18T20:49:09.225Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -1504,14 +1495,14 @@ baz", }, "context": Object { "custom": Object { - "containerId": 2193, + "containerId": 321, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3756, + "pid": 3142, "ppid": 1, "title": "node /app/server.js", }, @@ -1528,24 +1519,24 @@ baz", "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://opbeans-node:3000/api/types", + "full": "http://opbeans-node:3000/log-message", "hostname": "opbeans-node", - "pathname": "/api/types", + "pathname": "/log-message", "port": "3000", "protocol": "http:", - "raw": "/api/types", + "raw": "/log-message", }, }, "response": Object { "headers": Object { "connection": "close", - "content-length": "112", - "content-type": "application/json; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:53:44 GMT", - "etag": "W/\\"70-1z6hT7P1WHgBgS/BeUEVeHhOCQU\\"", + "content-length": "24", + "content-type": "text/html; charset=utf-8", + "date": "Sun, 18 Nov 2018 20:49:09 GMT", + "etag": "W/\\"18-MS3VbhH7auHMzO0fUuNF6v14N/M\\"", "x-powered-by": "Express", }, - "status_code": 200, + "status_code": 500, }, "service": Object { "agent": Object { @@ -1590,34 +1581,34 @@ baz", "name": "transaction", }, "timestamp": Object { - "us": 1542574424978005, + "us": 1542574149225004, }, "trace": Object { - "id": "0d84126973411c19b470f2d9eea958d3", + "id": "ba18b741cdd3ac83eca89a5fede47577", }, "transaction": Object { "duration": Object { - "us": 7891, + "us": 32381, }, - "id": "0f10668e4fb3adc7", - "name": "GET /api/types", - "result": "HTTP 2xx", + "id": "b9a8f96d7554d09f", + "name": "GET /log-message", + "result": "HTTP 5xx", "sampled": true, "span_count": Object { - "started": 2, + "started": 0, }, "type": "request", }, }, - "transactionsPerMinute": 75789.47368421052, + "transactionsPerMinute": 22105.263157894737, }, Object { - "averageResponseTime": 10584.05144193297, - "impact": 1.280810614916383, - "name": "GET /api/orders/:id", - "p95": 26555.399999999998, + "averageResponseTime": 10548.218597063622, + "impact": 1.8338763992340905, + "name": "GET /api/products/:id", + "p95": 28413.383333333328, "sample": Object { - "@timestamp": "2018-11-18T20:51:36.949Z", + "@timestamp": "2018-11-18T20:52:57.963Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -1625,14 +1616,14 @@ baz", }, "context": Object { "custom": Object { - "containerId": 5999, + "containerId": 7184, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3475, + "pid": 3686, "ppid": 1, "title": "node /app/server.js", }, @@ -1649,22 +1640,24 @@ baz", "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://opbeans-node:3000/api/orders/183", + "full": "http://opbeans-node:3000/api/products/3", "hostname": "opbeans-node", - "pathname": "/api/orders/183", + "pathname": "/api/products/3", "port": "3000", "protocol": "http:", - "raw": "/api/orders/183", + "raw": "/api/products/3", }, }, "response": Object { "headers": Object { "connection": "close", - "content-length": "0", - "date": "Sun, 18 Nov 2018 20:51:36 GMT", + "content-length": "231", + "content-type": "application/json; charset=utf-8", + "date": "Sun, 18 Nov 2018 20:52:57 GMT", + "etag": "W/\\"e7-kkuzj37GZDzXDh0CWqh5Gan0VO4\\"", "x-powered-by": "Express", }, - "status_code": 404, + "status_code": 200, }, "service": Object { "agent": Object { @@ -1709,18 +1702,18 @@ baz", "name": "transaction", }, "timestamp": Object { - "us": 1542574296949004, + "us": 1542574377963005, }, "trace": Object { - "id": "dab6421fa44a6869887e0edf32e1ad6f", + "id": "ca86ec845e412e4b4506a715d51548ec", }, "transaction": Object { "duration": Object { - "us": 5906, + "us": 6959, }, - "id": "937ef5588454f74a", - "name": "GET /api/orders/:id", - "result": "HTTP 4xx", + "id": "d324897ffb7ebcdc", + "name": "GET /api/products/:id", + "result": "HTTP 2xx", "sampled": true, "span_count": Object { "started": 1, @@ -1728,15 +1721,15 @@ baz", "type": "request", }, }, - "transactionsPerMinute": 40515.789473684206, + "transactionsPerMinute": 58073.68421052631, }, Object { - "averageResponseTime": 10548.218597063622, - "impact": 1.8338763992340905, - "name": "GET /api/products/:id", - "p95": 28413.383333333328, + "averageResponseTime": 9868.217894736843, + "impact": 1.7722323960215767, + "name": "GET /api/customers/:id", + "p95": 27486.5, "sample": Object { - "@timestamp": "2018-11-18T20:52:57.963Z", + "@timestamp": "2018-11-18T20:52:56.797Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -1744,7 +1737,7 @@ baz", }, "context": Object { "custom": Object { - "containerId": 7184, + "containerId": 8225, }, "process": Object { "argv": Array [ @@ -1757,32 +1750,35 @@ baz", }, "request": Object { "headers": Object { - "connection": "close", + "accept": "*/*", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "elastic-apm-traceparent": "00-e6140d30363f18b585f5d3b753f4d025-aa82e2c847265626-01", "host": "opbeans-node:3000", - "user-agent": "workload/2.4.3", + "user-agent": "python-requests/2.20.0", }, "http_version": "1.1", "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.10", + "remote_address": "::ffff:172.18.0.6", }, "url": Object { - "full": "http://opbeans-node:3000/api/products/3", + "full": "http://opbeans-node:3000/api/customers/700", "hostname": "opbeans-node", - "pathname": "/api/products/3", + "pathname": "/api/customers/700", "port": "3000", "protocol": "http:", - "raw": "/api/products/3", + "raw": "/api/customers/700", }, }, "response": Object { "headers": Object { - "connection": "close", - "content-length": "231", + "connection": "keep-alive", + "content-length": "193", "content-type": "application/json; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:52:57 GMT", - "etag": "W/\\"e7-kkuzj37GZDzXDh0CWqh5Gan0VO4\\"", + "date": "Sun, 18 Nov 2018 20:52:56 GMT", + "etag": "W/\\"c1-LbuhkuLzFyZ0H+7+JQGA5b0kvNs\\"", "x-powered-by": "Express", }, "status_code": 200, @@ -1825,22 +1821,25 @@ baz", "host": Object { "name": "b359e3afece8", }, + "parent": Object { + "id": "aa82e2c847265626", + }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542574377963005, + "us": 1542574376797031, }, "trace": Object { - "id": "ca86ec845e412e4b4506a715d51548ec", + "id": "e6140d30363f18b585f5d3b753f4d025", }, "transaction": Object { "duration": Object { - "us": 6959, + "us": 9735, }, - "id": "d324897ffb7ebcdc", - "name": "GET /api/products/:id", + "id": "60e230d12f3f0960", + "name": "GET /api/customers/:id", "result": "HTTP 2xx", "sampled": true, "span_count": Object { @@ -1849,15 +1848,15 @@ baz", "type": "request", }, }, - "transactionsPerMinute": 58073.68421052631, + "transactionsPerMinute": 59999.99999999999, }, Object { - "averageResponseTime": 9868.217894736843, - "impact": 1.7722323960215767, - "name": "GET /api/customers/:id", - "p95": 27486.5, + "averageResponseTime": 12763.68806073154, + "impact": 1.7479924334286208, + "name": "GET /api/types/:id", + "p95": 30576.749999999996, "sample": Object { - "@timestamp": "2018-11-18T20:52:56.797Z", + "@timestamp": "2018-11-18T20:53:35.967Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -1865,48 +1864,45 @@ baz", }, "context": Object { "custom": Object { - "containerId": 8225, + "containerId": 5345, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3686, + "pid": 3756, "ppid": 1, "title": "node /app/server.js", }, "request": Object { "headers": Object { - "accept": "*/*", - "accept-encoding": "gzip, deflate", - "connection": "keep-alive", - "elastic-apm-traceparent": "00-e6140d30363f18b585f5d3b753f4d025-aa82e2c847265626-01", + "connection": "close", "host": "opbeans-node:3000", - "user-agent": "python-requests/2.20.0", + "user-agent": "workload/2.4.3", }, "http_version": "1.1", "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.6", + "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://opbeans-node:3000/api/customers/700", + "full": "http://opbeans-node:3000/api/types/1", "hostname": "opbeans-node", - "pathname": "/api/customers/700", + "pathname": "/api/types/1", "port": "3000", "protocol": "http:", - "raw": "/api/customers/700", + "raw": "/api/types/1", }, }, "response": Object { "headers": Object { - "connection": "keep-alive", - "content-length": "193", + "connection": "close", + "content-length": "217", "content-type": "application/json; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:52:56 GMT", - "etag": "W/\\"c1-LbuhkuLzFyZ0H+7+JQGA5b0kvNs\\"", + "date": "Sun, 18 Nov 2018 20:53:35 GMT", + "etag": "W/\\"d9-cebOOHODBQMZd1wt+ZZBaSPgQLQ\\"", "x-powered-by": "Express", }, "status_code": 200, @@ -1949,42 +1945,39 @@ baz", "host": Object { "name": "b359e3afece8", }, - "parent": Object { - "id": "aa82e2c847265626", - }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542574376797031, + "us": 1542574415967005, }, "trace": Object { - "id": "e6140d30363f18b585f5d3b753f4d025", + "id": "2223b30b5cbaf2e221fcf70ac6d9abbe", }, "transaction": Object { "duration": Object { - "us": 9735, + "us": 13064, }, - "id": "60e230d12f3f0960", - "name": "GET /api/customers/:id", + "id": "053436abacdec0a4", + "name": "GET /api/types/:id", "result": "HTTP 2xx", "sampled": true, "span_count": Object { - "started": 1, + "started": 2, }, "type": "request", }, }, - "transactionsPerMinute": 59999.99999999999, + "transactionsPerMinute": 45757.8947368421, }, Object { - "averageResponseTime": 5192.9, - "impact": 0, - "name": "POST unknown route", - "p95": 13230.5, + "averageResponseTime": 10584.05144193297, + "impact": 1.280810614916383, + "name": "GET /api/orders/:id", + "p95": 26555.399999999998, "sample": Object { - "@timestamp": "2018-11-18T18:43:50.994Z", + "@timestamp": "2018-11-18T20:51:36.949Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -1992,52 +1985,43 @@ baz", }, "context": Object { "custom": Object { - "containerId": 6102, + "containerId": 5999, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 19196, + "pid": 3475, "ppid": 1, "title": "node /app/server.js", }, "request": Object { - "body": "[REDACTED]", "headers": Object { - "accept": "*/*", - "accept-encoding": "gzip, deflate", - "content-length": "380", - "content-type": "multipart/form-data; boundary=2b2e40be188a4cb5a56c05a0c182f6c9", - "elastic-apm-traceparent": "00-19688959ea6cbccda8013c11566ea329-1fc3665eef2dcdfc-01", - "host": "172.18.0.9:3000", - "user-agent": "Python/3.7 aiohttp/3.3.2", - "x-forwarded-for": "172.18.0.11", + "connection": "close", + "host": "opbeans-node:3000", + "user-agent": "workload/2.4.3", }, "http_version": "1.1", - "method": "POST", + "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.9", + "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://172.18.0.9:3000/api/orders/csv", - "hostname": "172.18.0.9", - "pathname": "/api/orders/csv", + "full": "http://opbeans-node:3000/api/orders/183", + "hostname": "opbeans-node", + "pathname": "/api/orders/183", "port": "3000", "protocol": "http:", - "raw": "/api/orders/csv", + "raw": "/api/orders/183", }, }, "response": Object { "headers": Object { - "connection": "keep-alive", - "content-length": "154", - "content-security-policy": "default-src 'self'", - "content-type": "text/html; charset=utf-8", - "date": "Sun, 18 Nov 2018 18:43:50 GMT", - "x-content-type-options": "nosniff", + "connection": "close", + "content-length": "0", + "date": "Sun, 18 Nov 2018 20:51:36 GMT", "x-powered-by": "Express", }, "status_code": 404, @@ -2080,92 +2064,87 @@ baz", "host": Object { "name": "b359e3afece8", }, - "parent": Object { - "id": "1fc3665eef2dcdfc", - }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542566630994005, + "us": 1542574296949004, }, "trace": Object { - "id": "19688959ea6cbccda8013c11566ea329", + "id": "dab6421fa44a6869887e0edf32e1ad6f", }, "transaction": Object { "duration": Object { - "us": 3467, + "us": 5906, }, - "id": "92c3ceea57899061", - "name": "POST unknown route", + "id": "937ef5588454f74a", + "name": "GET /api/orders/:id", "result": "HTTP 4xx", "sampled": true, "span_count": Object { - "started": 0, + "started": 1, }, "type": "request", }, }, - "transactionsPerMinute": 631.578947368421, + "transactionsPerMinute": 40515.789473684206, }, Object { - "averageResponseTime": 4694.005586592179, - "impact": 0.1498515000753004, - "name": "GET /is-it-coffee-time", - "p95": 11022.99999999992, + "averageResponseTime": 1422.926672899693, + "impact": 1.0027124806135428, + "name": "GET unknown route", + "p95": 2311.885238095238, "sample": Object { - "@timestamp": "2018-11-18T20:46:19.317Z", + "@timestamp": "2018-11-18T20:53:42.504Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", "version": "7.0.0-alpha1", }, "context": Object { - "custom": Object { - "containerId": 8593, - }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 2760, + "pid": 3756, "ppid": 1, "title": "node /app/server.js", }, "request": Object { "headers": Object { - "connection": "close", + "accept": "*/*", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", "host": "opbeans-node:3000", - "user-agent": "workload/2.4.3", + "referer": "http://opbeans-node:3000/dashboard", + "user-agent": "Chromeless 1.4.0", }, "http_version": "1.1", "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.10", + "remote_address": "::ffff:172.18.0.7", }, "url": Object { - "full": "http://opbeans-node:3000/is-it-coffee-time", + "full": "http://opbeans-node:3000/rum-config.js", "hostname": "opbeans-node", - "pathname": "/is-it-coffee-time", + "pathname": "/rum-config.js", "port": "3000", "protocol": "http:", - "raw": "/is-it-coffee-time", + "raw": "/rum-config.js", }, }, "response": Object { "headers": Object { - "connection": "close", - "content-length": "148", - "content-security-policy": "default-src 'self'", - "content-type": "text/html; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:46:19 GMT", - "x-content-type-options": "nosniff", + "connection": "keep-alive", + "content-length": "172", + "content-type": "text/javascript", + "date": "Sun, 18 Nov 2018 20:53:42 GMT", "x-powered-by": "Express", }, - "status_code": 500, + "status_code": 200, }, "service": Object { "agent": Object { @@ -2188,19 +2167,6 @@ baz", "ip": "172.18.0.10", "platform": "linux", }, - "tags": Object { - "foo": "bar", - "lorem": "ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus, ipsum id scelerisque consequat, enim leo vulputate massa, vel ultricies ante neque ac risus. Curabitur tincidunt vitae sapien id pulvinar. Mauris eu vestibulum tortor. Integer sit amet lorem fringilla, egestas tellus vitae, vulputate purus. Nulla feugiat blandit nunc et semper. Morbi purus libero, mattis sed mauris non, euismod iaculis lacus. Curabitur eleifend ante eros, non faucibus velit lacinia id. Duis posuere libero augue, at dignissim urna consectetur eget. Praesent eu congue est, iaculis finibus augue.", - "multi-line": "foo -bar -baz", - "this-is-a-very-long-tag-name-without-any-spaces": "test", - }, - "user": Object { - "email": "kimchy@elastic.co", - "id": "42", - "username": "kimchy", - }, }, "host": Object { "name": "b359e3afece8", @@ -2210,18 +2176,18 @@ baz", "name": "transaction", }, "timestamp": Object { - "us": 1542573979317007, + "us": 1542574422504004, }, "trace": Object { - "id": "821812b416de4c73ced87f8777fa46a6", + "id": "4399e7233e6e7b77e70c2fff111b8f28", }, "transaction": Object { "duration": Object { - "us": 4253, + "us": 911, }, - "id": "319a5c555a1ab207", - "name": "GET /is-it-coffee-time", - "result": "HTTP 5xx", + "id": "107881ae2be1b56d", + "name": "GET unknown route", + "result": "HTTP 2xx", "sampled": true, "span_count": Object { "started": 0, @@ -2229,15 +2195,15 @@ baz", "type": "request", }, }, - "transactionsPerMinute": 11305.263157894737, + "transactionsPerMinute": 236431.5789473684, }, Object { - "averageResponseTime": 4549.889880952381, - "impact": 0.13543365054509587, - "name": "GET /throw-error", - "p95": 7719.700000000001, + "averageResponseTime": 21331.714285714286, + "impact": 0.28817487960409877, + "name": "POST /api", + "p95": 30938, "sample": Object { - "@timestamp": "2018-11-18T20:47:10.714Z", + "@timestamp": "2018-11-18T20:29:42.751Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -2245,49 +2211,50 @@ baz", }, "context": Object { "custom": Object { - "containerId": 7220, + "containerId": 2927, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 2895, + "pid": 546, "ppid": 1, "title": "node /app/server.js", }, "request": Object { + "body": "[REDACTED]", "headers": Object { + "accept": "application/json", "connection": "close", + "content-length": "129", + "content-type": "application/json", "host": "opbeans-node:3000", "user-agent": "workload/2.4.3", }, "http_version": "1.1", - "method": "GET", + "method": "POST", "socket": Object { "encrypted": false, "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://opbeans-node:3000/throw-error", + "full": "http://opbeans-node:3000/api/orders", "hostname": "opbeans-node", - "pathname": "/throw-error", + "pathname": "/api/orders", "port": "3000", "protocol": "http:", - "raw": "/throw-error", + "raw": "/api/orders", }, }, "response": Object { "headers": Object { "connection": "close", - "content-length": "148", - "content-security-policy": "default-src 'self'", - "content-type": "text/html; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:47:10 GMT", - "x-content-type-options": "nosniff", + "content-length": "0", + "date": "Sun, 18 Nov 2018 20:29:42 GMT", "x-powered-by": "Express", }, - "status_code": 500, + "status_code": 400, }, "service": Object { "agent": Object { @@ -2332,34 +2299,34 @@ baz", "name": "transaction", }, "timestamp": Object { - "us": 1542574030714012, + "us": 1542572982751005, }, "trace": Object { - "id": "6c0ef23e1f963f304ce440a909914d35", + "id": "8ed4d94ec8fc11b1ea1b0aa59c2320ff", }, "transaction": Object { "duration": Object { - "us": 4458, + "us": 21083, }, - "id": "ecd187dc53f09fbd", - "name": "GET /throw-error", - "result": "HTTP 5xx", + "id": "d67c2f7aa897110c", + "name": "POST /api", + "result": "HTTP 4xx", "sampled": true, "span_count": Object { - "started": 0, + "started": 1, }, "type": "request", }, }, - "transactionsPerMinute": 10610.526315789473, + "transactionsPerMinute": 4642.105263157894, }, Object { - "averageResponseTime": 3504.5108924806746, - "impact": 2.3600993453143766, - "name": "GET *", - "p95": 11431.738095238095, + "averageResponseTime": 4694.005586592179, + "impact": 0.1498515000753004, + "name": "GET /is-it-coffee-time", + "p95": 11022.99999999992, "sample": Object { - "@timestamp": "2018-11-18T20:53:42.493Z", + "@timestamp": "2018-11-18T20:46:19.317Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -2367,54 +2334,49 @@ baz", }, "context": Object { "custom": Object { - "containerId": 6446, + "containerId": 8593, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3756, + "pid": 2760, "ppid": 1, "title": "node /app/server.js", }, "request": Object { "headers": Object { - "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", - "accept-encoding": "gzip, deflate", - "connection": "keep-alive", + "connection": "close", "host": "opbeans-node:3000", - "if-modified-since": "Mon, 12 Nov 2018 10:27:07 GMT", - "if-none-match": "W/\\"280-1670775e878\\"", - "upgrade-insecure-requests": "1", - "user-agent": "Chromeless 1.4.0", + "user-agent": "workload/2.4.3", }, "http_version": "1.1", "method": "GET", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.7", + "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://opbeans-node:3000/dashboard", + "full": "http://opbeans-node:3000/is-it-coffee-time", "hostname": "opbeans-node", - "pathname": "/dashboard", + "pathname": "/is-it-coffee-time", "port": "3000", "protocol": "http:", - "raw": "/dashboard", + "raw": "/is-it-coffee-time", }, }, "response": Object { "headers": Object { - "accept-ranges": "bytes", - "cache-control": "public, max-age=0", - "connection": "keep-alive", - "date": "Sun, 18 Nov 2018 20:53:42 GMT", - "etag": "W/\\"280-1670775e878\\"", - "last-modified": "Mon, 12 Nov 2018 10:27:07 GMT", + "connection": "close", + "content-length": "148", + "content-security-policy": "default-src 'self'", + "content-type": "text/html; charset=utf-8", + "date": "Sun, 18 Nov 2018 20:46:19 GMT", + "x-content-type-options": "nosniff", "x-powered-by": "Express", }, - "status_code": 304, + "status_code": 500, }, "service": Object { "agent": Object { @@ -2459,18 +2421,18 @@ baz", "name": "transaction", }, "timestamp": Object { - "us": 1542574422493006, + "us": 1542573979317007, }, "trace": Object { - "id": "7efb6ade88cdea20cd96ca482681cde7", + "id": "821812b416de4c73ced87f8777fa46a6", }, "transaction": Object { "duration": Object { - "us": 1901, + "us": 4253, }, - "id": "f5fc4621949b63fb", - "name": "GET *", - "result": "HTTP 3xx", + "id": "319a5c555a1ab207", + "name": "GET /is-it-coffee-time", + "result": "HTTP 5xx", "sampled": true, "span_count": Object { "started": 0, @@ -2478,15 +2440,15 @@ baz", "type": "request", }, }, - "transactionsPerMinute": 224684.21052631576, + "transactionsPerMinute": 11305.263157894737, }, Object { - "averageResponseTime": 2742.4615384615386, - "impact": 0.08501028923348058, - "name": "OPTIONS unknown route", - "p95": 4370.000000000002, + "averageResponseTime": 4549.889880952381, + "impact": 0.13543365054509587, + "name": "GET /throw-error", + "p95": 7719.700000000001, "sample": Object { - "@timestamp": "2018-11-18T20:49:00.707Z", + "@timestamp": "2018-11-18T20:47:10.714Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", @@ -2494,50 +2456,49 @@ baz", }, "context": Object { "custom": Object { - "containerId": 3775, + "containerId": 7220, }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3142, + "pid": 2895, "ppid": 1, "title": "node /app/server.js", }, "request": Object { "headers": Object { "connection": "close", - "content-length": "0", "host": "opbeans-node:3000", "user-agent": "workload/2.4.3", }, "http_version": "1.1", - "method": "OPTIONS", + "method": "GET", "socket": Object { "encrypted": false, "remote_address": "::ffff:172.18.0.10", }, "url": Object { - "full": "http://opbeans-node:3000/", + "full": "http://opbeans-node:3000/throw-error", "hostname": "opbeans-node", - "pathname": "/", + "pathname": "/throw-error", "port": "3000", "protocol": "http:", - "raw": "/", + "raw": "/throw-error", }, }, "response": Object { "headers": Object { - "allow": "GET,HEAD", "connection": "close", - "content-length": "8", + "content-length": "148", + "content-security-policy": "default-src 'self'", "content-type": "text/html; charset=utf-8", - "date": "Sun, 18 Nov 2018 20:49:00 GMT", - "etag": "W/\\"8-ZRAf8oNBS3Bjb/SU2GYZCmbtmXg\\"", + "date": "Sun, 18 Nov 2018 20:47:10 GMT", + "x-content-type-options": "nosniff", "x-powered-by": "Express", }, - "status_code": 200, + "status_code": 500, }, "service": Object { "agent": Object { @@ -2582,18 +2543,18 @@ baz", "name": "transaction", }, "timestamp": Object { - "us": 1542574140707006, + "us": 1542574030714012, }, "trace": Object { - "id": "469e3e5f91ffe3195a8e58cdd1cdefa8", + "id": "6c0ef23e1f963f304ce440a909914d35", }, "transaction": Object { "duration": Object { - "us": 2371, + "us": 4458, }, - "id": "a8c87ebc7ec68bc0", - "name": "OPTIONS unknown route", - "result": "HTTP 2xx", + "id": "ecd187dc53f09fbd", + "name": "GET /throw-error", + "result": "HTTP 5xx", "sampled": true, "span_count": Object { "started": 0, @@ -2601,38 +2562,42 @@ baz", "type": "request", }, }, - "transactionsPerMinute": 11494.736842105262, + "transactionsPerMinute": 10610.526315789473, }, Object { - "averageResponseTime": 2651.8784461553205, - "impact": 15.770246496477105, - "name": "GET static file", - "p95": 6140.579335038363, + "averageResponseTime": 2742.4615384615386, + "impact": 0.08501028923348058, + "name": "OPTIONS unknown route", + "p95": 4370.000000000002, "sample": Object { - "@timestamp": "2018-11-18T20:53:43.304Z", + "@timestamp": "2018-11-18T20:49:00.707Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", "version": "7.0.0-alpha1", }, "context": Object { + "custom": Object { + "containerId": 3775, + }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3756, + "pid": 3142, "ppid": 1, "title": "node /app/server.js", }, "request": Object { "headers": Object { - "accept": "*/*", + "connection": "close", + "content-length": "0", "host": "opbeans-node:3000", - "user-agent": "curl/7.38.0", + "user-agent": "workload/2.4.3", }, "http_version": "1.1", - "method": "GET", + "method": "OPTIONS", "socket": Object { "encrypted": false, "remote_address": "::ffff:172.18.0.10", @@ -2648,14 +2613,12 @@ baz", }, "response": Object { "headers": Object { - "accept-ranges": "bytes", - "cache-control": "public, max-age=0", - "connection": "keep-alive", - "content-length": "640", - "content-type": "text/html; charset=UTF-8", - "date": "Sun, 18 Nov 2018 20:53:43 GMT", - "etag": "W/\\"280-1670775e878\\"", - "last-modified": "Mon, 12 Nov 2018 10:27:07 GMT", + "allow": "GET,HEAD", + "connection": "close", + "content-length": "8", + "content-type": "text/html; charset=utf-8", + "date": "Sun, 18 Nov 2018 20:49:00 GMT", + "etag": "W/\\"8-ZRAf8oNBS3Bjb/SU2GYZCmbtmXg\\"", "x-powered-by": "Express", }, "status_code": 200, @@ -2681,6 +2644,19 @@ baz", "ip": "172.18.0.10", "platform": "linux", }, + "tags": Object { + "foo": "bar", + "lorem": "ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus, ipsum id scelerisque consequat, enim leo vulputate massa, vel ultricies ante neque ac risus. Curabitur tincidunt vitae sapien id pulvinar. Mauris eu vestibulum tortor. Integer sit amet lorem fringilla, egestas tellus vitae, vulputate purus. Nulla feugiat blandit nunc et semper. Morbi purus libero, mattis sed mauris non, euismod iaculis lacus. Curabitur eleifend ante eros, non faucibus velit lacinia id. Duis posuere libero augue, at dignissim urna consectetur eget. Praesent eu congue est, iaculis finibus augue.", + "multi-line": "foo +bar +baz", + "this-is-a-very-long-tag-name-without-any-spaces": "test", + }, + "user": Object { + "email": "kimchy@elastic.co", + "id": "42", + "username": "kimchy", + }, }, "host": Object { "name": "b359e3afece8", @@ -2690,17 +2666,17 @@ baz", "name": "transaction", }, "timestamp": Object { - "us": 1542574423304006, + "us": 1542574140707006, }, "trace": Object { - "id": "b303d2a4a007946b63b9db7fafe639a0", + "id": "469e3e5f91ffe3195a8e58cdd1cdefa8", }, "transaction": Object { "duration": Object { - "us": 1801, + "us": 2371, }, - "id": "2869c13633534be5", - "name": "GET static file", + "id": "a8c87ebc7ec68bc0", + "name": "OPTIONS unknown route", "result": "HTTP 2xx", "sampled": true, "span_count": Object { @@ -2709,63 +2685,71 @@ baz", "type": "request", }, }, - "transactionsPerMinute": 1977031.5789473683, + "transactionsPerMinute": 11494.736842105262, }, Object { - "averageResponseTime": 1422.926672899693, - "impact": 1.0027124806135428, - "name": "GET unknown route", - "p95": 2311.885238095238, + "averageResponseTime": 5192.9, + "impact": 0, + "name": "POST unknown route", + "p95": 13230.5, "sample": Object { - "@timestamp": "2018-11-18T20:53:42.504Z", + "@timestamp": "2018-11-18T18:43:50.994Z", "agent": Object { "hostname": "b359e3afece8", "type": "apm-server", "version": "7.0.0-alpha1", }, "context": Object { + "custom": Object { + "containerId": 6102, + }, "process": Object { "argv": Array [ "/usr/local/bin/node", "/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js", ], - "pid": 3756, + "pid": 19196, "ppid": 1, "title": "node /app/server.js", }, "request": Object { + "body": "[REDACTED]", "headers": Object { "accept": "*/*", "accept-encoding": "gzip, deflate", - "connection": "keep-alive", - "host": "opbeans-node:3000", - "referer": "http://opbeans-node:3000/dashboard", - "user-agent": "Chromeless 1.4.0", + "content-length": "380", + "content-type": "multipart/form-data; boundary=2b2e40be188a4cb5a56c05a0c182f6c9", + "elastic-apm-traceparent": "00-19688959ea6cbccda8013c11566ea329-1fc3665eef2dcdfc-01", + "host": "172.18.0.9:3000", + "user-agent": "Python/3.7 aiohttp/3.3.2", + "x-forwarded-for": "172.18.0.11", }, "http_version": "1.1", - "method": "GET", + "method": "POST", "socket": Object { "encrypted": false, - "remote_address": "::ffff:172.18.0.7", + "remote_address": "::ffff:172.18.0.9", }, "url": Object { - "full": "http://opbeans-node:3000/rum-config.js", - "hostname": "opbeans-node", - "pathname": "/rum-config.js", + "full": "http://172.18.0.9:3000/api/orders/csv", + "hostname": "172.18.0.9", + "pathname": "/api/orders/csv", "port": "3000", "protocol": "http:", - "raw": "/rum-config.js", + "raw": "/api/orders/csv", }, }, "response": Object { "headers": Object { "connection": "keep-alive", - "content-length": "172", - "content-type": "text/javascript", - "date": "Sun, 18 Nov 2018 20:53:42 GMT", + "content-length": "154", + "content-security-policy": "default-src 'self'", + "content-type": "text/html; charset=utf-8", + "date": "Sun, 18 Nov 2018 18:43:50 GMT", + "x-content-type-options": "nosniff", "x-powered-by": "Express", }, - "status_code": 200, + "status_code": 404, }, "service": Object { "agent": Object { @@ -2788,27 +2772,43 @@ baz", "ip": "172.18.0.10", "platform": "linux", }, + "tags": Object { + "foo": "bar", + "lorem": "ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus, ipsum id scelerisque consequat, enim leo vulputate massa, vel ultricies ante neque ac risus. Curabitur tincidunt vitae sapien id pulvinar. Mauris eu vestibulum tortor. Integer sit amet lorem fringilla, egestas tellus vitae, vulputate purus. Nulla feugiat blandit nunc et semper. Morbi purus libero, mattis sed mauris non, euismod iaculis lacus. Curabitur eleifend ante eros, non faucibus velit lacinia id. Duis posuere libero augue, at dignissim urna consectetur eget. Praesent eu congue est, iaculis finibus augue.", + "multi-line": "foo +bar +baz", + "this-is-a-very-long-tag-name-without-any-spaces": "test", + }, + "user": Object { + "email": "kimchy@elastic.co", + "id": "42", + "username": "kimchy", + }, }, "host": Object { "name": "b359e3afece8", }, + "parent": Object { + "id": "1fc3665eef2dcdfc", + }, "processor": Object { "event": "transaction", "name": "transaction", }, "timestamp": Object { - "us": 1542574422504004, + "us": 1542566630994005, }, "trace": Object { - "id": "4399e7233e6e7b77e70c2fff111b8f28", + "id": "19688959ea6cbccda8013c11566ea329", }, "transaction": Object { "duration": Object { - "us": 911, + "us": 3467, }, - "id": "107881ae2be1b56d", - "name": "GET unknown route", - "result": "HTTP 2xx", + "id": "92c3ceea57899061", + "name": "POST unknown route", + "result": "HTTP 4xx", "sampled": true, "span_count": Object { "started": 0, @@ -2816,7 +2816,7 @@ baz", "type": "request", }, }, - "transactionsPerMinute": 236431.5789473684, + "transactionsPerMinute": 631.578947368421, }, ] `; diff --git a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/fetcher.ts b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/fetcher.ts index b08bdc334fc878..a4885f2884976b 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/fetcher.ts +++ b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/fetcher.ts @@ -5,19 +5,21 @@ */ import { + SERVICE_NAME, TRANSACTION_DURATION, - TRANSACTION_SAMPLED + TRANSACTION_SAMPLED, + TRANSACTION_NAME } from '../../../common/elasticsearch_fieldnames'; +import { getTransactionGroupsProjection } from '../../../common/projections/transaction_groups'; +import { mergeProjection } from '../../../common/projections/util/merge_projection'; import { PromiseReturnType } from '../../../typings/common'; +import { SortOptions } from '../../../typings/elasticsearch/aggregations'; +import { Transaction } from '../../../typings/es_schemas/ui/Transaction'; import { Setup, SetupTimeRange, SetupUIFilters } from '../helpers/setup_request'; -import { getTransactionGroupsProjection } from '../../../common/projections/transaction_groups'; -import { mergeProjection } from '../../../common/projections/util/merge_projection'; -import { SortOptions } from '../../../typings/elasticsearch/aggregations'; -import { Transaction } from '../../../typings/es_schemas/ui/Transaction'; interface TopTransactionOptions { type: 'top_transactions'; @@ -38,7 +40,7 @@ export function transactionGroupsFetcher( options: Options, setup: Setup & SetupTimeRange & SetupUIFilters ) { - const { client, config } = setup; + const { client } = setup; const projection = getTransactionGroupsProjection({ setup, @@ -50,6 +52,13 @@ export function transactionGroupsFetcher( { '@timestamp': { order: 'desc' as const } } ]; + const isTopTraces = options.type === 'top_traces'; + + if (isTopTraces) { + // Delete the projection aggregation when searching for traces, as it should use the combined aggregation instead + delete projection.body.aggs; + } + const params = mergeProjection(projection, { body: { size: 0, @@ -60,19 +69,18 @@ export function transactionGroupsFetcher( } }, aggs: { - transactions: { - terms: { - ...projection.body.aggs.transactions.terms, - order: { sum: 'desc' as const }, - size: config['xpack.apm.ui.transactionGroupBucketSize'] + transaction_groups: { + composite: { + size: 10000, + sources: [ + ...(isTopTraces + ? [{ service: { terms: { field: SERVICE_NAME } } }] + : []), + { transaction: { terms: { field: TRANSACTION_NAME } } } + ] }, aggs: { - sample: { - top_hits: { - size: 1, - sort - } - }, + sample: { top_hits: { size: 1, sort } }, avg: { avg: { field: TRANSACTION_DURATION } }, p95: { percentiles: { field: TRANSACTION_DURATION, percents: [95] } diff --git a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/mock-responses/transactionGroupsResponse.ts b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/mock-responses/transactionGroupsResponse.ts index 2632cc6e94b937..bc61f1cab149e1 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/mock-responses/transactionGroupsResponse.ts +++ b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/mock-responses/transactionGroupsResponse.ts @@ -12,12 +12,12 @@ export const transactionGroupsResponse = ({ _shards: { total: 44, successful: 44, skipped: 0, failed: 0 }, hits: { total: 131557, max_score: null, hits: [] }, aggregations: { - transactions: { + transaction_groups: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { - key: 'POST /api/orders', + key: { transaction: 'POST /api/orders' }, doc_count: 180, avg: { value: 255966.30555555556 }, p95: { values: { '95.0': 320238.5 } }, @@ -137,7 +137,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /api', + key: { transaction: 'GET /api' }, doc_count: 21911, avg: { value: 48021.972616494 }, p95: { values: { '95.0': 67138.18364917398 } }, @@ -257,7 +257,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /api/orders', + key: { transaction: 'GET /api/orders' }, doc_count: 3247, avg: { value: 33265.03326147213 }, p95: { values: { '95.0': 58827.489999999976 } }, @@ -373,7 +373,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /log-message', + key: { transaction: 'GET /log-message' }, doc_count: 700, avg: { value: 32900.72714285714 }, p95: { values: { '95.0': 40444 } }, @@ -489,7 +489,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /api/stats', + key: { transaction: 'GET /api/stats' }, doc_count: 4639, avg: { value: 32554.36257814184 }, p95: { values: { '95.0': 59356.73611111111 } }, @@ -610,7 +610,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /log-error', + key: { transaction: 'GET /log-error' }, doc_count: 736, avg: { value: 32387.73641304348 }, p95: { values: { '95.0': 40061.1 } }, @@ -726,7 +726,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /api/customers', + key: { transaction: 'GET /api/customers' }, doc_count: 3366, avg: { value: 32159.926322043968 }, p95: { values: { '95.0': 59845.85714285714 } }, @@ -847,7 +847,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /api/products/top', + key: { transaction: 'GET /api/products/top' }, doc_count: 3694, avg: { value: 27516.89144558744 }, p95: { values: { '95.0': 56064.679999999986 } }, @@ -969,7 +969,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'POST /api', + key: { transaction: 'POST /api' }, doc_count: 147, avg: { value: 21331.714285714286 }, p95: { values: { '95.0': 30938 } }, @@ -1087,7 +1087,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /api/products/:id/customers', + key: { transaction: 'GET /api/products/:id/customers' }, doc_count: 2102, avg: { value: 17189.329210275926 }, p95: { values: { '95.0': 39284.79999999999 } }, @@ -1209,7 +1209,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /api/types/:id', + key: { transaction: 'GET /api/types/:id' }, doc_count: 1449, avg: { value: 12763.68806073154 }, p95: { values: { '95.0': 30576.749999999996 } }, @@ -1325,7 +1325,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /api/products', + key: { transaction: 'GET /api/products' }, doc_count: 3678, avg: { value: 12683.190864600327 }, p95: { values: { '95.0': 35009.67999999999 } }, @@ -1441,7 +1441,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /api/types', + key: { transaction: 'GET /api/types' }, doc_count: 2400, avg: { value: 11257.757916666667 }, p95: { values: { '95.0': 35222.944444444445 } }, @@ -1557,7 +1557,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /api/orders/:id', + key: { transaction: 'GET /api/orders/:id' }, doc_count: 1283, avg: { value: 10584.05144193297 }, p95: { values: { '95.0': 26555.399999999998 } }, @@ -1671,7 +1671,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /api/products/:id', + key: { transaction: 'GET /api/products/:id' }, doc_count: 1839, avg: { value: 10548.218597063622 }, p95: { values: { '95.0': 28413.383333333328 } }, @@ -1787,7 +1787,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /api/customers/:id', + key: { transaction: 'GET /api/customers/:id' }, doc_count: 1900, avg: { value: 9868.217894736843 }, p95: { values: { '95.0': 27486.5 } }, @@ -1908,7 +1908,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'POST unknown route', + key: { transaction: 'POST unknown route' }, doc_count: 20, avg: { value: 5192.9 }, p95: { values: { '95.0': 13230.5 } }, @@ -2034,7 +2034,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /is-it-coffee-time', + key: { transaction: 'GET /is-it-coffee-time' }, doc_count: 358, avg: { value: 4694.005586592179 }, p95: { values: { '95.0': 11022.99999999992 } }, @@ -2151,7 +2151,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET /throw-error', + key: { transaction: 'GET /throw-error' }, doc_count: 336, avg: { value: 4549.889880952381 }, p95: { values: { '95.0': 7719.700000000001 } }, @@ -2268,7 +2268,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET *', + key: { transaction: 'GET *' }, doc_count: 7115, avg: { value: 3504.5108924806746 }, p95: { values: { '95.0': 11431.738095238095 } }, @@ -2391,7 +2391,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'OPTIONS unknown route', + key: { transaction: 'OPTIONS unknown route' }, doc_count: 364, avg: { value: 2742.4615384615386 }, p95: { values: { '95.0': 4370.000000000002 } }, @@ -2509,7 +2509,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET static file', + key: { transaction: 'GET static file' }, doc_count: 62606, avg: { value: 2651.8784461553205 }, p95: { values: { '95.0': 6140.579335038363 } }, @@ -2614,7 +2614,7 @@ export const transactionGroupsResponse = ({ } }, { - key: 'GET unknown route', + key: { transaction: 'GET unknown route' }, doc_count: 7487, avg: { value: 1422.926672899693 }, p95: { values: { '95.0': 2311.885238095238 } }, diff --git a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/transform.test.ts b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/transform.test.ts index 6acd34af243535..709fa3afdc128d 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/transform.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/transform.test.ts @@ -21,7 +21,7 @@ describe('transactionGroupsTransformer', () => { it('should transform response correctly', () => { const bucket = { - key: 'POST /api/orders', + key: { transaction: 'POST /api/orders' }, doc_count: 180, avg: { value: 255966.30555555556 }, p95: { values: { '95.0': 320238.5 } }, @@ -36,7 +36,7 @@ describe('transactionGroupsTransformer', () => { const response = ({ aggregations: { - transactions: { + transaction_groups: { buckets: [bucket] } } @@ -58,7 +58,7 @@ describe('transactionGroupsTransformer', () => { it('should calculate impact from sum', () => { const getBucket = (sum: number) => ({ - key: 'POST /api/orders', + key: { transaction: 'POST /api/orders' }, doc_count: 180, avg: { value: 300000 }, p95: { values: { '95.0': 320000 } }, @@ -68,7 +68,9 @@ describe('transactionGroupsTransformer', () => { const response = ({ aggregations: { - transactions: { buckets: [getBucket(10), getBucket(20), getBucket(50)] } + transaction_groups: { + buckets: [getBucket(10), getBucket(20), getBucket(50)] + } } } as unknown) as ESResponse; @@ -76,6 +78,6 @@ describe('transactionGroupsTransformer', () => { transactionGroupsTransformer({ response, start: 100, end: 20000 }).map( bucket => bucket.impact ) - ).toEqual([0, 25, 100]); + ).toEqual([100, 25, 0]); }); }); diff --git a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/transform.ts b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/transform.ts index 58a952baa8233d..0a03a88cbf4a24 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/transform.ts +++ b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/transform.ts @@ -5,6 +5,7 @@ */ import moment from 'moment'; +import { sortByOrder } from 'lodash'; import { ESResponse } from './fetcher'; function calculateRelativeImpacts(transactionGroups: ITransactionGroup[]) { @@ -24,9 +25,20 @@ function calculateRelativeImpacts(transactionGroups: ITransactionGroup[]) { })); } +const getBuckets = (response: ESResponse) => { + if (response.aggregations) { + return sortByOrder( + response.aggregations.transaction_groups.buckets, + ['sum.value'], + ['desc'] + ); + } + return []; +}; + export type ITransactionGroup = ReturnType; function getTransactionGroup( - bucket: Required['aggregations']['transactions']['buckets'][0], + bucket: ReturnType[0], minutes: number ) { const averageResponseTime = bucket.avg.value; @@ -35,7 +47,7 @@ function getTransactionGroup( const sample = bucket.sample.hits.hits[0]._source; return { - name: bucket.key as string, + name: bucket.key.transaction, sample, p95: bucket.p95.values['95.0'], averageResponseTime, @@ -53,7 +65,7 @@ export function transactionGroupsTransformer({ start: number; end: number; }): ITransactionGroup[] { - const buckets = response.aggregations?.transactions.buckets || []; + const buckets = getBuckets(response); const duration = moment.duration(end - start); const minutes = duration.asMinutes(); const transactionGroups = buckets.map(bucket => diff --git a/x-pack/legacy/plugins/canvas/.storybook/config.js b/x-pack/legacy/plugins/canvas/.storybook/config.js index d3cd8e8057ae8c..725a3b12666d12 100644 --- a/x-pack/legacy/plugins/canvas/.storybook/config.js +++ b/x-pack/legacy/plugins/canvas/.storybook/config.js @@ -10,7 +10,6 @@ import { withKnobs } from '@storybook/addon-knobs/react'; import { withInfo } from '@storybook/addon-info'; import { create } from '@storybook/theming'; -import { coreMock } from 'src/core/public/mocks'; import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public'; // If we're running Storyshots, be sure to register the require context hook. @@ -38,9 +37,12 @@ if (process.env.NODE_ENV === 'test') { } // Add New Platform Context for any stories that need it -addDecorator(fn => ( - {fn()} -)); +const settings = new Map(); +settings.set('darkMode', true); +const platform = { + uiSettings: settings, +}; +addDecorator(fn => {fn()}); function loadStories() { require('./dll_contexts'); @@ -55,7 +57,7 @@ function loadStories() { css.keys().forEach(filename => css(filename)); // Find all files ending in *.examples.ts - const req = require.context('./..', true, /.examples.tsx$/); + const req = require.context('./..', true, /.(stories|examples).tsx$/); req.keys().forEach(filename => req(filename)); } diff --git a/x-pack/legacy/plugins/canvas/.storybook/dll_contexts.js b/x-pack/legacy/plugins/canvas/.storybook/dll_contexts.js index 66ef1a192d4030..273323d065ecf6 100644 --- a/x-pack/legacy/plugins/canvas/.storybook/dll_contexts.js +++ b/x-pack/legacy/plugins/canvas/.storybook/dll_contexts.js @@ -26,3 +26,10 @@ const uiStyles = require.context( /[\/\\](?!mixins|variables|_|\.|bootstrap_(light|dark))[^\/\\]+\.less/ ); uiStyles.keys().forEach(key => uiStyles(key)); + +const json = require.context( + '../shareable_runtime/test/workpads', + false, + /\.json$/ +); +json.keys().forEach(key => json(key)); diff --git a/x-pack/legacy/plugins/canvas/.storybook/storyshots.test.js b/x-pack/legacy/plugins/canvas/.storybook/storyshots.test.js index b7924486c34cb6..76240d212da155 100644 --- a/x-pack/legacy/plugins/canvas/.storybook/storyshots.test.js +++ b/x-pack/legacy/plugins/canvas/.storybook/storyshots.test.js @@ -52,7 +52,7 @@ jest.mock('plugins/interpreter/registries', () => ({})); // Disabling this test due to https://github.com/elastic/eui/issues/2242 jest.mock( - '../public/components/workpad_header/workpad_export/__examples__/disabled_panel.examples', + '../public/components/workpad_header/workpad_export/__examples__/disabled_panel.stories', () => { return 'Disabled Panel'; } @@ -60,7 +60,7 @@ jest.mock( // Disabling this test due to https://github.com/elastic/eui/issues/2242 jest.mock( - '../public/components/workpad_header/workpad_export/flyout/__examples__/share_website_flyout.examples', + '../public/components/workpad_header/workpad_export/flyout/__examples__/share_website_flyout.stories', () => { return 'Disabled Panel'; } diff --git a/x-pack/legacy/plugins/canvas/.storybook/webpack.config.js b/x-pack/legacy/plugins/canvas/.storybook/webpack.config.js index 662078585422f3..019194716b2307 100644 --- a/x-pack/legacy/plugins/canvas/.storybook/webpack.config.js +++ b/x-pack/legacy/plugins/canvas/.storybook/webpack.config.js @@ -47,15 +47,18 @@ module.exports = async ({ config }) => { }); // Parse props data for .tsx files - config.module.rules.push({ - test: /\.tsx$/, - // Exclude example files, as we don't display props info for them - exclude: /\.examples.tsx$/, - use: [ - // Parse TS comments to create Props tables in the UI - require.resolve('react-docgen-typescript-loader'), - ], - }); + // This is notoriously slow, and is making Storybook unusable. Disabling for now. + // See: https://github.com/storybookjs/storybook/issues/7998 + // + // config.module.rules.push({ + // test: /\.tsx$/, + // // Exclude example files, as we don't display props info for them + // exclude: /\.examples.tsx$/, + // use: [ + // // Parse TS comments to create Props tables in the UI + // require.resolve('react-docgen-typescript-loader'), + // ], + // }); // Enable SASS, but exclude CSS Modules in Storybook config.module.rules.push({ diff --git a/x-pack/legacy/plugins/canvas/.storybook/webpack.dll.config.js b/x-pack/legacy/plugins/canvas/.storybook/webpack.dll.config.js index 12f2195c067caf..0a648e861b386d 100644 --- a/x-pack/legacy/plugins/canvas/.storybook/webpack.dll.config.js +++ b/x-pack/legacy/plugins/canvas/.storybook/webpack.dll.config.js @@ -24,9 +24,7 @@ module.exports = { entry: [ '@elastic/eui/dist/eui_theme_light.css', '@kbn/ui-framework/dist/kui_light.css', - '@storybook/addon-actions', '@storybook/addon-actions/register', - '@storybook/addon-info', '@storybook/addon-knobs', '@storybook/addon-knobs/react', '@storybook/addon-knobs/register', diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/expression_types/embeddable_types.ts b/x-pack/legacy/plugins/canvas/canvas_plugin_src/expression_types/embeddable_types.ts index 8f5ad859d28ba9..cc92d864282e74 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/expression_types/embeddable_types.ts +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/expression_types/embeddable_types.ts @@ -6,7 +6,7 @@ // @ts-ignore import { MAP_SAVED_OBJECT_TYPE } from '../../../maps/common/constants'; -import { VISUALIZE_EMBEDDABLE_TYPE } from '../../../../../../src/legacy/core_plugins/kibana/public/visualize_embeddable/constants'; +import { VISUALIZE_EMBEDDABLE_TYPE } from '../../../../../../src/legacy/core_plugins/visualizations/public/embeddable/constants'; import { SEARCH_EMBEDDABLE_TYPE } from '../../../../../../src/legacy/core_plugins/kibana/public/discover/np_ready/embeddable/constants'; export const EmbeddableTypes: { map: string; search: string; visualization: string } = { diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_visualization.ts b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_visualization.ts index f6eb377e2698bd..d3b1bbe31c7155 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_visualization.ts +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_visualization.ts @@ -5,7 +5,7 @@ */ import { ExpressionFunction } from 'src/plugins/expressions/common/types'; -import { VisualizeInput } from 'src/legacy/core_plugins/kibana/public/visualize_embeddable'; +import { VisualizeInput } from 'src/legacy/core_plugins/visualizations/public/embeddable'; import { EmbeddableTypes, EmbeddableExpressionType, diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/metric/component/__examples__/__snapshots__/metric.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/metric/component/__examples__/__snapshots__/metric.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/metric/component/__examples__/__snapshots__/metric.examples.storyshot rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/metric/component/__examples__/__snapshots__/metric.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/metric/component/__examples__/metric.examples.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/metric/component/__examples__/metric.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/metric/component/__examples__/metric.examples.tsx rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/metric/component/__examples__/metric.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_calendar/__examples__/__snapshots__/datetime_calendar.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_calendar/__examples__/__snapshots__/datetime_calendar.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_calendar/__examples__/__snapshots__/datetime_calendar.examples.storyshot rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_calendar/__examples__/__snapshots__/datetime_calendar.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_calendar/__examples__/datetime_calendar.examples.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_calendar/__examples__/datetime_calendar.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_calendar/__examples__/datetime_calendar.examples.tsx rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_calendar/__examples__/datetime_calendar.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_input/__examples__/__snapshots__/datetime_input.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_input/__examples__/__snapshots__/datetime_input.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_input/__examples__/__snapshots__/datetime_input.examples.storyshot rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_input/__examples__/__snapshots__/datetime_input.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_input/__examples__/datetime_input.examples.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_input/__examples__/datetime_input.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_input/__examples__/datetime_input.examples.tsx rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_input/__examples__/datetime_input.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_quick_list/__examples__/__snapshots__/datetime_quick_list.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_quick_list/__examples__/__snapshots__/datetime_quick_list.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_quick_list/__examples__/__snapshots__/datetime_quick_list.examples.storyshot rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_quick_list/__examples__/__snapshots__/datetime_quick_list.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_quick_list/__examples__/datetime_quick_list.examples.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_quick_list/__examples__/datetime_quick_list.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_quick_list/__examples__/datetime_quick_list.examples.tsx rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_quick_list/__examples__/datetime_quick_list.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_quick_list/datetime_quick_list.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_quick_list/datetime_quick_list.tsx index fc4603b5be6e53..9d5a3893dbcb87 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_quick_list/datetime_quick_list.tsx +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_quick_list/datetime_quick_list.tsx @@ -8,7 +8,7 @@ import React, { ReactNode, FunctionComponent } from 'react'; import PropTypes from 'prop-types'; import { EuiButton, EuiButtonEmpty } from '@elastic/eui'; import 'react-datetime/css/react-datetime.css'; -import { UnitStrings } from '../../../../../i18n'; +import { UnitStrings } from '../../../../../i18n/units'; const { quickRanges: strings } = UnitStrings; diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_range_absolute/__examples__/__snapshots__/datetime_range_absolute.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_range_absolute/__examples__/__snapshots__/datetime_range_absolute.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_range_absolute/__examples__/__snapshots__/datetime_range_absolute.examples.storyshot rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_range_absolute/__examples__/__snapshots__/datetime_range_absolute.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_range_absolute/__examples__/datetime_range_absolute.examples.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_range_absolute/__examples__/datetime_range_absolute.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_range_absolute/__examples__/datetime_range_absolute.examples.tsx rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/datetime_range_absolute/__examples__/datetime_range_absolute.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/pretty_duration/__examples__/__snapshots__/pretty_duration.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/pretty_duration/__examples__/__snapshots__/pretty_duration.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/pretty_duration/__examples__/__snapshots__/pretty_duration.examples.storyshot rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/pretty_duration/__examples__/__snapshots__/pretty_duration.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/pretty_duration/__examples__/pretty_duration.examples.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/pretty_duration/__examples__/pretty_duration.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/pretty_duration/__examples__/pretty_duration.examples.tsx rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/pretty_duration/__examples__/pretty_duration.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/pretty_duration/lib/quick_ranges.ts b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/pretty_duration/lib/quick_ranges.ts index f52465fd3da703..1c436d3630b536 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/pretty_duration/lib/quick_ranges.ts +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/pretty_duration/lib/quick_ranges.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UnitStrings } from '../../../../../../i18n'; +import { UnitStrings } from '../../../../../../i18n/units'; export interface QuickRange { /** Start date string of range */ diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_picker/__examples__/__snapshots__/time_picker.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_picker/__examples__/__snapshots__/time_picker.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_picker/__examples__/__snapshots__/time_picker.examples.storyshot rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_picker/__examples__/__snapshots__/time_picker.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_picker/__examples__/time_picker.examples.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_picker/__examples__/time_picker.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_picker/__examples__/time_picker.examples.tsx rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_picker/__examples__/time_picker.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_picker/time_picker.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_picker/time_picker.tsx index a03e64ce3a02ef..599b15524ddda0 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_picker/time_picker.tsx +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_picker/time_picker.tsx @@ -11,7 +11,7 @@ import { EuiButton } from '@elastic/eui'; import moment from 'moment'; import { DatetimeQuickList } from '../datetime_quick_list'; import { DatetimeRangeAbsolute } from '../datetime_range_absolute'; -import { ComponentStrings } from '../../../../../i18n'; +import { ComponentStrings } from '../../../../../i18n/components'; const { TimePicker: strings } = ComponentStrings; diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/extended_template.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/extended_template.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/extended_template.examples.storyshot rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/extended_template.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/simple_template.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/simple_template.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/simple_template.examples.storyshot rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/simple_template.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/extended_template.examples.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/extended_template.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/extended_template.examples.tsx rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/extended_template.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/simple_template.examples.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/simple_template.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/simple_template.examples.tsx rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/simple_template.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/extended_template.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/extended_template.tsx index 0f01860520b502..806a61042494f2 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/extended_template.tsx +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/extended_template.tsx @@ -10,7 +10,7 @@ import { EuiSelect, EuiFormRow, EuiSpacer, EuiText } from '@elastic/eui'; import immutable from 'object-path-immutable'; import { get } from 'lodash'; import { ExpressionAST } from '../../../../types'; -import { ArgumentStrings } from '../../../../i18n'; +import { ArgumentStrings } from '../../../../i18n/ui'; const { AxisConfig: strings } = ArgumentStrings; diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/__examples__/__snapshots__/date_format.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/__examples__/__snapshots__/date_format.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/__examples__/__snapshots__/date_format.examples.storyshot rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/__examples__/__snapshots__/date_format.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/__examples__/date_format.examples.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/__examples__/date_format.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/__examples__/date_format.examples.tsx rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/__examples__/date_format.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/__examples__/__snapshots__/number_format.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/__examples__/__snapshots__/number_format.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/__examples__/__snapshots__/number_format.examples.storyshot rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/__examples__/__snapshots__/number_format.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/__examples__/number_format.examples.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/__examples__/number_format.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/__examples__/number_format.examples.tsx rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/__examples__/number_format.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/common/lib/constants.ts b/x-pack/legacy/plugins/canvas/common/lib/constants.ts index 7494ea13e6c08e..40e143b9ec589e 100644 --- a/x-pack/legacy/plugins/canvas/common/lib/constants.ts +++ b/x-pack/legacy/plugins/canvas/common/lib/constants.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SHAREABLE_RUNTIME_NAME } from '../../shareable_runtime/constants'; +import { SHAREABLE_RUNTIME_NAME } from '../../shareable_runtime/constants_static'; export const CANVAS_TYPE = 'canvas-workpad'; export const CUSTOM_ELEMENT_TYPE = 'canvas-element'; diff --git a/x-pack/legacy/plugins/canvas/public/components/arg_add_popover/arg_add_popover.tsx b/x-pack/legacy/plugins/canvas/public/components/arg_add_popover/arg_add_popover.tsx index 9cc6f870b9bded..9c660434545858 100644 --- a/x-pack/legacy/plugins/canvas/public/components/arg_add_popover/arg_add_popover.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/arg_add_popover/arg_add_popover.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { MouseEvent } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { EuiButtonIcon } from '@elastic/eui'; // @ts-ignore untyped local @@ -28,7 +28,7 @@ interface Props { } export const ArgAddPopover = ({ options }: Props) => { - const button = (handleClick: (ev: MouseEvent) => void) => ( + const button = (handleClick: React.MouseEventHandler) => ( = (props: Props) => { const { value, anchorPosition, ariaLabel, ...rest } = props; - const button = (handleClick: (ev: MouseEvent) => void) => ( + const button = (handleClick: React.MouseEventHandler) => ( -
- -
-
- - - -
-
- - - -
-
-
-
- -
-
- - - -
-
- - - -
-
-
-
- -
-
- - - -
-
- - - -
-
-
-
-`; - -exports[`Storyshots components/ElementTypes/ElementGrid with controls and filter 1`] = ` -
-
- -
-
- - - -
-
- - - -
-
-
-
-`; - -exports[`Storyshots components/ElementTypes/ElementGrid with filter 1`] = ` -
-
- -
-
-`; - -exports[`Storyshots components/ElementTypes/ElementGrid without controls 1`] = ` -
-
- -
-
- -
-
- -
-
-`; diff --git a/x-pack/legacy/plugins/canvas/public/components/element_card/__examples__/element_card.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/element_card/__examples__/element_card.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/element_card/__examples__/element_card.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/element_card/__examples__/element_card.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/__snapshots__/element_controls.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/__snapshots__/element_controls.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/__snapshots__/element_controls.examples.storyshot rename to x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/__snapshots__/element_controls.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/__snapshots__/element_grid.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/__snapshots__/element_grid.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/__snapshots__/element_grid.examples.storyshot rename to x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/__snapshots__/element_grid.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/element_controls.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/element_controls.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/element_controls.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/element_controls.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/element_grid.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/element_grid.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/element_grid.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/element_types/__examples__/element_grid.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/element_types/element_controls.tsx b/x-pack/legacy/plugins/canvas/public/components/element_types/element_controls.tsx index fd8836f5ac120a..a23274296f64f3 100644 --- a/x-pack/legacy/plugins/canvas/public/components/element_types/element_controls.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/element_types/element_controls.tsx @@ -7,7 +7,7 @@ import React, { FunctionComponent, MouseEvent } from 'react'; import PropTypes from 'prop-types'; import { EuiFlexGroup, EuiFlexItem, EuiButtonIcon, EuiToolTip } from '@elastic/eui'; -import { ComponentStrings } from '../../../i18n'; +import { ComponentStrings } from '../../../i18n/components'; const { ElementControls: strings } = ComponentStrings; diff --git a/x-pack/legacy/plugins/canvas/public/components/file_upload/__snapshots__/file_upload.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/file_upload/__snapshots__/file_upload.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/file_upload/__snapshots__/file_upload.examples.storyshot rename to x-pack/legacy/plugins/canvas/public/components/file_upload/__snapshots__/file_upload.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/public/components/file_upload/file_upload.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/file_upload/file_upload.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/file_upload/file_upload.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/file_upload/file_upload.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/font_picker/__snapshots__/font_picker.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/font_picker/__snapshots__/font_picker.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/font_picker/__snapshots__/font_picker.examples.storyshot rename to x-pack/legacy/plugins/canvas/public/components/font_picker/__snapshots__/font_picker.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/public/components/font_picker/font_picker.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/font_picker/font_picker.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/font_picker/font_picker.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/font_picker/font_picker.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/item_grid/__examples__/__snapshots__/item_grid.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/item_grid/__examples__/__snapshots__/item_grid.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/item_grid/__examples__/__snapshots__/item_grid.examples.storyshot rename to x-pack/legacy/plugins/canvas/public/components/item_grid/__examples__/__snapshots__/item_grid.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/public/components/item_grid/__examples__/item_grid.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/item_grid/__examples__/item_grid.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/item_grid/__examples__/item_grid.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/item_grid/__examples__/item_grid.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/keyboard_shortcuts_doc/__examples__/__snapshots__/keyboard_shortcuts_doc.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/keyboard_shortcuts_doc/__examples__/__snapshots__/keyboard_shortcuts_doc.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/keyboard_shortcuts_doc/__examples__/__snapshots__/keyboard_shortcuts_doc.examples.storyshot rename to x-pack/legacy/plugins/canvas/public/components/keyboard_shortcuts_doc/__examples__/__snapshots__/keyboard_shortcuts_doc.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/public/components/keyboard_shortcuts_doc/__examples__/keyboard_shortcuts_doc.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/keyboard_shortcuts_doc/__examples__/keyboard_shortcuts_doc.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/keyboard_shortcuts_doc/__examples__/keyboard_shortcuts_doc.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/keyboard_shortcuts_doc/__examples__/keyboard_shortcuts_doc.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/keyboard_shortcuts_doc/keyboard_shortcuts_doc.tsx b/x-pack/legacy/plugins/canvas/public/components/keyboard_shortcuts_doc/keyboard_shortcuts_doc.tsx index 27c951d1757f8f..1c94969292b594 100644 --- a/x-pack/legacy/plugins/canvas/public/components/keyboard_shortcuts_doc/keyboard_shortcuts_doc.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/keyboard_shortcuts_doc/keyboard_shortcuts_doc.tsx @@ -17,11 +17,11 @@ import { EuiTitle, } from '@elastic/eui'; import { keymap } from '../../lib/keymap'; -import { ShortcutMap, ShortcutNameSpace } from '../../../types'; +import { ShortcutMap, ShortcutNameSpace } from '../../../types/shortcuts'; import { getClientPlatform } from '../../lib/get_client_platform'; import { getId } from '../../lib/get_id'; import { getPrettyShortcut } from '../../lib/get_pretty_shortcut'; -import { ComponentStrings } from '../../../i18n'; +import { ComponentStrings } from '../../../i18n/components'; const { KeyboardShortcutsDoc: strings } = ComponentStrings; diff --git a/x-pack/legacy/plugins/canvas/public/components/popover/popover.tsx b/x-pack/legacy/plugins/canvas/public/components/popover/popover.tsx index a5d7ce11094476..25b2e6587c8693 100644 --- a/x-pack/legacy/plugins/canvas/public/components/popover/popover.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/popover/popover.tsx @@ -5,25 +5,23 @@ */ /* eslint react/no-did-mount-set-state: 0, react/forbid-elements: 0 */ -import React, { ReactNode, ReactElement, Component, MouseEvent } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { EuiToolTip, ToolTipPositions, EuiPopover, PropsOf } from '@elastic/eui'; +import { EuiPopover, EuiToolTip } from '@elastic/eui'; -export interface PopoverChildrenProps { - closePopover: () => void; -} - -type EuiPopoverProps = PropsOf; -interface Props extends Omit { +interface Props { + button: (handleClick: React.MouseEventHandler) => React.ReactElement; + tooltipPosition?: 'top' | 'bottom' | 'left' | 'right'; + children: (arg: { closePopover: () => void }) => React.ReactNode; isOpen?: boolean; ownFocus?: boolean; - - button: (handleClick: (ev: MouseEvent) => void) => ReactElement; - - children: (props: PopoverChildrenProps) => ReactNode; - - tooltip: string; - tooltipPosition: ToolTipPositions; + tooltip?: string; + panelClassName?: string; + anchorClassName?: string; + anchorPosition?: string; + panelPaddingSize?: 'none' | 's' | 'm' | 'l'; + id?: string; + className?: string; } interface State { @@ -47,8 +45,8 @@ export class Popover extends Component { tooltipPosition: 'top', }; - state = { - isPopoverOpen: false, + state: State = { + isPopoverOpen: !!this.props.isOpen, }; componentDidMount() { @@ -58,7 +56,7 @@ export class Popover extends Component { } handleClick = () => { - this.setState(state => ({ + this.setState((state: any) => ({ isPopoverOpen: !state.isPopoverOpen, })); }; @@ -72,9 +70,9 @@ export class Popover extends Component { render() { const { button, children, tooltip, tooltipPosition, ...rest } = this.props; - const wrappedButton = (handleClick: (ev: MouseEvent) => void) => { + const wrappedButton = (handleClick: any) => { // wrap button in tooltip, if tooltip text is provided - if (!this.state.isPopoverOpen && tooltip.length) { + if (!this.state.isPopoverOpen && tooltip && tooltip.length) { return ( {button(handleClick)} @@ -86,17 +84,18 @@ export class Popover extends Component { }; const appWrapper = document.querySelector('.app-wrapper'); + const EuiPopoverAny = (EuiPopover as any) as React.FC; return ( - {children({ closePopover: this.closePopover })} - + ); } } diff --git a/x-pack/legacy/plugins/canvas/public/components/shape_picker/__examples__/__snapshots__/shape_picker.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/shape_picker/__examples__/__snapshots__/shape_picker.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/shape_picker/__examples__/__snapshots__/shape_picker.examples.storyshot rename to x-pack/legacy/plugins/canvas/public/components/shape_picker/__examples__/__snapshots__/shape_picker.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/public/components/shape_picker/__examples__/shape_picker.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/shape_picker/__examples__/shape_picker.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/shape_picker/__examples__/shape_picker.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/shape_picker/__examples__/shape_picker.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/__examples__/__snapshots__/shape_picker_popover.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/__examples__/__snapshots__/shape_picker_popover.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/__examples__/__snapshots__/shape_picker_popover.examples.storyshot rename to x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/__examples__/__snapshots__/shape_picker_popover.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/__examples__/shape_picker_popover.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/__examples__/shape_picker_popover.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/__examples__/shape_picker_popover.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/__examples__/shape_picker_popover.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/shape_picker_popover.tsx b/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/shape_picker_popover.tsx index 717ec6d0faeccf..d42e08d2bc8524 100644 --- a/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/shape_picker_popover.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/shape_picker_popover/shape_picker_popover.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { MouseEvent } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { EuiLink, EuiPanel } from '@elastic/eui'; import { Popover } from '../popover'; @@ -21,7 +21,7 @@ interface Props { } export const ShapePickerPopover = ({ shapes, onChange, value, ariaLabel }: Props) => { - const button = (handleClick: (ev: MouseEvent) => void) => ( + const button = (handleClick: React.MouseEventHandler) => ( diff --git a/x-pack/legacy/plugins/canvas/public/components/shape_preview/__examples__/__snapshots__/shape_preview.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/shape_preview/__examples__/__snapshots__/shape_preview.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/shape_preview/__examples__/__snapshots__/shape_preview.examples.storyshot rename to x-pack/legacy/plugins/canvas/public/components/shape_preview/__examples__/__snapshots__/shape_preview.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/public/components/shape_preview/__examples__/shape_preview.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/shape_preview/__examples__/shape_preview.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/shape_preview/__examples__/shape_preview.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/shape_preview/__examples__/shape_preview.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/group_settings.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/group_settings.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/group_settings.examples.storyshot rename to x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/group_settings.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/multi_element_settings.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/multi_element_settings.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/multi_element_settings.examples.storyshot rename to x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/__snapshots__/multi_element_settings.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/group_settings.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/group_settings.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/group_settings.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/group_settings.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/multi_element_settings.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/multi_element_settings.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/multi_element_settings.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/sidebar/__examples__/multi_element_settings.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/group_settings.tsx b/x-pack/legacy/plugins/canvas/public/components/sidebar/group_settings.tsx index 95d9035774a6ae..e1ce539256daa6 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar/group_settings.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar/group_settings.tsx @@ -6,7 +6,7 @@ import React, { FunctionComponent } from 'react'; import { EuiText } from '@elastic/eui'; -import { ComponentStrings } from '../../../i18n'; +import { ComponentStrings } from '../../../i18n/components'; const { GroupSettings: strings } = ComponentStrings; diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/multi_element_settings.tsx b/x-pack/legacy/plugins/canvas/public/components/sidebar/multi_element_settings.tsx index 999c1c2daaf5b5..cae5671bf901bd 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar/multi_element_settings.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar/multi_element_settings.tsx @@ -6,7 +6,7 @@ import React, { FunctionComponent } from 'react'; import { EuiText } from '@elastic/eui'; -import { ComponentStrings } from '../../../i18n'; +import { ComponentStrings } from '../../../i18n/components'; const { MultiElementSettings: strings } = ComponentStrings; diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar_header/__examples__/__snapshots__/sidebar_header.examples.storyshot b/x-pack/legacy/plugins/canvas/public/components/sidebar_header/__examples__/__snapshots__/sidebar_header.stories.storyshot similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/sidebar_header/__examples__/__snapshots__/sidebar_header.examples.storyshot rename to x-pack/legacy/plugins/canvas/public/components/sidebar_header/__examples__/__snapshots__/sidebar_header.stories.storyshot diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar_header/__examples__/sidebar_header.examples.tsx b/x-pack/legacy/plugins/canvas/public/components/sidebar_header/__examples__/sidebar_header.stories.tsx similarity index 100% rename from x-pack/legacy/plugins/canvas/public/components/sidebar_header/__examples__/sidebar_header.examples.tsx rename to x-pack/legacy/plugins/canvas/public/components/sidebar_header/__examples__/sidebar_header.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar_header/sidebar_header.tsx b/x-pack/legacy/plugins/canvas/public/components/sidebar_header/sidebar_header.tsx index 3a0e191b9f4b5a..d4dec6cca064b8 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar_header/sidebar_header.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar_header/sidebar_header.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Component, Fragment, MouseEvent } from 'react'; +import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { EuiFlexGroup, @@ -20,7 +20,8 @@ import { import { Popover } from '../popover'; import { CustomElementModal } from '../custom_element_modal'; import { ToolTipShortcut } from '../tool_tip_shortcut/'; -import { ComponentStrings, ShortcutStrings } from '../../../i18n'; +import { ComponentStrings } from '../../../i18n/components'; +import { ShortcutStrings } from '../../../i18n/shortcuts'; const topBorderClassName = 'canvasContextMenu--topBorder'; @@ -138,7 +139,7 @@ interface MenuTuple { panel: EuiContextMenuPanelDescriptor; } -const contextMenuButton = (handleClick: (event: MouseEvent) => void) => ( +const contextMenuButton = (handleClick: React.MouseEventHandler) => ( void; @@ -129,7 +129,7 @@ export const WorkpadExport: FunctionComponent = ({ ], }); - const exportControl = (togglePopover: (ev: MouseEvent) => void) => ( + const exportControl = (togglePopover: React.MouseEventHandler) => ( !Array.isArray(v), 'Array'), + ]), }; const analyzerValidations = [ @@ -178,40 +181,40 @@ export const PARAMETERS_DEFINITION = { }, ], }, - schema: Joi.string(), + schema: t.string, }, store: { fieldConfig: { type: FIELD_TYPES.CHECKBOX, defaultValue: false, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, index: { fieldConfig: { type: FIELD_TYPES.CHECKBOX, defaultValue: true, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, doc_values: { fieldConfig: { defaultValue: true, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, doc_values_binary: { fieldConfig: { defaultValue: false, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, fielddata: { fieldConfig: { type: FIELD_TYPES.CHECKBOX, defaultValue: false, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, fielddata_frequency_filter: fielddataFrequencyFilterParam, fielddata_frequency_filter_percentage: { @@ -280,19 +283,19 @@ export const PARAMETERS_DEFINITION = { fieldConfig: { defaultValue: true, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, coerce_shape: { fieldConfig: { defaultValue: false, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, ignore_malformed: { fieldConfig: { defaultValue: false, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, null_value: { fieldConfig: { @@ -300,7 +303,7 @@ export const PARAMETERS_DEFINITION = { type: FIELD_TYPES.TEXT, label: nullValueLabel, }, - schema: Joi.string(), + schema: t.string, }, null_value_ip: { fieldConfig: { @@ -323,7 +326,7 @@ export const PARAMETERS_DEFINITION = { }, ], }, - schema: Joi.number(), + schema: t.number, }, null_value_boolean: { fieldConfig: { @@ -332,7 +335,7 @@ export const PARAMETERS_DEFINITION = { deserializer: (value: string | boolean) => mapIndexToValue.indexOf(value), serializer: (value: number) => mapIndexToValue[value], }, - schema: Joi.any().valid([true, false, 'true', 'false']), + schema: t.union([t.literal(true), t.literal(false), t.literal('true'), t.literal('false')]), }, null_value_geo_point: { fieldConfig: { @@ -376,7 +379,7 @@ export const PARAMETERS_DEFINITION = { } }, }, - schema: Joi.any(), + schema: t.any, }, copy_to: { fieldConfig: { @@ -398,7 +401,7 @@ export const PARAMETERS_DEFINITION = { }, ], }, - schema: Joi.string(), + schema: t.string, }, max_input_length: { fieldConfig: { @@ -421,7 +424,7 @@ export const PARAMETERS_DEFINITION = { }, ], }, - schema: Joi.number(), + schema: t.number, }, locale: { fieldConfig: { @@ -454,7 +457,7 @@ export const PARAMETERS_DEFINITION = { }, ], }, - schema: Joi.string(), + schema: t.string, }, orientation: { fieldConfig: { @@ -464,7 +467,7 @@ export const PARAMETERS_DEFINITION = { defaultMessage: 'Orientation', }), }, - schema: Joi.string(), + schema: t.string, }, boost: { fieldConfig: { @@ -484,7 +487,7 @@ export const PARAMETERS_DEFINITION = { }, ], } as FieldConfig, - schema: Joi.number(), + schema: t.number, }, scaling_factor: { title: i18n.translate('xpack.idxMgmt.mappingsEditor.parameters.scalingFactorFieldTitle', { @@ -535,7 +538,7 @@ export const PARAMETERS_DEFINITION = { defaultMessage: 'Value must be greater than 0.', }), } as FieldConfig, - schema: Joi.number(), + schema: t.number, }, dynamic: { fieldConfig: { @@ -545,7 +548,7 @@ export const PARAMETERS_DEFINITION = { type: FIELD_TYPES.CHECKBOX, defaultValue: true, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, enabled: { fieldConfig: { @@ -555,7 +558,7 @@ export const PARAMETERS_DEFINITION = { type: FIELD_TYPES.CHECKBOX, defaultValue: true, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, format: { fieldConfig: { @@ -577,7 +580,7 @@ export const PARAMETERS_DEFINITION = { /> ), }, - schema: Joi.string(), + schema: t.string, }, analyzer: { fieldConfig: { @@ -587,7 +590,7 @@ export const PARAMETERS_DEFINITION = { defaultValue: INDEX_DEFAULT, validations: analyzerValidations, }, - schema: Joi.string(), + schema: t.string, }, search_analyzer: { fieldConfig: { @@ -597,7 +600,7 @@ export const PARAMETERS_DEFINITION = { defaultValue: INDEX_DEFAULT, validations: analyzerValidations, }, - schema: Joi.string(), + schema: t.string, }, search_quote_analyzer: { fieldConfig: { @@ -607,7 +610,7 @@ export const PARAMETERS_DEFINITION = { defaultValue: INDEX_DEFAULT, validations: analyzerValidations, }, - schema: Joi.string(), + schema: t.string, }, normalizer: { fieldConfig: { @@ -636,76 +639,76 @@ export const PARAMETERS_DEFINITION = { defaultMessage: `The name of a normalizer defined in the index's settings.`, }), }, - schema: Joi.string(), + schema: t.string, }, index_options: { fieldConfig: { ...indexOptionsConfig, defaultValue: 'positions', }, - schema: Joi.string(), + schema: t.string, }, index_options_keyword: { fieldConfig: { ...indexOptionsConfig, defaultValue: 'docs', }, - schema: Joi.string(), + schema: t.string, }, index_options_flattened: { fieldConfig: { ...indexOptionsConfig, defaultValue: 'docs', }, - schema: Joi.string(), + schema: t.string, }, eager_global_ordinals: { fieldConfig: { defaultValue: false, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, index_phrases: { fieldConfig: { defaultValue: false, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, preserve_separators: { fieldConfig: { defaultValue: true, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, preserve_position_increments: { fieldConfig: { defaultValue: true, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, ignore_z_value: { fieldConfig: { defaultValue: true, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, points_only: { fieldConfig: { defaultValue: false, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, norms: { fieldConfig: { defaultValue: true, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, norms_keyword: { fieldConfig: { defaultValue: false, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, term_vector: { fieldConfig: { @@ -715,7 +718,7 @@ export const PARAMETERS_DEFINITION = { }), defaultValue: 'no', }, - schema: Joi.string(), + schema: t.string, }, path: { fieldConfig: { @@ -741,7 +744,7 @@ export const PARAMETERS_DEFINITION = { serializer: (value: AliasOption[]) => (value.length === 0 ? '' : value[0].id), } as FieldConfig, targetTypesNotAllowed: ['object', 'nested', 'alias'] as DataType[], - schema: Joi.string(), + schema: t.string, }, position_increment_gap: { fieldConfig: { @@ -771,7 +774,7 @@ export const PARAMETERS_DEFINITION = { }, ], }, - schema: Joi.number(), + schema: t.number, }, index_prefixes: { fieldConfig: { defaultValue: {} }, // Needed for FieldParams typing @@ -791,9 +794,9 @@ export const PARAMETERS_DEFINITION = { } as FieldConfig, }, }, - schema: Joi.object().keys({ - min_chars: Joi.number(), - max_chars: Joi.number(), + schema: t.partial({ + min_chars: t.number, + max_chars: t.number, }), }, similarity: { @@ -804,13 +807,13 @@ export const PARAMETERS_DEFINITION = { defaultMessage: 'Similarity algorithm', }), }, - schema: Joi.string(), + schema: t.string, }, split_queries_on_whitespace: { fieldConfig: { defaultValue: false, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, ignore_above: { fieldConfig: { @@ -842,13 +845,13 @@ export const PARAMETERS_DEFINITION = { }, ], }, - schema: Joi.number(), + schema: t.number, }, enable_position_increments: { fieldConfig: { defaultValue: true, }, - schema: Joi.boolean().strict(), + schema: t.boolean, }, depth_limit: { fieldConfig: { @@ -868,7 +871,7 @@ export const PARAMETERS_DEFINITION = { }, ], }, - schema: Joi.number(), + schema: t.number, }, dims: { fieldConfig: { @@ -894,6 +897,6 @@ export const PARAMETERS_DEFINITION = { }, ], }, - schema: Joi.string(), + schema: t.string, }, }; diff --git a/x-pack/legacy/plugins/index_management/public/app/components/mappings_editor/lib/error_reporter.ts b/x-pack/legacy/plugins/index_management/public/app/components/mappings_editor/lib/error_reporter.ts new file mode 100644 index 00000000000000..363ccfc2a5fab5 --- /dev/null +++ b/x-pack/legacy/plugins/index_management/public/app/components/mappings_editor/lib/error_reporter.ts @@ -0,0 +1,42 @@ +/* + * 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 { ValidationError, Validation } from 'io-ts'; +import { fold } from 'fp-ts/lib/Either'; +import { Reporter } from 'io-ts/lib/Reporter'; + +export type ReporterResult = Array<{ path: string[]; message: string }>; + +export const failure = (validation: any): ReporterResult => { + return validation.map((e: ValidationError) => { + const path: string[] = []; + let validationName = ''; + + e.context.forEach((ctx, idx) => { + if (ctx.key) { + path.push(ctx.key); + } + + if (idx === e.context.length - 1) { + validationName = ctx.type.name; + } + }); + const lastItemName = path[path.length - 1]; + return { + path, + message: + 'Invalid value ' + + JSON.stringify(e.value) + + ` supplied to ${lastItemName}(${validationName})`, + }; + }); +}; + +const empty: never[] = []; +const success = () => empty; + +export const ErrorReporter: Reporter = { + report: (validation: Validation) => fold(failure, success)(validation as any), +}; diff --git a/x-pack/legacy/plugins/index_management/public/app/components/mappings_editor/lib/mappings_validator.test.ts b/x-pack/legacy/plugins/index_management/public/app/components/mappings_editor/lib/mappings_validator.test.ts index e9af16af2afa07..5c9fa3fd05d8ce 100644 --- a/x-pack/legacy/plugins/index_management/public/app/components/mappings_editor/lib/mappings_validator.test.ts +++ b/x-pack/legacy/plugins/index_management/public/app/components/mappings_editor/lib/mappings_validator.test.ts @@ -63,9 +63,9 @@ describe('Mappings configuration validator', () => { expect(errors).not.toBe(undefined); expect(errors!.length).toBe(3); expect(errors!).toEqual([ - { code: 'ERR_CONFIG', configName: 'numeric_detection' }, - { code: 'ERR_CONFIG', configName: 'dynamic_date_formats' }, { code: 'ERR_CONFIG', configName: '_source' }, + { code: 'ERR_CONFIG', configName: 'dynamic_date_formats' }, + { code: 'ERR_CONFIG', configName: 'numeric_detection' }, ]); }); }); diff --git a/x-pack/legacy/plugins/index_management/public/app/components/mappings_editor/lib/mappings_validator.ts b/x-pack/legacy/plugins/index_management/public/app/components/mappings_editor/lib/mappings_validator.ts index cd7fc57d1dbc83..990d5ec961a6fb 100644 --- a/x-pack/legacy/plugins/index_management/public/app/components/mappings_editor/lib/mappings_validator.ts +++ b/x-pack/legacy/plugins/index_management/public/app/components/mappings_editor/lib/mappings_validator.ts @@ -3,7 +3,12 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import Joi from 'joi'; +import { pick } from 'lodash'; +import * as t from 'io-ts'; +import { ordString } from 'fp-ts/lib/Ord'; +import { toArray } from 'fp-ts/lib/Set'; +import { isLeft, isRight } from 'fp-ts/lib/Either'; +import { ErrorReporter } from './error_reporter'; import { ALL_DATA_TYPES, PARAMETERS_DEFINITION } from '../constants'; import { FieldMeta } from '../types'; import { getFieldMeta } from '../lib'; @@ -72,7 +77,7 @@ const validateParameter = (parameter: string, value: any): boolean => { const parameterSchema = (PARAMETERS_DEFINITION as any)[parameter]!.schema; if (parameterSchema) { - return Boolean(Joi.validate(value, parameterSchema).error) === false; + return isRight(parameterSchema.decode(value)); } // Fallback, if no schema defined for the parameter (this should not happen in theory) @@ -192,54 +197,55 @@ export const validateProperties = (properties = {}): PropertiesValidatorResponse * Single source of truth to validate the *configuration* of the mappings. * Whenever a user loads a JSON object it will be validate against this Joi schema. */ -export const mappingsConfigurationSchema = Joi.object().keys({ - dynamic: Joi.any().valid([true, false, 'strict']), - date_detection: Joi.boolean().strict(), - numeric_detection: Joi.boolean().strict(), - dynamic_date_formats: Joi.array().items(Joi.string()), - _source: Joi.object().keys({ - enabled: Joi.boolean().strict(), - includes: Joi.array().items(Joi.string()), - excludes: Joi.array().items(Joi.string()), +export const mappingsConfigurationSchema = t.partial({ + dynamic: t.union([t.literal(true), t.literal(false), t.literal('strict')]), + date_detection: t.boolean, + numeric_detection: t.boolean, + dynamic_date_formats: t.array(t.string), + _source: t.partial({ + enabled: t.boolean, + includes: t.array(t.string), + excludes: t.array(t.string), }), - _meta: Joi.object(), - _routing: Joi.object().keys({ - required: Joi.boolean().strict(), + _meta: t.UnknownRecord, + _routing: t.partial({ + required: t.boolean, }), }); +const mappingsConfigurationSchemaKeys = Object.keys(mappingsConfigurationSchema.props); + const validateMappingsConfiguration = ( mappingsConfiguration: any ): { value: any; errors: MappingsValidationError[] } => { // Array to keep track of invalid configuration parameters. - const configurationRemoved: string[] = []; + const configurationRemoved: Set = new Set(); - const { value: parsedConfiguration, error: configurationError } = Joi.validate( - mappingsConfiguration, - mappingsConfigurationSchema, - { - stripUnknown: true, - abortEarly: false, - } - ); + let copyOfMappingsConfig = { ...mappingsConfiguration }; + const result = mappingsConfigurationSchema.decode(mappingsConfiguration); - if (configurationError) { + if (isLeft(result)) { /** * To keep the logic simple we will strip out the parameters that contain errors */ - configurationError.details.forEach(error => { + const errors = ErrorReporter.report(result); + errors.forEach(error => { const configurationName = error.path[0]; - configurationRemoved.push(configurationName); - delete parsedConfiguration[configurationName]; + configurationRemoved.add(configurationName); + delete copyOfMappingsConfig[configurationName]; }); } - const errors: MappingsValidationError[] = configurationRemoved.map(configName => ({ - code: 'ERR_CONFIG', - configName, - })); + copyOfMappingsConfig = pick(copyOfMappingsConfig, mappingsConfigurationSchemaKeys); + + const errors: MappingsValidationError[] = toArray(ordString)(configurationRemoved) + .map(configName => ({ + code: 'ERR_CONFIG', + configName, + })) + .sort((a, b) => a.configName.localeCompare(b.configName)) as MappingsValidationError[]; - return { value: parsedConfiguration, errors }; + return { value: copyOfMappingsConfig, errors }; }; export const validateMappings = (mappings: any = {}): MappingsValidatorResponse => { diff --git a/x-pack/legacy/plugins/infra/public/components/loading/__examples__/index.stories.tsx b/x-pack/legacy/plugins/infra/public/components/loading/__examples__/index.stories.tsx new file mode 100644 index 00000000000000..04aa1a344d1a20 --- /dev/null +++ b/x-pack/legacy/plugins/infra/public/components/loading/__examples__/index.stories.tsx @@ -0,0 +1,12 @@ +/* + * 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 { storiesOf } from '@storybook/react'; +import React from 'react'; +import { InfraLoadingPanel } from '..'; + +storiesOf('infra/InfraLoadingPanel', module).add('example', () => ( + +)); diff --git a/x-pack/legacy/plugins/infra/scripts/storybook.js b/x-pack/legacy/plugins/infra/scripts/storybook.js new file mode 100644 index 00000000000000..05d5daedf58f21 --- /dev/null +++ b/x-pack/legacy/plugins/infra/scripts/storybook.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { join } from 'path'; + +// eslint-disable-next-line +require('@kbn/storybook').runStorybookCli({ + name: 'infra', + storyGlobs: [join(__dirname, '..', 'public', 'components', '**', '*.stories.tsx')], +}); diff --git a/x-pack/legacy/plugins/lens/public/app_plugin/plugin.tsx b/x-pack/legacy/plugins/lens/public/app_plugin/plugin.tsx index 7465de2dba7f1f..f7d9ae5741afbe 100644 --- a/x-pack/legacy/plugins/lens/public/app_plugin/plugin.tsx +++ b/x-pack/legacy/plugins/lens/public/app_plugin/plugin.tsx @@ -103,13 +103,13 @@ export class AppPlugin { }) ); const updateUrlTime = (urlVars: Record): void => { - const decoded: RisonObject = rison.decode(urlVars._g) as RisonObject; - if (!decoded) { + const decoded = rison.decode(urlVars._g); + if (!isRisonObject(decoded)) { return; } // @ts-ignore decoded.time = data.query.timefilter.timefilter.getTime(); - urlVars._g = rison.encode((decoded as unknown) as RisonObject); + urlVars._g = rison.encode(decoded); }; const redirectTo = ( routeProps: RouteComponentProps<{ id?: string }>, diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js b/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js index cc840d552e659e..df212f23cd8942 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js @@ -6,7 +6,7 @@ import React from 'react'; -import { vislibColorMaps } from 'ui/vislib/components/color/colormaps'; +import { vislibColorMaps } from 'ui/color_maps'; import { getLegendColors, getColor } from 'ui/vis/map/color_util'; import { ColorGradient } from './components/color_gradient'; import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; @@ -97,36 +97,6 @@ const COLOR_PALETTES_CONFIGS = [ id: 'palette_0', colors: DEFAULT_FILL_COLORS.slice(0, COLOR_PALETTE_MAX_SIZE), }, - { - id: 'palette_1', - colors: [ - '#a6cee3', - '#1f78b4', - '#b2df8a', - '#33a02c', - '#fb9a99', - '#e31a1c', - '#fdbf6f', - '#ff7f00', - '#cab2d6', - '#6a3d9a', - ], - }, - { - id: 'palette_2', - colors: [ - '#8dd3c7', - '#ffffb3', - '#bebada', - '#fb8072', - '#80b1d3', - '#fdb462', - '#b3de69', - '#fccde5', - '#d9d9d9', - '#bc80bd', - ], - }, ]; export function getColorPalette(paletteId) { diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js index 42e88220bd1d99..e80ccb9e144b9a 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js @@ -227,7 +227,7 @@ export class DynamicColorProperty extends DynamicStyleProperty { } mbStops.push(defaultColor); //last color is default color - return ['match', ['get', this._options.field.name], ...mbStops]; + return ['match', ['to-string', ['get', this._options.field.name]], ...mbStops]; } _getMbOrdinalColorStops() { diff --git a/x-pack/legacy/plugins/ml/public/application/components/navigation_menu/tabs.tsx b/x-pack/legacy/plugins/ml/public/application/components/navigation_menu/tabs.tsx index ac83d598f23826..774fe2d7428340 100644 --- a/x-pack/legacy/plugins/ml/public/application/components/navigation_menu/tabs.tsx +++ b/x-pack/legacy/plugins/ml/public/application/components/navigation_menu/tabs.tsx @@ -81,6 +81,8 @@ export const Tabs: FC = ({ tabId, mainTabId, disableLinks }) => { const tabs = getTabs(mainTabId, disableLinks); + if (tabs.length === 0) return null; + return ( {tabs.map((tab: Tab) => { diff --git a/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/common/fields.ts b/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/common/fields.ts index e7d5afeba371fa..e309013e585ad0 100644 --- a/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/common/fields.ts +++ b/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/common/fields.ts @@ -244,7 +244,7 @@ export function getFlattenedFields(obj: EsDocSource, resultsField: string): EsFi export const getDefaultFieldsFromJobCaps = ( fields: Field[], jobConfig: DataFrameAnalyticsConfig -): { selectedFields: Field[]; docFields: Field[] } => { +): { selectedFields: Field[]; docFields: Field[]; depVarType?: ES_FIELD_TYPES } => { const fieldsObj = { selectedFields: [], docFields: [] }; if (fields.length === 0) { return fieldsObj; @@ -282,6 +282,7 @@ export const getDefaultFieldsFromJobCaps = ( return { selectedFields, docFields: allFields, + depVarType: type, }; }; @@ -388,13 +389,40 @@ export const toggleSelectedFieldSimple = ( } return selectedFields; }; - -export const toggleSelectedField = (selectedFields: Field[], column: EsFieldName): Field[] => { +// Fields starting with 'ml' or custom result name not included in newJobCapsService fields so +// need to recreate the field with correct type and add to selected fields +export const toggleSelectedField = ( + selectedFields: Field[], + column: EsFieldName, + resultsField: string, + depVarType?: ES_FIELD_TYPES +): Field[] => { const index = selectedFields.map(field => field.name).indexOf(column); if (index === -1) { const columnField = newJobCapsService.getFieldById(column); if (columnField !== null) { selectedFields.push(columnField); + } else { + const resultFieldPattern = `^${resultsField}\.`; + const regex = new RegExp(resultFieldPattern); + const isResultField = column.match(regex) !== null; + let newField; + + if (isResultField && column.includes('is_training')) { + newField = { + id: column, + name: column, + type: ES_FIELD_TYPES.BOOLEAN, + }; + } else if (isResultField && depVarType !== undefined) { + newField = { + id: column, + name: column, + type: depVarType, + }; + } + + if (newField) selectedFields.push(newField); } } else { selectedFields.splice(index, 1); diff --git a/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/results_table.tsx b/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/results_table.tsx index 57c8b9ad37c650..d9699f1a50a91e 100644 --- a/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/results_table.tsx +++ b/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/results_table.tsx @@ -79,6 +79,7 @@ export const ResultsTable: FC = React.memo( const [pageSize, setPageSize] = useState(25); const [selectedFields, setSelectedFields] = useState([] as Field[]); const [docFields, setDocFields] = useState([] as Field[]); + const [depVarType, setDepVarType] = useState(undefined); const [isColumnsPopoverVisible, setColumnsPopoverVisible] = useState(false); const [searchQuery, setSearchQuery] = useState(defaultSearchQuery); const [searchError, setSearchError] = useState(undefined); @@ -102,7 +103,9 @@ export const ResultsTable: FC = React.memo( function toggleColumn(column: EsFieldName) { if (tableItems.length > 0 && jobConfig !== undefined) { // spread to a new array otherwise the component wouldn't re-render - setSelectedFields([...toggleSelectedField(selectedFields, column)]); + setSelectedFields([ + ...toggleSelectedField(selectedFields, column, jobConfig.dest.results_field, depVarType), + ]); } } @@ -113,7 +116,7 @@ export const ResultsTable: FC = React.memo( sortDirection, status, tableItems, - } = useExploreData(jobConfig, selectedFields, setSelectedFields, setDocFields); + } = useExploreData(jobConfig, selectedFields, setSelectedFields, setDocFields, setDepVarType); const columns: Array> = selectedFields.map(field => { const { type } = field; diff --git a/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_explore_data.ts b/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_explore_data.ts index b61f9f65241161..e19264a2ccdb18 100644 --- a/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_explore_data.ts +++ b/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_explore_data.ts @@ -20,6 +20,7 @@ import { getNestedProperty } from '../../../../../util/object_utils'; import { newJobCapsService } from '../../../../../services/new_job_capabilities_service'; import { Field } from '../../../../../../../common/types/fields'; import { LoadExploreDataArg } from '../../../../common/analytics'; +import { ES_FIELD_TYPES } from '../../../../../../../../../../../src/plugins/data/public'; import { getDefaultFieldsFromJobCaps, @@ -46,7 +47,8 @@ export const useExploreData = ( jobConfig: DataFrameAnalyticsConfig | undefined, selectedFields: Field[], setSelectedFields: React.Dispatch>, - setDocFields: React.Dispatch> + setDocFields: React.Dispatch>, + setDepVarType: React.Dispatch> ): UseExploreDataReturnType => { const [errorMessage, setErrorMessage] = useState(''); const [status, setStatus] = useState(INDEX_STATUS.UNUSED); @@ -58,11 +60,13 @@ export const useExploreData = ( const { fields } = newJobCapsService; if (selectedFields.length === 0 && jobConfig !== undefined) { - const { selectedFields: defaultSelected, docFields } = getDefaultFieldsFromJobCaps( - fields, - jobConfig - ); + const { + selectedFields: defaultSelected, + docFields, + depVarType, + } = getDefaultFieldsFromJobCaps(fields, jobConfig); + setDepVarType(depVarType); setSelectedFields(defaultSelected); setDocFields(docFields); } diff --git a/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/results_table.tsx b/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/results_table.tsx index 6c576003f27f87..493ec864f3335f 100644 --- a/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/results_table.tsx +++ b/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/results_table.tsx @@ -80,6 +80,7 @@ export const ResultsTable: FC = React.memo( const [pageSize, setPageSize] = useState(25); const [selectedFields, setSelectedFields] = useState([] as Field[]); const [docFields, setDocFields] = useState([] as Field[]); + const [depVarType, setDepVarType] = useState(undefined); const [isColumnsPopoverVisible, setColumnsPopoverVisible] = useState(false); const [searchQuery, setSearchQuery] = useState(defaultSearchQuery); const [searchError, setSearchError] = useState(undefined); @@ -103,7 +104,9 @@ export const ResultsTable: FC = React.memo( function toggleColumn(column: EsFieldName) { if (tableItems.length > 0 && jobConfig !== undefined) { // spread to a new array otherwise the component wouldn't re-render - setSelectedFields([...toggleSelectedField(selectedFields, column)]); + setSelectedFields([ + ...toggleSelectedField(selectedFields, column, jobConfig.dest.results_field, depVarType), + ]); } } @@ -114,7 +117,7 @@ export const ResultsTable: FC = React.memo( sortDirection, status, tableItems, - } = useExploreData(jobConfig, selectedFields, setSelectedFields, setDocFields); + } = useExploreData(jobConfig, selectedFields, setSelectedFields, setDocFields, setDepVarType); const columns: Array> = selectedFields.map(field => { const { type } = field; diff --git a/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/use_explore_data.ts b/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/use_explore_data.ts index f6aa3e490f3ec7..84a5ee09b51787 100644 --- a/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/use_explore_data.ts +++ b/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/use_explore_data.ts @@ -25,6 +25,7 @@ import { } from '../../../../common'; import { Field } from '../../../../../../../common/types/fields'; import { LoadExploreDataArg } from '../../../../common/analytics'; +import { ES_FIELD_TYPES } from '../../../../../../../../../../../src/plugins/data/public'; export type TableItem = Record; @@ -41,7 +42,8 @@ export const useExploreData = ( jobConfig: DataFrameAnalyticsConfig | undefined, selectedFields: Field[], setSelectedFields: React.Dispatch>, - setDocFields: React.Dispatch> + setDocFields: React.Dispatch>, + setDepVarType: React.Dispatch> ): UseExploreDataReturnType => { const [errorMessage, setErrorMessage] = useState(''); const [status, setStatus] = useState(INDEX_STATUS.UNUSED); @@ -53,11 +55,13 @@ export const useExploreData = ( const { fields } = newJobCapsService; if (selectedFields.length === 0 && jobConfig !== undefined) { - const { selectedFields: defaultSelected, docFields } = getDefaultFieldsFromJobCaps( - fields, - jobConfig - ); + const { + selectedFields: defaultSelected, + docFields, + depVarType, + } = getDefaultFieldsFromJobCaps(fields, jobConfig); + setDepVarType(depVarType); setSelectedFields(defaultSelected); setDocFields(docFields); } diff --git a/x-pack/legacy/plugins/ml/public/application/util/chart_utils.js b/x-pack/legacy/plugins/ml/public/application/util/chart_utils.js index d54b1a9c9ac222..dfa896b3124c66 100644 --- a/x-pack/legacy/plugins/ml/public/application/util/chart_utils.js +++ b/x-pack/legacy/plugins/ml/public/application/util/chart_utils.js @@ -107,7 +107,7 @@ export function drawLineChartDots(data, lineChartGroup, lineChartValuesLine, rad } // this replicates Kibana's filterAxisLabels() behavior -// which can be found in ui/vislib/lib/axis/axis_labels.js +// which can be found in src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/axis/axis_labels.js // axis labels which overflow the chart's boundaries will be removed export function filterAxisLabels(selection, chartWidth) { if (selection === undefined || selection.selectAll === undefined) { diff --git a/x-pack/legacy/plugins/monitoring/common/constants.js b/x-pack/legacy/plugins/monitoring/common/constants.js index 917f7fab1ed304..ff16b0e9c5167f 100644 --- a/x-pack/legacy/plugins/monitoring/common/constants.js +++ b/x-pack/legacy/plugins/monitoring/common/constants.js @@ -141,12 +141,23 @@ export const CLUSTER_ALERTS_ADDRESS_CONFIG_KEY = 'cluster_alerts.email_notificat export const STANDALONE_CLUSTER_CLUSTER_UUID = '__standalone_cluster__'; -export const INDEX_PATTERN = '.monitoring-*-6-*,.monitoring-*-7-*'; -export const INDEX_PATTERN_KIBANA = '.monitoring-kibana-6-*,.monitoring-kibana-7-*'; -export const INDEX_PATTERN_LOGSTASH = '.monitoring-logstash-6-*,.monitoring-logstash-7-*'; -export const INDEX_PATTERN_BEATS = '.monitoring-beats-6-*,.monitoring-beats-7-*'; -export const INDEX_ALERTS = '.monitoring-alerts-6,.monitoring-alerts-7'; -export const INDEX_PATTERN_ELASTICSEARCH = '.monitoring-es-6-*,.monitoring-es-7-*'; +const INDEX_PATTERN_NEW = ',monitoring-*-7-*,monitoring-*-8-*'; +const INDEX_PATTERN_KIBANA_NEW = ',monitoring-kibana-7-*,monitoring-kibana-8-*'; +const INDEX_PATTERN_LOGSTASH_NEW = ',monitoring-logstash-7-*,monitoring-logstash-8-*'; +const INDEX_PATTERN_BEATS_NEW = ',monitoring-beats-7-*,monitoring-beats-8-*'; +const INDEX_ALERTS_NEW = ',monitoring-alerts-7,monitoring-alerts-8'; +const INDEX_PATTERN_ELASTICSEARCH_NEW = ',monitoring-es-7-*,monitoring-es-8-*'; + +export const INDEX_PATTERN = '.monitoring-*-6-*,.monitoring-*-7-*' + INDEX_PATTERN_NEW; +export const INDEX_PATTERN_KIBANA = + '.monitoring-kibana-6-*,.monitoring-kibana-7-*' + INDEX_PATTERN_KIBANA_NEW; +export const INDEX_PATTERN_LOGSTASH = + '.monitoring-logstash-6-*,.monitoring-logstash-7-*' + INDEX_PATTERN_LOGSTASH_NEW; +export const INDEX_PATTERN_BEATS = + '.monitoring-beats-6-*,.monitoring-beats-7-*' + INDEX_PATTERN_BEATS_NEW; +export const INDEX_ALERTS = '.monitoring-alerts-6,.monitoring-alerts-7' + INDEX_ALERTS_NEW; +export const INDEX_PATTERN_ELASTICSEARCH = + '.monitoring-es-6-*,.monitoring-es-7-*' + INDEX_PATTERN_ELASTICSEARCH_NEW; export const INDEX_PATTERN_FILEBEAT = 'filebeat-*'; diff --git a/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_cluster_search.js b/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_cluster_search.js index f6dafb5bb8c7ee..1e5615cc907ba6 100644 --- a/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_cluster_search.js +++ b/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_cluster_search.js @@ -55,7 +55,7 @@ describe('Alerts Cluster Search', () => { const { mockReq, callWithRequestStub } = createStubs(mockQueryResult, featureStub); return alertsClusterSearch( mockReq, - '.monitoring-alerts', + '.monitoring-alerts,monitoring-alerts', { cluster_uuid: 'cluster-1234' }, checkLicense ).then(alerts => { @@ -68,7 +68,7 @@ describe('Alerts Cluster Search', () => { const { mockReq, callWithRequestStub } = createStubs(mockQueryResult, featureStub); return alertsClusterSearch( mockReq, - '.monitoring-alerts', + '.monitoring-alerts,monitoring-alerts', { cluster_uuid: 'cluster-1234' }, checkLicense, { size: 3 } @@ -89,9 +89,15 @@ describe('Alerts Cluster Search', () => { issue_date: 'fake-issue_date', }, }; - return alertsClusterSearch(mockReq, '.monitoring-alerts', cluster, checkLicense, { - size: 3, - }).then(alerts => { + return alertsClusterSearch( + mockReq, + '.monitoring-alerts,monitoring-alerts', + cluster, + checkLicense, + { + size: 3, + } + ).then(alerts => { expect(alerts).to.have.length(3); expect(alerts[0]).to.eql(mockAlerts[0]); expect(alerts[1]).to.eql({ @@ -122,9 +128,15 @@ describe('Alerts Cluster Search', () => { issue_date: 'fake-issue_date', }, }; - return alertsClusterSearch(mockReq, '.monitoring-alerts', cluster, checkLicense, { - size: 3, - }).then(alerts => { + return alertsClusterSearch( + mockReq, + '.monitoring-alerts,monitoring-alerts', + cluster, + checkLicense, + { + size: 3, + } + ).then(alerts => { expect(alerts).to.have.length(1); expect(alerts[0]).to.eql({ metadata: { @@ -155,7 +167,7 @@ describe('Alerts Cluster Search', () => { const { mockReq, callWithRequestStub } = createStubs({}, featureStub); return alertsClusterSearch( mockReq, - '.monitoring-alerts', + '.monitoring-alerts,monitoring-alerts', { cluster_uuid: 'cluster-1234' }, checkLicense ).then(alerts => { @@ -177,7 +189,7 @@ describe('Alerts Cluster Search', () => { const { mockReq, callWithRequestStub } = createStubs({}, featureStub); return alertsClusterSearch( mockReq, - '.monitoring-alerts', + '.monitoring-alerts,monitoring-alerts', { cluster_uuid: 'cluster-1234' }, checkLicense ).then(alerts => { diff --git a/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_clusters_aggregation.js b/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_clusters_aggregation.js index efd9a933e1f81f..9ee0d512a3c1c6 100644 --- a/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_clusters_aggregation.js +++ b/x-pack/legacy/plugins/monitoring/server/cluster_alerts/__tests__/alerts_clusters_aggregation.js @@ -73,34 +73,37 @@ describe('Alerts Clusters Aggregation', () => { it('aggregates alert count summary by cluster', () => { const { mockReq } = createStubs(mockQueryResult, featureStub); - return alertsClustersAggregation(mockReq, '.monitoring-alerts', clusters, checkLicense).then( - result => { - expect(result).to.eql({ - alertsMeta: { enabled: true }, - 'cluster-abc0': undefined, - 'cluster-abc1': { - count: 1, - high: 0, - low: 1, - medium: 0, - }, - 'cluster-abc2': { - count: 2, - high: 0, - low: 0, - medium: 2, - }, - 'cluster-abc3': { - count: 3, - high: 3, - low: 0, - medium: 0, - }, - 'cluster-no-license': undefined, - 'cluster-invalid': undefined, - }); - } - ); + return alertsClustersAggregation( + mockReq, + '.monitoring-alerts,monitoring-alerts', + clusters, + checkLicense + ).then(result => { + expect(result).to.eql({ + alertsMeta: { enabled: true }, + 'cluster-abc0': undefined, + 'cluster-abc1': { + count: 1, + high: 0, + low: 1, + medium: 0, + }, + 'cluster-abc2': { + count: 2, + high: 0, + low: 0, + medium: 2, + }, + 'cluster-abc3': { + count: 3, + high: 3, + low: 0, + medium: 0, + }, + 'cluster-no-license': undefined, + 'cluster-invalid': undefined, + }); + }); }); it('aggregates alert count summary by cluster include static alert', () => { @@ -113,7 +116,7 @@ describe('Alerts Clusters Aggregation', () => { return alertsClustersAggregation( mockReq, - '.monitoring-alerts', + '.monitoring-alerts,monitoring-alerts', newClusters, checkLicense ).then(result => { @@ -163,13 +166,16 @@ describe('Alerts Clusters Aggregation', () => { const checkLicense = () => ({ clusterAlerts: { enabled: true } }); const { mockReq } = createStubs(mockQueryResult, featureStub); - return alertsClustersAggregation(mockReq, '.monitoring-alerts', clusters, checkLicense).then( - result => { - expect(result).to.eql({ - alertsMeta: { enabled: false, message: 'monitoring cluster license is fail' }, - }); - } - ); + return alertsClustersAggregation( + mockReq, + '.monitoring-alerts,monitoring-alerts', + clusters, + checkLicense + ).then(result => { + expect(result).to.eql({ + alertsMeta: { enabled: false, message: 'monitoring cluster license is fail' }, + }); + }); }); it('returns the input set if disabled because production cluster checks', () => { @@ -181,53 +187,56 @@ describe('Alerts Clusters Aggregation', () => { const checkLicense = () => ({ clusterAlerts: { enabled: false } }); const { mockReq } = createStubs(mockQueryResult, featureStub); - return alertsClustersAggregation(mockReq, '.monitoring-alerts', clusters, checkLicense).then( - result => { - expect(result).to.eql({ - alertsMeta: { enabled: true }, - 'cluster-abc0': { - clusterMeta: { - enabled: false, - message: - 'Cluster [cluster-abc0-name] license type [test_license] does not support Cluster Alerts', - }, + return alertsClustersAggregation( + mockReq, + '.monitoring-alerts,monitoring-alerts', + clusters, + checkLicense + ).then(result => { + expect(result).to.eql({ + alertsMeta: { enabled: true }, + 'cluster-abc0': { + clusterMeta: { + enabled: false, + message: + 'Cluster [cluster-abc0-name] license type [test_license] does not support Cluster Alerts', }, - 'cluster-abc1': { - clusterMeta: { - enabled: false, - message: - 'Cluster [cluster-abc1-name] license type [test_license] does not support Cluster Alerts', - }, + }, + 'cluster-abc1': { + clusterMeta: { + enabled: false, + message: + 'Cluster [cluster-abc1-name] license type [test_license] does not support Cluster Alerts', }, - 'cluster-abc2': { - clusterMeta: { - enabled: false, - message: - 'Cluster [cluster-abc2-name] license type [test_license] does not support Cluster Alerts', - }, + }, + 'cluster-abc2': { + clusterMeta: { + enabled: false, + message: + 'Cluster [cluster-abc2-name] license type [test_license] does not support Cluster Alerts', }, - 'cluster-abc3': { - clusterMeta: { - enabled: false, - message: - 'Cluster [cluster-abc3-name] license type [test_license] does not support Cluster Alerts', - }, + }, + 'cluster-abc3': { + clusterMeta: { + enabled: false, + message: + 'Cluster [cluster-abc3-name] license type [test_license] does not support Cluster Alerts', }, - 'cluster-no-license': { - clusterMeta: { - enabled: false, - message: `Cluster [cluster-no-license-name] license type [undefined] does not support Cluster Alerts`, - }, + }, + 'cluster-no-license': { + clusterMeta: { + enabled: false, + message: `Cluster [cluster-no-license-name] license type [undefined] does not support Cluster Alerts`, }, - 'cluster-invalid': { - clusterMeta: { - enabled: false, - message: `Cluster [cluster-invalid-name] license type [undefined] does not support Cluster Alerts`, - }, + }, + 'cluster-invalid': { + clusterMeta: { + enabled: false, + message: `Cluster [cluster-invalid-name] license type [undefined] does not support Cluster Alerts`, }, - }); - } - ); + }, + }); + }); }); }); }); diff --git a/x-pack/legacy/plugins/monitoring/server/lib/__tests__/ccs_utils.js b/x-pack/legacy/plugins/monitoring/server/lib/__tests__/ccs_utils.js index c92c00720837ba..844dfc96bb19b9 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/__tests__/ccs_utils.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/__tests__/ccs_utils.js @@ -10,7 +10,8 @@ import { parseCrossClusterPrefix, prefixIndexPattern } from '../ccs_utils'; describe('ccs_utils', () => { describe('prefixIndexPattern', () => { - const indexPattern = '.monitoring-xyz-1-*,.monitoring-xyz-2-*'; + const indexPattern = + '.monitoring-xyz-1-*,.monitoring-xyz-2-*,monitoring-xyz-1-*,monitoring-xyz-2-*'; it('returns the index pattern if ccs is not enabled', () => { const get = sinon.stub(); @@ -53,9 +54,11 @@ describe('ccs_utils', () => { const abcPattern = prefixIndexPattern(config, indexPattern, 'aBc'); const underscorePattern = prefixIndexPattern(config, indexPattern, 'cluster_one'); - expect(abcPattern).to.eql('aBc:.monitoring-xyz-1-*,aBc:.monitoring-xyz-2-*'); + expect(abcPattern).to.eql( + 'aBc:.monitoring-xyz-1-*,aBc:.monitoring-xyz-2-*,aBc:monitoring-xyz-1-*,aBc:monitoring-xyz-2-*' + ); expect(underscorePattern).to.eql( - 'cluster_one:.monitoring-xyz-1-*,cluster_one:.monitoring-xyz-2-*' + 'cluster_one:.monitoring-xyz-1-*,cluster_one:.monitoring-xyz-2-*,cluster_one:monitoring-xyz-1-*,cluster_one:monitoring-xyz-2-*' ); expect(get.callCount).to.eql(2); }); @@ -69,7 +72,11 @@ describe('ccs_utils', () => { const pattern = prefixIndexPattern(config, indexPattern, '*'); // it should have BOTH patterns so that it searches all CCS clusters and the local cluster - expect(pattern).to.eql('*:.monitoring-xyz-1-*,*:.monitoring-xyz-2-*' + ',' + indexPattern); + expect(pattern).to.eql( + '*:.monitoring-xyz-1-*,*:.monitoring-xyz-2-*,*:monitoring-xyz-1-*,*:monitoring-xyz-2-*' + + ',' + + indexPattern + ); expect(get.callCount).to.eql(1); }); }); @@ -77,18 +84,25 @@ describe('ccs_utils', () => { describe('parseCrossClusterPrefix', () => { it('returns ccs prefix for index with one', () => { expect(parseCrossClusterPrefix('abc:.monitoring-es-6-2017.07.28')).to.eql('abc'); + expect(parseCrossClusterPrefix('abc:monitoring-es-6-2017.07.28')).to.eql('abc'); expect(parseCrossClusterPrefix('abc_123:.monitoring-es-6-2017.07.28')).to.eql('abc_123'); + expect(parseCrossClusterPrefix('abc_123:monitoring-es-6-2017.07.28')).to.eql('abc_123'); expect(parseCrossClusterPrefix('broken:example:.monitoring-es-6-2017.07.28')).to.eql( 'broken' ); + expect(parseCrossClusterPrefix('broken:example:monitoring-es-6-2017.07.28')).to.eql('broken'); expect(parseCrossClusterPrefix('with-a-dash:.monitoring-es-6-2017.07.28')).to.eql( 'with-a-dash' ); + expect(parseCrossClusterPrefix('with-a-dash:monitoring-es-6-2017.07.28')).to.eql( + 'with-a-dash' + ); expect(parseCrossClusterPrefix('something:not-monitoring')).to.eql('something'); }); it('returns null when no prefix exists', () => { expect(parseCrossClusterPrefix('.monitoring-es-6-2017.07.28')).to.be(null); + expect(parseCrossClusterPrefix('monitoring-es-6-2017.07.28')).to.be(null); expect(parseCrossClusterPrefix('random')).to.be(null); }); }); diff --git a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_node_ids.test.js b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_node_ids.test.js index 19fa99a783302c..a7827c7474a156 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_node_ids.test.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_node_ids.test.js @@ -47,7 +47,7 @@ describe('getNodeIds', () => { }; const clusterUuid = '1cb'; - const result = await getNodeIds(req, '.monitoring-es-*', { clusterUuid }, 10); + const result = await getNodeIds(req, '.monitoring-es-*,monitoring-es-*', { clusterUuid }, 10); expect(result).toEqual([ { name: 'foobar', uuid: 1 }, { name: 'barfoo', uuid: 2 }, diff --git a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_paginated_nodes.test.js b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_paginated_nodes.test.js index c08ae91769b9d4..d1126e79b69400 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_paginated_nodes.test.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/__test__/get_paginated_nodes.test.js @@ -45,7 +45,7 @@ describe('getPaginatedNodes', () => { }), }, }; - const esIndexPattern = '.monitoring-es-*'; + const esIndexPattern = '.monitoring-es-*,monitoring-es-*'; const clusterUuid = '1abc'; const metricSet = ['foo', 'bar']; const pagination = { index: 0, size: 10 }; diff --git a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/get_paginated_nodes.js b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/get_paginated_nodes.js index 0023b9515ad1cc..51c61046e9cda2 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/get_paginated_nodes.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/get_paginated_nodes.js @@ -20,7 +20,7 @@ import { getMetrics } from '../../../details/get_metrics'; * and returns that so the caller can perform their normal call to get the time-series data. * * @param {*} req - Server request object - * @param {*} esIndexPattern - The index pattern to search against (`.monitoring-es-*`) + * @param {*} esIndexPattern - The index pattern to search against (`.monitoring-es-*,monitoring-es-*`) * @param {*} uuids - The optional `clusterUuid` and `nodeUuid` to filter the results from * @param {*} metricSet - The array of metrics that are sortable in the UI * @param {*} pagination - ({ index, size }) diff --git a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/verify_monitoring_auth.js b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/verify_monitoring_auth.js index 8362ebec0206b1..1d48d300f8eb6e 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/verify_monitoring_auth.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/elasticsearch/verify_monitoring_auth.js @@ -30,7 +30,7 @@ export async function verifyMonitoringAuth(req) { /** * Reach out to the Monitoring cluster and ensure that it believes the current user has the privileges necessary - * to make API calls against .monitoring-* indices. + * to make API calls against .monitoring-*,monitoring-* indices. * * @param req {Object} the server route handler request object * @return {Promise} That either resolves with no response (void) or an exception. diff --git a/x-pack/legacy/plugins/monitoring/server/lib/logstash/get_paginated_pipelines.js b/x-pack/legacy/plugins/monitoring/server/lib/logstash/get_paginated_pipelines.js index 79aa0d21641ca9..c09df240d4f358 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/logstash/get_paginated_pipelines.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/logstash/get_paginated_pipelines.js @@ -21,7 +21,7 @@ import { getMetrics } from '../details/get_metrics'; * and returns that so the caller can perform their normal call to get the time-series data. * * @param {*} req - Server request object - * @param {*} lsIndexPattern - The index pattern to search against (`.monitoring-logstash-*`) + * @param {*} lsIndexPattern - The index pattern to search against (`.monitoring-logstash-*,monitoring-logstash-*`) * @param {*} uuids - The optional `clusterUuid` and `logstashUuid` to filter the results from * @param {*} metricSet - The array of metrics that are sortable in the UI * @param {*} pagination - ({ index, size }) diff --git a/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/__test__/get_collection_status_regular_index.js b/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/__test__/get_collection_status_regular_index.js new file mode 100644 index 00000000000000..86a0533ee07dbe --- /dev/null +++ b/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/__test__/get_collection_status_regular_index.js @@ -0,0 +1,241 @@ +/* + * 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 sinon from 'sinon'; +import { getCollectionStatus } from '../'; +import { getIndexPatterns } from '../../../cluster/get_index_patterns'; + +const liveClusterUuid = 'a12'; +const mockReq = (searchResult = {}) => { + return { + server: { + newPlatform: { + setup: { + plugins: { + usageCollection: { + getCollectorByType: () => ({ + isReady: () => false, + }), + }, + }, + }, + }, + config() { + return { + get: sinon + .stub() + .withArgs('server.uuid') + .returns('kibana-1234'), + }; + }, + usage: { + collectorSet: { + getCollectorByType: () => ({ + isReady: () => false, + }), + }, + }, + plugins: { + elasticsearch: { + getCluster() { + return { + callWithRequest(_req, type, params) { + if ( + type === 'transport.request' && + params && + params.path === '/_cluster/state/cluster_uuid' + ) { + return Promise.resolve({ cluster_uuid: liveClusterUuid }); + } + if (type === 'transport.request' && params && params.path === '/_nodes') { + return Promise.resolve({ nodes: {} }); + } + if (type === 'cat.indices') { + return Promise.resolve([1]); + } + return Promise.resolve(searchResult); + }, + }; + }, + }, + }, + }, + }; +}; + +describe('getCollectionStatus none system index', () => { + it('should handle all stack products with internal monitoring', async () => { + const req = mockReq({ + aggregations: { + indices: { + buckets: [ + { + key: 'monitoring-es-7-2019', + es_uuids: { buckets: [{ key: 'es_1' }] }, + }, + { + key: 'monitoring-kibana-7-2019', + kibana_uuids: { buckets: [{ key: 'kibana_1' }] }, + }, + { + key: 'monitoring-beats-7-2019', + beats_uuids: { + buckets: [ + { key: 'apm_1', beat_type: { buckets: [{ key: 'apm-server' }] } }, + { key: 'beats_1' }, + ], + }, + }, + { + key: 'monitoring-logstash-7-2019', + logstash_uuids: { buckets: [{ key: 'logstash_1' }] }, + }, + ], + }, + }, + }); + + const result = await getCollectionStatus(req, getIndexPatterns(req.server)); + + expect(result.kibana.totalUniqueInstanceCount).to.be(1); + expect(result.kibana.totalUniqueFullyMigratedCount).to.be(0); + expect(result.kibana.byUuid.kibana_1.isInternalCollector).to.be(true); + + expect(result.beats.totalUniqueInstanceCount).to.be(1); + expect(result.beats.totalUniqueFullyMigratedCount).to.be(0); + expect(result.beats.byUuid.beats_1.isInternalCollector).to.be(true); + + expect(result.apm.totalUniqueInstanceCount).to.be(1); + expect(result.apm.totalUniqueFullyMigratedCount).to.be(0); + expect(result.apm.byUuid.apm_1.isInternalCollector).to.be(true); + + expect(result.logstash.totalUniqueInstanceCount).to.be(1); + expect(result.logstash.totalUniqueFullyMigratedCount).to.be(0); + expect(result.logstash.byUuid.logstash_1.isInternalCollector).to.be(true); + + expect(result.elasticsearch.totalUniqueInstanceCount).to.be(1); + expect(result.elasticsearch.totalUniqueFullyMigratedCount).to.be(0); + expect(result.elasticsearch.byUuid.es_1.isInternalCollector).to.be(true); + }); + + it('should handle some stack products as fully migrated', async () => { + const req = mockReq({ + aggregations: { + indices: { + buckets: [ + { + key: 'monitoring-es-7-mb-2019', + es_uuids: { buckets: [{ key: 'es_1' }] }, + }, + { + key: 'monitoring-kibana-7-mb-2019', + kibana_uuids: { buckets: [{ key: 'kibana_1' }] }, + }, + { + key: 'monitoring-beats-7-2019', + beats_uuids: { buckets: [{ key: 'beats_1' }] }, + }, + { + key: 'monitoring-logstash-7-2019', + logstash_uuids: { buckets: [{ key: 'logstash_1' }] }, + }, + ], + }, + }, + }); + + const result = await getCollectionStatus(req, getIndexPatterns(req.server)); + + expect(result.kibana.totalUniqueInstanceCount).to.be(1); + expect(result.kibana.totalUniqueFullyMigratedCount).to.be(1); + expect(result.kibana.byUuid.kibana_1.isFullyMigrated).to.be(true); + + expect(result.beats.totalUniqueInstanceCount).to.be(1); + expect(result.beats.totalUniqueFullyMigratedCount).to.be(0); + expect(result.beats.byUuid.beats_1.isInternalCollector).to.be(true); + + expect(result.logstash.totalUniqueInstanceCount).to.be(1); + expect(result.logstash.totalUniqueFullyMigratedCount).to.be(0); + expect(result.logstash.byUuid.logstash_1.isInternalCollector).to.be(true); + + expect(result.elasticsearch.totalUniqueInstanceCount).to.be(1); + expect(result.elasticsearch.totalUniqueFullyMigratedCount).to.be(1); + expect(result.elasticsearch.byUuid.es_1.isFullyMigrated).to.be(true); + }); + + it('should handle some stack products as partially migrated', async () => { + const req = mockReq({ + aggregations: { + indices: { + buckets: [ + { + key: 'monitoring-es-7-mb-2019', + es_uuids: { buckets: [{ key: 'es_1' }] }, + }, + { + key: 'monitoring-kibana-7-mb-2019', + kibana_uuids: { buckets: [{ key: 'kibana_1' }, { key: 'kibana_2' }] }, + }, + { + key: 'monitoring-kibana-7-2019', + kibana_uuids: { buckets: [{ key: 'kibana_1', by_timestamp: { value: 12 } }] }, + }, + { + key: 'monitoring-beats-7-2019', + beats_uuids: { buckets: [{ key: 'beats_1' }] }, + }, + { + key: 'monitoring-logstash-7-2019', + logstash_uuids: { buckets: [{ key: 'logstash_1' }] }, + }, + ], + }, + }, + }); + + const result = await getCollectionStatus(req, getIndexPatterns(req.server)); + + expect(result.kibana.totalUniqueInstanceCount).to.be(2); + expect(result.kibana.totalUniqueFullyMigratedCount).to.be(1); + expect(result.kibana.byUuid.kibana_1.isPartiallyMigrated).to.be(true); + expect(result.kibana.byUuid.kibana_1.lastInternallyCollectedTimestamp).to.be(12); + + expect(result.beats.totalUniqueInstanceCount).to.be(1); + expect(result.beats.totalUniqueFullyMigratedCount).to.be(0); + expect(result.beats.byUuid.beats_1.isInternalCollector).to.be(true); + + expect(result.logstash.totalUniqueInstanceCount).to.be(1); + expect(result.logstash.totalUniqueFullyMigratedCount).to.be(0); + expect(result.logstash.byUuid.logstash_1.isInternalCollector).to.be(true); + + expect(result.elasticsearch.totalUniqueInstanceCount).to.be(1); + expect(result.elasticsearch.totalUniqueFullyMigratedCount).to.be(1); + expect(result.elasticsearch.byUuid.es_1.isFullyMigrated).to.be(true); + }); + + it('should detect products based on other indices', async () => { + const req = mockReq( + {}, + { + responses: [ + { hits: { total: { value: 1 } } }, + { hits: { total: { value: 1 } } }, + { hits: { total: { value: 1 } } }, + { hits: { total: { value: 1 } } }, + { hits: { total: { value: 1 } } }, + ], + } + ); + + const result = await getCollectionStatus(req, getIndexPatterns(req.server), liveClusterUuid); + + expect(result.kibana.detected.doesExist).to.be(true); + expect(result.elasticsearch.detected.doesExist).to.be(true); + expect(result.beats.detected.mightExist).to.be(true); + expect(result.logstash.detected.mightExist).to.be(true); + }); +}); diff --git a/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/get_collection_status.js b/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/get_collection_status.js index 73c37dc7f3f285..5f52e0c6a983b7 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/get_collection_status.js +++ b/x-pack/legacy/plugins/monitoring/server/lib/setup/collection/get_collection_status.js @@ -242,7 +242,7 @@ async function hasNecessaryPermissions(req) { * Determines if we should ignore this bucket from this product. * * We need this logic because APM and Beats are separate products, but their - * monitoring data appears in the same index (.monitoring-beats-*) and the single + * monitoring data appears in the same index (.monitoring-beats-*,monitoring-beats-*) and the single * way to determine the difference between two documents in that index * is `beats_stats.beat.type` which we are performing a terms agg in the above query. * If that value is `apm-server` and we're attempting to calculating status for beats @@ -325,7 +325,7 @@ async function getLiveElasticsearchCollectionEnabled(req) { * } * @param {*} req Standard request object. Can contain a timeRange to use for the query - * @param {*} indexPatterns Map of index patterns to search against (will be all .monitoring-* indices) + * @param {*} indexPatterns Map of index patterns to search against (will be all .monitoring-*,monitoring-* indices) * @param {*} clusterUuid Optional and will be used to filter down the query if used * @param {*} nodeUuid Optional and will be used to filter down the query if used * @param {*} skipLiveData Optional and will not make any live api calls if set to true diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_all_stats.js b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_all_stats.js index f27fde50242f43..ea6792433ea0b1 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_all_stats.js +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_all_stats.js @@ -19,11 +19,11 @@ describe.skip('get_all_stats', () => { get: sinon .stub() .withArgs('xpack.monitoring.elasticsearch.index_pattern') - .returns('.monitoring-es-N-*') + .returns('.monitoring-es-N-*,monitoring-es-N-*') .withArgs('xpack.monitoring.kibana.index_pattern') - .returns('.monitoring-kibana-N-*') + .returns('.monitoring-kibana-N-*,monitoring-kibana-N-*') .withArgs('xpack.monitoring.logstash.index_pattern') - .returns('.monitoring-logstash-N-*') + .returns('.monitoring-logstash-N-*,monitoring-logstash-N-*') .withArgs('xpack.monitoring.max_bucket_size') .returns(size), }), diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_cluster_uuids.js b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_cluster_uuids.js index 1f62c677dbb21d..820e6e2c1ec288 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_cluster_uuids.js +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_cluster_uuids.js @@ -20,7 +20,7 @@ describe('get_cluster_uuids', () => { get: sinon .stub() .withArgs('xpack.monitoring.elasticsearch.index_pattern') - .returns('.monitoring-es-N-*') + .returns('.monitoring-es-N-*,monitoring-es-N-*') .withArgs('xpack.monitoring.max_bucket_size') .returns(size), }), diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_es_stats.js b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_es_stats.js index 536e831640fad5..570a19e0766d46 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_es_stats.js +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_es_stats.js @@ -20,7 +20,7 @@ describe('get_es_stats', () => { get: sinon .stub() .withArgs('xpack.monitoring.elasticsearch.index_pattern') - .returns('.monitoring-es-N-*') + .returns('.monitoring-es-N-*,monitoring-es-N-*') .withArgs('xpack.monitoring.max_bucket_size') .returns(size), }), diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_high_level_stats.js b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_high_level_stats.js index 1c1f8dc888d017..dbdd3b8dbce4ab 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_high_level_stats.js +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_high_level_stats.js @@ -24,7 +24,7 @@ describe('get_high_level_stats', () => { get: sinon .stub() .withArgs(`xpack.monitoring.${product}.index_pattern`) - .returns(`.monitoring-${product}-N-*`) + .returns(`.monitoring-${product}-N-*,monitoring-${product}-N-*`) .withArgs('xpack.monitoring.max_bucket_size') .returns(size), }), diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/__tests__/execute_job.js b/x-pack/legacy/plugins/reporting/export_types/csv/server/__tests__/execute_job.js index a8ac99a48ca894..83be303191badb 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/__tests__/execute_job.js +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/__tests__/execute_job.js @@ -590,8 +590,7 @@ describe('CSV Execute Job', function() { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/43069 - describe.skip('cancellation', function() { + describe('cancellation', function() { const scrollId = getRandomScrollId(); beforeEach(function() { @@ -618,10 +617,10 @@ describe('CSV Execute Job', function() { cancellationToken ); - await delay(100); + await delay(250); const callCount = callWithRequestStub.callCount; cancellationToken.cancel(); - await delay(100); + await delay(250); expect(callWithRequestStub.callCount).to.be(callCount + 1); // last call is to clear the scroll }); diff --git a/x-pack/legacy/plugins/reporting/public/lib/download_report.ts b/x-pack/legacy/plugins/reporting/public/lib/download_report.ts index da22093da2ab0a..18bae64f8788d4 100644 --- a/x-pack/legacy/plugins/reporting/public/lib/download_report.ts +++ b/x-pack/legacy/plugins/reporting/public/lib/download_report.ts @@ -7,8 +7,15 @@ import chrome from 'ui/chrome'; import { API_BASE_URL } from '../../common/constants'; -export function downloadReport(jobId: string) { +export function getReportURL(jobId: string) { const apiBaseUrl = chrome.addBasePath(API_BASE_URL); const downloadLink = `${apiBaseUrl}/jobs/download/${jobId}`; - window.open(downloadLink); + + return downloadLink; +} + +export function downloadReport(jobId: string) { + const location = getReportURL(jobId); + + window.open(location); } diff --git a/x-pack/legacy/plugins/siem/public/components/and_or_badge/__examples__/index.stories.tsx b/x-pack/legacy/plugins/siem/public/components/and_or_badge/__examples__/index.stories.tsx new file mode 100644 index 00000000000000..f34e9ee214537d --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/and_or_badge/__examples__/index.stories.tsx @@ -0,0 +1,12 @@ +/* + * 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 { storiesOf } from '@storybook/react'; +import React from 'react'; +import { AndOrBadge } from '..'; + +storiesOf('components/AndOrBadge', module) + .add('and', () => ) + .add('or', () => ); diff --git a/x-pack/legacy/plugins/siem/public/components/auto_sizer/__examples__/index.stories.tsx b/x-pack/legacy/plugins/siem/public/components/auto_sizer/__examples__/index.stories.tsx new file mode 100644 index 00000000000000..414cea0d3f40d6 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/auto_sizer/__examples__/index.stories.tsx @@ -0,0 +1,27 @@ +/* + * 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 { storiesOf } from '@storybook/react'; +import React from 'react'; +import { AutoSizer } from '..'; + +storiesOf('components/AutoSizer', module).add('example', () => ( +
+ + {({ measureRef, content }) => ( +
+
+ {'width: '} + {content.width} +
+
+ {'height: '} + {content.height} +
+
+ )} +
+
+)); diff --git a/x-pack/legacy/plugins/siem/public/components/autocomplete_field/__examples__/index.stories.tsx b/x-pack/legacy/plugins/siem/public/components/autocomplete_field/__examples__/index.stories.tsx new file mode 100644 index 00000000000000..86d003bf577f3a --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/autocomplete_field/__examples__/index.stories.tsx @@ -0,0 +1,31 @@ +/* + * 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 * as React from 'react'; +import { storiesOf } from '@storybook/react'; +import { ThemeProvider } from 'styled-components'; +import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; +import { AutocompleteSuggestion } from '../../../../../../../../src/plugins/data/public'; +import { SuggestionItem } from '../suggestion_item'; + +const suggestion: AutocompleteSuggestion = { + description: 'Description...', + end: 3, + start: 1, + text: 'Text...', + type: 'value', +}; + +storiesOf('components/SuggestionItem', module).add('example', () => ( + ({ + eui: euiLightVars, + darkMode: false, + })} + > + + +)); diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx index 8741cfaa26ca6d..a9d70e4f35d355 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx @@ -12,6 +12,7 @@ import { TestProviders } from '../../../mock'; import { getEmptyStringTag } from '../../empty_value'; import { HostDetailsLink, IPDetailsLink } from '../../links'; import { useMountAppended } from '../../../utils/use_mount_appended'; +import { FlowTarget } from '../../../graphql/types'; jest.mock('../../search_bar', () => ({ siemFilterManager: { @@ -91,13 +92,15 @@ describe('PointToolTipContent', () => { test('it returns IPDetailsLink if field is source.ip', () => { const value = '127.0.0.1'; - expect(getRenderedFieldValue('source.ip', value)).toStrictEqual(); + expect(getRenderedFieldValue('source.ip', value)).toStrictEqual( + + ); }); test('it returns IPDetailsLink if field is destination.ip', () => { const value = '127.0.0.1'; expect(getRenderedFieldValue('destination.ip', value)).toStrictEqual( - + ); }); diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.tsx index b0d21b100eef32..c635061ca7b7a8 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.tsx +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.tsx @@ -15,6 +15,7 @@ import { DescriptionListStyled } from '../../page'; import { FeatureProperty } from '../types'; import { HostDetailsLink, IPDetailsLink } from '../../links'; import { DefaultFieldRenderer } from '../../field_renderers/field_renderers'; +import { FlowTarget } from '../../../graphql/types'; interface PointToolTipContentProps { contextId: string; @@ -66,7 +67,8 @@ export const getRenderedFieldValue = (field: string, value: string) => { } else if (['host.name'].includes(field)) { return ; } else if (['source.ip', 'destination.ip'].includes(field)) { - return ; + const flowTarget = field.split('.')[0] as FlowTarget; + return ; } return <>{value}; }; diff --git a/x-pack/legacy/plugins/siem/public/components/flow_controls/__snapshots__/flow_target_select.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/flow_controls/__snapshots__/flow_target_select.test.tsx.snap index a9b48c8ee16bec..efc4d4be9e9578 100644 --- a/x-pack/legacy/plugins/siem/public/components/flow_controls/__snapshots__/flow_target_select.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/flow_controls/__snapshots__/flow_target_select.test.tsx.snap @@ -7,7 +7,7 @@ exports[`FlowTargetSelect Component rendering it renders the FlowTargetSelect 1` hasDividers={false} isInvalid={false} isLoading={false} - onChange={[Function]} + onChange={[MockFunction]} options={ Array [ Object { diff --git a/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_target_select.test.tsx b/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_target_select.test.tsx index 373cc3cdc4a92d..67006d8a7a121a 100644 --- a/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_target_select.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_target_select.test.tsx @@ -7,7 +7,6 @@ import { mount, shallow } from 'enzyme'; import { clone } from 'lodash/fp'; import React from 'react'; -import { ActionCreator } from 'typescript-fsa'; import { FlowDirection, FlowTarget } from '../../graphql/types'; @@ -21,9 +20,7 @@ describe('FlowTargetSelect Component', () => { selectedDirection: FlowDirection.uniDirectional, isLoading: false, selectedTarget: FlowTarget.source, - updateFlowTargetAction: (jest.fn() as unknown) as ActionCreator<{ - flowTarget: FlowTarget; - }>, + updateFlowTargetAction: jest.fn(), }; describe('rendering', () => { @@ -51,10 +48,7 @@ describe('FlowTargetSelect Component', () => { wrapper.update(); - // @ts-ignore property mock does not exists - expect(mockProps.updateFlowTargetAction.mock.calls[0][0]).toEqual({ - flowTarget: 'destination', - }); + expect(mockProps.updateFlowTargetAction.mock.calls[0][0]).toEqual('destination'); }); test('when selectedDirection=unidirectional only source/destination are options', () => { diff --git a/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_target_select.tsx b/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_target_select.tsx index f5dd4650159cd3..15d1c663638374 100644 --- a/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_target_select.tsx +++ b/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_target_select.tsx @@ -5,8 +5,7 @@ */ import { EuiSuperSelect } from '@elastic/eui'; -import React, { useCallback } from 'react'; -import { ActionCreator } from 'typescript-fsa'; +import React from 'react'; import { FlowDirection, FlowTarget } from '../../graphql/types'; @@ -45,47 +44,31 @@ interface OwnProps { selectedTarget: FlowTarget; displayTextOverride?: string[]; selectedDirection?: FlowDirection; - updateFlowTargetAction: ActionCreator<{ flowTarget: FlowTarget }>; + updateFlowTargetAction: (flowTarget: FlowTarget) => void; } -const onChangeTarget = ( - flowTarget: FlowTarget, - updateFlowTargetSelectAction: ActionCreator<{ flowTarget: FlowTarget }> -) => { - updateFlowTargetSelectAction({ flowTarget }); -}; - export type FlowTargetSelectProps = OwnProps; -export const FlowTargetSelect = React.memo( - ({ - id, - isLoading = false, - selectedDirection, - selectedTarget, - displayTextOverride = [], - updateFlowTargetAction, - }) => { - const handleChange = useCallback( - (newFlowTarget: FlowTarget) => onChangeTarget(newFlowTarget, updateFlowTargetAction), - [updateFlowTargetAction] - ); - - return ( - - option.directions.includes(selectedDirection) - ) - : toggleTargetOptions(id, displayTextOverride) - } - valueOfSelected={selectedTarget} - onChange={handleChange} - isLoading={isLoading} - /> - ); - } +const FlowTargetSelectComponent: React.FC = ({ + id, + isLoading = false, + selectedDirection, + selectedTarget, + displayTextOverride = [], + updateFlowTargetAction, +}) => ( + + option.directions.includes(selectedDirection) + ) + : toggleTargetOptions(id, displayTextOverride) + } + valueOfSelected={selectedTarget} + onChange={updateFlowTargetAction} + isLoading={isLoading} + /> ); -FlowTargetSelect.displayName = 'FlowTargetSelect'; +export const FlowTargetSelect = React.memo(FlowTargetSelectComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/formatted_ip/index.tsx b/x-pack/legacy/plugins/siem/public/components/formatted_ip/index.tsx index 48d34451404bea..ba97e8d61451c3 100644 --- a/x-pack/legacy/plugins/siem/public/components/formatted_ip/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/formatted_ip/index.tsx @@ -59,13 +59,13 @@ const getDataProvider = ({ and: [], }); -const NonDecoratedIp = React.memo<{ +const NonDecoratedIpComponent: React.FC<{ contextId: string; eventId: string; fieldName: string; truncate?: boolean; value: string | object | null | undefined; -}>(({ contextId, eventId, fieldName, truncate, value }) => ( +}> = ({ contextId, eventId, fieldName, truncate, value }) => ( -)); +); -NonDecoratedIp.displayName = 'NonDecoratedIp'; +const NonDecoratedIp = React.memo(NonDecoratedIpComponent); -const AddressLinks = React.memo<{ +const AddressLinksComponent: React.FC<{ addresses: string[]; contextId: string; eventId: string; fieldName: string; truncate?: boolean; -}>(({ addresses, contextId, eventId, fieldName, truncate }) => ( +}> = ({ addresses, contextId, eventId, fieldName, truncate }) => ( <> {uniq(addresses).map(address => ( ))} -)); +); -AddressLinks.displayName = 'AddressLinks'; +const AddressLinks = React.memo(AddressLinksComponent); -export const FormattedIp = React.memo<{ +const FormattedIpComponent: React.FC<{ contextId: string; eventId: string; fieldName: string; truncate?: boolean; value: string | object | null | undefined; -}>(({ contextId, eventId, fieldName, truncate, value }) => { +}> = ({ contextId, eventId, fieldName, truncate, value }) => { if (isString(value) && !isEmpty(value)) { try { const addresses = JSON.parse(value); @@ -173,6 +173,6 @@ export const FormattedIp = React.memo<{ /> ); } -}); +}; -FormattedIp.displayName = 'FormattedIp'; +export const FormattedIp = React.memo(FormattedIpComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/ip/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/ip/__snapshots__/index.test.tsx.snap index 0199742242e59b..a2c71b914b9892 100644 --- a/x-pack/legacy/plugins/siem/public/components/ip/__snapshots__/index.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/ip/__snapshots__/index.test.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Port renders correctly against snapshot 1`] = ` - { .find('a') .first() .props().href - ).toEqual('#/link-to/network/ip/10.1.2.3'); + ).toEqual('#/link-to/network/ip/10.1.2.3/source'); }); }); diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx b/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx index b19ed8e44be9da..7c15af3fe642ad 100644 --- a/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx +++ b/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx @@ -55,7 +55,7 @@ export const LinkToPage = React.memo(({ match }) => ( /> ; export const RedirectToNetworkPage = ({ match: { - params: { detailName }, + params: { detailName, flowTarget }, }, location: { search }, }: NetworkComponentProps) => ( @@ -32,4 +34,7 @@ export const RedirectToNetworkPage = ({ const baseNetworkUrl = `#/link-to/${SiemPageName.network}`; export const getNetworkUrl = () => baseNetworkUrl; -export const getIPDetailsUrl = (detailName: string) => `${baseNetworkUrl}/ip/${detailName}`; +export const getIPDetailsUrl = ( + detailName: string, + flowTarget?: FlowTarget | FlowTargetSourceDest +) => `${baseNetworkUrl}/ip/${detailName}/${flowTarget || FlowTarget.source}`; diff --git a/x-pack/legacy/plugins/siem/public/components/links/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/links/index.test.tsx index dd5c3bf8bb5d59..ceef7e353b5219 100644 --- a/x-pack/legacy/plugins/siem/public/components/links/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/links/index.test.tsx @@ -50,7 +50,7 @@ describe('Custom Links', () => { test('should render valid link to IP Details with ipv4 as the display text', () => { const wrapper = mount(); expect(wrapper.find('EuiLink').prop('href')).toEqual( - `#/link-to/network/ip/${encodeURIComponent(ipv4)}` + `#/link-to/network/ip/${encodeURIComponent(ipv4)}/source` ); expect(wrapper.text()).toEqual(ipv4); }); @@ -58,7 +58,7 @@ describe('Custom Links', () => { test('should render valid link to IP Details with child text as the display text', () => { const wrapper = mount({hostName}); expect(wrapper.find('EuiLink').prop('href')).toEqual( - `#/link-to/network/ip/${encodeURIComponent(ipv4)}` + `#/link-to/network/ip/${encodeURIComponent(ipv4)}/source` ); expect(wrapper.text()).toEqual(hostName); }); @@ -66,7 +66,7 @@ describe('Custom Links', () => { test('should render valid link to IP Details with ipv6 as the display text', () => { const wrapper = mount(); expect(wrapper.find('EuiLink').prop('href')).toEqual( - `#/link-to/network/ip/${encodeURIComponent(ipv6Encoded)}` + `#/link-to/network/ip/${encodeURIComponent(ipv6Encoded)}/source` ); expect(wrapper.text()).toEqual(ipv6); }); diff --git a/x-pack/legacy/plugins/siem/public/components/links/index.tsx b/x-pack/legacy/plugins/siem/public/components/links/index.tsx index f63d13fcda7f03..e122b3e235a9e5 100644 --- a/x-pack/legacy/plugins/siem/public/components/links/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/links/index.tsx @@ -9,27 +9,31 @@ import React from 'react'; import { encodeIpv6 } from '../../lib/helpers'; import { getHostDetailsUrl, getIPDetailsUrl } from '../link_to'; +import { FlowTarget, FlowTargetSourceDest } from '../../graphql/types'; // Internal Links -export const HostDetailsLink = React.memo<{ children?: React.ReactNode; hostName: string }>( - ({ children, hostName }) => ( - - {children ? children : hostName} - - ) +const HostDetailsLinkComponent: React.FC<{ children?: React.ReactNode; hostName: string }> = ({ + children, + hostName, +}) => ( + + {children ? children : hostName} + ); -HostDetailsLink.displayName = 'HostDetailsLink'; +export const HostDetailsLink = React.memo(HostDetailsLinkComponent); -export const IPDetailsLink = React.memo<{ children?: React.ReactNode; ip: string }>( - ({ children, ip }) => ( - - {children ? children : ip} - - ) +const IPDetailsLinkComponent: React.FC<{ + children?: React.ReactNode; + ip: string; + flowTarget?: FlowTarget | FlowTargetSourceDest; +}> = ({ children, ip, flowTarget = FlowTarget.source }) => ( + + {children ? children : ip} + ); -IPDetailsLink.displayName = 'IPDetailsLink'; +export const IPDetailsLink = React.memo(IPDetailsLinkComponent); // External Links export const GoogleLink = React.memo<{ children?: React.ReactNode; link: string }>( diff --git a/x-pack/legacy/plugins/siem/public/components/ml/tables/anomalies_host_table.tsx b/x-pack/legacy/plugins/siem/public/components/ml/tables/anomalies_host_table.tsx index 7afcca47a87650..9e58e39a08f678 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/tables/anomalies_host_table.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml/tables/anomalies_host_table.tsx @@ -29,65 +29,69 @@ const sorting = { }, } as const; -export const AnomaliesHostTable = React.memo( - ({ startDate, endDate, narrowDateRange, hostName, skip, type }): JSX.Element | null => { - const capabilities = useContext(MlCapabilitiesContext); - const [loading, tableData] = useAnomaliesTableData({ - startDate, - endDate, - skip, - criteriaFields: getCriteriaFromHostType(type, hostName), - }); +const AnomaliesHostTableComponent: React.FC = ({ + startDate, + endDate, + narrowDateRange, + hostName, + skip, + type, +}) => { + const capabilities = useContext(MlCapabilitiesContext); + const [loading, tableData] = useAnomaliesTableData({ + startDate, + endDate, + skip, + criteriaFields: getCriteriaFromHostType(type, hostName), + }); - const hosts = convertAnomaliesToHosts(tableData, hostName); + const hosts = convertAnomaliesToHosts(tableData, hostName); - const interval = getIntervalFromAnomalies(tableData); - const columns = getAnomaliesHostTableColumnsCurated( - type, - startDate, - endDate, - interval, - narrowDateRange - ); - const pagination = { - initialPageIndex: 0, - initialPageSize: 10, - totalItemCount: hosts.length, - pageSizeOptions: [5, 10, 20, 50], - hidePerPageOptions: false, - }; + const interval = getIntervalFromAnomalies(tableData); + const columns = getAnomaliesHostTableColumnsCurated( + type, + startDate, + endDate, + interval, + narrowDateRange + ); + const pagination = { + initialPageIndex: 0, + initialPageSize: 10, + totalItemCount: hosts.length, + pageSizeOptions: [5, 10, 20, 50], + hidePerPageOptions: false, + }; - if (!hasMlUserPermissions(capabilities)) { - return null; - } else { - return ( - - + if (!hasMlUserPermissions(capabilities)) { + return null; + } else { + return ( + + - type is not as specific as EUI's... - columns={columns} - compressed - // @ts-ignore ...which leads to `networks` not "matching" the columns - items={hosts} - pagination={pagination} - sorting={sorting} - /> + type is not as specific as EUI's... + columns={columns} + compressed + // @ts-ignore ...which leads to `networks` not "matching" the columns + items={hosts} + pagination={pagination} + sorting={sorting} + /> - {loading && ( - - )} - - ); - } - }, - hostEquality -); + {loading && ( + + )} + + ); + } +}; -AnomaliesHostTable.displayName = 'AnomaliesHostTable'; +export const AnomaliesHostTable = React.memo(AnomaliesHostTableComponent, hostEquality); diff --git a/x-pack/legacy/plugins/siem/public/components/ml/tables/anomalies_network_table.tsx b/x-pack/legacy/plugins/siem/public/components/ml/tables/anomalies_network_table.tsx index 341e1c6e492357..05f3044ff29296 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/tables/anomalies_network_table.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml/tables/anomalies_network_table.tsx @@ -13,7 +13,6 @@ import { convertAnomaliesToNetwork } from './convert_anomalies_to_network'; import { Loader } from '../../loader'; import { AnomaliesNetworkTableProps } from '../types'; import { getAnomaliesNetworkTableColumnsCurated } from './get_anomalies_network_table_columns'; -import { getIntervalFromAnomalies } from '../anomaly/get_interval_from_anomalies'; import { hasMlUserPermissions } from '../permissions/has_ml_user_permissions'; import { MlCapabilitiesContext } from '../permissions/ml_capabilities_provider'; import { BasicTable } from './basic_table'; @@ -28,64 +27,61 @@ const sorting = { }, } as const; -export const AnomaliesNetworkTable = React.memo( - ({ startDate, endDate, narrowDateRange, skip, ip, type, flowTarget }): JSX.Element | null => { - const capabilities = useContext(MlCapabilitiesContext); - const [loading, tableData] = useAnomaliesTableData({ - startDate, - endDate, - skip, - criteriaFields: getCriteriaFromNetworkType(type, ip, flowTarget), - }); +const AnomaliesNetworkTableComponent: React.FC = ({ + startDate, + endDate, + skip, + ip, + type, + flowTarget, +}) => { + const capabilities = useContext(MlCapabilitiesContext); + const [loading, tableData] = useAnomaliesTableData({ + startDate, + endDate, + skip, + criteriaFields: getCriteriaFromNetworkType(type, ip, flowTarget), + }); - const networks = convertAnomaliesToNetwork(tableData, ip); - const interval = getIntervalFromAnomalies(tableData); - const columns = getAnomaliesNetworkTableColumnsCurated( - type, - startDate, - endDate, - interval, - narrowDateRange - ); - const pagination = { - initialPageIndex: 0, - initialPageSize: 10, - totalItemCount: networks.length, - pageSizeOptions: [5, 10, 20, 50], - hidePerPageOptions: false, - }; + const networks = convertAnomaliesToNetwork(tableData, ip); + const columns = getAnomaliesNetworkTableColumnsCurated(type, startDate, endDate, flowTarget); + const pagination = { + initialPageIndex: 0, + initialPageSize: 10, + totalItemCount: networks.length, + pageSizeOptions: [5, 10, 20, 50], + hidePerPageOptions: false, + }; - if (!hasMlUserPermissions(capabilities)) { - return null; - } else { - return ( - - + if (!hasMlUserPermissions(capabilities)) { + return null; + } else { + return ( + + - type is not as specific as EUI's... - columns={columns} - compressed - // @ts-ignore ...which leads to `networks` not "matching" the columns - items={networks} - pagination={pagination} - sorting={sorting} - /> + type is not as specific as EUI's... + columns={columns} + compressed + // @ts-ignore ...which leads to `networks` not "matching" the columns + items={networks} + pagination={pagination} + sorting={sorting} + /> - {loading && ( - - )} - - ); - } - }, - networkEquality -); + {loading && ( + + )} + + ); + } +}; -AnomaliesNetworkTable.displayName = 'AnomaliesNetworkTable'; +export const AnomaliesNetworkTable = React.memo(AnomaliesNetworkTableComponent, networkEquality); diff --git a/x-pack/legacy/plugins/siem/public/components/ml/tables/get_anomalies_network_table_columns.test.tsx b/x-pack/legacy/plugins/siem/public/components/ml/tables/get_anomalies_network_table_columns.test.tsx index b27ccaf1ca7de6..658444bfeda5c1 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/tables/get_anomalies_network_table_columns.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml/tables/get_anomalies_network_table_columns.test.tsx @@ -15,65 +15,33 @@ import { useMountAppended } from '../../../utils/use_mount_appended'; const startDate = new Date(2001).valueOf(); const endDate = new Date(3000).valueOf(); -const interval = 'days'; -const narrowDateRange = jest.fn(); describe('get_anomalies_network_table_columns', () => { const mount = useMountAppended(); test('on network page, we expect to get all columns', () => { expect( - getAnomaliesNetworkTableColumnsCurated( - NetworkType.page, - startDate, - endDate, - interval, - narrowDateRange - ).length + getAnomaliesNetworkTableColumnsCurated(NetworkType.page, startDate, endDate).length ).toEqual(6); }); test('on network details page, we expect to remove one columns', () => { - const columns = getAnomaliesNetworkTableColumnsCurated( - NetworkType.details, - startDate, - endDate, - interval, - narrowDateRange - ); + const columns = getAnomaliesNetworkTableColumnsCurated(NetworkType.details, startDate, endDate); expect(columns.length).toEqual(5); }); test('on network page, we should have Network Name', () => { - const columns = getAnomaliesNetworkTableColumnsCurated( - NetworkType.page, - startDate, - endDate, - interval, - narrowDateRange - ); + const columns = getAnomaliesNetworkTableColumnsCurated(NetworkType.page, startDate, endDate); expect(columns.some(col => col.name === i18n.NETWORK_NAME)).toEqual(true); }); test('on network details page, we should not have Network Name', () => { - const columns = getAnomaliesNetworkTableColumnsCurated( - NetworkType.details, - startDate, - endDate, - interval, - narrowDateRange - ); + const columns = getAnomaliesNetworkTableColumnsCurated(NetworkType.details, startDate, endDate); expect(columns.some(col => col.name === i18n.NETWORK_NAME)).toEqual(false); }); test('on network page, we should escape the draggable id', () => { - const columns = getAnomaliesNetworkTableColumnsCurated( - NetworkType.page, - startDate, - endDate, - interval, - narrowDateRange - ); + const columns = getAnomaliesNetworkTableColumnsCurated(NetworkType.page, startDate, endDate); const column = columns.find(col => col.name === i18n.SCORE) as Columns< string, AnomaliesByNetwork @@ -129,13 +97,7 @@ describe('get_anomalies_network_table_columns', () => { }); test('on network page, undefined influencers should turn into an empty column string', () => { - const columns = getAnomaliesNetworkTableColumnsCurated( - NetworkType.page, - startDate, - endDate, - interval, - narrowDateRange - ); + const columns = getAnomaliesNetworkTableColumnsCurated(NetworkType.page, startDate, endDate); const column = columns.find(col => col.name === i18n.INFLUENCED_BY) as Columns< Anomaly['influencers'], AnomaliesByNetwork diff --git a/x-pack/legacy/plugins/siem/public/components/ml/tables/get_anomalies_network_table_columns.tsx b/x-pack/legacy/plugins/siem/public/components/ml/tables/get_anomalies_network_table_columns.tsx index 0c823ef75cf26d..f6a493f80eb78f 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/tables/get_anomalies_network_table_columns.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml/tables/get_anomalies_network_table_columns.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui'; import { Columns } from '../../paginated_table'; -import { Anomaly, NarrowDateRange, AnomaliesByNetwork } from '../types'; +import { Anomaly, AnomaliesByNetwork } from '../types'; import { getRowItemDraggable } from '../../tables/helpers'; import { EntityDraggable } from '../entity_draggable'; import { createCompoundNetworkKey } from './create_compound_key'; @@ -23,12 +23,12 @@ import { createExplorerLink } from '../links/create_explorer_link'; import { FormattedRelativePreferenceDate } from '../../formatted_date'; import { NetworkType } from '../../../store/network/model'; import { escapeDataProviderId } from '../../drag_and_drop/helpers'; +import { FlowTarget } from '../../../graphql/types'; export const getAnomaliesNetworkTableColumns = ( startDate: number, endDate: number, - interval: string, - narrowDateRange: NarrowDateRange + flowTarget?: FlowTarget ): [ Columns, Columns, @@ -46,7 +46,7 @@ export const getAnomaliesNetworkTableColumns = ( rowItem: ip, attrName: anomaliesByNetwork.type, idPrefix: `anomalies-network-table-ip-${createCompoundNetworkKey(anomaliesByNetwork)}`, - render: item => , + render: item => , }), }, { @@ -129,10 +129,9 @@ export const getAnomaliesNetworkTableColumnsCurated = ( pageType: NetworkType, startDate: number, endDate: number, - interval: string, - narrowDateRange: NarrowDateRange + flowTarget?: FlowTarget ) => { - const columns = getAnomaliesNetworkTableColumns(startDate, endDate, interval, narrowDateRange); + const columns = getAnomaliesNetworkTableColumns(startDate, endDate, flowTarget); // Columns to exclude from ip details pages if (pageType === NetworkType.details) { diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/breadcrumbs/index.test.ts b/x-pack/legacy/plugins/siem/public/components/navigation/breadcrumbs/index.test.ts index f9d63a8594180e..fc0a37bc751c76 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/breadcrumbs/index.test.ts +++ b/x-pack/legacy/plugins/siem/public/components/navigation/breadcrumbs/index.test.ts @@ -194,7 +194,7 @@ describe('Navigation Breadcrumbs', () => { }, { text: ipv4, - href: `#/link-to/network/ip/${ipv4}?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))`, + href: `#/link-to/network/ip/${ipv4}/source?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))`, }, { text: 'Flows', href: '' }, ]); @@ -211,7 +211,7 @@ describe('Navigation Breadcrumbs', () => { }, { text: ipv6, - href: `#/link-to/network/ip/${ipv6Encoded}?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))`, + href: `#/link-to/network/ip/${ipv6Encoded}/source?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))`, }, { text: 'Flows', href: '' }, ]); diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx index d623f5f389ce5c..61ac84667d80f7 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx @@ -19,7 +19,7 @@ import { SiemNavigationProps, SiemNavigationComponentProps } from './types'; export const SiemNavigationComponent = React.memo< SiemNavigationComponentProps & SiemNavigationProps & RouteSpyState >( - ({ detailName, display, navTabs, pageName, pathName, search, tabName, urlState }) => { + ({ detailName, display, navTabs, pageName, pathName, search, tabName, urlState, flowTarget }) => { useEffect(() => { if (pathName) { setBreadcrumbs({ @@ -32,6 +32,7 @@ export const SiemNavigationComponent = React.memo< savedQuery: urlState.savedQuery, search, tabName, + flowTarget, timerange: urlState.timerange, timeline: urlState.timeline, }); diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/flow_target_select_connected/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/flow_target_select_connected/index.test.tsx index 8c744c6573ee88..006587d8fc294b 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/flow_target_select_connected/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/flow_target_select_connected/index.test.tsx @@ -7,38 +7,26 @@ import { mount } from 'enzyme'; import React from 'react'; -import { apolloClientObservable, mockGlobalState, TestProviders } from '../../../../mock'; -import { createStore, State } from '../../../../store'; - +import { TestProviders } from '../../../../mock'; import { FlowTargetSelectConnected } from './index'; -import { IpOverviewId } from '../../../field_renderers/field_renderers'; - -describe('Flow Target Select Connected', () => { - const state: State = mockGlobalState; - let store = createStore(state, apolloClientObservable); +import { FlowTarget } from '../../../../graphql/types'; - beforeEach(() => { - store = createStore(state, apolloClientObservable); - }); - test('Pick Relative Date', () => { +describe.skip('Flow Target Select Connected', () => { + test('renders correctly against snapshot flowTarget source', () => { const wrapper = mount( - - + + ); - expect(store.getState().network.details.flowTarget).toEqual('source'); - wrapper - .find('button') - .first() - .simulate('click'); - - wrapper.update(); - wrapper - .find(`button#${IpOverviewId}-select-flow-target-destination`) - .first() - .simulate('click'); + expect(wrapper.find('FlowTargetSelectConnected')).toMatchSnapshot(); + }); - wrapper.update(); - expect(store.getState().network.details.flowTarget).toEqual('destination'); + test('renders correctly against snapshot flowTarget destination', () => { + const wrapper = mount( + + + + ); + expect(wrapper.find('FlowTargetSelectConnected')).toMatchSnapshot(); }); }); diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/flow_target_select_connected/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/flow_target_select_connected/index.tsx index 956271b416ee8f..1b87c36902159b 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/flow_target_select_connected/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/flow_target_select_connected/index.tsx @@ -4,15 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Location } from 'history'; import { EuiFlexItem } from '@elastic/eui'; -import React from 'react'; -import { connect } from 'react-redux'; +import React, { useCallback } from 'react'; +import { useHistory, useLocation } from 'react-router-dom'; import styled from 'styled-components'; -import { ActionCreator } from 'typescript-fsa'; import { FlowDirection, FlowTarget } from '../../../../graphql/types'; -import { State } from '../../../../store'; -import { networkActions, networkSelectors } from '../../../../store/network'; import * as i18nIp from '../ip_overview/translations'; import { FlowTargetSelect } from '../../../flow_controls/flow_target_select'; @@ -24,20 +22,33 @@ const SelectTypeItem = styled(EuiFlexItem)` SelectTypeItem.displayName = 'SelectTypeItem'; -interface FlowTargetSelectReduxProps { +interface Props { flowTarget: FlowTarget; } -export interface FlowTargetSelectDispatchProps { - updateIpDetailsFlowTarget: ActionCreator<{ - flowTarget: FlowTarget; - }>; -} +const getUpdatedFlowTargetPath = ( + location: Location, + currentFlowTarget: FlowTarget, + newFlowTarget: FlowTarget +) => { + const newPathame = location.pathname.replace(currentFlowTarget, newFlowTarget); + + return `${newPathame}${location.search}`; +}; -type FlowTargetSelectProps = FlowTargetSelectReduxProps & FlowTargetSelectDispatchProps; +const FlowTargetSelectConnectedComponent: React.FC = ({ flowTarget }) => { + const history = useHistory(); + const location = useLocation(); -const FlowTargetSelectComponent = React.memo( - ({ flowTarget, updateIpDetailsFlowTarget }) => ( + const updateIpDetailsFlowTarget = useCallback( + (newFlowTarget: FlowTarget) => { + const newPath = getUpdatedFlowTargetPath(location, flowTarget, newFlowTarget); + history.push(newPath); + }, + [history, location, flowTarget] + ); + + return ( ( updateFlowTargetAction={updateIpDetailsFlowTarget} /> - ) -); - -FlowTargetSelectComponent.displayName = 'FlowTargetSelectComponent'; - -const makeMapStateToProps = () => { - const getIpDetailsFlowTargetSelector = networkSelectors.ipDetailsFlowTargetSelector(); - return (state: State) => { - return { - flowTarget: getIpDetailsFlowTargetSelector(state), - }; - }; + ); }; -export const FlowTargetSelectConnected = connect(makeMapStateToProps, { - updateIpDetailsFlowTarget: networkActions.updateIpDetailsFlowTarget, -})(FlowTargetSelectComponent); +export const FlowTargetSelectConnected = React.memo(FlowTargetSelectConnectedComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/__snapshots__/index.test.tsx.snap index f80a61836b86ed..3d47e398ed3956 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/__snapshots__/index.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/__snapshots__/index.test.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`NetworkTopNFlow Table Component rendering it renders the default NetworkTopNFlow table on the IP Details page 1`] = ` - [ { @@ -83,7 +80,7 @@ export const getNetworkTopNFlowColumns = ( ) : ( - + ) } /> @@ -233,12 +230,11 @@ export const getNetworkTopNFlowColumns = ( ]; export const getNFlowColumnsCurated = ( - indexPattern: IIndexPattern, flowTarget: FlowTargetSourceDest, type: networkModel.NetworkType, tableId: string ): NetworkTopNFlowColumns | NetworkTopNFlowColumnsIpDetails => { - const columns = getNetworkTopNFlowColumns(indexPattern, flowTarget, type, tableId); + const columns = getNetworkTopNFlowColumns(flowTarget, tableId); // Columns to exclude from host details pages if (type === networkModel.NetworkType.details) { diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/index.test.tsx index 24f68ef03d8917..78e8b15005f431 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/index.test.tsx @@ -11,12 +11,7 @@ import { MockedProvider } from 'react-apollo/test-utils'; import { Provider as ReduxStoreProvider } from 'react-redux'; import { FlowTargetSourceDest } from '../../../../graphql/types'; -import { - apolloClientObservable, - mockGlobalState, - mockIndexPattern, - TestProviders, -} from '../../../../mock'; +import { apolloClientObservable, mockGlobalState, TestProviders } from '../../../../mock'; import { useMountAppended } from '../../../../utils/use_mount_appended'; import { createStore, networkModel, State } from '../../../../store'; @@ -43,7 +38,6 @@ describe('NetworkTopNFlow Table Component', () => { fakeTotalCount={getOr(50, 'fakeTotalCount', mockData.NetworkTopNFlow.pageInfo)} flowTargeted={FlowTargetSourceDest.source} id="topNFlowSource" - indexPattern={mockIndexPattern} isInspect={false} loading={false} loadPage={loadPage} @@ -58,7 +52,7 @@ describe('NetworkTopNFlow Table Component', () => { ); - expect(wrapper.find('Connect(NetworkTopNFlowTableComponent)')).toMatchSnapshot(); + expect(wrapper.find('Connect(Component)')).toMatchSnapshot(); }); test('it renders the default NetworkTopNFlow table on the IP Details page', () => { @@ -69,7 +63,6 @@ describe('NetworkTopNFlow Table Component', () => { fakeTotalCount={getOr(50, 'fakeTotalCount', mockData.NetworkTopNFlow.pageInfo)} flowTargeted={FlowTargetSourceDest.source} id="topNFlowSource" - indexPattern={mockIndexPattern} isInspect={false} loading={false} loadPage={loadPage} @@ -84,7 +77,7 @@ describe('NetworkTopNFlow Table Component', () => { ); - expect(wrapper.find('Connect(NetworkTopNFlowTableComponent)')).toMatchSnapshot(); + expect(wrapper.find('Connect(Component)')).toMatchSnapshot(); }); }); @@ -99,7 +92,6 @@ describe('NetworkTopNFlow Table Component', () => { flowTargeted={FlowTargetSourceDest.source} id="topNFlowSource" isInspect={false} - indexPattern={mockIndexPattern} loading={false} loadPage={loadPage} showMorePagesIndicator={getOr( diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/index.tsx index 6cf3401031fa7a..7c1fcb2681a8c5 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/index.tsx @@ -8,7 +8,6 @@ import React, { useCallback, useMemo } from 'react'; import { connect } from 'react-redux'; import { compose } from 'redux'; import { ActionCreator } from 'typescript-fsa'; -import { IIndexPattern } from 'src/plugins/data/public'; import { networkActions } from '../../../../store/actions'; import { @@ -29,7 +28,6 @@ interface OwnProps { fakeTotalCount: number; flowTargeted: FlowTargetSourceDest; id: string; - indexPattern: IIndexPattern; isInspect: boolean; loading: boolean; loadPage: (newActivePage: number) => void; @@ -69,118 +67,112 @@ const rowItems: ItemsPerRow[] = [ export const NetworkTopNFlowTableId = 'networkTopSourceFlow-top-talkers'; -const NetworkTopNFlowTableComponent = React.memo( - ({ - activePage, - data, - fakeTotalCount, - flowTargeted, - id, - indexPattern, - isInspect, - limit, - loading, - loadPage, - showMorePagesIndicator, - sort, - totalCount, - type, - updateNetworkTable, - }) => { - const columns = useMemo( - () => getNFlowColumnsCurated(indexPattern, flowTargeted, type, NetworkTopNFlowTableId), - [indexPattern, flowTargeted, type] - ); - - let tableType: networkModel.TopNTableType; - const headerTitle: string = - flowTargeted === FlowTargetSourceDest.source ? i18n.SOURCE_IP : i18n.DESTINATION_IP; - - if (type === networkModel.NetworkType.page) { - tableType = - flowTargeted === FlowTargetSourceDest.source - ? networkModel.NetworkTableType.topNFlowSource - : networkModel.NetworkTableType.topNFlowDestination; - } else { - tableType = - flowTargeted === FlowTargetSourceDest.source - ? networkModel.IpDetailsTableType.topNFlowSource - : networkModel.IpDetailsTableType.topNFlowDestination; - } - - const onChange = useCallback( - (criteria: Criteria) => { - if (criteria.sort != null) { - const splitField = criteria.sort.field.split('.'); - const field = last(splitField); - const newSortDirection = field !== sort.field ? Direction.desc : criteria.sort.direction; // sort by desc on init click - const newTopNFlowSort: NetworkTopTablesSortField = { - field: field as NetworkTopTablesFields, - direction: newSortDirection as Direction, - }; - if (!isEqual(newTopNFlowSort, sort)) { - updateNetworkTable({ - networkType: type, - tableType, - updates: { - sort: newTopNFlowSort, - }, - }); - } - } - }, - [sort, type, tableType, updateNetworkTable] - ); - - const field = - sort.field === NetworkTopTablesFields.bytes_out || - sort.field === NetworkTopTablesFields.bytes_in - ? `node.network.${sort.field}` - : `node.${flowTargeted}.${sort.field}`; - - const updateActivePage = useCallback( - newPage => - updateNetworkTable({ - networkType: type, - tableType, - updates: { activePage: newPage }, - }), - [updateNetworkTable, type, tableType] - ); - - const updateLimitPagination = useCallback( - newLimit => - updateNetworkTable({ networkType: type, tableType, updates: { limit: newLimit } }), - [updateNetworkTable, type, tableType] - ); - - return ( - - ); +const NetworkTopNFlowTableComponent: React.FC = ({ + activePage, + data, + fakeTotalCount, + flowTargeted, + id, + isInspect, + limit, + loading, + loadPage, + showMorePagesIndicator, + sort, + totalCount, + type, + updateNetworkTable, +}) => { + const columns = useMemo( + () => getNFlowColumnsCurated(flowTargeted, type, NetworkTopNFlowTableId), + [flowTargeted, type] + ); + + let tableType: networkModel.TopNTableType; + const headerTitle: string = + flowTargeted === FlowTargetSourceDest.source ? i18n.SOURCE_IP : i18n.DESTINATION_IP; + + if (type === networkModel.NetworkType.page) { + tableType = + flowTargeted === FlowTargetSourceDest.source + ? networkModel.NetworkTableType.topNFlowSource + : networkModel.NetworkTableType.topNFlowDestination; + } else { + tableType = + flowTargeted === FlowTargetSourceDest.source + ? networkModel.IpDetailsTableType.topNFlowSource + : networkModel.IpDetailsTableType.topNFlowDestination; } -); -NetworkTopNFlowTableComponent.displayName = 'NetworkTopNFlowTableComponent'; + const onChange = useCallback( + (criteria: Criteria) => { + if (criteria.sort != null) { + const splitField = criteria.sort.field.split('.'); + const field = last(splitField); + const newSortDirection = field !== sort.field ? Direction.desc : criteria.sort.direction; // sort by desc on init click + const newTopNFlowSort: NetworkTopTablesSortField = { + field: field as NetworkTopTablesFields, + direction: newSortDirection as Direction, + }; + if (!isEqual(newTopNFlowSort, sort)) { + updateNetworkTable({ + networkType: type, + tableType, + updates: { + sort: newTopNFlowSort, + }, + }); + } + } + }, + [sort, type, tableType, updateNetworkTable] + ); + + const field = + sort.field === NetworkTopTablesFields.bytes_out || + sort.field === NetworkTopTablesFields.bytes_in + ? `node.network.${sort.field}` + : `node.${flowTargeted}.${sort.field}`; + + const updateActivePage = useCallback( + newPage => + updateNetworkTable({ + networkType: type, + tableType, + updates: { activePage: newPage }, + }), + [updateNetworkTable, type, tableType] + ); + + const updateLimitPagination = useCallback( + newLimit => updateNetworkTable({ networkType: type, tableType, updates: { limit: newLimit } }), + [updateNetworkTable, type, tableType] + ); + + return ( + + ); +}; const makeMapStateToProps = () => { const getTopNFlowSelector = networkSelectors.topNFlowSelector(); @@ -192,4 +184,4 @@ export const NetworkTopNFlowTable = compose>( connect(makeMapStateToProps, { updateNetworkTable: networkActions.updateNetworkTable, }) -)(NetworkTopNFlowTableComponent); +)(React.memo(NetworkTopNFlowTableComponent)); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/data_driven_columns/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/timeline/body/data_driven_columns/__snapshots__/index.test.tsx.snap index 75c05dd1455afd..93e12a0ed4fcd1 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/data_driven_columns/__snapshots__/index.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/data_driven_columns/__snapshots__/index.test.tsx.snap @@ -49,7 +49,7 @@ exports[`Columns it renders the expected columns 1`] = ` - - - - - - -`; +exports[`Events renders correctly against snapshot 1`] = `null`; diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/get_column_renderer.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/get_column_renderer.test.tsx.snap index a79a7ed23e3d10..e2c46a07af8cce 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/get_column_renderer.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/get_column_renderer.test.tsx.snap @@ -2,7 +2,7 @@ exports[`get_column_renderer renders correctly against snapshot 1`] = ` - - (({ contextId, eventId, fieldFormat, fieldName, fieldType, truncate, value }) => { +}> = ({ contextId, eventId, fieldFormat, fieldName, fieldType, truncate, value }) => { if (fieldType === IP_FIELD_TYPE) { return ( ); } -}); +}; -FormattedFieldValue.displayName = 'FormattedFieldValue'; +export const FormattedFieldValue = React.memo(FormattedFieldValueComponent); diff --git a/x-pack/legacy/plugins/siem/public/pages/network/index.tsx b/x-pack/legacy/plugins/siem/public/pages/network/index.tsx index 1bc3d9a054bb89..48fc1421d90bb6 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/index.tsx @@ -9,6 +9,7 @@ import { Redirect, Route, Switch, RouteComponentProps } from 'react-router-dom'; import { MlCapabilitiesContext } from '../../components/ml/permissions/ml_capabilities_provider'; import { hasMlUserPermissions } from '../../components/ml/permissions/has_ml_user_permissions'; +import { FlowTarget } from '../../graphql/types'; import { IPDetails } from './ip_details'; import { Network } from './network'; @@ -20,9 +21,9 @@ import { NetworkRouteType } from './navigation/types'; type Props = Partial> & { url: string }; const networkPagePath = `/:pageName(${SiemPageName.network})`; -const ipDetailsPagePath = `${networkPagePath}/ip/:detailName`; +const ipDetailsPageBasePath = `${networkPagePath}/ip/:detailName`; -export const NetworkContainer = React.memo(() => { +const NetworkContainerComponent: React.FC = () => { const capabilities = useContext(MlCapabilitiesContext); const capabilitiesFetched = capabilities.capabilitiesFetched; const userHasMlUserPermissions = useMemo(() => hasMlUserPermissions(capabilities), [ @@ -54,14 +55,15 @@ export const NetworkContainer = React.memo(() => { )} /> ( (() => { /> )} /> + ( + + )} + /> ( @@ -80,6 +95,6 @@ export const NetworkContainer = React.memo(() => { )} ); -}); +}; -NetworkContainer.displayName = 'NetworkContainer'; +export const NetworkContainer = React.memo(NetworkContainerComponent); diff --git a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx index 99ca12292a52c0..2e8044d2c2fe81 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx @@ -28,7 +28,7 @@ import { useKibana } from '../../../lib/kibana'; import { decodeIpv6 } from '../../../lib/helpers'; import { convertToBuildEsQuery } from '../../../lib/keury'; import { ConditionalFlexGroup } from '../../../pages/network/navigation/conditional_flex_group'; -import { networkModel, networkSelectors, State, inputsSelectors } from '../../../store'; +import { networkModel, State, inputsSelectors } from '../../../store'; import { setAbsoluteRangeDatePicker as dispatchAbsoluteRangeDatePicker } from '../../../store/inputs/actions'; import { setIpDetailsTablesActivePageToZero as dispatchIpDetailsTablesActivePageToZero } from '../../../store/network/actions'; import { SpyRoute } from '../../../utils/route/spy_routes'; @@ -102,7 +102,7 @@ export const IPDetailsComponent = ({ subtitle={} title={ip} > - + { const getGlobalQuerySelector = inputsSelectors.globalQuerySelector(); const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector(); - const getIpDetailsFlowTargetSelector = networkSelectors.ipDetailsFlowTargetSelector(); return (state: State) => ({ query: getGlobalQuerySelector(state), filters: getGlobalFiltersQuerySelector(state), - flowTarget: getIpDetailsFlowTargetSelector(state), }); }; diff --git a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/network_top_n_flow_query_table.tsx b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/network_top_n_flow_query_table.tsx index 47d68471fb69be..06ae3160415d96 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/network_top_n_flow_query_table.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/network_top_n_flow_query_table.tsx @@ -22,7 +22,6 @@ export const NetworkTopNFlowQueryTable = ({ skip, startDate, type, - indexPattern, }: NetworkWithIndexComponentsQueryTableProps) => ( ( ('UPDATE_IP_DETAILS_TARGET'); diff --git a/x-pack/legacy/plugins/siem/public/store/network/reducer.ts b/x-pack/legacy/plugins/siem/public/store/network/reducer.ts index 8e4d4555d3bd91..e6d7efc9cbb5f4 100644 --- a/x-pack/legacy/plugins/siem/public/store/network/reducer.ts +++ b/x-pack/legacy/plugins/siem/public/store/network/reducer.ts @@ -19,14 +19,13 @@ import { DEFAULT_TABLE_ACTIVE_PAGE, DEFAULT_TABLE_LIMIT } from '../constants'; import { setIpDetailsTablesActivePageToZero, setNetworkTablesActivePageToZero, - updateIpDetailsFlowTarget, updateNetworkTable, } from './actions'; import { setNetworkDetailsQueriesActivePageToZero, setNetworkPageQueriesActivePageToZero, } from './helpers'; -import { IpDetailsTableType, NetworkModel, NetworkTableType, NetworkType } from './model'; +import { IpDetailsTableType, NetworkModel, NetworkTableType } from './model'; export type NetworkState = NetworkModel; @@ -189,11 +188,4 @@ export const networkReducer = reducerWithInitialState(initialNetworkState) queries: setNetworkDetailsQueriesActivePageToZero(state), }, })) - .case(updateIpDetailsFlowTarget, (state, { flowTarget }) => ({ - ...state, - [NetworkType.details]: { - ...state[NetworkType.details], - flowTarget, - }, - })) .build(); diff --git a/x-pack/legacy/plugins/siem/public/store/network/selectors.ts b/x-pack/legacy/plugins/siem/public/store/network/selectors.ts index a33684472b279b..64a325b6e1ca4b 100644 --- a/x-pack/legacy/plugins/siem/public/store/network/selectors.ts +++ b/x-pack/legacy/plugins/siem/public/store/network/selectors.ts @@ -81,9 +81,5 @@ const selectHttpByType = (state: State, networkType: NetworkType) => { export const httpSelector = () => createSelector(selectHttpByType, httpQueries => httpQueries); -// IP Details Selectors -export const ipDetailsFlowTargetSelector = () => - createSelector(selectNetworkDetails, network => network.flowTarget); - export const usersSelector = () => createSelector(selectNetworkDetails, network => network.queries.users); diff --git a/x-pack/legacy/plugins/siem/public/utils/route/index.test.tsx b/x-pack/legacy/plugins/siem/public/utils/route/index.test.tsx index bcc256d50d960e..e777d281ed51ab 100644 --- a/x-pack/legacy/plugins/siem/public/utils/route/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/utils/route/index.test.tsx @@ -75,6 +75,7 @@ describe('Spy Routes', () => { detailName: '', tabName: HostsTableType.hosts, search: '', + flowTarget: undefined, }, }} /> @@ -106,6 +107,7 @@ describe('Spy Routes', () => { detailName: undefined, tabName: HostsTableType.hosts, search: '?IdoNotWantToSeeYou="true"', + flowTarget: undefined, }, }} /> @@ -156,6 +158,7 @@ describe('Spy Routes', () => { detailName: undefined, tabName: HostsTableType.hosts, search: '?IdoNotWantToSeeYou="true"', + flowTarget: undefined, }, }} /> diff --git a/x-pack/legacy/plugins/siem/public/utils/route/spy_routes.tsx b/x-pack/legacy/plugins/siem/public/utils/route/spy_routes.tsx index 3a02d81272344f..5c24b2f48488d8 100644 --- a/x-pack/legacy/plugins/siem/public/utils/route/spy_routes.tsx +++ b/x-pack/legacy/plugins/siem/public/utils/route/spy_routes.tsx @@ -17,7 +17,7 @@ export const SpyRouteComponent = memo( location: { pathname, search }, history, match: { - params: { pageName, detailName, tabName }, + params: { pageName, detailName, tabName, flowTarget }, }, }) => { const [isInitializing, setIsInitializing] = useState(true); @@ -43,6 +43,7 @@ export const SpyRouteComponent = memo( tabName, pathName: pathname, history, + flowTarget, }, }); setIsInitializing(false); @@ -56,11 +57,12 @@ export const SpyRouteComponent = memo( search, pathName: pathname, history, + flowTarget, }, }); } } - }, [pathname, search, pageName, detailName, tabName]); + }, [pathname, search, pageName, detailName, tabName, flowTarget]); return null; } ); diff --git a/x-pack/legacy/plugins/siem/public/utils/route/types.ts b/x-pack/legacy/plugins/siem/public/utils/route/types.ts index 002cd4d23786d2..79d2677eff06f6 100644 --- a/x-pack/legacy/plugins/siem/public/utils/route/types.ts +++ b/x-pack/legacy/plugins/siem/public/utils/route/types.ts @@ -10,6 +10,7 @@ import { RouteComponentProps } from 'react-router-dom'; import { HostsTableType } from '../../store/hosts/model'; import { NetworkRouteType } from '../../pages/network/navigation/types'; +import { FlowTarget } from '../../graphql/types'; export type SiemRouteType = HostsTableType | NetworkRouteType; export interface RouteSpyState { @@ -19,6 +20,7 @@ export interface RouteSpyState { search: string; pathName: string; history?: H.History; + flowTarget?: FlowTarget; } export interface HostRouteSpyState extends RouteSpyState { @@ -52,4 +54,5 @@ export type SpyRouteProps = RouteComponentProps<{ detailName: string | undefined; tabName: HostsTableType | undefined; search: string; + flowTarget: FlowTarget | undefined; }>; diff --git a/x-pack/legacy/plugins/siem/scripts/storybook.js b/x-pack/legacy/plugins/siem/scripts/storybook.js new file mode 100644 index 00000000000000..65662367049363 --- /dev/null +++ b/x-pack/legacy/plugins/siem/scripts/storybook.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { join } from 'path'; + +// eslint-disable-next-line +require('@kbn/storybook').runStorybookCli({ + name: 'siem', + storyGlobs: [join(__dirname, '..', 'public', 'components', '**', '*.stories.tsx')], +}); diff --git a/x-pack/legacy/plugins/tilemap/index.js b/x-pack/legacy/plugins/tilemap/index.js index b5f7839c7c7f75..767a0fe72985e8 100644 --- a/x-pack/legacy/plugins/tilemap/index.js +++ b/x-pack/legacy/plugins/tilemap/index.js @@ -12,7 +12,7 @@ export const tilemap = kibana => { return new kibana.Plugin({ id: 'tilemap', configPrefix: 'xpack.tilemap', - require: ['xpack_main', 'kbn_vislib_vis_types'], + require: ['xpack_main', 'vis_type_vislib'], publicDir: resolve(__dirname, 'public'), uiExports: { visTypeEnhancers: ['plugins/tilemap/vis_type_enhancers/update_tilemap_settings'], diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap index 148894920eb452..d19de73c16c5fb 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap +++ b/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap @@ -139,7 +139,9 @@ exports[`PingList component renders sorted list without errors 1`] = ` Object { "align": "right", "field": "http.response.status_code", - "name": "Response code", + "name": + Response code + , "render": [Function], }, Object { diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/ping_list.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/ping_list.tsx index 3f0ec298e32893..85517144edfc60 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/ping_list.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/ping_list/ping_list.tsx @@ -23,6 +23,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { get } from 'lodash'; import moment from 'moment'; import React, { Fragment, useState } from 'react'; +import styled from 'styled-components'; import { CriteriaWithPagination } from '@elastic/eui/src/components/basic_table/basic_table'; import { Ping, PingResults } from '../../../../common/graphql/types'; import { convertMicrosecondsToMilliseconds as microsToMillis } from '../../../lib/helper'; @@ -69,6 +70,10 @@ export const toggleDetails = ( setItemIdToExpandedRowMap(newItemIdToExpandedRowMap); }; +const SpanWithMargin = styled.span` + margin-right: 16px; +`; + export const PingListComponent = ({ data, loading, @@ -185,10 +190,18 @@ export const PingListComponent = ({ columns.push({ field: 'http.response.status_code', align: 'right', - name: i18n.translate('xpack.uptime.pingList.responseCodeColumnLabel', { - defaultMessage: 'Response code', - }), - render: (statusCode: string) => {statusCode}, + name: ( + + {i18n.translate('xpack.uptime.pingList.responseCodeColumnLabel', { + defaultMessage: 'Response code', + })} + + ), + render: (statusCode: string) => ( + + {statusCode}{' '} + + ), }); } diff --git a/x-pack/package.json b/x-pack/package.json index 9ead46745747b3..84f15d3d38828e 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -36,7 +36,6 @@ "@mattapperson/slapshot": "1.4.0", "@storybook/addon-actions": "^5.2.6", "@storybook/addon-console": "^1.2.1", - "@storybook/addon-info": "^5.2.6", "@storybook/addon-knobs": "^5.2.6", "@storybook/addon-storyshots": "^5.2.6", "@storybook/react": "^5.2.6", @@ -149,8 +148,6 @@ "mutation-observer": "^1.0.3", "node-fetch": "^2.6.0", "null-loader": "^3.0.0", - "pdf-image": "2.0.0", - "pdfjs-dist": "^2.0.943", "pixelmatch": "^5.1.0", "proxyquire": "1.8.0", "react-docgen-typescript-loader": "^3.1.1", @@ -188,6 +185,7 @@ "@kbn/config-schema": "1.0.0", "@kbn/i18n": "1.0.0", "@kbn/interpreter": "1.0.0", + "@kbn/storybook": "1.0.0", "@kbn/ui-framework": "1.0.0", "@mapbox/mapbox-gl-draw": "^1.1.1", "@mapbox/mapbox-gl-rtl-text": "0.2.3", diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/action.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/action.ts index b21b79e84f7417..090d5de901318e 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/action.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/action.ts @@ -6,18 +6,19 @@ import { Vector2 } from '../../types'; -interface UserScaled { - readonly type: 'userScaled'; +interface UserSetZoomLevel { + readonly type: 'userSetZoomLevel'; /** - * A vector who's `x` and `y` component will be the new scaling factors for the projection. + * A number whose value is always between 0 and 1 and will be the new scaling factor for the projection. */ - readonly payload: Vector2; + readonly payload: number; } interface UserZoomed { readonly type: 'userZoomed'; /** - * A value to zoom in by. Should be a fraction of `1`. For a `'wheel'` event when `event.deltaMode` is `'pixel'`, pass `event.deltaY / -renderHeight` where `renderHeight` is the height of the Resolver element in pixels. + * A value to zoom in by. Should be a fraction of `1`. For a `'wheel'` event when `event.deltaMode` is `'pixel'`, + * pass `event.deltaY / -renderHeight` where `renderHeight` is the height of the Resolver element in pixels. */ payload: number; } @@ -65,7 +66,7 @@ interface UserMovedPointer { } export type CameraAction = - | UserScaled + | UserSetZoomLevel | UserSetRasterSize | UserSetPositionOfCamera | UserStartedPanning diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/inverse_projection_matrix.test.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/inverse_projection_matrix.test.ts index 3d555b63d83926..41e3bc025f557a 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/inverse_projection_matrix.test.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/inverse_projection_matrix.test.ts @@ -10,6 +10,7 @@ import { CameraState } from '../../types'; import { cameraReducer } from './reducer'; import { inverseProjectionMatrix } from './selectors'; import { applyMatrix3 } from '../../lib/vector2'; +import { scaleToZoom } from './scale_to_zoom'; describe('inverseProjectionMatrix', () => { let store: Store; @@ -59,7 +60,7 @@ describe('inverseProjectionMatrix', () => { }); describe('when the user has zoomed to 0.5', () => { beforeEach(() => { - const action: CameraAction = { type: 'userScaled', payload: [0.5, 0.5] }; + const action: CameraAction = { type: 'userSetZoomLevel', payload: scaleToZoom(0.5) }; store.dispatch(action); }); it('should convert 150, 100 (center) to 0, 0 (center) in world space', () => { @@ -89,7 +90,7 @@ describe('inverseProjectionMatrix', () => { describe('when the user has scaled to 2', () => { // the viewport will only cover half, or 150x100 instead of 300x200 beforeEach(() => { - const action: CameraAction = { type: 'userScaled', payload: [2, 2] }; + const action: CameraAction = { type: 'userSetZoomLevel', payload: scaleToZoom(2) }; store.dispatch(action); }); // we expect the viewport to be diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/projection_matrix.test.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/projection_matrix.test.ts index 025c436a957e89..e21e3d10017949 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/projection_matrix.test.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/projection_matrix.test.ts @@ -10,6 +10,7 @@ import { CameraState } from '../../types'; import { cameraReducer } from './reducer'; import { projectionMatrix } from './selectors'; import { applyMatrix3 } from '../../lib/vector2'; +import { scaleToZoom } from './scale_to_zoom'; describe('projectionMatrix', () => { let store: Store; @@ -56,7 +57,7 @@ describe('projectionMatrix', () => { }); describe('when the user has zoomed to 0.5', () => { beforeEach(() => { - const action: CameraAction = { type: 'userScaled', payload: [0.5, 0.5] }; + const action: CameraAction = { type: 'userSetZoomLevel', payload: scaleToZoom(0.5) }; store.dispatch(action); }); it('should convert 0, 0 (center) in world space to 150, 100 (center)', () => { @@ -92,7 +93,7 @@ describe('projectionMatrix', () => { describe('when the user has scaled to 2', () => { // the viewport will only cover half, or 150x100 instead of 300x200 beforeEach(() => { - const action: CameraAction = { type: 'userScaled', payload: [2, 2] }; + const action: CameraAction = { type: 'userSetZoomLevel', payload: scaleToZoom(2) }; store.dispatch(action); }); // we expect the viewport to be diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/reducer.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/reducer.ts index 457d3904804f2a..b7229240684f15 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/reducer.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/reducer.ts @@ -10,52 +10,34 @@ import { userIsPanning, translation, projectionMatrix, inverseProjectionMatrix } import { clamp } from '../../lib/math'; import { CameraState, ResolverAction } from '../../types'; +import { scaleToZoom } from './scale_to_zoom'; function initialState(): CameraState { return { - scaling: [1, 1] as const, + scalingFactor: scaleToZoom(1), // Defaulted to 1 to 1 scale rasterSize: [0, 0] as const, translationNotCountingCurrentPanning: [0, 0] as const, latestFocusedWorldCoordinates: null, }; } -/** - * The minimum allowed value for the camera scale. This is the least scale that we will ever render something at. - */ -const minimumScale = 0.1; - -/** - * The maximum allowed value for the camera scale. This is greatest scale that we will ever render something at. - */ -const maximumScale = 6; - export const cameraReducer: Reducer = ( state = initialState(), action ) => { - if (action.type === 'userScaled') { + if (action.type === 'userSetZoomLevel') { /** * Handle the scale being explicitly set, for example by a 'reset zoom' feature, or by a range slider with exact scale values */ - const [deltaX, deltaY] = action.payload; + return { ...state, - scaling: [ - clamp(deltaX, minimumScale, maximumScale), - clamp(deltaY, minimumScale, maximumScale), - ], + scalingFactor: clamp(action.payload, 0, 1), }; } else if (action.type === 'userZoomed') { - /** - * When the user zooms we change the scale. Limit the change in scale so that we aren't liable for supporting crazy values (e.g. infinity or negative scale.) - */ - const newScaleX = clamp(state.scaling[0] + action.payload, minimumScale, maximumScale); - const newScaleY = clamp(state.scaling[1] + action.payload, minimumScale, maximumScale); - const stateWithNewScaling: CameraState = { ...state, - scaling: [newScaleX, newScaleY], + scalingFactor: clamp(state.scalingFactor + action.payload, 0, 1), }; /** diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/scale_to_zoom.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/scale_to_zoom.ts new file mode 100644 index 00000000000000..534e20e9ed3c41 --- /dev/null +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/scale_to_zoom.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 { maximum, minimum, zoomCurveRate } from './scaling_constants'; + +/** + * Calculates the zoom factor (between 0 and 1) for a given scale value. + */ +export const scaleToZoom = (scale: number): number => { + const delta = maximum - minimum; + return Math.pow((scale - minimum) / delta, 1 / zoomCurveRate); +}; diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/scaling_constants.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/scaling_constants.ts new file mode 100644 index 00000000000000..93c41fde64f0ea --- /dev/null +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/scaling_constants.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * The minimum allowed value for the camera scale. This is the least scale that we will ever render something at. + */ +export const minimum = 0.1; + +/** + * The maximum allowed value for the camera scale. This is greatest scale that we will ever render something at. + */ +export const maximum = 6; + +/** + * The curve of the zoom function growth rate. The higher the scale factor is, the higher the zoom rate will be. + */ +export const zoomCurveRate = 4; diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/selectors.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/selectors.ts index e0d2062bfc8706..a7b0bbf66052d0 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/selectors.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/selectors.ts @@ -13,6 +13,7 @@ import { orthographicProjection, translationTransformation, } from '../../lib/transformation'; +import { maximum, minimum, zoomCurveRate } from './scaling_constants'; interface ClippingPlanes { renderWidth: number; @@ -43,8 +44,8 @@ export function viewableBoundingBox(state: CameraState): AABB { function clippingPlanes(state: CameraState): ClippingPlanes { const renderWidth = state.rasterSize[0]; const renderHeight = state.rasterSize[1]; - const clippingPlaneRight = renderWidth / 2 / state.scaling[0]; - const clippingPlaneTop = renderHeight / 2 / state.scaling[1]; + const clippingPlaneRight = renderWidth / 2 / scale(state)[0]; + const clippingPlaneTop = renderHeight / 2 / scale(state)[1]; return { renderWidth, @@ -112,9 +113,9 @@ export function translation(state: CameraState): Vector2 { return add( state.translationNotCountingCurrentPanning, divide(subtract(state.panning.currentOffset, state.panning.origin), [ - state.scaling[0], + scale(state)[0], // Invert `y` since the `.panning` vectors are in screen coordinates and therefore have backwards `y` - -state.scaling[1], + -scale(state)[1], ]) ); } else { @@ -175,7 +176,11 @@ export const inverseProjectionMatrix: (state: CameraState) => Matrix3 = state => /** * The scale by which world values are scaled when rendered. */ -export const scale = (state: CameraState): Vector2 => state.scaling; +export const scale = (state: CameraState): Vector2 => { + const delta = maximum - minimum; + const value = Math.pow(state.scalingFactor, zoomCurveRate) * delta + minimum; + return [value, value]; +}; /** * Whether or not the user is current panning the map. diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/test_helpers.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/test_helpers.ts index fd446c42116a40..25e0ec642086fd 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/test_helpers.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/test_helpers.ts @@ -4,19 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Store } from 'redux'; -import { CameraAction } from './action'; -import { CameraState, Vector2 } from '../../types'; - -type CameraStore = Store; - -/** - * Dispatches a 'userScaled' action. - */ -export function userScaled(store: CameraStore, scalingValue: [number, number]): void { - const action: CameraAction = { type: 'userScaled', payload: scalingValue }; - store.dispatch(action); -} +import { Vector2 } from '../../types'; /** * Used to assert that two Vector2s are close to each other (accounting for round-off errors.) diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/zooming.test.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/zooming.test.ts index a04ca8376c9b19..4b0915282e86f2 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/zooming.test.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/store/camera/zooming.test.ts @@ -9,7 +9,8 @@ import { cameraReducer } from './reducer'; import { createStore, Store } from 'redux'; import { CameraState, AABB } from '../../types'; import { viewableBoundingBox, inverseProjectionMatrix } from './selectors'; -import { userScaled, expectVectorsToBeClose } from './test_helpers'; +import { expectVectorsToBeClose } from './test_helpers'; +import { scaleToZoom } from './scale_to_zoom'; import { applyMatrix3 } from '../../lib/vector2'; describe('zooming', () => { @@ -43,7 +44,8 @@ describe('zooming', () => { ); describe('when the user has scaled in to 2x', () => { beforeEach(() => { - userScaled(store, [2, 2]); + const action: CameraAction = { type: 'userSetZoomLevel', payload: scaleToZoom(2) }; + store.dispatch(action); }); it( ...cameraShouldBeBoundBy({ @@ -52,7 +54,7 @@ describe('zooming', () => { }) ); }); - describe('when the user zooms in by 1 zoom unit', () => { + describe('when the user zooms in all the way', () => { beforeEach(() => { const action: CameraAction = { type: 'userZoomed', @@ -60,12 +62,21 @@ describe('zooming', () => { }; store.dispatch(action); }); - it( - ...cameraShouldBeBoundBy({ - minimum: [-75, -50], - maximum: [75, 50], - }) - ); + it('should zoom to maximum scale factor', () => { + const actual = viewableBoundingBox(store.getState()); + expect(actual).toMatchInlineSnapshot(` + Object { + "maximum": Array [ + 25.000000000000007, + 16.666666666666668, + ], + "minimum": Array [ + -25, + -16.666666666666668, + ], + } + `); + }); }); it('the raster position 200, 50 should map to the world position 50, 50', () => { expectVectorsToBeClose(applyMatrix3([200, 50], inverseProjectionMatrix(store.getState())), [ @@ -126,7 +137,8 @@ describe('zooming', () => { }); describe('when the user scales to 2x', () => { beforeEach(() => { - userScaled(store, [2, 2]); + const action: CameraAction = { type: 'userSetZoomLevel', payload: scaleToZoom(2) }; + store.dispatch(action); }); it('should be centered on 100, 0', () => { const worldCenterPoint = applyMatrix3( diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/types.ts b/x-pack/plugins/endpoint/public/embeddables/resolver/types.ts index ed7eb79d621fcc..eae9ebf9ee9a63 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/types.ts +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/types.ts @@ -43,9 +43,9 @@ export interface CameraState { readonly panning?: PanningState; /** - * Scales the coordinate system, used for zooming. + * Scales the coordinate system, used for zooming. Should always be between 0 and 1 */ - readonly scaling: Vector2; + readonly scalingFactor: number; /** * The size (in pixels) of the Resolver component. diff --git a/x-pack/plugins/endpoint/public/embeddables/resolver/view/index.tsx b/x-pack/plugins/endpoint/public/embeddables/resolver/view/index.tsx index 2c5c60440522dd..c439e3318d3c92 100644 --- a/x-pack/plugins/endpoint/public/embeddables/resolver/view/index.tsx +++ b/x-pack/plugins/endpoint/public/embeddables/resolver/view/index.tsx @@ -95,7 +95,6 @@ const Resolver = styled( const handleWheel = useCallback( (event: WheelEvent) => { - // we use elementBoundingClientRect to interpret pixel deltas as a fraction of the element's height if ( elementBoundingClientRect !== null && event.ctrlKey && @@ -105,7 +104,9 @@ const Resolver = styled( event.preventDefault(); dispatch({ type: 'userZoomed', - payload: (-2 * event.deltaY) / elementBoundingClientRect.height, + // we use elementBoundingClientRect to interpret pixel deltas as a fraction of the element's height + // when pinch-zooming in on a mac, deltaY is a negative number but we want the payload to be positive + payload: event.deltaY / -elementBoundingClientRect.height, }); } }, diff --git a/x-pack/plugins/reporting/public/components/download_button.tsx b/x-pack/plugins/reporting/public/components/download_button.tsx index e762c796b0f860..911a19c0176c22 100644 --- a/x-pack/plugins/reporting/public/components/download_button.tsx +++ b/x-pack/plugins/reporting/public/components/download_button.tsx @@ -15,17 +15,12 @@ interface Props { } export const DownloadButton = ({ getUrl, job }: Props) => { - const downloadReport = () => { - window.open(getUrl(job.id)); - }; - return ( { - downloadReport(); - }} + href={getUrl(job.id)} + target="_blank" > + const allPaths = Object.values(ExternalServiceSimulator).map(service => getExternalServiceSimulatorPath(service) ); + allPaths.push(`/api/_${NAME}/${ExternalServiceSimulator.SERVICENOW}/api/now/v1/table/incident`); + return allPaths; } // eslint-disable-next-line import/no-default-export @@ -67,9 +71,10 @@ export default function(kibana: any) { }, }); + initPagerduty(server, getExternalServiceSimulatorPath(ExternalServiceSimulator.PAGERDUTY)); + initServiceNow(server, getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW)); initSlack(server, getExternalServiceSimulatorPath(ExternalServiceSimulator.SLACK)); initWebhook(server, getExternalServiceSimulatorPath(ExternalServiceSimulator.WEBHOOK)); - initPagerduty(server, getExternalServiceSimulatorPath(ExternalServiceSimulator.PAGERDUTY)); }, }); } diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/servicenow_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/servicenow_simulation.ts new file mode 100644 index 00000000000000..f215b63560339b --- /dev/null +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/servicenow_simulation.ts @@ -0,0 +1,120 @@ +/* + * 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 Joi from 'joi'; +import Hapi from 'hapi'; + +interface ServiceNowRequest extends Hapi.Request { + payload: { + comments: string; + short_description: string; + }; +} +export function initPlugin(server: Hapi.Server, path: string) { + server.route({ + method: 'POST', + path, + options: { + auth: false, + validate: { + options: { abortEarly: false }, + payload: Joi.object().keys({ + comments: Joi.string(), + short_description: Joi.string(), + }), + }, + }, + handler: servicenowHandler, + }); + + server.route({ + method: 'POST', + path: `${path}/api/now/v1/table/incident`, + options: { + auth: false, + validate: { + options: { abortEarly: false }, + payload: Joi.object().keys({ + comments: Joi.string(), + short_description: Joi.string(), + }), + }, + }, + handler: servicenowHandler, + }); +} +// ServiceNow simulator: create a servicenow action pointing here, and you can get +// different responses based on the message posted. See the README.md for +// more info. + +function servicenowHandler(request: ServiceNowRequest, h: any) { + const body = request.payload; + const text = body && body.short_description; + if (text == null) { + return jsonResponse(h, 400, 'bad request to servicenow simulator'); + } + + switch (text) { + case 'success': + return jsonResponse(h, 200, 'Success'); + + case 'created': + return jsonResponse(h, 201, 'Created'); + + case 'no_text': + return jsonResponse(h, 204, 'Success'); + + case 'invalid_payload': + return jsonResponse(h, 400, 'Bad Request'); + + case 'unauthorized': + return jsonResponse(h, 401, 'Unauthorized'); + + case 'forbidden': + return jsonResponse(h, 403, 'Forbidden'); + + case 'not_found': + return jsonResponse(h, 404, 'Not found'); + + case 'not_allowed': + return jsonResponse(h, 405, 'Method not allowed'); + + case 'not_acceptable': + return jsonResponse(h, 406, 'Not acceptable'); + + case 'unsupported': + return jsonResponse(h, 415, 'Unsupported media type'); + + case 'status_500': + return jsonResponse(h, 500, 'simulated servicenow 500 response'); + + case 'rate_limit': + const response = { + retry_after: 1, + ok: false, + error: 'rate_limited', + }; + + return h + .response(response) + .type('application/json') + .header('retry-after', '1') + .code(429); + } + + return jsonResponse(h, 400, 'unknown request to servicenow simulator'); +} + +function jsonResponse(h: any, code: number, object?: any) { + if (object == null) { + return h.response('').code(code); + } + + return h + .response(JSON.stringify(object)) + .type('application/json') + .code(code); +} diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts new file mode 100644 index 00000000000000..15662649266ae8 --- /dev/null +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts @@ -0,0 +1,271 @@ +/* + * 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 { FtrProviderContext } from '../../../../common/ftr_provider_context'; + +import { + getExternalServiceSimulatorPath, + ExternalServiceSimulator, +} from '../../../../common/fixtures/plugins/actions'; + +// node ../scripts/functional_test_runner.js --grep "Actions.servicenddd" --config=test/alerting_api_integration/security_and_spaces/config.ts + +// eslint-disable-next-line import/no-default-export +export default function servicenowTest({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); + const mockServiceNow = { + config: { + apiUrl: 'www.servicenowisinkibanaactions.com', + }, + secrets: { + password: 'elastic', + username: 'changeme', + }, + params: { + comments: 'hello cool service now incident', + short_description: 'this is a cool service now incident', + }, + }; + describe('servicenow', () => { + let simulatedActionId = ''; + let servicenowSimulatorURL: string = ''; + + // need to wait for kibanaServer to settle ... + before(() => { + servicenowSimulatorURL = kibanaServer.resolveUrl( + getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW) + ); + }); + + after(() => esArchiver.unload('empty_kibana')); + + it('should return 200 when creating a servicenow action successfully', async () => { + const { body: createdAction } = await supertest + .post('/api/action') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + actionTypeId: '.servicenow', + config: { + apiUrl: servicenowSimulatorURL, + }, + secrets: mockServiceNow.secrets, + }) + .expect(200); + + expect(createdAction).to.eql({ + id: createdAction.id, + name: 'A servicenow action', + actionTypeId: '.servicenow', + config: { + apiUrl: servicenowSimulatorURL, + }, + }); + + expect(typeof createdAction.id).to.be('string'); + + const { body: fetchedAction } = await supertest + .get(`/api/action/${createdAction.id}`) + .expect(200); + + expect(fetchedAction).to.eql({ + id: fetchedAction.id, + name: 'A servicenow action', + actionTypeId: '.servicenow', + config: { + apiUrl: servicenowSimulatorURL, + }, + }); + }); + + it('should respond with a 400 Bad Request when creating a servicenow action with no webhookUrl', async () => { + await supertest + .post('/api/action') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + actionTypeId: '.servicenow', + config: {}, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'error validating action type config: [apiUrl]: expected value of type [string] but got [undefined]', + }); + }); + }); + + it('should respond with a 400 Bad Request when creating a servicenow action with a non whitelisted webhookUrl', async () => { + await supertest + .post('/api/action') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + actionTypeId: '.servicenow', + config: { + apiUrl: 'http://servicenow.mynonexistent.com', + }, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'error validating action type config: error configuring servicenow action: target url "http://servicenow.mynonexistent.com" is not whitelisted in the Kibana config xpack.actions.whitelistedHosts', + }); + }); + }); + + it('should respond with a 400 Bad Request when creating a servicenow action without secrets', async () => { + await supertest + .post('/api/action') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow action', + actionTypeId: '.servicenow', + config: { + apiUrl: servicenowSimulatorURL, + }, + }) + .expect(400) + .then((resp: any) => { + expect(resp.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'error validating action type secrets: [password]: expected value of type [string] but got [undefined]', + }); + }); + }); + + it('should create our servicenow simulator action successfully', async () => { + const { body: createdSimulatedAction } = await supertest + .post('/api/action') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A servicenow simulator', + actionTypeId: '.servicenow', + config: { + apiUrl: servicenowSimulatorURL, + }, + secrets: mockServiceNow.secrets, + }) + .expect(200); + + simulatedActionId = createdSimulatedAction.id; + }); + + it('should handle executing with a simulated success', async () => { + const { body: result } = await supertest + .post(`/api/action/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + comments: 'success', + short_description: 'success', + }, + }) + .expect(200); + + expect(result.status).to.eql('ok'); + }); + + it('should handle executing with a simulated success without comments', async () => { + const { body: result } = await supertest + .post(`/api/action/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + short_description: 'success', + }, + }) + .expect(200); + + expect(result.status).to.eql('ok'); + }); + + it('should handle failing with a simulated success without short_description', async () => { + await supertest + .post(`/api/action/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + comments: 'success', + }, + }) + .then((resp: any) => { + expect(resp.body).to.eql({ + actionId: simulatedActionId, + status: 'error', + retry: false, + message: + 'error validating action params: [short_description]: expected value of type [string] but got [undefined]', + }); + }); + }); + + it('should handle a 40x servicenow error', async () => { + const { body: result } = await supertest + .post(`/api/action/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + comments: 'invalid_payload', + short_description: 'invalid_payload', + }, + }) + .expect(200); + expect(result.status).to.equal('error'); + expect(result.message).to.match(/error posting servicenow event: unexpected status 400/); + }); + + it('should handle a 429 servicenow error', async () => { + const { body: result } = await supertest + .post(`/api/action/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + comments: 'rate_limit', + short_description: 'rate_limit', + }, + }) + .expect(200); + + expect(result.status).to.equal('error'); + expect(result.message).to.equal( + 'error posting servicenow event: http status 429, retry later' + ); + expect(result.retry).to.equal(true); + }); + + it('should handle a 500 servicenow error', async () => { + const { body: result } = await supertest + .post(`/api/action/${simulatedActionId}/_execute`) + .set('kbn-xsrf', 'foo') + .send({ + params: { + comments: 'status_500', + short_description: 'status_500', + }, + }) + .expect(200); + + expect(result.status).to.equal('error'); + expect(result.message).to.equal( + 'error posting servicenow event: http status 500, retry later' + ); + expect(result.retry).to.equal(true); + }); + }); +} diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/index.ts index 7f67f2f5b60e72..c6960a4eedd256 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/index.ts @@ -9,18 +9,19 @@ import { FtrProviderContext } from '../../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export export default function actionsTests({ loadTestFile }: FtrProviderContext) { describe('Actions', () => { + loadTestFile(require.resolve('./builtin_action_types/email')); + loadTestFile(require.resolve('./builtin_action_types/es_index')); + loadTestFile(require.resolve('./builtin_action_types/pagerduty')); + loadTestFile(require.resolve('./builtin_action_types/server_log')); + loadTestFile(require.resolve('./builtin_action_types/servicenow')); + loadTestFile(require.resolve('./builtin_action_types/slack')); + loadTestFile(require.resolve('./builtin_action_types/webhook')); loadTestFile(require.resolve('./create')); loadTestFile(require.resolve('./delete')); + loadTestFile(require.resolve('./execute')); loadTestFile(require.resolve('./find')); loadTestFile(require.resolve('./get')); loadTestFile(require.resolve('./list_action_types')); loadTestFile(require.resolve('./update')); - loadTestFile(require.resolve('./execute')); - loadTestFile(require.resolve('./builtin_action_types/server_log')); - loadTestFile(require.resolve('./builtin_action_types/slack')); - loadTestFile(require.resolve('./builtin_action_types/email')); - loadTestFile(require.resolve('./builtin_action_types/es_index')); - loadTestFile(require.resolve('./builtin_action_types/pagerduty')); - loadTestFile(require.resolve('./builtin_action_types/webhook')); }); } diff --git a/x-pack/test/api_integration/apis/ml/calculate_model_memory_limit.ts b/x-pack/test/api_integration/apis/ml/calculate_model_memory_limit.ts new file mode 100644 index 00000000000000..b725996533732f --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/calculate_model_memory_limit.ts @@ -0,0 +1,162 @@ +/* + * 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 { FtrProviderContext } from '../../ftr_provider_context'; + +const COMMON_HEADERS = { + 'kbn-xsrf': 'some-xsrf-token', +}; + +const testDataList = [ + { + testTitleSuffix: 'with 0 metrics, 0 influencers and no split field', + requestBody: { + indexPattern: 'ecommerce', + splitFieldName: '', + query: { bool: { must: [{ match_all: {} }], filter: [], must_not: [] } }, + fieldNames: ['__ml_event_rate_count__'], + influencerNames: [], + timeFieldName: 'order_date', + earliestMs: 1560297859000, + latestMs: 1562975136000, + }, + expected: { + responseCode: 400, + responseBody: { + statusCode: 400, + error: 'Bad Request', + message: "[illegal_argument_exception] specified fields can't be null or empty", + }, + }, + }, + { + testTitleSuffix: 'with 1 metrics and 1 influencers same as split field', + requestBody: { + indexPattern: 'ecommerce', + splitFieldName: 'geoip.city_name', + query: { bool: { must: [{ match_all: {} }], filter: [], must_not: [] } }, + fieldNames: ['products.base_price'], + influencerNames: ['geoip.city_name'], + timeFieldName: 'order_date', + earliestMs: 1560297859000, + latestMs: 1562975136000, + }, + expected: { + responseCode: 200, + responseBody: { modelMemoryLimit: '12MB' }, + }, + }, + { + testTitleSuffix: 'with 3 metrics, 3 influencers, split by city', + requestBody: { + indexPattern: 'ecommerce', + splitFieldName: 'geoip.city_name', + query: { bool: { must: [{ match_all: {} }], filter: [], must_not: [] } }, + fieldNames: ['products.base_price', 'taxful_total_price', 'products.discount_amount'], + influencerNames: ['geoip.city_name', 'customer_gender', 'customer_full_name.keyword'], + timeFieldName: 'order_date', + earliestMs: 1560297859000, + latestMs: 1562975136000, + }, + expected: { + responseCode: 200, + responseBody: { modelMemoryLimit: '14MB' }, + }, + }, + { + testTitleSuffix: 'with 4 metrics, 4 influencers, split by customer_id', + requestBody: { + indexPattern: 'ecommerce', + splitFieldName: 'customer_id', + query: { bool: { must: [{ match_all: {} }], filter: [], must_not: [] } }, + fieldNames: [ + 'geoip.country_iso_code', + 'taxless_total_price', + 'taxful_total_price', + 'products.discount_amount', + ], + influencerNames: [ + 'customer_id', + 'geoip.country_iso_code', + 'products.discount_percentage', + 'products.discount_amount', + ], + timeFieldName: 'order_date', + earliestMs: 1560297859000, + latestMs: 1562975136000, + }, + expected: { + responseCode: 200, + responseBody: { modelMemoryLimit: '23MB' }, + }, + }, + { + testTitleSuffix: + 'with 4 metrics, 4 influencers, split by customer_id and filtering by country code', + requestBody: { + indexPattern: 'ecommerce', + splitFieldName: 'customer_id', + query: { + bool: { + filter: { + term: { + 'geoip.country_iso_code': 'US', + }, + }, + }, + }, + fieldNames: [ + 'geoip.country_iso_code', + 'taxless_total_price', + 'taxful_total_price', + 'products.discount_amount', + ], + influencerNames: [ + 'customer_id', + 'geoip.country_iso_code', + 'products.discount_percentage', + 'products.discount_amount', + ], + timeFieldName: 'order_date', + earliestMs: 1560297859000, + latestMs: 1562975136000, + }, + expected: { + responseCode: 200, + responseBody: { modelMemoryLimit: '14MB' }, + }, + }, +]; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const esArchiver = getService('esArchiver'); + const supertest = getService('supertest'); + + describe('calculate model memory limit', () => { + before(async () => { + await esArchiver.load('ml/ecommerce'); + }); + + after(async () => { + await esArchiver.unload('ml/ecommerce'); + }); + + for (const testData of testDataList) { + it(`calculates the model memory limit ${testData.testTitleSuffix}`, async () => { + const { body } = await supertest + .post('/api/ml/validate/calculate_model_memory_limit') + .set(COMMON_HEADERS) + .send(testData.requestBody) + .expect(testData.expected.responseCode); + + expect(body).to.eql(testData.expected.responseBody); + }); + } + }); +}; diff --git a/x-pack/test/api_integration/apis/ml/index.ts b/x-pack/test/api_integration/apis/ml/index.ts index 2e0521e2b82737..9fff4ca8436b06 100644 --- a/x-pack/test/api_integration/apis/ml/index.ts +++ b/x-pack/test/api_integration/apis/ml/index.ts @@ -11,5 +11,6 @@ export default function({ loadTestFile }: FtrProviderContext) { this.tags(['mlqa']); loadTestFile(require.resolve('./bucket_span_estimator')); + loadTestFile(require.resolve('./calculate_model_memory_limit')); }); } diff --git a/x-pack/test/functional/apps/lens/lens_reporting.ts b/x-pack/test/functional/apps/lens/lens_reporting.ts index 3d70390a2de41a..2e3e630680ff0b 100644 --- a/x-pack/test/functional/apps/lens/lens_reporting.ts +++ b/x-pack/test/functional/apps/lens/lens_reporting.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../ftr_provider_context'; // eslint-disable-next-line import/no-default-export export default function({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects(['common', 'dashboard', 'reporting']); - const find = getService('find'); const esArchiver = getService('esArchiver'); const listingTable = getService('listingTable'); @@ -28,8 +27,9 @@ export default function({ getService, getPageObjects }: FtrProviderContext) { await listingTable.clickItemLink('dashboard', 'Lens reportz'); await PageObjects.reporting.openPdfReportingPanel(); await PageObjects.reporting.clickGenerateReportButton(); + const url = await PageObjects.reporting.getReportURL(60000); - expect(await find.byButtonText('Download report', undefined, 60000)).to.be.ok(); + expect(url).to.be.ok(); }); }); } diff --git a/x-pack/test/functional/page_objects/reporting_page.js b/x-pack/test/functional/page_objects/reporting_page.js index acbc1dd100e5d6..7cdd1c083239bd 100644 --- a/x-pack/test/functional/page_objects/reporting_page.js +++ b/x-pack/test/functional/page_objects/reporting_page.js @@ -37,34 +37,6 @@ export function ReportingPageProvider({ getService, getPageObjects }) { await browser.setWindowSize(1600, 850); } - async getUrlOfTab(tabIndex) { - return await retry.try(async () => { - log.debug(`reportingPage.getUrlOfTab(${tabIndex}`); - const handles = await browser.getAllWindowHandles(); - log.debug(`Switching to window ${handles[tabIndex]}`); - await browser.switchToWindow(handles[tabIndex]); - - const url = await browser.getCurrentUrl(); - if (!url || url === 'about:blank') { - throw new Error('url is blank'); - } - - await browser.switchToWindow(handles[0]); - return url; - }); - } - - async closeTab(tabIndex) { - return await retry.try(async () => { - log.debug(`reportingPage.closeTab(${tabIndex}`); - const handles = await browser.getAllWindowHandles(); - log.debug(`Switching to window ${handles[tabIndex]}`); - await browser.switchToWindow(handles[tabIndex]); - await browser.closeCurrentWindow(); - await browser.switchToWindow(handles[0]); - }); - } - async forceSharedItemsContainerSize({ width }) { await browser.execute(` var el = document.querySelector('[data-shared-items-container]'); @@ -73,6 +45,16 @@ export function ReportingPageProvider({ getService, getPageObjects }) { `); } + async getReportURL(timeout) { + log.debug('getReportURL'); + + const url = await testSubjects.getAttribute('downloadCompletedReportButton', 'href', timeout); + + log.debug(`getReportURL got url: ${url}`); + + return url; + } + async removeForceSharedItemsContainerSize() { await browser.execute(` var el = document.querySelector('[data-shared-items-container]'); @@ -81,9 +63,8 @@ export function ReportingPageProvider({ getService, getPageObjects }) { `); } - getRawPdfReportData(url) { - log.debug(`getRawPdfReportData for ${url}`); - let data = []; // List of Buffer objects + getResponse(url) { + log.debug(`getResponse for ${url}`); const auth = config.get('servers.elasticsearch.auth'); const headers = { Authorization: `Basic ${Buffer.from(auth).toString('base64')}`, @@ -100,13 +81,7 @@ export function ReportingPageProvider({ getService, getPageObjects }) { headers, }, res => { - res.on('data', function(chunk) { - data.push(chunk); - }); - res.on('end', function() { - data = Buffer.concat(data); - resolve(data); - }); + resolve(res); } ) .on('error', e => { @@ -115,6 +90,18 @@ export function ReportingPageProvider({ getService, getPageObjects }) { }); } + async getRawPdfReportData(url) { + const data = []; // List of Buffer objects + log.debug(`getRawPdfReportData for ${url}`); + + return new Promise(async (resolve, reject) => { + const response = await this.getResponse(url).catch(reject); + + response.on('data', chunk => data.push(chunk)); + response.on('end', () => resolve(Buffer.concat(data))); + }); + } + async openCsvReportingPanel() { log.debug('openCsvReportingPanel'); await PageObjects.share.openShareMenuItem('CSV Reports'); @@ -130,10 +117,6 @@ export function ReportingPageProvider({ getService, getPageObjects }) { await PageObjects.share.openShareMenuItem('PNG Reports'); } - async clickDownloadReportButton(timeout) { - await testSubjects.click('downloadCompletedReportButton', timeout); - } - async clearToastNotifications() { const toasts = await testSubjects.findAll('toastCloseButton'); await Promise.all(toasts.map(async t => await t.click())); @@ -175,7 +158,9 @@ export function ReportingPageProvider({ getService, getPageObjects }) { async setTimepickerInDataRange() { log.debug('Reporting:setTimepickerInDataRange'); - await PageObjects.timePicker.setDefaultAbsoluteRange(); + const fromTime = 'Sep 19, 2015 @ 06:31:44.000'; + const toTime = 'Sep 19, 2015 @ 18:01:44.000'; + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); } async setTimepickerInNoDataRange() { diff --git a/x-pack/test/plugin_functional/plugins/resolver_test/public/applications/resolver_test/index.tsx b/x-pack/test/plugin_functional/plugins/resolver_test/public/applications/resolver_test/index.tsx index 55fd436de40a15..498aff62d40d48 100644 --- a/x-pack/test/plugin_functional/plugins/resolver_test/public/applications/resolver_test/index.tsx +++ b/x-pack/test/plugin_functional/plugins/resolver_test/public/applications/resolver_test/index.tsx @@ -13,7 +13,7 @@ import { useEffect } from 'react'; import styled from 'styled-components'; /** - * This module will be loaded asynchronously to reduce the bundle size of your plugin's main bundle. + * Render the Resolver Test app. Returns a cleanup function. */ export function renderApp( { element }: AppMountParameters, diff --git a/x-pack/test/plugin_functional/plugins/resolver_test/public/plugin.ts b/x-pack/test/plugin_functional/plugins/resolver_test/public/plugin.ts index 9252825ea11072..045cc56238ac9b 100644 --- a/x-pack/test/plugin_functional/plugins/resolver_test/public/plugin.ts +++ b/x-pack/test/plugin_functional/plugins/resolver_test/public/plugin.ts @@ -23,43 +23,35 @@ export class ResolverTestPlugin ResolverTestPluginSetupDependencies, ResolverTestPluginStartDependencies > { - private resolveEmbeddable!: ( - value: IEmbeddable | undefined | PromiseLike | undefined - ) => void; - /** - * We register our application during the `setup` phase, but the embeddable - * plugin API is not available until the `start` phase. In order to access - * the embeddable API from our application, we pass a Promise to the application - * which we resolve during the `start` phase. - */ - private embeddablePromise: Promise = new Promise< - IEmbeddable | undefined - >(resolve => { - this.resolveEmbeddable = resolve; - }); - public setup(core: CoreSetup) { + public setup(core: CoreSetup) { core.application.register({ id: 'resolver_test', title: i18n.translate('xpack.resolver_test.pluginTitle', { defaultMessage: 'Resolver Test', }), mount: async (_context, params) => { + let resolveEmbeddable: ( + value: IEmbeddable | undefined | PromiseLike | undefined + ) => void; + + const promise = new Promise(resolve => { + resolveEmbeddable = resolve; + }); + + (async () => { + const [, { embeddable }] = await core.getStartServices(); + const factory = embeddable.getEmbeddableFactory('resolver'); + resolveEmbeddable!(factory.create({ id: 'test basic render' })); + })(); + const { renderApp } = await import('./applications/resolver_test'); /** * Pass a promise which resolves to the Resolver embeddable. */ - return renderApp(params, this.embeddablePromise); + return renderApp(params, promise); }, }); } - public start(...args: [unknown, { embeddable: IEmbeddableStart }]) { - const [, plugins] = args; - const factory = plugins.embeddable.getEmbeddableFactory('resolver'); - /** - * Provide the Resolver embeddable to the application - */ - this.resolveEmbeddable(factory.create({ id: 'test basic render' })); - } - public stop() {} + public start() {} } diff --git a/x-pack/test/reporting/README.md b/x-pack/test/reporting/README.md index d4a6c20a835e22..fc5147ad8c4544 100644 --- a/x-pack/test/reporting/README.md +++ b/x-pack/test/reporting/README.md @@ -9,8 +9,8 @@ Reporting tests have their own top level test folder because: ### Running the tests There is more information on running x-pack tests here: https://github.com/elastic/kibana/blob/master/x-pack/README.md#running-functional-tests. Similar to running the API tests, you need to specify a reporting configuration file. Reporting currently has two configuration files you can point to: - - test/reporting/configs/chromium_api.js - - test/reporting/configs/chromium_functional.js + - test/reporting/configs/chromium_api.js + - test/reporting/configs/chromium_functional.js The `api` versions hit the reporting api and ensure report generation completes successfully, but does not verify the output of the reports. This is done in the `functional` test versions, which does a snapshot comparison of the generated URL against a baseline to determine success. @@ -33,10 +33,6 @@ node scripts/functional_tests_server.js --config test/reporting/configs/[test_co node ../scripts/functional_test_runner.js --config test/reporting/configs/[test_config_name_here].js ``` -**Prerequisites** -The reporting functional tests use [pdf-image](https://www.npmjs.com/package/pdf-image) to convert PDF's pages to png files for image comparisons between generated reports and baseline reports. -pdf-image requires the system commands `convert`, `gs`, and `pdfinfo` to function. Those can be set up by running the following. - ```sh //OSX brew install imagemagick ghostscript poppler @@ -99,7 +95,7 @@ node ../scripts/es_archiver.js --es-url http://elastic:changeme@localhost:9200 l 7. Generate some reporting URLs - Use a mixture of Visualize, Discover (CSV), Dashboard - Can view the current test coverage by checkout out [api/generation_urls.js](https://github.com/elastic/kibana/blob/master/x-pack/test/reporting/api/generation_urls.js). You can use different ones for better test coverage (e.g. different dashboards, different visualizations). - - Don’t generate urls from huge dashboards since this is time consuming. + - Don’t generate urls from huge dashboards since this is time consuming. - Use dashboards that have time saved with them if you wish to have data included. 8. Save these reporting urls. 9. Navigate back to the main branch via `git checkout master`. Then create, or work off your branch as usual to add the extra test coverage. diff --git a/x-pack/test/reporting/configs/chromium_functional.js b/x-pack/test/reporting/configs/chromium_functional.js index 22640e858cc6cf..81a51f44c1c5fc 100644 --- a/x-pack/test/reporting/configs/chromium_functional.js +++ b/x-pack/test/reporting/configs/chromium_functional.js @@ -25,6 +25,8 @@ export default async function({ readConfigFile }) { '["info","warning","error","fatal","optimize","reporting"]', '--xpack.endpoint.enabled=true', '--xpack.reporting.csv.enablePanelActionDownload=true', + '--xpack.reporting.csv.checkForFormulas=false', + '--xpack.reporting.csv.maxSizeBytes=25000000', '--xpack.security.session.idleTimeout=3600000', '--xpack.spaces.enabled=false', ], diff --git a/x-pack/test/reporting/functional/lib/compare_pdfs.js b/x-pack/test/reporting/functional/lib/compare_pdfs.js deleted file mode 100644 index 56e57b55646940..00000000000000 --- a/x-pack/test/reporting/functional/lib/compare_pdfs.js +++ /dev/null @@ -1,85 +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 path from 'path'; -import fs from 'fs'; -import { promisify } from 'util'; -import { PDFImage } from 'pdf-image'; -import PDFJS from 'pdfjs-dist'; -import { comparePngs } from '../../../../../test/functional/services/lib/compare_pngs'; - -const mkdirAsync = promisify(fs.mkdir); - -export async function checkIfPdfsMatch(actualPdfPath, baselinePdfPath, screenshotsDirectory, log) { - log.debug(`checkIfPdfsMatch: ${actualPdfPath} vs ${baselinePdfPath}`); - // Copy the pdfs into the screenshot session directory, as that's where the generated pngs will automatically be - // stored. - const sessionDirectoryPath = path.resolve(screenshotsDirectory, 'session'); - const failureDirectoryPath = path.resolve(screenshotsDirectory, 'failure'); - - await mkdirAsync(sessionDirectoryPath, { recursive: true }); - await mkdirAsync(failureDirectoryPath, { recursive: true }); - - const actualPdfFileName = path.basename(actualPdfPath, '.pdf'); - const baselinePdfFileName = path.basename(baselinePdfPath, '.pdf'); - - const baselineCopyPath = path.resolve( - sessionDirectoryPath, - `${baselinePdfFileName}_baseline.pdf` - ); - const actualCopyPath = path.resolve(sessionDirectoryPath, `${actualPdfFileName}_actual.pdf`); - - // Don't cause a test failure if the baseline snapshot doesn't exist - we don't have all OS's covered and we - // don't want to start causing failures for other devs working on OS's which are lacking snapshots. We have - // mac and linux covered which is better than nothing for now. - try { - log.debug(`writeFileSync: ${baselineCopyPath}`); - fs.writeFileSync(baselineCopyPath, fs.readFileSync(baselinePdfPath)); - } catch (error) { - log.error(`No baseline pdf found at ${baselinePdfPath}`); - return 0; - } - log.debug(`writeFileSync: ${actualCopyPath}`); - fs.writeFileSync(actualCopyPath, fs.readFileSync(actualPdfPath)); - - const convertOptions = {}; - - const actualPdfImage = new PDFImage(actualCopyPath, { convertOptions }); - const expectedPdfImage = new PDFImage(baselineCopyPath, { convertOptions }); - - log.debug(`Calculating numberOfPages`); - - const actualDoc = await PDFJS.getDocument(actualCopyPath); - const expectedDoc = await PDFJS.getDocument(baselineCopyPath); - const actualPages = actualDoc.numPages; - const expectedPages = expectedDoc.numPages; - - if (actualPages !== expectedPages) { - throw new Error( - `Expected ${expectedPages} pages but got ${actualPages} in PDFs expected: "${baselineCopyPath}" actual: "${actualCopyPath}".` - ); - } - - let diffTotal = 0; - - for (let pageNum = 0; pageNum <= expectedPages; ++pageNum) { - log.debug(`Converting expected pdf page ${pageNum} to png`); - const expectedPagePng = await expectedPdfImage.convertPage(pageNum); - log.debug(`Converting actual pdf page ${pageNum} to png`); - const actualPagePng = await actualPdfImage.convertPage(pageNum); - const diffPngPath = path.resolve(failureDirectoryPath, `${baselinePdfFileName}-${pageNum}.png`); - diffTotal += await comparePngs( - actualPagePng, - expectedPagePng, - diffPngPath, - sessionDirectoryPath, - log - ); - pageNum++; - } - - return diffTotal; -} diff --git a/x-pack/test/reporting/functional/lib/index.js b/x-pack/test/reporting/functional/lib/index.js index 3590995002c085..e7a08753b591f5 100644 --- a/x-pack/test/reporting/functional/lib/index.js +++ b/x-pack/test/reporting/functional/lib/index.js @@ -4,5 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { checkIfPdfsMatch } from './compare_pdfs'; export { checkIfPngsMatch } from './compare_pngs'; diff --git a/x-pack/test/reporting/functional/reporting.js b/x-pack/test/reporting/functional/reporting.js index 8458f4e537b70d..0e1078a2a4c8b0 100644 --- a/x-pack/test/reporting/functional/reporting.js +++ b/x-pack/test/reporting/functional/reporting.js @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import path from 'path'; import fs from 'fs'; import { promisify } from 'util'; -import { checkIfPdfsMatch, checkIfPngsMatch } from './lib'; +import { checkIfPngsMatch } from './lib'; const writeFileAsync = promisify(fs.writeFile); const mkdirAsync = promisify(fs.mkdir); @@ -29,9 +29,7 @@ export default function({ getService, getPageObjects }) { ]); const log = getService('log'); - // FLAKY: https://github.com/elastic/kibana/issues/45499 - // FLAKY: https://github.com/elastic/kibana/issues/48721 - describe.skip('Reporting', () => { + describe('Reporting', () => { before('initialize tests', async () => { await PageObjects.reporting.initTests(); }); @@ -68,7 +66,9 @@ export default function({ getService, getPageObjects }) { const getBaselineReportPath = (fileName, reportExt = 'pdf') => { const baselineFolder = path.resolve(REPORTS_FOLDER, 'baseline'); - return path.resolve(baselineFolder, `${fileName}.${reportExt}`); + const fullPath = path.resolve(baselineFolder, `${fileName}.${reportExt}`); + log.debug(`getBaselineReportPath (${fullPath})`); + return fullPath; }; describe('Dashboard', () => { @@ -83,118 +83,40 @@ export default function({ getService, getPageObjects }) { }); it('becomes available when saved', async () => { - await PageObjects.dashboard.saveDashboard('mypdfdash'); + await PageObjects.dashboard.saveDashboard('My PDF Dashboard'); await PageObjects.reporting.openPdfReportingPanel(); await expectEnabledGenerateReportButton(); }); }); - describe.skip('Print Layout', () => { - it('matches baseline report', async function() { + describe('Print Layout', () => { + it('downloads a PDF file', async function() { // Generating and then comparing reports can take longer than the default 60s timeout because the comparePngs // function is taking about 15 seconds per comparison in jenkins. - this.timeout(360000); + this.timeout(300000); await PageObjects.dashboard.switchToEditMode(); await PageObjects.reporting.setTimepickerInDataRange(); const visualizations = PageObjects.dashboard.getTestVisualizationNames(); - // There is a current issue causing reports with tilemaps to timeout: - // https://github.com/elastic/kibana/issues/14136. Once that is resolved, add the tilemap visualization - // back in! const tileMapIndex = visualizations.indexOf('Visualization TileMap'); visualizations.splice(tileMapIndex, 1); - await PageObjects.dashboard.addVisualizations(visualizations); - - await PageObjects.dashboard.saveDashboard('report test'); - - await PageObjects.reporting.openPdfReportingPanel(); - await PageObjects.reporting.checkUsePrintLayout(); - await PageObjects.reporting.clickGenerateReportButton(); - await PageObjects.reporting.clickDownloadReportButton(60000); - PageObjects.reporting.clearToastNotifications(); - const url = await PageObjects.reporting.getUrlOfTab(1); - await PageObjects.reporting.closeTab(1); - const reportData = await PageObjects.reporting.getRawPdfReportData(url); - const reportFileName = 'dashboard_print'; - const sessionReportPath = await writeSessionReport(reportFileName, reportData); - const percentSimilar = await checkIfPdfsMatch( - sessionReportPath, - getBaselineReportPath(reportFileName), - config.get('screenshots.directory'), - log - ); - // After expected OS differences, the diff count came to be around 128k - expect(percentSimilar).to.be.lessThan(0.05); - }); - - it('matches same baseline report with margins turned on', async function() { - // Generating and then comparing reports can take longer than the default 60s timeout because the comparePngs - // function is taking about 15 seconds per comparison in jenkins. - this.timeout(360000); - - await PageObjects.dashboard.switchToEditMode(); - await PageObjects.dashboard.useMargins(true); + await PageObjects.dashboard.addVisualizations(visualizations); await PageObjects.dashboard.saveDashboard('report test'); await PageObjects.reporting.openPdfReportingPanel(); await PageObjects.reporting.checkUsePrintLayout(); await PageObjects.reporting.clickGenerateReportButton(); - await PageObjects.reporting.clickDownloadReportButton(60000); - PageObjects.reporting.clearToastNotifications(); - - const url = await PageObjects.reporting.getUrlOfTab(1); - const reportData = await PageObjects.reporting.getRawPdfReportData(url); - - await PageObjects.reporting.closeTab(1); - const reportFileName = 'dashboard_print'; - const sessionReportPath = await writeSessionReport(reportFileName, reportData); - const percentSimilar = await checkIfPdfsMatch( - sessionReportPath, - getBaselineReportPath(reportFileName), - config.get('screenshots.directory'), - log - ); - // After expected OS differences, the diff count came to be around 128k - expect(percentSimilar).to.be.lessThan(0.05); - }); - }); - - // TODO Re-enable the tests after removing Phantom: - // https://github.com/elastic/kibana/issues/21485 - describe.skip('Preserve Layout', () => { - it('matches baseline report', async function() { - // Generating and then comparing reports can take longer than the default 60s timeout because the comparePngs - // function is taking about 15 seconds per comparison in jenkins. - this.timeout(360000); - - await PageObjects.reporting.openPdfReportingPanel(); - await PageObjects.reporting.forceSharedItemsContainerSize({ width: 1405 }); - await PageObjects.reporting.clickGenerateReportButton(); - await PageObjects.reporting.removeForceSharedItemsContainerSize(); - - await PageObjects.reporting.clickDownloadReportButton(60000); - PageObjects.reporting.clearToastNotifications(); - const url = await PageObjects.reporting.getUrlOfTab(1); - await PageObjects.reporting.closeTab(1); - const reportData = await PageObjects.reporting.getRawPdfReportData(url); - - const reportFileName = 'dashboard_preserve_layout'; - const sessionReportPath = await writeSessionReport(reportFileName, reportData); + const url = await PageObjects.reporting.getReportURL(60000); + const res = await PageObjects.reporting.getResponse(url); - const percentSimilar = await checkIfPdfsMatch( - sessionReportPath, - getBaselineReportPath(reportFileName), - config.get('screenshots.directory'), - log - ); - expect(percentSimilar).to.be.lessThan(0.05); + expect(res.statusCode).to.equal(200); + expect(res.headers['content-type']).to.equal('application/pdf'); }); }); - // FLAKY: https://github.com/elastic/kibana/issues/43131 - describe.skip('Print PNG button', () => { + describe('Print PNG button', () => { it('is not available if new', async () => { await PageObjects.common.navigateToApp('dashboard'); await PageObjects.dashboard.clickNewDashboard(); @@ -203,45 +125,32 @@ export default function({ getService, getPageObjects }) { }); it('becomes available when saved', async () => { - await PageObjects.dashboard.saveDashboard('mypngdash'); + await PageObjects.dashboard.saveDashboard('My PNG Dash'); await PageObjects.reporting.openPngReportingPanel(); await expectEnabledGenerateReportButton(); }); }); - // TODO Re-enable the tests after removing Phantom: - // https://github.com/elastic/kibana/issues/21485 - describe.skip('Preserve Layout', () => { + describe('Preserve Layout', () => { it('matches baseline report', async function() { - // Generating and then comparing reports can take longer than the default 60s timeout because the comparePngs - // function is taking about 15 seconds per comparison in jenkins. - this.timeout(360000); + this.timeout(300000); await PageObjects.dashboard.switchToEditMode(); await PageObjects.reporting.setTimepickerInDataRange(); - const visualizations = PageObjects.dashboard.getTestVisualizationNames(); - // There is a current issue causing reports with tilemaps to timeout: - // https://github.com/elastic/kibana/issues/14136. Once that is resolved, add the tilemap visualization - // back in! + const visualizations = PageObjects.dashboard.getTestVisualizationNames(); const tileMapIndex = visualizations.indexOf('Visualization TileMap'); visualizations.splice(tileMapIndex, 1); - await PageObjects.dashboard.addVisualizations(visualizations); + await PageObjects.dashboard.addVisualizations(visualizations); await PageObjects.dashboard.saveDashboard('PNG report test'); - await PageObjects.reporting.openPngReportingPanel(); await PageObjects.reporting.forceSharedItemsContainerSize({ width: 1405 }); await PageObjects.reporting.clickGenerateReportButton(); await PageObjects.reporting.removeForceSharedItemsContainerSize(); - await PageObjects.reporting.clickDownloadReportButton(60000); - PageObjects.reporting.clearToastNotifications(); - - const url = await PageObjects.reporting.getUrlOfTab(1); - await PageObjects.reporting.closeTab(1); + const url = await PageObjects.reporting.getReportURL(60000); const reportData = await PageObjects.reporting.getRawPdfReportData(url); - const reportFileName = 'dashboard_preserve_layout'; const sessionReportPath = await writeSessionReport(reportFileName, reportData, 'png'); const percentSimilar = await checkIfPngsMatch( @@ -250,14 +159,14 @@ export default function({ getService, getPageObjects }) { config.get('screenshots.directory'), log ); - expect(percentSimilar).to.be.lessThan(0.05); + + expect(percentSimilar).to.be.lessThan(0.1); }); }); }); describe('Discover', () => { - // FLAKY: https://github.com/elastic/kibana/issues/31379 - describe.skip('Generate CSV button', () => { + describe('Generate CSV button', () => { beforeEach(() => PageObjects.common.navigateToApp('discover')); it('is not available if new', async () => { @@ -307,31 +216,19 @@ export default function({ getService, getPageObjects }) { await expectEnabledGenerateReportButton(); }); - // TODO Re-enable the tests after removing Phantom: - // https://github.com/elastic/kibana/issues/21485 - it.skip('matches baseline report', async function() { + it('matches baseline report', async function() { // Generating and then comparing reports can take longer than the default 60s timeout because the comparePngs // function is taking about 15 seconds per comparison in jenkins. this.timeout(180000); await PageObjects.reporting.openPdfReportingPanel(); await PageObjects.reporting.clickGenerateReportButton(); - await PageObjects.reporting.clickDownloadReportButton(60000); - PageObjects.reporting.clearToastNotifications(); - const url = await PageObjects.reporting.getUrlOfTab(1); - const reportData = await PageObjects.reporting.getRawPdfReportData(url); + const url = await PageObjects.reporting.getReportURL(60000); + const res = await PageObjects.reporting.getResponse(url); - await PageObjects.reporting.closeTab(1); - const reportFileName = 'visualize_print'; - const sessionReportPath = await writeSessionReport(reportFileName, reportData); - const percentSimilar = await checkIfPdfsMatch( - sessionReportPath, - getBaselineReportPath(reportFileName), - config.get('screenshots.directory'), - log - ); - expect(percentSimilar).to.be.lessThan(0.05); + expect(res.statusCode).to.equal(200); + expect(res.headers['content-type']).to.equal('application/pdf'); }); }); }); diff --git a/yarn.lock b/yarn.lock index e7e1a3920fb2ca..587af6ba2e99d9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -114,6 +114,13 @@ dependencies: "@babel/types" "^7.0.0" +"@babel/helper-annotate-as-pure@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.4.tgz#bb3faf1e74b74bd547e867e48f551fa6b098b6ce" + integrity sha512-2BQmQgECKzYKFPpiycoF9tlb5HA4lrVyAmLLVK177EcQAqjVLciUb2/R+n1boQ9y5ENV3uz2ZqiNw7QMBBw1Og== + dependencies: + "@babel/types" "^7.7.4" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" @@ -122,6 +129,14 @@ "@babel/helper-explode-assignable-expression" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-builder-binary-assignment-operator-visitor@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz#5f73f2b28580e224b5b9bd03146a4015d6217f5f" + integrity sha512-Biq/d/WtvfftWZ9Uf39hbPBYDUo986m5Bb4zhkeYDGUllF43D+nUe5M6Vuo6/8JDK/0YX/uBdeoQpyaNhNugZQ== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.7.4" + "@babel/types" "^7.7.4" + "@babel/helper-builder-react-jsx@^7.3.0": version "7.3.0" resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz#a1ac95a5d2b3e88ae5e54846bf462eeb81b318a4" @@ -147,6 +162,15 @@ "@babel/traverse" "^7.4.4" "@babel/types" "^7.4.4" +"@babel/helper-call-delegate@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.7.4.tgz#621b83e596722b50c0066f9dc37d3232e461b801" + integrity sha512-8JH9/B7J7tCYJ2PpWVpw9JhPuEVHztagNVuQAFBVFYluRMlpG7F1CgKEgGeL6KFqcsIa92ZYVj6DSc0XwmN1ZA== + dependencies: + "@babel/helper-hoist-variables" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" + "@babel/helper-create-class-features-plugin@^7.4.4", "@babel/helper-create-class-features-plugin@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4" @@ -171,6 +195,14 @@ "@babel/helper-replace-supers" "^7.7.4" "@babel/helper-split-export-declaration" "^7.7.4" +"@babel/helper-create-regexp-features-plugin@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.4.tgz#6d5762359fd34f4da1500e4cff9955b5299aaf59" + integrity sha512-Mt+jBKaxL0zfOIWrfQpnfYCN7/rS6GKx6CCCfuoqVVd+17R8zNDlzVYmIi9qyb2wOk002NsmSTDymkIygDUH7A== + dependencies: + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.6.0" + "@babel/helper-define-map@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369" @@ -180,6 +212,15 @@ "@babel/types" "^7.5.5" lodash "^4.17.13" +"@babel/helper-define-map@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.7.4.tgz#2841bf92eb8bd9c906851546fe6b9d45e162f176" + integrity sha512-v5LorqOa0nVQUvAUTUF3KPastvUt/HzByXNamKQ6RdJRTV7j8rLL+WB5C/MzzWAwOomxDhYFb1wLLxHqox86lg== + dependencies: + "@babel/helper-function-name" "^7.7.4" + "@babel/types" "^7.7.4" + lodash "^4.17.13" + "@babel/helper-explode-assignable-expression@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" @@ -188,6 +229,14 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-explode-assignable-expression@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.4.tgz#fa700878e008d85dc51ba43e9fb835cddfe05c84" + integrity sha512-2/SicuFrNSXsZNBxe5UGdLr+HZg+raWBLE9vC98bdYOKX/U6PY0mdGlYUJdtTDPSU0Lw0PNbKKDpwYHJLn2jLg== + dependencies: + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" + "@babel/helper-function-name@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" @@ -227,6 +276,13 @@ dependencies: "@babel/types" "^7.4.4" +"@babel/helper-hoist-variables@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.4.tgz#612384e3d823fdfaaf9fce31550fe5d4db0f3d12" + integrity sha512-wQC4xyvc1Jo/FnLirL6CEgPgPCa8M74tOdjWpRhQYapz5JC7u3NYU1zCVoVAGCE3EaIP9T1A3iW0WLJ+reZlpQ== + dependencies: + "@babel/types" "^7.7.4" + "@babel/helper-member-expression-to-functions@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz#1fb5b8ec4453a93c439ee9fe3aeea4a84b76b590" @@ -248,6 +304,13 @@ dependencies: "@babel/types" "^7.0.0" +"@babel/helper-module-imports@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz#e5a92529f8888bf319a6376abfbd1cebc491ad91" + integrity sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ== + dependencies: + "@babel/types" "^7.7.4" + "@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz#f84ff8a09038dcbca1fd4355661a500937165b4a" @@ -260,6 +323,18 @@ "@babel/types" "^7.5.5" lodash "^4.17.13" +"@babel/helper-module-transforms@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.7.4.tgz#8d7cdb1e1f8ea3d8c38b067345924ac4f8e0879a" + integrity sha512-ehGBu4mXrhs0FxAqN8tWkzF8GSIGAiEumu4ONZ/hD9M88uHcD+Yu2ttKfOCgwzoesJOJrtQh7trI5YPbRtMmnA== + dependencies: + "@babel/helper-module-imports" "^7.7.4" + "@babel/helper-simple-access" "^7.7.4" + "@babel/helper-split-export-declaration" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/types" "^7.7.4" + lodash "^4.17.13" + "@babel/helper-optimise-call-expression@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" @@ -297,6 +372,17 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-remap-async-to-generator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.4.tgz#c68c2407350d9af0e061ed6726afb4fff16d0234" + integrity sha512-Sk4xmtVdM9sA/jCI80f+KS+Md+ZHIpjuqmYPk1M7F/upHou5e4ReYmExAiu6PVe65BhJPZA2CY9x9k4BqE5klw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.7.4" + "@babel/helper-wrap-function" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" + "@babel/helper-replace-supers@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz#f84ce43df031222d2bad068d2626cb5799c34bc2" @@ -325,6 +411,14 @@ "@babel/template" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-simple-access@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.7.4.tgz#a169a0adb1b5f418cfc19f22586b2ebf58a9a294" + integrity sha512-zK7THeEXfan7UlWsG2A6CI/L9jVnI5+xxKZOdej39Y0YtDYKx9raHk5F2EtK9K8DHRTihYwg20ADt9S36GR78A== + dependencies: + "@babel/template" "^7.7.4" + "@babel/types" "^7.7.4" + "@babel/helper-split-export-declaration@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" @@ -349,6 +443,16 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.2.0" +"@babel/helper-wrap-function@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.7.4.tgz#37ab7fed5150e22d9d7266e830072c0cdd8baace" + integrity sha512-VsfzZt6wmsocOaVU0OokwrIytHND55yvyT4BPB9AIIgwr8+x7617hetdJTsuGwygN5RC6mxA9EJztTjuwm2ofg== + dependencies: + "@babel/helper-function-name" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" + "@babel/helpers@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" @@ -410,6 +514,15 @@ "@babel/helper-remap-async-to-generator" "^7.1.0" "@babel/plugin-syntax-async-generators" "^7.2.0" +"@babel/plugin-proposal-async-generator-functions@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.4.tgz#0351c5ac0a9e927845fffd5b82af476947b7ce6d" + integrity sha512-1ypyZvGRXriY/QP668+s8sFr2mqinhkRDMPSQLNghCQE+GAkFtp+wkHVvg2+Hdki8gwP+NFzJBJ/N1BfzCCDEw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.7.4" + "@babel/plugin-syntax-async-generators" "^7.7.4" + "@babel/plugin-proposal-class-properties@7.5.5", "@babel/plugin-proposal-class-properties@^7.3.3", "@babel/plugin-proposal-class-properties@^7.5.1", "@babel/plugin-proposal-class-properties@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4" @@ -418,6 +531,14 @@ "@babel/helper-create-class-features-plugin" "^7.5.5" "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-proposal-class-properties@^7.7.0": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.4.tgz#2f964f0cb18b948450362742e33e15211e77c2ba" + integrity sha512-EcuXeV4Hv1X3+Q1TsuOmyyxeTRiSqurGJ26+I/FW1WbymmRRapVORm6x1Zl3iDIHyRxEs+VXWp6qnlcfcJSbbw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-decorators@7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.4.4.tgz#de9b2a1a8ab0196f378e2a82f10b6e2a36f21cc0" @@ -435,6 +556,14 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-dynamic-import" "^7.2.0" +"@babel/plugin-proposal-dynamic-import@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.7.4.tgz#dde64a7f127691758cbfed6cf70de0fa5879d52d" + integrity sha512-StH+nGAdO6qDB1l8sZ5UBV8AC3F2VW2I8Vfld73TMKyptMU9DY5YsJAS8U81+vEtxcH3Y/La0wG0btDrhpnhjQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-dynamic-import" "^7.7.4" + "@babel/plugin-proposal-json-strings@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" @@ -443,6 +572,14 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-json-strings" "^7.2.0" +"@babel/plugin-proposal-json-strings@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.7.4.tgz#7700a6bfda771d8dc81973249eac416c6b4c697d" + integrity sha512-wQvt3akcBTfLU/wYoqm/ws7YOAQKu8EVJEvHip/mzkNtjaclQoCCIqKXFP5/eyfnfbQCDV3OLRIK3mIVyXuZlw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.7.4" + "@babel/plugin-proposal-nullish-coalescing-operator@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.4.4.tgz#41c360d59481d88e0ce3a3f837df10121a769b39" @@ -459,6 +596,14 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" +"@babel/plugin-proposal-object-rest-spread@^7.6.2", "@babel/plugin-proposal-object-rest-spread@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.4.tgz#cc57849894a5c774214178c8ab64f6334ec8af71" + integrity sha512-rnpnZR3/iWKmiQyJ3LKJpSwLDcX/nSXhdLk4Aq/tXOApIvyu7qoabrige0ylsAJffaUC51WiBu209Q0U+86OWQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.7.4" + "@babel/plugin-proposal-optional-catch-binding@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" @@ -467,6 +612,14 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" +"@babel/plugin-proposal-optional-catch-binding@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.7.4.tgz#ec21e8aeb09ec6711bc0a39ca49520abee1de379" + integrity sha512-DyM7U2bnsQerCQ+sejcTNZh8KQEUuC3ufzdnVnSiUv/qoGJp2Z3hanKL18KDhsBT5Wj6a7CMT5mdyCNJsEaA9w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" + "@babel/plugin-proposal-optional-chaining@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.6.0.tgz#e9bf1f9b9ba10c77c033082da75f068389041af8" @@ -484,6 +637,14 @@ "@babel/helper-regex" "^7.4.4" regexpu-core "^4.5.4" +"@babel/plugin-proposal-unicode-property-regex@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.4.tgz#7c239ccaf09470dbe1d453d50057460e84517ebb" + integrity sha512-cHgqHgYvffluZk85dJ02vloErm3Y6xtH+2noOBOJ2kXOJH3aVCDnj5eR/lVNlTnYu4hndAPJD3rTFjW3qee0PA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-async-generators@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" @@ -491,6 +652,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-async-generators@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.7.4.tgz#331aaf310a10c80c44a66b238b6e49132bd3c889" + integrity sha512-Li4+EjSpBgxcsmeEF8IFcfV/+yJGxHXDirDkEoyFjumuwbmfCVHUt0HuowD/iGM7OhIRyXJH9YXxqiH6N815+g== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-decorators@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.2.0.tgz#c50b1b957dcc69e4b1127b65e1c33eef61570c1b" @@ -505,6 +673,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-dynamic-import@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.7.4.tgz#29ca3b4415abfe4a5ec381e903862ad1a54c3aec" + integrity sha512-jHQW0vbRGvwQNgyVxwDh4yuXu4bH1f5/EICJLAhl1SblLs2CDhrsmCk+v5XLdE9wxtAFRyxx+P//Iw+a5L/tTg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-flow@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz#a765f061f803bc48f240c26f8747faf97c26bf7c" @@ -519,6 +694,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-json-strings@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.7.4.tgz#86e63f7d2e22f9e27129ac4e83ea989a382e86cc" + integrity sha512-QpGupahTQW1mHRXddMG5srgpHWqRLwJnJZKXTigB9RPFCCGbDGCgBeM/iC82ICXp414WeYx/tD54w7M2qRqTMg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-jsx@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7" @@ -547,6 +729,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-object-rest-spread@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz#47cf220d19d6d0d7b154304701f468fc1cc6ff46" + integrity sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" @@ -554,6 +743,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-optional-catch-binding@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.7.4.tgz#a3e38f59f4b6233867b4a92dcb0ee05b2c334aa6" + integrity sha512-4ZSuzWgFxqHRE31Glu+fEr/MirNZOMYmD/0BhBWyLyOOQz/gTAl7QmWm2hX1QxEIXsr2vkdlwxIzTyiYRC4xcQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-chaining@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.2.0.tgz#a59d6ae8c167e7608eaa443fda9fa8fa6bf21dff" @@ -561,6 +757,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-top-level-await@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.7.4.tgz#bd7d8fa7b9fee793a36e4027fd6dd1aa32f946da" + integrity sha512-wdsOw0MvkL1UIgiQ/IFr3ETcfv1xb8RMM0H9wbiDyLaJFyiDg5oZvDLCXosIXmFeIlweML5iOBXAkqddkYNizg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-typescript@^7.2.0": version "7.3.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.3.3.tgz#a7cc3f66119a9f7ebe2de5383cce193473d65991" @@ -582,6 +785,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-arrow-functions@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.7.4.tgz#76309bd578addd8aee3b379d809c802305a98a12" + integrity sha512-zUXy3e8jBNPiffmqkHRNDdZM2r8DWhCB7HhcoyZjiK1TxYEluLHAvQuYnTT+ARqRpabWqy/NHkO6e3MsYB5YfA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-async-to-generator@^7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e" @@ -591,6 +801,15 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-remap-async-to-generator" "^7.1.0" +"@babel/plugin-transform-async-to-generator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.4.tgz#694cbeae6d613a34ef0292713fa42fb45c4470ba" + integrity sha512-zpUTZphp5nHokuy8yLlyafxCJ0rSlFoSHypTUWgpdwoDXWQcseaect7cJ8Ppk6nunOM6+5rPMkod4OYKPR5MUg== + dependencies: + "@babel/helper-module-imports" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.7.4" + "@babel/plugin-transform-block-scoped-functions@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" @@ -598,6 +817,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-block-scoped-functions@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.7.4.tgz#d0d9d5c269c78eaea76227ace214b8d01e4d837b" + integrity sha512-kqtQzwtKcpPclHYjLK//3lH8OFsCDuDJBaFhVwf8kqdnF6MN4l618UDlcA7TfRs3FayrHj+svYnSX8MC9zmUyQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-block-scoping@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce" @@ -614,6 +840,14 @@ "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.13" +"@babel/plugin-transform-block-scoping@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.7.4.tgz#200aad0dcd6bb80372f94d9e628ea062c58bf224" + integrity sha512-2VBe9u0G+fDt9B5OV5DQH4KBf5DoiNkwFKOz0TCvBWvdAN2rOykCTkrL+jTLxfCAm76l9Qo5OqL7HBOx2dWggg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + lodash "^4.17.13" + "@babel/plugin-transform-classes@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9" @@ -628,6 +862,20 @@ "@babel/helper-split-export-declaration" "^7.4.4" globals "^11.1.0" +"@babel/plugin-transform-classes@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.4.tgz#c92c14be0a1399e15df72667067a8f510c9400ec" + integrity sha512-sK1mjWat7K+buWRuImEzjNf68qrKcrddtpQo3swi9j7dUcG6y6R6+Di039QN2bD1dykeswlagupEmpOatFHHUg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.7.4" + "@babel/helper-define-map" "^7.7.4" + "@babel/helper-function-name" "^7.7.4" + "@babel/helper-optimise-call-expression" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.7.4" + "@babel/helper-split-export-declaration" "^7.7.4" + globals "^11.1.0" + "@babel/plugin-transform-computed-properties@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" @@ -635,6 +883,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-computed-properties@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.7.4.tgz#e856c1628d3238ffe12d668eb42559f79a81910d" + integrity sha512-bSNsOsZnlpLLyQew35rl4Fma3yKWqK3ImWMSC/Nc+6nGjC9s5NFWAer1YQ899/6s9HxO2zQC1WoFNfkOqRkqRQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-destructuring@7.5.0", "@babel/plugin-transform-destructuring@^7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a" @@ -649,6 +904,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-destructuring@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.7.4.tgz#2b713729e5054a1135097b6a67da1b6fe8789267" + integrity sha512-4jFMXI1Cu2aXbcXXl8Lr6YubCn6Oc7k9lLsu8v61TZh+1jny2BWmdtvY9zSUlLdGUvcy9DMAWyZEOqjsbeg/wA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3" @@ -658,6 +920,14 @@ "@babel/helper-regex" "^7.4.4" regexpu-core "^4.5.4" +"@babel/plugin-transform-dotall-regex@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.4.tgz#f7ccda61118c5b7a2599a72d5e3210884a021e96" + integrity sha512-mk0cH1zyMa/XHeb6LOTXTbG7uIJ8Rrjlzu91pUx/KS3JpcgaTDwMS8kM+ar8SLOvlL2Lofi4CGBAjCo3a2x+lw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-duplicate-keys@^7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz#c5dbf5106bf84cdf691222c0974c12b1df931853" @@ -665,6 +935,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-duplicate-keys@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.7.4.tgz#3d21731a42e3f598a73835299dd0169c3b90ac91" + integrity sha512-g1y4/G6xGWMD85Tlft5XedGaZBCIVN+/P0bs6eabmcPP9egFleMAo65OOjlhcz1njpwagyY3t0nsQC9oTFegJA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-exponentiation-operator@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" @@ -673,6 +950,14 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-exponentiation-operator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.7.4.tgz#dd30c0191e3a1ba19bcc7e389bdfddc0729d5db9" + integrity sha512-MCqiLfCKm6KEA1dglf6Uqq1ElDIZwFuzz1WH5mTf8k2uQSxEJMbOIEh7IZv7uichr7PMfi5YVSrr1vz+ipp7AQ== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-flow-strip-types@7.4.4", "@babel/plugin-transform-flow-strip-types@^7.0.0": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.4.tgz#d267a081f49a8705fc9146de0768c6b58dccd8f7" @@ -688,6 +973,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-for-of@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.7.4.tgz#248800e3a5e507b1f103d8b4ca998e77c63932bc" + integrity sha512-zZ1fD1B8keYtEcKF+M1TROfeHTKnijcVQm0yO/Yu1f7qoDoxEIc/+GX6Go430Bg84eM/xwPFp0+h4EbZg7epAA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-function-name@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad" @@ -696,6 +988,14 @@ "@babel/helper-function-name" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-function-name@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.4.tgz#75a6d3303d50db638ff8b5385d12451c865025b1" + integrity sha512-E/x09TvjHNhsULs2IusN+aJNRV5zKwxu1cpirZyRPw+FyyIKEHPXTsadj48bVpc1R5Qq1B5ZkzumuFLytnbT6g== + dependencies: + "@babel/helper-function-name" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-literals@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" @@ -703,6 +1003,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-literals@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.7.4.tgz#27fe87d2b5017a2a5a34d1c41a6b9f6a6262643e" + integrity sha512-X2MSV7LfJFm4aZfxd0yLVFrEXAgPqYoDG53Br/tCKiKYfX0MjVjQeWPIhPHHsCqzwQANq+FLN786fF5rgLS+gw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-member-expression-literals@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d" @@ -710,6 +1017,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-member-expression-literals@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.7.4.tgz#aee127f2f3339fc34ce5e3055d7ffbf7aa26f19a" + integrity sha512-9VMwMO7i69LHTesL0RdGy93JU6a+qOPuvB4F4d0kR0zyVjJRVJRaoaGjhtki6SzQUu8yen/vxPKN6CWnCUw6bA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-modules-amd@^7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz#ef00435d46da0a5961aa728a1d2ecff063e4fb91" @@ -719,6 +1033,15 @@ "@babel/helper-plugin-utils" "^7.0.0" babel-plugin-dynamic-import-node "^2.3.0" +"@babel/plugin-transform-modules-amd@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.4.tgz#276b3845ca2b228f2995e453adc2e6f54d72fb71" + integrity sha512-/542/5LNA18YDtg1F+QHvvUSlxdvjZoD/aldQwkq+E3WCkbEjNSN9zdrOXaSlfg3IfGi22ijzecklF/A7kVZFQ== + dependencies: + "@babel/helper-module-transforms" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + babel-plugin-dynamic-import-node "^2.3.0" + "@babel/plugin-transform-modules-commonjs@^7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74" @@ -739,6 +1062,16 @@ "@babel/helper-simple-access" "^7.1.0" babel-plugin-dynamic-import-node "^2.3.0" +"@babel/plugin-transform-modules-commonjs@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.4.tgz#bee4386e550446343dd52a571eda47851ff857a3" + integrity sha512-k8iVS7Jhc367IcNF53KCwIXtKAH7czev866ThsTgy8CwlXjnKZna2VHwChglzLleYrcHz1eQEIJlGRQxB53nqA== + dependencies: + "@babel/helper-module-transforms" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-simple-access" "^7.7.4" + babel-plugin-dynamic-import-node "^2.3.0" + "@babel/plugin-transform-modules-systemjs@^7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249" @@ -748,6 +1081,15 @@ "@babel/helper-plugin-utils" "^7.0.0" babel-plugin-dynamic-import-node "^2.3.0" +"@babel/plugin-transform-modules-systemjs@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.4.tgz#cd98152339d3e763dfe838b7d4273edaf520bb30" + integrity sha512-y2c96hmcsUi6LrMqvmNDPBBiGCiQu0aYqpHatVVu6kD4mFEXKjyNxd/drc18XXAf9dv7UXjrZwBVmTTGaGP8iw== + dependencies: + "@babel/helper-hoist-variables" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + babel-plugin-dynamic-import-node "^2.3.0" + "@babel/plugin-transform-modules-umd@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" @@ -756,6 +1098,14 @@ "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-modules-umd@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.4.tgz#1027c355a118de0aae9fee00ad7813c584d9061f" + integrity sha512-u2B8TIi0qZI4j8q4C51ktfO7E3cQ0qnaXFI1/OXITordD40tt17g/sXqgNNCcMTcBFKrUPcGDx+TBJuZxLx7tw== + dependencies: + "@babel/helper-module-transforms" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-named-capturing-groups-regex@^7.4.5": version "7.4.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106" @@ -770,6 +1120,13 @@ dependencies: regexp-tree "^0.1.13" +"@babel/plugin-transform-named-capturing-groups-regex@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.4.tgz#fb3bcc4ee4198e7385805007373d6b6f42c98220" + integrity sha512-jBUkiqLKvUWpv9GLSuHUFYdmHg0ujC1JEYoZUfeOOfNydZXp1sXObgyPatpcwjWgsdBGsagWW0cdJpX/DO2jMw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.7.4" + "@babel/plugin-transform-new-target@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5" @@ -777,6 +1134,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-new-target@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.7.4.tgz#4a0753d2d60639437be07b592a9e58ee00720167" + integrity sha512-CnPRiNtOG1vRodnsyGX37bHQleHE14B9dnnlgSeEs3ek3fHN1A1SScglTCg1sfbe7sRQ2BUcpgpTpWSfMKz3gg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-object-super@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9" @@ -785,6 +1149,14 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-replace-supers" "^7.5.5" +"@babel/plugin-transform-object-super@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.7.4.tgz#48488937a2d586c0148451bf51af9d7dda567262" + integrity sha512-ho+dAEhC2aRnff2JCA0SAK7V2R62zJd/7dmtoe7MHcso4C2mS+vZjn1Pb1pCVZvJs1mgsvv5+7sT+m3Bysb6eg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.7.4" + "@babel/plugin-transform-parameters@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16" @@ -794,6 +1166,15 @@ "@babel/helper-get-function-arity" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-parameters@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz#da4555c97f39b51ac089d31c7380f03bca4075ce" + integrity sha512-VJwhVePWPa0DqE9vcfptaJSzNDKrWU/4FbYCjZERtmqEs05g3UMXnYMZoXja7JAJ7Y7sPZipwm/pGApZt7wHlw== + dependencies: + "@babel/helper-call-delegate" "^7.7.4" + "@babel/helper-get-function-arity" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-property-literals@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905" @@ -801,6 +1182,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-property-literals@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.7.4.tgz#2388d6505ef89b266103f450f9167e6bd73f98c2" + integrity sha512-MatJhlC4iHsIskWYyawl53KuHrt+kALSADLQQ/HkhTjX954fkxIEh4q5slL4oRAnsm/eDoZ4q0CIZpcqBuxhJQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-react-constant-elements@^7.0.0", "@babel/plugin-transform-react-constant-elements@^7.2.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.5.0.tgz#4d6ae4033bc38f8a65dfca2b6235c44522a422fc" @@ -809,6 +1197,14 @@ "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-react-constant-elements@^7.6.3": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.7.4.tgz#499cf732a21ffd62cc4b0016e27c3906097f8982" + integrity sha512-U6XkHZ8RnmeEb8jBUOpeo6oFka5RhLgxAVvK4/fBbwoYlsHQYLb8I37ymTPDVsrWjqb94+hueuWQA/1OAA4rAQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-react-display-name@7.2.0", "@babel/plugin-transform-react-display-name@^7.0.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz#ebfaed87834ce8dc4279609a4f0c324c156e3eb0" @@ -880,6 +1276,13 @@ dependencies: regenerator-transform "^0.14.0" +"@babel/plugin-transform-regenerator@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.4.tgz#d18eac0312a70152d7d914cbed2dc3999601cfc0" + integrity sha512-e7MWl5UJvmPEwFJTwkBlPmqixCtr9yAASBqff4ggXTNicZiwbF8Eefzm6NVgfiBp7JdAGItecnctKTgH44q2Jw== + dependencies: + regenerator-transform "^0.14.0" + "@babel/plugin-transform-reserved-words@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz#4792af87c998a49367597d07fedf02636d2e1634" @@ -887,6 +1290,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-reserved-words@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.7.4.tgz#6a7cf123ad175bb5c69aec8f6f0770387ed3f1eb" + integrity sha512-OrPiUB5s5XvkCO1lS7D8ZtHcswIC57j62acAnJZKqGGnHP+TIc/ljQSrgdX/QyOTdEK5COAhuc820Hi1q2UgLQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-runtime@7.5.5", "@babel/plugin-transform-runtime@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" @@ -904,6 +1314,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-shorthand-properties@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.7.4.tgz#74a0a9b2f6d67a684c6fbfd5f0458eb7ba99891e" + integrity sha512-q+suddWRfIcnyG5YiDP58sT65AJDZSUhXQDZE3r04AuqD6d/XLaQPPXSBzP2zGerkgBivqtQm9XKGLuHqBID6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-spread@^7.2.0": version "7.2.2" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" @@ -911,6 +1328,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-spread@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.7.4.tgz#aa673b356fe6b7e70d69b6e33a17fef641008578" + integrity sha512-8OSs0FLe5/80cndziPlg4R0K6HcWSM0zyNhHhLsmw/Nc5MaA49cAsnoJ/t/YZf8qkG7fD+UjTRaApVDB526d7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-sticky-regex@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" @@ -919,6 +1343,14 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" +"@babel/plugin-transform-sticky-regex@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.7.4.tgz#ffb68c05090c30732076b1285dc1401b404a123c" + integrity sha512-Ls2NASyL6qtVe1H1hXts9yuEeONV2TJZmplLONkMPUG158CtmnrzW5Q5teibM5UVOFjG0D3IC5mzXR6pPpUY7A== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + "@babel/plugin-transform-template-literals@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0" @@ -927,6 +1359,14 @@ "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-template-literals@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.7.4.tgz#1eb6411736dd3fe87dbd20cc6668e5121c17d604" + integrity sha512-sA+KxLwF3QwGj5abMHkHgshp9+rRz+oY9uoRil4CyLtgEuE/88dpkeWgNk5qKVsJE9iSfly3nvHapdRiIS2wnQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-typeof-symbol@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" @@ -934,6 +1374,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-typeof-symbol@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.7.4.tgz#3174626214f2d6de322882e498a38e8371b2140e" + integrity sha512-KQPUQ/7mqe2m0B8VecdyaW5XcQYaePyl9R7IsKd+irzj6jvbhoGnRE+M0aNkyAzI07VfUQ9266L5xMARitV3wg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-typescript@^7.3.2": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz#6d862766f09b2da1cb1f7d505fe2aedab6b7d4b8" @@ -961,6 +1408,14 @@ "@babel/helper-regex" "^7.4.4" regexpu-core "^4.5.4" +"@babel/plugin-transform-unicode-regex@^7.7.4": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.4.tgz#a3c0f65b117c4c81c5b6484f2a5e7b95346b83ae" + integrity sha512-N77UUIV+WCvE+5yHw+oks3m18/umd7y392Zv7mYTpFqHtkpcc+QUz+gLJNTWVlWROIWeLqY0f3OjZxV5TcXnRw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/preset-env@7.5.5", "@babel/preset-env@^7.4.3", "@babel/preset-env@^7.4.5", "@babel/preset-env@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.5.tgz#bc470b53acaa48df4b8db24a570d6da1fef53c9a" @@ -1073,6 +1528,63 @@ js-levenshtein "^1.1.3" semver "^5.5.0" +"@babel/preset-env@^7.7.1": + version "7.7.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.7.4.tgz#ccaf309ae8d1ee2409c85a4e2b5e280ceee830f8" + integrity sha512-Dg+ciGJjwvC1NIe/DGblMbcGq1HOtKbw8RLl4nIjlfcILKEOkWT/vRqPpumswABEBVudii6dnVwrBtzD7ibm4g== + dependencies: + "@babel/helper-module-imports" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-async-generator-functions" "^7.7.4" + "@babel/plugin-proposal-dynamic-import" "^7.7.4" + "@babel/plugin-proposal-json-strings" "^7.7.4" + "@babel/plugin-proposal-object-rest-spread" "^7.7.4" + "@babel/plugin-proposal-optional-catch-binding" "^7.7.4" + "@babel/plugin-proposal-unicode-property-regex" "^7.7.4" + "@babel/plugin-syntax-async-generators" "^7.7.4" + "@babel/plugin-syntax-dynamic-import" "^7.7.4" + "@babel/plugin-syntax-json-strings" "^7.7.4" + "@babel/plugin-syntax-object-rest-spread" "^7.7.4" + "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" + "@babel/plugin-syntax-top-level-await" "^7.7.4" + "@babel/plugin-transform-arrow-functions" "^7.7.4" + "@babel/plugin-transform-async-to-generator" "^7.7.4" + "@babel/plugin-transform-block-scoped-functions" "^7.7.4" + "@babel/plugin-transform-block-scoping" "^7.7.4" + "@babel/plugin-transform-classes" "^7.7.4" + "@babel/plugin-transform-computed-properties" "^7.7.4" + "@babel/plugin-transform-destructuring" "^7.7.4" + "@babel/plugin-transform-dotall-regex" "^7.7.4" + "@babel/plugin-transform-duplicate-keys" "^7.7.4" + "@babel/plugin-transform-exponentiation-operator" "^7.7.4" + "@babel/plugin-transform-for-of" "^7.7.4" + "@babel/plugin-transform-function-name" "^7.7.4" + "@babel/plugin-transform-literals" "^7.7.4" + "@babel/plugin-transform-member-expression-literals" "^7.7.4" + "@babel/plugin-transform-modules-amd" "^7.7.4" + "@babel/plugin-transform-modules-commonjs" "^7.7.4" + "@babel/plugin-transform-modules-systemjs" "^7.7.4" + "@babel/plugin-transform-modules-umd" "^7.7.4" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.7.4" + "@babel/plugin-transform-new-target" "^7.7.4" + "@babel/plugin-transform-object-super" "^7.7.4" + "@babel/plugin-transform-parameters" "^7.7.4" + "@babel/plugin-transform-property-literals" "^7.7.4" + "@babel/plugin-transform-regenerator" "^7.7.4" + "@babel/plugin-transform-reserved-words" "^7.7.4" + "@babel/plugin-transform-shorthand-properties" "^7.7.4" + "@babel/plugin-transform-spread" "^7.7.4" + "@babel/plugin-transform-sticky-regex" "^7.7.4" + "@babel/plugin-transform-template-literals" "^7.7.4" + "@babel/plugin-transform-typeof-symbol" "^7.7.4" + "@babel/plugin-transform-unicode-regex" "^7.7.4" + "@babel/types" "^7.7.4" + browserslist "^4.6.0" + core-js-compat "^3.1.1" + invariant "^2.2.2" + js-levenshtein "^1.1.3" + semver "^5.5.0" + "@babel/preset-flow@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.0.0.tgz#afd764835d9535ec63d8c7d4caf1c06457263da2" @@ -1092,7 +1604,7 @@ "@babel/plugin-transform-react-jsx-self" "^7.0.0" "@babel/plugin-transform-react-jsx-source" "^7.0.0" -"@babel/preset-react@^7.7.4": +"@babel/preset-react@^7.7.0", "@babel/preset-react@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.7.4.tgz#3fe2ea698d8fb536d8e7881a592c3c1ee8bf5707" integrity sha512-j+vZtg0/8pQr1H8wKoaJyGL2IEk3rG/GIvua7Sec7meXVIvGycihlGMx5xcU00kqCJbwzHs18xTu3YfREOqQ+g== @@ -1175,6 +1687,13 @@ dependencies: regenerator-runtime "^0.13.2" +"@babel/runtime@^7.7.4": + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.7.tgz#194769ca8d6d7790ec23605af9ee3e42a0aa79cf" + integrity sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA== + dependencies: + regenerator-runtime "^0.13.2" + "@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237" @@ -2622,6 +3141,26 @@ react-inspector "^3.0.2" uuid "^3.3.2" +"@storybook/addon-actions@^5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-5.2.8.tgz#f63c6e1afb59e94ca1ebc776b7cad9b815e7419e" + integrity sha512-hadk+UaU6upOW0g447RfLRrnXRgE2rjRVk5sT8mVxBMj032NnwUd7ie/BZwy1yg5B8oFtpkgQYwqhPtoO2xBaQ== + dependencies: + "@storybook/addons" "5.2.8" + "@storybook/api" "5.2.8" + "@storybook/client-api" "5.2.8" + "@storybook/components" "5.2.8" + "@storybook/core-events" "5.2.8" + "@storybook/theming" "5.2.8" + core-js "^3.0.1" + fast-deep-equal "^2.0.1" + global "^4.3.2" + polished "^3.3.1" + prop-types "^15.7.2" + react "^16.8.3" + react-inspector "^3.0.2" + uuid "^3.3.2" + "@storybook/addon-console@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@storybook/addon-console/-/addon-console-1.2.1.tgz#f338401661b4636118b13839848061e996d4e104" @@ -2629,15 +3168,15 @@ dependencies: global "^4.3.2" -"@storybook/addon-info@^5.2.6": - version "5.2.6" - resolved "https://registry.yarnpkg.com/@storybook/addon-info/-/addon-info-5.2.6.tgz#25c8405ded9e20b1bf3b607d235601b087a73a5f" - integrity sha512-2ct91Zf14Be5HZ77szPpJK4Fvy4D/haQtziCfv9UKZXaBm7Rz9vKPuM3uCcfMywh1eMunhhluhJ/3bxmttHXAw== +"@storybook/addon-info@^5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-info/-/addon-info-5.2.8.tgz#bf29741c21c16c85f4a7007606e8afa3eb77965c" + integrity sha512-iY8malDF6yayLfpiffMwDXOWeeoXdRbxse1f+kNHK4aVEUXLyh+uiogPhO8dzVDy8dQw1LP9C7xKZe2Dls59kw== dependencies: - "@storybook/addons" "5.2.6" - "@storybook/client-logger" "5.2.6" - "@storybook/components" "5.2.6" - "@storybook/theming" "5.2.6" + "@storybook/addons" "5.2.8" + "@storybook/client-logger" "5.2.8" + "@storybook/components" "5.2.8" + "@storybook/theming" "5.2.8" core-js "^3.0.1" global "^4.3.2" jsx-to-string "^1.4.0" @@ -2675,6 +3214,39 @@ react-lifecycles-compat "^3.0.4" react-select "^3.0.0" +"@storybook/addon-knobs@^5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-knobs/-/addon-knobs-5.2.8.tgz#e0d03823969921a0da57a329376d03066dd749ee" + integrity sha512-5SAMJj+0pbhCiyNkKjkUxEbM9L/wrOE4HTvM7gvm902fULuKZklb3wV8iiUNRfIPCs6VhmmIhPzXICGjhW5xIg== + dependencies: + "@storybook/addons" "5.2.8" + "@storybook/api" "5.2.8" + "@storybook/client-api" "5.2.8" + "@storybook/components" "5.2.8" + "@storybook/core-events" "5.2.8" + "@storybook/theming" "5.2.8" + "@types/react-color" "^3.0.1" + copy-to-clipboard "^3.0.8" + core-js "^3.0.1" + escape-html "^1.0.3" + fast-deep-equal "^2.0.1" + global "^4.3.2" + lodash "^4.17.15" + prop-types "^15.7.2" + qs "^6.6.0" + react-color "^2.17.0" + react-lifecycles-compat "^3.0.4" + react-select "^3.0.0" + +"@storybook/addon-options@^5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-options/-/addon-options-5.2.8.tgz#579c7e1f331303382541fa77c1c26242d7d6b79d" + integrity sha512-w7b6c+K5kv6AnQW1tnGSuNEQ8Ek2kFZ4anTaMYiGpoa1nQJjDrvS6R13GWHgxGACFpOtcBPMxTEX6YKAxiOgaA== + dependencies: + "@storybook/addons" "5.2.8" + core-js "^3.0.1" + util-deprecate "^1.0.2" + "@storybook/addon-storyshots@^5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/addon-storyshots/-/addon-storyshots-5.2.6.tgz#cc94f256cb28e2769a3dd472af420f8e0fcc306f" @@ -2690,6 +3262,21 @@ regenerator-runtime "^0.12.1" ts-dedent "^1.1.0" +"@storybook/addon-storyshots@^5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-storyshots/-/addon-storyshots-5.2.8.tgz#1878d0cc7490941cc4006bd3bd96bfd06005e1e3" + integrity sha512-izUQTwzt1I0TdtYn3jv6yFIaW7H48gPW+nehisVXOA+0b0f+IySnC63+q3YcCQcC9cmZ5xxzZNJ1XycrsyVm0A== + dependencies: + "@jest/transform" "^24.9.0" + "@storybook/addons" "5.2.8" + core-js "^3.0.1" + glob "^7.1.3" + global "^4.3.2" + jest-specific-snapshot "^2.0.0" + read-pkg-up "^6.0.0" + regenerator-runtime "^0.12.1" + ts-dedent "^1.1.0" + "@storybook/addons@5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.2.6.tgz#c1278137acb3502e068b0b0d07a8371c607e9c02" @@ -2703,6 +3290,19 @@ global "^4.3.2" util-deprecate "^1.0.2" +"@storybook/addons@5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.2.8.tgz#f8bf8bd555b7a69fb1e9a52ab8cdb96384d931ff" + integrity sha512-yAo1N5z/45bNIQP8SD+HVTr7X898bYAtz1EZBrQ6zD8bGamzA2Br06rOLL9xXw29eQhsaVnPlqgDwCS1sTC7aQ== + dependencies: + "@storybook/api" "5.2.8" + "@storybook/channels" "5.2.8" + "@storybook/client-logger" "5.2.8" + "@storybook/core-events" "5.2.8" + core-js "^3.0.1" + global "^4.3.2" + util-deprecate "^1.0.2" + "@storybook/api@5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.2.6.tgz#43d3c20b90e585e6c94b36e29845d39704ae2135" @@ -2726,6 +3326,29 @@ telejson "^3.0.2" util-deprecate "^1.0.2" +"@storybook/api@5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.2.8.tgz#21f03df8041114eb929bd10b570a17f266568b7f" + integrity sha512-rFrPtTFDIPQoicLwq1AVsOvZNTUKnjD1w/NX1kKcyuWLL9BcOkU3YNLBlliGBg2JX/yS+fJKMyKk4NMzNBCZCg== + dependencies: + "@storybook/channels" "5.2.8" + "@storybook/client-logger" "5.2.8" + "@storybook/core-events" "5.2.8" + "@storybook/router" "5.2.8" + "@storybook/theming" "5.2.8" + core-js "^3.0.1" + fast-deep-equal "^2.0.1" + global "^4.3.2" + lodash "^4.17.15" + memoizerific "^1.11.3" + prop-types "^15.6.2" + react "^16.8.3" + semver "^6.0.0" + shallow-equal "^1.1.0" + store2 "^2.7.1" + telejson "^3.0.2" + util-deprecate "^1.0.2" + "@storybook/channel-postmessage@5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.2.6.tgz#60aaef0e80300c9812a571ca3ce0f28e2c404f04" @@ -2737,6 +3360,17 @@ global "^4.3.2" telejson "^3.0.2" +"@storybook/channel-postmessage@5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.2.8.tgz#7a84869ce0fc270c3b5dcd7fa4ed798b6055816f" + integrity sha512-RS3iDW1kpfODN+kBq3youn+KtLqHslZ4m7mTlOL80BUHKb4YkrA1lVkzpy1kVMWBU523pyDVQUVXr+M8y3iVug== + dependencies: + "@storybook/channels" "5.2.8" + "@storybook/client-logger" "5.2.8" + core-js "^3.0.1" + global "^4.3.2" + telejson "^3.0.2" + "@storybook/channels@5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.2.6.tgz#e2837508864dc4d5b5e03f078886f0ce113762ea" @@ -2744,6 +3378,13 @@ dependencies: core-js "^3.0.1" +"@storybook/channels@5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.2.8.tgz#79a99ad85dcacb688073c22340c5b7d16b801202" + integrity sha512-mFwQec27QSrqcl+IH0xA+4jfoEqC4m1G99LBHt/aTDjLZXclX1A470WqeZCp7Gx4OALpaPEVTaaaKPbiKz4C6w== + dependencies: + core-js "^3.0.1" + "@storybook/client-api@5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.2.6.tgz#5760cb4302d82ce9210a63f3f55b1e05f04759c1" @@ -2765,6 +3406,28 @@ qs "^6.6.0" util-deprecate "^1.0.2" +"@storybook/client-api@5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.2.8.tgz#1de791f7888442287f848e5f544eb883c5edc0da" + integrity sha512-OCKhZ+2sS3ot0ZV48nD79BWVzvvdMjUFYl0073ps5q+1+TLic1AlNmH0Sb5/9NrYXNV86v3VrM2jUbGsKe1qyw== + dependencies: + "@storybook/addons" "5.2.8" + "@storybook/channel-postmessage" "5.2.8" + "@storybook/channels" "5.2.8" + "@storybook/client-logger" "5.2.8" + "@storybook/core-events" "5.2.8" + "@storybook/router" "5.2.8" + common-tags "^1.8.0" + core-js "^3.0.1" + eventemitter3 "^4.0.0" + global "^4.3.2" + is-plain-object "^3.0.0" + lodash "^4.17.15" + memoizerific "^1.11.3" + qs "^6.6.0" + stable "^0.1.8" + util-deprecate "^1.0.2" + "@storybook/client-logger@5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.2.6.tgz#cfc4536e9b724b086f7509c2bb34c221016713c9" @@ -2772,6 +3435,13 @@ dependencies: core-js "^3.0.1" +"@storybook/client-logger@5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.2.8.tgz#5affe2f9dbbee374721fd2e8729116f5ac39c779" + integrity sha512-+oVSEJdeh7TQ1Bhanb3mCr7fc3Bug3+K79abZ28J45Ub5x4L/ZVClj1xMgUsJs30BZ5FB8vhdgH6TQb0NSxR4A== + dependencies: + core-js "^3.0.1" + "@storybook/components@5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.2.6.tgz#cddb60227720aea7cae34fe782d0370bcdbd4005" @@ -2797,6 +3467,31 @@ react-textarea-autosize "^7.1.0" simplebar-react "^1.0.0-alpha.6" +"@storybook/components@5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.2.8.tgz#f5d4a06ba4ba8c700b2d962deae182105b72fb99" + integrity sha512-h9l/LAMaj+emUCOyY/+ETy/S3P0npwQU280J88uL4O9XJALJ72EKfyttBCvMLvpM50E+fAPeDzuYn0t5qzGGxg== + dependencies: + "@storybook/client-logger" "5.2.8" + "@storybook/theming" "5.2.8" + "@types/react-syntax-highlighter" "10.1.0" + "@types/react-textarea-autosize" "^4.3.3" + core-js "^3.0.1" + global "^4.3.2" + markdown-to-jsx "^6.9.1" + memoizerific "^1.11.3" + polished "^3.3.1" + popper.js "^1.14.7" + prop-types "^15.7.2" + react "^16.8.3" + react-dom "^16.8.3" + react-focus-lock "^1.18.3" + react-helmet-async "^1.0.2" + react-popper-tooltip "^2.8.3" + react-syntax-highlighter "^8.0.1" + react-textarea-autosize "^7.1.0" + simplebar-react "^1.0.0-alpha.6" + "@storybook/core-events@5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.2.6.tgz#34c9aae256e7e5f4a565b81f1e77dda8bccc6752" @@ -2804,6 +3499,13 @@ dependencies: core-js "^3.0.1" +"@storybook/core-events@5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.2.8.tgz#93fc458ea0820ff1409d268b0fe51abba200f5a4" + integrity sha512-NkQKC5doO/YL9gsO61bqaxgveKktkiJWZ3XyyhL1ZebgnO9wTlrU+i9b5aX73Myk1oxbicQw9KcwDGYk0qFuNQ== + dependencies: + core-js "^3.0.1" + "@storybook/core@5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/core/-/core-5.2.6.tgz#60c092607158d7d28db59f7e67da4f7e12703fb2" @@ -2878,6 +3580,80 @@ webpack-dev-middleware "^3.7.0" webpack-hot-middleware "^2.25.0" +"@storybook/core@5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/core/-/core-5.2.8.tgz#3f6ddbacc705c1893deb15582c3a0a1ecd882cd1" + integrity sha512-P1Xx4setLBESPgS5KgL7Jskf5Q6fRa3ApwPt+ocjDoSDGCvsV7cUEpAp09U65u+89e5K4nQxvaZouhknFQBc1A== + dependencies: + "@babel/plugin-proposal-class-properties" "^7.7.0" + "@babel/plugin-proposal-object-rest-spread" "^7.6.2" + "@babel/plugin-syntax-dynamic-import" "^7.2.0" + "@babel/plugin-transform-react-constant-elements" "^7.6.3" + "@babel/preset-env" "^7.7.1" + "@storybook/addons" "5.2.8" + "@storybook/channel-postmessage" "5.2.8" + "@storybook/client-api" "5.2.8" + "@storybook/client-logger" "5.2.8" + "@storybook/core-events" "5.2.8" + "@storybook/node-logger" "5.2.8" + "@storybook/router" "5.2.8" + "@storybook/theming" "5.2.8" + "@storybook/ui" "5.2.8" + airbnb-js-shims "^1 || ^2" + ansi-to-html "^0.6.11" + autoprefixer "^9.4.9" + babel-plugin-add-react-displayname "^0.0.5" + babel-plugin-emotion "^10.0.14" + babel-plugin-macros "^2.4.5" + babel-preset-minify "^0.5.0 || 0.6.0-alpha.5" + boxen "^3.0.0" + case-sensitive-paths-webpack-plugin "^2.2.0" + chalk "^2.4.2" + cli-table3 "0.5.1" + commander "^2.19.0" + common-tags "^1.8.0" + core-js "^3.0.1" + corejs-upgrade-webpack-plugin "^2.2.0" + css-loader "^3.0.0" + detect-port "^1.3.0" + dotenv-webpack "^1.7.0" + ejs "^2.6.1" + express "^4.17.0" + file-loader "^3.0.1" + file-system-cache "^1.0.5" + find-cache-dir "^3.0.0" + fs-extra "^8.0.1" + global "^4.3.2" + html-webpack-plugin "^4.0.0-beta.2" + inquirer "^6.2.0" + interpret "^1.2.0" + ip "^1.1.5" + json5 "^2.1.0" + lazy-universal-dotenv "^3.0.1" + node-fetch "^2.6.0" + open "^6.1.0" + pnp-webpack-plugin "1.4.3" + postcss-flexbugs-fixes "^4.1.0" + postcss-loader "^3.0.0" + pretty-hrtime "^1.0.3" + qs "^6.6.0" + raw-loader "^2.0.0" + react-dev-utils "^9.0.0" + regenerator-runtime "^0.12.1" + resolve "^1.11.0" + resolve-from "^5.0.0" + semver "^6.0.0" + serve-favicon "^2.5.0" + shelljs "^0.8.3" + style-loader "^0.23.1" + terser-webpack-plugin "^1.2.4" + unfetch "^4.1.0" + url-loader "^2.0.1" + util-deprecate "^1.0.2" + webpack "^4.33.0" + webpack-dev-middleware "^3.7.0" + webpack-hot-middleware "^2.25.0" + "@storybook/node-logger@5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-5.2.6.tgz#e353aff14375bef9e922c217a0afb50f93e2ceb1" @@ -2889,6 +3665,17 @@ pretty-hrtime "^1.0.3" regenerator-runtime "^0.12.1" +"@storybook/node-logger@5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-5.2.8.tgz#4a3df21d731014d54b9ca53d5b9a72dd350bb075" + integrity sha512-3TK5mx6VWbfJO+WUrqwPhTbTQ4qESTnwJY/02xPzOhvuC6tIG1QOxzi+Rq6rFlwxTpUuWh6iyDYnGIqFFQywkA== + dependencies: + chalk "^2.4.2" + core-js "^3.0.1" + npmlog "^4.1.2" + pretty-hrtime "^1.0.3" + regenerator-runtime "^0.12.1" + "@storybook/react@^5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/react/-/react-5.2.6.tgz#e61c0ed184add9e715191649ddb995eead756a90" @@ -2917,10 +3704,51 @@ semver "^6.0.0" webpack "^4.33.0" -"@storybook/router@5.2.6": - version "5.2.6" - resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.2.6.tgz#5180d3785501699283c6c3717986c877f84fead5" - integrity sha512-/FZd3fYg5s2QzOqSIP8UMOSnCIFFIlli/jKlOxvm3WpcpxgwQOY4lfHsLO+r9ThCLs2UvVg2R/HqGrOHqDFU7A== +"@storybook/react@^5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-5.2.8.tgz#8d44c2d34caa1d7d748ec1fc9cf0fe2a88b001f9" + integrity sha512-T1DoWpSz33vaGx85Dh7q2KYetg7dQyiYhuOnZm2WxZTFZOw1jP62si53JGFp0PKxnT6iOBLHo3v2QkRkjt2mdQ== + dependencies: + "@babel/plugin-transform-react-constant-elements" "^7.6.3" + "@babel/preset-flow" "^7.0.0" + "@babel/preset-react" "^7.7.0" + "@storybook/addons" "5.2.8" + "@storybook/core" "5.2.8" + "@storybook/node-logger" "5.2.8" + "@svgr/webpack" "^4.0.3" + "@types/webpack-env" "^1.13.7" + babel-plugin-add-react-displayname "^0.0.5" + babel-plugin-named-asset-import "^0.3.1" + babel-plugin-react-docgen "^3.0.0" + babel-preset-react-app "^9.0.0" + common-tags "^1.8.0" + core-js "^3.0.1" + global "^4.3.2" + lodash "^4.17.15" + mini-css-extract-plugin "^0.7.0" + prop-types "^15.7.2" + react-dev-utils "^9.0.0" + regenerator-runtime "^0.12.1" + semver "^6.0.0" + webpack "^4.33.0" + +"@storybook/router@5.2.6": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.2.6.tgz#5180d3785501699283c6c3717986c877f84fead5" + integrity sha512-/FZd3fYg5s2QzOqSIP8UMOSnCIFFIlli/jKlOxvm3WpcpxgwQOY4lfHsLO+r9ThCLs2UvVg2R/HqGrOHqDFU7A== + dependencies: + "@reach/router" "^1.2.1" + "@types/reach__router" "^1.2.3" + core-js "^3.0.1" + global "^4.3.2" + lodash "^4.17.15" + memoizerific "^1.11.3" + qs "^6.6.0" + +"@storybook/router@5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.2.8.tgz#d7de2d401701857c033e28560c30e16512f7f72f" + integrity sha512-wnbyKESUMyv9fwo9W+n4Fev/jXylB8whpjtHrOttjguUOYX1zGSHdwNI66voPetbtVLxUeHyJteJwdyRDSirJg== dependencies: "@reach/router" "^1.2.1" "@types/reach__router" "^1.2.3" @@ -2948,6 +3776,24 @@ prop-types "^15.7.2" resolve-from "^5.0.0" +"@storybook/theming@5.2.8", "@storybook/theming@^5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.2.8.tgz#a4c9e0e9a5789c1aa71e4fcb7a8ee86efe3dadcf" + integrity sha512-rGb66GkXb0jNJMH8UQ3Ru4FL+m1x0+UdxM8a8HSE/qb1GMv2qOwjVETfAL6nVL9u6ZmrtbhHoero4f6xDwZdRg== + dependencies: + "@emotion/core" "^10.0.14" + "@emotion/styled" "^10.0.14" + "@storybook/client-logger" "5.2.8" + common-tags "^1.8.0" + core-js "^3.0.1" + deep-object-diff "^1.1.0" + emotion-theming "^10.0.14" + global "^4.3.2" + memoizerific "^1.11.3" + polished "^3.3.1" + prop-types "^15.7.2" + resolve-from "^5.0.0" + "@storybook/ui@5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-5.2.6.tgz#33df2f2e03d9cf81dc52928a0dc4db280ee8f56a" @@ -2987,6 +3833,45 @@ telejson "^3.0.2" util-deprecate "^1.0.2" +"@storybook/ui@5.2.8": + version "5.2.8" + resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-5.2.8.tgz#da8afca9eb29a40ef3ddc6a9f6e76d7a3344f2ef" + integrity sha512-7t1ARBfylhEsLmGsZBUCj1Wf1oAgCDDrf7fi+Fhdg5Rr16CMoBbe24Gv/mPYv01/pUDhGodxzltKGX5x0Hto2w== + dependencies: + "@storybook/addons" "5.2.8" + "@storybook/api" "5.2.8" + "@storybook/channels" "5.2.8" + "@storybook/client-logger" "5.2.8" + "@storybook/components" "5.2.8" + "@storybook/core-events" "5.2.8" + "@storybook/router" "5.2.8" + "@storybook/theming" "5.2.8" + copy-to-clipboard "^3.0.8" + core-js "^3.0.1" + core-js-pure "^3.0.1" + emotion-theming "^10.0.14" + fast-deep-equal "^2.0.1" + fuse.js "^3.4.4" + global "^4.3.2" + lodash "^4.17.15" + markdown-to-jsx "^6.9.3" + memoizerific "^1.11.3" + polished "^3.3.1" + prop-types "^15.7.2" + qs "^6.6.0" + react "^16.8.3" + react-dom "^16.8.3" + react-draggable "^4.0.3" + react-helmet-async "^1.0.2" + react-hotkeys "2.0.0-pre4" + react-sizeme "^2.6.7" + regenerator-runtime "^0.13.2" + resolve-from "^5.0.0" + semver "^6.0.0" + store2 "^2.7.1" + telejson "^3.0.2" + util-deprecate "^1.0.2" + "@svgr/babel-plugin-add-jsx-attribute@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1" @@ -4787,6 +5672,11 @@ accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" +acorn-dynamic-import@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948" + integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw== + acorn-globals@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf" @@ -4861,6 +5751,11 @@ acorn@^6.0.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== +acorn@^6.0.5: + version "6.4.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" + integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== + acorn@^6.2.1: version "6.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" @@ -7322,6 +8217,14 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +buffer@^5.0.3: + version "5.4.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" + integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + buffer@^5.1.0, buffer@^5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" @@ -7385,7 +8288,7 @@ cac@^4.3.4: string-width "^2.1.1" text-table "^0.2.0" -cacache@^11.3.3: +cacache@^11.3.2, cacache@^11.3.3: version "11.3.3" resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.3.tgz#8bd29df8c6a718a6ebd2d010da4d7972ae3bbadc" integrity sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA== @@ -8014,7 +8917,7 @@ chroma-js@^2.0.4: dependencies: cross-env "^6.0.3" -chrome-trace-event@^1.0.2: +chrome-trace-event@^1.0.0, chrome-trace-event@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== @@ -8930,6 +9833,24 @@ copy-to-clipboard@^3.2.0: dependencies: toggle-selection "^1.0.6" +copy-webpack-plugin@5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.0.3.tgz#2179e3c8fd69f13afe74da338896f1f01a875b5c" + integrity sha512-PlZRs9CUMnAVylZq+vg2Juew662jWtwOXOqH4lbQD9ZFhRG9R7tVStOgHt21CBGVq7k5yIJaz8TXDLSjV+Lj8Q== + dependencies: + cacache "^11.3.2" + find-cache-dir "^2.1.0" + glob-parent "^3.1.0" + globby "^7.1.1" + is-glob "^4.0.1" + loader-utils "^1.2.3" + minimatch "^3.0.4" + normalize-path "^3.0.0" + p-limit "^2.2.0" + schema-utils "^1.0.0" + serialize-javascript "^1.7.0" + webpack-log "^2.0.0" + copy-webpack-plugin@^5.0.4: version "5.0.4" resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.0.4.tgz#c78126f604e24f194c6ec2f43a64e232b5d43655" @@ -9145,6 +10066,14 @@ create-react-context@^0.2.1: fbjs "^0.8.0" gud "^1.0.0" +create-react-context@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.3.0.tgz#546dede9dc422def0d3fc2fe03afe0bc0f4f7d8c" + integrity sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw== + dependencies: + gud "^1.0.0" + warning "^4.0.3" + cronstrue@^1.51.0: version "1.51.0" resolved "https://registry.yarnpkg.com/cronstrue/-/cronstrue-1.51.0.tgz#7a63153d61d940344049037628da38a60784c8e2" @@ -9382,6 +10311,15 @@ css-select@^2.0.0: domutils "^1.7.0" nth-check "^1.0.2" +css-to-react-native@^2.0.3: + version "2.3.2" + resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-2.3.2.tgz#e75e2f8f7aa385b4c3611c52b074b70a002f2e7d" + integrity sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw== + dependencies: + camelize "^1.0.0" + css-color-keywords "^1.0.0" + postcss-value-parser "^3.3.0" + css-to-react-native@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756" @@ -10066,6 +11004,18 @@ deep-equal@^1.0.0, deep-equal@^1.0.1, deep-equal@~1.0.1: resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= +deep-equal@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + deep-extend@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" @@ -11309,7 +12259,7 @@ es6-promise-pool@^2.5.0: resolved "https://registry.yarnpkg.com/es6-promise-pool/-/es6-promise-pool-2.5.0.tgz#147c612b36b47f105027f9d2bf54a598a99d9ccb" integrity sha1-FHxhKza0fxBQJ/nSv1SlmKmdnMs= -es6-promise@^4.0.3, es6-promise@~4.2.4: +es6-promise@^4.0.3: version "4.2.4" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" integrity sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ== @@ -11650,7 +12600,7 @@ eslint-rule-composer@^0.3.0: resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== -eslint-scope@^4.0.3: +eslint-scope@^4.0.0, eslint-scope@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== @@ -11934,6 +12884,19 @@ execa@0.10.0, execa@^0.10.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@1.0.0, execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-0.1.1.tgz#b09c2a9309bc0ef0501479472db3180f8d4c3edd" @@ -11981,19 +12944,6 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - execa@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/execa/-/execa-3.2.0.tgz#18326b79c7ab7fbd6610fd900c1b9e95fa48f90a" @@ -12371,17 +13321,7 @@ fast-equals@^2.0.0: resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-2.0.0.tgz#bef2c423af3939f2c54310df54c57e64cd2adefc" integrity sha512-u6RBd8cSiLLxAiC04wVsLV6GBFDOXcTCgWkd3wEoFXgidPSoAJENqC9m7Jb2vewSvjBIfXV6icKeh3GTKfIaXA== -fast-glob@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.0.4.tgz#a4b9f49e36175f5ef1a3456f580226a6e7abcc9e" - integrity sha512-JAh0y6ScChRmATdQIsN416LK+bAFiGczD9A4zWBMPcTgkpj9SEOC7DEzpfbqoDKzieZw40dIAKx3PofGxukFqw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - glob-parent "3.1.0" - merge2 "1.2.1" - micromatch "3.1.5" - -fast-glob@^2.2.6: +fast-glob@2.2.7, fast-glob@^2.2.6: version "2.2.7" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== @@ -12393,6 +13333,16 @@ fast-glob@^2.2.6: merge2 "^1.2.3" micromatch "^3.1.10" +fast-glob@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.0.4.tgz#a4b9f49e36175f5ef1a3456f580226a6e7abcc9e" + integrity sha512-JAh0y6ScChRmATdQIsN416LK+bAFiGczD9A4zWBMPcTgkpj9SEOC7DEzpfbqoDKzieZw40dIAKx3PofGxukFqw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + glob-parent "3.1.0" + merge2 "1.2.1" + micromatch "3.1.5" + fast-glob@^3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.0.4.tgz#d484a41005cb6faeb399b951fd1bd70ddaebb602" @@ -13706,7 +14656,7 @@ glob-to-regexp@^0.4.0: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.0.tgz#49bd677b1671022bd10921c3788f23cdebf9c7e6" integrity sha512-fyPCII4vn9Gvjq2U/oDAfP433aiE64cyP/CJjRJcpVGjqqNdioUYn9+r0cSzT1XPwmGAHuTT7iv+rQT8u/YHKQ== -glob-watcher@^5.0.3: +glob-watcher@5.0.3, glob-watcher@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.3.tgz#88a8abf1c4d131eb93928994bc4a593c2e5dd626" integrity sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg== @@ -15978,6 +16928,11 @@ is-alphanumerical@^1.0.0: is-alphabetical "^1.0.0" is-decimal "^1.0.0" +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -17161,13 +18116,20 @@ jest-snapshot@^24.1.0, jest-snapshot@^24.9.0: pretty-format "^24.9.0" semver "^6.2.0" -jest-specific-snapshot@^2.0.0: +jest-specific-snapshot@2.0.0, jest-specific-snapshot@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/jest-specific-snapshot/-/jest-specific-snapshot-2.0.0.tgz#425fe524b25df154aa39f97fa6fe9726faaac273" integrity sha512-aXaNqBg/svwEpY5iQEzEHc5I85cUBKgfeVka9KmpznxLnatpjiqjr7QLb/BYNYlsrZjZzgRHTjQJ+Svx+dbdvg== dependencies: jest-snapshot "^24.1.0" +jest-styled-components@6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/jest-styled-components/-/jest-styled-components-6.3.1.tgz#fa21a89bfe8c20081c7c083cbaed2200854b60e3" + integrity sha512-zie3ajvJbwlbHCAq8/Bv5jdbcYCz0ZMRNNX6adL7wSRpkCVPQtiJigv1140JN1ZOJIODPn8VKrjeFCN+jlPa7w== + dependencies: + css "^2.2.4" + jest-styled-components@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/jest-styled-components/-/jest-styled-components-7.0.0.tgz#3e1b7dcd077800ea5191e1cc95b314917a2ed668" @@ -18316,7 +19278,7 @@ load-source-map@^1.0.0: semver "^5.3.0" source-map "^0.5.6" -loader-runner@^2.3.1, loader-runner@^2.4.0: +loader-runner@^2.3.0, loader-runner@^2.3.1, loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== @@ -19242,7 +20204,7 @@ memory-fs@^0.2.0: resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290" integrity sha1-8rslNovBIeORwlIN6Slpyu4KApA= -memory-fs@^0.4.0, memory-fs@^0.4.1: +memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= @@ -19346,7 +20308,7 @@ microevent.ts@~0.1.1: resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== -micromatch@3.1.10, micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: +micromatch@3.1.10, micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -19510,20 +20472,20 @@ mini-create-react-context@^0.3.0: gud "^1.0.0" tiny-warning "^1.0.2" -mini-css-extract-plugin@0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz#81d41ec4fe58c713a96ad7c723cdb2d0bd4d70e1" - integrity sha512-MNpRGbNA52q6U92i0qbVpQNsgk7LExy41MdAlG84FeytfDOtRIf/mCHdEgG8rpTKOaNKiqUnZdlptF469hxqOw== +mini-css-extract-plugin@0.7.0, mini-css-extract-plugin@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.7.0.tgz#5ba8290fbb4179a43dd27cca444ba150bee743a0" + integrity sha512-RQIw6+7utTYn8DBGsf/LpRgZCJMpZt+kuawJ/fju0KiOL6nAaTBNmCJwS7HtwSCXfS47gCkmtBFS7HdsquhdxQ== dependencies: loader-utils "^1.1.0" normalize-url "1.9.1" schema-utils "^1.0.0" webpack-sources "^1.1.0" -mini-css-extract-plugin@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.7.0.tgz#5ba8290fbb4179a43dd27cca444ba150bee743a0" - integrity sha512-RQIw6+7utTYn8DBGsf/LpRgZCJMpZt+kuawJ/fju0KiOL6nAaTBNmCJwS7HtwSCXfS47gCkmtBFS7HdsquhdxQ== +mini-css-extract-plugin@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz#81d41ec4fe58c713a96ad7c723cdb2d0bd4d70e1" + integrity sha512-MNpRGbNA52q6U92i0qbVpQNsgk7LExy41MdAlG84FeytfDOtRIf/mCHdEgG8rpTKOaNKiqUnZdlptF469hxqOw== dependencies: loader-utils "^1.1.0" normalize-url "1.9.1" @@ -20199,11 +21161,6 @@ node-dir@^0.1.10: dependencies: minimatch "^3.0.2" -node-ensure@^0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/node-ensure/-/node-ensure-0.0.0.tgz#ecae764150de99861ec5c810fd5d096b183932a7" - integrity sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc= - node-environment-flags@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" @@ -20323,7 +21280,7 @@ node-jose@1.1.0: util "^0.11.0" vm-browserify "0.0.4" -node-libs-browser@^2.2.1: +node-libs-browser@^2.0.0, node-libs-browser@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== @@ -20483,6 +21440,11 @@ normalize-package-data@^2.5.0: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" +normalize-path@3.0.0, normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -20490,11 +21452,6 @@ normalize-path@^2.0.1, normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - normalize-range@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" @@ -21801,21 +22758,6 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -pdf-image@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pdf-image/-/pdf-image-2.0.0.tgz#f134296876c3d5aacb6bb5805ad15d0a46775fd5" - integrity sha512-RyB8f/Khw8wZt2xXGWtQu/5ZyKl4pzNSi9/dnYNJOuGnxRiZvmUVmz6xmG6Xts53k8ZZaOBjDwoT4jjAVzIoPQ== - dependencies: - es6-promise "~4.2.4" - -pdfjs-dist@^2.0.943: - version "2.0.943" - resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-2.0.943.tgz#32fb9a2d863df5a1d89521a0b3cd900c16e7edde" - integrity sha512-iLhNcm4XceTHRaSU5o22ZGCm4YpuW5+rf4+BJFH/feBhMQLbCGBry+Jet8Q419QDI4qgARaIQzXuiNrsNWS8Yw== - dependencies: - node-ensure "^0.0.0" - worker-loader "^2.0.0" - pdfkit@>=0.8.1, pdfkit@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/pdfkit/-/pdfkit-0.11.0.tgz#9cdb2fc42bd2913587fe3ddf48cc5bbb3c36f7de" @@ -22436,7 +23378,7 @@ prop-types@15.6.1: loose-envify "^1.3.1" object-assign "^4.1.1" -prop-types@15.7.2, prop-types@15.x, prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@15.7.2, prop-types@15.x, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -23175,6 +24117,15 @@ react-dev-utils@^9.0.0: strip-ansi "5.2.0" text-table "0.2.0" +react-docgen-typescript-loader@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/react-docgen-typescript-loader/-/react-docgen-typescript-loader-3.1.0.tgz#09cacf872617c97f946ee920d2239f51d543be41" + integrity sha512-gY+b7RkRPty5ZN4NMQ+jwx9MzTVuIj6LJCwdWRAi1+nrHJfH2gMMytQfxFdzQ7BlgD4COWnSE8Ixtl2L62kCRw== + dependencies: + "@webpack-contrib/schema-utils" "^1.0.0-beta.0" + loader-utils "^1.2.3" + react-docgen-typescript "^1.12.3" + react-docgen-typescript-loader@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/react-docgen-typescript-loader/-/react-docgen-typescript-loader-3.1.1.tgz#c1992538524fb9e45246d6c1314ddcfbf26e9d08" @@ -23350,6 +24301,11 @@ react-is@^16.10.2, react-is@^16.9.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.11.0.tgz#b85dfecd48ad1ce469ff558a882ca8e8313928fa" integrity sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw== +react-is@^16.3.1: + version "16.12.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" + integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q== + react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6: version "16.8.6" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" @@ -23457,6 +24413,14 @@ react-onclickoutside@^6.7.1: resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.8.0.tgz#9f91b5b3ed59f4d9e43fd71620dc200773a4d569" integrity sha512-5Q4Rn7QLEoh7WIe66KFvYIpWJ49GeHoygP1/EtJyZjXKgrWH19Tf0Ty3lWyQzrEEDyLOwUvvmBFSE3dcDdvagA== +react-popper-tooltip@^2.10.1: + version "2.10.1" + resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-2.10.1.tgz#e10875f31916297c694d64a677d6f8fa0a48b4d1" + integrity sha512-cib8bKiyYcrIlHo9zXx81G0XvARfL8Jt+xum709MFCgQa3HTqTi4au3iJ9tm7vi7WU7ngnqbpWkMinBOtwo+IQ== + dependencies: + "@babel/runtime" "^7.7.4" + react-popper "^1.3.6" + react-popper-tooltip@^2.8.3: version "2.8.3" resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-2.8.3.tgz#1c63e7473a96362bd93be6c94fa404470a265197" @@ -23485,6 +24449,19 @@ react-popper@^1.3.3: typed-styles "^0.0.7" warning "^4.0.2" +react-popper@^1.3.6: + version "1.3.7" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.7.tgz#f6a3471362ef1f0d10a4963673789de1baca2324" + integrity sha512-nmqYTx7QVjCm3WUZLeuOomna138R1luC4EqkW3hxJUrAe+3eNz3oFCLYdnPwILfn0mX1Ew2c3wctrjlUMYYUww== + dependencies: + "@babel/runtime" "^7.1.2" + create-react-context "^0.3.0" + deep-equal "^1.1.1" + popper.js "^1.14.4" + prop-types "^15.6.1" + typed-styles "^0.0.7" + warning "^4.0.2" + react-portal@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/react-portal/-/react-portal-3.2.0.tgz#4224e19b2b05d5cbe730a7ba0e34ec7585de0043" @@ -23709,6 +24686,14 @@ react-textarea-autosize@^7.1.0: "@babel/runtime" "^7.1.2" prop-types "^15.6.0" +react-textarea-autosize@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-7.1.2.tgz#70fdb333ef86bcca72717e25e623e90c336e2cda" + integrity sha512-uH3ORCsCa3C6LHxExExhF4jHoXYCQwE5oECmrRsunlspaDAbS4mGKNlWZqjLfInWtFQcf0o1n1jC/NGXFdUBCg== + dependencies: + "@babel/runtime" "^7.1.2" + prop-types "^15.6.0" + react-tiny-virtual-list@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/react-tiny-virtual-list/-/react-tiny-virtual-list-2.2.0.tgz#eafb6fcf764e4ed41150ff9752cdaad8b35edf4a" @@ -24233,6 +25218,13 @@ regenerate-unicode-properties@^8.0.2: dependencies: regenerate "^1.4.0" +regenerate-unicode-properties@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" + integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== + dependencies: + regenerate "^1.4.0" + regenerate@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" @@ -24329,6 +25321,18 @@ regexpu-core@^4.5.4: unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.1.0" +regexpu-core@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" + integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.1.0" + regjsgen "^0.5.0" + regjsparser "^0.6.0" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.1.0" + registry-auth-token@^3.0.1, registry-auth-token@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" @@ -25167,6 +26171,13 @@ rxjs-marbles@^5.0.3: dependencies: fast-equals "^2.0.0" +rxjs@6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7" + integrity sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg== + dependencies: + tslib "^1.9.0" + rxjs@^5.0.0-beta.11, rxjs@^5.5.2: version "5.5.12" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" @@ -25356,7 +26367,7 @@ schema-utils@^0.3.0: dependencies: ajv "^5.0.0" -schema-utils@^0.4.0, schema-utils@^0.4.5: +schema-utils@^0.4.5: version "0.4.7" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== @@ -25582,7 +26593,7 @@ sentence-case@^2.1.0: no-case "^2.2.0" upper-case-first "^1.1.2" -serialize-javascript@^1.7.0, serialize-javascript@^2.1.0, serialize-javascript@^2.1.1: +serialize-javascript@^1.7.0, serialize-javascript@^2.1.0, serialize-javascript@^2.1.1, serialize-javascript@^2.1.2: version "2.1.1" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.1.tgz#952907a04a3e3a75af7f73d92d15e233862048b2" integrity sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ== @@ -25851,6 +26862,14 @@ simplebar-react@^1.0.0-alpha.6: prop-types "^15.6.1" simplebar "^4.2.0" +simplebar-react@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/simplebar-react/-/simplebar-react-2.1.0.tgz#57d524f4253579d81ac30db00acf7886b17bf826" + integrity sha512-UIMFPNkn6o57v058vPOiYbnbpc1CUZwPKLmQaDMvEJdgm+btZ2umFA6meXfiqFEQUjDE6Vq4ePnL7Fr6nzJd8w== + dependencies: + prop-types "^15.6.1" + simplebar "^5.1.0" + simplebar@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/simplebar/-/simplebar-4.2.0.tgz#97e5c1c85d05cc04f8c92939e4da71dd087e325c" @@ -25863,6 +26882,18 @@ simplebar@^4.2.0: lodash.throttle "^4.1.1" resize-observer-polyfill "^1.5.1" +simplebar@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/simplebar/-/simplebar-5.1.0.tgz#15437ace314ec888accd7d8f24ada672e9bb2717" + integrity sha512-bdi1SleK1YOSnfeUjo5UQXt/79zNjsCJVEfzrm6photmGi2aU6x0l7rX4KAGcrtj5AwsWPBVXgDyYAqbbpnuRg== + dependencies: + can-use-dom "^0.1.0" + core-js "^3.0.1" + lodash.debounce "^4.0.8" + lodash.memoize "^4.1.2" + lodash.throttle "^4.1.1" + resize-observer-polyfill "^1.5.1" + simplicial-complex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/simplicial-complex/-/simplicial-complex-1.0.0.tgz#6c33a4ed69fcd4d91b7bcadd3b30b63683eae241" @@ -26935,6 +27966,21 @@ style-loader@0.23.1, style-loader@^0.23.1: loader-utils "^1.1.0" schema-utils "^1.0.0" +styled-components@^3: + version "3.4.10" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-3.4.10.tgz#9a654c50ea2b516c36ade57ddcfa296bf85c96e1" + integrity sha512-TA8ip8LoILgmSAFd3r326pKtXytUUGu5YWuqZcOQVwVVwB6XqUMn4MHW2IuYJ/HAD81jLrdQed8YWfLSG1LX4Q== + dependencies: + buffer "^5.0.3" + css-to-react-native "^2.0.3" + fbjs "^0.8.16" + hoist-non-react-statics "^2.5.0" + prop-types "^15.5.4" + react-is "^16.3.1" + stylis "^3.5.0" + stylis-rule-sheet "^0.0.10" + supports-color "^3.2.3" + styled-components@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.0.0.tgz#fc59932c9b574571fa3cd462c862af1956114ff2" @@ -26951,11 +27997,21 @@ styled-components@^5.0.0: shallowequal "^1.1.0" supports-color "^5.5.0" +stylis-rule-sheet@^0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430" + integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw== + stylis@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.0.tgz#016fa239663d77f868fef5b67cf201c4b7c701e1" integrity sha512-pP7yXN6dwMzAR29Q0mBrabPCe0/mNO1MSr93bhay+hcZondvMMTpeGyd8nbhYJdyperNT2DRxONQuUGcJr5iPw== +stylis@^3.5.0: + version "3.5.4" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe" + integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== + stylus-lookup@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/stylus-lookup/-/stylus-lookup-3.0.2.tgz#c9eca3ff799691020f30b382260a67355fefdddd" @@ -27064,7 +28120,7 @@ supports-color@^2.0.0: resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= -supports-color@^3.1.0, supports-color@^3.1.2: +supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= @@ -27400,6 +28456,21 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" +terser-webpack-plugin@^1.1.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" + integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^2.1.2" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + terser-webpack-plugin@^1.2.4, terser-webpack-plugin@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz#61b18e40eaee5be97e771cdbb10ed1280888c2b4" @@ -29950,14 +31021,14 @@ warning@^3.0.0: dependencies: loose-envify "^1.0.0" -warning@^4.0.2: +warning@^4.0.2, warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== dependencies: loose-envify "^1.0.0" -watchpack@^1.6.0: +watchpack@^1.5.0, watchpack@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== @@ -30117,7 +31188,7 @@ webpack-sources@^1.1.0: source-list-map "^2.0.0" source-map "~0.6.1" -webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: +webpack-sources@^1.3.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== @@ -30125,6 +31196,36 @@ webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: source-list-map "^2.0.0" source-map "~0.6.1" +webpack@4.34.0: + version "4.34.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.34.0.tgz#a4c30129482f7b4ece4c0842002dedf2b56fab58" + integrity sha512-ry2IQy1wJjOefLe1uJLzn5tG/DdIKzQqNlIAd2L84kcaADqNvQDTBlo8UcCNyDaT5FiaB+16jhAkb63YeG3H8Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/wasm-edit" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + acorn "^6.0.5" + acorn-dynamic-import "^4.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^1.0.0" + tapable "^1.1.0" + terser-webpack-plugin "^1.1.0" + watchpack "^1.5.0" + webpack-sources "^1.3.0" + webpack@4.41.0, webpack@^4.33.0, webpack@^4.38.0, webpack@^4.41.0: version "4.41.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.0.tgz#db6a254bde671769f7c14e90a1a55e73602fc70b" @@ -30394,14 +31495,6 @@ worker-farm@^1.7.0: dependencies: errno "~0.1.7" -worker-loader@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-2.0.0.tgz#45fda3ef76aca815771a89107399ee4119b430ac" - integrity sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw== - dependencies: - loader-utils "^1.0.0" - schema-utils "^0.4.0" - worker-rpc@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5"