diff --git a/.gitattributes b/.gitattributes index 631783b0c97791a3c6dc85cc8fe0f0477cf224e8..fc08600221760329c77f34bc1029e5883458ca02 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1846,13 +1846,22 @@ LCU/Maintenance/MDB_WebView/maintenancedb_view/src/App.css -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/App.js -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/App.test.js -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/api_configuration.js -text -LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LandingPage.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.css -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.scss -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationDetails.js -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationList.css -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationList.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.css -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.scss -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationStatistics.js -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.css -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.scss -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.css -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.scss -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/lofar_logo.svg -text svneol=unset#image/svg%2Bxml LCU/Maintenance/MDB_WebView/maintenancedb_view/src/index.css -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/index.js -text @@ -1863,13 +1872,28 @@ LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/RTSMPage.js -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/StationOverviewPage.js -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/StationTestPage.js -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/TilesPage.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/appInitDataActions.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/landingPageActions.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/mainFiltersActions.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/appInitDataReducers.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/index.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/landingPageReducers.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/mainFilters.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/store.js -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/registerServiceWorker.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/latest_observations.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/station_details.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/station_overview.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/station_test_summary.js -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-styles.css -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-styles.scss -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-variables.css -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-variables.scss -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar.css -text LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar.scss -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/autoLoader.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/constants.js -text +LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/utils.js -text LCU/Maintenance/MDB_tools/CMakeLists.txt -text LCU/Maintenance/MDB_tools/bin/mdb_loader.py -text LCU/Maintenance/MDB_tools/bin/probe_mdb.py -text diff --git a/CMake/NPMInstall.cmake b/CMake/NPMInstall.cmake index 0f597438f175b9bd0761fc5fd595d360cc383446..907321f1a17c2fbd0401aa4c280566e3109f7782 100644 --- a/CMake/NPMInstall.cmake +++ b/CMake/NPMInstall.cmake @@ -40,6 +40,24 @@ find_package(NPM) +function(extract_relative_path OUTPUT_FILE_LIST BASE_PATH ARGC) + set(OUTPUT "") + foreach(FILE ${ARGC}) + file(RELATIVE_PATH RELPATH ${BASE_PATH} "${FILE}") + list(APPEND OUTPUT "${RELPATH}") + endforeach(FILE) + set(${OUTPUT_FILE_LIST} ${OUTPUT} PARENT_SCOPE) +endfunction(extract_relative_path) + +function(append_basepath_to_file OUTPUT_FILE_LIST BASE_PATH ARGC) + set(OUTPUT "") + foreach(FILE ${ARGC}) + set(ITEM "${BASE_PATH}/${FILE}") + list(APPEND OUTPUT "${ITEM}") + endforeach(FILE) + set(${OUTPUT_FILE_LIST} ${OUTPUT} PARENT_SCOPE) +endfunction(append_basepath_to_file) + # # function npm_install # @@ -70,7 +88,7 @@ function(npm_install NPM_PACKAGE_SPECIFICATION) get_filename_component(WEBSITE_PUBLIC_DIR "${NPM_INSTALL_PUBLIC}" REALPATH) get_filename_component(WEBSITE_SOURCE_DIR "${NPM_INSTALL_SOURCE}" REALPATH) get_filename_component(JSON_PACKAGE_SPECIFICATION "${NPM_PACKAGE_SPECIFICATION}" REALPATH) - + get_filename_component(NPM_BINARY_DIR "${NPM_BINARY_DIR}" REALPATH) # Checks if the directories public and source are actually present in the disk if(EXISTS WEBSITE_PUBLIC_DIR) message(FATAL_ERROR "public directory \"${NPM_INSTALL_PUBLIC}\" cannot be found.") @@ -82,49 +100,76 @@ function(npm_install NPM_PACKAGE_SPECIFICATION) get_filename_component(NPM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" REALPATH) - add_custom_target(copy_src_public_${PACKAGE_NAME} SOURCES ${NPM_BINARY_DIR}/public ${NPM_BINARY_DIR}/src) - add_custom_target(copy_package_json_${PACKAGE_NAME} SOURCES "${NPM_BINARY_DIR}/package.json") - add_custom_target(download_npm_dependencies_${PACKAGE_NAME} SOURCES "${NPM_BINARY_DIR}/node_modules" "${NPM_BINARY_DIR}/package-lock.json" DEPENDS copy_src_public_${PACKAGE_NAME} copy_package_json_${PACKAGE_NAME}) - add_custom_target(packing_javascript_files_${PACKAGE_NAME} ALL SOURCES ${NPM_BINARY_DIR}/build) - add_custom_target(start_development_server_${PACKAGE_NAME} SOURCES "${NPM_BINARY_DIR}/node_modules" "${NPM_BINARY_DIR}/package-lock.json" "${NPM_BINARY_DIR}/package.json" - COMMENT "Start start_development_server for ${PACKAGE_NAME}") + file(GLOB_RECURSE SOURCE_FILES_PATH ${WEBSITE_SOURCE_DIR} "${WEBSITE_SOURCE_DIR}/*") + file(GLOB_RECURSE PUBLIC_FILES_PATH ${WEBSITE_PUBLIC_DIR} "${WEBSITE_PUBLIC_DIR}/*") + + extract_relative_path(SOURCE_FILES ${WEBSITE_SOURCE_DIR} "${SOURCE_FILES_PATH}") + extract_relative_path(PUBLIC_FILES ${WEBSITE_PUBLIC_DIR} "${PUBLIC_FILES_PATH}") + + append_basepath_to_file(INSTALLED_SOURCE_FILES "${NPM_BINARY_DIR}/src" "${SOURCE_FILES}") + append_basepath_to_file(INSTALLED_PUBLIC_FILES "${NPM_BINARY_DIR}/public" "${PUBLIC_FILES}") add_custom_command( OUTPUT "${NPM_BINARY_DIR}/package.json" - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${JSON_PACKAGE_SPECIFICATION} ${NPM_BINARY_DIR}/package.json + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${JSON_PACKAGE_SPECIFICATION}" "${NPM_BINARY_DIR}/package.json" DEPENDS ${JSON_PACKAGE_SPECIFICATION} COMMENT "Copying ${JSON_PACKAGE_SPECIFICATION} to ${NPM_BINARY_DIR}/package.json for ${PACKAGE_NAME}") + foreach(file ${SOURCE_FILES}) + add_custom_command(OUTPUT "${NPM_BINARY_DIR}/src/${file}" + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${WEBSITE_SOURCE_DIR}/${file} ${NPM_BINARY_DIR}/src/${file} + DEPENDS "${WEBSITE_SOURCE_DIR}/${file}" + COMMENT "Copying file from ${WEBSITE_SOURCE_DIR}/${file} to ${NPM_BINARY_DIR}/src/${file}") + endforeach(file) + + foreach(file ${PUBLIC_FILES}) + add_custom_command(OUTPUT "${NPM_BINARY_DIR}/public/${file}" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${WEBSITE_PUBLIC_DIR}/${file}" "${NPM_BINARY_DIR}/public/${file}" + DEPENDS "${WEBSITE_PUBLIC_DIR}/${file}" + COMMENT "Copying file from ${WEBSITE_PUBLIC_DIR}/${file} to ${NPM_BINARY_DIR}/src/${file}") + endforeach(file) + + add_custom_target(copy_package_json_${PACKAGE_NAME} SOURCES "${JSON_PACKAGE_SPECIFICATION}") + add_custom_target(download_npm_dependencies_${PACKAGE_NAME} SOURCES "${NPM_BINARY_DIR}/package.json") + add_custom_target(packing_javascript_files_${PACKAGE_NAME} ALL + SOURCES ${INSTALLED_SOURCE_FILES} ${INSTALLED_PUBLIC_FILES} "${NPM_BINARY_DIR}/node_modules" "${NPM_BINARY_DIR}/package-lock.json") + + add_custom_target(start_development_server_${PACKAGE_NAME} + SOURCES "${NPM_BINARY_DIR}/node_modules" "${NPM_BINARY_DIR}/package-lock.json" "${NPM_BINARY_DIR}/package.json" + COMMENT "Start start_development_server for ${PACKAGE_NAME}") + + add_custom_command( OUTPUT "${NPM_BINARY_DIR}/src" - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${WEBSITE_SOURCE_DIR} ${NPM_BINARY_DIR}/src - COMMENT "Copying javascript src directory from ${WEBSITE_SOURCE_DIR} to ${NPM_BINARY_DIR}/src for ${PACKAGE_NAME}") + COMMAND ${CMAKE_COMMAND} -E make_directory ${NPM_BINARY_DIR}/src + COMMENT "Creating javascript src directory in ${NPM_BINARY_DIR}/src for ${PACKAGE_NAME}") add_custom_command( - OUTPUT "${NPM_BINARY_DIR}/public" - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${WEBSITE_PUBLIC_DIR} ${NPM_BINARY_DIR}/public - COMMENT "Copying public directory ${WEBSITE_PUBLIC_DIR} to ${NPM_BINARY_DIR}/public for ${PACKAGE_NAME}") + OUTPUT "${NPM_BINARY_DIR}/public" + COMMAND ${CMAKE_COMMAND} -E make_directory ${NPM_BINARY_DIR}/public + COMMENT "Creating public directory ${NPM_BINARY_DIR}/public for ${PACKAGE_NAME}") + add_custom_command( OUTPUT "${NPM_BINARY_DIR}/node_modules" "${NPM_BINARY_DIR}/package-lock.json" COMMAND npm install - DEPENDS "package.json" - WORKING_DIRECTORY ${NPM_BINARY_DIR} + DEPENDS "${NPM_BINARY_DIR}/package.json" + WORKING_DIRECTORY "${NPM_BINARY_DIR}" COMMENT "Downloading npm dependencies for ${NPM_BINARY_DIR}/package.json") add_custom_command( TARGET start_development_server_${PACKAGE_NAME} COMMAND npm start - WORKING_DIRECTORY ${NPM_BINARY_DIR} + DEPENDS ${INSTALLED_SOURCE_FILES} ${INSTALLED_PUBLIC_FILES} + WORKING_DIRECTORY "${NPM_BINARY_DIR}" COMMENT "Starting development server for ${PACKAGE_NAME}") + add_custom_command( - OUTPUT "${NPM_BINARY_DIR}/build" + TARGET packing_javascript_files_${PACKAGE_NAME} COMMAND npm run build - DEPENDS copy_src_public_${PACKAGE_NAME} download_npm_dependencies_${PACKAGE_NAME} + DEPENDS "${INSTALLED_SOURCE_FILES}" "${INSTALLED_PUBLIC_FILES}" + WORKING_DIRECTORY "${NPM_BINARY_DIR}" COMMENT "Packing javascript files for ${PACKAGE_NAME} into ${NPM_BINARY_DIR}/build for deployment") install(DIRECTORY ${NPM_BINARY_DIR}/build/ DESTINATION ${NPM_INSTALL_DESTINATION}) diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/CMakeLists.txt b/LCU/Maintenance/MDB_WebView/maintenancedb_view/CMakeLists.txt index 517bc1d64e03051f487337805c837ff0f5662ec0..8fa0dbaf72ada93314cac77eecf9b1a5fc6cf2bf 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/CMakeLists.txt +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/CMakeLists.txt @@ -4,4 +4,4 @@ lofar_package(mainteancedb_view 1.0) include(NPMInstall) -npm_install(package.json PUBLIC public SOURCE src DESTINATION /opt/lofar/share/www) +npm_install(package.json PUBLIC public SOURCE src DESTINATION opt/lofar/share/www) diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/package.json b/LCU/Maintenance/MDB_WebView/maintenancedb_view/package.json index 65195a89f98b91137e84fff65123416152154bc0..5cbbf37a648e393c568814565aadab97ff600087 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/package.json +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/package.json @@ -2,6 +2,7 @@ "name": "maintenancedb_view", "version": "0.1.0", "description": "WebPage meant to display the content of the maintenance db in the web browser,", + "proxy": "http://lofarmonitortest.control.lofar", "scripts": { "flow": "flow", "build-css": "node-sass-chokidar src/ -o src/", @@ -15,16 +16,26 @@ "deploy": "npm run build" }, "dependencies": { + "ajv": "^6.5.4", + "axios": "^0.18.0", "bootstrap": "^4.1.3", - "jquery": "^1.9.1", + "moment": "^2.22.2", "node-sass-chokidar": "^1.3.3", "react": "^16.4.2", "react-dom": "^16.4.2", + "react-grid-layout": "^0.16.6", + "react-redux": "^5.0.7", "react-router": "^4.3.1", "react-router-dom": "^4.3.1", "react-scripts": "1.1.4", "react-table": "^6.8.6", - "reactstrap": "^6.3.1" + "react-vega-lite": "^2.0.2", + "reactstrap": "^6.3.1", + "redux": "^4.0.1", + "redux-thunk": "^2.3.0", + "vega": "^4.3.0", + "vega-lite": "^2.6.0", + "vega-tooltip": "^0.13.0" }, "private": true } diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/public/index.html b/LCU/Maintenance/MDB_WebView/maintenancedb_view/public/index.html index 220f25585d0a20a827abb36046a4e319944fc185..d981de54896cac80cc3bd87cb20c6fbd15378bc3 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/public/index.html +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/public/index.html @@ -1,3 +1,4 @@ + <!DOCTYPE html> <html lang="en"> <head> diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/App.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/App.js index 9ab0dca7a238a464cb1bae5fdcf3842f4e69caa9..a2b05ebe3282f07093d567a6cbe4848fa5826e53 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/App.js +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/App.js @@ -4,24 +4,26 @@ import StationOverviewPage from './pages/StationOverviewPage.js' import TilesPage from './pages/TilesPage.js' import DetailsPage from './pages/DetailsPage.js' -import Header from './components/header.js' +import { connect } from "react-redux"; +import { fetchErrorTypes } from "./redux/actions/appInitDataActions.js"; + import './App.css'; import { BrowserRouter as Router, - Route, - Link + Route } from 'react-router-dom'; -class App extends Component { - constructor(props){ - super(props); +class AppC extends Component { + + componentDidMount( ) { + // Load initial application data + this.props.dispatch(fetchErrorTypes()); } render(){ - console.log(this.props.location); return ( <Router> <div> @@ -35,4 +37,6 @@ class App extends Component { } } +const App = connect()(AppC); + export default App; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LandingPage.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LandingPage.js deleted file mode 100644 index aa107c51da004e8d539209111b3449c178bb1528..0000000000000000000000000000000000000000 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LandingPage.js +++ /dev/null @@ -1,11 +0,0 @@ -import React, { Component } from 'react'; - -class LandingPage extends Component { - render() { - return ( - <div>Home sweet home</div> - ); - } -} - -export default LandingPage; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.css new file mode 100644 index 0000000000000000000000000000000000000000..3ec2c0158b7b87ed251af31b361753b754e2e02c --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.css @@ -0,0 +1,13 @@ +/* COLORS */ +/* Color palette interface (created with https://material.io/tools/color/) */ +/* font color */ +/* font color */ +/* Data colors */ +.hoverable:hover { + background-color: #bdbdbd; } + +.table-wrapper { + width: 10em; + max-height: 10em; + overflow: auto; + display: block; } diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.js new file mode 100644 index 0000000000000000000000000000000000000000..a7d482c1af740852a69defad3da798843593caf7 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.js @@ -0,0 +1,125 @@ +import React, { Component } from 'react'; +import { Table, Popover, PopoverHeader, PopoverBody } from 'reactstrap'; +import { unique_id } from '../utils/utils.js' +import AutoLoadWrapper from '../utils/autoLoader.js' +import * as moment from 'moment'; +import './LatestObservations.css' +/** + * SORow; Class to render the row for a station in the StationOverview. + */ +class SORow extends Component { + constructor(props){ + super(props); + this.state = {popoverOpen:false, mouseOverPopup:false}; + this.id = unique_id(); + this.togglePopover = this.togglePopover.bind(this); + this.mouseDown = this.mouseDown.bind(this); + } + + mouseDown(e){ + if(e.button === 1) + this.setState({mouseOverPopup: !this.state.mouseOverPopup}); + } + renderObservationID() { + return this.props.data.observation_id; + } + + getStationInvolvedList(){ + var result = []; + if(this.props.data !== undefined){ + const station_involved = this.props.data.station_involved; + for (var key in station_involved){ + if(station_involved.hasOwnProperty(key)){ + result.push(station_involved[key]); + } + } + } + return result; + } + + renderStationsWithProblems(station_involved_list){ + return station_involved_list.filter(rtsm_observation => rtsm_observation.n_errors > 0).length; + } + + togglePopover(){ + if(this.state.mouseOverPopup === false){ + this.setState({popoverOpen: !this.state.popoverOpen}); + } + } + + render() { + const data = this.props.data; + const station_involved_list = this.getStationInvolvedList(); + + const {total_component_errors, start_datetime, end_datetime, mode} = data; + const stations_and_errors = station_involved_list.map((station) => + <tr key={station.station_name}> + <th scope="row">{station.station_name}</th> + <td>{station.n_errors}</td> + </tr>); + return ( + <tr id={this.id} onMouseOver={this.togglePopover} onMouseOut={this.togglePopover} + onMouseDown={this.mouseDown} + className="hoverable"> + <th scope="row">{ this.renderObservationID() }</th> + <td>{ moment(start_datetime).format('lll') }</td> + <td>{ station_involved_list.length }</td> + <td>{ this.renderStationsWithProblems(station_involved_list) }</td> + <td>{ total_component_errors }</td> + + <Popover placement="auto-start" isOpen={this.state.popoverOpen} target={ this.id }> + <PopoverHeader>{data.observation_id}</PopoverHeader> + <PopoverBody> + <strong>Start:</strong> { start_datetime}<br/> + <strong>End:</strong> { end_datetime }<br/> + <strong>Mode:</strong> { mode.join(',') }<br/> + <Table size="sm" className="so-table table-wrapper"> + <thead><tr><th>Station name</th><th>errors</th></tr></thead> + <tbody>{stations_and_errors}</tbody> + </Table> + </PopoverBody> + </Popover> + </tr> + ); + } +} + + +/** + * StationOverview class. + */ +class LatestObservationsC extends Component { + + getTableRows() { + return this.props.data.map( (stationData) => <SORow key={stationData.observation_id} data={ stationData } /> ); + } + + render() { + + return ( + <div className="station-overview-ctrl"> + <Table size="sm" className="so-table"> + <thead> + <tr> + <th>Observation</th> + <th>Start date</th> + <th>Stations</th> + <th>Stations with errors</th> + <th>Total errors</th> + </tr> + </thead> + <tbody>{ this.getTableRows() } + </tbody> + </Table> + </div> + ); + } + +} + +/* Add some magic; use the AutoLoadWrapper to create a HOC that handles the + auto-loading of the data for StationOverviewC. + */ +const LatestObservations = AutoLoadWrapper(LatestObservationsC); + +export default LatestObservations; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.scss b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.scss new file mode 100644 index 0000000000000000000000000000000000000000..d1199fbe15d96ead401f3bc8d3678f7ac038afde --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.scss @@ -0,0 +1,16 @@ +@import '../themes/lofar-variables.scss'; + +.hoverable { + +} + +.hoverable:hover { + background-color: $secondary; +} + +.table-wrapper { + width: 10em; + max-height: 10em; + overflow: auto; + display: block; +} diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationDetails.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationDetails.js new file mode 100644 index 0000000000000000000000000000000000000000..94be8877bb218d3ee2435cfa3b0a984e35495993 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationDetails.js @@ -0,0 +1,132 @@ +import React, { Component } from 'react'; +import { Table, Badge, Popover, PopoverHeader, PopoverBody } from 'reactstrap'; +import { unique_id } from '../utils/utils.js' +import './StationOverview.css' + + +/** + * StationTestBadge; class to render one stationtest badge in the SORow. + */ +class StationTestBadge extends Component { + + constructor(props) { + super(props); + + this.id = unique_id(); + this.togglePopover = this.togglePopover.bind(this); + this.state = { + popoverOpen: false + }; + } + + getClass() { + let color = this.props.data.total_component_errors>0 ? "so-red" : "so-green"; + return "so-stationtestbadge " + color; + } + + togglePopover() { + this.setState({ + popoverOpen: !this.state.popoverOpen + }); + } + + render () { + let data = this.props.data; + return ( + <div> + <div id={ this.id } onMouseOver={this.togglePopover} onMouseOut={this.togglePopover} className={ this.getClass() }>{ this.props.data.total_component_errors }</div> + <Popover placement="auto" isOpen={this.state.popoverOpen} target={ this.id } toggle={this.togglePopover}> + <PopoverHeader>{this.props.station}</PopoverHeader> + <PopoverBody> + <strong>Start:</strong> { data.start_datetime}<br/> + <strong>End:</strong> { data.end_datetime }<br/> + <strong>Checks:</strong> { data.checks } + </PopoverBody> + </Popover> + </div> + ); + } +} + + +/** + * RTSMBadge; class to render one RTSM badge in the SORow. + */ +class RTSMBadge extends Component { + + getClass() { + let color = this.props.data.total_component_errors>0 ? "so-red" : "so-green"; + return "so-pill " + color; + } + + render () { + let data = this.props.data; + return <div className="so-rtsmbadge">{ data.observation_id }<span className={ this.getClass() }>{ data.total_component_errors }</span></div>; + } +} + + +/** + * SORow; Class to render the row for a station in the StationOverview. + */ +class SORow extends Component { + + renderStationName() { + return this.props.data.station_name; + } + + renderStationTests() { + let data = this.props.data; + return data.station_tests.map( (testData) => <StationTestBadge station={data.station_name} data={ testData } /> ); + } + + renderRTSM() { + if (! this.props.data.rtsm || this.props.data.rtsm.length == 0) { + return "No RTSM data found" + } + return this.props.data.rtsm.map( (testData) => <RTSMBadge data={ testData } /> ); + } + + render() { + return ( + <tr> + <th scope="row">{ this.renderStationName() }</th> + <td>{ this.renderStationTests() }</td> + <td>{ this.renderRTSM() }</td> + </tr> + ); + } +} + + +/** + * StationDetails class. + */ +class StationDetails extends Component { + + getTableRows() { + return this.props.data.map( (stationData) => <SORow data={ stationData } /> ); + } + + render() { + return ( + <div className="station-overview-ctrl"> + <Table size="sm" className="so-table"> + <thead> + <tr> + <th>Name</th> + <th>Station tests</th> + <th>Latest observations</th> + </tr> + </thead> + <tbody> + { this.getTableRows() } + </tbody> + </Table> + </div> + ); + } + +} + +export default StationOverview; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.css new file mode 100644 index 0000000000000000000000000000000000000000..32a3e3b713e9c855476633cf3ed361a829825d31 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.css @@ -0,0 +1,81 @@ +/* COLORS */ +/* Color palette interface (created with https://material.io/tools/color/) */ +/* font color */ +/* font color */ +/* Data colors */ +.so, .so-serious, .so-alarming, .so-warning, .so-good { + font-weight: 600 !important; } + +.so-serious { + background-color: #f17171; + color: white; } + +.so-alarming { + background-color: #ffcd74; + color: black; } + +.so-warning { + background-color: #fbfb83; + color: black; } + +.so-good { + background-color: #6fbd6f; + color: white; } + +.station-overview-ctrl { + font-size: .9rem; } + +.so-table { + width: auto !important; } + +.so-table th { + padding-right: 1.4em !important; } + +.so-stationtestbadge { + float: left; + width: 1.4rem; + height: 1.4rem; + line-height: 1.4rem; + border: 1px solid #999; + border-radius: .2rem; + padding: 0; + text-align: center; + margin-left: 1px; + font-size: 90%; } + +/* General badge styling */ +.so-badge { + float: left; + height: 1.4rem; + line-height: 1.4rem; + background: #e1e1e1; + border: 1px solid #8d8d8d; + border-radius: .2rem; + padding: 0 0.5em; + text-align: left; + margin-left: 2px; + font-size: 90%; } + +/* RTSM Badge styling */ +.so-rtsmbadge { + width: 7em; } + +.so-stationtestbadge:hover, +.so-badge:hover { + color: #fff; + background-color: #8d8d8d; + border-color: #8d8d8d; } + +.so-pill { + display: block; + float: right; + padding: .25em .45em; + font-size: 90%; + font-weight: 500; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 1em; + margin-top: 0.1rem; + margin-left: 0.5em; } diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.js new file mode 100644 index 0000000000000000000000000000000000000000..86aa03012572b8e9a6520abc2c579f277480ce65 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.js @@ -0,0 +1,280 @@ +import React, {Component} from 'react'; +import {withRouter} from "react-router"; +import {Table, Popover, PopoverHeader, PopoverBody} from 'reactstrap'; +import {unique_id} from '../utils/utils.js' +import AutoLoadWrapper from '../utils/autoLoader.js' +import './StationOverview.css' + +/** + * Badge; class to render a badge with label and pill. + */ +class Badge extends Component { + + getClass() { + let cnt = this.props.count; + let color = cnt > 10 + ? "so-serious" + : cnt > 5 + ? "so-alarming" + : cnt > 0 + ? "so-warning" + : "so-good"; + return "so-pill " + color; + } + + render() { + let props = this.props; + return (<div id={props.myid} className={"so-badge"} onMouseOver={props.togglePopOver} onMouseOut={props.togglePopOver}> + {props.label} + <span className={this.getClass()}>{props.count}</span> + </div>); + } +} + +/** + * StationTestBadge; class to render one stationtest badge in the SORow. + */ +class StationTestBadgeC extends Component { + + constructor(props) { + super(props); + + this.id = unique_id(); + this.togglePopover = this.togglePopover.bind(this); + this.onClick = this.onClick.bind(this); + this.state = { + popoverOpen: false + }; + } + + getClass() { + let total = this.props.data.total_component_errors; + let color = total > 10 + ? "so-serious" + : total > 5 + ? "so-alarming" + : total > 0 + ? "so-warning" + : "so-good"; + return `so-stationtestbadge ${color}`; + } + + onClick() { + this.props.history.push('/station_overview') + } + + togglePopover() { + this.setState({ + popoverOpen: !this.state.popoverOpen + }); + } + + renderPopOver() { + let data = this.props.data; + let summary = data.component_error_summary; + let rows = []; + + let components = Object.keys(summary).sort(); + components.forEach((component) => { + let comp_sum = summary[component]; + let errors = Object.keys(comp_sum).sort(); + rows.push(<tr key={component}> + <th>{component}</th> + <td>{errors.map((e, id) => <Badge key={id} count={comp_sum[e]} label={e}/>)}</td> + </tr>); + }); + + return (<Popover placement="auto" isOpen={this.state.popoverOpen} target={this.id} toggle={this.togglePopover}> + <PopoverHeader> + {this.props.station} + </PopoverHeader> + <PopoverBody> + <Table borderless size="sm"> + <tbody> + <tr> + <th>Start:</th> + <td>{data.start_datetime}</td> + </tr> + <tr> + <th>End:</th> + <td>{data.end_datetime}</td> + </tr> + <tr> + <th>Checks:</th> + <td>{data.checks}</td> + </tr> + {rows} + </tbody> + </Table> + </PopoverBody> + </Popover>); + } + + render() { + let popOver = ""; + + if (this.state.popoverOpen) { + popOver = this.renderPopOver(); + } + + return (<div> + <div id={this.id} onClick={this.onClick} onMouseOver={this.togglePopover} onMouseOut={this.togglePopover} className={this.getClass()}> + {this.props.data.total_component_errors} + </div> + {popOver} + </div>); + } +} + +const StationTestBadge = withRouter(StationTestBadgeC); + +/** + * RTSMBadge; class to render one RTSM badge in the SORow. + */ +class RTSMBadge extends Component { + + constructor(props) { + super(props); + + this.id = unique_id(); + this.togglePopover = this.togglePopover.bind(this); + this.state = { + popoverOpen: false + }; + } + + getClass() { + let total = this.props.data.total_component_errors; + let color = total > 10 + ? "so-serious" + : total > 5 + ? "so-alarming" + : total > 0 + ? "so-warning" + : "so-good"; + return "so-pill " + color; + } + + togglePopover() { + this.setState({ + popoverOpen: !this.state.popoverOpen + }); + } + + renderPopOver() { + let data = this.props.data; + let summary = data.error_summary; + let badges = ""; + + let errors = Object.keys(summary).sort(); + badges = errors.map((e, i) => <Badge key={i} count={summary[e]} label={e}/>); + + return (<Popover placement="auto" isOpen={this.state.popoverOpen} target={this.id} toggle={this.togglePopover}> + <PopoverHeader> + {data.observation_id} + </PopoverHeader> + <PopoverBody> + <Table borderless size="sm"> + <tbody> + <tr> + <th>Start:</th> + <td>{data.start_datetime}</td> + </tr> + <tr> + <th>End:</th> + <td>{data.end_datetime}</td> + </tr> + <tr> + <th>Mode:</th> + <td>{data.mode}</td> + </tr> + <tr> + <th>Errors:</th> + <td>{badges}</td> + </tr> + </tbody> + </Table> + </PopoverBody> + </Popover>); + } + + render() { + let popOver = ""; + let data = this.props.data; + + if (this.state.popoverOpen) { + popOver = this.renderPopOver(); + } + + return (<React.Fragment> + <Badge myid={this.id} className="so-rtsmbadge" togglePopOver={this.togglePopover} count={data.total_component_errors} label={data.observation_id}/> {popOver} + </React.Fragment>); + } +} + +/** + * SORow; Class to render the row for a station in the StationOverview. + */ +class SORow extends Component { + + renderStationName() { + return this.props.data.station_name; + } + + renderStationTests() { + let data = this.props.data; + return data.station_tests.map((testData) => <StationTestBadge key={testData.start_datetime} station={data.station_name} data={testData}/>); + } + + renderRTSM() { + if (!this.props.data.rtsm || this.props.data.rtsm.length === 0) { + return "No RTSM data found" + } + + return this.props.data.rtsm.map((testData) => <RTSMBadge key={testData.observation_id} data={testData}/>); + } + + render() { + return (<tr> + <th scope="row">{this.renderStationName()}</th> + <td>{this.renderStationTests()}</td> + <td>{this.renderRTSM()}</td> + </tr>); + } +} + +/** + * StationOverview class. + */ +class StationOverviewC extends Component { + + getTableRows() { + let d = this.props.data; + return d.map((stationData) => <SORow key={stationData.station_name} data={stationData}/>); + } + + render() { + return (<div className="station-overview-ctrl"> + <Table size="sm" className="so-table"> + <thead> + <tr> + <th>Name</th> + <th>Station tests</th> + <th>Latest observations</th> + </tr> + </thead> + <tbody> + {this.getTableRows()} + </tbody> + </Table> + </div>); + } + +} + +/* Add some magic; use the AutoLoadWrapper to create a HOC that handles the + auto-loading of the data for StationOverviewC. + */ +const StationOverview = AutoLoadWrapper(StationOverviewC); + +export default StationOverview; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.scss b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.scss new file mode 100644 index 0000000000000000000000000000000000000000..3997fddaefd41b8483d319f88e83315327157938 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.scss @@ -0,0 +1,94 @@ +@import '../themes/lofar-variables.scss'; + +.so { + font-weight: 600 !important; +} + +.so-serious { + @extend .so; + background-color: $serious; + color: $serious_fontcolor; +} +.so-alarming { + @extend .so; + background-color: $alarming; + color: $alarming_fontcolor; +} +.so-warning { + @extend .so; + background-color: $warning; + color: $warning_fontcolor; +} +.so-good { + @extend .so; + background-color: $good; + color: $good_fontcolor; +} + + +.station-overview-ctrl { + font-size: .9rem; +} + +.so-table { + width: auto!important; +} + +.so-table th { + padding-right: 1.4em!important; +} + +.so-stationtestbadge { + float: left; + width: 1.4rem; + height: 1.4rem; + line-height: 1.4rem; + border: 1px solid #999; + border-radius: .2rem; + padding: 0; + text-align: center; + margin-left: 1px; + font-size: 90%; +} + +/* General badge styling */ +.so-badge { + float: left; + height: 1.4rem; + line-height: 1.4rem; + background: $secondary-light; + border: 1px solid $secondary-dark; + border-radius: .2rem; + padding: 0 0.5em; + text-align: left; + margin-left: 2px; + font-size: 90%; +} + +/* RTSM Badge styling */ +.so-rtsmbadge { + width: 7em; +} + +.so-stationtestbadge:hover, +.so-badge:hover { + color: #fff; + background-color: $secondary-dark; + border-color: $secondary-dark; +} + + +.so-pill { + display: block; + float: right; + padding: .25em .45em; + font-size: 90%; + font-weight: 500; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 1em; + margin-top: 0.1rem; + margin-left: 0.5em; +} diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationStatistics.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationStatistics.js new file mode 100644 index 0000000000000000000000000000000000000000..bfb26b3737447cd79f08694705b6a1cb3582efb6 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationStatistics.js @@ -0,0 +1,217 @@ +import React, {Component} from 'react'; +import AutoLoadWrapper from '../utils/autoLoader.js' +import ReactVegaLite from 'react-vega-lite' +import { + Navbar, + Nav, + NavItem, + Input, + NavbarBrand +} from 'reactstrap'; +import {connect} from 'react-redux'; +import {setStationStatisticsTestType, setStationStatisticsAveragingWindow} from '../redux/actions/landingPageActions' + +class ToolBarC extends Component { + constructor(props){ + super(props); + + this.state = {isNavbarCollapsed: true}; + } + setAveragingWindow(e) { + this.props.setStationStatisticsAveragingWindow(e.target.value); + } + + setTestType(e) { + this.props.setStationStatisticsTestType(e.target.value); + } + + toggle(){ + this.setState({ + isNavbarCollapsed: !this.state.isNavbarCollapsed + }); + } + + render() { + return ( + <Nav className="ml-auto"> + <NavItem> + <select className="form-control custom-select custom-select-sm" id="selected-group" value={this.props.test_type} onChange={(e) => this.setTestType(e)} style={{ + width: 'auto' + }}> + <option value="B">Both test types</option> + <option value="R">RTSM only</option> + <option value="S">StationTest only</option> + </select> + </NavItem> + <NavItem> + <Input type="select" className="form-control custom-select custom-select-sm" style={{ + top: "0rem !important" + }} onChange={(e) => this.setAveragingWindow(e)} value={this.props.averaging_window}> + <option value={1}>day</option> + <option value={7}>week</option> + <option value={30}>month</option> + </Input> + </NavItem> + <NavItem> + <Input type="select" className="form-control custom-select custom-select-sm" onChange={(e) => this.props.switchHistogramEvent(e)} value={this.props.histogramType}> + <option value="per_error_type">per error type</option> + <option value="per_station">per station</option> + </Input> + </NavItem> + </Nav>); + } +} + +const mapStateToPropsToolBar = state => { + return { + ...state.landing_page.station_statistics + }; +}; + +const mapDispatchToPropsToolBar = { + setStationStatisticsAveragingWindow, + setStationStatisticsTestType +}; + +const ToolBar = connect(mapStateToPropsToolBar, mapDispatchToPropsToolBar)(ToolBarC); + +class StationStatisticsC extends Component { + constructor(props) { + super(props); + this.state = { + histogramType: 'per_error_type' + }; + this.ref = React.createRef(); + this.getErrorsPerTypeSpec.bind(this); + } + getErrorsPerStation() { + if (this.props.data.errors_per_station !== undefined) { + return {values: this.props.data.errors_per_station}; + } + } + + getErrorsPerType() { + if (this.props.data.errors_per_type !== undefined) { + return {values: this.props.data.errors_per_type}; + } + } + + getBaseSpec() { + return { + "$schema": "https://vega.github.io/schema/vega-lite/v2.json", + "mark": { + "type": "bar" + }, + "autosize": { + "type": "fit", + "contains": "padding" + }, + "config": { + "legend": { + "columns": 2 + } + }, + "encoding": { + "x": { + "field": "time", + "type": "ordinal", + "axis": { + "title": "day" + } + }, + "y": { + "field": "n_errors", + "type": "quantitative", + "axis": { + "title": "number of errors" + } + } + } + } + } + + getErrorsPerTypeSpec() { + let schema = this.getBaseSpec(); + schema.encoding["color"] = { + "field": "error_type", + "type": "nominal" + } + schema.encoding["tooltip"] = [ + { + field: "n_errors", + type: "quantitative" + }, { + field: "error_type", + type: "nominal" + } + ] + return schema; + } + + getErrorsPerStationSpec() { + let schema = this.getBaseSpec(); + schema.encoding["color"] = { + "field": "station_name", + "type": "nominal" + } + schema.encoding["tooltip"] = [ + { + field: "n_errors", + type: "quantitative" + }, { + field: "station_name", + type: "nominal" + } + ] + schema.config.legend.columns = 3 + return schema; + } + + getSpecData(histogram_type) { + switch (histogram_type) { + case "per_error_type": + return {spec: this.getErrorsPerTypeSpec(), data: this.getErrorsPerType()}; + case "per_station": + return {spec: this.getErrorsPerStationSpec(), data: this.getErrorsPerStation()}; + default: + return {spec: this.getErrorsPerTypeSpec(), data: this.getErrorsPerType()}; + } + } + + render() { + const {spec, data} = this.getSpecData(this.state.histogramType); + if (this.ref.current !== null) { + const width = this.ref.current.clientWidth + const height = this.ref.current.clientHeight + spec.width = width + spec.height = height + + } + return (<React.Fragment> + <Navbar + className="react-grid-item-header justify-content-between" + style={{ + padding: "0" + }}> + <NavbarBrand style={{ + padding: "0" + }}> + <h5 className="react-grid-item-header"> + Station statistics</h5> + </NavbarBrand> + <ToolBar style={{ + padding: "0" + }} histogramType={this.state.histogramType} switchHistogramEvent={e => this.setState({histogramType: e.target.value})}/> + </Navbar> + <div className="react-grid-item-body" id="plot" ref={this.ref}> + <ReactVegaLite spec={spec} data={data} enableHover={true}/> + </div> + </React.Fragment>); + } +} +/* Add some magic; use the AutoLoadWrapper to create a HOC that handles the + auto-loading of the data for StationOverviewC. + */ +const StationStatistics = AutoLoadWrapper(StationStatisticsC); + +export default StationStatistics; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.css index 938763dba19a1420f4890cd8926a020f1952a8b7..89cff5e0be1d41048634d5039ce833dec87d90cf 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.css +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.css @@ -1,36 +1,20 @@ -.card { - margin-top: 1em; - box-shadow: 0 .1em .2em .2em grey; -} -.content { - text-align: center; - vertical-align: bottom; -} -.content-title { - background-color: lightgrey; -} +.sts-toolbar { + position: absolute; + right: 0.5rem; + top: 0.1rem; + display: inline-block; } -.tableheader { - font-weight: bold; -} +.sts-table { + width: auto !important; + text-align: center; + font-size: .9rem; } -.detailsbutton { - background-color: lightgrey !important; - color: black !important; - font-weight: bold; -} +.sts-table th { + word-break: break-all; + min-width: 3em; } -.danger, -.no_error { - color: rgb(218, 242, 244); -} +.sts-table td { + text-align: center; } -.danger { - background-color: rgb(210, 7, 7) !important; - border-color: rgb(210, 7, 7) !important; -} - -.no_error { - background-color: rgb(90, 180, 0) !important; - border-color: rgb(90, 180, 0) !important; -} +.sts-table.table-sm td, .sts-table.table-sm th { + padding: .2rem; } diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.js index e68361a91f8b29d95b9d22a5bc7ff4f494abf64e..3a345d78a2002af1bc4c57f2cceb0324cc5996a7 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.js +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.js @@ -1,109 +1,197 @@ import React, { Component } from 'react'; -import station_test_summary from './StationTestSummary.css' -import { Link } from 'react-router-dom'; -import { Card, CardImg, CardText, CardBody, - CardHeader, - CardTitle, CardSubtitle, Button, Collapse, - Row, Col, Container} from 'reactstrap'; -import ReactTable from 'react-table' -import 'react-table/react-table.css' - - -class StationTestSummary extends Component { - constructor(props){ - super(props); - this.state = { collapse: false }; - } - - - toggleCollapse(){ - this.setState({'collapse':!this.state.collapse}); - } - - format_date(date_string){ - let date = new Date(date_string); - return date.toDateString(); - } - - render_component_errors(component_errors_data){ - - let columns = [ - { - Header: 'ID', - accessor: 'id' - }, - { - Header: 'Component #', - accessor: 'component_id' - }, - { - Header: 'Component type', - accessor: 'component_type' - }, - { - Header: 'Error type', - accessor: 'type' - } - ] - let result = ( - <ReactTable - defaultPageSize={5} - data={component_errors_data} - columns={columns} - filterable={true}/> - ); - return result - } - - aggregate_results(component_errors){ - let error_types = component_errors.map((item)=> item.component_type); - - let summary = error_types.reduce( (acc, val) => { - acc[val] = acc[val] === undefined? 1 : acc[val] + 1; - return acc; - }, {}) - return summary - } - - render_summary(component_errors){ - var summary = this.aggregate_results(component_errors) - var rendered_summary_items = []; - for (let key in summary){ - var item = <Col className='horizontal' key={key} >{key}: {summary[key]}</Col> - rendered_summary_items.push(item) +import { connect } from "react-redux"; +import { Table, Button } from 'reactstrap'; +import { unique_id } from '../utils/utils.js' +import { componentErrorTypes } from '../utils/constants.js' +import AutoLoadWrapper from '../utils/autoLoader.js' + +//import stdata from '../testdata/station_test_summary.js' + +import './StationTestSummary.css' + + +/** + * SORow; Class to render the row for a station in the StationOverview. + */ +class STSRow extends Component { + + renderStartDate() { + return this.props.date; + } + + renderStartTime() { + let arr = this.props.data.start_datetime.match(/T(.*):..Z/); + return arr[1]; + } + + render() { + let props = this.props, + component = props.component, + errors = props.data.component_error_summary[component] || {}, + cols = []; + + props.errorTypes.forEach((type) => { + cols.push(<td key={type}>{ errors[type] }</td>); + }); + + return ( + <tr> + <th scope="row" style={{whiteSpace: "nowrap"}}>{ this.renderStartDate() }</th> + <th>{ props.time }</th> + <th>{ props.station }</th> + <td>{ component }</td> + { cols } + </tr> + ); + } +} + + +class ToolBar extends Component { + + onErrorsOnlyClick(selected) { + this.props.onChange('allErrorTypes', !this.props.allErrorTypes ); } - var rendered_summary = <div> - <h5>Number of errors per component type</h5> - <Row>{rendered_summary_items}</Row> - </div> - return rendered_summary - } - - - render() { - var summary = this.render_summary(this.props.data.component_errors); - var total_errors = this.props.data.component_errors.length - var color_type = total_errors !== 0? 'danger': 'no_error'; - return ( - <div> - <Card outline className='card' > - <CardHeader className={color_type}> - <Row > - <Col xs='11'><h4>Station test on {this.props.data.station.name} of {this.format_date(this.props.data.end_datetime)} found: {total_errors} errors</h4></Col> - <Col> <Button className='detailsbutton' onClick={()=> this.toggleCollapse()}>details</Button> </Col> - </Row> - </CardHeader> - <Collapse isOpen={this.state.collapse}> - <CardBody className='content'> - {summary} - {this.render_component_errors(this.props.data.component_errors)} - </CardBody> - </Collapse> - </Card> - </div> - ); - } + render() { + return ( + <div className="sts-toolbar"> + { this.props.allErrorTypes + ? <Button color="info" size="xs" onClick={() => this.onErrorsOnlyClick()} active>All types</Button> + : <Button color="info" size="xs" onClick={() => this.onErrorsOnlyClick()}>All types</Button> + } + </div> + ); + } } + +/** + * StationOverview class. + */ +class StationTestSummaryC extends Component { + + activeErrorTypes = []; // Result of filtering state.errorTypes + + state = { + allErrorTypes: false // true: error types shown, even when there are no errors for that type + }; + + /* Handle changes of selected filters in the ToolBar */ + onToolbarChange(key, value) { + let obj = {}; + obj[key] = value; + this.setState(obj); + } + + + filterErrorTypes() { + let typesFound = {}, + retTypes = []; + + if (this.props.errorTypes.length === 0 || this.props.data.length === 0){ + return []; + } + + // Create index object for all error types in the data + this.props.data.forEach( (stationData) => { + let esummary = stationData.component_error_summary; + let key; + for(key in esummary){ + let errors = Object.keys(esummary[key]); + errors.forEach((e) => typesFound[e] = 1); + } + }); + + // Loop over all error types and check which ones are present in the data + this.props.errorTypes.forEach((t) => { + if (typesFound[t]) { + retTypes.push(t); + } + }) + + return retTypes; + } + + setActiveErrorTypes() { + if (this.state.allErrorTypes) { + this.activeErrorTypes = this.props.errorTypes; + } else { + this.activeErrorTypes = this.filterErrorTypes(); + } + } + + getTableRows() { + let rows = [], + prevDate = null; + + this.props.data.forEach( (stationData) => { + let date = (stationData.date !== prevDate ? stationData.date : ""); + let components = Object.keys(stationData.component_error_summary).sort(); + let station = stationData.station_name; + let time = (stationData.start_datetime.match(/T(.*):..Z/))[1]; + + components.forEach( (component) => { + rows.push(<STSRow key={ unique_id() } date={date} time={time} component={component} station={station} data={stationData} errorTypes={this.activeErrorTypes}/>) + date = station = time = ""; + }); + if (components.length === 0) { + rows.push(<STSRow key={ unique_id() } date={date} time={time} component={"-"} station={station} data={stationData} errorTypes={this.activeErrorTypes}/>) + } + prevDate = stationData.date; + }); + + return rows; + } + + renderTableHeaders() { + let th = [] + this.activeErrorTypes.forEach((err) => { + th.push( <th key={err} title={err}>{ componentErrorTypes[err] ? componentErrorTypes[err] : err }</th> ); + }); + return th; + } + + render() { + + this.setActiveErrorTypes(); + + return ( + <React.Fragment> + <h5 className="react-grid-item-header"> + Station test summary + <ToolBar onChange={(key,value) => this.onToolbarChange(key,value) } allErrorTypes={this.state.allErrorTypes} /> + </h5> + <div className="react-grid-item-body"> + <Table bordered hover size="sm" className="sts-table"> + <thead> + <tr> + <th>Date</th> + <th>Time</th> + <th>Station</th> + <th>Comp.</th> + {this.renderTableHeaders()} + </tr> + </thead> + <tbody> + { this.getTableRows() } + </tbody> + </Table> + </div> + </React.Fragment> + ); + } + +} + +// Map the appInitData from store for the error types +const mapStateToProps = state => { + return { ...state.appInitData }; +}; + +/* Add some magic; use the AutoLoadWrapper to create a HOC that handles the + auto-loading of the data for StationOverviewC. + */ +const StationTestSummary = AutoLoadWrapper( connect(mapStateToProps)(StationTestSummaryC) ); + export default StationTestSummary; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.scss b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.scss new file mode 100644 index 0000000000000000000000000000000000000000..e96c2c8a3acc41507b5c065720f74a9857699fd8 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary.scss @@ -0,0 +1,25 @@ +.sts-toolbar { + position: absolute; + right: 0.5rem; + top: 0.1rem; + display: inline-block; +} + +.sts-table { + width: auto!important; + text-align: center; + font-size: .9rem; +} + +.sts-table th { + word-break: break-all; + min-width: 3em; +} + +.sts-table td { + text-align: center; +} + +.sts-table.table-sm td, .sts-table.table-sm th { + padding: .2rem; +} diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.css index e22f2097ebf393d75422b4a0e801cf237cc11f3b..7af89cd86a7cd3bcc2903f84a096f640893668b3 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.css +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.css @@ -1,10 +1,13 @@ +/* COLORS */ +/* Color palette interface (created with https://material.io/tools/color/) */ +/* font color */ +/* font color */ +/* Data colors */ .header { - background-color: rgba(111,84,153,1); - padding: 20px; - color: white; -} + background-color: #773b6f; + padding: 20px; + color: white; } .lofar { - font-weight: bold; - font-style: normal; -} + font-weight: bold; + font-style: normal; } diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.js index 1fc15124b9f84403de48eaee3fdce54742c768f9..33aa07d52c2a20e68c69e6978e155e3ddca1ae7b 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.js +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.js @@ -25,7 +25,7 @@ class Header extends Component { } check_status(item){ - console.log(this.props.active_page.pathname) + //console.log(this.props.active_page.pathname) if (this.props.active_page.pathname === item){ return "active" } diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.scss b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.scss new file mode 100644 index 0000000000000000000000000000000000000000..941c3a6d21574df1e2cbd90638a11f6e56c4d66f --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.scss @@ -0,0 +1,12 @@ +@import '../themes/lofar-variables.scss'; + +.header { + background-color: $primary; + padding: 20px; + color: white; +} + +.lofar { + font-weight: bold; + font-style: normal; +} diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/index.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/index.js index 56dcbe6bab187ceccc47293ee7488bd02d12392f..560ea3fe281efbaf14c7adbcda9fc71079658c85 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/index.js +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/index.js @@ -4,8 +4,17 @@ import './index.css'; import App from './App'; import 'bootstrap/dist/css/bootstrap.min.css'; import registerServiceWorker from './registerServiceWorker'; -import { BrowserRouter } from 'react-router-dom' +// Redux +import { Provider } from "react-redux"; +import store from "./redux/store.js"; + + +ReactDOM.render( + <Provider store={store}> + <App /> + </Provider>, + document.getElementById('root') +); -ReactDOM.render(<App />, document.getElementById('root')); registerServiceWorker(); diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/LandingPage.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/LandingPage.js index 7e1cf0036fccaa904be260cfb97290cb57f015fc..aa0cf629449896dea9e5340d8d3eac7c3fcdd553 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/LandingPage.js +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/LandingPage.js @@ -1,15 +1,190 @@ -import React, { Component } from 'react'; +import React, {Component} from 'react'; import Header from '../components/header.js' -class LandingPage extends Component { - render() { - return ( - <div> - <Header active_page={this.props.location} /> - <div>Home sweet home</div> - </div> - ); - } +import StationOverview from '../components/StationOverview.js' +import StationTestSummary from '../components/StationTestSummary.js' +import LatestObservations from '../components/LatestObservations.js' +import StationStatistics from '../components/StationStatistics.js' + +import {Responsive, WidthProvider} from 'react-grid-layout'; +import {Button, ButtonGroup, Form} from 'reactstrap'; +import * as moment from 'moment'; +import {connect} from "react-redux"; +import { setNewLayout } from "../redux/actions/landingPageActions"; +import { setPeriod, setStationGroup, setErrorsOnly } from "../redux/actions/mainFiltersActions" +import 'react-grid-layout/css/styles.css'; +import 'react-resizable/css/styles.css'; +import '../themes/lofar-styles.css'; +import { composeQueryString } from '../utils/utils.js' + +const ResponsiveGridLayout = WidthProvider(Responsive); + +/** + * Class to display a secondary header for selecting data filters. + * The state is managed by the LandingPage class. + */ +class ToolBarC extends Component { + + onErrorsOnlyClick(selected) { + this.props.setErrorsOnly(!this.props.errorsOnly); + } + + onStationGroupChange(e) { + //this.props.onChange('selectedStationGroup', e.target.value) + this.props.setStationGroup(e.target.value); + } + + onPeriodClick(i) { + this.props.setPeriod(i); + } + + render() { + return (<div className="landing-page-toolbar"> + <Form inline> + <label htmlFor="selected-group">Station group </label> + <select className="form-control custom-select custom-select-sm" id="selected-group" value={this.props.selectedStationGroup} onChange={(e) => this.onStationGroupChange(e)} style={{ + width: 'auto' + }}> + <option value="A">All stations</option> + <option value="C">Core stations</option> + <option value="R">Remote stations</option> + <option value="I">ILT stations</option> + </select> + { + this.props.errorsOnly + ? <Button color="info" size="sm" onClick={() => this.onErrorsOnlyClick()} active="active">Errors only</Button> + : <Button color="info" size="sm" onClick={() => this.onErrorsOnlyClick()}>Errors only</Button> + } + + <label>Period </label> + <ButtonGroup size="sm"> + <Button color="info" onClick={() => this.onPeriodClick(7)} active={this.props.period === 7}>1 wk</Button> + <Button color="info" onClick={() => this.onPeriodClick(14)} active={this.props.period === 14}>2 wk</Button> + <Button color="info" onClick={() => this.onPeriodClick(21)} active={this.props.period === 21}>3 wk</Button> + <Button color="info" onClick={() => this.onPeriodClick(28)} active={this.props.period === 28}>4 wk</Button> + </ButtonGroup> + </Form> + </div>); + } } +const mapStateToPropsToolBar = state => { + return { + ...state.mainFilters + }; +}; + +const mapDispatchToPropsToolBar = { + setStationGroup, + setErrorsOnly, + setPeriod +}; + +const ToolBar = connect(mapStateToPropsToolBar, mapDispatchToPropsToolBar)(ToolBarC); + + +class LandingPageC extends Component { + + /* Boiler plate for a Grid panel. + Looks like a React component but is ordinary function! */ + createGridPanel(props) { + let body = props.body; + if (props.renderHeader) { + body = <React.Fragment> + <h5 className="react-grid-item-header">{props.title}</h5> + <div className="react-grid-item-body"> + {props.body} + </div> + </React.Fragment>; + } + return (<div key={props.key}> + {body} + </div>); + } + + getStationOverviewURL() { + const url = '/api/view/ctrl_stationoverview?format=json' + + const parametersString = + composeQueryString({ station_group: this.props.selectedStationGroup, + errors_only: this.props.errorsOnly, + n_station_tests: 4, + n_rtsm: 4 + }) + return `${url}&${parametersString}`; + } + + getStationTestSummaryURL() { + const url = '/api/view/ctrl_stationtestsummary?format=json' + + const parameters = {} + // ---- Mandatory parameters + parameters.lookback_time = this.props.period + // ---- Optional parameters + parameters.station_group = this.props.selectedStationGroup + parameters.errors_only = this.props.errorsOnly + + const parametersString = composeQueryString(parameters) + return `${url}&${parametersString}`; + } + + getLatestObservationURL() { + let nDaysAgo = moment().add(-this.props.period, 'days'); + let nDaysAgo_String = nDaysAgo.format('YYYY-MM-DD'); + const url = '/api/view/ctrl_latest_observation?format=json' + const parameters = {} + // ---- Mandatory parameters + parameters.from_date = nDaysAgo_String + // ---- Optional parameters + parameters.station_group = this.props.selectedStationGroup + parameters.errors_only = this.props.errorsOnly + const parametersString = composeQueryString(parameters) + + return `${url}&${parametersString}`; + } + + getStationStatisticsURL() { + let nDaysAgo = moment().add(-this.props.period, 'days').format('YYYY-MM-DD'); + let now = moment().format('YYYY-MM-DD'); + let averaging_interval = this.props.station_statistics.averaging_window + let test_type = this.props.station_statistics.test_type + let url = '/api/view/ctrl_stationtest_statistics?format=json' + + const parameters = {} + // ---- Mandatory parameters + // select from + parameters.from_date = nDaysAgo + // select to + parameters.to_date = now + // select averaging interval + parameters.averaging_interval = averaging_interval + // ---- Optional parameters + parameters.errors_only = this.props.errorsOnly + parameters.station_group = this.props.selectedStationGroup + parameters.test_type = test_type + const parametersString = composeQueryString(parameters) + + return `${url}&${parametersString}`; + } + render() { + return (<div> + <Header active_page={this.props.location}/> + <ToolBar/> + <ResponsiveGridLayout className="layout" layouts={this.props.layout.panels} measureBeforeMount={true} breakpoints={this.props.layout.breakpoints} cols={this.props.layout.cols} onResizeStop={e => this.props.setNewLayout(e)}> + {this.createGridPanel({key: "ul", renderHeader: true, title: "Station overview", body: <StationOverview url={this.getStationOverviewURL()}/>})} + {this.createGridPanel({key: "ur", renderHeader: true, title: "Latest observations", body: <LatestObservations url={this.getLatestObservationURL()}/>})} + {this.createGridPanel({key: "bl", renderHeader: false, body: <StationTestSummary url={this.getStationTestSummaryURL()}/>})} + {this.createGridPanel({key: "br", renderHeader: false, body: <StationStatistics url={this.getStationStatisticsURL()}/>})} + </ResponsiveGridLayout> + </div>); + } +} + +const LandingPage = connect(state => { + return { + ...state.mainFilters, + ...state.landing_page + }; +}, {setNewLayout})(LandingPageC); + export default LandingPage; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/appInitDataActions.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/appInitDataActions.js new file mode 100644 index 0000000000000000000000000000000000000000..1ef29598eb6f9ef36fae9021300ed30c8c9e3df4 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/appInitDataActions.js @@ -0,0 +1,39 @@ +import axios from 'axios'; + +export const FETCH_ERRORTYPES_BEGIN = 'FETCH_ERRORTYPES_BEGIN'; +export const FETCH_ERRORTYPES_SUCCESS = 'FETCH_ERRORTYPES_SUCCESS'; +export const FETCH_ERRORTYPES_FAILURE = 'FETCH_ERRORTYPES_FAILURE'; + +const errorTypesURL = '/api/view/ctrl_list_component_error_types'; + +export const fetchErrorTypesBegin = () => ({ + type: FETCH_ERRORTYPES_BEGIN +}); + +export const fetchErrorTypesSuccess = errorTypes => ({ + type: FETCH_ERRORTYPES_SUCCESS, + payload: { errorTypes } +}); + +export const fetchErrorTypesFailure = error => ({ + type: FETCH_ERRORTYPES_FAILURE, + payload: { error } +}); + + +export function fetchErrorTypes() { + return dispatch => { + // Not used: dispatch(fetchErrorTypesBegin()); + + return axios.get(errorTypesURL) + .then(res => { + dispatch(fetchErrorTypesSuccess(res.data)); + }) + .catch(error => { + console.log("Error fetching error types: "+error); + dispatch(fetchErrorTypesFailure(error)) + // Try again in 30s + setTimeout(() => dispatch(fetchErrorTypes()), 10000); + }); + }; +} diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/landingPageActions.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/landingPageActions.js new file mode 100644 index 0000000000000000000000000000000000000000..9a567db893deb6cb3697ddb0f3618d355b6ae37c --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/landingPageActions.js @@ -0,0 +1,25 @@ +export const SET_COMPONENT_SIZES = "SET_COMPONENT_SIZES"; +export const SET_AVERAGING_WINDOW = "SET_AVERAGING_WINDOW"; +export const SET_TEST_TYPE = "SET_TEST_TYPE"; + +export const setNewLayout = function(newLayout) { + var payload = {}; + for(const i in newLayout){ + const item = newLayout[i]; + payload[item['i']] = item; + } + return { + type: SET_COMPONENT_SIZES, + payload: payload + } +}; + +export const setStationStatisticsAveragingWindow = averagingWindow => ({ + type: SET_AVERAGING_WINDOW, + payload: { averagingWindow } +}); + +export const setStationStatisticsTestType = test_type => ({ + type: SET_TEST_TYPE, + payload: { test_type } +}); diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/mainFiltersActions.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/mainFiltersActions.js new file mode 100644 index 0000000000000000000000000000000000000000..5e208fd6d1ff4a3243875caca798ba7c97753ab9 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/mainFiltersActions.js @@ -0,0 +1,19 @@ + +export const SET_STATION_GROUP = "SET_STATION_GROUP"; +export const SET_ERRORS_ONLY = "SET_ERRORS_ONLY"; +export const SET_PERIOD = "SET_PERIOD"; + +export const setStationGroup = stationGroup => ({ + type: SET_STATION_GROUP, + payload: { stationGroup: stationGroup } +}); + +export const setErrorsOnly = errorsOnly => ({ + type: SET_ERRORS_ONLY, + payload: { errorsOnly } +}); + +export const setPeriod = period => ({ + type: SET_PERIOD, + payload: { period } +}); diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/appInitDataReducers.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/appInitDataReducers.js new file mode 100644 index 0000000000000000000000000000000000000000..5e1b4036a0a4abcdbbdc64fe48edfe02ea7eacd6 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/appInitDataReducers.js @@ -0,0 +1,48 @@ +import { + FETCH_ERRORTYPES_BEGIN, + FETCH_ERRORTYPES_SUCCESS, + FETCH_ERRORTYPES_FAILURE +} from '../actions/appInitDataActions'; + + +const initialState = { + errorTypesLoaded: false, + errorTypes: [] +}; + + +export default function (state = initialState, action) { + switch(action.type) { + case FETCH_ERRORTYPES_BEGIN: + // Mark the state as "loading" so we can show a spinner or something + // Also, reset any errors. We're starting fresh. + return { + ...state, + errorTypesLoaded: false, + errorTypes: [] + }; + + case FETCH_ERRORTYPES_SUCCESS: + // All done: set loading "false". + // Also, replace the items with the ones from the server + return { + ...state, + errorTypesLoaded: true, + errorTypes: action.payload.errorTypes + }; + + case FETCH_ERRORTYPES_FAILURE: + // The request failed, but it did stop, so set loading to "false". + // Save the error, and we can display it somewhere + return { + ...state, + errorTypesLoaded: false, + // don't: errorTypes: [] + errorTypesError: action.payload.error + }; + + default: + // ALWAYS have a default case in a reducer + return state; + } +} diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/index.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/index.js new file mode 100644 index 0000000000000000000000000000000000000000..15d63fbdf30d454efdd6bbc2e779bbf0e7eee698 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/index.js @@ -0,0 +1,11 @@ +import { combineReducers } from "redux"; +import appInitData from "./appInitDataReducers"; +import mainFilters from "./mainFilters"; +import landingPageReducers from "./landingPageReducers"; + + +export default combineReducers({ + appInitData, + mainFilters, + landing_page:landingPageReducers, +}); diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/landingPageReducers.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/landingPageReducers.js new file mode 100644 index 0000000000000000000000000000000000000000..cfb5d731fbfafaa4ec9547e896047844e1fe0717 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/landingPageReducers.js @@ -0,0 +1,118 @@ +import { + SET_AVERAGING_WINDOW, + SET_TEST_TYPE, + SET_COMPONENT_SIZES +} from '../actions/landingPageActions.js' + +const initialState = { + station_statistics: { + averaging_window: 1, + test_type: 'B' + }, + layout: { + breakpoints: { + md: 996, + xxs: 0 + }, + cols: { + md: 12, + xxs: 1 + }, + panels: { + md: [{ + i: 'ul', + x: 0, + y: 0, + w: 8, + h: 3 + }, + { + i: 'ur', + x: 9, + y: 0, + w: 4, + h: 3 + }, + { + i: 'bl', + x: 0, + y: 0, + w: 8, + h: 2 + }, + { + i: 'br', + x: 9, + y: 0, + w: 4, + h: 2 + } + ], + xxs: [{ + i: 'ul', + x: 0, + y: 0, + w: 1, + h: 3 + }, + { + i: 'ur', + x: 0, + y: 0, + w: 1, + h: 3 + }, + { + i: 'bl', + x: 0, + y: 0, + w: 1, + h: 2 + }, + { + i: 'br', + x: 0, + y: 0, + w: 1, + h: 2 + } + ] + }, + current_layout: {} + } +}; + + +export default function(state = initialState, action) { + switch (action.type) { + case SET_AVERAGING_WINDOW: + { + return { + ...state, + station_statistics: { ...state.station_statistics, + averaging_window: action.payload.averagingWindow + } + }; + } + case SET_TEST_TYPE: + { + return { + ...state, + station_statistics: { ...state.station_statistics, + test_type: action.payload.test_type + } + }; + } + case SET_COMPONENT_SIZES: + { + return { + ...state, + layout: { ...state.layout, + current_layout: action.payload + } + }; + } + default: + return state; + } +} diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/mainFilters.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/mainFilters.js new file mode 100644 index 0000000000000000000000000000000000000000..80b7cc50a42e045a06e58bbc8afc682e8df57c20 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/mainFilters.js @@ -0,0 +1,41 @@ +import { + SET_STATION_GROUP, + SET_ERRORS_ONLY, + SET_PERIOD +} from "../actions/mainFiltersActions"; + + +const initialState = { + selectedStationGroup: 'A', + errorsOnly: false, + period: 14 // days +}; + + +export default function(state = initialState, action) { + switch (action.type) { + case SET_STATION_GROUP: { + const { stationGroup } = action.payload; + return { + ...state, + selectedStationGroup: stationGroup + }; + } + case SET_ERRORS_ONLY: { + const { errorsOnly } = action.payload; + return { + ...state, + errorsOnly: errorsOnly + }; + } + case SET_PERIOD: { + const { period } = action.payload; + return { + ...state, + period: period + }; + } + default: + return state; + } +} diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/store.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/store.js new file mode 100644 index 0000000000000000000000000000000000000000..caceabe064b591e78593d2613e2b014129c90d3f --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/store.js @@ -0,0 +1,14 @@ +import { createStore, applyMiddleware, compose } from "redux"; +import rootReducer from "./reducers/index.js"; +import thunk from 'redux-thunk'; + +// Needed for the chrome Redux DevTools extension +const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; + +const store = createStore( + rootReducer, + /* preloadedState, */ + composeEnhancers( applyMiddleware(thunk) ) +); + +export default store; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/latest_observations.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/latest_observations.js new file mode 100644 index 0000000000000000000000000000000000000000..c0bc17b266c323e2b66d0340921e3ae6b69c6306 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/latest_observations.js @@ -0,0 +1,647 @@ +const data = [ + { + "station_name": "CS001C", + "rtsm": [ + { + "observation_id": 672048, + "start_datetime": "2018-10-14T19:55:00Z", + "end_datetime": "2018-10-14T20:15:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671992, + "start_datetime": "2018-10-14T15:25:00Z", + "end_datetime": "2018-10-14T15:55:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 1, + "LOW_NOISE": 1 + } + }, { + "observation_id": 671980, + "start_datetime": "2018-10-14T13:44:00Z", + "end_datetime": "2018-10-14T14:04:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671972, + "start_datetime": "2018-10-14T13:10:00Z", + "end_datetime": "2018-10-14T13:30:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671968, + "start_datetime": "2018-10-14T12:59:00Z", + "end_datetime": "2018-10-14T13:09:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671964, + "start_datetime": "2018-10-14T12:48:00Z", + "end_datetime": "2018-10-14T12:58:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671952, + "start_datetime": "2018-10-14T10:28:00Z", + "end_datetime": "2018-10-14T10:38:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671948, + "start_datetime": "2018-10-14T08:49:00Z", + "end_datetime": "2018-10-14T09:09:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671940, + "start_datetime": "2018-10-14T08:17:00Z", + "end_datetime": "2018-10-14T08:37:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 671936, + "start_datetime": "2018-10-14T08:06:00Z", + "end_datetime": "2018-10-14T08:16:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671932, + "start_datetime": "2018-10-14T07:44:00Z", + "end_datetime": "2018-10-14T08:04:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 671928, + "start_datetime": "2018-10-14T07:33:00Z", + "end_datetime": "2018-10-14T07:43:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671924, + "start_datetime": "2018-10-14T07:20:00Z", + "end_datetime": "2018-10-14T07:30:00Z", + "mode": [5], + "total_component_errors": 3, + "error_summary": { + "HIGH_NOISE": 1, + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 671920, + "start_datetime": "2018-10-14T07:09:00Z", + "end_datetime": "2018-10-14T07:19:00Z", + "mode": [5], + "total_component_errors": 3, + "error_summary": { + "HIGH_NOISE": 1, + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 671904, + "start_datetime": "2018-10-14T05:09:00Z", + "end_datetime": "2018-10-14T05:29:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 671896, + "start_datetime": "2018-10-14T04:28:00Z", + "end_datetime": "2018-10-14T04:38:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671880, + "start_datetime": "2018-10-14T02:56:00Z", + "end_datetime": "2018-10-14T03:06:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671840, + "start_datetime": "2018-10-13T22:22:00Z", + "end_datetime": "2018-10-13T22:32:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671792, + "start_datetime": "2018-10-13T18:40:00Z", + "end_datetime": "2018-10-13T18:50:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671772, + "start_datetime": "2018-10-13T17:14:00Z", + "end_datetime": "2018-10-13T17:34:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "LOW_NOISE": 2 + } + }, { + "observation_id": 671768, + "start_datetime": "2018-10-13T16:43:00Z", + "end_datetime": "2018-10-13T17:13:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "LOW_NOISE": 1 + } + }, { + "observation_id": 671756, + "start_datetime": "2018-10-13T15:55:00Z", + "end_datetime": "2018-10-13T16:05:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "LOW_NOISE": 2 + } + }, { + "observation_id": 671752, + "start_datetime": "2018-10-13T15:34:00Z", + "end_datetime": "2018-10-13T15:54:00Z", + "mode": [5], + "total_component_errors": 3, + "error_summary": { + "LOW_NOISE": 2, + "HIGH_NOISE": 1 + } + }, { + "observation_id": 671748, + "start_datetime": "2018-10-13T15:03:00Z", + "end_datetime": "2018-10-13T15:33:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "LOW_NOISE": 2 + } + }, { + "observation_id": 671740, + "start_datetime": "2018-10-13T14:33:00Z", + "end_datetime": "2018-10-13T14:43:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 1, + "LOW_NOISE": 1 + } + }, { + "observation_id": 672574, + "start_datetime": "2018-10-13T12:11:00Z", + "end_datetime": "2018-10-13T12:21:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672566, + "start_datetime": "2018-10-13T08:15:00Z", + "end_datetime": "2018-10-13T08:30:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672562, + "start_datetime": "2018-10-13T08:02:00Z", + "end_datetime": "2018-10-13T08:12:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672886, + "start_datetime": "2018-10-13T02:21:00Z", + "end_datetime": "2018-10-13T06:55:00Z", + "mode": [1], + "total_component_errors": 2, + "error_summary": { + "LOW_NOISE": 1, + "FLAT": 1 + } + }, { + "observation_id": 672878, + "start_datetime": "2018-10-13T02:05:00Z", + "end_datetime": "2018-10-13T02:20:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672666, + "start_datetime": "2018-10-12T22:36:00Z", + "end_datetime": "2018-10-12T22:46:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672662, + "start_datetime": "2018-10-12T22:20:00Z", + "end_datetime": "2018-10-12T22:35:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672882, + "start_datetime": "2018-10-12T20:45:00Z", + "end_datetime": "2018-10-12T22:15:00Z", + "mode": [1], + "total_component_errors": 2, + "error_summary": { + "LOW_NOISE": 1, + "FLAT": 1 + } + }, { + "observation_id": 672598, + "start_datetime": "2018-10-12T16:12:00Z", + "end_datetime": "2018-10-12T16:22:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672594, + "start_datetime": "2018-10-12T16:01:00Z", + "end_datetime": "2018-10-12T16:11:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 672862, + "start_datetime": "2018-10-12T05:00:00Z", + "end_datetime": "2018-10-12T07:55:00Z", + "mode": [1], + "total_component_errors": 1, + "error_summary": { + "FLAT": 1 + } + }, { + "observation_id": 672864, + "start_datetime": "2018-10-12T04:49:00Z", + "end_datetime": "2018-10-12T04:59:00Z", + "mode": [1], + "total_component_errors": 1, + "error_summary": { + "FLAT": 1 + } + }, { + "observation_id": 672840, + "start_datetime": "2018-10-12T04:37:00Z", + "end_datetime": "2018-10-12T04:47:00Z", + "mode": [1], + "total_component_errors": 1, + "error_summary": { + "FLAT": 1 + } + }, { + "observation_id": 672838, + "start_datetime": "2018-10-12T04:26:00Z", + "end_datetime": "2018-10-12T04:36:00Z", + "mode": [3], + "total_component_errors": 1, + "error_summary": { + "FLAT": 1 + } + }, { + "observation_id": 672690, + "start_datetime": "2018-10-12T04:00:00Z", + "end_datetime": "2018-10-12T04:15:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 1, + "HIGH_NOISE": 1 + } + }, { + "observation_id": 672590, + "start_datetime": "2018-10-12T03:24:00Z", + "end_datetime": "2018-10-12T03:34:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672750, + "start_datetime": "2018-10-12T03:12:00Z", + "end_datetime": "2018-10-12T03:22:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672734, + "start_datetime": "2018-10-11T19:11:00Z", + "end_datetime": "2018-10-12T03:11:00Z", + "mode": [5], + "total_component_errors": 4, + "error_summary": { + "HIGH_NOISE": 1, + "SUMMATOR_NOISE": 3 + } + }, { + "observation_id": 672730, + "start_datetime": "2018-10-11T19:00:00Z", + "end_datetime": "2018-10-11T19:10:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 672854, + "start_datetime": "2018-10-11T18:17:00Z", + "end_datetime": "2018-10-11T18:27:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672470, + "start_datetime": "2018-10-11T01:19:16Z", + "end_datetime": "2018-10-11T05:19:16Z", + "mode": [5], + "total_component_errors": 4, + "error_summary": { + "HIGH_NOISE": 1, + "SUMMATOR_NOISE": 3 + } + }, { + "observation_id": 672466, + "start_datetime": "2018-10-11T01:08:16Z", + "end_datetime": "2018-10-11T01:18:16Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 670310, + "start_datetime": "2018-10-10T12:06:40Z", + "end_datetime": "2018-10-10T20:06:40Z", + "mode": [5], + "total_component_errors": 5, + "error_summary": { + "HIGH_NOISE": 2, + "SUMMATOR_NOISE": 3 + } + }, { + "observation_id": 670306, + "start_datetime": "2018-10-10T11:55:40Z", + "end_datetime": "2018-10-10T12:05:40Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 672786, + "start_datetime": "2018-10-10T08:45:05Z", + "end_datetime": "2018-10-10T09:15:05Z", + "mode": [5], + "total_component_errors": 3, + "error_summary": { + "SUMMATOR_NOISE": 3 + } + }, { + "observation_id": 672420, + "start_datetime": "2018-10-10T07:15:28Z", + "end_datetime": "2018-10-10T07:25:28Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 672484, + "start_datetime": "2018-10-10T01:10:11Z", + "end_datetime": "2018-10-10T05:10:11Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 672480, + "start_datetime": "2018-10-10T00:59:11Z", + "end_datetime": "2018-10-10T01:09:11Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672708, + "start_datetime": "2018-10-09T23:07:07Z", + "end_datetime": "2018-10-09T23:17:07Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 672698, + "start_datetime": "2018-10-09T18:55:07Z", + "end_datetime": "2018-10-09T19:05:07Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672722, + "start_datetime": "2018-10-09T18:07:49Z", + "end_datetime": "2018-10-09T18:17:49Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672716, + "start_datetime": "2018-10-09T14:06:49Z", + "end_datetime": "2018-10-09T18:06:49Z", + "mode": [5], + "total_component_errors": 17, + "error_summary": { + "LOW_NOISE": 3, + "SUMMATOR_NOISE": 2, + "HIGH_NOISE": 12 + } + }, { + "observation_id": 672712, + "start_datetime": "2018-10-09T13:55:49Z", + "end_datetime": "2018-10-09T14:05:49Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 672402, + "start_datetime": "2018-10-09T12:44:21Z", + "end_datetime": "2018-10-09T12:54:21Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672410, + "start_datetime": "2018-10-08T20:20:14Z", + "end_datetime": "2018-10-09T04:20:14Z", + "mode": [5], + "total_component_errors": 6, + "error_summary": { + "HIGH_NOISE": 3, + "SUMMATOR_NOISE": 3 + } + }, { + "observation_id": 672406, + "start_datetime": "2018-10-08T20:09:14Z", + "end_datetime": "2018-10-08T20:19:14Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 667914, + "start_datetime": "2018-10-08T08:00:00Z", + "end_datetime": "2018-10-08T16:00:00Z", + "mode": [2], + "total_component_errors": 1, + "error_summary": { + "FLAT": 1 + } + }, { + "observation_id": 672090, + "start_datetime": "2018-10-07T17:01:00Z", + "end_datetime": "2018-10-07T17:11:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 2 + } + }, { + "observation_id": 672192, + "start_datetime": "2018-10-07T04:53:00Z", + "end_datetime": "2018-10-07T07:47:00Z", + "mode": [1], + "total_component_errors": 2, + "error_summary": { + "LOW_NOISE": 1, + "FLAT": 1 + } + }, { + "observation_id": 672076, + "start_datetime": "2018-10-07T04:47:00Z", + "end_datetime": "2018-10-07T04:52:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672072, + "start_datetime": "2018-10-06T22:56:00Z", + "end_datetime": "2018-10-07T04:46:00Z", + "mode": [5], + "total_component_errors": 3, + "error_summary": { + "SUMMATOR_NOISE": 3 + } + }, { + "observation_id": 672068, + "start_datetime": "2018-10-06T22:50:00Z", + "end_datetime": "2018-10-06T22:55:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 672060, + "start_datetime": "2018-10-05T22:56:00Z", + "end_datetime": "2018-10-06T04:46:00Z", + "mode": [5], + "total_component_errors": 4, + "error_summary": { + "HIGH_NOISE": 1, + "SUMMATOR_NOISE": 3 + } + }, { + "observation_id": 672056, + "start_datetime": "2018-10-05T22:50:00Z", + "end_datetime": "2018-10-05T22:55:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + } + ] + } +]; + +export default data; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/station_details.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/station_details.js new file mode 100644 index 0000000000000000000000000000000000000000..423531abe6c46cd596f7efb6254e4e2791c3ecbe --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/station_details.js @@ -0,0 +1,385 @@ +const data = [ + { + "station_name": "CS004C", + "station_tests": [ + { + "total_component_errors": 11, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:24Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 4, + "MODEM": 2, + "OSCILLATION": 1, + "C_SUMMATOR": 1 + }, + "LBL": { + "LOW_NOISE": 1, + "RF_FAIL": 1 + }, + "TBB": { + "TEMPERATURE": 1 + } + } + } + ] + }, { + "station_name": "CS006C", + "station_tests": [ + { + "total_component_errors": 15, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:46:26Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "JITTER": 4, + "MODEM": 3, + "RF_FAIL": 2, + "HIGH_NOISE": 2 + }, + "LBH": { + "RF_FAIL": 2, + "HIGH_NOISE": 1 + }, + "TBB": { + "TEMPERATURE": 1 + } + } + } + ] + }, { + "station_name": "CS017C", + "station_tests": [ + { + "total_component_errors": 6, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:32Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 3, + "HIGH_NOISE": 1, + "SPURIOUS": 1 + }, + "LBH": { + "LOW_NOISE": 1 + } + } + } + ] + }, { + "station_name": "CS028C", + "station_tests": [ + { + "total_component_errors": 9, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:21Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 3, + "HIGH_NOISE": 1, + "OSCILLATION": 1 + }, + "LBH": { + "DOWN": 2 + }, + "LBL": { + "DOWN": 2 + } + } + } + ] + }, { + "station_name": "CS032C", + "station_tests": [ + { + "total_component_errors": 5, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:46:02Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "MODEM": 2, + "JITTER": 1, + "RF_FAIL": 1 + }, + "LBH": { + "JITTER": 1 + } + } + } + ] + }, { + "station_name": "CS103C", + "station_tests": [ + { + "total_component_errors": 17, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:23Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "LBH": { + "DOWN": 3, + "RF_FAIL": 2, + "FLAT": 1 + }, + "HBA": { + "RF_FAIL": 3, + "MODEM": 1, + "C_SUMMATOR": 1 + }, + "LBL": { + "DOWN": 2, + "FLAT": 2, + "RF_FAIL": 1, + "LOW_NOISE": 1 + } + } + } + ] + }, { + "station_name": "CS302C", + "station_tests": [ + { + "total_component_errors": 26, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:17Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 9, + "MODEM": 7, + "HIGH_NOISE": 3, + "SUMMATOR_NOISE": 3, + "JITTER": 2, + "SPURIOUS": 1 + }, + "LBL": { + "FLAT": 1 + } + } + } + ] + }, { + "station_name": "DE602C", + "station_tests": [ + { + "total_component_errors": 6, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:34Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "MODEM": 3 + }, + "LBH": { + "HIGH_NOISE": 2, + "JITTER": 1 + } + } + } + ] + }, { + "station_name": "DE605C", + "station_tests": [ + { + "total_component_errors": 11, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:28:50Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E5 TV TBC TM", + "component_error_summary": { + "LBH": { + "DOWN": 2, + "RF_FAIL": 2, + "HIGH_NOISE": 1 + }, + "HBA": { + "SUMMATOR_NOISE": 2, + "MODEM": 2, + "OSCILLATION": 1 + }, + "RSP": { + "TEMPERATURE": 1 + } + } + } + ] + }, { + "station_name": "PL610C", + "station_tests": [ + { + "total_component_errors": 56, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:42Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "LBH": { + "RF_FAIL": 28, + "DOWN": 7, + "LOW_NOISE": 1, + "SPURIOUS": 1 + }, + "HBA": { + "SPURIOUS": 19 + } + } + } + ] + }, { + "station_name": "PL611C", + "station_tests": [ + { + "total_component_errors": 54, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:47:53Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "SPURIOUS": 47 + }, + "LBH": { + "RF_FAIL": 2, + "DOWN": 1 + }, + "TBB": { + "MEMORY": 1, + "VERSION": 1, + "VOLTAGE": 1 + }, + "RSP": { + "TEMPERATURE": 1 + } + } + } + ] + }, { + "station_name": "RS205C", + "station_tests": [ + { + "total_component_errors": 16, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:53:46Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 4, + "MODEM": 3, + "RF_FAIL": 2, + "SPURIOUS": 1, + "JITTER": 1 + }, + "LBL": { + "HIGH_NOISE": 3 + }, + "LBH": { + "HIGH_NOISE": 1, + "RF_FAIL": 1 + } + } + } + ] + }, { + "station_name": "RS210C", + "station_tests": [ + { + "total_component_errors": 9, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:28Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 4, + "HIGH_NOISE": 3, + "MODEM": 1 + }, + "LBL": { + "FLAT": 1 + } + } + } + ] + }, { + "station_name": "RS305C", + "station_tests": [ + { + "total_component_errors": 12, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:27Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 2, + "HIGH_NOISE": 1, + "JITTER": 1, + "C_SUMMATOR": 1 + }, + "TBB": { + "MEMORY": 2, + "VERSION": 2, + "VOLTAGE": 2 + }, + "LBH": { + "RF_FAIL": 1 + } + } + } + ] + }, { + "station_name": "RS409C", + "station_tests": [ + { + "total_component_errors": 17, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:51:06Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "SPURIOUS": 4, + "RF_FAIL": 2, + "SUMMATOR_NOISE": 2, + "HIGH_NOISE": 1, + "JITTER": 1, + "OSCILLATION": 1 + }, + "LBH": { + "SPURIOUS": 3, + "FLAT": 1, + "DOWN": 1 + }, + "TBB": { + "MEMORY": 1 + } + } + } + ] + }, { + "station_name": "SE607C", + "station_tests": [ + { + "total_component_errors": 24, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:48:55Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 S7 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "SPURIOUS": 21 + }, + "LBH": { + "RF_FAIL": 1 + }, + "RSP": { + "TEMPERATURE": 1 + }, + "TBB": { + "MEMORY": 1 + } + } + } + ] + } +]; + +export default data; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/station_overview.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/station_overview.js new file mode 100644 index 0000000000000000000000000000000000000000..4fd59c7224c6de14884a3b6abde8e2bbdca0288e --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/station_overview.js @@ -0,0 +1,818 @@ +const station_overview_data = [ + { + "station_name": "CS001C", + "station_tests": [ + { + "total_component_errors": 0, + "start_datetime": "2017-06-07T09:54:00Z", + "end_datetime": "2017-06-07T10:01:17Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 TV TBC TM", + "component_error_summary": {} + }, { + "total_component_errors": 22, + "start_datetime": "2017-01-03T14:40:56Z", + "end_datetime": "2017-01-03T14:49:29Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "TBB": { + "MEMORY": 18 + }, + "HBA": { + "MODEM": 1 + }, + "LBH": { + "HIGH_NOISE": 1, + "SPURIOUS": 1 + }, + "LBL": { + "SPURIOUS": 1 + } + } + }, { + "total_component_errors": 1, + "start_datetime": "2016-11-07T13:27:41Z", + "end_datetime": "2016-11-07T13:39:21Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "LBH": { + "DOWN": 1 + } + } + } + ], + "rtsm": [ + { + "observation_id": 672048, + "start_datetime": "2018-10-14T19:55:00Z", + "end_datetime": "2018-10-14T20:15:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + }, { + "observation_id": 671992, + "start_datetime": "2018-10-14T15:25:00Z", + "end_datetime": "2018-10-14T15:55:00Z", + "mode": [5], + "total_component_errors": 2, + "error_summary": { + "SUMMATOR_NOISE": 1, + "LOW_NOISE": 1 + } + }, { + "observation_id": 671980, + "start_datetime": "2018-10-14T13:44:00Z", + "end_datetime": "2018-10-14T14:04:00Z", + "mode": [5], + "total_component_errors": 1, + "error_summary": { + "SUMMATOR_NOISE": 1 + } + } + ] + }, { + "station_name": "CS002C", + "station_tests": [ + { + "total_component_errors": 15, + "start_datetime": "2014-05-12T12:11:30Z", + "end_datetime": "2014-05-12T12:29:38Z", + "checks": "O1 SP1 NS1=180 O3 SP3 NS3=180 M O5 SN SP5 NS5=300", + "component_error_summary": { + "LBH": { + "HIGH_NOISE": 5, + "RF_FAIL": 5 + }, + "HBA": { + "HIGH_NOISE": 3, + "JITTER": 2 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS004C", + "station_tests": [ + { + "total_component_errors": 11, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:24Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 4, + "MODEM": 2, + "OSCILLATION": 1, + "C_SUMMATOR": 1 + }, + "LBL": { + "LOW_NOISE": 1, + "RF_FAIL": 1 + }, + "TBB": { + "TEMPERATURE": 1 + } + } + }, { + "total_component_errors": 7, + "start_datetime": "2018-09-11T10:30:00Z", + "end_datetime": "2018-09-11T10:57:35Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 2, + "JITTER": 1 + }, + "LBH": { + "JITTER": 1 + }, + "LBL": { + "LOW_NOISE": 1, + "RF_FAIL": 1 + }, + "TBB": { + "TEMPERATURE": 1 + } + } + }, { + "total_component_errors": 9, + "start_datetime": "2018-09-10T20:00:00Z", + "end_datetime": "2018-09-10T22:54:06Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 2, + "MODEM": 2, + "RF_FAIL": 1, + "JITTER": 1 + }, + "LBL": { + "HIGH_NOISE": 1, + "RF_FAIL": 1 + }, + "TBB": { + "TEMPERATURE": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS005C", + "station_tests": [ + { + "total_component_errors": 3, + "start_datetime": "2016-11-07T13:27:41Z", + "end_datetime": "2016-11-07T13:39:46Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "HBA": { + "MODEM": 2 + }, + "LBL": { + "OSCILLATION": 1 + } + } + }, { + "total_component_errors": 5, + "start_datetime": "2014-05-12T12:11:30Z", + "end_datetime": "2014-05-12T12:29:43Z", + "checks": "O1 SP1 NS1=180 O3 SP3 NS3=180 M O5 SN SP5 NS5=300", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 4 + }, + "LBH": { + "RF_FAIL": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS006C", + "station_tests": [ + { + "total_component_errors": 15, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:46:26Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "JITTER": 4, + "MODEM": 3, + "RF_FAIL": 2, + "HIGH_NOISE": 2 + }, + "LBH": { + "RF_FAIL": 2, + "HIGH_NOISE": 1 + }, + "TBB": { + "TEMPERATURE": 1 + } + } + }, { + "total_component_errors": 8, + "start_datetime": "2018-09-11T10:30:00Z", + "end_datetime": "2018-09-11T10:57:37Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "HBA": { + "MODEM": 3, + "HIGH_NOISE": 2 + }, + "LBH": { + "RF_FAIL": 2 + }, + "TBB": { + "TEMPERATURE": 1 + } + } + }, { + "total_component_errors": 16, + "start_datetime": "2018-09-10T20:00:00Z", + "end_datetime": "2018-09-10T22:57:35Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 4, + "MODEM": 4, + "HIGH_NOISE": 3, + "JITTER": 1 + }, + "LBH": { + "RF_FAIL": 2, + "OSCILLATION": 1 + }, + "TBB": { + "TEMPERATURE": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS007C", + "station_tests": [ + { + "total_component_errors": 5, + "start_datetime": "2015-09-03T08:20:00Z", + "end_datetime": "2015-09-03T09:28:52Z", + "checks": "RV SPU RBV SH1 F1 D1 O1 SP1 NS1=120 S1 SH3 F3 D3 O3 SP3 NS3=120 S3 M5 O5 SN5 SP5 NS5=120 S7 E7 TV TM", + "component_error_summary": { + "SPU": { + "VOLTAGE": 3 + }, + "HBA": { + "HIGH_NOISE": 1 + }, + "LBL": { + "RF_FAIL": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS011C", + "station_tests": [ + { + "total_component_errors": 8, + "start_datetime": "2017-01-03T14:40:56Z", + "end_datetime": "2017-01-03T14:49:59Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "TBB": { + "MEMORY": 6, + "VERSION": 1, + "VOLTAGE": 1 + } + } + }, { + "total_component_errors": 5, + "start_datetime": "2015-09-03T08:20:00Z", + "end_datetime": "2015-09-03T09:37:26Z", + "checks": "RV SPU RBV SH1 F1 D1 O1 SP1 NS1=120 S1 SH3 F3 D3 O3 SP3 NS3=120 S3 M5 O5 SN5 SP5 NS5=120 S7 E7 TV TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 3, + "SUMMATOR_NOISE": 1 + }, + "RSP": { + "VOLTAGE": 1 + } + } + }, { + "total_component_errors": 2, + "start_datetime": "2014-05-12T12:11:30Z", + "end_datetime": "2014-05-12T12:29:34Z", + "checks": "O1 SP1 NS1=180 O3 SP3 NS3=180 M O5 SN SP5 NS5=300", + "component_error_summary": { + "LBH": { + "HIGH_NOISE": 1, + "RF_FAIL": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS013C", + "station_tests": [ + { + "total_component_errors": 3, + "start_datetime": "2016-11-07T13:27:41Z", + "end_datetime": "2016-11-07T13:37:43Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "HBA": { + "SUMMATOR_NOISE": 1 + }, + "LBH": { + "DOWN": 1, + "SPURIOUS": 1 + } + } + }, { + "total_component_errors": 6, + "start_datetime": "2015-08-20T19:53:48Z", + "end_datetime": "2015-08-20T20:05:12Z", + "checks": "RV SH1 F1 D1 O1 SP1 NS1=120 S1 SH3 F3 D3 O3 SP3 NS3=120 S3 M5 O5 SN5 SP5 NS5=120 S5", + "component_error_summary": { + "LBH": { + "OSCILLATION": 3, + "HIGH_NOISE": 1, + "SPURIOUS": 1 + }, + "LBL": { + "DOWN": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS017C", + "station_tests": [ + { + "total_component_errors": 6, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:32Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 3, + "HIGH_NOISE": 1, + "SPURIOUS": 1 + }, + "LBH": { + "LOW_NOISE": 1 + } + } + }, { + "total_component_errors": 2, + "start_datetime": "2018-09-11T10:30:00Z", + "end_datetime": "2018-09-11T10:57:21Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "LBH": { + "JITTER": 1, + "LOW_NOISE": 1 + } + } + }, { + "total_component_errors": 5, + "start_datetime": "2018-09-10T20:00:00Z", + "end_datetime": "2018-09-10T22:57:33Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 3 + }, + "LBH": { + "HIGH_NOISE": 1, + "LOW_NOISE": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS024C", + "station_tests": [ + { + "total_component_errors": 5, + "start_datetime": "2015-09-03T08:20:00Z", + "end_datetime": "2015-09-03T09:28:53Z", + "checks": "RV SPU RBV SH1 F1 D1 O1 SP1 NS1=120 S1 SH3 F3 D3 O3 SP3 NS3=120 S3 M5 O5 SN5 SP5 NS5=120 S7 E7 TV TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 2, + "RF_FAIL": 2 + }, + "LBH": { + "OSCILLATION": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS028C", + "station_tests": [ + { + "total_component_errors": 9, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:21Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 3, + "HIGH_NOISE": 1, + "OSCILLATION": 1 + }, + "LBH": { + "DOWN": 2 + }, + "LBL": { + "DOWN": 2 + } + } + }, { + "total_component_errors": 11, + "start_datetime": "2018-09-11T10:30:00Z", + "end_datetime": "2018-09-11T10:57:28Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "LBH": { + "RF_FAIL": 3, + "DOWN": 2, + "LOW_NOISE": 1 + }, + "LBL": { + "DOWN": 2, + "RF_FAIL": 1 + }, + "HBA": { + "OSCILLATION": 1, + "C_SUMMATOR": 1 + } + } + }, { + "total_component_errors": 9, + "start_datetime": "2018-09-10T20:00:00Z", + "end_datetime": "2018-09-10T22:50:54Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 3, + "OSCILLATION": 1, + "SPURIOUS": 1 + }, + "LBL": { + "DOWN": 2 + }, + "LBH": { + "DOWN": 1, + "LOW_NOISE": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS032C", + "station_tests": [ + { + "total_component_errors": 5, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:46:02Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "MODEM": 2, + "JITTER": 1, + "RF_FAIL": 1 + }, + "LBH": { + "JITTER": 1 + } + } + }, { + "total_component_errors": 2, + "start_datetime": "2018-09-11T10:30:00Z", + "end_datetime": "2018-09-11T10:57:29Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 1, + "MODEM": 1 + } + } + }, { + "total_component_errors": 9, + "start_datetime": "2018-08-30T03:46:00Z", + "end_datetime": "2018-08-30T06:42:28Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 3, + "JITTER": 2, + "MODEM": 2, + "RF_FAIL": 1 + }, + "LBH": { + "DOWN": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS103C", + "station_tests": [ + { + "total_component_errors": 17, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:23Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "LBH": { + "DOWN": 3, + "RF_FAIL": 2, + "FLAT": 1 + }, + "HBA": { + "RF_FAIL": 3, + "MODEM": 1, + "C_SUMMATOR": 1 + }, + "LBL": { + "DOWN": 2, + "FLAT": 2, + "RF_FAIL": 1, + "LOW_NOISE": 1 + } + } + }, { + "total_component_errors": 4, + "start_datetime": "2018-09-11T10:30:00Z", + "end_datetime": "2018-09-11T10:57:31Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "HBA": { + "SUMMATOR_NOISE": 1 + }, + "LBH": { + "FLAT": 1 + }, + "LBL": { + "FLAT": 1, + "LOW_NOISE": 1 + } + } + }, { + "total_component_errors": 8, + "start_datetime": "2018-09-10T20:00:00Z", + "end_datetime": "2018-09-10T22:57:23Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 3, + "HIGH_NOISE": 2 + }, + "LBH": { + "FLAT": 1 + }, + "LBL": { + "FLAT": 1, + "LOW_NOISE": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS201C", + "station_tests": [ + { + "total_component_errors": 14, + "start_datetime": "2018-09-10T20:00:00Z", + "end_datetime": "2018-09-10T22:57:38Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "LBH": { + "RF_FAIL": 2, + "SPURIOUS": 2, + "OSCILLATION": 2, + "DOWN": 1, + "JITTER": 1 + }, + "HBA": { + "RF_FAIL": 2, + "C_SUMMATOR": 1, + "MODEM": 1 + }, + "LBL": { + "OSCILLATION": 1, + "RF_FAIL": 1 + } + } + }, { + "total_component_errors": 9, + "start_datetime": "2018-08-30T03:46:00Z", + "end_datetime": "2018-08-30T06:42:17Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "LBL": { + "DOWN": 4 + }, + "HBA": { + "RF_FAIL": 2, + "C_SUMMATOR": 1 + }, + "LBH": { + "RF_FAIL": 2 + } + } + }, { + "total_component_errors": 7, + "start_datetime": "2018-08-14T00:15:00Z", + "end_datetime": "2018-08-14T03:42:28Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "LBH": { + "RF_FAIL": 2 + }, + "LBL": { + "DOWN": 2, + "RF_FAIL": 1 + }, + "HBA": { + "C_SUMMATOR": 1, + "RF_FAIL": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS301C", + "station_tests": [ + { + "total_component_errors": 33, + "start_datetime": "2017-01-03T14:40:56Z", + "end_datetime": "2017-01-03T14:49:32Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "TBB": { + "MEMORY": 18 + }, + "HBA": { + "MODEM": 7, + "C_SUMMATOR": 2, + "JITTER": 1, + "SPURIOUS": 1, + "HIGH_NOISE": 1 + }, + "LBH": { + "JITTER": 1 + }, + "LBL": { + "HIGH_NOISE": 1, + "SPURIOUS": 1 + } + } + }, { + "total_component_errors": 3, + "start_datetime": "2016-11-07T13:27:41Z", + "end_datetime": "2016-11-07T13:39:22Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 1, + "MODEM": 1 + }, + "TBB": { + "TEMPERATURE": 1 + } + } + }, { + "total_component_errors": 19, + "start_datetime": "2015-09-03T08:20:00Z", + "end_datetime": "2015-09-03T09:37:46Z", + "checks": "RV SPU RBV SH1 F1 D1 O1 SP1 NS1=120 S1 SH3 F3 D3 O3 SP3 NS3=120 S3 M5 O5 SN5 SP5 NS5=120 S7 E7 TV TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 14, + "RF_FAIL": 2, + "C_SUMMATOR": 1, + "JITTER": 1 + }, + "LBH": { + "FLAT": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS302C", + "station_tests": [ + { + "total_component_errors": 26, + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:17Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 9, + "MODEM": 7, + "HIGH_NOISE": 3, + "SUMMATOR_NOISE": 3, + "JITTER": 2, + "SPURIOUS": 1 + }, + "LBL": { + "FLAT": 1 + } + } + }, { + "total_component_errors": 17, + "start_datetime": "2018-09-11T10:30:00Z", + "end_datetime": "2018-09-11T10:57:26Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 TV TBC TM", + "component_error_summary": { + "HBA": { + "SUMMATOR_NOISE": 6, + "HIGH_NOISE": 3, + "MODEM": 3, + "C_SUMMATOR": 1 + }, + "LBH": { + "DOWN": 2 + }, + "LBL": { + "DOWN": 1, + "FLAT": 1 + } + } + }, { + "total_component_errors": 30, + "start_datetime": "2018-09-10T20:00:00Z", + "end_datetime": "2018-09-10T22:50:23Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 9, + "RF_FAIL": 8, + "MODEM": 4, + "SUMMATOR_NOISE": 3, + "JITTER": 2, + "C_SUMMATOR": 1 + }, + "LBH": { + "DOWN": 2 + }, + "LBL": { + "FLAT": 1 + } + } + } + ], + "rtsm": [] + }, { + "station_name": "CS401C", + "station_tests": [ + { + "total_component_errors": 19, + "start_datetime": "2015-09-03T08:20:00Z", + "end_datetime": "2015-09-03T09:37:40Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=120 S1 SH3 F3 D3 O3 SP3 NS3=120 S3 M5 O5 SN5 SP5 NS5=120 S7 E7 TV TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 8, + "SUMMATOR_NOISE": 2, + "C_SUMMATOR": 1, + "MODEM": 1, + "RF_FAIL": 1 + }, + "SPU": { + "VOLTAGE": 3, + "TEMPERATURE": 2 + }, + "LBH": { + "FLAT": 1 + } + } + } + ], + "rtsm": [] + } +]; + + +export default station_overview_data; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/station_test_summary.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/station_test_summary.js new file mode 100644 index 0000000000000000000000000000000000000000..aedbde378a328c85416bf1a2f6d18b5319bce3b3 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/testdata/station_test_summary.js @@ -0,0 +1,802 @@ +const stdata = [ + { + "station_name": "CS002C", + "total_component_errors": 18, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:34Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "LBL": { + "DOWN": 3, + "HIGH_NOISE": 1 + }, + "HBA": { + "JITTER": 3, + "RF_FAIL": 3, + "MODEM": 1, + "HIGH_NOISE": 1 + }, + "LBH": { + "RF_FAIL": 2, + "DOWN": 2, + "HIGH_NOISE": 2 + } + } + }, { + "station_name": "CS004C", + "total_component_errors": 11, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:24Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + } + }, { + "station_name": "CS005C", + "total_component_errors": 10, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:53:18Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 3, + "MODEM": 3, + "RF_FAIL": 2 + }, + "LBH": { + "FLAT": 1 + }, + "TBB": { + "TEMPERATURE": 1 + } + } + }, { + "station_name": "CS006C", + "total_component_errors": 15, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:46:26Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "JITTER": 4, + "MODEM": 3, + "RF_FAIL": 2, + "HIGH_NOISE": 2 + }, + "LBH": { + "RF_FAIL": 2, + "HIGH_NOISE": 1 + }, + "TBB": { + "TEMPERATURE": 1 + } + } + }, { + "station_name": "CS007C", + "total_component_errors": 10, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:19Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 2, + "JITTER": 2, + "HIGH_NOISE": 2, + "MODEM": 1 + }, + "LBL": { + "DOWN": 1 + }, + "LBH": { + "DOWN": 1, + "HIGH_NOISE": 1 + } + } + }, { + "station_name": "CS021C", + "total_component_errors": 20, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:25Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "SPURIOUS": 3, + "OSCILLATION": 2, + "RF_FAIL": 2, + "HIGH_NOISE": 2, + "MODEM": 2 + }, + "LBH": { + "FLAT": 3, + "RF_FAIL": 2, + "LOW_NOISE": 1 + }, + "LBL": { + "FLAT": 2, + "LOW_NOISE": 1 + } + } + }, { + "station_name": "CS026C", + "total_component_errors": 23, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:32Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 8, + "MODEM": 3, + "HIGH_NOISE": 3, + "C_SUMMATOR": 1, + "JITTER": 1, + "SPURIOUS": 1 + }, + "LBH": { + "HIGH_NOISE": 3, + "LOW_NOISE": 1 + }, + "LBL": { + "RF_FAIL": 1 + }, + "TBB": { + "MEMORY": 1 + } + } + }, { + "station_name": "CS028C", + "total_component_errors": 36, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:21Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 7, + "HIGH_NOISE": 3, + "SUMMATOR_NOISE": 3, + "MODEM": 1, + "OSCILLATION": 1, + "C_SUMMATOR": 1 + }, + "LBL": { + "FLAT": 5, + "SPURIOUS": 2, + "DOWN": 2, + "RF_FAIL": 2, + "SHORT": 1, + "LOW_NOISE": 1 + }, + "LBH": { + "DOWN": 2, + "HIGH_NOISE": 2, + "OSCILLATION": 1, + "SPURIOUS": 1, + "FLAT": 1 + } + } + }, { + "station_name": "CS030C", + "total_component_errors": 26, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:31Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 4, + "HIGH_NOISE": 3, + "JITTER": 2, + "MODEM": 2, + "C_SUMMATOR": 1, + "LOW_NOISE": 1, + "SPURIOUS": 1 + }, + "LBH": { + "LOW_NOISE": 2, + "SHORT": 2, + "FLAT": 1 + }, + "LBL": { + "SHORT": 1, + "FLAT": 1, + "LOW_NOISE": 1 + }, + "RSP": { + "TEMPERATURE": 1 + }, + "TBB": { + "MEMORY": 1, + "VERSION": 1, + "VOLTAGE": 1 + } + } + }, { + "station_name": "CS031C", + "total_component_errors": 26, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:35Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 6, + "MODEM": 4, + "HIGH_NOISE": 1, + "LOW_NOISE": 1, + "SPURIOUS": 1 + }, + "LBH": { + "FLAT": 3, + "SPURIOUS": 1, + "DOWN": 1 + }, + "LBL": { + "LOW_NOISE": 2, + "DOWN": 1, + "FLAT": 1 + }, + "TBB": { + "MEMORY": 1, + "TEMPERATURE": 1, + "VERSION": 1, + "VOLTAGE": 1 + } + } + }, { + "station_name": "CS032C", + "total_component_errors": 5, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:46:02Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "MODEM": 2, + "JITTER": 1, + "RF_FAIL": 1 + }, + "LBH": { + "JITTER": 1 + } + } + }, { + "station_name": "CS103C", + "total_component_errors": 17, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:23Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "LBH": { + "DOWN": 3, + "RF_FAIL": 2, + "FLAT": 1 + }, + "HBA": { + "RF_FAIL": 3, + "MODEM": 1, + "C_SUMMATOR": 1 + }, + "LBL": { + "DOWN": 2, + "FLAT": 2, + "RF_FAIL": 1, + "LOW_NOISE": 1 + } + } + }, { + "station_name": "CS302C", + "total_component_errors": 26, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:17Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 9, + "MODEM": 7, + "HIGH_NOISE": 3, + "SUMMATOR_NOISE": 3, + "JITTER": 2, + "SPURIOUS": 1 + }, + "LBL": { + "FLAT": 1 + } + } + }, { + "station_name": "CS501C", + "total_component_errors": 36, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:22Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 10, + "MODEM": 5, + "RF_FAIL": 5, + "JITTER": 2 + }, + "LBH": { + "FLAT": 2, + "DOWN": 1, + "HIGH_NOISE": 1, + "RF_FAIL": 1, + "SPURIOUS": 1 + }, + "LBL": { + "DOWN": 1, + "FLAT": 1, + "SHORT": 1 + }, + "RSP": { + "TEMPERATURE": 1 + }, + "TBB": { + "MEMORY": 1, + "TEMPERATURE": 1, + "VERSION": 1, + "VOLTAGE": 1 + } + } + }, { + "station_name": "DE601C", + "total_component_errors": 18, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:23Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 S7 E7 TV TBC TM", + "component_error_summary": { + "RSP": { + "TEMPERATURE": 7 + }, + "LBH": { + "LOW_NOISE": 2, + "DOWN": 2, + "FLAT": 2, + "HIGH_NOISE": 1, + "RF_FAIL": 1 + }, + "HBA": { + "MODEM": 2, + "HIGH_NOISE": 1 + } + } + }, { + "station_name": "DE602C", + "total_component_errors": 6, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:34Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "MODEM": 3 + }, + "LBH": { + "HIGH_NOISE": 2, + "JITTER": 1 + } + } + }, { + "station_name": "DE603C", + "total_component_errors": 3, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:43:42Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E5 TV TBC TM", + "component_error_summary": { + "RSP": { + "TEMPERATURE": 2 + }, + "LBH": { + "RF_FAIL": 1 + } + } + }, { + "station_name": "DE604C", + "total_component_errors": 1, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:50:07Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E5 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 1 + } + } + }, { + "station_name": "DE605C", + "total_component_errors": 11, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:28:50Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E5 TV TBC TM", + "component_error_summary": { + "LBH": { + "DOWN": 2, + "RF_FAIL": 2, + "HIGH_NOISE": 1 + }, + "HBA": { + "SUMMATOR_NOISE": 2, + "MODEM": 2, + "OSCILLATION": 1 + }, + "RSP": { + "TEMPERATURE": 1 + } + } + }, { + "station_name": "DE609C", + "total_component_errors": 6, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:39:15Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E5 TV TBC TM", + "component_error_summary": { + "TBB": { + "VERSION": 2, + "VOLTAGE": 2, + "MEMORY": 1 + }, + "LBH": { + "RF_FAIL": 1 + } + } + }, { + "station_name": "IE613C", + "total_component_errors": 23, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:36:21Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E5 TV TBC TM", + "component_error_summary": { + "LBH": { + "RF_FAIL": 16, + "DOWN": 4 + }, + "HBA": { + "SPURIOUS": 2 + }, + "TBB": { + "MEMORY": 1 + } + } + }, { + "station_name": "PL610C", + "total_component_errors": 56, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:42Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "LBH": { + "RF_FAIL": 28, + "DOWN": 7, + "LOW_NOISE": 1, + "SPURIOUS": 1 + }, + "HBA": { + "SPURIOUS": 19 + } + } + }, { + "station_name": "PL611C", + "total_component_errors": 54, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:47:53Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "SPURIOUS": 47 + }, + "LBH": { + "RF_FAIL": 2, + "DOWN": 1 + }, + "TBB": { + "MEMORY": 1, + "VERSION": 1, + "VOLTAGE": 1 + }, + "RSP": { + "TEMPERATURE": 1 + } + } + }, { + "station_name": "PL612C", + "total_component_errors": 29, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:36Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "SPURIOUS": 28 + }, + "LBH": { + "RF_FAIL": 1 + } + } + }, { + "station_name": "RS205C", + "total_component_errors": 16, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:53:46Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 4, + "MODEM": 3, + "RF_FAIL": 2, + "SPURIOUS": 1, + "JITTER": 1 + }, + "LBL": { + "HIGH_NOISE": 3 + }, + "LBH": { + "HIGH_NOISE": 1, + "RF_FAIL": 1 + } + } + }, { + "station_name": "RS210C", + "total_component_errors": 9, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:28Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 4, + "HIGH_NOISE": 3, + "MODEM": 1 + }, + "LBL": { + "FLAT": 1 + } + } + }, { + "station_name": "RS305C", + "total_component_errors": 19, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:27Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 5, + "C_SUMMATOR": 1, + "JITTER": 1, + "HIGH_NOISE": 1 + }, + "TBB": { + "MEMORY": 3, + "VOLTAGE": 3, + "VERSION": 3 + }, + "LBH": { + "RF_FAIL": 2 + } + } + }, { + "station_name": "RS306C", + "total_component_errors": 41, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:46Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 14, + "RF_FAIL": 9, + "MODEM": 7, + "JITTER": 4, + "SPURIOUS": 1, + "C_SUMMATOR": 1 + }, + "LBL": { + "FLAT": 2, + "RF_FAIL": 1, + "DOWN": 1 + }, + "LBH": { + "RF_FAIL": 1 + } + } + }, { + "station_name": "RS307C", + "total_component_errors": 38, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:26Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "HIGH_NOISE": 10, + "MODEM": 9, + "JITTER": 7, + "RF_FAIL": 4, + "SPURIOUS": 1 + }, + "LBH": { + "HIGH_NOISE": 1, + "JITTER": 1, + "LOW_NOISE": 1, + "RF_FAIL": 1, + "SHORT": 1, + "DOWN": 1, + "FLAT": 1 + } + } + }, { + "station_name": "RS407C", + "total_component_errors": 3, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:30Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "MODEM": 1 + }, + "LBL": { + "HIGH_NOISE": 1 + }, + "TBB": { + "TEMPERATURE": 1 + } + } + }, { + "station_name": "RS409C", + "total_component_errors": 17, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:51:06Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "SPURIOUS": 4, + "RF_FAIL": 2, + "SUMMATOR_NOISE": 2, + "HIGH_NOISE": 1, + "JITTER": 1, + "OSCILLATION": 1 + }, + "LBH": { + "SPURIOUS": 3, + "FLAT": 1, + "DOWN": 1 + }, + "TBB": { + "MEMORY": 1 + } + } + }, { + "station_name": "RS503C", + "total_component_errors": 56, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:20Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "RF_FAIL": 17, + "HIGH_NOISE": 16, + "MODEM": 6, + "JITTER": 3, + "C_SUMMATOR": 1, + "LOW_NOISE": 1, + "SPURIOUS": 1 + }, + "LBH": { + "RF_FAIL": 2, + "DOWN": 1, + "HIGH_NOISE": 1 + }, + "LBL": { + "DOWN": 1, + "FLAT": 1, + "HIGH_NOISE": 1, + "LOW_NOISE": 1, + "RF_FAIL": 1, + "SHORT": 1 + }, + "TBB": { + "MEMORY": 1 + } + } + }, { + "station_name": "RS508C", + "total_component_errors": 2, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:16Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "LBL": { + "FLAT": 1, + "LOW_NOISE": 1 + } + } + }, { + "station_name": "RS509C", + "total_component_errors": 7, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:39Z", + "checks": "RV SPU RBC SH1 F1 D1 O1 SP1 NS1=60 S1 SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 E7 TV TBC TM", + "component_error_summary": { + "LBH": { + "FLAT": 2, + "LOW_NOISE": 1 + }, + "HBA": { + "C_SUMMATOR": 1, + "HIGH_NOISE": 1, + "MODEM": 1 + }, + "LBL": { + "FLAT": 1 + } + } + }, { + "station_name": "SE607C", + "total_component_errors": 24, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:48:55Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 S7 E7 TV TBC TM", + "component_error_summary": { + "HBA": { + "SPURIOUS": 21 + }, + "LBH": { + "RF_FAIL": 1 + }, + "RSP": { + "TEMPERATURE": 1 + }, + "TBB": { + "MEMORY": 1 + } + } + }, { + "station_name": "UK608C", + "total_component_errors": 12, + "date": "2018-10-10", + "start_datetime": "2018-10-10T20:45:00Z", + "end_datetime": "2018-10-11T00:52:29Z", + "checks": "RV SPU RBC SH3 F3 D3 O3 SP3 NS3=60 S3 M5 O5 SN5 SP5 NS5=60 S7 E7 TV TBC TM", + "component_error_summary": { + "SPU": { + "VOLTAGE": 4 + }, + "LBH": { + "RF_FAIL": 3 + }, + "TBB": { + "TEMPERATURE": 1, + "VERSION": 1, + "VOLTAGE": 1, + "MEMORY": 1 + }, + "HBA": { + "MODEM": 1 + } + } + } +]; + +export default stdata; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-styles.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-styles.css index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..11f694951bd586c630659998656216e3454533ca 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-styles.css +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-styles.css @@ -0,0 +1,93 @@ +/*.react-grid-item:not(.react-grid-placeholder) {*/ +/* COLORS */ +/* Color palette interface (created with https://material.io/tools/color/) */ +/* font color */ +/* font color */ +/* Data colors */ +.react-grid-item { + background-color: white; + border: 1px solid #e1e1e1; + border-radius: 0.25rem; } + +.react-grid-item-header { + color: #333333; + background-color: #e1e1e1; + font-weight: bold; + padding: .3rem; + /* Note: must be same as the Bootstrap table for nice alignment */ + margin-bottom: 0; + height: 2rem; } + +.react-grid-item-body { + height: calc(100% - 2rem); + overflow: auto; + position: relative; } + +.react-grid-item > .react-resizable-handle::after { + border-color: #bce8f1; } + +/* autoLoader; CSS spinner*/ +.alLoading { + position: absolute; + top: 2.25em; + /* Check with height of .react-grid-item-header */ + left: 0.25em; + border: 0.55rem solid #e1e1e1; + border-top: 0.55rem solid #8d8d8d; + border-radius: 50%; + width: 3rem; + height: 3rem; + animation: spin 2s linear infinite; } + +@keyframes spin { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } + +/* Reacstrap only support sm, md and lg */ +.btn-group-xs > .btn, +.btn.btn-xs { + padding: .25rem .5rem; + font-size: .875rem; + line-height: 1.0; + border-radius: .2rem; } + +.popover { + max-width: 40em !important; + /* Max Width of the popover (depending on the container!) */ } + +.popover-header { + text-align: center; + font-weight: 700; } + +.landing-page-toolbar { + background-color: #a7689d; + color: #ffffff; + padding: 5px 10px; + /* Note: same padding as ResponsiveGridLayout */ + width: 100%; + overflow: auto; } + +.landing-page-toolbar { + font-weight: 500; } + +.landing-page-toolbar .btn-info:not(:disabled):not(.disabled).active, +.sts-toolbar .btn-info:not(:disabled):not(.disabled).active, +.landing-page-toolbar .btn-info:not(:disabled):not(.disabled):active, +.landing-page-toolbar .show > .btn-info.dropdown-toggle { + color: white; + background-color: #8d8d8d; + border-color: #8d8d8d; } + +.landing-page-toolbar .btn-info, +.sts-toolbar .btn-info { + color: white; + background-color: #bdbdbd; + border-color: #bdbdbd; } + +.landing-page-toolbar .btn-info:hover, +.sts-toolbar .btn-info:hover { + color: white; + background-color: #8d8d8d; + border-color: #8d8d8d; } diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-styles.scss b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-styles.scss index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..879601175c1ce8c8b34e00b86eb750fe4859d300 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-styles.scss +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-styles.scss @@ -0,0 +1,103 @@ +/*.react-grid-item:not(.react-grid-placeholder) {*/ + +@import '../themes/lofar-variables.scss'; + +body { + //background-color: #E1E2E1!important; +} + +$griditem: $secondary-light; +$griditem-color: #333333; + +.react-grid-item { + background-color: white; + border: 1px solid $griditem; + border-radius: 0.25rem; +} + +.react-grid-item-header { + color: $griditem-color; + background-color: $griditem; + font-weight: bold; + padding: .3rem; /* Note: must be same as the Bootstrap table for nice alignment */ + margin-bottom: 0; + height: 2rem; +} +.react-grid-item-body { + height: calc(100% - 2rem); + overflow: auto; + position: relative; +} + +.react-grid-item > .react-resizable-handle::after { + border-color: #bce8f1; +} + +/* autoLoader; CSS spinner*/ +.alLoading { + position: absolute; + top: 2.25em; /* Check with height of .react-grid-item-header */ + left: 0.25em; + border: .55rem solid $secondary-light; + border-top: .55rem solid $secondary-dark; + border-radius: 50%; + width: 3rem; + height: 3rem; + animation: spin 2s linear infinite; +} +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + + +/* Reacstrap only support sm, md and lg */ +.btn-group-xs>.btn, +.btn.btn-xs { + padding: .25rem .5rem; + font-size: .875rem; + line-height: 1.0; + border-radius: .2rem; +} + +.popover { + max-width: 40em!important; /* Max Width of the popover (depending on the container!) */ +} +.popover-header { + text-align: center; + font-weight: 700; +} + +.landing-page-toolbar { + background-color: $primary-light; + color: $primary-color; + padding: 5px 10px; /* Note: same padding as ResponsiveGridLayout */ + width: 100%; + overflow: auto; +} + +.landing-page-toolbar { + font-weight: 500; +} +.landing-page-toolbar .btn-info:not(:disabled):not(.disabled).active, +.sts-toolbar .btn-info:not(:disabled):not(.disabled).active, +.landing-page-toolbar .btn-info:not(:disabled):not(.disabled):active, +.landing-page-toolbar .show>.btn-info.dropdown-toggle { + color: $secondary-color; + background-color: $secondary-dark; + border-color: $secondary-dark; +} + +.landing-page-toolbar .btn-info, +.sts-toolbar .btn-info { + color: $secondary-color; + background-color: $secondary; + border-color: $secondary; +} + +.landing-page-toolbar .btn-info:hover, +.sts-toolbar .btn-info:hover { + color: $secondary-color; + background-color: $secondary-dark; + border-color: $secondary-dark; +} diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-variables.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-variables.css index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6a86564eb690cdb7b435a0b3a6f0d187ef46cdaa 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-variables.css +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-variables.css @@ -0,0 +1,5 @@ +/* COLORS */ +/* Color palette interface (created with https://material.io/tools/color/) */ +/* font color */ +/* font color */ +/* Data colors */ diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-variables.scss b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-variables.scss index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e868bb8726e852d3ae6fb804313824b8a3affa28 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-variables.scss +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar-variables.scss @@ -0,0 +1,28 @@ +/* COLORS */ + + +/* Color palette interface (created with https://material.io/tools/color/) */ + +$primary: #773b6f; +$primary-light: #a7689d; +$primary-dark: #490f44; +$primary-color: #ffffff; /* font color */ + +$secondary: #bdbdbd; +$secondary-light: #e1e1e1; +$secondary-dark: #8d8d8d; +$secondary-color: white; /* font color */ + + +/* Data colors */ +$serious: #f17171; +$serious-fontcolor: white; + +$warning: #fbfb83; +$warning-fontcolor: black; + +$alarming: #ffcd74; +$alarming-fontcolor: black; + +$good: #6fbd6f; +$good-fontcolor: white; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar.css index a378b2b241be03a821317b00ab093880c5ec847c..7f9870222eebe8ac83ca5aa3280af9fe58574dc3 100644 --- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar.css +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar.css @@ -1,3 +1,8 @@ +/* COLORS */ +/* Color palette interface (created with https://material.io/tools/color/) */ +/* font color */ +/* font color */ +/* Data colors */ /*! * Bootstrap v4.1.3 (https://getbootstrap.com/) * Copyright 2011-2018 The Bootstrap Authors @@ -18,11 +23,11 @@ --white: #fff; --gray: #6c757d; --gray-dark: #343a40; - --primary: #007bff; - --secondary: #6c757d; + --primary: #773b6f; + --secondary: #bdbdbd; --success: #28a745; --info: #17a2b8; - --warning: #ffc107; + --warning: #fbfb83; --danger: #dc3545; --light: #f8f9fa; --dark: #343a40; @@ -137,12 +142,12 @@ sup { top: -.5em; } a { - color: #007bff; + color: #773b6f; text-decoration: none; background-color: transparent; -webkit-text-decoration-skip: objects; } a:hover { - color: #0056b3; + color: #44223f; text-decoration: underline; } a:not([href]):not([tabindex]) { @@ -1078,24 +1083,24 @@ pre { .table-primary, .table-primary > th, .table-primary > td { - background-color: #b8daff; } + background-color: #d9c8d7; } .table-hover .table-primary:hover { - background-color: #9fcdff; } + background-color: #cfb9cc; } .table-hover .table-primary:hover > td, .table-hover .table-primary:hover > th { - background-color: #9fcdff; } + background-color: #cfb9cc; } .table-secondary, .table-secondary > th, .table-secondary > td { - background-color: #d6d8db; } + background-color: #ededed; } .table-hover .table-secondary:hover { - background-color: #c8cbcf; } + background-color: #e0e0e0; } .table-hover .table-secondary:hover > td, .table-hover .table-secondary:hover > th { - background-color: #c8cbcf; } + background-color: #e0e0e0; } .table-success, .table-success > th, @@ -1122,13 +1127,13 @@ pre { .table-warning, .table-warning > th, .table-warning > td { - background-color: #ffeeba; } + background-color: #fefedc; } .table-hover .table-warning:hover { - background-color: #ffe8a1; } + background-color: #fdfdc3; } .table-hover .table-warning:hover > td, .table-hover .table-warning:hover > th { - background-color: #ffe8a1; } + background-color: #fdfdc3; } .table-danger, .table-danger > th, @@ -1269,9 +1274,9 @@ pre { .form-control:focus { color: #495057; background-color: #fff; - border-color: #80bdff; + border-color: #bb76b2; outline: 0; - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } + box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.25); } .form-control::placeholder { color: #6c757d; opacity: 1; } @@ -1613,7 +1618,7 @@ textarea.form-control { text-decoration: none; } .btn:focus, .btn.focus { outline: 0; - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } + box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.25); } .btn.disabled, .btn:disabled { opacity: 0.65; } .btn:not(:disabled):not(.disabled) { @@ -1625,49 +1630,49 @@ fieldset:disabled a.btn { .btn-primary { color: #fff; - background-color: #007bff; - border-color: #007bff; } + background-color: #773b6f; + border-color: #773b6f; } .btn-primary:hover { color: #fff; - background-color: #0069d9; - border-color: #0062cc; } + background-color: #5d2e57; + border-color: #552a4f; } .btn-primary:focus, .btn-primary.focus { - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.5); } .btn-primary.disabled, .btn-primary:disabled { color: #fff; - background-color: #007bff; - border-color: #007bff; } + background-color: #773b6f; + border-color: #773b6f; } .btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active, .show > .btn-primary.dropdown-toggle { color: #fff; - background-color: #0062cc; - border-color: #005cbf; } + background-color: #552a4f; + border-color: #4c2647; } .btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus, .show > .btn-primary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.5); } .btn-secondary { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; } + color: #212529; + background-color: #bdbdbd; + border-color: #bdbdbd; } .btn-secondary:hover { - color: #fff; - background-color: #5a6268; - border-color: #545b62; } + color: #212529; + background-color: #aaaaaa; + border-color: #a4a4a4; } .btn-secondary:focus, .btn-secondary.focus { - box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(189, 189, 189, 0.5); } .btn-secondary.disabled, .btn-secondary:disabled { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; } + color: #212529; + background-color: #bdbdbd; + border-color: #bdbdbd; } .btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active, .show > .btn-secondary.dropdown-toggle { - color: #fff; - background-color: #545b62; - border-color: #4e555b; } + color: #212529; + background-color: #a4a4a4; + border-color: #9d9d9d; } .btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus, .show > .btn-secondary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(189, 189, 189, 0.5); } .btn-success { color: #fff; @@ -1717,26 +1722,26 @@ fieldset:disabled a.btn { .btn-warning { color: #212529; - background-color: #ffc107; - border-color: #ffc107; } + background-color: #fbfb83; + border-color: #fbfb83; } .btn-warning:hover { color: #212529; - background-color: #e0a800; - border-color: #d39e00; } + background-color: #fafa5e; + border-color: #f9f952; } .btn-warning:focus, .btn-warning.focus { - box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(251, 251, 131, 0.5); } .btn-warning.disabled, .btn-warning:disabled { color: #212529; - background-color: #ffc107; - border-color: #ffc107; } + background-color: #fbfb83; + border-color: #fbfb83; } .btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active, .show > .btn-warning.dropdown-toggle { color: #212529; - background-color: #d39e00; - border-color: #c69500; } + background-color: #f9f952; + border-color: #f9f945; } .btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus, .show > .btn-warning.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(251, 251, 131, 0.5); } .btn-danger { color: #fff; @@ -1808,50 +1813,50 @@ fieldset:disabled a.btn { box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); } .btn-outline-primary { - color: #007bff; + color: #773b6f; background-color: transparent; background-image: none; - border-color: #007bff; } + border-color: #773b6f; } .btn-outline-primary:hover { color: #fff; - background-color: #007bff; - border-color: #007bff; } + background-color: #773b6f; + border-color: #773b6f; } .btn-outline-primary:focus, .btn-outline-primary.focus { - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.5); } .btn-outline-primary.disabled, .btn-outline-primary:disabled { - color: #007bff; + color: #773b6f; background-color: transparent; } .btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active, .show > .btn-outline-primary.dropdown-toggle { color: #fff; - background-color: #007bff; - border-color: #007bff; } + background-color: #773b6f; + border-color: #773b6f; } .btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-primary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.5); } .btn-outline-secondary { - color: #6c757d; + color: #bdbdbd; background-color: transparent; background-image: none; - border-color: #6c757d; } + border-color: #bdbdbd; } .btn-outline-secondary:hover { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; } + color: #212529; + background-color: #bdbdbd; + border-color: #bdbdbd; } .btn-outline-secondary:focus, .btn-outline-secondary.focus { - box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(189, 189, 189, 0.5); } .btn-outline-secondary.disabled, .btn-outline-secondary:disabled { - color: #6c757d; + color: #bdbdbd; background-color: transparent; } .btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active, .show > .btn-outline-secondary.dropdown-toggle { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; } + color: #212529; + background-color: #bdbdbd; + border-color: #bdbdbd; } .btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-secondary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(189, 189, 189, 0.5); } .btn-outline-success { color: #28a745; @@ -1900,27 +1905,27 @@ fieldset:disabled a.btn { box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); } .btn-outline-warning { - color: #ffc107; + color: #fbfb83; background-color: transparent; background-image: none; - border-color: #ffc107; } + border-color: #fbfb83; } .btn-outline-warning:hover { color: #212529; - background-color: #ffc107; - border-color: #ffc107; } + background-color: #fbfb83; + border-color: #fbfb83; } .btn-outline-warning:focus, .btn-outline-warning.focus { - box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(251, 251, 131, 0.5); } .btn-outline-warning.disabled, .btn-outline-warning:disabled { - color: #ffc107; + color: #fbfb83; background-color: transparent; } .btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active, .show > .btn-outline-warning.dropdown-toggle { color: #212529; - background-color: #ffc107; - border-color: #ffc107; } + background-color: #fbfb83; + border-color: #fbfb83; } .btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-warning.dropdown-toggle:focus { - box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(251, 251, 131, 0.5); } .btn-outline-danger { color: #dc3545; @@ -1993,10 +1998,10 @@ fieldset:disabled a.btn { .btn-link { font-weight: 400; - color: #007bff; + color: #773b6f; background-color: transparent; } .btn-link:hover { - color: #0056b3; + color: #44223f; text-decoration: underline; background-color: transparent; border-color: transparent; } @@ -2204,7 +2209,7 @@ input[type="button"].btn-block { .dropdown-item.active, .dropdown-item:active { color: #fff; text-decoration: none; - background-color: #007bff; } + background-color: #773b6f; } .dropdown-item.disabled, .dropdown-item:disabled { color: #6c757d; background-color: transparent; } @@ -2468,12 +2473,12 @@ input[type="button"].btn-block { opacity: 0; } .custom-control-input:checked ~ .custom-control-label::before { color: #fff; - background-color: #007bff; } + background-color: #773b6f; } .custom-control-input:focus ~ .custom-control-label::before { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(119, 59, 111, 0.25); } .custom-control-input:active ~ .custom-control-label::before { color: #fff; - background-color: #b3d7ff; } + background-color: #cc98c5; } .custom-control-input:disabled ~ .custom-control-label { color: #6c757d; } .custom-control-input:disabled ~ .custom-control-label::before { @@ -2509,34 +2514,34 @@ input[type="button"].btn-block { border-radius: 0.25rem; } .custom-checkbox .custom-control-input:checked ~ .custom-control-label::before { - background-color: #007bff; } + background-color: #773b6f; } .custom-checkbox .custom-control-input:checked ~ .custom-control-label::after { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"); } .custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before { - background-color: #007bff; } + background-color: #773b6f; } .custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E"); } .custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before { - background-color: rgba(0, 123, 255, 0.5); } + background-color: rgba(119, 59, 111, 0.5); } .custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before { - background-color: rgba(0, 123, 255, 0.5); } + background-color: rgba(119, 59, 111, 0.5); } .custom-radio .custom-control-label::before { border-radius: 50%; } .custom-radio .custom-control-input:checked ~ .custom-control-label::before { - background-color: #007bff; } + background-color: #773b6f; } .custom-radio .custom-control-input:checked ~ .custom-control-label::after { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E"); } .custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before { - background-color: rgba(0, 123, 255, 0.5); } + background-color: rgba(119, 59, 111, 0.5); } .custom-select { display: inline-block; @@ -2552,9 +2557,9 @@ input[type="button"].btn-block { border-radius: 0.25rem; appearance: none; } .custom-select:focus { - border-color: #80bdff; + border-color: #bb76b2; outline: 0; - box-shadow: 0 0 0 0.2rem rgba(128, 189, 255, 0.5); } + box-shadow: 0 0 0 0.2rem rgba(187, 118, 178, 0.5); } .custom-select:focus::-ms-value { color: #495057; background-color: #fff; } @@ -2595,10 +2600,10 @@ input[type="button"].btn-block { margin: 0; opacity: 0; } .custom-file-input:focus ~ .custom-file-label { - border-color: #80bdff; - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } + border-color: #bb76b2; + box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.25); } .custom-file-input:focus ~ .custom-file-label::after { - border-color: #80bdff; } + border-color: #bb76b2; } .custom-file-input:disabled ~ .custom-file-label { background-color: #e9ecef; } .custom-file-input:lang(en) ~ .custom-file-label::after { @@ -2641,18 +2646,18 @@ input[type="button"].btn-block { .custom-range:focus { outline: none; } .custom-range:focus::-webkit-slider-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(119, 59, 111, 0.25); } .custom-range:focus::-moz-range-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(119, 59, 111, 0.25); } .custom-range:focus::-ms-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(119, 59, 111, 0.25); } .custom-range::-moz-focus-outer { border: 0; } .custom-range::-webkit-slider-thumb { width: 1rem; height: 1rem; margin-top: -0.25rem; - background-color: #007bff; + background-color: #773b6f; border: 0; border-radius: 1rem; transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; @@ -2661,7 +2666,7 @@ input[type="button"].btn-block { .custom-range::-webkit-slider-thumb { transition: none; } } .custom-range::-webkit-slider-thumb:active { - background-color: #b3d7ff; } + background-color: #cc98c5; } .custom-range::-webkit-slider-runnable-track { width: 100%; height: 0.5rem; @@ -2673,7 +2678,7 @@ input[type="button"].btn-block { .custom-range::-moz-range-thumb { width: 1rem; height: 1rem; - background-color: #007bff; + background-color: #773b6f; border: 0; border-radius: 1rem; transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; @@ -2682,7 +2687,7 @@ input[type="button"].btn-block { .custom-range::-moz-range-thumb { transition: none; } } .custom-range::-moz-range-thumb:active { - background-color: #b3d7ff; } + background-color: #cc98c5; } .custom-range::-moz-range-track { width: 100%; height: 0.5rem; @@ -2697,7 +2702,7 @@ input[type="button"].btn-block { margin-top: 0; margin-right: 0.2rem; margin-left: 0.2rem; - background-color: #007bff; + background-color: #773b6f; border: 0; border-radius: 1rem; transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; @@ -2706,7 +2711,7 @@ input[type="button"].btn-block { .custom-range::-ms-thumb { transition: none; } } .custom-range::-ms-thumb:active { - background-color: #b3d7ff; } + background-color: #cc98c5; } .custom-range::-ms-track { width: 100%; height: 0.5rem; @@ -2778,7 +2783,7 @@ input[type="button"].btn-block { .nav-pills .nav-link.active, .nav-pills .show > .nav-link { color: #fff; - background-color: #007bff; } + background-color: #773b6f; } .nav-fill .nav-item { flex: 1 1 auto; @@ -3279,19 +3284,19 @@ input[type="button"].btn-block { padding: 0.5rem 0.75rem; margin-left: -1px; line-height: 1.25; - color: #007bff; + color: #773b6f; background-color: #fff; border: 1px solid #dee2e6; } .page-link:hover { z-index: 2; - color: #0056b3; + color: #44223f; text-decoration: none; background-color: #e9ecef; border-color: #dee2e6; } .page-link:focus { z-index: 2; outline: 0; - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } + box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.25); } .page-link:not(:disabled):not(.disabled) { cursor: pointer; } @@ -3307,8 +3312,8 @@ input[type="button"].btn-block { .page-item.active .page-link { z-index: 1; color: #fff; - background-color: #007bff; - border-color: #007bff; } + background-color: #773b6f; + border-color: #773b6f; } .page-item.disabled .page-link { color: #6c757d; @@ -3367,19 +3372,19 @@ input[type="button"].btn-block { .badge-primary { color: #fff; - background-color: #007bff; } + background-color: #773b6f; } .badge-primary[href]:hover, .badge-primary[href]:focus { color: #fff; text-decoration: none; - background-color: #0062cc; } + background-color: #552a4f; } .badge-secondary { - color: #fff; - background-color: #6c757d; } + color: #212529; + background-color: #bdbdbd; } .badge-secondary[href]:hover, .badge-secondary[href]:focus { - color: #fff; + color: #212529; text-decoration: none; - background-color: #545b62; } + background-color: #a4a4a4; } .badge-success { color: #fff; @@ -3399,11 +3404,11 @@ input[type="button"].btn-block { .badge-warning { color: #212529; - background-color: #ffc107; } + background-color: #fbfb83; } .badge-warning[href]:hover, .badge-warning[href]:focus { color: #212529; text-decoration: none; - background-color: #d39e00; } + background-color: #f9f952; } .badge-danger { color: #fff; @@ -3466,22 +3471,22 @@ input[type="button"].btn-block { color: inherit; } .alert-primary { - color: #004085; - background-color: #cce5ff; - border-color: #b8daff; } + color: #3e1f3a; + background-color: #e4d8e2; + border-color: #d9c8d7; } .alert-primary hr { - border-top-color: #9fcdff; } + border-top-color: #cfb9cc; } .alert-primary .alert-link { - color: #002752; } + color: #1c0e1a; } .alert-secondary { - color: #383d41; - background-color: #e2e3e5; - border-color: #d6d8db; } + color: #626262; + background-color: #f2f2f2; + border-color: #ededed; } .alert-secondary hr { - border-top-color: #c8cbcf; } + border-top-color: #e0e0e0; } .alert-secondary .alert-link { - color: #202326; } + color: #494949; } .alert-success { color: #155724; @@ -3502,13 +3507,13 @@ input[type="button"].btn-block { color: #062c33; } .alert-warning { - color: #856404; - background-color: #fff3cd; - border-color: #ffeeba; } + color: #838344; + background-color: #fefee6; + border-color: #fefedc; } .alert-warning hr { - border-top-color: #ffe8a1; } + border-top-color: #fdfdc3; } .alert-warning .alert-link { - color: #533f03; } + color: #616133; } .alert-danger { color: #721c24; @@ -3558,7 +3563,7 @@ input[type="button"].btn-block { color: #fff; text-align: center; white-space: nowrap; - background-color: #007bff; + background-color: #773b6f; transition: width 0.6s ease; } @media screen and (prefers-reduced-motion: reduce) { .progress-bar { @@ -3619,8 +3624,8 @@ input[type="button"].btn-block { .list-group-item.active { z-index: 2; color: #fff; - background-color: #007bff; - border-color: #007bff; } + background-color: #773b6f; + border-color: #773b6f; } .list-group-flush .list-group-item { border-right: 0; @@ -3634,26 +3639,26 @@ input[type="button"].btn-block { border-bottom: 0; } .list-group-item-primary { - color: #004085; - background-color: #b8daff; } + color: #3e1f3a; + background-color: #d9c8d7; } .list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus { - color: #004085; - background-color: #9fcdff; } + color: #3e1f3a; + background-color: #cfb9cc; } .list-group-item-primary.list-group-item-action.active { color: #fff; - background-color: #004085; - border-color: #004085; } + background-color: #3e1f3a; + border-color: #3e1f3a; } .list-group-item-secondary { - color: #383d41; - background-color: #d6d8db; } + color: #626262; + background-color: #ededed; } .list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus { - color: #383d41; - background-color: #c8cbcf; } + color: #626262; + background-color: #e0e0e0; } .list-group-item-secondary.list-group-item-action.active { color: #fff; - background-color: #383d41; - border-color: #383d41; } + background-color: #626262; + border-color: #626262; } .list-group-item-success { color: #155724; @@ -3678,15 +3683,15 @@ input[type="button"].btn-block { border-color: #0c5460; } .list-group-item-warning { - color: #856404; - background-color: #ffeeba; } + color: #838344; + background-color: #fefedc; } .list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus { - color: #856404; - background-color: #ffe8a1; } + color: #838344; + background-color: #fdfdc3; } .list-group-item-warning.list-group-item-action.active { color: #fff; - background-color: #856404; - border-color: #856404; } + background-color: #838344; + border-color: #838344; } .list-group-item-danger { color: #721c24; @@ -4278,20 +4283,20 @@ button.close { vertical-align: text-top !important; } .bg-primary { - background-color: #007bff !important; } + background-color: #773b6f !important; } a.bg-primary:hover, a.bg-primary:focus, button.bg-primary:hover, button.bg-primary:focus { - background-color: #0062cc !important; } + background-color: #552a4f !important; } .bg-secondary { - background-color: #6c757d !important; } + background-color: #bdbdbd !important; } a.bg-secondary:hover, a.bg-secondary:focus, button.bg-secondary:hover, button.bg-secondary:focus { - background-color: #545b62 !important; } + background-color: #a4a4a4 !important; } .bg-success { background-color: #28a745 !important; } @@ -4310,12 +4315,12 @@ button.bg-info:focus { background-color: #117a8b !important; } .bg-warning { - background-color: #ffc107 !important; } + background-color: #fbfb83 !important; } a.bg-warning:hover, a.bg-warning:focus, button.bg-warning:hover, button.bg-warning:focus { - background-color: #d39e00 !important; } + background-color: #f9f952 !important; } .bg-danger { background-color: #dc3545 !important; } @@ -4378,10 +4383,10 @@ button.bg-dark:focus { border-left: 0 !important; } .border-primary { - border-color: #007bff !important; } + border-color: #773b6f !important; } .border-secondary { - border-color: #6c757d !important; } + border-color: #bdbdbd !important; } .border-success { border-color: #28a745 !important; } @@ -4390,7 +4395,7 @@ button.bg-dark:focus { border-color: #17a2b8 !important; } .border-warning { - border-color: #ffc107 !important; } + border-color: #fbfb83 !important; } .border-danger { border-color: #dc3545 !important; } @@ -6182,16 +6187,16 @@ button.bg-dark:focus { color: #fff !important; } .text-primary { - color: #007bff !important; } + color: #773b6f !important; } a.text-primary:hover, a.text-primary:focus { - color: #0062cc !important; } + color: #552a4f !important; } .text-secondary { - color: #6c757d !important; } + color: #bdbdbd !important; } a.text-secondary:hover, a.text-secondary:focus { - color: #545b62 !important; } + color: #a4a4a4 !important; } .text-success { color: #28a745 !important; } @@ -6206,10 +6211,10 @@ a.text-info:hover, a.text-info:focus { color: #117a8b !important; } .text-warning { - color: #ffc107 !important; } + color: #fbfb83 !important; } a.text-warning:hover, a.text-warning:focus { - color: #d39e00 !important; } + color: #f9f952 !important; } .text-danger { color: #dc3545 !important; } @@ -6311,3 +6316,97 @@ a.text-dark:hover, a.text-dark:focus { .table .thead-dark th { color: inherit; border-color: #dee2e6; } } + +/*.react-grid-item:not(.react-grid-placeholder) {*/ +/* COLORS */ +/* Color palette interface (created with https://material.io/tools/color/) */ +/* font color */ +/* font color */ +/* Data colors */ +.react-grid-item { + background-color: white; + border: 1px solid #e1e1e1; + border-radius: 0.25rem; } + +.react-grid-item-header { + color: #333333; + background-color: #e1e1e1; + font-weight: bold; + padding: .3rem; + /* Note: must be same as the Bootstrap table for nice alignment */ + margin-bottom: 0; + height: 2rem; } + +.react-grid-item-body { + height: calc(100% - 2rem); + overflow: auto; + position: relative; } + +.react-grid-item > .react-resizable-handle::after { + border-color: #bce8f1; } + +/* autoLoader; CSS spinner*/ +.alLoading { + position: absolute; + top: 2.25em; + /* Check with height of .react-grid-item-header */ + left: 0.25em; + border: 0.55rem solid #e1e1e1; + border-top: 0.55rem solid #8d8d8d; + border-radius: 50%; + width: 3rem; + height: 3rem; + animation: spin 2s linear infinite; } + +@keyframes spin { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } + +/* Reacstrap only support sm, md and lg */ +.btn-group-xs > .btn, +.btn.btn-xs { + padding: .25rem .5rem; + font-size: .875rem; + line-height: 1.0; + border-radius: .2rem; } + +.popover { + max-width: 40em !important; + /* Max Width of the popover (depending on the container!) */ } + +.popover-header { + text-align: center; + font-weight: 700; } + +.landing-page-toolbar { + background-color: #a7689d; + color: #ffffff; + padding: 5px 10px; + /* Note: same padding as ResponsiveGridLayout */ + width: 100%; + overflow: auto; } + +.landing-page-toolbar { + font-weight: 500; } + +.landing-page-toolbar .btn-info:not(:disabled):not(.disabled).active, +.sts-toolbar .btn-info:not(:disabled):not(.disabled).active, +.landing-page-toolbar .btn-info:not(:disabled):not(.disabled):active, +.landing-page-toolbar .show > .btn-info.dropdown-toggle { + color: white; + background-color: #8d8d8d; + border-color: #8d8d8d; } + +.landing-page-toolbar .btn-info, +.sts-toolbar .btn-info { + color: white; + background-color: #bdbdbd; + border-color: #bdbdbd; } + +.landing-page-toolbar .btn-info:hover, +.sts-toolbar .btn-info:hover { + color: white; + background-color: #8d8d8d; + border-color: #8d8d8d; } diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/autoLoader.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/autoLoader.js new file mode 100644 index 0000000000000000000000000000000000000000..953aff966014dfd194cd03bf0af26b3b426e40ee --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/autoLoader.js @@ -0,0 +1,111 @@ +import React from 'react'; +import axios from 'axios'; + + + +function AutoLoadWrapper(WrappedComponent) { + + // Note: returns another component + return class extends React.Component { + + _intervalId = null; + _source = undefined; + + state = { + data: [], + isLoading: false, + prevUrl: null + } + + static defaultProps = { + reloadInterval: 60000, + url: '' + } + + /* Called when props changed, before the render phase */ + static getDerivedStateFromProps(props, state) { + // Store prevUrl in state so we can compare when props change. + if (props.url !== state.prevUrl) { + return { + isLoading: true, + prevUrl: props.url + }; + } + + // No state update necessary + return null; + } + + fetchData() { + + // Set loading state + if (! this.state.isLoading) { + this.setState({ + isLoading: true + }); + } + + // Create cancellation token + if (typeof this._source !== typeof undefined) { + this._source.cancel('Operation canceled due to new request.') + } + this._source = axios.CancelToken.source(); + + // Handle the request + axios.get(this.props.url, { + cancelToken: this._source.token + }).then(res => { + this.setState({ + data: res.data, + isLoading: false + }); + }).catch(error => { + if (axios.isCancel(error)) { + console.log('Request canceled: ', error); + } + else { + // TODO render + console.log(error); + this.setState({ + isLoading: false + }); + } + }).then(() => { + // do always + this._source = undefined; + }); + } + + componentDidMount() { + this.fetchData(); + this._intervalId = setInterval(() => this.fetchData(), this.props.reloadInterval); + } + + componentDidUpdate(prevProps, prevState) { + if (prevProps.url !== this.props.url) { + this.fetchData(); + } + } + + componentWillUnmount() { + clearInterval(this._intervalId); + } + + render() { + let loadingHtml = ""; + if (this.state.isLoading) { + loadingHtml = <div className="alLoading"></div>; + } + + return( + <React.Fragment> + {loadingHtml} + <WrappedComponent data={this.state.data} {...this.props} /> + </React.Fragment> + ); + } + }; +} + + +export default AutoLoadWrapper; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/constants.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/constants.js new file mode 100644 index 0000000000000000000000000000000000000000..a452dac62841bf3466263c34359f0e574147074f --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/constants.js @@ -0,0 +1,26 @@ + +// List of known component error types and their abbreviations +const componentErrorTypes = { + "BOARD": "BD", + "C_SUMMATOR": "CS", + "CHECKSRV": "CK", + "DOWN": "DW", + "FLAT": "FL", + "HIGH_NOISE": "HN", + "JITTER": "JI", + "LOW_NOISE": "LN", + "MEMORY": "MY", + "MODEM": "MO", + "NOSIGNAL": "NS", + "OSCILLATION": "OS", + "P_SUMMATOR": "PS", + "RF_FAIL": "RF", + "SHORT": "SH", + "SPURIOUS": "SP", + "SUMMATOR_NOISE":"SM", + "TEMPERATURE": "TE", + "VERSION": "VS", + "VOLTAGE": "VO" +}; + +export { componentErrorTypes }; diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/utils.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..638bec56e69ad61d97d0158f77363f1846408730 --- /dev/null +++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/utils.js @@ -0,0 +1,20 @@ +let lastId = 0; + +function unique_id(prefix='id_') { + lastId++; + return `${prefix}${lastId}`; +} + +function capitalize(s) { + if (typeof s !== 'string') return '' + return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase() +} + +export function composeQueryString(params) { + const parametersString = Object.keys(params).map((key) => { + return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]) + }).join('&'); + return `${parametersString}`; +} + +export { unique_id, capitalize };