Missing items (#3125)

* Missing objects styling WIP

- Grabbing prior work from `missing-items` branch;

* Missing objects styling WIP

- Grabbing prior work on hover and missing theme constants from
`missing-items` branch;
- Refined theme constants values;
- Renamed relevant mixins and classes from "isUnknown" to "isMissing";
- Applied new hover and missing/unknown styling to Folder-view grid
items;

* Missing objects styling WIP

- Significant refinements and additions to `is-missing`;
- Normalize object type icons as a markup `*__type-icon` to support
styling and positioning of `is-missing__indicator` as a markup element;
- Application to tree items, l-browse-bar in main view, c-object-label,
grid view;
- Change hover approach in grid-items and tree to use filters;

* Missing objects styling WIP

- Styles added to object-name component in Inspector, markup simplified;
- Styles added to Tabs view;

* Missing objects styling WIP

- Simplified and consolidated `is-missing` approach into
`.c-object-label` class;
- Modded `.c-object-label` class to use flex 1 1 auto, instead of 0 1
auto - be on the outlook for regression problems!;
- TODO: wire up `is-missing` for real and Folder List view;

* Missing objects styling WIP

- Added `is-missing` styling to Folder list view;
- Cleanups, simplification and normalization with tree items in
list-item and list-view.scss;
- Using `c-object-label` now in Folder list view;
- Removed too-broad `<a>` color definition in table.scss;

* Missing objects styling WIP

- `is-missing` added to layout frames, with support for hidden
frames and telemetry views.
- Further styles enhancement;
- Continued added wiring points into markup;

* Missing objects styling WIP

- `is-missing` added to mct-plot;
- Significant improvements for cursor lock indicators in plots;

* Missing objects styling WIP

- Plot legend fixes, added overflow scrolling for collapsed and expanded
 legends;
- Removed conmmented code;

* Wire up 'is-missing'

- Added property checks on domainObject for status 'missing';

* Fix linting issues

* remove carat from eslint package

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
This commit is contained in:
Charles Hacskaylo 2020-07-10 15:08:14 -07:00 committed by GitHub
parent 8cc58946cf
commit 8a6f944655
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 310 additions and 133 deletions

View File

@ -19,7 +19,13 @@
this source code distribution or the Licensing information page available this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information. at runtime from the About dialog for additional information.
--> -->
<div class="c-object-label"> <div class="c-object-label"
<div class="c-object-label__type-icon {{type.getCssClass()}}" ng-class="{ 'l-icon-link':location.isLink() }"></div> ng-class="{ 'is-missing': model.status === 'missing' }"
>
<div class="c-object-label__type-icon {{type.getCssClass()}}"
ng-class="{ 'l-icon-link':location.isLink() }"
>
<span class="is-missing__indicator" title="This item is missing"></span>
</div>
<div class='c-object-label__name'>{{model.name}}</div> <div class='c-object-label__name'>{{model.name}}</div>
</div> </div>

View File

@ -31,10 +31,16 @@
<div <div
v-if="domainObject" v-if="domainObject"
class="c-telemetry-view" class="c-telemetry-view"
:class="styleClass" :class="{
styleClass,
'is-missing': domainObject.status === 'missing'
}"
:style="styleObject" :style="styleObject"
@contextmenu.prevent="showContextMenu" @contextmenu.prevent="showContextMenu"
> >
<div class="is-missing__indicator"
title="This item is missing"
></div>
<div <div
v-if="showLabel" v-if="showLabel"
class="c-telemetry-view__label" class="c-telemetry-view__label"

View File

@ -26,4 +26,14 @@
@include abs(); @include abs();
border: 1px solid transparent; border: 1px solid transparent;
} }
&.is-missing {
@include isMissing($absPos: true);
border: $borderMissing;
.is-missing__indicator {
top: 0;
left: 0;
}
}
} }

View File

@ -1,13 +1,18 @@
<template> <template>
<a <a
class="l-grid-view__item c-grid-item" class="l-grid-view__item c-grid-item"
:class="{ 'is-alias': item.isAlias === true }" :class="{
'is-alias': item.isAlias === true,
'is-missing': item.status === 'missing',
'c-grid-item--unknown': item.type.cssClass === undefined || item.type.cssClass.indexOf('unknown') !== -1
}"
:href="objectLink" :href="objectLink"
> >
<div <div
class="c-grid-item__type-icon" class="c-grid-item__type-icon"
:class="(item.type.cssClass != undefined) ? 'bg-' + item.type.cssClass : 'bg-icon-object-unknown'" :class="(item.type.cssClass != undefined) ? 'bg-' + item.type.cssClass : 'bg-icon-object-unknown'"
></div> >
</div>
<div class="c-grid-item__details"> <div class="c-grid-item__details">
<!-- Name and metadata --> <!-- Name and metadata -->
<div <div
@ -22,6 +27,9 @@
</div> </div>
</div> </div>
<div class="c-grid-item__controls"> <div class="c-grid-item__controls">
<div class="is-missing__indicator"
title="This item is missing"
></div>
<div <div
class="icon-people" class="icon-people"
title="Shared" title="Shared"

