diff --git a/.gitattributes b/.gitattributes
index 7973fabe8edf96baab4547c0d274c2a01735efba..803896696012fed33d039cf2bf56830c365ef839 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1850,6 +1850,9 @@ 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/AntennaErrorDetails.js -text
+LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/AntennaView.js -text
+LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/FillHeight.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
@@ -1875,6 +1878,9 @@ LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestSummary
 LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.css -text
 LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.js -text
 LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.scss -text
+LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/Toolbar.css -text
+LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/Toolbar.js -text
+LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/Toolbar.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
@@ -1888,10 +1894,12 @@ 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/antennaOverviewPageActions.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/actions/stationOverviewPageActions.js -text
+LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/antennaOverviewPageReducers.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
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/package.json b/LCU/Maintenance/MDB_WebView/maintenancedb_view/package.json
index bce306cf061e0de8f8ccc62e0ae452dc73d1b6ba..a4b265d0ed88957d46673e0264bf645c02271674 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/package.json
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/package.json
@@ -39,11 +39,12 @@
     "react-sticky": "^6.0.3",
     "react-table": "^6.8.6",
     "react-table-container": "^2.0.1",
+    "react-treeview": "^0.4.7",
     "react-vega-lite": "^2.0.2",
     "reactstrap": "^6.3.1",
     "redux": "^4.0.1",
     "redux-thunk": "^2.3.0",
