diff --git a/.eslintrc b/.eslintrc index 6c744eb461..8c709b599f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -21,6 +21,7 @@ /* jsx */ "jsx-a11y/no-static-element-interactions": 1, "jsx-a11y/href-no-hash": 0, + "jsx-a11y/label-has-for": 0, /* react */ "react/jsx-filename-extension": 0, diff --git a/.flowconfig b/.flowconfig index 54d2741198..cd8775744c 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,6 +1,9 @@ [ignore] +# node_module packages that have a .flowconfig in conflict with this file .*/node_modules/fbjs/.* .*/node_modules/uber-licence/.* +.*/node_modules/redux-form/.* +.*/node_modules/react-motion/.* [include] diff --git a/package.json b/package.json index a8e6e344b1..39c0593056 100644 --- a/package.json +++ b/package.json @@ -4,67 +4,67 @@ "main": "src/index.js", "license": "MIT", "proxy": "http://localhost:16686", + "homepage": null, "devDependencies": { - "babel-eslint": "^7.1.1", - "enzyme": "^2.4.1", - "eslint": "^3.16.1", - "eslint-config-airbnb": "^14.1.0", - "eslint-config-prettier": "^1.5.0", - "eslint-config-react-app": "^0.6.2", - "eslint-plugin-flowtype": "^2.21.0", - "eslint-plugin-import": "^2.2.0", - "eslint-plugin-jsx-a11y": "^4.0.0", - "eslint-plugin-react": "7.1.0", - "husky": "^0.13.3", - "lint-staged": "^3.4.0", + "babel-eslint": "^7.2.3", + "enzyme": "^2.9.1", + "eslint": "^4.5.0", + "eslint-config-airbnb": "^15.1.0", + "eslint-config-prettier": "^2.3.0", + "eslint-config-react-app": "^2.0.0", + "eslint-plugin-flowtype": "^2.35.0", + "eslint-plugin-import": "^2.7.0", + "eslint-plugin-jsx-a11y": "^6.0.2", + "eslint-plugin-react": "^7.2.1", + "husky": "^0.14.3", + "lint-staged": "^4.0.3", "prettier": "^1.5.3", - "react-scripts": "^0.9.5", - "sets-equal": "^1.0.0", - "sinon": "^1.17.5", + "react-scripts": "^1.0.11", + "react-test-renderer": "^15.6.1", + "sinon": "^3.2.1", "uber-licence": "^3.1.1" }, "dependencies": { "basscss": "^8.0.3", - "chance": "^1.0.4", - "cytoscape": "^2.7.13", - "cytoscape-dagre": "^1.3.0", - "d3-scale": "^1.0.4", + "chance": "^1.0.10", + "classnames": "^2.2.5", + "cytoscape": "^3.2.1", + "cytoscape-dagre": "^2.0.0", + "d3-scale": "^1.0.6", "dagre": "^0.7.4", - "flow-bin": "^0.36.0", - "fuzzy": "^0.1.1", - "global": "^4.3.0", + "flow-bin": "^0.53.1", + "fuzzy": "^0.1.3", + "global": "^4.3.2", + "history": "^4.6.3", "is-promise": "^2.1.0", "isomorphic-fetch": "^2.2.1", - "json-markup": "^1.0.0", - "lodash": "^4.17.2", - "moment": "^2.14.1", + "json-markup": "^1.1.0", + "lodash": "^4.17.4", + "moment": "^2.18.1", "prop-types": "^15.5.10", - "query-string": "^4.2.3", - "react": "^15.5.0", - "react-addons-perf": "^15.4.1", - "react-addons-shallow-compare": "^15.3.2", - "react-addons-test-utils": "^15.3.1", + "query-string": "^5.0.0", + "react": "^15.6.1", + "react-addons-perf": "^15.4.2", "react-dimensions": "^1.3.0", - "react-dom": "^15.5.0", - "react-ga": "^2.1.2", - "react-helmet": "^3.1.0", - "react-metrics": "^2.2.3", - "react-redux": "^4.4.5", - "react-router": "^2.7.0", - "react-router-redux": "^4.0.5", - "react-sticky": "^5.0.5", - "react-vis": "^0.6.4", - "react-vis-force": "^0.1.3", - "recompose": "^0.20.2", - "redux": "^3.5.2", - "redux-actions": "^0.11.0", - "redux-async-middleware": "0.0.0", - "redux-form": "6.3.2", - "redux-promise-middleware": "^4.0.0", - "reselect": "^2.5.3", - "semantic-ui-css": "^2.2.4", - "semantic-ui-react": "^0.58.1", - "store": "^1.3.20" + "react-dom": "^15.6.1", + "react-ga": "^2.2.0", + "react-helmet": "^5.1.3", + "react-metrics": "^2.3.2", + "react-redux": "^5.0.6", + "react-router-dom": "^4.1.2", + "react-router-redux": "5.0.0-alpha.6", + "react-vis": "^1.7.2", + "react-vis-force": "^0.3.1", + "recompose": "^0.25.0", + "redux": "^3.7.2", + "redux-actions": "^2.2.1", + "redux-async-middleware": "^0.0.0", + "redux-form": "^7.0.3", + "redux-promise-middleware": "^4.3.0", + "reselect": "^3.0.1", + "semantic-ui-css": "^2.2.12", + "semantic-ui-react": "^0.71.4", + "store": "^2.0.12" }, "scripts": { "start": "react-scripts start", diff --git a/src/api/jaeger.js b/src/api/jaeger.js index 63357c9287..266f04ad15 100644 --- a/src/api/jaeger.js +++ b/src/api/jaeger.js @@ -22,6 +22,8 @@ import fetch from 'isomorphic-fetch'; import moment from 'moment'; import queryString from 'query-string'; +import prefixUrl from '../utils/prefix-url'; + function getJSON(url, query) { return fetch(`${url}${query ? `?${queryString.stringify(query)}` : ''}`, { credentials: 'include', @@ -42,12 +44,11 @@ function getJSON(url, query) { } ); } - return response.json(); }); } -export const DEFAULT_API_ROOT = '/api/'; +export const DEFAULT_API_ROOT = prefixUrl('/api/'); export const DEFAULT_DEPENDENCY_LOOKBACK = moment.duration(1, 'weeks').asMilliseconds(); const JaegerAPI = { diff --git a/src/api/jaeger.test.js b/src/api/jaeger.test.js index 5db73918b6..5e7a854a76 100644 --- a/src/api/jaeger.test.js +++ b/src/api/jaeger.test.js @@ -23,14 +23,12 @@ import JaegerAPI from './jaeger'; const generatedTraces = traceGenerator.traces({ traces: 5 }); jest.mock('isomorphic-fetch', () => - jest.fn( - () => - new Promise(resolve => - resolve({ - status: 200, - data: () => Promise.resolve({ data: null }), - }) - ) + jest.fn(() => + Promise.resolve({ + status: 200, + data: () => Promise.resolve({ data: null }), + json: () => Promise.resolve({ data: null }), + }) ) ); diff --git a/src/components/App/App.css b/src/components/App/App.css index f16ed469d7..5981c33b50 100644 --- a/src/components/App/App.css +++ b/src/components/App/App.css @@ -1,21 +1,37 @@ +/* +Copyright (c) 2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#jaeger-ui-root { + height: 100%; +} + a { color: #11939A; } + a:hover { color: #00474E; cursor: pointer; } -.jaeger-ui--content { - padding-left: 1rem; - padding-right: 1rem; - padding-bottom: 1rem; -} - -.ui.menu.jaeger-ui--topnav { - border-radius: 0; - z-index: 1000; - padding: 5px; -} .clearfix:after { content: " "; @@ -53,10 +69,6 @@ a:hover { overflow-x: scroll; } -.overflow-x::-webkit-scrollbar { - display: none; -} - .ui.compact.table td { padding: 0.1em 0.5em; } diff --git a/src/components/App/NotFound.js b/src/components/App/NotFound.js index 70a01208a4..ebd7b64797 100644 --- a/src/components/App/NotFound.js +++ b/src/components/App/NotFound.js @@ -20,7 +20,9 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { Link } from 'react-router'; +import { Link } from 'react-router-dom'; + +import prefixUrl from '../../utils/prefix-url'; export default function NotFound({ error }) { return ( @@ -37,11 +39,11 @@ export default function NotFound({ error }) { {error &&

