Compare commits

..

8 Commits

Author SHA1 Message Date
62ff404bb3 Testing with non-reactive API 2021-09-27 16:45:54 -07:00
8243cf5d7b Fix missing object handling in several vues (#4259)
* If there is a pending create request for an id, queue a duplicate request.
* Fix downsteam errors when objects are missing
* Changed error logging from console.log to console.warn
2021-09-27 14:25:33 -07:00
c4c1fea17f snapshot clicked while in edit mode should open in preview mode #4115 (#4257) 2021-09-27 10:14:03 -07:00
5e920e90ce Fix bargraph color selection (#4253)
* Fix typo for attribute key
* Adds section heading for Bar Graph Series
2021-09-24 10:07:53 -07:00
886db23eb6 Hide independent time conductor mode if only 1 mode option is available. (#4250)
* If there is a pending create request for an id, queue a duplicate request.
* Hide independent time conductor mode if there is only 1 mode available
2021-09-23 10:47:35 -07:00
0ccb546a2e starting loading as false, since that makes sense (#4247) 2021-09-23 09:42:39 -07:00
271f8ed38f Fix file selection on pressing enter key (#4246)
* Invoke angular digest cycle after file input selection returns
2021-09-22 15:14:30 -07:00
650f84e95c [Telemetry Tables] Handling Request Loading (#4245)
* added two new events for telemetry collections to denote historical requests starting and ending (can be used for loading indicators)

* updating refresh data to use correct outstanding requests variable, binding request count update methods

* removing loading spinner (replaced with progress bar)

* if making a request, cancel any existing ones

* reverting edge case code updates
2021-09-22 15:01:28 -07:00
24 changed files with 160 additions and 141 deletions

View File

@ -44,9 +44,11 @@ define(
setText(result.name); setText(result.name);
scope.ngModel[scope.field] = result; scope.ngModel[scope.field] = result;
control.$setValidity("file-input", true); control.$setValidity("file-input", true);
scope.$digest();
}, function () { }, function () {
setText('Select File'); setText('Select File');
control.$setValidity("file-input", false); control.$setValidity("file-input", false);
scope.$digest();
}); });
} }

View File

@ -288,6 +288,8 @@ define([
this.install(this.plugins.ObjectInterceptors()); this.install(this.plugins.ObjectInterceptors());
this.install(this.plugins.NonEditableFolder()); this.install(this.plugins.NonEditableFolder());
this.install(this.plugins.DeviceClassifier()); this.install(this.plugins.DeviceClassifier());
this._isVue = true;
} }
MCT.prototype = Object.create(EventEmitter.prototype); MCT.prototype = Object.create(EventEmitter.prototype);

View File

@ -81,14 +81,8 @@ define([
return models; return models;
} }
return this.apiFetch(missingIds) //Temporary fix for missing models - don't retry using this.apiFetch
.then(function (apiResults) { return models;
Object.keys(apiResults).forEach(function (k) {
models[k] = apiResults[k];
});
return models;
});
}.bind(this)); }.bind(this));
}; };

View File

@ -110,7 +110,7 @@ class ActionsAPI extends EventEmitter {
return actionsObject; return actionsObject;
} }
_groupAndSortActions(actionsArray) { _groupAndSortActions(actionsArray = []) {
if (!Array.isArray(actionsArray) && typeof actionsArray === 'object') { if (!Array.isArray(actionsArray) && typeof actionsArray === 'object') {
actionsArray = Object.keys(actionsArray).map(key => actionsArray[key]); actionsArray = Object.keys(actionsArray).map(key => actionsArray[key]);
} }

View File

@ -190,6 +190,14 @@ ObjectAPI.prototype.get = function (identifier, abortSignal) {
result = this.applyGetInterceptors(identifier, result); result = this.applyGetInterceptors(identifier, result);
return result;
}).catch((result) => {
console.warn(`Failed to retrieve ${keystring}:`, result);
delete this.cache[keystring];
result = this.applyGetInterceptors(identifier);
return result; return result;
}); });

View File

