From eacbac6aad30132168c046f5d99708a8f70ea596 Mon Sep 17 00:00:00 2001
From: rukmini-bose <48999852+rukmini-bose@users.noreply.github.com>
Date: Thu, 7 Jul 2022 13:56:54 -0700
Subject: [PATCH] Fix for Fault Management Visual Bugs  (#5376)

* Closes #5365
* General visual improvements

Co-authored-by: Charles Hacskaylo <charlesh88@gmail.com>
Co-authored-by: Andrew Henry <akhenry@gmail.com>
---
 .../FaultManagementListHeader.vue             |  18 +-
 .../FaultManagementListItem.vue               |  63 ++--
 .../FaultManagementListView.vue               |  48 +--
 .../faultManagement/FaultManagementPlugin.js  |   2 +-
 .../FaultManagementToolbar.vue                |   2 +-
 .../faultManagement/FaultManagementView.vue   |   9 +-
 .../faultManagement/fault-manager.scss        | 340 ++++++++++--------
 src/ui/components/ObjectFrame.vue             |  11 +-
 src/ui/components/object-frame.scss           |   3 +-
 9 files changed, 272 insertions(+), 224 deletions(-)

diff --git a/src/plugins/faultManagement/FaultManagementListHeader.vue b/src/plugins/faultManagement/FaultManagementListHeader.vue
index 81ee602aa1..11c3bd6286 100644
--- a/src/plugins/faultManagement/FaultManagementListHeader.vue
+++ b/src/plugins/faultManagement/FaultManagementListHeader.vue
@@ -21,23 +21,25 @@
  *****************************************************************************/
 
 <template>
-<div class="c-fault-mgmt__list-header c-fault-mgmt__list">
-    <div class="c-fault-mgmt__checkbox">
+<div class="c-fault-mgmt-item-header c-fault-mgmt__list-header c-fault-mgmt__list">
+    <div class="c-fault-mgmt-item-header c-fault-mgmt__checkbox">
         <input
             type="checkbox"
             :checked="isSelectAll"
             @input="selectAll"
         >
     </div>
-    <div class="c-fault-mgmt__list-content">
-        <div class="c-fault-mgmt__list-header-results"> {{ totalFaultsCount }} Results </div>
+    <div class="c-fault-mgmt-item-header c-fault-mgmt__list-header-results c-fault-mgmt__list-severity">
+        {{ totalFaultsCount }} Results
+    </div>
+    <div class="c-fault-mgmt__list-header-content">
         <div class="c-fault-mgmt__list-content-right">
-            <div class="c-fault-mgmt__list-header-tripVal c-fault-mgmt__list-trigVal">Trip Value</div>
-            <div class="c-fault-mgmt__list-header-liveVal c-fault-mgmt__list-curVal">Live Value</div>
-            <div class="c-fault-mgmt__list-header-trigTime c-fault-mgmt__list-trigTime">Trigger Time</div>
+            <div class="c-fault-mgmt-item-header c-fault-mgmt__list-header-tripVal">Trip Value</div>
+            <div class="c-fault-mgmt-item-header c-fault-mgmt__list-header-liveVal">Live Value</div>
+            <div class="c-fault-mgmt-item-header c-fault-mgmt__list-header-trigTime">Trigger Time</div>
         </div>
     </div>
-    <div class="c-fault-mgmt__list-action-wrapper">
+    <div class=" c-fault-mgmt-item-header c-fault-mgmt__list-header-action-wrapper">
         <div class="c-fault-mgmt__list-header-sortButton c-fault-mgmt__list-action-button">
             <SelectField
                 class="c-fault-mgmt-viewButton"
diff --git a/src/plugins/faultManagement/FaultManagementListItem.vue b/src/plugins/faultManagement/FaultManagementListItem.vue
index 1acb39a9cb..764fa70de8 100644
--- a/src/plugins/faultManagement/FaultManagementListItem.vue
+++ b/src/plugins/faultManagement/FaultManagementListItem.vue
@@ -26,49 +26,57 @@
     :class="[
         {'is-selected': isSelected},
         {'is-unacknowledged': !fault.acknowledged},
-        {'is-shelved': fault.shelved}
+        {'is-shelved': fault.shelved},
+        {'is-acknowledged': fault.acknowledged}
     ]"
 >
