* Separate Vue component styles out from SFCs.
* Added 'MCT.prototype.getAssetPath' and using 'openmct.setAssetPath' to get relative path for assets.
* Re-implements `openmct.plugins.Snow()`, and `openmct.plugins.Espresso()` (as well as a new theme `openmct.plugins.Maelstron()`)
This commit is contained in:
Nikhil 2019-12-11 14:27:13 -08:00 committed by Andrew Henry
parent 23781fa686
commit 50173a4413
106 changed files with 3636 additions and 3690 deletions

View File

@ -43,6 +43,8 @@
].forEach(
openmct.legacyRegistry.enable.bind(openmct.legacyRegistry)
);
openmct.install(openmct.plugins.Espresso());
openmct.install(openmct.plugins.MyItems());
openmct.install(openmct.plugins.LocalStorage());
openmct.install(openmct.plugins.Generator());

View File

@ -11,8 +11,8 @@
"comma-separated-values": "^3.6.4",
"concurrently": "^3.6.1",
"copy-webpack-plugin": "^4.5.2",
"css-loader": "^1.0.0",
"cross-env": "^6.0.3",
"css-loader": "^1.0.0",
"d3-array": "1.2.x",
"d3-axis": "1.0.x",
"d3-collection": "1.0.x",
@ -63,7 +63,7 @@
"raw-loader": "^0.5.1",
"request": "^2.69.0",
"split": "^1.0.0",
"style-loader": "^0.21.0",
"style-loader": "^1.0.1",
"v8-compile-cache": "^1.1.0",
"vue": "2.5.6",
"vue-loader": "^15.2.6",

View File

