You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ea...@apache.org on 2019/11/21 12:42:12 UTC
[qpid-dispatch] branch eallen-DISPATCH-1385 updated: Latest changes
This is an automated email from the ASF dual-hosted git repository.
eallen pushed a commit to branch eallen-DISPATCH-1385
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git
The following commit(s) were added to refs/heads/eallen-DISPATCH-1385 by this push:
new 6ebfb4e Latest changes
6ebfb4e is described below
commit 6ebfb4e0a2b08add6cf9c9c4039708cb5c8692f8
Author: Ernest Allen <ea...@redhat.com>
AuthorDate: Thu Nov 21 07:41:50 2019 -0500
Latest changes
---
.gitignore | 3 +
LICENSE | 6 -
console/CMakeLists.txt | 119 +-
console/react/package.json | 33 +-
console/react/src/App.css | 26 +
console/react/src/App.js | 40 +-
console/react/src/App.test.js | 26 +-
console/react/src/DropdownMenu.test.js | 20 -
console/react/src/addressesComponent.test.js | 36 -
console/react/src/alertList.test.js | 30 -
console/react/src/amqp/connection.js | 354 --
console/react/src/brokers.ttf | 0
console/react/src/chord/chordToolbar.js | 25 +-
console/react/src/chord/chordToolbar.test.js | 19 +
console/react/src/chord/chordViewer.js | 2 +-
console/react/src/chord/chordViewer.test.js | 32 +-
console/react/src/chord/legendComponent.js | 2 +-
console/react/src/chord/optionsComponent.js | 2 +-
console/react/src/{ => common}/DropdownMenu.js | 4 +-
.../addressData.js => common/DropdownMenu.test.js} | 42 +-
.../react/src/{ => common}/addressesComponent.js | 0
.../react/src/common/addressesComponent.test.js | 50 +
console/react/src/common/amqp/connection.js | 385 ++
console/react/src/{ => common}/amqp/correlator.js | 40 +-
console/react/src/{ => common}/amqp/management.js | 35 +-
console/react/src/{ => common}/amqp/topology.js | 139 +-
console/react/src/{ => common}/amqp/utilities.js | 49 +-
console/react/src/{ => common}/connectionClose.js | 0
console/react/src/common/connectionClose.test.js | 58 +
.../contextMenu.test.js} | 44 +-
.../react/src/{ => common}/contextMenuComponent.js | 31 +-
console/react/src/{ => common}/dropdownPanel.js | 48 +-
console/react/src/common/pleaseWait.js | 58 +
console/react/src/{ => common}/qdrGlobals.js | 0
.../react/src/{updated.js => common/qdrPopup.js} | 12 +-
.../src/{updated.js => common/qdrPopup.test.js} | 31 +-
console/react/src/{ => common}/qdrService.js | 51 +-
console/react/src/{ => common}/tableToolbar.js | 0
console/react/src/common/tableToolbar.test.js | 46 +
console/react/src/{ => common}/updated.js | 0
.../src/{updated.js => common/updated.test.js} | 32 +-
console/react/src/connect.test.js | 31 -
console/react/src/{ => connect}/connect-form.js | 112 +-
console/react/src/connect/connect-form.test.js | 51 +
console/react/src/connect/connectPage.js | 100 +
.../{updated.js => connect/connectPage.test.js} | 28 +-
console/react/src/connectPage.js | 69 -
console/react/src/connectPage.test.js | 12 -
console/react/src/connectionClose.test.js | 42 -
console/react/src/contextMenu.test.js | 23 -
console/react/src/details/createTablePage.test.js | 57 +-
.../react/src/details/dataSources/addressData.js | 2 +-
.../src/details/dataSources/connectionData.js | 2 +-
.../react/src/details/dataSources/defaultData.js | 38 +-
.../react/src/{ => details}/detailsTablePage.js | 45 +-
.../addressData.js => detailsTablePage.test.js} | 39 +-
.../details/{enitiesPage.js => entitiesPage.js} | 36 +-
console/react/src/details/entitiesPage.test.js | 50 +
console/react/src/details/entityList.js | 3 +-
.../connectionData.js => entityList.test.js} | 45 +-
console/react/src/details/entityListTable.js | 16 +-
console/react/src/details/routerSelect.js | 26 +-
.../react/src/details/schema/schemaPage.test.js | 21 +-
console/react/src/details/updateTablePage.js | 91 +-
console/react/src/details/updateTablePage.test.js | 43 +-
console/react/src/detailsTablePage.test.js | 19 -
console/react/src/index.css | 13 -
console/react/src/index.js | 26 +-
console/react/src/layout.test.js | 33 -
console/react/src/notificationDrawer.test.js | 34 -
.../src/overview/dashboard/activeAddressesCard.js | 39 +-
.../src/{ => overview/dashboard}/alertList.js | 0
.../react/src/overview/dashboard/alertList.test.js | 47 +
console/react/src/overview/dashboard/chartBase.js | 72 +-
.../dashboard/{chartBase.js => chartData.js} | 63 +-
.../react/src/overview/dashboard/dashboardPage.js | 10 +-
.../src/overview/dashboard/dashboardPage.test.js | 42 +-
.../overview/dashboard/delayedDeliveriesCard.js | 55 +-
.../src/overview/dashboard/inflightChart.test.js | 40 +-
.../react/src/overview/dashboard/inflightData.js | 61 +
.../react/src/{ => overview/dashboard}/layout.js | 211 +-
.../react/src/overview/dashboard/layout.test.js | 76 +
.../{ => overview/dashboard}/notificationDrawer.js | 40 +-
.../overview/dashboard/notificationDrawer.test.js | 50 +
.../src/overview/dashboard/throughputChart.js | 18 -
.../src/overview/dashboard/throughputChart.test.js | 40 +-
.../{throughputChart.js => throughputData.js} | 23 +-
.../src/overview/dataSources/connectionData.js | 10 +-
console/react/src/overview/overviewPage.js | 2 +-
console/react/src/overview/overviewPage.test.js | 89 +-
console/react/src/overview/overviewTable.js | 16 +-
console/react/src/overview/overviewTable.test.js | 19 -
console/react/src/pleaseWait.js | 51 -
console/react/src/qdrPopup.js | 14 -
console/react/src/qdrPopup.test.js | 15 -
console/react/src/{updated.js => serviceTest.js} | 25 +-
console/react/src/serviceWorker.js | 135 -
console/react/src/setupTests.js | 22 +-
console/react/src/tableToolbar.test.js | 29 -
console/react/src/topology/clientInfoComponent.js | 2 +-
.../clientInfoDetailsComponent.js} | 22 +-
.../src/topology/clientInfoDetailsComponent.jsx | 24 -
console/react/src/topology/contextMenu.js | 2 +-
console/react/src/topology/legend.js | 42 +-
console/react/src/topology/links.js | 30 +-
console/react/src/topology/nodes.js | 2 +-
console/react/src/topology/svgUtils.js | 33 +-
console/react/src/topology/topoUtils.js | 61 +-
console/react/src/topology/topologyPage.test.js | 21 +-
console/react/src/topology/topologyToolbar.js | 31 +-
console/react/src/topology/topologyToolbar.test.js | 44 +-
console/react/src/topology/topologyViewer.js | 6 +-
console/react/src/topology/topologyViewer.test.js | 40 +-
console/react/src/topology/traffic.js | 40 +-
console/react/src/topology/trafficComponent.js | 16 +-
console/react/src/updated.test.js | 16 -
.../react/{src => test_data}/qdrService.mock.js | 12 +-
console/react/yarn.lock | 4799 ++++----------------
tests/system_test.py | 4 +-
tests/system_tests_console.py | 183 +-
120 files changed, 3658 insertions(+), 6123 deletions(-)
diff --git a/.gitignore b/.gitignore
index b4dc769..9a2c2c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,6 @@ console/stand-alone/dist/
console/stand-alone/package-lock.json
tools/qdmanage
tools/qdstat
+console/react/build/
+console/react/coverage/
+
diff --git a/LICENSE b/LICENSE
index 66380af..c620013 100644
--- a/LICENSE
+++ b/LICENSE
@@ -212,12 +212,6 @@ The following 3 files are licensed under the BSD license, for details see licens
2. console/hawtio/src/main/webapp/plugin/lib/d3.min.js
3. console/hawtio/src/main/webapp/plugin/lib/zd3-queue.min.js
-console/dispatch-dashboard/dispatch/static/dashboard/dispatch/jquery.dynatree.min.js is licensed under the MIT licence, for details see licenses/jquery.dynatree-license
-
-The following 2 files are covered by the MIT License, for details see licenses/angular-ui-license
-1. console/dispatch-dashboard/dispatch/static/dashboard/dispatch/lib/slider.js
-2. console/dispatch-dashboard/dispatch/static/dashboard/dispatch/lib/ui-grid.js
-
The following 2 files are covered by the MIT license, for details see licenses/jquery.tipsy-license
1. console/hawtio/src/main/webapp/plugin/css/jquery.tipsy.css
2. console/hawtio/src/main/webapp/plugin/lib/jquery.tipsy.js
diff --git a/console/CMakeLists.txt b/console/CMakeLists.txt
index 07b4a5f..749cff4 100644
--- a/console/CMakeLists.txt
+++ b/console/CMakeLists.txt
@@ -30,37 +30,51 @@ if(CONSOLE_INSTALL)
OUTPUT_VARIABLE NPM_VERSION)
if(NOT (${NPM_VERSION} VERSION_LESS "3.1.10"))
- set(CONSOLE_SOURCE_DIR "${CMAKE_SOURCE_DIR}/console/stand-alone")
+ set(CONSOLE_SOURCE_DIR "${CMAKE_SOURCE_DIR}/console/react")
set(CONSOLE_BUILD_DIR "${CMAKE_BINARY_DIR}/console")
## copy the build config files
configure_file( ${CONSOLE_SOURCE_DIR}/package.json ${CONSOLE_BUILD_DIR}/ COPYONLY)
- configure_file( ${CONSOLE_SOURCE_DIR}/package-lock.json ${CONSOLE_BUILD_DIR}/ COPYONLY)
- configure_file( ${CONSOLE_SOURCE_DIR}/tslint.json ${CONSOLE_BUILD_DIR}/ COPYONLY)
- configure_file( ${CONSOLE_SOURCE_DIR}/gulpfile.js ${CONSOLE_BUILD_DIR}/ COPYONLY)
- configure_file( ${CONSOLE_SOURCE_DIR}/vendor-js.txt ${CONSOLE_BUILD_DIR}/ COPYONLY)
- configure_file( ${CONSOLE_SOURCE_DIR}/vendor-css.txt ${CONSOLE_BUILD_DIR}/ COPYONLY)
-
- ## Files needed to create the ${CONSOLE_ARTIFACTS}
- file (GLOB_RECURSE CONSOLE_JS_SOURCES ${CONSOLE_SOURCE_DIR}/plugin/js/*.js)
- file (GLOB_RECURSE CONSOLE_TS_SOURCES ${CONSOLE_SOURCE_DIR}/plugin/js/*.ts)
- file (GLOB CONSOLE_TXT_SOURCES ${CONSOLE_BUILD_DIR}/vendor-*.txt)
- set(CONSOLE_CSS_SOURCE ${CONSOLE_SOURCE_DIR}/plugin/css/dispatch.css)
- set(ALL_CONSOLE_SOURCES ${CONSOLE_CSS_SOURCE} ${CONSOLE_TXT_SOURCES})
-
- ## Files created during the console build
+ configure_file( ${CONSOLE_SOURCE_DIR}/yarn.lock ${CONSOLE_BUILD_DIR}/ COPYONLY)
+
+ function(copyDirectory fromDir toDir subDir)
+ set(BASE "${fromDir}/${subDir}")
+ file (GLOB_RECURSE FILES ${BASE}/*.*)
+ foreach(ITEM ${FILES})
+ get_filename_component(ITEM_PATH ${ITEM} PATH)
+ get_filename_component(ITEM_FILE ${ITEM} NAME)
+ string(REPLACE ${BASE} "" ITEM_PATH ${ITEM_PATH})
+ #message(STATUS "from ${ITEM} to ${toDir}/${subDir}${ITEM_PATH}/${ITEM_FILE}")
+ configure_file( ${ITEM} "${toDir}/${subDir}${ITEM_PATH}/${ITEM_FILE}" COPYONLY)
+ endforeach()
+ endfunction()
+
+ # copy the files needed for the build to the build/console directory
+ # this is needed because 'npm run build' and 'npm test' create and modify
+ # files and we don't want that to happen in the source directory
+ copyDirectory(${CONSOLE_SOURCE_DIR} ${CONSOLE_BUILD_DIR} "src")
+ copyDirectory(${CONSOLE_SOURCE_DIR} ${CONSOLE_BUILD_DIR} "public")
+ copyDirectory(${CONSOLE_SOURCE_DIR} ${CONSOLE_BUILD_DIR} "test_data")
+
+ ## If any of these files change, rebuild the console
+ file (GLOB_RECURSE CONSOLE_SOURCES ${CONSOLE_SOURCE_DIR}/src/*.*)
+ file (GLOB_RECURSE CONSOLE_PUBLIC_FILES ${CONSOLE_SOURCE_DIR}/public/*.*)
+ file (GLOB_RECURSE CONSOLE_TEST_FILES ${CONSOLE_SOURCE_DIR}/test_data/*.*)
+ set(ALL_CONSOLE_SOURCES ${CONSOLE_SOURCES} ${CONSOLE_PUBLIC_FILES} ${CONSOLE_TEST_FILES})
+
+ ## If any of these files is older than the above ALL_CONSOLE_SOURCE
+ ## then rebuild the console
set(CONSOLE_ARTIFACTS
- ${CONSOLE_BUILD_DIR}/dist/js/vendor.min.js
- ${CONSOLE_BUILD_DIR}/dist/css/vendor.min.css
- ${CONSOLE_BUILD_DIR}/dist/css/dispatch.min.css
+ ${CONSOLE_BUILD_DIR}/build/index.html
+ ${CONSOLE_BUILD_DIR}/build/app.js
)
## Tell cmake how and when to build ${CONSOLE_ARTIFACTS}
add_custom_command (
OUTPUT ${CONSOLE_ARTIFACTS}
COMMENT "Running console build"
- COMMAND npm install --loglevel=error
- COMMAND ${NPM_EXECUTABLE} run build -- --src ${CONSOLE_SOURCE_DIR} --target "production"
+ COMMAND ${NPM_EXECUTABLE} install --loglevel=error
+ COMMAND ${NPM_EXECUTABLE} run build -- --target "production"
DEPENDS ${ALL_CONSOLE_SOURCES}
WORKING_DIRECTORY ${CONSOLE_BUILD_DIR}/
)
@@ -75,72 +89,11 @@ if(CONSOLE_INSTALL)
##
## Files copied to the root of the console's install dir
- set(BASE_FILES
- ${CONSOLE_SOURCE_DIR}/index.html
- ${CONSOLE_SOURCE_DIR}/main.js
- ${CONSOLE_SOURCE_DIR}/favicon-32x32.png
- ${CONSOLE_SOURCE_DIR}/config.json
- )
- ## Files copied to the img/ dir
- set(IMAGES
- ${CONSOLE_SOURCE_DIR}/plugin/img/bg-modal-about-pf.png
- ${CONSOLE_SOURCE_DIR}/plugin/img/logo-alt.svg
- ${CONSOLE_SOURCE_DIR}/plugin/img/console_logo.png
- )
- ## Files copied to the css/ dir
- set(CSS_FONTS
- ${CONSOLE_SOURCE_DIR}/plugin/css/brokers.ttf
- )
- ## Files copied to the css/fonts/ dir
- set(CSSFONTS_FONTS
- ${CONSOLE_BUILD_DIR}/node_modules/angular-ui-grid/fonts/ui-grid.woff
- ${CONSOLE_BUILD_DIR}/node_modules/angular-ui-grid/fonts/ui-grid.ttf
- )
- ## Files copied to the fonts/ dir
- set(VENDOR_FONTS
- ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-Regular-webfont.woff2
- ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-Bold-webfont.woff2
- ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-Light-webfont.woff2
- ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-Semibold-webfont.woff2
- ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-SemiboldItalic-webfont.woff2
- ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-BoldItalic-webfont.woff2
- ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/OpenSans-Italic-webfont.woff2
- ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/fontawesome-webfont.woff2
- ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/fontawesome-webfont.eot
- ${CONSOLE_BUILD_DIR}/node_modules/patternfly/dist/fonts/PatternFlyIcons-webfont.ttf
- ${CONSOLE_BUILD_DIR}/node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2
- )
-
- install(DIRECTORY ${CONSOLE_BUILD_DIR}/dist/
+ install(DIRECTORY ${CONSOLE_BUILD_DIR}/build/
DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}
PATTERN "*.map" EXCLUDE
)
- install(DIRECTORY ${CONSOLE_SOURCE_DIR}/plugin/html/
- DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}/html
- FILES_MATCHING PATTERN "*.html"
- )
- install(DIRECTORY ${CONSOLE_SOURCE_DIR}/plugin/js/
- DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}/plugin/js
- FILES_MATCHING PATTERN "*.js"
- )
- install(FILES ${BASE_FILES}
- DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}
- )
- install(FILES ${CSS_FONTS}
- DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}/css/
- )
- install(FILES ${CSSFONTS_FONTS}
- DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}/css/fonts/
- )
- install(FILES ${VENDOR_FONTS}
- DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}/fonts/
- )
- install(FILES ${IMAGES}
- DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}/img/
- )
- install(DIRECTORY ${CONSOLE_SOURCE_DIR}/plugin/data/
- DESTINATION ${CONSOLE_STAND_ALONE_INSTALL_DIR}/plugin/data
- )
+
else(NOT (${NPM_VERSION} VERSION_LESS "3.1.10"))
message(STATUS "Cannot build console. npm version 3.1.10 or greater is required.")
endif(NOT (${NPM_VERSION} VERSION_LESS "3.1.10"))
diff --git a/console/react/package.json b/console/react/package.json
index 74802e8..033aebf 100644
--- a/console/react/package.json
+++ b/console/react/package.json
@@ -4,32 +4,24 @@
"private": true,
"dependencies": {
"@patternfly/patternfly": "^2.13.0",
- "@patternfly/react-charts": "^4.1.5",
+ "@patternfly/react-charts": "^5.1.6",
"@patternfly/react-core": "^3.38.1",
"@patternfly/react-icons": "^3.10.4",
"@patternfly/react-styles": "^3.3.3",
"@patternfly/react-table": "^2.11.1",
"@patternfly/react-topology": "^2.7.31",
- "@react-mock/localstorage": "^0.1.2",
- "@testing-library/jest-dom": "^4.2.3",
- "@testing-library/react": "^9.3.2",
- "body-parser": "^1.19.0",
+ "d3": "^3.5.17",
"d3-queue": "^3.0.7",
- "eslint-plugin-patternfly-react": "^0.2.3",
"express": "^4.17.1",
- "jest-axe": "^3.2.0",
- "lodash-es": "^4.17.11",
- "patternfly-react": "^2.36.1",
- "prettier": "^1.18.2",
+ "patternfly": "^3.59.4",
"prop-types": "^15.7.2",
- "react": "^16.8.6",
- "react-dom": "^16.8.6",
+ "react": "^16.12.0",
+ "react-dom": "^16.12.0",
+ "react-fontawesome": "^1.7.1",
"react-router-dom": "^5.0.1",
- "react-scripts": "3.0.1",
- "redux": "^4.0.1",
+ "react-scripts": "^3.2.0",
"rhea": "^1.0.8",
- "topojson-client": "^3.0.1",
- "typescript": "^3.5.2"
+ "topojson-client": "^3.0.1"
},
"scripts": {
"start": "react-scripts start",
@@ -51,5 +43,14 @@
"last 1 firefox version",
"last 1 safari version"
]
+ },
+ "devDependencies": {
+ "jest-axe": "^3.2.0",
+ "eslint-plugin-patternfly-react": "^0.2.3",
+ "@react-mock/localstorage": "^0.1.2",
+ "@testing-library/jest-dom": "^4.2.3",
+ "@testing-library/react": "^9.3.2",
+ "body-parser": "^1.19.0",
+ "prettier": "^1.19.1"
}
}
diff --git a/console/react/src/App.css b/console/react/src/App.css
index a71287c..2f0581f 100644
--- a/console/react/src/App.css
+++ b/console/react/src/App.css
@@ -1,3 +1,22 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF 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.
+*/
+
#root {
height: 100vh;
}
@@ -379,6 +398,13 @@ div.state-container button.pf-c-clipboard-copy__group-copy {
letter-spacing: 0.3em;
}
+.pf-c-content h2.connect-description {
+ font-size: 16px;
+ margin-top: 2em;
+ margin-bottom: 0;
+ padding: 0;
+}
+
.overview-title::first-letter {
text-transform: uppercase;
}
diff --git a/console/react/src/App.js b/console/react/src/App.js
index d3ba9f8..dbcafa8 100644
--- a/console/react/src/App.js
+++ b/console/react/src/App.js
@@ -1,22 +1,52 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React, { Component } from "react";
+import { HashRouter as Router, Route } from "react-router-dom";
+
import "@patternfly/patternfly/patternfly.css";
import "@patternfly/patternfly/patternfly-addons.css";
import "patternfly/dist/css/patternfly.css";
import "patternfly/dist/css/patternfly-additions.css";
import "@patternfly/patternfly/components/Nav/nav.css";
-import { QDRService } from "./qdrService";
+import { QDRService } from "./common/qdrService";
import "./App.css";
-import PageLayout from "./layout";
+import PageLayout from "./overview/dashboard/layout";
class App extends Component {
state = {};
render() {
+ // service is passed in to make testing easier
const service = new QDRService();
+ // also, a router is used here to provide PageLayout with a history property
return (
- <div className="App pf-m-redhat-font">
- <PageLayout service={service} config={this.props.config} />
- </div>
+ <Router>
+ <div className="App pf-m-redhat-font">
+ <Route
+ path="/"
+ render={props => (
+ <PageLayout service={service} {...props} config={this.props.config} />
+ )}
+ />
+ </div>
+ </Router>
);
}
}
diff --git a/console/react/src/App.test.js b/console/react/src/App.test.js
index 18c16e5..3d23f5a 100644
--- a/console/react/src/App.test.js
+++ b/console/react/src/App.test.js
@@ -1,14 +1,30 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import { render } from "@testing-library/react";
-import { axe, toHaveNoViolations } from "jest-axe";
-
+import { axe } from "jest-axe";
import App from "./App";
-expect.extend(toHaveNoViolations);
-
const title = "Apache Qpid Dispatch Console";
const config = { title };
-it("renders the correct title without accessibility violations", async () => {
+it("renders the main page with the correct title and without accessibility violations", async () => {
const { container, getAllByText } = render(<App config={config} />);
const results = await axe(container);
diff --git a/console/react/src/DropdownMenu.test.js b/console/react/src/DropdownMenu.test.js
deleted file mode 100644
index 995b26d..0000000
--- a/console/react/src/DropdownMenu.test.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import React from "react";
-import { render } from '@testing-library/react';
-import DropdownMenu from "./DropdownMenu";
-
-it("the dropdown menu component renders and calls event handlers", () => {
- const isVisible = true;
- const isConnected = () => true;
- let logoutCalled = false;
- const handleDropdownLogout = () => logoutCalled = true
- let menuRef = null;
- render(
- <DropdownMenu
- ref={el => (menuRef = el)}
- isVisible={isVisible} isConnected={isConnected}
- handleDropdownLogout={handleDropdownLogout} />
- );
- menuRef.show(true)
- menuRef.logout()
- expect(logoutCalled).toBe(true)
-});
diff --git a/console/react/src/addressesComponent.test.js b/console/react/src/addressesComponent.test.js
deleted file mode 100644
index fffe287..0000000
--- a/console/react/src/addressesComponent.test.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from "react";
-import { render, fireEvent } from '@testing-library/react';
-import AddressesComponent from "./addressesComponent";
-
-it("renders the addresses component with an address", () => {
- let handleChangeAddressCalled = false;
- let handleHoverAddress = undefined;
- const props = {
- addresses: { test: true },
- addressColors: { test: "#EAEAEA" },
- handleChangeAddress: () => handleChangeAddressCalled = true,
- handleHoverAddress: (address, over) => handleHoverAddress = over
- }
- const { getByLabelText } = render(
- <AddressesComponent
- {...props} />);
- const node = getByLabelText("colored dot");
- fireEvent.click(node)
- expect(handleChangeAddressCalled).toBe(true)
- fireEvent.mouseOver(node);
- expect(handleHoverAddress).toBe(true)
- fireEvent.mouseOut(node);
- expect(handleHoverAddress).toBe(false)
-});
-
-it("renders the addresses component without an address", () => {
- const props = {
- addresses: {},
- addressColors: {},
- }
- const { getByText } = render(
- <AddressesComponent
- {...props} />);
- expect(getByText("There is no traffic")).toBeInTheDocument();
-});
-
diff --git a/console/react/src/alertList.test.js b/console/react/src/alertList.test.js
deleted file mode 100644
index f05c93d..0000000
--- a/console/react/src/alertList.test.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from "react";
-import { render } from '@testing-library/react';
-import AlertList from "./alertList";
-
-it("renders the AlertList component", () => {
- let ref = null;
- const props = {
- }
- const { getByLabelText, queryByLabelText } = render(
- <AlertList
- ref={el => (ref = el)}
- {...props} />)
- // the container should be there
- expect(getByLabelText("alert-list")).toBeInTheDocument();
- // there should be no alerts in the list to start with
- expect(queryByLabelText("alert-close-button")).toBeNull();
-
- // add an alert
- ref.addAlert("info", "testing");
- // the alert close button should now be there
- expect(getByLabelText("alert-close-button")).toBeInTheDocument();
-
- const alert = {
- key: 0
- }
- // hide the alert
- ref.hideAlert(alert);
- // the alert close button should now be gone
- expect(queryByLabelText("alert-close-button")).toBeNull();
-});
diff --git a/console/react/src/amqp/connection.js b/console/react/src/amqp/connection.js
deleted file mode 100644
index 97ff56f..0000000
--- a/console/react/src/amqp/connection.js
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Copyright 2017 Red Hat Inc.
- *
- * Licensed 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.
- */
-/* global Promise */
-import Correlator from "./correlator.js";
-
-const rhea = require("rhea");
-//import { on, websocket_connect, removeListener, once, connect } from 'rhea';
-
-class ConnectionManager {
- constructor(protocol) {
- this.sender = undefined;
- this.receiver = undefined;
- this.connection = undefined;
- this.version = undefined;
- this.errorText = undefined;
- this.protocol = protocol;
- this.schema = undefined;
- this.connectActions = [];
- this.disconnectActions = [];
- this.correlator = new Correlator();
- this.on_message = function (context) {
- this.correlator.resolve(context);
- }.bind(this);
- this.on_disconnected = function () {
- this.errorText = "Disconnected";
- this.executeDisconnectActions(this.errorText);
- }.bind(this);
- this.on_connection_open = function () {
- this.executeConnectActions();
- }.bind(this);
- }
- versionCheck(minVer) {
- var verparts = this.version.split(".");
- var minparts = minVer.split(".");
- try {
- for (var i = 0; i < minparts.length; ++i) {
- if (parseInt(minVer[i] > parseInt(verparts[i]))) return false;
- }
- } catch (e) {
- return false;
- }
- return true;
- }
- addConnectAction(action) {
- if (typeof action === "function") {
- this.delConnectAction(action);
- this.connectActions.push(action);
- }
- }
- addDisconnectAction(action) {
- if (typeof action === "function") {
- this.delDisconnectAction(action);
- this.disconnectActions.push(action);
- }
- }
- delConnectAction(action) {
- if (typeof action === "function") {
- var index = this.connectActions.indexOf(action);
- if (index >= 0) this.connectActions.splice(index, 1);
- }
- }
- delDisconnectAction(action) {
- if (typeof action === "function") {
- var index = this.disconnectActions.indexOf(action);
- if (index >= 0) this.disconnectActions.splice(index, 1);
- }
- }
- executeConnectActions() {
- this.connectActions.forEach(function (action) {
- try {
- action();
- } catch (e) {
- // in case the page that registered the handler has been unloaded
- }
- });
- this.connectActions = [];
- }
- executeDisconnectActions(message) {
- this.disconnectActions.forEach(action => {
- try {
- action(message);
- } catch (e) {
- // in case the page that registered the handler has been unloaded
- }
- });
- this.disconnectActions = [];
- }
- on(eventType, fn) {
- if (eventType === "connected") {
- this.addConnectAction(fn);
- } else if (eventType === "disconnected") {
- this.addDisconnectAction(fn);
- } else {
- console.log("unknown event type " + eventType);
- }
- }
- setSchema(schema) {
- this.schema = schema;
- }
- is_connected() {
- return (
- this.connection &&
- this.sender &&
- this.receiver &&
- this.receiver.remote &&
- this.receiver.remote.attach &&
- this.receiver.remote.attach.source &&
- this.receiver.remote.attach.source.address &&
- this.connection.is_open()
- );
- }
- disconnect() {
- if (this.sender) this.sender.close();
- if (this.receiver) this.receiver.close();
- if (this.connection) this.connection.close();
- }
- createSenderReceiver(options) {
- return new Promise(
- function (resolve, reject) {
- var timeout = options.timeout || 10000;
- // set a timer in case the setup takes too long
- var giveUp = function () {
- this.connection.removeListener("receiver_open", receiver_open);
- this.connection.removeListener("sendable", sendable);
- this.errorText = "timed out creating senders and receivers";
- reject(Error(this.errorText));
- }.bind(this);
- var timer = setTimeout(giveUp, timeout);
- // register an event hander for when the setup is complete
- var sendable = function (context) {
- clearTimeout(timer);
- this.version = this.connection.properties
- ? this.connection.properties.version
- : "0.1.0";
- // in case this connection dies
- rhea.on("disconnected", this.on_disconnected);
- // in case this connection dies and is then reconnected automatically
- rhea.on("connection_open", this.on_connection_open);
- // receive messages here
- this.connection.on("message", this.on_message);
- resolve(context);
- }.bind(this);
- this.connection.once("sendable", sendable);
- // Now actually createt the sender and receiver.
- // register an event handler for when the receiver opens
- var receiver_open = function () {
- // once the receiver is open, create the sender
- if (options.sender_address)
- this.sender = this.connection.open_sender(options.sender_address);
- else this.sender = this.connection.open_sender();
- }.bind(this);
- this.connection.once("receiver_open", receiver_open);
- // create a dynamic receiver
- this.receiver = this.connection.open_receiver({
- source: { dynamic: true }
- });
- }.bind(this)
- );
- }
- connect(options) {
- return new Promise(
- function (resolve, reject) {
- var finishConnecting = function () {
- this.createSenderReceiver(options).then(
- function (results) {
- resolve(results);
- },
- function (error) {
- reject(error);
- }
- );
- };
- if (!this.connection) {
- options.test = false; // if you didn't want a connection, you should have called testConnect() and not connect()
- this.testConnect(options).then(
- function () {
- finishConnecting.call(this);
- }.bind(this),
- function () {
- // connect failed or timed out
- this.errorText = `Unable to connect to ${options.address}:${options.port}`;
- this.executeDisconnectActions(this.errorText);
- reject(Error(this.errorText));
- }.bind(this)
- );
- } else {
- finishConnecting.call(this);
- }
- }.bind(this)
- );
- }
- getReceiverAddress() {
- return this.receiver.remote.attach.source.address;
- }
- // Try to connect using the options.
- // if options.test === true -> close the connection if it succeeded and resolve the promise
- // if the connection attempt fails or times out, reject the promise regardless of options.test
- testConnect(options, callback) {
- return new Promise(
- function (resolve, reject) {
- var timeout = options.timeout || 10000;
- var reconnect = options.reconnect || false; // in case options.reconnect is undefined
- var baseAddress = options.address + ":" + options.port;
- if (options.linkRouteAddress) {
- baseAddress += "/" + options.linkRouteAddress;
- }
- var wsprotocol = window.location.protocol === "https:" ? "wss" : "ws";
- if (this.connection) {
- delete this.connection;
- this.connection = null;
- }
- var ws = rhea.websocket_connect(WebSocket);
- var c = {
- connection_details: new ws(wsprotocol + "://" + baseAddress, [
- "binary"
- ]),
- reconnect: reconnect,
- properties: options.properties || {
- console_identifier: "Dispatch console"
- }
- };
- if (options.hostname) c.hostname = options.hostname;
- if (options.username && options.username !== "") {
- c.username = options.username;
- }
- if (options.password && options.password !== "") {
- c.password = options.password;
- }
- // set a timeout
- var disconnected = function () {
- clearTimeout(timer);
- rhea.removeListener("disconnected", disconnected);
- rhea.removeListener("connection_open", connection_open);
- this.connection = null;
- var rej = "failed to connect";
- if (callback) callback({ error: rej });
- reject(Error(rej));
- }.bind(this);
- var timer = setTimeout(disconnected, timeout);
- // the event handler for when the connection opens
- var connection_open = function (context) {
- clearTimeout(timer);
- // prevent future disconnects from calling reject
- rhea.removeListener("disconnected", disconnected);
- // we were just checking. we don't really want a connection
- if (options.test) {
- context.connection.close();
- this.connection = null;
- } else this.on_connection_open();
- var res = { context: context };
- if (callback) callback(res);
- resolve(res);
- }.bind(this);
- // register an event handler for when the connection opens
- rhea.once("connection_open", connection_open);
- // register an event handler for if the connection fails to open
- rhea.once("disconnected", disconnected);
- // attempt the connection
- this.connection = rhea.connect(c);
- }.bind(this)
- );
- }
- sendMgmtQuery(operation, to) {
- to = to || "/$management";
- return this.send([], to, operation);
- }
- sendQuery(toAddr, entity, attrs, operation) {
- operation = operation || "QUERY";
- var fullAddr = this._fullAddr(toAddr);
- var body = { attributeNames: attrs || [] };
- return this.send(
- body,
- fullAddr,
- operation,
- this.schema.entityTypes[entity].fullyQualifiedType
- );
- }
- send(body, to, operation, entityType) {
- var application_properties = {
- operation: operation,
- type: "org.amqp.management",
- name: "self"
- };
- if (entityType) application_properties.entityType = entityType;
- return this._send(body, to, application_properties);
- }
- sendMethod(toAddr, entity, attrs, operation, props) {
- var fullAddr = this._fullAddr(toAddr);
- var application_properties = {
- operation: operation
- };
- if (entity) {
- application_properties.type = this.schema.entityTypes[
- entity
- ].fullyQualifiedType;
- }
- if (attrs.name) application_properties.name = attrs.name;
- else if (attrs.identity) application_properties.identity = attrs.identity;
- if (props) {
- for (var attrname in props) {
- application_properties[attrname] = props[attrname];
- }
- }
- return this._send(attrs, fullAddr, application_properties);
- }
- _send(body, to, application_properties) {
- var _correlationId = this.correlator.corr();
- var self = this;
- return new Promise(function (resolve, reject) {
- self.correlator.register(_correlationId, resolve, reject);
- self.sender.send({
- body: body,
- to: to,
- reply_to: self.receiver.remote.attach.source.address,
- correlation_id: _correlationId,
- application_properties: application_properties
- });
- });
- }
- _fullAddr(toAddr) {
- var toAddrParts = toAddr.split("/");
- toAddrParts.shift();
- var fullAddr = toAddrParts.join("/");
- return fullAddr;
- }
- availableQeueuDepth() {
- return this.correlator.depth();
- }
-}
-
-class ConnectionException {
- constructor(message) {
- this.message = message;
- this.name = "ConnectionException";
- }
-}
-
-const _ConnectionManager = ConnectionManager;
-export { _ConnectionManager as ConnectionManager };
-const _ConnectionException = ConnectionException;
-export { _ConnectionException as ConnectionException };
diff --git a/console/react/src/brokers.ttf b/console/react/src/brokers.ttf
deleted file mode 100644
index e69de29..0000000
diff --git a/console/react/src/chord/chordToolbar.js b/console/react/src/chord/chordToolbar.js
index 4f5fc16..d2a5226 100644
--- a/console/react/src/chord/chordToolbar.js
+++ b/console/react/src/chord/chordToolbar.js
@@ -1,16 +1,35 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import { Toolbar, ToolbarGroup, ToolbarItem } from "@patternfly/react-core";
import OptionsComponent from "./optionsComponent";
import RoutersComponent from "./routersComponent";
-import DropdownPanel from "../dropdownPanel"
+import DropdownPanel from "../common/dropdownPanel";
class ChordToolbar extends React.Component {
-
render() {
return (
<Toolbar
data-testid="chord-toolbar"
- className="pf-l-toolbar pf-u-justify-content-space-between pf-u-mx-xl pf-u-my-md">
+ className="pf-l-toolbar pf-u-justify-content-space-between pf-u-mx-xl pf-u-my-md"
+ >
<ToolbarGroup>
<ToolbarItem className="pf-u-mr-md">
<DropdownPanel
diff --git a/console/react/src/chord/chordToolbar.test.js b/console/react/src/chord/chordToolbar.test.js
index bb53359..793fa65 100644
--- a/console/react/src/chord/chordToolbar.test.js
+++ b/console/react/src/chord/chordToolbar.test.js
@@ -1,3 +1,22 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import { render, fireEvent } from "@testing-library/react";
import ChordToolbar from "./chordToolbar";
diff --git a/console/react/src/chord/chordViewer.js b/console/react/src/chord/chordViewer.js
index b2ad22e..0d2c177 100644
--- a/console/react/src/chord/chordViewer.js
+++ b/console/react/src/chord/chordViewer.js
@@ -25,7 +25,7 @@ import { ChordData } from "./data.js";
import { qdrRibbon } from "./ribbon/ribbon.js";
import { qdrlayoutChord } from "./layout/layout.js";
import ChordToolbar from "./chordToolbar";
-import QDRPopup from "../qdrPopup";
+import QDRPopup from "../common/qdrPopup";
import * as d3 from "d3";
const CHORDOPTIONSKEY = "chordOptions";
diff --git a/console/react/src/chord/chordViewer.test.js b/console/react/src/chord/chordViewer.test.js
index 76e9265..2de8fa0 100644
--- a/console/react/src/chord/chordViewer.test.js
+++ b/console/react/src/chord/chordViewer.test.js
@@ -1,13 +1,39 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import { render, fireEvent, waitForElement } from "@testing-library/react";
-import { mockService } from "../qdrService.mock";
-import ChordViewer from "./chordViewer";
+import { service, login, TEST_PORT } from "../serviceTest";
import { LocalStorageMock } from "@react-mock/localstorage";
+import ChordViewer from "./chordViewer";
it("renders the ChordViewer component", async () => {
const props = {
- service: mockService({})
+ service
};
+
+ if (!TEST_PORT) {
+ console.log("using mock service");
+ }
+ await login();
+ expect(service.management.connection.is_connected()).toBe(true);
+
const { getByLabelText } = render(
<LocalStorageMock
items={{
diff --git a/console/react/src/chord/legendComponent.js b/console/react/src/chord/legendComponent.js
index 9ad75ac..0736984 100644
--- a/console/react/src/chord/legendComponent.js
+++ b/console/react/src/chord/legendComponent.js
@@ -26,7 +26,7 @@ import {
} from "@patternfly/react-core";
import OptionsComponent from "./optionsComponent";
import RoutersComponent from "./routersComponent";
-import AddressesComponent from "../addressesComponent";
+import AddressesComponent from "../common/addressesComponent";
class LegendComponent extends Component {
constructor(props) {
diff --git a/console/react/src/chord/optionsComponent.js b/console/react/src/chord/optionsComponent.js
index c7d920c..4e674dc 100644
--- a/console/react/src/chord/optionsComponent.js
+++ b/console/react/src/chord/optionsComponent.js
@@ -19,7 +19,7 @@ under the License.
import React, { Component } from "react";
import { Checkbox } from "@patternfly/react-core";
-import AddressesComponent from "../addressesComponent";
+import AddressesComponent from "../common/addressesComponent";
class OptionsComponent extends Component {
constructor(props) {
diff --git a/console/react/src/DropdownMenu.js b/console/react/src/common/DropdownMenu.js
similarity index 94%
rename from console/react/src/DropdownMenu.js
rename to console/react/src/common/DropdownMenu.js
index c51df43..30b0db7 100644
--- a/console/react/src/DropdownMenu.js
+++ b/console/react/src/common/DropdownMenu.js
@@ -25,9 +25,7 @@ class DropdownMenu extends Component {
super(props);
this.state = {
isVisible:
- typeof this.props.isVisible !== "undefined"
- ? this.props.isVisible
- : false
+ typeof this.props.isVisible !== "undefined" ? this.props.isVisible : false
};
this.contextMenuItems = [
{
diff --git a/console/react/src/details/dataSources/addressData.js b/console/react/src/common/DropdownMenu.test.js
similarity index 56%
copy from console/react/src/details/dataSources/addressData.js
copy to console/react/src/common/DropdownMenu.test.js
index 13c7e97..4442441 100644
--- a/console/react/src/details/dataSources/addressData.js
+++ b/console/react/src/common/DropdownMenu.test.js
@@ -18,28 +18,24 @@ under the License.
*/
import React from "react";
-import DefaultData from "./defaultData";
-import { utils } from "../../amqp/utilities";
+import { render } from "@testing-library/react";
+import DropdownMenu from "./DropdownMenu";
-const AddressType = ({ value, extraInfo }) => {
- const data = extraInfo.rowData.data;
- const identity = utils.identity_clean(data.identity);
- const cls = utils.addr_class(identity);
-
- return (
- <span className="entity-type">
- <i className={`address-${cls}`}></i>
- {cls}
- </span>
+it("the dropdown menu component renders and calls event handlers", () => {
+ const isVisible = true;
+ const isConnected = () => true;
+ let logoutCalled = false;
+ const handleDropdownLogout = () => (logoutCalled = true);
+ let menuRef = null;
+ render(
+ <DropdownMenu
+ ref={el => (menuRef = el)}
+ isVisible={isVisible}
+ isConnected={isConnected}
+ handleDropdownLogout={handleDropdownLogout}
+ />
);
-};
-
-class AddressData extends DefaultData {
- constructor(service, schema) {
- super(service, schema);
- this.typeFormatter = AddressType;
- this.detailName = "router.address";
- }
-}
-
-export default AddressData;
+ menuRef.show(true);
+ menuRef.logout();
+ expect(logoutCalled).toBe(true);
+});
diff --git a/console/react/src/addressesComponent.js b/console/react/src/common/addressesComponent.js
similarity index 100%
rename from console/react/src/addressesComponent.js
rename to console/react/src/common/addressesComponent.js
diff --git a/console/react/src/common/addressesComponent.test.js b/console/react/src/common/addressesComponent.test.js
new file mode 100644
index 0000000..291b861
--- /dev/null
+++ b/console/react/src/common/addressesComponent.test.js
@@ -0,0 +1,50 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import React from "react";
+import { render, fireEvent } from "@testing-library/react";
+import AddressesComponent from "./addressesComponent";
+
+it("renders the addresses component with an address", () => {
+ let handleChangeAddressCalled = false;
+ let handleHoverAddress = undefined;
+ const props = {
+ addresses: { test: true },
+ addressColors: { test: "#EAEAEA" },
+ handleChangeAddress: () => (handleChangeAddressCalled = true),
+ handleHoverAddress: (address, over) => (handleHoverAddress = over)
+ };
+ const { getByLabelText } = render(<AddressesComponent {...props} />);
+ const node = getByLabelText("colored dot");
+ fireEvent.click(node);
+ expect(handleChangeAddressCalled).toBe(true);
+ fireEvent.mouseOver(node);
+ expect(handleHoverAddress).toBe(true);
+ fireEvent.mouseOut(node);
+ expect(handleHoverAddress).toBe(false);
+});
+
+it("renders the addresses component without an address", () => {
+ const props = {
+ addresses: {},
+ addressColors: {}
+ };
+ const { getByText } = render(<AddressesComponent {...props} />);
+ expect(getByText("There is no traffic")).toBeInTheDocument();
+});
diff --git a/console/react/src/common/amqp/connection.js b/console/react/src/common/amqp/connection.js
new file mode 100644
index 0000000..bd8e3c0
--- /dev/null
+++ b/console/react/src/common/amqp/connection.js
@@ -0,0 +1,385 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF 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 Correlator from "./correlator";
+import rhea from "rhea";
+
+class ConnectionManager {
+ constructor(protocol) {
+ this.rhea = rhea;
+ this.sender = undefined;
+ this.receiver = undefined;
+ this.connection = undefined;
+ this.version = undefined;
+ this.errorText = undefined;
+ this.protocol = protocol;
+ this.schema = undefined;
+ this.connectActions = [];
+ this.disconnectActions = [];
+ this.correlator = new Correlator();
+ this.on_message = context => {
+ this.correlator.resolve(context);
+ };
+ this.on_disconnected = () => {
+ this.errorText = "Disconnected";
+ this.executeDisconnectActions(this.errorText);
+ };
+ this.on_connection_open = () => {
+ this.executeConnectActions();
+ };
+ }
+ versionCheck = minVer => {
+ var verparts = this.version.split(".");
+ var minparts = minVer.split(".");
+ try {
+ for (var i = 0; i < minparts.length; ++i) {
+ if (parseInt(minVer[i] > parseInt(verparts[i]))) return false;
+ }
+ } catch (e) {
+ return false;
+ }
+ return true;
+ };
+ addConnectAction = action => {
+ if (typeof action === "function") {
+ this.delConnectAction(action);
+ this.connectActions.push(action);
+ }
+ };
+ addDisconnectAction = action => {
+ if (typeof action === "function") {
+ this.delDisconnectAction(action);
+ this.disconnectActions.push(action);
+ }
+ };
+ delConnectAction = action => {
+ if (typeof action === "function") {
+ var index = this.connectActions.indexOf(action);
+ if (index >= 0) this.connectActions.splice(index, 1);
+ }
+ };
+ delDisconnectAction = action => {
+ if (typeof action === "function") {
+ var index = this.disconnectActions.indexOf(action);
+ if (index >= 0) this.disconnectActions.splice(index, 1);
+ }
+ };
+ executeConnectActions = () => {
+ this.connectActions.forEach(action => {
+ try {
+ action();
+ } catch (e) {
+ // in case the page that registered the handler has been unloaded
+ }
+ });
+ this.connectActions = [];
+ };
+ executeDisconnectActions = message => {
+ this.disconnectActions.forEach(action => {
+ try {
+ action(message);
+ } catch (e) {
+ // in case the page that registered the handler has been unloaded
+ }
+ });
+ this.disconnectActions = [];
+ };
+ on = (eventType, fn) => {
+ if (eventType === "connected") {
+ this.addConnectAction(fn);
+ } else if (eventType === "disconnected") {
+ this.addDisconnectAction(fn);
+ } else {
+ console.log("unknown event type " + eventType);
+ }
+ };
+ setSchema = schema => {
+ this.schema = schema;
+ };
+ is_connected = () => {
+ return (
+ this.connection &&
+ this.sender &&
+ this.receiver &&
+ this.receiver.remote &&
+ this.receiver.remote.attach &&
+ this.receiver.remote.attach.source &&
+ this.receiver.remote.attach.source.address &&
+ this.connection.is_open()
+ );
+ };
+ disconnect = () => {
+ if (this.sender) this.sender.close();
+ if (this.receiver) this.receiver.close();
+ if (this.connection) {
+ this.connection.close();
+ this.connection = null;
+ }
+ };
+ restrict = (count, f) => {
+ if (count) {
+ var current = count;
+ var reset;
+ return successful_attempts => {
+ if (reset !== successful_attempts) {
+ current = count;
+ reset = successful_attempts;
+ }
+ if (current--) return f(successful_attempts);
+ else return -1;
+ };
+ } else {
+ return f;
+ }
+ };
+
+ backoff = (initial, max) => {
+ var delay = initial;
+ var reset;
+ return successful_attempts => {
+ if (reset !== successful_attempts) {
+ delay = initial;
+ reset = successful_attempts;
+ }
+ var current = delay;
+ var next = delay * 2;
+ delay = max > next ? next : max;
+ return current;
+ };
+ };
+
+ setReconnect = reconnect => {
+ if (this.connection) {
+ if (reconnect) {
+ var initial = this.connection.get_option("initial_reconnect_delay", 100);
+ var max = this.connection.get_option("max_reconnect_delay", 60000);
+ this.connection.options.reconnect = this.restrict(
+ this.connection.get_option("reconnect_limit"),
+ this.backoff(initial, max)
+ );
+ } else {
+ this.connection.options.reconnect = false;
+ }
+ }
+ };
+
+ createSenderReceiver = options => {
+ return new Promise((resolve, reject) => {
+ var timeout = options.timeout || 10000;
+ // set a timer in case the setup takes too long
+ var giveUp = () => {
+ this.connection.removeListener("receiver_open", receiver_open);
+ this.connection.removeListener("sendable", sendable);
+ this.errorText = "timed out creating senders and receivers";
+ reject(Error(this.errorText));
+ };
+ var timer = setTimeout(giveUp, timeout);
+ // register an event hander for when the setup is complete
+ var sendable = context => {
+ clearTimeout(timer);
+ this.version = this.connection.properties
+ ? this.connection.properties.version
+ : "0.1.0";
+ // in case this connection dies
+ this.rhea.on("disconnected", this.on_disconnected);
+ // in case this connection dies and is then reconnected automatically
+ this.rhea.on("connection_open", this.on_connection_open);
+ // receive messages here
+ this.connection.on("message", this.on_message);
+ resolve(context);
+ };
+ this.connection.once("sendable", sendable);
+ // Now actually createt the sender and receiver.
+ // register an event handler for when the receiver opens
+ var receiver_open = () => {
+ // once the receiver is open, create the sender
+ if (options.sender_address)
+ this.sender = this.connection.open_sender(options.sender_address);
+ else this.sender = this.connection.open_sender();
+ };
+ this.connection.once("receiver_open", receiver_open);
+ // create a dynamic receiver
+ this.receiver = this.connection.open_receiver({
+ source: { dynamic: true }
+ });
+ });
+ };
+
+ connect = options => {
+ return new Promise((resolve, reject) => {
+ var finishConnecting = () => {
+ this.createSenderReceiver(options).then(
+ results => {
+ resolve(results);
+ },
+ error => {
+ reject(error);
+ }
+ );
+ };
+ if (!this.is_connected()) {
+ this.doConnect(options).then(
+ () => {
+ finishConnecting.call(this);
+ },
+ () => {
+ // connect failed or timed out
+ this.disconnect();
+ this.errorText = `Unable to connect to ${options.address}:${options.port}`;
+ this.executeDisconnectActions(this.errorText);
+ reject(Error(this.errorText));
+ }
+ );
+ } else {
+ console.log("called connect when already connected");
+ finishConnecting.call(this);
+ }
+ });
+ };
+ getReceiverAddress = () => {
+ return this.receiver.remote.attach.source.address;
+ };
+
+ doConnect = options => {
+ return new Promise((resolve, reject) => {
+ var timeout = options.timeout || 10000;
+ var reconnect = options.reconnect || false; // in case options.reconnect is undefined
+ var baseAddress = options.address + ":" + options.port;
+ if (options.linkRouteAddress) {
+ baseAddress += "/" + options.linkRouteAddress;
+ }
+ var wsprotocol = window.location.protocol === "https:" ? "wss" : "ws";
+ var ws = this.rhea.websocket_connect(WebSocket);
+ var c = {
+ connection_details: new ws(wsprotocol + "://" + baseAddress, ["binary"]),
+ reconnect: reconnect,
+ properties: options.properties || {
+ console_identifier: "Dispatch console"
+ }
+ };
+ if (options.hostname) c.hostname = options.hostname;
+ if (options.username && options.username !== "") {
+ c.username = options.username;
+ }
+ if (options.password && options.password !== "") {
+ c.password = options.password;
+ }
+ // set a timeout
+ var timedOut = () => {
+ clearTimeout(timer);
+ this.rhea.removeListener("disconnected", timedOut);
+ this.rhea.removeListener("connection_open", connection_open);
+ //this.connection = null;
+ var rej = "failed to connect";
+ reject(Error(rej));
+ };
+ var timer = setTimeout(timedOut, timeout);
+ // the event handler for when the connection opens
+ var connection_open = context => {
+ clearTimeout(timer);
+ // prevent future disconnects from calling reject
+ this.rhea.removeListener("disconnected", timedOut);
+ this.on_connection_open();
+ resolve({ context: context });
+ };
+ // register an event handler for when the connection opens
+ this.rhea.once("connection_open", connection_open);
+ // register an event handler for if the connection fails to open
+ this.rhea.once("disconnected", timedOut);
+ // attempt the connection
+ this.connection = this.rhea.connect(c);
+ });
+ };
+ sendMgmtQuery = (operation, to) => {
+ to = to || "/$management";
+ return this.send([], to, operation);
+ };
+ sendQuery = (toAddr, entity, attrs, operation) => {
+ operation = operation || "QUERY";
+ var fullAddr = this._fullAddr(toAddr);
+ var body = { attributeNames: attrs || [] };
+ return this.send(
+ body,
+ fullAddr,
+ operation,
+ this.schema.entityTypes[entity].fullyQualifiedType
+ );
+ };
+ send = (body, to, operation, entityType) => {
+ var application_properties = {
+ operation: operation,
+ type: "org.amqp.management",
+ name: "self"
+ };
+ if (entityType) application_properties.entityType = entityType;
+ return this._send(body, to, application_properties);
+ };
+ sendMethod = (toAddr, entity, attrs, operation, props) => {
+ var fullAddr = this._fullAddr(toAddr);
+ var application_properties = {
+ operation: operation
+ };
+ if (entity) {
+ application_properties.type = this.schema.entityTypes[entity].fullyQualifiedType;
+ }
+ if (attrs.name) application_properties.name = attrs.name;
+ else if (attrs.identity) application_properties.identity = attrs.identity;
+ if (props) {
+ for (var attrname in props) {
+ application_properties[attrname] = props[attrname];
+ }
+ }
+ return this._send(attrs, fullAddr, application_properties);
+ };
+ _send = (body, to, application_properties) => {
+ var _correlationId = this.correlator.corr();
+ var self = this;
+ return new Promise((resolve, reject) => {
+ self.correlator.register(_correlationId, resolve, reject);
+ self.sender.send({
+ body: body,
+ to: to,
+ reply_to: self.receiver.remote.attach.source.address,
+ correlation_id: _correlationId,
+ application_properties: application_properties
+ });
+ });
+ };
+ _fullAddr = toAddr => {
+ var toAddrParts = toAddr.split("/");
+ toAddrParts.shift();
+ var fullAddr = toAddrParts.join("/");
+ return fullAddr;
+ };
+ availableQeueuDepth = () => {
+ return this.correlator.depth();
+ };
+}
+
+class ConnectionException {
+ constructor(message) {
+ this.message = message;
+ this.name = "ConnectionException";
+ }
+}
+
+const _ConnectionManager = ConnectionManager;
+export { _ConnectionManager as ConnectionManager };
+const _ConnectionException = ConnectionException;
+export { _ConnectionException as ConnectionException };
diff --git a/console/react/src/amqp/correlator.js b/console/react/src/common/amqp/correlator.js
similarity index 51%
rename from console/react/src/amqp/correlator.js
rename to console/react/src/common/amqp/correlator.js
index bf34f93..c9f3e99 100644
--- a/console/react/src/amqp/correlator.js
+++ b/console/react/src/common/amqp/correlator.js
@@ -1,20 +1,23 @@
/*
- * Copyright 2017 Red Hat Inc.
- *
- * Licensed 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.
- */
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF 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
-import { utils } from './utilities.js';
+ 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 { utils } from "./utilities";
class Correlator {
constructor() {
@@ -23,7 +26,7 @@ class Correlator {
this.maxCorrelatorDepth = 10;
}
corr() {
- return ++(this._correlationID) + '';
+ return ++this._correlationID + "";
}
// Associate this correlation id with the promise's resolve and reject methods
register(id, resolve, reject) {
@@ -34,7 +37,10 @@ class Correlator {
resolve(context) {
var correlationID = context.message.correlation_id;
// call the promise's resolve function with a copy of the rhea response (so we don't keep any references to internal rhea data)
- this._objects[correlationID].resolver({ response: utils.copy(context.message.body), context: context });
+ this._objects[correlationID].resolver({
+ response: utils.copy(context.message.body),
+ context: context
+ });
delete this._objects[correlationID];
}
reject(id, error) {
diff --git a/console/react/src/amqp/management.js b/console/react/src/common/amqp/management.js
similarity index 67%
rename from console/react/src/amqp/management.js
rename to console/react/src/common/amqp/management.js
index 19ca359..6711da6 100644
--- a/console/react/src/amqp/management.js
+++ b/console/react/src/common/amqp/management.js
@@ -1,20 +1,21 @@
/*
- * Copyright 2015 Red Hat Inc.
- *
- * Licensed 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.
- */
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF 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
-/* global Promise */
+ 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 { ConnectionManager } from "./connection.js";
import Topology from "./topology.js";
@@ -45,9 +46,7 @@ export class Management {
var attribute = entity.attributes[attributeName];
if (attribute.deprecated) {
// deprecated attribute
- delete response.entityTypes[entityName].attributes[
- attributeName
- ];
+ delete response.entityTypes[entityName].attributes[attributeName];
}
}
}
diff --git a/console/react/src/amqp/topology.js b/console/react/src/common/amqp/topology.js
similarity index 85%
rename from console/react/src/amqp/topology.js
rename to console/react/src/common/amqp/topology.js
index 98b03da..c0ca63e 100644
--- a/console/react/src/amqp/topology.js
+++ b/console/react/src/common/amqp/topology.js
@@ -1,18 +1,21 @@
/*
- * Copyright 2015 Red Hat Inc.
- *
- * Licensed 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.
- */
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF 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 { utils } from "./utilities.js";
@@ -103,9 +106,7 @@ class Topology {
// check for changed number of connections
if (entity === "connection") {
const oldConnections =
- this._nodeInfo &&
- this._nodeInfo[rId] &&
- this._nodeInfo[rId].connection
+ this._nodeInfo && this._nodeInfo[rId] && this._nodeInfo[rId].connection
? this._nodeInfo[rId].connection.results.length
: 0;
const newConnections = workInfo[rId].connection.results.length;
@@ -146,9 +147,7 @@ class Topology {
this.connection.sendMgmtQuery("GET-MGMT-NODES").then(
function(results) {
let routerIds = results.response;
- if (
- Object.prototype.toString.call(routerIds) === "[object Array]"
- ) {
+ if (Object.prototype.toString.call(routerIds) === "[object Array]") {
// if there is only one node, it will not be returned
if (routerIds.length === 0) {
var parts = this.connection.getReceiverAddress().split("/");
@@ -190,29 +189,26 @@ class Topology {
// test for edge case
let routerId = connectedToEdge(routerIds, workInfo);
if (routerId) {
- this.connection
- .sendMgmtQuery("GET-MGMT-NODES", routerId)
- .then(
- function(results) {
- let response = results.response;
- if (
- Object.prototype.toString.call(response) ===
- "[object Array]"
- ) {
- // special case of edge case:
- // we are connected to an edge router that is connected to
- // a router that is not connected to any other interior routers
- if (response.length === 0) {
- response = [routerId];
- }
- this.doget(response).then(
- function(workInfo) {
- finish.call(this, workInfo);
- }.bind(this)
- );
+ this.connection.sendMgmtQuery("GET-MGMT-NODES", routerId).then(
+ function(results) {
+ let response = results.response;
+ if (
+ Object.prototype.toString.call(response) === "[object Array]"
+ ) {
+ // special case of edge case:
+ // we are connected to an edge router that is connected to
+ // a router that is not connected to any other interior routers
+ if (response.length === 0) {
+ response = [routerId];
}
- }.bind(this)
- );
+ this.doget(response).then(
+ function(workInfo) {
+ finish.call(this, workInfo);
+ }.bind(this)
+ );
+ }
+ }.bind(this)
+ );
} else {
finish.call(this, workInfo);
}
@@ -290,25 +286,14 @@ class Topology {
results = response;
};
var q = queue(this.connection.availableQeueuDepth());
- q.defer(
- this.q_fetchNodeInfo.bind(this),
- node,
- entity,
- attrs,
- q,
- gotResponse
- );
+ q.defer(this.q_fetchNodeInfo.bind(this), node, entity, attrs, q, gotResponse);
q.await(function() {
callback(node, entity, results);
});
}
// called from queue.defer so the last argument (callback) is supplied by d3
q_fetchNodeInfo(nodeId, entity, attrs, q, heartbeat, callback) {
- this.getNodeInfo(nodeId, entity, attrs, q, function(
- nodeName,
- dotentity,
- response
- ) {
+ this.getNodeInfo(nodeId, entity, attrs, q, function(nodeName, dotentity, response) {
heartbeat(nodeName, dotentity, response);
callback(null);
});
@@ -380,12 +365,7 @@ class Topology {
}
// enusre all the topology nones have all these entities
ensureAllEntities(entityAttribs, callback, extra) {
- this.ensureEntities(
- Object.keys(this._nodeInfo),
- entityAttribs,
- callback,
- extra
- );
+ this.ensureEntities(Object.keys(this._nodeInfo), entityAttribs, callback, extra);
}
// ensure these nodes have all these entities. don't fetch unless forced to
ensureEntities(nodes, entityAttribs, callback, extra) {
@@ -508,9 +488,7 @@ class Topology {
response.response.results.length === 0 &&
Object.keys(self._nodeInfo).length === 1
) {
- response.response.results = [
- self.getSingelRouterNode(nodeName, attrs)
- ];
+ response.response.results = [self.getSingelRouterNode(nodeName, attrs)];
}
callback(nodeName, entity, response.response);
},
@@ -519,14 +497,7 @@ class Topology {
}
);
}
- getMultipleNodeInfo(
- nodeNames,
- entity,
- attrs,
- callback,
- selectedNodeId,
- aggregate
- ) {
+ getMultipleNodeInfo(nodeNames, entity, attrs, callback, selectedNodeId, aggregate) {
var self = this;
if (typeof aggregate === "undefined") aggregate = true;
var responses = {};
@@ -535,24 +506,11 @@ class Topology {
};
var q = queue(this.connection.availableQeueuDepth());
nodeNames.forEach(function(id) {
- q.defer(
- self.q_fetchNodeInfo.bind(self),
- id,
- entity,
- attrs,
- q,
- gotNodesResult
- );
+ q.defer(self.q_fetchNodeInfo.bind(self), id, entity, attrs, q, gotNodesResult);
});
q.await(function() {
if (aggregate)
- self.aggregateNodeInfo(
- nodeNames,
- entity,
- selectedNodeId,
- responses,
- callback
- );
+ self.aggregateNodeInfo(nodeNames, entity, selectedNodeId, responses, callback);
else {
callback(nodeNames, entity, responses);
}
@@ -563,12 +521,7 @@ class Topology {
adminStatus: "disabled",
name: name
};
- return this.connection.sendMethod(
- nodeId,
- "router.link",
- attributes,
- "UPDATE"
- );
+ return this.connection.sendMethod(nodeId, "router.link", attributes, "UPDATE");
}
aggregateNodeInfo(nodeNames, entity, selectedNodeId, responses, callback) {
// aggregate the responses
diff --git a/console/react/src/amqp/utilities.js b/console/react/src/common/amqp/utilities.js
similarity index 86%
rename from console/react/src/amqp/utilities.js
rename to console/react/src/common/amqp/utilities.js
index 30e4ec8..61073c2 100644
--- a/console/react/src/amqp/utilities.js
+++ b/console/react/src/common/amqp/utilities.js
@@ -1,18 +1,21 @@
/*
- * Copyright 2018 Red Hat Inc.
- *
- * Licensed 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.
- */
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
import * as d3 from "d3";
@@ -26,23 +29,19 @@ var utils = {
});
},
isConsole: function(d) {
- return (
- d &&
- d.properties &&
- d.properties.console_identifier === "Dispatch console"
- );
+ return d && d.properties && d.properties.console_identifier === "Dispatch console";
},
isArtemis: function(d) {
return (
(d.nodeType === "route-container" || d.nodeType === "on-demand") &&
- (d.properties && d.properties.product === "apache-activemq-artemis")
+ d.properties && d.properties.product === "apache-activemq-artemis"
);
},
isQpid: function(d) {
return (
(d.nodeType === "route-container" || d.nodeType === "on-demand") &&
- (d.properties && d.properties.product === "qpid-cpp")
+ d.properties && d.properties.product === "qpid-cpp"
);
},
@@ -51,8 +50,7 @@ var utils = {
if (d.container) name = d.container;
if (d.properties) {
if (d.properties.product) name = d.properties.product;
- else if (d.properties.console_identifier)
- name = d.properties.console_identifier;
+ else if (d.properties.console_identifier) name = d.properties.console_identifier;
else if (d.properties.name) name = d.properties.name;
}
return name;
@@ -223,10 +221,7 @@ var utils = {
},
uuidv4: function() {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
- (
- c ^
- (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
- ).toString(16)
+ (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
);
},
getUrlParts: function(fullUrl) {
diff --git a/console/react/src/connectionClose.js b/console/react/src/common/connectionClose.js
similarity index 100%
rename from console/react/src/connectionClose.js
rename to console/react/src/common/connectionClose.js
diff --git a/console/react/src/common/connectionClose.test.js b/console/react/src/common/connectionClose.test.js
new file mode 100644
index 0000000..e381932
--- /dev/null
+++ b/console/react/src/common/connectionClose.test.js
@@ -0,0 +1,58 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import React from "react";
+import { render, fireEvent } from "@testing-library/react";
+import ConnectionClose from "./connectionClose";
+import { mockService } from "../../test_data/qdrService.mock";
+
+it("renders the ConnectionClose component", () => {
+ let sendMethodCalled = false;
+ let handleAddNotificationCalled = false;
+ let notifyClickCalled = false;
+
+ const props = {
+ service: mockService({ onSendMethod: () => (sendMethodCalled = true) }),
+ handleAddNotification: () => (handleAddNotificationCalled = true),
+ notifyClick: () => (notifyClickCalled = true),
+ extraInfo: { rowData: { data: { name: "test record", role: "normal" } } }
+ };
+ const { getByLabelText, queryByLabelText } = render(<ConnectionClose {...props} />);
+
+ // the close button should be there
+ const closeButton = getByLabelText("connection-close-button");
+ expect(closeButton).toBeInTheDocument();
+
+ // the confirmation dialog should not be there
+ expect(queryByLabelText("connection-close-modal")).toBeNull();
+
+ // clicking the close button should display the confirmation dialog
+ fireEvent.click(closeButton);
+ expect(getByLabelText("connection-close-modal")).toBeInTheDocument();
+
+ const confirmButton = getByLabelText("connection-close-confirm");
+ expect(confirmButton).toBeInTheDocument();
+ fireEvent.click(confirmButton);
+
+ expect(sendMethodCalled).toBe(true);
+ setTimeout(() => {
+ expect(handleAddNotificationCalled).toBe(true);
+ expect(notifyClickCalled).toBe(true);
+ }, 1);
+});
diff --git a/console/react/src/details/dataSources/connectionData.js b/console/react/src/common/contextMenu.test.js
similarity index 51%
copy from console/react/src/details/dataSources/connectionData.js
copy to console/react/src/common/contextMenu.test.js
index 2271434..3fabf0c 100644
--- a/console/react/src/details/dataSources/connectionData.js
+++ b/console/react/src/common/contextMenu.test.js
@@ -18,33 +18,23 @@ under the License.
*/
import React from "react";
-import DefaultData from "./defaultData";
-import ConnectionClose from "../../connectionClose";
+import { render, fireEvent } from "@testing-library/react";
+import ContextMenu from "./contextMenuComponent";
-class ConnectionData extends DefaultData {
- constructor(service, schema) {
- super(service, schema);
- this.extraFields = [
- {
- title: "",
- field: "connection",
- noSort: true,
- formatter: ConnectionClose
- }
- ];
- this.detailEntity = "router.link";
- this.detailName = "Link";
- }
-
- detailActions = (entity, props, record) => {
- return (
- <ConnectionClose
- asButton={true}
- extraInfo={{ rowData: { data: record } }}
- {...props}
- />
- );
+it("the contextMenu component renders and calls event handlers", () => {
+ let handleContextHideClicked = false;
+ let itemActionCalled = false;
+ const props = {
+ handleContextHide: () => (handleContextHideClicked = true),
+ menuItems: [{ enabled: () => true, action: () => (itemActionCalled = true) }],
+ contextEventData: {},
+ contextEventPosition: [-1, -1]
};
-}
+ const { getByLabelText } = render(<ContextMenu {...props} />);
+ const menuItem = getByLabelText("context-menu-item");
+ expect(menuItem).toBeInTheDocument();
-export default ConnectionData;
+ fireEvent.click(menuItem);
+ expect(handleContextHideClicked).toBe(true);
+ expect(itemActionCalled).toBe(true);
+});
diff --git a/console/react/src/contextMenuComponent.js b/console/react/src/common/contextMenuComponent.js
similarity index 57%
rename from console/react/src/contextMenuComponent.js
rename to console/react/src/common/contextMenuComponent.js
index d85516c..b021ff0 100644
--- a/console/react/src/contextMenuComponent.js
+++ b/console/react/src/common/contextMenuComponent.js
@@ -1,3 +1,22 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
class ContextMenuComponent extends React.Component {
@@ -31,10 +50,8 @@ class ContextMenuComponent extends React.Component {
render() {
const menuItems = this.props.menuItems.map((item, i) => {
let className = `menu-item${
- item.endGroup || i === this.props.menuItems.length - 1
- ? " separator"
- : ""
- } ${item.enabled(this.props.contextEventData) ? "" : " disabled"}`;
+ item.endGroup || i === this.props.menuItems.length - 1 ? " separator" : ""
+ } ${item.enabled(this.props.contextEventData) ? "" : " disabled"}`;
return (
<li
@@ -53,9 +70,9 @@ class ContextMenuComponent extends React.Component {
const style =
this.props.contextEventPosition[0] >= 0
? {
- left: `${this.props.contextEventPosition[0]}px`,
- top: `${this.props.contextEventPosition[1]}px`
- }
+ left: `${this.props.contextEventPosition[0]}px`,
+ top: `${this.props.contextEventPosition[1]}px`
+ }
: {};
return (
<ul
diff --git a/console/react/src/dropdownPanel.js b/console/react/src/common/dropdownPanel.js
similarity index 51%
rename from console/react/src/dropdownPanel.js
rename to console/react/src/common/dropdownPanel.js
index f2ab1ff..c34ca1c 100644
--- a/console/react/src/dropdownPanel.js
+++ b/console/react/src/common/dropdownPanel.js
@@ -1,5 +1,29 @@
-import React from 'react';
-import { Accordion, AccordionItem, AccordionContent, AccordionToggle } from '@patternfly/react-core';
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import React from "react";
+import {
+ Accordion,
+ AccordionItem,
+ AccordionContent,
+ AccordionToggle
+} from "@patternfly/react-core";
class DropdownPanel extends React.Component {
constructor(props) {
@@ -25,24 +49,20 @@ class DropdownPanel extends React.Component {
close = () => {
this.setState({ expanded: false });
- }
+ };
onToggle = () => {
if (this.state.expanded) {
this.close();
} else {
- this.setState({ expanded: true })
+ this.setState({ expanded: true });
}
};
render() {
return (
- <div
- ref={el => (this.accordionRef = el)}
- >
- <Accordion
- className="dropdown-panel-accordion"
- asDefinitionList>
+ <div ref={el => (this.accordionRef = el)}>
+ <Accordion className="dropdown-panel-accordion" asDefinitionList>
<AccordionItem>
<AccordionToggle
id={this.props.title}
@@ -53,12 +73,8 @@ class DropdownPanel extends React.Component {
>
{this.props.title}
</AccordionToggle>
- <AccordionContent
- isHidden={!this.state.expanded}
- >
- <div className="options-panel pf-u-box-shadow-md">
- {this.props.panel}
- </div>
+ <AccordionContent isHidden={!this.state.expanded}>
+ <div className="options-panel pf-u-box-shadow-md">{this.props.panel}</div>
</AccordionContent>
</AccordionItem>
</Accordion>
diff --git a/console/react/src/common/pleaseWait.js b/console/react/src/common/pleaseWait.js
new file mode 100644
index 0000000..0b63e96
--- /dev/null
+++ b/console/react/src/common/pleaseWait.js
@@ -0,0 +1,58 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import React from "react";
+import { TextContent, Text, TextVariants } from "@patternfly/react-core";
+import PropTypes from "prop-types";
+
+import { CogIcon } from "@patternfly/react-icons";
+
+class PleaseWait extends React.Component {
+ static propTypes = {
+ isOpen: PropTypes.bool.isRequired,
+ title: PropTypes.string.isRequired,
+ message: PropTypes.string.isRequired
+ };
+
+ state = {};
+
+ render() {
+ return (
+ this.props.isOpen && (
+ <div className="topic-creating-wrapper">
+ <div id="topicCogWrapper">
+ <CogIcon id="topicCogMain" className="spinning-clockwise" color="#AAAAAA" />
+ <CogIcon id="topicCogUpper" className="spinning-cclockwise" color="#AAAAAA" />
+ <CogIcon id="topicCogLower" className="spinning-cclockwise" color="#AAAAAA" />
+ </div>
+ <TextContent>
+ <Text component={TextVariants.p}>{this.props.title}</Text>
+ </TextContent>
+ <TextContent>
+ <Text className="topic-creating-message" component={TextVariants.p}>
+ {this.props.message}
+ </Text>
+ </TextContent>
+ </div>
+ )
+ );
+ }
+}
+
+export default PleaseWait;
diff --git a/console/react/src/qdrGlobals.js b/console/react/src/common/qdrGlobals.js
similarity index 100%
rename from console/react/src/qdrGlobals.js
rename to console/react/src/common/qdrGlobals.js
diff --git a/console/react/src/updated.js b/console/react/src/common/qdrPopup.js
similarity index 73%
copy from console/react/src/updated.js
copy to console/react/src/common/qdrPopup.js
index e762d8e..091ae54 100644
--- a/console/react/src/updated.js
+++ b/console/react/src/common/qdrPopup.js
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
under the License.
*/
-import React, { Component } from "react";
+import React from "react";
-class Updated extends Component {
+class QDRPopup extends React.Component {
constructor(props) {
super(props);
this.state = {};
@@ -27,13 +27,9 @@ class Updated extends Component {
render() {
return (
- <pre aria-label="last-updated" data-pf-content="true" className="overview-loading">
- {`Updated ${this.props.service.utilities.strDate(
- this.props.lastUpdated
- )}`}
- </pre>
+ <div aria-label="popup" dangerouslySetInnerHTML={{ __html: this.props.content }} />
);
}
}
-export default Updated;
+export default QDRPopup;
diff --git a/console/react/src/updated.js b/console/react/src/common/qdrPopup.test.js
similarity index 63%
copy from console/react/src/updated.js
copy to console/react/src/common/qdrPopup.test.js
index e762d8e..0068397 100644
--- a/console/react/src/updated.js
+++ b/console/react/src/common/qdrPopup.test.js
@@ -17,23 +17,16 @@ specific language governing permissions and limitations
under the License.
*/
-import React, { Component } from "react";
+import React from "react";
+import { render } from "@testing-library/react";
+import QDRPopup from "./qdrPopup";
-class Updated extends Component {
- constructor(props) {
- super(props);
- this.state = {};
- }
-
- render() {
- return (
- <pre aria-label="last-updated" data-pf-content="true" className="overview-loading">
- {`Updated ${this.props.service.utilities.strDate(
- this.props.lastUpdated
- )}`}
- </pre>
- );
- }
-}
-
-export default Updated;
+it("the popup component renders HTML", () => {
+ const text = "Hello world";
+ const props = {
+ content: `<h1>${text}</h1>`
+ };
+ const { getByText, getByLabelText } = render(<QDRPopup {...props} />);
+ expect(getByLabelText("popup")).toBeInTheDocument();
+ expect(getByText("Hello world")).toBeInTheDocument();
+});
diff --git a/console/react/src/qdrService.js b/console/react/src/common/qdrService.js
similarity index 78%
rename from console/react/src/qdrService.js
rename to console/react/src/common/qdrService.js
index 8adcff8..d1387c7 100644
--- a/console/react/src/qdrService.js
+++ b/console/react/src/common/qdrService.js
@@ -24,35 +24,35 @@ import { utils } from "./amqp/utilities.js";
const DEFAULT_INTERVAL = 5000;
export class QDRService {
constructor(hooks) {
- const url = utils.getUrlParts(window.location);
- this.management = new dm(url.protocol, DEFAULT_INTERVAL);
this.utilities = utils;
this.hooks = hooks;
this.schema = null;
+ this.initManagement();
}
- setHooks = (hooks) => {
+ initManagement = () => {
+ const url = utils.getUrlParts(window.location);
+ this.management = new dm(url.protocol, DEFAULT_INTERVAL);
+ };
+ setHooks = hooks => {
this.hooks = hooks;
- }
+ };
- onReconnect() {
- this.management.connection.on("disconnected", this.onDisconnect.bind(this));
+ onReconnect = () => {
+ this.management.connection.on("disconnected", this.onDisconnect);
this.hooks.setLocation("reconnect");
- }
- onDisconnect() {
+ };
+ onDisconnect = () => {
this.hooks.setLocation("disconnect");
- this.management.connection.on("connected", this.onReconnect.bind(this));
- }
- connect(connectOptions) {
+ this.management.connection.on("connected", this.onReconnect);
+ };
+ connect = connectOptions => {
let self = this;
return new Promise((resolve, reject) => {
self.management.connection.connect(connectOptions).then(
r => {
// if we are ever disconnected, show the connect page and wait for a reconnect
- self.management.connection.on(
- "disconnected",
- this.onDisconnect.bind(this)
- );
+ self.management.connection.on("disconnected", this.onDisconnect);
self.management.getSchema().then(schema => {
self.schema = schema;
@@ -72,19 +72,20 @@ export class QDRService {
}
);
});
- }
- disconnect() {
+ };
+ disconnect = () => {
this.management.connection.disconnect();
delete this.management;
- const url = utils.getUrlParts(window.location);
- this.management = new dm(url.protocol, DEFAULT_INTERVAL);
- }
+ this.initManagement();
+ };
+
+ setReconnect = reconnect => {
+ this.management.connection.setReconnect(reconnect);
+ };
}
-(function () {
- console.dump = function (o) {
- if (window.JSON && window.JSON.stringify)
- console.log(JSON.stringify(o, undefined, 2));
- else console.log(o);
+(function() {
+ console.dump = function(o) {
+ console.log(JSON.stringify(o, undefined, 2));
};
})();
diff --git a/console/react/src/tableToolbar.js b/console/react/src/common/tableToolbar.js
similarity index 100%
rename from console/react/src/tableToolbar.js
rename to console/react/src/common/tableToolbar.js
diff --git a/console/react/src/common/tableToolbar.test.js b/console/react/src/common/tableToolbar.test.js
new file mode 100644
index 0000000..aba4745
--- /dev/null
+++ b/console/react/src/common/tableToolbar.test.js
@@ -0,0 +1,46 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import React from "react";
+import { render, fireEvent } from "@testing-library/react";
+import TableToolbar from "./tableToolbar";
+
+it("should render tableToolbar", () => {
+ let handleChangeFilterValueCalled = false;
+ const props = {
+ fields: [{ title: "field0" }, { title: "field1" }],
+ filterBy: { value: "f" },
+ handleChangeFilterValue: () => (handleChangeFilterValueCalled = true),
+ total: 2,
+ page: 1,
+ perPage: 1,
+ onSetPage: () => {},
+ onPerPageSelect: () => {}
+ };
+ const { getByLabelText } = render(<TableToolbar {...props} />);
+ expect(getByLabelText("toolbar-pagination")).toBeInTheDocument();
+ const filterInput = getByLabelText("search text input");
+ expect(filterInput).toBeInTheDocument();
+
+ fireEvent.change(filterInput, { target: { value: "fi" } });
+ expect(handleChangeFilterValueCalled).toBe(true);
+
+ const paginationInput = getByLabelText("Current page");
+ expect(paginationInput).toBeInTheDocument();
+});
diff --git a/console/react/src/updated.js b/console/react/src/common/updated.js
similarity index 100%
copy from console/react/src/updated.js
copy to console/react/src/common/updated.js
diff --git a/console/react/src/updated.js b/console/react/src/common/updated.test.js
similarity index 63%
copy from console/react/src/updated.js
copy to console/react/src/common/updated.test.js
index e762d8e..885affb 100644
--- a/console/react/src/updated.js
+++ b/console/react/src/common/updated.test.js
@@ -17,23 +17,17 @@ specific language governing permissions and limitations
under the License.
*/
-import React, { Component } from "react";
+import React from "react";
+import { render } from "@testing-library/react";
+import { QDRService } from "../common/qdrService";
+import Updated from "./updated";
-class Updated extends Component {
- constructor(props) {
- super(props);
- this.state = {};
- }
-
- render() {
- return (
- <pre aria-label="last-updated" data-pf-content="true" className="overview-loading">
- {`Updated ${this.props.service.utilities.strDate(
- this.props.lastUpdated
- )}`}
- </pre>
- );
- }
-}
-
-export default Updated;
+it("should render the Updated component", () => {
+ const service = new QDRService(() => {});
+ const props = {
+ lastUpdated: new Date(),
+ service
+ };
+ const { getByLabelText } = render(<Updated {...props} />);
+ expect(getByLabelText("last-updated")).toBeInTheDocument();
+});
diff --git a/console/react/src/connect.test.js b/console/react/src/connect.test.js
deleted file mode 100644
index 8208e74..0000000
--- a/console/react/src/connect.test.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import React from "react";
-import { render } from '@testing-library/react';
-import ConnectForm from "./connect-form";
-import { QDRService } from "./qdrService";
-
-it("can create a service object", () => {
- const service = new QDRService(() => { });
-});
-
-it("renders the connect form", () => {
- render(
- <ConnectForm />
- );
-});
-
-it("connect form can be submitted", () => {
- let connectFormRef = null;
- const service = new QDRService(() => { });
- const handleConnect = (fromPath, r) => { };
- const handleAddNotification = (section, message, date, severity) => { }
- render(
- <ConnectForm
- ref={el => (connectFormRef = el)}
- service={service}
- handleConnect={handleConnect}
- handleAddNotification={handleAddNotification}
- fromPath={"/test"}
- />
- );
- connectFormRef.handleConnect();
-});
diff --git a/console/react/src/connect-form.js b/console/react/src/connect/connect-form.js
similarity index 61%
rename from console/react/src/connect-form.js
rename to console/react/src/connect/connect-form.js
index 009af85..e19d85a 100644
--- a/console/react/src/connect-form.js
+++ b/console/react/src/connect/connect-form.js
@@ -1,18 +1,22 @@
/*
- * Copyright 2019 Red Hat Inc.
- *
- * Licensed 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.
- */
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import {
Form,
@@ -24,7 +28,7 @@ import {
Text,
TextVariants
} from "@patternfly/react-core";
-import PleaseWait from "./pleaseWait";
+import PleaseWait from "../common/pleaseWait";
const CONNECT_KEY = "QDRSettings";
class ConnectForm extends React.Component {
@@ -37,7 +41,8 @@ class ConnectForm extends React.Component {
username: "",
password: "",
connecting: false,
- connectError: null
+ connectError: null,
+ isValid: false
};
}
@@ -55,18 +60,38 @@ class ConnectForm extends React.Component {
savedValues = JSON.parse(savedValues);
savedValues.connectError = null;
}
- this.setState(savedValues);
+ this.setState(savedValues, () => {
+ this.setState({ isValid: this.validate() });
+ });
+ document.addEventListener("keypress", this.handleKeyPress);
+ this.validate();
};
+ componentWillUnmount() {
+ document.removeEventListener("keypress", this.handleKeyPress);
+ }
+
+ handleKeyPress = event => {
+ if (this.validate()) {
+ if (event.code === "Enter") {
+ this.handleConnect();
+ }
+ }
+ };
+
+ validate = () => this.state.address !== "" && this.state.port !== "";
+
handleTextInputChange = (field, value) => {
const formValues = Object.assign(this.state);
formValues[field] = value;
this.setState(formValues, () => {
- const state2Save = JSON.parse(JSON.stringify(formValues));
- // don't save the password
- state2Save.password = "";
- state2Save.connectError = null;
- localStorage.setItem(CONNECT_KEY, JSON.stringify(state2Save));
+ this.setState({ isValid: this.validate() }, () => {
+ const state2Save = JSON.parse(JSON.stringify(formValues));
+ // don't save the password
+ state2Save.password = "";
+ state2Save.connectError = null;
+ localStorage.setItem(CONNECT_KEY, JSON.stringify(state2Save));
+ });
});
};
@@ -78,9 +103,9 @@ class ConnectForm extends React.Component {
const connectOptions = JSON.parse(JSON.stringify(this.state));
if (connectOptions.username === "") connectOptions.username = undefined;
if (connectOptions.password === "") connectOptions.password = undefined;
- connectOptions.reconnect = true;
this.setState({ connecting: true }, () => {
+ connectOptions.reconnect = true;
this.props.service.connect(connectOptions).then(
r => {
this.setState({ connecting: false });
@@ -88,6 +113,7 @@ class ConnectForm extends React.Component {
},
e => {
console.log(e);
+ this.props.service.setReconnect(false);
this.setState({ connecting: false, connectError: e.message });
this.props.handleAddNotification(
"action",
@@ -106,11 +132,19 @@ class ConnectForm extends React.Component {
};
render() {
- const { address, port, username, password, connecting, connectError } = this.state;
+ const {
+ address,
+ port,
+ username,
+ password,
+ connecting,
+ connectError,
+ isValid
+ } = this.state;
return this.props.isConnectFormOpen ? (
<div>
<div className="connect-modal">
- <div className={connecting ? "connecting" : ""}>
+ <div className={this.props.connecting || connecting ? "connecting" : ""}>
<Form isHorizontal>
<TextContent className="connect-title">
<Text component={TextVariants.h1}>Connect</Text>
@@ -118,7 +152,11 @@ class ConnectForm extends React.Component {
Enter the address and an HTTP-enabled port of a qpid dispatch router.
</Text>
</TextContent>
- <FormGroup label="Address" isRequired fieldId={`form-address-${this.props.prefix}`}>
+ <FormGroup
+ label="Address"
+ isRequired
+ fieldId={`form-address-${this.props.prefix}`}
+ >
<TextInput
value={address}
isRequired
@@ -129,7 +167,11 @@ class ConnectForm extends React.Component {
onChange={value => this.handleTextInputChange("address", value)}
/>
</FormGroup>
- <FormGroup label="Port" isRequired fieldId={`form-port-${this.props.prefix}`}>
+ <FormGroup
+ label="Port"
+ isRequired
+ fieldId={`form-port-${this.props.prefix}`}
+ >
<TextInput
value={port}
onChange={value => this.handleTextInputChange("port", value)}
@@ -163,19 +205,27 @@ class ConnectForm extends React.Component {
</TextContent>
)}
<ActionGroup>
- <Button variant="primary" data-testid="connect-button" onClick={this.handleConnect}>
+ <Button
+ variant={this.props.isConnected || isValid ? "primary" : "danger"}
+ isDisabled={this.props.isConnected ? false : !isValid}
+ data-testid="connect-button"
+ onClick={this.handleConnect}
+ >
{this.props.isConnected ? "Disconnect" : "Connect"}
</Button>
<Button variant="secondary" onClick={this.toggleDrawerHide}>
Cancel
</Button>
+ <input type="submit" style={{ display: "none" }} />
</ActionGroup>
</Form>
</div>
<PleaseWait
- isOpen={connecting}
- title="Connecting"
- message="Connecting to the router, please wait..."
+ isOpen={this.props.connecting || connecting}
+ title={this.props.connectingTitle || "Connecting"}
+ message={
+ this.props.connectingMessage || "Connecting to the router, please wait..."
+ }
/>
</div>
</div>
diff --git a/console/react/src/connect/connect-form.test.js b/console/react/src/connect/connect-form.test.js
new file mode 100644
index 0000000..ba1eb1e
--- /dev/null
+++ b/console/react/src/connect/connect-form.test.js
@@ -0,0 +1,51 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import React from "react";
+import { render, fireEvent } from "@testing-library/react";
+import ConnectForm from "./connect-form";
+import { service, login, TEST_PORT } from "../serviceTest";
+
+it("renders the connect form", () => {
+ render(<ConnectForm />);
+});
+
+it("connect form can be submitted", async () => {
+ const props = {
+ service,
+ handleConnect: (section, message, date, severity) => {},
+ handleConnectCancel: () => {},
+ handleAddNotification: () => {},
+ fromPath: "/test",
+ prefix: "test",
+ isConnectFormOpen: true,
+ isConnected: false,
+ connecting: false
+ };
+
+ const { getByLabelText, getByTestId } = render(<ConnectForm {...props} />);
+
+ // fill out the form
+ fireEvent.change(getByLabelText(/address/i), { target: { value: "localhost" } });
+ fireEvent.change(getByLabelText(/port/i), {
+ target: { value: TEST_PORT || 5673 }
+ });
+
+ fireEvent.click(getByTestId("connect-button"));
+});
diff --git a/console/react/src/connect/connectPage.js b/console/react/src/connect/connectPage.js
new file mode 100644
index 0000000..dda2034
--- /dev/null
+++ b/console/react/src/connect/connectPage.js
@@ -0,0 +1,100 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import React from "react";
+import {
+ PageSection,
+ PageSectionVariants,
+ TextContent,
+ Text
+} from "@patternfly/react-core";
+import ConnectForm from "./connect-form";
+
+class ConnectPage extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = { showForm: true };
+ }
+
+ handleConnectCancel = () => {
+ this.setState({ showForm: false });
+ };
+
+ shouldComponentUpdate = (nextProps, nextState) => {
+ if (nextState.showForm !== this.state.showForm) return true;
+ const nextPathname =
+ nextProps.location && nextProps.location.state && nextProps.location.state.pathname
+ ? nextProps.location.state.pathname
+ : undefined;
+ const currentPathname =
+ this.props.location &&
+ this.props.location.state &&
+ this.props.location.state.pathname
+ ? this.props.location.state.pathname
+ : undefined;
+
+ return nextPathname !== currentPathname;
+ };
+
+ render() {
+ const { showForm } = this.state;
+ const { from } = this.props.location.state || { from: { pathname: "/" } };
+ return (
+ <PageSection variant={PageSectionVariants.light} className="connect-page">
+ {showForm ? (
+ <ConnectForm
+ prefix="form"
+ service={this.props.service}
+ handleConnect={this.props.handleConnect}
+ handleConnectCancel={this.handleConnectCancel}
+ handleAddNotification={this.props.handleAddNotification}
+ fromPath={from.pathname}
+ isConnectFormOpen={true}
+ connecting={this.props.connecting}
+ connectingTitle={this.props.connectingTitle}
+ connectingMessage={this.props.connectingMessage}
+ isConnected={false}
+ />
+ ) : (
+ <React.Fragment />
+ )}
+ <div className="left-content">
+ <TextContent>
+ <Text component="h1" className="console-banner">
+ {this.props.config.title}
+ </Text>
+ </TextContent>
+ <TextContent>
+ <Text component="h2" className="connect-description">
+ The console displays information about a qpid dispatch router network. It
+ allows monitoring and management control of the router's entities.
+ </Text>
+ <Text component="h2" className="connect-description">
+ The console only provides limited information about the clients that are
+ attached to the router network and is therfore more appropriate for
+ administrators needing to know the layout and health of the router network.
+ </Text>
+ </TextContent>
+ </div>
+ </PageSection>
+ );
+ }
+}
+
+export default ConnectPage;
diff --git a/console/react/src/updated.js b/console/react/src/connect/connectPage.test.js
similarity index 62%
copy from console/react/src/updated.js
copy to console/react/src/connect/connectPage.test.js
index e762d8e..4396eed 100644
--- a/console/react/src/updated.js
+++ b/console/react/src/connect/connectPage.test.js
@@ -17,23 +17,13 @@ specific language governing permissions and limitations
under the License.
*/
-import React, { Component } from "react";
+import React from "react";
+import { render } from "@testing-library/react";
+import ConnectPage from "./connectPage";
-class Updated extends Component {
- constructor(props) {
- super(props);
- this.state = {};
- }
-
- render() {
- return (
- <pre aria-label="last-updated" data-pf-content="true" className="overview-loading">
- {`Updated ${this.props.service.utilities.strDate(
- this.props.lastUpdated
- )}`}
- </pre>
- );
- }
-}
-
-export default Updated;
+it("renders the connect page", () => {
+ const locationState = { location: { state: { pathname: "/fromTest", from: "/test" } } };
+ const config = { title: "Qpid Dispatch Router Test Console" };
+ const { getByText } = render(<ConnectPage config={config} location={locationState} />);
+ expect(getByText(config.title)).toBeInTheDocument();
+});
diff --git a/console/react/src/connectPage.js b/console/react/src/connectPage.js
deleted file mode 100644
index 724c3f7..0000000
--- a/console/react/src/connectPage.js
+++ /dev/null
@@ -1,69 +0,0 @@
-import React from "react";
-import { PageSection, PageSectionVariants, TextContent, Text } from "@patternfly/react-core";
-import ConnectForm from "./connect-form";
-
-class ConnectPage extends React.Component {
- constructor(props) {
- super(props);
- this.state = { showForm: true };
- }
-
- handleConnectCancel = () => {
- this.setState({ showForm: false });
- };
-
- shouldComponentUpdate = (nextProps, nextState) => {
- if (nextState.showForm !== this.state.showForm) return true;
- const nextPathname =
- nextProps.location && nextProps.location.state && nextProps.location.state.pathname
- ? nextProps.location.state.pathname
- : undefined;
- const currentPathname =
- this.props.location && this.props.location.state && this.props.location.state.pathname
- ? this.props.location.state.pathname
- : undefined;
-
- return nextPathname !== currentPathname;
- };
-
- render() {
- const { showForm } = this.state;
- const { from } = this.props.location.state || { from: { pathname: "/" } };
- return (
- <React.Fragment>
- <PageSection variant={PageSectionVariants.light} className="connect-page">
- {showForm ? (
- <ConnectForm
- prefix="form"
- service={this.props.service}
- handleConnect={this.props.handleConnect}
- handleConnectCancel={this.handleConnectCancel}
- handleAddNotification={this.props.handleAddNotification}
- fromPath={from.pathname}
- isConnectFormOpen={true}
- />
- ) : (
- <React.Fragment />
- )}
- <div className="left-content">
- <TextContent>
- <Text component="h1" className="console-banner">
- {this.props.config.title}
- </Text>
- </TextContent>
- <TextContent>
- <Text component="p">
- The console is an HTML based web site that displays information about a qpid
- dispatch router network. The console only provides limited information about the
- clients that are attached to the router network and is therfore more appropriate for
- administrators needing to know the layout and health of the router network.
- </Text>
- </TextContent>
- </div>
- </PageSection>
- </React.Fragment>
- );
- }
-}
-
-export default ConnectPage;
diff --git a/console/react/src/connectPage.test.js b/console/react/src/connectPage.test.js
deleted file mode 100644
index 878a06e..0000000
--- a/console/react/src/connectPage.test.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from "react";
-import { render } from '@testing-library/react';
-import ConnectPage from "./connectPage";
-
-it("renders the connect page", () => {
- const locationState = { location: { state: { pathname: "/fromTest", from: "/test" } } }
- const config = { title: "Qpid Dispatch Router Test Console" }
- const { getByText } = render(
- <ConnectPage config={config} location={locationState} />
- );
- expect(getByText(config.title)).toBeInTheDocument();
-});
diff --git a/console/react/src/connectionClose.test.js b/console/react/src/connectionClose.test.js
deleted file mode 100644
index 06f8e8b..0000000
--- a/console/react/src/connectionClose.test.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from "react";
-import { render, fireEvent } from '@testing-library/react';
-import ConnectionClose from "./connectionClose";
-import { mockService } from "./qdrService.mock";
-
-it("renders the ConnectionClose component", () => {
- let sendMethodCalled = false;
- let handleAddNotificationCalled = false;
- let notifyClickCalled = false;
-
- const props = {
- service: mockService({ onSendMethod: () => sendMethodCalled = true }),
- handleAddNotification: () => handleAddNotificationCalled = true,
- notifyClick: () => notifyClickCalled = true,
- extraInfo: { rowData: { data: { name: "test record", role: "normal" } } }
- }
- const { getByLabelText, queryByLabelText } = render(
- <ConnectionClose {...props} />
- )
-
- // the close button should be there
- const closeButton = getByLabelText("connection-close-button");
- expect(closeButton).toBeInTheDocument();
-
- // the confirmation dialog should not be there
- expect(queryByLabelText("connection-close-modal")).toBeNull();
-
- // clicking the close button should display the confirmation dialog
- fireEvent.click(closeButton);
- expect(getByLabelText("connection-close-modal")).toBeInTheDocument();
-
- const confirmButton = getByLabelText("connection-close-confirm");
- expect(confirmButton).toBeInTheDocument();
- fireEvent.click(confirmButton);
-
- expect(sendMethodCalled).toBe(true);
- setTimeout(() => {
- expect(handleAddNotificationCalled).toBe(true);
- expect(notifyClickCalled).toBe(true);
- }, 1);
-
-});
diff --git a/console/react/src/contextMenu.test.js b/console/react/src/contextMenu.test.js
deleted file mode 100644
index 121f765..0000000
--- a/console/react/src/contextMenu.test.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import React from "react";
-import { render, fireEvent } from '@testing-library/react';
-import ContextMenu from "./contextMenuComponent"
-
-it("the contextMenu component renders and calls event handlers", () => {
- let handleContextHideClicked = false;
- let itemActionCalled = false;
- const props = {
- handleContextHide: () => handleContextHideClicked = true,
- menuItems: [{ enabled: () => true, action: () => itemActionCalled = true }],
- contextEventData: {},
- contextEventPosition: [-1, -1]
- }
- const { getByLabelText } = render(
- <ContextMenu {...props} />
- );
- const menuItem = getByLabelText("context-menu-item");
- expect(menuItem).toBeInTheDocument();
-
- fireEvent.click(menuItem);
- expect(handleContextHideClicked).toBe(true);
- expect(itemActionCalled).toBe(true);
-});
diff --git a/console/react/src/details/createTablePage.test.js b/console/react/src/details/createTablePage.test.js
index 0f3cc8c..09c51ea 100644
--- a/console/react/src/details/createTablePage.test.js
+++ b/console/react/src/details/createTablePage.test.js
@@ -1,28 +1,54 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
-import { render, fireEvent } from '@testing-library/react';
+import { render, fireEvent, waitForElement } from "@testing-library/react";
import CreateTablePage from "./createTablePage";
-import { mockService } from "../qdrService.mock";
+import { service, login, TEST_PORT } from "../serviceTest";
-it('renders a CreateTablePage', () => {
- let sendMethodCalled = false;
- const service = mockService({ onSendMethod: () => sendMethodCalled = true });
+it("renders a CreateTablePage", async () => {
+ if (!TEST_PORT) {
+ console.log("using mock service");
+ }
+ await login();
+ expect(service.management.connection.is_connected()).toBe(true);
+
+ const listenerName = "testListener";
const props = {
entity: "listener",
service,
schema: service.schema,
locationState: {},
routerId: Object.keys(service.management.topology._nodeInfo)[0],
- handleAddNotification: () => { },
- handleActionCancel: () => { }
- }
- const {
- getByLabelText,
- getByText
- } = render(<CreateTablePage {...props} />);
+ handleAddNotification: () => {},
+ handleActionCancel: () => {}
+ };
+ const { getByLabelText, getByText, getByTestId } = render(
+ <CreateTablePage {...props} />
+ );
// the create form should be present
- const notificationIcon = getByLabelText("create-entity-form");
- expect(notificationIcon).toBeInTheDocument();
+ const createForm = getByLabelText("create-entity-form");
+ expect(createForm).toBeInTheDocument();
+
+ // add a listener name
+ fireEvent.change(getByLabelText(/name/i), { target: { value: listenerName } });
// there should be a create button
const createButton = getByText("Create");
@@ -30,5 +56,4 @@ it('renders a CreateTablePage', () => {
// clicking the create button should submit the method
fireEvent.click(createButton);
- expect(sendMethodCalled).toBe(true);
-})
\ No newline at end of file
+});
diff --git a/console/react/src/details/dataSources/addressData.js b/console/react/src/details/dataSources/addressData.js
index 13c7e97..a0e0f0f 100644
--- a/console/react/src/details/dataSources/addressData.js
+++ b/console/react/src/details/dataSources/addressData.js
@@ -19,7 +19,7 @@ under the License.
import React from "react";
import DefaultData from "./defaultData";
-import { utils } from "../../amqp/utilities";
+import { utils } from "../../common/amqp/utilities";
const AddressType = ({ value, extraInfo }) => {
const data = extraInfo.rowData.data;
diff --git a/console/react/src/details/dataSources/connectionData.js b/console/react/src/details/dataSources/connectionData.js
index 2271434..b906960 100644
--- a/console/react/src/details/dataSources/connectionData.js
+++ b/console/react/src/details/dataSources/connectionData.js
@@ -19,7 +19,7 @@ under the License.
import React from "react";
import DefaultData from "./defaultData";
-import ConnectionClose from "../../connectionClose";
+import ConnectionClose from "../../common/connectionClose";
class ConnectionData extends DefaultData {
constructor(service, schema) {
diff --git a/console/react/src/details/dataSources/defaultData.js b/console/react/src/details/dataSources/defaultData.js
index 6e4b401..d448d1d 100644
--- a/console/react/src/details/dataSources/defaultData.js
+++ b/console/react/src/details/dataSources/defaultData.js
@@ -18,7 +18,7 @@ under the License.
*/
import React from "react";
-import { utils } from "../../amqp/utilities";
+import { utils } from "../../common/amqp/utilities";
import DeleteEntity from "../deleteEntity";
import UpdateEntity from "../updateEntity";
import CreateEntity from "../createEntity";
@@ -38,14 +38,7 @@ class DefaultData {
schemaOperations = entity => this.schema.entityTypes[entity].operations;
// emit a single button/component
- entityAction = ({
- component: Component,
- props,
- record,
- click,
- i,
- asButton
- }) => (
+ entityAction = ({ component: Component, props, record, click, i, asButton }) => (
<Component
key={`action-${i}`}
record={record}
@@ -85,10 +78,7 @@ class DefaultData {
const result = record.results.find(
r => r[identityIndex] === currentRecord.identity
);
- let object = this.service.utilities.flatten(
- record.attributeNames,
- result
- );
+ let object = this.service.utilities.flatten(record.attributeNames, result);
object = this.service.utilities.formatAttributes(
object,
schema.entityTypes[entity]
@@ -101,9 +91,7 @@ class DefaultData {
// return a list of operations allowed for this entity
actions = entity =>
- this.schema.entityTypes[entity].operations.filter(
- action => action !== "READ"
- );
+ this.schema.entityTypes[entity].operations.filter(action => action !== "READ");
// action button for the entityListTable
actionButton = ({ action, props, click, record, i, asButton }) =>
@@ -130,17 +118,13 @@ class DefaultData {
// called by entityListTable to get the list of records
doFetch = (page, perPage, routerId, entity) => {
return new Promise(resolve => {
- this.service.management.topology.fetchEntities(
- routerId,
- { entity },
- results => {
- const data = utils.flattenAll(results[routerId][entity], f => {
- f.routerId = routerId;
- return f;
- });
- resolve({ data, page, perPage });
- }
- );
+ this.service.management.topology.fetchEntities(routerId, { entity }, results => {
+ const data = utils.flattenAll(results[routerId][entity], f => {
+ f.routerId = routerId;
+ return f;
+ });
+ resolve({ data, page, perPage });
+ });
});
};
}
diff --git a/console/react/src/detailsTablePage.js b/console/react/src/details/detailsTablePage.js
similarity index 84%
rename from console/react/src/detailsTablePage.js
rename to console/react/src/details/detailsTablePage.js
index dcc4492..b216f18 100644
--- a/console/react/src/detailsTablePage.js
+++ b/console/react/src/details/detailsTablePage.js
@@ -38,9 +38,9 @@ import {
} from "@patternfly/react-table";
import { Card, CardBody } from "@patternfly/react-core";
import { Redirect } from "react-router-dom";
-import { dataMap } from "./overview/entityData";
-import { dataMap as detailsDataMap, defaultData } from "./details/entityData";
-import Updated from "./updated";
+import { dataMap } from "../overview/entityData";
+import { dataMap as detailsDataMap, defaultData } from "./entityData";
+import Updated from "../common/updated";
class DetailTablesPage extends React.Component {
constructor(props) {
@@ -76,15 +76,9 @@ class DetailTablesPage extends React.Component {
if (this.props.details) {
this.dataSource = !detailsDataMap[this.entity]
? new defaultData(this.props.service, this.props.schema)
- : new detailsDataMap[this.entity](
- this.props.service,
- this.props.schema
- );
+ : new detailsDataMap[this.entity](this.props.service, this.props.schema);
} else {
- this.dataSource = new dataMap[this.entity](
- this.props.service,
- this.props.schema
- );
+ this.dataSource = new dataMap[this.entity](this.props.service, this.props.schema);
}
}
}
@@ -101,9 +95,7 @@ class DetailTablesPage extends React.Component {
};
locationState = () => {
- return this.props.details
- ? this.props.locationState
- : this.props.location.state;
+ return this.props.details ? this.props.locationState : this.props.location.state;
};
update = () => {
@@ -133,11 +125,7 @@ class DetailTablesPage extends React.Component {
reject("no data source");
}
this.dataSource
- .fetchRecord(
- this.locationState().currentRecord,
- this.props.schema,
- this.entity
- )
+ .fetchRecord(this.locationState().currentRecord, this.props.schema, this.entity)
.then(data => {
for (const attribute in data) {
if (
@@ -191,30 +179,27 @@ class DetailTablesPage extends React.Component {
this.entity,
this.props,
this.locationState().currentRecord,
- event =>
- this.handleActionClicked(event, this.locationState().currentRecord)
+ event => this.handleActionClicked(event, this.locationState().currentRecord)
);
};
return (
<React.Fragment>
- <PageSection
- variant={PageSectionVariants.light}
- className="overview-table-page"
- >
+ <PageSection variant={PageSectionVariants.light} className="overview-table-page">
<Stack>
<StackItem className="overview-header details">
<Breadcrumb>
- <BreadcrumbItem
- className="link-button"
- onClick={this.breadcrumbSelected}
- >
+ <BreadcrumbItem className="link-button" onClick={this.breadcrumbSelected}>
{this.icap(this.entity)}
</BreadcrumbItem>
</Breadcrumb>
<TextContent className="details-table-header">
- <Text className="overview-title" component={TextVariants.h1}>
+ <Text
+ data-testid={`detail-for-${this.parentItem()}`}
+ className="overview-title"
+ component={TextVariants.h1}
+ >
{this.parentItem()}
</Text>
{!this.props.details && (
diff --git a/console/react/src/details/dataSources/addressData.js b/console/react/src/details/detailsTablePage.test.js
similarity index 56%
copy from console/react/src/details/dataSources/addressData.js
copy to console/react/src/details/detailsTablePage.test.js
index 13c7e97..9f49d38 100644
--- a/console/react/src/details/dataSources/addressData.js
+++ b/console/react/src/details/detailsTablePage.test.js
@@ -18,28 +18,19 @@ under the License.
*/
import React from "react";
-import DefaultData from "./defaultData";
-import { utils } from "../../amqp/utilities";
+import { render } from "@testing-library/react";
+import DetailsTablePage from "./detailsTablePage";
-const AddressType = ({ value, extraInfo }) => {
- const data = extraInfo.rowData.data;
- const identity = utils.identity_clean(data.identity);
- const cls = utils.addr_class(identity);
-
- return (
- <span className="entity-type">
- <i className={`address-${cls}`}></i>
- {cls}
- </span>
- );
-};
-
-class AddressData extends DefaultData {
- constructor(service, schema) {
- super(service, schema);
- this.typeFormatter = AddressType;
- this.detailName = "router.address";
- }
-}
-
-export default AddressData;
+it("renders the detailsTablePage", () => {
+ const entity = "testEntity";
+ const props = {
+ entity,
+ locationState: { currentRecord: { name: "test" } },
+ details: true,
+ schema: { entityTypes: { testEntity: { attributes: [], operations: [] } } },
+ service: { management: { topology: { fetchEntities: () => Promise.resolve([]) } } }
+ };
+ const { getByLabelText } = render(<DetailsTablePage {...props} />);
+ const table = getByLabelText(entity);
+ expect(table).toBeInTheDocument();
+});
diff --git a/console/react/src/details/enitiesPage.js b/console/react/src/details/entitiesPage.js
similarity index 91%
rename from console/react/src/details/enitiesPage.js
rename to console/react/src/details/entitiesPage.js
index 6416b62..81d1916 100644
--- a/console/react/src/details/enitiesPage.js
+++ b/console/react/src/details/entitiesPage.js
@@ -22,13 +22,13 @@ import { PageSection, PageSectionVariants } from "@patternfly/react-core";
import { Stack, StackItem } from "@patternfly/react-core";
import { Split, SplitItem } from "@patternfly/react-core";
-import DetailsTablePage from "../detailsTablePage";
+import DetailsTablePage from "./detailsTablePage";
import UpdateTablePage from "./updateTablePage";
import CreateTablePage from "./createTablePage";
import EntityListTable from "./entityListTable";
import EntityList from "./entityList";
import RouterSelect from "./routerSelect";
-import Updated from "../updated";
+import Updated from "../common/updated";
class EntitiesPage extends React.Component {
constructor(props) {
@@ -58,20 +58,11 @@ class EntitiesPage extends React.Component {
this.setState({ entity, showTable: "entities" });
};
- fixNull = rec => {
- for (const attr in rec) {
- if (rec[attr] === null) {
- rec[attr] = "";
- }
- return rec;
- };
- }
-
handleEntityAction = (action, record) => {
if (action === "Done") action = "entities";
this.setState({
actionState: {
- currentRecord: this.fixNull(record),
+ currentRecord: record,
entity: this.props.entity
},
showTable: action
@@ -85,16 +76,12 @@ class EntitiesPage extends React.Component {
if (!props.locationState.currentRecord) {
this.handleSwitchEntity(this.state.entity);
} else {
- this.handleDetailClick(
- props.locationState.currentRecord.name,
- extraInfo,
- {
- page,
- sortBy,
- filterBy,
- perPage
- }
- );
+ this.handleDetailClick(props.locationState.currentRecord.name, extraInfo, {
+ page,
+ sortBy,
+ filterBy,
+ perPage
+ });
}
};
@@ -184,10 +171,7 @@ class EntitiesPage extends React.Component {
};
return (
- <PageSection
- variant={PageSectionVariants.light}
- className="details-table-page"
- >
+ <PageSection variant={PageSectionVariants.light} className="details-table-page">
<Stack>
<StackItem className="details-header">
<Split>
diff --git a/console/react/src/details/entitiesPage.test.js b/console/react/src/details/entitiesPage.test.js
new file mode 100644
index 0000000..8b5e012
--- /dev/null
+++ b/console/react/src/details/entitiesPage.test.js
@@ -0,0 +1,50 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import React from "react";
+import { render, waitForElement, fireEvent } from "@testing-library/react";
+import { service, login, TEST_PORT } from "../serviceTest";
+import EntitiesPage from "./entitiesPage";
+
+it("renders an EntitiesPage", async () => {
+ if (!TEST_PORT) {
+ console.log("using mock service");
+ }
+ await login();
+ expect(service.management.connection.is_connected()).toBe(true);
+
+ const props = {
+ service,
+ schema: service.schema
+ };
+ let pageRef = null;
+ const { getByTestId } = render(<EntitiesPage ref={el => (pageRef = el)} {...props} />);
+
+ // force page to show the router entity list
+ pageRef.handleSelectEntity("router");
+
+ // the router A should be in the list
+ await waitForElement(() => getByTestId("A"));
+
+ // click on the A
+ fireEvent.click(getByTestId("A"));
+
+ // the details page should show for router A
+ await waitForElement(() => getByTestId("detail-for-A"));
+});
diff --git a/console/react/src/details/entityList.js b/console/react/src/details/entityList.js
index dff5d78..6859def 100644
--- a/console/react/src/details/entityList.js
+++ b/console/react/src/details/entityList.js
@@ -36,7 +36,7 @@ class EntityList extends React.Component {
li => !this.exclude.includes(li)
);
- this.cleanList.sort((a, b) => (a > b ? 1 : a < b ? -1 : 0));
+ this.cleanList.sort();
}
handleSelectEntity = event => {
@@ -50,6 +50,7 @@ class EntityList extends React.Component {
<List className="entities-list pf-u-box-shadow-sm-right">
{this.cleanList.map(entity => (
<ListItem
+ data-testid={entity}
key={entity}
onClick={this.handleSelectEntity}
className={entity === this.state.entity ? "selected" : ""}
diff --git a/console/react/src/details/dataSources/connectionData.js b/console/react/src/details/entityList.test.js
similarity index 53%
copy from console/react/src/details/dataSources/connectionData.js
copy to console/react/src/details/entityList.test.js
index 2271434..40b43f7 100644
--- a/console/react/src/details/dataSources/connectionData.js
+++ b/console/react/src/details/entityList.test.js
@@ -18,33 +18,28 @@ under the License.
*/
import React from "react";
-import DefaultData from "./defaultData";
-import ConnectionClose from "../../connectionClose";
+import { render, fireEvent } from "@testing-library/react";
+import { service, login, TEST_PORT } from "../serviceTest";
+import EntityList from "./entityList";
-class ConnectionData extends DefaultData {
- constructor(service, schema) {
- super(service, schema);
- this.extraFields = [
- {
- title: "",
- field: "connection",
- noSort: true,
- formatter: ConnectionClose
- }
- ];
- this.detailEntity = "router.link";
- this.detailName = "Link";
+it("renders a EntityList", async () => {
+ if (!TEST_PORT) {
+ console.log("using mock service");
}
+ await login();
+ expect(service.management.connection.is_connected()).toBe(true);
- detailActions = (entity, props, record) => {
- return (
- <ConnectionClose
- asButton={true}
- extraInfo={{ rowData: { data: record } }}
- {...props}
- />
- );
+ const props = {
+ service,
+ schema: service.schema,
+ handleSelectEntity: () => {}
};
-}
+ const { getByTestId } = render(<EntityList {...props} />);
-export default ConnectionData;
+ // the log item should be there
+ const logEntity = getByTestId("log");
+ expect(logEntity).toBeInTheDocument();
+
+ // clicking on the log entity should not crash
+ fireEvent.click(logEntity);
+});
diff --git a/console/react/src/details/entityListTable.js b/console/react/src/details/entityListTable.js
index c494540..403dc63 100644
--- a/console/react/src/details/entityListTable.js
+++ b/console/react/src/details/entityListTable.js
@@ -28,15 +28,13 @@ import {
} from "@patternfly/react-table";
import { Button, Pagination } from "@patternfly/react-core";
import { Redirect } from "react-router-dom";
-import TableToolbar from "../tableToolbar";
+import TableToolbar from "../common/tableToolbar";
import { dataMap, defaultData } from "./entityData";
// If the breadcrumb on the detailsTablePage was used to return to this page,
// we will have saved state info in props.location.state
const propFromLocation = (props, which, defaultValue) => {
- return props &&
- props.detailsState &&
- typeof props.detailsState[which] !== "undefined"
+ return props && props.detailsState && typeof props.detailsState[which] !== "undefined"
? props.detailsState[which]
: defaultValue;
};
@@ -149,9 +147,7 @@ class EntityListTable extends React.Component {
if (!this.mounted) return;
const { rows, page, total, allRows } = sliced;
allRows.forEach(row => {
- const prevRow = this.state.allRows.find(
- r => r.data.name === row.data.name
- );
+ const prevRow = this.state.allRows.find(r => r.data.name === row.data.name);
if (prevRow && prevRow.selected) {
row.selected = true;
}
@@ -173,6 +169,7 @@ class EntityListTable extends React.Component {
}
return (
<Button
+ data-testid={value}
className="link-button"
onClick={() => this.detailClick(value, extraInfo)}
>
@@ -395,10 +392,7 @@ class EntityListTable extends React.Component {
const tableProps = {
cells: this.columns,
rows: this.state.rows,
- actions: this.dataSource.actionMenuItems(
- this.props.entity,
- this.handleAction
- ),
+ actions: this.dataSource.actionMenuItems(this.props.entity, this.handleAction),
"aria-label": this.props.entity,
sortBy: this.state.sortBy,
onSort: this.onSort,
diff --git a/console/react/src/details/routerSelect.js b/console/react/src/details/routerSelect.js
index b755df4..0d3bec0 100644
--- a/console/react/src/details/routerSelect.js
+++ b/console/react/src/details/routerSelect.js
@@ -1,10 +1,29 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import {
OptionsMenu,
OptionsMenuItem,
OptionsMenuToggleWithText
} from "@patternfly/react-core";
-import { utils } from "../amqp/utilities";
+import { utils } from "../common/amqp/utilities";
class RouterSelect extends React.Component {
constructor(props) {
@@ -57,10 +76,7 @@ class RouterSelect extends React.Component {
));
const toggle = (
- <OptionsMenuToggleWithText
- toggleText={selectedOption}
- onToggle={this.onToggle}
- />
+ <OptionsMenuToggleWithText toggleText={selectedOption} onToggle={this.onToggle} />
);
return (
diff --git a/console/react/src/details/schema/schemaPage.test.js b/console/react/src/details/schema/schemaPage.test.js
index 7954c8e..84e8923 100644
--- a/console/react/src/details/schema/schemaPage.test.js
+++ b/console/react/src/details/schema/schemaPage.test.js
@@ -1,6 +1,25 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import { render, fireEvent } from "@testing-library/react";
-import { mockService } from "../../qdrService.mock";
+import { mockService } from "../../../test_data/qdrService.mock";
import SchemaPage from "./schemaPage";
it("renders a SchemaPage", () => {
diff --git a/console/react/src/details/updateTablePage.js b/console/react/src/details/updateTablePage.js
index 86c4a29..c893698 100644
--- a/console/react/src/details/updateTablePage.js
+++ b/console/react/src/details/updateTablePage.js
@@ -44,7 +44,7 @@ import { cellWidth } from "@patternfly/react-table";
import { Card, CardBody } from "@patternfly/react-core";
import { Redirect } from "react-router-dom";
import { dataMap as detailsDataMap, defaultData } from "./entityData";
-import { utils } from "../amqp/utilities";
+import { utils } from "../common/amqp/utilities";
class UpdateTablePage extends React.Component {
constructor(props) {
@@ -64,10 +64,7 @@ class UpdateTablePage extends React.Component {
} else {
this.dataSource = !detailsDataMap[this.entity]
? new defaultData(this.props.service, this.props.schema)
- : new detailsDataMap[this.entity](
- this.props.service,
- this.props.schema
- );
+ : new detailsDataMap[this.entity](this.props.service, this.props.schema);
}
this.state = {
@@ -85,11 +82,26 @@ class UpdateTablePage extends React.Component {
redirectPath: "/dashboard",
lastUpdated: new Date(),
changes: false,
- record: this.props.locationState.currentRecord
+ record: this.fixNull(this.props.locationState.currentRecord)
};
this.originalRecord = utils.copy(this.state.record);
}
+ fixNull = rec => {
+ const record = utils.copy(rec);
+ const attributes = this.dataSource.schemaAttributes(this.entity);
+ for (const attr in record) {
+ if (record[attr] === null) {
+ if (attributes[attr].type === "string") {
+ record[attr] = "";
+ } else if (attributes[attr].type === "integer") {
+ record[attr] = 0;
+ }
+ }
+ }
+ return record;
+ };
+
handleTextInputChange = (value, key) => {
const { record } = this.state;
record[key] = value;
@@ -112,14 +124,6 @@ class UpdateTablePage extends React.Component {
if (type === "list") readOnly = true;
if (type === "integer" && attribute.graph) readOnly = true;
let required = attribute.required;
- if (record[attributeKey] === null) {
- if (attribute.type === "string")
- record[attributeKey] = "";
- if (attribute.type === "boolean")
- record[attributeKey] = false;
- if (attribute.type === "integer")
- record[attributeKey] = 0;
- }
const value = record[attributeKey];
if (
this.dataSource.updateMetaData &&
@@ -154,9 +158,7 @@ class UpdateTablePage extends React.Component {
aria-describedby="entiy-form-field"
name={attributeKey}
isDisabled={readOnly}
- onChange={value =>
- this.handleTextInputChange(value, attributeKey)
- }
+ onChange={value => this.handleTextInputChange(value, attributeKey)}
/>
</FormGroup>
);
@@ -165,9 +167,7 @@ class UpdateTablePage extends React.Component {
<FormGroup {...formGroupProps} key={attributeKey}>
<FormSelect
value={value}
- onChange={value =>
- this.handleTextInputChange(value, attributeKey)
- }
+ onChange={value => this.handleTextInputChange(value, attributeKey)}
id={id}
name={attributeKey}
>
@@ -186,12 +186,8 @@ class UpdateTablePage extends React.Component {
formGroups.push(
<FormGroup {...formGroupProps} key={attributeKey}>
<Checkbox
- isChecked={
- record[attributeKey] === null ? false : record[attributeKey]
- }
- onChange={value =>
- this.handleTextInputChange(value, attributeKey)
- }
+ isChecked={record[attributeKey] === null ? false : record[attributeKey]}
+ onChange={value => this.handleTextInputChange(value, attributeKey)}
label={attributeKey}
id={id}
name={attributeKey}
@@ -225,27 +221,24 @@ class UpdateTablePage extends React.Component {
const attributes = {};
// identity is needed to update the record
attributes["identity"] = record.identity;
+ const schemaAttributes = this.dataSource.schemaAttributes(this.entity);
// pass any other attributes that have changed
for (const attr in record) {
if (record[attr] !== this.originalRecord[attr]) {
attributes[attr] = record[attr];
}
+ if (schemaAttributes[attr] && schemaAttributes[attr].required) {
+ attributes[attr] = record[attr];
+ }
if (attr === "outputFile") {
- attributes["outputFile"] =
- record.outputFile === "" ? null : record.outputFile;
+ attributes["outputFile"] = record.outputFile === "" ? null : record.outputFile;
}
}
// call update
this.props.service.management.connection
- .sendMethod(
- record.routerId || record.nodeId,
- this.entity,
- attributes,
- "UPDATE"
- )
+ .sendMethod(record.routerId || record.nodeId, this.entity, attributes, "UPDATE")
.then(results => {
- let statusCode =
- results.context.message.application_properties.statusCode;
+ let statusCode = results.context.message.application_properties.statusCode;
if (statusCode < 200 || statusCode >= 300) {
const msg = `Updated ${record.name} failed with message: ${results.context.message.application_properties.statusDescription}`;
console.log(`error ${msg}`);
@@ -253,12 +246,7 @@ class UpdateTablePage extends React.Component {
} else {
const msg = `Updated ${this.props.entity} ${record.name}`;
console.log(`success ${msg}`);
- this.props.handleAddNotification(
- "action",
- msg,
- new Date(),
- "success"
- );
+ this.props.handleAddNotification("action", msg, new Date(), "success");
}
const props = this.props;
props.locationState.currentRecord = record;
@@ -280,17 +268,11 @@ class UpdateTablePage extends React.Component {
return (
<React.Fragment>
- <PageSection
- variant={PageSectionVariants.light}
- className="overview-table-page"
- >
+ <PageSection variant={PageSectionVariants.light} className="overview-table-page">
<Stack>
<StackItem className="overview-header details">
<Breadcrumb>
- <BreadcrumbItem
- className="link-button"
- onClick={this.breadcrumbSelected}
- >
+ <BreadcrumbItem className="link-button" onClick={this.breadcrumbSelected}>
{this.icap(this.entity)}
</BreadcrumbItem>
</Breadcrumb>
@@ -306,10 +288,7 @@ class UpdateTablePage extends React.Component {
>
Cancel
</Button>
- <Button
- onClick={this.handleUpdate}
- isDisabled={!this.state.changes}
- >
+ <Button onClick={this.handleUpdate} isDisabled={!this.state.changes}>
Update
</Button>
</ActionGroup>
@@ -318,7 +297,9 @@ class UpdateTablePage extends React.Component {
<StackItem id="update-form">
<Card>
<CardBody>
- <Form isHorizontal aria-label="update-entity-form">{this.schemaToForm()}</Form>
+ <Form isHorizontal aria-label="update-entity-form">
+ {this.schemaToForm()}
+ </Form>
</CardBody>
</Card>
</StackItem>
diff --git a/console/react/src/details/updateTablePage.test.js b/console/react/src/details/updateTablePage.test.js
index c2bb740..270669c 100644
--- a/console/react/src/details/updateTablePage.test.js
+++ b/console/react/src/details/updateTablePage.test.js
@@ -1,24 +1,40 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
-import { render, fireEvent } from '@testing-library/react';
-import { mockService } from "../qdrService.mock";
+import { render, fireEvent } from "@testing-library/react";
+import { mockService } from "../../test_data/qdrService.mock";
import UpdateTablePage from "./updateTablePage";
-it('renders a UpdateTablePage', () => {
+it("renders a UpdateTablePage", () => {
let sendMethodCalled = false;
- const service = mockService({ onSendMethod: () => sendMethodCalled = true });
+ const service = mockService({ onSendMethod: () => (sendMethodCalled = true) });
const props = {
entity: "log",
service,
schema: service.schema,
locationState: { currentRecord: { name: "test.log.name", enable: "" } },
routerId: Object.keys(service.management.topology._nodeInfo)[0],
- handleAddNotification: () => { },
- handleActionCancel: () => { }
- }
- const {
- getByLabelText,
- getByText
- } = render(<UpdateTablePage {...props} />);
+ handleAddNotification: () => {},
+ handleActionCancel: () => {}
+ };
+ const { getByLabelText, getByText } = render(<UpdateTablePage {...props} />);
// the update form should be present
expect(getByLabelText("update-entity-form")).toBeInTheDocument();
@@ -33,8 +49,7 @@ it('renders a UpdateTablePage', () => {
expect(sendMethodCalled).toBe(false);
// change a form field and try the update button again
- fireEvent.change(getByLabelText(/enable/i), { target: { value: 'debug' } });
+ fireEvent.change(getByLabelText(/enable/i), { target: { value: "debug" } });
fireEvent.click(updateButton);
expect(sendMethodCalled).toBe(true);
-
-})
\ No newline at end of file
+});
diff --git a/console/react/src/detailsTablePage.test.js b/console/react/src/detailsTablePage.test.js
deleted file mode 100644
index 300678e..0000000
--- a/console/react/src/detailsTablePage.test.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import React from "react";
-import { render } from '@testing-library/react';
-import DetailsTablePage from "./detailsTablePage";
-
-it("renders the detailsTablePage", () => {
- const entity = "testEntity"
- const props = {
- entity,
- locationState: { currentRecord: { name: "test" } },
- details: true,
- schema: { entityTypes: { testEntity: { attributes: [], operations: [] } } },
- service: { management: { topology: { fetchEntities: () => Promise.resolve([]) } } }
- }
- const { getByLabelText } = render(
- <DetailsTablePage {...props} />
- );
- const table = getByLabelText(entity);
- expect(table).toBeInTheDocument();
-});
diff --git a/console/react/src/index.css b/console/react/src/index.css
deleted file mode 100644
index 4a1df4d..0000000
--- a/console/react/src/index.css
+++ /dev/null
@@ -1,13 +0,0 @@
-body {
- margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
- "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
- sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
- monospace;
-}
diff --git a/console/react/src/index.js b/console/react/src/index.js
index 7af6900..9297040 100644
--- a/console/react/src/index.js
+++ b/console/react/src/index.js
@@ -1,14 +1,31 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
-import * as serviceWorker from "./serviceWorker";
let config = { title: "Apache Qpid Dispatch Console" };
fetch("/config.json")
.then(res => res.json())
.then(cfg => {
config = cfg;
- console.log("successfully loaded console title from /config.json");
})
.catch(error => {
console.log("/config.json not found. Using default console title");
@@ -16,8 +33,3 @@ fetch("/config.json")
.finally(() =>
ReactDOM.render(<App config={config} />, document.getElementById("root"))
);
-
-// If you want your app to work offline and load faster, you can change
-// unregister() to register() below. Note this comes with some pitfalls.
-// Learn more about service workers: https://bit.ly/CRA-PWA
-serviceWorker.unregister();
diff --git a/console/react/src/layout.test.js b/console/react/src/layout.test.js
deleted file mode 100644
index 8f75b15..0000000
--- a/console/react/src/layout.test.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import React from "react";
-import { render, fireEvent } from '@testing-library/react';
-import PageLayout from "./layout";
-import { mockService } from "./qdrService.mock";
-
-it('allows the user to login successfully', async () => {
- const title = "Test Layout Page";
- const props = {
- config: { title: title },
- service: mockService({})
- };
-
- const {
- getAllByText,
- getByLabelText,
- findByLabelText,
- getByTestId } = render(<PageLayout {...props} />);
-
- // the correct title should be found
- expect(getAllByText(title));
-
- // fill out the form
- fireEvent.change(getByLabelText(/address/i), { target: { value: 'localhost' } });
- fireEvent.change(getByLabelText(/port/i), { target: { value: '5673' } });
-
- fireEvent.click(getByTestId("connect-button"));
-
- // wait for the dashboard
- // to show up before continuing with our assertions.
- const dashboard = await findByLabelText('dashboard-page');
-
- expect(dashboard).toHaveTextContent(/Router network statistics/i);
-})
\ No newline at end of file
diff --git a/console/react/src/notificationDrawer.test.js b/console/react/src/notificationDrawer.test.js
deleted file mode 100644
index 574720e..0000000
--- a/console/react/src/notificationDrawer.test.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import React from "react";
-import { render, fireEvent } from '@testing-library/react';
-import NotificationDrawer from "./notificationDrawer";
-
-it('renders without crashing', () => {
- render(<NotificationDrawer />);
-})
-
-it('renders a notification icon', () => {
- let notificationRef = null;
- const {
- getByLabelText,
- getByText
- } = render(<NotificationDrawer
- ref={el => (notificationRef = el)}
- />);
-
- // the notifications icon should be present
- const notificationIcon = getByLabelText("Notifications");
- expect(notificationIcon).toBeInTheDocument();
-
- // add a notification
- const section = "action";
- const message = "test message";
- const timestamp = new Date();
- const severity = "info";
- notificationRef.addNotification({ section, message, timestamp, severity })
-
- // click the notification icon
- fireEvent.click(notificationIcon);
-
- // there should now be a single notification-item
- expect(getByText("1 new event")).toBeInTheDocument();
-})
\ No newline at end of file
diff --git a/console/react/src/overview/dashboard/activeAddressesCard.js b/console/react/src/overview/dashboard/activeAddressesCard.js
index 6ec88d2..f1c509d 100644
--- a/console/react/src/overview/dashboard/activeAddressesCard.js
+++ b/console/react/src/overview/dashboard/activeAddressesCard.js
@@ -1,3 +1,22 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import { Table, TableHeader, TableBody } from "@patternfly/react-table";
@@ -41,25 +60,19 @@ class ActiveAddressesCard extends React.Component {
aresult.attributeNames,
aresult.results[i]
);
- if (result.linkType === "endpoint" && result.linkDir === "out") {
+ if (result.linkType === "endpoint" && result.linkDir === "in") {
if (
parseInt(result.settleRate) > 0 &&
- !result.owningAddr.startsWith("Ltemp.")
+ result.owningAddr && !result.owningAddr.startsWith("Ltemp.")
) {
if (!active.hasOwnProperty[result.owningAddr]) {
active[result.owningAddr] = {
- addr: this.props.service.utilities.addr_text(
- result.owningAddr
- ),
- cls: this.props.service.utilities.addr_class(
- result.owningAddr
- ),
+ addr: this.props.service.utilities.addr_text(result.owningAddr),
+ cls: this.props.service.utilities.addr_class(result.owningAddr),
settleRate: 0
};
}
- active[result.owningAddr].settleRate += parseInt(
- result.settleRate
- );
+ active[result.owningAddr].settleRate += parseInt(result.settleRate);
}
}
}
@@ -79,9 +92,7 @@ class ActiveAddressesCard extends React.Component {
};
nextUpdateString = () => {
- const nextUpdate = new Date(
- this.state.lastUpdate.getTime() + UPDATE_INTERVAL
- );
+ const nextUpdate = new Date(this.state.lastUpdate.getTime() + UPDATE_INTERVAL);
return this.props.service.utilities.strDate(nextUpdate);
};
diff --git a/console/react/src/alertList.js b/console/react/src/overview/dashboard/alertList.js
similarity index 100%
rename from console/react/src/alertList.js
rename to console/react/src/overview/dashboard/alertList.js
diff --git a/console/react/src/overview/dashboard/alertList.test.js b/console/react/src/overview/dashboard/alertList.test.js
new file mode 100644
index 0000000..55614a7
--- /dev/null
+++ b/console/react/src/overview/dashboard/alertList.test.js
@@ -0,0 +1,47 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import React from "react";
+import { render } from "@testing-library/react";
+import AlertList from "./alertList";
+
+it("renders the AlertList component", () => {
+ let ref = null;
+ const props = {};
+ const { getByLabelText, queryByLabelText } = render(
+ <AlertList ref={el => (ref = el)} {...props} />
+ );
+ // the container should be there
+ expect(getByLabelText("alert-list")).toBeInTheDocument();
+ // there should be no alerts in the list to start with
+ expect(queryByLabelText("alert-close-button")).toBeNull();
+
+ // add an alert
+ ref.addAlert("info", "testing");
+ // the alert close button should now be there
+ expect(getByLabelText("alert-close-button")).toBeInTheDocument();
+
+ const alert = {
+ key: 0
+ };
+ // hide the alert
+ ref.hideAlert(alert);
+ // the alert close button should now be gone
+ expect(queryByLabelText("alert-close-button")).toBeNull();
+});
diff --git a/console/react/src/overview/dashboard/chartBase.js b/console/react/src/overview/dashboard/chartBase.js
index c7478b7..5cd2727 100644
--- a/console/react/src/overview/dashboard/chartBase.js
+++ b/console/react/src/overview/dashboard/chartBase.js
@@ -25,28 +25,27 @@ import OverviewChart from "./overviewChart";
class ChartBase extends React.Component {
constructor(props) {
super(props);
- this.state = {
- rates: []
- };
- this.rawData = [];
- this.rateStorage = {};
- this.initialized = false;
- for (let i = 0; i < 60 * 60; i++) {
- this.state.rates.push(0);
- }
this.title = "Override me";
this.ariaLabel = "base-chart";
this.isRate = false;
+ this.style = { fill: "#EBAEBA", fillOpacity: 1, stroke: "#EAEAEA" };
+ this.state = {
+ data: this.props.chartData.data(this.props.period)
+ };
}
componentDidMount = () => {
- this.mounted = true;
- this.timer = setInterval(this.updateData, 1000);
+ this.timer = setInterval(this.setData, 1000);
};
componentWillUnmount = () => {
- this.mounted = false;
- clearInterval(this.timer);
+ if (this.timer) {
+ clearInterval(this.timer);
+ }
+ };
+
+ setData = () => {
+ this.setState({ data: this.props.chartData.data(this.props.period) });
};
setStyle = (color, opacity) => {
@@ -56,50 +55,15 @@ class ChartBase extends React.Component {
stroke: d3.rgb(color).darker(2)
};
};
- updateData = () => {
- console.log("updateData should be overridden");
- };
-
- init = datum => {
- for (let i = 0; i < 60 * 60; i++) {
- this.rawData.push(datum);
- }
- this.initialized = true;
- };
-
- addData = datum => {
- if (!this.initialized) {
- this.init(datum);
- }
- if (!this.mounted) return;
- const { rates } = this.state;
- this.rawData.push(datum);
- this.rawData.splice(0, 1);
- if (this.isRate) {
- // get the average rate of change for the last three values
- const avg = this.props.service.utilities.rates(
- { val: datum },
- ["val"],
- this.rateStorage,
- "val",
- 3
- );
- datum = Math.round(avg.val);
- }
- rates.push(datum);
- rates.splice(0, 1);
- this.setState({ rates });
- };
-
- data = () => {
- const start = Math.max(this.state.rates.length - this.props.period, 0);
- const end = this.state.rates.length - 1;
- return this.state.rates.slice(start, end);
- };
render() {
return (
- <OverviewChart ariaLabel={this.ariaLabel} data={this.data()} title={this.title} style={this.style} />
+ <OverviewChart
+ ariaLabel={this.ariaLabel}
+ data={this.state.data}
+ title={this.title}
+ style={this.style}
+ />
);
}
}
diff --git a/console/react/src/overview/dashboard/chartBase.js b/console/react/src/overview/dashboard/chartData.js
similarity index 51%
copy from console/react/src/overview/dashboard/chartBase.js
copy to console/react/src/overview/dashboard/chartData.js
index c7478b7..508efda 100644
--- a/console/react/src/overview/dashboard/chartBase.js
+++ b/console/react/src/overview/dashboard/chartData.js
@@ -17,49 +17,19 @@ specific language governing permissions and limitations
under the License.
*/
-import React from "react";
-import * as d3 from "d3";
-
-import OverviewChart from "./overviewChart";
-
-class ChartBase extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- rates: []
- };
+class ChartData {
+ constructor(service) {
+ this.service = service;
+ this.rates = [];
this.rawData = [];
this.rateStorage = {};
this.initialized = false;
for (let i = 0; i < 60 * 60; i++) {
- this.state.rates.push(0);
+ this.rates.push(0);
}
- this.title = "Override me";
- this.ariaLabel = "base-chart";
this.isRate = false;
}
- componentDidMount = () => {
- this.mounted = true;
- this.timer = setInterval(this.updateData, 1000);
- };
-
- componentWillUnmount = () => {
- this.mounted = false;
- clearInterval(this.timer);
- };
-
- setStyle = (color, opacity) => {
- this.style = {
- fill: color,
- fillOpacity: opacity || 1,
- stroke: d3.rgb(color).darker(2)
- };
- };
- updateData = () => {
- console.log("updateData should be overridden");
- };
-
init = datum => {
for (let i = 0; i < 60 * 60; i++) {
this.rawData.push(datum);
@@ -71,13 +41,11 @@ class ChartBase extends React.Component {
if (!this.initialized) {
this.init(datum);
}
- if (!this.mounted) return;
- const { rates } = this.state;
this.rawData.push(datum);
this.rawData.splice(0, 1);
if (this.isRate) {
// get the average rate of change for the last three values
- const avg = this.props.service.utilities.rates(
+ const avg = this.service.utilities.rates(
{ val: datum },
["val"],
this.rateStorage,
@@ -86,22 +54,11 @@ class ChartBase extends React.Component {
);
datum = Math.round(avg.val);
}
- rates.push(datum);
- rates.splice(0, 1);
- this.setState({ rates });
+ this.rates.push(datum);
+ this.rates.splice(0, 1);
};
- data = () => {
- const start = Math.max(this.state.rates.length - this.props.period, 0);
- const end = this.state.rates.length - 1;
- return this.state.rates.slice(start, end);
- };
-
- render() {
- return (
- <OverviewChart ariaLabel={this.ariaLabel} data={this.data()} title={this.title} style={this.style} />
- );
- }
+ data = period => this.rates.slice(-period);
}
-export default ChartBase;
+export default ChartData;
diff --git a/console/react/src/overview/dashboard/dashboardPage.js b/console/react/src/overview/dashboard/dashboardPage.js
index 7116a78..23d2221 100644
--- a/console/react/src/overview/dashboard/dashboardPage.js
+++ b/console/react/src/overview/dashboard/dashboardPage.js
@@ -80,8 +80,14 @@ class DashboardPage extends React.Component {
<div className="time-period">For the past {this.timePeriodString()}</div>
</CardHeader>
<CardBody>
- <ThroughputChart period={this.state.timePeriod} service={this.props.service} />
- <InflightChart period={this.state.timePeriod} service={this.props.service} />
+ <ThroughputChart
+ period={this.state.timePeriod}
+ chartData={this.props.throughputChartData}
+ />
+ <InflightChart
+ period={this.state.timePeriod}
+ chartData={this.props.inflightChartData}
+ />
</CardBody>
</Card>
</StackItem>
diff --git a/console/react/src/overview/dashboard/dashboardPage.test.js b/console/react/src/overview/dashboard/dashboardPage.test.js
index 3269f7d..535ae9f 100644
--- a/console/react/src/overview/dashboard/dashboardPage.test.js
+++ b/console/react/src/overview/dashboard/dashboardPage.test.js
@@ -1,15 +1,41 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
-import { render } from '@testing-library/react';
+import { render } from "@testing-library/react";
+import { service, login, TEST_PORT } from "../../serviceTest";
+import throughputChartData from "./throughputData";
+import inflightChartData from "./inflightData";
import DashboardPage from "./dashboardPage";
-import { mockService } from "../../qdrService.mock";
-it("renders the DashboardPage component", () => {
+it("renders the DashboardPage component", async () => {
const props = {
- service: mockService({})
- }
- const { getByLabelText } = render(
- <DashboardPage {...props} />
- )
+ service,
+ throughputChartData: new throughputChartData(service),
+ inflightChartData: new inflightChartData(service)
+ };
+
+ if (!TEST_PORT) console.log("using mock service");
+ await login();
+ expect(service.management.connection.is_connected()).toBe(true);
+
+ const { getByLabelText } = render(<DashboardPage {...props} />);
// make sure it rendered the component
expect(getByLabelText("dashboard-page")).toBeInTheDocument();
diff --git a/console/react/src/overview/dashboard/delayedDeliveriesCard.js b/console/react/src/overview/dashboard/delayedDeliveriesCard.js
index 0fa44b3..990d029 100644
--- a/console/react/src/overview/dashboard/delayedDeliveriesCard.js
+++ b/console/react/src/overview/dashboard/delayedDeliveriesCard.js
@@ -1,9 +1,27 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import { Table, TableHeader, TableBody } from "@patternfly/react-table";
-import ConnectionClose from "../../connectionClose";
+import ConnectionClose from "../../common/connectionClose";
-// update the table every 5 seconds
-const UPDATE_INTERVAL = 1000 * 5;
+const UPDATE_INTERVAL = 5000;
class DelayedDeliveriesCard extends React.Component {
constructor(props) {
@@ -25,13 +43,21 @@ class DelayedDeliveriesCard extends React.Component {
}
closeButton = (value, extraInfo) => {
- return <ConnectionClose extraInfo={extraInfo} {...this.props} service={this.props.service} />;
+ return (
+ <ConnectionClose
+ extraInfo={extraInfo}
+ {...this.props}
+ service={this.props.service}
+ />
+ );
};
componentDidMount = () => {
this.mounted = true;
this.timer = setInterval(this.updateData, UPDATE_INTERVAL);
this.updateData();
+ // we need 2 measurements to get a rate
+ setTimeout(this.updateData, 1000);
};
componentWillUnmount = () => {
@@ -50,7 +76,10 @@ class DelayedDeliveriesCard extends React.Component {
let response = nodes[node]["router.link"];
// eslint-disable-next-line no-loop-func
response.results.forEach(result => {
- let link = this.props.service.utilities.flatten(response.attributeNames, result);
+ let link = this.props.service.utilities.flatten(
+ response.attributeNames,
+ result
+ );
if (link.linkType === "endpoint") {
link.router = this.props.service.utilities.nameFromId(node);
link.role = "normal";
@@ -71,10 +100,16 @@ class DelayedDeliveriesCard extends React.Component {
["deliveriesDelayed1Sec", "deliveriesDelayed10Sec"],
this.rates,
link.name,
- 12 // average over 12 snapshots (each snapshot is 5 seconds apart)
+ 2 // average over 2 snapshots (each snapshot is 5 seconds apart)
+ );
+ link.deliveriesDelayed1SecRate = Math.round(
+ delayedRates.deliveriesDelayed1Sec,
+ 1
+ );
+ link.deliveriesDelayed10SecRate = Math.round(
+ delayedRates.deliveriesDelayed10Sec,
+ 1
);
- link.deliveriesDelayed1SecRate = Math.round(delayedRates.deliveriesDelayed1Sec, 1);
- link.deliveriesDelayed10SecRate = Math.round(delayedRates.deliveriesDelayed10Sec, 1);
/* The killConnection event handler (in qdrOverview.js) expects
a row object with a routerId and the identity of a connection.
Here we set those attributes so that when killConnection is
@@ -90,7 +125,9 @@ class DelayedDeliveriesCard extends React.Component {
if (links.length === 0) return;
// update the grid's data
links = links.filter(link => {
- return link.deliveriesDelayed1SecRate > 0 || link.deliveriesDelayed10SecRate > 0;
+ return (
+ link.deliveriesDelayed1SecRate > 0 || link.deliveriesDelayed10SecRate > 0
+ );
});
links.sort((a, b) => {
if (a.deliveriesDelayed1SecRate > b.deliveriesDelayed1SecRate) return -1;
diff --git a/console/react/src/overview/dashboard/inflightChart.test.js b/console/react/src/overview/dashboard/inflightChart.test.js
index ce2177c..d90e5c3 100644
--- a/console/react/src/overview/dashboard/inflightChart.test.js
+++ b/console/react/src/overview/dashboard/inflightChart.test.js
@@ -1,15 +1,39 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
-import { render } from '@testing-library/react';
+import { render } from "@testing-library/react";
+import { service, login, TEST_PORT } from "../../serviceTest";
import InflightChart from "./inflightChart";
-import { mockService } from "../../qdrService.mock";
+import InflightChartData from "./inflightData";
-it("renders the InflightChart component", () => {
+it("renders the InflightChart component", async () => {
const props = {
- service: mockService({})
- }
- const { getByLabelText } = render(
- <InflightChart {...props} />
- )
+ service,
+ chartData: new InflightChartData(service)
+ };
+
+ if (!TEST_PORT) console.log("using mock service");
+ await login();
+ expect(service.management.connection.is_connected()).toBe(true);
+
+ const { getByLabelText } = render(<InflightChart {...props} />);
// make sure it rendered the component
setTimeout(() => expect(getByLabelText("inflight-chart")).toBeInTheDocument(), 1);
diff --git a/console/react/src/overview/dashboard/inflightData.js b/console/react/src/overview/dashboard/inflightData.js
new file mode 100644
index 0000000..50a8dbb
--- /dev/null
+++ b/console/react/src/overview/dashboard/inflightData.js
@@ -0,0 +1,61 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF 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 ChartData from "./chartData";
+
+class InflightData extends ChartData {
+ constructor(service) {
+ super(service);
+ this.isRate = false;
+ this.running = true;
+ }
+
+ stop = () => {
+ this.running = false;
+ };
+ updateData = () => {
+ if (!this.service.management.connection.is_connected()) return;
+ this.service.management.topology.fetchAllEntities(
+ {
+ entity: "router.link",
+ attrs: ["undeliveredCount", "unsettledCount", "linkType", "linkDir"]
+ },
+ results => {
+ if (!this.running) return;
+ let inflight = 0;
+ for (let id in results) {
+ const aresult = results[id]["router.link"];
+ for (let i = 0; i < aresult.results.length; i++) {
+ const result = this.service.utilities.flatten(
+ aresult.attributeNames,
+ aresult.results[i]
+ );
+ inflight +=
+ result.linkType === "endpoint" && result.linkDir === "out"
+ ? parseInt(result.unsettledCount) + parseInt(result.undeliveredCount)
+ : 0;
+ }
+ }
+ this.addData(inflight);
+ }
+ );
+ };
+}
+
+export default InflightData;
diff --git a/console/react/src/layout.js b/console/react/src/overview/dashboard/layout.js
similarity index 65%
rename from console/react/src/layout.js
rename to console/react/src/overview/dashboard/layout.js
index 4bd80e7..46fe58c 100644
--- a/console/react/src/layout.js
+++ b/console/react/src/overview/dashboard/layout.js
@@ -36,38 +36,41 @@ import {
PageSidebar
} from "@patternfly/react-core";
-import { BrowserRouter as Router, Switch, Route, Link, Redirect } from "react-router-dom";
+import { HashRouter as Router, Switch, Route, Link, Redirect } from "react-router-dom";
import accessibleStyles from "@patternfly/patternfly/utilities/Accessibility/accessibility.css";
import { css } from "@patternfly/react-styles";
import { PowerOffIcon } from "@patternfly/react-icons";
-import DropdownMenu from "./DropdownMenu";
-import ConnectPage from "./connectPage";
-import DashboardPage from "./overview/dashboard/dashboardPage";
-import OverviewPage from "./overview/overviewPage";
-import DetailsTablePage from "./detailsTablePage";
-import EntitiesPage from "./details/enitiesPage";
-import TopologyPage from "./topology/topologyPage";
-import MessageFlowPage from "./chord/chordPage";
-import SchemaPage from "./details/schema/schemaPage";
-import LogDetails from "./overview/logDetails";
-import ConnectForm from "./connect-form";
+import DropdownMenu from "../../common/DropdownMenu";
+import ConnectPage from "../../connect/connectPage";
+import DashboardPage from "./dashboardPage";
+import OverviewPage from "../overviewPage";
+import DetailsTablePage from "../../details/detailsTablePage";
+import EntitiesPage from "../../details/entitiesPage";
+import TopologyPage from "../../topology/topologyPage";
+import MessageFlowPage from "../../chord/chordPage";
+import SchemaPage from "../../details/schema/schemaPage";
+import LogDetails from "../logDetails";
+import ConnectForm from "../../connect/connect-form";
import NotificationDrawer from "./notificationDrawer";
-import { utils } from "./amqp/utilities";
+import { utils } from "../../common/amqp/utilities";
+import throughputData from "./throughputData";
+import inflightData from "./inflightData";
class PageLayout extends React.Component {
constructor(props) {
super(props);
this.state = {
connected: false,
- connectPath: "",
+ connecting: false,
+ isConnectFormOpen: false,
activeGroup: "overview",
activeItem: "dashboard",
isNavOpenDesktop: true,
isNavOpenMobile: false,
isMobileView: false,
user: "anonymous",
- isConnectFormOpen: false
+ timePeriod: 60
};
this.isDropdownOpen = false;
@@ -85,23 +88,84 @@ class PageLayout extends React.Component {
visualizations: [{ name: "topology" }, { name: "flow", title: "Message flow" }],
details: [{ name: "entities" }, { name: "schema" }]
};
+ this.state.connecting = true;
+ this.tryInitialConnect();
}
+ componentDidMount = () => {
+ this.chartTimer = setInterval(this.updateCharts, 1000);
+ this.throughputChartData = new throughputData(this.service);
+ this.inflightChartData = new inflightData(this.service);
+ this.updateCharts();
+ };
+
+ componentWillUnmount = () => {
+ if (this.chartTimer) {
+ this.throughputChartData.stop();
+ this.inflightChartData.stop();
+ clearInterval(this.chartTimer);
+ }
+ };
+
+ tryInitialConnect = () => {
+ const connectOptions = {
+ address: window.location.hostname,
+ port: window.location.port,
+ timeout: 2000,
+ reconnect: false
+ };
+ this.service.connect(connectOptions).then(
+ () => {
+ this.service.setReconnect(true);
+ this.schema = this.service.schema;
+ this.props.history.replace("/dashboard");
+ this.redirect = true;
+ this.setState({ connecting: false, connected: true });
+ },
+ () => {
+ //this.service.disconnect();
+ this.props.history.replace("/");
+ this.setState({ connecting: false });
+ }
+ );
+ };
+
// the connection to the routers was lost
setLocation = whatHappened => {
if (whatHappened === "disconnect") {
+ this.handleAddNotification(
+ "event",
+ "Connection to router dropped",
+ new Date(),
+ "warning"
+ );
+ this.lastLocation = this.props.location.pathname;
this.setState({ connected: false });
} else if (whatHappened === "reconnect") {
- this.handleConnectCancel();
- const connectPath = this.lastConnectPath || "/";
- this.lastConnectPath = connectPath;
+ this.handleAddNotification(
+ "event",
+ "Connection to router resumed",
+ new Date(),
+ "info"
+ );
+ this.redirect = true;
+ let to = "/dashboard";
+ if (this.lastLocation) {
+ to = this.lastLocation;
+ }
+ this.props.history.push(to);
this.setState({
- connectPath,
+ isConnectFormOpen: false,
connected: true
});
}
};
+ updateCharts = () => {
+ this.throughputChartData.updateData();
+ this.inflightChartData.updateData();
+ };
+
onDropdownToggle = () => {
this.isDropdownOpen = !this.isDropdownOpen;
this.dropdownRef.show(this.isDropdownOpen);
@@ -118,7 +182,7 @@ class PageLayout extends React.Component {
handleConnect = (connectPath, result) => {
if (this.state.connected) {
- this.setState({ connectPath: "", connected: false }, () => {
+ this.setState({ connected: false }, () => {
this.handleConnectCancel();
this.service.disconnect();
this.handleAddNotification("event", "Manually disconnected", new Date(), "info");
@@ -135,24 +199,29 @@ class PageLayout extends React.Component {
break;
}
}
- this.handleConnectCancel();
- this.handleAddNotification("event", `Console connected to router`, new Date(), "success");
+ this.handleAddNotification(
+ "event",
+ `Console connected to router`,
+ new Date(),
+ "success",
+ true
+ );
+ this.redirect = true;
+ this.props.history.replace(connectPath);
this.setState({
activeItem,
activeGroup,
connected: true,
- connectPath
+ isConnectFormOpen: false
});
}
};
- onNavSelect = (result, connectPath) => {
- this.lastConnectPath = connectPath || this.state.connectPath;
+ onNavSelect = result => {
this.setState({
activeItem: result.itemId,
- activeGroup: result.groupId,
- connectPath: ""
+ activeGroup: result.groupId
});
};
@@ -191,13 +260,14 @@ class PageLayout extends React.Component {
return this.state.connected;
};
- handleAddNotification = (section, message, timestamp, severity) => {
+ handleAddNotification = (section, message, timestamp, severity, silent) => {
if (this.notificationRef) {
this.notificationRef.addNotification({
section,
message,
timestamp,
- severity
+ severity,
+ silent
});
}
};
@@ -222,7 +292,12 @@ class PageLayout extends React.Component {
{this.nav[section].map(item => {
const key = item.name;
return (
- <NavItem groupId={section} itemId={key} isActive={activeItem === key} key={key}>
+ <NavItem
+ groupId={section}
+ itemId={key}
+ isActive={activeItem === key}
+ key={key}
+ >
<Link to={`/${item.pre ? section + "/" : ""}${key}`}>
{item.title ? item.title : utils.Icap(key)}
</Link>
@@ -237,7 +312,9 @@ class PageLayout extends React.Component {
);
const PageToolbar = (
<Toolbar>
- <ToolbarGroup className={css(accessibleStyles.screenReader, accessibleStyles.visibleOnLg)}>
+ <ToolbarGroup
+ className={css(accessibleStyles.screenReader, accessibleStyles.visibleOnLg)}
+ >
<ToolbarItem>
<Button
id="connectButton"
@@ -253,7 +330,9 @@ class PageLayout extends React.Component {
</ToolbarItem>
</ToolbarGroup>
<ToolbarGroup>
- <ToolbarItem className={css(accessibleStyles.screenReader, accessibleStyles.visibleOnMd)}>
+ <ToolbarItem
+ className={css(accessibleStyles.screenReader, accessibleStyles.visibleOnMd)}
+ >
<DropdownToggle className="user-button" onToggle={this.onDropdownToggle}>
{this.state.user}
</DropdownToggle>
@@ -281,7 +360,9 @@ class PageLayout extends React.Component {
/>
);
const pageId = "main-content-page-layout-manual-nav";
- const PageSkipToContent = <SkipToContent href={`#${pageId}`}>Skip to Content</SkipToContent>;
+ const PageSkipToContent = (
+ <SkipToContent href={`#${pageId}`}>Skip to Content</SkipToContent>
+ );
const sidebar = PageNav => {
if (this.state.connected) {
@@ -312,26 +393,19 @@ class PageLayout extends React.Component {
{...more}
/>
) : (
- <Redirect to={{ pathname: "/login", state: { from: props.location } }} />
+ <Redirect
+ to={{
+ pathname: `/login${this.state.connecting ? "/connecting" : ""}`,
+ state: { from: props.location }
+ }}
+ />
)
}
/>
);
- // When we need to display a different component(page),
- // we render a <Redirect> object
- const redirectAfterConnect = () => {
- let { connectPath } = this.state;
- if (connectPath !== "") {
- if (connectPath === "/login") connectPath = "/";
- this.lastConnectPath = connectPath;
- return <Redirect to={connectPath} />;
- }
- return <React.Fragment />;
- };
-
const connectForm = () => {
- return (
+ return this.state.isConnectFormOpen ? (
<ConnectForm
service={this.service}
isConnectFormOpen={this.state.isConnectFormOpen}
@@ -341,9 +415,22 @@ class PageLayout extends React.Component {
isConnected={this.state.connected}
fromLayout={true}
/>
+ ) : (
+ <React.Fragment />
);
};
+ // When we need to display a different component(page),
+ // we render a <Redirect> object
+ const redirectAfterConnect = () => {
+ if (this.state.connected && this.redirect) {
+ this.redirect = false;
+ return <Redirect to={this.props.location.pathname} />;
+ } else {
+ return <React.Fragment />;
+ }
+ };
+
return (
<Router>
{redirectAfterConnect()}
@@ -356,10 +443,25 @@ class PageLayout extends React.Component {
>
{connectForm()}
<Switch>
- <PrivateRoute path="/" exact component={DashboardPage} />
- <PrivateRoute path="/dashboard" component={DashboardPage} />
+ <PrivateRoute
+ path="/"
+ exact
+ throughputChartData={this.throughputChartData}
+ inflightChartData={this.inflightChartData}
+ component={DashboardPage}
+ />
+ <PrivateRoute
+ path="/dashboard"
+ throughputChartData={this.throughputChartData}
+ inflightChartData={this.inflightChartData}
+ component={DashboardPage}
+ />
<PrivateRoute path="/overview/:entity" component={OverviewPage} />
- <PrivateRoute path="/details" schema={this.schema} component={DetailsTablePage} />
+ <PrivateRoute
+ path="/details"
+ schema={this.schema}
+ component={DetailsTablePage}
+ />
<PrivateRoute path="/topology" component={TopologyPage} />
<PrivateRoute path="/flow" component={MessageFlowPage} />
<PrivateRoute path="/logs" component={LogDetails} />
@@ -370,6 +472,15 @@ class PageLayout extends React.Component {
render={props => (
<ConnectPage
{...props}
+ connecting={this.state.connecting}
+ connectingTitle={
+ this.state.connecting ? "Attempting to auto connect" : undefined
+ }
+ connectingMessage={
+ this.state.connecting
+ ? `Trying to connect to ${window.location.hostname}:${window.location.port}`
+ : undefined
+ }
fromPath={"/"}
service={this.service}
config={this.props.config}
diff --git a/console/react/src/overview/dashboard/layout.test.js b/console/react/src/overview/dashboard/layout.test.js
new file mode 100644
index 0000000..b8edfb1
--- /dev/null
+++ b/console/react/src/overview/dashboard/layout.test.js
@@ -0,0 +1,76 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import React from "react";
+import { render } from "@testing-library/react";
+import { service } from "../../serviceTest";
+import PageLayout from "./layout";
+
+it("renders the correct title", async () => {
+ const title = "Test Layout Page";
+ const props = {
+ config: { title: title },
+ service,
+ history: { push: () => {}, replace: () => {} },
+ location: { pathname: "/dashboard" }
+ };
+
+ const { getAllByText } = render(<PageLayout {...props} />);
+
+ // the correct title should be found
+ expect(getAllByText(title));
+});
+
+it("calls some utility functions", () => {
+ let name = service.utilities.clientName({});
+ expect(name).toEqual("client");
+
+ name = service.utilities.clientName({ container: "test-container" });
+ expect(name).toEqual("test-container");
+
+ name = service.utilities.clientName({ properties: { product: "test-product" } });
+ expect(name).toEqual("test-product");
+
+ let addr = service.utilities.addr_class();
+ expect(addr).toEqual("-");
+ addr = service.utilities.addr_class("Mtest");
+ expect(addr).toEqual("mobile");
+ addr = service.utilities.addr_class("Atest");
+ expect(addr).toEqual("area");
+ addr = service.utilities.addr_class("Rtest");
+ expect(addr).toEqual("router");
+ addr = service.utilities.addr_class("Ltest");
+ expect(addr).toEqual("local");
+ addr = service.utilities.addr_class("Htest");
+ expect(addr).toEqual("edge");
+ addr = service.utilities.addr_class("Ztest");
+ expect(addr).toEqual("unknown: Z");
+
+ let sec = service.utilities.connSecurity({});
+ expect(sec).toEqual("no-security");
+ sec = service.utilities.connSecurity({ isEncrypted: true, sasl: "GSSAPI" });
+ expect(sec).toEqual("Kerberos");
+ sec = service.utilities.connSecurity({
+ isEncrypted: true,
+ sasl: "",
+ sslProto: "https",
+ sslCipher: "test"
+ });
+ expect(sec).toEqual("https(test)");
+});
diff --git a/console/react/src/notificationDrawer.js b/console/react/src/overview/dashboard/notificationDrawer.js
similarity index 91%
rename from console/react/src/notificationDrawer.js
rename to console/react/src/overview/dashboard/notificationDrawer.js
index 9a947c5..ccd6cf5 100644
--- a/console/react/src/notificationDrawer.js
+++ b/console/react/src/overview/dashboard/notificationDrawer.js
@@ -34,13 +34,13 @@ import {
TimesIcon
} from "@patternfly/react-icons";
import AlertList from "./alertList";
-import { safePlural } from "./qdrGlobals";
+import { safePlural } from "../../common/qdrGlobals";
class NotificationDrawer extends React.Component {
constructor(props) {
super(props);
this.state = {
- isShown: false, // is the drawer shown
+ isShown: false, // is the drawer shown
expanded: false, // is the drawer wide
isAnyUnread: false,
accordionSections: {
@@ -78,7 +78,7 @@ class NotificationDrawer extends React.Component {
}
};
- addNotification = ({ section, message, timestamp, severity }) => {
+ addNotification = ({ section, message, timestamp, severity, silent }) => {
const { accordionSections } = this.state;
const event = { message, timestamp, severity };
event.date = timestamp.toLocaleDateString(undefined, {
@@ -93,7 +93,7 @@ class NotificationDrawer extends React.Component {
});
event.isRead = false;
accordionSections[section].events.unshift(event);
- if (this.alertListRef) {
+ if (this.alertListRef && !silent) {
this.alertListRef.addAlert(severity, message);
}
this.setState({
@@ -124,8 +124,7 @@ class NotificationDrawer extends React.Component {
let isAnyUnread = false;
for (let sectionKey in accordionSections) {
isAnyUnread =
- isAnyUnread ||
- accordionSections[sectionKey].events.some(e => !e.isRead);
+ isAnyUnread || accordionSections[sectionKey].events.some(e => !e.isRead);
}
this.setState({ accordionSections, isAnyUnread });
};
@@ -156,11 +155,7 @@ class NotificationDrawer extends React.Component {
const DrawerTitle = (
<div className="drawer-pf-title">
<Button variant="plain" aria-label="expand" onClick={this.toggleExpand}>
- {this.state.expanded ? (
- <AngleDoubleRightIcon />
- ) : (
- <AngleDoubleLeftIcon />
- )}
+ {this.state.expanded ? <AngleDoubleRightIcon /> : <AngleDoubleLeftIcon />}
</Button>
<h3 className="text-center">Notifications Drawer</h3>
<Button variant="plain" aria-label="close" onClick={this.close}>
@@ -202,7 +197,10 @@ class NotificationDrawer extends React.Component {
{Object.keys(this.state.accordionSections).map(sectionKey => {
const section = this.state.accordionSections[sectionKey];
return (
- <AccordionItem aria-label="notification-item" key={`${sectionKey}-item`}>
+ <AccordionItem
+ aria-label="notification-item"
+ key={`${sectionKey}-item`}
+ >
<AccordionToggle
onClick={() => this.toggleDrawer(sectionKey)}
isExpanded={section.isOpen}
@@ -212,10 +210,10 @@ class NotificationDrawer extends React.Component {
{section.title}
<span className="panel-counter">{`${
section.events.filter(e => !e.isRead).length
- } new ${safePlural(
- section.events.filter(e => !e.isRead).length,
- "event"
- )}`}</span>
+ } new ${safePlural(
+ section.events.filter(e => !e.isRead).length,
+ "event"
+ )}`}</span>
</AccordionToggle>
<AccordionContent
key={`${sectionKey}-content`}
@@ -225,7 +223,7 @@ class NotificationDrawer extends React.Component {
<div
className={`panel-body ${
section.events.length === 0 ? "hidden" : ""
- }`}
+ }`}
>
{section.events.map((event, i) => {
return (
@@ -233,7 +231,7 @@ class NotificationDrawer extends React.Component {
key={`${sectionKey}-event-${i}`}
className={`drawer-pf-notification ${
event.isRead ? "" : "unread"
- }`}
+ }`}
onClick={() => this.markAsRead(event)}
>
{severityIcon(event)}
@@ -253,7 +251,7 @@ class NotificationDrawer extends React.Component {
<div
className={`blank-slate-pf ${
section.events.length === 0 ? "" : "hidden"
- }`}
+ }`}
>
<div className="blank-slate-pf-icon">
<span className="pficon pficon-info"></span>
@@ -263,13 +261,13 @@ class NotificationDrawer extends React.Component {
<div
className={`drawer-pf-action ${
section.events.length > 0 ? "" : "hidden"
- }`}
+ }`}
>
<div className="drawer-pf-action-link">
<button
className={`btn btn-link ${
this.hasUnread(section) ? "" : "disabled"
- }`}
+ }`}
onClick={() => this.markAllRead(sectionKey)}
>
Mark All Read
diff --git a/console/react/src/overview/dashboard/notificationDrawer.test.js b/console/react/src/overview/dashboard/notificationDrawer.test.js
new file mode 100644
index 0000000..ecd540b
--- /dev/null
+++ b/console/react/src/overview/dashboard/notificationDrawer.test.js
@@ -0,0 +1,50 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+import React from "react";
+import { render, fireEvent } from "@testing-library/react";
+import NotificationDrawer from "./notificationDrawer";
+
+it("renders without crashing", () => {
+ render(<NotificationDrawer />);
+});
+
+it("renders a notification icon", () => {
+ let notificationRef = null;
+ const { getByLabelText, getByText } = render(
+ <NotificationDrawer ref={el => (notificationRef = el)} />
+ );
+
+ // the notifications icon should be present
+ const notificationIcon = getByLabelText("Notifications");
+ expect(notificationIcon).toBeInTheDocument();
+
+ // add a notification
+ const section = "action";
+ const message = "test message";
+ const timestamp = new Date();
+ const severity = "info";
+ notificationRef.addNotification({ section, message, timestamp, severity });
+
+ // click the notification icon
+ fireEvent.click(notificationIcon);
+
+ // there should now be a single notification-item
+ expect(getByText("1 new event")).toBeInTheDocument();
+});
diff --git a/console/react/src/overview/dashboard/throughputChart.js b/console/react/src/overview/dashboard/throughputChart.js
index 291e75e..6600df4 100644
--- a/console/react/src/overview/dashboard/throughputChart.js
+++ b/console/react/src/overview/dashboard/throughputChart.js
@@ -25,26 +25,8 @@ class ThroughputChart extends ChartBase {
this.title = "Deliveries per sec";
this.color = "#99C2EB"; //ChartThemeColor.blue;
this.setStyle(this.color);
- this.isRate = true;
this.ariaLabel = "throughput-chart";
}
-
- updateData = () => {
- this.props.service.management.topology.fetchAllEntities(
- {
- entity: "router",
- attrs: ["deliveriesEgress"]
- },
- results => {
- let deliveries = 0;
- for (let id in results) {
- const aresult = results[id]["router"];
- deliveries += parseInt(aresult.results[0]);
- }
- this.addData(deliveries);
- }
- );
- };
}
export default ThroughputChart;
diff --git a/console/react/src/overview/dashboard/throughputChart.test.js b/console/react/src/overview/dashboard/throughputChart.test.js
index e74f9b1..2d0c41d 100644
--- a/console/react/src/overview/dashboard/throughputChart.test.js
+++ b/console/react/src/overview/dashboard/throughputChart.test.js
@@ -1,15 +1,39 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
-import { render } from '@testing-library/react';
+import { render } from "@testing-library/react";
+import { service, login, TEST_PORT } from "../../serviceTest";
+import ThroughputChartData from "./throughputData";
import ThroughputChart from "./throughputChart";
-import { mockService } from "../../qdrService.mock";
-it("renders the ThroughputChart component", () => {
+it("renders the ThroughputChart component", async () => {
const props = {
- service: mockService({})
- }
- const { getByLabelText, queryByLabelText } = render(
- <ThroughputChart {...props} />
- )
+ service,
+ chartData: new ThroughputChartData(service)
+ };
+
+ if (!TEST_PORT) console.log("using mock service");
+ await login();
+ expect(service.management.connection.is_connected()).toBe(true);
+
+ const { getByLabelText, queryByLabelText } = render(<ThroughputChart {...props} />);
// the component should initially render
// blank until it gets the contianer's width.
diff --git a/console/react/src/overview/dashboard/throughputChart.js b/console/react/src/overview/dashboard/throughputData.js
similarity index 74%
copy from console/react/src/overview/dashboard/throughputChart.js
copy to console/react/src/overview/dashboard/throughputData.js
index 291e75e..4c02d9b 100644
--- a/console/react/src/overview/dashboard/throughputChart.js
+++ b/console/react/src/overview/dashboard/throughputData.js
@@ -17,25 +17,28 @@ specific language governing permissions and limitations
under the License.
*/
-import ChartBase from "./chartBase";
+import ChartData from "./chartData";
-class ThroughputChart extends ChartBase {
- constructor(props) {
- super(props);
- this.title = "Deliveries per sec";
- this.color = "#99C2EB"; //ChartThemeColor.blue;
- this.setStyle(this.color);
+class ThroughputData extends ChartData {
+ constructor(service) {
+ super(service);
this.isRate = true;
- this.ariaLabel = "throughput-chart";
+ this.running = true;
}
+ stop = () => {
+ this.running = false;
+ };
+
updateData = () => {
- this.props.service.management.topology.fetchAllEntities(
+ if (!this.service.management.connection.is_connected()) return;
+ this.service.management.topology.fetchAllEntities(
{
entity: "router",
attrs: ["deliveriesEgress"]
},
results => {
+ if (!this.running) return;
let deliveries = 0;
for (let id in results) {
const aresult = results[id]["router"];
@@ -47,4 +50,4 @@ class ThroughputChart extends ChartBase {
};
}
-export default ThroughputChart;
+export default ThroughputData;
diff --git a/console/react/src/overview/dataSources/connectionData.js b/console/react/src/overview/dataSources/connectionData.js
index 4942c7b..e5225cf 100644
--- a/console/react/src/overview/dataSources/connectionData.js
+++ b/console/react/src/overview/dataSources/connectionData.js
@@ -17,7 +17,7 @@ specific language governing permissions and limitations
under the License.
*/
-import ConnectionClose from "../../connectionClose";
+import ConnectionClose from "../../common/connectionClose";
class ConnectionData {
constructor(service) {
@@ -56,10 +56,7 @@ class ConnectionData {
const result = record.results.find(
r => r[identityIndex] === currentRecord.identity
);
- let connection = this.service.utilities.flatten(
- record.attributeNames,
- result
- );
+ let connection = this.service.utilities.flatten(record.attributeNames, result);
connection = this.service.utilities.formatAttributes(
connection,
schema.entityTypes["connection"]
@@ -100,8 +97,7 @@ class ConnectionData {
let sec = "no-security";
if (connection.isEncrypted) {
if (sasl === "GSSAPI") sec = "Kerberos";
- else
- sec = connection.sslProto + "(" + connection.sslCipher + ")";
+ else sec = connection.sslProto + "(" + connection.sslCipher + ")";
}
let host = connection.host;
diff --git a/console/react/src/overview/overviewPage.js b/console/react/src/overview/overviewPage.js
index 023e37d..5268222 100644
--- a/console/react/src/overview/overviewPage.js
+++ b/console/react/src/overview/overviewPage.js
@@ -29,7 +29,7 @@ import {
import { Card, CardBody } from "@patternfly/react-core";
import OverviewTable from "./overviewTable";
-import Updated from "../updated";
+import Updated from "../common/updated";
class OverviewPage extends React.Component {
constructor(props) {
diff --git a/console/react/src/overview/overviewPage.test.js b/console/react/src/overview/overviewPage.test.js
index 6edafb9..bc2d0e8 100644
--- a/console/react/src/overview/overviewPage.test.js
+++ b/console/react/src/overview/overviewPage.test.js
@@ -1,18 +1,87 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
-import { render } from '@testing-library/react';
-import { mockService } from "../qdrService.mock";
+import { render } from "@testing-library/react";
+import { service, login, TEST_PORT } from "../serviceTest";
import OverviewPage from "./overviewPage";
-it("renders the overview page", () => {
+it("renders the overview connections page", async () => {
+ const entity = "connections";
+ const props = {
+ service,
+ location: { pathname: `/overview/${entity}` },
+ lastUpdated: () => {}
+ };
+
+ if (!TEST_PORT) console.log("using mock service");
+ await login();
+ expect(service.management.connection.is_connected()).toBe(true);
+
+ const { getByLabelText } = render(<OverviewPage {...props} />);
+ expect(getByLabelText(entity)).toBeInTheDocument();
+});
+
+it("renders the overview logs page", async () => {
const entity = "logs";
const props = {
- service: mockService({}),
+ service,
+ location: { pathname: `/overview/${entity}` },
+ lastUpdated: () => {}
+ };
+
+ const { getByLabelText } = render(<OverviewPage {...props} />);
+ expect(getByLabelText(entity)).toBeInTheDocument();
+});
+
+it("renders the overview links page", async () => {
+ const entity = "links";
+ const props = {
+ service,
+ location: { pathname: `/overview/${entity}` },
+ lastUpdated: () => {}
+ };
+
+ const { getByLabelText } = render(<OverviewPage {...props} />);
+ expect(getByLabelText(entity)).toBeInTheDocument();
+});
+
+it("renders the overview routers page", async () => {
+ const entity = "routers";
+ const props = {
+ service,
+ location: { pathname: `/overview/${entity}` },
+ lastUpdated: () => {}
+ };
+
+ const { getByLabelText } = render(<OverviewPage {...props} />);
+ expect(getByLabelText(entity)).toBeInTheDocument();
+});
+
+it("renders the overview addresses page", async () => {
+ const entity = "addresses";
+ const props = {
+ service,
location: { pathname: `/overview/${entity}` },
- lastUpdated: () => { }
- }
+ lastUpdated: () => {}
+ };
- const { getByTestId } = render(
- <OverviewPage {...props} />
- );
- expect(getByTestId("overview-page")).toBeInTheDocument();
+ const { getByLabelText } = render(<OverviewPage {...props} />);
+ expect(getByLabelText(entity)).toBeInTheDocument();
});
diff --git a/console/react/src/overview/overviewTable.js b/console/react/src/overview/overviewTable.js
index e412370..2832876 100644
--- a/console/react/src/overview/overviewTable.js
+++ b/console/react/src/overview/overviewTable.js
@@ -28,16 +28,16 @@ import {
} from "@patternfly/react-table";
import { Button, Pagination } from "@patternfly/react-core";
import { Redirect } from "react-router-dom";
-import TableToolbar from "../tableToolbar";
+import TableToolbar from "../common/tableToolbar";
import { dataMap } from "./entityData";
// If the breadcrumb on the details page was used to return to this page,
// we will have saved state info in props.location.state
const propFromLocation = (props, which, defaultValue) =>
props &&
- props.location &&
- props.location.state &&
- typeof props.location.state[which] !== "undefined"
+ props.location &&
+ props.location.state &&
+ typeof props.location.state[which] !== "undefined"
? props.location.state[which]
: defaultValue;
@@ -129,10 +129,7 @@ class OverviewTable extends React.Component {
detailLink = (value, extraInfo) => {
return (
- <Button
- className="link-button"
- onClick={() => this.detailClick(value, extraInfo)}
- >
+ <Button className="link-button" onClick={() => this.detailClick(value, extraInfo)}>
{value}
</Button>
);
@@ -282,8 +279,7 @@ class OverviewTable extends React.Component {
return (
<Redirect
to={{
- pathname:
- (this.dataSource && this.dataSource.detailPath) || "/details",
+ pathname: (this.dataSource && this.dataSource.detailPath) || "/details",
state: this.state.redirectState
}}
/>
diff --git a/console/react/src/overview/overviewTable.test.js b/console/react/src/overview/overviewTable.test.js
deleted file mode 100644
index d8e119e..0000000
--- a/console/react/src/overview/overviewTable.test.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import React from "react";
-import { render } from '@testing-library/react';
-import OverviewTable from "./overviewTable";
-import { mockService } from "../qdrService.mock";
-
-it("renders the OverviewTable component", () => {
- const entity = "routers";
- const props = {
- service: mockService({}),
- location: { pathname: `/overview/${entity}` },
- lastUpdated: () => { }
- }
- const { getByLabelText } = render(
- <OverviewTable {...props} />
- )
-
- // make sure it rendered the component
- expect(getByLabelText(entity)).toBeInTheDocument();
-});
diff --git a/console/react/src/pleaseWait.js b/console/react/src/pleaseWait.js
deleted file mode 100644
index 228538b..0000000
--- a/console/react/src/pleaseWait.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import React from "react";
-import { TextContent, Text, TextVariants } from "@patternfly/react-core";
-import PropTypes from "prop-types";
-
-import { CogIcon } from "@patternfly/react-icons";
-
-class PleaseWait extends React.Component {
- static propTypes = {
- isOpen: PropTypes.bool.isRequired,
- title: PropTypes.string.isRequired,
- message: PropTypes.string.isRequired
- };
-
- state = {};
-
- render() {
- return (
- this.props.isOpen && (
- <div className="topic-creating-wrapper">
- <div id="topicCogWrapper">
- <CogIcon
- id="topicCogMain"
- className="spinning-clockwise"
- color="#AAAAAA"
- />
- <CogIcon
- id="topicCogUpper"
- className="spinning-cclockwise"
- color="#AAAAAA"
- />
- <CogIcon
- id="topicCogLower"
- className="spinning-cclockwise"
- color="#AAAAAA"
- />
- </div>
- <TextContent>
- <Text component={TextVariants.h3}>{this.props.title}</Text>
- </TextContent>
- <TextContent>
- <Text className="topic-creating-message" component={TextVariants.p}>
- {this.props.message}
- </Text>
- </TextContent>
- </div>
- )
- );
- }
-}
-
-export default PleaseWait;
diff --git a/console/react/src/qdrPopup.js b/console/react/src/qdrPopup.js
deleted file mode 100644
index ba1ad28..0000000
--- a/console/react/src/qdrPopup.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import React from "react";
-
-class QDRPopup extends React.Component {
- constructor(props) {
- super(props);
- this.state = {};
- }
-
- render() {
- return <div aria-label="popup" dangerouslySetInnerHTML={{ __html: this.props.content }} />;
- }
-}
-
-export default QDRPopup;
diff --git a/console/react/src/qdrPopup.test.js b/console/react/src/qdrPopup.test.js
deleted file mode 100644
index c9c18c5..0000000
--- a/console/react/src/qdrPopup.test.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from "react";
-import { render } from '@testing-library/react';
-import QDRPopup from "./qdrPopup";
-
-it("the popup component renders HTML", () => {
- const text = "Hello world";
- const props = {
- content: `<h1>${text}</h1>`
- }
- const { getByText, getByLabelText } = render(
- <QDRPopup {...props} />
- );
- expect(getByLabelText("popup")).toBeInTheDocument()
- expect(getByText("Hello world")).toBeInTheDocument();
-});
diff --git a/console/react/src/updated.js b/console/react/src/serviceTest.js
similarity index 64%
copy from console/react/src/updated.js
copy to console/react/src/serviceTest.js
index e762d8e..ef14533 100644
--- a/console/react/src/updated.js
+++ b/console/react/src/serviceTest.js
@@ -17,23 +17,12 @@ specific language governing permissions and limitations
under the License.
*/
-import React, { Component } from "react";
+import { mockService } from "../test_data/qdrService.mock";
+import { QDRService } from "./common/qdrService";
-class Updated extends Component {
- constructor(props) {
- super(props);
- this.state = {};
- }
+const TEST_PORT = process.env.TEST_PORT;
+const service = TEST_PORT ? new QDRService() : mockService({});
- render() {
- return (
- <pre aria-label="last-updated" data-pf-content="true" className="overview-loading">
- {`Updated ${this.props.service.utilities.strDate(
- this.props.lastUpdated
- )}`}
- </pre>
- );
- }
-}
-
-export default Updated;
+const login = () =>
+ service.connect({ address: "localhost", port: TEST_PORT, reconnect: false });
+export { service, TEST_PORT, login };
diff --git a/console/react/src/serviceWorker.js b/console/react/src/serviceWorker.js
deleted file mode 100644
index f8c7e50..0000000
--- a/console/react/src/serviceWorker.js
+++ /dev/null
@@ -1,135 +0,0 @@
-// This optional code is used to register a service worker.
-// register() is not called by default.
-
-// This lets the app load faster on subsequent visits in production, and gives
-// it offline capabilities. However, it also means that developers (and users)
-// will only see deployed updates on subsequent visits to a page, after all the
-// existing tabs open on the page have been closed, since previously cached
-// resources are updated in the background.
-
-// To learn more about the benefits of this model and instructions on how to
-// opt-in, read https://bit.ly/CRA-PWA
-
-const isLocalhost = Boolean(
- window.location.hostname === 'localhost' ||
- // [::1] is the IPv6 localhost address.
- window.location.hostname === '[::1]' ||
- // 127.0.0.1/8 is considered localhost for IPv4.
- window.location.hostname.match(
- /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
- )
-);
-
-export function register(config) {
- if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
- // The URL constructor is available in all browsers that support SW.
- const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
- if (publicUrl.origin !== window.location.origin) {
- // Our service worker won't work if PUBLIC_URL is on a different origin
- // from what our page is served on. This might happen if a CDN is used to
- // serve assets; see https://github.com/facebook/create-react-app/issues/2374
- return;
- }
-
- window.addEventListener('load', () => {
- const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
-
- if (isLocalhost) {
- // This is running on localhost. Let's check if a service worker still exists or not.
- checkValidServiceWorker(swUrl, config);
-
- // Add some additional logging to localhost, pointing developers to the
- // service worker/PWA documentation.
- navigator.serviceWorker.ready.then(() => {
- console.log(
- 'This web app is being served cache-first by a service ' +
- 'worker. To learn more, visit https://bit.ly/CRA-PWA'
- );
- });
- } else {
- // Is not localhost. Just register service worker
- registerValidSW(swUrl, config);
- }
- });
- }
-}
-
-function registerValidSW(swUrl, config) {
- navigator.serviceWorker
- .register(swUrl)
- .then(registration => {
- registration.onupdatefound = () => {
- const installingWorker = registration.installing;
- if (installingWorker == null) {
- return;
- }
- installingWorker.onstatechange = () => {
- if (installingWorker.state === 'installed') {
- if (navigator.serviceWorker.controller) {
- // At this point, the updated precached content has been fetched,
- // but the previous service worker will still serve the older
- // content until all client tabs are closed.
- console.log(
- 'New content is available and will be used when all ' +
- 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
- );
-
- // Execute callback
- if (config && config.onUpdate) {
- config.onUpdate(registration);
- }
- } else {
- // At this point, everything has been precached.
- // It's the perfect time to display a
- // "Content is cached for offline use." message.
- console.log('Content is cached for offline use.');
-
- // Execute callback
- if (config && config.onSuccess) {
- config.onSuccess(registration);
- }
- }
- }
- };
- };
- })
- .catch(error => {
- console.error('Error during service worker registration:', error);
- });
-}
-
-function checkValidServiceWorker(swUrl, config) {
- // Check if the service worker can be found. If it can't reload the page.
- fetch(swUrl)
- .then(response => {
- // Ensure service worker exists, and that we really are getting a JS file.
- const contentType = response.headers.get('content-type');
- if (
- response.status === 404 ||
- (contentType != null && contentType.indexOf('javascript') === -1)
- ) {
- // No service worker found. Probably a different app. Reload the page.
- navigator.serviceWorker.ready.then(registration => {
- registration.unregister().then(() => {
- window.location.reload();
- });
- });
- } else {
- // Service worker found. Proceed as normal.
- registerValidSW(swUrl, config);
- }
- })
- .catch(() => {
- console.log(
- 'No internet connection found. App is running in offline mode.'
- );
- });
-}
-
-export function unregister() {
- if ('serviceWorker' in navigator) {
- navigator.serviceWorker.ready.then(registration => {
- registration.unregister();
- });
- }
-}
diff --git a/console/react/src/setupTests.js b/console/react/src/setupTests.js
index a8be446..f3021dc 100644
--- a/console/react/src/setupTests.js
+++ b/console/react/src/setupTests.js
@@ -1,3 +1,23 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF 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.
+*/
+
// react-testing-library renders your components to document.body,
// this adds jest-dom's custom assertions
-import '@testing-library/jest-dom/extend-expect';
+import "@testing-library/jest-dom/extend-expect";
+import "jest-axe/extend-expect";
diff --git a/console/react/src/tableToolbar.test.js b/console/react/src/tableToolbar.test.js
deleted file mode 100644
index 634d26e..0000000
--- a/console/react/src/tableToolbar.test.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import React from "react";
-import { render, fireEvent } from '@testing-library/react';
-import TableToolbar from "./tableToolbar";
-
-it("should render tableToolbar", () => {
- let handleChangeFilterValueCalled = false;
- const props = {
- fields: [{ title: "field0" }, { title: "field1" }],
- filterBy: { value: "f" },
- handleChangeFilterValue: () => handleChangeFilterValueCalled = true,
- total: 2,
- page: 1,
- perPage: 1,
- onSetPage: () => { },
- onPerPageSelect: () => { }
- }
- const { getByLabelText } = render(
- <TableToolbar {...props} />
- );
- expect(getByLabelText("toolbar-pagination")).toBeInTheDocument()
- const filterInput = getByLabelText("search text input");
- expect(filterInput).toBeInTheDocument()
-
- fireEvent.change(filterInput, { target: { value: 'fi' } });
- expect(handleChangeFilterValueCalled).toBe(true);
-
- const paginationInput = getByLabelText("Current page");
- expect(paginationInput).toBeInTheDocument();
-});
diff --git a/console/react/src/topology/clientInfoComponent.js b/console/react/src/topology/clientInfoComponent.js
index b05462b..feb6e5f 100644
--- a/console/react/src/topology/clientInfoComponent.js
+++ b/console/react/src/topology/clientInfoComponent.js
@@ -29,7 +29,7 @@ import {
import { CodeBranchIcon } from "@patternfly/react-icons";
import DetailsTable from "./clientInfoDetailsComponent";
-import { utils } from "../amqp/utilities.js";
+import { utils } from "../common/amqp/utilities.js";
const { queue } = require("d3-queue");
class ClientInfoComponent extends Component {
diff --git a/console/react/src/updated.js b/console/react/src/topology/clientInfoDetailsComponent.js
similarity index 62%
rename from console/react/src/updated.js
rename to console/react/src/topology/clientInfoDetailsComponent.js
index e762d8e..5045309 100644
--- a/console/react/src/updated.js
+++ b/console/react/src/topology/clientInfoDetailsComponent.js
@@ -17,23 +17,27 @@ specific language governing permissions and limitations
under the License.
*/
-import React, { Component } from "react";
+import React from "react";
+import { Table, TableHeader, TableBody } from "@patternfly/react-table";
-class Updated extends Component {
+class DetailsTable extends React.Component {
constructor(props) {
super(props);
- this.state = {};
+ this.state = {
+ columns: ["Link type", "Addr", "Settle rate", "Delayed1", "Delayed10", "Usage"]
+ };
}
render() {
+ const { columns } = this.state;
+ let subRows = this.props.subRows || [];
return (
- <pre aria-label="last-updated" data-pf-content="true" className="overview-loading">
- {`Updated ${this.props.service.utilities.strDate(
- this.props.lastUpdated
- )}`}
- </pre>
+ <Table aria-label="client-info-details-table" cells={columns} rows={subRows}>
+ <TableHeader />
+ <TableBody />
+ </Table>
);
}
}
-export default Updated;
+export default DetailsTable;
diff --git a/console/react/src/topology/clientInfoDetailsComponent.jsx b/console/react/src/topology/clientInfoDetailsComponent.jsx
deleted file mode 100644
index 478467b..0000000
--- a/console/react/src/topology/clientInfoDetailsComponent.jsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from "react";
-import { Table, TableHeader, TableBody } from "@patternfly/react-table";
-
-class DetailsTable extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- columns: ["Link type", "Addr", "Settle rate", "Delayed1", "Delayed10", "Usage"]
- };
- }
-
- render() {
- const { columns } = this.state;
- let subRows = this.props.subRows || [];
- return (
- <Table aria-label="client-info-details-table" cells={columns} rows={subRows}>
- <TableHeader />
- <TableBody />
- </Table>
- );
- }
-}
-
-export default DetailsTable;
diff --git a/console/react/src/topology/contextMenu.js b/console/react/src/topology/contextMenu.js
index f68751d..abfb77a 100644
--- a/console/react/src/topology/contextMenu.js
+++ b/console/react/src/topology/contextMenu.js
@@ -18,7 +18,7 @@ under the License.
*/
import React, { Component } from "react";
-import ContextMenuComponent from "../contextMenuComponent";
+import ContextMenuComponent from "../common/contextMenuComponent";
class ContextMenu extends Component {
constructor(props) {
diff --git a/console/react/src/topology/legend.js b/console/react/src/topology/legend.js
index 82a49d7..76fbf1b 100644
--- a/console/react/src/topology/legend.js
+++ b/console/react/src/topology/legend.js
@@ -1,18 +1,21 @@
/*
- * Copyright 2018 Red Hat Inc.
- *
- * Licensed 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.
- */
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF 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 { Nodes } from "./nodes.js";
import { appendCircle, appendContent, appendTitle } from "./svgUtils.js";
@@ -71,8 +74,7 @@ const lookFor = [
role: "route-container",
title: "Qpid broker",
text: "Qpid broker",
- cmp: n =>
- n.nodeType === "route-container" && n.properties.product === "qpid-cpp",
+ cmp: n => n.nodeType === "route-container" && n.properties.product === "qpid-cpp",
props: { product: "qpid-cpp" }
},
{
@@ -80,8 +82,7 @@ const lookFor = [
title: "Service",
text: "Service",
cmp: n =>
- n.nodeType === "route-container" &&
- n.properties.product === "External Service",
+ n.nodeType === "route-container" && n.properties.product === "External Service",
props: { product: " External Service" }
}
];
@@ -99,10 +100,7 @@ export class Legend {
.attr("id", "svglegend")
.attr("xmlns", "http://www.w3.org/2000/svg")
.append("svg:g")
- .attr(
- "transform",
- `translate(${Nodes.maxRadius()}, ${Nodes.maxRadius()})`
- )
+ .attr("transform", `translate(${Nodes.maxRadius()}, ${Nodes.maxRadius()})`)
.selectAll("g");
}
diff --git a/console/react/src/topology/links.js b/console/react/src/topology/links.js
index 1e54288..b05663c 100644
--- a/console/react/src/topology/links.js
+++ b/console/react/src/topology/links.js
@@ -17,7 +17,7 @@ specific language governing permissions and limitations
under the License.
*/
-import { utils } from "../amqp/utilities.js";
+import { utils } from "../common/amqp/utilities.js";
class Link {
constructor(source, target, dir, cls, uid) {
@@ -29,15 +29,9 @@ class Link {
this.uid = uid;
}
markerId(end) {
- let selhigh = this.highlighted
- ? "highlighted"
- : this.selected
- ? "selected"
- : "";
- if (selhigh === "" && (!this.left && !this.right)) selhigh = "unknown";
- return `-${selhigh}-${
- end === "end" ? this.target.radius() : this.source.radius()
- }`;
+ let selhigh = this.highlighted ? "highlighted" : this.selected ? "selected" : "";
+ if (selhigh === "" && !this.left && !this.right) selhigh = "unknown";
+ return `-${selhigh}-${end === "end" ? this.target.radius() : this.source.radius()}`;
}
}
@@ -92,17 +86,11 @@ export class Links {
}
getPosition(name, nodes, source, client, height, localStorage) {
- let position = localStorage[name]
- ? JSON.parse(localStorage[name])
- : undefined;
+ let position = localStorage[name] ? JSON.parse(localStorage[name]) : undefined;
if (typeof position === "undefined") {
position = {
- x: Math.round(
- nodes.get(source).x + 40 * Math.sin(client / (Math.PI * 2.0))
- ),
- y: Math.round(
- nodes.get(source).y + 40 * Math.cos(client / (Math.PI * 2.0))
- ),
+ x: Math.round(nodes.get(source).x + 40 * Math.sin(client / (Math.PI * 2.0))),
+ y: Math.round(nodes.get(source).y + 40 * Math.cos(client / (Math.PI * 2.0))),
fixed: false,
animate: true
};
@@ -148,9 +136,7 @@ export class Links {
// we need a unique connection.container
if (connection.container === "") {
- connection.container = connection.name
- .replace("/", "")
- .replace(":", "-");
+ connection.container = connection.name.replace("/", "").replace(":", "-");
//utils.uuidv4();
}
// this is a connection to another interior router
diff --git a/console/react/src/topology/nodes.js b/console/react/src/topology/nodes.js
index dcad31c..1ae1337 100644
--- a/console/react/src/topology/nodes.js
+++ b/console/react/src/topology/nodes.js
@@ -17,7 +17,7 @@ specific language governing permissions and limitations
under the License.
*/
-import { utils } from "../amqp/utilities.js";
+import { utils } from "../common/amqp/utilities.js";
import * as d3 from "d3";
export class Node {
diff --git a/console/react/src/topology/svgUtils.js b/console/react/src/topology/svgUtils.js
index 873a0c4..c9d9477 100644
--- a/console/react/src/topology/svgUtils.js
+++ b/console/react/src/topology/svgUtils.js
@@ -1,21 +1,24 @@
/*
- * Copyright 2018 Red Hat Inc.
- *
- * Licensed 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.
- */
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF 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 { Nodes } from "./nodes.js";
-import { utils } from "../amqp/utilities.js";
+import { utils } from "../common/amqp/utilities.js";
// update the node's classes based on the node's data
export function updateState(circle) {
diff --git a/console/react/src/topology/topoUtils.js b/console/react/src/topology/topoUtils.js
index 1f04d05..58f1a5b 100644
--- a/console/react/src/topology/topoUtils.js
+++ b/console/react/src/topology/topoUtils.js
@@ -18,7 +18,7 @@ under the License.
*/
/* global Set */
-import { utils } from "../amqp/utilities.js";
+import { utils } from "../common/amqp/utilities.js";
// highlight the paths between the selected node and the hovered node
function findNextHopNode(from, d, nodeInfo, selected_node, nodes) {
@@ -43,15 +43,7 @@ function findNextHopNode(from, d, nodeInfo, selected_node, nodes) {
}
return null;
}
-export function nextHop(
- thisNode,
- d,
- nodes,
- links,
- nodeInfo,
- selected_node,
- cb
-) {
+export function nextHop(thisNode, d, nodes, links, nodeInfo, selected_node, cb) {
if (thisNode && thisNode !== d) {
let target = findNextHopNode(thisNode, d, nodeInfo, selected_node, nodes);
if (target) {
@@ -74,7 +66,7 @@ export function connectionPopupHTML(d, nodeInfo) {
return;
}
// return all of onode's connections that connecto to right
- let getConnsArray = function (onode, key, right) {
+ let getConnsArray = function(onode, key, right) {
if (right.normals) {
// if we want connections between a router and a client[s]
let connIds = new Set();
@@ -84,16 +76,16 @@ export function connectionPopupHTML(d, nodeInfo) {
if (normal.key === key) {
connIds.add(normal.connectionId);
} else if (normal.alsoConnectsTo) {
- normal.alsoConnectsTo.forEach(function (ac2) {
+ normal.alsoConnectsTo.forEach(function(ac2) {
if (ac2.key === key) connIds.add(ac2.connectionId);
});
}
}
return onode.connection.results
- .filter(function (result) {
+ .filter(function(result) {
return connIds.has(result[connIndex]);
})
- .map(function (c) {
+ .map(function(c) {
return utils.flatten(onode.connection.attributeNames, c);
});
} else {
@@ -102,20 +94,17 @@ export function connectionPopupHTML(d, nodeInfo) {
let containerIndex = onode.connection.attributeNames.indexOf("container");
let roleIndex = onode.connection.attributeNames.indexOf("role");
return onode.connection.results
- .filter(function (conn) {
- return (
- conn[containerIndex] === container &&
- conn[roleIndex] === "inter-router"
- );
+ .filter(function(conn) {
+ return conn[containerIndex] === container && conn[roleIndex] === "inter-router";
})
- .map(function (c) {
+ .map(function(c) {
return utils.flatten(onode.connection.attributeNames, c);
});
}
};
// construct HTML to be used in a popup when the mouse is moved over a link.
// The HTML is sanitized elsewhere before it is displayed
- let linksHTML = function (onode, conns) {
+ let linksHTML = function(onode, conns) {
const max_links = 10;
const fields = [
"deliveryCount",
@@ -126,13 +115,13 @@ export function connectionPopupHTML(d, nodeInfo) {
"modifiedCount"
];
// local function to determine if a link's connectionId is in any of the connections
- let isLinkFor = function (connectionId, conns) {
+ let isLinkFor = function(connectionId, conns) {
for (let c = 0; c < conns.length; c++) {
if (conns[c].identity === connectionId) return true;
}
return false;
};
- let fnJoin = function (ar, sepfn) {
+ let fnJoin = function(ar, sepfn) {
let out = "";
out = ar[0];
for (let i = 1; i < ar.length; i++) {
@@ -154,13 +143,7 @@ export function connectionPopupHTML(d, nodeInfo) {
if (isLinkFor(link.connectionId, conns)) {
if (link.owningAddr) hasAddress = true;
if (link.name) {
- let rates = utils.rates(
- link,
- fields,
- linkRateHistory,
- link.name,
- 1
- );
+ let rates = utils.rates(link, fields, linkRateHistory, link.name, 1);
// replace the raw value with the rate
for (let i = 0; i < fields.length; i++) {
if (rates[fields[i]] > 0) allZero = false;
@@ -172,14 +155,14 @@ export function connectionPopupHTML(d, nodeInfo) {
}
}
// we may need to limit the number of links displayed, so sort descending by the sum of the field values
- let sum = function (a) {
+ let sum = function(a) {
let s = 0;
for (let i = 0; i < fields.length; i++) {
s += a[fields[i]];
}
return s;
};
- links.sort(function (a, b) {
+ links.sort(function(a, b) {
let asum = sum(a);
let bsum = sum(b);
return asum < bsum ? 1 : asum > bsum ? -1 : 0;
@@ -200,15 +183,14 @@ export function connectionPopupHTML(d, nodeInfo) {
td.unshift("owningAddr");
}
- let rate_th = function (th) {
- let rth = th.map(function (t) {
+ let rate_th = function(th) {
+ let rth = th.map(function(t) {
if (t.endsWith("Count")) t = t.replace("Count", "Rate");
return utils.humanify(t);
});
return rth;
};
- HTML +=
- '<tr class="header"><td>' + rate_th(th).join("</td><td>") + "</td></tr>";
+ HTML += '<tr class="header"><td>' + rate_th(th).join("</td><td>") + "</td></tr>";
// add rows to the table for each link
for (let l = 0; l < links.length; l++) {
if (l >= max_links) {
@@ -216,14 +198,14 @@ export function connectionPopupHTML(d, nodeInfo) {
break;
}
let link = links[l];
- let vals = td.map(function (f) {
+ let vals = td.map(function(f) {
if (f === "owningAddr") {
let identity = utils.identity_clean(link.owningAddr);
return utils.addr_text(identity);
}
return link[f];
});
- let joinedVals = fnJoin(vals, function (v1, last) {
+ let joinedVals = fnJoin(vals, function(v1, last) {
return [
`</td><td${isNaN(+v1) ? "" : ' align="right"'}>`,
last ? v1 : utils.pretty(v1 || "0", ",.2f")
@@ -270,7 +252,8 @@ export function connectionPopupHTML(d, nodeInfo) {
export function getSizes(topologyRef) {
const gap = 5;
- let topoWidth = topologyRef.offsetWidth > 0 ? topologyRef.offsetWidth : window.innerWidth;
+ let topoWidth =
+ topologyRef.offsetWidth > 0 ? topologyRef.offsetWidth : window.innerWidth;
let width = topoWidth - gap;
let top = topologyRef.offsetTop;
let height = window.innerHeight - top - gap;
diff --git a/console/react/src/topology/topologyPage.test.js b/console/react/src/topology/topologyPage.test.js
index 2b99aed..f8d4ed2 100644
--- a/console/react/src/topology/topologyPage.test.js
+++ b/console/react/src/topology/topologyPage.test.js
@@ -1,6 +1,25 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import { render } from "@testing-library/react";
-import { mockService } from "../qdrService.mock";
+import { mockService } from "../../test_data/qdrService.mock";
import TopologyPage from "./topologyPage";
it("renders the TopologyPage component", () => {
diff --git a/console/react/src/topology/topologyToolbar.js b/console/react/src/topology/topologyToolbar.js
index d04d90c..071807f 100644
--- a/console/react/src/topology/topologyToolbar.js
+++ b/console/react/src/topology/topologyToolbar.js
@@ -1,15 +1,36 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import { Toolbar, ToolbarGroup, ToolbarItem } from "@patternfly/react-core";
import TrafficComponent from "./trafficComponent";
import MapComponent from "./mapComponent";
import ArrowsComponent from "./arrowsComponent";
-import DropdownPanel from "../dropdownPanel"
-
+import DropdownPanel from "../common/dropdownPanel";
class TopologyToolbar extends React.Component {
render() {
return (
- <Toolbar data-testid="topology-toolbar" className="pf-l-toolbar pf-u-justify-content-space-between pf-u-mx-xl pf-u-my-md">
+ <Toolbar
+ data-testid="topology-toolbar"
+ className="pf-l-toolbar pf-u-justify-content-space-between pf-u-mx-xl pf-u-my-md"
+ >
<ToolbarGroup>
<ToolbarItem className="pf-u-mr-md">
<DropdownPanel
@@ -18,9 +39,7 @@ class TopologyToolbar extends React.Component {
<TrafficComponent
addresses={this.props.legendOptions.traffic.addresses}
addressColors={this.props.legendOptions.traffic.addressColors}
- handleChangeTrafficAnimation={
- this.props.handleChangeTrafficAnimation
- }
+ handleChangeTrafficAnimation={this.props.handleChangeTrafficAnimation}
handleChangeTrafficFlowAddress={
this.props.handleChangeTrafficFlowAddress
}
diff --git a/console/react/src/topology/topologyToolbar.test.js b/console/react/src/topology/topologyToolbar.test.js
index 53be27e..317602b 100644
--- a/console/react/src/topology/topologyToolbar.test.js
+++ b/console/react/src/topology/topologyToolbar.test.js
@@ -1,8 +1,27 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
-import { render } from '@testing-library/react';
+import { render } from "@testing-library/react";
import TopologyToolbar from "./topologyToolbar";
-it('renders a TopologyToolbar', () => {
+it("renders a TopologyToolbar", () => {
const props = {
legendOptions: {
traffic: {
@@ -19,18 +38,15 @@ it('renders a TopologyToolbar', () => {
arrows: { routerArrows: true, clientArrows: true }
},
mapOptions: { areaColor: "#EAEAEA", oceanColor: "#EBAEBA" },
- handleChangeTrafficAnimation: () => { },
- handleChangeTrafficFlowAddress: () => { },
- handleHoverAddress: () => { },
- handleUpdateMapColor: () => { },
- handleUpdateMapShown: () => { },
- handleChangeArrows: () => { }
- }
- const {
- getByTestId
- } = render(<TopologyToolbar {...props} />);
+ handleChangeTrafficAnimation: () => {},
+ handleChangeTrafficFlowAddress: () => {},
+ handleHoverAddress: () => {},
+ handleUpdateMapColor: () => {},
+ handleUpdateMapShown: () => {},
+ handleChangeArrows: () => {}
+ };
+ const { getByTestId } = render(<TopologyToolbar {...props} />);
// the toolbar should be present
expect(getByTestId("topology-toolbar")).toBeInTheDocument();
-
-})
+});
diff --git a/console/react/src/topology/topologyViewer.js b/console/react/src/topology/topologyViewer.js
index 9d7a0af..5871970 100644
--- a/console/react/src/topology/topologyViewer.js
+++ b/console/react/src/topology/topologyViewer.js
@@ -26,14 +26,14 @@ import {
TopologySideBar
} from "@patternfly/react-topology";
-import QDRPopup from "../qdrPopup";
+import QDRPopup from "../common/qdrPopup";
import { Traffic } from "./traffic.js";
import { separateAddresses } from "../chord/filters.js";
import { Nodes } from "./nodes.js";
import { Links } from "./links.js";
import { nextHop, connectionPopupHTML, getSizes } from "./topoUtils.js";
import { BackgroundMap } from "./map.js";
-import { utils } from "../amqp/utilities.js";
+import { utils } from "../common/amqp/utilities.js";
import { Legend } from "./legend.js";
import RouterInfoComponent from "./routerInfoComponent";
import ClientInfoComponent from "./clientInfoComponent";
@@ -47,7 +47,7 @@ import {
addDefs,
updateState
} from "./svgUtils.js";
-import { QDRLogger } from "../qdrGlobals";
+import { QDRLogger } from "../common/qdrGlobals";
const TOPOOPTIONSKEY = "topologyLegendOptions";
class TopologyPage extends Component {
diff --git a/console/react/src/topology/topologyViewer.test.js b/console/react/src/topology/topologyViewer.test.js
index 382b950..a2a093e 100644
--- a/console/react/src/topology/topologyViewer.test.js
+++ b/console/react/src/topology/topologyViewer.test.js
@@ -1,6 +1,25 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
import React from "react";
import { render, fireEvent, waitForElement } from "@testing-library/react";
-import { mockService } from "../qdrService.mock";
+import { service, login } from "../serviceTest";
import TopologyViewer from "./topologyViewer";
import * as world from "../../public/data/countries.json";
@@ -11,8 +30,11 @@ it("renders the TopologyViewer component", async () => {
});
});
const props = {
- service: mockService({})
+ service
};
+
+ await login();
+
const { getByLabelText, getByText, getByTestId } = render(
<TopologyViewer {...props} />
);
@@ -49,12 +71,24 @@ it("renders the TopologyViewer component", async () => {
// close the modal
fireEvent.click(getByLabelText("Close"));
+ // make sure the legend opens
const legendButton = getByText("topology-legend");
expect(legendButton).toBeInTheDocument();
-
fireEvent.click(legendButton);
fireEvent.click(getByLabelText("Close"));
+ // turn on the traffic animation
+
+ // dropdown the traffic panel
fireEvent.contextMenu(client);
fireEvent.click(pfTopologyView);
+ const trafficButton = getByLabelText("button-for-Traffic");
+ expect(trafficButton).toBeInTheDocument();
+ fireEvent.click(trafficButton);
+
+ // click on the show traffic checkbox
+ const trafficCheckbox = getByLabelText("show traffic by address");
+ fireEvent.click(trafficCheckbox);
+ // the address dot should be there
+ await waitForElement(() => getByText("toB"));
});
diff --git a/console/react/src/topology/traffic.js b/console/react/src/topology/traffic.js
index ed49d96..b15b9fa 100644
--- a/console/react/src/topology/traffic.js
+++ b/console/react/src/topology/traffic.js
@@ -21,7 +21,7 @@ import * as d3 from "d3";
import { ChordData } from "../chord/data.js";
import { MIN_CHORD_THRESHOLD } from "../chord/matrix.js";
import { nextHop } from "./topoUtils.js";
-import { utils } from "../amqp/utilities.js";
+import { utils } from "../common/amqp/utilities.js";
const transitionDuration = 1000;
//const CHORDFILTERKEY = "chordFilter";
@@ -76,9 +76,7 @@ export class Traffic {
addAnimationType(type, converter, radius) {
if (!this.viss.some(v => v.type === type)) {
this.viss.push(
- type === "dots"
- ? new Dots(this, converter, radius)
- : new Congestion(this)
+ type === "dots" ? new Dots(this, converter, radius) : new Congestion(this)
);
}
this.start();
@@ -125,10 +123,7 @@ class Congestion extends TrafficAnimation {
if (attrIndex >= 0) {
for (let i = 0; i < node[entity].results.length; i++) {
if (node[entity].results[i][attrIndex] === value) {
- return utils.flatten(
- node[entity].attributeNames,
- node[entity].results[i]
- );
+ return utils.flatten(node[entity].attributeNames, node[entity].results[i]);
}
}
}
@@ -166,10 +161,7 @@ class Congestion extends TrafficAnimation {
nodeLinks.results[n]
);
if (link.linkType !== "router-control") {
- let f = self.nodeIndexFor(
- nodes,
- srv.utilities.nameFromId(nodeId)
- );
+ let f = self.nodeIndexFor(nodes, srv.utilities.nameFromId(nodeId));
let connection = self.findResult(
node,
"connection",
@@ -181,11 +173,9 @@ class Congestion extends TrafficAnimation {
let little = Math.min(f, t);
let big = Math.max(f, t);
if (little >= 0) {
- let key = [
- "#path",
- nodes[little].uid(srv),
- nodes[big].uid(srv)
- ].join("-");
+ let key = ["#path", nodes[little].uid(srv), nodes[big].uid(srv)].join(
+ "-"
+ );
if (!links[key]) links[key] = [];
links[key].push(link);
}
@@ -295,8 +285,7 @@ class Dots extends TrafficAnimation {
updateAddresses() {
this.excludedAddresses = [];
for (const address in this.traffic.addresses) {
- if (!this.traffic.addresses[address])
- this.excludedAddresses.push(address);
+ if (!this.traffic.addresses[address]) this.excludedAddresses.push(address);
}
if (this.chordData) {
this.chordData.setFilter(this.excludedAddresses);
@@ -423,8 +412,10 @@ class Dots extends TrafficAnimation {
this.addressIndex(this, ahop.address) +
(ahop.back ? "b" : "");
let path = d3.select("#path" + pathId);
- // start the animation. If the animation is already running, this will have no effect
- this.startAnimation(path, flowId, ahop, flowScale(ahop.val));
+ if (!path.empty()) {
+ // start the animation. If the animation is already running, this will have no effect
+ this.startAnimation(path, flowId, ahop, flowScale(ahop.val));
+ }
keep[flowId] = true;
}
}
@@ -446,10 +437,7 @@ class Dots extends TrafficAnimation {
.transition()
.ease("easeLinear")
.duration((l * 10) / rate)
- .attrTween(
- "transform",
- this.translateDots(this.radius, path, count, back)
- )
+ .attrTween("transform", this.translateDots(this.radius, path, count, back))
.each("end", () => {
if (this.stopped === false) {
this.animateFlow(flow, path, count, back, rate);
@@ -465,6 +453,7 @@ class Dots extends TrafficAnimation {
let back = hop.back,
address = hop.address;
// the density of dots is determined by the rate of this traffic relative to the other traffic
+ if (!path.node().getTotalLength) return;
let len = Math.max(Math.floor(path.node().getTotalLength() / 50), 1);
let dots = [];
for (let i = 0, offset = this.addressIndex(this, address); i < len; ++i) {
@@ -494,6 +483,7 @@ class Dots extends TrafficAnimation {
.enter()
.append("circle")
.attr("class", "flow flow" + id)
+ .attr("data-testid", (d, i) => `flow${id}-${i}`)
.attr("fill", this.fillColor(address, this.traffic.addressColors))
.attr("r", 4);
this.animateFlow(circles, path, dots.length, back, rate);
diff --git a/console/react/src/topology/trafficComponent.js b/console/react/src/topology/trafficComponent.js
index 46c6023..ab377fb 100644
--- a/console/react/src/topology/trafficComponent.js
+++ b/console/react/src/topology/trafficComponent.js
@@ -19,7 +19,7 @@ under the License.
import React, { Component } from "react";
import { Checkbox } from "@patternfly/react-core";
-import AddressesComponent from "../addressesComponent";
+import AddressesComponent from "../common/addressesComponent";
class TrafficComponent extends Component {
constructor(props) {
@@ -47,9 +47,7 @@ class TrafficComponent extends Component {
<AddressesComponent
addresses={this.props.addresses}
addressColors={this.props.addressColors}
- handleChangeAddress={
- this.props.handleChangeTrafficFlowAddress
- }
+ handleChangeAddress={this.props.handleChangeTrafficFlowAddress}
handleHoverAddress={this.props.handleHoverAddress}
/>
</li>
@@ -89,10 +87,7 @@ class TrafficComponent extends Component {
x2="100%"
y2="0%"
>
- <stop
- style={{ stopColor: "#999999", stopOpacity: 1 }}
- offset="0"
- />
+ <stop style={{ stopColor: "#999999", stopOpacity: 1 }} offset="0" />
<stop
style={{ stopColor: "#00FF00", stopOpacity: 1 }}
offset="0.333"
@@ -101,10 +96,7 @@ class TrafficComponent extends Component {
style={{ stopColor: "#FFA500", stopOpacity: 1 }}
offset="0.666"
/>
- <stop
- style={{ stopColor: "#FF0000", stopOpacity: 1 }}
- offset="1"
- />
+ <stop style={{ stopColor: "#FF0000", stopOpacity: 1 }} offset="1" />
</linearGradient>
</defs>
<g>
diff --git a/console/react/src/updated.test.js b/console/react/src/updated.test.js
deleted file mode 100644
index 28353ae..0000000
--- a/console/react/src/updated.test.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import React from "react";
-import { render } from '@testing-library/react';
-import { QDRService } from "./qdrService";
-import Updated from "./updated";
-
-it("should render the Updated component", () => {
- const service = new QDRService(() => { });
- const props = {
- lastUpdated: new Date(),
- service
- }
- const { getByLabelText } = render(
- <Updated {...props} />
- );
- expect(getByLabelText("last-updated")).toBeInTheDocument()
-});
diff --git a/console/react/src/qdrService.mock.js b/console/react/test_data/qdrService.mock.js
similarity index 88%
rename from console/react/src/qdrService.mock.js
rename to console/react/test_data/qdrService.mock.js
index c1229f9..b247a63 100644
--- a/console/react/src/qdrService.mock.js
+++ b/console/react/test_data/qdrService.mock.js
@@ -17,10 +17,10 @@ specific language governing permissions and limitations
under the License.
*/
-import { utils } from "./amqp/utilities";
-import fetchResults from "../test_data/fetchEntities";
-import nodeInfo from "../test_data/nodeInfo";
-import schema from "../test_data/schema";
+import { utils } from "../src/common/amqp/utilities";
+import fetchResults from "./fetchEntities";
+import nodeInfo from "./nodeInfo";
+import schema from "./schema";
const methodResults = {
context: {
@@ -41,7 +41,9 @@ export const mockService = ({ onSendMethod }) => {
sendMethod: () => {
cbSendMethod();
return Promise.resolve(methodResults);
- }
+ },
+ is_connected: () => true,
+ setReconnect: () => {}
},
topology: {
setUpdateEntities: () => {},
diff --git a/console/react/yarn.lock b/console/react/yarn.lock
index 7c28ef6..6230861 100644
--- a/console/react/yarn.lock
+++ b/console/react/yarn.lock
@@ -9,26 +9,6 @@
dependencies:
"@babel/highlight" "^7.0.0"
-"@babel/core@7.4.3":
- version "7.4.3"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.3.tgz#198d6d3af4567be3989550d97e068de94503074f"
- integrity sha512-oDpASqKFlbspQfzAE7yaeTmdljSH2ADIvBlb0RwbStltTuWa0+7CCI1fYVINNv9saHPa1W7oaKeuNuKj+RQCvA==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- "@babel/generator" "^7.4.0"
- "@babel/helpers" "^7.4.3"
- "@babel/parser" "^7.4.3"
- "@babel/template" "^7.4.0"
- "@babel/traverse" "^7.4.3"
- "@babel/types" "^7.4.0"
- convert-source-map "^1.1.0"
- debug "^4.1.0"
- json5 "^2.1.0"
- lodash "^4.17.11"
- resolve "^1.3.2"
- semver "^5.4.1"
- source-map "^0.5.0"
-
"@babel/core@7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.0.tgz#9b00f73554edd67bebc86df8303ef678be3d7b48"
@@ -49,7 +29,7 @@
semver "^5.4.1"
source-map "^0.5.0"
-"@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.4.5":
+"@babel/core@^7.1.0", "@babel/core@^7.4.5":
version "7.7.2"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.2.tgz#ea5b99693bcfc058116f42fa1dd54da412b29d91"
integrity sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ==
@@ -262,7 +242,7 @@
"@babel/traverse" "^7.7.0"
"@babel/types" "^7.7.0"
-"@babel/helpers@^7.4.3", "@babel/helpers@^7.6.0", "@babel/helpers@^7.7.0":
+"@babel/helpers@^7.6.0", "@babel/helpers@^7.7.0":
version "7.7.0"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.7.0.tgz#359bb5ac3b4726f7c1fde0ec75f64b3f4275d60b"
integrity sha512-VnNwL4YOhbejHb7x/b5F39Zdg5vIQpUUNzJwx0ww1EcVRt41bbGRZWhAURrfY32T5zTT3qwNOQFWpn+P0i0a2g==
@@ -796,7 +776,7 @@
js-levenshtein "^1.1.3"
semver "^5.5.0"
-"@babel/preset-env@^7.1.6":
+"@babel/preset-env@^7.4.5":
version "7.7.1"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.7.1.tgz#04a2ff53552c5885cf1083e291c8dd5490f744bb"
integrity sha512-/93SWhi3PxcVTDpSqC+Dp4YxUu3qZ4m7I76k0w73wYfn7bGVuRIO4QUz95aJksbS+AD1/mT1Ie7rbkT0wSplaA==
@@ -883,14 +863,6 @@
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-typescript" "^7.6.0"
-"@babel/runtime-corejs2@^7.0.0":
- version "7.7.2"
- resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.7.2.tgz#5a8c4e2f8688ce58adc9eb1d8320b6e7341f96ce"
- integrity sha512-GfVnHchOBvIMsweQ13l4jd9lT4brkevnavnVOej5g2y7PpTRY+R4pcQlCjWMZoUla5rMLFzaS/Ll2s59cB1TqQ==
- dependencies:
- core-js "^2.6.5"
- regenerator-runtime "^0.13.2"
-
"@babel/runtime@7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205"
@@ -898,7 +870,7 @@
dependencies:
regenerator-runtime "^0.13.2"
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.1", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3":
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.1", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2":
version "7.7.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.2.tgz#111a78002a5c25fc8e3361bedc9529c696b85a6a"
integrity sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw==
@@ -946,35 +918,6 @@
exec-sh "^0.3.2"
minimist "^1.2.0"
-"@commitlint/execute-rule@^8.2.0":
- version "8.2.0"
- resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-8.2.0.tgz#aefb3744e22613660adefb7ebcccaa60bd24e78d"
- integrity sha512-9MBRthHaulbWTa8ReG2Oii2qc117NuvzhZdnkuKuYLhker7sUXGFcVhLanuWUKGyfyI2o9zVr/NHsNbCCsTzAA==
-
-"@commitlint/load@>6.1.1":
- version "8.2.0"
- resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-8.2.0.tgz#9ca53a0c795e4f63d796b4d42279e856549add1a"
- integrity sha512-EV6PfAY/p83QynNd1llHxJiNxKmp43g8+7dZbyfHFbsGOdokrCnoelAVZ+WGgktXwLN/uXyfkcIAxwac015UYw==
- dependencies:
- "@commitlint/execute-rule" "^8.2.0"
- "@commitlint/resolve-extends" "^8.2.0"
- babel-runtime "^6.23.0"
- chalk "2.4.2"
- cosmiconfig "^5.2.0"
- lodash "4.17.14"
- resolve-from "^5.0.0"
-
-"@commitlint/resolve-extends@^8.2.0":
- version "8.2.0"
- resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-8.2.0.tgz#b7f2f0c71c10f24b98a199ed11d2c14cfd7a318f"
- integrity sha512-cwi0HUsDcD502HBP8huXfTkVuWmeo1Fiz3GKxNwMBBsJV4+bKa7QrtxbNpXhVuarX7QjWfNTvmW6KmFS7YK9uw==
- dependencies:
- "@types/node" "^12.0.2"
- import-fresh "^3.0.0"
- lodash "4.17.14"
- resolve-from "^5.0.0"
- resolve-global "^1.0.0"
-
"@csstools/convert-colors@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7"
@@ -1045,9 +988,9 @@
"@fortawesome/fontawesome-common-types" "^0.2.25"
"@hapi/address@2.x.x":
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.2.tgz#1c794cd6dbf2354d1eb1ef10e0303f573e1c7222"
- integrity sha512-O4QDrx+JoGKZc6aN64L04vqa7e41tIiLU+OvKdcYaEMP97UttL0f9GIi9/0A4WAMx0uBd6SidDIhktZhgOcN8Q==
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
+ integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==
"@hapi/bourne@1.x.x":
version "1.3.2"
@@ -1215,7 +1158,7 @@
source-map "^0.6.1"
write-file-atomic "2.4.1"
-"@jest/types@^24.7.0", "@jest/types@^24.9.0":
+"@jest/types@^24.9.0":
version "24.9.0"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59"
integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==
@@ -1232,89 +1175,11 @@
call-me-maybe "^1.0.1"
glob-to-regexp "^0.3.0"
-"@nodelib/fs.scandir@2.1.3":
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b"
- integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==
- dependencies:
- "@nodelib/fs.stat" "2.0.3"
- run-parallel "^1.1.9"
-
-"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2":
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3"
- integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==
-
"@nodelib/fs.stat@^1.1.2":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
-"@nodelib/fs.walk@^1.2.3":
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976"
- integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==
- dependencies:
- "@nodelib/fs.scandir" "2.1.3"
- fastq "^1.6.0"
-
-"@octokit/endpoint@^5.5.0":
- version "5.5.1"
- resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-5.5.1.tgz#2eea81e110ca754ff2de11c79154ccab4ae16b3f"
- integrity sha512-nBFhRUb5YzVTCX/iAK1MgQ4uWo89Gu0TH00qQHoYRCsE12dWcG1OiLd7v2EIo2+tpUKPMOQ62QFy9hy9Vg2ULg==
- dependencies:
- "@octokit/types" "^2.0.0"
- is-plain-object "^3.0.0"
- universal-user-agent "^4.0.0"
-
-"@octokit/request-error@^1.0.1", "@octokit/request-error@^1.0.2":
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-1.2.0.tgz#a64d2a9d7a13555570cd79722de4a4d76371baaa"
- integrity sha512-DNBhROBYjjV/I9n7A8kVkmQNkqFAMem90dSxqvPq57e2hBr7mNTX98y3R2zDpqMQHVRpBDjsvsfIGgBzy+4PAg==
- dependencies:
- "@octokit/types" "^2.0.0"
- deprecation "^2.0.0"
- once "^1.4.0"
-
-"@octokit/request@^5.2.0":
- version "5.3.1"
- resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.3.1.tgz#3a1ace45e6f88b1be4749c5da963b3a3b4a2f120"
- integrity sha512-5/X0AL1ZgoU32fAepTfEoggFinO3rxsMLtzhlUX+RctLrusn/CApJuGFCd0v7GMFhF+8UiCsTTfsu7Fh1HnEJg==
- dependencies:
- "@octokit/endpoint" "^5.5.0"
- "@octokit/request-error" "^1.0.1"
- "@octokit/types" "^2.0.0"
- deprecation "^2.0.0"
- is-plain-object "^3.0.0"
- node-fetch "^2.3.0"
- once "^1.4.0"
- universal-user-agent "^4.0.0"
-
-"@octokit/rest@^16.27.0":
- version "16.35.0"
- resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.35.0.tgz#7ccc1f802f407d5b8eb21768c6deca44e7b4c0d8"
- integrity sha512-9ShFqYWo0CLoGYhA1FdtdykJuMzS/9H6vSbbQWDX4pWr4p9v+15MsH/wpd/3fIU+tSxylaNO48+PIHqOkBRx3w==
- dependencies:
- "@octokit/request" "^5.2.0"
- "@octokit/request-error" "^1.0.2"
- atob-lite "^2.0.0"
- before-after-hook "^2.0.0"
- btoa-lite "^1.0.0"
- deprecation "^2.0.0"
- lodash.get "^4.4.2"
- lodash.set "^4.3.2"
- lodash.uniq "^4.5.0"
- octokit-pagination-methods "^1.1.0"
- once "^1.4.0"
- universal-user-agent "^4.0.0"
-
-"@octokit/types@^2.0.0":
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/@octokit/types/-/types-2.0.1.tgz#0caf0364e010296265621593ac9a37f40ef75dad"
- integrity sha512-YDYgV6nCzdGdOm7wy43Ce8SQ3M5DMKegB8E5sTB/1xrxOdo2yS/KgUgML2N2ZGD621mkbdrAglwTyA4NDOlFFA==
- dependencies:
- "@types/node" ">= 8"
-
"@patternfly/patternfly@2.40.13":
version "2.40.13"
resolved "https://registry.yarnpkg.com/@patternfly/patternfly/-/patternfly-2.40.13.tgz#d1aa7de123dd63972951a67ecc0a6e04117f85db"
@@ -1325,20 +1190,19 @@
resolved "https://registry.yarnpkg.com/@patternfly/patternfly/-/patternfly-2.41.0.tgz#64437b2b54c91cbfe5a37f2490b6a3fba515eba2"
integrity sha512-w85M4hr/fhnedIcSyjxeswgdkKREd7Y2To8tl0/EiVlNfmNowZ06NuRXrzmPKjVEB8AWtSwvgCwUo+YWL2ZUJg==
-"@patternfly/react-charts@^4.1.5":
- version "4.9.14"
- resolved "https://registry.yarnpkg.com/@patternfly/react-charts/-/react-charts-4.9.14.tgz#e2ecf07acfe18053fa868de309d96211e421e493"
- integrity sha512-f6E9gC0MSXrKiYYC/bksQJDv8n1zwtIAGp/VqggiwRpGrOl4+Bk2Ryok/4b93hEteoyfqBl6oGyKaI5As3tN6g==
+"@patternfly/react-charts@^5.1.6":
+ version "5.1.6"
+ resolved "https://registry.yarnpkg.com/@patternfly/react-charts/-/react-charts-5.1.6.tgz#848004238d75dde9cb720c0a5d720a3b0f6add00"
+ integrity sha512-T7dPN/URaUgA0+RAzy1TaDK6Xqk4aBT0zoWCPbLGztv3YIIotA/qk68kHFOdHjZ/NMHkZ/rleEzHejQFQgdvcg==
dependencies:
- "@patternfly/react-styles" "^3.5.23"
- optionalDependencies:
- "@types/lodash" "^4.14.132"
- "@types/victory" "^31.0.18"
+ "@patternfly/patternfly" "2.40.13"
+ "@patternfly/react-styles" "^3.6.6"
+ "@patternfly/react-tokens" "^2.7.6"
hoist-non-react-statics "^3.3.0"
- lodash "^4.17.11"
- victory "^32.2.3"
- victory-core "^32.2.3"
- victory-legend "^32.2.3"
+ lodash "^4.17.15"
+ victory "^33.0.5"
+ victory-core "^33.0.1"
+ victory-legend "^33.0.1"
"@patternfly/react-core@^3.120.8", "@patternfly/react-core@^3.38.1":
version "3.120.8"
@@ -1360,7 +1224,7 @@
dependencies:
"@fortawesome/free-brands-svg-icons" "^5.8.1"
-"@patternfly/react-styles@^3.3.3", "@patternfly/react-styles@^3.5.23", "@patternfly/react-styles@^3.6.6":
+"@patternfly/react-styles@^3.3.3", "@patternfly/react-styles@^3.6.6":
version "3.6.6"
resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-3.6.6.tgz#d4b481fbd34adc28b3129842aea4834c384d4382"
integrity sha512-BOn6s9kuwsWRVHeTvA9D55JMYMwoNaQn9eB+MBzX2zIbZxy0TGOTgNifU99lJct+6TFxSUxx81gzpby+xBcDSQ==
@@ -1416,79 +1280,6 @@
"@babel/runtime" "^7.1.2"
lodash "^4.17.11"
-"@semantic-release/commit-analyzer@^6.1.0":
- version "6.3.3"
- resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-6.3.3.tgz#885f7e46e2f0aef23a23be0904dbf18d6ece45ca"
- integrity sha512-Pyv1ZL2u5AIOY4YbxFCAB5J1PEh5yON8ylbfiPiriDGGW6Uu1U3Y8lysMtWu+FUD5x7tSnyIzhqx0+fxPxqbgw==
- dependencies:
- conventional-changelog-angular "^5.0.0"
- conventional-commits-filter "^2.0.0"
- conventional-commits-parser "^3.0.7"
- debug "^4.0.0"
- import-from "^3.0.0"
- lodash "^4.17.4"
-
-"@semantic-release/error@^2.2.0":
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/@semantic-release/error/-/error-2.2.0.tgz#ee9d5a09c9969eade1ec864776aeda5c5cddbbf0"
- integrity sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==
-
-"@semantic-release/github@^5.1.0":
- version "5.5.5"
- resolved "https://registry.yarnpkg.com/@semantic-release/github/-/github-5.5.5.tgz#4666367f16d8ad91fd1d3c71a7238498de14ec38"
- integrity sha512-Wo9OIULMRydbq+HpFh9yiLvra1XyEULPro9Tp4T5MQJ0WZyAQ3YQm74IdT8Pe/UmVDq2nfpT1oHrWkwOc4loHg==
- dependencies:
- "@octokit/rest" "^16.27.0"
- "@semantic-release/error" "^2.2.0"
- aggregate-error "^3.0.0"
- bottleneck "^2.18.1"
- debug "^4.0.0"
- dir-glob "^3.0.0"
- fs-extra "^8.0.0"
- globby "^10.0.0"
- http-proxy-agent "^2.1.0"
- https-proxy-agent "^3.0.0"
- issue-parser "^5.0.0"
- lodash "^4.17.4"
- mime "^2.4.3"
- p-filter "^2.0.0"
- p-retry "^4.0.0"
- url-join "^4.0.0"
-
-"@semantic-release/npm@^5.0.5":
- version "5.3.4"
- resolved "https://registry.yarnpkg.com/@semantic-release/npm/-/npm-5.3.4.tgz#2998cd9455aaedf278334d4a5b56f8e0b715919d"
- integrity sha512-XjITNRA/oOpJ7BfHk/WaOHs1WniYBszTde/bwADjjk1Luacpxg87jbDQVVt/oA3Zlx+MelxACRIEuRiPC5gu8g==
- dependencies:
- "@semantic-release/error" "^2.2.0"
- aggregate-error "^3.0.0"
- execa "^3.2.0"
- fs-extra "^8.0.0"
- lodash "^4.17.15"
- nerf-dart "^1.0.0"
- normalize-url "^4.0.0"
- npm "^6.10.3"
- rc "^1.2.8"
- read-pkg "^5.0.0"
- registry-auth-token "^4.0.0"
- tempy "^0.3.0"
-
-"@semantic-release/release-notes-generator@^7.1.2":
- version "7.3.2"
- resolved "https://registry.yarnpkg.com/@semantic-release/release-notes-generator/-/release-notes-generator-7.3.2.tgz#a858b35c9c62f780d285aeaca8ef9891a62c2f9c"
- integrity sha512-vYGydZPoQqL4aJOsaqXTZIekRb3aa/OlxlEVUvyrWWlNGqmQ1T7NUOos9eoN5DBCEuk6PwDrxPbhzgswxcvprQ==
- dependencies:
- conventional-changelog-angular "^5.0.0"
- conventional-changelog-writer "^4.0.0"
- conventional-commits-filter "^2.0.0"
- conventional-commits-parser "^3.0.0"
- debug "^4.0.0"
- get-stream "^5.0.0"
- import-from "^3.0.0"
- into-stream "^5.0.0"
- lodash "^4.17.4"
- read-pkg-up "^7.0.0"
-
"@sheerun/mutationobserver-shim@^0.3.2":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz#8013f2af54a2b7d735f71560ff360d3a8176a87b"
@@ -1548,7 +1339,7 @@
"@svgr/babel-plugin-transform-react-native-svg" "^4.2.0"
"@svgr/babel-plugin-transform-svg-component" "^4.2.0"
-"@svgr/core@^4.1.0":
+"@svgr/core@^4.3.2":
version "4.3.3"
resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.3.tgz#b37b89d5b757dc66e8c74156d00c368338d24293"
integrity sha512-qNuGF1QON1626UCaZamWt5yedpgOytvLj5BQZe2j1k1B8DUG4OyugZyfEwBeXozCUwhLEpsrgPrE+eCu4fY17w==
@@ -1564,7 +1355,7 @@
dependencies:
"@babel/types" "^7.4.4"
-"@svgr/plugin-jsx@^4.1.0", "@svgr/plugin-jsx@^4.3.3":
+"@svgr/plugin-jsx@^4.3.2", "@svgr/plugin-jsx@^4.3.3":
version "4.3.3"
resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.3.tgz#e2ba913dbdfbe85252a34db101abc7ebd50992fa"
integrity sha512-cLOCSpNWQnDB1/v+SUENHH7a0XY09bfuMKdq9+gYvtuwzC2rU4I0wKGFEp1i24holdQdwodCtDQdFtJiTCWc+w==
@@ -1574,7 +1365,7 @@
"@svgr/hast-util-to-babel-ast" "^4.3.2"
svg-parser "^2.0.0"
-"@svgr/plugin-svgo@^4.0.3":
+"@svgr/plugin-svgo@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-4.3.1.tgz#daac0a3d872e3f55935c6588dd370336865e9e32"
integrity sha512-PrMtEDUWjX3Ea65JsVCwTIXuSqa3CG9px+DluF1/eo9mlDrgrtFE7NE/DjdhjJgSM9wenlVBzkzneSIUgfUI/w==
@@ -1583,19 +1374,19 @@
merge-deep "^3.0.2"
svgo "^1.2.2"
-"@svgr/webpack@4.1.0":
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-4.1.0.tgz#20c88f32f731c7b1d4711045b2b993887d731c28"
- integrity sha512-d09ehQWqLMywP/PT/5JvXwPskPK9QCXUjiSkAHehreB381qExXf5JFCBWhfEyNonRbkIneCeYM99w+Ud48YIQQ==
+"@svgr/webpack@4.3.2":
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-4.3.2.tgz#319d4471c8f3d5c3af35059274834d9b5b8fb956"
+ integrity sha512-F3VE5OvyOWBEd2bF7BdtFRyI6E9it3mN7teDw0JQTlVtc4HZEYiiLSl+Uf9Uub6IYHVGc+qIrxxDyeedkQru2w==
dependencies:
- "@babel/core" "^7.1.6"
+ "@babel/core" "^7.4.5"
"@babel/plugin-transform-react-constant-elements" "^7.0.0"
- "@babel/preset-env" "^7.1.6"
+ "@babel/preset-env" "^7.4.5"
"@babel/preset-react" "^7.0.0"
- "@svgr/core" "^4.1.0"
- "@svgr/plugin-jsx" "^4.1.0"
- "@svgr/plugin-svgo" "^4.0.3"
- loader-utils "^1.1.0"
+ "@svgr/core" "^4.3.2"
+ "@svgr/plugin-jsx" "^4.3.2"
+ "@svgr/plugin-svgo" "^4.3.1"
+ loader-utils "^1.2.3"
"@testing-library/dom@^6.3.0":
version "6.10.1"
@@ -1610,9 +1401,9 @@
wait-for-expect "^3.0.0"
"@testing-library/jest-dom@^4.2.3":
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-4.2.3.tgz#2b40d463d6cb00b5550d04381912e048e8e35966"
- integrity sha512-lrsm8OMaOLjh8AJhTNZW85Vur+a2U00ej1r/dNzABN4vfJ2kllsP/eLgkOdfCHuspdXn3/Q6rLt/41dSueVCyg==
+ version "4.2.4"
+ resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-4.2.4.tgz#00dfa0cbdd837d9a3c2a7f3f0a248ea6e7b89742"
+ integrity sha512-j31Bn0rQo12fhCWOUWy9fl7wtqkp7In/YP2p5ZFyRuiiB9Qs3g+hS4gAmDWONbAHcRmVooNJ5eOHQDCOmUFXHg==
dependencies:
"@babel/runtime" "^7.5.1"
chalk "^2.4.1"
@@ -1880,25 +1671,16 @@
"@types/d3-voronoi" "*"
"@types/d3-zoom" "*"
-"@types/events@*":
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
- integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
+"@types/eslint-visitor-keys@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
+ integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
"@types/geojson@*":
version "7946.0.7"
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.7.tgz#c8fa532b60a0042219cdf173ca21a975ef0666ad"
integrity sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ==
-"@types/glob@^7.1.1":
- version "7.1.1"
- resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
- integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==
- dependencies:
- "@types/events" "*"
- "@types/minimatch" "*"
- "@types/node" "*"
-
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff"
@@ -1919,25 +1701,10 @@
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-lib-report" "*"
-"@types/lodash@^4.14.132":
- version "4.14.146"
- resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.146.tgz#de0d2c8610012f12a6a796455054cbc654f8fecf"
- integrity sha512-JzJcmQ/ikHSv7pbvrVNKJU5j9jL9VLf3/gqs048CEnBVVVEv4kve3vLxoPHGvclutS+Il4SBIuQQ087m1eHffw==
-
-"@types/minimatch@*":
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
- integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
-
-"@types/node@*", "@types/node@>= 8", "@types/node@^12.0.2":
- version "12.12.7"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
- integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
-
-"@types/normalize-package-data@^2.4.0":
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
- integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==
+"@types/json-schema@^7.0.3":
+ version "7.0.3"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636"
+ integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==
"@types/parse-json@^4.0.0":
version "4.0.0"
@@ -1961,7 +1728,7 @@
dependencies:
"@types/react" "*"
-"@types/react@*", "@types/react@^16.9.11":
+"@types/react@*":
version "16.9.11"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.11.tgz#70e0b7ad79058a7842f25ccf2999807076ada120"
integrity sha512-UBT4GZ3PokTXSWmdgC/GeCGEJXE5ofWyibCcecRLUVN2ZBpXQGVgQGtG2foS7CrTKFKlQVVswLvf7Js6XA/CVQ==
@@ -1969,11 +1736,6 @@
"@types/prop-types" "*"
csstype "^2.2.0"
-"@types/retry@^0.12.0":
- version "0.12.0"
- resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d"
- integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==
-
"@types/stack-utils@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
@@ -1994,13 +1756,6 @@
"@types/react-dom" "*"
"@types/testing-library__dom" "*"
-"@types/victory@^31.0.18":
- version "31.0.22"
- resolved "https://registry.yarnpkg.com/@types/victory/-/victory-31.0.22.tgz#b1c0f87261af7bc264207e3864acfe75d0abf605"
- integrity sha512-6xwSLp6nefiN7/xXk3tscmz2C9JAGgT5z/WtPlHz2uAqstbnyC0EmUXzU/RScZT1odLmHyLhkDRzEezJOzxb5A==
- dependencies:
- "@types/react" "*"
-
"@types/yargs-parser@*":
version "13.1.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228"
@@ -2013,32 +1768,47 @@
dependencies:
"@types/yargs-parser" "*"
-"@typescript-eslint/eslint-plugin@1.6.0":
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.6.0.tgz#a5ff3128c692393fb16efa403ec7c8a5593dab0f"
- integrity sha512-U224c29E2lo861TQZs6GSmyC0OYeRNg6bE9UVIiFBxN2MlA0nq2dCrgIVyyRbC05UOcrgf2Wk/CF2gGOPQKUSQ==
+"@typescript-eslint/eslint-plugin@^2.2.0":
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.7.0.tgz#dff176bdb73dfd7e2e43062452189bd1b9db6021"
+ integrity sha512-H5G7yi0b0FgmqaEUpzyBlVh0d9lq4cWG2ap0RKa6BkF3rpBb6IrAoubt1NWh9R2kRs/f0k6XwRDiDz3X/FqXhQ==
dependencies:
- "@typescript-eslint/parser" "1.6.0"
- "@typescript-eslint/typescript-estree" "1.6.0"
- requireindex "^1.2.0"
- tsutils "^3.7.0"
+ "@typescript-eslint/experimental-utils" "2.7.0"
+ eslint-utils "^1.4.2"
+ functional-red-black-tree "^1.0.1"
+ regexpp "^2.0.1"
+ tsutils "^3.17.1"
-"@typescript-eslint/parser@1.6.0":
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-1.6.0.tgz#f01189c8b90848e3b8e45a6cdad27870529d1804"
- integrity sha512-VB9xmSbfafI+/kI4gUK3PfrkGmrJQfh0N4EScT1gZXSZyUxpsBirPL99EWZg9MmPG0pzq/gMtgkk7/rAHj4aQw==
+"@typescript-eslint/experimental-utils@2.7.0":
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.7.0.tgz#58d790a3884df3041b5a5e08f9e5e6b7c41864b5"
+ integrity sha512-9/L/OJh2a5G2ltgBWJpHRfGnt61AgDeH6rsdg59BH0naQseSwR7abwHq3D5/op0KYD/zFT4LS5gGvWcMmegTEg==
dependencies:
- "@typescript-eslint/typescript-estree" "1.6.0"
- eslint-scope "^4.0.0"
- eslint-visitor-keys "^1.0.0"
+ "@types/json-schema" "^7.0.3"
+ "@typescript-eslint/typescript-estree" "2.7.0"
+ eslint-scope "^5.0.0"
-"@typescript-eslint/typescript-estree@1.6.0":
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-1.6.0.tgz#6cf43a07fee08b8eb52e4513b428c8cdc9751ef0"
- integrity sha512-A4CanUwfaG4oXobD5y7EXbsOHjCwn8tj1RDd820etpPAjH+Icjc2K9e/DQM1Hac5zH2BSy+u6bjvvF2wwREvYA==
+"@typescript-eslint/parser@^2.2.0":
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.7.0.tgz#b5e6a4944e2b68dba1e7fbfd5242e09ff552fd12"
+ integrity sha512-ctC0g0ZvYclxMh/xI+tyqP0EC2fAo6KicN9Wm2EIao+8OppLfxji7KAGJosQHSGBj3TcqUrA96AjgXuKa5ob2g==
+ dependencies:
+ "@types/eslint-visitor-keys" "^1.0.0"
+ "@typescript-eslint/experimental-utils" "2.7.0"
+ "@typescript-eslint/typescript-estree" "2.7.0"
+ eslint-visitor-keys "^1.1.0"
+
+"@typescript-eslint/typescript-estree@2.7.0":
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.7.0.tgz#34fd98c77a07b40d04d5b4203eddd3abeab909f4"
+ integrity sha512-vVCE/DY72N4RiJ/2f10PTyYekX2OLaltuSIBqeHYI44GQ940VCYioInIb8jKMrK9u855OEJdFC+HmWAZTnC+Ag==
dependencies:
+ debug "^4.1.1"
+ glob "^7.1.4"
+ is-glob "^4.0.1"
lodash.unescape "4.0.1"
- semver "5.5.0"
+ semver "^6.3.0"
+ tsutils "^3.17.1"
"@webassemblyjs/ast@1.8.5":
version "1.8.5"
@@ -2196,20 +1966,12 @@
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
-JSONStream@^1.0.4, JSONStream@^1.3.4, JSONStream@^1.3.5:
- version "1.3.5"
- resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
- integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==
- dependencies:
- jsonparse "^1.2.0"
- through ">=2.2.7 <3"
-
abab@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a"
integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==
-abbrev@1, abbrev@~1.1.1:
+abbrev@1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
@@ -2222,11 +1984,6 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
mime-types "~2.1.24"
negotiator "0.6.2"
-acorn-dynamic-import@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948"
- integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==
-
acorn-globals@^4.1.0, acorn-globals@^4.3.0, acorn-globals@^4.3.2:
version "4.3.4"
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7"
@@ -2235,7 +1992,7 @@ acorn-globals@^4.1.0, acorn-globals@^4.3.0, acorn-globals@^4.3.2:
acorn "^6.0.1"
acorn-walk "^6.0.1"
-acorn-jsx@^5.0.0:
+acorn-jsx@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384"
integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==
@@ -2250,7 +2007,7 @@ acorn@^5.5.3:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
-acorn@^6.0.1, acorn@^6.0.4, acorn@^6.0.5, acorn@^6.0.7:
+acorn@^6.0.1, acorn@^6.0.4, acorn@^6.2.1:
version "6.3.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e"
integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==
@@ -2265,46 +2022,28 @@ address@1.1.2, address@^1.0.1:
resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==
-agent-base@4, agent-base@^4.3.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
- integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
- dependencies:
- es6-promisify "^5.0.0"
-
-agent-base@~4.2.1:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9"
- integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==
- dependencies:
- es6-promisify "^5.0.0"
-
-agentkeepalive@^3.4.1:
- version "3.5.2"
- resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67"
- integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==
- dependencies:
- humanize-ms "^1.2.1"
-
-aggregate-error@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0"
- integrity sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==
+adjust-sourcemap-loader@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz#6471143af75ec02334b219f54bc7970c52fb29a4"
+ integrity sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA==
dependencies:
- clean-stack "^2.0.0"
- indent-string "^4.0.0"
+ assert "1.4.1"
+ camelcase "5.0.0"
+ loader-utils "1.2.3"
+ object-path "0.11.4"
+ regex-parser "2.2.10"
ajv-errors@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==
-ajv-keywords@^3.1.0:
+ajv-keywords@^3.1.0, ajv-keywords@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da"
integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==
-ajv@^6.1.0, ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1:
+ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5:
version "6.10.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52"
integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==
@@ -2319,13 +2058,6 @@ alphanum-sort@^1.0.0:
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=
-ansi-align@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f"
- integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=
- dependencies:
- string-width "^2.0.0"
-
ansi-colors@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9"
@@ -2345,11 +2077,18 @@ ansi-cyan@^0.1.1:
dependencies:
ansi-wrap "0.1.0"
-ansi-escapes@^3.0.0, ansi-escapes@^3.1.0, ansi-escapes@^3.2.0:
+ansi-escapes@^3.0.0, ansi-escapes@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==
+ansi-escapes@^4.2.1:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.0.tgz#a4ce2b33d6b214b7950d8595c212f12ac9cc569d"
+ integrity sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==
+ dependencies:
+ type-fest "^0.8.1"
+
ansi-gray@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251"
@@ -2384,6 +2123,11 @@ ansi-regex@^4.0.0, ansi-regex@^4.1.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
+ansi-regex@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
+ integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
+
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
@@ -2401,16 +2145,6 @@ ansi-wrap@0.1.0, ansi-wrap@^0.1.0:
resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768=
-ansicolors@~0.3.2:
- version "0.3.2"
- resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979"
- integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=
-
-ansistyles@~0.1.3:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539"
- integrity sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk=
-
anymatch@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
@@ -2419,21 +2153,11 @@ anymatch@^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
-aproba@^1.0.3, aproba@^1.1.1, aproba@^1.1.2:
+aproba@^1.0.3, aproba@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
-"aproba@^1.1.2 || 2", aproba@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc"
- integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==
-
-archy@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40"
- integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=
-
are-we-there-yet@~1.1.2:
version "1.1.5"
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
@@ -2449,11 +2173,6 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
-argv-formatter@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/argv-formatter/-/argv-formatter-1.0.0.tgz#a0ca0cbc29a5b73e836eebe1cbf6c5e0e4eb82f9"
- integrity sha1-oMoMvCmltz6Dbuvhy/bF4OTrgvk=
-
aria-query@3.0.0, aria-query@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc"
@@ -2462,6 +2181,11 @@ aria-query@3.0.0, aria-query@^3.0.0:
ast-types-flow "0.0.7"
commander "^2.11.0"
+arity-n@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/arity-n/-/arity-n-1.0.4.tgz#d9e76b11733e08569c0847ae7b39b2860b30b745"
+ integrity sha1-2edrEXM+CFacCEeuezmyhgswt0U=
+
arr-diff@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a"
@@ -2495,11 +2219,6 @@ array-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
-array-find-index@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
- integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=
-
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@@ -2510,11 +2229,6 @@ array-flatten@^2.1.0:
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
-array-ify@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece"
- integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=
-
array-includes@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d"
@@ -2535,21 +2249,11 @@ array-union@^1.0.1:
dependencies:
array-uniq "^1.0.1"
-array-union@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
- integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
-
array-uniq@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=
-array-uniq@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-2.1.0.tgz#46603d5e28e79bfd02b046fcc1d77c6820bd8e98"
- integrity sha512-bdHxtev7FN6+MXI1YFW0Q8mQ8dTJc2S8AMfju+ZR77pbg2yAdVyDlwkaUI7Har0LyOMRFPHrJ9lYdyjZZswdlQ==
-
array-unique@^0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
@@ -2560,7 +2264,7 @@ arrify@^1.0.1:
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
-asap@^2.0.0, asap@~2.0.3, asap@~2.0.6:
+asap@~2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
@@ -2586,6 +2290,13 @@ assert-plus@1.0.0, assert-plus@^1.0.0:
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
+assert@1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91"
+ integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=
+ dependencies:
+ util "0.10.3"
+
assert@^1.1.1:
version "1.5.0"
resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb"
@@ -2631,17 +2342,12 @@ asynckit@^0.4.0:
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
-atob-lite@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-2.0.0.tgz#0fef5ad46f1bd7a8502c65727f0367d5ee43d696"
- integrity sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=
-
atob@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
-autoprefixer@^9.4.9:
+autoprefixer@^9.6.1:
version "9.7.1"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.1.tgz#9ffc44c55f5ca89253d9bb7186cefb01ef57747f"
integrity sha512-w3b5y1PXWlhYulevrTJ0lizkQ5CyqfeU6BIRDbuhsMupstHQOeb1Ur80tcB1zxSu7AwyY/qCQ7Vvqklh31ZBFw==
@@ -2710,17 +2416,17 @@ babel-core@^6.26.0, babel-core@^6.7.2:
slash "^1.0.0"
source-map "^0.5.7"
-babel-eslint@10.0.1:
- version "10.0.1"
- resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed"
- integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==
+babel-eslint@10.0.3:
+ version "10.0.3"
+ resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a"
+ integrity sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==
dependencies:
"@babel/code-frame" "^7.0.0"
"@babel/parser" "^7.0.0"
"@babel/traverse" "^7.0.0"
"@babel/types" "^7.0.0"
- eslint-scope "3.7.1"
eslint-visitor-keys "^1.0.0"
+ resolve "^1.12.0"
babel-eslint@^9.0.0:
version "9.0.0"
@@ -2839,7 +2545,7 @@ babel-helpers@^6.24.1:
babel-runtime "^6.22.0"
babel-template "^6.24.1"
-babel-jest@^24.8.0, babel-jest@^24.9.0:
+babel-jest@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54"
integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==
@@ -2852,15 +2558,15 @@ babel-jest@^24.8.0, babel-jest@^24.9.0:
chalk "^2.4.2"
slash "^2.0.0"
-babel-loader@8.0.5:
- version "8.0.5"
- resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.5.tgz#225322d7509c2157655840bba52e46b6c2f2fe33"
- integrity sha512-NTnHnVRd2JnRqPC0vW+iOQWU5pchDbYXsG2E6DMXEpMfUcQKclF9gmf3G3ZMhzG7IG9ji4coL0cm+FxeWxDpnw==
+babel-loader@8.0.6:
+ version "8.0.6"
+ resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb"
+ integrity sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==
dependencies:
find-cache-dir "^2.0.0"
loader-utils "^1.0.2"
mkdirp "^0.5.1"
- util.promisify "^1.0.0"
+ pify "^4.0.1"
babel-messages@^6.23.0:
version "6.23.0"
@@ -2918,7 +2624,7 @@ babel-plugin-jest-hoist@^24.9.0:
dependencies:
"@types/babel__traverse" "^7.0.6"
-babel-plugin-macros@2.6.1, babel-plugin-macros@^2.0.0:
+babel-plugin-macros@2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.6.1.tgz#41f7ead616fc36f6a93180e89697f69f51671181"
integrity sha512-6W2nwiXme6j1n2erPOnmRiWfObUhWH7Qw1LMi9XZy8cj+KtESu3T6asZvtk5bMQQjX8te35o7CFueiSdL/2NmQ==
@@ -2927,7 +2633,16 @@ babel-plugin-macros@2.6.1, babel-plugin-macros@^2.0.0:
cosmiconfig "^5.2.0"
resolve "^1.10.0"
-babel-plugin-named-asset-import@^0.3.2:
+babel-plugin-macros@^2.0.0:
+ version "2.6.2"
+ resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.6.2.tgz#98ae30a02645dfa8033628fe613854ec9541bbc8"
+ integrity sha512-Ntviq8paRTkXIxvrJBauib+2KqQbZQuh4593CEZFF8qz3IVP8VituTZmkGe6N7rsuiOIbejxXj6kx3LMlEq0UA==
+ dependencies:
+ "@babel/runtime" "^7.7.2"
+ cosmiconfig "^6.0.0"
+ resolve "^1.12.0"
+
+babel-plugin-named-asset-import@^0.3.4:
version "0.3.4"
resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.4.tgz#4a8fc30e9a3e2b1f5ed36883386ab2d84e1089bd"
integrity sha512-S6d+tEzc5Af1tKIMbsf2QirCcPdQ+mKUCY2H1nJj1DyA1ShwpsoxEOAwbWsG5gcXNV/olpvQd9vrUWRx4bnhpw==
@@ -3198,7 +2913,7 @@ babel-preset-jest@^24.9.0:
"@babel/plugin-syntax-object-rest-spread" "^7.0.0"
babel-plugin-jest-hoist "^24.9.0"
-babel-preset-react-app@^9.0.0:
+babel-preset-react-app@^9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-9.0.2.tgz#247d37e883d6d6f4b4691e5f23711bb2dd80567d"
integrity sha512-aXD+CTH8Chn8sNJr4tO/trWKqe5sSE4hdO76j9fhVezJSzmpWYWUSc5JoPmdSxADwef5kQFNGKXd433vvkd2VQ==
@@ -3233,7 +2948,7 @@ babel-register@^6.26.0:
mkdirp "^0.5.1"
source-map-support "^0.4.15"
-babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0:
+babel-runtime@^6.22.0, babel-runtime@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
@@ -3317,33 +3032,17 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
-before-after-hook@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635"
- integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==
-
big.js@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
-bin-links@^1.1.2, bin-links@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.3.tgz#702fd59552703727313bc624bdbc4c0d3431c2ca"
- integrity sha512-TEwmH4PHU/D009stP+fkkazMJgkBNCv60z01lQ/Mn8E6+ThHoD03svMnBVuCowwXo2nP2qKyKZxKxp58OHRzxw==
- dependencies:
- bluebird "^3.5.3"
- cmd-shim "^3.0.0"
- gentle-fs "^2.0.1"
- graceful-fs "^4.1.15"
- write-file-atomic "^2.3.0"
-
binary-extensions@^1.0.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65"
integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==
-bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5:
+bluebird@^3.5.5:
version "3.7.1"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.1.tgz#df70e302b471d7473489acf26a93d63b53f874de"
integrity sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==
@@ -3405,11 +3104,6 @@ bootstrap-select@1.12.2:
dependencies:
jquery ">=1.8"
-bootstrap-slider-without-jquery@^10.0.0:
- version "10.0.0"
- resolved "https://registry.yarnpkg.com/bootstrap-slider-without-jquery/-/bootstrap-slider-without-jquery-10.0.0.tgz#5c304461b3b915037c7c118806c8ca08102f5de3"
- integrity sha512-CB9CrpNVrIytlOoqHtRXhhxFo/jencr1U5cMqPBA0WmMdb13bzjHnXQVNGYde/g5gWW+RWiuT9jTquZuz3VE8A==
-
bootstrap-slider@^9.9.0:
version "9.10.0"
resolved "https://registry.yarnpkg.com/bootstrap-slider/-/bootstrap-slider-9.10.0.tgz#1103d6bc00cfbfa8cfc9a2599ab518c55643da3f"
@@ -3430,24 +3124,6 @@ bootstrap@^3.3, bootstrap@^3.4.1, bootstrap@~3.4.1:
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-3.4.1.tgz#c3a347d419e289ad11f4033e3c4132b87c081d72"
integrity sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==
-bottleneck@^2.18.1:
- version "2.19.5"
- resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.19.5.tgz#5df0b90f59fd47656ebe63c78a98419205cadd91"
- integrity sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==
-
-boxen@^1.2.1:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
- integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==
- dependencies:
- ansi-align "^2.0.0"
- camelcase "^4.0.0"
- chalk "^2.0.1"
- cli-boxes "^1.0.0"
- string-width "^2.0.0"
- term-size "^1.2.0"
- widest-line "^2.0.0"
-
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -3472,18 +3148,6 @@ braces@^2.3.1, braces@^2.3.2:
split-string "^3.0.2"
to-regex "^3.0.1"
-braces@^3.0.1:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
- integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
- dependencies:
- fill-range "^7.0.1"
-
-breakjs@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/breakjs/-/breakjs-1.0.0.tgz#ec8353a06862eb43962deae09072ee66a4cd8459"
- integrity sha1-7INToGhi60OWLergkHLuZqTNhFk=
-
brorand@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
@@ -3569,7 +3233,7 @@ browserslist@4.7.0:
electron-to-chromium "^1.3.247"
node-releases "^1.1.29"
-browserslist@^4.0.0, browserslist@^4.1.1, browserslist@^4.4.2, browserslist@^4.6.0, browserslist@^4.7.2:
+browserslist@^4.0.0, browserslist@^4.1.1, browserslist@^4.6.0, browserslist@^4.6.4, browserslist@^4.7.2:
version "4.7.2"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.2.tgz#1bb984531a476b5d389cedecb195b2cd69fb1348"
integrity sha512-uZavT/gZXJd2UTi9Ov7/Z340WOSQ3+m1iBVRUknf+okKxonL9P83S3ctiBDtuRmRu8PiCHjqyueqQ9HYlJhxiw==
@@ -3585,11 +3249,6 @@ bser@^2.0.0:
dependencies:
node-int64 "^0.4.0"
-btoa-lite@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337"
- integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc=
-
buffer-from@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
@@ -3624,21 +3283,6 @@ builtin-status-codes@^3.0.0:
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
-builtins@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88"
- integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og=
-
-byline@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1"
- integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=
-
-byte-size@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-5.0.1.tgz#4b651039a5ecd96767e71a3d7ed380e48bed4191"
- integrity sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw==
-
bytes@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
@@ -3649,34 +3293,14 @@ bytes@3.1.0:
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
-c3@^0.4.11, c3@~0.4.11:
- version "0.4.23"
- resolved "https://registry.yarnpkg.com/c3/-/c3-0.4.23.tgz#32ece135d0ac6d124187be5c6935903699643002"
- integrity sha512-fI6hbx1QoATU0gRQtPWsUGWX+ssXhxGH1ogew32KjVmGHFE4WmfmBkh+RkuHDoeCIoGFon7XTpKcwUZpBGW4mQ==
+c3@~0.4.11:
+ version "0.4.24"
+ resolved "https://registry.yarnpkg.com/c3/-/c3-0.4.24.tgz#57b62357098842d38e265a265f6de1e8c6faadd2"
+ integrity sha512-mVCFtN5ZWUT5UE7ilFQ7KBQ7TUCdKIq6KsDt1hH/1m6gC1tBjvzFTO7fqhaiWHfhNOjjM7makschdhg6DkWQMA==
dependencies:
d3 "~3.5.0"
-cacache@^11.0.2:
- version "11.3.3"
- resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.3.tgz#8bd29df8c6a718a6ebd2d010da4d7972ae3bbadc"
- integrity sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==
- dependencies:
- bluebird "^3.5.5"
- chownr "^1.1.1"
- figgy-pudding "^3.5.1"
- glob "^7.1.4"
- graceful-fs "^4.1.15"
- lru-cache "^5.1.1"
- mississippi "^3.0.0"
- mkdirp "^0.5.1"
- move-concurrently "^1.0.1"
- promise-inflight "^1.0.1"
- rimraf "^2.6.3"
- ssri "^6.0.1"
- unique-filename "^1.1.1"
- y18n "^4.0.0"
-
-cacache@^12.0.0, cacache@^12.0.2, cacache@^12.0.3:
+cacache@^12.0.2:
version "12.0.3"
resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390"
integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==
@@ -3712,16 +3336,6 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"
-cachedir@2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.2.0.tgz#19afa4305e05d79e417566882e0c8f960f62ff0e"
- integrity sha512-VvxA0xhNqIIfg0V9AmJkDg91DaJwryutH5rVEZAhcNi4iJFj9f+QxmAjgK1LT9I8OgToX27fypX6/MeCXVbBjQ==
-
-call-limit@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.1.tgz#ef15f2670db3f1992557e2d965abc459e6e358d4"
- integrity sha512-5twvci5b9eRBw2wCfPtN0GmlR2/gadZqyFpPhOK6CvMFoFgA+USnZ6Jpu1lhG9h85pQ3Ouil3PfXWRD4EUaRiQ==
-
call-me-maybe@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b"
@@ -3759,16 +3373,12 @@ camel-case@3.0.x, camel-case@^3.0.0:
no-case "^2.2.0"
upper-case "^1.1.1"
-camelcase-keys@^4.0.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77"
- integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=
- dependencies:
- camelcase "^4.1.0"
- map-obj "^2.0.0"
- quick-lru "^1.0.0"
+camelcase@5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42"
+ integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==
-camelcase@^4.0.0, camelcase@^4.1.0:
+camelcase@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
@@ -3788,10 +3398,10 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000939, caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30001004, caniuse-lite@^1.0.30001006:
- version "1.0.30001009"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001009.tgz#69b77997b882a7aee6af24c8d7d2fa27ee41f348"
- integrity sha512-M3rEqHN6SaVjgo4bIik7HsGcWXsi+lI9WA0p51RPMFx5gXfduyOXWJrc0R4xBkSK1pgNf4CNgy5M+6H+WiEP8g==
+caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30001004, caniuse-lite@^1.0.30001006:
+ version "1.0.30001010"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001010.tgz#397a14034d384260453cc81994f494626d34b938"
+ integrity sha512-RA5GH9YjFNea4ZQszdWgh2SC+dpLiRAg4VDQS2b5JRI45OxmbGrYocYHTa9x0bKMQUE7uvHkNPNffUr+pCxSGw==
capture-exit@^2.0.0:
version "2.0.0"
@@ -3800,19 +3410,6 @@ capture-exit@^2.0.0:
dependencies:
rsvp "^4.8.4"
-capture-stack-trace@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d"
- integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==
-
-cardinal@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-2.1.1.tgz#7cc1055d822d212954d07b085dea251cc7bc5505"
- integrity sha1-fMEFXYItISlU0HsIXeolHMe8VQU=
- dependencies:
- ansicolors "~0.3.2"
- redeyed "~2.1.0"
-
case-sensitive-paths-webpack-plugin@2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.2.0.tgz#3371ef6365ef9c25fa4b81c16ace0e9c7dc58c3e"
@@ -3823,7 +3420,7 @@ caseless@~0.12.0:
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
-chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2:
+chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -3843,11 +3440,6 @@ chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
-change-emitter@^0.1.2:
- version "0.1.6"
- resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515"
- integrity sha1-6LL+PX8at9aaMhma/5HqaTFAlRU=
-
chardet@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
@@ -3872,35 +3464,23 @@ chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.4:
optionalDependencies:
fsevents "^1.2.7"
-chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.3:
+chownr@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142"
integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==
-chrome-trace-event@^1.0.0:
+chrome-trace-event@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4"
integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==
dependencies:
tslib "^1.9.0"
-ci-info@^1.5.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
- integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==
-
ci-info@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
-cidr-regex@^2.0.10:
- version "2.0.10"
- resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-2.0.10.tgz#af13878bd4ad704de77d6dc800799358b3afa70d"
- integrity sha512-sB3ogMQXWvreNPbJUZMRApxuRYd+KoIo4RGQ81VatjmMW6WJPo+IJZ2846FGItr9VzKo5w7DXzijPLGtSd0N3Q==
- dependencies:
- ip-regex "^2.1.0"
-
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
@@ -3919,7 +3499,7 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
-classnames@^2.2.0, classnames@^2.2.5:
+classnames@^2.2.5:
version "2.2.6"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
@@ -3931,24 +3511,6 @@ clean-css@4.2.x:
dependencies:
source-map "~0.6.0"
-clean-stack@^2.0.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
- integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
-
-cli-boxes@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
- integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM=
-
-cli-columns@^3.1.2:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/cli-columns/-/cli-columns-3.1.2.tgz#6732d972979efc2ae444a1f08e08fa139c96a18e"
- integrity sha1-ZzLZcpee/CrkRKHwjgj6E5yWoY4=
- dependencies:
- string-width "^2.0.0"
- strip-ansi "^3.0.1"
-
cli-cursor@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
@@ -3956,22 +3518,12 @@ cli-cursor@^2.1.0:
dependencies:
restore-cursor "^2.0.0"
-cli-table3@^0.5.0, cli-table3@^0.5.1:
- version "0.5.1"
- resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202"
- integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==
- dependencies:
- object-assign "^4.1.0"
- string-width "^2.1.1"
- optionalDependencies:
- colors "^1.1.2"
-
-cli-table@^0.3.1:
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23"
- integrity sha1-9TsFJmqLGguTSz0IIebi3FkUriM=
+cli-cursor@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
+ integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==
dependencies:
- colors "1.0.3"
+ restore-cursor "^3.1.0"
cli-width@^2.0.0:
version "2.2.0"
@@ -4007,28 +3559,14 @@ clone-deep@^0.2.4:
lazy-cache "^1.0.3"
shallow-clone "^0.1.2"
-clone-deep@^2.0.1:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-2.0.2.tgz#00db3a1e173656730d1188c3d6aced6d7ea97713"
- integrity sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==
+clone-deep@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
+ integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==
dependencies:
- for-own "^1.0.0"
is-plain-object "^2.0.4"
- kind-of "^6.0.0"
- shallow-clone "^1.0.0"
-
-clone@^1.0.2:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
- integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
-
-cmd-shim@^3.0.0, cmd-shim@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-3.0.3.tgz#2c35238d3df37d98ecdd7d5f6b8dc6b21cadc7cb"
- integrity sha512-DtGg+0xiFhQIntSBRzL2fRQBnmtAVwXIDo4Qq46HPpObYquxMaZS4sb82U9nH91qJrlosC1wa9gwr0QyL/HypA==
- dependencies:
- graceful-fs "^4.1.2"
- mkdirp "~0.5.0"
+ kind-of "^6.0.2"
+ shallow-clone "^3.0.0"
co@^4.6.0:
version "4.6.0"
@@ -4095,24 +3633,6 @@ color@^3.0.0:
color-convert "^1.9.1"
color-string "^1.5.2"
-colors@1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
- integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
-
-colors@^1.1.2:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
- integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
-
-columnify@~1.5.4:
- version "1.5.4"
- resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb"
- integrity sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=
- dependencies:
- strip-ansi "^3.0.0"
- wcwidth "^1.0.0"
-
combined-stream@^1.0.6, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@@ -4120,7 +3640,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"
-commander@2, commander@^2.11.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.3:
+commander@2, commander@^2.11.0, commander@^2.20.0, commander@~2.20.3:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -4135,27 +3655,6 @@ commander@~2.19.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
-commitizen@^4.0.3:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/commitizen/-/commitizen-4.0.3.tgz#c19a4213257d0525b85139e2f36db7cc3b4f6dae"
- integrity sha512-lxu0F/Iq4dudoFeIl5pY3h3CQJzkmQuh3ygnaOvqhAD8Wu2pYBI17ofqSuPHNsBTEOh1r1AVa9kR4Hp0FAHKcQ==
- dependencies:
- cachedir "2.2.0"
- cz-conventional-changelog "3.0.1"
- dedent "0.7.0"
- detect-indent "6.0.0"
- find-node-modules "2.0.0"
- find-root "1.1.0"
- fs-extra "8.1.0"
- glob "7.1.4"
- inquirer "6.5.0"
- is-utf8 "^0.2.1"
- lodash "4.17.15"
- minimist "1.2.0"
- shelljs "0.7.6"
- strip-bom "4.0.0"
- strip-json-comments "3.0.1"
-
common-tags@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
@@ -4166,19 +3665,18 @@ commondir@^1.0.1:
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
-compare-func@^1.3.1:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648"
- integrity sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=
- dependencies:
- array-ify "^1.0.0"
- dot-prop "^3.0.0"
-
component-emitter@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
+compose-function@3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/compose-function/-/compose-function-3.0.3.tgz#9ed675f13cc54501d30950a486ff6a7ba3ab185f"
+ integrity sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=
+ dependencies:
+ arity-n "^1.0.4"
+
compressible@~2.0.16:
version "2.0.17"
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1"
@@ -4214,27 +3712,7 @@ concat-stream@^1.5.0:
readable-stream "^2.2.2"
typedarray "^0.0.6"
-config-chain@^1.1.12:
- version "1.1.12"
- resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa"
- integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==
- dependencies:
- ini "^1.3.4"
- proto-list "~1.2.1"
-
-configstore@^3.0.0:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f"
- integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==
- dependencies:
- dot-prop "^4.1.0"
- graceful-fs "^4.1.2"
- make-dir "^1.0.0"
- unique-string "^1.0.0"
- write-file-atomic "^2.0.0"
- xdg-basedir "^3.0.0"
-
-confusing-browser-globals@^1.0.7:
+confusing-browser-globals@^1.0.9:
version "1.0.9"
resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd"
integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==
@@ -4249,7 +3727,7 @@ console-browserify@^1.1.0:
resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==
-console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0:
+console-control-strings@^1.0.0, console-control-strings@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
@@ -4276,55 +3754,17 @@ content-type@~1.0.4:
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
-conventional-changelog-angular@^5.0.0:
- version "5.0.6"
- resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.6.tgz#269540c624553aded809c29a3508fdc2b544c059"
- integrity sha512-QDEmLa+7qdhVIv8sFZfVxU1VSyVvnXPsxq8Vam49mKUcO1Z8VTLEJk9uI21uiJUsnmm0I4Hrsdc9TgkOQo9WSA==
- dependencies:
- compare-func "^1.3.1"
- q "^1.5.1"
-
-conventional-changelog-writer@^4.0.0:
- version "4.0.10"
- resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.10.tgz#39f6458cca62a8151b3ce582a57ff71fd2b0ff7a"
- integrity sha512-vtO9vBAVh7XnSpGLTB1BOGgsGTz1MdvFjzbSXLrtapWCHWwuVOZFgwdLhlS0MaXwlF1dksWdEb6tnr42Ie2INw==
- dependencies:
- compare-func "^1.3.1"
- conventional-commits-filter "^2.0.2"
- dateformat "^3.0.0"
- handlebars "^4.4.0"
- json-stringify-safe "^5.0.1"
- lodash "^4.17.15"
- meow "^4.0.0"
- semver "^6.0.0"
- split "^1.0.0"
- through2 "^3.0.0"
-
-conventional-commit-types@^2.0.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/conventional-commit-types/-/conventional-commit-types-2.3.0.tgz#bc3c8ebba0a9e4b3ecc548f1d0674e251ab8be22"
- integrity sha512-6iB39PrcGYdz0n3z31kj6/Km6mK9hm9oMRhwcLnKxE7WNoeRKZbTAobliKrbYZ5jqyCvtcVEfjCiaEzhL3AVmQ==
-
-conventional-commits-filter@^2.0.0, conventional-commits-filter@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.2.tgz#f122f89fbcd5bb81e2af2fcac0254d062d1039c1"
- integrity sha512-WpGKsMeXfs21m1zIw4s9H5sys2+9JccTzpN6toXtxhpw2VNF2JUXwIakthKBy+LN4DvJm+TzWhxOMWOs1OFCFQ==
+convert-source-map@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20"
+ integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==
dependencies:
- lodash.ismatch "^4.4.0"
- modify-values "^1.0.0"
+ safe-buffer "~5.1.1"
-conventional-commits-parser@^3.0.0, conventional-commits-parser@^3.0.7:
- version "3.0.7"
- resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.7.tgz#55b6cde6a2d0b4a7ab399392777d527134a8d05c"
- integrity sha512-4mx/FRC92z0yIiXGyRVYQFhn0jWDwvxnj2UuLaUi3hJSG4Thall6GXA8YOPHQK2qvotciJandJIVmuSvLgDLbQ==
- dependencies:
- JSONStream "^1.0.4"
- is-text-path "^1.0.1"
- lodash "^4.17.15"
- meow "^4.0.0"
- split2 "^2.0.0"
- through2 "^3.0.0"
- trim-off-newlines "^1.0.0"
+convert-source-map@^0.3.3:
+ version "0.3.5"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190"
+ integrity sha1-8dgClQr33SYxof6+BZZVDIarMZA=
convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.5.1, convert-source-map@^1.7.0:
version "1.7.0"
@@ -4373,12 +3813,7 @@ core-js@3.2.1:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.2.1.tgz#cd41f38534da6cc59f7db050fe67307de9868b09"
integrity sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw==
-core-js@^1.0.0:
- version "1.2.7"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
- integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
-
-core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0, core-js@^2.6.5:
+core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0:
version "2.6.10"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.10.tgz#8a5b8391f8cc7013da703411ce5b585706300d7f"
integrity sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==
@@ -4439,13 +3874,6 @@ create-emotion@^9.2.12:
stylis "^3.5.0"
stylis-rule-sheet "^0.0.10"
-create-error-class@^3.0.0:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
- integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=
- dependencies:
- capture-stack-trace "^1.0.0"
-
create-hash@^1.1.0, create-hash@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
@@ -4469,14 +3897,6 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
-create-react-context@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.3.0.tgz#546dede9dc422def0d3fc2fe03afe0bc0f4f7d8c"
- integrity sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==
- dependencies:
- gud "^1.0.0"
- warning "^4.0.3"
-
cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
@@ -4488,7 +3908,7 @@ cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
shebang-command "^1.2.0"
which "^1.2.9"
-cross-spawn@^5.0.1, cross-spawn@^5.1.0:
+cross-spawn@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
@@ -4497,15 +3917,6 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0:
shebang-command "^1.2.0"
which "^1.2.9"
-cross-spawn@^7.0.0:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14"
- integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==
- dependencies:
- path-key "^3.1.0"
- shebang-command "^2.0.0"
- which "^2.0.1"
-
crypto-browserify@^3.11.0:
version "3.12.0"
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
@@ -4523,11 +3934,6 @@ crypto-browserify@^3.11.0:
randombytes "^2.0.0"
randomfill "^1.0.3"
-crypto-random-string@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
- integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=
-
css-blank-pseudo@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5"
@@ -4548,11 +3954,6 @@ css-declaration-sorter@^4.0.1:
postcss "^7.0.1"
timsort "^0.3.0"
-css-element-queries@^1.0.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/css-element-queries/-/css-element-queries-1.2.1.tgz#70d1a0f676fc0bd0a3306522a5b2d3bcc55c9fe6"
- integrity sha512-hiI1tSzf+U/gE13qhfwnCvN90Ay0THnE+mT3pjN/c/mvFmEUHZVNrvMJrrkw2ppOzkl69FdgH2ZGZENYQUaN2A==
-
css-has-pseudo@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee"
@@ -4638,7 +4039,7 @@ css.escape@^1.5.1:
resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=
-css@^2.2.3:
+css@^2.0.0, css@^2.2.3:
version "2.2.4"
resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929"
integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==
@@ -4648,7 +4049,7 @@ css@^2.2.3:
source-map-resolve "^0.5.2"
urix "^0.1.0"
-cssdb@^4.3.0:
+cssdb@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0"
integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==
@@ -4721,7 +4122,7 @@ cssnano-util-same-parent@^4.0.0:
resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3"
integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==
-cssnano@^4.1.0:
+cssnano@^4.1.10:
version "4.1.10"
resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2"
integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==
@@ -4744,9 +4145,9 @@ cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@^0.3.4, cssom@~0.3.6:
integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
cssom@^0.4.1:
- version "0.4.2"
- resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.2.tgz#e2abd06e1267a7f2e5eccd7770c9ebe1bd88648b"
- integrity sha512-fVXFVBr7JPDcgqa92UNr6HIpeMypyG/XVloB+512KH43Z2aum8ZNVzRapWR4mZ/f2UlRMymIoDO3aFJmQ6Y3RA==
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
+ integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==
cssstyle@^0.3.1:
version "0.3.1"
@@ -4774,47 +4175,11 @@ csstype@^2.2.0, csstype@^2.5.2:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.7.tgz#20b0024c20b6718f4eda3853a1f5a1cce7f5e4a5"
integrity sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ==
-currently-unhandled@^0.4.1:
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
- integrity sha1-mI3zP+qxke95mmE2nddsF635V+o=
- dependencies:
- array-find-index "^1.0.1"
-
cyclist@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
-cz-conventional-changelog@3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/cz-conventional-changelog/-/cz-conventional-changelog-3.0.1.tgz#b1f207ae050355e7ada65aad5c52e9de3d0c8e5b"
- integrity sha512-7KASIwB8/ClEyCRvQrCPbN7WkQnUSjSSVNyPM+gDJ0jskLi8h8N2hrdpyeCk7fIqKMRzziqVSOBTB8yyLTMHGQ==
- dependencies:
- chalk "^2.4.1"
- conventional-commit-types "^2.0.0"
- lodash.map "^4.5.1"
- longest "^2.0.1"
- right-pad "^1.0.1"
- word-wrap "^1.0.3"
- optionalDependencies:
- "@commitlint/load" ">6.1.1"
-
-cz-conventional-changelog@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/cz-conventional-changelog/-/cz-conventional-changelog-3.0.2.tgz#f6b9a406177ab07f9a3a087e06103a045b376260"
- integrity sha512-MPxERbtQyVp0nnpCBiwzKGKmMBSswmCV3Jpef3Axqd5f3c/SOc6VFiSUlclOyZXBn3Xtf4snzt4O15hBTRb2gA==
- dependencies:
- chalk "^2.4.1"
- commitizen "^4.0.3"
- conventional-commit-types "^2.0.0"
- lodash.map "^4.5.1"
- longest "^2.0.1"
- right-pad "^1.0.1"
- word-wrap "^1.0.3"
- optionalDependencies:
- "@commitlint/load" ">6.1.1"
-
d3-array@^1.2.0:
version "1.2.4"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f"
@@ -4831,26 +4196,26 @@ d3-color@1:
integrity sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg==
d3-ease@^1.0.0:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.5.tgz#8ce59276d81241b1b72042d6af2d40e76d936ffb"
- integrity sha512-Ct1O//ly5y5lFM9YTdu+ygq7LleSgSE4oj7vUt9tPLHUi8VCV7QoizGpdWRWAwCO9LdYzIrQDg97+hGVdsSGPQ==
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.6.tgz#ebdb6da22dfac0a22222f2d4da06f66c416a0ec0"
+ integrity sha512-SZ/lVU7LRXafqp7XtIcBdxnWl8yyLpgOmzAk0mWBI9gXNzLDx5ybZgnRbH9dN/yY5tzVBqCQ9avltSnqVwessQ==
d3-format@1:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.1.tgz#c45f74b17c5a290c072a4ba7039dd19662cd5ce6"
- integrity sha512-TUswGe6hfguUX1CtKxyG2nymO+1lyThbkS1ifLX0Sr+dOQtAD5gkrffpHnx+yHNKUZ0Bmg5T4AjUQwugPDrm0g==
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.2.tgz#2a8c0ebf500f315981c2110eaaf70b82f472cb2b"
+ integrity sha512-gco1Ih54PgMsyIXgttLxEhNy/mXxq8+rLnCb5shQk+P5TsiySrwWU5gpB4zen626J4LIwBxHvDChyA8qDm57ww==
d3-interpolate@1, d3-interpolate@^1.1.1:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.3.2.tgz#417d3ebdeb4bc4efcc8fd4361c55e4040211fd68"
- integrity sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w==
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.3.3.tgz#cef4ba06dfccebcc45e4ae9d4d836a931a945076"
+ integrity sha512-wTsi4AqnC2raZ3Q9eqFxiZGUf5r6YiEdi23vXjjKSWXFYLCQNUtBVMk6uk2tg4cOY6YrjRdmSmI/Mf0ze1zPzQ==
dependencies:
d3-color "1"
d3-path@1:
- version "1.0.8"
- resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.8.tgz#4a0606a794d104513ec4a8af43525f374b278719"
- integrity sha512-J6EfUNwcMQ+aM5YPOB8ZbgAZu6wc82f/0WFxrxwV6Ll8wBwLaHLKCqQ5Imub02JriCVVdPjgI+6P3a4EWJCxAg==
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf"
+ integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==
d3-queue@^3.0.7:
version "3.0.7"
@@ -4871,16 +4236,16 @@ d3-scale@^1.0.0:
d3-time-format "2"
d3-shape@^1.0.0, d3-shape@^1.2.0:
- version "1.3.5"
- resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.5.tgz#e81aea5940f59f0a79cfccac012232a8987c6033"
- integrity sha512-VKazVR3phgD+MUCldapHD7P9kcrvPcexeX/PkMJmkUov4JM8IxsSg1DvbYoYich9AtdTsa5nNk2++ImPiDiSxg==
+ version "1.3.7"
+ resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7"
+ integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==
dependencies:
d3-path "1"
d3-time-format@2:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.2.1.tgz#971f66aae3b8fb268040494986f41512d4d4dca6"
- integrity sha512-VA6WqORO1+H1SvSzgl2oT0z3niANh3opa8Cencpen1LFthw/bEX71R/DgjPlWw78J4UHmD0jCPP1W0HpwMkhjg==
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.2.2.tgz#187597ffc6a0f37cb36bb7a1d7167cdc887ecda0"
+ integrity sha512-pweL2Ri2wqMY+wlW/wpkl8T3CUzKAha8S9nmiQlMABab8r5MJN0PD1V4YyRNVaKQfeh4Z0+VO70TLw6ESVOYzw==
dependencies:
d3-time "1"
@@ -4890,20 +4255,28 @@ d3-time@1:
integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==
d3-timer@^1.0.0:
- version "1.0.9"
- resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.9.tgz#f7bb8c0d597d792ff7131e1c24a36dd471a471ba"
- integrity sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg==
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.10.tgz#dfe76b8a91748831b13b6d9c793ffbd508dd9de5"
+ integrity sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==
d3-voronoi@^1.1.2:
version "1.1.4"
resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.4.tgz#dd3c78d7653d2bb359284ae478645d95944c8297"
integrity sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg==
-d3@~3.5.0, d3@~3.5.17:
+d3@^3.5.17, d3@~3.5.0, d3@~3.5.17:
version "3.5.17"
resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8"
integrity sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g=
+d@1, d@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
+ integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
+ dependencies:
+ es5-ext "^0.10.50"
+ type "^1.0.1"
+
damerau-levenshtein@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz#780cf7144eb2e8dbd1c3bb83ae31100ccc31a414"
@@ -4965,12 +4338,7 @@ datatables.net@1.10.20, datatables.net@^1.10.15:
dependencies:
jquery ">=1.7"
-dateformat@^3.0.0:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
- integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
-
-"debug@0.8.0 - 3.5.0", debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
+"debug@0.8.0 - 3.5.0", debug@^3.0.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
@@ -4984,34 +4352,14 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.
dependencies:
ms "2.0.0"
-debug@3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
- integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
- dependencies:
- ms "2.0.0"
-
-debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
+debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
dependencies:
ms "^2.1.1"
-debuglog@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
- integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
-
-decamelize-keys@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9"
- integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=
- dependencies:
- decamelize "^1.1.0"
- map-obj "^1.0.0"
-
-decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.2.0:
+decamelize@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
@@ -5028,11 +4376,6 @@ decode-uri-component@^0.2.0:
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
-dedent@0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
- integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
-
deep-equal@^1.0.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
@@ -5063,13 +4406,6 @@ default-gateway@^4.2.0:
execa "^1.0.0"
ip-regex "^2.1.0"
-defaults@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
- integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=
- dependencies:
- clone "^1.0.2"
-
define-properties@^1.1.2, define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@@ -5116,10 +4452,10 @@ delaunator@^4.0.0:
resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-4.0.1.tgz#3d779687f57919a7a418f8ab947d3bddb6846957"
integrity sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==
-delaunay-find@0.0.3:
- version "0.0.3"
- resolved "https://registry.yarnpkg.com/delaunay-find/-/delaunay-find-0.0.3.tgz#b9863465c4cbca963b3d75a54550e73b2fc56c30"
- integrity sha512-Ex8DtJudrPsB0IhmJxFjHqzZnzbCOoFgw8kTGAnTlc6uU/v25nd7o2HeWhyZSaPhholsfL33PmLSEdaBi0qfug==
+delaunay-find@0.0.5:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/delaunay-find/-/delaunay-find-0.0.5.tgz#5fb37e6509da934881b4b16c08898ac89862c097"
+ integrity sha512-7yAJ/wmKWj3SgqjtkGqT/RCwI0HWAo5YnHMoF5nYXD8cdci+YSo23iPmgrZUNOpDxRWN91PqxUvMMr2lKpjr+w==
dependencies:
delaunator "^4.0.0"
@@ -5138,11 +4474,6 @@ depd@~1.1.2:
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
-deprecation@^2.0.0:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
- integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
-
des.js@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
@@ -5156,16 +4487,6 @@ destroy@~1.0.4:
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
-detect-file@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
- integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=
-
-detect-indent@6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.0.0.tgz#0abd0f549f69fc6659a254fe96786186b6f528fd"
- integrity sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==
-
detect-indent@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
@@ -5173,11 +4494,6 @@ detect-indent@^4.0.0:
dependencies:
repeating "^2.0.0"
-detect-indent@~5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
- integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50=
-
detect-libc@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
@@ -5201,14 +4517,6 @@ detect-port-alt@1.1.6:
address "^1.0.1"
debug "^2.6.0"
-dezalgo@^1.0.0, dezalgo@~1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456"
- integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=
- dependencies:
- asap "^2.0.0"
- wrappy "1"
-
diff-sequences@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5"
@@ -5231,13 +4539,6 @@ dir-glob@2.0.0:
arrify "^1.0.1"
path-type "^3.0.0"
-dir-glob@^3.0.0, dir-glob@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
- integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
- dependencies:
- path-type "^4.0.0"
-
dns-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
@@ -5287,13 +4588,6 @@ dom-converter@^0.2:
dependencies:
utila "~0.4"
-dom-helpers@^3.2.0, dom-helpers@^3.2.1, dom-helpers@^3.4.0:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8"
- integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==
- dependencies:
- "@babel/runtime" "^7.1.2"
-
dom-serializer@0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
@@ -5347,35 +4641,23 @@ domutils@^1.5.1, domutils@^1.7.0:
dom-serializer "0"
domelementtype "1"
-dot-prop@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177"
- integrity sha1-G3CK8JSknJoOfbyteQq6U52sEXc=
- dependencies:
- is-obj "^1.0.0"
-
-dot-prop@^4.1.0, dot-prop@^4.1.1:
+dot-prop@^4.1.1:
version "4.2.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==
dependencies:
is-obj "^1.0.0"
-dotenv-expand@4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-4.2.0.tgz#def1f1ca5d6059d24a766e587942c21106ce1275"
- integrity sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU=
+dotenv-expand@5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0"
+ integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==
dotenv@6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064"
integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==
-dotenv@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef"
- integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==
-
drmonty-datatables-colvis@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/drmonty-datatables-colvis/-/drmonty-datatables-colvis-1.1.2.tgz#96ab9edfb48643cc2edda3f87b88933cdee8127c"
@@ -5383,18 +4665,13 @@ drmonty-datatables-colvis@~1.1.2:
dependencies:
jquery ">=1.7.0"
-duplexer2@^0.1.2, duplexer2@~0.1.0:
+duplexer2@^0.1.2:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
integrity sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=
dependencies:
readable-stream "^2.0.2"
-duplexer3@^0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
- integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
-
duplexer@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
@@ -5418,11 +4695,6 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
-editor@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742"
- integrity sha1-YMf4e9YrzGqJT6jM1q+3gjok90I=
-
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@@ -5451,6 +4723,11 @@ emoji-regex@^7.0.1, emoji-regex@^7.0.2:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
+emoji-regex@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
+ integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+
emojis-list@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
@@ -5476,13 +4753,6 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
-encoding@^0.1.11:
- version "0.1.12"
- resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
- integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=
- dependencies:
- iconv-lite "~0.4.13"
-
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
@@ -5509,19 +4779,6 @@ entities@^2.0.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4"
integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==
-env-ci@^4.0.0:
- version "4.5.1"
- resolved "https://registry.yarnpkg.com/env-ci/-/env-ci-4.5.1.tgz#2ef014dcb974728b46d1244e491e9e6ccc1923ef"
- integrity sha512-Xtmr+ordf8POu3NcNzx3eOa2zHyfD4h3fPHX5fLklkWa86ck35n1c9oZmyUnVPUl9zHnpZWdWtCUBPSWEagjCQ==
- dependencies:
- execa "^3.2.0"
- java-properties "^1.0.0"
-
-env-paths@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0"
- integrity sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=
-
eonasdan-bootstrap-datetimepicker@^4.17.47:
version "4.17.47"
resolved "https://registry.yarnpkg.com/eonasdan-bootstrap-datetimepicker/-/eonasdan-bootstrap-datetimepicker-4.17.47.tgz#7a49970044065276e7965efd16f822735219e735"
@@ -5532,11 +4789,6 @@ eonasdan-bootstrap-datetimepicker@^4.17.47:
moment "^2.10"
moment-timezone "^0.4.0"
-err-code@^1.0.0:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960"
- integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=
-
errno@^0.1.3, errno@~0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
@@ -5576,17 +4828,31 @@ es-to-primitive@^1.2.0:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
-es6-promise@^4.0.3:
- version "4.2.8"
- resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
- integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
+es5-ext@^0.10.35, es5-ext@^0.10.50:
+ version "0.10.52"
+ resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.52.tgz#bb21777e919a04263736ded120a9d665f10ea63f"
+ integrity sha512-bWCbE9fbpYQY4CU6hJbJ1vSz70EClMlDgJ7BmwI+zEJhxrwjesZRPglGJlsZhu0334U3hI+gaspwksH9IGD6ag==
+ dependencies:
+ es6-iterator "~2.0.3"
+ es6-symbol "~3.1.2"
+ next-tick "~1.0.0"
-es6-promisify@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
- integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
+es6-iterator@2.0.3, es6-iterator@~2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
+ integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
dependencies:
- es6-promise "^4.0.3"
+ d "1"
+ es5-ext "^0.10.35"
+ es6-symbol "^3.1.1"
+
+es6-symbol@^3.1.1, es6-symbol@~3.1.2:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
+ integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
+ dependencies:
+ d "^1.0.1"
+ ext "^1.1.2"
escape-html@~1.0.3:
version "1.0.3"
@@ -5631,12 +4897,12 @@ eslint-config-prettier@^2.9.0:
dependencies:
get-stdin "^5.0.1"
-eslint-config-react-app@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-4.0.1.tgz#23fd0fd7ea89442ef1e733f66a7207674b23c8db"
- integrity sha512-ZsaoXUIGsK8FCi/x4lT2bZR5mMkL/Kgj+Lnw690rbvvUr/uiwgFiD8FcfAhkCycm7Xte6O5lYz4EqMx2vX7jgw==
+eslint-config-react-app@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-5.0.2.tgz#df40d73a1402986030680c040bbee520db5a32a4"
+ integrity sha512-VhlESAQM83uULJ9jsvcKxx2Ab0yrmjUt8kDz5DyhTQufqWE0ssAnejlWri5LXv25xoXfdqOyeDPdfJS9dXKagQ==
dependencies:
- confusing-browser-globals "^1.0.7"
+ confusing-browser-globals "^1.0.9"
eslint-config-standard-jsx@^5.0.0:
version "5.0.0"
@@ -5663,18 +4929,18 @@ eslint-import-resolver-node@^0.3.2:
debug "^2.6.9"
resolve "^1.5.0"
-eslint-loader@2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.1.2.tgz#453542a1230d6ffac90e4e7cb9cadba9d851be68"
- integrity sha512-rA9XiXEOilLYPOIInvVH5S/hYfyTPyxag6DZhoQOduM+3TkghAEQ3VcFO8VnX4J4qg/UIBzp72aOf/xvYmpmsg==
+eslint-loader@3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-3.0.2.tgz#5a627316a51d6f41d357b9f6f0554e91506cdd6e"
+ integrity sha512-S5VnD+UpVY1PyYRqeBd/4pgsmkvSokbHqTXAQMpvCyRr3XN2tvSLo9spm2nEpqQqh9dezw3os/0zWihLeOg2Rw==
dependencies:
- loader-fs-cache "^1.0.0"
- loader-utils "^1.0.2"
- object-assign "^4.0.1"
- object-hash "^1.1.4"
- rimraf "^2.6.1"
+ fs-extra "^8.1.0"
+ loader-fs-cache "^1.0.2"
+ loader-utils "^1.2.3"
+ object-hash "^1.3.1"
+ schema-utils "^2.2.0"
-eslint-module-utils@^2.3.0, eslint-module-utils@^2.4.0:
+eslint-module-utils@^2.4.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz#7b4675875bf96b0dbf1b21977456e5bb1f5e018c"
integrity sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==
@@ -5682,30 +4948,14 @@ eslint-module-utils@^2.3.0, eslint-module-utils@^2.4.0:
debug "^2.6.8"
pkg-dir "^2.0.0"
-eslint-plugin-flowtype@2.50.1:
- version "2.50.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.1.tgz#36d4c961ac8b9e9e1dc091d3fba0537dad34ae8a"
- integrity sha512-9kRxF9hfM/O6WGZcZPszOVPd2W0TLHBtceulLTsGfwMPtiCCLnCW0ssRiOOiXyqrCA20pm1iXdXm7gQeN306zQ==
- dependencies:
- lodash "^4.17.10"
-
-eslint-plugin-import@2.16.0:
- version "2.16.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz#97ac3e75d0791c4fac0e15ef388510217be7f66f"
- integrity sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A==
+eslint-plugin-flowtype@3.13.0:
+ version "3.13.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-3.13.0.tgz#e241ebd39c0ce519345a3f074ec1ebde4cf80f2c"
+ integrity sha512-bhewp36P+t7cEV0b6OdmoRWJCBYRiHFlqPZAG1oS3SF+Y0LQkeDvFSM4oxoxvczD1OdONCXMlJfQFiWLcV9urw==
dependencies:
- contains-path "^0.1.0"
- debug "^2.6.9"
- doctrine "1.5.0"
- eslint-import-resolver-node "^0.3.2"
- eslint-module-utils "^2.3.0"
- has "^1.0.3"
- lodash "^4.17.11"
- minimatch "^3.0.4"
- read-pkg-up "^2.0.0"
- resolve "^1.9.0"
+ lodash "^4.17.15"
-eslint-plugin-import@^2.13.0:
+eslint-plugin-import@2.18.2, eslint-plugin-import@^2.13.0:
version "2.18.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz#02f1180b90b077b33d447a17a2326ceb400aceb6"
integrity sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==
@@ -5727,21 +4977,7 @@ eslint-plugin-jest@^21.15.0:
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-21.27.2.tgz#2a795b7c3b5e707df48a953d651042bd01d7b0a8"
integrity sha512-0E4OIgBJVlAmf1KfYFtZ3gYxgUzC5Eb3Jzmrc9ikI1OY+/cM8Kh72Ti7KfpeHNeD3HJNf9SmEfmvQLIz44Hrhw==
-eslint-plugin-jsx-a11y@6.2.1:
- version "6.2.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz#4ebba9f339b600ff415ae4166e3e2e008831cf0c"
- integrity sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w==
- dependencies:
- aria-query "^3.0.0"
- array-includes "^3.0.3"
- ast-types-flow "^0.0.7"
- axobject-query "^2.0.2"
- damerau-levenshtein "^1.0.4"
- emoji-regex "^7.0.2"
- has "^1.0.3"
- jsx-ast-utils "^2.0.1"
-
-eslint-plugin-jsx-a11y@^6.0.3:
+eslint-plugin-jsx-a11y@6.2.3, eslint-plugin-jsx-a11y@^6.0.3:
version "6.2.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz#b872a09d5de51af70a97db1eea7dc933043708aa"
integrity sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==
@@ -5800,23 +5036,25 @@ eslint-plugin-promise@^3.7.0:
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz#65ebf27a845e3c1e9d6f6a5622ddd3801694b621"
integrity sha512-JiFL9UFR15NKpHyGii1ZcvmtIqa3UTwiDAGb8atSffe43qJ3+1czVGN6UtkklpcJ2DVnqvTMzEKRaJdBkAL2aQ==
-eslint-plugin-react-hooks@^1.5.0:
+eslint-plugin-react-hooks@^1.6.1:
version "1.7.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04"
integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==
-eslint-plugin-react@7.12.4:
- version "7.12.4"
- resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c"
- integrity sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ==
+eslint-plugin-react@7.14.3:
+ version "7.14.3"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13"
+ integrity sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==
dependencies:
array-includes "^3.0.3"
doctrine "^2.1.0"
has "^1.0.3"
- jsx-ast-utils "^2.0.1"
+ jsx-ast-utils "^2.1.0"
+ object.entries "^1.1.0"
object.fromentries "^2.0.0"
- prop-types "^15.6.2"
- resolve "^1.9.0"
+ object.values "^1.1.0"
+ prop-types "^15.7.2"
+ resolve "^1.10.1"
eslint-plugin-react@^7.7.0:
version "7.16.0"
@@ -5856,7 +5094,7 @@ eslint-scope@3.7.1:
esrecurse "^4.1.0"
estraverse "^4.1.1"
-eslint-scope@^4.0.0, eslint-scope@^4.0.3:
+eslint-scope@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848"
integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==
@@ -5864,7 +5102,15 @@ eslint-scope@^4.0.0, eslint-scope@^4.0.3:
esrecurse "^4.1.0"
estraverse "^4.1.1"
-eslint-utils@^1.3.1:
+eslint-scope@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9"
+ integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==
+ dependencies:
+ esrecurse "^4.1.0"
+ estraverse "^4.1.1"
+
+eslint-utils@^1.4.2, eslint-utils@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f"
integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==
@@ -5876,63 +5122,64 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
-eslint@^5.16.0:
- version "5.16.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea"
- integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==
+eslint@^6.1.0:
+ version "6.6.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.6.0.tgz#4a01a2fb48d32aacef5530ee9c5a78f11a8afd04"
+ integrity sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g==
dependencies:
"@babel/code-frame" "^7.0.0"
- ajv "^6.9.1"
+ ajv "^6.10.0"
chalk "^2.1.0"
cross-spawn "^6.0.5"
debug "^4.0.1"
doctrine "^3.0.0"
- eslint-scope "^4.0.3"
- eslint-utils "^1.3.1"
- eslint-visitor-keys "^1.0.0"
- espree "^5.0.1"
+ eslint-scope "^5.0.0"
+ eslint-utils "^1.4.3"
+ eslint-visitor-keys "^1.1.0"
+ espree "^6.1.2"
esquery "^1.0.1"
esutils "^2.0.2"
file-entry-cache "^5.0.1"
functional-red-black-tree "^1.0.1"
- glob "^7.1.2"
+ glob-parent "^5.0.0"
globals "^11.7.0"
ignore "^4.0.6"
import-fresh "^3.0.0"
imurmurhash "^0.1.4"
- inquirer "^6.2.2"
- js-yaml "^3.13.0"
+ inquirer "^7.0.0"
+ is-glob "^4.0.0"
+ js-yaml "^3.13.1"
json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.3.0"
- lodash "^4.17.11"
+ lodash "^4.17.14"
minimatch "^3.0.4"
mkdirp "^0.5.1"
natural-compare "^1.4.0"
optionator "^0.8.2"
- path-is-inside "^1.0.2"
progress "^2.0.0"
regexpp "^2.0.1"
- semver "^5.5.1"
- strip-ansi "^4.0.0"
- strip-json-comments "^2.0.1"
+ semver "^6.1.2"
+ strip-ansi "^5.2.0"
+ strip-json-comments "^3.0.1"
table "^5.2.3"
text-table "^0.2.0"
+ v8-compile-cache "^2.0.3"
-espree@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a"
- integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==
+espree@^6.1.2:
+ version "6.1.2"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.2.tgz#6c272650932b4f91c3714e5e7b5f5e2ecf47262d"
+ integrity sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==
dependencies:
- acorn "^6.0.7"
- acorn-jsx "^5.0.0"
- eslint-visitor-keys "^1.0.0"
+ acorn "^7.1.0"
+ acorn-jsx "^5.1.0"
+ eslint-visitor-keys "^1.1.0"
esprima@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
-esprima@^4.0.0, esprima@~4.0.0:
+esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
@@ -5996,19 +5243,6 @@ exec-sh@^0.3.2:
resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5"
integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==
-execa@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
- integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=
- dependencies:
- cross-spawn "^5.0.1"
- get-stream "^3.0.0"
- is-stream "^1.1.0"
- npm-run-path "^2.0.0"
- p-finally "^1.0.0"
- signal-exit "^3.0.0"
- strip-eof "^1.0.0"
-
execa@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
@@ -6022,22 +5256,6 @@ execa@^1.0.0:
signal-exit "^3.0.0"
strip-eof "^1.0.0"
-execa@^3.2.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/execa/-/execa-3.3.0.tgz#7e348eef129a1937f21ecbbd53390942653522c1"
- integrity sha512-j5Vit5WZR/cbHlqU97+qcnw9WHRCIL4V1SVe75VcHcD1JRBdt8fv0zw89b7CQHQdUHTt2VjuhcF5ibAgVOxqpg==
- dependencies:
- cross-spawn "^7.0.0"
- get-stream "^5.0.0"
- human-signals "^1.1.1"
- is-stream "^2.0.0"
- merge-stream "^2.0.0"
- npm-run-path "^4.0.0"
- onetime "^5.1.0"
- p-finally "^2.0.0"
- signal-exit "^3.0.2"
- strip-final-newline "^2.0.0"
-
exenv@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
@@ -6061,13 +5279,6 @@ expand-brackets@^2.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
-expand-tilde@^2.0.0, expand-tilde@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
- integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=
- dependencies:
- homedir-polyfill "^1.0.1"
-
expect@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca"
@@ -6116,6 +5327,13 @@ express@^4.16.2, express@^4.17.1:
utils-merge "1.0.1"
vary "~1.1.2"
+ext@^1.1.2:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/ext/-/ext-1.2.0.tgz#8dd8d2dd21bcced3045be09621fa0cbf73908ba4"
+ integrity sha512-0ccUQK/9e3NreLFg6K6np8aPyRgwycx+oFGtfx1dSp7Wj00Ozw9r05FgBRlzjf2XBM7LAzwgLyDscRrtSU91hA==
+ dependencies:
+ type "^2.0.0"
+
extend-shallow@^1.1.2:
version "1.1.4"
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071"
@@ -6208,17 +5426,6 @@ fast-glob@^2.0.2:
merge2 "^1.2.3"
micromatch "^3.1.10"
-fast-glob@^3.0.3:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.1.0.tgz#77375a7e3e6f6fc9b18f061cddd28b8d1eec75ae"
- integrity sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==
- dependencies:
- "@nodelib/fs.stat" "^2.0.2"
- "@nodelib/fs.walk" "^1.2.3"
- glob-parent "^5.1.0"
- merge2 "^1.3.0"
- micromatch "^4.0.2"
-
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
@@ -6229,13 +5436,6 @@ fast-levenshtein@~2.0.6:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
-fastq@^1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2"
- integrity sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==
- dependencies:
- reusify "^1.0.0"
-
faye-websocket@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
@@ -6273,20 +5473,7 @@ fbjs-scripts@^0.8.3:
semver "^5.1.0"
through2 "^2.0.0"
-fbjs@^0.8.1:
- version "0.8.17"
- resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
- integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=
- dependencies:
- core-js "^1.0.0"
- isomorphic-fetch "^2.1.1"
- loose-envify "^1.0.0"
- object-assign "^4.1.0"
- promise "^7.1.1"
- setimmediate "^1.0.5"
- ua-parser-js "^0.7.18"
-
-figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
+figgy-pudding@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
@@ -6335,13 +5522,6 @@ fill-range@^4.0.0:
repeat-string "^1.6.1"
to-regex-range "^2.1.0"
-fill-range@^7.0.1:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
- integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
- dependencies:
- to-regex-range "^5.0.1"
-
finalhandler@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
@@ -6373,20 +5553,7 @@ find-cache-dir@^2.0.0, find-cache-dir@^2.1.0:
make-dir "^2.0.0"
pkg-dir "^3.0.0"
-find-node-modules@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/find-node-modules/-/find-node-modules-2.0.0.tgz#5db1fb9e668a3d451db3d618cd167cdd59e41b69"
- integrity sha512-8MWIBRgJi/WpjjfVXumjPKCtmQ10B+fjx6zmSA+770GMJirLhWIzg8l763rhjl9xaeaHbnxPNRQKq2mgMhr+aw==
- dependencies:
- findup-sync "^3.0.0"
- merge "^1.2.1"
-
-find-npm-prefix@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf"
- integrity sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA==
-
-find-root@1.1.0, find-root@^1.1.0:
+find-root@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
@@ -6413,32 +5580,6 @@ find-up@^2.0.0, find-up@^2.1.0:
dependencies:
locate-path "^2.0.0"
-find-up@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
- integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
- dependencies:
- locate-path "^5.0.0"
- path-exists "^4.0.0"
-
-find-versions@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.1.0.tgz#10161f29cf3eb4350dec10a29bdde75bff0df32d"
- integrity sha512-NCTfNiVzeE/xL+roNDffGuRbrWI6atI18lTJ22vKp7rs2OhYzMK3W1dIdO2TUndH/QMcacM4d1uWwgcZcHK69Q==
- dependencies:
- array-uniq "^2.1.0"
- semver-regex "^2.0.0"
-
-findup-sync@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1"
- integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==
- dependencies:
- detect-file "^1.0.0"
- is-glob "^4.0.0"
- micromatch "^3.0.4"
- resolve-dir "^1.0.1"
-
flat-cache@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0"
@@ -6515,13 +5656,6 @@ for-own@^0.1.3:
... 5404 lines suppressed ...
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org