-    <div class="c-fault-mgmt__checkbox">
+    <div class="c-fault-mgmt-item c-fault-mgmt__list-checkbox">
         <input
             type="checkbox"
             :checked="isSelected"
             @input="toggleSelected"
         >
     </div>
-    <div
-        class="c-fault-mgmt__list-severity"
-        :title="fault.severity"
-        :class="[
-            'is-severity-' + severity
-        ]"
-    >
+    <div class="c-fault-mgmt-item">
+        <div
+            class="c-fault-mgmt__list-severity"
+            :title="fault.severity"
+            :class="[
+                'is-severity-' + severity
+            ]"
+        >
+        </div>
     </div>
-    <div class="c-fault-mgmt__list-content">
-        <div class="c-fault-mgmt__list-pathname">
+    <div class="c-fault-mgmt-item c-fault-mgmt__list-content">
+        <div class="c-fault-mgmt-item c-fault-mgmt__list-pathname">
             <div class="c-fault-mgmt__list-path">{{ fault.namespace }}</div>
             <div class="c-fault-mgmt__list-faultname">{{ fault.name }}</div>
         </div>
         <div class="c-fault-mgmt__list-content-right">
-            <div
-                class="c-fault-mgmt__list-trigVal"
-                :class="tripValueClassname"
-                title="Trip Value"
-            >{{ fault.triggerValueInfo.value }}</div>
-            <div
-                class="c-fault-mgmt__list-curVal"
-                :class="liveValueClassname"
-                title="Live Value"
-            >
-                {{ fault.currentValueInfo.value }}
+            <div class="c-fault-mgmt-item c-fault-mgmt__list-trigVal">
+                <div
+                    class="c-fault-mgmt-item__value"
+                    :class="tripValueClassname"
+                    title="Trip Value"
+                >{{ fault.triggerValueInfo.value }}</div>
             </div>
-            <div
-                class="c-fault-mgmt__list-trigTime"
-            >{{ fault.triggerTime }}
+            <div class="c-fault-mgmt-item c-fault-mgmt__list-curVal">
+                <div
+                    class="c-fault-mgmt-item__value"
+                    :class="liveValueClassname"
+                    title="Live Value"
+                >{{ fault.currentValueInfo.value }}</div>
+            </div>
+            <div class="c-fault-mgmt-item c-fault-mgmt__list-trigTime">
+                <div
+                    class="c-fault-mgmt-item__value"
+                    title="Last Trigger Time"
+                >{{ fault.triggerTime }}
+                </div>
             </div>
         </div>
     </div>
-    <div class="c-fault-mgmt__list-action-wrapper">
+    <div class="c-fault-mgmt-item c-fault-mgmt__list-action-wrapper">
         <button
             class="c-fault-mgmt__list-action-button l-browse-bar__actions c-icon-button icon-3-dots"
             title="Disposition Actions"
@@ -77,7 +85,6 @@
     </div>
 </div>
 </template>