-    "vega": "^4.3.0",
+    "vega": "^4.4.0",
     "vega-lite": "^2.6.0",
     "vega-tooltip": "^0.13.0"
   },
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/App.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/App.js
index 584a61eb5158a326e8e55743d1afc0d76cf1855d..5c4c238b5b2a2972d80a129fb1112b7519637c69 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/App.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/App.js
@@ -33,7 +33,7 @@ class AppC extends Component {
                 <Switch>
                     <Route exact path="/" component={LandingPage}/>
                     <Route path="/station_overview/:name?" component={StationOverviewPage}/>
-                    <Route exact path="/tiles" component={TilesPage}/>
+                    <Route exact path="/tiles/:antenna?" component={TilesPage}/>
                     <Route exact path="/details" component={DetailsPage}/>
                 </Switch>
             </div>
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/AntennaErrorDetails.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/AntennaErrorDetails.js
new file mode 100644
index 0000000000000000000000000000000000000000..c0766214a0e77550525a9f0c3d37b1c9cde89ca5
--- /dev/null
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/AntennaErrorDetails.js
@@ -0,0 +1,248 @@
+import React, {
+    Component
+} from 'react';
+import TreeView from 'react-treeview';
+import 'react-treeview/react-treeview.css';
+import moment from 'moment';
+import {
+    Button,
+    Modal,
+    ModalHeader,
+    ModalBody,
+    Card,
+    CardSubtitle,
+    CardBody,
+    Container,
+    Row,
+    Col
+} from 'reactstrap';
+import { IoMdCloseCircleOutline as CloseIcon} from 'react-icons/io';
+import {pinAntennaError, selectAntennaError} from '../redux/actions/antennaOverviewPageActions';
+import {LOFARTESTS} from '../utils/LOFARDefinitions';
+import {datetime_format} from '../utils/constants';
+import {connect} from "react-redux";
+
+
+class ModalPicture extends Component {
+
+    state = {
+        modal: false,
+        modalUrl: ''
+    };
+
+    toggleModal = (e) => {
+        this.setState({
+            modal: !this.state.modal,
+            modalUrl: e.currentTarget.src
+        });
+    };
+
+    onImgError = (e) => {
+        const img = e.currentTarget;
+        img.alt = 'Reloading in 2 sec..';
+        // let the window figure out if the timeout id is still valid
+        if(this.timeout){
+            clearTimeout(this.timeout);
+        }
+        this.timeout = setTimeout(() => { img.src = img.src; }, 2000 );
+    };
+
+    clearTimeouts() {
+        clearTimeout(this.timeout);
+        this.timeout = null;
+    }
+
+    render(){
+        this.clearTimeouts();
+        return (
+            <React.Fragment>
+                <img src={this.props.url} onClick={this.toggleModal} onError={this.onImgError} title="Click to enlarge" alt="Not present"/>
+                <Modal isOpen={this.state.modal} fade={false} size="lg" toggle={this.toggle} className={this.props.className}>
+                  <ModalHeader toggle={this.toggleModal}></ModalHeader>
+                  <ModalBody>
+                    <img style={{width: '100%'}} src={this.state.modalUrl} alt="Not present" />
+                  </ModalBody>
+                </Modal>
+            </React.Fragment>
+        );
+    }
+}
+
+class AntennaErrorDetailsC extends Component {
+
+    composeTitle(){
+        const test_type = LOFARTESTS[this.props.test_type];
+        let title = "Error details";
+        if(this.props.test_type !== undefined){
+            title = `${test_type}: ${this.props.error_type} Antenna: ${this.props.antennaId} Date: ${moment(this.props.start_date).format(datetime_format)}`;
+            if(this.props.element_id) title += `\t Element: ${this.props.element_id}`;
+        }
+        return title
+    }
+
+    static renderDetails(details){
+        if(details === undefined) return;
+
+        const details_lines = [];
+        if(details === Object(details)){
+            for(let entity_name of Object.keys(details)){
+                if(details.hasOwnProperty(entity_name)){
+                    const element = details[entity_name];
+                    const children = this.renderDetails(details[entity_name]);
+
+                    if(element === Object(element)){
+                        details_lines.push(<TreeView key={entity_name} nodeLabel={entity_name}>{children}</TreeView>)
+                    }else{
+                        details_lines.push(<div key={entity_name}> {entity_name}: <em>{children}</em></div>)
+                    }
+                }
+            }
+            return (
+                <React.Fragment>
+                    {details_lines.length? details_lines: undefined}
+                </React.Fragment>
+            );
+        }else{
+            return (
+                <React.Fragment>
+                    {details}
+                </React.Fragment>
+            );
+        }
+    }
+
+    unpinPanel = () => {
+        this.props.pinAntennaError(!this.props.isPinned);
+        this.props.selectAntennaError({});
+    };
+
+    renderElementErrors(){
+        if(this.props.content.element_errors === undefined) return;
+
+        const element_errors = this.props.content.element_errors;
+        const rendered_element_errors = [];
+        for(let element_id of Object.keys(element_errors)){
+            const element_error = (
+                        <TreeView key={element_id} nodeLabel={element_id}>{AntennaErrorDetailsC.renderDetails(element_errors[element_id])}</TreeView>
+            );
+            rendered_element_errors.push(element_error)
+        }
+        return (
+            <React.Fragment>
+                    {rendered_element_errors}
+            </React.Fragment>
+        );
+    }
+
+    renderRTSMPolarizationDetails(polarization){
+        const RTSMPerPolarization = this.props.content[polarization];
+        if(RTSMPerPolarization === undefined) return;
+        return (
+            <Card>
+                <CardBody>
+                <CardSubtitle className="stcv-header">
+                    RCU {RTSMPerPolarization.rcu} - {polarization}
+                </CardSubtitle>
+
+                <Container>
+                    <Row>
+                    <Col>
+                    <Row>
+                        <div>percentage: {RTSMPerPolarization.percentage.toFixed(2)} %</div>
+                    </Row>
+                    <Row>
+                        <div>mode: {RTSMPerPolarization.mode}</div>
+                    </Row>
+                    </Col>
+                    <Col>
+                    <div style={{width: "20em"}}><ModalPicture url={RTSMPerPolarization.url} /></div>
+                    </Col>
+                    </Row>
+                </Container>
+                </CardBody>
+            </Card>
+        );
+    }
+
+    renderRTSMDetails(){
+        if (this.props.hasOwnProperty('test_type') && this.props.test_type === 'S') return;
+        return (
+            <React.Fragment>
+            {this.renderRTSMPolarizationDetails('X')}
+            {this.renderRTSMPolarizationDetails('Y')}
+            </React.Fragment>
+        )
+
+    }
+
+    renderSTDetails(){
+        if (this.props.hasOwnProperty('test_type') && this.props.test_type === 'R') return;
+        const detailsFragment = (
+            <TreeView nodeLabel="details">
+                    {AntennaErrorDetailsC.renderDetails(this.props.content.details)}
+            </TreeView>
+        );
+        const elementsFragment = (
+            <TreeView nodeLabel="elements">
+                {this.renderElementErrors()}
+            </TreeView>
+        );
+        const elementErrors = this.props.content.element_errors;
+        return (
+            <React.Fragment>
+                {this.props.content.hasOwnProperty('details')? detailsFragment: undefined}
+                {elementErrors  !== undefined && Object.keys(elementErrors).length > 0? elementsFragment: undefined}
+            </React.Fragment>
+        );
+    }
+
+    static renderEmptyContent(){
+        return (
+            <div>
+                <i>Hover the mouse over an error to view the details. Right-click on the error to pin it on this panel.</i>
+            </div>);
+    }
+
+    renderContent(){
+        if(this.props.test_type === undefined) return AntennaErrorDetailsC.renderEmptyContent();
+        let jsx;
+        switch(this.props.test_type){
+            case 'S':
+                jsx = this.renderSTDetails();
+                break;
+            case 'R':
+                jsx = this.renderRTSMDetails();
+                break;
+        }
+        return (
+            <React.Fragment>
+                    {jsx}
+            </React.Fragment>
+        );
+    }
+    render(){
+        const title = this.composeTitle();
+        let unpinButton = "";
+        if (this.props.isPinned) {
+            unpinButton = <Button title="Click to unpin the error details" color="info" size="xs" style={{float:'right'}} onClick={this.unpinPanel}>
+                            <CloseIcon/>&nbsp;unpin
+                          </Button>
+        }
+        return (
+            <div className="stcv">
+                <div className="stcv-header">{title} {unpinButton}</div>
+                {this.renderContent()}
+            </div>)
+    }
+}
+
+const AntennaErrorDetails = connect(state => {
+    return {
+        ...state.antenna_page.child_panel,
+        ...state.antenna_page.main_panel.antenna_error_data,
+        ...state.mainFilters
+    };
+},{pinAntennaError, selectAntennaError})(AntennaErrorDetailsC);
+
+
+export default AntennaErrorDetails;
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/AntennaView.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/AntennaView.js
new file mode 100644
index 0000000000000000000000000000000000000000..9fe8768a0c929773dda40cf8ad24fb8f23a9e4ef
--- /dev/null
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/AntennaView.js
@@ -0,0 +1,352 @@
+import React, {
+    Component
+} from 'react';
+
+import ReactTableContainer from 'react-table-container';
+import AutoLoadWrapper from '../utils/autoLoader.js';
+import {connect} from 'react-redux';
+import {componentErrorTypes, datetime_format} from "../utils/constants.js";
+import moment from 'moment';
+import { IoMdArrowDropdown as DropDownIcon} from 'react-icons/io';
+
+import {selectAntennaError, pinAntennaError} from '../redux/actions/antennaOverviewPageActions';
+import {renderDateRange} from '../utils/utils';
+
+import classnames from 'classnames';
+
+// CSS
+import './StationOverview.scss';
+import './StationTestView.scss';
+import FillHeight from './FillHeight.js';
+
+
+class GenericStatusC extends Component {
+
+    mouseOver = () => {
+        if (this.props.data !== undefined && this.props.isPinned === false) {
+            this.props.selectAntennaError(this.props.data);
+        }
+    }
+
+    mouseOut = () => {
+        if (this.props.data !== undefined && this.props.isPinned === false) {
+            this.props.selectAntennaError({});
+        }
+    }
+
+    renderStationTest() {
+        const label = this.props.isGood ? '' : 'X';
+        return (<React.Fragment>{label}</React.Fragment>);
+    }
+
+    renderRTSM() {
+        const xPolStyle = {
+            float: 'left',
+            position: 'relative',
+            top: '-0.3rem'
+        };
+        const yPolStyle = {
+            float: 'right',
+            position: 'relative',
+            right: '0.rem',
+            bottom: '-.2rem'
+        };
+
+
+        const xPol = (
+            <div style={xPolStyle} key={'X'}>X</div>
+        );
+        const yPol = (
+            <div style={yPolStyle} key={'Y'}>Y</div>
+        );
+        let presentErrors = [];
+        const errorsPerPolarization = this.props.data.content;
+        if (errorsPerPolarization.hasOwnProperty('X')) presentErrors.push(xPol);
+        if (errorsPerPolarization.hasOwnProperty('Y')) presentErrors.push(yPol);
+
+        return <div>{presentErrors}</div>;
+    }
+
+    renderError() {
+        switch (this.props.data.test_type) {
+            case 'R':
+                return this.renderRTSM();
+            case 'S':
+                return this.renderStationTest();
+            default:
+                return
+        }
+    }
+
+    onContextMenu = (e) => {
+        e.preventDefault();
+        if (this.props.data !== undefined) {
+            this.props.selectAntennaError(this.props.data);
+            this.props.pinAntennaError(true);
+        }
+    }
+
+    render() {
+
+        const color = this.props.isGood ? "so-good" : "so-serious";
+        const label = this.props.isGood ? "" : this.renderError();
+        return (
+            <td className={"stv-component-status " + color}
+                onContextMenu={this.onContextMenu}
+                onMouseOver={this.mouseOver}
+                onMouseOut={this.mouseOut}>
+                {label}
+            </td>);
+    }
+}
+
+// TestLine is connected to Redux store
+const GenericStatus = connect(state => {
+    return {
+        ...state.antenna_page.main_panel,
+        ...state.antenna_page.child_panel
+    };
+}, {
+    selectAntennaError,
+    pinAntennaError
+})(GenericStatusC);
+
+
+class AntennaErrorLineC extends Component {
+
+    state = {
+        isCollapsed: true
+    }
+
+    static composeHeaderLine(data) {
+        return (<React.Fragment>
+            <th>{data.test_type}</th>
+            <th>{moment(data.start_date).format(datetime_format)}</th>
+        </React.Fragment>);
+    }
+
+    
+
+    composeTestLine(data) {
+        let line = [];
+        let element = {};
+        let component_errors;
+        component_errors = data.component_errors;
+
+        for (let i = 0; i < this.props.errorTypes.length; i++) {
+            const error_type = this.props.errorTypes[i];
+            if (component_errors && component_errors.hasOwnProperty(error_type)) {
+                const component_errors_per_type = component_errors[error_type];
+
+                if (component_errors_per_type.hasOwnProperty('element_errors')) {
+                    for (let element_id of Object.keys(component_errors_per_type.element_errors)) {
+                        if (!element.hasOwnProperty(element_id)) element[element_id] = [];
+                        element[element_id].push({
+                            'error type': error_type,
+                            'content': component_errors_per_type.element_errors[element_id]
+                        })
+                    }
+                }
+                line.push(<GenericStatus isGood={false}
+                                         key={i} data={{
+                    test_type: data.test_type,
+                    start_date: data.start_date,
+                    end_date:  data.end_date,
+
+                    error_type: error_type,
+                    content: component_errors_per_type
+                }}/>)
+            } else {
+                line.push(<GenericStatus key={i} isGood={true}/>)
+            }
+
+
+        }
+        line.push(<td key="space"></td>);
+        for (let i = 1; i <= 16; i++) {
+            if (element.hasOwnProperty(i)) {
+                const errorType = element[i].length > 1 ? 'Multiple': element[i][0]['error type'];
+                const elementErrors = {};
+                elementErrors['details'] = {};
+                if(element[i].length > 1){
+                    for(const key in element[i]){
+                        elementErrors.details[`Error #${key}`] = element[i][key]
+                    }
+                }else{
+                    elementErrors.details = {...element[i][0]}
+                }
+
+                line.push(<GenericStatus key={`element${i}`} isGood={false}
+                                         data={
+                                             {
+                                                 test_type: data.test_type,
+                                                 start_date: data.start_date,
+                                                 end_date:  data.end_date,
+                                                 error_type: errorType,
+                                                 element_id: i,
+                                                 content: elementErrors
+                                             }
+                                         }/>);
+
+            } else if (this.props.data.test_type === 'S') {
+                line.push(<GenericStatus key={`element${i}`} isGood={true}/>);
+            }
+        }
+
+        return line
+    }
+
+    dropdownClick = () => {
+        this.setState({isCollapsed: !this.state.isCollapsed})
+        this.props.update()
+    }
+
+    renderCollapsedLine() {
+        const errorTypes = this.props.errorTypes;
+        const errors = this.props.data;
+        const totalNumberOfErrors = errors.length;
+        const timeSpan = renderDateRange(errors);
+        const summary = {};
+        for (const type of errorTypes) {
+            for (const error of errors) {
+                if (error.component_errors.hasOwnProperty(type)) {
+                    if (!summary.hasOwnProperty(type)) summary[type] = 0.;
+                    summary[type] += 1.;
+                }
+            }
+        }
+        const summaryItems = errorTypes.map(item => {
+            if (summary.hasOwnProperty(item)) {
+                return <td key={`element-${item}`}
+                           className="stv-rtsm-summary-badge">{(summary[item] * 100 / totalNumberOfErrors).toFixed(0)}%</td>
+            } else {
+                return <td key={`element-${item}`}></td>
+            }
+        });
+        const dropdownClass = classnames('dropdownbutton', {'dropdownbutton-up': !this.state.isCollapsed});
+        return <tr className={'stv-rtsm-summary-row'}>
+            <td >R</td>
+            <td onClick={this.dropdownClick}>{timeSpan}
+            <DropDownIcon className={dropdownClass}/>
+            </td>
+            {summaryItems}</tr>
+    }
+
+    renderAllLines() {
+        return this.props.data.map((test, id) =>
+            <tr key={id}>{AntennaErrorLineC.composeHeaderLine(test)}{this.composeTestLine(test)}</tr>);
+
+    }
+
+    renderMultilineSummary() {
+
+        const summaryLine = this.renderCollapsedLine();
+        let additionalLines;
+        if (!this.state.isCollapsed) {
+            additionalLines = this.renderAllLines();
+        }
+        return <React.Fragment>{summaryLine}{additionalLines}</React.Fragment>
+    }
+
+    render() {
+        const data = this.props.data;
+        if (data.hasOwnProperty('test_type')) {
+            return <React.Fragment>
+                <tr>{AntennaErrorLineC.composeHeaderLine(data)}{this.composeTestLine(data)}</tr>
+            </React.Fragment>;
+        } else {
+            return <React.Fragment>{this.renderMultilineSummary()}</React.Fragment>;
+        }
+    }
+}
+
+const AntennaErrorLine = connect(state => {
+    return {
+        ...state.mainFilters,
+        ...state.appInitData
+    };
+})(AntennaErrorLineC);
+
+
+class AntennaViewC extends Component {
+
+    renderHeader() {
+        const errors_columns = this.props.errorTypes.map((error_type, key) => {
+            return (<td key={key} title={error_type}>{componentErrorTypes[error_type]}</td>)
+        });
+
+        const element_ids = [];
+        for (let i = 1; i <= 16; i++) element_ids.push(<td key={i}>{i}</td>);
+        return <tr>
+            <th title="Test type">T</th>
+            <th style={{width: "10em"}}>Date</th>
+            {errors_columns}
+            <th></th>
+            {element_ids}
+        </tr>;
+    };
+
+    static groupData(data) {
+        let grouped = [];
+        let group = [];
+        for (let test of data) {
+
+            if (test.test_type !== 'R') {
+                if (group.length > 0) {
+                    grouped.push(group);
+                    group = [];
+                }
+                grouped.push(test)
+            } else {
+                group.push(test)
+            }
+        }
+        if (group.length > 0) grouped.push(group);
+
+        return grouped
+    }
+
+    updateIfContentChanges = () => {
+        this.setState({state:this.state})
+    }
+
+    renderBody() {
+        if (this.props.data.hasOwnProperty('errors')) {
+            let groupedData = AntennaViewC.groupData(this.props.data.errors);
+            return groupedData.map((test, id) => <AntennaErrorLine key={id} data={test} update={this.updateIfContentChanges}/>);
+        }
+
+
+    }
+
+    render() {
+        
+        const jsx = (
+            <ReactTableContainer width="100%" height={this.props.height+'px'}>
+                <table className="stv-table table-sm table-hover table-bordered">
+                    <thead className={"stv-tableheader"} >{this.renderHeader()}</thead>
+                    <tbody>{this.renderBody()}</tbody>
+                </table>
+            </ReactTableContainer>
+        );
+        return jsx;
+    }
+}
+
+const AntennaViewContent = function(props){
+    return (
+        <FillHeight className="border-right">
+           { ({height}) => <AntennaViewC  {...props} height={height} />}
+        </FillHeight>
+    )
+}
+
+const AntennaViewController = connect(state => {
+    return {
+        ...state.mainFilters,
+        ...state.appInitData
+    };
+})(AntennaViewContent);
+const AntennaView = AutoLoadWrapper(AntennaViewController);
+
+export default AntennaView;
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/FillHeight.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/FillHeight.js
new file mode 100644
index 0000000000000000000000000000000000000000..f36a94934af6d9cc28eaf3c7986d37549a94afbb
--- /dev/null
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/FillHeight.js
@@ -0,0 +1,88 @@
+import React from "react";
+
+/*
+ * FillHeight: Creates a div that fills the remaining height of the viewport.
+ * Window resize is monitored to scale the div accordingly.
+ *
+ * This component uses the 'render prop' pattern where the 'children' prop is used
+ * as the render function. The height of the div (in an object) is passed to
+ * the function for use by subcomponents. E.g.:
+ *
+ *  <FillHeight>
+ *      { (props) => <MyComponent hgt={props.height} /> }
+ *  </FillHeight>
+ */
+class FillHeight extends React.Component {
+
+    static defaultProps = {
+        className: 'fill-height-container',  // classname for the container div
+        gutterBottom: 10,  // px, leave some space at the bottom
+        minHeight: 200     // px, minimum height
+    };
+
+    state = {
+        height: 500        // px, height of the container div
+    };
+
+    node = null;           // internal ref to the DOM node (div)
+    mounted = false;       // bool
+    resizeTimeout = null;  // throttling of render during resize
+
+
+    componentDidMount() {
+        this.mounted = true;
+
+        window.addEventListener("resize", () => {
+            window.clearTimeout(this.resizeTimeout);
+            this.resizeTimeout = window.setTimeout(this.onWindowResize, 200);
+        });
+
+        // force a render now that it has been mounted
+        // (the offset is known at this point)
+        this.onWindowResize();
+    }
+
+    componentWillUnmount() {
+        this.mounted = false;
+        window.removeEventListener("resize", this.onWindowResize);
+    }
+
+    onWindowResize = () => {
+        if (!this.mounted || !this.node) {
+            return;
+        }
+
+        let offset = this.node.getBoundingClientRect().top;
+        let height = window.innerHeight - offset - this.props.gutterBottom;
+        if (height < this.props.minHeight) {
+            height = this.props.minHeight;
+        }
+
+        this.setState({
+            height
+        });
+    };
+
+    getNodeRef = (node) => {
+        this.node = node;
+    }
+
+    render() {
+        // Create a simple div for measuring the viewport offset when it mounts,
+        // then re-render.
+        if (!this.mounted) {
+            return (
+                <div ref={this.getNodeRef} />
+            );
+        }
+
+        // Render prop pattern; pass height to child render function
+        return (
+            <div ref={this.getNodeRef} className={this.props.className} style={{height: this.state.height+'px'}}>
+                { this.props.children({height: this.state.height}) }
+            </div>
+        );
+    }
+};
+
+export default FillHeight;
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.css
index 3ec2c0158b7b87ed251af31b361753b754e2e02c..5621f63474414e48e745aa3863172fe5abd38c11 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.css
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.css
@@ -4,7 +4,7 @@
 /* font color */
 /* Data colors */
 .hoverable:hover {
-  background-color: #bdbdbd; }
+  background-color: #b6b6ba; }
 
 .table-wrapper {
   width: 10em;
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/MultiSelectDropdown.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/MultiSelectDropdown.js
index ddebb174766ae830b7a371eadc6cddabf54f3b67..75e0d715aadf3c486551d3a3f7065aa0842c246d 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/MultiSelectDropdown.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/MultiSelectDropdown.js
@@ -10,18 +10,19 @@ class SelectableOption extends Component {
         const selectMark = this.props.isSelected ? <IsSelectIcon style={{width:'1rem'}} /> : <div style={{paddingRight:'1rem'}}/>;
         const jsx = (
             <DropdownItem onClick={this.selectedItem} >
+                <table><tbody>
                 <tr style={{position:'relative', left: '-1rem'}}>
                 <td>{selectMark}</td>
-                <td>{this.props.children}</td></tr>
+                <td>{this.props.children}</td></tr></tbody></table>
             </DropdownItem>
-        )
+        );
         return jsx
     }
 }
 
 export class MultiSelectDropdown extends Component{
     constructor(props){
-        super(props)
+        super(props);
 
         this.state = {
             isOpen: false,
@@ -79,7 +80,7 @@ export class MultiSelectDropdown extends Component{
 
     isItemSelected = (e) => {
         if(this.state.selectedItems.hasOwnProperty(e))
-            return this.state.selectedItems[e]
+            return this.state.selectedItems[e];
         return false
     }
 
@@ -89,7 +90,7 @@ export class MultiSelectDropdown extends Component{
         if(this.props.selectedItems === undefined) return
         for(let item of this.props.selectedItems){
             if(!selectedItems.hasOwnProperty(item) || !selectedItems[item] ){
-                selectedItems[item] = true
+                selectedItems[item] = true;
                 update = true
             }
         }
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationAutoComplete.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationAutoComplete.css
index d76b043672b29789d9e5849176b2f0e51358b4c5..b7172e7d24fd1e8a071985ffb4592b35bc7f0e36 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationAutoComplete.css
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationAutoComplete.css
@@ -7,13 +7,18 @@
   position: relative;
   display: inline-block; }
 
+.react-autosuggest__container svg {
+  font-size: 1.2rem; }
+
+.react-autosuggest__container button.btn.btn-info {
+  padding: .25rem .3rem; }
+
 /*
 .react-autosuggest__input {
 }
 */
-.react-autosuggest__container--open .react-autosuggest__input {
-  border-bottom-left-radius: 0;
-  border-bottom-right-radius: 0; }
+.react-autosuggest__container .react-autosuggest__input {
+  border-radius: 0; }
 
 .react-autosuggest__suggestions-container {
   display: none; }
@@ -56,4 +61,17 @@
   background-repeat: no-repeat; }
 
 .react-autosuggest__suggestion--highlighted {
-  background-color: #8d8d8d; }
+  background-color: #86868a; }
+
+.react-autosuggest__container .btn-clear {
+  position: absolute;
+  right: 4px;
+  top: 0;
+  bottom: 0;
+  height: 100%;
+  margin: auto;
+  cursor: pointer;
+  color: #b6b6ba; }
+
+.react-autosuggest__container .btn-clear:hover {
+  color: #86868a; }
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationAutoComplete.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationAutoComplete.js
index 383544a188ea96feeb0a3ebd69c8e9abec27139a..b8def694ce7dd4d59935ce50205f8c53ffc93d28 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationAutoComplete.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationAutoComplete.js
@@ -1,12 +1,23 @@
 import React, {Component} from 'react';
 import {connect} from "react-redux";
 import Autosuggest from 'react-autosuggest';
+import { Input, InputGroup, InputGroupAddon, Button } from 'reactstrap';
+import {
+    IoMdCloseCircleOutline as CloseIcon,
+    IoIosArrowBack as BackIcon,
+    IoIosArrowForward as ForwardIcon
+} from 'react-icons/io';
 
-import './StationAutoComplete.css'
+// History handling
+import { push } from 'connected-react-router';
+import { store } from "../redux/store.js";
+
+// CSS
+import './StationAutoComplete.scss'
 
 
 /**
- * StationAutoCompleteC; class to render an input field for station name with auto-completion.
+ * AutoCompleteC; class to render an input field for station name with auto-completion.
  *
  * The parent component is notified about a new station name (through the onChange callback)
  * when the user presses 'Enter' in the input field or when an item from the list of
@@ -17,9 +28,15 @@ import './StationAutoComplete.css'
  * selected station was changed outside this component. In a new instance the state.value is
  * set to the selectedStation prop.
  *
- * Usage: <StationAutoComplete key={station} selectedStation={station} onChange={onchange} />
+ * Usage: <AutoComplete key={station} onChange={onchange} stations={stations} selectedStation={selectedStation}/>
  */
-class StationAutoCompleteC extends Component {
+class AutoComplete extends Component {
+
+    // The DOM node of the input
+    inputRef = null;
+
+    // Timeout for station loading when back/forward button is used
+    timeoutId = null;
 
     // Autosuggest is a controlled component.
     // However the input value is decoupled from Redux state but gets its
@@ -34,26 +51,19 @@ class StationAutoCompleteC extends Component {
         const inputValue = value.trim().toLowerCase();
         const inputLength = inputValue.length;
 
-        return inputLength === 0 ? this.props.stations : this.props.stations.filter(lang =>
-            //lang.name.toLowerCase().slice(0, inputLength) === inputValue
-            lang.name.toLowerCase().indexOf(inputValue) > -1
+        return inputLength === 0 ? this.props.stations : this.props.stations.filter(obj =>
+            //obj.name.toLowerCase().slice(0, inputLength) === inputValue
+            obj.name.toLowerCase().indexOf(inputValue) > -1
         );
     };
 
     // Get value to show in the input field when a suggestion is chosen
     getSuggestionValue = suggestion => suggestion.name;
 
-    // Render a suggestion
-    renderSuggestion = suggestion => (
-      <div>
-        {suggestion.name}
-      </div>
-    );
-
     // Change handler for input
     onChange = (event, { newValue, method }) => {
         this.setState({
-          value: newValue
+          value: newValue.toUpperCase()
         });
     };
 
@@ -89,6 +99,75 @@ class StationAutoCompleteC extends Component {
         return true;
     };
 
+    getInput = (input) => {
+        this.inputRef = input
+    }
+
+    // Clear button handler for input
+    clearInput = () => {
+        this.setState(
+            { value: "" },
+            () => this.inputRef.focus()
+        );
+    };
+
+    inputNotification = (bgcolor, text) => {
+        this.inputRef.style.backgroundColor = bgcolor;
+        this.inputRef.value = text;
+        window.setTimeout(() => {
+            if (this.inputRef) {
+                this.inputRef.style.backgroundColor = null;
+                this.inputRef.value = this.state.value;
+            }
+        }, 300)
+
+    }
+
+    backForward = (e) => {
+        const mode = e.currentTarget.id;
+        const v = this.state.value;
+        // Find index of selected station in array
+        let idx = this.props.stations.findIndex(obj => obj.name === v);
+        if (idx === -1) {
+            this.inputNotification('#f9abab', 'NOT FOUND');
+            return;
+        }
+        idx = (mode === "btn-forward" ? idx+1 : idx-1);
+        if (idx < 0 || idx >= this.props.stations.length) {
+            // At first station (mode=back) or at last station (mode=forward)
+            this.inputNotification('#a2d6a2', mode==="btn-forward" ? 'LAST' : 'FIRST');
+            return;
+        }
+        // Update display value and reload after 500ms (prevents reloading on fast clicking)
+        window.clearTimeout(this.timeoutId);
+        this.setState({
+          value: this.props.stations[idx].name
+        });
+        this.timeoutId = window.setTimeout(() => this.props.onChange(this.props.stations[idx].name), 500);
+    }
+
+    // Render a suggestion
+    renderSuggestion = suggestion => (
+      <div>
+        {suggestion.name}
+      </div>
+    );
+
+    renderInputComponent = inputProps => (
+        <InputGroup size="sm">
+          <InputGroupAddon addonType="prepend">
+              <Button id="btn-back" color="info" onClick={this.backForward}><BackIcon /></Button>
+          </InputGroupAddon>
+          <div className="btn-group">
+            <Input innerRef={this.getInput} {...inputProps} />
+            <CloseIcon onClick={this.clearInput} className="btn-clear"/>
+        </div>
+          <InputGroupAddon addonType="append">
+              <Button id="btn-forward" color="info" onClick={this.backForward}><ForwardIcon /></Button>
+          </InputGroupAddon>
+        </InputGroup>
+    );
+
 
     render() {
 
@@ -110,17 +189,42 @@ class StationAutoCompleteC extends Component {
                 shouldRenderSuggestions={this.shouldRenderSuggestions}
                 getSuggestionValue={this.getSuggestionValue}
                 renderSuggestion={this.renderSuggestion}
+                renderInputComponent={this.renderInputComponent}
                 inputProps={inputProps}
             />
         );
     }
 }
 
+
+
+class StationAutoCompleteC extends Component {
+
+
+    // Callback for StationAutoComplete
+    onStationChange = (station) => {
+        store.dispatch(push(`?station=${station}`))
+    }
+
+    render() {
+        // The key on AutoComplete is important, see the desc of AutoComplete
+        // That's the main reason why this wrapper exists.
+        return(
+            <div className="toolbar-ctrl">
+                <AutoComplete key={this.props.selectedStation}
+                              stations={this.props.stations}
+                              selectedStation={this.props.selectedStation}
+                              onChange={this.onStationChange}/>
+            </div>
+        );
+    }
+}
+
 // Get full list of stations from redux
 const mapStateToPropsToolBar = state => {
     return {
-        //stations: [{name:'cs001c'},{name:'cs002c'},{name:'cs003c'}]
-        stations: state.appInitData.stations
+        stations: state.appInitData.stations,
+        selectedStation: state.mainFilters.selectedStation
     };
 };
 
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationAutoComplete.scss b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationAutoComplete.scss
index a9d65f862b64fc5016539333edf885267e0d4afe..4b7f44a72a7e1696fe817bb016af9a41a53b7e6b 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationAutoComplete.scss
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationAutoComplete.scss
@@ -6,14 +6,19 @@
     display: inline-block;
 }
 
+.react-autosuggest__container svg {
+    font-size: 1.2rem;
+}
+.react-autosuggest__container button.btn.btn-info {
+    padding: .25rem .3rem;
+}
 /*
 .react-autosuggest__input {
 }
 */
 
-.react-autosuggest__container--open .react-autosuggest__input {
-    border-bottom-left-radius: 0;
-    border-bottom-right-radius: 0;
+.react-autosuggest__container .react-autosuggest__input {
+    border-radius: 0;
 }
 
 .react-autosuggest__suggestions-container {
@@ -66,3 +71,18 @@
 .react-autosuggest__suggestion--highlighted {
     background-color: $secondary-dark;
 }
+
+// Clear icon in input
+.react-autosuggest__container .btn-clear {
+    position: absolute;
+    right: 4px;
+    top: 0;
+    bottom: 0;
+    height: 100%;
+    margin: auto;
+    cursor: pointer;
+    color: $secondary;
+}
+.react-autosuggest__container .btn-clear:hover {
+    color: $secondary-dark;
+}
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.css
index 32a3e3b713e9c855476633cf3ed361a829825d31..11a0240c2c57a99f62ab7ef9cb93dbed336b962b 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.css
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.css
@@ -48,8 +48,8 @@
   float: left;
   height: 1.4rem;
   line-height: 1.4rem;
-  background: #e1e1e1;
-  border: 1px solid #8d8d8d;
+  background: #e8e8ec;
+  border: 1px solid #86868a;
   border-radius: .2rem;
   padding: 0 0.5em;
   text-align: left;
@@ -63,8 +63,8 @@
 .so-stationtestbadge:hover,
 .so-badge:hover {
   color: #fff;
-  background-color: #8d8d8d;
-  border-color: #8d8d8d; }
+  background-color: #86868a;
+  border-color: #86868a; }
 
 .so-pill {
   display: block;
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.js
index 2e423eefd723ecc722ef4b353da603532eacd754..d61e96a4f824764cc59971de04c8cf6e6699f172 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.js
@@ -42,14 +42,14 @@ const SOPopover = ({target, isOpen, togglePopover, title, lines}) => {
         return null;
     }
 
-    return (<Popover placement="auto" isOpen={isOpen} target={target} toggle={togglePopover}>
+    return (<Popover placement="auto" isOpen={isOpen} target={target} toggle={togglePopover} key={title}>
         <PopoverHeader>
             {title}
         </PopoverHeader>
         <PopoverBody>
             <Table borderless size="sm">
                 <tbody>
-                    {lines.map( (obj, id) => <tr>
+                    {lines.map( (obj, id) => <tr key={id}>
                             <th>{obj.th}</th>
                             <td>{obj.td}</td>
                         </tr>)
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationStatistics.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationStatistics.js
index 5ff27fd80e34ac18dc30480b725b0975d8a5c0dc..9fd2a6e3d046d0f0f83c7cf4f3b27f657d57458d 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationStatistics.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationStatistics.js
@@ -86,7 +86,7 @@ class StationStatisticsC extends Component {
             histogramType: 'per_error_type'
         };
         this.ref = React.createRef();
-        this.getErrorsPerTypeSpec.bind(this);
+        StationStatisticsC.getErrorsPerTypeSpec.bind(this);
     }
     getErrorsPerStation() {
         if (this.props.data.errors_per_station !== undefined) {
@@ -99,8 +99,7 @@ class StationStatisticsC extends Component {
             return {values: this.props.data.errors_per_type};
         }
     }
-
-    getBaseSpec() {
+    static getBaseSpec() {
         return {
             "$schema": "https://vega.github.io/schema/vega-lite/v2.json",
             "mark": {
@@ -110,9 +109,12 @@ class StationStatisticsC extends Component {
                 "type": "fit",
                 "contains": "padding"
             },
+            "selection":{
+                "highlight": {"type":"single", "empty":"none","on": "mouseover"},
+            },
             "config": {
                 "legend": {
-                    "columns": 2
+                    "columns": 2,
                 }
             },
             "encoding": {
@@ -128,14 +130,19 @@ class StationStatisticsC extends Component {
                     "type": "quantitative",
                     "axis": {
                         "title": "number of errors"
-                    }
+                    },
+
+                },
+                opacity: {
+                    "condition": {"selection": "highlight", "value": .6},
+                    value: 1
                 }
-            }
+            },
         }
     }
 
-    getErrorsPerTypeSpec() {
-        let schema = this.getBaseSpec();
+    static getErrorsPerTypeSpec() {
+        let schema = StationStatisticsC.getBaseSpec();
         schema.encoding["color"] = {
             "field": "error_type",
             "type": "nominal"
@@ -152,12 +159,12 @@ class StationStatisticsC extends Component {
         return schema;
     }
 
-    getErrorsPerStationSpec() {
-        let schema = this.getBaseSpec();
+    static getErrorsPerStationSpec() {
+        let schema = StationStatisticsC.getBaseSpec();
         schema.encoding["color"] = {
             "field": "station_name",
             "type": "nominal"
-        }
+        };
         schema.encoding["tooltip"] = [
             {
                 field: "n_errors",
@@ -166,19 +173,19 @@ class StationStatisticsC extends Component {
                 field: "station_name",
                 type: "nominal"
             }
-        ]
-        schema.config.legend.columns = 3
+        ];
+        schema.config.legend.columns = 3;
         return schema;
     }
 
     getSpecData(histogram_type) {
         switch (histogram_type) {
             case "per_error_type":
-                return {spec: this.getErrorsPerTypeSpec(), data: this.getErrorsPerType()};
+                return {spec: StationStatisticsC.getErrorsPerTypeSpec(), data: this.getErrorsPerType()};
             case "per_station":
-                return {spec: this.getErrorsPerStationSpec(), data: this.getErrorsPerStation()};
+                return {spec: StationStatisticsC.getErrorsPerStationSpec(), data: this.getErrorsPerStation()};
             default:
-                return {spec: this.getErrorsPerTypeSpec(), data: this.getErrorsPerType()};
+                return {spec: StationStatisticsC.getErrorsPerTypeSpec(), data: this.getErrorsPerType()};
         }
     }
 
@@ -195,8 +202,8 @@ class StationStatisticsC extends Component {
     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
+            const width = this.ref.current.clientWidth;
+            const height = this.ref.current.clientHeight;
             spec.width = width
             spec.height = height
 
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestChildView.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestChildView.css
index b4c07fae728766e11eeb124422f6164c121221e9..5dc5cc855b3ac5b93a00c83e21d2f5335ee67476 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestChildView.css
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestChildView.css
@@ -5,7 +5,7 @@
 /* Data colors */
 .stcv-header {
   padding: .5rem 0;
-  color: #8d8d8d; }
+  color: #86868a; }
 
 .stcv img {
   cursor: pointer;
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestChildView.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestChildView.js
index c5323ec642d6cf42b2401468cb17847a1ae23c26..679263de7c633c9e8028d472726985f9ae18794c 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestChildView.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestChildView.js
@@ -1,48 +1,107 @@
-import React, {
-    Component
-} from 'react';
+import React, {Component} from 'react';
 import {connect} from "react-redux";
 import {unpinChildPanelData} from '../redux/actions/stationOverviewPageActions'
-import {
-    Button,
-    Table,
-    Badge,
-    Modal,
-    ModalHeader,
-    ModalBody
-} from 'reactstrap';
-import { IoMdCloseCircleOutline as CloseIcon} from 'react-icons/io';
+import {Badge, Button, Modal, ModalBody, ModalHeader, Table} from 'reactstrap';
+import {IoMdCloseCircleOutline as CloseIcon} from 'react-icons/io';
 import './StationOverview.css'
 import './StationTestView.css'
 import '../themes/lofar-styles.css'
-
 // CSS
 import './StationTestChildView.css';
 
 
-
 class StationTestChildViewC extends Component {
 
     state = {
         modal: false,
-        modal_url: ""
-    }
+        modalUrl: ""
+    };
+
+    imgLoadTimeout = {};
 
     toggleModal = (e) => {
         this.setState({
           modal: !this.state.modal,
-          modal_url: e.currentTarget.src
+          modalUrl: e.currentTarget.src
         });
-    }
+    };
 
     unpinPanel = () => {
         this.props.unpinChildPanelData();
-    }
+    };
+
+    onImgError = (e) => {
+        let img = e.currentTarget;
+        img.alt = "Reloading in 2 sec..";
+        // let the window figure out if the timeout id is still valid
+        if (this.imgLoadTimeout[img.id]) {
+            clearTimeout(this.imgLoadTimeout[img.id]);
+        }
+        this.imgLoadTimeout[img.id] = setTimeout(() => { img.src = img.src; }, 2000 );
+    };
+
+    clearTimeouts() {
+        let key;
+        for (key in this.imgLoadTimeout) {
+            clearTimeout(this.imgLoadTimeout[key]);
+        }
+        this.imgLoadTimeout = {};
+    };
+
+    renderErrorDetails(pdata, key){
+
+        let pol = pdata['polarization'];
+        let rcuId = pdata['rcu_id'];
+        let err_items = [],
+            ignore = {
+                start_frequency: 1,
+                stop_frequency: 1,
+                polarization: 1,
+                rcu_id: 1,
+                antenna_id: 1,
+                url: 1
+            },
+            img = "";
+
+        // first process frequency range and url
+        if (pdata.details.hasOwnProperty("start_frequency")) {
+            err_items.push(<li key="freq">frequency-range: {pdata.details.start_frequency}-{pdata.details.stop_frequency} MHz</li>);
+        }
+        if (pdata.details.url) {
+            img = <img id={'img-'+pol+'-'+key} src={pdata.details.url} onClick={this.toggleModal} onError={this.onImgError} title="Click to enlarge" alt="Not present"/>;
+        }
+
+        // process remaining items
+        Object.keys(pdata.details).forEach((parameter, key) =>{
+            if (! ignore.hasOwnProperty(parameter)) {
+                const parameter_value = pdata.details[parameter];
+                const rendered_parameter = parameter === 'percentage'? parameter_value.toFixed(2) + '%' : parameter_value;
+                err_items.push(<li key={parameter}>{parameter}: {rendered_parameter}</li>);
+            }});
+
+        if (err_items.length === 0) {
+            err_items = <li><em>See element error.</em></li>;
+        }
+        const imgHeader = (<th scope="row">RCU {rcuId} ({pol}){img}</th>);
+        return (
+            <tr key={key}>
+                {rcuId ? imgHeader : undefined}
+                <td>
+                    <ul style={{listStyleType: 'none', paddingLeft: '0.5em'}}>
+                        <li><Badge className='error-type-badge' color="danger">{pdata.error_type}</Badge></li>
+                        {err_items}
+                    </ul>
+                </td>
+            </tr>
+        );
+    };
 
     render() {
         let rows,
             title;
 
+        this.clearTimeouts();
+
         // defaults when data is null
         rows = <tr><td><i>Hover the mouse over an error to view the details. Right-click on the error to pin it on this panel.</i></td></tr>;
         title = "Error details";
@@ -51,56 +110,20 @@ class StationTestChildViewC extends Component {
             rows = [];
             title = `${this.props.data.component_type}, Antenna ${this.props.data.component_id}, Test ${this.props.data.datetime}`;
 
-            for (let pol of ['X', 'Y']){
-                let pdata = this.props.data[pol];
-                let rcuId = this.props.data[pol+"_rcu_id"];
-
-                pdata.forEach((item, key) => {
-                    let err_items = [],
-                        ignore = {
-                            start_frequency: 1,
-                            stop_frequency: 1,
-                            url: 1
-                        },
-                        img = "";
-
-                    // first process frequency range and url
-                    if (item.details.hasOwnProperty("start_frequency")) {
-                        err_items.push(<li key="freq">frequency-range: {item.details.start_frequency}-{item.details.stop_frequency} MHz</li>);
-                    }
-                    if (item.details.url) {
-                        img = <img src={item.details.url} onClick={this.toggleModal} title="Click to enlarge" alt="Not present"/>;
-                    }
-
-                    // process remaining items
-                    Object.keys(item.details).forEach((parameter, key) =>{
-                        if (! ignore.hasOwnProperty(parameter)) {
-                            const parameter_value = item.details[parameter];
-                            const rendered_parameter = parameter === 'percentage'? parameter_value.toFixed(2) + '%' : parameter_value;
-                            err_items.push(<li key={parameter}>{parameter}: {rendered_parameter}</li>);
+            const data = this.props.data.errors;
+            for (const error_type of Object.keys(data)){
+                let pdata = data[error_type];
+                const key = error_type;
+                if(pdata.hasOwnProperty('X') || pdata.hasOwnProperty('Y')){
+                    for(const pol of ['X', 'Y']){
+                        if(!pdata.hasOwnProperty(pol)){
+                            continue;
                         }
-                    });
-
-                    if (err_items.length === 0) {
-                        err_items = <li><em>See element error.</em></li>;
+                        rows.push(this.renderErrorDetails(pdata[pol], key + pol))
                     }
-
-                    rows.push(
-                        <tr key={pol}>
-                            <th scope="row">RCU {rcuId} ({pol})
-                                {img}
-                            </th>
-                            <td>
-                                <ul style={{listStyleType: 'none', paddingLeft: '0.5em'}}>
-                                    <li><Badge className='error-type-badge' color="danger">{item.error_type}</Badge></li>
-                                    { err_items }
-                                </ul>
-                            </td>
-                        </tr>
-                    );
-
-                    pol = "";
-                });
+                }else{
+                    rows.push(this.renderErrorDetails(pdata, key))
+                }
             }
         }
 
@@ -121,14 +144,12 @@ class StationTestChildViewC extends Component {
                     <Modal isOpen={this.state.modal} fade={false} size="lg" toggle={this.toggle} className={this.props.className}>
                       <ModalHeader toggle={this.toggleModal}></ModalHeader>
                       <ModalBody>
-                        <img style={{width: '100%'}} src={this.state.modal_url} alt="Not present" />
+                        <img style={{width: '100%'}} src={this.state.modalUrl} alt="Not present" />
                       </ModalBody>
                     </Modal>
                </div>;
     }
 }
-
-
 /* Add some magic; use the AutoLoadWrapper to create a HOC that handles the
    auto-loading of the data for StationOverviewC.
  */
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.css
index 395189869afb3d2d326302e77f9eed609541458e..aefc047c97d4cbd290e08d3f3cbf7705b5d5904f 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.css
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.css
@@ -24,7 +24,7 @@
 
 .stv-component-status.highlight,
 .stv-testline.highlight {
-  background-color: #8d8d8d !important;
+  background-color: #86868a !important;
   color: white; }
 
 .stv-testline.highlight td:first-child::before {
@@ -36,11 +36,12 @@
 
 .stv-component-status:hover {
   color: #fff;
-  background-color: #8d8d8d;
-  border-color: #8d8d8d; }
+  background-color: #86868a;
+  border-color: #86868a; }
 
 .stv-rtsm-summary-badge {
-  background-color: #ffcd74;
+  background-color: #fbfb83;
+  color: black;
   text-shadow: 1px 2px white;
   font-size: 80%;
   text-align: center; }
@@ -58,14 +59,14 @@
 
 .clickable-tab-active {
   color: white !important;
-  background-color: #a7689d; }
+  background-color: #4a6889; }
 
 .clickable-tab {
   cursor: pointer;
-  color: #490f44; }
+  color: #001832; }
 
 .clickable-tab:hover {
-  color: #a7689d; }
+  color: #4a6889; }
 
 @keyframes animation-open {
   from {
@@ -79,7 +80,7 @@
   to {
     transform: rotate(0deg); } }
 
-.stv-rtsm-summary-row .row-header-dropdownbutton {
+.stv-rtsm-summary-row .dropdownbutton {
   display: inline;
   float: right;
   animation: animation-close;
@@ -87,7 +88,7 @@
   animation-iteration-count: 1;
   animation-timing-function: linear; }
 
-.stv-rtsm-summary-row .row-header-dropdownbutton-up {
+.stv-rtsm-summary-row .dropdownbutton-up {
   transform: rotate(180deg);
   animation: animation-open;
   animation-duration: 100ms;
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.js
index 1553575993b913bc42f1e354b9a7c400114de703..60824482bf264510ed02871cc4be2b72fc9c4068 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.js
@@ -3,7 +3,6 @@ import React, {
 } from 'react';
 import {connect} from "react-redux";
 import {setChildPanelData} from '../redux/actions/stationOverviewPageActions'
-
 import {
     Badge,
     NavItem,
@@ -12,65 +11,30 @@ import {
     TabContent,
     Nav
 } from 'reactstrap';
-import { IoMdArrowDropdown as DropDownIcon} from 'react-icons/io';
+import {IoMdArrowDropdown as DropDownIcon} from 'react-icons/io';
 import AutoLoadWrapper from '../utils/autoLoader.js'
 import * as LOFARDefinitions from '../utils/LOFARDefinitions'
-import { datetime_format } from '../utils/constants'
+import {datetime_format} from '../utils/constants'
+import {renderDateRange} from '../utils/utils'
 import ReactTableContainer from "react-table-container";
 import moment from 'moment';
+import {withRouter} from "react-router";
+import classNames from "classnames";
+import FillHeight from '../components/FillHeight.js';
 
-// CSS
-import '../themes/lofar-styles.css'
-import './StationOverview.css'
-import './StationTestView.css'
-
-function antennaNumberFromRCUID(rcuID, componentType) {
-    if (componentType === "LBH" || componentType === "HBA") {
-        const result = {}
-        result.polarization = rcuID % 2 === 0
-            ? 'X'
-            : 'Y'
-        result.id = Math.floor(rcuID / 2)
-        return result
-    } else if (componentType === "LBL") {
-        const result = {}
-        result.polarization = rcuID % 2 === 1
-            ? 'X'
-            : 'Y'
-        result.id = Math.floor(rcuID / 2) + 48
-        return result
-    } else {
-        return {id: rcuID}
-    }
-}
 
-function RCUIDFromAntennaNumberPolarization(antennaNumber, polarization, componentType) {
-    if (componentType === "LBH" || componentType === "HBA") {
-        const result = {}
-        const polarization_id = polarization === 'X'
-            ? 0
-            : 1
-        result.id = antennaNumber * 2 + polarization_id
-        return result
-    } else if (componentType === "LBL") {
-        const result = {}
-        const polarization_id = polarization === 'X'
-            ? 1
-            : 0
-        result.id = (antennaNumber - 48) * 2 + polarization_id
-        return result
-    } else {
-        return {id: antennaNumber}
-    }
-}
+// CSS
+import '../themes/lofar-styles.css';
+import './StationOverview.css';
+import './StationTestView.css';
 
 
-class GenericStatus extends Component {
+class GenericStatusTdC extends Component {
 
-    getClass(){
+    getClass() {
         let cls = 'stv-component-status';
         if (this.props.doHighlight) {
-                cls += " highlight";
+            cls += " highlight";
         }
         if (this.props.n_errors > 0) {
             cls += ' so-serious'
@@ -83,9 +47,9 @@ class GenericStatus extends Component {
     onMouseOver = (e) => {
         e.stopPropagation();
         if (this.props.n_errors > 0) {
-            this.props.onSelect(this.props.errors_per_polarization);
+            this.props.onSelect(this.props.data);
         }
-    }
+    };
 
     onMouseOut = (e) => {
         e.stopPropagation();
@@ -93,34 +57,37 @@ class GenericStatus extends Component {
             this.props.onSelect(null);
         }
 
-    }
+    };
 
     // left-click with mouse
     onClick = () => {
-        console.log('click (TODO, switch to tiles page)');
-    }
+        this.props.history.push(`/tiles?antenna_id=${this.props.antenna_id}&antenna_type=${this.props.antenna_type}&station=${this.props.station_name}`);
+    };
 
     // right-click with mouse
     onContextMenu = (e) => {
         e.preventDefault();
         if (this.props.n_errors > 0) {
-            this.props.onSelect(this.props.errors_per_polarization, true);
+            this.props.onSelect(this.props.data, true);
         }
-    }
+    };
 
-    render(){
-        const jsx = <td className={this.getClass()}
-                        onContextMenu={this.onContextMenu}
-                        onClick={this.onClick}
-                        onMouseOver={this.onMouseOver}
-                        onMouseOut={this.onMouseOut}>
-                        {this.props.n_errors === 0 ? ' ' : this.props.n_errors}
-                    </td>;
+    render() {
+        const content = (this.props.n_errors===0 ? ' ' : this.props.n_errors);
 
-        return jsx;
+        return (
+            <td className={this.getClass()}
+                onContextMenu={this.onContextMenu}
+                onClick={this.onClick}
+                onMouseOver={this.onMouseOver}
+                onMouseOut={this.onMouseOut}>
+                {content}
+            </td>
+        );
     }
 }
 
+const GenericStatusTd = withRouter(GenericStatusTdC);
 
 /**
  * TestLine: renders a table row with the results of one station test or RTSM run.
@@ -129,23 +96,23 @@ class TestLineC extends Component {
 
     doHighlight = false;
 
-    formatDate(date){
+    static formatDate(date) {
         return moment(date).format(datetime_format);
     }
 
     shouldHighlight() {
         const props = this.props,
-              data  = props.highlightData;
+              errorData = props.highlightData;
 
-        return data !== null &&
-               data.component_type === props.component_type &&
-               data.test_type === props.test_type &&
-               data.datetime === this.formatDate(props.data.end_date);
+        return errorData !== null &&
+            errorData.component_type === props.component_type &&
+            errorData.test_type === props.test_type &&
+            errorData.datetime === TestLineC.formatDate(props.data.start_date);
     }
 
-    shouldComponentUpdate(nextProps, nextState) {
+    shouldComponentUpdate(nextProps, nextState, nextContext) {
         // this.doHighlight will only be true for the previously and currently selected row
-        if (nextProps.highlightData !== this.props.highlightData && ! this.doHighlight) {
+        if (nextProps.highlightData !== this.props.highlightData && !this.doHighlight) {
             return false;
         }
         return true;
@@ -156,55 +123,56 @@ class TestLineC extends Component {
             this.doHighlight = true;
         }
         this.props.setChildPanelData(data, doPin);
-    }
+    };
 
     renderComponentErrors() {
-        const component_errors = this.props.data.component_errors;
-        const component_type = this.props.component_type;
-        const rendered_component_errors = this.props.ordered_component_ids.map((item, key) => {
-            let component_errors_count = 0
-            const errorsPerPolarization = {
-                X: [],
-                Y: [],
-                // add some items for the child panel
-                X_rcu_id: RCUIDFromAntennaNumberPolarization(item, 'X', component_type).id,
-                Y_rcu_id: RCUIDFromAntennaNumberPolarization(item, 'Y', component_type).id,
-                test_type: this.props.test_type,
-                component_type: component_type,
-                component_id: item,
-                datetime: this.formatDate(this.props.data.end_date)
-            }
-            for (let polarization of['X', 'Y']) {
-                let rcu_id = RCUIDFromAntennaNumberPolarization(item, polarization, component_type).id
-                if (component_errors.hasOwnProperty(rcu_id)) {
-                    component_errors_count += component_errors[rcu_id].length;
-                    errorsPerPolarization[polarization].push(...component_errors[rcu_id])
-                }
+        const componentErrors = this.props.data.component_errors;
+
+        const renderedComponentErrors = this.props.ordered_component_ids.map((component_id, key) => {
+            let nErrors = 0,
+                errors = [],
+                errorData = {};
+
+            if (componentErrors.hasOwnProperty(component_id)) {
+                errors = componentErrors[component_id];
+                nErrors = Object.keys(errors).length;
+
+                // Data for child panel and checking if an antenna item must be highlighted permanently (see shouldHighlight)
+                errorData.errors = errors;
+                errorData.datetime= TestLineC.formatDate(this.props.data.start_date);
+                errorData.test_type = this.props.test_type;
+                errorData.component_id = component_id;
+                errorData.component_type = this.props.component_type;
             }
 
-            return <GenericStatus
-                        doHighlight={this.doHighlight && item === this.props.highlightData.component_id}
-                        key={key}
-                        errors_per_polarization={errorsPerPolarization}
-                        n_errors={component_errors_count}
-                        onSelect={this.onSelect}
-                    />
+            return <GenericStatusTd
+                doHighlight={this.doHighlight && component_id === this.props.highlightData.component_id}
+                key={key}
+                data={errorData}
+                antenna_id={component_id}
+                antenna_type={this.props.component_type}
+                station_name={this.props.station_name}
+                n_errors={nErrors}
+                onSelect={this.onSelect} />
         });
-        return rendered_component_errors;
+
+        return renderedComponentErrors;
     }
 
     render() {
-        const date = this.formatDate(this.props.data.end_date);
+        const date = TestLineC.formatDate(this.props.data.start_date);
 
         // Determine if this row needs to be highlighted
         this.doHighlight = this.shouldHighlight();
 
         const cls = this.doHighlight ? "stv-testline highlight" : "stv-testline";
 
-        return  <tr className={cls}>
-                    <td className="stv-testline-header">{this.props.test_type} {date}</td>
-                    {this.renderComponentErrors()}
-                </tr>
+        return (
+            <tr className={cls}>
+                <td className="stv-testline-header">{this.props.test_type} {date}</td>
+                {this.renderComponentErrors()}
+            </tr>
+        );
     }
 }
 
@@ -218,104 +186,99 @@ const TestLine = connect(state => {
 })(TestLineC);
 
 
+/*
+ * RTSMSummaryLine: create one table row with percentages of errors per antenna.
+ */
+function RTSMSummaryLine(props) {
+    const data = props.data;
 
-class RTSMSummaryLine extends Component {
+    const cols = props.ordered_component_ids.map((item, key) => {
+        if (data[item] > 0) {
+            let perc = Math.ceil(data[item]);
+            return (<td key={key} className={'stv-rtsm-summary-badge'}>{perc + '%'} </td>);
+        } else {
+            return <td key={key}></td>;
+        }
+    });
+
+    const dropdownAdditionStyles = classNames(
+        'dropdownbutton', {'dropdownbutton-up': props.isExpanded});
+
+    return (
+        <tr className='stv-rtsm-summary-row'>
+            <td className="row-header" onClick={props.onClick}>
+                RT {props.dateRange}
+                <DropDownIcon className={"row-header-dropdownbutton " + dropdownAdditionStyles} color="black"/>
+            </td>
+            {cols}
+        </tr>
+    );
+}
 
-    constructor(props){
-        super(props);
-        this.state = {displaySingleTests: false}
-    }
+/*
+ * RTSMLines: create summary line + expandable data rows
+ */
+class RTSMLines extends Component {
 
-    renderTestLine(key, data, component_id_list){
-        return (<TestLine className="collapse open" key={key} ordered_component_ids={component_id_list} test_type="RT" component_type={this.props.component_type} station_type={this.props.station_type} data={data}/>)
+    state = {
+        displaySingleTests: false
     }
 
-    renderTestSummaryLine(data, component_id_list){
-        const result = component_id_list.map((item, key) => {
-            if(data[item] > 0){
-                let perc = Math.ceil(data[item]);
-                return (<td key={key} className={'stv-rtsm-summary-badge'}>{perc + '%'} </td> );
-            } else {
-                return <td key={key}></td>;
-            }
-        })
-        return result
-    }
-
-    computeSummary(){
-        let summary = {}
+    computeSummary() {
+        let summary = {};
         let n_tests = this.props.data.length;
-        const component_id_list = this.props.ordered_component_ids
-        component_id_list.forEach(component_id => summary[component_id] = 0)
+        const component_id_list = this.props.ordered_component_ids;
+        component_id_list.forEach(component_id => summary[component_id] = 0);
 
         this.props.data.forEach((item, key) => {
-            Object.keys(item.component_errors).forEach((item) =>
-                {
-                    const id = antennaNumberFromRCUID(item, this.props.component_type).id
-                    summary[id] += 1
-                })
-        })
+            Object.keys(item.component_errors).forEach((component_id) => {
+                summary[component_id] += 1
+            })
+        });
 
-        Object.keys(summary).forEach(item => summary[item] /= n_tests/50. )
+        Object.keys(summary).forEach(item => summary[item] /= n_tests / 100.);
         return summary
     }
 
-    renderDateRange(data){
-        const lastTest = data[0]
-        const firstTest = data[data.length - 1]
-        const duration = moment.duration(moment(lastTest.end_date)-moment(firstTest.start_date))
-        const years = duration.years()
-        const days = duration.days()
-        const months = duration.months()
-        const hours = duration.hours()
-        let string = `${data.length} obs `
-        if (years > 0) string += `${years}Y`
-        if (months > 0) string += `${months}M`
-        if (days > 0) string += `${days}d`
-        if (hours > 0) string += `${hours}h`
-
-        return string
-    }
-
     toggleDisplaySingleTests = (e) => {
         this.setState({
-            displaySingleTests:!this.state.displaySingleTests
+            displaySingleTests: !this.state.displaySingleTests
         });
-    }
+        this.props.update();
+    };
 
-    render(){
-        let summary = this.computeSummary()
-        const component_id_list = this.props.ordered_component_ids
-        const summaryLine = this.renderTestSummaryLine(summary, component_id_list)
-        var jsx = undefined
-        var all_rtsm = undefined
+    render() {
+        let summaryData = this.computeSummary();
 
-        if (this.state.displaySingleTests){
-            all_rtsm = this.props.data.map((item, key) => this.renderTestLine(key, item, component_id_list))
-        }
+        // RTSM data rows, only shown when expanded
+        let all_rtsm = this.state.displaySingleTests ? this.props.data : [];
 
-        let dropdownAdditionStyles = ""
-        if(this.state.displaySingleTests) dropdownAdditionStyles += "row-header-dropdownbutton-up"
-        jsx = (
-                <React.Fragment>
-                    <tr className='stv-rtsm-summary-row'>
-                        <td className="row-header" onClick={this.toggleDisplaySingleTests}>
-                            RT {this.renderDateRange(this.props.data)}
-                            <DropDownIcon className={"row-header-dropdownbutton " + dropdownAdditionStyles} color="black" />
-                        </td>
-                        {summaryLine}
-                    </tr>
-                    {all_rtsm}
-                </React.Fragment>
-            )
-
-
-        return jsx;
+        return (
+            <React.Fragment>
+                <RTSMSummaryLine onClick={this.toggleDisplaySingleTests}
+                                 isExpanded={this.state.displaySingleTests}
+                                 data={summaryData}
+                                 ordered_component_ids={this.props.ordered_component_ids}
+                                 dateRange={renderDateRange(this.props.data)} />
+                {   // All RTSM lines in this block (expanded or folded)
+                    all_rtsm.map((item, key) =>
+                        <TestLine className="collapse open"
+                            key={key}
+                            test_type="RT"
+                            ordered_component_ids={this.props.ordered_component_ids}
+                            component_type={this.props.component_type}
+                            station_name={this.props.station_name}
+                            station_type={this.props.station_type}
+                            data={item}/>
+                    )
+                }
+            </React.Fragment>
+        );
     }
 }
 
 /**
- * ComponentClass; renders a table of station tests and rtsm data for a component (HBA, RSP, LBH, etc.)
+ * ComponentClass; renders a table of station tests and rtsm data for one component (HBA, RSP, LBH, etc.)
  *
  * Props:
  * station_type: C, R or I
@@ -324,156 +287,181 @@ class RTSMSummaryLine extends Component {
  */
 class ComponentClass extends Component {
 
-    computeComponentIDList(componentType){
+    computeComponentIDList(componentType) {
         let componentIDSet = new Set();
-        let toComponentID = item => {return antennaNumberFromRCUID(item, componentType).id}
-
-        this.props.data.forEach(test => {Object.keys(test.component_errors).forEach(item => componentIDSet.add(toComponentID(item)))})
-        // Javascript only sorts strings :/
-        // a comparing function is therefore needed
+        this.props.data.forEach(test => {
+            Object.keys(test.component_errors).forEach(item => componentIDSet.add(item))
+        });
+        // Numerical sort
         return Array.from(componentIDSet).sort((a, b) => a - b);
     }
 
-    renderHeader(){
-        const components_id = this.computeComponentIDList(this.props.type)
-
-        const result = components_id.map((item, key) => <th scope="col" key={key}>{item}</th>);
-        const jsx = (
-            <thead className="stv-tableheader">
-                <tr><th style={{textAlign:"left"}} scope="col"><Badge color="info">{this.props.type}</Badge></th>{result}</tr>
-            </thead>
-        )
-        return jsx
+    renderStationTestLine(key, data, component_ids) {
+        return (<TestLine key={key}
+                          test_type="ST"
+                          ordered_component_ids={component_ids}
+                          component_type={this.props.type}
+                          station_name={this.props.station_name}
+                          station_type={this.props.station_type}
+                          data={data}/>)
     }
 
-    renderStationTestLine(key, data, component_id_list){
-        return (<TestLine key={key} ordered_component_ids={component_id_list} test_type="ST" component_type={this.props.type} station_type={this.props.station_type} data={data}/>)
+    renderRTSMLines(key, data, component_ids) {
+        return (<RTSMLines key={key}
+                           ordered_component_ids={component_ids}
+                           component_type={this.props.type}
+                           station_name={this.props.station_name}
+                           station_type={this.props.station_type}
+                           data={data}
+                           update={this.updateIfComponentChanges} />)
     }
 
-    renderRTSMSummaryLine(key, data, component_id_list){
-        return (<RTSMSummaryLine key={key} ordered_component_ids={component_id_list} component_type={this.props.type} station_type={this.props.station_type} data={data}/>)
-    }
+    renderTestLines(data, component_ids) {
+        const rows = [];
+        let tmp_rtsm_set = [],
+            num_items = data.length;
+
+        for (let i = 0; i < num_items; i++) {
+            const current_item = data[i],
+                  next_item = (i===num_items-1 ? null : data[i + 1]);
 
-    renderTestLines(data){
-        const component_id_list = this.computeComponentIDList(this.props.type)
-        const rows = []
-        var tmp_rtsm_set = []
+            // Temporarily store RTSM lines
+            if (current_item.test_type === 'R') {
+                tmp_rtsm_set.push(current_item)
 
-        for (let i=0; i<data.length - 1; i++){
-            const next_item = data[i + 1]
-            const current_item = data[i]
-            if (current_item.test_type === 'R' ){
-               tmp_rtsm_set.push(current_item)
+                // Push lines when next item is a station test or when we are at the last item
+                if (next_item === null || next_item.test_type === 'S') {
+                    rows.push(this.renderRTSMLines(rows.length, tmp_rtsm_set, component_ids))
+                    tmp_rtsm_set = []
+                }
             }
-            if (current_item.test_type === 'R' && next_item.test_type === 'S'){
-                rows.push(this.renderRTSMSummaryLine(rows.length, tmp_rtsm_set, component_id_list))
-                tmp_rtsm_set = []
-            } else if (current_item.test_type === 'S'){
-                rows.push(this.renderStationTestLine(rows.length, current_item, component_id_list));
+            else if (current_item.test_type === 'S') {
+                rows.push(this.renderStationTestLine(rows.length, current_item, component_ids));
             }
         }
 
-        const lastTest = data[data.length - 1]
-        if (lastTest.test_type === 'R'){
-            tmp_rtsm_set.push(lastTest)
-        } else {
-            rows.push(this.renderStationTestLine(rows.length, lastTest, component_id_list));
-        }
-        if (tmp_rtsm_set.length > 0) {
-            rows.push(this.renderRTSMSummaryLine(rows.length, tmp_rtsm_set, component_id_list))
-            tmp_rtsm_set = []
-        }
         return rows
     }
 
+    updateIfComponentChanges = () => {
+        this.setState({ state: this.state });
+    }
+
     render() {
-        const rows = this.renderTestLines(this.props.data)
+        const comp_ids = this.computeComponentIDList(this.props.type);
 
-        const jsx = (
-            <ReactTableContainer width="100%" height="79vh">
+        return (
+            <ReactTableContainer width="100%" height={this.props.height+'px'}>
                 <table className="stv-table table-sm table-hover table-bordered">
-                 {this.renderHeader()}
-                 <tbody>
-                     {rows}
-                 </tbody>
+                    <thead className="stv-tableheader">
+                        <tr>
+                            <th style={{textAlign: "left"}} scope="col">
+                                <Badge color="info">{this.props.type}</Badge>
+                            </th>
+                            {comp_ids.map((item, key) =>
+                                <th scope="col" key={key}>{item}</th>)
+                            }
+                        </tr>
+                    </thead>
+                    <tbody>
+                        {this.renderTestLines(this.props.data, comp_ids)}
+                    </tbody>
                 </table>
             </ReactTableContainer>
-        )
-        return jsx;
+        );
     }
 }
+
+/*
+ * Render a Tab item
+ */
+function Tab({label, onClick, isActive}) {
+    const cls = isActive ? 'clickable-tab-active' : 'clickable-tab-unactive';
+
+    return (
+        <NavItem className="clickable-tab">
+            <NavLink className={cls} onClick={onClick}>
+                {label}
+            </NavLink>
+        </NavItem>
+    );
+}
+
 /**
  * StationTestView class.
  */
 class StationTestViewC extends Component {
 
-    constructor(props) {
-        super(props);
-        this.toggle = this.toggle.bind(this);
-        this.state = {
-            activeTab: undefined
-        };
+    state = {
+        activeTab: undefined
     }
 
-    toggle(tab) {
-        if (this.state.activeTab !== tab) {
-            this.setState({
-                activeTab: tab
-            });
-        }
-    }
+    // Set the activeTab to the first component if it wasn't set yet or when
+    // the station changed and doesn't have the active component
+    static getDerivedStateFromProps(props, state) {
+        let componentTypes = Object.keys(props.data).sort(),
+            currentComponent = state.activeTab;
 
-    componentDidUpdate(){
-        this.setDefaultTabIfUndefined()
-    }
+        if (componentTypes.length === 0) {
+            return null;
+        }
 
-    setDefaultTabIfUndefined(){
-        const firstComponent = Object.keys(this.props.data)[0]
-        if(this.state !== undefined && this.state.activeTab === undefined && firstComponent !== undefined){
-            this.setState({
-                activeTab: firstComponent
-            })
+        if (! currentComponent || componentTypes.findIndex((c) => currentComponent === c) === -1) {
+            return {
+                activeTab: componentTypes[0]
+            };
         }
+        return null;
     }
 
-    isActiveClass = (componentType) => {
-        const className = this.state.activeTab === componentType ? 'active' : 'unactive'
-        return className
+    // Do not (re)render when data is loading (performance improvement)
+    shouldComponentUpdate(nextProps, nextState, nextContext) {
+        return nextProps.isLoading ? false : true;
     }
 
-    // Do not (re)render when data is loading (performance improvement)
-    shouldComponentUpdate(nextProps, nextState) {
-        if (nextProps.isLoading) {
-            return false;
+    toggleTab = (e) => {
+        let tab = e.currentTarget.innerHTML;
+        if (this.state.activeTab !== tab) {
+            this.setState({
+                activeTab: tab
+            });
         }
-        return true;
     }
 
     render() {
-        //console.log("render main");
         const stationType = LOFARDefinitions.stationTypeFromName(this.props.selectedStation);
+        const componentTypes = Object.keys(this.props.data).sort();
 
-        const navBar = Object.keys(this.props.data).map((componentType, key) =>
-            (<NavItem key={key} className="clickable-tab">
-                <NavLink className={'clickable-tab-' + this.isActiveClass(componentType)}
-                         onClick={() => this.toggle(componentType)}>{componentType}</NavLink>
-            </NavItem>)
-        );
-
-        const componentListTabs = Object.keys(this.props.data).map((componentType, key) =>
-             <TabPane key={key} tabId={componentType}>
-                 <ComponentClass key={componentType} station_type={stationType} type={componentType} data={this.props.data[componentType]}/>
-             </TabPane>
-         );
+        if (this.props.isLoading) {
+            return null;
+        }
 
         return (
             <div>
                 <Nav tabs className="component-type-selector">
-                    {navBar}
+                {
+                    componentTypes.map((componentType, key) =>
+                        <Tab key={key} onClick={this.toggleTab} isActive={this.state.activeTab===componentType} label={componentType} />
+                    )
+                }
                 </Nav>
-                <TabContent activeTab={this.state.activeTab}>
-                    {componentListTabs}
-                </TabContent>
+                <FillHeight className="border-right">
+                    { ({height}) => (
+                        <TabContent  activeTab={this.state.activeTab}>
+                        {componentTypes.map((componentType, key) =>
+                            <TabPane key={key} tabId={componentType}>
+                                <ComponentClass key={componentType}
+                                                station_type={stationType}
+                                                type={componentType}
+                                                station_name={this.props.selectedStation}
+                                                data={this.props.data[componentType]}
+                                                height={height}
+                                />
+                            </TabPane>
+                        )}
+                        </TabContent>
+                    )}
+                </FillHeight>
             </div>);
     }
 
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.scss b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.scss
index e155759eb20ef4e8191db1c27c5651ebc9b3efa6..31c17f5985150fdcb3c2d6d3642e3db82565db34 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.scss
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.scss
@@ -45,7 +45,8 @@
 }
 
 .stv-rtsm-summary-badge{
-    background-color: $alarming;
+    background-color: $warning;
+    color: $warning-fontcolor;
     text-shadow: 1px 2px white;
     font-size: 80%;
     text-align: center;
@@ -101,7 +102,7 @@
   }
 }
 
-.stv-rtsm-summary-row .row-header-dropdownbutton {
+.stv-rtsm-summary-row .dropdownbutton {
   display: inline;
   float: right;
   animation: animation-close;
@@ -110,7 +111,7 @@
   animation-timing-function: linear;
 }
 
-.stv-rtsm-summary-row .row-header-dropdownbutton-up {
+.stv-rtsm-summary-row .dropdownbutton-up {
   transform: rotate(180deg);
   animation: animation-open;
   animation-duration: 100ms;
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/Toolbar.css b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/Toolbar.css
new file mode 100644
index 0000000000000000000000000000000000000000..ad6dc8f2444266c9f8b7fd79ad3da630df61288d
--- /dev/null
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/Toolbar.css
@@ -0,0 +1,42 @@
+/* COLORS */
+/* Color palette interface (created with https://material.io/tools/color/) */
+/* font color */
+/* font color */
+/* Data colors */
+.toolbar-top {
+  background-color: #4a6889;
+  color: #ffffff;
+  padding: 5px 10px;
+  /* Note: same padding as ResponsiveGridLayout */
+  width: 100%;
+  overflow: visible; }
+
+.toolbar-top {
+  font-weight: 500; }
+
+.toolbar-top .btn-info:not(:disabled):not(.disabled).active,
+.sts-toolbar .btn-info:not(:disabled):not(.disabled).active,
+.toolbar-top .btn-info:not(:disabled):not(.disabled):active,
+.toolbar-top .show > .btn-info.dropdown-toggle {
+  color: white;
+  background-color: #86868a;
+  border-color: #86868a; }
+
+.toolbar-top .btn-info,
+.sts-toolbar .btn-info {
+  color: white;
+  background-color: #b6b6ba;
+  border-color: #b6b6ba; }
+
+.toolbar-top .btn-info:hover,
+.sts-toolbar .btn-info:hover {
+  color: white;
+  background-color: #86868a;
+  border-color: #86868a; }
+
+.react-datepicker-popper {
+  z-index: 2 !important; }
+
+.toolbar-ctrl {
+  display: inline-block;
+  margin-right: 1em; }
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/Toolbar.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/Toolbar.js
new file mode 100644
index 0000000000000000000000000000000000000000..0ffb52a22ab4ae8ffd5ebed86e0b3cdf08d0d938
--- /dev/null
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/Toolbar.js
@@ -0,0 +1,417 @@
+import React, {Component} from 'react';
+import {connect} from "react-redux";
+import {Button, ButtonGroup, Input} from 'reactstrap';
+import {
+    setDateRange,
+    setTestType,
+    setErrorTypes,
+    setStationGroup,
+    setErrorsOnly,
+    setPeriod, setAntennaID,
+    setAntennaType
+} from "../redux/actions/mainFiltersActions";
+import {stationTypeFromName} from "../utils/LOFARDefinitions";
+// History handling
+import { push } from 'connected-react-router';
+import { store } from "../redux/store.js";
+
+import DatePicker from 'react-datepicker';
+import moment from 'moment';
+import MultiSelectDropdown from '../components/MultiSelectDropdown.js'
+import {AntennaIdsPerTypeStationType} from '../utils/LOFARDefinitions.js'
+// CSS
+import './Toolbar.css'
+import 'react-datepicker/dist/react-datepicker.css';
+
+
+/**
+ * Class to display a secondary header for selecting data filters.
+ * The state is managed by the LandingPage class.
+ */
+class DateRangeSelectorC extends Component {
+
+    handleChange(obj) {
+        var startDate = obj.startDate,
+            endDate = obj.endDate;
+
+        startDate = startDate || this.props.startDate;
+        endDate = endDate || this.props.endDate;
+
+        if (startDate.isAfter(endDate)) {
+          endDate = startDate;
+        }
+
+        this.props.setDateRange({
+            startDate: startDate,
+            endDate: endDate
+        });
+    };
+
+    handleChangeStart = (startDate) => {
+        return this.handleChange({
+            startDate: startDate
+        });
+    };
+
+    handleChangeEnd = (endDate) => {
+        return this.handleChange({
+            endDate: endDate
+        });
+    };
+
+    onPeriodClick = (i) => {
+        this.handleChange({
+            startDate: moment().subtract(i, 'days'),
+            endDate: moment()
+        });
+
+    }
+
+    periodIsActive(ndays) {
+        let now = moment().format("YYYY-MMM-DD"),
+            past = moment().subtract(ndays, 'days').format("YYYY-MMM-DD");
+        if (this.props.endDate.format("YYYY-MMM-DD") === now && this.props.startDate.format("YYYY-MMM-DD") === past) {
+            return true;
+        }
+        return false;
+    }
+
+    render() {
+        return (<div className="toolbar-ctrl">
+            <label>Period&nbsp;&nbsp;</label>
+            <ButtonGroup size="sm">
+                <Button color="info" onClick={() => this.onPeriodClick(7)} active={this.periodIsActive(7)}>1 wk</Button>
+                <Button color="info" onClick={() => this.onPeriodClick(14)} active={this.periodIsActive(14)}>2 wk</Button>
+                <Button color="info" onClick={() => this.onPeriodClick(28)} active={this.periodIsActive(28)}>4 wk</Button>
+            </ButtonGroup>
+            &nbsp;
+            <div style={{display: 'inline-block', width: '7em'}}>
+                <DatePicker
+                    selected={this.props.startDate}
+                    selectsStart
+                    dateFormat="YYYY-MMM-DD"
+                    className='form-control form-control-sm'
+                    startDate={this.props.startDate}
+                    endDate={this.props.endDate}
+                    onChange={this.handleChangeStart}
+                />
+            </div>
+            &nbsp;
+            <div style={{display: 'inline-block', width: '7em'}}>
+                <DatePicker
+                    selected={this.props.endDate}
+                    selectsEnd
+                    dateFormat="YYYY-MMM-DD"
+                    className='form-control form-control-sm'
+                    startDate={this.props.startDate}
+                    endDate={this.props.endDate}
+                    onChange={this.handleChangeEnd}
+                />
+            </div>
+        </div>);
+    }
+}
+
+const mapStateDateRangeSelector = state => {
+    return {
+        startDate: state.mainFilters.startDate,
+        endDate: state.mainFilters.endDate
+    };
+};
+
+const mapDispatchDateRangeSelector = {
+    setDateRange
+};
+
+export const DateRangeSelector = connect(mapStateDateRangeSelector, mapDispatchDateRangeSelector)(DateRangeSelectorC);
+
+
+
+/**
+ * Radio buttons for Test Type
+ */
+class TestTypeSelectorC extends Component {
+
+    onTestTypeClick(type) {
+        this.props.setTestType(type);
+    }
+
+    render() {
+        return (<div className="toolbar-ctrl">
+            <label>Type&nbsp;&nbsp;</label>
+            <ButtonGroup size="sm">
+                <Button color="info" onClick={() => this.onTestTypeClick('B')} active={this.props.testType === 'B'}>BOTH</Button>
+                <Button color="info" onClick={() => this.onTestTypeClick('S')} active={this.props.testType === 'S'}>ST-TEST</Button>
+                <Button color="info" onClick={() => this.onTestTypeClick('R')} active={this.props.testType === 'R'}>RTSM</Button>
+            </ButtonGroup>
+        </div>);
+    }
+}
+
+const mapStateTestTypeSelector = state => {
+    return {
+        testType: state.mainFilters.testType
+    };
+};
+
+const mapDispatchTestTypeSelector = {
+    setTestType
+};
+
+export const TestTypeSelector = connect(mapStateTestTypeSelector, mapDispatchTestTypeSelector)(TestTypeSelectorC);
+
+
+/**
+ * Radio buttons for Antenna Type
+ */
+class AntennaTypeSelectorC extends Component {
+
+    onAntennaTypeClick = (e) => {
+        let type = e.currentTarget.innerHTML;
+        //this.props.setAntennaType(type);
+
+        store.dispatch(push(`?antenna_type=${type}`))
+    }
+
+    render() {
+        return (<div className="toolbar-ctrl">
+            <label>Type&nbsp;&nbsp;</label>
+            <ButtonGroup size="sm">
+                <Button color="info" onClick={this.onAntennaTypeClick} active={this.props.antennaType === 'HBA'}>HBA</Button>
+                <Button color="info" onClick={this.onAntennaTypeClick} active={this.props.antennaType === 'LBH'}>LBH</Button>
+                <Button color="info" onClick={this.onAntennaTypeClick} active={this.props.antennaType === 'LBL'}>LBL</Button>
+            </ButtonGroup>
+        </div>);
+    }
+}
+
+const mapStateAntennaTypeSelector = state => {
+    return {
+        antennaType: state.mainFilters.antennaType
+    };
+};
+
+const mapDispatchAntennaTypeSelector = {
+    setAntennaType
+};
+
+export const AntennaTypeSelector = connect(mapStateAntennaTypeSelector, mapDispatchAntennaTypeSelector)(AntennaTypeSelectorC);
+
+
+/**
+ * Radio buttons for Antenna Id
+ */
+class AntennaIdSelectorC extends Component {
+
+    antennaIdList(type, stationType){
+        const antennaIdRange = AntennaIdsPerTypeStationType[stationType][type];
+        let options = [];
+        for(let i=antennaIdRange.start; i<antennaIdRange.end; i++){
+            options.push(<option key={i} value={i}>{i}</option>);
+        }
+        return options
+    }
+    onSelectedAntenna = (e) => {
+        //this.props.setAntennaID(Number(e.target.value));
+        store.dispatch(push(`?antenna_id=${e.target.value}`))
+    };
+
+    render() {
+        const stationType = stationTypeFromName(this.props.selectedStation);
+
+        const options = this.antennaIdList(this.props.antennaType, stationType);
+
+        return (
+        <div className="toolbar-ctrl">
+            <label>Antenna id&nbsp;&nbsp;</label>
+            <Input type="select"
+                   value={this.props.antennaId}
+                   onChange={this.onSelectedAntenna}
+                   bsSize="sm"
+                   style={{display:"inline-block", width:"auto"}}>
+                {options}
+            </Input>
+        </div>);
+    }
+
+}
+
+const mapStateAntennaIdSelector = state => {
+    return {
+        selectedStation: state.mainFilters.selectedStation,
+        antennaId: state.mainFilters.antennaId,
+        antennaType: state.mainFilters.antennaType
+    };
+};
+
+const mapDispatchAntennaIdSelector = {
+    setAntennaID
+};
+
+export const AntennaIdSelector = connect(mapStateAntennaIdSelector, mapDispatchAntennaIdSelector)(AntennaIdSelectorC);
+
+
+/**
+ * Class to display a secondary header for selecting data filters.
+ * The state is managed by the LandingPage class.
+ */
+class ErrorTypesSelectorC extends Component {
+
+    onSelectionErrorTypes = (errorTypes) => {
+        this.props.setErrorTypes(errorTypes)
+    }
+
+    render() {
+        const errorTypes = this.props.errorTypes.map(item => ({value:item, label:item}))
+
+        return (<div className="toolbar-ctrl">
+            <label>Error type&nbsp;&nbsp;</label>
+            <MultiSelectDropdown
+                className="form-input"
+                placeHolder="All"
+                options={errorTypes}
+                selectedItems={this.props.selectedErrorTypes}
+                onSelectionChange={this.onSelectionErrorTypes}
+            />
+        </div>);
+    }
+}
+
+const mapStateErrorTypesSelector = state => {
+    return {
+        selectedErrorTypes: state.mainFilters.selectedErrorTypes,
+        errorTypes: state.appInitData.errorTypes
+    };
+};
+
+const mapDispatchErrorTypesSelector = {
+    setErrorTypes
+};
+
+export const ErrorTypesSelector = connect(mapStateErrorTypesSelector, mapDispatchErrorTypesSelector)(ErrorTypesSelectorC);
+
+
+
+/*
+ *
+ */
+class StationGroupSelectorC extends Component {
+
+    onStationGroupChange = (e) => {
+        this.props.setStationGroup(e.target.value);
+    }
+
+    render() {
+        return (<div className="toolbar-ctrl">
+            <label htmlFor="selected-group">Station group&nbsp;&nbsp;</label>
+            <select className="form-control custom-select custom-select-sm" id="selected-group"
+                    value={this.props.selectedStationGroup}
+                    onChange={this.onStationGroupChange}
+                    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>
+        </div>);
+    }
+}
+
+const mapStateStationGroupSelector = state => {
+    return {
+        selectedStationGroup: state.mainFilters.selectedStationGroup
+    };
+};
+
+const mapDispatchStationGroupSelector = {
+    setStationGroup
+};
+
+export const StationGroupSelector = connect(mapStateStationGroupSelector, mapDispatchStationGroupSelector)(StationGroupSelectorC);
+
+
+/*
+ * Toggle button for "errorsOnly"
+ */
+class ErrorsOnlySelectorC extends Component {
+
+    onErrorsOnlyClick = () => {
+        this.props.setErrorsOnly(!this.props.errorsOnly);
+    }
+
+    render() {
+        return (
+            <div className="toolbar-ctrl">
+                <Button color="info" size="sm" onClick={this.onErrorsOnlyClick} active={this.props.errorsOnly}>
+                    Errors only
+                </Button>
+            </div>);
+    }
+}
+
+const mapStateErrorsOnlySelector = state => {
+    return {
+        errorsOnly: state.mainFilters.errorsOnly
+    };
+};
+
+const mapDispatchErrorsOnlySelector = {
+    setErrorsOnly
+};
+
+export const ErrorsOnlySelector = connect(mapStateErrorsOnlySelector, mapDispatchErrorsOnlySelector)(ErrorsOnlySelectorC);
+
+
+
+/**
+ * Class to display a secondary header for selecting data filters.
+ * The state is managed by the LandingPage class.
+ */
+class PeriodSelectorC extends Component {
+
+    onPeriodClick(i) {
+        this.props.setPeriod(i);
+    }
+
+    render() {
+
+        return (<div className="toolbar-ctrl">
+            <label>Period&nbsp;&nbsp;</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>
+        </div>);
+    }
+}
+
+const mapStatePeriodSelector = state => {
+    return {
+        period: state.mainFilters.period
+    };
+};
+
+const mapDispatchPeriodSelector = {
+    setPeriod
+};
+
+export const PeriodSelector = connect(mapStatePeriodSelector, mapDispatchPeriodSelector)(PeriodSelectorC);
+
+
+
+/*
+ * Toolbar: the wrapper for all toolbar components. Use as:
+ * <Toolbar>
+ *   <StationAutoComplete />
+ *   <TestTypeSelector />
+ *   <..>
+ * </Toolbar>
+ */
+export function Toolbar(props) {
+
+    return (<div className="toolbar-top">
+                {props.children}
+            </div>);
+}
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/Toolbar.scss b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/Toolbar.scss
new file mode 100644
index 0000000000000000000000000000000000000000..050a6d5954be21965c598b77519a4a12954eda6a
--- /dev/null
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/Toolbar.scss
@@ -0,0 +1,44 @@
+@import '../themes/lofar-variables.scss';
+
+
+.toolbar-top {
+    background-color: $primary-light;
+    color: $primary-color;
+    padding: 5px 10px;   /* Note: same padding as ResponsiveGridLayout */
+    width: 100%;
+    overflow: visible;
+}
+
+.toolbar-top {
+    font-weight: 500;
+}
+.toolbar-top .btn-info:not(:disabled):not(.disabled).active,
+.sts-toolbar .btn-info:not(:disabled):not(.disabled).active,
+.toolbar-top .btn-info:not(:disabled):not(.disabled):active,
+.toolbar-top .show>.btn-info.dropdown-toggle {
+    color: $secondary-color;
+    background-color: $secondary-dark;
+    border-color: $secondary-dark;
+}
+
+.toolbar-top .btn-info,
+.sts-toolbar .btn-info {
+    color: $secondary-color;
+    background-color: $secondary;
+    border-color:  $secondary;
+}
+
+.toolbar-top .btn-info:hover,
+.sts-toolbar .btn-info:hover {
+    color: $secondary-color;
+    background-color: $secondary-dark;
+    border-color: $secondary-dark;
+}
+.react-datepicker-popper {
+    z-index: 2 !important;
+}
+
+.toolbar-ctrl {
+    display: inline-block;
+    margin-right: 1em;
+}
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 7af89cd86a7cd3bcc2903f84a096f640893668b3..504f1c3657d8fc1676916b406bac7dd4679edd07 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.css
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.css
@@ -3,11 +3,16 @@
 /* font color */
 /* font color */
 /* Data colors */
-.header {
-  background-color: #773b6f;
-  padding: 20px;
+.header-navbar.navbar {
+  background-color: #1c3e5c;
+  padding: .3rem 1rem;
   color: white; }
 
-.lofar {
+.header-brand em {
   font-weight: bold;
   font-style: normal; }
+
+.header-brand span {
+  color: #86868a;
+  font-size: 1.5rem;
+  font-style: italic; }
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 33aa07d52c2a20e68c69e6978e155e3ddca1ae7b..bc1daa61bf8fb50dd1da8380f4ee3d4d84b773b5 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.js
@@ -1,5 +1,4 @@
 import React, { Component } from 'react';
-import './header.css'
 import { Link } from 'react-router-dom';
 import { Collapse,
         Nav,
@@ -9,52 +8,54 @@ import { Collapse,
         NavItem,
         NavLink } from 'reactstrap';
 
+// CSS
+import './header.scss'
+
 
 class Header extends Component {
-  constructor(props){
-    super(props);
-    this.state = {
-      isOpen: false
-    };
-  }
-
-  toggle(){
-      this.setState({
-          isOpen:!this.state.isOpen
+
+    state = {
+        isOpen: false
+    }
+
+    toggle = () => {
+        this.setState({
+            isOpen:!this.state.isOpen
         });
-  }
+    }
+
+    check_status(item){
+        //console.log(this.props.active_page.pathname)
+        if (this.props.active_page.pathname === item){
+            return "active"
+        }
+    }
 
-  check_status(item){
-    //console.log(this.props.active_page.pathname)
-    if (this.props.active_page.pathname === item){
-      return "active"
+    render() {
+        return (
+          <Navbar className="header-navbar" dark expand="lg">
+            <NavbarBrand className='header-brand'><h1><em>LOFAR</em> Station monitor <span>v0.1</span></h1></NavbarBrand>
+            <NavbarToggler onClick={this.toggle} />
+            <Collapse isOpen={this.state.isOpen} navbar>
+              <Nav className="ml-auto" navbar>
+                <NavItem className={this.check_status("/")}>
+                  <NavLink tag={Link} to="/"><h3>Dashboard</h3></NavLink>
+                </NavItem>
+                <NavItem className={this.check_status("/station_overview")}>
+                  <NavLink tag={Link} to="/station_overview"><h3>Station Overview</h3></NavLink>
+                </NavItem>
+                <NavItem className={this.check_status("/tiles")}>
+                  <NavLink tag={Link} to="/tiles"><h3>Tiles</h3></NavLink>
+                </NavItem>
+                { /*}
+                <NavItem className={this.check_status("/details")}>
+                  <NavLink tag={Link} to="/details"><h3>Details</h3></NavLink>
+                </NavItem>
+                */ }
+              </Nav>
+            </Collapse>
+          </Navbar>);
     }
-  }
-
-  render() {
-    return (
-      <Navbar className="header" dark expand="lg">
-        <NavbarBrand><h1><em className='lofar'>LOFAR</em> Station monitor</h1></NavbarBrand>
-        <NavbarToggler onClick={() => this.toggle()} />
-        <Collapse isOpen={this.state.isOpen} navbar>
-          <Nav className="ml-auto" navbar>
-            <NavItem className={this.check_status("/")}>
-              <NavLink tag={Link} to="/"><h3>Dashboard</h3></NavLink>
-            </NavItem>
-            <NavItem className={this.check_status("/station_overview")}>
-              <NavLink tag={Link} to="/station_overview"><h3>Station Overview</h3></NavLink>
-            </NavItem>
-            <NavItem className={this.check_status("/tiles")}>
-              <NavLink tag={Link} to="/tiles"><h3>Tiles</h3></NavLink>
-            </NavItem>
-            <NavItem className={this.check_status("/details")}>
-              <NavLink tag={Link} to="/details"><h3>Details</h3></NavLink></NavItem>
-
-          </Nav>
-        </Collapse>
-      </Navbar>
-    );
-  }
 }
 
 export default Header;
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.scss b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.scss
index 941c3a6d21574df1e2cbd90638a11f6e56c4d66f..f0e366076c6e65a817143c04335f09578bab6f08 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.scss
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/header.scss
@@ -1,12 +1,18 @@
 @import '../themes/lofar-variables.scss';
 
-.header {
+.header-navbar.navbar {
     background-color: $primary;
-    padding: 20px;
+    padding: .3rem 1rem;
     color: white;
 }
 
-.lofar {
+.header-brand em {
     font-weight: bold;
     font-style: normal;
 }
+
+.header-brand span {
+    color: $secondary-dark;
+    font-size: 1.5rem;
+    font-style: italic;
+}
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 c0afbcd0c9d77392f0c351aef6c110b74cf64f5f..fab99a8ad74b55a98f47719114ace6126ae3ef7f 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/LandingPage.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/LandingPage.js
@@ -7,16 +7,14 @@ 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 { connect } from "react-redux";
 import { setNewLayout } from "../redux/actions/landingPageActions";
-import { setPeriod, setStationGroup, setErrorsOnly, setErrorTypes } from "../redux/actions/mainFiltersActions";
 import { composeQueryString } from '../utils/utils.js';
 import { createGridPanel } from '../utils/grid.js';
+import { Toolbar, StationGroupSelector, ErrorTypesSelector, ErrorsOnlySelector, PeriodSelector } from '../components/Toolbar'
 
-import MultiSelectDropdown from '../components/MultiSelectDropdown.js'
 import 'react-grid-layout/css/styles.css';
 import 'react-resizable/css/styles.css';
 import '../themes/lofar-styles.css';
@@ -24,87 +22,6 @@ import '../themes/lofar-styles.css';
 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);
-    }
-
-    onSelectionErrorTypes(errorTypes) {
-        this.props.setErrorTypes(errorTypes)
-    }
-
-    render() {
-
-        const errorTypes = this.props.errorTypes.map(item => ({value:item, label:item}))
-
-        return (<div className="toolbar-top">
-            <Form inline>
-                <label htmlFor="selected-group">Station group&nbsp;&nbsp;</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>
-                &nbsp;&nbsp;&nbsp; {
-                    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>
-                }
-                &nbsp;&nbsp;&nbsp;
-                <label>Period&nbsp;&nbsp;</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>
-                &nbsp;&nbsp;&nbsp;
-                <label>Error type&nbsp;&nbsp;</label>
-                <MultiSelectDropdown
-                    className="form-input"
-                    placeHolder="All"
-                    options={errorTypes}
-                    selectedItems={this.props.selectedErrorTypes}
-                    onSelectionChange={(e)=> this.onSelectionErrorTypes(e)}/>
-            </Form>
-        </div>);
-    }
-}
-
-const mapStateToPropsToolBar = state => {
-    return {
-        ...state.mainFilters,
-        ...state.appInitData
-    };
-};
-
-const mapDispatchToPropsToolBar = {
-    setStationGroup,
-    setErrorsOnly,
-    setPeriod,
-    setErrorTypes,
-};
-
-const ToolBar = connect(mapStateToPropsToolBar, mapDispatchToPropsToolBar)(ToolBarC);
-
-
 class LandingPageC extends Component {
 
     getStationOverviewURL() {
@@ -178,10 +95,16 @@ class LandingPageC extends Component {
 
         return `${url}&${parametersString}`;
     }
+
     render() {
         return (<div>
             <Header active_page={this.props.location}/>
-            <ToolBar/>
+            <Toolbar>
+                <StationGroupSelector />
+                <ErrorsOnlySelector />
+                <PeriodSelector />
+                <ErrorTypesSelector />
+            </Toolbar>
             <ResponsiveGridLayout className="layout" layouts={this.props.layout.panels} measureBeforeMount={true}
                                   breakpoints={this.props.layout.breakpoints} cols={this.props.layout.cols}
                                   onResizeStop={this.props.setNewLayout}>
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/StationOverviewPage.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/StationOverviewPage.js
index d4f9413032a72a22b52291e8154d3ebfdf3ec46f..36cdae18940b23258fb11bd201dd12cd685ed968 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/StationOverviewPage.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/StationOverviewPage.js
@@ -1,209 +1,98 @@
 import React, { Component } from 'react';
 import {connect} from "react-redux";
-import {Alert, Button, ButtonGroup, Container, Row, Col} from 'reactstrap';
-import { setDateRange, setTestType, setStation, setErrorTypes } from "../redux/actions/mainFiltersActions";
-import DatePicker from 'react-datepicker';
+import {Alert, Container, Row, Col} from 'reactstrap';
 import moment from 'moment';
 
 import Header from '../components/header.js'
 import StationAutoComplete from '../components/StationAutoComplete';
 import StationTestView from '../components/StationTestView';
 import StationTestChildView from '../components/StationTestChildView';
-import MultiSelectDropdown from '../components/MultiSelectDropdown.js'
 import { composeQueryString } from '../utils/utils.js';
+import { Toolbar, DateRangeSelector, TestTypeSelector, ErrorTypesSelector } from '../components/Toolbar'
 
-// History handling
-import { push } from 'connected-react-router';
-import { store } from "../redux/store.js";
-
-// CSS
-import 'react-datepicker/dist/react-datepicker.css';
-
-
-/**
- * Class to display a secondary header for selecting data filters.
- * The state is managed by the LandingPage class.
+/*
+ * Display an Alert
  */
-class ToolBarC extends Component {
+function ErrorAlert({doDisplay, message}){
 
-    constructor(props) {
-        super(props);
-        this.handleChangeStart = this.handleChangeStart.bind(this);
-        this.handleChangeEnd = this.handleChangeEnd.bind(this);
-        this.onStationChange = this.onStationChange.bind(this);
+    if (! doDisplay) {
+        return null;
     }
 
-    handleChange(obj) {
-        var startDate = obj.startDate,
-            endDate = obj.endDate;
-
-        startDate = startDate || this.props.startDate;
-        endDate = endDate || this.props.endDate;
-
-        if (startDate.isAfter(endDate)) {
-          endDate = startDate;
-        }
-
-        this.props.setDateRange({
-            startDate: startDate,
-            endDate: endDate
-        });
-    };
-
-    handleChangeStart(startDate) {
-        return this.handleChange({
-            startDate: startDate
-        });
-    };
-
-    handleChangeEnd(endDate) {
-        return this.handleChange({
-            endDate: endDate
-        });
-    };
-
-    onPeriodClick(i) {
-        this.handleChange({
-            startDate: moment().subtract(i, 'days'),
-            endDate: moment()
-        });
-
-    }
-
-    onTestTypeClick(type) {
-        this.props.setTestType(type);
-    }
+    // The 10px is the margin that ResponsiveGridLayout uses
+    return (
+        <Alert style={{margin: '10px'}} color="warning">
+            {message}
+        </Alert>
+    );
+}
 
-    // Callback for StationAutoComplete
-    onStationChange(station) {
-        //this.props.setStation(station);
-        store.dispatch(push(`?station=${station}`))
-    }
+/*
+ * Display the page body (below the header)
+ */
+function PageBody({doDisplay, url}) {
 
-    onSelectionErrorTypes(errorTypes) {
-        this.props.setErrorTypes(errorTypes)
+    if (! doDisplay) {
+        return null;
     }
 
-    render() {
-        const errorTypes = this.props.errorTypes.map(item => ({value:item, label:item}))
-        // The key on StationAutoComplete is important, see the desc of StationAutoComplete
-        return (<div className="toolbar-top">
-            <StationAutoComplete key={this.props.selectedStation} selectedStation={this.props.selectedStation} onChange={this.onStationChange}/>
-            &nbsp;&nbsp;&nbsp;
-            <label>Type&nbsp;&nbsp;</label>
-            <ButtonGroup size="sm">
-                <Button color="info" onClick={() => this.onTestTypeClick('B')} active={this.props.testType === 'B'}>BOTH</Button>
-                <Button color="info" onClick={() => this.onTestTypeClick('S')} active={this.props.testType === 'S'}>ST-TEST</Button>
-                <Button color="info" onClick={() => this.onTestTypeClick('R')} active={this.props.testType === 'R'}>RTSM</Button>
-            </ButtonGroup>
-            &nbsp;&nbsp;&nbsp;&nbsp;
-            <label>Period&nbsp;&nbsp;</label>
-            <ButtonGroup size="sm">
-                <Button color="info" onClick={() => this.onPeriodClick(7)}>1 wk</Button>
-                <Button color="info" onClick={() => this.onPeriodClick(14)}>2 wk</Button>
-                <Button color="info" onClick={() => this.onPeriodClick(28)}>4 wk</Button>
-            </ButtonGroup>
-            &nbsp;
-            <div style={{display: 'inline-block', width: '7em'}}>
-                <DatePicker
-                    selected={this.props.startDate}
-                    selectsStart
-                    dateFormat="YYYY-MMM-DD"
-                    className='form-control form-control-sm'
-                    startDate={this.props.startDate}
-                    endDate={this.props.endDate}
-                    onChange={this.handleChangeStart}
-                />
-            </div>
-            &nbsp;
-            <div style={{display: 'inline-block', width: '7em'}}>
-                <DatePicker
-                    selected={this.props.endDate}
-                    selectsEnd
-                    dateFormat="YYYY-MMM-DD"
-                    className='form-control form-control-sm'
-                    startDate={this.props.startDate}
-                    endDate={this.props.endDate}
-                    onChange={this.handleChangeEnd}
-                />
-            </div>
-            &nbsp;&nbsp;&nbsp;
-            <label>Error type&nbsp;&nbsp;</label>
-            <MultiSelectDropdown
-                className="form-input"
-                placeHolder="All"
-                options={errorTypes}
-                selectedItems={this.props.selectedErrorTypes}
-                onSelectionChange={(e)=> this.onSelectionErrorTypes(e)}/>
-        </div>);
-    }
+    return (
+        <Container fluid={true}>
+            <Row>
+                <Col md="8" className="col-padding">
+                    <StationTestView url={url} />
+                </Col>
+                <Col md="4" className="col-padding">
+                    <StationTestChildView />
+                </Col>
+            </Row>
+        </Container>
+    );
 }
 
-const mapStateToPropsToolBar = state => {
-    return {
-        ...state.mainFilters,
-        ...state.appInitData
-    };
-};
-
-const mapDispatchToPropsToolBar = {
-    setTestType,
-    setDateRange,
-    setStation,
-    setErrorTypes,
-};
-
-const ToolBar = connect(mapStateToPropsToolBar, mapDispatchToPropsToolBar)(ToolBarC);
 
 class StationOverviewPageC extends Component {
 
-    getStationSummaryURL(){
-        const parameters = {};
+    getStationSummaryURL() {
 
         if (this.isParameterMissing()) {
-            return "";
+            return '';
         }
 
-        parameters.station_name = this.props.selectedStation;
-        parameters.test_type = this.props.testType;
-        parameters.from_date = moment(this.props.startDate).format('YYYY-MM-DD');
-        parameters.to_date = moment(this.props.endDate).format('YYYY-MM-DD');
-        parameters.error_types = this.props.selectedErrorTypes
-        const baseURL = '/api/view/ctrl_station_component_errors?format=json';
+        const parameters = {
+            format: 'json',
+            station_name: this.props.selectedStation,
+            test_type: this.props.testType,
+            from_date: moment(this.props.startDate).format('YYYY-MM-DD'),
+            to_date: moment(this.props.endDate).format('YYYY-MM-DD'),
+            error_types: this.props.selectedErrorTypes
+        };
+
+        const baseURL = '/api/view/ctrl_station_component_errors';
         const queryString = composeQueryString(parameters);
-        return `${baseURL}&${queryString}`
-    }
 
-    isParameterMissing(){
-        const stationName = this.props.selectedStation
-        return stationName === undefined ||
-               stationName === ""
+        return `${baseURL}?${queryString}`
     }
 
-    renderErrorIfParameterMissing(){
-        if (this.isParameterMissing()){
-            // The 10px is the margin that ResponsiveGridLayout uses
-            return <Alert style={{margin: '10px'}} color="warning">Please select a station</Alert>
-        }else {
-            return ""
-        }
+    isParameterMissing(){
+        const stationName = this.props.selectedStation;
+        return stationName === undefined || stationName === "";
     }
-    setNewLayout() {}
 
     render() {
+        const parmMissing = this.isParameterMissing();
+
         return (
             <React.Fragment>
                 <Header active_page={this.props.location} />
-                <ToolBar/>
-                {this.renderErrorIfParameterMissing()}
-                { this.isParameterMissing() ? "" :
-                    <Container fluid={true} style={{padding: '10px'}}>
-                        <Row>
-                            <Col md="8"><StationTestView url={this.getStationSummaryURL()} /></Col>
-                            <Col md="4"><StationTestChildView /></Col>
-                        </Row>
-                    </Container>
-                }
+                <Toolbar>
+                    <StationAutoComplete />
+                    <TestTypeSelector />
+                    <DateRangeSelector />
+                    <ErrorTypesSelector />
+                </Toolbar>
+                <ErrorAlert doDisplay={parmMissing} message="Please select a station" />
+                <PageBody doDisplay={!parmMissing} url={this.getStationSummaryURL()} />
             </React.Fragment>
     );
   }
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/TilesPage.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/TilesPage.js
index c9c5e05acd99d7f9536ced9fe62f678c92a2067b..43eabbd06801579f4a781667db46c262d5461728 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/TilesPage.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/pages/TilesPage.js
@@ -1,16 +1,84 @@
 import React, { Component } from 'react';
 import Header from '../components/header.js'
+import moment from 'moment'
+import {connect} from "react-redux";
+import StationAutoComplete from '../components/StationAutoComplete';
+import { Toolbar, DateRangeSelector, TestTypeSelector, AntennaTypeSelector, AntennaIdSelector } from '../components/Toolbar'
+import {Alert, Container, Col, Row} from "reactstrap";
+import { composeQueryString } from '../utils/utils.js';
+import AntennaErrorDetails from '../components/AntennaErrorDetails'
+import AntennaView from '../components/AntennaView';
+
+
+// Component to display an alert
+function StationAlert(props) {
+    if (props.show) {
+        return <Alert style={{margin: '10px'}} color="warning">Please select a station</Alert>;
+    }
+    return null;
+}
+
+
+class TilesPageC extends Component {
+
+  isParameterMissing(){
+        const stationName = this.props.selectedStation
+        return stationName === undefined ||
+               stationName === ""
+  }
+
+  getTilesDataURL () {
+      const url = '/api/view/ctrl_station_component_element_errors?format=json';
+      const parameters = {};
+      // ---- Mandatory parameters
+      parameters.station_name = this.props.selectedStation;
+      // ---- Optional parameters
+      parameters.from_date = moment(this.props.startDate).format('YYYY-MM-DD');
+      parameters.to_date = moment(this.props.endDate).format('YYYY-MM-DD');
+      parameters.component_type = this.props.antennaType;
+      parameters.antenna_id = this.props.antennaId;
+      parameters.test_type = this.props.testType === 'B' ? 'A' : this.props.testType;
+      const parametersString = composeQueryString(parameters);
+
+      return `${url}&${parametersString}`;
+  }
 
-class TilesPage extends Component {
   render() {
+    let parmMissing = this.isParameterMissing(),
+        url = this.getTilesDataURL();
+
     return (
       <div>
         <Header active_page={this.props.location} />
-
-        <div>Tiles Overview</div>
+        <Toolbar>
+            <StationAutoComplete />
+            <AntennaTypeSelector />
+            <AntennaIdSelector />
+            <TestTypeSelector />
+            <DateRangeSelector />
+        </Toolbar>
+        <StationAlert show={parmMissing} />
+        { parmMissing ? null :
+            <Container fluid={true}>
+                <Row>
+                    <Col md="8" className="col-padding">
+                        <AntennaView url={url}/>
+                    </Col>
+                    <Col md="4" className="col-padding">
+                        <AntennaErrorDetails/>
+                    </Col>
+                </Row>
+            </Container>
+        }
       </div>
     );
   }
 }
 
+const TilesPage = connect(state => {
+    return {
+        ...state.mainFilters
+    };
+})(TilesPageC);
+
 export default TilesPage;
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/antennaOverviewPageActions.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/antennaOverviewPageActions.js
new file mode 100644
index 0000000000000000000000000000000000000000..fc03517f386bf672129c2d64801d01b1085c760a
--- /dev/null
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/antennaOverviewPageActions.js
@@ -0,0 +1,12 @@
+export const SELECT_ANTENNA_ERROR = "SELECT_ANTENNA_ERROR";
+export const PIN_ANTENNA_ERROR = "PIN_ANTENNA_ERROR";
+
+export const selectAntennaError = antenna_error_data => ({
+  type: SELECT_ANTENNA_ERROR,
+  payload: { antenna_error_data }
+});
+
+export const pinAntennaError = is_pin => ({
+  type: PIN_ANTENNA_ERROR,
+  payload: { is_pin }
+});
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
index 674e6fc9a4e89beebaffeac447bee549594c82b7..5c546aeb7513e972c6a1e6619c007d3d60a2631d 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/appInitDataActions.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/appInitDataActions.js
@@ -38,7 +38,7 @@ export function fetchErrorTypes() {
         })
         .catch(error => {
             console.log("Error fetching error types: "+error);
-            dispatch(fetchErrorTypesFailure(error))
+            dispatch(fetchErrorTypesFailure(error));
             // Try again in 30s
             setTimeout(() => dispatch(fetchErrorTypes()), 10000);
         });
@@ -67,7 +67,6 @@ export const fetchStationsFailure = error => ({
 export function fetchStations() {
   return dispatch => {
     // Not used: dispatch(fetchstationsBegin());
-
     return axios.get(stationsURL)
         .then(res => {
             let stations = res.data.results ? res.data.results : [];
@@ -76,7 +75,7 @@ export function fetchStations() {
         })
         .catch(error => {
             console.log("Error fetching error types: "+error);
-            dispatch(fetchStationsFailure(error))
+            dispatch(fetchStationsFailure(error));
             // Try again in 30s
             setTimeout(() => dispatch(fetchStations()), 10000);
         });
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
index c6bdd70742fac2f84e369d47e91ea19ce60c4aaf..bcc42b5f4c6ef1a25b35718db6f017aebc3d5003 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/mainFiltersActions.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/actions/mainFiltersActions.js
@@ -1,4 +1,3 @@
-
 export const SET_STATION_GROUP = "SET_STATION_GROUP";
 export const SET_STATION = "SET_STATION";
 export const SET_ERRORS_ONLY = "SET_ERRORS_ONLY";
@@ -6,6 +5,18 @@ export const SET_PERIOD = "SET_PERIOD";
 export const SET_DATE_RANGE = "SET_DATE_RANGE";
 export const SET_TEST_TYPE = "SET_TEST_TYPE";
 export const SET_ERROR_TYPES = "SET_ERROR_TYPES";
+export const SET_ANTENNA_TYPE = "SET_ANTENNA_TYPE";
+export const SET_ANTENNA_ID = "SET_ANTENNA_ID";
+
+export const setAntennaID = antennaId => ({
+  type: SET_ANTENNA_ID,
+  payload: { antennaId }
+});
+
+export const setAntennaType = antennaType => ({
+  type: SET_ANTENNA_TYPE,
+  payload: { antennaType }
+});
 
 export const setStationGroup = stationGroup => ({
   type: SET_STATION_GROUP,
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/antennaOverviewPageReducers.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/antennaOverviewPageReducers.js
new file mode 100644
index 0000000000000000000000000000000000000000..2854320b7225121e1f4b1bc23b79d5f21b388ec7
--- /dev/null
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/antennaOverviewPageReducers.js
@@ -0,0 +1,25 @@
+import { SELECT_ANTENNA_ERROR,
+         PIN_ANTENNA_ERROR } from '../actions/antennaOverviewPageActions'
+
+const initialState = {
+    main_panel : {},
+    child_panel : {isPinned: false}
+};
+
+
+export default function(state = initialState, action) {
+    let newState =  {...state};
+    switch (action.type) {
+
+        case SELECT_ANTENNA_ERROR:
+            newState.main_panel = action.payload;
+            return newState;
+
+        case PIN_ANTENNA_ERROR:
+            newState.child_panel.isPinned = action.payload.is_pin;
+            return newState;
+            
+        default:
+            return newState
+    }
+}
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
index c877894fe8e09a03c9d9c61a170745bdd13df88b..8e93f1fb02b34c97ac319c0185ec2f8421a7bf14 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/index.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/index.js
@@ -3,10 +3,11 @@ import appInitData from "./appInitDataReducers";
 import mainFilters from "./mainFilters";
 import landingPageReducers from "./landingPageReducers";
 import stationOverviewPageReducers from "./stationOverviewPageReducers";
-
+import antennaOverviePageReducers from "./antennaOverviewPageReducers";
 export default combineReducers({
     appInitData,
     mainFilters,
     landing_page: landingPageReducers,
-    station_page: stationOverviewPageReducers
+    station_page: stationOverviewPageReducers,
+    antenna_page: antennaOverviePageReducers
 });
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
index ef52320124f903e15fc190f904b747a0614ea1c8..61be6786f9f436db6650d9ffc4fd7a63a23dde64 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/mainFilters.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/redux/reducers/mainFilters.js
@@ -11,24 +11,42 @@ const initialState = {
     period: 7,             // days
     startDate: moment().subtract(7, 'days'),
     endDate: moment(),
-    selectedErrorTypes: []
+    selectedErrorTypes: [],
+    antennaId: 0,
+    antennaType: 'HBA',
 };
 
 
 export default function(state = initialState, action) {
+
     switch (action.type) {
         case LOCATION_CHANGE: {
             // Location changed, check is a station parameter is present
             let newState = {
                 ...state
             };
-            const values = queryString.parse( action.payload.location.search);
+            const values = queryString.parse(action.payload.location.search);
             if ('station' in values) {
                 newState.selectedStation = values.station;
             }
+            if ('antenna_id' in values){
+                newState.antennaId = values.antenna_id;
+            }
+            if('antenna_type' in values){
+                newState.antennaType = values.antenna_type;
+            }
+            return newState;
+        }
+        case a.SET_ANTENNA_ID: {
+            let newState = {...state};
+            newState.antennaId = action.payload.antennaId;
+            return newState;
+        }
+        case a.SET_ANTENNA_TYPE: {
+            let newState = {...state};
+            newState.antennaType = action.payload.antennaType;
             return newState;
         }
-
         case a.SET_STATION_GROUP: {
             const { stationGroup }  = action.payload;
             return {
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 f48fba4d3e0dd6e764adb80dd595bbfcca26117b..3a0c2bded0cb8179f7727639a6d37e2cfcd3716c 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
@@ -4,14 +4,18 @@
 /* font color */
 /* font color */
 /* Data colors */
+/* For alt text */
+img {
+  font-weight: 400 !important; }
+
 .react-grid-item {
   background-color: white;
-  border: 1px solid #e1e1e1;
+  border: 1px solid #e8e8ec;
   border-radius: 0.25rem; }
 
 .react-grid-item-header {
-  color: #8d8d8d;
-  background-color: #e1e1e1;
+  color: #86868a;
+  background-color: #e8e8ec;
   font-weight: bold;
   padding: .3rem;
   /* Note: must be same as the Bootstrap table for nice alignment */
@@ -36,8 +40,8 @@
   top: 2.25em;
   /* Check with height of .react-grid-item-header */
   left: 0.25em;
-  border: 0.55rem solid #e1e1e1;
-  border-top: 0.55rem solid #a7689d;
+  border: 0.55rem solid #e8e8ec;
+  border-top: 0.55rem solid #4a6889;
   border-radius: 50%;
   width: 3rem;
   height: 3rem;
@@ -66,41 +70,10 @@
   text-align: center;
   font-weight: 700; }
 
-.toolbar-top {
-  background-color: #a7689d;
-  color: #ffffff;
-  padding: 5px 10px;
-  /* Note: same padding as ResponsiveGridLayout */
-  width: 100%;
-  overflow: visible; }
-
-.toolbar-top {
-  font-weight: 500; }
-
-.toolbar-top .btn-info:not(:disabled):not(.disabled).active,
-.sts-toolbar .btn-info:not(:disabled):not(.disabled).active,
-.toolbar-top .btn-info:not(:disabled):not(.disabled):active,
-.toolbar-top .show > .btn-info.dropdown-toggle {
-  color: white;
-  background-color: #8d8d8d;
-  border-color: #8d8d8d; }
-
-.toolbar-top .btn-info,
-.sts-toolbar .btn-info {
-  color: white;
-  background-color: #bdbdbd;
-  border-color: #bdbdbd; }
-
-.toolbar-top .btn-info:hover,
-.sts-toolbar .btn-info:hover {
-  color: white;
-  background-color: #8d8d8d;
-  border-color: #8d8d8d; }
-
 .tooltip > .tooltip-inner {
   background-color: white !important;
   color: black !important;
-  border: 1px solid #8d8d8d; }
+  border: 1px solid #86868a; }
 
 .react-select-container {
   min-width: 20rem; }
@@ -115,4 +88,8 @@
   border: none; }
 
 .form-input button:hover {
-  background-color: #e1e1e1 !important; }
+  background-color: #e8e8ec !important; }
+
+/* Padding on column in bootstrap grid */
+.row .col-padding {
+  padding-top: 15px; }
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 ae80678c68f190303bffbcba143823077efa66c9..a06cfc16b5fc08b0b54b81b4d4e37317f9cd0a84 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
@@ -6,6 +6,11 @@ body {
     //background-color: #E1E2E1!important;
 }
 
+/* For alt text */
+img {
+    font-weight: 400!important;
+}
+
 $griditem: $secondary-light;
 $griditem-color: $secondary-dark;
 
@@ -74,40 +79,6 @@ $griditem-color: $secondary-dark;
     font-weight: 700;
 }
 
-.toolbar-top {
-    background-color: $primary-light;
-    color: $primary-color;
-    padding: 5px 10px;   /* Note: same padding as ResponsiveGridLayout */
-    width: 100%;
-    overflow: visible;
-}
-
-.toolbar-top {
-    font-weight: 500;
-}
-.toolbar-top .btn-info:not(:disabled):not(.disabled).active,
-.sts-toolbar .btn-info:not(:disabled):not(.disabled).active,
-.toolbar-top .btn-info:not(:disabled):not(.disabled):active,
-.toolbar-top .show>.btn-info.dropdown-toggle {
-    color: $secondary-color;
-    background-color: $secondary-dark;
-    border-color: $secondary-dark;
-}
-
-.toolbar-top .btn-info,
-.sts-toolbar .btn-info {
-    color: $secondary-color;
-    background-color: $secondary;
-    border-color:  $secondary;
-}
-
-.toolbar-top .btn-info:hover,
-.sts-toolbar .btn-info:hover {
-    color: $secondary-color;
-    background-color: $secondary-dark;
-    border-color: $secondary-dark;
-}
-
 .tooltip > .tooltip-inner {
     background-color: white !important;
     color: black !important;
@@ -115,6 +86,7 @@ $griditem-color: $secondary-dark;
     border: 1px solid $secondary-dark;
 
 }
+
 .react-select-container{
     min-width: 20rem;
 }
@@ -134,3 +106,9 @@ $griditem-color: $secondary-dark;
 .form-input button:hover {
     background-color: $secondary-light !important;
 }
+
+
+/* Padding on column in bootstrap grid */
+.row .col-padding {
+    padding-top: 15px;
+}
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 e868bb8726e852d3ae6fb804313824b8a3affa28..ce151724f088f43ac79938ed956baf1c4dd58cbb 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
@@ -3,14 +3,14 @@
 
 /* Color palette interface (created with https://material.io/tools/color/) */
 
-$primary: #773b6f;
-$primary-light: #a7689d;
-$primary-dark: #490f44;
+$primary: #1c3e5c; //#773b6f;
+$primary-light: #4a6889; // #a7689d;
+$primary-dark: #001832; //#490f44;
 $primary-color: #ffffff;  /* font color */
 
-$secondary: #bdbdbd;
-$secondary-light: #e1e1e1;
-$secondary-dark: #8d8d8d;
+$secondary: #b6b6ba; //#bdbdbd;
+$secondary-light: #e8e8ec; //#e1e1e1;
+$secondary-dark: #86868a; //#8d8d8d;
 $secondary-color: white;  /* font color */
 
 
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 a40b42bb57c95fc8e2eba5674461f641c72f07f1..aab891291b8281dacb619f0553f7465bc3fde7de 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar.css
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/themes/lofar.css
@@ -23,8 +23,8 @@
   --white: #fff;
   --gray: #6c757d;
   --gray-dark: #343a40;
-  --primary: #773b6f;
-  --secondary: #bdbdbd;
+  --primary: #1c3e5c;
+  --secondary: #b6b6ba;
   --success: #28a745;
   --info: #17a2b8;
   --warning: #fbfb83;
@@ -142,12 +142,12 @@ sup {
   top: -.5em; }
 
 a {
-  color: #773b6f;
+  color: #1c3e5c;
   text-decoration: none;
   background-color: transparent;
   -webkit-text-decoration-skip: objects; }
   a:hover {
-    color: #44223f;
+    color: #0a1621;
     text-decoration: underline; }
 
 a:not([href]):not([tabindex]) {
@@ -1083,24 +1083,24 @@ pre {
 .table-primary,
 .table-primary > th,
 .table-primary > td {
-  background-color: #d9c8d7; }
+  background-color: #bfc9d1; }
 
 .table-hover .table-primary:hover {
-  background-color: #cfb9cc; }
+  background-color: #b0bcc6; }
   .table-hover .table-primary:hover > td,
   .table-hover .table-primary:hover > th {
-    background-color: #cfb9cc; }
+    background-color: #b0bcc6; }
 
 .table-secondary,
 .table-secondary > th,
 .table-secondary > td {
-  background-color: #ededed; }
+  background-color: #ebebec; }
 
 .table-hover .table-secondary:hover {
-  background-color: #e0e0e0; }
+  background-color: #dedee0; }
   .table-hover .table-secondary:hover > td,
   .table-hover .table-secondary:hover > th {
-    background-color: #e0e0e0; }
+    background-color: #dedee0; }
 
 .table-success,
 .table-success > th,
@@ -1274,9 +1274,9 @@ pre {
   .form-control:focus {
     color: #495057;
     background-color: #fff;
-    border-color: #bb76b2;
+    border-color: #3a80be;
     outline: 0;
-    box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.25); }
+    box-shadow: 0 0 0 0.2rem rgba(28, 62, 92, 0.25); }
   .form-control::placeholder {
     color: #6c757d;
     opacity: 1; }
@@ -1618,7 +1618,7 @@ textarea.form-control {
     text-decoration: none; }
   .btn:focus, .btn.focus {
     outline: 0;
-    box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.25); }
+    box-shadow: 0 0 0 0.2rem rgba(28, 62, 92, 0.25); }
   .btn.disabled, .btn:disabled {
     opacity: 0.65; }
   .btn:not(:disabled):not(.disabled) {
@@ -1630,49 +1630,49 @@ fieldset:disabled a.btn {
 
 .btn-primary {
   color: #fff;
-  background-color: #773b6f;
-  border-color: #773b6f; }
+  background-color: #1c3e5c;
+  border-color: #1c3e5c; }
   .btn-primary:hover {
     color: #fff;
-    background-color: #5d2e57;
-    border-color: #552a4f; }
+    background-color: #132a3f;
+    border-color: #102435; }
   .btn-primary:focus, .btn-primary.focus {
-    box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.5); }
+    box-shadow: 0 0 0 0.2rem rgba(28, 62, 92, 0.5); }
   .btn-primary.disabled, .btn-primary:disabled {
     color: #fff;
-    background-color: #773b6f;
-    border-color: #773b6f; }
+    background-color: #1c3e5c;
+    border-color: #1c3e5c; }
   .btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,
   .show > .btn-primary.dropdown-toggle {
     color: #fff;
-    background-color: #552a4f;
-    border-color: #4c2647; }
+    background-color: #102435;
+    border-color: #0d1d2b; }
     .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(119, 59, 111, 0.5); }
+      box-shadow: 0 0 0 0.2rem rgba(28, 62, 92, 0.5); }
 
 .btn-secondary {
   color: #212529;
-  background-color: #bdbdbd;
-  border-color: #bdbdbd; }
+  background-color: #b6b6ba;
+  border-color: #b6b6ba; }
   .btn-secondary:hover {
     color: #212529;
-    background-color: #aaaaaa;
-    border-color: #a4a4a4; }
+    background-color: #a2a2a7;
+    border-color: #9c9ca1; }
   .btn-secondary:focus, .btn-secondary.focus {
-    box-shadow: 0 0 0 0.2rem rgba(189, 189, 189, 0.5); }
+    box-shadow: 0 0 0 0.2rem rgba(182, 182, 186, 0.5); }
   .btn-secondary.disabled, .btn-secondary:disabled {
     color: #212529;
-    background-color: #bdbdbd;
-    border-color: #bdbdbd; }
+    background-color: #b6b6ba;
+    border-color: #b6b6ba; }
   .btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,
   .show > .btn-secondary.dropdown-toggle {
     color: #212529;
-    background-color: #a4a4a4;
-    border-color: #9d9d9d; }
+    background-color: #9c9ca1;
+    border-color: #95959b; }
     .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(189, 189, 189, 0.5); }
+      box-shadow: 0 0 0 0.2rem rgba(182, 182, 186, 0.5); }
 
 .btn-success {
   color: #fff;
@@ -1813,50 +1813,50 @@ fieldset:disabled a.btn {
       box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); }
 
 .btn-outline-primary {
-  color: #773b6f;
+  color: #1c3e5c;
   background-color: transparent;
   background-image: none;
-  border-color: #773b6f; }
+  border-color: #1c3e5c; }
   .btn-outline-primary:hover {
     color: #fff;
-    background-color: #773b6f;
-    border-color: #773b6f; }
+    background-color: #1c3e5c;
+    border-color: #1c3e5c; }
   .btn-outline-primary:focus, .btn-outline-primary.focus {
-    box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.5); }
+    box-shadow: 0 0 0 0.2rem rgba(28, 62, 92, 0.5); }
   .btn-outline-primary.disabled, .btn-outline-primary:disabled {
-    color: #773b6f;
+    color: #1c3e5c;
     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: #773b6f;
-    border-color: #773b6f; }
+    background-color: #1c3e5c;
+    border-color: #1c3e5c; }
     .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(119, 59, 111, 0.5); }
+      box-shadow: 0 0 0 0.2rem rgba(28, 62, 92, 0.5); }
 
 .btn-outline-secondary {
-  color: #bdbdbd;
+  color: #b6b6ba;
   background-color: transparent;
   background-image: none;
-  border-color: #bdbdbd; }
+  border-color: #b6b6ba; }
   .btn-outline-secondary:hover {
     color: #212529;
-    background-color: #bdbdbd;
-    border-color: #bdbdbd; }
+    background-color: #b6b6ba;
+    border-color: #b6b6ba; }
   .btn-outline-secondary:focus, .btn-outline-secondary.focus {
-    box-shadow: 0 0 0 0.2rem rgba(189, 189, 189, 0.5); }
+    box-shadow: 0 0 0 0.2rem rgba(182, 182, 186, 0.5); }
   .btn-outline-secondary.disabled, .btn-outline-secondary:disabled {
-    color: #bdbdbd;
+    color: #b6b6ba;
     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: #212529;
-    background-color: #bdbdbd;
-    border-color: #bdbdbd; }
+    background-color: #b6b6ba;
+    border-color: #b6b6ba; }
     .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(189, 189, 189, 0.5); }
+      box-shadow: 0 0 0 0.2rem rgba(182, 182, 186, 0.5); }
 
 .btn-outline-success {
   color: #28a745;
@@ -1998,10 +1998,10 @@ fieldset:disabled a.btn {
 
 .btn-link {
   font-weight: 400;
-  color: #773b6f;
+  color: #1c3e5c;
   background-color: transparent; }
   .btn-link:hover {
-    color: #44223f;
+    color: #0a1621;
     text-decoration: underline;
     background-color: transparent;
     border-color: transparent; }
@@ -2209,7 +2209,7 @@ input[type="button"].btn-block {
   .dropdown-item.active, .dropdown-item:active {
     color: #fff;
     text-decoration: none;
-    background-color: #773b6f; }
+    background-color: #1c3e5c; }
   .dropdown-item.disabled, .dropdown-item:disabled {
     color: #6c757d;
     background-color: transparent; }
@@ -2473,12 +2473,12 @@ input[type="button"].btn-block {
   opacity: 0; }
   .custom-control-input:checked ~ .custom-control-label::before {
     color: #fff;
-    background-color: #773b6f; }
+    background-color: #1c3e5c; }
   .custom-control-input:focus ~ .custom-control-label::before {
-    box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(119, 59, 111, 0.25); }
+    box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(28, 62, 92, 0.25); }
   .custom-control-input:active ~ .custom-control-label::before {
     color: #fff;
-    background-color: #cc98c5; }
+    background-color: #5d99ce; }
   .custom-control-input:disabled ~ .custom-control-label {
     color: #6c757d; }
     .custom-control-input:disabled ~ .custom-control-label::before {
@@ -2514,34 +2514,34 @@ input[type="button"].btn-block {
   border-radius: 0.25rem; }
 
 .custom-checkbox .custom-control-input:checked ~ .custom-control-label::before {
-  background-color: #773b6f; }
+  background-color: #1c3e5c; }
 
 .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: #773b6f; }
+  background-color: #1c3e5c; }
 
 .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(119, 59, 111, 0.5); }
+  background-color: rgba(28, 62, 92, 0.5); }
 
 .custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {
-  background-color: rgba(119, 59, 111, 0.5); }
+  background-color: rgba(28, 62, 92, 0.5); }
 
 .custom-radio .custom-control-label::before {
   border-radius: 50%; }
 
 .custom-radio .custom-control-input:checked ~ .custom-control-label::before {
-  background-color: #773b6f; }
+  background-color: #1c3e5c; }
 
 .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(119, 59, 111, 0.5); }
+  background-color: rgba(28, 62, 92, 0.5); }
 
 .custom-select {
   display: inline-block;
@@ -2557,9 +2557,9 @@ input[type="button"].btn-block {
   border-radius: 0.25rem;
   appearance: none; }
   .custom-select:focus {
-    border-color: #bb76b2;
+    border-color: #3a80be;
     outline: 0;
-    box-shadow: 0 0 0 0.2rem rgba(187, 118, 178, 0.5); }
+    box-shadow: 0 0 0 0.2rem rgba(58, 128, 190, 0.5); }
     .custom-select:focus::-ms-value {
       color: #495057;
       background-color: #fff; }
@@ -2600,10 +2600,10 @@ input[type="button"].btn-block {
   margin: 0;
   opacity: 0; }
   .custom-file-input:focus ~ .custom-file-label {
-    border-color: #bb76b2;
-    box-shadow: 0 0 0 0.2rem rgba(119, 59, 111, 0.25); }
+    border-color: #3a80be;
+    box-shadow: 0 0 0 0.2rem rgba(28, 62, 92, 0.25); }
     .custom-file-input:focus ~ .custom-file-label::after {
-      border-color: #bb76b2; }
+      border-color: #3a80be; }
   .custom-file-input:disabled ~ .custom-file-label {
     background-color: #e9ecef; }
   .custom-file-input:lang(en) ~ .custom-file-label::after {
@@ -2646,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(119, 59, 111, 0.25); }
+      box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(28, 62, 92, 0.25); }
     .custom-range:focus::-moz-range-thumb {
-      box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(119, 59, 111, 0.25); }
+      box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(28, 62, 92, 0.25); }
     .custom-range:focus::-ms-thumb {
-      box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(119, 59, 111, 0.25); }
+      box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(28, 62, 92, 0.25); }
   .custom-range::-moz-focus-outer {
     border: 0; }
   .custom-range::-webkit-slider-thumb {
     width: 1rem;
     height: 1rem;
     margin-top: -0.25rem;
-    background-color: #773b6f;
+    background-color: #1c3e5c;
     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;
@@ -2666,7 +2666,7 @@ input[type="button"].btn-block {
       .custom-range::-webkit-slider-thumb {
         transition: none; } }
     .custom-range::-webkit-slider-thumb:active {
-      background-color: #cc98c5; }
+      background-color: #5d99ce; }
   .custom-range::-webkit-slider-runnable-track {
     width: 100%;
     height: 0.5rem;
@@ -2678,7 +2678,7 @@ input[type="button"].btn-block {
   .custom-range::-moz-range-thumb {
     width: 1rem;
     height: 1rem;
-    background-color: #773b6f;
+    background-color: #1c3e5c;
     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;
@@ -2687,7 +2687,7 @@ input[type="button"].btn-block {
       .custom-range::-moz-range-thumb {
         transition: none; } }
     .custom-range::-moz-range-thumb:active {
-      background-color: #cc98c5; }
+      background-color: #5d99ce; }
   .custom-range::-moz-range-track {
     width: 100%;
     height: 0.5rem;
@@ -2702,7 +2702,7 @@ input[type="button"].btn-block {
     margin-top: 0;
     margin-right: 0.2rem;
     margin-left: 0.2rem;
-    background-color: #773b6f;
+    background-color: #1c3e5c;
     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;
@@ -2711,7 +2711,7 @@ input[type="button"].btn-block {
       .custom-range::-ms-thumb {
         transition: none; } }
     .custom-range::-ms-thumb:active {
-      background-color: #cc98c5; }
+      background-color: #5d99ce; }
   .custom-range::-ms-track {
     width: 100%;
     height: 0.5rem;
@@ -2783,7 +2783,7 @@ input[type="button"].btn-block {
 .nav-pills .nav-link.active,
 .nav-pills .show > .nav-link {
   color: #fff;
-  background-color: #773b6f; }
+  background-color: #1c3e5c; }
 
 .nav-fill .nav-item {
   flex: 1 1 auto;
@@ -3284,19 +3284,19 @@ input[type="button"].btn-block {
   padding: 0.5rem 0.75rem;
   margin-left: -1px;
   line-height: 1.25;
-  color: #773b6f;
+  color: #1c3e5c;
   background-color: #fff;
   border: 1px solid #dee2e6; }
   .page-link:hover {
     z-index: 2;
-    color: #44223f;
+    color: #0a1621;
     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(119, 59, 111, 0.25); }
+    box-shadow: 0 0 0 0.2rem rgba(28, 62, 92, 0.25); }
   .page-link:not(:disabled):not(.disabled) {
     cursor: pointer; }
 
@@ -3312,8 +3312,8 @@ input[type="button"].btn-block {
 .page-item.active .page-link {
   z-index: 1;
   color: #fff;
-  background-color: #773b6f;
-  border-color: #773b6f; }
+  background-color: #1c3e5c;
+  border-color: #1c3e5c; }
 
 .page-item.disabled .page-link {
   color: #6c757d;
@@ -3372,19 +3372,19 @@ input[type="button"].btn-block {
 
 .badge-primary {
   color: #fff;
-  background-color: #773b6f; }
+  background-color: #1c3e5c; }
   .badge-primary[href]:hover, .badge-primary[href]:focus {
     color: #fff;
     text-decoration: none;
-    background-color: #552a4f; }
+    background-color: #102435; }
 
 .badge-secondary {
   color: #212529;
-  background-color: #bdbdbd; }
+  background-color: #b6b6ba; }
   .badge-secondary[href]:hover, .badge-secondary[href]:focus {
     color: #212529;
     text-decoration: none;
-    background-color: #a4a4a4; }
+    background-color: #9c9ca1; }
 
 .badge-success {
   color: #fff;
@@ -3471,22 +3471,22 @@ input[type="button"].btn-block {
     color: inherit; }
 
 .alert-primary {
-  color: #3e1f3a;
-  background-color: #e4d8e2;
-  border-color: #d9c8d7; }
+  color: #0f2030;
+  background-color: #d2d8de;
+  border-color: #bfc9d1; }
   .alert-primary hr {
-    border-top-color: #cfb9cc; }
+    border-top-color: #b0bcc6; }
   .alert-primary .alert-link {
-    color: #1c0e1a; }
+    color: #030609; }
 
 .alert-secondary {
-  color: #626262;
-  background-color: #f2f2f2;
-  border-color: #ededed; }
+  color: #5f5f61;
+  background-color: #f0f0f1;
+  border-color: #ebebec; }
   .alert-secondary hr {
-    border-top-color: #e0e0e0; }
+    border-top-color: #dedee0; }
   .alert-secondary .alert-link {
-    color: #494949; }
+    color: #464647; }
 
 .alert-success {
   color: #155724;
@@ -3563,7 +3563,7 @@ input[type="button"].btn-block {
   color: #fff;
   text-align: center;
   white-space: nowrap;
-  background-color: #773b6f;
+  background-color: #1c3e5c;
   transition: width 0.6s ease; }
   @media screen and (prefers-reduced-motion: reduce) {
     .progress-bar {
@@ -3624,8 +3624,8 @@ input[type="button"].btn-block {
   .list-group-item.active {
     z-index: 2;
     color: #fff;
-    background-color: #773b6f;
-    border-color: #773b6f; }
+    background-color: #1c3e5c;
+    border-color: #1c3e5c; }
 
 .list-group-flush .list-group-item {
   border-right: 0;
@@ -3639,26 +3639,26 @@ input[type="button"].btn-block {
   border-bottom: 0; }
 
 .list-group-item-primary {
-  color: #3e1f3a;
-  background-color: #d9c8d7; }
+  color: #0f2030;
+  background-color: #bfc9d1; }
   .list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {
-    color: #3e1f3a;
-    background-color: #cfb9cc; }
+    color: #0f2030;
+    background-color: #b0bcc6; }
   .list-group-item-primary.list-group-item-action.active {
     color: #fff;
-    background-color: #3e1f3a;
-    border-color: #3e1f3a; }
+    background-color: #0f2030;
+    border-color: #0f2030; }
 
 .list-group-item-secondary {
-  color: #626262;
-  background-color: #ededed; }
+  color: #5f5f61;
+  background-color: #ebebec; }
   .list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {
-    color: #626262;
-    background-color: #e0e0e0; }
+    color: #5f5f61;
+    background-color: #dedee0; }
   .list-group-item-secondary.list-group-item-action.active {
     color: #fff;
-    background-color: #626262;
-    border-color: #626262; }
+    background-color: #5f5f61;
+    border-color: #5f5f61; }
 
 .list-group-item-success {
   color: #155724;
@@ -4283,20 +4283,20 @@ button.close {
   vertical-align: text-top !important; }
 
 .bg-primary {
-  background-color: #773b6f !important; }
+  background-color: #1c3e5c !important; }
 
 a.bg-primary:hover, a.bg-primary:focus,
 button.bg-primary:hover,
 button.bg-primary:focus {
-  background-color: #552a4f !important; }
+  background-color: #102435 !important; }
 
 .bg-secondary {
-  background-color: #bdbdbd !important; }
+  background-color: #b6b6ba !important; }
 
 a.bg-secondary:hover, a.bg-secondary:focus,
 button.bg-secondary:hover,
 button.bg-secondary:focus {
-  background-color: #a4a4a4 !important; }
+  background-color: #9c9ca1 !important; }
 
 .bg-success {
   background-color: #28a745 !important; }
@@ -4383,10 +4383,10 @@ button.bg-dark:focus {
   border-left: 0 !important; }
 
 .border-primary {
-  border-color: #773b6f !important; }
+  border-color: #1c3e5c !important; }
 
 .border-secondary {
-  border-color: #bdbdbd !important; }
+  border-color: #b6b6ba !important; }
 
 .border-success {
   border-color: #28a745 !important; }
@@ -6187,16 +6187,16 @@ button.bg-dark:focus {
   color: #fff !important; }
 
 .text-primary {
-  color: #773b6f !important; }
+  color: #1c3e5c !important; }
 
 a.text-primary:hover, a.text-primary:focus {
-  color: #552a4f !important; }
+  color: #102435 !important; }
 
 .text-secondary {
-  color: #bdbdbd !important; }
+  color: #b6b6ba !important; }
 
 a.text-secondary:hover, a.text-secondary:focus {
-  color: #a4a4a4 !important; }
+  color: #9c9ca1 !important; }
 
 .text-success {
   color: #28a745 !important; }
@@ -6323,14 +6323,18 @@ a.text-dark:hover, a.text-dark:focus {
 /* font color */
 /* font color */
 /* Data colors */
+/* For alt text */
+img {
+  font-weight: 400 !important; }
+
 .react-grid-item {
   background-color: white;
-  border: 1px solid #e1e1e1;
+  border: 1px solid #e8e8ec;
   border-radius: 0.25rem; }
 
 .react-grid-item-header {
-  color: #8d8d8d;
-  background-color: #e1e1e1;
+  color: #86868a;
+  background-color: #e8e8ec;
   font-weight: bold;
   padding: .3rem;
   /* Note: must be same as the Bootstrap table for nice alignment */
@@ -6355,8 +6359,8 @@ a.text-dark:hover, a.text-dark:focus {
   top: 2.25em;
   /* Check with height of .react-grid-item-header */
   left: 0.25em;
-  border: 0.55rem solid #e1e1e1;
-  border-top: 0.55rem solid #a7689d;
+  border: 0.55rem solid #e8e8ec;
+  border-top: 0.55rem solid #4a6889;
   border-radius: 50%;
   width: 3rem;
   height: 3rem;
@@ -6385,41 +6389,10 @@ a.text-dark:hover, a.text-dark:focus {
   text-align: center;
   font-weight: 700; }
 
-.toolbar-top {
-  background-color: #a7689d;
-  color: #ffffff;
-  padding: 5px 10px;
-  /* Note: same padding as ResponsiveGridLayout */
-  width: 100%;
-  overflow: visible; }
-
-.toolbar-top {
-  font-weight: 500; }
-
-.toolbar-top .btn-info:not(:disabled):not(.disabled).active,
-.sts-toolbar .btn-info:not(:disabled):not(.disabled).active,
-.toolbar-top .btn-info:not(:disabled):not(.disabled):active,
-.toolbar-top .show > .btn-info.dropdown-toggle {
-  color: white;
-  background-color: #8d8d8d;
-  border-color: #8d8d8d; }
-
-.toolbar-top .btn-info,
-.sts-toolbar .btn-info {
-  color: white;
-  background-color: #bdbdbd;
-  border-color: #bdbdbd; }
-
-.toolbar-top .btn-info:hover,
-.sts-toolbar .btn-info:hover {
-  color: white;
-  background-color: #8d8d8d;
-  border-color: #8d8d8d; }
-
 .tooltip > .tooltip-inner {
   background-color: white !important;
   color: black !important;
-  border: 1px solid #8d8d8d; }
+  border: 1px solid #86868a; }
 
 .react-select-container {
   min-width: 20rem; }
@@ -6434,4 +6407,8 @@ a.text-dark:hover, a.text-dark:focus {
   border: none; }
 
 .form-input button:hover {
-  background-color: #e1e1e1 !important; }
+  background-color: #e8e8ec !important; }
+
+/* Padding on column in bootstrap grid */
+.row .col-padding {
+  padding-top: 15px; }
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/LOFARDefinitions.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/LOFARDefinitions.js
index f1c0459dbdcc0c20ce539bf024a17775c1a2f0b2..f40e48031d0706909593487d33fd8ee7103e5a8c 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/LOFARDefinitions.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/LOFARDefinitions.js
@@ -1,23 +1,77 @@
 export const HBATilesPerStationType = {
-  C: 48,
-  R: 48,
+  C: 96,
+  R: 96,
   I: 96
-}
+};
 
 export const LBHAntennasPerStationType = {
   C: 48,
   R: 48,
-  I: 48
-}
+  I: 96
+};
 
 export const LBLAntennasPerStationType = {
   C: 48,
   R: 48,
   I: 48
-}
+};
+
+export const AntennaIdsPerTypeStationType = {
+  C: {
+    HBA: {
+      start: 0,
+      end: 96,
+      number: 96
+    },
+    LBL: {
+      start: 48,
+      end: 96,
+      number: 48
+    },
+    LBH: {
+      start: 0,
+      end: 48,
+      number: 48
+    }
+  },
+  R: {
+    HBA: {
+      start: 0,
+      end: 96,
+      number: 96
+    },
+    LBL: {
+      start: 48,
+      end: 96,
+      number: 48
+    },
+    LBH: {
+      start: 0,
+      end: 48,
+      number: 48
+    }
+  },
+  I: {
+    HBA: {
+      start: 0,
+      end: 96,
+      number: 96
+    },
+    LBH: {
+      start: 0,
+      end: 96,
+      number: 96
+    },
+    LBL: {
+      start: 0,
+      end: 0,
+      number: 0
+    }
+  },
+};
 
 export function stationTypeFromName(stationName){
-  if(stationName === undefined) return undefined
+  if(stationName === undefined) return undefined;
   if(stationName.includes('CS')) return 'C';
   if(stationName.includes('RS')) return 'R';
   return 'I'
@@ -27,3 +81,8 @@ export function getInspectPageURLFromSASid(sasId){
   const url =`https://proxy.lofar.eu/inspect/HTML/${sasId}/index.html`
   return url
 }
+
+export const LOFARTESTS = {
+    S: "StationTest",
+    R: "RTSM"
+}
diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/utils.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/utils.js
index bdaf6ab2677a4fc813ef527034d3f3b8482b0b79..b635c0c9e109a2f14ae6b6d3754ff29ea212e3aa 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/utils.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/utils/utils.js
@@ -1,3 +1,5 @@
+import moment from "moment";
+
 let lastId = 0;
 
 function unique_id(prefix='id_') {
@@ -32,5 +34,20 @@ function stringSort(a, b, caseInsensitive = true) {
     }
     return 0;
 }
+function renderDateRange(data){
+    const lastTest = data[0];
+    const firstTest = data[data.length - 1];
+    const duration = moment.duration(moment(lastTest.end_date)-moment(firstTest.start_date));
+    const years = duration.years();
+    const days = duration.days();
+    const months = duration.months();
+    const hours = duration.hours();
+    let string = `${data.length} obs `;
+    if (years > 0) {string += `${years}Y`;}
+    if (months > 0) {string += `${months}M`;}
+    if (days > 0) {string += `${days}d`;}
+    if (hours > 0) {string += `${hours}h`;}
+    return string;
+}
 
-export { unique_id, capitalize, composeQueryString, stringSort };
+export { unique_id, capitalize, composeQueryString, stringSort, renderDateRange };