Merge branch 'master' of https://github.com/elastic/kibana into bug/ingest-dev-480-484-485/host-details-update

This commit is contained in:
Michael Marcialis 2019-06-03 15:09:04 -04:00
commit fa1d6073c4
163 changed files with 4256 additions and 5657 deletions

View file

@ -44,7 +44,7 @@
# the username and password that the Kibana server uses to perform maintenance on the Kibana
# index at startup. Your Kibana users still need to authenticate with Elasticsearch, which
# is proxied through the Kibana server.
#elasticsearch.username: "user"
#elasticsearch.username: "kibana"
#elasticsearch.password: "pass"
# Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively.

View file

@ -46,13 +46,12 @@ These wizards create {ml} jobs, dashboards, searches, and visualizations that
are customized to help you analyze your {auditbeat} and {filebeat} data.
If you are not certain which type of job to create, you can use the
*Data Visualizer* to learn more about your data and to identify possible fields
for {ml} analysis.
*Data Visualizer* to learn more about your data. If your index pattern contains
a time field, it can identify possible fields for {ml} analysis.
[NOTE]
===============================
* If your index pattern does not contain a time field, you cannot use the *Data Visualizer*.
* If your data is located outside of {es}, you cannot use {kib} to create
If your data is located outside of {es}, you cannot use {kib} to create
your jobs and you cannot use {dfeeds} to retrieve your data in real time.
Machine learning analysis is still possible, however, by using APIs to
create and manage jobs and post data to them. For more information, see

View file

@ -16,8 +16,9 @@ The {ml-features} run in and scale with {es}, and include an
intuitive UI on the {kib} *Machine Learning* page for creating anomaly detection
jobs and understanding results.
If you have a basic license, you can use the *Data Visualizer* to learn more
about the data that you've stored in {es} and to identify possible fields for
If you have a basic license, you can use the *Data Visualizer* to learn more
about your data. In particular, if your data is stored in {es} and contains a
time field, you can use the *Data Visualizer* to identify possible fields for
{ml} analysis:
[role="screenshot"]

View file

@ -20,7 +20,7 @@ To assign {kib} privileges to the role, click **Add space privilege** in the Kib
[role="screenshot"]
image::security/images/add-space-privileges.png[Add space privileges]
Open the **Spaces** dropdown menu to specify whether to grant the role access to all spaces *** Global (all spaces)** or one or more individual spaces. If you select *** Global (all spaces)**, you cant select individual spaces until you clear your selection.
Open the **Spaces** selection control to specify whether to grant the role access to all spaces *** Global (all spaces)** or one or more individual spaces. If you select *** Global (all spaces)**, you cant select individual spaces until you clear your selection.
Use the **Privilege** menu to grant access to features. The default is **Custom**, which you can use to grant access to individual features. Otherwise, you can grant read and write access to all current and future features by selecting **All**, or grant read access to all current and future features by selecting **Read**.
@ -39,7 +39,7 @@ image::security/images/create-space-privilege.png[Create space privilege]
==== Assigning different privileges to different spaces
Using the same role, its possible to assign different privileges to different spaces. After youve added space privileges, click **Add space privilege**. If youve already added privileges for either *** Global (all spaces)** or an individual space, you will not be able to select these in the **Spaces** control.
Using the same role, its possible to assign different privileges to different spaces. After youve added space privileges, click **Add space privilege**. If youve already added privileges for either *** Global (all spaces)** or an individual space, you will not be able to select these in the **Spaces** selection control.
Additionally, if youve already assigned privileges at *** Global (all spaces)**, you are only able to assign additional privileges to individual spaces. Similar to the behavior of multiple roles granting the union of all privileges, space privileges are also a union. If youve already granted the user the **All** privilege at *** Global (all spaces)**, youre not able to restrict the role to only the **Read** privilege at an individual space.

View file