-
 <script>
 
 const RANGE_CONDITION_CLASS = {
@@ -149,7 +156,7 @@ export default {
 
             const menuItems = [
                 {
-                    cssClass: 'icon-bell',
+                    cssClass: 'icon-check',
                     isDisabled: this.fault.acknowledged,
                     name: 'Acknowledge',
                     description: '',
diff --git a/src/plugins/faultManagement/FaultManagementListView.vue b/src/plugins/faultManagement/FaultManagementListView.vue
index 15f214fa92..e99d6a7ba5 100644
--- a/src/plugins/faultManagement/FaultManagementListView.vue
+++ b/src/plugins/faultManagement/FaultManagementListView.vue
@@ -35,25 +35,31 @@
         @shelveSelected="toggleShelveSelected"
     />
 
-    <FaultManagementListHeader
-        class="header"
-        :selected-faults="Object.values(selectedFaults)"
-        :total-faults-count="filteredFaultsList.length"
-        @selectAll="selectAll"
-        @sortChanged="sortChanged"
-    />
+    <div class="c-faults-list-view-header-item-container-wrapper">
+        <div class="c-faults-list-view-header-item-container">
+            <FaultManagementListHeader
+                class="header"
+                :selected-faults="Object.values(selectedFaults)"
+                :total-faults-count="filteredFaultsList.length"
+                @selectAll="selectAll"
+                @sortChanged="sortChanged"
+            />
 
-    <template v-if="filteredFaultsList.length > 0">
-        <FaultManagementListItem
-            v-for="fault of filteredFaultsList"
-            :key="fault.id"
-            :fault="fault"
-            :is-selected="isSelected(fault)"
-            @toggleSelected="toggleSelected"
-            @acknowledgeSelected="toggleAcknowledgeSelected"
-            @shelveSelected="toggleShelveSelected"
-        />
-    </template>
+            <div class="c-faults-list-view-item-body">
+                <template v-if="filteredFaultsList.length > 0">
+                    <FaultManagementListItem
+                        v-for="fault of filteredFaultsList"
+                        :key="fault.id"
+                        :fault="fault"
+                        :is-selected="isSelected(fault)"
+                        @toggleSelected="toggleSelected"
+                        @acknowledgeSelected="toggleAcknowledgeSelected"
+                        @shelveSelected="toggleShelveSelected"
+                    />
+                </template>
+            </div>
+        </div>
+    </div>
 </div>
 </template>
 
@@ -195,7 +201,7 @@ export default {
                             {
                                 key: 'comment',
                                 control: 'textarea',
-                                name: 'Comment',
+                                name: 'Optional comment',
                                 pattern: '\\S+',
                                 required: false,
                                 cssClass: 'l-input-lg',
@@ -237,7 +243,7 @@ export default {
                                 {
                                     key: 'comment',
                                     control: 'textarea',
-                                    name: 'Comment',
+                                    name: 'Optional comment',
                                     pattern: '\\S+',
                                     required: false,
                                     cssClass: 'l-input-lg',
@@ -246,7 +252,7 @@ export default {
                                 {
                                     key: 'shelveDuration',
                                     control: 'select',
-                                    name: 'Shelve Duration',
+                                    name: 'Shelve duration',
                                     options: FAULT_MANAGEMENT_SHELVE_DURATIONS_IN_MS,
                                     required: false,
                                     cssClass: 'l-input-lg',
diff --git a/src/plugins/faultManagement/FaultManagementPlugin.js b/src/plugins/faultManagement/FaultManagementPlugin.js
index 13e5a5dd60..93dda8f5b7 100644
--- a/src/plugins/faultManagement/FaultManagementPlugin.js
+++ b/src/plugins/faultManagement/FaultManagementPlugin.js
@@ -32,7 +32,7 @@ export default function FaultManagementPlugin() {
             name: 'Fault Management',
             creatable: false,
             description: 'Fault Management View',
-            cssClass: 'icon-telemetry'
+            cssClass: 'icon-bell'
         });
 
         openmct.objectViews.addProvider(new FaultManagementViewProvider(openmct));
diff --git a/src/plugins/faultManagement/FaultManagementToolbar.vue b/src/plugins/faultManagement/FaultManagementToolbar.vue
index c366081d9f..6134a449bd 100644
--- a/src/plugins/faultManagement/FaultManagementToolbar.vue
+++ b/src/plugins/faultManagement/FaultManagementToolbar.vue
@@ -23,7 +23,7 @@
 <template>
 <div class="c-fault-mgmt__toolbar">
     <button
-        class="c-icon-button icon-bell"
+        class="c-icon-button icon-check"
         title="Acknowledge selected faults"
         :disabled="disableAcknowledge"
         @click="acknowledgeSelected"
diff --git a/src/plugins/faultManagement/FaultManagementView.vue b/src/plugins/faultManagement/FaultManagementView.vue
index 3ae0c9a2fb..71ba7cfe73 100644
--- a/src/plugins/faultManagement/FaultManagementView.vue
+++ b/src/plugins/faultManagement/FaultManagementView.vue
@@ -21,14 +21,13 @@
  *****************************************************************************/
 
 <template>
-<div class="c-fault-mgmt">
-    <FaultManagementListView
-        :faults-list="faultsList"
-    />
-</div>
+<FaultManagementListView
+    :faults-list="faultsList"
+/>
 </template>
 
 <script>
+
 import FaultManagementListView from './FaultManagementListView.vue';
 import { FAULT_MANAGEMENT_ALARMS, FAULT_MANAGEMENT_GLOBAL_ALARMS } from './constants';
 
diff --git a/src/plugins/faultManagement/fault-manager.scss b/src/plugins/faultManagement/fault-manager.scss
index 6b75e548ab..e1c97443de 100644
--- a/src/plugins/faultManagement/fault-manager.scss
+++ b/src/plugins/faultManagement/fault-manager.scss
@@ -19,216 +19,250 @@
  * this source code distribution or the Licensing information page available
  * at runtime from the About dialog for additional information.
  *****************************************************************************/
-
-/*********************************************** FAULT PROPERTIES */
-.is-severity-critical{
-    @include glyphBefore($glyph-icon-alert-triangle);
-    color: $colorStatusError;
-}
-
-.is-severity-warning{
-    @include glyphBefore($glyph-icon-alert-rect);
-    color: $colorStatusAlert;
-}
-
-.is-severity-watch{
-    @include glyphBefore($glyph-icon-info);
-    color: $colorCommand;
-}
-
-.is-unacknowledged{
-    .c-fault-mgmt__list-severity{
-        @include pulse($animName: severityAnim, $dur: 200ms);
-    }
-}
-
-.is-selected { 
-    background: $colorSelectedBg;
-}
-
-.is-shelved{
-    .c-fault-mgmt__list-content{
-        opacity: 50% !important;
-        font-style: italic;
-    }
-    .c-fault-mgmt__list-severity{
-        @include pulse($animName: shelvedAnim, $dur: 0ms);
-    }
-}
-
-
+$colorFaultItemFg: $colorBodyFg;
+$colorFaultItemFgEmphasis: $colorBodyFgEm;
+$colorFaultItemBg: pullForward($colorBodyBg, 5%);
 
 /*********************************************** SEARCH  */
-.c-fault-mgmt__search-row{
+.c-fault-mgmt__search-row {
     display: flex;
     align-items: center;
+    flex: 0 0 auto;
     > * + * {
        margin-left: 10px;
        float: right;
     }
 }
 
-.c-fault-mgmt-search{
+.c-fault-mgmt-search {
     width: 95%;
 }
 
 /*********************************************** TOOLBAR */
-.c-fault-mgmt__toolbar{
-    display: flex; 
+.c-fault-mgmt__toolbar {
+    display: flex;
     justify-content: center;
-    > * {
-        font-size: 1.25em;
+    flex: 0 0 auto;
+    > * + * {
+       margin-left: $interiorMargin;
     }
 }
 
 /*********************************************** LIST VIEW */
-.c-faults-list-view { 
+.c-faults-list-view {
     display: flex;
     flex-direction: column;
+    height: 100%;
+
     > * + * {
-        margin-top: $interiorMargin; 
+        margin-top: $interiorMargin;
     }
 }
 
+.c-faults-list-view-header-item-container {
+    display: grid;
+    width: 100%;
+    grid-template-columns: max-content max-content repeat(5,minmax(max-content, 20%)) max-content;
+    grid-row-gap: $interiorMargin;
 
-/*********************************************** FAULT ITEM */
-.c-fault-mgmt__list{
-    background: rgba($colorBodyFg, 0.1);
-    margin-bottom: 5px;
-    padding: 4px;
-    display: flex;
-    align-items: center;
-
-    > * {
-        margin-left: $interiorMargin;
+    &-wrapper {
+        flex: 1 1 auto;
+        padding-right: $interiorMargin; // Fend of from scrollbar
+        overflow-y: auto;
     }
-    
-    &-severity{
+
+    .--width-less-than-600 & {
+        grid-template-columns: max-content max-content 1fr 1fr max-content;
+    }
+}
+
+.c-faults-list-view-item-body {
+   display: contents;
+}
+
+/*********************************************** LIST */
+.c-fault-mgmt__list {
+    display: contents;
+    color: $colorFaultItemFg;
+
+    &-checkbox{
+        border-top-left-radius: 4px;
+        border-bottom-left-radius: 4px;
+    }
+
+    &-severity {
         font-size: 2em;
-        margin-left: $interiorMarginLg;
-     }
 
-    &-pathname{
-        flex-wrap: wrap;
-        flex: 1 1 auto;
-        
-    }
-    &-path{
-        font-size: .75em;
-    } 
+        &.is-severity-critical {
+            @include glyphBefore($glyph-icon-alert-triangle);
+            color: $colorStatusError;
+        }
 
-    &-faultname{
-        font-weight: bold;
-        font-size: 1.3em;
-    }
+        &.is-severity-warning {
+            @include glyphBefore($glyph-icon-alert-rect);
+            color: $colorStatusAlert;
+        }
 
-    &-content{
-        display: flex;
-        flex-wrap: wrap;
-        flex: 1 1 auto;
-        align-items: center;
-    }
-
-    &-content-right{
-        margin-left: auto;
-        display: flex;
-        flex-wrap: wrap;
-    }
-
-    &-trigVal, &-curVal, &-trigTime{
-        @include ellipsize;
-        border-radius: $controlCr;
-        padding: $interiorMargin;
-        width: 80px;
-        margin-right: $interiorMarginLg;
-
-    }
-
-    &-trigVal {
-        @include isLimit();
-        background: rgba($colorBodyFg, 0.25);
-    }
-
-    &-curVal {
-        @include isLimit();
-        background: rgba($colorBodyFg, 0.25);
-        &-alert{
-            background: $colorWarningHi;
+        &.is-severity-watch {
+            @include glyphBefore($glyph-icon-info);
+            color: $colorCommand;
         }
     }
 
-    &-trigTime{
-        width: auto;
+     &-content {
+        display: contents;
+
+        .--width-less-than-600 & {
+            display: flex;
+            flex-wrap: wrap;
+            grid-column: span 2;
+         }
     }
 
-    &-action-wrapper{
-        display: flex;
-        align-content: right;
-        width: 100px;
+    &-pathname {
+        padding-right: $interiorMarginLg;
+        overflow-wrap: anywhere;
+        min-width: 100px;
+
+    }
+    &-path {
+        font-size: .85em;
+        margin-left: $interiorMargin;
     }
 
-    &-action-button{
+    &-faultname{
+        font-size: 1.3em;
+        margin-left: $interiorMargin;
+    }
+
+    &-content-right {
+        display: contents;
+    }
+
+    &-trigTime {
+        grid-column: 6 / span 2;
+    }
+
+    &-action-wrapper {
+        text-align: right;
+        flex: 0 0 auto;
+        align-items: stretch;
+    }
+
+    &-action-button {
         flex: 0 0 auto;
         margin-left: auto;
-        justify-content: right;
+        text-align: right;
+    }
+
+    // STATES
+    &.is-unacknowledged {
+        color: $colorFaultItemFgEmphasis;
+        .c-fault-mgmt__list-severity {
+            @include pulse($animName: severityAnim, $dur: 200ms);
+        }
+    }
+
+    &.is-acknowledged,
+    &.is-shelved {
+        .c-fault-mgmt__list-severity {
+            &:before {
+                opacity: 60%;
+                //font-size: 1.5em;
+            }
+
+            &:after {
+                color: $colorFaultItemFgEmphasis;
+                display: block;
+                font-family: symbolsfont;
+                position: absolute;
+                //text-shadow: black 0 0 2px;
+                right: -3px;
+                bottom: -3px;
+                transform-origin: right bottom;
+                transform: scale(0.6);
+            }
+        }
+    }
+
+    &.is-shelved {
+        .c-fault-mgmt__list-pathname {
+            font-style: italic;
+        }
+    }
+
+    &.is-acknowledged .c-fault-mgmt__list-severity:after {
+        content: $glyph-icon-check;
+    }
+
+    &.is-shelved .c-fault-mgmt__list-severity:after {
+        content: $glyph-icon-timer;
     }
 }
 
 /*********************************************** LIST HEADER */
-.c-fault-mgmt__list-header{
-    display: flex;
-    background: rgba($colorBodyFg, .23);
+.c-fault-mgmt__list-header {
+    display: contents;
     border-radius: $controlCr;
+    align-items: center;
 
-    &-tripVal, &-liveVal, &-trigTime{
-        background: none;
+    * {
+        margin: 0px;
+        border-radius: 0px;
     }
 
-    &-trigTime{
-        width: 160px;
-    }
-    &-sortButton{
-        flex: 0 0 auto;
-        margin-left: auto;
-        justify-content: right;
-        display: flex;
-        align-content: right;
-        width: 100px;
+    .--width-less-than-600 & {
+        .c-fault-mgmt__list-content-right {
+            display:none;
+        }
     }
 
-}
+    &-content {
+        display: contents;
+    }
 
-.is-severity-critical{
-    @include glyphBefore($glyph-icon-alert-triangle);
-    color: $colorStatusError;
-}
+    &-results {
+        grid-column: 2 / span 2;
+        font-size: 1em;
+        height: auto;
+    }
 
-.is-severity-warning{
-    @include glyphBefore($glyph-icon-alert-rect);
-    color: $colorStatusAlert;
-}
+    &-action-wrapper {
+        grid-column: 7 / span 2;
 
-.is-severity-watch{
-    @include glyphBefore($glyph-icon-info);
-    color: $colorCommand;
-}
-
-.is-unacknowledged{
-    .c-fault-mgmt__list-severity{
-        @include pulse($animName: severityAnim, $dur: 200ms);
+        .--width-less-than-600 & {
+            grid-column: 4 / span 2;
+        }
     }
 }
 
-.is-selected { 
-    background: $colorSelectedBg;
-}
+/*********************************************** GRID ITEM */
+.c-fault-mgmt-item {
+    $p: $interiorMargin;
+    padding: $p;
+    background: $colorFaultItemBg;
+    white-space: nowrap;
 
-.is-shelved{
-    .c-fault-mgmt__list-content{
-        opacity: 60% !important;
-        font-style: italic;
+    &-header {
+        $c: $colorBodyBg;
+        background: $c;
+        border-bottom: 5px solid $c; // Creates illusion of "space" beneath header
+        min-height: 30px; // Needed to align cells
+        padding: $p;
+        position: sticky;
+        top: 0;
+        z-index: 2;
     }
-    .c-fault-mgmt__list-severity{
-        @include pulse($animName: shelvedAnim, $dur: 0ms);
+
+    &__value {
+        @include isLimit();
+        background: rgba($colorBodyFg, 0.1);
+        padding: $p;
+        border-radius: $controlCr;
+        display: inline-flex;
+    }
+
+    .is-selected & {
+        background: $colorSelectedBg;
     }
 }
diff --git a/src/ui/components/ObjectFrame.vue b/src/ui/components/ObjectFrame.vue
index 1254cc3cbb..694ba2786d 100644
--- a/src/ui/components/ObjectFrame.vue
+++ b/src/ui/components/ObjectFrame.vue
@@ -223,15 +223,16 @@ export default {
         },
         resizeSoView() {
             let cW = this.$refs.soView.offsetWidth;
+            let widths = [220, 600];
             let wClass = '';
 
-            if (cW < 220) {
-                wClass = CSS_WIDTH_LESS_STR + '220';
-            } else if (cW < 600) {
-                wClass = CSS_WIDTH_LESS_STR + '600';
+            for (let width of widths) {
+                if (cW < width) {
+                    wClass = wClass.concat(' ', CSS_WIDTH_LESS_STR, width);
+                }
             }
 
-            this.widthClass = wClass;
+            this.widthClass = wClass.trimStart();
         }
     }
 };
diff --git a/src/ui/components/object-frame.scss b/src/ui/components/object-frame.scss
index 1656b5b375..5c65f095d0 100644
--- a/src/ui/components/object-frame.scss
+++ b/src/ui/components/object-frame.scss
@@ -11,6 +11,7 @@
         margin-bottom: $interiorMarginSm;
         overflow: hidden;
         padding: 3px;
+        @include smallerControlButtons; // Make button in frame headers a bit smaller
 
         .c-object-label {
             font-size: 1.05em;
@@ -132,8 +133,6 @@
         }
     }
 
-    @include smallerControlButtons;
-
     &.has-complex-content {
         > .c-so-view__view-large { display: block; }
     }