View File

@ -7,13 +7,19 @@
<td class="c-list-item__name"> <td class="c-list-item__name">
<a <a
ref="objectLink" ref="objectLink"
class="c-object-label"
:class="{ 'is-missing': item.status === 'missing' }"
:href="objectLink" :href="objectLink"
> >
<div <div
class="c-list-item__type-icon" class="c-object-label__type-icon c-list-item__type-icon"
:class="item.type.cssClass" :class="item.type.cssClass"
></div> >
<div class="c-list-item__name-value">{{ item.model.name }}</div> <span class="is-missing__indicator"
title="This item is missing"
></span>
</div>
<div class="c-object-label__name c-list-item__name">{{ item.model.name }}</div>
</a> </a>
</td> </td>
<td class="c-list-item__type"> <td class="c-list-item__type">

View File

@ -38,7 +38,15 @@
// Object is an alias to an original. // Object is an alias to an original.
[class*='__type-icon'] { [class*='__type-icon'] {
@include isAlias(); @include isAlias();
color: $colorIconAliasForKeyFilter; }
}
&.is-missing {
@include isMissing();
[class*='__type-icon'],
[class*='__details'] {
opacity: $opacityMissing;
} }
} }
@ -85,15 +93,14 @@
body.desktop & { body.desktop & {
$transOutMs: 300ms; $transOutMs: 300ms;
flex-flow: column nowrap; flex-flow: column nowrap;
transition: background $transOutMs ease-in-out; transition: $transOutMs ease-in-out;
&:hover { &:hover {
background: $colorItemBgHov; filter: $filterItemHoverFg;
transition: $transIn; transition: $transIn;
.c-grid-item__type-icon { .c-grid-item__type-icon {
filter: $colorKeyFilterHov; transform: scale(1.1);
transform: scale(1);
transition: $transInBounce; transition: $transInBounce;
} }
} }
@ -103,7 +110,7 @@
} }
&__controls { &__controls {
align-items: start; align-items: baseline;
flex: 0 0 auto; flex: 0 0 auto;
order: 1; order: 1;
.c-info-button, .c-info-button,
@ -115,7 +122,6 @@
font-size: floor($gridItemDesk / 3); font-size: floor($gridItemDesk / 3);
margin: $interiorMargin 22.5% $interiorMargin * 3 22.5%; margin: $interiorMargin 22.5% $interiorMargin * 3 22.5%;
order: 2; order: 2;
transform: scale(0.9);
transform-origin: center; transform-origin: center;
transition: all $transOutMs ease-in-out; transition: all $transOutMs ease-in-out;
} }

View File

@ -1,37 +1,17 @@
/******************************* LIST ITEM */ /******************************* LIST ITEM */
.c-list-item { .c-list-item {
&__name a {
display: flex;
> * + * { margin-left: $interiorMarginSm; }
}
&__type-icon { &__type-icon {
// Have to do it this way instead of using icon-* class, due to need to apply alias to the icon color: $colorItemTreeIcon;
color: $colorKey;
display: inline-block;
width: 1em;
margin-right:$interiorMarginSm;
} }
&__name-value { &__name {
@include ellipsize(); @include ellipsize();
} }
&.is-alias { &.is-alias {
// Object is an alias to an original. // Object is an alias to an original.
[class*='__type-icon'] { [class*='__type-icon'] {
&:after { @include isAlias();
color: $colorIconAlias;
content: $glyph-icon-link;
font-family: symbolsfont;
display: block;
position: absolute;
text-shadow: rgba(black, 0.5) 0 1px 2px;
top: auto; left: -1px; bottom: 1px; right: auto;
transform-origin: bottom left;
transform: scale(0.65);
}
} }
} }
} }

View File

@ -13,7 +13,8 @@
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background: $colorListItemBgHov; background: $colorItemTreeHoverBg;
filter: $filterHov;
transition: $transIn; transition: $transIn;
} }
} }

View File