- {error.toString()} + {String(error)}

}
- + {'Back home'}
diff --git a/src/components/App/Page.css b/src/components/App/Page.css new file mode 100644 index 0000000000..6199b9bcbf --- /dev/null +++ b/src/components/App/Page.css @@ -0,0 +1,30 @@ +/* +Copyright (c) 2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +.jaeger-ui-page { + height: 100%; +} + +.jaeger-ui--content { + height: 100%; + padding-top: 50px; +} diff --git a/src/components/App/Page.js b/src/components/App/Page.js index d6dbdce99f..a5ae110838 100644 --- a/src/components/App/Page.js +++ b/src/components/App/Page.js @@ -21,26 +21,23 @@ import PropTypes from 'prop-types'; import React from 'react'; import Helmet from 'react-helmet'; -import { Sticky, StickyContainer } from 'react-sticky'; import TopNav from './TopNav'; +import './Page.css'; + export default function JaegerUIPage({ children }) { return ( -
- - - - - -
- {children} -
-
+
+ + +
+ {children} +
); } JaegerUIPage.propTypes = { - children: PropTypes.any, + children: PropTypes.node, }; diff --git a/src/components/App/TopNav.css b/src/components/App/TopNav.css new file mode 100644 index 0000000000..73315ece98 --- /dev/null +++ b/src/components/App/TopNav.css @@ -0,0 +1,29 @@ +/* +Copyright (c) 2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +.ui.menu.jaeger-ui--topnav { + border-radius: 0; + padding: 5px; + position: fixed; + width: 100%; + z-index: 1000; +} diff --git a/src/components/App/TopNav.js b/src/components/App/TopNav.js index 0bb68015a9..835356661b 100644 --- a/src/components/App/TopNav.js +++ b/src/components/App/TopNav.js @@ -19,18 +19,22 @@ // THE SOFTWARE. import React from 'react'; -import { Link } from 'react-router'; +import { Link } from 'react-router-dom'; + import TraceIDSearchInput from './TraceIDSearchInput'; +import prefixUrl from '../../utils/prefix-url'; + +import './TopNav.css'; const NAV_LINKS = [ { key: 'dependencies', - to: '/dependencies', + to: prefixUrl('/dependencies'), text: 'Dependencies', }, { key: 'search', - to: '/search', + to: prefixUrl('/search'), text: 'Search', }, ]; @@ -38,7 +42,7 @@ const NAV_LINKS = [ export default function TopNav() { return (