mirror of
https://github.com/nasa/openmct.git
synced 2025-06-25 18:50:11 +00:00
Compare commits
8 Commits
telemetry-
...
tabs-testi
Author | SHA1 | Date | |
---|---|---|---|
294bed974f | |||
4c9c084eec | |||
b64ee10812 | |||
ee1ecf43db | |||
4d8db8eb7c | |||
1b13965200 | |||
38db8f7fe5 | |||
4ba8f893a6 |
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -2,6 +2,7 @@
|
||||
|
||||
* [ ] Have you followed the guidelines in our [Contributing document](https://github.com/nasa/openmct/blob/master/CONTRIBUTING.md)?
|
||||
* [ ] Have you checked to ensure there aren't other open [Pull Requests](https://github.com/nasa/openmct/pulls) for the same update/change?
|
||||
* [ ] Is this change backwards compatible? Will users need to change how they are calling the API, or how they've extended core plugins such as Tables or Plots?
|
||||
|
||||
### Author Checklist
|
||||
|
||||
|
@ -317,6 +317,7 @@ checklist).
|
||||
### Reviewer Checklist
|
||||
|
||||
* [ ] Changes appear to address issue?
|
||||
* [ ] Changes appear not to be breaking changes?
|
||||
* [ ] Appropriate unit tests included?
|
||||
* [ ] Code style and in-line documentation are appropriate?
|
||||
* [ ] Commit messages meet standards?
|
||||
|
@ -25,15 +25,14 @@ define([
|
||||
], function (
|
||||
moment
|
||||
) {
|
||||
|
||||
var DATE_FORMAT = "YYYY-MM-DD HH:mm:ss.SSS",
|
||||
DATE_FORMATS = [
|
||||
DATE_FORMAT,
|
||||
DATE_FORMAT + "Z",
|
||||
"YYYY-MM-DD HH:mm:ss",
|
||||
"YYYY-MM-DD HH:mm",
|
||||
"YYYY-MM-DD"
|
||||
];
|
||||
const DATE_FORMAT = "YYYY-MM-DD HH:mm:ss.SSS";
|
||||
const DATE_FORMATS = [
|
||||
DATE_FORMAT,
|
||||
DATE_FORMAT + "Z",
|
||||
"YYYY-MM-DD HH:mm:ss",
|
||||
"YYYY-MM-DD HH:mm",
|
||||
"YYYY-MM-DD"
|
||||
];
|
||||
|
||||
/**
|
||||
* @typedef Scale
|
||||
@ -53,15 +52,27 @@ define([
|
||||
this.key = "utc";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} formatString
|
||||
* @returns the value of formatString if the value is a string type and exists in the DATE_FORMATS array; otherwise the DATE_FORMAT value.
|
||||
*/
|
||||
function validateFormatString(formatString) {
|
||||
return typeof formatString === 'string' && DATE_FORMATS.includes(formatString) ? formatString : DATE_FORMAT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} value The value to format.
|
||||
* @returns {string} the formatted date(s). If multiple values were requested, then an array of
|
||||
* @param {string} formatString The string format to format. Default "YYYY-MM-DD HH:mm:ss.SSS" + "Z"
|
||||
* @returns {string} the formatted date(s) according to the proper parameter of formatString or the default value of "YYYY-MM-DD HH:mm:ss.SSS" + "Z".
|
||||
* If multiple values were requested, then an array of
|
||||
* formatted values will be returned. Where a value could not be formatted, `undefined` will be returned at its position
|
||||
* in the array.
|
||||
*/
|
||||
UTCTimeFormat.prototype.format = function (value) {
|
||||
UTCTimeFormat.prototype.format = function (value, formatString) {
|
||||
if (value !== undefined) {
|
||||
return moment.utc(value).format(DATE_FORMAT) + "Z";
|
||||
const format = validateFormatString(formatString);
|
||||
|
||||
return moment.utc(value).format(format) + (formatString ? '' : 'Z');
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
|
@ -30,10 +30,10 @@
|
||||
<div v-if="staticStyle"
|
||||
class="c-inspect-styles__style"
|
||||
>
|
||||
<style-editor class="c-inspect-styles__editor"
|
||||
:style-item="staticStyle"
|
||||
:is-editing="isEditing"
|
||||
@persist="updateStaticStyle"
|
||||
<StyleEditor class="c-inspect-styles__editor"
|
||||
:style-item="staticStyle"
|
||||
:is-editing="isEditing"
|
||||
@persist="updateStaticStyle"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
@ -87,10 +87,10 @@
|
||||
<condition-description :show-label="true"
|
||||
:condition="getCondition(conditionStyle.conditionId)"
|
||||
/>
|
||||
<style-editor class="c-inspect-styles__editor"
|
||||
:style-item="conditionStyle"
|
||||
:is-editing="isEditing"
|
||||
@persist="updateConditionalStyle"
|
||||
<StyleEditor class="c-inspect-styles__editor"
|
||||
:style-item="conditionStyle"
|
||||
:is-editing="isEditing"
|
||||
@persist="updateConditionalStyle"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -240,10 +240,10 @@ export default {
|
||||
}
|
||||
|
||||
let vm = new Vue({
|
||||
components: {ConditionSetSelectorDialog},
|
||||
provide: {
|
||||
openmct: this.openmct
|
||||
},
|
||||
components: {ConditionSetSelectorDialog},
|
||||
data() {
|
||||
return {
|
||||
handleItemSelection
|
||||
|
@ -40,13 +40,13 @@
|
||||
<div v-if="staticStyle"
|
||||
class="c-inspect-styles__style"
|
||||
>
|
||||
<style-editor class="c-inspect-styles__editor"
|
||||
:style-item="staticStyle"
|
||||
:is-editing="allowEditing"
|
||||
:mixed-styles="mixedStyles"
|
||||
:non-specific-font-properties="nonSpecificFontProperties"
|
||||
@persist="updateStaticStyle"
|
||||
@save-style="saveStyle"
|
||||
<StyleEditor class="c-inspect-styles__editor"
|
||||
:style-item="staticStyle"
|
||||
:is-editing="allowEditing"
|
||||
:mixed-styles="mixedStyles"
|
||||
:non-specific-font-properties="nonSpecificFontProperties"
|
||||
@persist="updateStaticStyle"
|
||||
@save-style="saveStyle"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
@ -108,12 +108,12 @@
|
||||
<condition-description :show-label="true"
|
||||
:condition="getCondition(conditionStyle.conditionId)"
|
||||
/>
|
||||
<style-editor class="c-inspect-styles__editor"
|
||||
:style-item="conditionStyle"
|
||||
:non-specific-font-properties="nonSpecificFontProperties"
|
||||
:is-editing="allowEditing"
|
||||
@persist="updateConditionalStyle"
|
||||
@save-style="saveStyle"
|
||||
<StyleEditor class="c-inspect-styles__editor"
|
||||
:style-item="conditionStyle"
|
||||
:non-specific-font-properties="nonSpecificFontProperties"
|
||||
:is-editing="allowEditing"
|
||||
@persist="updateConditionalStyle"
|
||||
@save-style="saveStyle"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -556,10 +556,10 @@ export default {
|
||||
}
|
||||
|
||||
let vm = new Vue({
|
||||
components: {ConditionSetSelectorDialog},
|
||||
provide: {
|
||||
openmct: this.openmct
|
||||
},
|
||||
components: {ConditionSetSelectorDialog},
|
||||
data() {
|
||||
return {
|
||||
handleItemSelection
|
||||
|
@ -47,8 +47,8 @@
|
||||
|
||||
.is-editing {
|
||||
.l-shell__main-container {
|
||||
&[s-selected],
|
||||
&[s-selected-parent] {
|
||||
[s-selected],
|
||||
[s-selected-parent] {
|
||||
// Display grid and allow edit marquee to display in main layout holder when editing
|
||||
> .l-layout {
|
||||
background: $editUIGridColorBg;
|
||||
|
@ -84,18 +84,18 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-local-controls c-local-controls--show-on-hover c-imagery__prev-next-buttons">
|
||||
<button class="c-nav c-nav--prev"
|
||||
title="Previous image"
|
||||
:disabled="isPrevDisabled"
|
||||
@click="prevImage()"
|
||||
></button>
|
||||
<button class="c-nav c-nav--next"
|
||||
title="Next image"
|
||||
:disabled="isNextDisabled"
|
||||
@click="nextImage()"
|
||||
></button>
|
||||
</div>
|
||||
|
||||
<button class="c-local-controls c-local-controls--show-on-hover c-imagery__prev-next-button c-nav c-nav--prev"
|
||||
title="Previous image"
|
||||
:disabled="isPrevDisabled"
|
||||
@click="prevImage()"
|
||||
></button>
|
||||
|
||||
<button class="c-local-controls c-local-controls--show-on-hover c-imagery__prev-next-button c-nav c-nav--next"
|
||||
title="Next image"
|
||||
:disabled="isNextDisabled"
|
||||
@click="nextImage()"
|
||||
></button>
|
||||
|
||||
<div class="c-imagery__control-bar">
|
||||
<div class="c-imagery__time">
|
||||
|
@ -285,17 +285,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
.c-imagery__prev-next-buttons {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
pointer-events: none;
|
||||
.c-imagery__prev-next-button {
|
||||
pointer-events: all;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-75%);
|
||||
transform: translateY(-75%); // 75% due to transform: rotation approach to the button
|
||||
|
||||
.c-nav {
|
||||
pointer-events: all;
|
||||
&.c-nav {
|
||||
position: absolute;
|
||||
|
||||
&--prev { left: 0; }
|
||||
&--next { right: 0; }
|
||||
}
|
||||
|
||||
.s-status-taking-snapshot & {
|
||||
|
@ -45,8 +45,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import packages from './third-party-licenses.json';
|
||||
|
||||
|
@ -39,10 +39,6 @@ export default function BarGraphCompositionPolicy(openmct) {
|
||||
return metadata.values().length > 0 && hasAggregateDomainAndRange(metadata);
|
||||
}
|
||||
|
||||
function hasNoChildren(parentObject) {
|
||||
return parentObject.composition && parentObject.composition.length < 1;
|
||||
}
|
||||
|
||||
return {
|
||||
allow: function (parent, child) {
|
||||
if ((parent.type === BAR_GRAPH_KEY)
|
||||
|
@ -19,6 +19,9 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
|
||||
<template>
|
||||
<div class="gl-plot-chart-area">
|
||||
<span v-html="canvasTemplate"></span>
|
||||
|
@ -52,17 +52,19 @@
|
||||
>
|
||||
</button>
|
||||
</div>
|
||||
<stacked-plot-item v-for="object in compositionObjects"
|
||||
:key="object.id"
|
||||
class="c-plot--stacked-container"
|
||||
:object="object"
|
||||
:options="options"
|
||||
:grid-lines="gridLines"
|
||||
:cursor-guide="cursorGuide"
|
||||
:plot-tick-width="maxTickWidth"
|
||||
@plotTickWidth="onTickWidthChange"
|
||||
@loadingUpdated="loadingUpdated"
|
||||
/>
|
||||
<div class="l-view-section">
|
||||
<stacked-plot-item v-for="object in compositionObjects"
|
||||
:key="object.id"
|
||||
class="c-plot--stacked-container"
|
||||
:object="object"
|
||||
:options="options"
|
||||
:grid-lines="gridLines"
|
||||
:cursor-guide="cursorGuide"
|
||||
:plot-tick-width="maxTickWidth"
|
||||
@plotTickWidth="onTickWidthChange"
|
||||
@loadingUpdated="loadingUpdated"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -152,7 +152,11 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
addTabToLoaded(tab) {
|
||||
this.loadedTabs[tab.keyString] = true;
|
||||
if (this.internalDomainObject.keep_alive) {
|
||||
this.loadedTabs[tab.keyString] = true;
|
||||
} else {
|
||||
this.loadedTabs = { [tab.keyString]: true };
|
||||
}
|
||||
},
|
||||
setCurrentTabByIndex(index) {
|
||||
if (this.tabsList[index]) {
|
||||
|
@ -48,17 +48,17 @@ define([
|
||||
components: {
|
||||
TabsComponent: TabsComponent.default
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isEditing: editMode
|
||||
};
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
domainObject,
|
||||
objectPath,
|
||||
composition: openmct.composition.get(domainObject)
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isEditing: editMode
|
||||
};
|
||||
},
|
||||
template: '<tabs-component :isEditing="isEditing"></tabs-component>'
|
||||
});
|
||||
},
|
||||
|
@ -168,13 +168,16 @@ export default {
|
||||
}
|
||||
},
|
||||
zoom(bounds) {
|
||||
this.isZooming = true;
|
||||
this.formattedBounds.start = this.timeFormatter.format(bounds.start);
|
||||
this.formattedBounds.end = this.timeFormatter.format(bounds.end);
|
||||
if (isNaN(bounds.start) || isNaN(bounds.end)) {
|
||||
this.isZooming = false;
|
||||
} else {
|
||||
this.isZooming = true;
|
||||
this.formattedBounds.start = this.timeFormatter.format(bounds.start);
|
||||
this.formattedBounds.end = this.timeFormatter.format(bounds.end);
|
||||
}
|
||||
},
|
||||
endZoom(bounds) {
|
||||
this.isZooming = false;
|
||||
|
||||
if (bounds) {
|
||||
this.openmct.time.bounds(bounds);
|
||||
} else {
|
||||
|
@ -40,7 +40,7 @@ const LOCAL_STORAGE_HISTORY_KEY_FIXED = 'tcHistory';
|
||||
const LOCAL_STORAGE_HISTORY_KEY_REALTIME = 'tcHistoryRealtime';
|
||||
const DEFAULT_RECORDS = 10;
|
||||
|
||||
import { getDuration } from "utils/duration";
|
||||
import { millisecondsToDHMS } from "utils/duration";
|
||||
|
||||
export default {
|
||||
inject: ['openmct', 'configuration'],
|
||||
@ -142,7 +142,7 @@ export default {
|
||||
let description = `${startTime} - ${this.formatTime(timespan.end)}`;
|
||||
|
||||
if (this.timeSystem.isUTCBased && !this.openmct.time.clock()) {
|
||||
name = `${startTime} ${getDuration(timespan.end - timespan.start)}`;
|
||||
name = `${startTime} ${millisecondsToDHMS(timespan.end - timespan.start)}`;
|
||||
} else {
|
||||
name = description;
|
||||
}
|
||||
@ -263,7 +263,7 @@ export default {
|
||||
format: format
|
||||
}).formatter;
|
||||
|
||||
return (isNegativeOffset ? '-' : '') + formatter.format(time);
|
||||
return (isNegativeOffset ? '-' : '') + formatter.format(time, 'YYYY-MM-DD HH:mm:ss');
|
||||
},
|
||||
showHistoryMenu() {
|
||||
const elementBoundingClientRect = this.$refs.historyButton.getBoundingClientRect();
|
||||
|
@ -1006,6 +1006,9 @@ input[type="range"] {
|
||||
transition: $transIn;
|
||||
opacity: 1;
|
||||
pointer-events: inherit;
|
||||
|
||||
&[disabled] { opacity: $controlDisabledOpacity; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,6 @@ mct-plot {
|
||||
|
||||
.c-plot,
|
||||
.gl-plot {
|
||||
overflow: hidden;
|
||||
min-height: 100px;
|
||||
|
||||
.s-status-taking-snapshot & {
|
||||
.c-control-bar {
|
||||
display: none;
|
||||
@ -67,16 +64,17 @@ mct-plot {
|
||||
|
||||
.c-plot {
|
||||
@include abs($mainViewPad);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
min-height: $plotMinH;
|
||||
|
||||
.c-control-bar {
|
||||
flex: 0 0 auto;
|
||||
margin-bottom: $interiorMargin;
|
||||
}
|
||||
|
||||
.l-view-section, .c-plot--stacked-container {
|
||||
.l-view-section {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
flex-direction: column;
|
||||
@ -84,7 +82,18 @@ mct-plot {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.c-plot--stacked-container {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
flex-direction: column;
|
||||
min-height: $plotMinH;
|
||||
overflow: hidden;
|
||||
}
|
||||
;
|
||||
|
||||
&--stacked {
|
||||
min-height: auto !important;
|
||||
|
||||
.child-frame {
|
||||
.has-control-bar {
|
||||
.c-control-bar {
|
||||
@ -124,7 +133,7 @@ mct-plot {
|
||||
.plot-wrapper-axis-and-display-area {
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
min-height: $plotMinH;
|
||||
//min-height: $plotMinH;
|
||||
}
|
||||
|
||||
.gl-plot-wrapper-display-area-and-x-axis {
|
||||
@ -465,6 +474,7 @@ mct-plot {
|
||||
.gl-plot-legend,
|
||||
.c-plot-legend {
|
||||
overflow: hidden;
|
||||
flex: 0 0 auto; // Prevents clipping for all legend placements (top, bottom, etc.)
|
||||
|
||||
&__wrapper {
|
||||
// Holds view-control and both collapsed and expanded legends
|
||||
|
@ -599,8 +599,6 @@
|
||||
@mixin cArrowButtonBase($colorBg: transparent, $colorFg: $colorBtnFg, $filterHov: $filterHov) {
|
||||
// Copied from branch new-tree-refactor
|
||||
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
background: $colorBg;
|
||||
|
||||
&:before {
|
||||
|
@ -54,15 +54,15 @@ export default {
|
||||
let viewContainer = document.createElement('div');
|
||||
this.$el.append(viewContainer);
|
||||
this.component = new Vue({
|
||||
el: viewContainer,
|
||||
components: {
|
||||
StylesView
|
||||
},
|
||||
provide: {
|
||||
openmct: this.openmct,
|
||||
selection: selection,
|
||||
stylesManager: this.stylesManager
|
||||
},
|
||||
el: viewContainer,
|
||||
components: {
|
||||
StylesView
|
||||
},
|
||||
template: '<styles-view/>'
|
||||
});
|
||||
}
|
||||
|
@ -42,10 +42,10 @@ export default {
|
||||
methods: {
|
||||
launchAbout() {
|
||||
let vm = new Vue({
|
||||
components: {AboutDialog},
|
||||
provide: {
|
||||
openmct: this.openmct
|
||||
},
|
||||
components: {AboutDialog},
|
||||
template: '<about-dialog></about-dialog>'
|
||||
}).$mount();
|
||||
|
||||
|
@ -20,7 +20,8 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
const ONE_MINUTE = 60 * 1000;
|
||||
const ONE_SECOND = 1000;
|
||||
const ONE_MINUTE = 60 * ONE_SECOND;
|
||||
const ONE_HOUR = ONE_MINUTE * 60;
|
||||
const ONE_DAY = ONE_HOUR * 24;
|
||||
|
||||
@ -39,34 +40,20 @@ function toDoubleDigits(num) {
|
||||
}
|
||||
}
|
||||
|
||||
export function getDuration(numericDuration) {
|
||||
let result;
|
||||
let age;
|
||||
function addTimeSuffix(value, suffix) {
|
||||
return typeof value === 'number' && value > 0 ? `${value + suffix}` : '';
|
||||
}
|
||||
|
||||
if (numericDuration > ONE_DAY - 1) {
|
||||
age = normalizeAge((numericDuration / ONE_DAY)).toFixed(2);
|
||||
result = `+ ${age} day`;
|
||||
export function millisecondsToDHMS(numericDuration) {
|
||||
const ms = numericDuration || 0;
|
||||
const dhms = [
|
||||
addTimeSuffix(Math.floor(normalizeAge(ms / ONE_DAY)), 'd'),
|
||||
addTimeSuffix(Math.floor(normalizeAge((ms % ONE_DAY) / ONE_HOUR)), 'h'),
|
||||
addTimeSuffix(Math.floor(normalizeAge((ms % ONE_HOUR) / ONE_MINUTE)), 'm'),
|
||||
addTimeSuffix(Math.floor(normalizeAge((ms % ONE_MINUTE) / ONE_SECOND)), 's')
|
||||
].filter(Boolean).join(' ');
|
||||
|
||||
if (age !== 1) {
|
||||
result += 's';
|
||||
}
|
||||
} else if (numericDuration > ONE_HOUR - 1) {
|
||||
age = normalizeAge((numericDuration / ONE_HOUR).toFixed(2));
|
||||
result = `+ ${age} hour`;
|
||||
|
||||
if (age !== 1) {
|
||||
result += 's';
|
||||
}
|
||||
} else {
|
||||
age = normalizeAge((numericDuration / ONE_MINUTE).toFixed(2));
|
||||
result = `+ ${age} min`;
|
||||
|
||||
if (age !== 1) {
|
||||
result += 's';
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return `${ dhms ? '+' : ''} ${dhms}`;
|
||||
}
|
||||
|
||||
export function getPreciseDuration(numericDuration) {
|
||||
|
Reference in New Issue
Block a user