@ -28,17 +28,22 @@
ng-click="legend.set('expanded', !legend.get('expanded'));"> ng-click="legend.set('expanded', !legend.get('expanded'));">
</div> </div>
<div class="c-plot-legend__wrapper"> <div class="c-plot-legend__wrapper"
ng-class="{ 'is-cursor-locked': !!lockHighlightPoint }">
<!-- COLLAPSED PLOT LEGEND --> <!-- COLLAPSED PLOT LEGEND -->
<div class="plot-wrapper-collapsed-legend" <div class="plot-wrapper-collapsed-legend"
ng-class="{'icon-cursor-lock': !!lockHighlightPoint}"> ng-class="{'is-cursor-locked': !!lockHighlightPoint }">
<div class="c-state-indicator__alert-cursor-lock icon-cursor-lock" title="Cursor is point locked. Click anywhere in the plot to unlock."></div>
<div class="plot-legend-item" <div class="plot-legend-item"
ng-repeat="series in series track by $index"> ng-class="{'is-missing': series.status === 'missing'}"
ng-repeat="series in series track by $index"
>
<div class="plot-series-swatch-and-name"> <div class="plot-series-swatch-and-name">
<span class="plot-series-color-swatch" <span class="plot-series-color-swatch "
ng-style="{ 'background-color': series.get('color').asHexString() }"> ng-style="{ 'background-color': series.get('color').asHexString() }">
</span> </span>
<span class="is-missing__indicator" title="This item is missing"></span>
<span class="plot-series-name">{{ series.get('name') }}</span> <span class="plot-series-name">{{ series.get('name') }}</span>
</div> </div>
<div class="plot-series-value hover-value-enabled value-to-display-{{ legend.get('valueToShowWhenCollapsed') }} {{ series.closest.mctLimitState.cssClass }}" <div class="plot-series-value hover-value-enabled value-to-display-{{ legend.get('valueToShowWhenCollapsed') }} {{ series.closest.mctLimitState.cssClass }}"
@ -55,7 +60,10 @@
</div> </div>
<!-- EXPANDED PLOT LEGEND --> <!-- EXPANDED PLOT LEGEND -->
<div class="plot-wrapper-expanded-legend"> <div class="plot-wrapper-expanded-legend"
ng-class="{'is-cursor-locked': !!lockHighlightPoint }"
>
<div class="c-state-indicator__alert-cursor-lock--verbose icon-cursor-lock" title="Click anywhere in the plot to unlock."> Cursor locked to point</div>
<table> <table>
<thead> <thead>
<tr> <tr>
@ -76,12 +84,15 @@
</th> </th>
</tr> </tr>
</thead> </thead>
<tr ng-repeat="series in series" class="plot-legend-item"> <tr ng-repeat="series in series"
<td class="plot-series-swatch-and-name" class="plot-legend-item"
ng-class="{'icon-cursor-lock': !!lockHighlightPoint}"> ng-class="{'is-missing': series.status === 'missing'}"
>
<td class="plot-series-swatch-and-name">
<span class="plot-series-color-swatch" <span class="plot-series-color-swatch"
ng-style="{ 'background-color': series.get('color').asHexString() }"> ng-style="{ 'background-color': series.get('color').asHexString() }">
</span> </span>
<span class="is-missing__indicator" title="This item is missing"></span>
<span class="plot-series-name">{{ series.get('name') }}</span> <span class="plot-series-name">{{ series.get('name') }}</span>
</td> </td>
@ -134,7 +145,7 @@
{{option.name}} {{option.name}}
</option> </option>
</select> </select>
<mct-ticks axis="yAxis"> <mct-ticks axis="yAxis">
<div ng-repeat="tick in ticks track by tick.value" <div ng-repeat="tick in ticks track by tick.value"

View File

@ -22,14 +22,21 @@
<button <button
v-for="(tab,index) in tabsList" v-for="(tab,index) in tabsList"
:key="index" :key="index"
class="c-tabs-view__tab c-tab" class="c-tabs-view__tab c-tab c-object-label"
:class="[ :class="{
{'is-current': isCurrent(tab)}, 'is-current': isCurrent(tab),
tab.type.definition.cssClass 'is-missing': tab.domainObject.status === 'missing'
]" }"
@click="showTab(tab, index)" @click="showTab(tab, index)"
> >
<span class="c-button__label">{{ tab.domainObject.name }}</span> <div class="c-object-label__type-icon"
:class="tab.type.definition.cssClass"
>
<span class="is-missing__indicator"
title="This item is missing"
></span>
</div>
<span class="c-button__label c-object-label__name">{{ tab.domainObject.name }}</span>
</button> </button>
</div> </div>
<div <div
@ -38,15 +45,6 @@
class="c-tabs-view__object-holder" class="c-tabs-view__object-holder"
:class="{'c-tabs-view__object-holder--hidden': !isCurrent(tab)}" :class="{'c-tabs-view__object-holder--hidden': !isCurrent(tab)}"
> >
<div
v-if="currentTab"
class="c-tabs-view__object-name c-object-label l-browse-bar__object-name--w"
:class="currentTab.type.definition.cssClass"
>
<div class="l-browse-bar__object-name c-object-label__name">
{{ currentTab.domainObject.name }}
</div>
</div>
<object-view <object-view
v-if="internalDomainObject.keep_alive ? currentTab : isCurrent(tab)" v-if="internalDomainObject.keep_alive ? currentTab : isCurrent(tab)"
class="c-tabs-view__object" class="c-tabs-view__object"

