Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Time] Conductors and API Enhancements #6768

Merged
merged 117 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from 102 commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
e86c741
Fixed #4975 - Compact Time Conductor styling
charlesh88 May 13, 2022
c61fa04
Fixes #4975 - Compact Time Conductor styling
charlesh88 May 14, 2022
3e7e9d5
Fixes #4975 - Compact Time Conductor styling
charlesh88 May 14, 2022
bc20d89
Fixes #4975 - Compact Time Conductor styling
charlesh88 May 17, 2022
26c592f
Fixes #4975 - Compact Time Conductor styling
charlesh88 May 17, 2022
5fa4898
Fixes #4975 - Compact Time Conductor styling
charlesh88 May 17, 2022
7247a42
Fixes #4975 - Compact Time Conductor styling
charlesh88 May 17, 2022
7f97441
Fixes #4975 - Compact Time Conductor styling
charlesh88 May 17, 2022
65801de
Fixes #4975 - Compact Time Conductor styling
charlesh88 May 17, 2022
5db595d
Fixes #4975 - Compact Time Conductor styling
charlesh88 May 18, 2022
e743e09
Fixes #4975 - Compact Time Conductor styling
charlesh88 May 18, 2022
b744594
Fixes #4975 - Compact Time Conductor styling
charlesh88 May 18, 2022
485ff91
Closes #4975
charlesh88 Apr 6, 2023
170686a
Initial work on getting the conductor popup working
shefalijoshi Apr 17, 2023
baf41fb
Ensure toggling between fixed timespan and clock modes works. Save cl…
shefalijoshi Apr 19, 2023
995a10b
Save fixed time bounds
shefalijoshi Apr 19, 2023
9d256ac
Ensure conductor history works when mode is switched. Submit and canc…
shefalijoshi Apr 20, 2023
db04cf1
Add independent time conductor popup logic
shefalijoshi Apr 21, 2023
36a0fe9
Independent time conductor popup draft
shefalijoshi Apr 24, 2023
3c86c43
object path for independent time conductor
shefalijoshi Apr 25, 2023
f1398cf
Ensure independent time conductor mode works as expected
shefalijoshi Apr 25, 2023
84882be
Ensure that clock changes are reflected downstream
shefalijoshi Apr 25, 2023
2bbe713
manually cherry picking over my changes to this existing branch
jvigliotta Apr 26, 2023
6f5e3d2
WIP
jvigliotta Apr 28, 2023
2179bc4
Stubs for the new Time API methods
shefalijoshi Apr 26, 2023
d847b26
WIP
jvigliotta May 2, 2023
668e88a
WIP
jvigliotta May 10, 2023
7578d33
various changes for setting modes and clocks, also updates to conduct…
jvigliotta May 10, 2023
05c0042
moved conductor popup into conductor instead of creating the componen…
jvigliotta May 10, 2023
b4454ad
WIP: lots of updates to methods and moving component creation from pr…
jvigliotta May 19, 2023
e4497f5
working on independent time conductor part
jvigliotta May 22, 2023
dbeb7c4
WIP
jvigliotta May 22, 2023
f1a89e0
realtime working on load
jvigliotta May 23, 2023
727eaa8
updated xAxis to new api, it was thrwoing many warnings for calling .…
jvigliotta May 23, 2023
d464ded
cleaning up some items
jvigliotta May 24, 2023
a24df42
using constants for events in the conductor components
jvigliotta May 24, 2023
5aca274
forgot one
jvigliotta May 24, 2023
546662a
itc work, moving mutating the domain object into itc so its in one place
jvigliotta May 24, 2023
0e9542c
cleanup
jvigliotta May 24, 2023
55342a0
various changes, but mainly changes to independent time context
jvigliotta May 24, 2023
2585c80
WIP
jvigliotta Jun 1, 2023
4a37475
stil WIP, but progress made on independent and regular conductor popu…
jvigliotta Jun 15, 2023
3923d02
WIP
jvigliotta Jun 20, 2023
6a45e2e
Shefali fixes! thanks!
jvigliotta Jun 26, 2023
62d14ed
prevent flash after appending conductor popup to body element
jvigliotta Jun 27, 2023
fdf405c
fixing buttons and when they hide
jvigliotta Jun 27, 2023
fc453ee
cleaning up
jvigliotta Jun 27, 2023
94c1cc6
more cleaning up
jvigliotta Jun 27, 2023
7169ca9
updating styles for popups that pop out
jvigliotta Jun 27, 2023
956c9a5
weird dupe event, maybe from toggle?
jvigliotta Jun 27, 2023
1e97049
small change
jvigliotta Jun 27, 2023
e16f4fc
refactor: format with prettier
jvigliotta Jun 28, 2023
2403228
merging prettier, fixing conflicts
jvigliotta Jun 28, 2023
e9f4793
adding read only mode, clock and timesystem to conductor and some cle…
jvigliotta Jun 29, 2023
7ed5b42
adding back a newline at end of file
jvigliotta Jun 29, 2023
903540d
updates related to stopping clocks
jvigliotta Jun 29, 2023
02c30c5
remvoing commented code
jvigliotta Jun 29, 2023
e9f806e
some pre pr review review changes
jvigliotta Jun 29, 2023
959b4ee
lint fixes
jvigliotta Jun 29, 2023
2762f5d
fixed panning and zooming styles as well as the ability to pan and zo…
jvigliotta Jul 11, 2023
c55f27e
making sure mode is respected in conductor and emitting new bounds ev…
jvigliotta Jul 11, 2023
b909207
fix typo
jvigliotta Jul 11, 2023
6edbb67
Fixes instances of the old Time API being called
shefalijoshi Jul 11, 2023
c8595ee
Merge branch 'mode-dropdown' of https://github.com/nasa/openmct into …
jvigliotta Jul 11, 2023
80cae84
WIP
jvigliotta Jul 11, 2023
0947794
separate mode and clock mixin, constants in url time sync, reactive c…
jvigliotta Jul 11, 2023
fa5de7c
typo fix and removing unused vars
jvigliotta Jul 11, 2023
b8ab9a6
remove console log, revert incorrect logic in url time sync
jvigliotta Jul 11, 2023
1d72a15
removing older code, more descerning object frame in regard to itc
jvigliotta Jul 11, 2023
2c7b27d
Merge branch 'master' into mode-dropdown
jvigliotta Jul 12, 2023
22fb33b
Closes #4975
charlesh88 Jul 12, 2023
045b6fd
Merge branch 'mode-dropdown' of github.com:nasa/openmct into mode-dro…
charlesh88 Jul 12, 2023
ee8bc16
handling clock updates when in fixed mode
jvigliotta Jul 12, 2023
dac4c52
Merge branch 'mode-dropdown' of https://github.com/nasa/openmct into …
jvigliotta Jul 12, 2023
f90f6d6
Closes #4975
charlesh88 Jul 12, 2023
39a3b49
Merge branch 'mode-dropdown' of github.com:nasa/openmct into mode-dro…
charlesh88 Jul 12, 2023
bef67c8
Closes #4975
charlesh88 Jul 13, 2023
be793dc
Closes #4975
charlesh88 Jul 13, 2023
b5a8a2b
Closes #4975
charlesh88 Jul 13, 2023
e8926da
Closes #4975
charlesh88 Jul 13, 2023
43602d9
fixed positioning of popup if window is resized to prevent "jumping",…
jvigliotta Jul 13, 2023
40e53e0
Closes #4975
charlesh88 Jul 13, 2023
4e788f7
Merge branch 'mode-dropdown' of github.com:nasa/openmct into mode-dro…
charlesh88 Jul 13, 2023
4d28763
Closes #4975
charlesh88 Jul 13, 2023
3cb2fef
pretty substantial rewrite of conductor history
jvigliotta Jul 14, 2023
9404384
Closes #4975
charlesh88 Jul 14, 2023
ca0d411
Merge remote-tracking branch 'origin/mode-dropdown' into mode-dropdown
charlesh88 Jul 14, 2023
1de96e6
Merge branch 'master' into mode-dropdown
jvigliotta Jul 14, 2023
6d1b2ef
updating setters
jvigliotta Jul 14, 2023
a17566c
Merge branch 'master' into mode-dropdown
jvigliotta Jul 14, 2023
47dce7b
Merge branch 'master' into mode-dropdown
akhenry Jul 14, 2023
db33539
somehow forgot to be backwards compatible
jvigliotta Jul 14, 2023
0a2de2a
[Global Clock] Clock, Clock Indicator, Timer and Notebook entries (#6…
jvigliotta Jul 14, 2023
60c260d
Merge branch 'master' into mode-dropdown
jvigliotta Jul 14, 2023
0f2b73e
fixing tests for new clock functionality
jvigliotta Jul 15, 2023
ed8b75d
Merge branch 'master' of https://github.com/nasa/openmct into mode-dr…
shefalijoshi Jul 15, 2023
6adc14e
fixing time api spec tests
jvigliotta Jul 15, 2023
c1ee1e0
Merge branch 'mode-dropdown' of https://github.com/nasa/openmct into …
shefalijoshi Jul 15, 2023
19d5bb0
Merge branch 'master' into mode-dropdown
jvigliotta Jul 15, 2023
f898aa3
Uncomment test and add missing events
shefalijoshi Jul 15, 2023
1eb2810
Merge branch 'mode-dropdown' of https://github.com/nasa/openmct into …
shefalijoshi Jul 15, 2023
df6a3e4
imagery to use new time.now
jvigliotta Jul 15, 2023
d9c8a78
Merge branch 'master' into mode-dropdown
unlikelyzero Jul 17, 2023
7fa554b
Mode dropdown clock bounds fix (#6804)
shefalijoshi Jul 17, 2023
249f820
ImageryView 🖼️ + IndependentTimeConductor ⏰ (#6791)
scottbell Jul 17, 2023
da1ae38
Fix tests
shefalijoshi Jul 18, 2023
5de350e
Fix URLTimeSynchronizer takeovers
shefalijoshi Jul 18, 2023
5ce7754
Fix urlSpec test
shefalijoshi Jul 18, 2023
ae364e2
Disable a few unit tests. TODO fixes later.
shefalijoshi Jul 18, 2023
78c0f83
Fix timeConductor test
shefalijoshi Jul 18, 2023
7645dc9
Fix timelist tests
shefalijoshi Jul 18, 2023
46ac06f
Fix linting issues
shefalijoshi Jul 18, 2023
871b13f
comment out flaky tests
shefalijoshi Jul 18, 2023
b33a523
Fix some e2e tests
shefalijoshi Jul 18, 2023
043233f
Default local clock (#6807)
jvigliotta Jul 18, 2023
0a86d1d
Don't set bounds if not provided
shefalijoshi Jul 19, 2023
abda0b4
Add deprecation warning back
shefalijoshi Jul 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**

- [Building Applications With Open MCT](#developing-applications-with-open-mct)
- [Developing Applications With Open MCT](#developing-applications-with-open-mct)
- [Scope and purpose of this document](#scope-and-purpose-of-this-document)
- [Building From Source](#building-from-source)
- [Starting an Open MCT application](#starting-an-open-mct-application)
Expand All @@ -26,7 +26,7 @@
- [Value Hints](#value-hints)
- [The Time Conductor and Telemetry](#the-time-conductor-and-telemetry)
- [Telemetry Providers](#telemetry-providers)
- [Telemetry Requests and Responses.](#telemetry-requests-and-responses)
- [Telemetry Requests and Responses](#telemetry-requests-and-responses)
- [Request Strategies **draft**](#request-strategies-draft)
- [`latest` request strategy](#latest-request-strategy)
- [`minmax` request strategy](#minmax-request-strategy)
Expand Down Expand Up @@ -873,6 +873,8 @@ function without any arguments.

#### Stopping an active clock

_As of July 2023, this method will be deprecated. Open MCT will always have a ticking clock._

The `stopClock` method can be used to stop an active clock, and to clear it. It
will stop the clock from ticking, and set the active clock to `undefined`.

Expand Down
18 changes: 9 additions & 9 deletions example/imagery/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ export default function () {
key: 'thumbnail',
...formatThumbnail
});
openmct.telemetry.addProvider(getRealtimeProvider());
openmct.telemetry.addProvider(getHistoricalProvider());
openmct.telemetry.addProvider(getLadProvider());
openmct.telemetry.addProvider(getRealtimeProvider(openmct));
openmct.telemetry.addProvider(getHistoricalProvider(openmct));
openmct.telemetry.addProvider(getLadProvider(openmct));
};
}

Expand Down Expand Up @@ -207,14 +207,14 @@ function getImageLoadDelay(domainObject) {
return imageLoadDelay;
}

function getRealtimeProvider() {
function getRealtimeProvider(openmct) {
return {
supportsSubscribe: (domainObject) => domainObject.type === 'example.imagery',
subscribe: (domainObject, callback) => {
const delay = getImageLoadDelay(domainObject);
const interval = setInterval(() => {
const imageSamples = getImageSamples(domainObject.configuration);
const datum = pointForTimestamp(Date.now(), domainObject.name, imageSamples, delay);
const datum = pointForTimestamp(openmct.time.now(), domainObject.name, imageSamples, delay);
callback(datum);
}, delay);

Expand All @@ -225,15 +225,15 @@ function getRealtimeProvider() {
};
}

function getHistoricalProvider() {
function getHistoricalProvider(openmct) {
return {
supportsRequest: (domainObject, options) => {
return domainObject.type === 'example.imagery' && options.strategy !== 'latest';
},
request: (domainObject, options) => {
const delay = getImageLoadDelay(domainObject);
let start = options.start;
const end = Math.min(options.end, Date.now());
const end = Math.min(options.end, openmct.time.now());
const data = [];
while (start <= end && data.length < delay) {
data.push(
Expand All @@ -252,15 +252,15 @@ function getHistoricalProvider() {
};
}

function getLadProvider() {
function getLadProvider(openmct) {
return {
supportsRequest: (domainObject, options) => {
return domainObject.type === 'example.imagery' && options.strategy === 'latest';
},
request: (domainObject, options) => {
const delay = getImageLoadDelay(domainObject);
const datum = pointForTimestamp(
Date.now(),
openmct.time.now(),
domainObject.name,
getImageSamples(domainObject.configuration),
delay
Expand Down
1 change: 0 additions & 1 deletion src/api/menu/components/SuperMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
:key="action.name"
role="menuitem"
:class="action.cssClass"
:title="action.description"
:data-testid="action.testId || false"
@click="action.onItemClicked"
@mouseover="toggleItemDescription(action)"
Expand Down
178 changes: 166 additions & 12 deletions src/api/time/IndependentTimeContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/

import TimeContext, { TIME_CONTEXT_EVENTS } from './TimeContext';
import TimeContext from './TimeContext';
import { REALTIME_MODE_KEY, TIME_CONTEXT_EVENTS } from './constants';

/**
* The IndependentTimeContext handles getting and setting time of the openmct application in general.
Expand All @@ -46,35 +47,59 @@ class IndependentTimeContext extends TimeContext {
this.globalTimeContext.on('removeOwnContext', this.removeIndependentContext);
}

bounds(newBounds) {
bounds() {
if (this.upstreamTimeContext) {
return this.upstreamTimeContext.bounds(...arguments);
} else {
return super.bounds(...arguments);
}
}

tick(timestamp) {
getBounds() {
if (this.upstreamTimeContext) {
return this.upstreamTimeContext.getBounds();
} else {
return super.getBounds();
}
}

setBounds() {
if (this.upstreamTimeContext) {
return this.upstreamTimeContext.setBounds(...arguments);
} else {
return super.setBounds(...arguments);
}
}

tick() {
if (this.upstreamTimeContext) {
return this.upstreamTimeContext.tick(...arguments);
} else {
return super.tick(...arguments);
}
}

clockOffsets(offsets) {
clockOffsets() {
if (this.upstreamTimeContext) {
return this.upstreamTimeContext.clockOffsets(...arguments);
} else {
return super.clockOffsets(...arguments);
}
}

stopClock() {
getClockOffsets() {
if (this.upstreamTimeContext) {
this.upstreamTimeContext.stopClock();
return this.upstreamTimeContext.getClockOffsets();
} else {
super.stopClock();
return super.getClockOffsets();
}
}

setClockOffsets() {
if (this.upstreamTimeContext) {
return this.upstreamTimeContext.setClockOffsets(...arguments);
} else {
return super.setClockOffsets(...arguments);
}
}

Expand All @@ -86,10 +111,19 @@ class IndependentTimeContext extends TimeContext {
return this.globalTimeContext.timeSystem(...arguments);
}

/**
* Get the time system of the TimeAPI.
* @returns {TimeSystem} The currently applied time system
* @memberof module:openmct.TimeAPI#
* @method getTimeSystem
*/
getTimeSystem() {
return this.globalTimeContext.getTimeSystem();
}

/**
* Set the active clock. Tick source will be immediately subscribed to
* and ticking will begin. Offsets from 'now' must also be provided. A clock
* can be unset by calling {@link stopClock}.
* and ticking will begin. Offsets from 'now' must also be provided.
*
* @param {Clock || string} keyOrClock The clock to activate, or its key
* @param {ClockOffsets} offsets on each tick these will be used to calculate
Expand Down Expand Up @@ -126,15 +160,18 @@ class IndependentTimeContext extends TimeContext {
this.activeClock = clock;

/**
* The active clock has changed. Clock can be unset by calling {@link stopClock}
* The active clock has changed.
* @event clock
* @memberof module:openmct.TimeAPI~
* @property {Clock} clock The newly activated clock, or undefined
* if the system is no longer following a clock source
*/
this.emit('clock', this.activeClock);
this.emit(TIME_CONTEXT_EVENTS.clockChanged, this.activeClock);

if (this.activeClock !== undefined) {
this.setMode(REALTIME_MODE_KEY);

this.clockOffsets(offsets);
this.activeClock.on('tick', this.tick);
}
Expand All @@ -145,14 +182,125 @@ class IndependentTimeContext extends TimeContext {
return this.activeClock;
}

/**
* Get the active clock.
* @return {Clock} the currently active clock;
*/
getClock() {
if (this.upstreamTimeContext) {
return this.upstreamTimeContext.getClock();
}

return this.activeClock;
}

/**
* Set the active clock. Tick source will be immediately subscribed to
* and the currently ticking will begin.
* Offsets from 'now', if provided, will be used to set realtime mode offsets
*
* @param {Clock || string} keyOrClock The clock to activate, or its key
* @param {ClockOffsets} offsets on each tick these will be used to calculate
* the start and end bounds when in realtime mode.
* This maintains a sliding time window of a fixed width that automatically updates.
* @fires module:openmct.TimeAPI~clock
* @return {Clock} the currently active clock;
*/
setClock(keyOrClock, offsets) {
if (this.upstreamTimeContext) {
return this.upstreamTimeContext.setClock(...arguments);
}

let clock;

if (typeof keyOrClock === 'string') {
clock = this.globalTimeContext.clocks.get(keyOrClock);
if (clock === undefined) {
throw `Unknown clock ${keyOrClock}. Has it been registered with 'addClock'?`;
}
} else if (typeof keyOrClock === 'object') {
clock = keyOrClock;
if (!this.globalTimeContext.clocks.has(clock.key)) {
throw `Unknown clock ${keyOrClock.key}. Has it been registered with 'addClock'?`;
}
}

// this.setMode(REALTIME_MODE_KEY);

const previousClock = this.activeClock;
if (previousClock) {
previousClock.off('tick', this.tick);
}

this.activeClock = clock;
this.activeClock.on('tick', this.tick);

/**
* The active clock has changed.
* @event clock
* @memberof module:openmct.TimeAPI~
* @property {Clock} clock The newly activated clock, or undefined
* if the system is no longer following a clock source
*/
this.emit(TIME_CONTEXT_EVENTS.clockChanged, this.activeClock);

if (offsets !== undefined) {
this.setClockOffsets(offsets);
}

return this.activeClock;
}

/**
* Get the current mode.
* @return {Mode} the current mode;
*/
getMode() {
if (this.upstreamTimeContext) {
return this.upstreamTimeContext.getMode();
}

return this.mode;
}

/**
* Set the mode to either fixed or realtime.
*
* @param {Mode} mode The mode to activate
* @fires module:openmct.TimeAPI~clock
* @return {Mode} the currently active mode;
*/
setMode(mode) {
if (!mode || mode === this.mode) {
return;
}

if (this.upstreamTimeContext) {
return this.upstreamTimeContext.setMode(...arguments);
}

this.mode = mode;

/**
* The active clock has changed.
* @event clock
* @memberof module:openmct.TimeAPI~
* @property {Clock} clock The newly activated clock, or undefined
* if the system is no longer following a clock source
*/
this.emit(TIME_CONTEXT_EVENTS.modeChanged, this.#copy(this.mode));

return this.mode;
}

/**
* Causes this time context to follow another time context (either the global context, or another upstream time context)
* This allows views to have their own time context which points to the appropriate upstream context as necessary, achieving nesting.
*/
followTimeContext() {
this.stopFollowingTimeContext();
if (this.upstreamTimeContext) {
TIME_CONTEXT_EVENTS.forEach((eventName) => {
Object.values(TIME_CONTEXT_EVENTS).forEach((eventName) => {
const thisTimeContext = this;
this.upstreamTimeContext.on(eventName, passthrough);
this.unlisteners.push(() => {
Expand Down Expand Up @@ -197,6 +345,7 @@ class IndependentTimeContext extends TimeContext {

// Emit bounds so that views that are changing context get the upstream bounds
this.emit('bounds', this.bounds());
this.emit(TIME_CONTEXT_EVENTS.boundsChanged, this.getBounds());
}

hasOwnContext() {
Expand Down Expand Up @@ -259,11 +408,16 @@ class IndependentTimeContext extends TimeContext {
this.followTimeContext();

// Emit bounds so that views that are changing context get the upstream bounds
this.emit('bounds', this.bounds());
this.emit('bounds', this.getBounds());
this.emit(TIME_CONTEXT_EVENTS.boundsChanged, this.getBounds());
// now that the view's context is set, tell others to check theirs in case they were following this view's context.
this.globalTimeContext.emit('refreshContext', viewKey);
}
}

#copy(object) {
return JSON.parse(JSON.stringify(object));
}
}

export default IndependentTimeContext;
Loading