mirror of
https://github.com/nasa/openmct.git
synced 2024-12-18 12:56:25 +00:00
Fix complex displays not loading (#7858)
Clock * pass in default timeContext in request options * observe for clock tick, instead of polling, to determine if clock has time set Progress Bars * use scale instead of move animation Plan * use a ResizeObserver instead of polling for size changes --------- Co-authored-by: Jesse Mazzella <jesse.d.mazzella@nasa.gov> Co-authored-by: Charles Hacskaylo <charlesh88@gmail.com> Co-authored-by: Charles Hacskaylo <charles.f.hacskaylo@nasa.gov> Co-authored-by: Andrew Henry <akhenry@gmail.com>
This commit is contained in:
parent
83e4a124e2
commit
4415fe7952
@ -231,26 +231,20 @@ export default class TelemetryAPI {
|
||||
* @returns {TelemetryRequestOptions} the options, with defaults filled in
|
||||
*/
|
||||
standardizeRequestOptions(options = {}) {
|
||||
if (!Object.hasOwn(options, 'start')) {
|
||||
const bounds = options.timeContext?.getBounds();
|
||||
if (bounds?.start) {
|
||||
options.start = options.timeContext.getBounds().start;
|
||||
} else {
|
||||
options.start = this.openmct.time.getBounds().start;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Object.hasOwn(options, 'end')) {
|
||||
const bounds = options.timeContext?.getBounds();
|
||||
if (bounds?.end) {
|
||||
options.end = options.timeContext.getBounds().end;
|
||||
} else {
|
||||
options.end = this.openmct.time.getBounds().end;
|
||||
}
|
||||
if (!Object.hasOwn(options, 'timeContext')) {
|
||||
options.timeContext = this.openmct.time;
|
||||
}
|
||||
|
||||
if (!Object.hasOwn(options, 'domain')) {
|
||||
options.domain = this.openmct.time.getTimeSystem().key;
|
||||
options.domain = options.timeContext.getTimeSystem().key;
|
||||
}
|
||||
|
||||
if (!Object.hasOwn(options, 'start')) {
|
||||
options.start = options.timeContext.getBounds().start;
|
||||
}
|
||||
|
||||
if (!Object.hasOwn(options, 'end')) {
|
||||
options.end = options.timeContext.getBounds().end;
|
||||
}
|
||||
|
||||
return options;
|
||||
|
@ -269,36 +269,40 @@ describe('Telemetry API', () => {
|
||||
|
||||
await telemetryAPI.request(domainObject);
|
||||
const { signal } = new AbortController();
|
||||
expect(telemetryProvider.supportsRequest).toHaveBeenCalledWith(jasmine.any(Object), {
|
||||
expect(telemetryProvider.supportsRequest).toHaveBeenCalledWith(domainObject, {
|
||||
signal,
|
||||
start: 0,
|
||||
end: 1,
|
||||
domain: 'system'
|
||||
domain: 'system',
|
||||
timeContext: openmct.time
|
||||
});
|
||||
|
||||
expect(telemetryProvider.request).toHaveBeenCalledWith(jasmine.any(Object), {
|
||||
expect(telemetryProvider.request).toHaveBeenCalledWith(domainObject, {
|
||||
signal,
|
||||
start: 0,
|
||||
end: 1,
|
||||
domain: 'system'
|
||||
domain: 'system',
|
||||
timeContext: openmct.time
|
||||
});
|
||||
|
||||
telemetryProvider.supportsRequest.calls.reset();
|
||||
telemetryProvider.request.calls.reset();
|
||||
|
||||
await telemetryAPI.request(domainObject, {});
|
||||
expect(telemetryProvider.supportsRequest).toHaveBeenCalledWith(jasmine.any(Object), {
|
||||
expect(telemetryProvider.supportsRequest).toHaveBeenCalledWith(domainObject, {
|
||||
signal,
|
||||
start: 0,
|
||||
end: 1,
|
||||
domain: 'system'
|
||||
domain: 'system',
|
||||
timeContext: openmct.time
|
||||
});
|
||||
|
||||
expect(telemetryProvider.request).toHaveBeenCalledWith(jasmine.any(Object), {
|
||||
expect(telemetryProvider.request).toHaveBeenCalledWith(domainObject, {
|
||||
signal,
|
||||
start: 0,
|
||||
end: 1,
|
||||
domain: 'system'
|
||||
domain: 'system',
|
||||
timeContext: openmct.time
|
||||
});
|
||||
});
|
||||
|
||||
@ -313,18 +317,20 @@ describe('Telemetry API', () => {
|
||||
domain: 'someDomain'
|
||||
});
|
||||
const { signal } = new AbortController();
|
||||
expect(telemetryProvider.supportsRequest).toHaveBeenCalledWith(jasmine.any(Object), {
|
||||
expect(telemetryProvider.supportsRequest).toHaveBeenCalledWith(domainObject, {
|
||||
start: 20,
|
||||
end: 30,
|
||||
domain: 'someDomain',
|
||||
signal
|
||||
signal,
|
||||
timeContext: openmct.time
|
||||
});
|
||||
|
||||
expect(telemetryProvider.request).toHaveBeenCalledWith(jasmine.any(Object), {
|
||||
expect(telemetryProvider.request).toHaveBeenCalledWith(domainObject, {
|
||||
start: 20,
|
||||
end: 30,
|
||||
domain: 'someDomain',
|
||||
signal
|
||||
signal,
|
||||
timeContext: openmct.time
|
||||
});
|
||||
});
|
||||
describe('telemetry batching support', () => {
|
||||
|
@ -62,9 +62,6 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
this.futureBuffer = [];
|
||||
this.parseTime = undefined;
|
||||
this.metadata = this.openmct.telemetry.getMetadata(domainObject);
|
||||
if (!Object.hasOwn(options, 'timeContext')) {
|
||||
options.timeContext = this.openmct.time;
|
||||
}
|
||||
this.options = options;
|
||||
this.unsubscribe = undefined;
|
||||
this.pageState = undefined;
|
||||
@ -84,6 +81,9 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
this._error(LOADED_ERROR);
|
||||
}
|
||||
|
||||
if (!Object.hasOwn(this.options, 'timeContext')) {
|
||||
this.options.timeContext = this.openmct.time;
|
||||
}
|
||||
this._setTimeSystem(this.options.timeContext.getTimeSystem());
|
||||
this.lastBounds = this.options.timeContext.getBounds();
|
||||
this._watchBounds();
|
||||
@ -127,7 +127,7 @@ export default class TelemetryCollection extends EventEmitter {
|
||||
* @private
|
||||
*/
|
||||
async _requestHistoricalTelemetry() {
|
||||
let options = this.openmct.telemetry.standardizeRequestOptions({ ...this.options });
|
||||
const options = this.openmct.telemetry.standardizeRequestOptions({ ...this.options });
|
||||
const historicalProvider = this.openmct.telemetry.findRequestProvider(
|
||||
this.domainObject,
|
||||
options
|
||||
|
@ -69,7 +69,6 @@ const INNER_TEXT_PADDING = 15;
|
||||
const TEXT_LEFT_PADDING = 5;
|
||||
const ROW_PADDING = 5;
|
||||
const SWIMLANE_PADDING = 3;
|
||||
const RESIZE_POLL_INTERVAL = 200;
|
||||
const ROW_HEIGHT = 22;
|
||||
const MAX_TEXT_WIDTH = 300;
|
||||
const MIN_ACTIVITY_WIDTH = 2;
|
||||
@ -143,13 +142,15 @@ export default {
|
||||
this.canvasContext = canvas.getContext('2d');
|
||||
this.setDimensions();
|
||||
this.setTimeContext();
|
||||
this.resizeTimer = setInterval(this.resize, RESIZE_POLL_INTERVAL);
|
||||
this.handleConfigurationChange(this.configuration);
|
||||
this.planViewConfiguration.on('change', this.handleConfigurationChange);
|
||||
this.loadComposition();
|
||||
|
||||
this.resizeObserver = new ResizeObserver(this.resize);
|
||||
this.resizeObserver.observe(this.$refs.plan);
|
||||
},
|
||||
beforeUnmount() {
|
||||
clearInterval(this.resizeTimer);
|
||||
this.resizeObserver.disconnect();
|
||||
this.stopFollowingTimeContext();
|
||||
if (this.unlisten) {
|
||||
this.unlisten();
|
||||
|
@ -152,15 +152,18 @@ export default class RemoteClock extends DefaultClock {
|
||||
*/
|
||||
#waitForReady() {
|
||||
const waitForInitialTick = (resolve) => {
|
||||
if (this.lastTick > 0) {
|
||||
const offsets = this.openmct.time.getClockOffsets();
|
||||
resolve({
|
||||
start: this.lastTick + offsets.start,
|
||||
end: this.lastTick + offsets.end
|
||||
});
|
||||
} else {
|
||||
setTimeout(() => waitForInitialTick(resolve), 100);
|
||||
}
|
||||
const tickListener = () => {
|
||||
if (this.lastTick > 0) {
|
||||
const offsets = this.openmct.time.getClockOffsets();
|
||||
this.openmct.time.off('tick', tickListener); // Unregister the tick listener
|
||||
resolve({
|
||||
start: this.lastTick + offsets.start,
|
||||
end: this.lastTick + offsets.end
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.openmct.time.on('tick', tickListener);
|
||||
};
|
||||
|
||||
return new Promise(waitForInitialTick);
|
||||
|
@ -20,16 +20,43 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Intercepts requests to ensure the remote clock is ready.
|
||||
*
|
||||
* @param {import('../../openmct').OpenMCT} openmct - The OpenMCT instance.
|
||||
* @param {import('../../openmct').Identifier} _remoteClockIdentifier - The identifier for the remote clock.
|
||||
* @param {Function} waitForBounds - A function that returns a promise resolving to the initial bounds.
|
||||
* @returns {Object} The request interceptor.
|
||||
*/
|
||||
function remoteClockRequestInterceptor(openmct, _remoteClockIdentifier, waitForBounds) {
|
||||
let remoteClockLoaded = false;
|
||||
|
||||
return {
|
||||
appliesTo: () => {
|
||||
/**
|
||||
* Determines if the interceptor applies to the given request.
|
||||
*
|
||||
* @param {Object} _ - Unused parameter.
|
||||
* @param {import('../../api/telemetry/TelemetryAPI').TelemetryRequestOptions} request - The request object.
|
||||
* @returns {boolean} True if the interceptor applies, false otherwise.
|
||||
*/
|
||||
appliesTo: (_, request) => {
|
||||
// Get the activeClock from the Global Time Context
|
||||
/** @type {import("../../api/time/TimeContext").default} */
|
||||
const { activeClock } = openmct.time;
|
||||
|
||||
// this type of request does not rely on clock having bounds
|
||||
if (request.strategy === 'latest' && request.timeContext.isRealTime()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return activeClock?.key === 'remote-clock' && !remoteClockLoaded;
|
||||
},
|
||||
/**
|
||||
* Invokes the interceptor to modify the request.
|
||||
*
|
||||
* @param {Object} request - The request object.
|
||||
* @returns {Promise<Object>} The modified request object.
|
||||
*/
|
||||
invoke: async (request) => {
|
||||
const timeContext = request?.timeContext ?? openmct.time;
|
||||
|
||||
|
@ -150,7 +150,7 @@ export default {
|
||||
mounted() {
|
||||
this.handleNewBounds = _.throttle(this.handleNewBounds, 300, {
|
||||
leading: true,
|
||||
trailing: false
|
||||
trailing: true
|
||||
});
|
||||
this.setTimeSystem(this.copy(this.openmct.time.getTimeSystem()));
|
||||
this.openmct.time.on(TIME_CONTEXT_EVENTS.timeSystemChanged, this.setTimeSystem);
|
||||
@ -181,6 +181,8 @@ export default {
|
||||
}
|
||||
},
|
||||
stopFollowingTime() {
|
||||
this.handleNewBounds.cancel();
|
||||
|
||||
if (this.timeContext) {
|
||||
this.timeContext.off(TIME_CONTEXT_EVENTS.boundsChanged, this.handleNewBounds);
|
||||
this.timeContext.off(TIME_CONTEXT_EVENTS.clockOffsetsChanged, this.setViewFromOffsets);
|
||||
|
@ -1,16 +1,13 @@
|
||||
/******************************************************** PROGRESS BAR */
|
||||
@keyframes progressIndeterminate {
|
||||
0% {
|
||||
left: 0;
|
||||
width: 0;
|
||||
transform:scaleX(0);
|
||||
}
|
||||
70% {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
90% {
|
||||
transform:scaleX(1);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
left: 100%;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@ -24,11 +21,10 @@
|
||||
|
||||
&__bar {
|
||||
background: $colorProgressBar;
|
||||
height: 100%;
|
||||
min-height: $progressBarMinH;
|
||||
transform-origin: left;
|
||||
|
||||
&.--indeterminate {
|
||||
position: absolute;
|
||||
@include abs();
|
||||
animation: progressIndeterminate 1.5s ease-in infinite;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user