From 7c0a529cdf06c86b0bc8fd334dc5cf964b6d3fa7 Mon Sep 17 00:00:00 2001
From: rbokhorst <rbokhorst@astron.nl>
Date: Wed, 21 Nov 2018 19:16:21 +0000
Subject: [PATCH] OSB-31: highlight of obs on dashboard

---
 .../src/components/LatestObservations.js      |  12 ++
 .../src/components/StationOverview.js         | 165 ++++++++----------
 .../src/components/StationTestView.js         |   2 +
 3 files changed, 84 insertions(+), 95 deletions(-)

diff --git a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.js b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.js
index 530012f72fc..8200d851c2a 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/LatestObservations.js
@@ -4,6 +4,7 @@ import { unique_id } from '../utils/utils.js'
 import AutoLoadWrapper from '../utils/autoLoader.js'
 import * as moment from 'moment';
 import { datetime_format } from '../utils/constants'
+import { highlightClass, unHighlightClass } from '../utils/highlightClass'
 import ObservationInspectTag from './ObservationInspectTag.js'
 // CSS
 import './LatestObservations.css'
@@ -46,6 +47,17 @@ class SORow extends Component {
     togglePopover(){
         this.setState({popoverOpen: !this.state.popoverOpen});
     }
+
+    componentDidUpdate(prevProps, prevState) {
+        if (this.state.popoverOpen !== prevState.popoverOpen) {
+            if (this.state.popoverOpen) {
+                highlightClass('obs-'+this.props.data.observation_id);
+            } else {
+                unHighlightClass('obs-'+this.props.data.observation_id);
+            }
+        }
+    }
+
     render() {
         const data = this.props.data;
         const station_involved_list = this.getStationInvolvedList();
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 551053e73fe..15cbbfb425c 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationOverview.js
@@ -1,4 +1,4 @@
-import React, {Component} from 'react';
+import React, {Component, PureComponent} from 'react';
 import {withRouter} from "react-router";
 import {Table, Popover, PopoverHeader, PopoverBody} from 'reactstrap';
 import {unique_id} from '../utils/utils.js'
@@ -12,7 +12,7 @@ import './StationOverview.css'
 /**
  * Badge; class to render a badge with label and pill.
  */
-class Badge extends Component {
+class Badge extends PureComponent {
 
     getClass() {
         let cnt = this.props.count;
@@ -28,28 +28,49 @@ class Badge extends Component {
 
     render() {
         let props = this.props;
-        return (<div id={props.myid} className={"so-badge"} onMouseOver={props.togglePopOver} onMouseOut={props.togglePopOver}>
+        return (<div id={props.myid} className={"so-badge "+this.props.className} onMouseOver={props.togglePopOver} onMouseOut={props.togglePopOver}>
             {props.label}
             <span className={this.getClass()}>{props.count}</span>
         </div>);
     }
 }
 
+
+const SOPopover = ({target, isOpen, togglePopover, title, lines}) => {
+
+    if (!isOpen) {
+        return null;
+    }
+
+    return (<Popover placement="auto" isOpen={isOpen} target={target} toggle={togglePopover}>
+        <PopoverHeader>
+            {title}
+        </PopoverHeader>
+        <PopoverBody>
+            <Table borderless size="sm">
+                <tbody>
+                    {lines.map( (obj, id) => <tr>
+                            <th>{obj.th}</th>
+                            <td>{obj.td}</td>
+                        </tr>)
+                    }
+                </tbody>
+            </Table>
+        </PopoverBody>
+    </Popover>);
+}
+
+
 /**
  * StationTestBadge; class to render one stationtest badge in the SORow.
  */
 class StationTestBadgeC extends Component {
 
-    constructor(props) {
-        super(props);
+    id = unique_id();
 
-        this.id = unique_id();
-        this.togglePopover = this.togglePopover.bind(this);
-        this.onClick = this.onClick.bind(this);
-        this.state = {
-            popoverOpen: false
-        };
-    }
+    state = {
+        popoverOpen: false
+    };
 
     getClass() {
         let total = this.props.data.total_component_errors;
@@ -63,70 +84,47 @@ class StationTestBadgeC extends Component {
         return `so-stationtestbadge ${color}`;
     }
 
-    onClick() {
+    onClick = () => {
         let station = this.props.station;
         this.props.history.push(`/station_overview?station=${station}`);
     }
 
-    togglePopover() {
+    togglePopover = () => {
         this.setState({
             popoverOpen: !this.state.popoverOpen
         });
     }
 
-    renderPopOver() {
+    popoverLines() {
         let data = this.props.data;
         let summary = data.component_error_summary;
-        let rows = [];
+
+        let lines = [
+            { th: 'Start:' , td: moment.utc(data.start_datetime).format(datetime_format)},
+            { th: 'End:',    td: moment.utc(data.end_datetime).format(datetime_format)},
+            { th: 'Checks:', td: data.checks}
+        ];
 
         let components = Object.keys(summary).sort();
         components.forEach((component) => {
             let comp_sum = summary[component];
             let errors = Object.keys(comp_sum).sort();
-            rows.push(<tr key={component}>
-                <th>{component}</th>
-                <td>{errors.map((e, id) => <Badge key={id} count={comp_sum[e]} label={e}/>)}</td>
-            </tr>);
+            lines.push({
+                th: component, td: errors.map((e, id) => <Badge key={id} count={comp_sum[e]} label={e}/>)
+            });
         });
 
-        return (<Popover placement="auto" isOpen={this.state.popoverOpen} target={this.id} toggle={this.togglePopover}>
-            <PopoverHeader>
-                {this.props.station}
-            </PopoverHeader>
-            <PopoverBody>
-                <Table borderless size="sm">
-                    <tbody>
-                        <tr>
-                            <th>Start:</th>
-                            <td>{moment.utc(data.start_datetime).format(datetime_format)}</td>
-                        </tr>
-                        <tr>
-                            <th>End:</th>
-                            <td>{moment.utc(data.end_datetime).format(datetime_format)}</td>
-                        </tr>
-                        <tr>
-                            <th>Checks:</th>
-                            <td>{data.checks}</td>
-                        </tr>
-                        {rows}
-                    </tbody>
-                </Table>
-            </PopoverBody>
-        </Popover>);
+        return lines;
     }
 
     render() {
-        let popOver = "";
-
-        if (this.state.popoverOpen) {
-            popOver = this.renderPopOver();
-        }
+        let lines = this.state.popoverOpen ? this.popoverLines() : [];
 
         return (<div>
             <div id={this.id} onClick={this.onClick} onMouseOver={this.togglePopover} onMouseOut={this.togglePopover} className={this.getClass()}>
                 {this.props.data.total_component_errors}
             </div>
-            {popOver}
+            <SOPopover target={this.id} isOpen={this.state.popoverOpen} togglePopover={this.togglePopover} title={this.props.data.observation_id} lines={lines} />
         </div>);
     }
 }
@@ -138,15 +136,11 @@ const StationTestBadge = withRouter(StationTestBadgeC);
  */
 class RTSMBadge extends Component {
 
-    constructor(props) {
-        super(props);
+    id = unique_id();
 
-        this.id = unique_id();
-        this.togglePopover = this.togglePopover.bind(this);
-        this.state = {
-            popoverOpen: false
-        };
-    }
+    state = {
+        popoverOpen: false
+    };
 
     getClass() {
         let total = this.props.data.total_component_errors;
@@ -160,59 +154,40 @@ class RTSMBadge extends Component {
         return "so-pill " + color;
     }
 
-    togglePopover() {
+    togglePopover = () => {
         this.setState({
             popoverOpen: !this.state.popoverOpen
         });
     }
 
-    renderPopOver() {
+    popoverLines() {
         let data = this.props.data;
-        let summary = data.error_summary;
-        let badges = "";
-
-        let errors = Object.keys(summary).sort();
-        badges = errors.map((e, i) => <Badge key={i} count={summary[e]} label={e}/>);
-
-        return (<Popover placement="auto" isOpen={this.state.popoverOpen} target={this.id} toggle={this.togglePopover}>
-            <PopoverHeader>
-                {data.observation_id}
-            </PopoverHeader>
-            <PopoverBody>
-                <Table borderless size="sm">
-                    <tbody>
-                        <tr>
-                            <th>Start:</th>
-                            <td>{moment.utc(data.start_datetime).format(datetime_format)}</td>
-                        </tr>
-                        <tr>
-                            <th>End:</th>
-                            <td>{moment.utc(data.end_datetime).format(datetime_format)}</td>
-                        </tr>
-                        <tr>
-                            <th>Mode:</th>
-                            <td>{data.mode}</td>
-                        </tr>
-                        <tr>
-                            <th>Errors:</th>
-                            <td>{badges}</td>
-                        </tr>
-                    </tbody>
-                </Table>
-            </PopoverBody>
-        </Popover>);
+
+        let errors = Object.keys(data.error_summary).sort();
+        let badges = errors.map((e, i) => <Badge key={i} count={data.error_summary[e]} label={e}/>);
+
+        let lines = [
+            { th: 'Start:' , td: moment.utc(data.start_datetime).format(datetime_format)},
+            { th: 'End:',    td: moment.utc(data.end_datetime).format(datetime_format)},
+            { th: 'Mode:',   td: data.mode },
+            { th: 'Errors:', td: badges}
+        ];
+
+        return lines;
     }
 
     render() {
         let popOver = "";
         let data = this.props.data;
 
+        let lines = [];
         if (this.state.popoverOpen) {
-            popOver = this.renderPopOver();
+            lines = this.popoverLines();
         }
 
         return (<React.Fragment>
-            <Badge myid={this.id} className="so-rtsmbadge" togglePopOver={this.togglePopover} count={data.total_component_errors} label={data.observation_id}/> {popOver}
+            <Badge myid={this.id} className={'obs-'+data.observation_id} togglePopOver={this.togglePopover} count={data.total_component_errors} label={data.observation_id}/>
+            <SOPopover target={this.id} isOpen={this.state.popoverOpen} togglePopover={this.togglePopover} title={data.observation_id} lines={lines} />
         </React.Fragment>);
     }
 }
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 741261fec8c..1553575993b 100644
--- a/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.js
+++ b/LCU/Maintenance/MDB_WebView/maintenancedb_view/src/components/StationTestView.js
@@ -198,6 +198,7 @@ class TestLineC extends Component {
 
         // 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}>
@@ -405,6 +406,7 @@ class ComponentClass extends Component {
  * StationTestView class.
  */
 class StationTestViewC extends Component {
+
     constructor(props) {
         super(props);
         this.toggle = this.toggle.bind(this);
-- 
GitLab