@ -104,7 +104,7 @@
"@babel/register": "7.4.4",
"@elastic/charts": "^4.2.6",
"@elastic/datemath": "5.0.2",
"@elastic/eui": "10.4.1",
"@elastic/eui": "11.0.1",
"@elastic/filesaver": "1.1.2",
"@elastic/good": "8.1.1-kibana2",
"@elastic/numeral": "2.3.3",
@ -145,17 +145,17 @@
"core-js": "2.6.9",
"css-loader": "1.0.0",
"custom-event-polyfill": "^0.3.0",
"d3": "3.5.6",
"d3-cloud": "1.2.1",
"d3": "3.5.17",
"d3-cloud": "1.2.5",
"del": "^4.0.0",
"dragula": "3.7.2",
"elasticsearch": "^15.5.0",
"elasticsearch-browser": "^15.5.0",
"encode-uri-query": "1.0.0",
"encode-uri-query": "1.0.1",
"execa": "^1.0.0",
"expiry-js": "0.1.7",
"file-loader": "2.0.0",
"font-awesome": "4.4.0",
"font-awesome": "4.7.0",
"getos": "^3.1.0",
"glob": "^7.1.2",
"glob-all": "^3.1.0",
@ -165,37 +165,37 @@
"handlebars": "4.1.2",
"hapi": "^17.5.3",
"hapi-auth-cookie": "^9.0.0",
"hjson": "3.1.0",
"hjson": "3.1.2",
"hoek": "^5.0.4",
"http-proxy-agent": "^2.1.0",
"https-proxy-agent": "^2.2.1",
"inert": "^5.1.0",
"joi": "^13.5.2",
"jquery": "^3.4.1",
"js-yaml": "3.4.1",
"js-yaml": "3.13.1",
"json-stable-stringify": "^1.0.1",
"json-stringify-pretty-compact": "1.0.4",
"json-stringify-pretty-compact": "1.2.0",
"json-stringify-safe": "5.0.1",
"leaflet": "1.0.3",
"leaflet-draw": "0.4.10",
"leaflet-responsive-popup": "0.2.0",
"leaflet-draw": "0.4.14",
"leaflet-responsive-popup": "0.6.4",
"leaflet-vega": "^0.8.6",
"leaflet.heat": "0.2.0",
"less": "^2.7.3",
"less-loader": "4.1.0",
"lodash": "npm:@elastic/lodash@3.10.1-kibana1",
"lodash.clonedeep": "^4.5.0",
"lru-cache": "4.1.1",
"lru-cache": "4.1.5",
"markdown-it": "^8.4.1",
"mini-css-extract-plugin": "0.4.4",
"minimatch": "^3.0.4",
"mkdirp": "0.5.1",
"moment": "^2.20.1",
"moment-timezone": "^0.5.14",
"mustache": "2.3.0",
"mustache": "2.3.2",
"ngreact": "0.5.1",
"no-ui-slider": "1.2.0",
"node-fetch": "1.3.2",
"node-fetch": "1.7.3",
"opn": "^5.4.0",
"oppsy": "^2.0.0",
"pegjs": "0.9.0",
@ -258,6 +258,7 @@
},
"devDependencies": {
"@babel/parser": "7.4.5",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/types": "7.4.4",
"@elastic/eslint-config-kibana": "0.15.0",
"@elastic/github-checks-reporter": "0.0.15",
@ -268,7 +269,7 @@
"@kbn/expect": "1.0.0",
"@kbn/plugin-generator": "1.0.0",
"@kbn/test": "1.0.0",
"@microsoft/api-documenter": "7.0.49",
"@microsoft/api-documenter": "7.2.1",
"@microsoft/api-extractor": "7.1.1",
"@octokit/rest": "^15.10.0",
"@types/angular": "1.6.50",
@ -287,7 +288,7 @@
"@types/enzyme": "^3.1.12",
"@types/eslint": "^4.16.6",
"@types/execa": "^0.9.0",
"@types/fetch-mock": "7.2.1",
"@types/fetch-mock": "7.3.0",
"@types/getopts": "^2.0.1",
"@types/glob": "^7.1.1",
"@types/globby": "^8.0.0",
@ -302,7 +303,7 @@
"@types/jquery": "^3.3.6",
"@types/js-yaml": "^3.11.1",
"@types/json5": "^0.0.30",
"@types/listr": "^0.13.0",
"@types/listr": "^0.14.0",
"@types/lodash": "^3.10.1",
"@types/lru-cache": "^5.1.0",
"@types/minimatch": "^2.0.29",
@ -338,6 +339,7 @@
"archiver": "^3.0.0",
"babel-eslint": "10.0.1",
"babel-jest": "^24.1.0",
"babel-plugin-dynamic-import-node": "^2.2.0",
"backport": "4.5.5",
"chai": "3.5.0",
"chance": "1.0.18",
@ -366,7 +368,7 @@
"eslint-plugin-react-hooks": "1.6.0",
"exit-hook": "^2.1.0",
"faker": "1.1.0",
"fetch-mock": "7.3.0",
"fetch-mock": "7.3.3",
"geckodriver": "1.13.0",
"getopts": "^2.2.4",
"grunt": "1.0.4",
@ -378,7 +380,7 @@
"gulp-babel": "8.0.0",
"gulp-sourcemaps": "2.6.5",
"has-ansi": "^3.0.0",
"image-diff": "1.6.0",
"image-diff": "1.6.3",
"intl-messageformat-parser": "^1.4.0",
"is-path-inside": "^2.0.0",
"istanbul-instrumenter-loader": "3.0.1",
@ -386,7 +388,7 @@
"jest-cli": "^24.1.0",
"jest-dom": "^3.1.3",
"jest-raw-loader": "^1.0.1",
"jimp": "0.6.0",
"jimp": "0.6.4",
"json5": "^1.0.1",
"karma": "3.1.4",
"karma-chrome-launcher": "2.2.0",

View file

@ -7,11 +7,11 @@ module.exports = {
plugins: ['@kbn/eslint-plugin-eslint'],
parserOptions: {
ecmaVersion: 6
ecmaVersion: 2018
},
env: {
es6: true
es6: true,
},
rules: {

View file

@ -44,8 +44,7 @@ module.exports = {
parserOptions: {
sourceType: 'module',
ecmaVersion: 6,
ecmaFeatures: { experimentalObjectRestSpread: true },
ecmaVersion: 2018,
},
rules: {

View file

@ -42,9 +42,8 @@ module.exports = {
parserOptions: {
sourceType: 'module',
ecmaVersion: 6,
ecmaVersion: 2018,
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true
},
// NOTE: That is to avoid a known performance issue related with the `ts.Program` used by

View file

@ -24,7 +24,7 @@ const dedent = require('dedent');
const ruleTester = new RuleTester({
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 2015,
ecmaVersion: 2018,
},
});

View file

@ -35,7 +35,7 @@ const ruleTester = new RuleTester({
parser: 'babel-eslint',
parserOptions: {
sourceType: 'module',
ecmaVersion: 2015,
ecmaVersion: 2018,
},
});

View file

@ -24,7 +24,7 @@ const dedent = require('dedent');
const ruleTester = new RuleTester({
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 2015,
ecmaVersion: 2018,
},
});

View file

@ -19,7 +19,7 @@
"globby": "^8.0.1",
"gulp-babel": "^8.0.0",
"gulp-rename": "1.4.0",
"gulp-zip": "4.1.0",
"gulp-zip": "4.2.0",
"inquirer": "^1.2.2",
"minimatch": "^3.0.4",
"node-sass": "^4.9.4",

View file

@ -33,7 +33,7 @@
"@types/read-pkg": "^3.0.0",
"@types/strip-ansi": "^3.0.0",
"@types/strong-log-transformer": "^1.0.0",
"@types/tempy": "^0.1.0",
"@types/tempy": "^0.2.0",
"@types/wrap-ansi": "^2.0.14",
"@types/write-pkg": "^3.1.0",
"babel-loader": "8.0.5",
@ -60,7 +60,7 @@
"string-replace-loader": "^2.1.1",
"strip-ansi": "^4.0.0",
"strong-log-transformer": "^2.1.0",
"tempy": "^0.2.1",
"tempy": "^0.3.0",
"typescript": "^3.3.3333",
"unlazy-loader": "^0.1.3",
"webpack": "^4.23.1",

View file

@ -106,6 +106,12 @@
groupName: 'grunt related packages',
groupSlug: 'grunt',
},
{
packagePatterns: ['\\bangular\\b'],
groupName: 'angular related packages',
groupSlug: 'angular',
recreateClosed: false,
},
{
packagePatterns: ['\\bd3\\b'],
groupName: 'd3 related packages',

View file

@ -3,7 +3,7 @@
"strict": true,
"skipLibCheck": true,
"lib": [
"esnext"
"es2018"
]
},
"files": [

View file

@ -23,4 +23,9 @@ module.exports = babelJest.createTransformer({
presets: [
require.resolve('@kbn/babel-preset/node_preset')
],
plugins: [
// enables jest to parse and execute dynamic import() calls
'@babel/plugin-syntax-dynamic-import',
'dynamic-import-node'
]
});

View file

@ -88,7 +88,8 @@ export default {
'^.+\\.html?$': 'jest-raw-loader',
},
transformIgnorePatterns: [
'[/\\\\]node_modules[/\\\\].+\\.js$',
// ignore all node_modules except @elastic/eui which requires babel transforms to handle dynamic import()
'[/\\\\]node_modules(?![\\/\\\\]@elastic[\\/\\\\]eui)[/\\\\].+\\.js$',
'packages/kbn-pm/dist/index.js'
],
snapshotSerializers: [

View file

@ -60,7 +60,7 @@ export const LICENSE_WHITELIST = [
'MIT*',
'MIT/X11',
'new BSD, and MIT',
'OFL-1.1 AND MIT',
'(OFL-1.1 AND MIT)',
'Public Domain',
'Unlicense',
'WTFPL OR ISC',

View file

@ -33,24 +33,13 @@ exports[`DashboardPanel matches snapshot 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiButtonIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M.164 10.329L1.87 8 .163 5.67c.18-.601.43-1.19.758-1.757a8.197 8.197 0 0 1 1.142-1.535l2.872.313L6.099.05a8.166 8.166 0 0 1 3.8-.003l1.166 2.644 2.872-.313a8.166 8.166 0 0 1 1.899 3.293L14.13 8l1.706 2.33c-.18.601-.43 1.19-.758 1.757a8.197 8.197 0 0 1-1.142 1.535l-2.872-.313-1.164 2.641a8.166 8.166 0 0 1-3.8.003l-1.166-2.644-2.872.313a8.166 8.166 0 0 1-1.899-3.293zm4.663 1.986a1 1 0 0 1 1.023.591l.957 2.17c.79.134 1.597.132 2.387-.001l.956-2.169a1 1 0 0 1 1.023-.59l2.358.256a7.23 7.23 0 0 0 1.194-2.068l-1.401-1.913a1 1 0 0 1 0-1.182l1.4-1.912a7.165 7.165 0 0 0-1.192-2.069l-2.359.257a1 1 0 0 1-1.023-.591L9.193.924a7.165 7.165 0 0 0-2.387.001L5.85 3.094a1 1 0 0 1-1.023.59l-2.358-.256a7.23 7.23 0 0 0-1.194 2.068l1.401 1.913a1 1 0 0 1 0 1.182l-1.4 1.912c.28.751.681 1.45 1.192 2.069l2.359-.257zM8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-1a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"
id="gear-a"
/>
</defs>
<use
xlink:href="#gear-a"
/>
</svg>
/>
</button>
</div>
</div>

View file

@ -20,25 +20,13 @@ Array [
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiCallOutHeader__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiCallOutHeader__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.6 12.186l-1.357-1.358c-.025-.025-.058-.034-.084-.056.53-.794.84-1.746.84-2.773a4.977 4.977 0 0 0-.84-2.772c.026-.02.059-.03.084-.056L13.6 3.813a6.96 6.96 0 0 1 0 8.373zM8 15A6.956 6.956 0 0 1 3.814 13.6l1.358-1.358c.025-.025.034-.057.055-.084C6.02 12.688 6.974 13 8 13a4.978 4.978 0 0 0 2.773-.84c.02.026.03.058.056.083l1.357 1.358A6.956 6.956 0 0 1 8 15zm-5.601-2.813a6.963 6.963 0 0 1 0-8.373l1.359 1.358c.024.025.057.035.084.056A4.97 4.97 0 0 0 3 8c0 1.027.31 1.98.842 2.773-.027.022-.06.031-.084.056l-1.36 1.358zm5.6-.187A4 4 0 1 1 8 4a4 4 0 0 1 0 8zM8 1c1.573 0 3.019.525 4.187 1.4l-1.357 1.358c-.025.025-.035.057-.056.084A4.979 4.979 0 0 0 8 3a4.979 4.979 0 0 0-2.773.842c-.021-.027-.03-.059-.055-.084L3.814 2.4A6.957 6.957 0 0 1 8 1zm0-1a8.001 8.001 0 1 0 .003 16.002A8.001 8.001 0 0 0 8 0z"
id="help-a"
/>
</defs>
<use
fill-rule="evenodd"
href="#help-a"
/>
</svg>
/>
<span
class="euiCallOutHeader__title"
>
@ -223,25 +211,13 @@ Array [
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiCallOutHeader__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiCallOutHeader__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.6 12.186l-1.357-1.358c-.025-.025-.058-.034-.084-.056.53-.794.84-1.746.84-2.773a4.977 4.977 0 0 0-.84-2.772c.026-.02.059-.03.084-.056L13.6 3.813a6.96 6.96 0 0 1 0 8.373zM8 15A6.956 6.956 0 0 1 3.814 13.6l1.358-1.358c.025-.025.034-.057.055-.084C6.02 12.688 6.974 13 8 13a4.978 4.978 0 0 0 2.773-.84c.02.026.03.058.056.083l1.357 1.358A6.956 6.956 0 0 1 8 15zm-5.601-2.813a6.963 6.963 0 0 1 0-8.373l1.359 1.358c.024.025.057.035.084.056A4.97 4.97 0 0 0 3 8c0 1.027.31 1.98.842 2.773-.027.022-.06.031-.084.056l-1.36 1.358zm5.6-.187A4 4 0 1 1 8 4a4 4 0 0 1 0 8zM8 1c1.573 0 3.019.525 4.187 1.4l-1.357 1.358c-.025.025-.035.057-.056.084A4.979 4.979 0 0 0 8 3a4.979 4.979 0 0 0-2.773.842c-.021-.027-.03-.059-.055-.084L3.814 2.4A6.957 6.957 0 0 1 8 1zm0-1a8.001 8.001 0 1 0 .003 16.002A8.001 8.001 0 0 0 8 0z"
id="help-a"
/>
</defs>
<use
fill-rule="evenodd"
href="#help-a"
/>
</svg>
/>
<span
class="euiCallOutHeader__title"
>
@ -274,25 +250,13 @@ Array [
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiCallOutHeader__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiCallOutHeader__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.6 12.186l-1.357-1.358c-.025-.025-.058-.034-.084-.056.53-.794.84-1.746.84-2.773a4.977 4.977 0 0 0-.84-2.772c.026-.02.059-.03.084-.056L13.6 3.813a6.96 6.96 0 0 1 0 8.373zM8 15A6.956 6.956 0 0 1 3.814 13.6l1.358-1.358c.025-.025.034-.057.055-.084C6.02 12.688 6.974 13 8 13a4.978 4.978 0 0 0 2.773-.84c.02.026.03.058.056.083l1.357 1.358A6.956 6.956 0 0 1 8 15zm-5.601-2.813a6.963 6.963 0 0 1 0-8.373l1.359 1.358c.024.025.057.035.084.056A4.97 4.97 0 0 0 3 8c0 1.027.31 1.98.842 2.773-.027.022-.06.031-.084.056l-1.36 1.358zm5.6-.187A4 4 0 1 1 8 4a4 4 0 0 1 0 8zM8 1c1.573 0 3.019.525 4.187 1.4l-1.357 1.358c-.025.025-.035.057-.056.084A4.979 4.979 0 0 0 8 3a4.979 4.979 0 0 0-2.773.842c-.021-.027-.03-.059-.055-.084L3.814 2.4A6.957 6.957 0 0 1 8 1zm0-1a8.001 8.001 0 1 0 .003 16.002A8.001 8.001 0 0 0 8 0z"
id="help-a"
/>
</defs>
<use
fill-rule="evenodd"
href="#help-a"
/>
</svg>
/>
<span
class="euiCallOutHeader__title"
>
@ -393,25 +357,13 @@ Array [
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiCallOutHeader__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiCallOutHeader__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.6 12.186l-1.357-1.358c-.025-.025-.058-.034-.084-.056.53-.794.84-1.746.84-2.773a4.977 4.977 0 0 0-.84-2.772c.026-.02.059-.03.084-.056L13.6 3.813a6.96 6.96 0 0 1 0 8.373zM8 15A6.956 6.956 0 0 1 3.814 13.6l1.358-1.358c.025-.025.034-.057.055-.084C6.02 12.688 6.974 13 8 13a4.978 4.978 0 0 0 2.773-.84c.02.026.03.058.056.083l1.357 1.358A6.956 6.956 0 0 1 8 15zm-5.601-2.813a6.963 6.963 0 0 1 0-8.373l1.359 1.358c.024.025.057.035.084.056A4.97 4.97 0 0 0 3 8c0 1.027.31 1.98.842 2.773-.027.022-.06.031-.084.056l-1.36 1.358zm5.6-.187A4 4 0 1 1 8 4a4 4 0 0 1 0 8zM8 1c1.573 0 3.019.525 4.187 1.4l-1.357 1.358c-.025.025-.035.057-.056.084A4.979 4.979 0 0 0 8 3a4.979 4.979 0 0 0-2.773.842c-.021-.027-.03-.059-.055-.084L3.814 2.4A6.957 6.957 0 0 1 8 1zm0-1a8.001 8.001 0 1 0 .003 16.002A8.001 8.001 0 0 0 8 0z"
id="help-a"
/>
</defs>
<use
fill-rule="evenodd"
href="#help-a"
/>
</svg>
/>
<span
class="euiCallOutHeader__title"
>

View file

@ -522,24 +522,20 @@ exports[`bulkCreate should display success message when bulkCreate is successful
title="complete"
type="check"
>
<check
className="euiIcon euiIcon--medium euiStepNumber__icon"
<EuiIconCheck
className="euiIcon euiIcon--medium euiIcon-isLoaded euiStepNumber__icon"
focusable="false"
height="16"
style={null}
title="complete"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<svg
className="euiIcon euiIcon--medium euiStepNumber__icon"
className="euiIcon euiIcon--medium euiIcon-isLoaded euiStepNumber__icon"
focusable="false"
height="16"
height={16}
style={null}
title="complete"
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
@ -547,7 +543,7 @@ exports[`bulkCreate should display success message when bulkCreate is successful
fillRule="evenodd"
/>
</svg>
</check>
</EuiIconCheck>
</EuiIcon>
</EuiI18n>
</div>

View file

@ -135,16 +135,11 @@ exports[`Table should render normally 1`] = `
exports[`Table should render the boolean template (false) 1`] = `<span />`;
exports[`Table should render the boolean template (true) 1`] = `
<dot
<EuiIconEmpty
aria-label="Is searchable"
className="euiIcon euiIcon--medium euiIcon--secondary"
className="euiIcon euiIcon--medium euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
/>
`;

View file

@ -32,7 +32,6 @@ import { FeatureCatalogueRegistryProvider, FeatureCatalogueCategory } from 'ui/r
import { i18n } from '@kbn/i18n';
import { I18nContext } from 'ui/i18n';
import { UICapabilitiesProvider } from 'ui/capabilities/react';
import { EuiBadge } from '@elastic/eui';
import { getListBreadcrumbs } from './breadcrumbs';
import React from 'react';
@ -124,36 +123,39 @@ uiModules.get('apps/management')
});
const renderList = () => {
$scope.indexPatternList = $route.current.locals.indexPatterns.map(pattern => {
const id = pattern.id;
const tags = indexPatternListProvider.getIndexPatternTags(pattern, $scope.defaultIndex === id);
$scope.indexPatternList =
$route.current.locals.indexPatterns
.map(pattern => {
const id = pattern.id;
const title = pattern.get('title');
const isDefault = $scope.defaultIndex === id;
const tags = indexPatternListProvider.getIndexPatternTags(
pattern,
isDefault
);
return {
id: id,
title:
<span>
{pattern.get('title')}{$scope.defaultIndex === id && (<EuiBadge className="indexPatternList__badge">Default</EuiBadge>)}
</span>,
url: kbnUrl.eval('#/management/kibana/index_patterns/{{id}}', { id: id }),
active: $scope.editingId === id,
default: $scope.defaultIndex === id,
tag: tags && tags.length ? tags[0] : null,
};
}).sort((a, b) => {
if(a.default) {
return -1;
}
if(b.default) {
return 1;
}
if(a.title < b.title) {
return -1;
}
if(a.title > b.title) {
return 1;
}
return 0;
}) || [];
return {
id,
title,
url: kbnUrl.eval('#/management/kibana/index_patterns/{{id}}', { id: id }),
active: $scope.editingId === id,
default: isDefault,
tag: tags && tags.length ? tags[0] : null,
//the prepending of 0 at the default pattern takes care of prioritization
//so the sorting will but the default index on top
//or on bottom of a the table
sort: `${isDefault ? '0' : '1'}${title}`,
};
})
.sort((a, b) => {
if (a.sort < b.sort) {
return -1;
} else if (a.sort > b.sort) {
return 1;
} else {
return 0;
}
}) || [];
updateIndexPatternList($scope.indexPatternList, kbnUrl, indexPatternCreationOptions);
};

View file

@ -18,6 +18,7 @@
*/
import {
EuiBadge,
EuiButtonEmpty,
EuiButtonIcon,
EuiFlexGroup,
@ -38,13 +39,14 @@ const columns = [
{
field: 'title',
name: 'Pattern',
render: (name: string, { id }: { id: string }) => (
<EuiButtonEmpty size="xs" href={`#/management/kibana/index_patterns/${id}`}>
render: (name: string, index: { id: string; default: boolean }) => (
<EuiButtonEmpty size="xs" href={`#/management/kibana/index_patterns/${index.id}`}>
{name}
{index.default && <EuiBadge className="indexPatternList__badge">Default</EuiBadge>}
</EuiButtonEmpty>
),
dataType: 'string',
sortable: true,
sortable: ({ sort }: { sort: string }) => sort,
},
];
@ -56,7 +58,7 @@ const pagination = {
const sorting = {
sort: {
field: 'title',
direction: 'desc',
direction: 'asc',
},
};
@ -90,9 +92,9 @@ export class IndexPatternTable extends React.Component<Props, State> {
<CreateIndexPatternPrompt onClose={() => this.setState({ showFlyout: false })} />
)}
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiFlexItem grow={false} className="euiIEFlexWrapFix">
<EuiFlexGroup alignItems="center" gutterSize="s">
<EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiText>
<h2>
<FormattedMessage
@ -123,6 +125,7 @@ export class IndexPatternTable extends React.Component<Props, State> {
</EuiFlexGroup>
<EuiSpacer />
<EuiInMemoryTable
allowNeutralSort={false}
itemId="id"
isSelectable={false}
items={this.props.indexPatterns}

View file

@ -25,9 +25,10 @@ export interface IndexPatternCreationOption {
export interface IndexPattern {
id: string;
title: HTMLElement;
title: string;
url: string;
active: boolean;
default: boolean;
tag?: string[];
sort: string;
}

View file

@ -174,17 +174,13 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiButtonIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
/>
</button>
<div
class="euiModal__flex"
@ -235,24 +231,13 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11.271 11.978l3.872 3.873a.502.502 0 0 0 .708 0 .502.502 0 0 0 0-.708l-3.565-3.564c2.38-2.747 2.267-6.923-.342-9.532-2.73-2.73-7.17-2.73-9.898 0-2.728 2.729-2.728 7.17 0 9.9a6.955 6.955 0 0 0 4.949 2.05.5.5 0 0 0 0-1 5.96 5.96 0 0 1-4.242-1.757 6.01 6.01 0 0 1 0-8.486c2.337-2.34 6.143-2.34 8.484 0a6.01 6.01 0 0 1 0 8.486.5.5 0 0 0 .034.738z"
id="search-a"
/>
</defs>
<use
xlink:href="#search-a"
/>
</svg>
/>
</span>
</div>
</div>
@ -288,7 +273,7 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--large euiIcon--secondary"
class="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
@ -324,7 +309,7 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--large euiIcon--secondary"
class="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
@ -457,17 +442,13 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiButtonIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
/>
</button>
<div
class="euiModal__flex"
@ -518,24 +499,13 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11.271 11.978l3.872 3.873a.502.502 0 0 0 .708 0 .502.502 0 0 0 0-.708l-3.565-3.564c2.38-2.747 2.267-6.923-.342-9.532-2.73-2.73-7.17-2.73-9.898 0-2.728 2.729-2.728 7.17 0 9.9a6.955 6.955 0 0 0 4.949 2.05.5.5 0 0 0 0-1 5.96 5.96 0 0 1-4.242-1.757 6.01 6.01 0 0 1 0-8.486c2.337-2.34 6.143-2.34 8.484 0a6.01 6.01 0 0 1 0 8.486.5.5 0 0 0 .034.738z"
id="search-a"
/>
</defs>
<use
xlink:href="#search-a"
/>
</svg>
/>
</span>
</div>
</div>
@ -571,7 +541,7 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--large euiIcon--secondary"
class="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
@ -607,7 +577,7 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--large euiIcon--secondary"
class="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
@ -679,17 +649,13 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiButtonIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
/>
</button>
<div
class="euiModal__flex"
@ -740,24 +706,13 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11.271 11.978l3.872 3.873a.502.502 0 0 0 .708 0 .502.502 0 0 0 0-.708l-3.565-3.564c2.38-2.747 2.267-6.923-.342-9.532-2.73-2.73-7.17-2.73-9.898 0-2.728 2.729-2.728 7.17 0 9.9a6.955 6.955 0 0 0 4.949 2.05.5.5 0 0 0 0-1 5.96 5.96 0 0 1-4.242-1.757 6.01 6.01 0 0 1 0-8.486c2.337-2.34 6.143-2.34 8.484 0a6.01 6.01 0 0 1 0 8.486.5.5 0 0 0 .034.738z"
id="search-a"
/>
</defs>
<use
xlink:href="#search-a"
/>
</svg>
/>
</span>
</div>
</div>
@ -793,7 +748,7 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--large euiIcon--secondary"
class="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
@ -829,7 +784,7 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--large euiIcon--secondary"
class="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
@ -914,31 +869,23 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
size="m"
type="cross"
>
<cross
<EuiIconEmpty
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
</cross>
/>
</EuiIconEmpty>
</EuiIcon>
</button>
</EuiButtonIcon>
@ -1084,39 +1031,23 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
className="euiFormControlLayoutCustomIcon__icon"
type="search"
>
<search
<EuiIconEmpty
aria-hidden="true"
className="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11.271 11.978l3.872 3.873a.502.502 0 0 0 .708 0 .502.502 0 0 0 0-.708l-3.565-3.564c2.38-2.747 2.267-6.923-.342-9.532-2.73-2.73-7.17-2.73-9.898 0-2.728 2.729-2.728 7.17 0 9.9a6.955 6.955 0 0 0 4.949 2.05.5.5 0 0 0 0-1 5.96 5.96 0 0 1-4.242-1.757 6.01 6.01 0 0 1 0-8.486c2.337-2.34 6.143-2.34 8.484 0a6.01 6.01 0 0 1 0 8.486.5.5 0 0 0 .034.738z"
id="search-a"
/>
</defs>
<use
xlinkHref="#search-a"
/>
</svg>
</search>
/>
</EuiIconEmpty>
</EuiIcon>
</span>
</EuiFormControlLayoutCustomIcon>
@ -1224,27 +1155,23 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
size="l"
type="empty"
>
<empty
<EuiIconEmpty
aria-hidden="true"
className="euiIcon euiIcon--large euiIcon--secondary"
className="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--large euiIcon--secondary"
className="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
/>
</empty>
</EuiIconEmpty>
</EuiIcon>
</VisTypeIcon>
</div>
@ -1322,27 +1249,23 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
size="l"
type="empty"
>
<empty
<EuiIconEmpty
aria-hidden="true"
className="euiIcon euiIcon--large euiIcon--secondary"
className="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--large euiIcon--secondary"
className="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
/>
</empty>
</EuiIconEmpty>
</EuiIcon>
</VisTypeIcon>
</div>
@ -1618,17 +1541,13 @@ exports[`NewVisModal should render as expected 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiButtonIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
/>
</button>
<div
class="euiModal__flex"
@ -1679,24 +1598,13 @@ exports[`NewVisModal should render as expected 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11.271 11.978l3.872 3.873a.502.502 0 0 0 .708 0 .502.502 0 0 0 0-.708l-3.565-3.564c2.38-2.747 2.267-6.923-.342-9.532-2.73-2.73-7.17-2.73-9.898 0-2.728 2.729-2.728 7.17 0 9.9a6.955 6.955 0 0 0 4.949 2.05.5.5 0 0 0 0-1 5.96 5.96 0 0 1-4.242-1.757 6.01 6.01 0 0 1 0-8.486c2.337-2.34 6.143-2.34 8.484 0a6.01 6.01 0 0 1 0 8.486.5.5 0 0 0 .034.738z"
id="search-a"
/>
</defs>
<use
xlink:href="#search-a"
/>
</svg>
/>
</span>
</div>
</div>
@ -1730,7 +1638,7 @@ exports[`NewVisModal should render as expected 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--large euiIcon--secondary"
class="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
@ -1765,7 +1673,7 @@ exports[`NewVisModal should render as expected 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--large euiIcon--secondary"
class="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
@ -1898,17 +1806,13 @@ exports[`NewVisModal should render as expected 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiButtonIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
/>
</button>
<div
class="euiModal__flex"
@ -1959,24 +1863,13 @@ exports[`NewVisModal should render as expected 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11.271 11.978l3.872 3.873a.502.502 0 0 0 .708 0 .502.502 0 0 0 0-.708l-3.565-3.564c2.38-2.747 2.267-6.923-.342-9.532-2.73-2.73-7.17-2.73-9.898 0-2.728 2.729-2.728 7.17 0 9.9a6.955 6.955 0 0 0 4.949 2.05.5.5 0 0 0 0-1 5.96 5.96 0 0 1-4.242-1.757 6.01 6.01 0 0 1 0-8.486c2.337-2.34 6.143-2.34 8.484 0a6.01 6.01 0 0 1 0 8.486.5.5 0 0 0 .034.738z"
id="search-a"
/>
</defs>
<use
xlink:href="#search-a"
/>
</svg>
/>
</span>
</div>
</div>
@ -2010,7 +1903,7 @@ exports[`NewVisModal should render as expected 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--large euiIcon--secondary"
class="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
@ -2045,7 +1938,7 @@ exports[`NewVisModal should render as expected 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--large euiIcon--secondary"
class="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
@ -2117,17 +2010,13 @@ exports[`NewVisModal should render as expected 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiButtonIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
/>
</button>
<div
class="euiModal__flex"
@ -2178,24 +2067,13 @@ exports[`NewVisModal should render as expected 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11.271 11.978l3.872 3.873a.502.502 0 0 0 .708 0 .502.502 0 0 0 0-.708l-3.565-3.564c2.38-2.747 2.267-6.923-.342-9.532-2.73-2.73-7.17-2.73-9.898 0-2.728 2.729-2.728 7.17 0 9.9a6.955 6.955 0 0 0 4.949 2.05.5.5 0 0 0 0-1 5.96 5.96 0 0 1-4.242-1.757 6.01 6.01 0 0 1 0-8.486c2.337-2.34 6.143-2.34 8.484 0a6.01 6.01 0 0 1 0 8.486.5.5 0 0 0 .034.738z"
id="search-a"
/>
</defs>
<use
xlink:href="#search-a"
/>
</svg>
/>
</span>
</div>
</div>
@ -2229,7 +2107,7 @@ exports[`NewVisModal should render as expected 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--large euiIcon--secondary"
class="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
@ -2264,7 +2142,7 @@ exports[`NewVisModal should render as expected 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--large euiIcon--secondary"
class="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
@ -2349,31 +2227,23 @@ exports[`NewVisModal should render as expected 1`] = `
size="m"
type="cross"
>
<cross
<EuiIconEmpty
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
</cross>
/>
</EuiIconEmpty>
</EuiIcon>
</button>
</EuiButtonIcon>
@ -2519,39 +2389,23 @@ exports[`NewVisModal should render as expected 1`] = `
className="euiFormControlLayoutCustomIcon__icon"
type="search"
>
<search
<EuiIconEmpty
aria-hidden="true"
className="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11.271 11.978l3.872 3.873a.502.502 0 0 0 .708 0 .502.502 0 0 0 0-.708l-3.565-3.564c2.38-2.747 2.267-6.923-.342-9.532-2.73-2.73-7.17-2.73-9.898 0-2.728 2.729-2.728 7.17 0 9.9a6.955 6.955 0 0 0 4.949 2.05.5.5 0 0 0 0-1 5.96 5.96 0 0 1-4.242-1.757 6.01 6.01 0 0 1 0-8.486c2.337-2.34 6.143-2.34 8.484 0a6.01 6.01 0 0 1 0 8.486.5.5 0 0 0 .034.738z"
id="search-a"
/>
</defs>
<use
xlinkHref="#search-a"
/>
</svg>
</search>
/>
</EuiIconEmpty>
</EuiIcon>
</span>
</EuiFormControlLayoutCustomIcon>
@ -2647,27 +2501,23 @@ exports[`NewVisModal should render as expected 1`] = `
size="l"
type="empty"
>
<empty
<EuiIconEmpty
aria-hidden="true"
className="euiIcon euiIcon--large euiIcon--secondary"
className="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--large euiIcon--secondary"
className="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
/>
</empty>
</EuiIconEmpty>
</EuiIcon>
</VisTypeIcon>
</div>
@ -2745,27 +2595,23 @@ exports[`NewVisModal should render as expected 1`] = `
size="l"
type="empty"
>
<empty
<EuiIconEmpty
aria-hidden="true"
className="euiIcon euiIcon--large euiIcon--secondary"
className="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--large euiIcon--secondary"
className="euiIcon euiIcon--large euiIcon--secondary euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
/>
</empty>
</EuiIconEmpty>
</EuiIcon>
</VisTypeIcon>
</div>

View file

@ -0,0 +1,40 @@
/*
* 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 { MappingProperties } from 'src/legacy/server/mappings';
import { SavedObjectsSchemaDefinition } from '../../schema';
/*
* This file contains logic to convert savedObjectSchemas into a dictonary of indexes and documents
*/
export function createIndexMap(
defaultIndex: string,
savedObjectSchemas: SavedObjectsSchemaDefinition,
indexMap: MappingProperties
) {
const map: { [index: string]: MappingProperties } = {};
Object.keys(indexMap).forEach(type => {
const indexPattern = (savedObjectSchemas[type] || {}).indexPattern || defaultIndex;
if (!map.hasOwnProperty(indexPattern as string)) {
map[indexPattern] = {};
}
map[indexPattern][type] = indexMap[type];
});
return map;
}

View file

@ -61,14 +61,12 @@ describe('KibanaMigrator', () => {
const { kbnServer } = mockKbnServer();
kbnServer.server.plugins.elasticsearch = undefined;
const result = await new KibanaMigrator({ kbnServer }).awaitMigration();
expect(result).toEqual({ status: 'skipped' });
expect(result).toEqual([{ status: 'skipped' }, { status: 'skipped' }]);
});
it('waits for kbnServer.ready and elasticsearch.ready before attempting migrations', async () => {
const { kbnServer } = mockKbnServer();
const clusterStub = jest.fn<any, any>(() => {
throw new Error('Doh!');
});
const clusterStub = jest.fn<any, any>(() => ({ status: 404 }));
const waitUntilReady = jest.fn(async () => undefined);
kbnServer.server.plugins.elasticsearch = {
@ -83,7 +81,8 @@ describe('KibanaMigrator', () => {
},
};
await expect(new KibanaMigrator({ kbnServer }).awaitMigration()).rejects.toThrow(/Doh!/);
const migrationResults = await new KibanaMigrator({ kbnServer }).awaitMigration();
expect(migrationResults.length).toEqual(2);
});
});
});
@ -94,11 +93,37 @@ function mockKbnServer({ configValues }: { configValues?: any } = {}) {
version: '8.2.3',
ready: jest.fn(async () => undefined),
uiExports: {
savedObjectsManagement: {},
savedObjectValidations: {},
savedObjectMigrations: {},
savedObjectMappings: [],
savedObjectSchemas: {},
savedObjectsManagement: {},
savedObjectMappings: [
{
pluginId: 'testtype',
properties: {
testtype: {
properties: {
name: { type: 'keyword' },
},
},
},
},
{
pluginId: 'testtype2',
properties: {
testtype2: {
properties: {
name: { type: 'keyword' },
},
},
},
},
],
savedObjectSchemas: {
testtype2: {
isNamespaceAgnostic: false,
indexPattern: 'other-index',
},
},
},
server: {
config: () => ({

View file

@ -30,7 +30,7 @@ import { RawSavedObjectDoc, SavedObjectsSerializer } from '../../serialization';
import { docValidator } from '../../validation';
import { buildActiveMappings, CallCluster, IndexMigrator, LogFn } from '../core';
import { DocumentMigrator, VersionedTransformer } from '../core/document_migrator';
import { createIndexMap } from '../core/build_index_map';
export interface KbnServer {
server: Server;
version: string;
@ -86,27 +86,39 @@ export class KibanaMigrator {
['warning', 'migration'],
'The elasticsearch plugin is disabled. Skipping migrations.'
);
return { status: 'skipped' };
return Object.keys(this.mappingProperties).map(() => ({ status: 'skipped' }));
}
// Wait until elasticsearch is green...
await server.plugins.elasticsearch.waitUntilReady();
const config = server.config();
const migrator = new IndexMigrator({
batchSize: config.get('migrations.batchSize'),
callCluster: server.plugins.elasticsearch!.getCluster('admin').callWithInternalUser,
documentMigrator: this.documentMigrator,
index: config.get('kibana.index'),
log: this.log,
mappingProperties: this.mappingProperties,
pollInterval: config.get('migrations.pollInterval'),
scrollDuration: config.get('migrations.scrollDuration'),
serializer: this.serializer,
obsoleteIndexTemplatePattern: 'kibana_index_template*',
const indexMap = createIndexMap(
config.get('kibana.index'),
this.kbnServer.uiExports.savedObjectSchemas,
this.mappingProperties
);
const migrators = Object.keys(indexMap).map(index => {
return new IndexMigrator({
batchSize: config.get('migrations.batchSize'),
callCluster: server.plugins.elasticsearch!.getCluster('admin').callWithInternalUser,
documentMigrator: this.documentMigrator,
index,
log: this.log,
mappingProperties: indexMap[index],
pollInterval: config.get('migrations.pollInterval'),
scrollDuration: config.get('migrations.scrollDuration'),
serializer: this.serializer,
obsoleteIndexTemplatePattern: 'kibana_index_template*',
});
});
return migrator.migrate();
if (migrators.length === 0) {
throw new Error(`Migrations failed to run, no mappings found or Kibana is not "ready".`);
}
return Promise.all(migrators.map(migrator => migrator.migrate()));
});
private kbnServer: KbnServer;
@ -124,11 +136,15 @@ export class KibanaMigrator {
*/
constructor({ kbnServer }: { kbnServer: KbnServer }) {
this.kbnServer = kbnServer;
this.serializer = new SavedObjectsSerializer(
new SavedObjectsSchema(kbnServer.uiExports.savedObjectSchemas)
);
this.mappingProperties = mergeProperties(kbnServer.uiExports.savedObjectMappings || []);
this.log = (meta: string[], message: string) => kbnServer.server.log(meta, message);
this.documentMigrator = new DocumentMigrator({
kibanaVersion: kbnServer.version,
migrations: kbnServer.uiExports.savedObjectMigrations || {},
@ -138,7 +154,7 @@ export class KibanaMigrator {
}
/**
* Gets the index mappings defined by Kibana's enabled plugins.
* Gets all the index mappings defined by Kibana's enabled plugins.
*
* @returns
* @memberof KibanaMigrator

View file

@ -17,6 +17,10 @@
* under the License.
*/
jest.mock('../export', () => ({
getSortedObjectsForExport: jest.fn(),
}));
import Hapi from 'hapi';
import * as exportMock from '../export';
import { createMockServer } from './_mock_server';
@ -24,10 +28,6 @@ import { createExportRoute } from './export';
const getSortedObjectsForExport = exportMock.getSortedObjectsForExport as jest.Mock;
jest.mock('../export', () => ({
getSortedObjectsForExport: jest.fn(),
}));
describe('POST /api/saved_objects/_export', () => {
let server: Hapi.Server;
const savedObjectsClient = {

View file

@ -67,6 +67,9 @@ describe('Saved Objects Mixin', () => {
hiddentype: {
hidden: true,
},
doc1: {
indexPattern: 'other-index',
},
},
savedObjectMappings: [
{
@ -79,6 +82,21 @@ describe('Saved Objects Mixin', () => {
},
},
},
{
pluginId: 'testtype2',
properties: {
doc1: {
properties: {
name: { type: 'keyword' },
},
},
doc2: {
properties: {
name: { type: 'keyword' },
},
},
},
},
{
pluginId: 'secretPlugin',
properties: {
@ -198,7 +216,7 @@ describe('Saved Objects Mixin', () => {
it('should return all but hidden types', () => {
expect(service).toBeDefined();
expect(service.types).toEqual(['config', 'testtype']);
expect(service.types).toEqual(['config', 'testtype', 'doc1', 'doc2']);
});
const mockCallEs = jest.fn();
@ -212,7 +230,7 @@ describe('Saved Objects Mixin', () => {
it('should create a repository without hidden types', () => {
const repository = service.getSavedObjectsRepository(mockCallEs);
expect(repository).toBeDefined();
expect(repository._allowedTypes).toEqual(['config', 'testtype']);
expect(repository._allowedTypes).toEqual(['config', 'testtype', 'doc1', 'doc2']);
});
it('should create a repository with a unique list of allowed types', () => {
@ -221,7 +239,7 @@ describe('Saved Objects Mixin', () => {
'config',
'config',
]);
expect(repository._allowedTypes).toEqual(['config', 'testtype']);
expect(repository._allowedTypes).toEqual(['config', 'testtype', 'doc1', 'doc2']);
});
it('should create a repository with extraTypes minus duplicate', () => {
@ -229,7 +247,13 @@ describe('Saved Objects Mixin', () => {
'hiddentype',
'hiddentype',
]);
expect(repository._allowedTypes).toEqual(['config', 'testtype', 'hiddentype']);
expect(repository._allowedTypes).toEqual([
'config',
'testtype',
'doc1',
'doc2',
'hiddentype',
]);
});
it('should not allow a repository without a callCluster function', () => {

View file

@ -20,6 +20,7 @@
interface SavedObjectsSchemaTypeDefinition {
isNamespaceAgnostic: boolean;
hidden?: boolean;
indexPattern?: string;
}
export interface SavedObjectsSchemaDefinition {

View file

@ -26,7 +26,22 @@ export interface SavedObjectsRepositoryOptions {
schema: unknown;
serializer: unknown;
migrator: unknown;
onBeforeWrite: unknown;
onBeforeWrite?: (
action: 'create' | 'index' | 'update' | 'bulk' | 'delete' | 'deleteByQuery',
params: {
index: string;
id?: string;
body: any;
}
) => void;
onBeforeRead?: (
action: 'get' | 'bulk',
params: {
index: string;
id?: string;
body: any;
}
) => void;
}
export declare class SavedObjectsRepository {

View file

@ -17,7 +17,7 @@
* under the License.
*/
import { omit } from 'lodash';
import { omit, flatten } from 'lodash';
import { getRootPropertiesObjects } from '../../../mappings';
import { getSearchDsl } from './search_dsl';
import { includedFields } from './included_fields';
@ -39,6 +39,7 @@ export class SavedObjectsRepository {
migrator,
allowedTypes = [],
onBeforeWrite = () => {},
onBeforeRead = () => {},
} = options;
// It's important that we migrate documents / mark them as up-to-date
@ -58,6 +59,8 @@ export class SavedObjectsRepository {
this._allowedTypes = allowedTypes;
this._onBeforeWrite = onBeforeWrite;
this._onBeforeRead = onBeforeRead;
this._unwrappedCallCluster = async (...args) => {
await migrator.awaitMigration();
return callCluster(...args);
@ -104,7 +107,7 @@ export class SavedObjectsRepository {
const response = await this._writeToCluster(method, {
id: raw._id,
index: this._index,
index: this._getIndexForType(type),
refresh: 'wait_for',
body: raw._source,
});
@ -170,6 +173,7 @@ export class SavedObjectsRepository {
{
[method]: {
_id: expectedResult.rawMigratedDoc._id,
_index: this._getIndexForType(object.type),
},
},
expectedResult.rawMigratedDoc._source
@ -179,7 +183,6 @@ export class SavedObjectsRepository {
});
const esResponse = await this._writeToCluster('bulk', {
index: this._index,
refresh: 'wait_for',
body: bulkCreateParams,
});
@ -251,7 +254,7 @@ export class SavedObjectsRepository {
const response = await this._writeToCluster('delete', {
id: this._serializer.generateRawId(namespace, type, id),
index: this._index,
index: this._getIndexForType(type),
refresh: 'wait_for',
ignore: [404],
});
@ -288,8 +291,16 @@ export class SavedObjectsRepository {
const typesToDelete = allTypes.filter(type => !this._schema.isNamespaceAgnostic(type));
const indexes = flatten(
Object.values(this._schema).map(schema =>
Object.values(schema).map(props => props.indexPattern)
)
)
.filter(pattern => pattern !== undefined)
.concat([this._index]);
const esOptions = {
index: this._index,
index: indexes,
ignore: [404],
refresh: 'wait_for',
body: {
@ -369,7 +380,7 @@ export class SavedObjectsRepository {
}
const esOptions = {
index: this._index,
index: this._getIndexForType(type),
size: perPage,
from: perPage * (page - 1),
_source: includedFields(type, fields),
@ -434,12 +445,12 @@ export class SavedObjectsRepository {
const unsupportedTypes = [];
const response = await this._callCluster('mget', {
index: this._index,
body: {
docs: objects.reduce((acc, { type, id, fields }) => {
if (this._isTypeAllowed(type)) {
acc.push({
_id: this._serializer.generateRawId(namespace, type, id),
_index: this._getIndexForType(type),
_source: includedFields(type, fields),
});
} else {
@ -500,7 +511,7 @@ export class SavedObjectsRepository {
const response = await this._callCluster('get', {
id: this._serializer.generateRawId(namespace, type, id),
index: this._index,
index: this._getIndexForType(type),
ignore: [404],
});
@ -545,7 +556,7 @@ export class SavedObjectsRepository {
const time = this._getCurrentTime();
const response = await this._writeToCluster('update', {
id: this._serializer.generateRawId(namespace, type, id),
index: this._index,
index: this._getIndexForType(type),
...(version && decodeRequestVersion(version)),
refresh: 'wait_for',
ignore: [404],
@ -610,7 +621,7 @@ export class SavedObjectsRepository {
const response = await this._writeToCluster('update', {
id: this._serializer.generateRawId(namespace, type, id),
index: this._index,
index: this._getIndexForType(type),
refresh: 'wait_for',
_source: true,
body: {
@ -648,7 +659,16 @@ export class SavedObjectsRepository {
async _writeToCluster(method, params) {
try {
await this._onBeforeWrite();
await this._onBeforeWrite(method, params);
return await this._callCluster(method, params);
} catch (err) {
throw decorateEsError(err);
}
}
async _readFromCluster(method, params) {
try {
await this._onBeforeRead(method, params);
return await this._callCluster(method, params);
} catch (err) {
throw decorateEsError(err);
@ -663,6 +683,15 @@ export class SavedObjectsRepository {
}
}
_getIndexForType(type) {
return (
(this._schema.definition &&
this._schema.definition[type] &&
this._schema.definition[type].indexPattern) ||
this._index
);
}
_getCurrentTime() {
return new Date().toISOString();
}

View file

@ -214,6 +214,11 @@ describe('SavedObjectsRepository', () => {
type: 'keyword',
},
},
baz: {
properties: {
type: 'keyword',
},
},
'index-pattern': {
properties: {
someField: {
@ -249,6 +254,7 @@ describe('SavedObjectsRepository', () => {
globaltype: { isNamespaceAgnostic: true },
foo: { isNamespaceAgnostic: true },
bar: { isNamespaceAgnostic: true },
baz: { indexPattern: 'beats' },
hiddenType: { isNamespaceAgnostic: true, hidden: true },
});
@ -358,6 +364,36 @@ describe('SavedObjectsRepository', () => {
expect(onBeforeWrite).toHaveBeenCalledTimes(1);
});
it('should use default index', async () => {
await savedObjectsRepository.create('index-pattern', {
id: 'logstash-*',
title: 'Logstash',
});
expect(onBeforeWrite).toHaveBeenCalledTimes(1);
expect(onBeforeWrite).toHaveBeenCalledWith(
'index',
expect.objectContaining({
index: '.kibana-test',
})
);
});
it('should use custom index', async () => {
await savedObjectsRepository.create('baz', {
id: 'logstash-*',
title: 'Logstash',
});
expect(onBeforeWrite).toHaveBeenCalledTimes(1);
expect(onBeforeWrite).toHaveBeenCalledWith(
'index',
expect.objectContaining({
index: 'beats',
})
);
});
it('migrates the doc', async () => {
migrator.migrateDocument = doc => {
doc.attributes.title = doc.attributes.title + '!!';
@ -572,14 +608,14 @@ describe('SavedObjectsRepository', () => {
expect(bulkCalls.length).toEqual(1);
expect(bulkCalls[0][1].body).toEqual([
{ create: { _id: 'config:one' } },
{ create: { _index: '.kibana-test', _id: 'config:one' } },
{
type: 'config',
...mockTimestampFields,
config: { title: 'Test One' },
references: [{ name: 'ref_0', type: 'test', id: '1' }],
},
{ create: { _id: 'index-pattern:two' } },
{ create: { _index: '.kibana-test', _id: 'index-pattern:two' } },
{
type: 'index-pattern',
...mockTimestampFields,
@ -629,7 +665,7 @@ describe('SavedObjectsRepository', () => {
'bulk',
expect.objectContaining({
body: [
{ create: { _id: 'config:one' } },
{ create: { _index: '.kibana-test', _id: 'config:one' } },
{
type: 'config',
...mockTimestampFields,
@ -637,7 +673,7 @@ describe('SavedObjectsRepository', () => {
migrationVersion: { foo: '2.3.4' },
references: [{ name: 'search_0', type: 'search', id: '123' }],
},
{ create: { _id: 'index-pattern:two' } },
{ create: { _index: '.kibana-test', _id: 'index-pattern:two' } },
{
type: 'index-pattern',
...mockTimestampFields,
@ -689,7 +725,7 @@ describe('SavedObjectsRepository', () => {
expect.objectContaining({
body: [
// uses create because overwriting is not allowed
{ create: { _id: 'foo:bar' } },
{ create: { _index: '.kibana-test', _id: 'foo:bar' } },
{ type: 'foo', ...mockTimestampFields, foo: {}, references: [] },
],
})
@ -713,7 +749,7 @@ describe('SavedObjectsRepository', () => {
expect.objectContaining({
body: [
// uses index because overwriting is allowed
{ index: { _id: 'foo:bar' } },
{ index: { _index: '.kibana-test', _id: 'foo:bar' } },
{ type: 'foo', ...mockTimestampFields, foo: {}, references: [] },
],
})
@ -829,6 +865,7 @@ describe('SavedObjectsRepository', () => {
create: {
_type: '_doc',
_id: 'foo-namespace:config:one',
_index: '.kibana-test',
_primary_term: 1,
_seq_no: 2,
},
@ -857,7 +894,7 @@ describe('SavedObjectsRepository', () => {
'bulk',
expect.objectContaining({
body: [
{ create: { _id: 'foo-namespace:config:one' } },
{ create: { _index: '.kibana-test', _id: 'foo-namespace:config:one' } },
{
namespace: 'foo-namespace',
type: 'config',
@ -865,7 +902,7 @@ describe('SavedObjectsRepository', () => {
config: { title: 'Test One' },
references: [],
},
{ create: { _id: 'foo-namespace:index-pattern:two' } },
{ create: { _index: '.kibana-test', _id: 'foo-namespace:index-pattern:two' } },
{
namespace: 'foo-namespace',
type: 'index-pattern',
@ -908,14 +945,14 @@ describe('SavedObjectsRepository', () => {
'bulk',
expect.objectContaining({
body: [
{ create: { _id: 'config:one' } },
{ create: { _id: 'config:one', _index: '.kibana-test' } },
{
type: 'config',
...mockTimestampFields,
config: { title: 'Test One' },
references: [],
},
{ create: { _id: 'index-pattern:two' } },
{ create: { _id: 'index-pattern:two', _index: '.kibana-test' } },
{
type: 'index-pattern',
...mockTimestampFields,
@ -943,7 +980,7 @@ describe('SavedObjectsRepository', () => {
'bulk',
expect.objectContaining({
body: [
{ create: { _id: 'globaltype:one' } },
{ create: { _id: 'globaltype:one', _index: '.kibana-test' } },
{
type: 'globaltype',
...mockTimestampFields,
@ -1063,13 +1100,13 @@ describe('SavedObjectsRepository', () => {
expect(getSearchDslNS.getSearchDsl).toHaveBeenCalledWith(mappings, schema, {
namespace: 'my-namespace',
type: ['config', 'index-pattern', 'dashboard'],
type: ['config', 'baz', 'index-pattern', 'dashboard'],
});
expect(callAdminCluster).toHaveBeenCalledWith('deleteByQuery', {
body: { conflicts: 'proceed' },
ignore: [404],
index: '.kibana-test',
index: ['beats', '.kibana-test'],
refresh: 'wait_for',
});
});
@ -1401,9 +1438,9 @@ describe('SavedObjectsRepository', () => {
expect.objectContaining({
body: {
docs: [
{ _id: 'config:one' },
{ _id: 'index-pattern:two' },
{ _id: 'globaltype:three' },
{ _id: 'config:one', _index: '.kibana-test' },
{ _id: 'index-pattern:two', _index: '.kibana-test' },
{ _id: 'globaltype:three', _index: '.kibana-test' },
],
},
})
@ -1432,9 +1469,9 @@ describe('SavedObjectsRepository', () => {
expect.objectContaining({
body: {
docs: [
{ _id: 'foo-namespace:config:one' },
{ _id: 'foo-namespace:index-pattern:two' },
{ _id: 'globaltype:three' },
{ _id: 'foo-namespace:config:one', _index: '.kibana-test' },
{ _id: 'foo-namespace:index-pattern:two', _index: '.kibana-test' },
{ _id: 'globaltype:three', _index: '.kibana-test' },
],
},
})
@ -1966,6 +2003,14 @@ describe('SavedObjectsRepository', () => {
});
});
describe('types on custom index', () => {
it("should error when attempting to 'update' an unsupported type", async () => {
await expect(
savedObjectsRepository.update('hiddenType', 'bogus', { title: 'some title' })
).rejects.toEqual(new Error('Saved object [hiddenType/bogus] not found'));
});
});
describe('unsupported types', () => {
it("should error when attempting to 'update' an unsupported type", async () => {
await expect(

View file

@ -274,40 +274,23 @@ exports[`InspectorPanel should render as expected 1`] = `
size="m"
type="arrowDown"
>
<arrowDown
<EuiIconEmpty
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonEmpty__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonEmpty__icon"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonEmpty__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonEmpty__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
</arrowDown>
/>
</EuiIconEmpty>
</EuiIcon>
<span
className="euiButtonEmpty__text"

View file

@ -26,25 +26,13 @@ exports[`<EditorOptionsGroup/> renders as expected 1`] = `
class="euiFlexItem euiFlexItem--flexGrowZero euiAccordion__iconWrapper"
>
<svg
class="euiIcon euiIcon--medium"
class="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fill-rule="nonzero"
href="#arrow_down-a"
/>
</svg>
/>
</div>
<div
class="euiFlexItem euiAccordion__buttonContent"
@ -109,25 +97,13 @@ exports[`<EditorOptionsGroup/> renders as expected with actions 1`] = `
class="euiFlexItem euiFlexItem--flexGrowZero euiAccordion__iconWrapper"
>
<svg
class="euiIcon euiIcon--medium"
class="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fill-rule="nonzero"
href="#arrow_down-a"
/>
</svg>
/>
</div>
<div
class="euiFlexItem euiAccordion__buttonContent"
@ -151,24 +127,13 @@ exports[`<EditorOptionsGroup/> renders as expected with actions 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiButtonIcon__icon"
class="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M11 3h5v1H0V3h5V1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2zm-7.056 8H7v1H4.1l.392 2.519c.042.269.254.458.493.458h6.03c.239 0 .451-.189.493-.458l1.498-9.576H14l-1.504 9.73c-.116.747-.74 1.304-1.481 1.304h-6.03c-.741 0-1.365-.557-1.481-1.304l-1.511-9.73H9V5.95H3.157L3.476 8H8v1H3.632l.312 2zM6 3h4V1H6v2z"
id="trash-a"
/>
</defs>
<use
href="#trash-a"
/>
</svg>
/>
</button>
</div>
</div>
@ -219,26 +184,13 @@ exports[`<EditorOptionsGroup/> renders as expected with initial collapsed 1`] =
class="euiFlexItem euiFlexItem--flexGrowZero euiAccordion__iconWrapper"
>
<svg
class="euiIcon euiIcon--medium"
class="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fill-rule="nonzero"
href="#arrow_right-a"
transform="matrix(0 1 1 0 0 0)"
/>
</svg>
/>
</div>
<div
class="euiFlexItem euiAccordion__buttonContent"

View file

@ -23,7 +23,7 @@ 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 $ from 'jquery';
import { VislibVisualizationsTimeMarkerProvider } from '../../visualizations/time_marker';
import { TimeMarker } from '../../visualizations/time_marker';
describe('Vislib Time Marker Test Suite', function () {
const height = 50;
@ -49,7 +49,6 @@ describe('Vislib Time Marker Test Suite', function () {
});
};
const times = [];
let TimeMarker;
let defaultMarker;
let customMarker;
let selection;
@ -59,8 +58,7 @@ describe('Vislib Time Marker Test Suite', function () {
let domain;
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
TimeMarker = Private(VislibVisualizationsTimeMarkerProvider);
beforeEach(ngMock.inject(function () {
minDomain = getExtent(series.series, d3.min);
maxDomain = getExtent(series.series, d3.max);
domain = [minDomain, maxDomain];

View file

@ -22,7 +22,7 @@ import _ from 'lodash';
import $ from 'jquery';
import { VislibLibErrorHandlerProvider } from '../_error_handler';
import { VislibLibAxisTitleProvider } from './axis_title';
import { VislibAxisLabelsProvider } from './axis_labels';
import { AxisLabels } from './axis_labels';
import { VislibAxisScaleProvider } from './axis_scale';
import { VislibLibAxisConfigProvider } from './axis_config';
import { VislibError } from '../../../errors';
@ -30,7 +30,6 @@ import { VislibError } from '../../../errors';
export function VislibLibAxisProvider(Private) {
const ErrorHandler = Private(VislibLibErrorHandlerProvider);
const AxisTitle = Private(VislibLibAxisTitleProvider);
const AxisLabels = Private(VislibAxisLabelsProvider);
const AxisScale = Private(VislibAxisScaleProvider);
const AxisConfig = Private(VislibLibAxisConfigProvider);

View file

@ -21,125 +21,121 @@ import d3 from 'd3';
import $ from 'jquery';
import { truncateLabel } from '../../components/labels/truncate_labels';
export function VislibAxisLabelsProvider() {
class AxisLabels {
constructor(axisConfig, scale) {
this.axisConfig = axisConfig;
this.axisScale = scale;
}
render(selection) {
selection.call(this.draw());
}
rotateAxisLabels() {
const config = this.axisConfig;
return function (selection) {
const text = selection.selectAll('.tick text');
if (config.get('labels.rotate')) {
text
.style('text-anchor', function () {
const currentValue = $(this).css('text-anchor');
const rotateDeg = config.get('labels.rotate');
if (!rotateDeg) return currentValue;
else {
const position = config.get('position');
switch (position) {
case 'top': return 'end';
case 'bottom': return 'end';
default:
if (rotateDeg === 90 || rotateDeg === -90) return 'middle';
return currentValue;
}
}
})
.attr('dy', function () {
return config.isHorizontal() ? '0.3em' : '0';
})
.attr('transform', function rotate(d, j) {
const position = config.get('position');
const rotateDeg = position === 'top' ? config.get('labels.rotate') : -config.get('labels.rotate');
if ($(this).css('text-anchor') === 'middle') {
const coord = text[0][j].getBBox();
const transX = ((coord.x) + (coord.width / 2));
const transY = ((coord.y) + (coord.height / 2));
return `rotate(${rotateDeg}, ${transX}, ${transY})`;
} else {
const transX = this.attributes.x.nodeValue;
const transY = this.attributes.y.nodeValue;
return `rotate(${rotateDeg}, ${transX}, ${transY})`;
}
});
}
};
}
truncateLabels() {
const config = this.axisConfig;
return function (selection) {
if (!config.get('labels.truncate')) return;
selection.selectAll('.tick text')
.text(function () {
return truncateLabel(this, config.get('labels.truncate'));
});
};
}
filterAxisLabels() {
const self = this;
const config = this.axisConfig;
let startPos = 0;
const padding = 1.1;
return function (selection) {
if (!config.get('labels.filter')) return;
const el = $(config.get('rootEl')).find(config.get('elSelector'));
const maxSize = config.isHorizontal() ? el.width() : el.height();
const scaleRange = self.axisScale.scale.range();
const scaleWidth = Math.abs(scaleRange[scaleRange.length - 1] - scaleRange[0]);
const scaleStartPad = .5 * (maxSize - scaleWidth);
selection.selectAll('.tick text')
.text(function (d) {
const par = d3.select(this.parentNode).node();
const myPos = scaleStartPad + self.axisScale.scale(d);
const mySize = (config.isHorizontal() ? par.getBBox().width : par.getBBox().height) * padding;
const halfSize = mySize / 2;
if ((startPos + halfSize) < myPos && maxSize > (myPos + halfSize)) {
startPos = myPos + halfSize;
return this.textContent;
} else {
d3.select(this.parentNode).remove();
}
});
};
}
draw() {
const self = this;
const config = this.axisConfig;
return function (selection) {
selection.each(function () {
selection.selectAll('text')
.attr('style', function () {
const currentStyle = d3.select(this).attr('style');
return `${currentStyle} font-size: ${config.get('labels.fontSize')};`;
});
if (!config.get('labels.show')) selection.selectAll('text').attr('style', 'display: none;');
selection.call(self.truncateLabels());
selection.call(self.rotateAxisLabels());
selection.call(self.filterAxisLabels());
});
};
}
export class AxisLabels {
constructor(axisConfig, scale) {
this.axisConfig = axisConfig;
this.axisScale = scale;
}
return AxisLabels;
render(selection) {
selection.call(this.draw());
}
rotateAxisLabels() {
const config = this.axisConfig;
return function (selection) {
const text = selection.selectAll('.tick text');
if (config.get('labels.rotate')) {
text
.style('text-anchor', function () {
const currentValue = $(this).css('text-anchor');
const rotateDeg = config.get('labels.rotate');
if (!rotateDeg) return currentValue;
else {
const position = config.get('position');
switch (position) {
case 'top': return 'end';
case 'bottom': return 'end';
default:
if (rotateDeg === 90 || rotateDeg === -90) return 'middle';
return currentValue;
}
}
})
.attr('dy', function () {
return config.isHorizontal() ? '0.3em' : '0';
})
.attr('transform', function rotate(d, j) {
const position = config.get('position');
const rotateDeg = position === 'top' ? config.get('labels.rotate') : -config.get('labels.rotate');
if ($(this).css('text-anchor') === 'middle') {
const coord = text[0][j].getBBox();
const transX = ((coord.x) + (coord.width / 2));
const transY = ((coord.y) + (coord.height / 2));
return `rotate(${rotateDeg}, ${transX}, ${transY})`;
} else {
const transX = this.attributes.x.nodeValue;
const transY = this.attributes.y.nodeValue;
return `rotate(${rotateDeg}, ${transX}, ${transY})`;
}
});
}
};
}
truncateLabels() {
const config = this.axisConfig;
return function (selection) {
if (!config.get('labels.truncate')) return;
selection.selectAll('.tick text')
.text(function () {
return truncateLabel(this, config.get('labels.truncate'));
});
};
}
filterAxisLabels() {
const self = this;
const config = this.axisConfig;
let startPos = 0;
const padding = 1.1;
return function (selection) {
if (!config.get('labels.filter')) return;
const el = $(config.get('rootEl')).find(config.get('elSelector'));
const maxSize = config.isHorizontal() ? el.width() : el.height();
const scaleRange = self.axisScale.scale.range();
const scaleWidth = Math.abs(scaleRange[scaleRange.length - 1] - scaleRange[0]);
const scaleStartPad = .5 * (maxSize - scaleWidth);
selection.selectAll('.tick text')
.text(function (d) {
const par = d3.select(this.parentNode).node();
const myPos = scaleStartPad + self.axisScale.scale(d);
const mySize = (config.isHorizontal() ? par.getBBox().width : par.getBBox().height) * padding;
const halfSize = mySize / 2;
if ((startPos + halfSize) < myPos && maxSize > (myPos + halfSize)) {
startPos = myPos + halfSize;
return this.textContent;
} else {
d3.select(this.parentNode).remove();
}
});
};
}
draw() {
const self = this;
const config = this.axisConfig;
return function (selection) {
selection.each(function () {
selection.selectAll('text')
.attr('style', function () {
const currentStyle = d3.select(this).attr('style');
return `${currentStyle} font-size: ${config.get('labels.fontSize')};`;
});
if (!config.get('labels.show')) selection.selectAll('text').attr('style', 'display: none;');
selection.call(self.truncateLabels());
selection.call(self.rotateAxisLabels());
selection.call(self.filterAxisLabels());
});
};
}
}

View file

@ -21,7 +21,7 @@ import d3 from 'd3';
import _ from 'lodash';
import { dataLabel } from '../lib/_data_label';
import { VislibLibDispatchProvider } from '../lib/dispatch';
import { TooltipProvider } from '../../vis/components/tooltip';
import { Tooltip } from '../../vis/components/tooltip';
import { getFormat } from '../../visualize/loader/pipeline_helpers/utilities';
import { HierarchicalTooltipFormatterProvider } from '../../agg_response/hierarchical/_hierarchical_tooltip_formatter';
import { PointSeriesTooltipFormatter } from '../../agg_response/point_series/_tooltip_formatter';
@ -29,7 +29,6 @@ import { PointSeriesTooltipFormatter } from '../../agg_response/point_series/_to
export function VislibVisualizationsChartProvider(Private) {
const Dispatch = Private(VislibLibDispatchProvider);
const Tooltip = Private(TooltipProvider);
/**
* The Base Class for all visualizations.
*

View file

@ -19,11 +19,10 @@
import d3 from 'd3';
import { VislibVisualizationsChartProvider } from './_chart';
import { GaugeTypesProvider } from './gauges/gauge_types';
import { gaugeTypes } from './gauges/gauge_types';
export function GaugeChartProvider(Private) {
const Chart = Private(VislibVisualizationsChartProvider);
const gaugeTypes = Private(GaugeTypesProvider);
class GaugeChart extends Chart {
constructor(handler, chartEl, chartData) {

View file

@ -17,11 +17,8 @@
* under the License.
*/
import { MeterGaugeProvider } from './meter';
import { MeterGauge } from './meter';
export function GaugeTypesProvider(Private) {
return {
meter: Private(MeterGaugeProvider)
};
}
export const gaugeTypes = {
meter: MeterGauge
};

View file

@ -21,326 +21,321 @@ import d3 from 'd3';
import _ from 'lodash';
import { getHeatmapColors } from '../../components/color/heatmap_color';
export function MeterGaugeProvider() {
const defaultConfig = {
showTooltip: true,
percentageMode: true,
maxAngle: 2 * Math.PI * 1.3,
minAngle: 2 * Math.PI * 0.7,
innerSpace: 5,
extents: [0, 10000],
scale: {
show: true,
color: '#666',
width: 2,
ticks: 10,
tickLength: 8,
},
labels: {
show: true,
color: '#666'
},
style: {
bgWidth: 0.5,
width: 0.9
}
};
const defaultConfig = {
showTooltip: true,
percentageMode: true,
maxAngle: 2 * Math.PI * 1.3,
minAngle: 2 * Math.PI * 0.7,
innerSpace: 5,
extents: [0, 10000],
scale: {
show: true,
color: '#666',
width: 2,
ticks: 10,
tickLength: 8,
},
labels: {
show: true,
color: '#666'
},
style: {
bgWidth: 0.5,
width: 0.9
}
};
export class MeterGauge {
constructor(gaugeChart) {
this.gaugeChart = gaugeChart;
this.gaugeConfig = gaugeChart.gaugeConfig;
this.gaugeConfig = _.defaultsDeep(this.gaugeConfig, defaultConfig);
class MeterGauge {
constructor(gaugeChart) {
this.gaugeChart = gaugeChart;
this.gaugeConfig = gaugeChart.gaugeConfig;
this.gaugeConfig = _.defaultsDeep(this.gaugeConfig, defaultConfig);
this.gaugeChart.handler.visConfig.set('legend', {
labels: this.getLabels(),
colors: this.getColors()
});
this.gaugeChart.handler.visConfig.set('legend', {
labels: this.getLabels(),
colors: this.getColors()
});
const colors = this.gaugeChart.handler.visConfig.get('legend.colors', null);
if (colors) {
this.gaugeChart.handler.vis.uiState.setSilent('vis.defaultColors', null);
this.gaugeChart.handler.vis.uiState.setSilent('vis.defaultColors', colors);
}
this.colorFunc = this.gaugeChart.handler.data.getColorFunc();
const colors = this.gaugeChart.handler.visConfig.get('legend.colors', null);
if (colors) {
this.gaugeChart.handler.vis.uiState.setSilent('vis.defaultColors', null);
this.gaugeChart.handler.vis.uiState.setSilent('vis.defaultColors', colors);
}
getLabels() {
const isPercentageMode = this.gaugeConfig.percentageMode;
const colorsRange = this.gaugeConfig.colorsRange;
const max = _.last(colorsRange).to;
const labels = [];
colorsRange.forEach(range => {
const from = isPercentageMode ? Math.round(100 * range.from / max) : range.from;
const to = isPercentageMode ? Math.round(100 * range.to / max) : range.to;
labels.push(`${from} - ${to}`);
});
return labels;
}
getColors() {
const invertColors = this.gaugeConfig.invertColors;
const colorSchema = this.gaugeConfig.colorSchema;
const colorsRange = this.gaugeConfig.colorsRange;
const labels = this.getLabels();
const colors = {};
for (let i = 0; i < labels.length; i += 1) {
const divider = Math.max(colorsRange.length - 1, 1);
const val = invertColors ? 1 - i / divider : i / divider;
colors[labels[i]] = getHeatmapColors(val, colorSchema);
}
return colors;
}
getBucket(val) {
let bucket = _.findIndex(this.gaugeConfig.colorsRange, range => {
return range.from <= val && range.to > val;
});
if (bucket === -1) {
if (val < this.gaugeConfig.colorsRange[0].from) bucket = 0;
else bucket = this.gaugeConfig.colorsRange.length - 1;
}
return bucket;
}
getLabel(val) {
const bucket = this.getBucket(val);
const labels = this.gaugeChart.handler.visConfig.get('legend.labels');
return labels[bucket];
}
getColorBucket(val) {
const bucket = this.getBucket(val);
const labels = this.gaugeChart.handler.visConfig.get('legend.labels');
return this.colorFunc(labels[bucket]);
}
drawScale(svg, radius, angle) {
const scaleWidth = this.gaugeConfig.scale.width;
const tickLength = this.gaugeConfig.scale.tickLength;
const scaleTicks = this.gaugeConfig.scale.ticks;
const scale = svg.append('g');
this.gaugeConfig.colorsRange.forEach(range => {
const color = this.getColorBucket(range.from);
const scaleArc = d3.svg.arc()
.startAngle(angle(range.from))
.endAngle(angle(range.to))
.innerRadius(radius)
.outerRadius(radius + scaleWidth);
scale
.append('path')
.attr('d', scaleArc)
.style('stroke', color)
.style('fill', color);
});
const extents = angle.domain();
for (let i = 0; i <= scaleTicks; i++) {
const val = i * (extents[1] - extents[0]) / scaleTicks;
const tickAngle = angle(val) - Math.PI / 2;
const x0 = Math.cos(tickAngle) * radius;
const x1 = Math.cos(tickAngle) * (radius - tickLength);
const y0 = Math.sin(tickAngle) * radius;
const y1 = Math.sin(tickAngle) * (radius - tickLength);
const color = this.getColorBucket(val);
scale.append('line')
.attr('x1', x0).attr('x2', x1)
.attr('y1', y0).attr('y2', y1)
.style('stroke-width', scaleWidth)
.style('stroke', color);
}
return scale;
}
drawGauge(svg, data, width, height) {
const self = this;
const marginFactor = 0.95;
const tooltip = this.gaugeChart.tooltip;
const isTooltip = this.gaugeChart.handler.visConfig.get('addTooltip');
const isDisplayWarning = this.gaugeChart.handler.visConfig.get('isDisplayWarning', false);
const maxAngle = this.gaugeConfig.maxAngle;
const minAngle = this.gaugeConfig.minAngle;
const angleFactor = this.gaugeConfig.gaugeType === 'Arc' ? 0.75 : 1;
const maxRadius = (Math.min(width, height / angleFactor) / 2) * marginFactor;
const extendRange = this.gaugeConfig.extendRange;
const maxY = _.max(data.values, 'y').y;
const min = this.gaugeConfig.colorsRange[0].from;
const max = _.last(this.gaugeConfig.colorsRange).to;
const angle = d3.scale.linear()
.range([minAngle, maxAngle])
.domain([min, extendRange && max < maxY ? maxY : max]);
const radius = d3.scale.linear()
.range([0, maxRadius])
.domain([this.gaugeConfig.innerSpace + 1, 0]);
const totalWidth = Math.abs(radius(0) - radius(1));
const bgPadding = totalWidth * (1 - this.gaugeConfig.style.bgWidth) / 2;
const gaugePadding = totalWidth * (1 - this.gaugeConfig.style.width) / 2;
/**
* Function to calculate the free space in the center of the gauge. This takes into account
* whether ticks are enabled or not.
*
* This is calculated using the inner diameter (radius(1) * 2) of the gauge.
* If ticks/scale are enabled we need to still subtract the tick length * 2 to make space for a tick
* on every side. If ticks/scale are disabled, the radius(1) function actually leaves space for the scale,
* so we add that free space (which is expressed via the paddings, we just use the larger of those) to the diameter.
*/
const getInnerFreeSpace = () => (radius(1) * 2) -
(this.gaugeConfig.scale.show
? this.gaugeConfig.scale.tickLength * 2
: -Math.max(bgPadding, gaugePadding) * 2
);
const arc = d3.svg.arc()
.startAngle(minAngle)
.endAngle(function (d) {
return Math.max(0, Math.min(maxAngle, angle(Math.max(min, d.y))));
})
.innerRadius(function (d, i, j) {
return Math.max(0, radius(j + 1) + gaugePadding);
})
.outerRadius(function (d, i, j) {
return Math.max(0, radius(j) - gaugePadding);
});
const bgArc = d3.svg.arc()
.startAngle(minAngle)
.endAngle(maxAngle)
.innerRadius(function (d, i, j) {
return Math.max(0, radius(j + 1) + bgPadding);
})
.outerRadius(function (d, i, j) {
return Math.max(0, radius(j) - bgPadding);
});
const gaugeHolders = svg
.selectAll('path')
.data([data])
.enter()
.append('g')
.attr('data-label', (d) => this.getLabel(d.values[0].y));
const gauges = gaugeHolders
.selectAll('g')
.data(d => d.values)
.enter();
gauges
.append('path')
.attr('d', bgArc)
.style('fill', this.gaugeConfig.style.bgFill);
const series = gauges
.append('path')
.attr('d', arc)
.style('fill', function (d) {
return self.getColorBucket(Math.max(min, d.y));
});
const smallContainer = svg.node().getBBox().height < 70;
let hiddenLabels = smallContainer;
// If the value label is hidden we later want to hide also all other labels
// since they don't make sense as long as the actual value is hidden.
let valueLabelHidden = false;
gauges
.append('text')
.attr('class', 'chart-label')
.attr('y', -5)
.text(d => {
if (this.gaugeConfig.percentageMode) {
const percentage = Math.round(100 * (d.y - min) / (max - min));
return `${percentage}%`;
}
return data.yAxisFormatter(d.y);
})
.attr('style', 'dominant-baseline: central;')
.style('text-anchor', 'middle')
.style('font-size', '2em')
.style('display', function () {
const textLength = this.getBBox().width;
// The text is too long if it's larger than the inner free space minus a couple of random pixels for padding.
const textTooLong = textLength >= getInnerFreeSpace() - 6;
if (textTooLong) {
hiddenLabels = true;
valueLabelHidden = true;
}
return textTooLong ? 'none' : 'initial';
});
if (this.gaugeConfig.labels.show) {
svg
.append('text')
.attr('class', 'chart-label')
.text(data.label)
.attr('y', -30)
.attr('style', 'dominant-baseline: central; text-anchor: middle;')
.style('display', function () {
const textLength = this.getBBox().width;
const textTooLong = textLength > maxRadius;
if (textTooLong) {
hiddenLabels = true;
}
return smallContainer || textTooLong ? 'none' : 'initial';
});
svg
.append('text')
.attr('class', 'chart-label')
.text(this.gaugeConfig.style.subText)
.attr('y', 20)
.attr('style', 'dominant-baseline: central; text-anchor: middle;')
.style('display', function () {
const textLength = this.getBBox().width;
const textTooLong = textLength > maxRadius;
if (textTooLong) {
hiddenLabels = true;
}
return valueLabelHidden || smallContainer || textTooLong ? 'none' : 'initial';
});
}
if (this.gaugeConfig.scale.show) {
this.drawScale(svg, radius(1), angle);
}
if (isTooltip) {
series.each(function () {
const gauge = d3.select(this);
gauge.call(tooltip.render());
});
}
if (hiddenLabels && isDisplayWarning) {
this.gaugeChart.handler.alerts.show('Some labels were hidden due to size constraints');
}
//center the visualization
const transformX = width / 2;
const transformY = height / 2 > maxRadius ? height / 2 : maxRadius;
svg.attr('transform', `translate(${transformX}, ${transformY})`);
return series;
}
this.colorFunc = this.gaugeChart.handler.data.getColorFunc();
}
return MeterGauge;
getLabels() {
const isPercentageMode = this.gaugeConfig.percentageMode;
const colorsRange = this.gaugeConfig.colorsRange;
const max = _.last(colorsRange).to;
const labels = [];
colorsRange.forEach(range => {
const from = isPercentageMode ? Math.round(100 * range.from / max) : range.from;
const to = isPercentageMode ? Math.round(100 * range.to / max) : range.to;
labels.push(`${from} - ${to}`);
});
return labels;
}
getColors() {
const invertColors = this.gaugeConfig.invertColors;
const colorSchema = this.gaugeConfig.colorSchema;
const colorsRange = this.gaugeConfig.colorsRange;
const labels = this.getLabels();
const colors = {};
for (let i = 0; i < labels.length; i += 1) {
const divider = Math.max(colorsRange.length - 1, 1);
const val = invertColors ? 1 - i / divider : i / divider;
colors[labels[i]] = getHeatmapColors(val, colorSchema);
}
return colors;
}
getBucket(val) {
let bucket = _.findIndex(this.gaugeConfig.colorsRange, range => {
return range.from <= val && range.to > val;
});
if (bucket === -1) {
if (val < this.gaugeConfig.colorsRange[0].from) bucket = 0;
else bucket = this.gaugeConfig.colorsRange.length - 1;
}
return bucket;
}
getLabel(val) {
const bucket = this.getBucket(val);
const labels = this.gaugeChart.handler.visConfig.get('legend.labels');
return labels[bucket];
}
getColorBucket(val) {
const bucket = this.getBucket(val);
const labels = this.gaugeChart.handler.visConfig.get('legend.labels');
return this.colorFunc(labels[bucket]);
}
drawScale(svg, radius, angle) {
const scaleWidth = this.gaugeConfig.scale.width;
const tickLength = this.gaugeConfig.scale.tickLength;
const scaleTicks = this.gaugeConfig.scale.ticks;
const scale = svg.append('g');
this.gaugeConfig.colorsRange.forEach(range => {
const color = this.getColorBucket(range.from);
const scaleArc = d3.svg.arc()
.startAngle(angle(range.from))
.endAngle(angle(range.to))
.innerRadius(radius)
.outerRadius(radius + scaleWidth);
scale
.append('path')
.attr('d', scaleArc)
.style('stroke', color)
.style('fill', color);
});
const extents = angle.domain();
for (let i = 0; i <= scaleTicks; i++) {
const val = i * (extents[1] - extents[0]) / scaleTicks;
const tickAngle = angle(val) - Math.PI / 2;
const x0 = Math.cos(tickAngle) * radius;
const x1 = Math.cos(tickAngle) * (radius - tickLength);
const y0 = Math.sin(tickAngle) * radius;
const y1 = Math.sin(tickAngle) * (radius - tickLength);
const color = this.getColorBucket(val);
scale.append('line')
.attr('x1', x0).attr('x2', x1)
.attr('y1', y0).attr('y2', y1)
.style('stroke-width', scaleWidth)
.style('stroke', color);
}
return scale;
}
drawGauge(svg, data, width, height) {
const self = this;
const marginFactor = 0.95;
const tooltip = this.gaugeChart.tooltip;
const isTooltip = this.gaugeChart.handler.visConfig.get('addTooltip');
const isDisplayWarning = this.gaugeChart.handler.visConfig.get('isDisplayWarning', false);
const maxAngle = this.gaugeConfig.maxAngle;
const minAngle = this.gaugeConfig.minAngle;
const angleFactor = this.gaugeConfig.gaugeType === 'Arc' ? 0.75 : 1;
const maxRadius = (Math.min(width, height / angleFactor) / 2) * marginFactor;
const extendRange = this.gaugeConfig.extendRange;
const maxY = _.max(data.values, 'y').y;
const min = this.gaugeConfig.colorsRange[0].from;
const max = _.last(this.gaugeConfig.colorsRange).to;
const angle = d3.scale.linear()
.range([minAngle, maxAngle])
.domain([min, extendRange && max < maxY ? maxY : max]);
const radius = d3.scale.linear()
.range([0, maxRadius])
.domain([this.gaugeConfig.innerSpace + 1, 0]);
const totalWidth = Math.abs(radius(0) - radius(1));
const bgPadding = totalWidth * (1 - this.gaugeConfig.style.bgWidth) / 2;
const gaugePadding = totalWidth * (1 - this.gaugeConfig.style.width) / 2;
/**
* Function to calculate the free space in the center of the gauge. This takes into account
* whether ticks are enabled or not.
*
* This is calculated using the inner diameter (radius(1) * 2) of the gauge.
* If ticks/scale are enabled we need to still subtract the tick length * 2 to make space for a tick
* on every side. If ticks/scale are disabled, the radius(1) function actually leaves space for the scale,
* so we add that free space (which is expressed via the paddings, we just use the larger of those) to the diameter.
*/
const getInnerFreeSpace = () => (radius(1) * 2) -
(this.gaugeConfig.scale.show
? this.gaugeConfig.scale.tickLength * 2
: -Math.max(bgPadding, gaugePadding) * 2
);
const arc = d3.svg.arc()
.startAngle(minAngle)
.endAngle(function (d) {
return Math.max(0, Math.min(maxAngle, angle(Math.max(min, d.y))));
})
.innerRadius(function (d, i, j) {
return Math.max(0, radius(j + 1) + gaugePadding);
})
.outerRadius(function (d, i, j) {
return Math.max(0, radius(j) - gaugePadding);
});
const bgArc = d3.svg.arc()
.startAngle(minAngle)
.endAngle(maxAngle)
.innerRadius(function (d, i, j) {
return Math.max(0, radius(j + 1) + bgPadding);
})
.outerRadius(function (d, i, j) {
return Math.max(0, radius(j) - bgPadding);
});
const gaugeHolders = svg
.selectAll('path')
.data([data])
.enter()
.append('g')
.attr('data-label', (d) => this.getLabel(d.values[0].y));
const gauges = gaugeHolders
.selectAll('g')
.data(d => d.values)
.enter();
gauges
.append('path')
.attr('d', bgArc)
.style('fill', this.gaugeConfig.style.bgFill);
const series = gauges
.append('path')
.attr('d', arc)
.style('fill', function (d) {
return self.getColorBucket(Math.max(min, d.y));
});
const smallContainer = svg.node().getBBox().height < 70;
let hiddenLabels = smallContainer;
// If the value label is hidden we later want to hide also all other labels
// since they don't make sense as long as the actual value is hidden.
let valueLabelHidden = false;
gauges
.append('text')
.attr('class', 'chart-label')
.attr('y', -5)
.text(d => {
if (this.gaugeConfig.percentageMode) {
const percentage = Math.round(100 * (d.y - min) / (max - min));
return `${percentage}%`;
}
return data.yAxisFormatter(d.y);
})
.attr('style', 'dominant-baseline: central;')
.style('text-anchor', 'middle')
.style('font-size', '2em')
.style('display', function () {
const textLength = this.getBBox().width;
// The text is too long if it's larger than the inner free space minus a couple of random pixels for padding.
const textTooLong = textLength >= getInnerFreeSpace() - 6;
if (textTooLong) {
hiddenLabels = true;
valueLabelHidden = true;
}
return textTooLong ? 'none' : 'initial';
});
if (this.gaugeConfig.labels.show) {
svg
.append('text')
.attr('class', 'chart-label')
.text(data.label)
.attr('y', -30)
.attr('style', 'dominant-baseline: central; text-anchor: middle;')
.style('display', function () {
const textLength = this.getBBox().width;
const textTooLong = textLength > maxRadius;
if (textTooLong) {
hiddenLabels = true;
}
return smallContainer || textTooLong ? 'none' : 'initial';
});
svg
.append('text')
.attr('class', 'chart-label')
.text(this.gaugeConfig.style.subText)
.attr('y', 20)
.attr('style', 'dominant-baseline: central; text-anchor: middle;')
.style('display', function () {
const textLength = this.getBBox().width;
const textTooLong = textLength > maxRadius;
if (textTooLong) {
hiddenLabels = true;
}
return valueLabelHidden || smallContainer || textTooLong ? 'none' : 'initial';
});
}
if (this.gaugeConfig.scale.show) {
this.drawScale(svg, radius(1), angle);
}
if (isTooltip) {
series.each(function () {
const gauge = d3.select(this);
gauge.call(tooltip.render());
});
}
if (hiddenLabels && isDisplayWarning) {
this.gaugeChart.handler.alerts.show('Some labels were hidden due to size constraints');
}
//center the visualization
const transformX = width / 2;
const transformY = height / 2 > maxRadius ? height / 2 : maxRadius;
svg.attr('transform', `translate(${transformX}, ${transformY})`);
return series;
}
}

View file

@ -20,17 +20,15 @@
import d3 from 'd3';
import _ from 'lodash';
import $ from 'jquery';
import { TooltipProvider } from '../../vis/components/tooltip';
import { Tooltip } from '../../vis/components/tooltip';
import { VislibVisualizationsChartProvider } from './_chart';
import { VislibVisualizationsTimeMarkerProvider } from './time_marker';
import { VislibVisualizationsSeriesTypesProvider } from './point_series/series_types';
import { TimeMarker } from './time_marker';
import { seriesTypes } from './point_series/series_types';
export function VislibVisualizationsPointSeriesProvider(Private) {
const Chart = Private(VislibVisualizationsChartProvider);
const Tooltip = Private(TooltipProvider);
const TimeMarker = Private(VislibVisualizationsTimeMarkerProvider);
const seriTypes = Private(VislibVisualizationsSeriesTypesProvider);
const seriTypes = seriesTypes;
const touchdownTmpl = _.template(require('../partials/touchdown.tmpl.html'));
/**
* Line Chart Visualization

View file

@ -19,70 +19,65 @@
import _ from 'lodash';
export function VislibVisualizationsPointSeriesProvider() {
class PointSeries {
constructor(handler, seriesEl, seriesData, seriesConfig) {
this.handler = handler;
this.baseChart = handler.pointSeries;
this.chartEl = seriesEl;
this.chartData = seriesData;
this.seriesConfig = seriesConfig;
}
getGroupedCount() {
const stacks = [];
return this.baseChart.chartConfig.series.reduce((sum, series) => {
const valueAxis = series.valueAxis || this.baseChart.handler.valueAxes[0].id;
const isStacked = series.mode === 'stacked';
const isHistogram = series.type === 'histogram';
if (!isHistogram) return sum;
if (isStacked && stacks.includes(valueAxis)) return sum;
if (isStacked) stacks.push(valueAxis);
return sum + 1;
}, 0);
}
getGroupedNum(data) {
let i = 0;
const stacks = [];
for (const seri of this.baseChart.chartConfig.series) {
const valueAxis = seri.valueAxis || this.baseChart.handler.valueAxes[0].id;
const isStacked = seri.mode === 'stacked';
if (!isStacked) {
if (seri.data === data) return i;
i++;
} else {
if (!(valueAxis in stacks)) stacks[valueAxis] = i++;
if (seri.data === data) return stacks[valueAxis];
}
}
return 0;
}
getValueAxis() {
return _.find(this.handler.valueAxes, axis => {
return axis.axisConfig.get('id') === this.seriesConfig.valueAxis;
}) || this.handler.valueAxes[0];
}
getCategoryAxis() {
return _.find(this.handler.categoryAxes, axis => {
return axis.axisConfig.get('id') === this.seriesConfig.categoryAxis;
}) || this.handler.categoryAxes[0];
}
addCircleEvents(element) {
const events = this.events;
if (this.handler.visConfig.get('enableHover')) {
const hover = events.addHoverEvent();
const mouseout = events.addMouseoutEvent();
element.call(hover).call(mouseout);
}
const click = events.addClickEvent();
return element.call(click);
}
export class PointSeries {
constructor(handler, seriesEl, seriesData, seriesConfig) {
this.handler = handler;
this.baseChart = handler.pointSeries;
this.chartEl = seriesEl;
this.chartData = seriesData;
this.seriesConfig = seriesConfig;
}
return PointSeries;
getGroupedCount() {
const stacks = [];
return this.baseChart.chartConfig.series.reduce((sum, series) => {
const valueAxis = series.valueAxis || this.baseChart.handler.valueAxes[0].id;
const isStacked = series.mode === 'stacked';
const isHistogram = series.type === 'histogram';
if (!isHistogram) return sum;
if (isStacked && stacks.includes(valueAxis)) return sum;
if (isStacked) stacks.push(valueAxis);
return sum + 1;
}, 0);
}
getGroupedNum(data) {
let i = 0;
const stacks = [];
for (const seri of this.baseChart.chartConfig.series) {
const valueAxis = seri.valueAxis || this.baseChart.handler.valueAxes[0].id;
const isStacked = seri.mode === 'stacked';
if (!isStacked) {
if (seri.data === data) return i;
i++;
} else {
if (!(valueAxis in stacks)) stacks[valueAxis] = i++;
if (seri.data === data) return stacks[valueAxis];
}
}
return 0;
}
getValueAxis() {
return _.find(this.handler.valueAxes, axis => {
return axis.axisConfig.get('id') === this.seriesConfig.valueAxis;
}) || this.handler.valueAxes[0];
}
getCategoryAxis() {
return _.find(this.handler.categoryAxes, axis => {
return axis.axisConfig.get('id') === this.seriesConfig.categoryAxis;
}) || this.handler.categoryAxes[0];
}
addCircleEvents(element) {
const events = this.events;
if (this.handler.visConfig.get('enableHover')) {
const hover = events.addHoverEvent();
const mouseout = events.addMouseoutEvent();
element.call(hover).call(mouseout);
}
const click = events.addClickEvent();
return element.call(click);
}
}

View file

@ -20,250 +20,244 @@
import d3 from 'd3';
import _ from 'lodash';
import $ from 'jquery';
import { VislibVisualizationsPointSeriesProvider } from './_point_series';
import { PointSeries } from './_point_series';
export function VislibVisualizationsAreaChartProvider(Private) {
const PointSeries = Private(VislibVisualizationsPointSeriesProvider);
const defaults = {
mode: 'normal',
showCircles: true,
radiusRatio: 9,
showLines: true,
interpolate: 'linear',
color: undefined,
fillColor: undefined,
};
/**
* Area chart visualization
*
* @class AreaChart
* @constructor
* @extends Chart
* @param handler {Object} Reference to the Handler Class Constructor
* @param el {HTMLElement} HTML element to which the chart will be appended
* @param chartData {Object} Elasticsearch query results for this specific
* chart
*/
export class AreaChart extends PointSeries {
constructor(handler, chartEl, chartData, seriesConfigArgs) {
super(handler, chartEl, chartData, seriesConfigArgs);
const defaults = {
mode: 'normal',
showCircles: true,
radiusRatio: 9,
showLines: true,
interpolate: 'linear',
color: undefined,
fillColor: undefined,
};
/**
* Area chart visualization
*
* @class AreaChart
* @constructor
* @extends Chart
* @param handler {Object} Reference to the Handler Class Constructor
* @param el {HTMLElement} HTML element to which the chart will be appended
* @param chartData {Object} Elasticsearch query results for this specific
* chart
*/
class AreaChart extends PointSeries {
constructor(handler, chartEl, chartData, seriesConfigArgs) {
super(handler, chartEl, chartData, seriesConfigArgs);
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
this.isOverlapping = (this.seriesConfig.mode !== 'stacked');
if (this.isOverlapping) {
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
this.isOverlapping = (this.seriesConfig.mode !== 'stacked');
if (this.isOverlapping) {
// Default opacity should return to 0.6 on mouseout
const defaultOpacity = 0.6;
this.seriesConfig.defaultOpacity = defaultOpacity;
handler.highlight = function (element) {
const label = this.getAttribute('data-label');
if (!label) return;
// Default opacity should return to 0.6 on mouseout
const defaultOpacity = 0.6;
this.seriesConfig.defaultOpacity = defaultOpacity;
handler.highlight = function (element) {
const label = this.getAttribute('data-label');
if (!label) return;
const highlightOpacity = 0.8;
const highlightElements = $('[data-label]', element.parentNode).filter(
function (els, el) {
return `${$(el).data('label')}` === label;
});
$('[data-label]', element.parentNode).not(highlightElements).css('opacity', defaultOpacity / 2); // half of the default opacity
highlightElements.css('opacity', highlightOpacity);
};
handler.unHighlight = function (element) {
$('[data-label]', element).css('opacity', defaultOpacity);
//The legend should keep max opacity
$('[data-label]', $(element).siblings()).css('opacity', 1);
};
}
}
addPath(svg, data) {
const ordered = this.handler.data.get('ordered');
const isTimeSeries = (ordered && ordered.date);
const isOverlapping = this.isOverlapping;
const color = this.handler.data.getColorFunc();
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const interpolate = this.seriesConfig.interpolate;
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
// Data layers
const layer = svg.append('g')
.attr('class', function (d, i) {
return 'series series-' + i;
});
// Append path
const path = layer.append('path')
.attr('data-label', data.label)
.style('fill', () => color(data.label))
.style('stroke', () => color(data.label))
.classed('visAreaChart__overlapArea', function () {
return isOverlapping;
})
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
function x(d) {
if (isTimeSeries) {
return xScale(d.x);
}
return xScale(d.x) + xScale.rangeBand() / 2;
}
function y1(d) {
const y0 = d.y0 || 0;
const y = d.y || 0;
return yScale(y0 + y);
}
function y0(d) {
const y0 = d.y0 || 0;
return yScale(y0);
}
function getArea() {
if (isHorizontal) {
return d3.svg.area()
.x(x)
.y0(y0)
.y1(y1);
} else {
return d3.svg.area()
.y(x)
.x0(y0)
.x1(y1);
}
}
// update
path
.attr('d', function () {
const area = getArea()
.defined(function (d) {
return !_.isNull(d.y);
})
.interpolate(interpolate);
return area(data.values);
})
.style('stroke-width', '1px');
return path;
}
/**
* Adds SVG circles to area chart
*
* @method addCircles
* @param svg {HTMLElement} SVG to which circles are appended
* @param data {Array} Chart data array
* @returns {D3.UpdateSelection} SVG with circles added
*/
addCircles(svg, data) {
const color = this.handler.data.getColorFunc();
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const ordered = this.handler.data.get('ordered');
const circleRadius = 12;
const circleStrokeWidth = 0;
const tooltip = this.baseChart.tooltip;
const isTooltip = this.handler.visConfig.get('tooltip.show');
const isOverlapping = this.isOverlapping;
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const layer = svg.append('g')
.attr('class', 'points area')
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
// append the circles
const circles = layer.selectAll('circles')
.data(function appendData() {
return data.values.filter(function isZeroOrNull(d) {
return d.y !== 0 && !_.isNull(d.y);
const highlightOpacity = 0.8;
const highlightElements = $('[data-label]', element.parentNode).filter(
function (els, el) {
return `${$(el).data('label')}` === label;
});
});
// exit
circles.exit().remove();
// enter
circles
.enter()
.append('circle')
.attr('data-label', data.label)
.attr('stroke', () => {
return color(data.label);
})
.attr('fill', 'transparent')
.attr('stroke-width', circleStrokeWidth);
function cx(d) {
if (ordered && ordered.date) {
return xScale(d.x);
}
return xScale(d.x) + xScale.rangeBand() / 2;
}
function cy(d) {
const y = d.y || 0;
if (isOverlapping) {
return yScale(y);
}
return yScale(d.y0 + y);
}
// update
circles
.attr('cx', isHorizontal ? cx : cy)
.attr('cy', isHorizontal ? cy : cx)
.attr('r', circleRadius);
// Add tooltip
if (isTooltip) {
circles.call(tooltip.render());
}
return circles;
}
addPathEvents(path) {
const events = this.events;
if (this.handler.visConfig.get('enableHover')) {
const hover = events.addHoverEvent();
const mouseout = events.addMouseoutEvent();
path.call(hover).call(mouseout);
}
}
/**
* Renders d3 visualization
*
* @method draw
* @returns {Function} Creates the area chart
*/
draw() {
const self = this;
return function (selection) {
selection.each(function () {
const svg = self.chartEl.append('g');
svg.data([self.chartData]);
const path = self.addPath(svg, self.chartData);
self.addPathEvents(path);
const circles = self.addCircles(svg, self.chartData);
self.addCircleEvents(circles);
self.events.emit('rendered', {
chart: self.chartData
});
return svg;
});
$('[data-label]', element.parentNode).not(highlightElements).css('opacity', defaultOpacity / 2); // half of the default opacity
highlightElements.css('opacity', highlightOpacity);
};
handler.unHighlight = function (element) {
$('[data-label]', element).css('opacity', defaultOpacity);
//The legend should keep max opacity
$('[data-label]', $(element).siblings()).css('opacity', 1);
};
}
}
addPath(svg, data) {
const ordered = this.handler.data.get('ordered');
const isTimeSeries = (ordered && ordered.date);
const isOverlapping = this.isOverlapping;
const color = this.handler.data.getColorFunc();
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const interpolate = this.seriesConfig.interpolate;
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
// Data layers
const layer = svg.append('g')
.attr('class', function (d, i) {
return 'series series-' + i;
});
// Append path
const path = layer.append('path')
.attr('data-label', data.label)
.style('fill', () => color(data.label))
.style('stroke', () => color(data.label))
.classed('visAreaChart__overlapArea', function () {
return isOverlapping;
})
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
function x(d) {
if (isTimeSeries) {
return xScale(d.x);
}
return xScale(d.x) + xScale.rangeBand() / 2;
}
function y1(d) {
const y0 = d.y0 || 0;
const y = d.y || 0;
return yScale(y0 + y);
}
function y0(d) {
const y0 = d.y0 || 0;
return yScale(y0);
}
function getArea() {
if (isHorizontal) {
return d3.svg.area()
.x(x)
.y0(y0)
.y1(y1);
} else {
return d3.svg.area()
.y(x)
.x0(y0)
.x1(y1);
}
}
// update
path
.attr('d', function () {
const area = getArea()
.defined(function (d) {
return !_.isNull(d.y);
})
.interpolate(interpolate);
return area(data.values);
})
.style('stroke-width', '1px');
return path;
}
/**
* Adds SVG circles to area chart
*
* @method addCircles
* @param svg {HTMLElement} SVG to which circles are appended
* @param data {Array} Chart data array
* @returns {D3.UpdateSelection} SVG with circles added
*/
addCircles(svg, data) {
const color = this.handler.data.getColorFunc();
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const ordered = this.handler.data.get('ordered');
const circleRadius = 12;
const circleStrokeWidth = 0;
const tooltip = this.baseChart.tooltip;
const isTooltip = this.handler.visConfig.get('tooltip.show');
const isOverlapping = this.isOverlapping;
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const layer = svg.append('g')
.attr('class', 'points area')
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
// append the circles
const circles = layer.selectAll('circles')
.data(function appendData() {
return data.values.filter(function isZeroOrNull(d) {
return d.y !== 0 && !_.isNull(d.y);
});
});
// exit
circles.exit().remove();
// enter
circles
.enter()
.append('circle')
.attr('data-label', data.label)
.attr('stroke', () => {
return color(data.label);
})
.attr('fill', 'transparent')
.attr('stroke-width', circleStrokeWidth);
function cx(d) {
if (ordered && ordered.date) {
return xScale(d.x);
}
return xScale(d.x) + xScale.rangeBand() / 2;
}
function cy(d) {
const y = d.y || 0;
if (isOverlapping) {
return yScale(y);
}
return yScale(d.y0 + y);
}
// update
circles
.attr('cx', isHorizontal ? cx : cy)
.attr('cy', isHorizontal ? cy : cx)
.attr('r', circleRadius);
// Add tooltip
if (isTooltip) {
circles.call(tooltip.render());
}
return circles;
}
addPathEvents(path) {
const events = this.events;
if (this.handler.visConfig.get('enableHover')) {
const hover = events.addHoverEvent();
const mouseout = events.addMouseoutEvent();
path.call(hover).call(mouseout);
}
}
return AreaChart;
/**
* Renders d3 visualization
*
* @method draw
* @returns {Function} Creates the area chart
*/
draw() {
const self = this;
return function (selection) {
selection.each(function () {
const svg = self.chartEl.append('g');
svg.data([self.chartData]);
const path = self.addPath(svg, self.chartData);
self.addPathEvents(path);
const circles = self.addCircles(svg, self.chartData);
self.addCircleEvents(circles);
self.events.emit('rendered', {
chart: self.chartData
});
return svg;
});
};
}
}

View file

@ -18,263 +18,257 @@
*/
import _ from 'lodash';
import { VislibVisualizationsPointSeriesProvider } from './_point_series';
import { PointSeries } from './_point_series';
export function VislibVisualizationsColumnChartProvider(Private) {
const PointSeries = Private(VislibVisualizationsPointSeriesProvider);
const defaults = {
mode: 'normal',
showTooltip: true,
color: undefined,
fillColor: undefined,
};
const defaults = {
mode: 'normal',
showTooltip: true,
color: undefined,
fillColor: undefined,
};
/**
* Histogram intervals are not always equal widths, e.g, monthly time intervals.
* It is more visually appealing to vary bar width so that gutter width is constant.
*/
function datumWidth(defaultWidth, datum, nextDatum, scale, gutterWidth, groupCount = 1) {
let datumWidth = defaultWidth;
if (nextDatum) {
datumWidth = ((scale(nextDatum.x) - scale(datum.x)) - gutterWidth) / groupCount;
// To handle data-sets with holes, do not let width be larger than default.
if (datumWidth > defaultWidth) {
datumWidth = defaultWidth;
}
}
return datumWidth;
}
/**
* Vertical Bar Chart Visualization: renders vertical and/or stacked bars
*
* @class ColumnChart
* @constructor
* @extends Chart
* @param handler {Object} Reference to the Handler Class Constructor
* @param el {HTMLElement} HTML element to which the chart will be appended
* @param chartData {Object} Elasticsearch query results for this specific chart
*/
class ColumnChart extends PointSeries {
constructor(handler, chartEl, chartData, seriesConfigArgs) {
super(handler, chartEl, chartData, seriesConfigArgs);
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
}
addBars(svg, data) {
const self = this;
const color = this.handler.data.getColorFunc();
const tooltip = this.baseChart.tooltip;
const isTooltip = this.handler.visConfig.get('tooltip.show');
const layer = svg.append('g')
.attr('class', 'series histogram')
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
const bars = layer.selectAll('rect')
.data(data.values.filter(function (d) {
return !_.isNull(d.y);
}));
bars
.exit()
.remove();
bars
.enter()
.append('rect')
.attr('data-label', data.label)
.attr('fill', () => color(data.label))
.attr('stroke', () => color(data.label));
self.updateBars(bars);
// Add tooltip
if (isTooltip) {
bars.call(tooltip.render());
}
return bars;
}
/**
* Determines whether bars are grouped or stacked and updates the D3
* selection
*
* @method updateBars
* @param bars {D3.UpdateSelection} SVG with rect added
* @returns {D3.UpdateSelection}
*/
updateBars(bars) {
if (this.seriesConfig.mode === 'stacked') {
return this.addStackedBars(bars);
}
return this.addGroupedBars(bars);
}
/**
* Adds stacked bars to column chart visualization
*
* @method addStackedBars
* @param bars {D3.UpdateSelection} SVG with rect added
* @returns {D3.UpdateSelection}
*/
addStackedBars(bars) {
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const isTimeScale = this.getCategoryAxis().axisConfig.isTimeDomain();
const yMin = yScale.domain()[0];
const gutterSpacingPercentage = 0.15;
const groupCount = this.getGroupedCount();
const groupNum = this.getGroupedNum(this.chartData);
let barWidth;
let gutterWidth;
if (isTimeScale) {
const { min, interval } = this.handler.data.get('ordered');
let intervalWidth = xScale(min + interval) - xScale(min);
intervalWidth = Math.abs(intervalWidth);
gutterWidth = intervalWidth * gutterSpacingPercentage;
barWidth = (intervalWidth - gutterWidth) / groupCount;
}
function x(d, i) {
if (isTimeScale) {
return xScale(d.x) + datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount) * groupNum;
}
return xScale(d.x) + xScale.rangeBand() / groupCount * groupNum;
}
function y(d) {
if ((isHorizontal && d.y < 0) || (!isHorizontal && d.y > 0)) {
return yScale(d.y0);
}
return yScale(d.y0 + d.y);
}
function widthFunc(d, i) {
if (isTimeScale) {
return datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount);
}
return xScale.rangeBand() / groupCount;
}
function heightFunc(d) {
// for split bars or for one series,
// last series will have d.y0 = 0
if (d.y0 === 0 && yMin > 0) {
return yScale(yMin) - yScale(d.y);
}
return Math.abs(yScale(d.y0) - yScale(d.y0 + d.y));
}
// update
bars
.attr('x', isHorizontal ? x : y)
.attr('width', isHorizontal ? widthFunc : heightFunc)
.attr('y', isHorizontal ? y : x)
.attr('height', isHorizontal ? heightFunc : widthFunc);
return bars;
}
/**
* Adds grouped bars to column chart visualization
*
* @method addGroupedBars
* @param bars {D3.UpdateSelection} SVG with rect added
* @returns {D3.UpdateSelection}
*/
addGroupedBars(bars) {
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const groupCount = this.getGroupedCount();
const groupNum = this.getGroupedNum(this.chartData);
const gutterSpacingPercentage = 0.15;
const isTimeScale = this.getCategoryAxis().axisConfig.isTimeDomain();
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const isLogScale = this.getValueAxis().axisConfig.isLogScale();
let barWidth;
let gutterWidth;
if (isTimeScale) {
const { min, interval } = this.handler.data.get('ordered');
let intervalWidth = xScale(min + interval) - xScale(min);
intervalWidth = Math.abs(intervalWidth);
gutterWidth = intervalWidth * gutterSpacingPercentage;
barWidth = (intervalWidth - gutterWidth) / groupCount;
}
function x(d, i) {
if (isTimeScale) {
return xScale(d.x) + datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount) * groupNum;
}
return xScale(d.x) + xScale.rangeBand() / groupCount * groupNum;
}
function y(d) {
if ((isHorizontal && d.y < 0) || (!isHorizontal && d.y > 0)) {
return yScale(0);
}
return yScale(d.y);
}
function widthFunc(d, i) {
if (isTimeScale) {
return datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount);
}
return xScale.rangeBand() / groupCount;
}
function heightFunc(d) {
const baseValue = isLogScale ? 1 : 0;
return Math.abs(yScale(baseValue) - yScale(d.y));
}
// update
bars
.attr('x', isHorizontal ? x : y)
.attr('width', isHorizontal ? widthFunc : heightFunc)
.attr('y', isHorizontal ? y : x)
.attr('height', isHorizontal ? heightFunc : widthFunc);
return bars;
}
/**
* Renders d3 visualization
*
* @method draw
* @returns {Function} Creates the vertical bar chart
*/
draw() {
const self = this;
return function (selection) {
selection.each(function () {
const svg = self.chartEl.append('g');
svg.data([self.chartData]);
const bars = self.addBars(svg, self.chartData);
self.addCircleEvents(bars);
self.events.emit('rendered', {
chart: self.chartData
});
return svg;
});
};
/**
* Histogram intervals are not always equal widths, e.g, monthly time intervals.
* It is more visually appealing to vary bar width so that gutter width is constant.
*/
function datumWidth(defaultWidth, datum, nextDatum, scale, gutterWidth, groupCount = 1) {
let datumWidth = defaultWidth;
if (nextDatum) {
datumWidth = ((scale(nextDatum.x) - scale(datum.x)) - gutterWidth) / groupCount;
// To handle data-sets with holes, do not let width be larger than default.
if (datumWidth > defaultWidth) {
datumWidth = defaultWidth;
}
}
return ColumnChart;
return datumWidth;
}
/**
* Vertical Bar Chart Visualization: renders vertical and/or stacked bars
*
* @class ColumnChart
* @constructor
* @extends Chart
* @param handler {Object} Reference to the Handler Class Constructor
* @param el {HTMLElement} HTML element to which the chart will be appended
* @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);
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
}
addBars(svg, data) {
const self = this;
const color = this.handler.data.getColorFunc();
const tooltip = this.baseChart.tooltip;
const isTooltip = this.handler.visConfig.get('tooltip.show');
const layer = svg.append('g')
.attr('class', 'series histogram')
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
const bars = layer.selectAll('rect')
.data(data.values.filter(function (d) {
return !_.isNull(d.y);
}));
bars
.exit()
.remove();
bars
.enter()
.append('rect')
.attr('data-label', data.label)
.attr('fill', () => color(data.label))
.attr('stroke', () => color(data.label));
self.updateBars(bars);
// Add tooltip
if (isTooltip) {
bars.call(tooltip.render());
}
return bars;
}
/**
* Determines whether bars are grouped or stacked and updates the D3
* selection
*
* @method updateBars
* @param bars {D3.UpdateSelection} SVG with rect added
* @returns {D3.UpdateSelection}
*/
updateBars(bars) {
if (this.seriesConfig.mode === 'stacked') {
return this.addStackedBars(bars);
}
return this.addGroupedBars(bars);
}
/**
* Adds stacked bars to column chart visualization
*
* @method addStackedBars
* @param bars {D3.UpdateSelection} SVG with rect added
* @returns {D3.UpdateSelection}
*/
addStackedBars(bars) {
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const isTimeScale = this.getCategoryAxis().axisConfig.isTimeDomain();
const yMin = yScale.domain()[0];
const gutterSpacingPercentage = 0.15;
const groupCount = this.getGroupedCount();
const groupNum = this.getGroupedNum(this.chartData);
let barWidth;
let gutterWidth;
if (isTimeScale) {
const { min, interval } = this.handler.data.get('ordered');
let intervalWidth = xScale(min + interval) - xScale(min);
intervalWidth = Math.abs(intervalWidth);
gutterWidth = intervalWidth * gutterSpacingPercentage;
barWidth = (intervalWidth - gutterWidth) / groupCount;
}
function x(d, i) {
if (isTimeScale) {
return xScale(d.x) + datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount) * groupNum;
}
return xScale(d.x) + xScale.rangeBand() / groupCount * groupNum;
}
function y(d) {
if ((isHorizontal && d.y < 0) || (!isHorizontal && d.y > 0)) {
return yScale(d.y0);
}
return yScale(d.y0 + d.y);
}
function widthFunc(d, i) {
if (isTimeScale) {
return datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount);
}
return xScale.rangeBand() / groupCount;
}
function heightFunc(d) {
// for split bars or for one series,
// last series will have d.y0 = 0
if (d.y0 === 0 && yMin > 0) {
return yScale(yMin) - yScale(d.y);
}
return Math.abs(yScale(d.y0) - yScale(d.y0 + d.y));
}
// update
bars
.attr('x', isHorizontal ? x : y)
.attr('width', isHorizontal ? widthFunc : heightFunc)
.attr('y', isHorizontal ? y : x)
.attr('height', isHorizontal ? heightFunc : widthFunc);
return bars;
}
/**
* Adds grouped bars to column chart visualization
*
* @method addGroupedBars
* @param bars {D3.UpdateSelection} SVG with rect added
* @returns {D3.UpdateSelection}
*/
addGroupedBars(bars) {
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const groupCount = this.getGroupedCount();
const groupNum = this.getGroupedNum(this.chartData);
const gutterSpacingPercentage = 0.15;
const isTimeScale = this.getCategoryAxis().axisConfig.isTimeDomain();
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const isLogScale = this.getValueAxis().axisConfig.isLogScale();
let barWidth;
let gutterWidth;
if (isTimeScale) {
const { min, interval } = this.handler.data.get('ordered');
let intervalWidth = xScale(min + interval) - xScale(min);
intervalWidth = Math.abs(intervalWidth);
gutterWidth = intervalWidth * gutterSpacingPercentage;
barWidth = (intervalWidth - gutterWidth) / groupCount;
}
function x(d, i) {
if (isTimeScale) {
return xScale(d.x) + datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount) * groupNum;
}
return xScale(d.x) + xScale.rangeBand() / groupCount * groupNum;
}
function y(d) {
if ((isHorizontal && d.y < 0) || (!isHorizontal && d.y > 0)) {
return yScale(0);
}
return yScale(d.y);
}
function widthFunc(d, i) {
if (isTimeScale) {
return datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount);
}
return xScale.rangeBand() / groupCount;
}
function heightFunc(d) {
const baseValue = isLogScale ? 1 : 0;
return Math.abs(yScale(baseValue) - yScale(d.y));
}
// update
bars
.attr('x', isHorizontal ? x : y)
.attr('width', isHorizontal ? widthFunc : heightFunc)
.attr('y', isHorizontal ? y : x)
.attr('height', isHorizontal ? heightFunc : widthFunc);
return bars;
}
/**
* Renders d3 visualization
*
* @method draw
* @returns {Function} Creates the vertical bar chart
*/
draw() {
const self = this;
return function (selection) {
selection.each(function () {
const svg = self.chartEl.append('g');
svg.data([self.chartData]);
const bars = self.addBars(svg, self.chartData);
self.addCircleEvents(bars);
self.events.emit('rendered', {
chart: self.chartData
});
return svg;
});
};
}
}

View file

@ -19,314 +19,308 @@
import _ from 'lodash';
import moment from 'moment';
import { VislibVisualizationsPointSeriesProvider } from './_point_series';
import { PointSeries } from './_point_series';
import { getHeatmapColors } from '../../components/color/heatmap_color';
import {
isColorDark
} from '@elastic/eui';
export function VislibVisualizationsHeatmapChartProvider(Private) {
const PointSeries = Private(VislibVisualizationsPointSeriesProvider);
const defaults = {
color: undefined, // todo
fillColor: undefined // todo
};
/**
* Line Chart Visualization
*
* @class HeatmapChart
* @constructor
* @extends Chart
* @param handler {Object} Reference to the Handler Class Constructor
* @param el {HTMLElement} HTML element to which the chart will be appended
* @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);
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
const defaults = {
color: undefined, // todo
fillColor: undefined // todo
};
/**
* Line Chart Visualization
*
* @class HeatmapChart
* @constructor
* @extends Chart
* @param handler {Object} Reference to the Handler Class Constructor
* @param el {HTMLElement} HTML element to which the chart will be appended
* @param chartData {Object} Elasticsearch query results for this specific chart
*/
class HeatmapChart extends PointSeries {
constructor(handler, chartEl, chartData, seriesConfigArgs) {
super(handler, chartEl, chartData, seriesConfigArgs);
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
this.handler.visConfig.set('legend', {
labels: this.getHeatmapLabels(this.handler.visConfig),
colors: this.getHeatmapColors(this.handler.visConfig)
});
this.handler.visConfig.set('legend', {
labels: this.getHeatmapLabels(this.handler.visConfig),
colors: this.getHeatmapColors(this.handler.visConfig)
});
const colors = this.handler.visConfig.get('legend.colors', null);
if (colors) {
this.handler.vis.uiState.setSilent('vis.defaultColors', null);
this.handler.vis.uiState.setSilent('vis.defaultColors', colors);
}
}
getHeatmapLabels(cfg) {
const percentageMode = cfg.get('percentageMode');
const colorsNumber = cfg.get('colorsNumber');
const colorsRange = cfg.get('colorsRange');
const zAxisConfig = this.getValueAxis().axisConfig;
const zAxisFormatter = zAxisConfig.get('labels.axisFormatter');
const zScale = this.getValueAxis().getScale();
const [min, max] = zScale.domain();
const labels = [];
const maxColorCnt = 10;
if (cfg.get('setColorRange')) {
colorsRange.forEach(range => {
const from = isFinite(range.from) ? zAxisFormatter(range.from) : range.from;
const to = isFinite(range.to) ? zAxisFormatter(range.to) : range.to;
labels.push(`${from} - ${to}`);
});
} else {
if (max === min) {
return [ min.toString() ];
}
for (let i = 0; i < colorsNumber; i++) {
let label;
let val = i / colorsNumber;
let nextVal = (i + 1) / colorsNumber;
if (percentageMode) {
val = Math.ceil(val * 100);
nextVal = Math.ceil(nextVal * 100);
label = `${val}% - ${nextVal}%`;
} else {
val = val * (max - min) + min;
nextVal = nextVal * (max - min) + min;
if (max - min > maxColorCnt) {
const valInt = Math.ceil(val);
if (i === 0) {
val = (valInt === val ? val : valInt - 1);
}
else{
val = valInt;
}
nextVal = Math.ceil(nextVal);
}
if (isFinite(val)) val = zAxisFormatter(val);
if (isFinite(nextVal)) nextVal = zAxisFormatter(nextVal);
label = `${val} - ${nextVal}`;
}
labels.push(label);
}
}
return labels;
}
getHeatmapColors(cfg) {
const invertColors = cfg.get('invertColors');
const colorSchema = cfg.get('colorSchema');
const labels = this.getHeatmapLabels(cfg);
const colors = {};
for (const i in labels) {
if (labels[i]) {
const val = invertColors ? 1 - i / labels.length : i / labels.length;
colors[labels[i]] = getHeatmapColors(val, colorSchema);
}
}
return colors;
}
addSquares(svg, data) {
const xScale = this.getCategoryAxis().getScale();
const yScale = this.handler.categoryAxes[1].getScale();
const zScale = this.getValueAxis().getScale();
const tooltip = this.baseChart.tooltip;
const isTooltip = this.handler.visConfig.get('tooltip.show');
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const colorsNumber = this.handler.visConfig.get('colorsNumber');
const setColorRange = this.handler.visConfig.get('setColorRange');
const colorsRange = this.handler.visConfig.get('colorsRange');
const color = this.handler.data.getColorFunc();
const labels = this.handler.visConfig.get('legend.labels');
const zAxisConfig = this.getValueAxis().axisConfig;
const zAxisFormatter = zAxisConfig.get('labels.axisFormatter');
const showLabels = zAxisConfig.get('labels.show');
const overwriteLabelColor = zAxisConfig.get('labels.overwriteColor', false);
const layer = svg.append('g')
.attr('class', 'series');
const squares = layer
.selectAll('g.square')
.data(data.values);
squares
.exit()
.remove();
let barWidth;
if (this.getCategoryAxis().axisConfig.isTimeDomain()) {
const { min, interval } = this.handler.data.get('ordered');
const start = min;
const end = moment(min).add(interval).valueOf();
barWidth = xScale(end) - xScale(start);
if (!isHorizontal) barWidth *= -1;
}
function x(d) {
return xScale(d.x);
}
function y(d) {
return yScale(d.series);
}
const [min, max] = zScale.domain();
function getColorBucket(d) {
let val = 0;
if (setColorRange && colorsRange.length) {
const bucket = _.find(colorsRange, range => {
return range.from <= d.y && range.to > d.y;
});
return bucket ? colorsRange.indexOf(bucket) : -1;
} else {
if (isNaN(min) || isNaN(max)) {
val = colorsNumber - 1;
} else if (min === max) {
val = 0;
} else {
val = (d.y - min) / (max - min); /* get val from 0 - 1 */
val = Math.min(colorsNumber - 1, Math.floor(val * colorsNumber));
}
}
if (d.y == null) {
return -1;
}
return !isNaN(val) ? val : -1;
}
function label(d) {
const colorBucket = getColorBucket(d);
// colorBucket id should always GTE 0
if (colorBucket < 0) d.hide = true;
return labels[colorBucket];
}
function z(d) {
if (label(d) === '') return 'transparent';
return color(label(d));
}
const squareWidth = barWidth || xScale.rangeBand();
const squareHeight = yScale.rangeBand();
squares
.enter()
.append('g')
.attr('class', 'square');
squares.append('rect')
.attr('x', x)
.attr('width', squareWidth)
.attr('y', y)
.attr('height', squareHeight)
.attr('data-label', label)
.attr('fill', z)
.attr('style', 'cursor: pointer; stroke: black; stroke-width: 0.1px')
.style('display', d => {
return d.hide ? 'none' : 'initial';
});
// todo: verify that longest label is not longer than the barwidth
// or barwidth is not smaller than textheight (and vice versa)
//
if (showLabels) {
const rotate = zAxisConfig.get('labels.rotate');
const rotateRad = rotate * Math.PI / 180;
const cellPadding = 5;
const maxLength = Math.min(
Math.abs(squareWidth / Math.cos(rotateRad)),
Math.abs(squareHeight / Math.sin(rotateRad))
) - cellPadding;
const maxHeight = Math.min(
Math.abs(squareWidth / Math.sin(rotateRad)),
Math.abs(squareHeight / Math.cos(rotateRad))
) - cellPadding;
let labelColor;
if (overwriteLabelColor) {
// If overwriteLabelColor is true, use the manual specified color
labelColor = zAxisConfig.get('labels.color');
} else {
// Otherwise provide a function that will calculate a light or dark color
labelColor = d => {
const bgColor = z(d);
const color = /rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/.exec(bgColor);
return color && isColorDark(parseInt(color[1]), parseInt(color[2]), parseInt(color[3]))
? '#FFF' : '#222';
};
}
let hiddenLabels = false;
squares.append('text')
.text(d => zAxisFormatter(d.y))
.style('display', function (d) {
const textLength = this.getBBox().width;
const textHeight = this.getBBox().height;
const textTooLong = textLength > maxLength;
const textTooWide = textHeight > maxHeight;
if (!d.hide && (textTooLong || textTooWide)) {
hiddenLabels = true;
}
return d.hide || textTooLong || textTooWide ? 'none' : 'initial';
})
.style('dominant-baseline', 'central')
.style('text-anchor', 'middle')
.style('fill', labelColor)
.attr('x', function (d) {
const center = x(d) + squareWidth / 2;
return center;
})
.attr('y', function (d) {
const center = y(d) + squareHeight / 2;
return center;
})
.attr('transform', function (d) {
const horizontalCenter = x(d) + squareWidth / 2;
const verticalCenter = y(d) + squareHeight / 2;
return `rotate(${rotate},${horizontalCenter},${verticalCenter})`;
});
if (hiddenLabels) {
this.baseChart.handler.alerts.show('Some labels were hidden due to size constraints');
}
}
if (isTooltip) {
squares.call(tooltip.render());
}
return squares.selectAll('rect');
}
/**
* Renders d3 visualization
*
* @method draw
* @returns {Function} Creates the line chart
*/
draw() {
const self = this;
return function (selection) {
selection.each(function () {
const svg = self.chartEl.append('g');
svg.data([self.chartData]);
const squares = self.addSquares(svg, self.chartData);
self.addCircleEvents(squares);
self.events.emit('rendered', {
chart: self.chartData
});
return svg;
});
};
const colors = this.handler.visConfig.get('legend.colors', null);
if (colors) {
this.handler.vis.uiState.setSilent('vis.defaultColors', null);
this.handler.vis.uiState.setSilent('vis.defaultColors', colors);
}
}
return HeatmapChart;
getHeatmapLabels(cfg) {
const percentageMode = cfg.get('percentageMode');
const colorsNumber = cfg.get('colorsNumber');
const colorsRange = cfg.get('colorsRange');
const zAxisConfig = this.getValueAxis().axisConfig;
const zAxisFormatter = zAxisConfig.get('labels.axisFormatter');
const zScale = this.getValueAxis().getScale();
const [min, max] = zScale.domain();
const labels = [];
const maxColorCnt = 10;
if (cfg.get('setColorRange')) {
colorsRange.forEach(range => {
const from = isFinite(range.from) ? zAxisFormatter(range.from) : range.from;
const to = isFinite(range.to) ? zAxisFormatter(range.to) : range.to;
labels.push(`${from} - ${to}`);
});
} else {
if (max === min) {
return [ min.toString() ];
}
for (let i = 0; i < colorsNumber; i++) {
let label;
let val = i / colorsNumber;
let nextVal = (i + 1) / colorsNumber;
if (percentageMode) {
val = Math.ceil(val * 100);
nextVal = Math.ceil(nextVal * 100);
label = `${val}% - ${nextVal}%`;
} else {
val = val * (max - min) + min;
nextVal = nextVal * (max - min) + min;
if (max - min > maxColorCnt) {
const valInt = Math.ceil(val);
if (i === 0) {
val = (valInt === val ? val : valInt - 1);
}
else{
val = valInt;
}
nextVal = Math.ceil(nextVal);
}
if (isFinite(val)) val = zAxisFormatter(val);
if (isFinite(nextVal)) nextVal = zAxisFormatter(nextVal);
label = `${val} - ${nextVal}`;
}
labels.push(label);
}
}
return labels;
}
getHeatmapColors(cfg) {
const invertColors = cfg.get('invertColors');
const colorSchema = cfg.get('colorSchema');
const labels = this.getHeatmapLabels(cfg);
const colors = {};
for (const i in labels) {
if (labels[i]) {
const val = invertColors ? 1 - i / labels.length : i / labels.length;
colors[labels[i]] = getHeatmapColors(val, colorSchema);
}
}
return colors;
}
addSquares(svg, data) {
const xScale = this.getCategoryAxis().getScale();
const yScale = this.handler.categoryAxes[1].getScale();
const zScale = this.getValueAxis().getScale();
const tooltip = this.baseChart.tooltip;
const isTooltip = this.handler.visConfig.get('tooltip.show');
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const colorsNumber = this.handler.visConfig.get('colorsNumber');
const setColorRange = this.handler.visConfig.get('setColorRange');
const colorsRange = this.handler.visConfig.get('colorsRange');
const color = this.handler.data.getColorFunc();
const labels = this.handler.visConfig.get('legend.labels');
const zAxisConfig = this.getValueAxis().axisConfig;
const zAxisFormatter = zAxisConfig.get('labels.axisFormatter');
const showLabels = zAxisConfig.get('labels.show');
const overwriteLabelColor = zAxisConfig.get('labels.overwriteColor', false);
const layer = svg.append('g')
.attr('class', 'series');
const squares = layer
.selectAll('g.square')
.data(data.values);
squares
.exit()
.remove();
let barWidth;
if (this.getCategoryAxis().axisConfig.isTimeDomain()) {
const { min, interval } = this.handler.data.get('ordered');
const start = min;
const end = moment(min).add(interval).valueOf();
barWidth = xScale(end) - xScale(start);
if (!isHorizontal) barWidth *= -1;
}
function x(d) {
return xScale(d.x);
}
function y(d) {
return yScale(d.series);
}
const [min, max] = zScale.domain();
function getColorBucket(d) {
let val = 0;
if (setColorRange && colorsRange.length) {
const bucket = _.find(colorsRange, range => {
return range.from <= d.y && range.to > d.y;
});
return bucket ? colorsRange.indexOf(bucket) : -1;
} else {
if (isNaN(min) || isNaN(max)) {
val = colorsNumber - 1;
} else if (min === max) {
val = 0;
} else {
val = (d.y - min) / (max - min); /* get val from 0 - 1 */
val = Math.min(colorsNumber - 1, Math.floor(val * colorsNumber));
}
}
if (d.y == null) {
return -1;
}
return !isNaN(val) ? val : -1;
}
function label(d) {
const colorBucket = getColorBucket(d);
// colorBucket id should always GTE 0
if (colorBucket < 0) d.hide = true;
return labels[colorBucket];
}
function z(d) {
if (label(d) === '') return 'transparent';
return color(label(d));
}
const squareWidth = barWidth || xScale.rangeBand();
const squareHeight = yScale.rangeBand();
squares
.enter()
.append('g')
.attr('class', 'square');
squares.append('rect')
.attr('x', x)
.attr('width', squareWidth)
.attr('y', y)
.attr('height', squareHeight)
.attr('data-label', label)
.attr('fill', z)
.attr('style', 'cursor: pointer; stroke: black; stroke-width: 0.1px')
.style('display', d => {
return d.hide ? 'none' : 'initial';
});
// todo: verify that longest label is not longer than the barwidth
// or barwidth is not smaller than textheight (and vice versa)
//
if (showLabels) {
const rotate = zAxisConfig.get('labels.rotate');
const rotateRad = rotate * Math.PI / 180;
const cellPadding = 5;
const maxLength = Math.min(
Math.abs(squareWidth / Math.cos(rotateRad)),
Math.abs(squareHeight / Math.sin(rotateRad))
) - cellPadding;
const maxHeight = Math.min(
Math.abs(squareWidth / Math.sin(rotateRad)),
Math.abs(squareHeight / Math.cos(rotateRad))
) - cellPadding;
let labelColor;
if (overwriteLabelColor) {
// If overwriteLabelColor is true, use the manual specified color
labelColor = zAxisConfig.get('labels.color');
} else {
// Otherwise provide a function that will calculate a light or dark color
labelColor = d => {
const bgColor = z(d);
const color = /rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/.exec(bgColor);
return color && isColorDark(parseInt(color[1]), parseInt(color[2]), parseInt(color[3]))
? '#FFF' : '#222';
};
}
let hiddenLabels = false;
squares.append('text')
.text(d => zAxisFormatter(d.y))
.style('display', function (d) {
const textLength = this.getBBox().width;
const textHeight = this.getBBox().height;
const textTooLong = textLength > maxLength;
const textTooWide = textHeight > maxHeight;
if (!d.hide && (textTooLong || textTooWide)) {
hiddenLabels = true;
}
return d.hide || textTooLong || textTooWide ? 'none' : 'initial';
})
.style('dominant-baseline', 'central')
.style('text-anchor', 'middle')
.style('fill', labelColor)
.attr('x', function (d) {
const center = x(d) + squareWidth / 2;
return center;
})
.attr('y', function (d) {
const center = y(d) + squareHeight / 2;
return center;
})
.attr('transform', function (d) {
const horizontalCenter = x(d) + squareWidth / 2;
const verticalCenter = y(d) + squareHeight / 2;
return `rotate(${rotate},${horizontalCenter},${verticalCenter})`;
});
if (hiddenLabels) {
this.baseChart.handler.alerts.show('Some labels were hidden due to size constraints');
}
}
if (isTooltip) {
squares.call(tooltip.render());
}
return squares.selectAll('rect');
}
/**
* Renders d3 visualization
*
* @method draw
* @returns {Function} Creates the line chart
*/
draw() {
const self = this;
return function (selection) {
selection.each(function () {
const svg = self.chartEl.append('g');
svg.data([self.chartData]);
const squares = self.addSquares(svg, self.chartData);
self.addCircleEvents(squares);
self.events.emit('rendered', {
chart: self.chartData
});
return svg;
});
};
}
}

View file

@ -19,224 +19,217 @@
import d3 from 'd3';
import _ from 'lodash';
import { VislibVisualizationsPointSeriesProvider } from './_point_series';
import { PointSeries } from './_point_series';
export function VislibVisualizationsLineChartProvider(Private) {
const PointSeries = Private(VislibVisualizationsPointSeriesProvider);
const defaults = {
mode: 'normal',
showCircles: true,
radiusRatio: 9,
showLines: true,
interpolate: 'linear',
lineWidth: 2,
color: undefined,
fillColor: undefined
};
/**
* Line Chart Visualization
*
* @class LineChart
* @constructor
* @extends Chart
* @param handler {Object} Reference to the Handler Class Constructor
* @param el {HTMLElement} HTML element to which the chart will be appended
* @param chartData {Object} Elasticsearch query results for this specific chart
*/
class LineChart extends PointSeries {
constructor(handler, chartEl, chartData, seriesConfigArgs) {
super(handler, chartEl, chartData, seriesConfigArgs);
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
}
addCircles(svg, data) {
const self = this;
const showCircles = this.seriesConfig.showCircles;
const color = this.handler.data.getColorFunc();
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const ordered = this.handler.data.get('ordered');
const tooltip = this.baseChart.tooltip;
const isTooltip = this.handler.visConfig.get('tooltip.show');
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const lineWidth = this.seriesConfig.lineWidth;
const radii = this.baseChart.radii;
const radiusStep = ((radii.max - radii.min) || (radii.max * 100)) / Math.pow(this.seriesConfig.radiusRatio, 2);
const layer = svg.append('g')
.attr('class', 'points line')
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
const circles = layer
.selectAll('circle')
.data(function appendData() {
return data.values.filter(function (d) {
return !_.isNull(d.y) && (d.y || !d.y0);
});
});
circles
.exit()
.remove();
function cx(d) {
if (ordered && ordered.date) {
return xScale(d.x);
}
return xScale(d.x) + xScale.rangeBand() / 2;
}
function cy(d) {
const y0 = d.y0 || 0;
const y = d.y || 0;
return yScale(y0 + y);
}
function cColor(d) {
return color(d.series);
}
function colorCircle(d) {
const parent = d3.select(this).node().parentNode;
const lengthOfParent = d3.select(parent).data()[0].length;
const isVisible = (lengthOfParent === 1);
// If only 1 point exists, show circle
if (!showCircles && !isVisible) return 'none';
return cColor(d);
}
function getCircleRadiusFn(modifier) {
return function getCircleRadius(d) {
const width = self.baseChart.chartConfig.width;
const height = self.baseChart.chartConfig.height;
const circleRadius = (d.z - radii.min) / radiusStep;
const baseMagicNumber = 2;
const base = circleRadius ? Math.sqrt(circleRadius + baseMagicNumber) + lineWidth : lineWidth;
return _.min([base, width, height]) + (modifier || 0);
};
}
circles
.enter()
.append('circle')
.attr('r', getCircleRadiusFn())
.attr('fill-opacity', (this.seriesConfig.drawLinesBetweenPoints ? 1 : 0.7))
.attr('cx', isHorizontal ? cx : cy)
.attr('cy', isHorizontal ? cy : cx)
.attr('class', 'circle-decoration')
.attr('data-label', data.label)
.attr('fill', colorCircle);
circles
.enter()
.append('circle')
.attr('r', getCircleRadiusFn(10))
.attr('cx', isHorizontal ? cx : cy)
.attr('cy', isHorizontal ? cy : cx)
.attr('fill', 'transparent')
.attr('class', 'circle')
.attr('data-label', data.label)
.attr('stroke', cColor)
.attr('stroke-width', 0);
if (isTooltip) {
circles.call(tooltip.render());
}
return circles;
}
/**
* Adds path to SVG
*
* @method addLines
* @param svg {HTMLElement} SVG to which path are appended
* @param data {Array} Array of object data points
* @returns {D3.UpdateSelection} SVG with paths added
*/
addLine(svg, data) {
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const color = this.handler.data.getColorFunc();
const ordered = this.handler.data.get('ordered');
const lineWidth = this.seriesConfig.lineWidth;
const interpolate = this.seriesConfig.interpolate;
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const line = svg.append('g')
.attr('class', 'pathgroup lines')
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
function cx(d) {
if (ordered && ordered.date) {
return xScale(d.x);
}
return xScale(d.x) + xScale.rangeBand() / 2;
}
function cy(d) {
const y = d.y || 0;
const y0 = d.y0 || 0;
return yScale(y0 + y);
}
line.append('path')
.attr('data-label', data.label)
.attr('d', () => {
const d3Line = d3.svg.line()
.defined(function (d) {
return !_.isNull(d.y);
})
.interpolate(interpolate)
.x(isHorizontal ? cx : cy)
.y(isHorizontal ? cy : cx);
return d3Line(data.values);
})
.attr('fill', 'none')
.attr('stroke', () => {
return color(data.label);
})
.attr('stroke-width', lineWidth);
return line;
}
/**
* Renders d3 visualization
*
* @method draw
* @returns {Function} Creates the line chart
*/
draw() {
const self = this;
return function (selection) {
selection.each(function () {
const svg = self.chartEl.append('g');
svg.data([self.chartData]);
if (self.seriesConfig.drawLinesBetweenPoints) {
self.addLine(svg, self.chartData);
}
const circles = self.addCircles(svg, self.chartData);
self.addCircleEvents(circles);
self.events.emit('rendered', {
chart: self.chartData
});
return svg;
});
};
}
const defaults = {
mode: 'normal',
showCircles: true,
radiusRatio: 9,
showLines: true,
interpolate: 'linear',
lineWidth: 2,
color: undefined,
fillColor: undefined
};
/**
* Line Chart Visualization
*
* @class LineChart
* @constructor
* @extends Chart
* @param handler {Object} Reference to the Handler Class Constructor
* @param el {HTMLElement} HTML element to which the chart will be appended
* @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);
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
}
return LineChart;
addCircles(svg, data) {
const self = this;
const showCircles = this.seriesConfig.showCircles;
const color = this.handler.data.getColorFunc();
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const ordered = this.handler.data.get('ordered');
const tooltip = this.baseChart.tooltip;
const isTooltip = this.handler.visConfig.get('tooltip.show');
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const lineWidth = this.seriesConfig.lineWidth;
const radii = this.baseChart.radii;
const radiusStep = ((radii.max - radii.min) || (radii.max * 100)) / Math.pow(this.seriesConfig.radiusRatio, 2);
const layer = svg.append('g')
.attr('class', 'points line')
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
const circles = layer
.selectAll('circle')
.data(function appendData() {
return data.values.filter(function (d) {
return !_.isNull(d.y) && (d.y || !d.y0);
});
});
circles
.exit()
.remove();
function cx(d) {
if (ordered && ordered.date) {
return xScale(d.x);
}
return xScale(d.x) + xScale.rangeBand() / 2;
}
function cy(d) {
const y0 = d.y0 || 0;
const y = d.y || 0;
return yScale(y0 + y);
}
function cColor(d) {
return color(d.series);
}
function colorCircle(d) {
const parent = d3.select(this).node().parentNode;
const lengthOfParent = d3.select(parent).data()[0].length;
const isVisible = (lengthOfParent === 1);
// If only 1 point exists, show circle
if (!showCircles && !isVisible) return 'none';
return cColor(d);
}
function getCircleRadiusFn(modifier) {
return function getCircleRadius(d) {
const width = self.baseChart.chartConfig.width;
const height = self.baseChart.chartConfig.height;
const circleRadius = (d.z - radii.min) / radiusStep;
const baseMagicNumber = 2;
const base = circleRadius ? Math.sqrt(circleRadius + baseMagicNumber) + lineWidth : lineWidth;
return _.min([base, width, height]) + (modifier || 0);
};
}
circles
.enter()
.append('circle')
.attr('r', getCircleRadiusFn())
.attr('fill-opacity', (this.seriesConfig.drawLinesBetweenPoints ? 1 : 0.7))
.attr('cx', isHorizontal ? cx : cy)
.attr('cy', isHorizontal ? cy : cx)
.attr('class', 'circle-decoration')
.attr('data-label', data.label)
.attr('fill', colorCircle);
circles
.enter()
.append('circle')
.attr('r', getCircleRadiusFn(10))
.attr('cx', isHorizontal ? cx : cy)
.attr('cy', isHorizontal ? cy : cx)
.attr('fill', 'transparent')
.attr('class', 'circle')
.attr('data-label', data.label)
.attr('stroke', cColor)
.attr('stroke-width', 0);
if (isTooltip) {
circles.call(tooltip.render());
}
return circles;
}
/**
* Adds path to SVG
*
* @method addLines
* @param svg {HTMLElement} SVG to which path are appended
* @param data {Array} Array of object data points
* @returns {D3.UpdateSelection} SVG with paths added
*/
addLine(svg, data) {
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const color = this.handler.data.getColorFunc();
const ordered = this.handler.data.get('ordered');
const lineWidth = this.seriesConfig.lineWidth;
const interpolate = this.seriesConfig.interpolate;
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const line = svg.append('g')
.attr('class', 'pathgroup lines')
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
function cx(d) {
if (ordered && ordered.date) {
return xScale(d.x);
}
return xScale(d.x) + xScale.rangeBand() / 2;
}
function cy(d) {
const y = d.y || 0;
const y0 = d.y0 || 0;
return yScale(y0 + y);
}
line.append('path')
.attr('data-label', data.label)
.attr('d', () => {
const d3Line = d3.svg.line()
.defined(function (d) {
return !_.isNull(d.y);
})
.interpolate(interpolate)
.x(isHorizontal ? cx : cy)
.y(isHorizontal ? cy : cx);
return d3Line(data.values);
})
.attr('fill', 'none')
.attr('stroke', () => {
return color(data.label);
})
.attr('stroke-width', lineWidth);
return line;
}
/**
* Renders d3 visualization
*
* @method draw
* @returns {Function} Creates the line chart
*/
draw() {
const self = this;
return function (selection) {
selection.each(function () {
const svg = self.chartEl.append('g');
svg.data([self.chartData]);
if (self.seriesConfig.drawLinesBetweenPoints) {
self.addLine(svg, self.chartData);
}
const circles = self.addCircles(svg, self.chartData);
self.addCircleEvents(circles);
self.events.emit('rendered', {
chart: self.chartData
});
return svg;
});
};
}
}

View file

@ -17,17 +17,14 @@
* under the License.
*/
import { VislibVisualizationsColumnChartProvider } from './column_chart';
import { VislibVisualizationsLineChartProvider } from './line_chart';
import { VislibVisualizationsAreaChartProvider } from './area_chart';
import { VislibVisualizationsHeatmapChartProvider } from './heatmap_chart';
import { ColumnChart } from './column_chart';
import { LineChart } from './line_chart';
import { AreaChart } from './area_chart';
import { HeatmapChart } from './heatmap_chart';
export function VislibVisualizationsSeriesTypesProvider(Private) {
return {
histogram: Private(VislibVisualizationsColumnChartProvider),
line: Private(VislibVisualizationsLineChartProvider),
area: Private(VislibVisualizationsAreaChartProvider),
heatmap: Private(VislibVisualizationsHeatmapChartProvider)
};
}
export const seriesTypes = {
histogram: ColumnChart,
line: LineChart,
area: AreaChart,
heatmap: HeatmapChart
};

View file

@ -20,72 +20,67 @@
import d3 from 'd3';
import dateMath from '@elastic/datemath';
export function VislibVisualizationsTimeMarkerProvider() {
export class TimeMarker {
constructor(times, xScale, height) {
const currentTimeArr = [{
'time': new Date().getTime(),
'class': 'time-marker',
'color': '#c80000',
'opacity': 0.3,
'width': 2
}];
class TimeMarker {
constructor(times, xScale, height) {
const currentTimeArr = [{
'time': new Date().getTime(),
'class': 'time-marker',
'color': '#c80000',
'opacity': 0.3,
'width': 2
}];
this.xScale = xScale;
this.height = height;
this.times = (times.length) ? times.map(function (d) {
return {
'time': dateMath.parse(d.time),
'class': d.class || 'time-marker',
'color': d.color || '#c80000',
'opacity': d.opacity || 0.3,
'width': d.width || 2
};
}) : currentTimeArr;
}
_isTimeBasedChart(selection) {
const data = selection.data();
return data.every(function (datum) {
return (datum.ordered && datum.ordered.date);
});
}
render(selection) {
const self = this;
// return if not time based chart
if (!self._isTimeBasedChart(selection)) return;
selection.each(function () {
d3.select(this).selectAll('time-marker')
.data(self.times)
.enter().append('line')
.attr('class', function (d) {
return d.class;
})
.attr('pointer-events', 'none')
.attr('stroke', function (d) {
return d.color;
})
.attr('stroke-width', function (d) {
return d.width;
})
.attr('stroke-opacity', function (d) {
return d.opacity;
})
.attr('x1', function (d) {
return self.xScale(d.time);
})
.attr('x2', function (d) {
return self.xScale(d.time);
})
.attr('y1', self.height)
.attr('y2', self.xScale.range()[0]);
});
}
this.xScale = xScale;
this.height = height;
this.times = (times.length) ? times.map(function (d) {
return {
'time': dateMath.parse(d.time),
'class': d.class || 'time-marker',
'color': d.color || '#c80000',
'opacity': d.opacity || 0.3,
'width': d.width || 2
};
}) : currentTimeArr;
}
return TimeMarker;
_isTimeBasedChart(selection) {
const data = selection.data();
return data.every(function (datum) {
return (datum.ordered && datum.ordered.date);
});
}
render(selection) {
const self = this;
// return if not time based chart
if (!self._isTimeBasedChart(selection)) return;
selection.each(function () {
d3.select(this).selectAll('time-marker')
.data(self.times)
.enter().append('line')
.attr('class', function (d) {
return d.class;
})
.attr('pointer-events', 'none')
.attr('stroke', function (d) {
return d.color;
})
.attr('stroke-width', function (d) {
return d.width;
})
.attr('stroke-opacity', function (d) {
return d.opacity;
})
.attr('x1', function (d) {
return self.xScale(d.time);
})
.attr('x2', function (d) {
return self.xScale(d.time);
})
.attr('y1', self.height)
.attr('y2', self.xScale.range()[0]);
});
}
}

View file

@ -18,24 +18,13 @@ exports[`VisualizationNoResults should render according to snapshot 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiIcon--subdued euiIcon--app"
class="euiIcon euiIcon--medium euiIcon--subdued euiIcon--app euiIcon-isLoading"
focusable="false"
height="32"
viewBox="0 0 32 32"
width="32"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
class="euiIcon__fillSecondary"
d="M32 32H4a4 4 0 0 1-4-4V0h2v28a2 2 0 0 0 2 2h28v2z"
/>
<path
d="M6 20h2v7H6zM16 12h2v15h-2zM26 17h2v10h-2z"
/>
<path
d="M27 6a3 3 0 0 0-2.08.84L20 4.36A2.2 2.2 0 0 0 20 4a3 3 0 0 0-6 0c.001.341.062.68.18 1l-5.6 4.46A3 3 0 0 0 7 9a3 3 0 1 0 3 3 2.93 2.93 0 0 0-.18-1l5.6-4.48A3 3 0 0 0 17 7a3 3 0 0 0 2.08-.84l5 2.48A2.2 2.2 0 0 0 24 9a3 3 0 1 0 3-3zM7 13a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm10-8a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm10 5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"
/>
</svg>
/>
<div
class="euiSpacer euiSpacer--s"
/>

View file

@ -12,18 +12,13 @@ exports[`VisualizationRequestError should render according to snapshot 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiIcon--danger"
class="euiIcon euiIcon--medium euiIcon--danger euiIcon-isLoading"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.59 10.059L7.35 5.18h1.3L8.4 10.06h-.81zm.394 1.901a.61.61 0 0 1-.448-.186.606.606 0 0 1-.186-.444c0-.174.062-.323.186-.446a.614.614 0 0 1 .448-.184c.169 0 .315.06.44.182.124.122.186.27.186.448a.6.6 0 0 1-.189.446.607.607 0 0 1-.437.184zM2 14a1 1 0 0 1-.878-1.479l6-11a1 1 0 0 1 1.756 0l6 11A1 1 0 0 1 14 14H2zm0-1h12L8 2 2 13z"
fill-rule="evenodd"
/>
</svg>
/>
<div
class="euiSpacer euiSpacer--s"
/>

View file

@ -7,7 +7,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@elastic/eui": "10.4.1",
"@elastic/eui": "11.0.1",
"react": "^16.8.0",
"react-dom": "^16.8.0"
}

View file

@ -7,7 +7,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@elastic/eui": "10.4.1",
"@elastic/eui": "11.0.1",
"react": "^16.8.0"
}
}

View file

@ -8,7 +8,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@elastic/eui": "10.4.1",
"@elastic/eui": "11.0.1",
"react": "^16.8.0"
},
"scripts": {

View file

@ -7,7 +7,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@elastic/eui": "10.4.1",
"@elastic/eui": "11.0.1",
"react": "^16.8.0",
"react-dom": "^16.8.0"
}

View file

@ -20,8 +20,9 @@
"strict": true,
// enables "core language features"
"lib": [
// ESNext auto includes previous versions all the way back to es5
"esnext",
// ES2018 includes previous versions all the way back to es5
// We are not using esnext because @babel/polyfill is on core-js 2, not 3
"es2018",
// includes support for browser APIs
"dom"
],

View file

@ -41,7 +41,8 @@ export function createJestConfig({
'^.+\\.(js|tsx?)$': `${kibanaDirectory}/src/dev/jest/babel_transform.js`,
},
transformIgnorePatterns: [
'[/\\\\]node_modules[/\\\\].+\\.js$'
// ignore all node_modules except @elastic/eui which requires babel transforms to handle dynamic import()
'[/\\\\]node_modules(?![\\/\\\\]@elastic[\\/\\\\]eui)[/\\\\].+\\.js$'
],
snapshotSerializers: [
`${kibanaDirectory}/node_modules/enzyme-to-json/serializer`

View file

@ -84,7 +84,7 @@
"@types/react-sticky": "^6.0.3",
"@types/react-test-renderer": "^16.8.0",
"@types/recompose": "^0.30.2",
"@types/reduce-reducers": "^0.1.3",
"@types/reduce-reducers": "^0.3.0",
"@types/redux-actions": "^2.2.1",
"@types/rimraf": "^2.0.2",
"@types/sinon": "^7.0.0",
@ -120,7 +120,7 @@
"enzyme-to-json": "^3.3.4",
"execa": "^1.0.0",
"fancy-log": "^1.3.2",
"fetch-mock": "7.3.0",
"fetch-mock": "7.3.3",
"graphql-code-generator": "^0.13.0",
"graphql-codegen-introspection-template": "^0.13.0",
"graphql-codegen-typescript-resolvers-template": "^0.13.0",
@ -168,7 +168,7 @@
"@babel/register": "7.4.4",
"@babel/runtime": "7.4.5",
"@elastic/datemath": "5.0.2",
"@elastic/eui": "10.4.1",
"@elastic/eui": "11.0.1",
"@elastic/javascript-typescript-langserver": "^0.1.27",
"@elastic/lsp-extension": "^0.1.1",
"@elastic/node-crypto": "^1.0.0",
@ -212,16 +212,16 @@
"copy-to-clipboard": "^3.0.8",
"core-js": "2.6.9",
"cronstrue": "^1.51.0",
"d3": "3.5.6",
"d3-scale": "1.0.6",
"d3": "3.5.17",
"d3-scale": "1.0.7",
"dataloader": "^1.4.0",
"dedent": "^0.7.0",
"dragselect": "1.8.1",
"dragselect": "1.12.2",
"elasticsearch": "^15.5.0",
"extract-zip": "1.5.0",
"extract-zip": "1.6.7",
"file-saver": "^1.3.8",
"file-type": "^10.9.0",
"font-awesome": "4.4.0",
"font-awesome": "4.7.0",
"formsy-react": "^1.1.5",
"get-port": "4.2.0",
"getos": "^3.1.0",
@ -246,7 +246,7 @@
"io-ts": "^1.4.2",
"joi": "^13.5.2",
"jquery": "^3.4.1",
"js-yaml": "3.4.1",
"js-yaml": "3.13.1",
"json-stable-stringify": "^1.0.1",
"jsonwebtoken": "^8.3.0",
"lodash": "npm:@elastic/lodash@3.10.1-kibana1",
@ -268,7 +268,7 @@
"moment-duration-format": "^1.3.0",
"moment-timezone": "^0.5.14",
"memoize-one": "^5.0.0",
"monaco-editor": "^0.14.3",
"monaco-editor": "^0.17.0",
"ngreact": "^0.5.1",
"nock": "10.0.4",
"node-fetch": "^2.1.2",

View file

@ -42,26 +42,14 @@ exports[`ErrorGroupOverview -> List should render empty state 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonEmpty__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonEmpty__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
<span
className="euiButtonEmpty__text"
>
@ -190,18 +178,14 @@ exports[`ErrorGroupOverview -> List should render empty state 1`] = `
</span>
<svg
aria-label="Sorted in descending order"
className="euiIcon euiIcon--medium euiTableSortIcon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiTableSortIcon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7 11.692V3.556C7 3.249 7.224 3 7.5 3s.5.249.5.556v8.136l4.096-4.096a.5.5 0 0 1 .707.707l-4.242 4.243a1.494 1.494 0 0 1-.925.433.454.454 0 0 1-.272 0 1.494 1.494 0 0 1-.925-.433L2.197 8.303a.5.5 0 1 1 .707-.707L7 11.692z"
/>
</svg>
/>
<span
className="euiScreenReaderOnly"
>
@ -266,26 +250,14 @@ exports[`ErrorGroupOverview -> List should render empty state 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonEmpty__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonEmpty__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
<span
className="euiButtonEmpty__text"
>
@ -374,26 +346,14 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonEmpty__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonEmpty__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
<span
className="euiButtonEmpty__text"
>
@ -522,18 +482,14 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = `
</span>
<svg
aria-label="Sorted in descending order"
className="euiIcon euiIcon--medium euiTableSortIcon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiTableSortIcon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7 11.692V3.556C7 3.249 7.224 3 7.5 3s.5.249.5.556v8.136l4.096-4.096a.5.5 0 0 1 .707.707l-4.242 4.243a1.494 1.494 0 0 1-.925.433.454.454 0 0 1-.272 0 1.494 1.494 0 0 1-.925-.433L2.197 8.303a.5.5 0 1 1 .707-.707L7 11.692z"
/>
</svg>
/>
<span
className="euiScreenReaderOnly"
>
@ -1008,26 +964,14 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonEmpty__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonEmpty__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
<span
className="euiButtonEmpty__text"
>

View file

@ -16,13 +16,16 @@ import {
asDecimal
} from '../../../utils/formatters';
import { Coordinate } from '../../../../typings/timeseries';
import { getEmptySeries } from '../../shared/charts/CustomPlot/getEmptySeries';
interface Props {
start: number | string | undefined;
end: number | string | undefined;
chart: GenericMetricsChart;
hoverXHandlers: HoverXHandlers;
}
export function MetricsChart({ chart, hoverXHandlers }: Props) {
export function MetricsChart({ start, end, chart, hoverXHandlers }: Props) {
const formatYValue = getYTickFormatter(chart);
const formatTooltip = getTooltipFormatter(chart);
@ -31,6 +34,8 @@ export function MetricsChart({ chart, hoverXHandlers }: Props) {
legendValue: formatYValue(series.overallValue)
}));
const noHits = chart.totalHits === 0;
return (
<React.Fragment>
<EuiTitle size="xs">
@ -38,8 +43,8 @@ export function MetricsChart({ chart, hoverXHandlers }: Props) {
</EuiTitle>
<CustomPlot
{...hoverXHandlers}
noHits={chart.totalHits === 0}
series={transformedSeries}
noHits={noHits}
series={noHits ? getEmptySeries(start, end) : transformedSeries}
tickFormatY={formatYValue}
formatTooltipValue={formatTooltip}
yMax={chart.yUnit === 'percent' ? 1 : 'max'}
@ -52,8 +57,8 @@ function getYTickFormatter(chart: GenericMetricsChart) {
switch (chart.yUnit) {
case 'bytes': {
const max = Math.max(
...chart.series.flatMap(series =>
series.data.map(coord => coord.y || 0)
...chart.series.map(({ data }) =>
Math.max(...data.map(({ y }) => y || 0))
)
);
return getFixedByteFormatter(max);

View file

@ -18,6 +18,7 @@ interface ServiceMetricsProps {
export function ServiceMetrics({ urlParams, agentName }: ServiceMetricsProps) {
const { data } = useServiceMetricCharts(urlParams, agentName);
const { start, end } = urlParams;
return (
<React.Fragment>
<SyncChartGroup
@ -26,7 +27,12 @@ export function ServiceMetrics({ urlParams, agentName }: ServiceMetricsProps) {
{data.charts.map(chart => (
<EuiFlexItem key={chart.key}>
<EuiPanel>
<MetricsChart chart={chart} hoverXHandlers={hoverXHandlers} />
<MetricsChart
start={start}
end={end}
chart={chart}
hoverXHandlers={hoverXHandlers}
/>
</EuiPanel>
</EuiFlexItem>
))}

View file

@ -106,13 +106,12 @@ NodeList [
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiButton__icon"
class="euiIcon euiIcon--medium euiIcon-isLoaded euiButton__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<path

View file

@ -18,13 +18,12 @@ exports[`TransactionActionMenu component should match the snapshot 1`] = `
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium euiButtonEmpty__icon"
class="euiIcon euiIcon--medium euiIcon-isLoaded euiButtonEmpty__icon"
focusable="false"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<path

View file

@ -0,0 +1,30 @@
/*
* 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 { memoize } from 'lodash';
import d3 from 'd3';
export const getEmptySeries = memoize(
(
start: number | string = Date.now() - 3600000,
end: number | string = Date.now()
) => {
const dates = d3.time
.scale()
.domain([new Date(start), new Date(end)])
.ticks();
return [
{
data: dates.map(x => ({
x: x.getTime(),
y: 1
}))
}
];
},
(start: string, end: string) => [start, end].join('_')
);

View file

@ -13,10 +13,8 @@ import { InnerCustomPlot } from '../index';
import responseWithData from './responseWithData.json';
import VoronoiPlot from '../VoronoiPlot';
import InteractivePlot from '../InteractivePlot';
import {
getResponseTimeSeries,
getEmptySerie
} from '../../../../../selectors/chartSelectors';
import { getResponseTimeSeries } from '../../../../../selectors/chartSelectors';
import { getEmptySeries } from '../getEmptySeries';
function getXValueByIndex(index) {
return responseWithData.responseTimes.avg[index].x;
@ -289,7 +287,7 @@ describe('when response has no data', () => {
const onSelectionEnd = jest.fn();
let wrapper;
beforeEach(() => {
const series = getEmptySerie(1451606400000, 1451610000000);
const series = getEmptySeries(1451606400000, 1451610000000);
wrapper = mount(
<InnerCustomPlot

View file

@ -27,6 +27,7 @@ import { MLJobLink } from '../../Links/MachineLearningLinks/MLJobLink';
import CustomPlot from '../CustomPlot';
import { SyncChartGroup } from '../SyncChartGroup';
import { LicenseContext } from '../../../../context/LicenseContext';
import { getEmptySeries } from '../CustomPlot/getEmptySeries';
interface TransactionChartProps {
hasMLJob: boolean;
@ -134,7 +135,7 @@ export class TransactionCharts extends Component<TransactionChartProps> {
public render() {
const { charts, urlParams } = this.props;
const { noHits, responseTimeSeries, tpmSeries } = charts;
const { transactionType } = urlParams;
const { transactionType, start, end } = urlParams;
return (
<SyncChartGroup
@ -157,7 +158,9 @@ export class TransactionCharts extends Component<TransactionChartProps> {
</EuiFlexGroup>
<CustomPlot
noHits={noHits}
series={responseTimeSeries}
series={
noHits ? getEmptySeries(start, end) : responseTimeSeries
}
{...hoverXHandlers}
tickFormatY={this.getResponseTimeTickFormatter}
formatTooltipValue={this.getResponseTimeTooltipFormatter}
@ -174,7 +177,7 @@ export class TransactionCharts extends Component<TransactionChartProps> {
</EuiTitle>
<CustomPlot
noHits={noHits}
series={tpmSeries}
series={noHits ? getEmptySeries(start, end) : tpmSeries}
{...hoverXHandlers}
tickFormatY={this.getTPMFormatter}
formatTooltipValue={this.getTPMTooltipFormatter}

View file

@ -6,8 +6,7 @@
import theme from '@elastic/eui/dist/eui_theme_light.json';
import { i18n } from '@kbn/i18n';
import d3 from 'd3';
import { difference, memoize, zipObject } from 'lodash';
import { difference, zipObject } from 'lodash';
import mean from 'lodash.mean';
import { rgba } from 'polished';
import { TimeSeriesAPIResponse } from '../../server/lib/transactions/charts';
@ -17,32 +16,6 @@ import { Coordinate, RectCoordinate } from '../../typings/timeseries';
import { asDecimal, asMillis, tpmUnit } from '../utils/formatters';
import { IUrlParams } from '../context/UrlParamsContext/types';
export const getEmptySerie = memoize(
(
start: string | number = Date.now() - 3600000,
end: string | number = Date.now()
) => {
const dates = d3.time
.scale()
.domain([new Date(start), new Date(end)])
.ticks();
return [
{
data: dates.map(x => ({
x: x.getTime(),
y: 1
}))
}
];
},
(start: string, end: string) => [start, end].join('_')
);
interface IEmptySeries {
data: Coordinate[];
}
export interface ITpmBucket {
title: string;
data: Coordinate[];
@ -53,8 +26,8 @@ export interface ITpmBucket {
export interface ITransactionChartData {
noHits: boolean;
tpmSeries: ITpmBucket[] | IEmptySeries[];
responseTimeSeries: TimeSerie[] | IEmptySeries[];
tpmSeries: ITpmBucket[];
responseTimeSeries: TimeSerie[];
}
const INITIAL_DATA = {
@ -72,17 +45,16 @@ const INITIAL_DATA = {
};
export function getTransactionCharts(
{ start, end, transactionType }: IUrlParams,
{ transactionType }: IUrlParams,
{ apmTimeseries, anomalyTimeseries }: TimeSeriesAPIResponse = INITIAL_DATA
): ITransactionChartData {
const noHits = apmTimeseries.totalHits === 0;
const tpmSeries = noHits
? getEmptySerie(start, end)
: getTpmSeries(apmTimeseries, transactionType);
const tpmSeries = getTpmSeries(apmTimeseries, transactionType);
const responseTimeSeries = noHits
? getEmptySerie(start, end)
: getResponseTimeSeries({ apmTimeseries, anomalyTimeseries });
const responseTimeSeries = getResponseTimeSeries({
apmTimeseries,
anomalyTimeseries
});
return {
noHits,

View file

@ -1,41 +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.
*/
declare module 'ui/autocomplete_providers' {
import { StaticIndexPattern } from 'ui/index_patterns';
export type AutocompleteProvider = (
args: {
config: {
get(configKey: string): any;
};
indexPatterns: StaticIndexPattern[];
boolFilter: any;
}
) => GetSuggestions;
export type GetSuggestions = (
args: {
query: string;
selectionStart: number;
selectionEnd: number;
}
) => Promise<AutocompleteSuggestion[]>;
export type AutocompleteSuggestionType = 'field' | 'value' | 'operator' | 'conjunction';
export interface AutocompleteSuggestion {
description: string;
end: number;
start: number;
text: string;
type: AutocompleteSuggestionType;
}
export function addAutocompleteProvider(language: string, provider: AutocompleteProvider): void;
export function getAutocompleteProvider(language: string): AutocompleteProvider | undefined;
}

View file

@ -16,26 +16,14 @@ exports[`Storyshots renderers/DropdownFilter default 1`] = `
</option>
</select>
<svg
className="euiIcon euiIcon--medium canvasDropdownFilter__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading canvasDropdownFilter__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
</div>
`;
@ -73,26 +61,14 @@ exports[`Storyshots renderers/DropdownFilter with choices 1`] = `
</option>
</select>
<svg
className="euiIcon euiIcon--medium canvasDropdownFilter__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading canvasDropdownFilter__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
</div>
`;
@ -131,26 +107,14 @@ exports[`Storyshots renderers/DropdownFilter with choices and new value 1`] = `
</option>
</select>
<svg
className="euiIcon euiIcon--medium canvasDropdownFilter__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading canvasDropdownFilter__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
</div>
`;
@ -189,26 +153,14 @@ exports[`Storyshots renderers/DropdownFilter with choices and value 1`] = `
</option>
</select>
<svg
className="euiIcon euiIcon--medium canvasDropdownFilter__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading canvasDropdownFilter__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
</div>
`;
@ -229,25 +181,13 @@ exports[`Storyshots renderers/DropdownFilter with new value 1`] = `
</option>
</select>
<svg
className="euiIcon euiIcon--medium canvasDropdownFilter__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading canvasDropdownFilter__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
</div>
`;

View file

@ -81,18 +81,14 @@ exports[`Storyshots components/Asset airplane 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12.5 11V5H11V3.5H5V5H3.5v6H5v1.5h6V11h1.5zm1 0H15v4h-4v-1.5H5V15H1v-4h1.5V5H1V1h4v1.5h6V1h4v4h-1.5v6zM4 4V2H2v2h2zm8 0h2V2h-2v2zM2 14h2v-2H2v2zm10 0h2v-2h-2v2z"
/>
</svg>
/>
</button>
</span>
</div>
@ -118,18 +114,14 @@ exports[`Storyshots components/Asset airplane 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7 11.692V3.556C7 3.249 7.224 3 7.5 3s.5.249.5.556v8.136l4.096-4.096a.5.5 0 0 1 .707.707l-4.242 4.243a1.494 1.494 0 0 1-.925.433.454.454 0 0 1-.272 0 1.494 1.494 0 0 1-.925-.433L2.197 8.303a.5.5 0 1 1 .707-.707L7 11.692z"
/>
</svg>
/>
</button>
</div>
</span>
@ -156,21 +148,14 @@ exports[`Storyshots components/Asset airplane 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 2.729V2a1 1 0 0 1 1-1h2v1H1v12h4v1H1a1 1 0 0 1-1-1V2.729zM12 5V2a1 1 0 0 0-1-1H9v1h2v3h1zm-1 1h2v9H6V6h5V5H6a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2v1z"
/>
<path
d="M7 10h5V9H7zM7 8h5V7H7zM7 12h5v-1H7zM7 14h5v-1H7zM9 2V1a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v1h1V1h4v1h1zM3 3h6V2H3z"
/>
</svg>
/>
</button>
</div>
</span>
@ -194,25 +179,14 @@ exports[`Storyshots components/Asset airplane 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11 3h5v1H0V3h5V1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2zm-7.056 8H7v1H4.1l.392 2.519c.042.269.254.458.493.458h6.03c.239 0 .451-.189.493-.458l1.498-9.576H14l-1.504 9.73c-.116.747-.74 1.304-1.481 1.304h-6.03c-.741 0-1.365-.557-1.481-1.304l-1.511-9.73H9V5.95H3.157L3.476 8H8v1H3.632l.312 2zM6 3h4V1H6v2z"
id="trash-a"
/>
</defs>
<use
xlinkHref="#trash-a"
/>
</svg>
/>
</button>
</span>
</div>
@ -303,18 +277,14 @@ exports[`Storyshots components/Asset marker 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12.5 11V5H11V3.5H5V5H3.5v6H5v1.5h6V11h1.5zm1 0H15v4h-4v-1.5H5V15H1v-4h1.5V5H1V1h4v1.5h6V1h4v4h-1.5v6zM4 4V2H2v2h2zm8 0h2V2h-2v2zM2 14h2v-2H2v2zm10 0h2v-2h-2v2z"
/>
</svg>
/>
</button>
</span>
</div>
@ -340,18 +310,14 @@ exports[`Storyshots components/Asset marker 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7 11.692V3.556C7 3.249 7.224 3 7.5 3s.5.249.5.556v8.136l4.096-4.096a.5.5 0 0 1 .707.707l-4.242 4.243a1.494 1.494 0 0 1-.925.433.454.454 0 0 1-.272 0 1.494 1.494 0 0 1-.925-.433L2.197 8.303a.5.5 0 1 1 .707-.707L7 11.692z"
/>
</svg>
/>
</button>
</div>
</span>
@ -378,21 +344,14 @@ exports[`Storyshots components/Asset marker 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 2.729V2a1 1 0 0 1 1-1h2v1H1v12h4v1H1a1 1 0 0 1-1-1V2.729zM12 5V2a1 1 0 0 0-1-1H9v1h2v3h1zm-1 1h2v9H6V6h5V5H6a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2v1z"
/>
<path
d="M7 10h5V9H7zM7 8h5V7H7zM7 12h5v-1H7zM7 14h5v-1H7zM9 2V1a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v1h1V1h4v1h1zM3 3h6V2H3z"
/>
</svg>
/>
</button>
</div>
</span>
@ -416,25 +375,14 @@ exports[`Storyshots components/Asset marker 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11 3h5v1H0V3h5V1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2zm-7.056 8H7v1H4.1l.392 2.519c.042.269.254.458.493.458h6.03c.239 0 .451-.189.493-.458l1.498-9.576H14l-1.504 9.73c-.116.747-.74 1.304-1.481 1.304h-6.03c-.741 0-1.365-.557-1.481-1.304l-1.511-9.73H9V5.95H3.157L3.476 8H8v1H3.632l.312 2zM6 3h4V1H6v2z"
id="trash-a"
/>
</defs>
<use
xlinkHref="#trash-a"
/>
</svg>
/>
</button>
</span>
</div>

View file

@ -82,23 +82,18 @@ Array [
}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#000",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z"
fillRule="evenodd"
/>
</svg>
/>
</div>
</div>,
<div
@ -116,23 +111,18 @@ Array [
}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#fff",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z"
fillRule="evenodd"
/>
</svg>
/>
</div>
</div>,
<div
@ -150,23 +140,18 @@ Array [
}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#fff",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.59 10.059L7.35 5.18h1.3L8.4 10.06h-.81zm.394 1.901a.61.61 0 0 1-.448-.186.606.606 0 0 1-.186-.444c0-.174.062-.323.186-.446a.614.614 0 0 1 .448-.184c.169 0 .315.06.44.182.124.122.186.27.186.448a.6.6 0 0 1-.189.446.607.607 0 0 1-.437.184zM2 14a1 1 0 0 1-.878-1.479l6-11a1 1 0 0 1 1.756 0l6 11A1 1 0 0 1 14 14H2zm0-1h12L8 2 2 13z"
fillRule="evenodd"
/>
</svg>
/>
</div>
</div>,
<div
@ -184,23 +169,18 @@ Array [
}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#fff",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.5 12a.502.502 0 0 1-.354-.146l-4-4a.502.502 0 0 1 .708-.708L6.5 10.793l6.646-6.647a.502.502 0 0 1 .708.708l-7 7A.502.502 0 0 1 6.5 12"
fillRule="evenodd"
/>
</svg>
/>
</div>
</div>,
]

View file

@ -202,19 +202,14 @@ exports[`Storyshots components/ColorManager interactive 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z"
fillRule="evenodd"
/>
</svg>
/>
</button>
<button
aria-label="Remove Color"
@ -225,19 +220,14 @@ exports[`Storyshots components/ColorManager interactive 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z"
fillRule="evenodd"
/>
</svg>
/>
</button>
</div>
</div>
@ -415,19 +405,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z"
fillRule="evenodd"
/>
</svg>
/>
</button>
<button
aria-label="Remove Color"
@ -438,19 +423,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z"
fillRule="evenodd"
/>
</svg>
/>
</button>
</div>
</div>,
@ -512,19 +492,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z"
fillRule="evenodd"
/>
</svg>
/>
</button>
<button
aria-label="Remove Color"
@ -535,19 +510,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z"
fillRule="evenodd"
/>
</svg>
/>
</button>
</div>
</div>,
@ -609,19 +579,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z"
fillRule="evenodd"
/>
</svg>
/>
</button>
<button
aria-label="Remove Color"
@ -632,19 +597,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z"
fillRule="evenodd"
/>
</svg>
/>
</button>
</div>
</div>,

View file

@ -364,23 +364,18 @@ Array [
}
>
<svg
className="euiIcon euiIcon--medium selected-color"
className="euiIcon euiIcon--medium euiIcon-isLoading selected-color"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#333",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.5 12a.502.502 0 0 1-.354-.146l-4-4a.502.502 0 0 1 .708-.708L6.5 10.793l6.646-6.647a.502.502 0 0 1 .708.708l-7 7A.502.502 0 0 1 6.5 12"
fillRule="evenodd"
/>
</svg>
/>
</div>
</div>
</button>
@ -718,23 +713,18 @@ exports[`Storyshots components/ColorPalette six colors, wrap at 4 1`] = `
}
>
<svg
className="euiIcon euiIcon--medium selected-color"
className="euiIcon euiIcon--medium euiIcon-isLoading selected-color"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#333",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.5 12a.502.502 0 0 1-.354-.146l-4-4a.502.502 0 0 1 .708-.708L6.5 10.793l6.646-6.647a.502.502 0 0 1 .708.708l-7 7A.502.502 0 0 1 6.5 12"
fillRule="evenodd"
/>
</svg>
/>
</div>
</div>
</button>
@ -995,23 +985,18 @@ Array [
}
>
<svg
className="euiIcon euiIcon--medium selected-color"
className="euiIcon euiIcon--medium euiIcon-isLoading selected-color"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#333",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.5 12a.502.502 0 0 1-.354-.146l-4-4a.502.502 0 0 1 .708-.708L6.5 10.793l6.646-6.647a.502.502 0 0 1 .708.708l-7 7A.502.502 0 0 1 6.5 12"
fillRule="evenodd"
/>
</svg>
/>
</div>
</div>
</button>

View file

@ -221,19 +221,14 @@ exports[`Storyshots components/ColorPicker interactive 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z"
fillRule="evenodd"
/>
</svg>
/>
</button>
<button
aria-label="Remove Color"
@ -244,19 +239,14 @@ exports[`Storyshots components/ColorPicker interactive 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z"
fillRule="evenodd"
/>
</svg>
/>
</button>
</div>
</div>
@ -317,23 +307,18 @@ exports[`Storyshots components/ColorPicker six colors 1`] = `
}
>
<svg
className="euiIcon euiIcon--medium selected-color"
className="euiIcon euiIcon--medium euiIcon-isLoading selected-color"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#333",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.5 12a.502.502 0 0 1-.354-.146l-4-4a.502.502 0 0 1 .708-.708L6.5 10.793l6.646-6.647a.502.502 0 0 1 .708.708l-7 7A.502.502 0 0 1 6.5 12"
fillRule="evenodd"
/>
</svg>
/>
</div>
</div>
</button>
@ -527,19 +512,14 @@ exports[`Storyshots components/ColorPicker six colors 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z"
fillRule="evenodd"
/>
</svg>
/>
</button>
<button
aria-label="Remove Color"
@ -550,19 +530,14 @@ exports[`Storyshots components/ColorPicker six colors 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z"
fillRule="evenodd"
/>
</svg>
/>
</button>
</div>
</div>
@ -793,19 +768,14 @@ exports[`Storyshots components/ColorPicker six colors, value missing 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z"
fillRule="evenodd"
/>
</svg>
/>
</button>
<button
aria-label="Remove Color"
@ -816,19 +786,14 @@ exports[`Storyshots components/ColorPicker six colors, value missing 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z"
fillRule="evenodd"
/>
</svg>
/>
</button>
</div>
</div>
@ -868,23 +833,18 @@ exports[`Storyshots components/ColorPicker three colors 1`] = `
}
>
<svg
className="euiIcon euiIcon--medium selected-color"
className="euiIcon euiIcon--medium euiIcon-isLoading selected-color"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#333",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.5 12a.502.502 0 0 1-.354-.146l-4-4a.502.502 0 0 1 .708-.708L6.5 10.793l6.646-6.647a.502.502 0 0 1 .708.708l-7 7A.502.502 0 0 1 6.5 12"
fillRule="evenodd"
/>
</svg>
/>
</div>
</div>
</button>
@ -1000,19 +960,14 @@ exports[`Storyshots components/ColorPicker three colors 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z"
fillRule="evenodd"
/>
</svg>
/>
</button>
<button
aria-label="Remove Color"
@ -1023,19 +978,14 @@ exports[`Storyshots components/ColorPicker three colors 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z"
fillRule="evenodd"
/>
</svg>
/>
</button>
</div>
</div>

View file

@ -56,18 +56,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
/>
</button>
<div
className="euiModal__flex"
@ -197,18 +193,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiFilePicker__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFilePicker__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9 10.114l1.85-1.943a.52.52 0 0 1 .77 0c.214.228.214.6 0 .829l-1.95 2.05a1.552 1.552 0 0 1-2.31 0L5.41 9a.617.617 0 0 1 0-.829.52.52 0 0 1 .77 0L8 10.082V1.556C8 1.249 8.224 1 8.5 1s.5.249.5.556v8.558zM4.18 6a.993.993 0 0 0-.972.804l-1.189 6A.995.995 0 0 0 2.991 14h11.018a1 1 0 0 0 .972-1.196l-1.19-6a.993.993 0 0 0-.97-.804H4.18zM6 5v1h5V5h1.825c.946 0 1.76.673 1.946 1.608l1.19 6A2 2 0 0 1 14.016 15H2.984a1.992 1.992 0 0 1-1.945-2.392l1.19-6C2.414 5.673 3.229 5 4.174 5H6z"
/>
</svg>
/>
<div
className="euiFilePicker__promptText"
>
@ -244,22 +236,14 @@ Array [
className="euiCard__top"
>
<svg
className="euiIcon euiIcon--xxLarge euiIcon--app euiCard__icon"
className="euiIcon euiIcon--xxLarge euiIcon--app euiIcon-isLoading euiCard__icon"
focusable="false"
height="32"
height={16}
style={null}
viewBox="0 0 32 32"
width="32"
viewBox="0 0 16 16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
className="euiIcon__fillSecondary"
d="M7 17h2v7H7zM12 14h2v10h-2zM17 16h2v8h-2zM22 14h3v2h-3zM22 18h3v2h-3zM22 22h3v2h-3z"
/>
<path
d="M30.73 24a6.47 6.47 0 0 1 .45-2.19c.337-.9.52-1.85.54-2.81a8.55 8.55 0 0 0-.54-2.81 6.47 6.47 0 0 1-.45-2.19 9.2 9.2 0 0 1 .62-2.49c.53-1.57 1.08-3.19.08-4.2-1-1.01-2.41-.44-3.52.05a5.59 5.59 0 0 1-2.09.64 5.3 5.3 0 0 1-.59 0L16 .28 6.77 8a5.3 5.3 0 0 1-.59 0 5.59 5.59 0 0 1-2.09-.65C3 6.87 1.6 6.25.57 7.31c-1.03 1.06-.45 2.63.08 4.2A9.2 9.2 0 0 1 1.27 14a6.47 6.47 0 0 1-.45 2.19A8.55 8.55 0 0 0 .28 19c.02.96.203 1.91.54 2.81A6.47 6.47 0 0 1 1.27 24a9.2 9.2 0 0 1-.62 2.49c-.53 1.57-1.08 3.19-.08 4.2.353.38.852.59 1.37.58a5.67 5.67 0 0 0 2.15-.63A5.59 5.59 0 0 1 6.18 30a7.13 7.13 0 0 1 2.29.47 8 8 0 0 0 2.62.53 7.37 7.37 0 0 0 2.47-.51A7.14 7.14 0 0 1 16 30a6.24 6.24 0 0 1 2.14.45 8 8 0 0 0 2.77.55 8.08 8.08 0 0 0 2.77-.55 6.24 6.24 0 0 1 2.14-.45 5.59 5.59 0 0 1 2.09.65c1.11.49 2.49 1.11 3.52.05 1.03-1.06.45-2.63-.08-4.2a9.2 9.2 0 0 1-.62-2.5zM21.17 7h-.26a8 8 0 0 0-2.77.55A6.24 6.24 0 0 1 16 8a6.24 6.24 0 0 1-2.14-.45A8 8 0 0 0 11.09 7h-.26L16 2.72 21.17 7zm8.89 22.27a4.42 4.42 0 0 1-1.34-.46 7.08 7.08 0 0 0-2.9-.82 8.14 8.14 0 0 0-2.78.55 6.13 6.13 0 0 1-2.13.45 6.24 6.24 0 0 1-2.14-.45A8 8 0 0 0 16 28a9 9 0 0 0-3.08.6 5.74 5.74 0 0 1-1.83.4 6.36 6.36 0 0 1-2-.43A8.72 8.72 0 0 0 6.18 28a7.08 7.08 0 0 0-2.9.82 9.65 9.65 0 0 1-1.28.52 6.08 6.08 0 0 1 .52-2.21c.403-1 .65-2.055.73-3.13a8.55 8.55 0 0 0-.54-2.81A6.47 6.47 0 0 1 2.27 19a6.47 6.47 0 0 1 .44-2.19c.337-.9.52-1.85.54-2.81a10.48 10.48 0 0 0-.72-3.13 9 9 0 0 1-.59-2.16H2c.447.1.88.255 1.29.46a7.08 7.08 0 0 0 2.9.82A8.14 8.14 0 0 0 9 9.44 6.13 6.13 0 0 1 11.09 9a6.13 6.13 0 0 1 2.13.45A8.14 8.14 0 0 0 16 10a8.14 8.14 0 0 0 2.78-.55A6.13 6.13 0 0 1 20.91 9a6.13 6.13 0 0 1 2.09.44 8.14 8.14 0 0 0 2.78.55 7.08 7.08 0 0 0 2.9-.82A9.65 9.65 0 0 1 30 8.66a6.08 6.08 0 0 1-.52 2.21c-.403 1-.65 2.055-.73 3.13.02.96.203 1.91.54 2.81a6.47 6.47 0 0 1 .44 2.19 6.47 6.47 0 0 1-.44 2.19 8.55 8.55 0 0 0-.54 2.81c.078 1.074.32 2.13.72 3.13a9 9 0 0 1 .59 2.16v-.02z"
/>
</svg>
/>
</span>
<span
className="euiCard__content"
@ -410,18 +394,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
/>
</button>
<div
className="euiModal__flex"
@ -551,18 +531,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiFilePicker__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFilePicker__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9 10.114l1.85-1.943a.52.52 0 0 1 .77 0c.214.228.214.6 0 .829l-1.95 2.05a1.552 1.552 0 0 1-2.31 0L5.41 9a.617.617 0 0 1 0-.829.52.52 0 0 1 .77 0L8 10.082V1.556C8 1.249 8.224 1 8.5 1s.5.249.5.556v8.558zM4.18 6a.993.993 0 0 0-.972.804l-1.189 6A.995.995 0 0 0 2.991 14h11.018a1 1 0 0 0 .972-1.196l-1.19-6a.993.993 0 0 0-.97-.804H4.18zM6 5v1h5V5h1.825c.946 0 1.76.673 1.946 1.608l1.19 6A2 2 0 0 1 14.016 15H2.984a1.992 1.992 0 0 1-1.945-2.392l1.19-6C2.414 5.673 3.229 5 4.174 5H6z"
/>
</svg>
/>
<div
className="euiFilePicker__promptText"
>
@ -753,18 +729,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
/>
</button>
<div
className="euiModal__flex"
@ -894,18 +866,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiFilePicker__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFilePicker__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9 10.114l1.85-1.943a.52.52 0 0 1 .77 0c.214.228.214.6 0 .829l-1.95 2.05a1.552 1.552 0 0 1-2.31 0L5.41 9a.617.617 0 0 1 0-.829.52.52 0 0 1 .77 0L8 10.082V1.556C8 1.249 8.224 1 8.5 1s.5.249.5.556v8.558zM4.18 6a.993.993 0 0 0-.972.804l-1.189 6A.995.995 0 0 0 2.991 14h11.018a1 1 0 0 0 .972-1.196l-1.19-6a.993.993 0 0 0-.97-.804H4.18zM6 5v1h5V5h1.825c.946 0 1.76.673 1.946 1.608l1.19 6A2 2 0 0 1 14.016 15H2.984a1.992 1.992 0 0 1-1.945-2.392l1.19-6C2.414 5.673 3.229 5 4.174 5H6z"
/>
</svg>
/>
<div
className="euiFilePicker__promptText"
>
@ -941,22 +909,14 @@ Array [
className="euiCard__top"
>
<svg
className="euiIcon euiIcon--xxLarge euiIcon--app euiCard__icon"
className="euiIcon euiIcon--xxLarge euiIcon--app euiIcon-isLoading euiCard__icon"
focusable="false"
height="32"
height={16}
style={null}
viewBox="0 0 32 32"
width="32"
viewBox="0 0 16 16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
className="euiIcon__fillSecondary"
d="M7 17h2v7H7zM12 14h2v10h-2zM17 16h2v8h-2zM22 14h3v2h-3zM22 18h3v2h-3zM22 22h3v2h-3z"
/>
<path
d="M30.73 24a6.47 6.47 0 0 1 .45-2.19c.337-.9.52-1.85.54-2.81a8.55 8.55 0 0 0-.54-2.81 6.47 6.47 0 0 1-.45-2.19 9.2 9.2 0 0 1 .62-2.49c.53-1.57 1.08-3.19.08-4.2-1-1.01-2.41-.44-3.52.05a5.59 5.59 0 0 1-2.09.64 5.3 5.3 0 0 1-.59 0L16 .28 6.77 8a5.3 5.3 0 0 1-.59 0 5.59 5.59 0 0 1-2.09-.65C3 6.87 1.6 6.25.57 7.31c-1.03 1.06-.45 2.63.08 4.2A9.2 9.2 0 0 1 1.27 14a6.47 6.47 0 0 1-.45 2.19A8.55 8.55 0 0 0 .28 19c.02.96.203 1.91.54 2.81A6.47 6.47 0 0 1 1.27 24a9.2 9.2 0 0 1-.62 2.49c-.53 1.57-1.08 3.19-.08 4.2.353.38.852.59 1.37.58a5.67 5.67 0 0 0 2.15-.63A5.59 5.59 0 0 1 6.18 30a7.13 7.13 0 0 1 2.29.47 8 8 0 0 0 2.62.53 7.37 7.37 0 0 0 2.47-.51A7.14 7.14 0 0 1 16 30a6.24 6.24 0 0 1 2.14.45 8 8 0 0 0 2.77.55 8.08 8.08 0 0 0 2.77-.55 6.24 6.24 0 0 1 2.14-.45 5.59 5.59 0 0 1 2.09.65c1.11.49 2.49 1.11 3.52.05 1.03-1.06.45-2.63-.08-4.2a9.2 9.2 0 0 1-.62-2.5zM21.17 7h-.26a8 8 0 0 0-2.77.55A6.24 6.24 0 0 1 16 8a6.24 6.24 0 0 1-2.14-.45A8 8 0 0 0 11.09 7h-.26L16 2.72 21.17 7zm8.89 22.27a4.42 4.42 0 0 1-1.34-.46 7.08 7.08 0 0 0-2.9-.82 8.14 8.14 0 0 0-2.78.55 6.13 6.13 0 0 1-2.13.45 6.24 6.24 0 0 1-2.14-.45A8 8 0 0 0 16 28a9 9 0 0 0-3.08.6 5.74 5.74 0 0 1-1.83.4 6.36 6.36 0 0 1-2-.43A8.72 8.72 0 0 0 6.18 28a7.08 7.08 0 0 0-2.9.82 9.65 9.65 0 0 1-1.28.52 6.08 6.08 0 0 1 .52-2.21c.403-1 .65-2.055.73-3.13a8.55 8.55 0 0 0-.54-2.81A6.47 6.47 0 0 1 2.27 19a6.47 6.47 0 0 1 .44-2.19c.337-.9.52-1.85.54-2.81a10.48 10.48 0 0 0-.72-3.13 9 9 0 0 1-.59-2.16H2c.447.1.88.255 1.29.46a7.08 7.08 0 0 0 2.9.82A8.14 8.14 0 0 0 9 9.44 6.13 6.13 0 0 1 11.09 9a6.13 6.13 0 0 1 2.13.45A8.14 8.14 0 0 0 16 10a8.14 8.14 0 0 0 2.78-.55A6.13 6.13 0 0 1 20.91 9a6.13 6.13 0 0 1 2.09.44 8.14 8.14 0 0 0 2.78.55 7.08 7.08 0 0 0 2.9-.82A9.65 9.65 0 0 1 30 8.66a6.08 6.08 0 0 1-.52 2.21c-.403 1-.65 2.055-.73 3.13.02.96.203 1.91.54 2.81a6.47 6.47 0 0 1 .44 2.19 6.47 6.47 0 0 1-.44 2.19 8.55 8.55 0 0 0-.54 2.81c.078 1.074.32 2.13.72 3.13a9 9 0 0 1 .59 2.16v-.02z"
/>
</svg>
/>
</span>
<span
className="euiCard__content"
@ -1106,18 +1066,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
/>
</button>
<div
className="euiModal__flex"
@ -1247,18 +1203,14 @@ Array [
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiFilePicker__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFilePicker__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9 10.114l1.85-1.943a.52.52 0 0 1 .77 0c.214.228.214.6 0 .829l-1.95 2.05a1.552 1.552 0 0 1-2.31 0L5.41 9a.617.617 0 0 1 0-.829.52.52 0 0 1 .77 0L8 10.082V1.556C8 1.249 8.224 1 8.5 1s.5.249.5.556v8.558zM4.18 6a.993.993 0 0 0-.972.804l-1.189 6A.995.995 0 0 0 2.991 14h11.018a1 1 0 0 0 .972-1.196l-1.19-6a.993.993 0 0 0-.97-.804H4.18zM6 5v1h5V5h1.825c.946 0 1.76.673 1.946 1.608l1.19 6A2 2 0 0 1 14.016 15H2.984a1.992 1.992 0 0 1-1.945-2.392l1.19-6C2.414 5.673 3.229 5 4.174 5H6z"
/>
</svg>
/>
<div
className="euiFilePicker__promptText"
>
@ -1294,22 +1246,14 @@ Array [
className="euiCard__top"
>
<svg
className="euiIcon euiIcon--xxLarge euiIcon--app euiCard__icon"
className="euiIcon euiIcon--xxLarge euiIcon--app euiIcon-isLoading euiCard__icon"
focusable="false"
height="32"
height={16}
style={null}
viewBox="0 0 32 32"
width="32"
viewBox="0 0 16 16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
className="euiIcon__fillSecondary"
d="M7 17h2v7H7zM12 14h2v10h-2zM17 16h2v8h-2zM22 14h3v2h-3zM22 18h3v2h-3zM22 22h3v2h-3z"
/>
<path
d="M30.73 24a6.47 6.47 0 0 1 .45-2.19c.337-.9.52-1.85.54-2.81a8.55 8.55 0 0 0-.54-2.81 6.47 6.47 0 0 1-.45-2.19 9.2 9.2 0 0 1 .62-2.49c.53-1.57 1.08-3.19.08-4.2-1-1.01-2.41-.44-3.52.05a5.59 5.59 0 0 1-2.09.64 5.3 5.3 0 0 1-.59 0L16 .28 6.77 8a5.3 5.3 0 0 1-.59 0 5.59 5.59 0 0 1-2.09-.65C3 6.87 1.6 6.25.57 7.31c-1.03 1.06-.45 2.63.08 4.2A9.2 9.2 0 0 1 1.27 14a6.47 6.47 0 0 1-.45 2.19A8.55 8.55 0 0 0 .28 19c.02.96.203 1.91.54 2.81A6.47 6.47 0 0 1 1.27 24a9.2 9.2 0 0 1-.62 2.49c-.53 1.57-1.08 3.19-.08 4.2.353.38.852.59 1.37.58a5.67 5.67 0 0 0 2.15-.63A5.59 5.59 0 0 1 6.18 30a7.13 7.13 0 0 1 2.29.47 8 8 0 0 0 2.62.53 7.37 7.37 0 0 0 2.47-.51A7.14 7.14 0 0 1 16 30a6.24 6.24 0 0 1 2.14.45 8 8 0 0 0 2.77.55 8.08 8.08 0 0 0 2.77-.55 6.24 6.24 0 0 1 2.14-.45 5.59 5.59 0 0 1 2.09.65c1.11.49 2.49 1.11 3.52.05 1.03-1.06.45-2.63-.08-4.2a9.2 9.2 0 0 1-.62-2.5zM21.17 7h-.26a8 8 0 0 0-2.77.55A6.24 6.24 0 0 1 16 8a6.24 6.24 0 0 1-2.14-.45A8 8 0 0 0 11.09 7h-.26L16 2.72 21.17 7zm8.89 22.27a4.42 4.42 0 0 1-1.34-.46 7.08 7.08 0 0 0-2.9-.82 8.14 8.14 0 0 0-2.78.55 6.13 6.13 0 0 1-2.13.45 6.24 6.24 0 0 1-2.14-.45A8 8 0 0 0 16 28a9 9 0 0 0-3.08.6 5.74 5.74 0 0 1-1.83.4 6.36 6.36 0 0 1-2-.43A8.72 8.72 0 0 0 6.18 28a7.08 7.08 0 0 0-2.9.82 9.65 9.65 0 0 1-1.28.52 6.08 6.08 0 0 1 .52-2.21c.403-1 .65-2.055.73-3.13a8.55 8.55 0 0 0-.54-2.81A6.47 6.47 0 0 1 2.27 19a6.47 6.47 0 0 1 .44-2.19c.337-.9.52-1.85.54-2.81a10.48 10.48 0 0 0-.72-3.13 9 9 0 0 1-.59-2.16H2c.447.1.88.255 1.29.46a7.08 7.08 0 0 0 2.9.82A8.14 8.14 0 0 0 9 9.44 6.13 6.13 0 0 1 11.09 9a6.13 6.13 0 0 1 2.13.45A8.14 8.14 0 0 0 16 10a8.14 8.14 0 0 0 2.78-.55A6.13 6.13 0 0 1 20.91 9a6.13 6.13 0 0 1 2.09.44 8.14 8.14 0 0 0 2.78.55 7.08 7.08 0 0 0 2.9-.82A9.65 9.65 0 0 1 30 8.66a6.08 6.08 0 0 1-.52 2.21c-.403 1-.65 2.055-.73 3.13.02.96.203 1.91.54 2.81a6.47 6.47 0 0 1 .44 2.19 6.47 6.47 0 0 1-.44 2.19 8.55 8.55 0 0 0-.54 2.81c.078 1.074.32 2.13.72 3.13a9 9 0 0 1 .59 2.16v-.02z"
/>
</svg>
/>
</span>
<span
className="euiCard__content"

View file

@ -16,22 +16,14 @@ exports[`Storyshots components/ElementCard with click handler 1`] = `
className="euiCard__top"
>
<svg
className="euiIcon euiIcon--xxLarge euiIcon--app euiCard__icon"
className="euiIcon euiIcon--xxLarge euiIcon--app euiIcon-isLoading euiCard__icon"
focusable="false"
height="32"
height={16}
style={null}
viewBox="0 0 32 32"
width="32"
viewBox="0 0 16 16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
className="euiIcon__fillSecondary"
d="M7 17h2v7H7zM12 14h2v10h-2zM17 16h2v8h-2zM22 14h3v2h-3zM22 18h3v2h-3zM22 22h3v2h-3z"
/>
<path
d="M30.73 24a6.47 6.47 0 0 1 .45-2.19c.337-.9.52-1.85.54-2.81a8.55 8.55 0 0 0-.54-2.81 6.47 6.47 0 0 1-.45-2.19 9.2 9.2 0 0 1 .62-2.49c.53-1.57 1.08-3.19.08-4.2-1-1.01-2.41-.44-3.52.05a5.59 5.59 0 0 1-2.09.64 5.3 5.3 0 0 1-.59 0L16 .28 6.77 8a5.3 5.3 0 0 1-.59 0 5.59 5.59 0 0 1-2.09-.65C3 6.87 1.6 6.25.57 7.31c-1.03 1.06-.45 2.63.08 4.2A9.2 9.2 0 0 1 1.27 14a6.47 6.47 0 0 1-.45 2.19A8.55 8.55 0 0 0 .28 19c.02.96.203 1.91.54 2.81A6.47 6.47 0 0 1 1.27 24a9.2 9.2 0 0 1-.62 2.49c-.53 1.57-1.08 3.19-.08 4.2.353.38.852.59 1.37.58a5.67 5.67 0 0 0 2.15-.63A5.59 5.59 0 0 1 6.18 30a7.13 7.13 0 0 1 2.29.47 8 8 0 0 0 2.62.53 7.37 7.37 0 0 0 2.47-.51A7.14 7.14 0 0 1 16 30a6.24 6.24 0 0 1 2.14.45 8 8 0 0 0 2.77.55 8.08 8.08 0 0 0 2.77-.55 6.24 6.24 0 0 1 2.14-.45 5.59 5.59 0 0 1 2.09.65c1.11.49 2.49 1.11 3.52.05 1.03-1.06.45-2.63-.08-4.2a9.2 9.2 0 0 1-.62-2.5zM21.17 7h-.26a8 8 0 0 0-2.77.55A6.24 6.24 0 0 1 16 8a6.24 6.24 0 0 1-2.14-.45A8 8 0 0 0 11.09 7h-.26L16 2.72 21.17 7zm8.89 22.27a4.42 4.42 0 0 1-1.34-.46 7.08 7.08 0 0 0-2.9-.82 8.14 8.14 0 0 0-2.78.55 6.13 6.13 0 0 1-2.13.45 6.24 6.24 0 0 1-2.14-.45A8 8 0 0 0 16 28a9 9 0 0 0-3.08.6 5.74 5.74 0 0 1-1.83.4 6.36 6.36 0 0 1-2-.43A8.72 8.72 0 0 0 6.18 28a7.08 7.08 0 0 0-2.9.82 9.65 9.65 0 0 1-1.28.52 6.08 6.08 0 0 1 .52-2.21c.403-1 .65-2.055.73-3.13a8.55 8.55 0 0 0-.54-2.81A6.47 6.47 0 0 1 2.27 19a6.47 6.47 0 0 1 .44-2.19c.337-.9.52-1.85.54-2.81a10.48 10.48 0 0 0-.72-3.13 9 9 0 0 1-.59-2.16H2c.447.1.88.255 1.29.46a7.08 7.08 0 0 0 2.9.82A8.14 8.14 0 0 0 9 9.44 6.13 6.13 0 0 1 11.09 9a6.13 6.13 0 0 1 2.13.45A8.14 8.14 0 0 0 16 10a8.14 8.14 0 0 0 2.78-.55A6.13 6.13 0 0 1 20.91 9a6.13 6.13 0 0 1 2.09.44 8.14 8.14 0 0 0 2.78.55 7.08 7.08 0 0 0 2.9-.82A9.65 9.65 0 0 1 30 8.66a6.08 6.08 0 0 1-.52 2.21c-.403 1-.65 2.055-.73 3.13.02.96.203 1.91.54 2.81a6.47 6.47 0 0 1 .44 2.19 6.47 6.47 0 0 1-.44 2.19 8.55 8.55 0 0 0-.54 2.81c.078 1.074.32 2.13.72 3.13a9 9 0 0 1 .59 2.16v-.02z"
/>
</svg>
/>
</span>
<span
className="euiCard__content"
@ -119,22 +111,14 @@ exports[`Storyshots components/ElementCard with tags 1`] = `
className="euiCard__top"
>
<svg
className="euiIcon euiIcon--xxLarge euiIcon--app euiCard__icon"
className="euiIcon euiIcon--xxLarge euiIcon--app euiIcon-isLoading euiCard__icon"
focusable="false"
height="32"
height={16}
style={null}
viewBox="0 0 32 32"
width="32"
viewBox="0 0 16 16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
className="euiIcon__fillSecondary"
d="M7 17h2v7H7zM12 14h2v10h-2zM17 16h2v8h-2zM22 14h3v2h-3zM22 18h3v2h-3zM22 22h3v2h-3z"
/>
<path
d="M30.73 24a6.47 6.47 0 0 1 .45-2.19c.337-.9.52-1.85.54-2.81a8.55 8.55 0 0 0-.54-2.81 6.47 6.47 0 0 1-.45-2.19 9.2 9.2 0 0 1 .62-2.49c.53-1.57 1.08-3.19.08-4.2-1-1.01-2.41-.44-3.52.05a5.59 5.59 0 0 1-2.09.64 5.3 5.3 0 0 1-.59 0L16 .28 6.77 8a5.3 5.3 0 0 1-.59 0 5.59 5.59 0 0 1-2.09-.65C3 6.87 1.6 6.25.57 7.31c-1.03 1.06-.45 2.63.08 4.2A9.2 9.2 0 0 1 1.27 14a6.47 6.47 0 0 1-.45 2.19A8.55 8.55 0 0 0 .28 19c.02.96.203 1.91.54 2.81A6.47 6.47 0 0 1 1.27 24a9.2 9.2 0 0 1-.62 2.49c-.53 1.57-1.08 3.19-.08 4.2.353.38.852.59 1.37.58a5.67 5.67 0 0 0 2.15-.63A5.59 5.59 0 0 1 6.18 30a7.13 7.13 0 0 1 2.29.47 8 8 0 0 0 2.62.53 7.37 7.37 0 0 0 2.47-.51A7.14 7.14 0 0 1 16 30a6.24 6.24 0 0 1 2.14.45 8 8 0 0 0 2.77.55 8.08 8.08 0 0 0 2.77-.55 6.24 6.24 0 0 1 2.14-.45 5.59 5.59 0 0 1 2.09.65c1.11.49 2.49 1.11 3.52.05 1.03-1.06.45-2.63-.08-4.2a9.2 9.2 0 0 1-.62-2.5zM21.17 7h-.26a8 8 0 0 0-2.77.55A6.24 6.24 0 0 1 16 8a6.24 6.24 0 0 1-2.14-.45A8 8 0 0 0 11.09 7h-.26L16 2.72 21.17 7zm8.89 22.27a4.42 4.42 0 0 1-1.34-.46 7.08 7.08 0 0 0-2.9-.82 8.14 8.14 0 0 0-2.78.55 6.13 6.13 0 0 1-2.13.45 6.24 6.24 0 0 1-2.14-.45A8 8 0 0 0 16 28a9 9 0 0 0-3.08.6 5.74 5.74 0 0 1-1.83.4 6.36 6.36 0 0 1-2-.43A8.72 8.72 0 0 0 6.18 28a7.08 7.08 0 0 0-2.9.82 9.65 9.65 0 0 1-1.28.52 6.08 6.08 0 0 1 .52-2.21c.403-1 .65-2.055.73-3.13a8.55 8.55 0 0 0-.54-2.81A6.47 6.47 0 0 1 2.27 19a6.47 6.47 0 0 1 .44-2.19c.337-.9.52-1.85.54-2.81a10.48 10.48 0 0 0-.72-3.13 9 9 0 0 1-.59-2.16H2c.447.1.88.255 1.29.46a7.08 7.08 0 0 0 2.9.82A8.14 8.14 0 0 0 9 9.44 6.13 6.13 0 0 1 11.09 9a6.13 6.13 0 0 1 2.13.45A8.14 8.14 0 0 0 16 10a8.14 8.14 0 0 0 2.78-.55A6.13 6.13 0 0 1 20.91 9a6.13 6.13 0 0 1 2.09.44 8.14 8.14 0 0 0 2.78.55 7.08 7.08 0 0 0 2.9-.82A9.65 9.65 0 0 1 30 8.66a6.08 6.08 0 0 1-.52 2.21c-.403 1-.65 2.055-.73 3.13.02.96.203 1.91.54 2.81a6.47 6.47 0 0 1 .44 2.19 6.47 6.47 0 0 1-.44 2.19 8.55 8.55 0 0 0-.54 2.81c.078 1.074.32 2.13.72 3.13a9 9 0 0 1 .59 2.16v-.02z"
/>
</svg>
/>
</span>
<span
className="euiCard__content"
@ -291,22 +275,14 @@ exports[`Storyshots components/ElementCard with title and description 1`] = `
className="euiCard__top"
>
<svg
className="euiIcon euiIcon--xxLarge euiIcon--app euiCard__icon"
className="euiIcon euiIcon--xxLarge euiIcon--app euiIcon-isLoading euiCard__icon"
focusable="false"
height="32"
height={16}
style={null}
viewBox="0 0 32 32"
width="32"
viewBox="0 0 16 16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
className="euiIcon__fillSecondary"
d="M7 17h2v7H7zM12 14h2v10h-2zM17 16h2v8h-2zM22 14h3v2h-3zM22 18h3v2h-3zM22 22h3v2h-3z"
/>
<path
d="M30.73 24a6.47 6.47 0 0 1 .45-2.19c.337-.9.52-1.85.54-2.81a8.55 8.55 0 0 0-.54-2.81 6.47 6.47 0 0 1-.45-2.19 9.2 9.2 0 0 1 .62-2.49c.53-1.57 1.08-3.19.08-4.2-1-1.01-2.41-.44-3.52.05a5.59 5.59 0 0 1-2.09.64 5.3 5.3 0 0 1-.59 0L16 .28 6.77 8a5.3 5.3 0 0 1-.59 0 5.59 5.59 0 0 1-2.09-.65C3 6.87 1.6 6.25.57 7.31c-1.03 1.06-.45 2.63.08 4.2A9.2 9.2 0 0 1 1.27 14a6.47 6.47 0 0 1-.45 2.19A8.55 8.55 0 0 0 .28 19c.02.96.203 1.91.54 2.81A6.47 6.47 0 0 1 1.27 24a9.2 9.2 0 0 1-.62 2.49c-.53 1.57-1.08 3.19-.08 4.2.353.38.852.59 1.37.58a5.67 5.67 0 0 0 2.15-.63A5.59 5.59 0 0 1 6.18 30a7.13 7.13 0 0 1 2.29.47 8 8 0 0 0 2.62.53 7.37 7.37 0 0 0 2.47-.51A7.14 7.14 0 0 1 16 30a6.24 6.24 0 0 1 2.14.45 8 8 0 0 0 2.77.55 8.08 8.08 0 0 0 2.77-.55 6.24 6.24 0 0 1 2.14-.45 5.59 5.59 0 0 1 2.09.65c1.11.49 2.49 1.11 3.52.05 1.03-1.06.45-2.63-.08-4.2a9.2 9.2 0 0 1-.62-2.5zM21.17 7h-.26a8 8 0 0 0-2.77.55A6.24 6.24 0 0 1 16 8a6.24 6.24 0 0 1-2.14-.45A8 8 0 0 0 11.09 7h-.26L16 2.72 21.17 7zm8.89 22.27a4.42 4.42 0 0 1-1.34-.46 7.08 7.08 0 0 0-2.9-.82 8.14 8.14 0 0 0-2.78.55 6.13 6.13 0 0 1-2.13.45 6.24 6.24 0 0 1-2.14-.45A8 8 0 0 0 16 28a9 9 0 0 0-3.08.6 5.74 5.74 0 0 1-1.83.4 6.36 6.36 0 0 1-2-.43A8.72 8.72 0 0 0 6.18 28a7.08 7.08 0 0 0-2.9.82 9.65 9.65 0 0 1-1.28.52 6.08 6.08 0 0 1 .52-2.21c.403-1 .65-2.055.73-3.13a8.55 8.55 0 0 0-.54-2.81A6.47 6.47 0 0 1 2.27 19a6.47 6.47 0 0 1 .44-2.19c.337-.9.52-1.85.54-2.81a10.48 10.48 0 0 0-.72-3.13 9 9 0 0 1-.59-2.16H2c.447.1.88.255 1.29.46a7.08 7.08 0 0 0 2.9.82A8.14 8.14 0 0 0 9 9.44 6.13 6.13 0 0 1 11.09 9a6.13 6.13 0 0 1 2.13.45A8.14 8.14 0 0 0 16 10a8.14 8.14 0 0 0 2.78-.55A6.13 6.13 0 0 1 20.91 9a6.13 6.13 0 0 1 2.09.44 8.14 8.14 0 0 0 2.78.55 7.08 7.08 0 0 0 2.9-.82A9.65 9.65 0 0 1 30 8.66a6.08 6.08 0 0 1-.52 2.21c-.403 1-.65 2.055-.73 3.13.02.96.203 1.91.54 2.81a6.47 6.47 0 0 1 .44 2.19 6.47 6.47 0 0 1-.44 2.19 8.55 8.55 0 0 0-.54 2.81c.078 1.074.32 2.13.72 3.13a9 9 0 0 1 .59 2.16v-.02z"
/>
</svg>
/>
</span>
<span
className="euiCard__content"

View file

@ -30,25 +30,14 @@ exports[`Storyshots components/ElementTypes/ElementControls has two buttons 1`]
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M12.148 3.148L11 2l-9 9v3h3l9-9-1.144-1.144-8.002 7.998a.502.502 0 0 1-.708 0 .502.502 0 0 1 0-.708l8.002-7.998zM11 1c.256 0 .512.098.707.293l3 3a.999.999 0 0 1 0 1.414l-9 9A.997.997 0 0 1 5 15H2a1 1 0 0 1-1-1v-3c0-.265.105-.52.293-.707l9-9A.997.997 0 0 1 11 1zM5 14H2v-3l3 3z"
id="pencil-a"
/>
</defs>
<use
xlinkHref="#pencil-a"
/>
</svg>
/>
</button>
</span>
</div>
@ -71,25 +60,14 @@ exports[`Storyshots components/ElementTypes/ElementControls has two buttons 1`]
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11 3h5v1H0V3h5V1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2zm-7.056 8H7v1H4.1l.392 2.519c.042.269.254.458.493.458h6.03c.239 0 .451-.189.493-.458l1.498-9.576H14l-1.504 9.73c-.116.747-.74 1.304-1.481 1.304h-6.03c-.741 0-1.365-.557-1.481-1.304l-1.511-9.73H9V5.95H3.157L3.476 8H8v1H3.632l.312 2zM6 3h4V1H6v2z"
id="trash-a"
/>
</defs>
<use
xlinkHref="#trash-a"
/>
</svg>
/>
</button>
</span>
</div>

View file

@ -71,25 +71,14 @@ exports[`Storyshots components/ElementTypes/ElementGrid with controls 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M12.148 3.148L11 2l-9 9v3h3l9-9-1.144-1.144-8.002 7.998a.502.502 0 0 1-.708 0 .502.502 0 0 1 0-.708l8.002-7.998zM11 1c.256 0 .512.098.707.293l3 3a.999.999 0 0 1 0 1.414l-9 9A.997.997 0 0 1 5 15H2a1 1 0 0 1-1-1v-3c0-.265.105-.52.293-.707l9-9A.997.997 0 0 1 11 1zM5 14H2v-3l3 3z"
id="pencil-a"
/>
</defs>
<use
xlinkHref="#pencil-a"
/>
</svg>
/>
</button>
</span>
</div>
@ -112,25 +101,14 @@ exports[`Storyshots components/ElementTypes/ElementGrid with controls 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11 3h5v1H0V3h5V1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2zm-7.056 8H7v1H4.1l.392 2.519c.042.269.254.458.493.458h6.03c.239 0 .451-.189.493-.458l1.498-9.576H14l-1.504 9.73c-.116.747-.74 1.304-1.481 1.304h-6.03c-.741 0-1.365-.557-1.481-1.304l-1.511-9.73H9V5.95H3.157L3.476 8H8v1H3.632l.312 2zM6 3h4V1H6v2z"
id="trash-a"
/>
</defs>
<use
xlinkHref="#trash-a"
/>
</svg>
/>
</button>
</span>
</div>
@ -196,25 +174,14 @@ exports[`Storyshots components/ElementTypes/ElementGrid with controls 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M12.148 3.148L11 2l-9 9v3h3l9-9-1.144-1.144-8.002 7.998a.502.502 0 0 1-.708 0 .502.502 0 0 1 0-.708l8.002-7.998zM11 1c.256 0 .512.098.707.293l3 3a.999.999 0 0 1 0 1.414l-9 9A.997.997 0 0 1 5 15H2a1 1 0 0 1-1-1v-3c0-.265.105-.52.293-.707l9-9A.997.997 0 0 1 11 1zM5 14H2v-3l3 3z"
id="pencil-a"
/>
</defs>
<use
xlinkHref="#pencil-a"
/>
</svg>
/>
</button>
</span>
</div>
@ -237,25 +204,14 @@ exports[`Storyshots components/ElementTypes/ElementGrid with controls 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11 3h5v1H0V3h5V1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2zm-7.056 8H7v1H4.1l.392 2.519c.042.269.254.458.493.458h6.03c.239 0 .451-.189.493-.458l1.498-9.576H14l-1.504 9.73c-.116.747-.74 1.304-1.481 1.304h-6.03c-.741 0-1.365-.557-1.481-1.304l-1.511-9.73H9V5.95H3.157L3.476 8H8v1H3.632l.312 2zM6 3h4V1H6v2z"
id="trash-a"
/>
</defs>
<use
xlinkHref="#trash-a"
/>
</svg>
/>
</button>
</span>
</div>
@ -321,25 +277,14 @@ exports[`Storyshots components/ElementTypes/ElementGrid with controls 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M12.148 3.148L11 2l-9 9v3h3l9-9-1.144-1.144-8.002 7.998a.502.502 0 0 1-.708 0 .502.502 0 0 1 0-.708l8.002-7.998zM11 1c.256 0 .512.098.707.293l3 3a.999.999 0 0 1 0 1.414l-9 9A.997.997 0 0 1 5 15H2a1 1 0 0 1-1-1v-3c0-.265.105-.52.293-.707l9-9A.997.997 0 0 1 11 1zM5 14H2v-3l3 3z"
id="pencil-a"
/>
</defs>
<use
xlinkHref="#pencil-a"
/>
</svg>
/>
</button>
</span>
</div>
@ -362,25 +307,14 @@ exports[`Storyshots components/ElementTypes/ElementGrid with controls 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11 3h5v1H0V3h5V1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2zm-7.056 8H7v1H4.1l.392 2.519c.042.269.254.458.493.458h6.03c.239 0 .451-.189.493-.458l1.498-9.576H14l-1.504 9.73c-.116.747-.74 1.304-1.481 1.304h-6.03c-.741 0-1.365-.557-1.481-1.304l-1.511-9.73H9V5.95H3.157L3.476 8H8v1H3.632l.312 2zM6 3h4V1H6v2z"
id="trash-a"
/>
</defs>
<use
xlinkHref="#trash-a"
/>
</svg>
/>
</button>
</span>
</div>
@ -461,25 +395,14 @@ exports[`Storyshots components/ElementTypes/ElementGrid with controls and filter
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M12.148 3.148L11 2l-9 9v3h3l9-9-1.144-1.144-8.002 7.998a.502.502 0 0 1-.708 0 .502.502 0 0 1 0-.708l8.002-7.998zM11 1c.256 0 .512.098.707.293l3 3a.999.999 0 0 1 0 1.414l-9 9A.997.997 0 0 1 5 15H2a1 1 0 0 1-1-1v-3c0-.265.105-.52.293-.707l9-9A.997.997 0 0 1 11 1zM5 14H2v-3l3 3z"
id="pencil-a"
/>
</defs>
<use
xlinkHref="#pencil-a"
/>
</svg>
/>
</button>
</span>
</div>
@ -502,25 +425,14 @@ exports[`Storyshots components/ElementTypes/ElementGrid with controls and filter
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M11 3h5v1H0V3h5V1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2zm-7.056 8H7v1H4.1l.392 2.519c.042.269.254.458.493.458h6.03c.239 0 .451-.189.493-.458l1.498-9.576H14l-1.504 9.73c-.116.747-.74 1.304-1.481 1.304h-6.03c-.741 0-1.365-.557-1.481-1.304l-1.511-9.73H9V5.95H3.157L3.476 8H8v1H3.632l.312 2zM6 3h4V1H6v2z"
id="trash-a"
/>
</defs>
<use
xlinkHref="#trash-a"
/>
</svg>
/>
</button>
</span>
</div>

View file

@ -21,18 +21,14 @@ exports[`Storyshots components/FileUpload default 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiFilePicker__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFilePicker__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M9 10.114l1.85-1.943a.52.52 0 0 1 .77 0c.214.228.214.6 0 .829l-1.95 2.05a1.552 1.552 0 0 1-2.31 0L5.41 9a.617.617 0 0 1 0-.829.52.52 0 0 1 .77 0L8 10.082V1.556C8 1.249 8.224 1 8.5 1s.5.249.5.556v8.558zM4.18 6a.993.993 0 0 0-.972.804l-1.189 6A.995.995 0 0 0 2.991 14h11.018a1 1 0 0 0 .972-1.196l-1.19-6a.993.993 0 0 0-.97-.804H4.18zM6 5v1h5V5h1.825c.946 0 1.76.673 1.946 1.608l1.19 6A2 2 0 0 1 14.016 15H2.984a1.992 1.992 0 0 1-1.945-2.392l1.19-6C2.414 5.673 3.229 5 4.174 5H6z"
/>
</svg>
/>
<div
className="euiFilePicker__promptText"
>

View file

@ -48,26 +48,14 @@ exports[`Storyshots components/FontPicker default 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
</span>
</div>
</div>
@ -142,26 +130,14 @@ exports[`Storyshots components/FontPicker with value 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
</span>
</div>
</div>

View file

@ -71,23 +71,18 @@ exports[`Storyshots components/ItemGrid complex grid 1`] = `
}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#333",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z"
fillRule="evenodd"
/>
</svg>
/>
</div>
</div>
<div
@ -105,23 +100,18 @@ exports[`Storyshots components/ItemGrid complex grid 1`] = `
}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#FFF",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z"
fillRule="evenodd"
/>
</svg>
/>
</div>
</div>
<div
@ -139,23 +129,18 @@ exports[`Storyshots components/ItemGrid complex grid 1`] = `
}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#FFF",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.5 12a.502.502 0 0 1-.354-.146l-4-4a.502.502 0 0 1 .708-.708L6.5 10.793l6.646-6.647a.502.502 0 0 1 .708.708l-7 7A.502.502 0 0 1 6.5 12"
fillRule="evenodd"
/>
</svg>
/>
</div>
</div>
</div>
@ -166,47 +151,32 @@ exports[`Storyshots components/ItemGrid icon grid 1`] = `
className="item-grid-row"
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z"
fillRule="evenodd"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z"
fillRule="evenodd"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.5 12a.502.502 0 0 1-.354-.146l-4-4a.502.502 0 0 1 .708-.708L6.5 10.793l6.646-6.647a.502.502 0 0 1 .708.708l-7 7A.502.502 0 0 1 6.5 12"
fillRule="evenodd"
/>
</svg>
/>
</div>
`;

View file

@ -16,8 +16,8 @@ storiesOf('components/ItemGrid', module)
))
.add('icon grid', () => (
<ItemGrid
items={['plusInCircle', 'minusInCircle', 'check'] as IconType[]}
children={(item: IconType) => <EuiIcon key={item} type={item} />}
items={['plusInCircle', 'minusInCircle', 'check']}
children={item => <EuiIcon key={item} type={item} />}
/>
))
.add('color dot grid', () => (

View file

@ -57,18 +57,14 @@ exports[`Storyshots components/KeyboardShortcutsDoc default 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.293 8L3.146 3.854a.5.5 0 1 1 .708-.708L8 7.293l4.146-4.147a.5.5 0 0 1 .708.708L8.707 8l4.147 4.146a.5.5 0 0 1-.708.708L8 8.707l-4.146 4.147a.5.5 0 0 1-.708-.708L7.293 8z"
/>
</svg>
/>
</button>
<div
className="euiFlyoutHeader euiFlyoutHeader--hasBorder"

View file

@ -45,18 +45,14 @@ exports[`Storyshots components/SidebarHeader/ default 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 2H2v11h6v1H1V1h12v6h-1V2zM5 5h5.999V4H5v1zM3 5V4h1v1H3zm2 3V7h3v1H5zM3 8V7h1v1H3zm2 3v-1h2v1H5zm5-1H8v1h2v2h1v-2h2v-1h-2V8h-1v2zm-7 1v-1h1v1H3zm7.5-5a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9z"
/>
</svg>
/>
</button>
</span>
</div>
@ -92,25 +88,14 @@ exports[`Storyshots components/SidebarHeader/ default 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M7 1v2h2V1H7zM6 0h4v4H6V0zm0 6h4v4H6V6zm1 1v2h2V7H7zm-1 5h4v4H6v-4zm1 1v2h2v-2H7z"
id="boxes_vertical-a"
/>
</defs>
<use
xlinkHref="#boxes_vertical-a"
/>
</svg>
/>
</button>
</span>
</div>
@ -167,18 +152,14 @@ exports[`Storyshots components/SidebarHeader/ without layer controls 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 2H2v11h6v1H1V1h12v6h-1V2zM5 5h5.999V4H5v1zM3 5V4h1v1H3zm2 3V7h3v1H5zM3 8V7h1v1H3zm2 3v-1h2v1H5zm5-1H8v1h2v2h1v-2h2v-1h-2V8h-1v2zm-7 1v-1h1v1H3zm7.5-5a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9z"
/>
</svg>
/>
</button>
</span>
</div>
@ -214,25 +195,14 @@ exports[`Storyshots components/SidebarHeader/ without layer controls 1`] = `
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiButtonIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiButtonIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M7 1v2h2V1H7zM6 0h4v4H6V0zm0 6h4v4H6V6zm1 1v2h2V7H7zm-1 5h4v4H6v-4zm1 1v2h2v-2H7z"
id="boxes_vertical-a"
/>
</defs>
<use
xlinkHref="#boxes_vertical-a"
/>
</svg>
/>
</button>
</span>
</div>

View file

@ -55,31 +55,18 @@ exports[`Storyshots components/Tag as health 1`] = `
className="euiFlexItem euiFlexItem--flexGrowZero"
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#666666",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<circle
cx="8"
cy="8"
id="dot-a"
r="4"
/>
</defs>
<use
xlinkHref="#dot-a"
/>
</svg>
/>
</div>
<div
className="euiFlexItem euiFlexItem--flexGrowZero"
@ -101,31 +88,18 @@ exports[`Storyshots components/Tag as health with color 1`] = `
className="euiFlexItem euiFlexItem--flexGrowZero"
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#9b3067",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<circle
cx="8"
cy="8"
id="dot-a"
r="4"
/>
</defs>
<use
xlinkHref="#dot-a"
/>
</svg>
/>
</div>
<div
className="euiFlexItem euiFlexItem--flexGrowZero"

View file

@ -76,31 +76,18 @@ Array [
className="euiFlexItem euiFlexItem--flexGrowZero"
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#cc3b54",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<circle
cx="8"
cy="8"
id="dot-a"
r="4"
/>
</defs>
<use
xlinkHref="#dot-a"
/>
</svg>
/>
</div>
<div
className="euiFlexItem euiFlexItem--flexGrowZero"
@ -119,31 +106,18 @@ Array [
className="euiFlexItem euiFlexItem--flexGrowZero"
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#9b3067",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<circle
cx="8"
cy="8"
id="dot-a"
r="4"
/>
</defs>
<use
xlinkHref="#dot-a"
/>
</svg>
/>
</div>
<div
className="euiFlexItem euiFlexItem--flexGrowZero"
@ -162,31 +136,18 @@ Array [
className="euiFlexItem euiFlexItem--flexGrowZero"
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={
Object {
"fill": "#d41e93",
}
}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<circle
cx="8"
cy="8"
id="dot-a"
r="4"
/>
</defs>
<use
xlinkHref="#dot-a"
/>
</svg>
/>
</div>
<div
className="euiFlexItem euiFlexItem--flexGrowZero"

View file

@ -2,7 +2,7 @@
"extends": "../../../../../tsconfig",
"compilerOptions": {
"module": "commonjs",
"lib": ["esnext", "dom"],
"lib": ["es2018", "dom"],
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": false,

View file

@ -72,6 +72,7 @@ export enum FileTreeItemType {
export interface WorkerResult {
uri: string;
cancelled?: boolean;
}
// TODO(mengwei): create a AbstractGitWorkerResult since we now have an

View file

@ -60,10 +60,11 @@ export class CodeBlock extends React.PureComponent<Props> {
(e.target.type === monaco.editor.MouseTargetType.GUTTER_LINE_NUMBERS ||
e.target.type === monaco.editor.MouseTargetType.CONTENT_TEXT)
) {
const lineNumber = (this.props.startLine || 0) + e.target.position.lineNumber;
const position = e.target.position || { lineNumber: 0, column: 0 };
const lineNumber = (this.props.startLine || 0) + position.lineNumber;
this.props.onClick({
lineNumber,
column: e.target.position.column,
column: position.column,
});
}
});
@ -94,21 +95,24 @@ export class CodeBlock extends React.PureComponent<Props> {
prevProps.highlightRanges !== this.props.highlightRanges
) {
if (this.ed) {
this.ed.getModel().setValue(this.props.code);
const model = this.ed.getModel();
if (model) {
model.setValue(this.props.code);
if (this.props.highlightRanges) {
const decorations = this.props.highlightRanges!.map((range: IRange) => {
return {
range,
options: {
inlineClassName: 'codeSearch__highlight',
},
};
});
this.currentHighlightDecorations = this.ed.deltaDecorations(
this.currentHighlightDecorations,
decorations
);
if (this.props.highlightRanges) {
const decorations = this.props.highlightRanges!.map((range: IRange) => {
return {
range,
options: {
inlineClassName: 'codeSearch__highlight',
},
};
});
this.currentHighlightDecorations = this.ed.deltaDecorations(
this.currentHighlightDecorations,
decorations
);
}
}
}
}

View file

@ -181,7 +181,8 @@ export class EditorComponent extends React.Component<IProps> {
this.editor.onMouseDown((e: editorInterfaces.IEditorMouseEvent) => {
if (e.target.type === monaco.editor.MouseTargetType.GUTTER_LINE_NUMBERS) {
const uri = `${repo}/blob/${encodeRevisionString(revision)}/${file}`;
history.push(`/${uri}!L${e.target.position.lineNumber}:0${qs}`);
const position = e.target.position || { lineNumber: 0, column: 0 };
history.push(`/${uri}!L${position.lineNumber}:0${qs}`);
}
this.monaco!.container.focus();
});

View file

@ -16,25 +16,14 @@ exports[`render correctly 1`] = `
/>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiSideNav__mobileIcon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiSideNav__mobileIcon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M2 4V2h2v2H2zm5 0V2h2v2H7zm5 0V2h2v2h-2zM2 9V7h2v2H2zm5 0V7h2v2H7zm5 0V7h2v2h-2zM2 14v-2h2v2H2zm5 0v-2h2v2H7zm5 0v-2h2v2h-2z"
id="apps-a"
/>
</defs>
<use
xlinkHref="#apps-a"
/>
</svg>
/>
</span>
</button>
<div
@ -86,41 +75,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fillRule="nonzero"
transform="matrix(0 1 1 0 0 0)"
xlinkHref="#arrow_right-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-android-closed"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 2H1v11h14V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2zm.25-1a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H15a1 1 0 0 1 1 1V13a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -148,41 +120,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fillRule="nonzero"
transform="matrix(0 1 1 0 0 0)"
xlinkHref="#arrow_right-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-futures-closed"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 2H1v11h14V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2zm.25-1a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H15a1 1 0 0 1 1 1V13a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -210,40 +165,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-guava-open"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1 9.5l.826-3.717A1 1 0 0 1 2.802 5H13V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2H1v7.5zm.247 3.5h11.95l1.556-7H2.803l-1.556 7zM13 14H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H13a1 1 0 0 1 1 1V5h.753a1 1 0 0 1 .977 1.217l-1.556 7a1 1 0 0 1-.976.783H13z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -273,41 +212,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fillRule="nonzero"
transform="matrix(0 1 1 0 0 0)"
xlinkHref="#arrow_right-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-guava/javadoc-link-closed"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 2H1v11h14V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2zm.25-1a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H15a1 1 0 0 1 1 1V13a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -335,25 +257,14 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M10.8 0H2a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4.429c0-.256-.098-.503-.274-.689l-3.2-3.428A1.002 1.002 0 0 0 10.8 0M14 5v10H2V1h8v3.5a.5.5 0 0 0 .5.5H14z"
id="document-a"
/>
</defs>
<use
xlinkHref="#document-a"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -385,40 +296,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-guava/src/com/google-open"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1 9.5l.826-3.717A1 1 0 0 1 2.802 5H13V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2H1v7.5zm.247 3.5h11.95l1.556-7H2.803l-1.556 7zM13 14H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H13a1 1 0 0 1 1 1V5h.753a1 1 0 0 1 .977 1.217l-1.556 7a1 1 0 0 1-.976.783H13z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -451,41 +346,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fillRule="nonzero"
transform="matrix(0 1 1 0 0 0)"
xlinkHref="#arrow_right-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-guava/src/com/google/common-closed"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 2H1v11h14V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2zm.25-1a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H15a1 1 0 0 1 1 1V13a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -513,41 +391,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fillRule="nonzero"
transform="matrix(0 1 1 0 0 0)"
xlinkHref="#arrow_right-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-guava/src/com/google/thirdparty/publicsuffix-closed"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 2H1v11h14V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2zm.25-1a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H15a1 1 0 0 1 1 1V13a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -579,41 +440,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fillRule="nonzero"
transform="matrix(0 1 1 0 0 0)"
xlinkHref="#arrow_right-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-guava-bom-closed"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 2H1v11h14V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2zm.25-1a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H15a1 1 0 0 1 1 1V13a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -641,41 +485,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fillRule="nonzero"
transform="matrix(0 1 1 0 0 0)"
xlinkHref="#arrow_right-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-guava-gwt-closed"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 2H1v11h14V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2zm.25-1a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H15a1 1 0 0 1 1 1V13a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -703,41 +530,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fillRule="nonzero"
transform="matrix(0 1 1 0 0 0)"
xlinkHref="#arrow_right-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-guava-testlib-closed"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 2H1v11h14V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2zm.25-1a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H15a1 1 0 0 1 1 1V13a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -765,41 +575,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fillRule="nonzero"
transform="matrix(0 1 1 0 0 0)"
xlinkHref="#arrow_right-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-guava-tests-closed"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 2H1v11h14V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2zm.25-1a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H15a1 1 0 0 1 1 1V13a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -827,41 +620,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fillRule="nonzero"
transform="matrix(0 1 1 0 0 0)"
xlinkHref="#arrow_right-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-refactorings-closed"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 2H1v11h14V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2zm.25-1a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H15a1 1 0 0 1 1 1V13a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -889,41 +665,24 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--small codeFileTree__icon"
className="euiIcon euiIcon--small euiIcon-isLoading codeFileTree__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fillRule="nonzero"
transform="matrix(0 1 1 0 0 0)"
xlinkHref="#arrow_right-a"
/>
</svg>
/>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
data-test-subj="codeFileTreeNode-Directory-Icon-util-closed"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 2H1v11h14V3.5H7.125A1.125 1.125 0 0 1 6 2.375V2zm.25-1a.75.75 0 0 1 .75.75v.625c0 .069.056.125.125.125H15a1 1 0 0 1 1 1V13a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.25z"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -951,25 +710,14 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M10.8 0H2a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4.429c0-.256-.098-.503-.274-.689l-3.2-3.428A1.002 1.002 0 0 0 10.8 0M14 5v10H2V1h8v3.5a.5.5 0 0 0 .5.5H14z"
id="document-a"
/>
</defs>
<use
xlinkHref="#document-a"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -1001,25 +749,14 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M10.8 0H2a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4.429c0-.256-.098-.503-.274-.689l-3.2-3.428A1.002 1.002 0 0 0 10.8 0M14 5v10H2V1h8v3.5a.5.5 0 0 0 .5.5H14z"
id="document-a"
/>
</defs>
<use
xlinkHref="#document-a"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -1051,25 +788,14 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M10.8 0H2a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4.429c0-.256-.098-.503-.274-.689l-3.2-3.428A1.002 1.002 0 0 0 10.8 0M14 5v10H2V1h8v3.5a.5.5 0 0 0 .5.5H14z"
id="document-a"
/>
</defs>
<use
xlinkHref="#document-a"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -1101,25 +827,14 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M10.8 0H2a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4.429c0-.256-.098-.503-.274-.689l-3.2-3.428A1.002 1.002 0 0 0 10.8 0M14 5v10H2V1h8v3.5a.5.5 0 0 0 .5.5H14z"
id="document-a"
/>
</defs>
<use
xlinkHref="#document-a"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -1151,25 +866,14 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M10.8 0H2a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4.429c0-.256-.098-.503-.274-.689l-3.2-3.428A1.002 1.002 0 0 0 10.8 0M14 5v10H2V1h8v3.5a.5.5 0 0 0 .5.5H14z"
id="document-a"
/>
</defs>
<use
xlinkHref="#document-a"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -1201,25 +905,14 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M10.8 0H2a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4.429c0-.256-.098-.503-.274-.689l-3.2-3.428A1.002 1.002 0 0 0 10.8 0M14 5v10H2V1h8v3.5a.5.5 0 0 0 .5.5H14z"
id="document-a"
/>
</defs>
<use
xlinkHref="#document-a"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -1251,25 +944,14 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M10.8 0H2a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4.429c0-.256-.098-.503-.274-.689l-3.2-3.428A1.002 1.002 0 0 0 10.8 0M14 5v10H2V1h8v3.5a.5.5 0 0 0 .5.5H14z"
id="document-a"
/>
</defs>
<use
xlinkHref="#document-a"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -1301,25 +983,14 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M10.8 0H2a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4.429c0-.256-.098-.503-.274-.689l-3.2-3.428A1.002 1.002 0 0 0 10.8 0M14 5v10H2V1h8v3.5a.5.5 0 0 0 .5.5H14z"
id="document-a"
/>
</defs>
<use
xlinkHref="#document-a"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -1351,25 +1022,14 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M10.8 0H2a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4.429c0-.256-.098-.503-.274-.689l-3.2-3.428A1.002 1.002 0 0 0 10.8 0M14 5v10H2V1h8v3.5a.5.5 0 0 0 .5.5H14z"
id="document-a"
/>
</defs>
<use
xlinkHref="#document-a"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>
@ -1401,25 +1061,14 @@ exports[`render correctly 1`] = `
tabIndex={0}
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M10.8 0H2a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4.429c0-.256-.098-.503-.274-.689l-3.2-3.428A1.002 1.002 0 0 0 10.8 0M14 5v10H2V1h8v3.5a.5.5 0 0 0 .5.5H14z"
id="document-a"
/>
</defs>
<use
xlinkHref="#document-a"
/>
</svg>
/>
<span
className="codeFileTree__directory"
>

View file

@ -44,7 +44,6 @@ test('render correctly', () => {
location={location}
closeTreePath={mockFunction}
openTreePath={mockFunction}
fetchRepoTree={mockFunction}
/>
)
.toJSON();

View file

@ -11,7 +11,7 @@ import classes from 'classnames';
import { connect } from 'react-redux';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { FileTree as Tree, FileTreeItemType } from '../../../model';
import { closeTreePath, fetchRepoTree, FetchRepoTreePayload, openTreePath } from '../../actions';
import { closeTreePath, openTreePath } from '../../actions';
import { EuiSideNavItem, MainRouteParams, PathTypes } from '../../common/types';
import { RootState } from '../../reducers';
import { encodeRevisionString } from '../../utils/url';
@ -20,9 +20,7 @@ interface Props extends RouteComponentProps<MainRouteParams> {
node?: Tree;
closeTreePath: (paths: string) => void;
openTreePath: (paths: string) => void;
fetchRepoTree: (p: FetchRepoTreePayload) => void;
openedPaths: string[];
treeLoading?: boolean;
}
export class CodeFileTree extends React.Component<Props> {
@ -33,16 +31,6 @@ export class CodeFileTree extends React.Component<Props> {
}
}
public fetchTree(path = '', isDir: boolean) {
const { resource, org, repo, revision } = this.props.match.params;
this.props.fetchRepoTree({
uri: `${resource}/${org}/${repo}`,
revision,
path: path || '',
isDir,
});
}
public onClick = (node: Tree) => {
const { resource, org, repo, revision, path } = this.props.match.params;
if (!(path === node.path)) {
@ -257,11 +245,9 @@ export class CodeFileTree extends React.Component<Props> {
const mapStateToProps = (state: RootState) => ({
node: state.file.tree,
openedPaths: state.file.openedPaths,
treeLoading: state.file.rootFileTreeLoading,
});
const mapDispatchToProps = {
fetchRepoTree,
closeTreePath,
openTreePath,
};

View file

@ -53,8 +53,8 @@ interface Props extends RouteComponentProps<MainRouteParams> {
onSearchScopeChanged: (s: SearchScope) => void;
repoScope: string[];
notFoundDirs: string[];
fileTreeLoadingPaths: string[];
searchOptions: SearchOptions;
fileTreeLoading: boolean;
query: string;
}
const LANG_MD = 'markdown';
@ -266,7 +266,7 @@ class CodeContent extends React.PureComponent<Props> {
}
public renderContent() {
const { file, match, tree, fileTreeLoading, isNotFound, notFoundDirs } = this.props;
const { file, match, tree, fileTreeLoadingPaths, isNotFound, notFoundDirs } = this.props;
const { path, pathType, resource, org, repo, revision } = match.params;
if (isNotFound || notFoundDirs.includes(path || '')) {
return <NotFound />;
@ -281,7 +281,7 @@ class CodeContent extends React.PureComponent<Props> {
const node = this.findNode(path ? path.split('/') : [], tree);
return (
<div className="codeContainer__directoryView">
<Directory node={node} loading={fileTreeLoading} />
<Directory node={node} loading={fileTreeLoadingPaths.includes(path)} />
<CommitHistory
repoUri={repoUri}
header={
@ -390,7 +390,7 @@ const mapStateToProps = (state: RootState) => ({
notFoundDirs: state.file.notFoundDirs,
file: state.file.file,
tree: state.file.tree,
fileTreeLoading: state.file.fileTreeLoading,
fileTreeLoadingPaths: state.file.fileTreeLoadingPaths,
currentTree: currentTreeSelector(state),
branches: state.file.branches,
hasMoreCommits: hasMoreCommitsSelector(state),

View file

@ -74,7 +74,7 @@ class CodeMain extends React.Component<Props> {
}
const mapStateToProps = (state: RootState) => ({
loadingFileTree: state.file.rootFileTreeLoading,
loadingFileTree: state.file.fileTreeLoadingPaths.includes(''),
loadingStructureTree: state.symbol.loading,
hasStructure: structureSelector(state).length > 0 && !state.symbol.error,
languageServerInitializing: state.symbol.languageServerInitializing,

View file

@ -71,7 +71,7 @@ class CodeSideTabs extends React.PureComponent<Props> {
id: Tabs.file,
name: 'File',
content: fileTabContent,
'data-test-subj': 'codeFileTreeTab',
'data-test-subj': `codeFileTreeTab${this.sideTab === Tabs.file ? 'Active' : ''}`,
},
{
id: Tabs.structure,

View file

@ -349,29 +349,21 @@ exports[`render correctly with empty query string 1`] = `
<EuiIcon
type="bullseye"
>
<bullseye
className="euiIcon euiIcon--medium"
<EuiIconEmpty
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12zm0 1A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0-3a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0-1a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"
/>
</svg>
</bullseye>
/>
</EuiIconEmpty>
</EuiIcon>
Search Everything
@ -408,29 +400,21 @@ exports[`render correctly with empty query string 1`] = `
<EuiIcon
type="bullseye"
>
<bullseye
className="euiIcon euiIcon--medium"
<EuiIconEmpty
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12zm0 1A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0-3a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0-1a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"
/>
</svg>
</bullseye>
/>
</EuiIconEmpty>
</EuiIcon>
Search Everything
@ -461,40 +445,23 @@ exports[`render correctly with empty query string 1`] = `
className="euiFormControlLayoutCustomIcon__icon"
type="arrowDown"
>
<arrowDown
<EuiIconEmpty
aria-hidden="true"
className="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
</arrowDown>
/>
</EuiIconEmpty>
</EuiIcon>
</span>
</EuiFormControlLayoutCustomIcon>
@ -1093,29 +1060,21 @@ exports[`render correctly with input query string changed 1`] = `
<EuiIcon
type="bullseye"
>
<bullseye
className="euiIcon euiIcon--medium"
<EuiIconEmpty
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12zm0 1A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0-3a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0-1a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"
/>
</svg>
</bullseye>
/>
</EuiIconEmpty>
</EuiIcon>
Search Everything
@ -1152,29 +1111,21 @@ exports[`render correctly with input query string changed 1`] = `
<EuiIcon
type="bullseye"
>
<bullseye
className="euiIcon euiIcon--medium"
<EuiIconEmpty
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<svg
className="euiIcon euiIcon--medium"
className="euiIcon euiIcon--medium euiIcon-isLoading"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12zm0 1A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0-3a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0-1a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"
/>
</svg>
</bullseye>
/>
</EuiIconEmpty>
</EuiIcon>
Search Everything
@ -1205,40 +1156,23 @@ exports[`render correctly with input query string changed 1`] = `
className="euiFormControlLayoutCustomIcon__icon"
type="arrowDown"
>
<arrowDown
<EuiIconEmpty
aria-hidden="true"
className="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
style={null}
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<svg
aria-hidden="true"
className="euiIcon euiIcon--medium euiFormControlLayoutCustomIcon__icon"
className="euiIcon euiIcon--medium euiIcon-isLoading euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
height={16}
style={null}
viewBox="0 0 16 16"
width="16"
width={16}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fillRule="nonzero"
xlinkHref="#arrow_down-a"
/>
</svg>
</arrowDown>
/>
</EuiIconEmpty>
</EuiIcon>
</span>
</EuiFormControlLayoutCustomIcon>

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