diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/DetailView.test.js b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/DetailView.test.js index c41fe7891a6b6e..1111a7aec186a4 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/DetailView.test.js +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/DetailView.test.js @@ -7,43 +7,36 @@ import React from 'react'; import DetailView from '../index'; import props from './props.json'; +import { shallow } from 'enzyme'; -import { - mountWithRouterAndStore, - mockMoment, - toJson -} from '../../../../../utils/testHelpers'; +import { mockMoment } from '../../../../../utils/testHelpers'; describe('DetailView', () => { - let storeState; beforeEach(() => { // Avoid timezone issues mockMoment(); - - storeState = { - location: { search: '' } - }; }); it('should render empty state', () => { - const wrapper = mountWithRouterAndStore( - , - storeState + const wrapper = shallow( + ); - - expect(toJson(wrapper)).toMatchSnapshot(); + expect(wrapper).toMatchSnapshot(); }); it('should render with data', () => { - const wrapper = mountWithRouterAndStore( + const wrapper = shallow( , - storeState + location={{ state: '' }} + /> ); - expect(toJson(wrapper)).toMatchSnapshot(); + expect(wrapper).toMatchSnapshot(); }); }); diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/__snapshots__/DetailView.test.js.snap b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/__snapshots__/DetailView.test.js.snap index fae5b56c028922..7b59b132d30402 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/__snapshots__/DetailView.test.js.snap +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/__test__/__snapshots__/DetailView.test.js.snap @@ -3,1812 +3,1988 @@ exports[`DetailView should render empty state 1`] = `""`; exports[`DetailView should render with data 1`] = ` -.c4 { - margin-bottom: 8px; - font-size: 12px; - color: #999999; -} - -.c4 span { - cursor: help; -} - -.c6 { - color: #999999; -} - -.c5 { - display: inline-block; - line-height: 16px; -} - -.c7 { - display: inline-block; - line-height: 16px; - max-width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.c2 { - margin: 24px 0; - font-size: 20px; - margin: 0; -} - -.c9 { - display: inline-block; - font-size: 16px; - padding: 16px 20px; - text-align: center; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-bottom: 2px solid #006E8A; -} - -.c10 { - display: inline-block; - font-size: 16px; - padding: 16px 20px; - text-align: center; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.c15 { - position: relative; - border-radius: 0 0 5px 5px; -} - -.c16 { - position: absolute; - width: 100%; - height: 18px; - top: 126px; - pointer-events: none; - background-color: #FCF2E6; -} - -.c17 { - position: absolute; - top: 0; - left: 0; - border-radius: 0 0 0 5px; - background: #f5f5f5; -} - -.c18 { - position: relative; - min-width: 42px; - padding-left: 8px; - padding-right: 4px; - color: #999999; - line-height: 18px; - text-align: right; - border-right: 1px solid #d9d9d9; -} - -.c18:last-of-type { - border-radius: 0 0 0 5px; -} - -.c19 { - position: relative; - min-width: 42px; - padding-left: 8px; - padding-right: 4px; - color: #999999; - line-height: 18px; - text-align: right; - border-right: 1px solid #d9d9d9; - background-color: #FCF2E6; -} - -.c19:last-of-type { - border-radius: 0 0 0 5px; -} - -.c20 { - overflow: auto; - margin: 0 0 0 42px; - padding: 0; - background-color: #ffffff; -} - -.c20:last-of-type { - border-radius: 0 0 5px 0; -} - -.c21 { - margin: 0; - color: inherit; - background: inherit; - border: 0; - border-radius: 0; - overflow: initial; - padding: 0 18px; - line-height: 18px; -} - -.c22 { - position: relative; - padding: 0; - margin: 0; - white-space: pre; - z-index: 2; -} - -.c12 { - color: #999999; - padding: 8px; - border-bottom: 1px solid #d9d9d9; - border-radius: 5px 5px 0 0; -} - -.c14 { - font-weight: bold; -} - -.c11 { - margin: 0 0 24px 0; - position: relative; - font-family: "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace; - border: 1px solid #d9d9d9; - border-radius: 5px; - background: #f5f5f5; -} - -.c11 .c13 { - color: #000000; -} - -.c23 { - margin: 0 0 24px 0; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.c0 { - position: relative; - border: 1px solid #d9d9d9; - border-radius: 5px; - margin-top: 24px; -} - -.c1 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - -webkit-align-items: flex-start; - -webkit-box-align: flex-start; - -ms-flex-align: flex-start; - align-items: flex-start; - padding: 24px 24px 0; - margin-bottom: 16px; -} - -.c8 { - padding: 0 24px; - border-bottom: 1px solid #d9d9d9; -} - -.c3 { - padding: 24px 24px 0; -} - -
-
-

+ + Error occurrence -

- - - - - View 18 occurences in Discover - - - - -
-
-
+ -
+ + + -
- - Timestamp - -
-
- 1337 minutes ago (mocking 1515508740) - - - ( - 1st of January (mocking 1515508740) - ) - -
-
-
-
- - URL - -
- - N/A - -
-
-
- - Request method - -
-
- GET -
-
-
-
- - Handled - -
-
- N/A -
-
-
-
- - User ID - -
-
- N/A -
-
-
-
-
-
+ + + Exception stacktrace -
-
+ Request -
-
+ Response -
-
+ System -
-
+ Service -
-
+ Process -
-
+ User -
-
+ Tags -
-
+ Custom -
-
-
-
-

- Stack traces -

-
-
- - server/coffee.js - - in - - - <anonymous> - - at - - - line - 9 - -
-
-
-
-
- 2 - . -
-
- 3 - . -
-
- 4 - . -
-
- 5 - . -
-
- 6 - . -
-
- 7 - . -
-
- 8 - . -
-
- 9 - . -
-
- 10 - . -
-
- 11 - . -
-
- 12 - . -
-
- 13 - . -
-
- 14 - . -
-
- 15 - . -
-
- 16 - . -
-
-
-
-              
-                
-
-              
-            
-
-              
-                
-                  var
-                
-                 express = 
-                
-                  require
-                
-                (
-                
-                  'express'
-                
-                )
-              
-            
-
-              
-                
-                  var
-                
-                 apm = 
-                
+  
+  
+     (server/coffee.js)",
+                "exception": Object {
+                  "message": "Cannot read property 'level' of undefined",
+                  "stacktrace": Array [
                     Object {
-                      "color": "#5c2699",
-                    }
-                  }
-                >
-                  require
-                
-                (
-                ",
+                      "libraryFrame": false,
+                      "line": Object {
+                        "context": "  if (req.paarms.level === 11) {",
+                        "number": 9,
+                      },
+                    },
                     Object {
-                      "color": "#c41a16",
-                    }
-                  }
-                >
-                  'elastic-apm-node'
-                
-                )
-              
-            
-
-              
-                
-
-              
-            
-
-              
-                 3) {",
+                          "    // not a standard request handler",
+                          "    return next();",
+                          "  }",
+                          "",
+                          "  try {",
+                        ],
+                      },
+                      "filename": "node_modules/express/lib/router/layer.js",
+                      "function": "handle",
+                      "libraryFrame": true,
+                      "line": Object {
+                        "context": "    fn(req, res, next);",
+                        "number": 95,
+                      },
+                    },
                     Object {
-                      "color": "#aa0d91",
-                    }
-                  }
-                >
-                  var
-                
-                 app = 
-                
-                  module
-                
-                .exports = 
-                
-                  new
-                
-                 express.Router()
-              
-            
-
-              
-                
-
-              
-            
-
-              
-                app.get(
-                 3) {",
+                          "    // not a standard request handler",
+                          "    return next();",
+                          "  }",
+                          "",
+                          "  try {",
+                        ],
+                      },
+                      "filename": "node_modules/express/lib/router/layer.js",
+                      "function": "handle",
+                      "libraryFrame": true,
+                      "line": Object {
+                        "context": "    fn(req, res, next);",
+                        "number": 95,
+                      },
+                    },
                     Object {
-                      "color": "#c41a16",
-                    }
-                  }
-                >
-                  '/is-it-coffee-time'
-                
-                , 
-                
-                  
-                    function
-                  
-                   (
-                  
-                    req, res
-                  
-                  ) 
-                
-                {
-              
-            
-
-              
-                  
-                ",
+                      "libraryFrame": true,
+                      "line": Object {
+                        "context": "        return layer.handle_request(req, res, next);",
+                        "number": 281,
+                      },
+                    },
                     Object {
-                      "color": "#aa0d91",
-                    }
-                  }
-                >
-                  if
-                
-                 (req.paarms.level === 
-                
-                  11
-                
-                ) {
-              
-            
-
-              
-                    res.send(
-                
-                  'Of course!'
-                
-                )
-              
-            
-
-              
-                  } 
-                
-                  else
-                
-                 {
-              
-            
-
-              
-                    res.send(
-                
-                  'You can\\'t have any!'
-                
-                )
-              
-            
-
-              
-                  }
-              
-            
-
-              
-                })
-              
-            
-
-              
-                
-
-              
-            
-
-              
-                app.get(
-                 3) {",
+                          "    // not a standard request handler",
+                          "    return next();",
+                          "  }",
+                          "",
+                          "  try {",
+                        ],
+                      },
+                      "filename": "node_modules/express/lib/router/layer.js",
+                      "function": "handle",
+                      "libraryFrame": true,
+                      "line": Object {
+                        "context": "    fn(req, res, next);",
+                        "number": 95,
+                      },
+                    },
                     Object {
-                      "color": "#c41a16",
-                    }
-                  }
-                >
-                  '/log-error'
-                
-                , 
-                
-                  
-                    function
-                  
-                   (
-                  
-                    req, res
-                  
-                  ) 
-                
-                {
-              
-            
-
-
-
-
-
- -
-
-
-
-
- - server.js - - in - - - <anonymous> - - at - - - line - 27 - -
-
-
-
-
- 20 - . -
-
- 21 - . -
-
- 22 - . -
-
- 23 - . -
-
- 24 - . -
-
- 25 - . -
-
- 26 - . -
-
- 27 - . -
-
- 28 - . -
-
- 29 - . -
-
- 30 - . -
-
- 31 - . -
-
- 32 - . -
-
- 33 - . -
-
- 34 - . -
-
-
-
-              
-                app.use(
-                
-                  require
-                
-                (
-                ",
+                      "libraryFrame": true,
+                      "line": Object {
+                        "context": "      trim_prefix(layer, layerError, layerPath, path);",
+                        "number": 284,
+                      },
+                    },
                     Object {
-                      "color": "#c41a16",
-                    }
-                  }
-                >
-                  'body-parser'
-                
-                ).json())
-              
-            
-
-              
-                app.use(express.static(
-                
-                  'client/build'
-                
-                ))
-              
-            
-
-              
-                app.use(
-                
-                  
-                    function
-                  
-                   (
-                  
-                    req, res, next
-                  
-                  ) 
-                
-                {
-              
-            
-
-              
-                  apm.setTag(
-                
-                  'foo'
-                
-                , 
-                ",
+                      "libraryFrame": false,
+                      "line": Object {
+                        "context": "  next()",
+                        "number": 27,
+                      },
+                    },
                     Object {
-                      "color": "#c41a16",
-                    }
-                  }
-                >
-                  'bar'
-                
-                )
-              
-            
-
-              
-                  apm.setTag(
-                 3) {",
+                          "    // not a standard request handler",
+                          "    return next();",
+                          "  }",
+                          "",
+                          "  try {",
+                        ],
+                      },
+                      "filename": "node_modules/express/lib/router/layer.js",
+                      "function": "handle",
+                      "libraryFrame": true,
+                      "line": Object {
+                        "context": "    fn(req, res, next);",
+                        "number": 95,
+                      },
+                    },
                     Object {
-                      "color": "#c41a16",
-                    }
-                  }
-                >
-                  'lorem'
-                
-                , 
-                
-                  'ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus, ipsum id scelerisque consequat, enim leo vulputate massa, vel ultricies ante neque ac risus. Curabitur tincidunt vitae sapien id pulvinar. Mauris eu vestibulum tortor. Integer sit amet lorem fringilla, egestas tellus vitae, vulputate purus. Nulla feugiat blandit nunc et semper. Morbi purus libero, mattis sed mauris non, euismod iaculis lacus. Curabitur eleifend ante eros, non faucibus velit lacinia id. Duis posuere libero augue, at dignissim urna consectetur eget. Praesent eu congue est, iaculis finibus augue.'
-                
-                )
-              
-            
-
-              
-                  apm.setTag(
-                ",
+                      "libraryFrame": true,
+                      "line": Object {
+                        "context": "      trim_prefix(layer, layerError, layerPath, path);",
+                        "number": 284,
+                      },
+                    },
                     Object {
-                      "color": "#c41a16",
-                    }
-                  }
-                >
-                  'this-is-a-very-long-tag-name-without-any-spaces'
-                
-                , 
-                
-                  'test'
-                
-                )
-              
-            
-
-              
-                  apm.setTag(
-                
-                  'multi-line'
-                
-                , 
-                
-                  'foo\\nbar\\nbaz'
-                
-                )
-              
-            
-
-              
-                  next()
-              
-            
-
-              
-                })
-              
-            
-
-              
-                
-
-              
-            
-
-              
-                app.use(
-                
-                  require
-                
-                (
-                
-                  './server/coffee'
-                
-                ))
-              
-            
-
-              
-                app.use(
-                
-                  '/api'
-                
-                , 
-                
-                  require
-                
-                (
-                
-                  './server/routes'
-                
-                ))
-              
-            
-
-              
-                app.get(
-                
-                  '*'
-                
-                , 
-                
-                  
-                    function
-                  
-                   (
-                  
-                    req, res
-                  
-                  ) 
-                
-                {
-              
-            
-
-              
-                  res.sendFile(path.resolve(__dirname, 
-                
-                  'client/build'
-                
-                , 
-                
-                  'index.html'
-                
-                ))
-              
-            
-
-              
-                })
-              
-            
-
-
-
-
-
- -
-
-
-
-
-
+ "absPath": "fs.js", + "filename": "fs.js", + "function": "FSReqWrap.oncomplete", + "libraryFrame": true, + "line": Object { + "number": 123, + }, + }, + ], + "type": "TypeError", + }, + "groupingKey": "c00e245c2fbebaf178fc31eeb2bb0250", + "id": "c5e55dfc-09cc-4e0d-ace3-1ba4233f66eb", + }, + "processor": Object { + "event": "error", + "name": "error", + }, + }, + "groupId": "c00e245c2fbebaf178fc31eeb2bb0250", + "occurrencesCount": 18, + }, + "status": "SUCCESS", + } + } + excStackframes={ + Array [ + Object { + "absPath": "/app/server/coffee.js", + "context": Object { + "post": Array [ + " res.send('Of course!')", + " } else {", + " res.send('You can\\\\'t have any!')", + " }", + "})", + "", + "app.get('/log-error', function (req, res) {", + ], + "pre": Array [ + "", + "var express = require('express')", + "var apm = require('elastic-apm-node')", + "", + "var app = module.exports = new express.Router()", + "", + "app.get('/is-it-coffee-time', function (req, res) {", + ], + }, + "filename": "server/coffee.js", + "function": "", + "libraryFrame": false, + "line": Object { + "context": " if (req.paarms.level === 11) {", + "number": 9, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/layer.js", + "context": Object { + "post": Array [ + " } catch (err) {", + " next(err);", + " }", + "};", + "", + "/**", + " * Check if this route matches \`path\`, if so", + ], + "pre": Array [ + "", + " if (fn.length > 3) {", + " // not a standard request handler", + " return next();", + " }", + "", + " try {", + ], + }, + "filename": "node_modules/express/lib/router/layer.js", + "function": "handle", + "libraryFrame": true, + "line": Object { + "context": " fn(req, res, next);", + "number": 95, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/route.js", + "context": Object { + "post": Array [ + " }", + " }", + "};", + "", + "/**", + " * Add a handler for all HTTP verbs to this route.", + " *", + ], + "pre": Array [ + " if (layer.method && layer.method !== method) {", + " return next(err);", + " }", + "", + " if (err) {", + " layer.handle_error(err, req, res, next);", + " } else {", + ], + }, + "filename": "node_modules/express/lib/router/route.js", + "function": "next", + "libraryFrame": true, + "line": Object { + "context": " layer.handle_request(req, res, next);", + "number": 137, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/route.js", + "context": Object { + "post": Array [ + "", + " function next(err) {", + " // signal to exit route", + " if (err && err === 'route') {", + " return done();", + " }", + "", + ], + "pre": Array [ + " var method = req.method.toLowerCase();", + " if (method === 'head' && !this.methods['head']) {", + " method = 'get';", + " }", + "", + " req.route = this;", + "", + ], + }, + "filename": "node_modules/express/lib/router/route.js", + "function": "dispatch", + "libraryFrame": true, + "line": Object { + "context": " next();", + "number": 112, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/layer.js", + "context": Object { + "post": Array [ + " } catch (err) {", + " next(err);", + " }", + "};", + "", + "/**", + " * Check if this route matches \`path\`, if so", + ], + "pre": Array [ + "", + " if (fn.length > 3) {", + " // not a standard request handler", + " return next();", + " }", + "", + " try {", + ], + }, + "filename": "node_modules/express/lib/router/layer.js", + "function": "handle", + "libraryFrame": true, + "line": Object { + "context": " fn(req, res, next);", + "number": 95, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + " }", + "", + " trim_prefix(layer, layerError, layerPath, path);", + " });", + " }", + "", + " function trim_prefix(layer, layerError, layerPath, path) {", + ], + "pre": Array [ + " // this should be done for the layer", + " self.process_params(layer, paramcalled, req, res, function (err) {", + " if (err) {", + " return next(layerError || err);", + " }", + "", + " if (route) {", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "", + "libraryFrame": true, + "line": Object { + "context": " return layer.handle_request(req, res, next);", + "number": 281, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + " }", + "", + " var i = 0;", + " var name;", + " var paramIndex = 0;", + " var key;", + " var paramVal;", + ], + "pre": Array [ + " var params = this.params;", + "", + " // captured parameters from the layer, keys and values", + " var keys = layer.keys;", + "", + " // fast track", + " if (!keys || keys.length === 0) {", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "process_params", + "libraryFrame": true, + "line": Object { + "context": " return done();", + "number": 335, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + " if (err) {", + " return next(layerError || err);", + " }", + "", + " if (route) {", + " return layer.handle_request(req, res, next);", + " }", + ], + "pre": Array [ + " // Capture one-time layer values", + " req.params = self.mergeParams", + " ? mergeParams(layer.params, parentParams)", + " : layer.params;", + " var layerPath = layer.path;", + "", + " // this should be done for the layer", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "next", + "libraryFrame": true, + "line": Object { + "context": " self.process_params(layer, paramcalled, req, res, function (err) {", + "number": 275, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + "", + " function next(err) {", + " var layerError = err === 'route'", + " ? null", + " : err;", + "", + " // remove added slash", + ], + "pre": Array [ + " });", + " }", + "", + " // setup basic req values", + " req.baseUrl = parentUrl;", + " req.originalUrl = req.originalUrl || req.url;", + "", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "handle", + "libraryFrame": true, + "line": Object { + "context": " next();", + "number": 174, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + " }", + "", + " // mixin Router class functions", + " setPrototypeOf(router, proto)", + "", + " router.params = {};", + " router._params = [];", + ], + "pre": Array [ + " * @public", + " */", + "", + "var proto = module.exports = function(options) {", + " var opts = options || {};", + "", + " function router(req, res, next) {", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "router", + "libraryFrame": true, + "line": Object { + "context": " router.handle(req, res, next);", + "number": 47, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/layer.js", + "context": Object { + "post": Array [ + " } catch (err) {", + " next(err);", + " }", + "};", + "", + "/**", + " * Check if this route matches \`path\`, if so", + ], + "pre": Array [ + "", + " if (fn.length > 3) {", + " // not a standard request handler", + " return next();", + " }", + "", + " try {", + ], + }, + "filename": "node_modules/express/lib/router/layer.js", + "function": "handle", + "libraryFrame": true, + "line": Object { + "context": " fn(req, res, next);", + "number": 95, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + " }", + " }", + "};", + "", + "/**", + " * Process any parameters for the layer.", + " * @private", + ], + "pre": Array [ + " }", + "", + " debug('%s %s : %s', layer.name, layerPath, req.originalUrl);", + "", + " if (layerError) {", + " layer.handle_error(layerError, req, res, next);", + " } else {", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "trim_prefix", + "libraryFrame": true, + "line": Object { + "context": " layer.handle_request(req, res, next);", + "number": 317, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + " });", + " }", + "", + " function trim_prefix(layer, layerError, layerPath, path) {", + " if (layerPath.length !== 0) {", + " // Validate path breaks on a path separator", + " var c = path[layerPath.length]", + ], + "pre": Array [ + " return next(layerError || err);", + " }", + "", + " if (route) {", + " return layer.handle_request(req, res, next);", + " }", + "", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "", + "libraryFrame": true, + "line": Object { + "context": " trim_prefix(layer, layerError, layerPath, path);", + "number": 284, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + " }", + "", + " var i = 0;", + " var name;", + " var paramIndex = 0;", + " var key;", + " var paramVal;", + ], + "pre": Array [ + " var params = this.params;", + "", + " // captured parameters from the layer, keys and values", + " var keys = layer.keys;", + "", + " // fast track", + " if (!keys || keys.length === 0) {", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "process_params", + "libraryFrame": true, + "line": Object { + "context": " return done();", + "number": 335, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + " if (err) {", + " return next(layerError || err);", + " }", + "", + " if (route) {", + " return layer.handle_request(req, res, next);", + " }", + ], + "pre": Array [ + " // Capture one-time layer values", + " req.params = self.mergeParams", + " ? mergeParams(layer.params, parentParams)", + " : layer.params;", + " var layerPath = layer.path;", + "", + " // this should be done for the layer", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "next", + "libraryFrame": true, + "line": Object { + "context": " self.process_params(layer, paramcalled, req, res, function (err) {", + "number": 275, + }, + }, + Object { + "absPath": "/app/server.js", + "context": Object { + "post": Array [ + "})", + "", + "app.use(require('./server/coffee'))", + "app.use('/api', require('./server/routes'))", + "app.get('*', function (req, res) {", + " res.sendFile(path.resolve(__dirname, 'client/build', 'index.html'))", + "})", + ], + "pre": Array [ + "app.use(require('body-parser').json())", + "app.use(express.static('client/build'))", + "app.use(function (req, res, next) {", + " apm.setTag('foo', 'bar')", + " apm.setTag('lorem', 'ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus, ipsum id scelerisque consequat, enim leo vulputate massa, vel ultricies ante neque ac risus. Curabitur tincidunt vitae sapien id pulvinar. Mauris eu vestibulum tortor. Integer sit amet lorem fringilla, egestas tellus vitae, vulputate purus. Nulla feugiat blandit nunc et semper. Morbi purus libero, mattis sed mauris non, euismod iaculis lacus. Curabitur eleifend ante eros, non faucibus velit lacinia id. Duis posuere libero augue, at dignissim urna consectetur eget. Praesent eu congue est, iaculis finibus augue.')", + " apm.setTag('this-is-a-very-long-tag-name-without-any-spaces', 'test')", + " apm.setTag('multi-line', 'foo\\\\nbar\\\\nbaz')", + ], + }, + "filename": "server.js", + "function": "", + "libraryFrame": false, + "line": Object { + "context": " next()", + "number": 27, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/layer.js", + "context": Object { + "post": Array [ + " } catch (err) {", + " next(err);", + " }", + "};", + "", + "/**", + " * Check if this route matches \`path\`, if so", + ], + "pre": Array [ + "", + " if (fn.length > 3) {", + " // not a standard request handler", + " return next();", + " }", + "", + " try {", + ], + }, + "filename": "node_modules/express/lib/router/layer.js", + "function": "handle", + "libraryFrame": true, + "line": Object { + "context": " fn(req, res, next);", + "number": 95, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + " }", + " }", + "};", + "", + "/**", + " * Process any parameters for the layer.", + " * @private", + ], + "pre": Array [ + " }", + "", + " debug('%s %s : %s', layer.name, layerPath, req.originalUrl);", + "", + " if (layerError) {", + " layer.handle_error(layerError, req, res, next);", + " } else {", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "trim_prefix", + "libraryFrame": true, + "line": Object { + "context": " layer.handle_request(req, res, next);", + "number": 317, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + " });", + " }", + "", + " function trim_prefix(layer, layerError, layerPath, path) {", + " if (layerPath.length !== 0) {", + " // Validate path breaks on a path separator", + " var c = path[layerPath.length]", + ], + "pre": Array [ + " return next(layerError || err);", + " }", + "", + " if (route) {", + " return layer.handle_request(req, res, next);", + " }", + "", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "", + "libraryFrame": true, + "line": Object { + "context": " trim_prefix(layer, layerError, layerPath, path);", + "number": 284, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + " }", + "", + " var i = 0;", + " var name;", + " var paramIndex = 0;", + " var key;", + " var paramVal;", + ], + "pre": Array [ + " var params = this.params;", + "", + " // captured parameters from the layer, keys and values", + " var keys = layer.keys;", + "", + " // fast track", + " if (!keys || keys.length === 0) {", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "process_params", + "libraryFrame": true, + "line": Object { + "context": " return done();", + "number": 335, + }, + }, + Object { + "absPath": "/app/node_modules/express/lib/router/index.js", + "context": Object { + "post": Array [ + " if (err) {", + " return next(layerError || err);", + " }", + "", + " if (route) {", + " return layer.handle_request(req, res, next);", + " }", + ], + "pre": Array [ + " // Capture one-time layer values", + " req.params = self.mergeParams", + " ? mergeParams(layer.params, parentParams)", + " : layer.params;", + " var layerPath = layer.path;", + "", + " // this should be done for the layer", + ], + }, + "filename": "node_modules/express/lib/router/index.js", + "function": "next", + "libraryFrame": true, + "line": Object { + "context": " self.process_params(layer, paramcalled, req, res, function (err) {", + "number": 275, + }, + }, + Object { + "absPath": "/app/node_modules/elastic-apm-node/lib/instrumentation/modules/express.js", + "context": Object { + "post": Array [ + " }", + " }", + " }", + " })", + "", + " return express", + "}", + ], + "pre": Array [ + " return function serveStatic (req, res, next) {", + " req._elastic_apm_static = true", + "", + " return origServeStatic(req, res, nextHook)", + "", + " function nextHook (err) {", + " if (!err) req._elastic_apm_static = false", + ], + }, + "filename": "node_modules/elastic-apm-node/lib/instrumentation/modules/express.js", + "function": "nextHook", + "libraryFrame": true, + "line": Object { + "context": " return next.apply(this, arguments)", + "number": 90, + }, + }, + Object { + "absPath": "/app/node_modules/serve-static/index.js", + "context": Object { + "post": Array [ + " })", + "", + " // pipe", + " stream.pipe(res)", + " }", + "}", + "", + ], + "pre": Array [ + " // forward errors", + " stream.on('error', function error (err) {", + " if (forwardError || !(err.statusCode < 500)) {", + " next(err)", + " return", + " }", + "", + ], + }, + "filename": "node_modules/serve-static/index.js", + "function": "error", + "libraryFrame": true, + "line": Object { + "context": " next()", + "number": 121, + }, + }, + Object { + "absPath": "events.js", + "filename": "events.js", + "function": "emitOne", + "libraryFrame": true, + "line": Object { + "number": 96, + }, + }, + Object { + "absPath": "events.js", + "filename": "events.js", + "function": "emit", + "libraryFrame": true, + "line": Object { + "number": 188, + }, + }, + Object { + "absPath": "/app/node_modules/send/index.js", + "context": Object { + "post": Array [ + " expose: false", + " }))", + " }", + "", + " var res = this.res", + " var msg = statuses[status] || String(status)", + " var doc = createHtmlDocument('Error', escapeHtml(msg))", + ], + "pre": Array [ + " * @param {Error} [err]", + " * @private", + " */", + "", + "SendStream.prototype.error = function error (status, err) {", + " // emit if listeners instead of responding", + " if (hasListeners(this, 'error')) {", + ], + }, + "filename": "node_modules/send/index.js", + "function": "error", + "libraryFrame": true, + "line": Object { + "context": " return this.emit('error', createError(status, err, {", + "number": 270, + }, + }, + Object { + "absPath": "/app/node_modules/send/index.js", + "context": Object { + "post": Array [ + " break", + " default:", + " this.error(500, error)", + " break", + " }", + "}", + "", + ], + "pre": Array [ + " */", + "", + "SendStream.prototype.onStatError = function onStatError (error) {", + " switch (error.code) {", + " case 'ENAMETOOLONG':", + " case 'ENOENT':", + " case 'ENOTDIR':", + ], + }, + "filename": "node_modules/send/index.js", + "function": "onStatError", + "libraryFrame": true, + "line": Object { + "context": " this.error(404, error)", + "number": 421, + }, + }, + Object { + "absPath": "/app/node_modules/send/index.js", + "context": Object { + "post": Array [ + " : self.error(404)", + " }", + "", + " var p = path + '.' + self._extensions[i++]", + "", + " debug('stat \\"%s\\"', p)", + " fs.stat(p, function (err, stat) {", + ], + "pre": Array [ + " self.emit('file', path, stat)", + " self.send(path, stat)", + " })", + "", + " function next (err) {", + " if (self._extensions.length <= i) {", + " return err", + ], + }, + "filename": "node_modules/send/index.js", + "function": "next", + "libraryFrame": true, + "line": Object { + "context": " ? self.onStatError(err)", + "number": 736, + }, + }, + Object { + "absPath": "/app/node_modules/send/index.js", + "context": Object { + "post": Array [ + " }", + " if (err) return self.onStatError(err)", + " if (stat.isDirectory()) return self.redirect(path)", + " self.emit('file', path, stat)", + " self.send(path, stat)", + " })", + "", + ], + "pre": Array [ + " var i = 0", + " var self = this", + "", + " debug('stat \\"%s\\"', path)", + " fs.stat(path, function onstat (err, stat) {", + " if (err && err.code === 'ENOENT' && !extname(path) && path[path.length - 1] !== sep) {", + " // not found, check extensions", + ], + }, + "filename": "node_modules/send/index.js", + "function": "onstat", + "libraryFrame": true, + "line": Object { + "context": " return next(err)", + "number": 725, + }, + }, + Object { + "absPath": "/app/node_modules/elastic-apm-node/lib/instrumentation/index.js", + "context": Object { + "post": Array [ + " ins.currentTransaction = prev", + " return result", + " }", + "}", + "", + "Instrumentation.prototype._recoverTransaction = function (trans) {", + " if (this.currentTransaction === trans) return", + ], + "pre": Array [ + " var trans = this.currentTransaction", + "", + " return elasticAPMCallbackWrapper", + "", + " function elasticAPMCallbackWrapper () {", + " var prev = ins.currentTransaction", + " ins.currentTransaction = trans", + ], + }, + "filename": "node_modules/elastic-apm-node/lib/instrumentation/index.js", + "function": "elasticAPMCallbackWrapper", + "libraryFrame": true, + "line": Object { + "context": " var result = original.apply(this, arguments)", + "number": 116, + }, + }, + Object { + "absPath": "fs.js", + "filename": "fs.js", + "function": "FSReqWrap.oncomplete", + "libraryFrame": true, + "line": Object { + "number": 123, + }, + }, + ] + } + /> + + `; diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx index 8c4dd4c262d26d..23a3a5ca54c0f6 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EuiIcon, EuiText, EuiTitle, EuiToolTip } from '@elastic/eui'; import d3 from 'd3'; import React, { Component } from 'react'; import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; @@ -11,15 +12,10 @@ import { IBucket } from 'x-pack/plugins/apm/server/lib/transactions/distribution import { IDistributionResponse } from 'x-pack/plugins/apm/server/lib/transactions/distribution/get_distribution'; // @ts-ignore import { getTimeFormatter, timeUnit } from '../../../../utils/formatters'; -// @ts-ignore import { fromQuery, history, toQuery } from '../../../../utils/url'; // @ts-ignore import Histogram from '../../../shared/charts/Histogram'; import EmptyMessage from '../../../shared/EmptyMessage'; -// @ts-ignore -import { HeaderSmall } from '../../../shared/UIComponents'; -// @ts-ignore -import SamplingTooltip from './SamplingTooltip'; interface IChartPoint { sample?: IBucket['sample']; @@ -88,15 +84,28 @@ export class Distribution extends Component { return (
- - Response time distribution - - + +
+ Response time distribution{' '} + + + Sampling + + + Each bucket will show a sample transaction. If there's + no sample available, it's most likely because of the + sampling limit set in the agent configuration. + +
+ } + > + + + + + - - - - -

Span details

-
-
+ + + + + + +

Span details

+
+
- - - {`View span in Discover`} - - -
-
- - - - - - - - - - -
+ + + {`View span in Discover`} + + +
+
+ + + + + + + + + + + + ); } diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/TransactionFlyout/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/TransactionFlyout/index.tsx index 82ef27823ca6e0..4460404066fba2 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/TransactionFlyout/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/TransactionFlyout/index.tsx @@ -5,17 +5,16 @@ */ import { - EuiButton, EuiFlexGroup, EuiFlexItem, EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiHorizontalRule, + EuiPortal, EuiTitle } from '@elastic/eui'; import React from 'react'; -import { TransactionLink } from 'x-pack/plugins/apm/public/components/shared/TransactionLink'; import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; import { Transaction } from 'x-pack/plugins/apm/typings/Transaction'; import { ActionMenu } from '../../../ActionMenu'; @@ -44,39 +43,33 @@ export function TransactionFlyout({ } return ( - - - - - -

Transaction details

-
-
+ + + + + + +

Transaction details

+
+
- - - - - - - - View transaction group details - - - -
-
- - - - - - - -
+ + + +
+
+ + + + + + + +
+ ); } diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/WaterfallItem.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/WaterfallItem.tsx index be831598aca9a4..616b770944499b 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/WaterfallItem.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/WaterfallItem.tsx @@ -7,9 +7,12 @@ import React from 'react'; import styled from 'styled-components'; +import { EuiIcon } from '@elastic/eui'; import { colors, + fontFamily, fontFamilyCode, + fontSize, fontSizes, px, unit, @@ -17,29 +20,53 @@ import { } from '../../../../../../style/variables'; import { IWaterfallItem } from './waterfall_helpers/waterfall_helpers'; -const ItemBar = styled.div` +interface ItemBarProps { + type: 'transaction' | 'span'; + left: number; + width: number; + color: string; +} + +const ItemBar = styled('div')` + box-sizing: border-box; position: relative; - height: ${unit}px; + height: ${px(unit)}; + left: ${props => props.left}%; + width: ${props => props.width}%; + min-width: '2px'; + background-color: ${props => props.color}; `; -const ItemLabel = styled.div` + +const SpanLabel = styled<{ left: number }, any>('div')` white-space: nowrap; position: relative; - direction: rtl; + left: ${props => `${props.left}%`}; + width: ${props => `${100 - props.left}%`}; text-align: left; margin: ${px(units.quarter)} 0 0; font-family: ${fontFamilyCode}; font-size: ${fontSizes.small}; `; -const Container = styled< - { timelineMargins: TimelineMargins; isSelected: boolean }, - 'div' ->('div')` +const TransactionLabel = styled(SpanLabel)` + font-weight: 600; + font-family: ${fontFamily}; + font-size: ${fontSize}; +`; + +interface IContainerProps { + item: IWaterfallItem; + timelineMargins: ITimelineMargins; + isSelected: boolean; +} + +const Container = styled('div')` position: relative; display: block; user-select: none; padding: ${px(units.half)} ${props => px(props.timelineMargins.right)} - ${px(units.eighth)} ${props => px(props.timelineMargins.left)}; + ${props => px(props.item.docType === 'span' ? units.half : units.quarter)} + ${props => px(props.timelineMargins.left)}; border-top: 1px solid ${colors.gray4}; background-color: ${props => (props.isSelected ? colors.gray5 : 'initial')}; cursor: pointer; @@ -48,15 +75,15 @@ const Container = styled< } `; -interface TimelineMargins { +interface ITimelineMargins { right: number; left: number; top: number; bottom: number; } -interface Props { - timelineMargins: TimelineMargins; +interface IWaterfallItemProps { + timelineMargins: ITimelineMargins; totalDuration: number; item: IWaterfallItem; color: string; @@ -64,6 +91,18 @@ interface Props { onClick: () => any; } +function Prefix({ item }: { item: IWaterfallItem }) { + if (item.docType !== 'transaction') { + return null; + } + + return ( + + {' '} + + ); +} + export function WaterfallItem({ timelineMargins, totalDuration, @@ -71,34 +110,23 @@ export function WaterfallItem({ color, isSelected, onClick -}: Props) { +}: IWaterfallItemProps) { const width = (item.duration / totalDuration) * 100; const left = (item.offset / totalDuration) * 100; + const Label = item.docType === 'transaction' ? TransactionLabel : SpanLabel; return ( - - - ‎ + + + ); } diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/index.tsx index 42eadcab397c41..76c8eada51a0dd 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/index.tsx @@ -78,11 +78,11 @@ export const Transaction: React.SFC = ({ const root = waterfallRoot || transaction; return ( - + - Transaction sample +
Transaction sample
diff --git a/x-pack/plugins/apm/public/components/shared/StickyProperties/StickyProperties.test.js b/x-pack/plugins/apm/public/components/shared/StickyProperties/StickyProperties.test.js index b35069a44f2190..4cc7d9b978a400 100644 --- a/x-pack/plugins/apm/public/components/shared/StickyProperties/StickyProperties.test.js +++ b/x-pack/plugins/apm/public/components/shared/StickyProperties/StickyProperties.test.js @@ -6,9 +6,9 @@ import React from 'react'; import { StickyProperties } from './index'; -import { mount } from 'enzyme'; +import { shallow } from 'enzyme'; import { USER_ID, REQUEST_URL_FULL } from '../../../../common/constants'; -import { toJson, mockMoment } from '../../../utils/testHelpers'; +import { mockMoment } from '../../../utils/testHelpers'; describe('StickyProperties', () => { beforeEach(mockMoment); @@ -43,10 +43,10 @@ describe('StickyProperties', () => { } ]; - const wrapper = mount( + const wrapper = shallow( ); - expect(toJson(wrapper)).toMatchSnapshot(); + expect(wrapper).toMatchSnapshot(); }); }); diff --git a/x-pack/plugins/apm/public/components/shared/StickyProperties/__snapshots__/StickyProperties.test.js.snap b/x-pack/plugins/apm/public/components/shared/StickyProperties/__snapshots__/StickyProperties.test.js.snap index daefa91bbd80fa..0788f6fd759a51 100644 --- a/x-pack/plugins/apm/public/components/shared/StickyProperties/__snapshots__/StickyProperties.test.js.snap +++ b/x-pack/plugins/apm/public/components/shared/StickyProperties/__snapshots__/StickyProperties.test.js.snap @@ -1,45 +1,25 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`StickyProperties should render 1`] = ` -.c0 { - margin-bottom: 8px; - font-size: 12px; - color: #999999; -} - -.c0 span { - cursor: help; -} - -.c2 { - color: #999999; -} - -.c1 { - display: inline-block; - line-height: 16px; -} - -.c3 { - display: inline-block; - line-height: 16px; - max-width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -
-
-
- - Timestamp - -
-
- 1337 minutes ago (mocking 1536405447) - - + + @timestamp + + } + delay="regular" + position="top" > - ( - 1st of January (mocking 1536405447) - ) - -
-
-
+ Timestamp + + + + + + -
- + + context.request.url.full + + } + delay="regular" + position="top" > - URL - -
- + URL + + + + - https://www.elastic.co/test - -
-
+ https://www.elastic.co/test + + + + -
- + + context.request.method + + } + delay="regular" + position="top" > - Request method - -
-
+ + Request method + + + + GET -
-
-
+ + -
- + + error.exception.handled + + } + delay="regular" + position="top" > - Handled - -
-
+ + Handled + + + + true -
-
-
+ + -
- + + context.user.id + + } + delay="regular" + position="top" > - User ID - -
-
+ + User ID + + + + 1337 -
-
-
+ + +
`; diff --git a/x-pack/plugins/apm/public/components/shared/StickyProperties/index.js b/x-pack/plugins/apm/public/components/shared/StickyProperties/index.tsx similarity index 80% rename from x-pack/plugins/apm/public/components/shared/StickyProperties/index.js rename to x-pack/plugins/apm/public/components/shared/StickyProperties/index.tsx index 5a51ba338ad5a5..c0ef09d8ae3387 100644 --- a/x-pack/plugins/apm/public/components/shared/StickyProperties/index.js +++ b/x-pack/plugins/apm/public/components/shared/StickyProperties/index.tsx @@ -5,20 +5,28 @@ */ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiToolTip } from '@elastic/eui'; +import moment from 'moment'; import React from 'react'; import styled from 'styled-components'; -import moment from 'moment'; -import TooltipOverlay from '../../shared/TooltipOverlay'; import { - unit, - units, - px, + colors, fontFamilyCode, fontSizes, - colors, - truncate + px, + truncate, + unit, + units } from '../../../style/variables'; +export interface IStickyProperty { + val: any; + label: string; + fieldName?: string; + width?: 0 | string; + truncated?: boolean; +} + const TooltipFieldName = styled.span` font-family: ${fontFamilyCode}; `; @@ -48,16 +56,7 @@ const PropertyValueTruncated = styled.span` ${truncate('100%')}; `; -function fieldNameHelper(name) { - return ( - - Field name:
- {name} -
- ); -} - -function TimestampValue({ timestamp }) { +function TimestampValue({ timestamp }: { timestamp: Date }) { const time = moment(timestamp); const timeAgo = timestamp ? time.fromNow() : 'N/A'; const timestampFull = timestamp @@ -71,13 +70,13 @@ function TimestampValue({ timestamp }) { ); } -function getPropertyLabel({ fieldName, label }) { +function getPropertyLabel({ fieldName, label }: Partial) { if (fieldName) { return ( - + {fieldName}}> {label} - + ); } @@ -85,23 +84,31 @@ function getPropertyLabel({ fieldName, label }) { return {label}; } -function getPropertyValue({ val, fieldName, truncated = false }) { +function getPropertyValue({ + val, + fieldName, + truncated = false +}: Partial) { if (fieldName === '@timestamp') { return ; } if (truncated) { return ( - + {String(val)} - + ); } return {val}; } -export function StickyProperties({ stickyProperties }) { +export function StickyProperties({ + stickyProperties +}: { + stickyProperties: IStickyProperty[]; +}) { /** * Note: the padding and margin styles here are strange because * EUI flex groups and items have a default "gutter" applied that diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.js b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.js index 72c77caba9a345..a4b93f6693e90c 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.js +++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.js @@ -5,11 +5,12 @@ */ import React, { Component } from 'react'; +import { EuiTitle } from '@elastic/eui'; import PropTypes from 'prop-types'; import CustomPlot from '../CustomPlot'; import { asMillis, tpmUnit, asInteger } from '../../../../utils/formatters'; import styled from 'styled-components'; -import { units, unit, px, fontSizes } from '../../../../style/variables'; +import { units, unit, px } from '../../../../style/variables'; import { timefilter } from 'ui/timefilter'; import moment from 'moment'; @@ -41,11 +42,6 @@ const ChartHeader = styled.div` margin-bottom: ${px(units.half)}; `; -const ChartTitle = styled.div` - font-weight: 600; - font-size: ${fontSizes.large}; -`; - export class Charts extends Component { state = { hoverX: null @@ -92,7 +88,9 @@ export class Charts extends Component { - {responseTimeLabel(transactionType)} + +
{responseTimeLabel(transactionType)}
+
{this.props.ChartHeaderContent}
- {tpmLabel(transactionType)} + +
{tpmLabel(transactionType)}
+
{ - if (!waterfall) { + if (!waterfall || !waterfall.hits) { return; }