mirror of
https://github.com/nasa/openmct.git
synced 2024-12-20 05:37:53 +00:00
cherry-pick #7850
This commit is contained in:
parent
e2a17b5f06
commit
cbb5dcea39
@ -229,6 +229,8 @@ $glyph-icon-grid-on: '\ea38';
|
|||||||
$glyph-icon-grid-off: '\ea39';
|
$glyph-icon-grid-off: '\ea39';
|
||||||
$glyph-icon-camera: '\ea3a';
|
$glyph-icon-camera: '\ea3a';
|
||||||
$glyph-icon-folders-collapse: '\ea3b';
|
$glyph-icon-folders-collapse: '\ea3b';
|
||||||
|
$glyph-icon-multiline: '\ea3c';
|
||||||
|
$glyph-icon-singleline: '\ea3d';
|
||||||
$glyph-icon-activity: '\eb00';
|
$glyph-icon-activity: '\eb00';
|
||||||
$glyph-icon-activity-mode: '\eb01';
|
$glyph-icon-activity-mode: '\eb01';
|
||||||
$glyph-icon-autoflow-tabular: '\eb02';
|
$glyph-icon-autoflow-tabular: '\eb02';
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -123,6 +123,8 @@
|
|||||||
<glyph unicode="" glyph-name="icon-grid-off" d="M256 344.6l128 157.6v9.8h8l104 128h-112v256h-128v-256h-256v-128h256v-167.4zM184 256h-184v-128h80l104 128zM768 423.4l-128-157.6v-9.8h-8l-104-128h112v-256h128v256h256v128h-256v167.4zM840 512h184v128h-80l-104-128zM832 896l-832-1024h192l832 1024h-192z" />
|
<glyph unicode="" glyph-name="icon-grid-off" d="M256 344.6l128 157.6v9.8h8l104 128h-112v256h-128v-256h-256v-128h256v-167.4zM184 256h-184v-128h80l104 128zM768 423.4l-128-157.6v-9.8h-8l-104-128h112v-256h128v256h256v128h-256v167.4zM840 512h184v128h-80l-104-128zM832 896l-832-1024h192l832 1024h-192z" />
|
||||||
<glyph unicode="" glyph-name="icon-camera" d="M896 640h-128l-128 256h-256l-128-256h-128c-70.601-0.227-127.773-57.399-128-127.978v-512.022c0.227-70.601 57.399-127.773 127.978-128h768.022c70.601 0.227 127.773 57.399 128 127.978v512.022c-0.227 70.601-57.399 127.773-127.978 128h-0.022zM512 32c-141.385 0-256 114.615-256 256s114.615 256 256 256c141.385 0 256-114.615 256-256v0c0-141.385-114.615-256-256-256v0z" />
|
<glyph unicode="" glyph-name="icon-camera" d="M896 640h-128l-128 256h-256l-128-256h-128c-70.601-0.227-127.773-57.399-128-127.978v-512.022c0.227-70.601 57.399-127.773 127.978-128h768.022c70.601 0.227 127.773 57.399 128 127.978v512.022c-0.227 70.601-57.399 127.773-127.978 128h-0.022zM512 32c-141.385 0-256 114.615-256 256s114.615 256 256 256c141.385 0 256-114.615 256-256v0c0-141.385-114.615-256-256-256v0z" />
|
||||||
<glyph unicode="" glyph-name="icon-folders-collapse" d="M896 576v-448c-0.215-70.606-57.394-127.785-127.979-128h-576.021c0.215-70.606 57.394-127.785 127.979-128h576.021c70.606 0.215 127.785 57.394 128 127.979v448.021c-0.215 70.606-57.394 127.785-127.979 128h-0.021zM832 192v448c-0.215 70.606-57.394 127.785-127.979 128h-192.021l-101.5 82.74c-24.88 24.9-74.040 45.26-109.24 45.26h-237.26c-35.305-0.102-63.898-28.695-64-63.99v-640.010c0.215-70.606 57.394-127.785 127.979-128h576.021c70.606 0.215 127.785 57.394 128 127.979v0.021zM128 252v516l256-260z" />
|
<glyph unicode="" glyph-name="icon-folders-collapse" d="M896 576v-448c-0.215-70.606-57.394-127.785-127.979-128h-576.021c0.215-70.606 57.394-127.785 127.979-128h576.021c70.606 0.215 127.785 57.394 128 127.979v448.021c-0.215 70.606-57.394 127.785-127.979 128h-0.021zM832 192v448c-0.215 70.606-57.394 127.785-127.979 128h-192.021l-101.5 82.74c-24.88 24.9-74.040 45.26-109.24 45.26h-237.26c-35.305-0.102-63.898-28.695-64-63.99v-640.010c0.215-70.606 57.394-127.785 127.979-128h576.021c70.606 0.215 127.785 57.394 128 127.979v0.021zM128 252v516l256-260z" />
|
||||||
|
<glyph unicode="" glyph-name="icon-multiline" d="M832.4 767.4c22.8 0 38-11.8 45-19 7-7 19-22.4 19-45v-640c0-22.8-11.8-38-19-45-7-7-22.4-19-45-19h-640c-22.8 0-38 11.8-45 19-7 7-19 22.4-19 45v640c0 22.8 11.8 38 19 45 7 7 22.4 19 45 19h640zM832.4 895.4h-640c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h640c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192v0zM256.4 575.4h512v-128h-512v128zM384.4 319.4h384v-128h-384v128z" />
|
||||||
|
<glyph unicode="" glyph-name="icon-singleline" d="M832.4 895.4h-640c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h640c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM896.4 447.4h-512v-128h512v-256c0-22.8-11.8-38-19-45-7-7-22.4-19-45-19h-640c-22.8 0-38 11.8-45 19-7 7-19 22.4-19 45v640c0 22.8 11.8 38 19 45 7 7 22.4 19 45 19h640c22.8 0 38-11.8 45-19 7-7 19-22.4 19-45v-256z" />
|
||||||
<glyph unicode="" glyph-name="icon-activity" d="M576 832h-256l320-320h-290.256c-44.264 76.516-126.99 128-221.744 128h-128v-512h128c94.754 0 177.48 51.484 221.744 128h290.256l-320-320h256l448 448-448 448z" />
|
<glyph unicode="" glyph-name="icon-activity" d="M576 832h-256l320-320h-290.256c-44.264 76.516-126.99 128-221.744 128h-128v-512h128c94.754 0 177.48 51.484 221.744 128h290.256l-320-320h256l448 448-448 448z" />
|
||||||
<glyph unicode="" glyph-name="icon-activity-mode" d="M512 896c-214.8 0-398.8-132.4-474.8-320h90.8c56.8 0 108-24.8 143-64h241l-192 192h256l320-320-320-320h-256l192 192h-241c-35-39.2-86.2-64-143-64h-90.8c76-187.6 259.8-320 474.8-320 282.8 0 512 229.2 512 512s-229.2 512-512 512z" />
|
<glyph unicode="" glyph-name="icon-activity-mode" d="M512 896c-214.8 0-398.8-132.4-474.8-320h90.8c56.8 0 108-24.8 143-64h241l-192 192h256l320-320-320-320h-256l192 192h-241c-35-39.2-86.2-64-143-64h-90.8c76-187.6 259.8-320 474.8-320 282.8 0 512 229.2 512 512s-229.2 512-512 512z" />
|
||||||
<glyph unicode="" glyph-name="icon-autoflow-tabular" d="M192 896c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h64v1024h-64zM384 896h256v-1024h-256v1024zM832 896h-64v-704h256v512c0 105.6-86.4 192-192 192z" />
|
<glyph unicode="" glyph-name="icon-autoflow-tabular" d="M192 896c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h64v1024h-64zM384 896h256v-1024h-256v1024zM832 896h-64v-704h256v512c0 105.6-86.4 192-192 192z" />
|
||||||
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 71 KiB |
Binary file not shown.
Binary file not shown.
@ -32,21 +32,25 @@
|
|||||||
class="l-shell__head"
|
class="l-shell__head"
|
||||||
:class="{
|
:class="{
|
||||||
'l-shell__head--expanded': headExpanded,
|
'l-shell__head--expanded': headExpanded,
|
||||||
'l-shell__head--minify-indicators': !headExpanded
|
'l-shell__head--minify-indicators': !headExpanded,
|
||||||
|
'l-shell__head--indicators-single-line': !indicatorsMultiline
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<CreateButton class="l-shell__create-button" />
|
<CreateButton class="l-shell__create-button" />
|
||||||
<GrandSearch ref="grand-search" />
|
<GrandSearch ref="grand-search" />
|
||||||
<StatusIndicators />
|
<StatusIndicators ref="indicatorsComponent" />
|
||||||
<button
|
<button
|
||||||
class="l-shell__head__collapse-button c-icon-button"
|
class="l-shell__head__button"
|
||||||
:class="
|
:class="indicatorsMultilineCssClass"
|
||||||
headExpanded
|
:aria-label="indicatorsMultilineLabel"
|
||||||
? 'l-shell__head__collapse-button--collapse'
|
:title="indicatorsMultilineLabel"
|
||||||
: 'l-shell__head__collapse-button--expand'
|
@click="toggleIndicatorsMultiline"
|
||||||
"
|
></button>
|
||||||
:aria-label="`Click to ${headExpanded ? 'collapse' : 'expand'} items`"
|
<button
|
||||||
:title="`Click to ${headExpanded ? 'collapse' : 'expand'} items`"
|
class="l-shell__head__button"
|
||||||
|
:class="headExpanded ? 'icon-items-collapse' : 'icon-items-expand'"
|
||||||
|
:aria-label="`Show ${headExpanded ? 'icon only' : 'icon and name'}`"
|
||||||
|
:title="`Show ${headExpanded ? 'icon only' : 'icon and name'}`"
|
||||||
@click="toggleShellHead"
|
@click="toggleShellHead"
|
||||||
></button>
|
></button>
|
||||||
<NotificationBanner />
|
<NotificationBanner />
|
||||||
@ -167,6 +171,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue';
|
||||||
|
|
||||||
import ObjectView from '../components/ObjectView.vue';
|
import ObjectView from '../components/ObjectView.vue';
|
||||||
import Inspector from '../inspector/InspectorPanel.vue';
|
import Inspector from '../inspector/InspectorPanel.vue';
|
||||||
import Toolbar from '../toolbar/ToolbarContainer.vue';
|
import Toolbar from '../toolbar/ToolbarContainer.vue';
|
||||||
@ -181,6 +187,10 @@ import GrandSearch from './search/GrandSearch.vue';
|
|||||||
import NotificationBanner from './status-bar/NotificationBanner.vue';
|
import NotificationBanner from './status-bar/NotificationBanner.vue';
|
||||||
import StatusIndicators from './status-bar/StatusIndicators.vue';
|
import StatusIndicators from './status-bar/StatusIndicators.vue';
|
||||||
|
|
||||||
|
const SHELL_HEAD_LOCAL_STORAGE_KEY = 'openmct-shell-head';
|
||||||
|
const DEFAULT_HEAD_EXPANDED = true;
|
||||||
|
const DEFAULT_INDICATORS_MULTILINE = true;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Inspector,
|
Inspector,
|
||||||
@ -198,13 +208,120 @@ export default {
|
|||||||
RecentObjectsList
|
RecentObjectsList
|
||||||
},
|
},
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
data: function () {
|
setup() {
|
||||||
let storedHeadProps = window.localStorage.getItem('openmct-shell-head');
|
let resizeObserver;
|
||||||
let headExpanded = true;
|
let element;
|
||||||
if (storedHeadProps) {
|
|
||||||
headExpanded = JSON.parse(storedHeadProps).expanded;
|
const storedHeadProps = localStorage.getItem(SHELL_HEAD_LOCAL_STORAGE_KEY);
|
||||||
|
const storedHeadPropsObject = JSON.parse(storedHeadProps);
|
||||||
|
const storedHeadExpanded = storedHeadPropsObject?.expanded;
|
||||||
|
const storedIndicatorsMultiline = storedHeadPropsObject?.multiline;
|
||||||
|
|
||||||
|
// template ref of StatusIndicators component
|
||||||
|
const indicatorsComponent = ref(null);
|
||||||
|
|
||||||
|
const width = ref(null);
|
||||||
|
const scrollWidth = ref(null);
|
||||||
|
const headExpanded = ref(storedHeadExpanded ?? DEFAULT_HEAD_EXPANDED);
|
||||||
|
const indicatorsMultiline = ref(storedIndicatorsMultiline ?? DEFAULT_INDICATORS_MULTILINE);
|
||||||
|
|
||||||
|
const isOverflowing = computed(() => scrollWidth.value > width.value);
|
||||||
|
const indicatorsMultilineCssClass = computed(() => {
|
||||||
|
const multilineClass = indicatorsMultiline.value ? 'icon-singleline' : 'icon-multiline';
|
||||||
|
const overflowingClass =
|
||||||
|
isOverflowing.value && !indicatorsMultiline.value
|
||||||
|
? 'c-button c-button--major'
|
||||||
|
: 'c-icon-button';
|
||||||
|
return `${multilineClass} ${overflowingClass}`;
|
||||||
|
});
|
||||||
|
const indicatorsMultilineLabel = computed(() => {
|
||||||
|
return `Display as ${indicatorsMultiline.value ? 'single line' : 'multiple lines'}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const initialHeadProps = JSON.stringify({
|
||||||
|
expanded: headExpanded.value,
|
||||||
|
multiline: indicatorsMultiline.value
|
||||||
|
});
|
||||||
|
|
||||||
|
if (initialHeadProps !== storedHeadProps) {
|
||||||
|
localStorage.setItem(SHELL_HEAD_LOCAL_STORAGE_KEY, initialHeadProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
resizeObserver = new ResizeObserver((entries) => {
|
||||||
|
width.value = entries[0].target.clientWidth;
|
||||||
|
scrollWidth.value = entries[0].target.scrollWidth;
|
||||||
|
});
|
||||||
|
|
||||||
|
// indicatorsContainer is a template ref inside of indicatorsComponent
|
||||||
|
element = indicatorsComponent.value.$refs.indicatorsContainer;
|
||||||
|
|
||||||
|
if (!indicatorsMultiline.value) {
|
||||||
|
observeIndicatorsOverflow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
resizeObserver.disconnect();
|
||||||
|
});
|
||||||
|
|
||||||
|
function observeIndicatorsOverflow() {
|
||||||
|
resizeObserver.observe(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
function unObserveIndicatorsOverflow() {
|
||||||
|
resizeObserver.unobserve(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkIndicatorsElementWidths() {
|
||||||
|
if (!indicatorsMultiline.value) {
|
||||||
|
width.value = element.clientWidth;
|
||||||
|
scrollWidth.value = element.scrollWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function toggleShellHead() {
|
||||||
|
headExpanded.value = !headExpanded.value;
|
||||||
|
setLocalStorageShellHead();
|
||||||
|
|
||||||
|
// nextTick is used because the element width on toggle is updated using css
|
||||||
|
await nextTick();
|
||||||
|
checkIndicatorsElementWidths();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleIndicatorsMultiline() {
|
||||||
|
indicatorsMultiline.value = !indicatorsMultiline.value;
|
||||||
|
setLocalStorageShellHead();
|
||||||
|
|
||||||
|
if (indicatorsMultiline.value) {
|
||||||
|
unObserveIndicatorsOverflow();
|
||||||
|
} else {
|
||||||
|
observeIndicatorsOverflow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLocalStorageShellHead() {
|
||||||
|
localStorage.setItem(
|
||||||
|
SHELL_HEAD_LOCAL_STORAGE_KEY,
|
||||||
|
JSON.stringify({
|
||||||
|
expanded: headExpanded.value,
|
||||||
|
multiline: indicatorsMultiline.value
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
indicatorsComponent,
|
||||||
|
isOverflowing,
|
||||||
|
headExpanded,
|
||||||
|
indicatorsMultiline,
|
||||||
|
indicatorsMultilineCssClass,
|
||||||
|
indicatorsMultilineLabel,
|
||||||
|
toggleIndicatorsMultiline,
|
||||||
|
toggleShellHead
|
||||||
|
};
|
||||||
|
},
|
||||||
|
data() {
|
||||||
return {
|
return {
|
||||||
fullScreen: false,
|
fullScreen: false,
|
||||||
conductorComponent: undefined,
|
conductorComponent: undefined,
|
||||||
@ -213,7 +330,6 @@ export default {
|
|||||||
actionCollection: undefined,
|
actionCollection: undefined,
|
||||||
triggerSync: false,
|
triggerSync: false,
|
||||||
triggerReset: false,
|
triggerReset: false,
|
||||||
headExpanded,
|
|
||||||
isResizing: false,
|
isResizing: false,
|
||||||
disableClearButton: false
|
disableClearButton: false
|
||||||
};
|
};
|
||||||
@ -261,16 +377,6 @@ export default {
|
|||||||
document.msExitFullscreen();
|
document.msExitFullscreen();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggleShellHead() {
|
|
||||||
this.headExpanded = !this.headExpanded;
|
|
||||||
|
|
||||||
window.localStorage.setItem(
|
|
||||||
'openmct-shell-head',
|
|
||||||
JSON.stringify({
|
|
||||||
expanded: this.headExpanded
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
|
||||||
fullScreenToggle() {
|
fullScreenToggle() {
|
||||||
if (this.fullScreen) {
|
if (this.fullScreen) {
|
||||||
this.fullScreen = false;
|
this.fullScreen = false;
|
||||||
|
@ -213,27 +213,14 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
background: $colorHeadBg;
|
background: $colorHeadBg;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: min-content 1fr 3fr repeat(3, min-content);
|
grid-template-columns: min-content 1fr 3fr repeat(4, min-content);
|
||||||
grid-column-gap: $interiorMargin;
|
grid-column-gap: $interiorMargin;
|
||||||
min-height: 34px;
|
|
||||||
padding: $interiorMargin $interiorMargin + 2;
|
padding: $interiorMargin $interiorMargin + 2;
|
||||||
|
|
||||||
.l-shell__head__collapse-button {
|
.l-shell__head__button {
|
||||||
color: $colorBtnMajorBg;
|
color: $colorBtnMajorBg;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
|
|
||||||
&--collapse {
|
|
||||||
&:before {
|
|
||||||
content: $glyph-icon-items-collapse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--expand {
|
|
||||||
&:before {
|
|
||||||
content: $glyph-icon-items-expand;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-section {
|
&-section {
|
||||||
@ -271,14 +258,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__indicators {
|
&__indicators {
|
||||||
|
// Style as multiline by default
|
||||||
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
|
min-height: 25px;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
|
||||||
.l-shell__head--expanded & {
|
.l-shell__head--indicators-single-line & {
|
||||||
// Force elements to wrap down when width constrained
|
flex-wrap: nowrap;
|
||||||
height: 24px;
|
justify-content: flex-start; // Overflow detection doesn't work with flex-end.
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
> *:first-child {
|
||||||
|
margin-left: auto; // Mimics justify-content: flex-end when in single line mode.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="l-shell__head-section l-shell__indicators">
|
<div ref="indicatorsContainer" class="l-shell__head-section l-shell__indicators">
|
||||||
<component
|
<component
|
||||||
:is="indicator.value.vueComponent"
|
:is="indicator.value.vueComponent"
|
||||||
v-for="indicator in sortedIndicators"
|
v-for="indicator in sortedIndicators"
|
||||||
@ -28,9 +28,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { shallowRef } from 'vue';
|
import { defineExpose, ref, shallowRef } from 'vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
|
setup() {
|
||||||
|
const indicatorsContainer = ref(null);
|
||||||
|
|
||||||
|
defineExpose({ indicatorsContainer });
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
indicators: this.openmct.indicators.getIndicatorObjectsByPriority().map(shallowRef)
|
indicators: this.openmct.indicators.getIndicatorObjectsByPriority().map(shallowRef)
|
||||||
|
Loading…
Reference in New Issue
Block a user