@ -483,6 +483,10 @@ define([
* @returns {Object<String, {TelemetryValueFormatter}>} * @returns {Object<String, {TelemetryValueFormatter}>}
*/ */
TelemetryAPI.prototype.getFormatMap = function (metadata) { TelemetryAPI.prototype.getFormatMap = function (metadata) {
if (!metadata) {
return {};
}
if (!this.formatMapCache.has(metadata)) { if (!this.formatMapCache.has(metadata)) {
const formatMap = metadata.values().reduce(function (map, valueMetadata) { const formatMap = metadata.values().reduce(function (map, valueMetadata) {
map[valueMetadata.key] = this.getValueFormatter(valueMetadata); map[valueMetadata.key] = this.getValueFormatter(valueMetadata);

View File

@ -130,8 +130,13 @@ export class TelemetryCollection extends EventEmitter {
this.options.onPartialResponse = this._processNewTelemetry.bind(this); this.options.onPartialResponse = this._processNewTelemetry.bind(this);
try { try {
if (this.requestAbort) {
this.requestAbort.abort();
}
this.requestAbort = new AbortController(); this.requestAbort = new AbortController();
this.options.signal = this.requestAbort.signal; this.options.signal = this.requestAbort.signal;
this.emit('requestStarted');
historicalData = await this.historicalProvider.request(this.domainObject, this.options); historicalData = await this.historicalProvider.request(this.domainObject, this.options);
} catch (error) { } catch (error) {
if (error.name !== 'AbortError') { if (error.name !== 'AbortError') {
@ -140,6 +145,7 @@ export class TelemetryCollection extends EventEmitter {
} }
} }
this.emit('requestEnded');
this.requestAbort = undefined; this.requestAbort = undefined;
this._processNewTelemetry(historicalData); this._processNewTelemetry(historicalData);

View File

@ -96,11 +96,11 @@ export default {
this.timestampKey = this.openmct.time.timeSystem().key; this.timestampKey = this.openmct.time.timeSystem().key;
this.valueMetadata = this this.valueMetadata = this.metadata ? this
.metadata .metadata
.valuesForHints(['range'])[0]; .valuesForHints(['range'])[0] : undefined;
this.valueKey = this.valueMetadata.key; this.valueKey = this.valueMetadata ? this.valueMetadata.key : undefined;
this.unsubscribe = this.openmct this.unsubscribe = this.openmct
.telemetry .telemetry
@ -151,7 +151,10 @@ export default {
size: 1, size: 1,
strategy: 'latest' strategy: 'latest'
}) })
.then((array) => this.updateValues(array[array.length - 1])); .then((array) => this.updateValues(array[array.length - 1]))
.catch((error) => {
console.warn('Error fetching data', error);
});
}, },
updateBounds(bounds, isTick) { updateBounds(bounds, isTick) {
this.bounds = bounds; this.bounds = bounds;

View File

@ -73,8 +73,9 @@ export default {
hasUnits() { hasUnits() {
let itemsWithUnits = this.items.filter((item) => { let itemsWithUnits = this.items.filter((item) => {
let metadata = this.openmct.telemetry.getMetadata(item.domainObject); let metadata = this.openmct.telemetry.getMetadata(item.domainObject);
const valueMetadatas = metadata ? metadata.valueMetadatas : [];
return this.metadataHasUnits(metadata.valueMetadatas); return this.metadataHasUnits(valueMetadatas);
}); });

View File

@ -101,7 +101,7 @@ export default {
addChildren(domainObject) { addChildren(domainObject) {
let keyString = this.openmct.objects.makeKeyString(domainObject.identifier); let keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
let metadata = this.openmct.telemetry.getMetadata(domainObject); let metadata = this.openmct.telemetry.getMetadata(domainObject);
let metadataWithFilters = metadata.valueMetadatas.filter(value => value.filters); let metadataWithFilters = metadata ? metadata.valueMetadatas.filter(value => value.filters) : [];
let hasFiltersWithKeyString = this.persistedFilters[keyString] !== undefined; let hasFiltersWithKeyString = this.persistedFilters[keyString] !== undefined;
let mutateFilters = false; let mutateFilters = false;
let childObject = { let childObject = {

View File

@ -180,9 +180,13 @@ export default {
this.openmct.notifications.alert(message); this.openmct.notifications.alert(message);
} }
const relativeHash = hash.slice(hash.indexOf('#')); if (this.openmct.editor.isEditing()) {
const url = new URL(relativeHash, `${location.protocol}//${location.host}${location.pathname}`); this.previewEmbed();
this.openmct.router.navigate(url.hash); } else {
const relativeHash = hash.slice(hash.indexOf('#'));
const url = new URL(relativeHash, `${location.protocol}//${location.host}${location.pathname}`);
this.openmct.router.navigate(url.hash);
}
}, },
formatTime(unixTime, timeFormat) { formatTime(unixTime, timeFormat) {
return Moment.utc(unixTime).format(timeFormat); return Moment.utc(unixTime).format(timeFormat);

View File

@ -21,67 +21,57 @@
--> -->
<template> <template>
<div class="u-contents"> <div class="u-contents">
<ul v-if="canEdit" <div v-if="canEdit"
class="l-inspector-part" class="grid-row"
> >
<h2 v-if="heading" <div class="grid-cell label"
:title="heading" :title="editTitle"
>{{ heading }}</h2> >{{ shortLabel }}</div>
<li class="grid-row"> <div class="grid-cell value">
<div class="grid-cell label" <div class="c-click-swatch c-click-swatch--menu"
:title="editTitle" @click="toggleSwatch()"
>{{ shortLabel }}</div> >
<div class="grid-cell value"> <span class="c-color-swatch"
<div class="c-click-swatch c-click-swatch--menu" :style="{ background: currentColor }"
@click="toggleSwatch()"
> >
<span class="c-color-swatch" </span>
:style="{ background: currentColor }" </div>
<div class="c-palette c-palette--color">
<div v-show="swatchActive"
class="c-palette__items"
>
<div v-for="group in colorPaletteGroups"
:key="group.id"
class="u-contents"
> >
</span> <div v-for="color in group"
</div> :key="color.id"
<div class="c-palette c-palette--color"> class="c-palette__item"
<div v-show="swatchActive" :class="{ 'selected': currentColor === color.hexString }"
class="c-palette__items" :style="{ background: color.hexString }"
> @click="setColor(color)"
<div v-for="group in colorPaletteGroups"
:key="group.id"
class="u-contents"
> >
<div v-for="color in group"
:key="color.id"
class="c-palette__item"
:class="{ 'selected': currentColor === color.hexString }"
:style="{ background: color.hexString }"
@click="setColor(color)"
>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</li> </div>
</ul> </div>
<ul v-else <div v-else
class="l-inspector-part" class="grid-row"
> >
<h2 v-if="heading" <div class="grid-cell label"
:title="heading" :title="viewTitle"
>{{ heading }}</h2> >{{ shortLabel }}</div>
<li class="grid-row"> <div class="grid-cell value">
<div class="grid-cell label" <span class="c-color-swatch"
:title="viewTitle" :style="{
>{{ shortLabel }}</div> 'background': currentColor
<div class="grid-cell value"> }"
<span class="c-color-swatch" >
:style="{ </span>
'background': currentColor </div>
}" </div>
>
</span>
</div>
</li>
</ul>
</div> </div>
</template> </template>
@ -114,12 +104,6 @@ export default {
default() { default() {
return 'Color'; return 'Color';
} }
},
heading: {
type: String,
default() {
return '';
}
} }
}, },
data() { data() {

View File

@ -107,7 +107,7 @@ export default {
}; };
this.openmct.objects.mutate( this.openmct.objects.mutate(
this.domainObject, this.domainObject,
`configuration.barStyles[${this.key}]`, `configuration.barStyles[${key}]`,
this.domainObject.configuration.barStyles[key] this.domainObject.configuration.barStyles[key]
); );
} else { } else {
@ -150,6 +150,10 @@ export default {
}, },
getAxisMetadata(telemetryObject) { getAxisMetadata(telemetryObject) {
const metadata = this.openmct.telemetry.getMetadata(telemetryObject); const metadata = this.openmct.telemetry.getMetadata(telemetryObject);
if (!metadata) {
return {};
}
const yAxisMetadata = metadata.valuesForHints(['range'])[0]; const yAxisMetadata = metadata.valuesForHints(['range'])[0];
//Exclude 'name' and 'time' based metadata specifically, from the x-Axis values by using range hints only //Exclude 'name' and 'time' based metadata specifically, from the x-Axis values by using range hints only
const xAxisMetadata = metadata.valuesForHints(['range']); const xAxisMetadata = metadata.valuesForHints(['range']);
@ -255,6 +259,9 @@ export default {
data.forEach((datum) => { data.forEach((datum) => {
this.processData(telemetryObject, datum, axisMetadata); this.processData(telemetryObject, datum, axisMetadata);
}); });
})
.catch((error) => {
console.warn(`Error fetching data`, error);
}); });
}, },
subscribeToObject(telemetryObject) { subscribeToObject(telemetryObject) {

View File

@ -33,9 +33,9 @@
</li> </li>
<ColorSwatch v-if="expanded" <ColorSwatch v-if="expanded"
:current-color="currentColor" :current-color="currentColor"
title="Manually set the color for this bar graph." title="Manually set the color for this bar graph series."
edit-title="Manually set the color for this bar graph" edit-title="Manually set the color for this bar graph series"
view-title="The color for this bar graph." view-title="The color for this bar graph series."
short-label="Color" short-label="Color"
class="grid-properties" class="grid-properties"
@colorSet="setColor" @colorSet="setColor"

View File

@ -20,15 +20,13 @@
at runtime from the About dialog for additional information. at runtime from the About dialog for additional information.
--> -->
<template> <template>
<div> <ul class="c-tree">
<ul class="c-tree"> <h2 title="Display properties for this object">Bar Graph Series</h2>
<li v-for="series in domainObject.composition" <bar-graph-options v-for="series in domainObject.composition"
:key="series.key" :key="series.key"
> :item="series"
<bar-graph-options :item="series" /> />
</li> </ul>
</ul>
</div>
</template> </template>
<script> <script>

View File

@ -82,12 +82,17 @@ export default class PlotSeries extends Model {
.openmct .openmct
.telemetry .telemetry
.getMetadata(options.domainObject); .getMetadata(options.domainObject);
this.formats = options this.formats = options
.openmct .openmct
.telemetry .telemetry
.getFormatMap(this.metadata); .getFormatMap(this.metadata);
const range = this.metadata.valuesForHints(['range'])[0]; //if the object is missing or doesn't have metadata for some reason
let range = {};
if (this.metadata) {
range = this.metadata.valuesForHints(['range'])[0];
}
return { return {
name: options.domainObject.name, name: options.domainObject.name,
@ -191,7 +196,10 @@ export default class PlotSeries extends Model {
.uniq(true, point => [this.getXVal(point), this.getYVal(point)].join()) .uniq(true, point => [this.getXVal(point), this.getYVal(point)].join())
.value(); .value();
this.reset(newPoints); this.reset(newPoints);
}.bind(this)); }.bind(this))
.catch((error) => {
console.warn('Error fetching data', error);
});
/* eslint-enable you-dont-need-lodash-underscore/concat */ /* eslint-enable you-dont-need-lodash-underscore/concat */
} }
/** /**
@ -199,7 +207,9 @@ export default class PlotSeries extends Model {
*/ */
onXKeyChange(xKey) { onXKeyChange(xKey) {
const format = this.formats[xKey]; const format = this.formats[xKey];
this.getXVal = format.parse.bind(format); if (format) {
this.getXVal = format.parse.bind(format);
}
} }
/** /**
* Update y formatter on change, default to stepAfter interpolation if * Update y formatter on change, default to stepAfter interpolation if

View File

@ -184,7 +184,7 @@ export default class YAxisModel extends Model {
this.set('values', yMetadata.values); this.set('values', yMetadata.values);
if (!label) { if (!label) {
const labelName = series.map(function (s) { const labelName = series.map(function (s) {
return s.metadata.value(s.get('yKey')).name; return s.metadata ? s.metadata.value(s.get('yKey')).name : '';
}).reduce(function (a, b) { }).reduce(function (a, b) {
if (a === undefined) { if (a === undefined) {
return b; return b;
@ -204,7 +204,7 @@ export default class YAxisModel extends Model {
} }
const labelUnits = series.map(function (s) { const labelUnits = series.map(function (s) {
return s.metadata.value(s.get('yKey')).units; return s.metadata ? s.metadata.value(s.get('yKey')).units : '';
}).reduce(function (a, b) { }).reduce(function (a, b) {
if (a === undefined) { if (a === undefined) {
return b; return b;

View File

@ -60,18 +60,17 @@ define([
this.addTelemetryObject = this.addTelemetryObject.bind(this); this.addTelemetryObject = this.addTelemetryObject.bind(this);
this.removeTelemetryObject = this.removeTelemetryObject.bind(this); this.removeTelemetryObject = this.removeTelemetryObject.bind(this);
this.removeTelemetryCollection = this.removeTelemetryCollection.bind(this); this.removeTelemetryCollection = this.removeTelemetryCollection.bind(this);
this.incrementOutstandingRequests = this.incrementOutstandingRequests.bind(this);
this.decrementOutstandingRequests = this.decrementOutstandingRequests.bind(this);
this.resetRowsFromAllData = this.resetRowsFromAllData.bind(this); this.resetRowsFromAllData = this.resetRowsFromAllData.bind(this);
this.isTelemetryObject = this.isTelemetryObject.bind(this); this.isTelemetryObject = this.isTelemetryObject.bind(this);
this.refreshData = this.refreshData.bind(this);
this.updateFilters = this.updateFilters.bind(this); this.updateFilters = this.updateFilters.bind(this);
this.clearData = this.clearData.bind(this);
this.buildOptionsFromConfiguration = this.buildOptionsFromConfiguration.bind(this); this.buildOptionsFromConfiguration = this.buildOptionsFromConfiguration.bind(this);
this.filterObserver = undefined; this.filterObserver = undefined;
this.createTableRowCollections(); this.createTableRowCollections();
openmct.time.on('bounds', this.refreshData);
openmct.time.on('timeSystem', this.refreshData);
} }
/** /**
@ -141,8 +140,6 @@ define([
let columnMap = this.getColumnMapForObject(keyString); let columnMap = this.getColumnMapForObject(keyString);
let limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject); let limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject);
this.incrementOutstandingRequests();
const telemetryProcessor = this.getTelemetryProcessor(keyString, columnMap, limitEvaluator); const telemetryProcessor = this.getTelemetryProcessor(keyString, columnMap, limitEvaluator);
const telemetryRemover = this.getTelemetryRemover(); const telemetryRemover = this.getTelemetryRemover();
@ -151,13 +148,13 @@ define([
this.telemetryCollections[keyString] = this.openmct.telemetry this.telemetryCollections[keyString] = this.openmct.telemetry
.requestCollection(telemetryObject, requestOptions); .requestCollection(telemetryObject, requestOptions);
this.telemetryCollections[keyString].on('requestStarted', this.incrementOutstandingRequests);
this.telemetryCollections[keyString].on('requestEnded', this.decrementOutstandingRequests);
this.telemetryCollections[keyString].on('remove', telemetryRemover); this.telemetryCollections[keyString].on('remove', telemetryRemover);
this.telemetryCollections[keyString].on('add', telemetryProcessor); this.telemetryCollections[keyString].on('add', telemetryProcessor);
this.telemetryCollections[keyString].on('clear', this.tableRows.clear); this.telemetryCollections[keyString].on('clear', this.clearData);
this.telemetryCollections[keyString].load(); this.telemetryCollections[keyString].load();
this.decrementOutstandingRequests();
this.telemetryObjects[keyString] = { this.telemetryObjects[keyString] = {
telemetryObject, telemetryObject,
keyString, keyString,
@ -268,17 +265,6 @@ define([
this.emit('object-removed', objectIdentifier); this.emit('object-removed', objectIdentifier);
} }
refreshData(bounds, isTick) {
if (!isTick && this.tableRows.outstandingRequests === 0) {
this.tableRows.clear();
this.tableRows.sortBy({
key: this.openmct.time.timeSystem().key,
direction: 'asc'
});
this.tableRows.resubscribe();
}
}
clearData() { clearData() {
this.tableRows.clear(); this.tableRows.clear();
this.emit('refresh'); this.emit('refresh');
@ -378,9 +364,6 @@ define([
let keystrings = Object.keys(this.telemetryCollections); let keystrings = Object.keys(this.telemetryCollections);
keystrings.forEach(this.removeTelemetryCollection); keystrings.forEach(this.removeTelemetryCollection);
this.openmct.time.off('bounds', this.refreshData);
this.openmct.time.off('timeSystem', this.refreshData);
if (this.filterObserver) { if (this.filterObserver) {
this.filterObserver(); this.filterObserver();
} }

View File

@ -131,7 +131,8 @@ export default {
objects.forEach(object => this.addColumnsForObject(object, false)); objects.forEach(object => this.addColumnsForObject(object, false));
}, },
addColumnsForObject(telemetryObject) { addColumnsForObject(telemetryObject) {
let metadataValues = this.openmct.telemetry.getMetadata(telemetryObject).values(); const metadata = this.openmct.telemetry.getMetadata(telemetryObject);
let metadataValues = metadata ? metadata.values() : [];
metadataValues.forEach(metadatum => { metadataValues.forEach(metadatum => {
let column = new TelemetryTableColumn(this.openmct, metadatum); let column = new TelemetryTableColumn(this.openmct, metadatum);
this.tableConfiguration.addSingleColumnForObject(telemetryObject, column); this.tableConfiguration.addSingleColumnForObject(telemetryObject, column);

View File

@ -105,7 +105,8 @@ export default {
composition.load().then((domainObjects) => { composition.load().then((domainObjects) => {
domainObjects.forEach(telemetryObject => { domainObjects.forEach(telemetryObject => {
let keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier); let keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier);
let metadataValues = this.openmct.telemetry.getMetadata(telemetryObject).values(); const metadata = this.openmct.telemetry.getMetadata(telemetryObject);
let metadataValues = metadata ? metadata.values() : [];
let filters = this.filteredTelemetry[keyString]; let filters = this.filteredTelemetry[keyString];
if (filters !== undefined) { if (filters !== undefined) {

View File

@ -125,7 +125,6 @@
<div <div
class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar u-style-receiver js-style-receiver" class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar u-style-receiver js-style-receiver"
:class="{ :class="{
'loading': loading,
'is-paused' : paused 'is-paused' : paused
}" }"
> >
@ -362,7 +361,7 @@ export default {
autoScroll: true, autoScroll: true,
sortOptions: {}, sortOptions: {},
filters: {}, filters: {},
loading: true, loading: false,
scrollable: undefined, scrollable: undefined,
tableEl: undefined, tableEl: undefined,
headersHolderEl: undefined, headersHolderEl: undefined,
@ -422,6 +421,14 @@ export default {
} }
}, },
watch: { watch: {
loading: {
handler(isLoading) {
if (this.viewActionsCollection) {
let action = isLoading ? 'disable' : 'enable';
this.viewActionsCollection[action](['export-csv-all']);
}
}
},
markedRows: { markedRows: {
handler(newVal, oldVal) { handler(newVal, oldVal) {
this.$emit('marked-rows-updated', newVal, oldVal); this.$emit('marked-rows-updated', newVal, oldVal);
@ -1020,6 +1027,12 @@ export default {
this.viewActionsCollection.disable(['export-csv-marked', 'unmark-all-rows']); this.viewActionsCollection.disable(['export-csv-marked', 'unmark-all-rows']);
} }
if (this.loading) {
this.viewActionsCollection.disable(['export-csv-all']);
} else {
this.viewActionsCollection.enable(['export-csv-all']);
}
if (this.paused) { if (this.paused) {
this.viewActionsCollection.hide(['pause-data']); this.viewActionsCollection.hide(['pause-data']);
this.viewActionsCollection.show(['play-data']); this.viewActionsCollection.show(['play-data']);

View File

@ -151,29 +151,22 @@ export default {
this.stopFollowingTimeContext(); this.stopFollowingTimeContext();
this.timeContext = this.openmct.time.getContextForView([this.domainObject]); this.timeContext = this.openmct.time.getContextForView([this.domainObject]);
this.timeContext.on('timeContext', this.setTimeContext); this.timeContext.on('timeContext', this.setTimeContext);
this.timeContext.on('clock', this.setViewFromClock); this.timeContext.on('clock', this.setTimeOptions);
}, },
stopFollowingTimeContext() { stopFollowingTimeContext() {
if (this.timeContext) { if (this.timeContext) {
this.timeContext.off('timeContext', this.setTimeContext); this.timeContext.off('timeContext', this.setTimeContext);
this.timeContext.off('clock', this.setViewFromClock); this.timeContext.off('clock', this.setTimeOptions);
} }
}, },
setViewFromClock(clock) { setTimeOptions(clock) {
if (!this.timeOptions.mode) { this.timeOptions.clockOffsets = this.timeOptions.clockOffsets || this.timeContext.clockOffsets();
this.setTimeOptions(clock); this.timeOptions.fixedOffsets = this.timeOptions.fixedOffsets || this.timeContext.bounds();
}
},
setTimeOptions() {
if (!this.timeOptions || !this.timeOptions.mode) {
this.mode = this.timeContext.clock() === undefined ? { key: 'fixed' } : { key: Object.create(this.timeContext.clock()).key};
this.timeOptions = {
clockOffsets: this.timeContext.clockOffsets(),
fixedOffsets: this.timeContext.bounds()
};
}
this.registerIndependentTimeOffsets(); if (!this.timeOptions.mode) {
this.mode = this.timeContext.clock() === undefined ? {key: 'fixed'} : {key: Object.create(this.timeContext.clock()).key};
this.registerIndependentTimeOffsets();
}
}, },
saveFixedOffsets(offsets) { saveFixedOffsets(offsets) {
const newOptions = Object.assign({}, this.timeOptions, { const newOptions = Object.assign({}, this.timeOptions, {

View File

@ -20,7 +20,8 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
<template> <template>
<div ref="modeMenuButton" <div v-if="modes.length > 1"
ref="modeMenuButton"
class="c-ctrl-wrapper c-ctrl-wrapper--menus-up" class="c-ctrl-wrapper c-ctrl-wrapper--menus-up"
> >
<div class="c-menu-button c-ctrl-wrapper c-ctrl-wrapper--menus-left"> <div class="c-menu-button c-ctrl-wrapper c-ctrl-wrapper--menus-left">

View File

@ -160,7 +160,9 @@ export default {
this.status = this.openmct.status.get(this.domainObject.identifier); this.status = this.openmct.status.get(this.domainObject.identifier);
this.removeStatusListener = this.openmct.status.observe(this.domainObject.identifier, this.setStatus); this.removeStatusListener = this.openmct.status.observe(this.domainObject.identifier, this.setStatus);
const provider = this.openmct.objectViews.get(this.domainObject, this.objectPath)[0]; const provider = this.openmct.objectViews.get(this.domainObject, this.objectPath)[0];
this.$refs.objectView.show(this.domainObject, provider.key, false, this.objectPath); if (provider) {
this.$refs.objectView.show(this.domainObject, provider.key, false, this.objectPath);
}
}, },
beforeDestroy() { beforeDestroy() {
this.removeStatusListener(); this.removeStatusListener();
@ -193,8 +195,10 @@ export default {
}, },
showMenuItems(event) { showMenuItems(event) {
const sortedActions = this.openmct.actions._groupAndSortActions(this.menuActionItems); const sortedActions = this.openmct.actions._groupAndSortActions(this.menuActionItems);
const menuItems = this.openmct.menus.actionsToMenuItems(sortedActions, this.actionCollection.objectPath, this.actionCollection.view); if (sortedActions.length) {
this.openmct.menus.showMenu(event.x, event.y, menuItems); const menuItems = this.openmct.menus.actionsToMenuItems(sortedActions, this.actionCollection.objectPath, this.actionCollection.view);
this.openmct.menus.showMenu(event.x, event.y, menuItems);
}
}, },
setStatus(status) { setStatus(status) {
this.status = status; this.status = status;