@ -38,7 +38,6 @@ define([
'./ui/router/ApplicationRouter',
'./ui/router/Browse',
'../platform/framework/src/Main',
'./styles/core.scss',
'./styles/notebook.scss',
'./ui/layout/Layout.vue',
'../platform/core/src/objects/DomainObjectImpl',
@ -66,7 +65,6 @@ define([
ApplicationRouter,
Browse,
Main,
coreStyles,
NotebookStyles,
Layout,
DomainObjectImpl,
@ -318,11 +316,26 @@ define([
* @memberof module:openmct.MCT#
* @method setAssetPath
*/
MCT.prototype.setAssetPath = function (path) {
this.legacyExtension('constants', {
key: "ASSETS_PATH",
value: path
});
MCT.prototype.setAssetPath = function (assetPath) {
this._assetPath = assetPath;
};
/**
* Get path to where assets are hosted.
* @memberof module:openmct.MCT#
* @method getAssetPath
*/
MCT.prototype.getAssetPath = function () {
const assetPathLength = this._assetPath && this._assetPath.length;
if (!assetPathLength) {
return '/';
}
if (this._assetPath[assetPathLength - 1] !== '/') {
return this._assetPath + '/';
}
return this._assetPath;
};
/**

View File

@ -33,92 +33,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
@mixin legacyMessage() {
flex: 0 1 auto;
font-family: symbolsfont;
font-size: $messageIconD; // Singleton message in a dialog
margin-right: $interiorMarginLg;
}
.c-message {
display: flex;
align-items: center;
> * + * {
margin-left: $interiorMarginLg;
}
&__icon {
// Holds a background SVG graphic
$s: 80px;
flex: 0 0 auto;
min-width: $s;
min-height: $s;
}
&__text {
display: flex;
flex-direction: column;
flex: 1 1 auto;
> * + * {
margin-top: $interiorMargin;
}
}
// __text elements
&__action-text {
font-size: 1.2em;
}
&__title {
font-size: 1.5em;
font-weight: bold;
}
&--simple {
// Icon and text elements only
&:before {
font-size: 30px !important;
}
[class*='__text'] {
font-size: 1.25em;
}
}
/************************** LEGACY */
&.message-severity-info:before {
@include legacyMessage();
content: $glyph-icon-info;
color: $colorInfo;
}
&.message-severity-alert:before {
@include legacyMessage();
content: $glyph-icon-alert-rect;
color: $colorWarningLo;
}
&.message-severity-error:before {
@include legacyMessage();
content: $glyph-icon-alert-triangle;
color: $colorWarningHi;
}
// Messages in a list
.c-overlay__messages & {
padding: $interiorMarginLg;
&:before {
font-size: $messageListIconD;
}
}
}
</style>
<script>
export default {
inject:['iconClass', 'title', 'hint', 'timestamp', 'message']

View File

@ -36,154 +36,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
@mixin overlaySizing($marginTB: 5%, $marginLR: $marginTB, $width: auto, $height: auto) {
position: absolute;
top: $marginTB; right: $marginLR; bottom: $marginTB; left: $marginLR;
width: $width;
height: $height;
}
.l-overlay-wrapper {
// Created by overlayService.js, contains this template.
// Acts as an anchor for one or more overlays.
display: contents;
}
.c-overlay {
@include abs();
z-index: 70;
&__blocker {
display: none; // Mobile-first
}
&__outer {
@include abs();
background: $overlayColorBg;
color: $overlayColorFg;
display: flex;
flex-direction: column;
padding: $overlayInnerMargin;
}
&__close-button {
$p: $interiorMargin;
border-radius: 100% !important;
color: $overlayColorFg;
display: inline-block;
font-size: 1.25em;
position: absolute;
top: $p; right: $p;
}
&__contents {
flex: 1 1 auto;
display: flex;
flex-direction: column;
outline: none;
overflow: hidden;
}
&__top-bar {
flex: 0 0 auto;
flex-direction: column;
display: flex;
> * {
flex: 0 0 auto;
margin-bottom: $interiorMargin;
}
}
&__dialog-title {
@include ellipsize();
font-size: 1.5em;
line-height: 120%;
}
&__contents-main {
display: flex;
flex-direction: column;
flex: 1 1 auto;
height: 0; // Chrome 73 overflow bug fix
overflow: auto;
padding-right: $interiorMargin; // fend off scroll bar
}
&__button-bar {
flex: 0 0 auto;
display: flex;
justify-content: flex-end;
margin-top: $interiorMargin;
> * + * {
margin-left: $interiorMargin;
}
}
.c-button,
.c-click-icon {
filter: $overlayBrightnessAdjust;
}
}
body.desktop {
.c-overlay {
&__blocker {
@include abs();
background: $colorOvrBlocker;
cursor: pointer;
display: block;
}
}
// Overlay types, styling for desktop. Appended to .l-overlay-wrapper element.
.l-overlay-large,
.l-overlay-small,
.l-overlay-fit {
.c-overlay__outer {
border-radius: $overlayCr;
box-shadow: rgba(black, 0.5) 0 2px 25px;
}
}
.l-overlay-fullscreen {
// Used by About > Licenses display
.c-overlay__outer {
@include overlaySizing($overlayOuterMarginFullscreen);
}
}
.l-overlay-large {
// Default
.c-overlay__outer {
@include overlaySizing($overlayOuterMarginLg);
}
}
.l-overlay-small {
.c-overlay__outer {
@include overlaySizing($overlayOuterMarginDialog);
}
}
.t-dialog-sm .l-overlay-small, // Legacy dialog support
.l-overlay-fit {
.c-overlay__outer {
@include overlaySizing(auto);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
min-width: 20%;
}
}
}
</style>
<script>
export default {
data: function () {

View File

@ -4,9 +4,6 @@
</dialog-component>
</template>
<style lang="scss">
</style>
<script>
import ProgressComponent from '../../../ui/components/ProgressBar.vue';
import DialogComponent from './DialogComponent.vue';

View File

@ -0,0 +1,81 @@
@mixin legacyMessage() {
flex: 0 1 auto;
font-family: symbolsfont;
font-size: $messageIconD; // Singleton message in a dialog
margin-right: $interiorMarginLg;
}
.c-message {
display: flex;
align-items: center;
> * + * {
margin-left: $interiorMarginLg;
}
&__icon {
// Holds a background SVG graphic
$s: 80px;
flex: 0 0 auto;
min-width: $s;
min-height: $s;
}
&__text {
display: flex;
flex-direction: column;
flex: 1 1 auto;
> * + * {
margin-top: $interiorMargin;
}
}
// __text elements
&__action-text {
font-size: 1.2em;
}
&__title {
font-size: 1.5em;
font-weight: bold;
}
&--simple {
// Icon and text elements only
&:before {
font-size: 30px !important;
}
[class*='__text'] {
font-size: 1.25em;
}
}
/************************** LEGACY */
&.message-severity-info:before {
@include legacyMessage();
content: $glyph-icon-info;
color: $colorInfo;
}
&.message-severity-alert:before {
@include legacyMessage();
content: $glyph-icon-alert-rect;
color: $colorWarningLo;
}
&.message-severity-error:before {
@include legacyMessage();
content: $glyph-icon-alert-triangle;
color: $colorWarningHi;
}
// Messages in a list
.c-overlay__messages & {
padding: $interiorMarginLg;
&:before {
font-size: $messageListIconD;
}
}
}

View File

@ -0,0 +1,142 @@
@mixin overlaySizing($marginTB: 5%, $marginLR: $marginTB, $width: auto, $height: auto) {
position: absolute;
top: $marginTB; right: $marginLR; bottom: $marginTB; left: $marginLR;
width: $width;
height: $height;
}
.l-overlay-wrapper {
// Created by overlayService.js, contains this template.
// Acts as an anchor for one or more overlays.
display: contents;
}
.c-overlay {
@include abs();
z-index: 70;
&__blocker {
display: none; // Mobile-first
}
&__outer {
@include abs();
background: $overlayColorBg;
color: $overlayColorFg;
display: flex;
flex-direction: column;
padding: $overlayInnerMargin;
}
&__close-button {
$p: $interiorMargin;
border-radius: 100% !important;
color: $overlayColorFg;
display: inline-block;
font-size: 1.25em;
position: absolute;
top: $p; right: $p;
}
&__contents {
flex: 1 1 auto;
display: flex;
flex-direction: column;
outline: none;
overflow: hidden;
}
&__top-bar {
flex: 0 0 auto;
flex-direction: column;
display: flex;
> * {
flex: 0 0 auto;
margin-bottom: $interiorMargin;
}
}
&__dialog-title {
@include ellipsize();
font-size: 1.5em;
line-height: 120%;
}
&__contents-main {
display: flex;
flex-direction: column;
flex: 1 1 auto;
height: 0; // Chrome 73 overflow bug fix
overflow: auto;
padding-right: $interiorMargin; // fend off scroll bar
}
&__button-bar {
flex: 0 0 auto;
display: flex;
justify-content: flex-end;
margin-top: $interiorMargin;
> * + * {
margin-left: $interiorMargin;
}
}
.c-button,
.c-click-icon {
filter: $overlayBrightnessAdjust;
}
}
body.desktop {
.c-overlay {
&__blocker {
@include abs();
background: $colorOvrBlocker;
cursor: pointer;
display: block;
}
}
// Overlay types, styling for desktop. Appended to .l-overlay-wrapper element.
.l-overlay-large,
.l-overlay-small,
.l-overlay-fit {
.c-overlay__outer {
border-radius: $overlayCr;
box-shadow: rgba(black, 0.5) 0 2px 25px;
}
}
.l-overlay-fullscreen {
// Used by About > Licenses display
.c-overlay__outer {
@include overlaySizing($overlayOuterMarginFullscreen);
}
}
.l-overlay-large {
// Default
.c-overlay__outer {
@include overlaySizing($overlayOuterMarginLg);
}
}
.l-overlay-small {
.c-overlay__outer {
@include overlaySizing($overlayOuterMarginDialog);
}
}
.t-dialog-sm .l-overlay-small, // Legacy dialog support
.l-overlay-fit {
.c-overlay__outer {
@include overlaySizing(auto);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
min-width: 20%;
}
}
}

View File

@ -31,10 +31,6 @@
</tr>
</template>
<style lang="scss">
</style>
<script>
const CONTEXT_MENU_ACTIONS = [

View File

@ -51,10 +51,6 @@
</table>
</template>
<style lang="scss">
</style>
<script>
import LadRow from './LADRow.vue';

View File

@ -34,19 +34,6 @@
</layout-frame>
</template>
<style lang="scss">
@import '~styles/sass-base';
.c-box-view {
display: flex;
align-items: stretch;
.c-frame & {
@include abs();
}
}
</style>
<script>
import LayoutFrame from './LayoutFrame.vue'

View File

@ -66,81 +66,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
@mixin displayMarquee($c) {
> .c-frame-edit {
// All other frames
//@include test($c, 0.4);
display: block;
}
> .c-frame > .c-frame-edit {
// Line object frame
//@include test($c, 0.4);
display: block;
}
}
.l-layout {
@include abs();
display: flex;
flex-direction: column;
overflow: auto;
&__grid-holder {
display: none;
}
&__frame {
position: absolute;
}
}
.is-editing {
.l-shell__main-container {
&[s-selected],
&[s-selected-parent] {
// Display grid and allow edit marquee to display in main layout holder when editing
> .l-layout {
background: $editUIGridColorBg;
> [class*="__grid-holder"] {
display: block;
}
}
}
}
.l-layout__frame {
&[s-selected],
&[s-selected-parent] {
// Display grid and allow edit marquee to display in nested layouts when editing
> * > * > .l-layout {
background: $editUIGridColorBg;
box-shadow: inset $editUIGridColorFg 0 0 2px 1px;
> [class*='grid-holder'] {
display: block;
}
}
}
}
/*********************** EDIT MARQUEE CONTROL */
*[s-selected-parent] {
> .l-layout {
// When main shell layout is the parent
@include displayMarquee(deeppink);
}
> * > * > * {
// When a sub-layout is the parent
@include displayMarquee(blue);
}
}
}
</style>
<script>
import uuid from 'uuid';

View File

@ -45,66 +45,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-frame-edit {
// In Layouts, this is the editing rect and handles
display: none; // Set to display: block in DisplayLayout.vue
pointer-events: none;
@include abs();
border: $editMarqueeBorder;
&__handle {
$d: 6px;
$o: floor($d * -0.5);
background: $editFrameColorHandleFg;
box-shadow: $editFrameColorHandleBg 0 0 0 2px;
pointer-events: all;
position: absolute;
width: $d; height: $d;
top: auto; right: auto; bottom: auto; left: auto;
&:before {
// Extended hit area
@include abs(-10px);
content: '';
display: block;
z-index: 0;
}
&:hover {
background: $editUIColor;
}
&--nwse {
cursor: nwse-resize;
}
&--nw {
cursor: nw-resize;
left: $o; top: $o;
}
&--ne {
cursor: ne-resize;
right: $o; top: $o;
}
&--se {
cursor: se-resize;
right: $o; bottom: $o;
}
&--sw {
cursor: sw-resize;
left: $o; bottom: $o;
}
}
}
</style>
<script>
import LayoutDrag from './../LayoutDrag'

View File

@ -34,21 +34,6 @@
</layout-frame>
</template>
<style lang="scss">
@import '~styles/sass-base';
.c-image-view {
background-size: cover;
background-repeat: no-repeat;
background-position: center;
.c-frame & {
@include abs();
border: 1px solid transparent;
}
}
</style>
<script>
import LayoutFrame from './LayoutFrame.vue'

View File

@ -38,142 +38,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
/******************* FRAME */
.c-frame {
display: flex;
flex-direction: column;
// Whatever is placed into the slot, make it fill the entirety of the space, obeying padding
> *:first-child {
flex: 1 1 auto;
}
}
.c-frame-edit__move {
display: none;
}
.is-editing {
/******************* STYLES FOR C-FRAME WHILE EDITING */
.c-frame {
&:not([s-selected]) {
&:hover {
border: $editFrameBorderHov;
}
}
&[s-selected] {
// All frames selected while editing
border: $editFrameSelectedBorder;
box-shadow: $editFrameSelectedShdw;
.c-frame-edit__move {
cursor: move;
}
}
}
/******************* DEFAULT STYLES FOR -EDIT__MOVE */
// All object types
.c-frame-edit__move {
@include abs();
display: block;
}
// Has-complex-content objects
.c-so-view.has-complex-content {
transition: $transOut;
transition-delay: $moveBarOutDelay;
> .c-so-view__local-controls {
transition: transform 250ms ease-in-out;
transition-delay: $moveBarOutDelay;
}
+ .c-frame-edit__move {
display: none;
}
}
.l-layout {
/******************* 0 - 1 ITEM SELECTED */
&:not(.is-multi-selected) {
> .l-layout__frame[s-selected] {
> .c-so-view.has-complex-content {
> .c-so-view__local-controls {
transition: transform $transOutTime ease-in-out;
transition-delay: $moveBarOutDelay;
}
+ .c-frame-edit__move {
transition: $transOut;
transition-delay: $moveBarOutDelay;
@include userSelectNone();
background: $editFrameMovebarColorBg;
box-shadow: rgba(black, 0.2) 0 1px;
bottom: auto;
display: block;
height: 0; // Height is set on hover below
opacity: 0.8;
max-height: 100%;
overflow: hidden;
text-align: center;
&:before {
// Grippy
$h: 4px;
$tbOffset: ($editFrameMovebarH - $h) / 2;
$lrOffset: 25%;
@include grippy($editFrameMovebarColorFg);
content: '';
display: block;
position: absolute;
top: $tbOffset;
right: $lrOffset;
bottom: $tbOffset;
left: $lrOffset;
}
}
}
&:hover {
> .c-so-view.has-complex-content {
transition: $transIn;
transition-delay: 0s;
padding-top: $editFrameMovebarH + $interiorMarginSm;
> .c-so-view__local-controls {
transform: translateY($editFrameMovebarH);
transition: transform $transInTime ease-in-out;
transition-delay: 0s;
}
+ .c-frame-edit__move {
transition: $transIn;
transition-delay: 0s;
height: $editFrameMovebarH;
}
}
}
}
}
/******************* > 1 ITEMS SELECTED */
&.is-multi-selected {
.l-layout__frame[s-selected] {
> .c-so-view.has-complex-content + .c-frame-edit__move {
display: block;
}
}
}
}
}
</style>
<script>
import LayoutDrag from './../LayoutDrag'

View File

@ -56,40 +56,6 @@
</layout-frame>
</template>
<style lang="scss">
@import '~styles/sass-base';
.c-telemetry-view {
display: flex;
align-items: stretch;
> * {
// Label and value holders
flex: 1 1 auto;
display: flex;
flex-direction: row;
// justify-content: center;
align-items: center;
overflow: hidden;
padding: $interiorMargin;
> * {
// Text elements
@include ellipsize();
}
}
> * + * {
margin-left: $interiorMargin;
}
.c-frame & {
@include abs();
border: 1px solid transparent;
}
}
</style>
<script>
import LayoutFrame from './LayoutFrame.vue'
import printj from 'printj'

View File

@ -36,20 +36,6 @@
</layout-frame>
</template>
<style lang="scss">
@import '~styles/sass-base';
.c-text-view {
display: flex;
align-items: stretch;
.c-frame & {
@include abs();
border: 1px solid transparent;
}
}
</style>
<script>
import LayoutFrame from './LayoutFrame.vue'

View File

@ -0,0 +1,8 @@
.c-box-view {
display: flex;
align-items: stretch;
.c-frame & {
@include abs();
}
}

View File

@ -0,0 +1,70 @@
@mixin displayMarquee($c) {
> .c-frame-edit {
// All other frames
//@include test($c, 0.4);
display: block;
}
> .c-frame > .c-frame-edit {
// Line object frame
//@include test($c, 0.4);
display: block;
}
}
.l-layout {
@include abs();
display: flex;
flex-direction: column;
overflow: auto;
&__grid-holder {
display: none;
}
&__frame {
position: absolute;
}
}
.is-editing {
.l-shell__main-container {
&[s-selected],
&[s-selected-parent] {
// Display grid and allow edit marquee to display in main layout holder when editing
> .l-layout {
background: $editUIGridColorBg;
> [class*="__grid-holder"] {
display: block;
}
}
}
}
.l-layout__frame {
&[s-selected],
&[s-selected-parent] {
// Display grid and allow edit marquee to display in nested layouts when editing
> * > * > .l-layout {
background: $editUIGridColorBg;
box-shadow: inset $editUIGridColorFg 0 0 2px 1px;
> [class*='grid-holder'] {
display: block;
}
}
}
}
/*********************** EDIT MARQUEE CONTROL */
*[s-selected-parent] {
> .l-layout {
// When main shell layout is the parent
@include displayMarquee(deeppink);
}
> * > * > * {
// When a sub-layout is the parent
@include displayMarquee(blue);
}
}
}

View File

@ -0,0 +1,54 @@
.c-frame-edit {
// In Layouts, this is the editing rect and handles
display: none; // Set to display: block in DisplayLayout.vue
pointer-events: none;
@include abs();
border: $editMarqueeBorder;
&__handle {
$d: 6px;
$o: floor($d * -0.5);
background: $editFrameColorHandleFg;
box-shadow: $editFrameColorHandleBg 0 0 0 2px;
pointer-events: all;
position: absolute;
width: $d; height: $d;
top: auto; right: auto; bottom: auto; left: auto;
&:before {
// Extended hit area
@include abs(-10px);
content: '';
display: block;
z-index: 0;
}
&:hover {
background: $editUIColor;
}
&--nwse {
cursor: nwse-resize;
}
&--nw {
cursor: nw-resize;
left: $o; top: $o;
}
&--ne {
cursor: ne-resize;
right: $o; top: $o;
}
&--se {
cursor: se-resize;
right: $o; bottom: $o;
}
&--sw {
cursor: sw-resize;
left: $o; bottom: $o;
}
}
}

View File

@ -0,0 +1,10 @@
.c-image-view {
background-size: cover;
background-repeat: no-repeat;
background-position: center;
.c-frame & {
@include abs();
border: 1px solid transparent;
}
}

View File

@ -0,0 +1,131 @@
/******************* FRAME */
.c-frame {
display: flex;
flex-direction: column;
// Whatever is placed into the slot, make it fill the entirety of the space, obeying padding
> *:first-child {
flex: 1 1 auto;
}
}
.c-frame-edit__move {
display: none;
}
.is-editing {
/******************* STYLES FOR C-FRAME WHILE EDITING */
.c-frame {
&:not([s-selected]) {
&:hover {
border: $editFrameBorderHov;
}
}
&[s-selected] {
// All frames selected while editing
border: $editFrameSelectedBorder;
box-shadow: $editFrameSelectedShdw;
.c-frame-edit__move {
cursor: move;
}
}
}
/******************* DEFAULT STYLES FOR -EDIT__MOVE */
// All object types
.c-frame-edit__move {
@include abs();
display: block;
}
// Has-complex-content objects
.c-so-view.has-complex-content {
transition: $transOut;
transition-delay: $moveBarOutDelay;
> .c-so-view__local-controls {
transition: transform 250ms ease-in-out;
transition-delay: $moveBarOutDelay;
}
+ .c-frame-edit__move {
display: none;
}
}
.l-layout {
/******************* 0 - 1 ITEM SELECTED */
&:not(.is-multi-selected) {
> .l-layout__frame[s-selected] {
> .c-so-view.has-complex-content {
> .c-so-view__local-controls {
transition: transform $transOutTime ease-in-out;
transition-delay: $moveBarOutDelay;
}
+ .c-frame-edit__move {
transition: $transOut;
transition-delay: $moveBarOutDelay;
@include userSelectNone();
background: $editFrameMovebarColorBg;
box-shadow: rgba(black, 0.2) 0 1px;
bottom: auto;
display: block;
height: 0; // Height is set on hover below
opacity: 0.8;
max-height: 100%;
overflow: hidden;
text-align: center;
&:before {
// Grippy
$h: 4px;
$tbOffset: ($editFrameMovebarH - $h) / 2;
$lrOffset: 25%;
@include grippy($editFrameMovebarColorFg);
content: '';
display: block;
position: absolute;
top: $tbOffset;
right: $lrOffset;
bottom: $tbOffset;
left: $lrOffset;
}
}
}
&:hover {
> .c-so-view.has-complex-content {
transition: $transIn;
transition-delay: 0s;
padding-top: $editFrameMovebarH + $interiorMarginSm;
> .c-so-view__local-controls {
transform: translateY($editFrameMovebarH);
transition: transform $transInTime ease-in-out;
transition-delay: 0s;
}
+ .c-frame-edit__move {
transition: $transIn;
transition-delay: 0s;
height: $editFrameMovebarH;
}
}
}
}
}
/******************* > 1 ITEMS SELECTED */
&.is-multi-selected {
.l-layout__frame[s-selected] {
> .c-so-view.has-complex-content + .c-frame-edit__move {
display: block;
}
}
}
}
}

View File

@ -0,0 +1,29 @@
.c-telemetry-view {
display: flex;
align-items: stretch;
> * {
// Label and value holders
flex: 1 1 auto;
display: flex;
flex-direction: row;
// justify-content: center;
align-items: center;
overflow: hidden;
padding: $interiorMargin;
> * {
// Text elements
@include ellipsize();
}
}
> * + * {
margin-left: $interiorMargin;
}
.c-frame & {
@include abs();
border: 1px solid transparent;
}
}

View File

@ -0,0 +1,9 @@
.c-text-view {
display: flex;
align-items: stretch;
.c-frame & {
@include abs();
border: 1px solid transparent;
}
}

View File

@ -25,26 +25,6 @@
</ul>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-inspector {
.c-filter-indication {
border-radius: $smallCr;
font-size: inherit;
padding: $interiorMarginSm $interiorMargin;
text-transform: inherit;
}
.c-filter-tree {
// Filters UI uses a tree-based structure
.c-properties {
// Add extra margin to account for filter-indicator
margin-left: 38px;
}
}
}
</style>
<script>
import FilterObject from './FilterObject.vue';
import GlobalFilters from './GlobalFilters.vue'

View File

@ -37,38 +37,6 @@
</li>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-filter-indication {
// Appears as a block element beneath tables
@include userSelectNone();
background: $colorFilterBg;
color: $colorFilterFg;
display: flex;
align-items: center;
font-size: 0.9em;
margin-top: $interiorMarginSm;
padding: 2px;
text-transform: uppercase;
&:before {
font-family: symbolsfont-12px;
content: $glyph-icon-filter;
display: block;
font-size: 12px;
margin-right: $interiorMarginSm;
}
}
.c-filter-tree-item {
&__filter-indicator {
color: $colorFilter;
width: 1.2em; // Set width explicitly for layout reasons: will either have class icon-filter, or none.
flex: 0 0 auto;
}
}
</style>
<script>
import FilterField from './FilterField.vue';

View File

@ -0,0 +1,15 @@
.c-inspector {
.c-filter-indication {
border-radius: $smallCr;
font-size: inherit;
padding: $interiorMarginSm $interiorMargin;
text-transform: inherit;
}
.c-filter-tree {
// Filters UI uses a tree-based structure
.c-properties {
// Add extra margin to account for filter-indicator
margin-left: 38px;
}
}
}

View File

@ -0,0 +1,28 @@
.c-filter-indication {
// Appears as a block element beneath tables
@include userSelectNone();
background: $colorFilterBg;
color: $colorFilterFg;
display: flex;
align-items: center;
font-size: 0.9em;
margin-top: $interiorMarginSm;
padding: 2px;
text-transform: uppercase;
&:before {
font-family: symbolsfont-12px;
content: $glyph-icon-filter;
display: block;
font-size: 12px;
margin-right: $interiorMarginSm;
}
}
.c-filter-tree-item {
&__filter-indicator {
color: $colorFilter;
width: 1.2em; // Set width explicitly for layout reasons: will either have class icon-filter, or none.
flex: 0 0 auto;
}
}

View File

@ -33,10 +33,6 @@
</div>
</template>
<style lang="scss">
</style>
<script>
export default {
props:{

View File

@ -0,0 +1,320 @@
@mixin containerGrippy($headerSize, $dir) {
position: absolute;
$h: 6px;
$minorOffset: ($headerSize - $h) / 2;
$majorOffset: 35%;
content: '';
display: block;
position: absolute;
@include grippy($c: $editFrameSelectedMovebarColorFg, $dir: $dir);
@if $dir == 'x' {
top: $minorOffset; right: $majorOffset; bottom: $minorOffset; left: $majorOffset;
} @else {
top: $majorOffset; right: $minorOffset; bottom: $majorOffset; left: $minorOffset;
}
}
.c-fl {
@include abs();
display: flex;
.temp-toolbar {
flex: 0 0 auto;
}
&__container-holder {
display: flex;
flex: 1 1 100%; // Must be 100% to work
overflow: auto;
// Columns by default
flex-direction: row;
> * + * { margin-left: 1px; }
&[class*='--rows'] {
flex-direction: column;
> * + * {
margin-left: 0;
margin-top: 1px;
}
}
}
&__empty {
@include abs();
background: rgba($colorBodyFg, 0.1);
display: flex;
align-items: center;
justify-content: center;
text-align: center;
> * {
font-style: italic;
opacity: 0.5;
}
}
&__drag-ghost{
background: $colorItemTreeHoverBg;
color: $colorItemTreeHoverFg;
border-radius: $basicCr;
display: flex;
align-items: center;
padding: $interiorMarginLg $interiorMarginLg * 2;
position: absolute;
top: -10000px;
z-index: 2;
&:before {
color: $colorKey;
margin-right: $interiorMarginSm;
}
}
}
.c-fl-container {
/***************************************************** CONTAINERS */
$headerSize: 16px;
display: flex;
flex-direction: column;
overflow: auto;
// flex-basis is set with inline style in code, controls size
flex-grow: 1;
flex-shrink: 1;
&__header {
// Only displayed when editing, controlled via JS
background: $editFrameMovebarColorBg;
color: $editFrameMovebarColorFg;
cursor: move;
display: flex;
align-items: center;
flex: 0 0 $headerSize;
&:before {
// Drag grippy
@include containerGrippy($headerSize, 'x');
opacity: 0.5;
}
}
&__size-indicator {
position: absolute;
display: inline-block;
right: $interiorMargin;
}
&__frames-holder {
display: flex;
flex: 1 1 100%; // Must be 100% to work
flex-direction: column; // Default
align-content: stretch;
align-items: stretch;
overflow: hidden; // This sucks, but doing in the short-term
}
.is-editing & {
&:hover {
.c-fl-container__header {
background: $editFrameHovMovebarColorBg;
color: $editFrameHovMovebarColorFg;
&:before {
opacity: .75;
}
}
}
&[s-selected] {
border: $editFrameSelectedBorder;
.c-fl-container__header {
background:$editFrameSelectedMovebarColorBg;
color: $editFrameSelectedMovebarColorFg;
&:before {
// Grippy
opacity: 1;
}
}
}
}
/****** THEIR FRAMES */
// Frames get styled here because this is particular to their presence in this layout type
.c-fl-frame {
@include browserPrefix(margin-collapse, collapse);
}
/****** ROWS LAYOUT */
.c-fl--rows & {
// Layout is rows
flex-direction: row;
&__header {
flex-basis: $headerSize;
overflow: hidden;
&:before {
// Grippy
@include containerGrippy($headerSize, 'y');
}
}
&__size-indicator {
right: 0;
top: $interiorMargin;
transform-origin: top right;
transform: rotate(-90deg) translateY(-100%);
}
&__frames-holder {
flex-direction: row;
}
}
}
.c-fl-frame {
/***************************************************** CONTAINER FRAMES */
$sizeIndicatorM: 16px;
$dropHintSize: 15px;
display: flex;
flex: 1 1;
flex-direction: column;
overflow: hidden; // Needed to allow frames to collapse when sized down
&__drag-wrapper {
flex: 1 1 auto;
overflow: auto;
.is-editing & {
> * {
pointer-events: none;
}
}
}
&__header {
flex: 0 0 auto;
margin-bottom: $interiorMargin;
}
&__size-indicator {
$size: 35px;
@include ellipsize();
background: $colorBtnBg;
border-top-left-radius: $controlCr;
color: $colorBtnFg;
display: inline-block;
padding: $interiorMarginSm 0;
position: absolute;
pointer-events: none;
text-align: center;
width: $size;
// Changed when layout is different, see below
border-top-right-radius: $controlCr;
bottom: 1px;
right: $sizeIndicatorM;
}
&__drop-hint {
flex: 0 0 $dropHintSize;
.c-drop-hint {
border-radius: $smallCr;
}
}
&__resize-handle {
$size: 2px;
$margin: 3px;
$marginHov: 0;
$grippyThickness: $size + 6;
$grippyLen: $grippyThickness * 2;
display: flex;
flex-direction: column;
flex: 0 0 ($margin * 2) + $size;
transition: $transOut;
&:before {
// The visible resize line
background: $editUIColor;
content: '';
display: block;
flex: 1 1 auto;
min-height: $size; min-width: $size;
}
&.vertical {
padding: $margin $size;
&:hover{
cursor: row-resize;
}
}
&.horizontal {
padding: $size $margin;
&:hover{
cursor: col-resize;
}
}
&:hover {
transition: $transOut;
&:before {
// The visible resize line
background: $editUIColorHov;
}
}
}
// Hide the resize-handles in first and last c-fl-frame elements
&:first-child,
&:last-child {
.c-fl-frame__resize-handle {
display: none;
}
}
.c-fl--rows & {
flex-direction: row;
&__size-indicator {
border-bottom-left-radius: $controlCr;
border-top-right-radius: 0;
bottom: $sizeIndicatorM;
right: 1px;
}
}
&--first-in-container {
border: none;
flex: 0 0 0;
.c-fl-frame__drag-wrapper {
display: none;
}
&.is-dragging {
flex-basis: $dropHintSize;
}
}
.is-empty & {
&.c-fl-frame--first-in-container {
flex: 1 1 auto;
}
&__drop-hint {
flex: 1 0 100%;
margin: 0;
}
}
.c-object-view {
display: contents;
}
}

View File

@ -86,331 +86,6 @@
</div>
</template>
<style lang="scss">
@import '~styles/sass-base';
@mixin containerGrippy($headerSize, $dir) {
position: absolute;
$h: 6px;
$minorOffset: ($headerSize - $h) / 2;
$majorOffset: 35%;
content: '';
display: block;
position: absolute;
@include grippy($c: $editFrameSelectedMovebarColorFg, $dir: $dir);
@if $dir == 'x' {
top: $minorOffset; right: $majorOffset; bottom: $minorOffset; left: $majorOffset;
} @else {
top: $majorOffset; right: $minorOffset; bottom: $majorOffset; left: $minorOffset;
}
}
.c-fl {
@include abs();
display: flex;
.temp-toolbar {
flex: 0 0 auto;
}
&__container-holder {
display: flex;
flex: 1 1 100%; // Must be 100% to work
overflow: auto;
// Columns by default
flex-direction: row;
> * + * { margin-left: 1px; }
&[class*='--rows'] {
flex-direction: column;
> * + * {
margin-left: 0;
margin-top: 1px;
}
}
}
&__empty {
@include abs();
background: rgba($colorBodyFg, 0.1);
display: flex;
align-items: center;
justify-content: center;
text-align: center;
> * {
font-style: italic;
opacity: 0.5;
}
}
&__drag-ghost{
background: $colorItemTreeHoverBg;
color: $colorItemTreeHoverFg;
border-radius: $basicCr;
display: flex;
align-items: center;
padding: $interiorMarginLg $interiorMarginLg * 2;
position: absolute;
top: -10000px;
z-index: 2;
&:before {
color: $colorKey;
margin-right: $interiorMarginSm;
}
}
}
.c-fl-container {
/***************************************************** CONTAINERS */
$headerSize: 16px;
display: flex;
flex-direction: column;
overflow: auto;
// flex-basis is set with inline style in code, controls size
flex-grow: 1;
flex-shrink: 1;
&__header {
// Only displayed when editing, controlled via JS
background: $editFrameMovebarColorBg;
color: $editFrameMovebarColorFg;
cursor: move;
display: flex;
align-items: center;
flex: 0 0 $headerSize;
&:before {
// Drag grippy
@include containerGrippy($headerSize, 'x');
opacity: 0.5;
}
}
&__size-indicator {
position: absolute;
display: inline-block;
right: $interiorMargin;
}
&__frames-holder {
display: flex;
flex: 1 1 100%; // Must be 100% to work
flex-direction: column; // Default
align-content: stretch;
align-items: stretch;
overflow: hidden; // This sucks, but doing in the short-term
}
.is-editing & {
&:hover {
.c-fl-container__header {
background: $editFrameHovMovebarColorBg;
color: $editFrameHovMovebarColorFg;
&:before {
opacity: .75;
}
}
}
&[s-selected] {
border: $editFrameSelectedBorder;
.c-fl-container__header {
background:$editFrameSelectedMovebarColorBg;
color: $editFrameSelectedMovebarColorFg;
&:before {
// Grippy
opacity: 1;
}
}
}
}
/****** THEIR FRAMES */
// Frames get styled here because this is particular to their presence in this layout type
.c-fl-frame {
@include browserPrefix(margin-collapse, collapse);
}
/****** ROWS LAYOUT */
.c-fl--rows & {
// Layout is rows
flex-direction: row;
&__header {
flex-basis: $headerSize;
overflow: hidden;
&:before {
// Grippy
@include containerGrippy($headerSize, 'y');
}
}
&__size-indicator {
right: 0;
top: $interiorMargin;
transform-origin: top right;
transform: rotate(-90deg) translateY(-100%);
}
&__frames-holder {
flex-direction: row;
}
}
}
.c-fl-frame {
/***************************************************** CONTAINER FRAMES */
$sizeIndicatorM: 16px;
$dropHintSize: 15px;
display: flex;
flex: 1 1;
flex-direction: column;
overflow: hidden; // Needed to allow frames to collapse when sized down
&__drag-wrapper {
flex: 1 1 auto;
overflow: auto;
.is-editing & {
> * {
pointer-events: none;
}
}
}
&__header {
flex: 0 0 auto;
margin-bottom: $interiorMargin;
}
&__size-indicator {
$size: 35px;
@include ellipsize();
background: $colorBtnBg;
border-top-left-radius: $controlCr;
color: $colorBtnFg;
display: inline-block;
padding: $interiorMarginSm 0;
position: absolute;
pointer-events: none;
text-align: center;
width: $size;
// Changed when layout is different, see below
border-top-right-radius: $controlCr;
bottom: 1px;
right: $sizeIndicatorM;
}
&__drop-hint {
flex: 0 0 $dropHintSize;
.c-drop-hint {
border-radius: $smallCr;
}
}
&__resize-handle {
$size: 2px;
$margin: 3px;
$marginHov: 0;
$grippyThickness: $size + 6;
$grippyLen: $grippyThickness * 2;
display: flex;
flex-direction: column;
flex: 0 0 ($margin * 2) + $size;
transition: $transOut;
&:before {
// The visible resize line
background: $editUIColor;
content: '';
display: block;
flex: 1 1 auto;
min-height: $size; min-width: $size;
}
&.vertical {
padding: $margin $size;
&:hover{
cursor: row-resize;
}
}
&.horizontal {
padding: $size $margin;
&:hover{
cursor: col-resize;
}
}
&:hover {
transition: $transOut;
&:before {
// The visible resize line
background: $editUIColorHov;
}
}
}
// Hide the resize-handles in first and last c-fl-frame elements
&:first-child,
&:last-child {
.c-fl-frame__resize-handle {
display: none;
}
}
.c-fl--rows & {
flex-direction: row;
&__size-indicator {
border-bottom-left-radius: $controlCr;
border-top-right-radius: 0;
bottom: $sizeIndicatorM;
right: 1px;
}
}
&--first-in-container {
border: none;
flex: 0 0 0;
.c-fl-frame__drag-wrapper {
display: none;
}
&.is-dragging {
flex-basis: $dropHintSize;
}
}
.is-empty & {
&.c-fl-frame--first-in-container {
flex: 1 1 auto;
}
&__drop-hint {
flex: 1 0 100%;
margin: 0;
}
}
.c-object-view {
display: contents;
}
}
</style>
<script>
import ContainerComponent from './container.vue';
import Container from '../utils/container';

View File

@ -35,132 +35,6 @@
</a>
</template>
<style lang="scss">
@import "~styles/sass-base";
/******************************* GRID ITEMS */
.c-grid-item {
// Mobile-first
@include button($bg: $colorItemBg, $fg: $colorItemFg);
cursor: pointer;
display: flex;
padding: $interiorMarginLg;
&__type-icon {
filter: $colorKeyFilter;
flex: 0 0 $gridItemMobile;
font-size: floor($gridItemMobile / 2);
margin-right: $interiorMarginLg;
}
&.is-alias {
// Object is an alias to an original.
[class*='__type-icon'] {
@include isAlias();
color: $colorIconAliasForKeyFilter;
}
}
&__details {
display: flex;
flex-flow: column nowrap;
flex: 1 1 auto;
}
&__name {
@include ellipsize();
color: $colorItemFg;
@include headerFont(1.2em);
margin-bottom: $interiorMarginSm;
}
&__metadata {
color: $colorItemFgDetails;
font-size: 0.9em;
body.mobile & {
[class*='__item-count'] {
&:before {
content: ' - ';
}
}
}
}
&__controls {
color: $colorItemFgDetails;
flex: 0 0 64px;
font-size: 1.2em;
display: flex;
align-items: center;
justify-content: flex-end;
> * + * {
margin-left: $interiorMargin;
}
}
body.desktop & {
$transOutMs: 300ms;
flex-flow: column nowrap;
transition: background $transOutMs ease-in-out;
&:hover {
background: $colorItemBgHov;
transition: $transIn;
.c-grid-item__type-icon {
filter: $colorKeyFilterHov;
transform: scale(1);
transition: $transInBounce;
}
}
> * {
margin: 0; // Reset from mobile
}
&__controls {
align-items: start;
flex: 0 0 auto;
order: 1;
.c-info-button,
.c-pointer-icon { display: none; }
}
&__type-icon {
flex: 1 1 auto;
font-size: floor($gridItemDesk / 3);
margin: $interiorMargin 22.5% $interiorMargin * 3 22.5%;
order: 2;
transform: scale(0.9);
transform-origin: center;
transition: all $transOutMs ease-in-out;
}
&__details {
flex: 0 0 auto;
justify-content: flex-end;
order: 3;
}
&__metadata {
display: flex;
&__type {
flex: 1 1 auto;
@include ellipsize();
}
&__item-count {
opacity: 0.7;
flex: 0 0 auto;
}
}
}
}
</style>
<script>
import contextMenuGesture from '../../../ui/mixins/context-menu-gesture';
import objectLink from '../../../ui/mixins/object-link';

View File

@ -9,154 +9,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
/******************************* GRID VIEW */
.l-grid-view {
display: flex;
flex-flow: column nowrap;
overflow: auto;
&__item {
flex: 0 0 auto;
+ .l-grid-view__item { margin-top: $interiorMargin; }
}
body.desktop & {
flex-flow: row wrap;
&__item {
height: $gridItemDesk;
width: $gridItemDesk;
margin: 0 $interiorMargin $interiorMargin 0;
}
}
}
/******************************* GRID ITEMS */
.c-grid-item {
// Mobile-first
@include button($bg: $colorItemBg, $fg: $colorItemFg);
cursor: pointer;
display: flex;
padding: $interiorMarginLg;
&__type-icon {
filter: $colorKeyFilter;
flex: 0 0 $gridItemMobile;
font-size: floor($gridItemMobile / 2);
margin-right: $interiorMarginLg;
}
&.is-alias {
// Object is an alias to an original.
[class*='__type-icon'] {
@include isAlias();
color: $colorIconAliasForKeyFilter;
}
}
&__details {
display: flex;
flex-flow: column nowrap;
flex: 1 1 auto;
}
&__name {
@include ellipsize();
color: $colorItemFg;
font-size: 1.2em;
font-weight: 400;
margin-bottom: $interiorMarginSm;
}
&__metadata {
color: $colorItemFgDetails;
font-size: 0.9em;
body.mobile & {
[class*='__item-count'] {
&:before {
content: ' - ';
}
}
}
}
&__controls {
color: $colorItemFgDetails;
flex: 0 0 64px;
font-size: 1.2em;
display: flex;
align-items: center;
justify-content: flex-end;
> * + * {
margin-left: $interiorMargin;
}
}
body.desktop & {
$transOutMs: 300ms;
flex-flow: column nowrap;
transition: background $transOutMs ease-in-out;
&:hover {
background: $colorItemBgHov;
transition: $transIn;
.c-grid-item__type-icon {
filter: $colorKeyFilterHov;
transform: scale(1);
transition: $transInBounce;
}
}
> * {
margin: 0; // Reset from mobile
}
&__controls {
align-items: start;
flex: 0 0 auto;
order: 1;
.c-info-button,
.c-pointer-icon { display: none; }
}
&__type-icon {
flex: 1 1 auto;
font-size: floor($gridItemDesk / 3);
margin: $interiorMargin 22.5% $interiorMargin * 3 22.5%;
order: 2;
transform: scale(0.9);
transform-origin: center;
transition: all $transOutMs ease-in-out;
}
&__details {
flex: 0 0 auto;
justify-content: flex-end;
order: 3;
}
&__metadata {
display: flex;
&__type {
flex: 1 1 auto;
@include ellipsize();
}
&__item-count {
opacity: 0.7;
flex: 0 0 auto;
}
}
}
}
</style>
<script>
import compositionLoader from './composition-loader';

View File

@ -28,48 +28,6 @@
</tr>
</template>
<style lang="scss">
@import "~styles/sass-base";
/******************************* LIST ITEM */
.c-list-item {
&__name a {
display: flex;
> * + * { margin-left: $interiorMarginSm; }
}
&__type-icon {
// Have to do it this way instead of using icon-* class, due to need to apply alias to the icon
color: $colorKey;
display: inline-block;
width: 1em;
margin-right:$interiorMarginSm;
}
&__name-value {
@include ellipsize();
}
&.is-alias {
// Object is an alias to an original.
[class*='__type-icon'] {
&:after {
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);
}
}
}
}
</style>
<script>
import moment from 'moment';

View File

@ -61,46 +61,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
/******************************* LIST VIEW */
.c-list-view {
overflow-x: auto !important;
overflow-y: auto;
tbody tr {
background: $colorListItemBg;
transition: $transOut;
}
body.desktop & {
tbody tr {
cursor: pointer;
&:hover {
background: $colorListItemBgHov;
transition: $transIn;
}
}
}
td {
$p: floor($interiorMargin * 1.5);
@include ellipsize();
line-height: 120%; // Needed for icon alignment
max-width: 0;
padding-top: $p;
padding-bottom: $p;
width: 25%;
&:not(.c-list-item__name) {
color: $colorItemFgDetails;
}
}
}
</style>
<script>
import compositionLoader from './composition-loader';
import ListItem from './ListItem.vue';

View File

@ -0,0 +1,121 @@
/******************************* GRID ITEMS */
.c-grid-item {
// Mobile-first
@include button($bg: $colorItemBg, $fg: $colorItemFg);
cursor: pointer;
display: flex;
padding: $interiorMarginLg;
&__type-icon {
filter: $colorKeyFilter;
flex: 0 0 $gridItemMobile;
font-size: floor($gridItemMobile / 2);
margin-right: $interiorMarginLg;
}
&.is-alias {
// Object is an alias to an original.
[class*='__type-icon'] {
@include isAlias();
color: $colorIconAliasForKeyFilter;
}
}
&__details {
display: flex;
flex-flow: column nowrap;
flex: 1 1 auto;
}
&__name {
@include ellipsize();
color: $colorItemFg;
@include headerFont(1.2em);
margin-bottom: $interiorMarginSm;
}
&__metadata {
color: $colorItemFgDetails;
font-size: 0.9em;
body.mobile & {
[class*='__item-count'] {
&:before {
content: ' - ';
}
}
}
}
&__controls {
color: $colorItemFgDetails;
flex: 0 0 64px;
font-size: 1.2em;
display: flex;
align-items: center;
justify-content: flex-end;
> * + * {
margin-left: $interiorMargin;
}
}
body.desktop & {
$transOutMs: 300ms;
flex-flow: column nowrap;
transition: background $transOutMs ease-in-out;
&:hover {
background: $colorItemBgHov;
transition: $transIn;
.c-grid-item__type-icon {
filter: $colorKeyFilterHov;
transform: scale(1);
transition: $transInBounce;
}
}
> * {
margin: 0; // Reset from mobile
}
&__controls {
align-items: start;
flex: 0 0 auto;
order: 1;
.c-info-button,
.c-pointer-icon { display: none; }
}
&__type-icon {
flex: 1 1 auto;
font-size: floor($gridItemDesk / 3);
margin: $interiorMargin 22.5% $interiorMargin * 3 22.5%;
order: 2;
transform: scale(0.9);
transform-origin: center;
transition: all $transOutMs ease-in-out;
}
&__details {
flex: 0 0 auto;
justify-content: flex-end;
order: 3;
}
&__metadata {
display: flex;
&__type {
flex: 1 1 auto;
@include ellipsize();
}
&__item-count {
opacity: 0.7;
flex: 0 0 auto;
}
}
}
}

View File

@ -0,0 +1,143 @@
/******************************* GRID VIEW */
.l-grid-view {
display: flex;
flex-flow: column nowrap;
overflow: auto;
&__item {
flex: 0 0 auto;
+ .l-grid-view__item { margin-top: $interiorMargin; }
}
body.desktop & {
flex-flow: row wrap;
&__item {
height: $gridItemDesk;
width: $gridItemDesk;
margin: 0 $interiorMargin $interiorMargin 0;
}
}
}
/******************************* GRID ITEMS */
.c-grid-item {
// Mobile-first
@include button($bg: $colorItemBg, $fg: $colorItemFg);
cursor: pointer;
display: flex;
padding: $interiorMarginLg;
&__type-icon {
filter: $colorKeyFilter;
flex: 0 0 $gridItemMobile;
font-size: floor($gridItemMobile / 2);
margin-right: $interiorMarginLg;
}
&.is-alias {
// Object is an alias to an original.
[class*='__type-icon'] {
@include isAlias();
color: $colorIconAliasForKeyFilter;
}
}
&__details {
display: flex;
flex-flow: column nowrap;
flex: 1 1 auto;
}
&__name {
@include ellipsize();
color: $colorItemFg;
font-size: 1.2em;
font-weight: 400;
margin-bottom: $interiorMarginSm;
}
&__metadata {
color: $colorItemFgDetails;
font-size: 0.9em;
body.mobile & {
[class*='__item-count'] {
&:before {
content: ' - ';
}
}
}
}
&__controls {
color: $colorItemFgDetails;
flex: 0 0 64px;
font-size: 1.2em;
display: flex;
align-items: center;
justify-content: flex-end;
> * + * {
margin-left: $interiorMargin;
}
}
body.desktop & {
$transOutMs: 300ms;
flex-flow: column nowrap;
transition: background $transOutMs ease-in-out;
&:hover {
background: $colorItemBgHov;
transition: $transIn;
.c-grid-item__type-icon {
filter: $colorKeyFilterHov;
transform: scale(1);
transition: $transInBounce;
}
}
> * {
margin: 0; // Reset from mobile
}
&__controls {
align-items: start;
flex: 0 0 auto;
order: 1;
.c-info-button,
.c-pointer-icon { display: none; }
}
&__type-icon {
flex: 1 1 auto;
font-size: floor($gridItemDesk / 3);
margin: $interiorMargin 22.5% $interiorMargin * 3 22.5%;
order: 2;
transform: scale(0.9);
transform-origin: center;
transition: all $transOutMs ease-in-out;
}
&__details {
flex: 0 0 auto;
justify-content: flex-end;
order: 3;
}
&__metadata {
display: flex;
&__type {
flex: 1 1 auto;
@include ellipsize();
}
&__item-count {
opacity: 0.7;
flex: 0 0 auto;
}
}
}
}

View File

@ -0,0 +1,37 @@
/******************************* LIST ITEM */
.c-list-item {
&__name a {
display: flex;
> * + * { margin-left: $interiorMarginSm; }
}
&__type-icon {
// Have to do it this way instead of using icon-* class, due to need to apply alias to the icon
color: $colorKey;
display: inline-block;
width: 1em;
margin-right:$interiorMarginSm;
}
&__name-value {
@include ellipsize();
}
&.is-alias {
// Object is an alias to an original.
[class*='__type-icon'] {
&:after {
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

@ -0,0 +1,35 @@
/******************************* LIST VIEW */
.c-list-view {
overflow-x: auto !important;
overflow-y: auto;
tbody tr {
background: $colorListItemBg;
transition: $transOut;
}
body.desktop & {
tbody tr {
cursor: pointer;
&:hover {
background: $colorListItemBgHov;
transition: $transIn;
}
}
}
td {
$p: floor($interiorMargin * 1.5);
@include ellipsize();
line-height: 120%; // Needed for icon alignment
max-width: 0;
padding-top: $p;
padding-bottom: $p;
width: 25%;
&:not(.c-list-item__name) {
color: $colorItemFgDetails;
}
}
}

View File

@ -45,7 +45,10 @@ define([
'./objectMigration/plugin',
'./goToOriginalAction/plugin',
'./clearData/plugin',
'./webPage/plugin'
'./webPage/plugin',
'./themes/espresso',
'./themes/maelstrom',
'./themes/snow'
], function (
_,
UTCTimeSystem,
@ -71,7 +74,10 @@ define([
ObjectMigration,
GoToOriginalAction,
ClearData,
WebPagePlugin
WebPagePlugin,
Espresso,
Maelstrom,
Snow
) {
var bundleMap = {
LocalStorage: 'platform/persistence/local',
@ -173,6 +179,9 @@ define([
plugins.GoToOriginalAction = GoToOriginalAction.default;
plugins.ClearData = ClearData;
plugins.WebPage = WebPagePlugin.default;
plugins.Espresso = Espresso.default;
plugins.Maelstrom = Maelstrom.default;
plugins.Snow = Snow.default;
return plugins;
});

View File

@ -0,0 +1,58 @@
.c-tabs-view {
$h: 20px;
@include abs();
display: flex;
flex-flow: column nowrap;
> * + * {
margin-top: $interiorMargin;
}
&__tabs-holder {
min-height: $h;
}
&__tab {
&:before {
margin-right: $interiorMarginSm;
opacity: 0.7;
}
}
&__object-holder {
flex: 1 1 auto;
display: flex;
flex-direction: column;
&--hidden {
height: 1000px;
width: 1000px;
position: absolute;
left: -9999px;
top: -9999px;
}
}
&__object-name {
flex: 0 0 auto;
@include headerFont();
font-size: 1.2em !important;
margin: $interiorMargin 0 $interiorMarginLg 0;
}
&__object {
display: flex;
flex-flow: column nowrap;
flex: 1 1 auto;
height: 0; // Chrome 73 oveflow bug fix
}
&__empty-message {
background: rgba($colorBodyFg, 0.1);
color: rgba($colorBodyFg, 0.7);
font-style: italic;
text-align: center;
line-height: $h;
width: 100%;
}
}

View File

@ -55,69 +55,6 @@
</div>
</template>
<style lang="scss">
@import '~styles/sass-base.scss';
.c-tabs-view {
$h: 20px;
@include abs();
display: flex;
flex-flow: column nowrap;
> * + * {
margin-top: $interiorMargin;
}
&__tabs-holder {
min-height: $h;
}
&__tab {
&:before {
margin-right: $interiorMarginSm;
opacity: 0.7;
}
}
&__object-holder {
flex: 1 1 auto;
display: flex;
flex-direction: column;
&--hidden {
height: 1000px;
width: 1000px;
position: absolute;
left: -9999px;
top: -9999px;
}
}
&__object-name {
flex: 0 0 auto;
@include headerFont();
font-size: 1.2em !important;
margin: $interiorMargin 0 $interiorMarginLg 0;
}
&__object {
display: flex;
flex-flow: column nowrap;
flex: 1 1 auto;
height: 0; // Chrome 73 oveflow bug fix
}
&__empty-message {
background: rgba($colorBodyFg, 0.1);
color: rgba($colorBodyFg, 0.7);
font-style: italic;
text-align: center;
line-height: $h;
width: 100%;
}
}
</style>
<script>
import ObjectView from '../../../ui/components/ObjectView.vue';
import _ from 'lodash';

View File

@ -16,47 +16,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-filter-indication {
@include userSelectNone();
background: $colorFilterBg;
color: $colorFilterFg;
display: flex;
align-items: center;
font-size: 0.9em;
margin-top: $interiorMarginSm;
padding: 2px;
text-transform: uppercase;
&:before {
font-family: symbolsfont-12px;
content: $glyph-icon-filter;
display: block;
font-size: 12px;
margin-right: $interiorMarginSm;
}
&__mixed {
margin-right: $interiorMarginSm;
}
&--mixed {
.c-filter-indication__mixed {
font-style: italic;
}
}
&__label {
+ .c-filter-indication__label {
&:before {
content: ',';
}
}
}
}
</style>
<script>
const FILTER_INDICATOR_LABEL = 'Filters:';
const FILTER_INDICATOR_LABEL_MIXED = 'Mixed Filters:';

View File

@ -27,6 +27,7 @@
{{ formattedValue }}
</td>
</template>
<script>
export default {
inject: ['openmct'],

View File

@ -51,9 +51,6 @@
</div>
</template>
<style>
</style>
<script>
import TelemetryTableColumn from '../TelemetryTableColumn';

View File

@ -0,0 +1,9 @@
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}

View File

@ -42,18 +42,6 @@
</tr>
</template>
<style>
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
</style>
<script>
import TableCell from './table-cell.vue';

View File

@ -0,0 +1,175 @@
.c-telemetry-table__drop-target {
position: absolute;
width: 2px;
background-color: $editUIColor;
box-shadow: rgba($editUIColor, 0.5) 0 0 10px;
z-index: 1;
pointer-events: none;
}
.c-telemetry-table {
// Table that displays telemetry in a scrolling body area
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
overflow: hidden;
th, td {
display: block;
flex: 1 0 auto;
width: 100px;
vertical-align: middle; // This is crucial to hiding 4px height injected by browser by default
}
td {
color: $colorTelemFresh;
}
/******************************* WRAPPERS */
&__headers-w {
// Wraps __headers table
flex: 0 0 auto;
overflow: hidden;
background: $colorTabHeaderBg;
}
/******************************* TABLES */
&__headers,
&__body {
tr {
display: flex;
align-items: stretch;
}
}
&__headers {
// A table
thead {
display: block;
}
&__labels {
// Top row, has labels
.c-telemetry-table__headers__content {
// Holds __label, sort indicator and resize-hitarea
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
}
}
&__headers__label {
overflow: hidden;
flex: 0 1 auto;
}
&__resize-hitarea {
// In table-column-header.vue
@include abs();
display: none; // Set to display: block in .is-editing section below
left: auto; right: -1 * $tabularTdPadLR;
width: $tableResizeColHitareaD;
cursor: col-resize;
transform: translateX(50%); // Move so this element sits over border between columns
}
/******************************* ELEMENTS */
&__scroll-forcer {
// Force horz scroll when needed; width set via JS
font-size: 0;
height: 1px; // Height 0 won't force scroll properly
position: relative;
}
/******************************* WRAPPERS */
&__body-w {
// Wraps __body table provides scrolling
flex: 1 1 100%;
height: 0; // Fixes Chrome 73 overflow bug
overflow-x: auto;
overflow-y: scroll;
}
/******************************* TABLES */
&__body {
// A table
flex: 1 1 100%;
overflow-x: auto;
tr {
display: flex; // flex-flow defaults to row nowrap (which is what we want) so no need to define
align-items: stretch;
position: absolute;
height: 18px; // Needed when a row has empty values in its cells
&.is-selected {
background-color: $colorSelectedBg !important;
color: $colorSelectedFg !important;
td {
background: none !important;
color: inherit !important;
}
}
}
td {
overflow: hidden;
text-overflow: ellipsis;
}
}
&__sizing {
// A table
display: table;
z-index: -1;
visibility: hidden;
pointer-events: none;
position: absolute;
//Add some padding to allow for decorations such as limits indicator
tr {
display: table-row;
}
th, td {
display: table-cell;
padding-right: 10px;
padding-left: 10px;
white-space: nowrap;
}
}
}
/******************************* EDITING */
.is-editing {
.c-telemetry-table__headers__labels {
th[draggable],
th[draggable] > * {
cursor: move;
}
th[draggable]:hover {
$b: $editFrameHovMovebarColorBg;
background: $b;
> * { background: $b; }
}
}
.c-telemetry-table__resize-hitarea {
display: block;
}
}
.paused {
border: 1px solid #ff9900;
}
/******************************* LEGACY */
.s-status-taking-snapshot,
.overlay.snapshot {
// Handle overflow-y issues with tables and html2canvas
// Replaces .l-sticky-headers .l-tabular-body { overflow: auto; }
.c-table__body-w { overflow: auto; }
}

View File

@ -198,186 +198,6 @@
</div><!-- closes c-table-wrapper -->
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-telemetry-table__drop-target {
position: absolute;
width: 2px;
background-color: $editUIColor;
box-shadow: rgba($editUIColor, 0.5) 0 0 10px;
z-index: 1;
pointer-events: none;
}
.c-telemetry-table {
// Table that displays telemetry in a scrolling body area
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
overflow: hidden;
th, td {
display: block;
flex: 1 0 auto;
width: 100px;
vertical-align: middle; // This is crucial to hiding 4px height injected by browser by default
}
td {
color: $colorTelemFresh;
}
/******************************* WRAPPERS */
&__headers-w {
// Wraps __headers table
flex: 0 0 auto;
overflow: hidden;
background: $colorTabHeaderBg;
}
/******************************* TABLES */
&__headers,
&__body {
tr {
display: flex;
align-items: stretch;
}
}
&__headers {
// A table
thead {
display: block;
}
&__labels {
// Top row, has labels
.c-telemetry-table__headers__content {
// Holds __label, sort indicator and resize-hitarea
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
}
}
&__headers__label {
overflow: hidden;
flex: 0 1 auto;
}
&__resize-hitarea {
// In table-column-header.vue
@include abs();
display: none; // Set to display: block in .is-editing section below
left: auto; right: -1 * $tabularTdPadLR;
width: $tableResizeColHitareaD;
cursor: col-resize;
transform: translateX(50%); // Move so this element sits over border between columns
}
/******************************* ELEMENTS */
&__scroll-forcer {
// Force horz scroll when needed; width set via JS
font-size: 0;
height: 1px; // Height 0 won't force scroll properly
position: relative;
}
/******************************* WRAPPERS */
&__body-w {
// Wraps __body table provides scrolling
flex: 1 1 100%;
height: 0; // Fixes Chrome 73 overflow bug
overflow-x: auto;
overflow-y: scroll;
}
/******************************* TABLES */
&__body {
// A table
flex: 1 1 100%;
overflow-x: auto;
tr {
display: flex; // flex-flow defaults to row nowrap (which is what we want) so no need to define
align-items: stretch;
position: absolute;
height: 18px; // Needed when a row has empty values in its cells
&.is-selected {
background-color: $colorSelectedBg !important;
color: $colorSelectedFg !important;
td {
background: none !important;
color: inherit !important;
}
}
}
td {
overflow: hidden;
text-overflow: ellipsis;
}
}
&__sizing {
// A table
display: table;
z-index: -1;
visibility: hidden;
pointer-events: none;
position: absolute;
//Add some padding to allow for decorations such as limits indicator
tr {
display: table-row;
}
th, td {
display: table-cell;
padding-right: 10px;
padding-left: 10px;
white-space: nowrap;
}
}
}
/******************************* EDITING */
.is-editing {
.c-telemetry-table__headers__labels {
th[draggable],
th[draggable] > * {
cursor: move;
}
th[draggable]:hover {
$b: $editFrameHovMovebarColorBg;
background: $b;
> * { background: $b; }
}
}
.c-telemetry-table__resize-hitarea {
display: block;
}
}
.paused {
border: 1px solid #ff9900;
}
/******************************* LEGACY */
.s-status-taking-snapshot,
.overlay.snapshot {
// Handle overflow-y issues with tables and html2canvas
// Replaces .l-sticky-headers .l-tabular-body { overflow: auto; }
.c-table__body-w { overflow: auto; }
}
</style>
<script>
import TelemetryTableRow from './table-row.vue';
import search from '../../../ui/components/search.vue';

View File

@ -0,0 +1,37 @@
.c-filter-indication {
@include userSelectNone();
background: $colorFilterBg;
color: $colorFilterFg;
display: flex;
align-items: center;
font-size: 0.9em;
margin-top: $interiorMarginSm;
padding: 2px;
text-transform: uppercase;
&:before {
font-family: symbolsfont-12px;
content: $glyph-icon-filter;
display: block;
font-size: 12px;
margin-right: $interiorMarginSm;
}
&__mixed {
margin-right: $interiorMarginSm;
}
&--mixed {
.c-filter-indication__mixed {
font-style: italic;
}
}
&__label {
+ .c-filter-indication__label {
&:before {
content: ',';
}
}
}
}

View File

@ -0,0 +1,22 @@
@import "~styles/vendor/normalize-min";
@import "~styles/constants";
@import "~styles/constants-mobile.scss";
@import "~styles/constants-espresso";
@import "~styles/mixins";
@import "~styles/animations";
@import "~styles/about";
@import "~styles/glyphs";
@import "~styles/global";
@import "~styles/status";
@import "~styles/controls";
@import "~styles/forms";
@import "~styles/table";
@import "~styles/layout";
@import "~styles/legacy";
@import "~styles/legacy-plots";
@import "~styles/plotly";
@import "~styles/legacy-messages";
@import "~styles/vue-styles.scss";

View File

@ -0,0 +1,7 @@
import { installTheme } from './installTheme';
export default function plugin() {
return function install(openmct) {
installTheme(openmct, 'espresso');
};
}

View File

@ -0,0 +1,18 @@
const dataAttribute = 'theme';
export const installTheme = (openmct, themeName) => {
const currentTheme = document.querySelector(`link[data-${dataAttribute}]`);
if (currentTheme) {
currentTheme.remove();
}
const newTheme = document.createElement('link');
newTheme.setAttribute('rel', 'stylesheet');
// eslint-disable-next-line no-undef
const href = `${openmct.getAssetPath()}${__OPENMCT_ROOT_RELATIVE__}${themeName}Theme.css`;
newTheme.setAttribute('href', href);
newTheme.dataset[dataAttribute] = themeName;
document.head.appendChild(newTheme);
}

View File

@ -0,0 +1,22 @@
@import "~styles/vendor/normalize-min";
@import "~styles/constants";
@import "~styles/constants-mobile.scss";
@import "~styles/constants-maelstrom";
@import "~styles/mixins";
@import "~styles/animations";
@import "~styles/about";
@import "~styles/glyphs";
@import "~styles/global";
@import "~styles/status";
@import "~styles/controls";
@import "~styles/forms";
@import "~styles/table";
@import "~styles/layout";
@import "~styles/legacy";
@import "~styles/legacy-plots";
@import "~styles/plotly";
@import "~styles/legacy-messages";
@import "~styles/vue-styles.scss";

View File

@ -0,0 +1,7 @@
import { installTheme } from './installTheme';
export default function plugin() {
return function install(openmct) {
installTheme(openmct, 'maelstrom');
};
}

View File

@ -0,0 +1,22 @@
@import "~styles/vendor/normalize-min";
@import "~styles/constants";
@import "~styles/constants-mobile.scss";
@import "~styles/constants-snow";
@import "~styles/mixins";
@import "~styles/animations";
@import "~styles/about";
@import "~styles/glyphs";
@import "~styles/global";
@import "~styles/status";
@import "~styles/controls";
@import "~styles/forms";
@import "~styles/table";
@import "~styles/layout";
@import "~styles/legacy";
@import "~styles/legacy-plots";
@import "~styles/plotly";
@import "~styles/legacy-messages";
@import "~styles/vue-styles.scss";

View File

@ -0,0 +1,7 @@
import { installTheme } from './installTheme';
export default function plugin() {
return function install(openmct) {
installTheme(openmct, 'snow');
};
}

View File

@ -139,190 +139,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-input--submit {
// Can't use display: none because some browsers will pretend the input doesn't exist, and enter won't work
visibility: none;
height: 0;
width: 0;
padding: 0;
}
/*********************************************** CONDUCTOR LAYOUT */
.c-conductor {
&__time-bounds {
display: grid;
grid-column-gap: $interiorMargin;
grid-row-gap: $interiorMargin;
align-items: center;
// Default: fixed mode, desktop
grid-template-rows: 1fr;
grid-template-columns: 20px auto 1fr auto;
grid-template-areas: "tc-mode-icon tc-start tc-ticks tc-end";
}
&__mode-icon {
grid-area: tc-mode-icon;
}
&__start-fixed,
&__start-delta {
grid-area: tc-start;
display: flex;
}
&__end-fixed,
&__end-delta {
grid-area: tc-end;
display: flex;
justify-content: flex-end;
}
&__ticks {
grid-area: tc-ticks;
}
&__controls {
grid-area: tc-controls;
display: flex;
align-items: center;
> * + * {
margin-left: $interiorMargin;
}
}
[class*='-delta'] {
&:before {
content: $glyph-icon-clock;
font-family: symbolsfont;
}
}
&.is-realtime-mode {
.c-conductor__time-bounds {
grid-template-columns: 20px auto 1fr auto auto;
grid-template-areas: "tc-mode-icon tc-start tc-ticks tc-updated tc-end";
}
.c-conductor__end-fixed {
grid-area: tc-updated;
}
}
body.phone.portrait & {
.c-conductor__time-bounds {
grid-row-gap: $interiorMargin;
grid-template-rows: auto auto;
grid-template-columns: 20px auto auto;
}
.c-conductor__controls {
padding-left: 25px; // Line up visually with other controls
}
&__mode-icon {
grid-row: 1;
}
&__ticks,
&__zoom {
display: none;
}
&.is-fixed-mode {
[class*='__start-fixed'],
[class*='__end-fixed'] {
[class*='__label'] {
// Start and end are in separate columns; make the labels line up
width: 30px;
}
}
[class*='__end-input'] {
justify-content: flex-start;
}
.c-conductor__time-bounds {
grid-template-areas:
"tc-mode-icon tc-start tc-start"
"tc-mode-icon tc-end tc-end"
}
}
&.is-realtime-mode {
.c-conductor__time-bounds {
grid-template-areas:
"tc-mode-icon tc-start tc-updated"
"tc-mode-icon tc-end tc-end";
}
.c-conductor__end-fixed {
justify-content: flex-end;
}
}
}
}
.c-conductor-input {
color: $colorInputFg;
display: flex;
align-items: center;
justify-content: flex-start;
> * + * {
margin-left: $interiorMarginSm;
}
&:before {
// Realtime-mode clock icon symbol
margin-right: $interiorMarginSm;
}
.c-direction-indicator {
// Holds realtime-mode + and - symbols
font-size: 0.7em;
}
input:invalid {
background: rgba($colorFormInvalid, 0.5);
}
}
.is-realtime-mode {
button {
@include themedButton($colorTimeBg);
color: $colorTimeFg;
&:hover {
background: $colorTimeHov !important;
color: $colorTimeFg !important;
}
}
.c-conductor-input {
&:before {
color: $colorTime;
}
}
.c-conductor__end-fixed {
// Displays last RT udpate
color: $colorTime;
input {
// Remove input look
background: none;
box-shadow: none;
color: $colorTime;
pointer-events: none;
}
}
}
</style>
<script>
import ConductorMode from './ConductorMode.vue';
import ConductorTimeSystem from './ConductorTimeSystem.vue';

View File

@ -27,90 +27,6 @@
></div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-conductor-axis {
$h: 18px;
$tickYPos: ($h / 2) + 12px;
@include userSelectNone();
@include bgTicks($c: rgba($colorBodyFg, 0.4));
background-position: 0 50%;
background-size: 5px 2px;
border-radius: $controlCr;
height: $h;
svg {
text-rendering: geometricPrecision;
width: 100%;
height: 100%;
> g {
// Overall Tick holder
transform: translateY($tickYPos);
path {
// Domain line
display: none;
}
g {
// Each tick. These move on drag.
line {
// Line beneath ticks
display: none;
}
}
}
text {
// Tick labels
fill: $colorBodyFg;
font-size: 1em;
paint-order: stroke;
font-weight: bold;
stroke: $colorBodyBg;
stroke-linecap: butt;
stroke-linejoin: bevel;
stroke-width: 6px;
}
}
body.desktop .is-fixed-mode & {
@include cursorGrab();
background-size: 3px 30%;
background-color: $colorBodyBgSubtle;
box-shadow: inset rgba(black, 0.4) 0 1px 1px;
transition: $transOut;
svg text {
fill: $colorBodyFg;
stroke: $colorBodyBgSubtle;
transition: $transOut;
}
&:hover,
&:active {
$c: $colorKeySubtle;
background-color: $c;
transition: $transIn;
svg text {
stroke: $c;
transition: $transIn;
}
}
}
.is-realtime-mode & {
$c: 1px solid rgba($colorTime, 0.7);
border-left: $c;
border-right: $c;
svg text {
fill: $colorTime;
}
}
}
</style>
<script>
import * as d3Selection from 'd3-selection';

View File

@ -59,25 +59,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-conductor__mode-menu {
max-height: 80vh;
max-width: 500px;
min-height: 250px;
z-index: 70;
[class*="__icon"] {
filter: $colorKeyFilter;
}
[class*="__item-description"] {
min-width: 200px;
}
}
</style>
<script>
import toggleMixin from '../../ui/mixins/toggle-mixin';

View File

@ -25,115 +25,3 @@
<div class="hand-big"></div>
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
@keyframes clock-hands {
0% { transform: translate(-50%, -50%) rotate(0deg); }
100% { transform: translate(-50%, -50%) rotate(360deg); }
}
@keyframes clock-hands-sticky {
0% { transform: translate(-50%, -50%) rotate(0deg); }
7% { transform: translate(-50%, -50%) rotate(0deg); }
8% { transform: translate(-50%, -50%) rotate(30deg); }
15% { transform: translate(-50%, -50%) rotate(30deg); }
16% { transform: translate(-50%, -50%) rotate(60deg); }
24% { transform: translate(-50%, -50%) rotate(60deg); }
25% { transform: translate(-50%, -50%) rotate(90deg); }
32% { transform: translate(-50%, -50%) rotate(90deg); }
33% { transform: translate(-50%, -50%) rotate(120deg); }
40% { transform: translate(-50%, -50%) rotate(120deg); }
41% { transform: translate(-50%, -50%) rotate(150deg); }
49% { transform: translate(-50%, -50%) rotate(150deg); }
50% { transform: translate(-50%, -50%) rotate(180deg); }
57% { transform: translate(-50%, -50%) rotate(180deg); }
58% { transform: translate(-50%, -50%) rotate(210deg); }
65% { transform: translate(-50%, -50%) rotate(210deg); }
66% { transform: translate(-50%, -50%) rotate(240deg); }
74% { transform: translate(-50%, -50%) rotate(240deg); }
75% { transform: translate(-50%, -50%) rotate(270deg); }
82% { transform: translate(-50%, -50%) rotate(270deg); }
83% { transform: translate(-50%, -50%) rotate(300deg); }
90% { transform: translate(-50%, -50%) rotate(300deg); }
91% { transform: translate(-50%, -50%) rotate(330deg); }
99% { transform: translate(-50%, -50%) rotate(330deg); }
100% { transform: translate(-50%, -50%) rotate(360deg); }
}
.c-clock-symbol {
$c: $colorBtnBg; //$colorObjHdrIc;
$d: 18px;
height: $d;
width: $d;
position: relative;
&:before {
font-family: symbolsfont;
color: $c;
content: $glyph-icon-brackets;
font-size: $d;
line-height: normal;
display: block;
width: 100%;
height: 100%;
z-index: 1;
}
// Clock hands
div[class*="hand"] {
$handW: 2px;
$handH: $d * 0.4;
animation-iteration-count: infinite;
animation-timing-function: linear;
transform-origin: bottom;
position: absolute;
height: $handW;
width: $handW;
left: 50%;
top: 50%;
z-index: 2;
&:before {
background: $c;
content: '';
display: block;
position: absolute;
width: 100%;
bottom: -1px;
}
&.hand-little {
z-index: 2;
animation-duration: 12s;
transform: translate(-50%, -50%) rotate(120deg);
&:before {
height: ceil($handH * 0.6);
}
}
&.hand-big {
z-index: 1;
animation-duration: 1s;
transform: translate(-50%, -50%);
&:before {
height: $handH;
}
}
}
// Modes
.is-realtime-mode &,
.is-lad-mode & {
&:before {
// Brackets icon
color: $colorTime;
}
div[class*="hand"] {
animation-name: clock-hands;
&:before {
background: $colorTime;
}
}
}
}
</style>

View File

@ -84,107 +84,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
/******************************************************** PICKER */
.c-datetime-picker {
@include userSelectNone();
padding: $interiorMarginLg !important;
display: flex !important; // Override .c-menu display: block;
flex-direction: column;
> * + * {
margin-top: $interiorMargin;
}
&__close-button {
display: none; // Only show when body.phone, see below.
}
&__pager {
flex: 0 0 auto;
}
&__calendar {
border-top: 1px solid $colorInteriorBorder;
flex: 1 1 auto;
}
}
.c-pager {
display: grid;
grid-column-gap: $interiorMargin;
grid-template-rows: 1fr;
grid-template-columns: auto 1fr auto;
align-items: center;
.c-icon-button {
font-size: 0.8em;
}
&__month-year {
text-align: center;
}
}
/******************************************************** CALENDAR */
.c-calendar {
display: grid;
grid-template-columns: repeat(7, min-content);
grid-template-rows: auto;
grid-gap: 1px;
height: 100%;
$mutedOpacity: 0.5;
ul {
display: contents;
&[class*='--header'] {
pointer-events: none;
li {
opacity: $mutedOpacity;
}
}
}
li {
display: flex;
flex-direction: column;
justify-content: center !important;
padding: $interiorMargin;
&.is-in-month {
background: $colorMenuElementHilite;
}
}
&__day {
&--sub {
opacity: $mutedOpacity;
font-size: 0.8em;
}
}
}
/******************************************************** MOBILE */
body.phone {
.c-datetime-picker {
&.c-menu {
@include modalFullScreen();
}
&__close-button {
display: flex;
justify-content: flex-end;
}
}
.c-calendar {
grid-template-columns: repeat(7, auto);
}
}
</style>
<script>
import moment from 'moment';
import toggleMixin from '../../ui/mixins/toggle-mixin';

View File

@ -0,0 +1,79 @@
.c-conductor-axis {
$h: 18px;
$tickYPos: ($h / 2) + 12px;
@include userSelectNone();
@include bgTicks($c: rgba($colorBodyFg, 0.4));
background-position: 0 50%;
background-size: 5px 2px;
border-radius: $controlCr;
height: $h;
svg {
text-rendering: geometricPrecision;
width: 100%;
height: 100%;
> g {
// Overall Tick holder
transform: translateY($tickYPos);
path {
// Domain line
display: none;
}
g {
// Each tick. These move on drag.
line {
// Line beneath ticks
display: none;
}
}
}
text {
// Tick labels
fill: $colorBodyFg;
font-size: 1em;
paint-order: stroke;
font-weight: bold;
stroke: $colorBodyBg;
stroke-linecap: butt;
stroke-linejoin: bevel;
stroke-width: 6px;
}
}
body.desktop .is-fixed-mode & {
@include cursorGrab();
background-size: 3px 30%;
background-color: $colorBodyBgSubtle;
box-shadow: inset rgba(black, 0.4) 0 1px 1px;
transition: $transOut;
svg text {
fill: $colorBodyFg;
stroke: $colorBodyBgSubtle;
transition: $transOut;
}
&:hover,
&:active {
$c: $colorKeySubtle;
background-color: $c;
transition: $transIn;
svg text {
stroke: $c;
transition: $transIn;
}
}
}
.is-realtime-mode & {
$c: 1px solid rgba($colorTime, 0.7);
border-left: $c;
border-right: $c;
svg text {
fill: $colorTime;
}
}
}

View File

@ -0,0 +1,107 @@
@keyframes clock-hands {
0% { transform: translate(-50%, -50%) rotate(0deg); }
100% { transform: translate(-50%, -50%) rotate(360deg); }
}
@keyframes clock-hands-sticky {
0% { transform: translate(-50%, -50%) rotate(0deg); }
7% { transform: translate(-50%, -50%) rotate(0deg); }
8% { transform: translate(-50%, -50%) rotate(30deg); }
15% { transform: translate(-50%, -50%) rotate(30deg); }
16% { transform: translate(-50%, -50%) rotate(60deg); }
24% { transform: translate(-50%, -50%) rotate(60deg); }
25% { transform: translate(-50%, -50%) rotate(90deg); }
32% { transform: translate(-50%, -50%) rotate(90deg); }
33% { transform: translate(-50%, -50%) rotate(120deg); }
40% { transform: translate(-50%, -50%) rotate(120deg); }
41% { transform: translate(-50%, -50%) rotate(150deg); }
49% { transform: translate(-50%, -50%) rotate(150deg); }
50% { transform: translate(-50%, -50%) rotate(180deg); }
57% { transform: translate(-50%, -50%) rotate(180deg); }
58% { transform: translate(-50%, -50%) rotate(210deg); }
65% { transform: translate(-50%, -50%) rotate(210deg); }
66% { transform: translate(-50%, -50%) rotate(240deg); }
74% { transform: translate(-50%, -50%) rotate(240deg); }
75% { transform: translate(-50%, -50%) rotate(270deg); }
82% { transform: translate(-50%, -50%) rotate(270deg); }
83% { transform: translate(-50%, -50%) rotate(300deg); }
90% { transform: translate(-50%, -50%) rotate(300deg); }
91% { transform: translate(-50%, -50%) rotate(330deg); }
99% { transform: translate(-50%, -50%) rotate(330deg); }
100% { transform: translate(-50%, -50%) rotate(360deg); }
}
.c-clock-symbol {
$c: $colorBtnBg; //$colorObjHdrIc;
$d: 18px;
height: $d;
width: $d;
position: relative;
&:before {
font-family: symbolsfont;
color: $c;
content: $glyph-icon-brackets;
font-size: $d;
line-height: normal;
display: block;
width: 100%;
height: 100%;
z-index: 1;
}
// Clock hands
div[class*="hand"] {
$handW: 2px;
$handH: $d * 0.4;
animation-iteration-count: infinite;
animation-timing-function: linear;
transform-origin: bottom;
position: absolute;
height: $handW;
width: $handW;
left: 50%;
top: 50%;
z-index: 2;
&:before {
background: $c;
content: '';
display: block;
position: absolute;
width: 100%;
bottom: -1px;
}
&.hand-little {
z-index: 2;
animation-duration: 12s;
transform: translate(-50%, -50%) rotate(120deg);
&:before {
height: ceil($handH * 0.6);
}
}
&.hand-big {
z-index: 1;
animation-duration: 1s;
transform: translate(-50%, -50%);
&:before {
height: $handH;
}
}
}
// Modes
.is-realtime-mode &,
.is-lad-mode & {
&:before {
// Brackets icon
color: $colorTime;
}
div[class*="hand"] {
animation-name: clock-hands;
&:before {
background: $colorTime;
}
}
}
}

View File

@ -0,0 +1,14 @@
.c-conductor__mode-menu {
max-height: 80vh;
max-width: 500px;
min-height: 250px;
z-index: 70;
[class*="__icon"] {
filter: $colorKeyFilter;
}
[class*="__item-description"] {
min-width: 200px;
}
}

View File

@ -0,0 +1,179 @@
.c-input--submit {
// Can't use display: none because some browsers will pretend the input doesn't exist, and enter won't work
visibility: none;
height: 0;
width: 0;
padding: 0;
}
/*********************************************** CONDUCTOR LAYOUT */
.c-conductor {
&__time-bounds {
display: grid;
grid-column-gap: $interiorMargin;
grid-row-gap: $interiorMargin;
align-items: center;
// Default: fixed mode, desktop
grid-template-rows: 1fr;
grid-template-columns: 20px auto 1fr auto;
grid-template-areas: "tc-mode-icon tc-start tc-ticks tc-end";
}
&__mode-icon {
grid-area: tc-mode-icon;
}
&__start-fixed,
&__start-delta {
grid-area: tc-start;
display: flex;
}
&__end-fixed,
&__end-delta {
grid-area: tc-end;
display: flex;
justify-content: flex-end;
}
&__ticks {
grid-area: tc-ticks;
}
&__controls {
grid-area: tc-controls;
display: flex;
align-items: center;
> * + * {
margin-left: $interiorMargin;
}
}
[class*='-delta'] {
&:before {
content: $glyph-icon-clock;
font-family: symbolsfont;
}
}
&.is-realtime-mode {
.c-conductor__time-bounds {
grid-template-columns: 20px auto 1fr auto auto;
grid-template-areas: "tc-mode-icon tc-start tc-ticks tc-updated tc-end";
}
.c-conductor__end-fixed {
grid-area: tc-updated;
}
}
body.phone.portrait & {
.c-conductor__time-bounds {
grid-row-gap: $interiorMargin;
grid-template-rows: auto auto;
grid-template-columns: 20px auto auto;
}
.c-conductor__controls {
padding-left: 25px; // Line up visually with other controls
}
&__mode-icon {
grid-row: 1;
}
&__ticks,
&__zoom {
display: none;
}
&.is-fixed-mode {
[class*='__start-fixed'],
[class*='__end-fixed'] {
[class*='__label'] {
// Start and end are in separate columns; make the labels line up
width: 30px;
}
}
[class*='__end-input'] {
justify-content: flex-start;
}
.c-conductor__time-bounds {
grid-template-areas:
"tc-mode-icon tc-start tc-start"
"tc-mode-icon tc-end tc-end"
}
}
&.is-realtime-mode {
.c-conductor__time-bounds {
grid-template-areas:
"tc-mode-icon tc-start tc-updated"
"tc-mode-icon tc-end tc-end";
}
.c-conductor__end-fixed {
justify-content: flex-end;
}
}
}
}
.c-conductor-input {
color: $colorInputFg;
display: flex;
align-items: center;
justify-content: flex-start;
> * + * {
margin-left: $interiorMarginSm;
}
&:before {
// Realtime-mode clock icon symbol
margin-right: $interiorMarginSm;
}
.c-direction-indicator {
// Holds realtime-mode + and - symbols
font-size: 0.7em;
}
input:invalid {
background: rgba($colorFormInvalid, 0.5);
}
}
.is-realtime-mode {
button {
@include themedButton($colorTimeBg);
color: $colorTimeFg;
&:hover {
background: $colorTimeHov !important;
color: $colorTimeFg !important;
}
}
.c-conductor-input {
&:before {
color: $colorTime;
}
}
.c-conductor__end-fixed {
// Displays last RT udpate
color: $colorTime;
input {
// Remove input look
background: none;
box-shadow: none;
color: $colorTime;
pointer-events: none;
}
}
}

View File

@ -0,0 +1,96 @@
/******************************************************** PICKER */
.c-datetime-picker {
@include userSelectNone();
padding: $interiorMarginLg !important;
display: flex !important; // Override .c-menu display: block;
flex-direction: column;
> * + * {
margin-top: $interiorMargin;
}
&__close-button {
display: none; // Only show when body.phone, see below.
}
&__pager {
flex: 0 0 auto;
}
&__calendar {
border-top: 1px solid $colorInteriorBorder;
flex: 1 1 auto;
}
}
.c-pager {
display: grid;
grid-column-gap: $interiorMargin;
grid-template-rows: 1fr;
grid-template-columns: auto 1fr auto;
align-items: center;
.c-icon-button {
font-size: 0.8em;
}
&__month-year {
text-align: center;
}
}
/******************************************************** CALENDAR */
.c-calendar {
display: grid;
grid-template-columns: repeat(7, min-content);
grid-template-rows: auto;
grid-gap: 1px;
height: 100%;
$mutedOpacity: 0.5;
ul {
display: contents;
&[class*='--header'] {
pointer-events: none;
li {
opacity: $mutedOpacity;
}
}
}
li {
display: flex;
flex-direction: column;
justify-content: center !important;
padding: $interiorMargin;
&.is-in-month {
background: $colorMenuElementHilite;
}
}
&__day {
&--sub {
opacity: $mutedOpacity;
font-size: 0.8em;
}
}
}
/******************************************************** MOBILE */
body.phone {
.c-datetime-picker {
&.c-menu {
@include modalFullScreen();
}
&__close-button {
display: flex;
justify-content: flex-end;
}
}
.c-calendar {
grid-template-columns: repeat(7, auto);
}
}

View File

@ -36,3 +36,5 @@
@import "legacy-plots";
@import "plotly";
@import "legacy-messages";
@import "vue-styles.scss";

View File

@ -0,0 +1,43 @@
@import "../api/overlays/components/dialog-component.scss";
@import "../api/overlays/components/overlay-component.scss";
@import "../plugins/displayLayout/components/box-view.scss";
@import "../plugins/displayLayout/components/display-layout.scss";
@import "../plugins/displayLayout/components/edit-marquee.scss";
@import "../plugins/displayLayout/components/image-view.scss";
@import "../plugins/displayLayout/components/layout-frame.scss";
@import "../plugins/displayLayout/components/telemetry-view.scss";
@import "../plugins/displayLayout/components/text-view.scss";
@import "../plugins/filters/components/filters-view.scss";
@import "../plugins/filters/components/global-filters.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/list-item.scss";
@import "../plugins/folderView/components/list-view.scss";
@import "../plugins/telemetryTable/components/table-row.scss";
@import "../plugins/telemetryTable/components/telemetry-filter-indicator.scss";
@import "../plugins/tabs/components/tabs.scss";
@import "../plugins/telemetryTable/components/table.scss";
@import "../plugins/timeConductor/conductor.scss";
@import "../plugins/timeConductor/conductor-axis.scss";
@import "../plugins/timeConductor/conductor-mode.scss";
@import "../plugins/timeConductor/conductor-mode-icon.scss";
@import "../plugins/timeConductor/date-picker.scss";
@import "../ui/components/object-frame.scss";
@import "../ui/components/object-label.scss";
@import "../ui/components/progress-bar.scss";
@import "../ui/components/search.scss";
@import "../ui/components/toggle-switch.scss";
@import "../ui/inspector/elements.scss";
@import "../ui/inspector/inspector.scss";
@import "../ui/inspector/location.scss";
@import "../ui/layout/app-logo.scss";
@import "../ui/layout/create-button.scss";
@import "../ui/layout/layout.scss";
@import "../ui/layout/mct-tree.scss";
@import "../ui/layout/mct-search.scss";
@import "../ui/layout/pane.scss";
@import "../ui/layout/status-bar/indicators.scss";
@import "../ui/layout/status-bar/notification-banner.scss";
@import "../ui/preview/preview.scss";
@import "../ui/toolbar/components/toolbar-checkbox.scss";

View File

@ -56,86 +56,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-so-view {
display: flex;
flex-direction: column;
/*************************** HEADER */
&__header {
flex: 0 0 auto;
display: flex;
align-items: center;
margin-bottom: $interiorMargin;
&__icon {
flex: 0 0 auto;
margin-right: $interiorMarginSm;
opacity: 0.5;
}
&__name {
@include headerFont(1em);
@include ellipsize();
flex: 0 1 auto;
}
}
&:not(.c-so-view--no-frame) {
background: $colorBodyBg;
border: $browseFrameBorder;
padding: $interiorMargin;
}
&--no-frame {
> .c-so-view__header {
display: none;
}
> .c-so-view__local-controls {
top: $interiorMarginSm; right: $interiorMarginSm;
}
}
&__local-controls {
position: absolute;
top: $interiorMargin; right: $interiorMargin;
z-index: 2;
}
&__view-large {
display: none;
}
&.has-complex-content {
> .c-so-view__view-large { display: block; }
}
/*************************** OBJECT VIEW */
&__object-view {
flex: 1 1 auto;
height: 0; // Chrome 73 overflow bug fix
overflow: auto;
.c-object-view {
.u-fills-container {
// Expand component types that fill a container
@include abs();
}
}
}
.c-click-icon,
.c-button {
// Shrink buttons a bit when they appear in a frame
font-size: 0.85em;
padding: 3px 5px;
}
}
</style>
<script>
import ObjectView from './ObjectView.vue'
import ContextMenuDropDown from './contextMenuDropDown.vue';

View File

@ -14,39 +14,6 @@
</a>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-object-label {
// <a> tag and draggable element that holds type icon and name.
// Used mostly in trees and lists
border-radius: $controlCr;
display: flex;
align-items: center;
flex: 1 1 auto;
overflow: hidden;
padding: $interiorMarginSm 1px;
white-space: nowrap;
&__name {
@include ellipsize();
display: inline;
color: $colorItemTreeFg;
width: 100%;
}
&__type-icon {
// Type icon. Must be an HTML entity to allow inclusion of alias indicator.
display: block;
flex: 0 0 auto;
font-size: 1.3em;
margin-right: $interiorMarginSm;
color: $colorItemTreeIcon;
width: $treeTypeIconW;
}
}
</style>
<script>
import ObjectLink from '../mixins/object-link';

View File

@ -17,54 +17,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
/******************************************************** PROGRESS BAR */
@keyframes progress {
100% { background-position: $progressAnimW center; }
}
@mixin progressAnim($c1, $c2, $size) {
$edge: 20%;
background-image: linear-gradient(-90deg,
$c1 0%, $c2 $edge,
$c2 $edge, $c1 100%
);
background-position: 0 center;
background-repeat: repeat-x;
background-size: $size 100%;
}
.c-progress-bar {
display: flex;
flex-direction: column;
width: 100%;
> * + * {
margin-top: $interiorMargin;
}
&__holder {
background: $colorProgressBarHolder;
box-shadow: inset rgba(black, 0.4) 0 0.25px 3px;
flex: 1 1 auto;
padding: 1px;
}
&__bar {
@include progressAnim($colorProgressBar, lighten($colorProgressBar, 10%), $progressAnimW);
animation: progress 1000ms linear infinite;
min-height: $progressBarMinH;
height: 100%;
&.--indeterminate {
width: 100% !important;
}
}
}
</style>
<script>
export default {
props: {

View File

@ -10,60 +10,6 @@
</label>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-toggle-switch {
$d: 12px;
$m: 2px;
$br: $d/1.5;
cursor: pointer;
overflow: hidden;
display: inline;
vertical-align: middle;
&__slider {
background: $colorBtnBg; // TODO: make discrete theme constants for these colors
border-radius: $br;
//box-shadow: inset rgba($colorBtnFg, 0.4) 0 0 0 1px;
display: inline-block;
height: $d + ($m*2);
position: relative;
transform: translateY(2px); // TODO: get this to work without this kind of hack!
width: $d*2 + $m*2;
&:before {
// Knob
background: $colorBtnFg; // TODO: make discrete theme constants for these colors
border-radius: floor($br * 0.8);
box-shadow: rgba(black, 0.4) 0 0 2px;
content: '';
display: block;
position: absolute;
height: $d; width: $d;
top: $m; left: $m; right: auto;
transition: transform 100ms ease-in-out;
}
}
input {
opacity: 0;
width: 0;
height: 0;
&:checked {
+ .c-toggle-switch__slider {
background: $colorKey; // TODO: make discrete theme constants for these colors
&:before {
transform: translateX(100%);
}
}
}
}
}
</style>
<script>
export default {
inject: ['openmct'],

View File

@ -0,0 +1,75 @@
.c-so-view {
display: flex;
flex-direction: column;
/*************************** HEADER */
&__header {
flex: 0 0 auto;
display: flex;
align-items: center;
margin-bottom: $interiorMargin;
&__icon {
flex: 0 0 auto;
margin-right: $interiorMarginSm;
opacity: 0.5;
}
&__name {
@include headerFont(1em);
@include ellipsize();
flex: 0 1 auto;
}
}
&:not(.c-so-view--no-frame) {
background: $colorBodyBg;
border: $browseFrameBorder;
padding: $interiorMargin;
}
&--no-frame {
> .c-so-view__header {
display: none;
}
> .c-so-view__local-controls {
top: $interiorMarginSm; right: $interiorMarginSm;
}
}
&__local-controls {
position: absolute;
top: $interiorMargin; right: $interiorMargin;
z-index: 2;
}
&__view-large {
display: none;
}
&.has-complex-content {
> .c-so-view__view-large { display: block; }
}
/*************************** OBJECT VIEW */
&__object-view {
flex: 1 1 auto;
height: 0; // Chrome 73 overflow bug fix
overflow: auto;
.c-object-view {
.u-fills-container {
// Expand component types that fill a container
@include abs();
}
}
}
.c-click-icon,
.c-button {
// Shrink buttons a bit when they appear in a frame
font-size: 0.85em;
padding: 3px 5px;
}
}

View File

@ -0,0 +1,28 @@
.c-object-label {
// <a> tag and draggable element that holds type icon and name.
// Used mostly in trees and lists
border-radius: $controlCr;
display: flex;
align-items: center;
flex: 1 1 auto;
overflow: hidden;
padding: $interiorMarginSm 1px;
white-space: nowrap;
&__name {
@include ellipsize();
display: inline;
color: $colorItemTreeFg;
width: 100%;
}
&__type-icon {
// Type icon. Must be an HTML entity to allow inclusion of alias indicator.
display: block;
flex: 0 0 auto;
font-size: 1.3em;
margin-right: $interiorMarginSm;
color: $colorItemTreeIcon;
width: $treeTypeIconW;
}
}

View File

@ -0,0 +1,43 @@
/******************************************************** PROGRESS BAR */
@keyframes progress {
100% { background-position: $progressAnimW center; }
}
@mixin progressAnim($c1, $c2, $size) {
$edge: 20%;
background-image: linear-gradient(-90deg,
$c1 0%, $c2 $edge,
$c2 $edge, $c1 100%
);
background-position: 0 center;
background-repeat: repeat-x;
background-size: $size 100%;
}
.c-progress-bar {
display: flex;
flex-direction: column;
width: 100%;
> * + * {
margin-top: $interiorMargin;
}
&__holder {
background: $colorProgressBarHolder;
box-shadow: inset rgba(black, 0.4) 0 0.25px 3px;
flex: 1 1 auto;
padding: 1px;
}
&__bar {
@include progressAnim($colorProgressBar, lighten($colorProgressBar, 10%), $progressAnimW);
animation: progress 1000ms linear infinite;
min-height: $progressBarMinH;
height: 100%;
&.--indeterminate {
width: 100% !important;
}
}
}

View File

@ -0,0 +1,26 @@
.c-search {
@include wrappedInput();
padding-top: 2px;
padding-bottom: 2px;
&:before {
// Mag glass icon
content: $glyph-icon-magnify;
}
&__clear-input {
display: none;
}
&.is-active {
.c-search__clear-input {
display: block;
}
}
input[type='text'],
input[type='search'] {
text-align: left;
}
}

View File

@ -18,37 +18,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-search {
@include wrappedInput();
padding-top: 2px;
padding-bottom: 2px;
&:before {
// Mag glass icon
content: $glyph-icon-magnify;
}
&__clear-input {
display: none;
}
&.is-active {
.c-search__clear-input {
display: block;
}
}
input[type='text'],
input[type='search'] {
text-align: left;
}
}
</style>
<script>
/* Emits input and clear events */
export default {

View File

@ -0,0 +1,48 @@
.c-toggle-switch {
$d: 12px;
$m: 2px;
$br: $d/1.5;
cursor: pointer;
overflow: hidden;
display: inline;
vertical-align: middle;
&__slider {
background: $colorBtnBg; // TODO: make discrete theme constants for these colors
border-radius: $br;
//box-shadow: inset rgba($colorBtnFg, 0.4) 0 0 0 1px;
display: inline-block;
height: $d + ($m*2);
position: relative;
transform: translateY(2px); // TODO: get this to work without this kind of hack!
width: $d*2 + $m*2;
&:before {
// Knob
background: $colorBtnFg; // TODO: make discrete theme constants for these colors
border-radius: floor($br * 0.8);
box-shadow: rgba(black, 0.4) 0 0 2px;
content: '';
display: block;
position: absolute;
height: $d; width: $d;
top: $m; left: $m; right: auto;
transition: transform 100ms ease-in-out;
}
}
input {
opacity: 0;
width: 0;
height: 0;
&:checked {
+ .c-toggle-switch__slider {
background: $colorKey; // TODO: make discrete theme constants for these colors
&:before {
transform: translateX(100%);
}
}
}
}
}

View File

@ -47,45 +47,7 @@
</div>
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-elements-pool {
display: flex;
flex-direction: column;
overflow: hidden;
flex: 1 1 auto !important;
> * + * {
margin-top: $interiorMargin;
}
&__search {
flex: 0 0 auto;
}
&__elements {
flex: 1 1 auto;
overflow: auto;
&.is-dragging {
li { opacity: 0.2; }
}
}
&__grippy {
$d: 8px;
@include grippy($c: $colorItemTreeVC, $dir: 'y');
flex: 0 0 auto;
margin-right: $interiorMarginSm;
transform: translateY(-2px);
width: $d; height: $d;
}
}
.js-last-place {
height: 10px;
}
</style>
<script>
import _ from 'lodash';
import Search from '../components/search.vue';

View File

@ -19,165 +19,6 @@
</multipane>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-inspector {
> [class*="__"] {
min-height: 50px;
+ [class*="__"] {
margin-top: $interiorMargin;
}
> .l-pane__contents {
overflow: auto;
> * {
// Fend off scrollbar
margin-right: $interiorMarginSm;
}
}
}
&__elements {
height: 200px; // Initial height
.tree-item {
.t-object-label {
// Elements pool is a flat list, so don't indent items.
left: 0;
}
}
}
.c-color-swatch {
$d: 12px;
display: block;
flex: 0 0 auto;
width: $d;
height: $d;
}
.c-tree {
// When a tree is in the Inspector, remove scrolling and right pad
overflow: visible;
padding-right: 0;
}
/************************************************************** LEGACY */
.l-inspector-part {
display: contents;
}
h2 {
@include propertiesHeader();
font-size: 0.65rem;
grid-column: 1 / 3;
}
.c-tree .grid-properties {
margin-left: $treeItemIndent;
}
}
.c-properties {
display: grid;
grid-row-gap: 0;
grid-template-columns: 1fr 2fr;
align-items: start;
min-width: 150px;
[class*="header"] {
@include propertiesHeader();
&:not(:first-child) {
// Allow multiple headers within a component
margin-top: $interiorMarginLg;
}
}
[class*="span-all"],
[class*="header"] {
grid-column: 1 / 3;
}
+ .c-properties {
margin-top: $interiorMarginLg;
}
&__section,
&__row {
display: contents;
}
&__row + &__row,
&__section + &__section {
[class*="__label"],
[class*="__value"] {
// Row borders, effected via border-top on child elements of the row
border-top: 1px solid $colorInspectorSectionHeaderBg;
}
}
&__header {
font-size: .85em;
text-transform: uppercase;
}
&__label,
&__value {
padding: 3px $interiorMarginLg 3px 0;
}
&__label {
color: $colorInspectorPropName;
&[title] {
// When a cell has a title, assume it's helpful text
cursor: help;
}
}
&__value {
color: $colorInspectorPropVal;
word-break: break-all;
&:first-child {
// If there is no preceding .label element, make value span columns
grid-column: 1 / 3;
}
}
}
/********************************************* LEGACY SUPPORT */
.c-inspector {
// FilterField.vue
.u-contents + .u-contents {
li.grid-row > * {
border-top: 1px solid $colorInspectorSectionHeaderBg;
}
}
li.grid-row + li.grid-row {
> * {
border-top: 1px solid $colorInspectorSectionHeaderBg;
}
}
li.grid-row .label {
color: $colorInspectorPropName;
}
li.grid-row .value {
color: $colorInspectorPropVal;
word-break: break-all;
&:first-child {
// If there is no preceding .label element, make value span columns
grid-column: 1 / 3;
}
}
}
</style>
<script>
import multipane from '../layout/multipane.vue';
import pane from '../layout/pane.vue';

View File

@ -37,49 +37,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-location {
display: flex;
flex-wrap: wrap;
&__item {
$m: $interiorMarginSm;
cursor: pointer;
display: flex;
align-items: center;
margin: 0 $m $m 0;
&:not(:last-child) {
&:after {
color: $colorInspectorPropName;
content: $glyph-icon-arrow-right;
font-family: symbolsfont;
font-size: 0.7em;
margin-left: $m;
opacity: 0.8;
}
}
.c-object-label {
padding: 0;
transition: $transOut;
&__type-icon {
width: auto;
font-size: 1em;
}
&:hover {
transition: $transIn;
filter: $filterHov;
}
}
}
}
</style>
<script>
import ObjectLabel from '../components/ObjectLabel.vue';

View File

@ -0,0 +1,35 @@
.c-elements-pool {
display: flex;
flex-direction: column;
overflow: hidden;
flex: 1 1 auto !important;
> * + * {
margin-top: $interiorMargin;
}
&__search {
flex: 0 0 auto;
}
&__elements {
flex: 1 1 auto;
overflow: auto;
&.is-dragging {
li { opacity: 0.2; }
}
}
&__grippy {
$d: 8px;
@include grippy($c: $colorItemTreeVC, $dir: 'y');
flex: 0 0 auto;
margin-right: $interiorMarginSm;
transform: translateY(-2px);
width: $d; height: $d;
}
}
.js-last-place {
height: 10px;
}

View File

@ -0,0 +1,154 @@
.c-inspector {
> [class*="__"] {
min-height: 50px;
+ [class*="__"] {
margin-top: $interiorMargin;
}
> .l-pane__contents {
overflow: auto;
> * {
// Fend off scrollbar
margin-right: $interiorMarginSm;
}
}
}
&__elements {
height: 200px; // Initial height
.tree-item {
.t-object-label {
// Elements pool is a flat list, so don't indent items.
left: 0;
}
}
}
.c-color-swatch {
$d: 12px;
display: block;
flex: 0 0 auto;
width: $d;
height: $d;
}
.c-tree {
// When a tree is in the Inspector, remove scrolling and right pad
overflow: visible;
padding-right: 0;
}
/************************************************************** LEGACY */
.l-inspector-part {
display: contents;
}
h2 {
@include propertiesHeader();
font-size: 0.65rem;
grid-column: 1 / 3;
}
.c-tree .grid-properties {
margin-left: $treeItemIndent;
}
}
.c-properties {
display: grid;
grid-row-gap: 0;
grid-template-columns: 1fr 2fr;
align-items: start;
min-width: 150px;
[class*="header"] {
@include propertiesHeader();
&:not(:first-child) {
// Allow multiple headers within a component
margin-top: $interiorMarginLg;
}
}
[class*="span-all"],
[class*="header"] {
grid-column: 1 / 3;
}
+ .c-properties {
margin-top: $interiorMarginLg;
}
&__section,
&__row {
display: contents;
}
&__row + &__row,
&__section + &__section {
[class*="__label"],
[class*="__value"] {
// Row borders, effected via border-top on child elements of the row
border-top: 1px solid $colorInspectorSectionHeaderBg;
}
}
&__header {
font-size: .85em;
text-transform: uppercase;
}
&__label,
&__value {
padding: 3px $interiorMarginLg 3px 0;
}
&__label {
color: $colorInspectorPropName;
&[title] {
// When a cell has a title, assume it's helpful text
cursor: help;
}
}
&__value {
color: $colorInspectorPropVal;
word-break: break-all;
&:first-child {
// If there is no preceding .label element, make value span columns
grid-column: 1 / 3;
}
}
}
/********************************************* LEGACY SUPPORT */
.c-inspector {
// FilterField.vue
.u-contents + .u-contents {
li.grid-row > * {
border-top: 1px solid $colorInspectorSectionHeaderBg;
}
}
li.grid-row + li.grid-row {
> * {
border-top: 1px solid $colorInspectorSectionHeaderBg;
}
}
li.grid-row .label {
color: $colorInspectorPropName;
}
li.grid-row .value {
color: $colorInspectorPropVal;
word-break: break-all;
&:first-child {
// If there is no preceding .label element, make value span columns
grid-column: 1 / 3;
}
}
}

View File

@ -0,0 +1,38 @@
.c-location {
display: flex;
flex-wrap: wrap;
&__item {
$m: $interiorMarginSm;
cursor: pointer;
display: flex;
align-items: center;
margin: 0 $m $m 0;
&:not(:last-child) {
&:after {
color: $colorInspectorPropName;
content: $glyph-icon-arrow-right;
font-family: symbolsfont;
font-size: 0.7em;
margin-left: $m;
opacity: 0.8;
}
}
.c-object-label {
padding: 0;
transition: $transOut;
&__type-icon {
width: auto;
font-size: 1em;
}
&:hover {
transition: $transIn;
filter: $filterHov;
}
}
}
}

View File

@ -26,14 +26,7 @@
@click="launchAbout"
></div>
</template>
<style lang="scss">
.l-shell__app-logo {
cursor: pointer;
width: 70px;
height: 20px;
background: url('assets/images/logo-openmct.svg') center no-repeat;
}
</style>
<script>
import AboutDialog from './AboutDialog.vue';
import Vue from 'vue';

View File

@ -37,40 +37,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-create-button,
.c-create-menu {
font-size: 1.1em;
}
.c-create-button {
.is-editing & {
@include disabled();
}
.c-button__label {
text-transform: $createBtnTextTransform;
}
}
.c-create-menu {
max-height: 80vh;
max-width: 500px;
min-height: 250px;
z-index: 70;
[class*="__icon"] {
filter: $colorKeyFilter;
}
[class*="__item-description"] {
min-width: 200px;
}
}
</style>
<script>
import CreateAction from '../../../platform/commonUI/edit/src/creation/CreateAction';
import objectUtils from '../../api/objects/object-utils';

View File

@ -81,250 +81,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
/******************************* SHELL */
.l-shell {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
display: flex;
flex-flow: column nowrap;
overflow: hidden;
&__pane-tree {
width: 40%;
[class*="collapse-button"] {
// For mobile, collapse button becomes menu icon
body.mobile & {
@include cClickIconButton();
color: $colorKey !important;
position: absolute;
right: -2 * nth($shellPanePad, 2); // Needs to be -1 * when pane is collapsed
top: 0;
transform: translateX(100%);
width: $mobileMenuIconD;
z-index: 2;
&:before {
content: $glyph-icon-menu-hamburger;
}
}
}
}
&__pane-tree,
&__pane-inspector,
&__pane-main {
.l-pane__contents {
display: flex;
flex-flow: column nowrap;
overflow-x: hidden;
> * {
flex: 0 0 auto;
+ * {
margin-top: $interiorMarginLg;
}
}
}
}
body.mobile & {
&__pane-tree {
background: linear-gradient(90deg, transparent 70%, rgba(black, 0.2) 99%, rgba(black, 0.3));
&[class*="--collapsed"] {
[class*="collapse-button"] {
right: -1 * nth($shellPanePad, 2);
}
}
}
}
body.phone.portrait & {
&__pane-tree {
width: calc(100% - #{$mobileMenuIconD + (2 * nth($shellPanePad, 2))});
+ .l-pane {
// Hide pane-main when this pane is expanded
opacity: 0;
pointer-events: none;
}
&[class*="--collapsed"] + .l-pane {
// Show pane-main when tree is collapsed
opacity: 1;
pointer-events: inherit;
transition: opacity 250ms ease 250ms;
}
}
}
&__head,
&__pane-inspector {
body.mobile & {
display: none;
}
}
&__head,
&__status {
flex: 0 0 auto;
display: flex;
}
/******************************* HEAD */
&__main-view-browse-bar {
flex: 0 0 auto;
}
body.mobile & .l-shell__main-view-browse-bar {
margin-left: $mobileMenuIconD; // Make room for the hamburger!
}
&__head {
align-items: stretch;
background: $colorHeadBg;
justify-content: space-between;
padding: $interiorMargin $interiorMargin + 2;
> [class*="__"] + [class*="__"] {
margin-left: $interiorMargin;
}
[class*='__head__collapse-button'] {
align-self: start;
flex: 0 0 auto;
margin-top: 6px;
&:before {
content: $glyph-icon-arrow-down;
font-size: 1.1em;
}
}
&-section {
// Subdivides elements across the head
display: flex;
flex: 0 1 auto;
padding: 0 $interiorMargin;
}
&--expanded {
.c-indicator__label {
transition: none !important;
}
[class*='__head__collapse-button'] {
&:before {
transform: rotate(180deg);
}
}
}
}
&__controls {
$brdr: 1px solid $colorInteriorBorder;
border-right: $brdr;
border-left: $brdr;
align-items: start;
}
&__create-button,
&__app-logo {
flex: 0 0 auto;
}
&__create-button { margin-right: $interiorMarginLg; }
&__indicators {
flex: 1 1 auto;
flex-wrap: wrap;
justify-content: flex-end;
[class*='indicator-clock'] { order: 90; }
.c-indicator .label {
font-size: 0.9em;
}
}
/******************************* MAIN AREA */
&__main-container {
// Wrapper for main views
flex: 1 1 auto !important;
height: 0; // Chrome 73 overflow bug fix
overflow: auto;
}
&__tree {
// Tree component within __pane-tree
flex: 1 1 auto !important;
}
&__time-conductor {
border-top: 1px solid $colorInteriorBorder;
padding-top: $interiorMargin;
}
&__main {
> .l-pane {
padding: nth($shellPanePad, 1) nth($shellPanePad, 2);
}
}
body.desktop & {
&__main {
// Top and bottom padding in container that holds tree, __pane-main and Inspector
padding: $shellMainPad;
min-height: 0;
> .l-pane {
padding-top: 0;
padding-bottom: 0;
}
}
&__pane-tree,
&__pane-inspector {
max-width: 30%;
}
&__pane-tree {
width: 300px;
}
&__pane-inspector {
width: 200px;
}
}
&__toolbar {
$p: $interiorMargin;
background: $editUIBaseColor;
border-radius: $basicCr;
height: $p + 24px; // Need to standardize the height
padding: $p;
}
}
.is-editing {
.l-shell__main-container {
$m: 3px;
box-shadow: $colorBodyBg 0 0 0 1px, $editUIAreaShdw;
margin-left: $m;
margin-right: $m;
&[s-selected] {
// Provide a clearer selection context articulation for the main edit area
box-shadow: $colorBodyBg 0 0 0 1px, $editUIAreaShdwSelected;
}
}
}
</style>
<script>
import Inspector from '../inspector/Inspector.vue';
import MctTree from './mct-tree.vue';

View File

@ -7,21 +7,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/constants";
/******************************* SEARCH */
.c-search {
input[type=search] {
width: 100%;
}
&--major {
display: flex;
}
}
</style>
<script>
export default {
}

View File

@ -0,0 +1,6 @@
.l-shell__app-logo {
cursor: pointer;
width: 70px;
height: 20px;
background: url('assets/images/logo-openmct.svg') center no-repeat;
}

View File

@ -0,0 +1,29 @@
.c-create-button,
.c-create-menu {
font-size: 1.1em;
}
.c-create-button {
.is-editing & {
@include disabled();
}
.c-button__label {
text-transform: $createBtnTextTransform;
}
}
.c-create-menu {
max-height: 80vh;
max-width: 500px;
min-height: 250px;
z-index: 70;
[class*="__icon"] {
filter: $colorKeyFilter;
}
[class*="__item-description"] {
min-width: 200px;
}
}

238
src/ui/layout/layout.scss Normal file
View File

@ -0,0 +1,238 @@
/******************************* SHELL */
.l-shell {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
display: flex;
flex-flow: column nowrap;
overflow: hidden;
&__pane-tree {
width: 40%;
[class*="collapse-button"] {
// For mobile, collapse button becomes menu icon
body.mobile & {
@include cClickIconButton();
color: $colorKey !important;
position: absolute;
right: -2 * nth($shellPanePad, 2); // Needs to be -1 * when pane is collapsed
top: 0;
transform: translateX(100%);
width: $mobileMenuIconD;
z-index: 2;
&:before {
content: $glyph-icon-menu-hamburger;
}
}
}
}
&__pane-tree,
&__pane-inspector,
&__pane-main {
.l-pane__contents {
display: flex;
flex-flow: column nowrap;
overflow-x: hidden;
> * {
flex: 0 0 auto;
+ * {
margin-top: $interiorMarginLg;
}
}
}
}
body.mobile & {
&__pane-tree {
background: linear-gradient(90deg, transparent 70%, rgba(black, 0.2) 99%, rgba(black, 0.3));
&[class*="--collapsed"] {
[class*="collapse-button"] {
right: -1 * nth($shellPanePad, 2);
}
}
}
}
body.phone.portrait & {
&__pane-tree {
width: calc(100% - #{$mobileMenuIconD + (2 * nth($shellPanePad, 2))});
+ .l-pane {
// Hide pane-main when this pane is expanded
opacity: 0;
pointer-events: none;
}
&[class*="--collapsed"] + .l-pane {
// Show pane-main when tree is collapsed
opacity: 1;
pointer-events: inherit;
transition: opacity 250ms ease 250ms;
}
}
}
&__head,
&__pane-inspector {
body.mobile & {
display: none;
}
}
&__head,
&__status {
flex: 0 0 auto;
display: flex;
}
/******************************* HEAD */
&__main-view-browse-bar {
flex: 0 0 auto;
}
body.mobile & .l-shell__main-view-browse-bar {
margin-left: $mobileMenuIconD; // Make room for the hamburger!
}
&__head {
align-items: stretch;
background: $colorHeadBg;
justify-content: space-between;
padding: $interiorMargin $interiorMargin + 2;
> [class*="__"] + [class*="__"] {
margin-left: $interiorMargin;
}
[class*='__head__collapse-button'] {
align-self: start;
flex: 0 0 auto;
margin-top: 6px;
&:before {
content: $glyph-icon-arrow-down;
font-size: 1.1em;
}
}
&-section {
// Subdivides elements across the head
display: flex;
flex: 0 1 auto;
padding: 0 $interiorMargin;
}
&--expanded {
.c-indicator__label {
transition: none !important;
}
[class*='__head__collapse-button'] {
&:before {
transform: rotate(180deg);
}
}
}
}
&__controls {
$brdr: 1px solid $colorInteriorBorder;
border-right: $brdr;
border-left: $brdr;
align-items: start;
}
&__create-button,
&__app-logo {
flex: 0 0 auto;
}
&__create-button { margin-right: $interiorMarginLg; }
&__indicators {
flex: 1 1 auto;
flex-wrap: wrap;
justify-content: flex-end;
[class*='indicator-clock'] { order: 90; }
.c-indicator .label {
font-size: 0.9em;
}
}
/******************************* MAIN AREA */
&__main-container {
// Wrapper for main views
flex: 1 1 auto !important;
height: 0; // Chrome 73 overflow bug fix
overflow: auto;
}
&__tree {
// Tree component within __pane-tree
flex: 1 1 auto !important;
}
&__time-conductor {
border-top: 1px solid $colorInteriorBorder;
padding-top: $interiorMargin;
}
&__main {
> .l-pane {
padding: nth($shellPanePad, 1) nth($shellPanePad, 2);
}
}
body.desktop & {
&__main {
// Top and bottom padding in container that holds tree, __pane-main and Inspector
padding: $shellMainPad;
min-height: 0;
> .l-pane {
padding-top: 0;
padding-bottom: 0;
}
}
&__pane-tree,
&__pane-inspector {
max-width: 30%;
}
&__pane-tree {
width: 300px;
}
&__pane-inspector {
width: 200px;
}
}
&__toolbar {
$p: $interiorMargin;
background: $editUIBaseColor;
border-radius: $basicCr;
height: $p + 24px; // Need to standardize the height
padding: $p;
}
}
.is-editing {
.l-shell__main-container {
$m: 3px;
box-shadow: $colorBodyBg 0 0 0 1px, $editUIAreaShdw;
margin-left: $m;
margin-right: $m;
&[s-selected] {
// Provide a clearer selection context articulation for the main edit area
box-shadow: $colorBodyBg 0 0 0 1px, $editUIAreaShdwSelected;
}
}
}

View File

@ -0,0 +1,10 @@
/******************************* SEARCH */
.c-search {
input[type=search] {
width: 100%;
}
&--major {
display: flex;
}
}

138
src/ui/layout/mct-tree.scss Normal file
View File

@ -0,0 +1,138 @@
.c-tree-and-search {
display: flex;
flex-direction: column;
padding-right: $interiorMarginSm;
overflow: auto;
> * + * { margin-top: $interiorMargin; }
&__search {
flex: 0 0 auto;
}
&__loading {
flex: 1 1 auto;
}
&__no-results {
font-style: italic;
opacity: 0.6;
}
&__tree {
flex: 1 1 auto;
height: 0; // Chrome 73 overflow bug fix
}
}
.c-tree {
@include userSelectNone();
overflow-x: hidden;
overflow-y: auto;
padding-right: $interiorMargin;
li {
position: relative;
&.c-tree__item-h { display: block; }
}
.c-tree {
margin-left: 15px;
}
&__item {
$aPad: $interiorMarginSm;
border-radius: $controlCr;
display: flex;
align-items: center;
cursor: pointer;
line-height: 110%;
padding: $interiorMargin - $aPad;
transition: background 150ms ease;
> * + * {
margin-left: $interiorMarginSm;
}
&:hover {
background: $colorItemTreeHoverBg;
.c-tree__item__type-icon:before {
color: $colorItemTreeIconHover;
}
.c-tree__item__name {
color: $colorItemTreeHoverFg;
}
}
&.is-navigated-object,
&.is-selected {
background: $colorItemTreeSelectedBg;
.c-tree__item__type-icon:before {
color: $colorItemTreeIconHover;
}
.c-tree__item__name {
color: $colorItemTreeSelectedFg;
}
}
&.is-being-edited {
background: $colorItemTreeEditingBg;
.c-tree__item__type-icon:before {
color: $colorItemTreeEditingIcon;
}
.c-tree__item__name {
color: $colorItemTreeEditingFg;
font-style: italic;
}
}
// Object labels in trees
&__label {
// <a> tag that holds type icon and name.
// Draggable element.
/*border-radius: $controlCr;
display: flex;
align-items: center;
flex: 1 1 auto;
overflow: hidden;
padding: $aPad;
white-space: nowrap;*/
}
&__name {
// @include ellipsize();
// display: inline;
color: $colorItemTreeFg;
// width: 100%;
}
&__type-icon {
// Type icon. Must be an HTML entity to allow inclusion of alias indicator.
// display: block;
// flex: 0 0 auto;
// font-size: 1.3em;
// margin-right: $interiorMarginSm;
color: $colorItemTreeIcon;
// width: $treeTypeIconW;
}
&.is-alias {
// Object is an alias to an original.
[class*='__type-icon'] {
@include isAlias();
}
}
body.mobile & {
@include button($bg: $colorMobilePaneLeftTreeItemBg, $fg: $colorMobilePaneLeftTreeItemFg);
height: $mobileTreeItemH;
margin-bottom: $interiorMarginSm;
[class*="view-control"] {
width: ceil($mobileTreeItemH * 0.5);
}
}
}
}

View File

@ -53,149 +53,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-tree-and-search {
display: flex;
flex-direction: column;
padding-right: $interiorMarginSm;
overflow: auto;
> * + * { margin-top: $interiorMargin; }
&__search {
flex: 0 0 auto;
}
&__loading {
flex: 1 1 auto;
}
&__no-results {
font-style: italic;
opacity: 0.6;
}
&__tree {
flex: 1 1 auto;
height: 0; // Chrome 73 overflow bug fix
}
}
.c-tree {
@include userSelectNone();
overflow-x: hidden;
overflow-y: auto;
padding-right: $interiorMargin;
li {
position: relative;
&.c-tree__item-h { display: block; }
}
.c-tree {
margin-left: 15px;
}
&__item {
$aPad: $interiorMarginSm;
border-radius: $controlCr;
display: flex;
align-items: center;
cursor: pointer;
line-height: 110%;
padding: $interiorMargin - $aPad;
transition: background 150ms ease;
> * + * {
margin-left: $interiorMarginSm;
}
&:hover {
background: $colorItemTreeHoverBg;
.c-tree__item__type-icon:before {
color: $colorItemTreeIconHover;
}
.c-tree__item__name {
color: $colorItemTreeHoverFg;
}
}
&.is-navigated-object,
&.is-selected {
background: $colorItemTreeSelectedBg;
.c-tree__item__type-icon:before {
color: $colorItemTreeIconHover;
}
.c-tree__item__name {
color: $colorItemTreeSelectedFg;
}
}
&.is-being-edited {
background: $colorItemTreeEditingBg;
.c-tree__item__type-icon:before {
color: $colorItemTreeEditingIcon;
}
.c-tree__item__name {
color: $colorItemTreeEditingFg;
font-style: italic;
}
}
// Object labels in trees
&__label {
// <a> tag that holds type icon and name.
// Draggable element.
/*border-radius: $controlCr;
display: flex;
align-items: center;
flex: 1 1 auto;
overflow: hidden;
padding: $aPad;
white-space: nowrap;*/
}
&__name {
// @include ellipsize();
// display: inline;
color: $colorItemTreeFg;
// width: 100%;
}
&__type-icon {
// Type icon. Must be an HTML entity to allow inclusion of alias indicator.
// display: block;
// flex: 0 0 auto;
// font-size: 1.3em;
// margin-right: $interiorMarginSm;
color: $colorItemTreeIcon;
// width: $treeTypeIconW;
}
&.is-alias {
// Object is an alias to an original.
[class*='__type-icon'] {
@include isAlias();
}
}
body.mobile & {
@include button($bg: $colorMobilePaneLeftTreeItemBg, $fg: $colorMobilePaneLeftTreeItemFg);
height: $mobileTreeItemH;
margin-bottom: $interiorMarginSm;
[class*="view-control"] {
width: ceil($mobileTreeItemH * 0.5);
}
}
}
}
</style>
<script>
import treeItem from './tree-item.vue'
import search from '../components/search.vue';

312
src/ui/layout/pane.scss Normal file
View File

@ -0,0 +1,312 @@
/**************************** BASE - MOBILE AND DESKTOP */
.l-multipane {
display: flex;
flex: 1 1 auto;
&--horizontal,
> .l-pane {
flex-flow: row nowrap;
}
&--vertical,
> .l-pane {
flex-flow: column nowrap;
}
&--vertical {
height: 100%;
}
}
.l-pane {
backface-visibility: hidden;
display: flex;
min-width: 0px;
min-height: 0px;
opacity: 1;
pointer-events: inherit;
&__handle,
&__label {
// __handle and __label don't appear in mobile
display: none;
}
&__header {
display: flex;
align-items: center;
margin-bottom: $interiorMargin;
}
&--reacts {
// This is the pane that doesn't hold the handle
// It reacts to other panes that are able to resize
flex: 1 1 0;
}
&--collapsed {
flex-basis: 0px !important;
transition: all 350ms ease;
.l-pane__contents {
transition: opacity 150ms ease;
opacity: 0;
pointer-events: none;
overflow: hidden;
> * {
min-width: 0 !important;
min-height: 0 !important;
}
}
}
&[class*="--horizontal"] {
&.l-pane--collapsed {
padding-left: 0 !important;
padding-right: 0 !important;
}
}
&[class*="--vertical"] {
&.l-pane--collapsed {
padding-top: 0 !important;
padding-top: 0 !important;
}
}
/************************ CONTENTS */
&__contents {
flex: 1 1 100%;
opacity: 1;
pointer-events: inherit;
transition: opacity 250ms ease 250ms;
.l-pane__contents {
// Don't pad all nested __contents
padding: 0;
}
> [class*="__"] + [class*="__"] {
}
}
/************************************************ DESKTOP STYLES */
body.desktop & {
&__handle {
background: $colorSplitterBg;
display: block;
position: absolute;
transition: $transOut;
&:before {
// Extended hit area
content: '';
display: block;
position: absolute;
z-index: -1;
}
&:hover {
background: $colorSplitterHover;
transition: $transIn;
}
}
&__header {
font-size: floor(12px * .9);
}
&__label {
// Name of the pane
@include ellipsize();
@include userSelectNone();
color: $splitterBtnLabelColorFg;
display: block;
pointer-events: none;
text-transform: uppercase;
transform-origin: top left;
flex: 1 1 auto;
}
&--resizing {
// User is dragging the handle and resizing a pane
@include userSelectNone();
+ .l-pane {
@include userSelectNone();
}
.l-pane {
&__handle {
background: $colorSplitterHover;
}
}
}
&[class*="--collapsed"] {
/********************************* STYLES FOR DESKTOP COLLAPSED PANES, ALL ORIENTATIONS */
$d: nth($splitterBtnD, 1);
flex-basis: $d;
min-width: $d;
min-height: $d;
> .l-pane__handle {
display: none;
}
.l-pane__header {
&:hover {
color: $splitterCollapsedBtnColorFgHov;
.l-pane__label {
color: inherit;
}
.l-pane__collapse-button {
background: $splitterCollapsedBtnColorBgHov;
color: inherit;
transition: $transIn;
}
}
}
.l-pane__collapse-button {
background: $splitterCollapsedBtnColorBg;
color: $splitterCollapsedBtnColorFg;
}
}
&[class*="--horizontal"] {
> .l-pane__handle {
cursor: col-resize;
top: 0;
bottom: 0;
width: $splitterHandleD;
&:before {
// Extended hit area
top: 0;
right: $splitterHandleHitMargin * -1;
bottom: 0;
left: $splitterHandleHitMargin * -1;
}
}
.l-pane__collapse-button {
&:before {
content: $glyph-icon-arrow-right-equilateral;
}
}
&[class*="--collapsed"] {
/************************ COLLAPSED HORIZONTAL SPLITTER, EITHER DIRECTION */
[class*="__header"] {
@include abs();
margin: 0;
}
[class*="label"] {
position: absolute;
transform: translate($interiorMarginLg + 1, 18px) rotate(90deg);
left: 3px;
top: 0;
z-index: 1;
}
.l-pane__collapse-button {
border-top-left-radius: 0;
border-bottom-left-radius: 0; // Only have to do this once, because of scaleX(-1) below.
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
height: auto; width: 100%;
padding: 0;
&:before {
position: absolute;
top: 5px;
}
}
}
/************************** Horizontal Splitter Before */
// Inspector pane
&[class*="-before"] {
> .l-pane__handle {
left: 0;
transform: translateX(floor($splitterHandleD / -2)); // Center over the pane edge
}
&[class*="--collapsed"] {
.l-pane__collapse-button {
transform: scaleX(-1);
}
}
}
/************************** Horizontal Splitter After */
// Tree pane
&[class*="-after"] {
> .l-pane__handle {
right: 0;
transform: translateX(floor($splitterHandleD / 2));
}
&:not([class*="--collapsed"]) {
.l-pane__collapse-button {
transform: scaleX(-1);
}
}
}
}
&[class*="--vertical"] {
> .l-pane__handle {
cursor: row-resize;
left: 0;
right: 0;
height: $splitterHandleD;
&:before {
// Extended hit area
left: 0;
top: $splitterHandleHitMargin * -1;
right: 0;
bottom: $splitterHandleHitMargin * -1;
}
}
/************************** Vertical Splitter Before */
// Pane collapses downward. Used by Elements pool in Inspector
&[class*="-before"] {
> .l-pane__handle {
top: 0;
transform: translateY(floor($splitterHandleD / -1));
}
.l-pane__collapse-button:before {
content: $glyph-icon-arrow-down;
}
&.l-pane--collapsed {
> .l-pane__collapse-button {
transform: scaleY(-1);
}
}
}
/************************** Vertical Splitter After */
// Pane collapses upward. Not sure we'll ever use this...
&[class*="-after"] {
> .l-pane__handle {
bottom: 0;
transform: translateY(floor($splitterHandleD / 1));
}
&:not(.l-pane--collapsed) > .l-pane__collapse-button {
&:after {
transform: scaleY(-1);
}
}
}
}
} // Ends .body.desktop
} // Ends .l-pane

View File

@ -33,323 +33,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
/**************************** BASE - MOBILE AND DESKTOP */
.l-multipane {
display: flex;
flex: 1 1 auto;
&--horizontal,
> .l-pane {
flex-flow: row nowrap;
}
&--vertical,
> .l-pane {
flex-flow: column nowrap;
}
&--vertical {
height: 100%;
}
}
.l-pane {
backface-visibility: hidden;
display: flex;
min-width: 0px;
min-height: 0px;
opacity: 1;
pointer-events: inherit;
&__handle,
&__label {
// __handle and __label don't appear in mobile
display: none;
}
&__header {
display: flex;
align-items: center;
margin-bottom: $interiorMargin;
}
&--reacts {
// This is the pane that doesn't hold the handle
// It reacts to other panes that are able to resize
flex: 1 1 0;
}
&--collapsed {
flex-basis: 0px !important;
transition: all 350ms ease;
.l-pane__contents {
transition: opacity 150ms ease;
opacity: 0;
pointer-events: none;
overflow: hidden;
> * {
min-width: 0 !important;
min-height: 0 !important;
}
}
}
&[class*="--horizontal"] {
&.l-pane--collapsed {
padding-left: 0 !important;
padding-right: 0 !important;
}
}
&[class*="--vertical"] {
&.l-pane--collapsed {
padding-top: 0 !important;
padding-top: 0 !important;
}
}
/************************ CONTENTS */
&__contents {
flex: 1 1 100%;
opacity: 1;
pointer-events: inherit;
transition: opacity 250ms ease 250ms;
.l-pane__contents {
// Don't pad all nested __contents
padding: 0;
}
> [class*="__"] + [class*="__"] {
}
}
/************************************************ DESKTOP STYLES */
body.desktop & {
&__handle {
background: $colorSplitterBg;
display: block;
position: absolute;
transition: $transOut;
&:before {
// Extended hit area
content: '';
display: block;
position: absolute;
z-index: -1;
}
&:hover {
background: $colorSplitterHover;
transition: $transIn;
}
}
&__header {
font-size: floor(12px * .9);
}
&__label {
// Name of the pane
@include ellipsize();
@include userSelectNone();
color: $splitterBtnLabelColorFg;
display: block;
pointer-events: none;
text-transform: uppercase;
transform-origin: top left;
flex: 1 1 auto;
}
&--resizing {
// User is dragging the handle and resizing a pane
@include userSelectNone();
+ .l-pane {
@include userSelectNone();
}
.l-pane {
&__handle {
background: $colorSplitterHover;
}
}
}
&[class*="--collapsed"] {
/********************************* STYLES FOR DESKTOP COLLAPSED PANES, ALL ORIENTATIONS */
$d: nth($splitterBtnD, 1);
flex-basis: $d;
min-width: $d;
min-height: $d;
> .l-pane__handle {
display: none;
}
.l-pane__header {
&:hover {
color: $splitterCollapsedBtnColorFgHov;
.l-pane__label {
color: inherit;
}
.l-pane__collapse-button {
background: $splitterCollapsedBtnColorBgHov;
color: inherit;
transition: $transIn;
}
}
}
.l-pane__collapse-button {
background: $splitterCollapsedBtnColorBg;
color: $splitterCollapsedBtnColorFg;
}
}
&[class*="--horizontal"] {
> .l-pane__handle {
cursor: col-resize;
top: 0;
bottom: 0;
width: $splitterHandleD;
&:before {
// Extended hit area
top: 0;
right: $splitterHandleHitMargin * -1;
bottom: 0;
left: $splitterHandleHitMargin * -1;
}
}
.l-pane__collapse-button {
&:before {
content: $glyph-icon-arrow-right-equilateral;
}
}
&[class*="--collapsed"] {
/************************ COLLAPSED HORIZONTAL SPLITTER, EITHER DIRECTION */
[class*="__header"] {
@include abs();
margin: 0;
}
[class*="label"] {
position: absolute;
transform: translate($interiorMarginLg + 1, 18px) rotate(90deg);
left: 3px;
top: 0;
z-index: 1;
}
.l-pane__collapse-button {
border-top-left-radius: 0;
border-bottom-left-radius: 0; // Only have to do this once, because of scaleX(-1) below.
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
height: auto; width: 100%;
padding: 0;
&:before {
position: absolute;
top: 5px;
}
}
}
/************************** Horizontal Splitter Before */
// Inspector pane
&[class*="-before"] {
> .l-pane__handle {
left: 0;
transform: translateX(floor($splitterHandleD / -2)); // Center over the pane edge
}
&[class*="--collapsed"] {
.l-pane__collapse-button {
transform: scaleX(-1);
}
}
}
/************************** Horizontal Splitter After */
// Tree pane
&[class*="-after"] {
> .l-pane__handle {
right: 0;
transform: translateX(floor($splitterHandleD / 2));
}
&:not([class*="--collapsed"]) {
.l-pane__collapse-button {
transform: scaleX(-1);
}
}
}
}
&[class*="--vertical"] {
> .l-pane__handle {
cursor: row-resize;
left: 0;
right: 0;
height: $splitterHandleD;
&:before {
// Extended hit area
left: 0;
top: $splitterHandleHitMargin * -1;
right: 0;
bottom: $splitterHandleHitMargin * -1;
}
}
/************************** Vertical Splitter Before */
// Pane collapses downward. Used by Elements pool in Inspector
&[class*="-before"] {
> .l-pane__handle {
top: 0;
transform: translateY(floor($splitterHandleD / -1));
}
.l-pane__collapse-button:before {
content: $glyph-icon-arrow-down;
}
&.l-pane--collapsed {
> .l-pane__collapse-button {
transform: scaleY(-1);
}
}
}
/************************** Vertical Splitter After */
// Pane collapses upward. Not sure we'll ever use this...
&[class*="-after"] {
> .l-pane__handle {
bottom: 0;
transform: translateY(floor($splitterHandleD / 1));
}
&:not(.l-pane--collapsed) > .l-pane__collapse-button {
&:after {
transform: scaleY(-1);
}
}
}
}
} // Ends .body.desktop
} // Ends .l-pane
</style>
<script>
const COLLAPSE_THRESHOLD_PX = 40;

View File

@ -20,138 +20,6 @@
<div></div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-indicator {
@include cControl();
@include cClickIconButtonLayout();
button { text-transform: uppercase; }
background: none !important;
border-radius: $controlCr;
overflow: visible;
position: relative;
text-transform: uppercase;
&.no-minify {
// For items that cannot be minified
display: flex;
flex-flow: row nowrap;
align-items: center;
> *,
&:before {
flex: 1 1 auto;
}
&:before {
margin-right: $interiorMarginSm;
}
}
&:not(.no-minify) {
&:before {
margin-right: 0 !important;
}
}
}
.c-indicator__label {
// Label element. Appears as a hover bubble element when Indicators are minified;
// Appears as an inline element when not.
display: inline-block;
transition:none;
white-space: nowrap;
a,
button,
s-button,
.c-button {
// Make <a> in label look like buttons
transition: $transIn;
background: transparent;
border: 1px solid rgba($colorIndicatorMenuFg, 0.5);
border-radius: $controlCr;
box-sizing: border-box;
color: inherit;
font-size: inherit;
height: auto;
line-height: normal;
padding: 0 2px;
&:hover {
background: rgba($colorIndicatorMenuFg, 0.1);
border-color: rgba($colorIndicatorMenuFg, 0.75);
color: $colorIndicatorMenuFgHov;
}
}
[class*='icon-'] {
// If any elements within label include the class 'icon-*' then deal with their :before's
&:before {
font-size: 0.8em;
margin-right: $interiorMarginSm;
}
}
}
.c-indicator__count {
display: none; // Only displays when Indicator is minified, see below
}
[class*='minify-indicators'] {
// All styles for minified Indicators should go in here
.c-indicator:not(.no-minify) {
@include hover() {
background: $colorIndicatorBgHov;
.c-indicator__label {
box-shadow: $colorIndicatorMenuBgShdw;
transform: scale(1.0);
transition: all 100ms ease-out 100ms;
}
}
.c-indicator__label {
transition: all 250ms ease-in 200ms;
background: $colorIndicatorMenuBg;
color: $colorIndicatorMenuFg;
border-radius: $controlCr;
right: 0;
top: 130%;
padding: $interiorMargin $interiorMargin;
position: absolute;
transform-origin: 90% 0;
transform: scale(0.0);
overflow: visible;
z-index: 50;
&:before {
// Infobubble-style arrow element
content: '';
display: block;
position: absolute;
bottom: 100%;
right: 8px;
@include triangle('up', $size: 4px, $ratio: 1, $color: $colorIndicatorMenuBg);
}
}
.c-indicator__count {
display: inline-block;
margin-left: $interiorMarginSm;
}
}
}
/* Mobile */
// Hide the clock indicator when we're phone portrait
body.phone.portrait {
.c-indicator.t-indicator-clock {
display: none;
}
}
</style>
<script>
export default {
inject: ['openmct'],

View File

@ -41,85 +41,6 @@
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
@mixin statusBannerColors($bg, $fg: $colorStatusFg) {
$bgPb: 10%;
$bgPbD: 10%;
background-color: darken($bg, $bgPb);
color: $fg;
&:hover {
background-color: darken($bg, $bgPb - $bgPbD);
}
.s-action {
background-color: darken($bg, $bgPb + $bgPbD);
&:hover {
background-color: darken($bg, $bgPb);
}
}
}
.c-message-banner {
$closeBtnSize: 7px;
border-radius: $controlCr;
@include statusBannerColors($colorStatusDefault, $colorStatusFg);
cursor: pointer;
display: flex;
align-items: center;
left: 50%;
top: 50%;
max-width: 50%;
max-height: 25px;
padding: $interiorMarginSm $interiorMargin $interiorMarginSm $interiorMarginLg;
position: absolute;
transform: translate(-50%, -50%);
z-index: 2;
> * + * {
margin-left: $interiorMargin;
}
&.ok {
@include statusBannerColors($colorOk, $colorOkFg);
}
&.info {
@include statusBannerColors($colorInfo, $colorInfoFg);
}
&.caution,
&.warning,
&.alert {
@include statusBannerColors($colorWarningLo,$colorWarningLoFg);
}
&.error {
@include statusBannerColors($colorWarningHi, $colorWarningHiFg);
}
&__message {
@include ellipsize();
flex: 1 1 auto;
}
&__progress-bar {
flex: 0 0 auto;
width: 70px;
// Only show the progress bar
.c-progress-bar {
&__text {
display: none;
}
}
}
&__close-button {
font-size: 1.25em;
}
}
</style>
<script>
import ProgressBar from '../../components/ProgressBar.vue';
let activeNotification = undefined;

View File

@ -0,0 +1,127 @@
.c-indicator {
@include cControl();
@include cClickIconButtonLayout();
button { text-transform: uppercase; }
background: none !important;
border-radius: $controlCr;
overflow: visible;
position: relative;
text-transform: uppercase;
&.no-minify {
// For items that cannot be minified
display: flex;
flex-flow: row nowrap;
align-items: center;
> *,
&:before {
flex: 1 1 auto;
}
&:before {
margin-right: $interiorMarginSm;
}
}
&:not(.no-minify) {
&:before {
margin-right: 0 !important;
}
}
}
.c-indicator__label {
// Label element. Appears as a hover bubble element when Indicators are minified;
// Appears as an inline element when not.
display: inline-block;
transition:none;
white-space: nowrap;
a,
button,
s-button,
.c-button {
// Make <a> in label look like buttons
transition: $transIn;
background: transparent;
border: 1px solid rgba($colorIndicatorMenuFg, 0.5);
border-radius: $controlCr;
box-sizing: border-box;
color: inherit;
font-size: inherit;
height: auto;
line-height: normal;
padding: 0 2px;
&:hover {
background: rgba($colorIndicatorMenuFg, 0.1);
border-color: rgba($colorIndicatorMenuFg, 0.75);
color: $colorIndicatorMenuFgHov;
}
}
[class*='icon-'] {
// If any elements within label include the class 'icon-*' then deal with their :before's
&:before {
font-size: 0.8em;
margin-right: $interiorMarginSm;
}
}
}
.c-indicator__count {
display: none; // Only displays when Indicator is minified, see below
}
[class*='minify-indicators'] {
// All styles for minified Indicators should go in here
.c-indicator:not(.no-minify) {
@include hover() {
background: $colorIndicatorBgHov;
.c-indicator__label {
box-shadow: $colorIndicatorMenuBgShdw;
transform: scale(1.0);
transition: all 100ms ease-out 100ms;
}
}
.c-indicator__label {
transition: all 250ms ease-in 200ms;
background: $colorIndicatorMenuBg;
color: $colorIndicatorMenuFg;
border-radius: $controlCr;
right: 0;
top: 130%;
padding: $interiorMargin $interiorMargin;
position: absolute;
transform-origin: 90% 0;
transform: scale(0.0);
overflow: visible;
z-index: 50;
&:before {
// Infobubble-style arrow element
content: '';
display: block;
position: absolute;
bottom: 100%;
right: 8px;
@include triangle('up', $size: 4px, $ratio: 1, $color: $colorIndicatorMenuBg);
}
}
.c-indicator__count {
display: inline-block;
margin-left: $interiorMarginSm;
}
}
}
/* Mobile */
// Hide the clock indicator when we're phone portrait
body.phone.portrait {
.c-indicator.t-indicator-clock {
display: none;
}
}

Some files were not shown because too many files have changed in this diff Show More