View File

@ -151,6 +151,10 @@ $browseFrameColor: pullForward($colorBodyBg, 10%);
$browseFrameBorder: 1px solid $browseFrameColor; // Frames in Disp and Flex Layouts when frame is showing $browseFrameBorder: 1px solid $browseFrameColor; // Frames in Disp and Flex Layouts when frame is showing
$browseSelectableShdwHov: rgba($colorBodyFg, 0.3) 0 0 3px; $browseSelectableShdwHov: rgba($colorBodyFg, 0.3) 0 0 3px;
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.4); $browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.4);
$filterItemHoverFg: brightness(1.2) contrast(1.1);
$filterItemMissing: brightness(0.6) grayscale(1);
$opacityMissing: 0.5;
$borderMissing: 1px dashed $colorAlert !important;
/************************************************** EDITING */ /************************************************** EDITING */
$editUIColor: $uiColor; // Base color $editUIColor: $uiColor; // Base color

View File

@ -155,6 +155,10 @@ $browseFrameColor: pullForward($colorBodyBg, 10%);
$browseFrameBorder: 1px solid $browseFrameColor; // Frames in Disp and Flex Layouts when frame is showing $browseFrameBorder: 1px solid $browseFrameColor; // Frames in Disp and Flex Layouts when frame is showing
$browseSelectableShdwHov: rgba($colorBodyFg, 0.3) 0 0 3px; $browseSelectableShdwHov: rgba($colorBodyFg, 0.3) 0 0 3px;
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.4); $browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.4);
$filterItemHoverFg: brightness(1.2) contrast(1.1);
$filterItemMissing: contrast(0.2);
$opacityMissing: 0.5;
$borderMissing: 1px dashed $colorAlert !important;
/************************************************** EDITING */ /************************************************** EDITING */
$editUIColor: $uiColor; // Base color $editUIColor: $uiColor; // Base color

View File

@ -151,6 +151,10 @@ $browseFrameColor: pullForward($colorBodyBg, 10%);
$browseFrameBorder: 1px solid $browseFrameColor; // Frames in Disp and Flex Layouts when frame is showing $browseFrameBorder: 1px solid $browseFrameColor; // Frames in Disp and Flex Layouts when frame is showing
$browseSelectableShdwHov: rgba($colorBodyFg, 0.3) 0 0 3px; $browseSelectableShdwHov: rgba($colorBodyFg, 0.3) 0 0 3px;
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.4); $browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.4);
$filterItemHoverFg: brightness(0.9);
$filterItemMissing: contrast(0.2);
$opacityMissing: 0.4;
$borderMissing: 1px dashed $colorAlert !important;
/************************************************** EDITING */ /************************************************** EDITING */
$editUIColor: $uiColor; // Base color $editUIColor: $uiColor; // Base color

View File

@ -61,7 +61,7 @@ $plotXBarH: 35px;
$plotLegendH: 20px; $plotLegendH: 20px;
$plotLegendWidthCollapsed: 20%; $plotLegendWidthCollapsed: 20%;
$plotLegendWidthExpanded: 50%; $plotLegendWidthExpanded: 50%;
$plotSwatchD: 10px; $plotSwatchD: 12px;
$plotDisplayArea: (0, 0, $plotXBarH, $plotYBarW); // 1: Top, 2: right, 3: bottom, 4: left $plotDisplayArea: (0, 0, $plotXBarH, $plotYBarW); // 1: Top, 2: right, 3: bottom, 4: left
$plotMinH: 95px; $plotMinH: 95px;
$controlBarH: 25px; $controlBarH: 25px;

View File

@ -420,9 +420,7 @@ select {
margin: 1px 1px 0 0; margin: 1px 1px 0 0;
padding: $interiorMargin $interiorMarginLg; padding: $interiorMargin $interiorMarginLg;
white-space: nowrap; white-space: nowrap;
--notchSize: 7px; --notchSize: 7px;
clip-path: clip-path:
polygon( polygon(
0% 0%, 0% 0%,
@ -433,8 +431,12 @@ select {
0% 100% 0% 100%
); );
> * + * {
margin-left: $interiorMargin;
}
@include hover() { @include hover() {
background: $colorBtnBgHov; filter: $filterHov;
} }
&.is-current { &.is-current {

View File

@ -43,7 +43,9 @@ mct-plot {
.c-plot, .c-plot,
.gl-plot { .gl-plot {
.s-status-taking-snapshot & { overflow: hidden;
.s-status-taking-snapshot & {
.c-control-bar { .c-control-bar {
display: none; display: none;
} }
@ -51,6 +53,17 @@ mct-plot {
display: none; display: none;
} }
} }
/*********************** MISSING ITEM INDICATORS */
.is-missing__indicator {
display: none;
}
.is-missing {
@include isMissing();
.is-missing__indicator {
font-size: 0.8em;
}
}
} }
.c-plot { .c-plot {
@ -74,6 +87,7 @@ mct-plot {
display: flex; display: flex;
flex: 1 1 auto; flex: 1 1 auto;
flex-direction: column; flex-direction: column;
overflow: hidden;
} }
&--stacked { &--stacked {
@ -102,18 +116,17 @@ mct-plot {
} }
} }
.gl-plot { .gl-plot {
display: flex; display: flex;
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
min-height: $plotMinH;
/*********************** AXIS AND DISPLAY AREA */ /*********************** AXIS AND DISPLAY AREA */
.plot-wrapper-axis-and-display-area { .plot-wrapper-axis-and-display-area {
position: relative; position: relative;
flex: 1 1 auto; flex: 1 1 auto;
min-height: $plotMinH;
} }
.gl-plot-wrapper-display-area-and-x-axis { .gl-plot-wrapper-display-area-and-x-axis {
@ -196,7 +209,6 @@ mct-plot {
left: 0; top: 0; right: auto; bottom: 0; left: 0; top: 0; right: auto; bottom: 0;
padding-left: 5px; padding-left: 5px;
text-orientation: mixed; text-orientation: mixed;
//overflow: hidden;
writing-mode: vertical-lr; writing-mode: vertical-lr;
&:before { &:before {
// Icon denoting configurability // Icon denoting configurability
@ -368,12 +380,6 @@ mct-plot {
z-index: -10; z-index: -10;
.l-view-section { .l-view-section {
//$m: $interiorMargin;
//top: $m !important;
//right: $m;
//bottom: $m;
//left: $m;
.s-status-timeconductor-unsynced .holder-plot { .s-status-timeconductor-unsynced .holder-plot {
.t-object-alert.t-alert-unsynced { .t-object-alert.t-alert-unsynced {
display: none; display: none;
@ -429,14 +435,18 @@ mct-plot {
/****************** _LEGEND.SCSS */ /****************** _LEGEND.SCSS */
.gl-plot-legend, .gl-plot-legend,
.c-plot-legend { .c-plot-legend {
overflow: hidden;
&__wrapper { &__wrapper {
// Holds view-control and both collapsed and expanded legends // Holds view-control and both collapsed and expanded legends
flex: 1 1 auto; flex: 1 1 auto;
overflow: auto; // Prevents collapsed legend from forcing scrollbars on higher parent containers height: 100%;
overflow: auto;
padding: 2px;
} }
&__view-control { &__view-control {
padding-top: 2px; padding-top: 4px;
margin-right: $interiorMarginSm; margin-right: $interiorMarginSm;
} }
@ -481,15 +491,21 @@ mct-plot {
/***************** GENERAL STYLES, ALL STATES */ /***************** GENERAL STYLES, ALL STATES */
.plot-legend-item { .plot-legend-item {
// General styles for legend items, both expanded and collapsed legend states // General styles for legend items, both expanded and collapsed legend states
> * + * {
margin-left: $interiorMarginSm;
}
.plot-series-color-swatch { .plot-series-color-swatch {
border-radius: $smallCr; border-radius: 30%; //$smallCr;
border: 1px solid $colorBodyBg; border: 1px solid $colorBodyBg;
display: inline-block; display: inline-block;
flex: 0 0 auto;
height: $plotSwatchD; height: $plotSwatchD;
width: $plotSwatchD; width: $plotSwatchD;
} }
.plot-series-name { .plot-series-name {
display: inline; display: inline;
@include ellipsize();
} }
.plot-series-value { .plot-series-value {
@ -497,6 +513,16 @@ mct-plot {
} }
} }
.plot-series-swatch-and-name {
display: flex;
flex: 0 1 auto;
align-items: center;
> * + * {
margin-left: $interiorMarginSm;
}
}
.plot-wrapper-expanded-legend { .plot-wrapper-expanded-legend {
flex: 1 1 auto; flex: 1 1 auto;
} }
@ -505,9 +531,6 @@ mct-plot {
&.plot-legend-collapsed .plot-wrapper-expanded-legend { display: none; } &.plot-legend-collapsed .plot-wrapper-expanded-legend { display: none; }
&.plot-legend-expanded .plot-wrapper-collapsed-legend { display: none; } &.plot-legend-expanded .plot-wrapper-collapsed-legend { display: none; }
&.plot-legend-collapsed .icon-cursor-lock::before { padding-right: 5px; }
&.plot-legend-expanded .icon-cursor-lock::before { padding-right: 5px; }
&.plot-legend-top .gl-plot-legend { margin-bottom: $interiorMargin; } &.plot-legend-top .gl-plot-legend { margin-bottom: $interiorMargin; }
&.plot-legend-bottom .gl-plot-legend { margin-top: $interiorMargin; } &.plot-legend-bottom .gl-plot-legend { margin-top: $interiorMargin; }
&.plot-legend-right .gl-plot-legend { margin-left: $interiorMargin; } &.plot-legend-right .gl-plot-legend { margin-left: $interiorMargin; }
@ -521,19 +544,13 @@ mct-plot {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: stretch; justify-content: stretch;
&:not(:first-child) {
margin-left: $interiorMarginLg;
}
.plot-series-swatch-and-name, .plot-series-swatch-and-name,
.plot-series-value { .plot-series-value {
@include ellipsize(); @include ellipsize();
flex: 1 1 auto; flex: 1 1 auto;
} }
.plot-series-swatch-and-name {
margin-right: $interiorMarginSm;
}
.plot-series-value { .plot-series-value {
text-align: left; text-align: left;
} }
@ -543,7 +560,7 @@ mct-plot {
/***************** GENERAL STYLES, EXPANDED */ /***************** GENERAL STYLES, EXPANDED */
&.plot-legend-expanded { &.plot-legend-expanded {
.gl-plot-legend { .gl-plot-legend {
// max-height: 70%; max-height: 70%;
} }
.plot-wrapper-expanded-legend { .plot-wrapper-expanded-legend {
@ -564,6 +581,11 @@ mct-plot {
display: flex; display: flex;
flex: 1 1 auto; flex: 1 1 auto;
overflow: hidden; overflow: hidden;
> .plot-legend-item + .plot-legend-item {
// Space between plot items
margin-left: $interiorMarginLg;
}
} }
} }
} }
@ -595,12 +617,17 @@ mct-plot {
min-width: 0; min-width: 0;
flex: 1 1 auto; flex: 1 1 auto;
overflow-y: auto; overflow-y: auto;
> * + * {
// Space between plot items
margin-top: $interiorMarginSm;
}
} }
.plot-legend-item { .plot-legend-item {
margin-bottom: 1px;
margin-left: 0; margin-left: 0;
flex-wrap: wrap; flex-wrap: nowrap;
.plot-series-swatch-and-name { .plot-series-swatch-and-name {
@include ellipsize();
flex: 0 1 auto; flex: 0 1 auto;
min-width: 20%; min-width: 20%;
} }
@ -654,3 +681,24 @@ mct-plot {
display: inline-block !important; display: inline-block !important;
} }
} }
/*********************** CURSOR LOCK INDICATOR */
[class*='c-state-indicator__alert-cursor-lock'] {
display: none;
}
[class*='is-cursor-locked'] {
background: rgba($colorInfo, 0.1);
[class*='c-state-indicator__alert-cursor-lock'] {
@include userSelectNone();
color: $colorInfo;
display: block;
margin-right: $interiorMarginSm;
&[class*='--verbose'] {
padding: $interiorMarginSm;
}
}
}

View File

@ -117,6 +117,30 @@
} }
} }
@mixin isMissing($absPos: false) {
// Common styles to be applied to tree items, object labels, grid and list item views
//opacity: 0.7;
//pointer-events: none; // Don't think we can do this, as disables title hover on icon element
.is-missing__indicator {
display: block;
text-shadow: $colorBodyBg 0 0 2px;
color: $colorAlert;
font-family: symbolsfont;
&:before {
content: $glyph-icon-alert-triangle;
}
}
@if $absPos {
.is-missing__indicator {
position: absolute;
z-index: 3;
}
}
}
@mixin bgDiagonalStripes($c: yellow, $a: 0.1, $d: 40px) { @mixin bgDiagonalStripes($c: yellow, $a: 0.1, $d: 40px) {
background-image: linear-gradient(-45deg, background-image: linear-gradient(-45deg,
rgba($c, $a) 25%, transparent 25%, rgba($c, $a) 25%, transparent 25%,

View File

@ -49,8 +49,6 @@ table {
td { td {
vertical-align: top; vertical-align: top;
} }
a { color: $colorBtnMajorBg; }
} }
.is-editing { .is-editing {

View File

@ -13,7 +13,6 @@
@import "../plugins/filters/components/filters-view.scss"; @import "../plugins/filters/components/filters-view.scss";
@import "../plugins/filters/components/global-filters.scss"; @import "../plugins/filters/components/global-filters.scss";
@import "../plugins/flexibleLayout/components/flexible-layout.scss"; @import "../plugins/flexibleLayout/components/flexible-layout.scss";
@import "../plugins/folderView/components/grid-item.scss";
@import "../plugins/folderView/components/grid-view.scss"; @import "../plugins/folderView/components/grid-view.scss";
@import "../plugins/folderView/components/list-item.scss"; @import "../plugins/folderView/components/list-item.scss";
@import "../plugins/folderView/components/list-view.scss"; @import "../plugins/folderView/components/list-view.scss";

View File

@ -24,13 +24,24 @@
class="c-so-view has-local-controls" class="c-so-view has-local-controls"
:class="{ :class="{
'c-so-view--no-frame': !hasFrame, 'c-so-view--no-frame': !hasFrame,
'has-complex-content': complexContent 'has-complex-content': complexContent,
'is-missing': domainObject.status === 'missing'
}" }"
> >
<div class="c-so-view__header"> <div class="c-so-view__header">
<div class="c-object-label" <div class="c-object-label"
:class="[cssClass, classList]" :class="{
classList,
'is-missing': domainObject.status === 'missing'
}"
> >
<div class="c-object-label__type-icon"
:class="cssClass"
>
<span class="is-missing__indicator"
title="This item is missing"
></span>
</div>
<div class="c-object-label__name"> <div class="c-object-label__name">
{{ domainObject && domainObject.name }} {{ domainObject && domainObject.name }}
</div> </div>
@ -46,6 +57,9 @@
@click="expand" @click="expand"
></button> ></button>
</div> </div>
<div class="is-missing__indicator"
title="This item is missing"
></div>
<object-view <object-view
ref="objectView" ref="objectView"
class="c-so-view__object-view" class="c-so-view__object-view"

View File

@ -1,7 +1,10 @@
<template> <template>
<a <a
class="c-tree__item__label c-object-label" class="c-tree__item__label c-object-label"
:class="classList" :class="{
classList,
'is-missing': observedObject.status === 'missing'
}"
draggable="true" draggable="true"
:href="objectLink" :href="objectLink"
@dragstart="dragStart" @dragstart="dragStart"
@ -10,8 +13,14 @@
<div <div
class="c-tree__item__type-icon c-object-label__type-icon" class="c-tree__item__type-icon c-object-label__type-icon"
:class="typeClass" :class="typeClass"
></div> >
<div class="c-tree__item__name c-object-label__name">{{ observedObject.name }}</div> <span class="is-missing__indicator"
title="This item is missing"
></span>
</div>
<div class="c-tree__item__name c-object-label__name">
{{ observedObject.name }}
</div>
</a> </a>
</template> </template>

View File

@ -2,6 +2,10 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
&.is-missing {
border: $borderMissing;
}
/*************************** HEADER */ /*************************** HEADER */
&__header { &__header {
flex: 0 0 auto; flex: 0 0 auto;
@ -39,6 +43,15 @@
> .c-so-view__local-controls { > .c-so-view__local-controls {
top: $interiorMarginSm; right: $interiorMarginSm; top: $interiorMarginSm; right: $interiorMarginSm;
} }
&.is-missing {
@include isMissing($absPos: true);
.is-missing__indicator {
top: $interiorMargin;
left: $interiorMargin;
}
}
} }
&__local-controls { &__local-controls {

View File

@ -3,23 +3,38 @@
// Used mostly in trees and lists // Used mostly in trees and lists
display: flex; display: flex;
align-items: center; align-items: center;
flex: 0 1 auto; flex: 1 1 auto;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
> * + * { margin-left: $interiorMargin; }
&__name { &__name {
@include ellipsize(); @include ellipsize();
display: inline; display: inline;
} }
&__type-icon, &__type-icon {
&:before {
// Type icon. Must be an HTML entity to allow inclusion of alias indicator. // Type icon. Must be an HTML entity to allow inclusion of alias indicator.
display: block; display: block;
flex: 0 0 auto; flex: 0 0 auto;
font-size: 1.1em; font-size: 1.1em;
opacity: 0.6; //margin-right: $interiorMargin;
margin-right: $interiorMargin; }
&.is-missing {
@include isMissing($absPos: true);
[class*='__type-icon']:before,
[class*='__type-icon']:after{
opacity: $opacityMissing;
}
.is-missing__indicator {
right: -3px;
top: -3px;
transform: scale(0.7);
}
} }
} }
@ -27,6 +42,8 @@
border-radius: $controlCr; border-radius: $controlCr;
padding: $interiorMarginSm 1px; padding: $interiorMarginSm 1px;
> * + * { margin-left: $interiorMarginSm; }
&__name { &__name {
display: inline; display: inline;
width: 100%; width: 100%;

View File

@ -1,16 +1,24 @@
<template> <template>
<div class="c-inspector__header"> <div class="c-inspector__header">
<div v-if="!multiSelect && !singleSelectNonObject" <div v-if="!multiSelect"
class="c-inspector__selected-w c-object-label" class="c-inspector__selected-w c-object-label"
:class="typeCssClass" :class="{'is-missing': domainObject.status === 'missing' }"
> >
<span class="c-inspector__selected c-object-label__name">{{ item.name }}</span> <div class="c-object-label__type-icon"
</div> :class="typeCssClass"
<div v-if="singleSelectNonObject" >
class="c-inspector__selected-w c-object-label" <span class="is-missing__indicator"
:class="typeCssClass" title="This item is missing"
> ></span>
<span class="c-inspector__selected c-object-label__name c-inspector__selected--non-domain-object">Layout Object</span> </div>
<span v-if="!singleSelectNonObject"
class="c-inspector__selected c-object-label__name"
>{{ item.name }}</span>
<span v-if="singleSelectNonObject"
class="c-inspector__selected c-object-label__name c-inspector__selected--non-domain-object"
>Layout Object</span>
</div> </div>
<div v-if="multiSelect" <div v-if="multiSelect"
class="c-inspector__multiple-selected-w" class="c-inspector__multiple-selected-w"

View File

@ -8,8 +8,18 @@
></button> ></button>
<div <div
class="l-browse-bar__object-name--w c-object-label" class="l-browse-bar__object-name--w c-object-label"
:class="[ type.cssClass, classList ]" :class="{
classList,
'is-missing': domainObject.status === 'missing'
}"
> >
<div class="c-object-label__type-icon"
:class="type.cssClass"
>
<span class="is-missing__indicator"
title="This item is missing"
></span>
</div>
<span <span
class="l-browse-bar__object-name c-object-label__name c-input-inline" class="l-browse-bar__object-name c-object-label__name c-input-inline"
contenteditable contenteditable

View File

@ -354,9 +354,9 @@
@include headerFont(1.4em); @include headerFont(1.4em);
min-width: 0; min-width: 0;
&:before { .is-missing__indicator {
// Icon right: -5px !important;
margin-right: $interiorMargin; top: -4px !important;
} }
} }

View File

@ -52,12 +52,13 @@
padding: $interiorMarginSm $interiorMargin; padding: $interiorMarginSm $interiorMargin;
transition: background 150ms ease; transition: background 150ms ease;
&__type-icon {
color: $colorItemTreeIcon;
}
&:hover { &:hover {
background: $colorItemTreeHoverBg; background: $colorItemTreeHoverBg;
filter: $filterHov;
[class*="__name"] {
color: $colorItemTreeHoverFg;
}
} }
&.is-navigated-object, &.is-navigated-object,
@ -81,12 +82,6 @@
margin-left: $interiorMarginSm; margin-left: $interiorMarginSm;
} }
&:hover {
.c-tree__item__type-icon:before {
color: $colorItemTreeIconHover;
}
}
&.is-navigated-object, &.is-navigated-object,
&.is-selected { &.is-selected {
.c-tree__item__type-icon:before { .c-tree__item__type-icon:before {
@ -115,10 +110,6 @@
color: $colorItemTreeFg; color: $colorItemTreeFg;
} }
&__type-icon {
color: $colorItemTreeIcon;
}
&.is-alias { &.is-alias {
// Object is an alias to an original. // Object is an alias to an original.
[class*='__type-icon'] { [class*='__type-icon'] {