Skip to content

Commit

Permalink
Refine display options and add Independent Time Conductor option for …
Browse files Browse the repository at this point in the history
…Time List view (#7161)

* Apply sort settings immediately - even when in edit mode.

* Adds test for sort order

* Enable independent time conductor for time list view

* Remove time frame duration options.

* Remove immediate sorting in edit mode.

* Closes #7113
- Color of current events changed to bring more in-line with color conventions.
- Changed Time List rgba colors to solids.
- Removed bolding on current events text.

* Fix tests to include new changes

---------

Co-authored-by: Charles Hacskaylo <[email protected]>
  • Loading branch information
shefalijoshi and charlesh88 authored Nov 1, 2023
1 parent a0fd1f0 commit ae22920
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 166 deletions.
125 changes: 35 additions & 90 deletions src/plugins/timelist/TimelistComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ export default {
},
mounted() {
this.isEditing = this.openmct.editor.isEditing();
this.timestamp = this.openmct.time.now();
this.openmct.time.on(TIME_CONTEXT_EVENTS.modeChanged, this.setFixedTime);
this.updateTimestamp = _.throttle(this.updateTimestamp, 1000);

this.setTimeContext();
this.timestamp = this.timeContext.now();

this.getPlanDataAndSetConfig(this.domainObject);

Expand All @@ -137,8 +139,6 @@ export default {
);
this.status = this.openmct.status.get(this.domainObject.identifier);

this.updateTimestamp = _.throttle(this.updateTimestamp, 1000);
this.openmct.time.on('tick', this.updateTimestamp);
this.openmct.editor.on('isEditing', this.setEditState);

this.deferAutoScroll = _.debounce(this.deferAutoScroll, 500);
Expand All @@ -150,7 +150,7 @@ export default {
this.composition.load();
}

this.setFixedTime(this.openmct.time.getMode());
this.setFixedTime(this.timeContext.getMode());
},
beforeUnmount() {
if (this.unlisten) {
Expand All @@ -166,8 +166,7 @@ export default {
}

this.openmct.editor.off('isEditing', this.setEditState);
this.openmct.time.off('tick', this.updateTimestamp);
this.openmct.time.off(TIME_CONTEXT_EVENTS.modeChanged, this.setFixedTime);
this.stopFollowingTimeContext();

this.$el.parentElement?.removeEventListener('scroll', this.deferAutoScroll, true);
if (this.clearAutoScrollDisabledTimer) {
Expand All @@ -180,6 +179,21 @@ export default {
}
},
methods: {
setTimeContext() {
this.stopFollowingTimeContext();
this.timeContext = this.openmct.time.getContextForView(this.path);
this.followTimeContext();
},
followTimeContext() {
this.timeContext.on(TIME_CONTEXT_EVENTS.modeChanged, this.setFixedTime);
this.timeContext.on(TIME_CONTEXT_EVENTS.tick, this.updateTimestamp);
},
stopFollowingTimeContext() {
if (this.timeContext) {
this.timeContext.off(TIME_CONTEXT_EVENTS.modeChanged, this.setFixedTime);
this.timeContext.off(TIME_CONTEXT_EVENTS.tick, this.updateTimestamp);
}
},
planFileUpdated(selectFile) {
this.getPlanData({
selectFile,
Expand All @@ -198,7 +212,6 @@ export default {
} else {
this.filterValue = configuration.filter;
this.setSort();
this.setViewBounds();
this.listActivities();
}
},
Expand All @@ -208,7 +221,7 @@ export default {
},
setFixedTime() {
this.filterValue = this.domainObject.configuration.filter;
this.isFixedTime = !this.openmct.time.isRealTime();
this.isFixedTime = !this.timeContext.isRealTime();
if (this.isFixedTime) {
this.hideAll = false;
}
Expand Down Expand Up @@ -269,71 +282,6 @@ export default {
getPlanData(domainObject) {
this.planData = getValidatedData(domainObject);
},
setViewBounds() {
const pastEventsIndex = this.domainObject.configuration.pastEventsIndex;
const currentEventsIndex = this.domainObject.configuration.currentEventsIndex;
const futureEventsIndex = this.domainObject.configuration.futureEventsIndex;
const pastEventsDuration = this.domainObject.configuration.pastEventsDuration;
const pastEventsDurationIndex = this.domainObject.configuration.pastEventsDurationIndex;
const futureEventsDuration = this.domainObject.configuration.futureEventsDuration;
const futureEventsDurationIndex = this.domainObject.configuration.futureEventsDurationIndex;

if (pastEventsIndex === 0 && futureEventsIndex === 0 && currentEventsIndex === 0) {
this.viewBounds = undefined;
this.hideAll = true;

return;
}

this.hideAll = false;

if (pastEventsIndex === 1 && futureEventsIndex === 1 && currentEventsIndex === 1) {
this.viewBounds = undefined;

return;
}

this.viewBounds = {};

if (pastEventsIndex !== 1) {
const pastDurationInMS = this.getDurationInMilliSeconds(
pastEventsDuration,
pastEventsDurationIndex
);
this.viewBounds.pastEnd = (timestamp) => {
if (pastEventsIndex === 2) {
return timestamp - pastDurationInMS;
} else if (pastEventsIndex === 0) {
return timestamp + 1;
}
};
}

if (futureEventsIndex !== 1) {
const futureDurationInMS = this.getDurationInMilliSeconds(
futureEventsDuration,
futureEventsDurationIndex
);
this.viewBounds.futureStart = (timestamp) => {
if (futureEventsIndex === 2) {
return timestamp + futureDurationInMS;
} else if (futureEventsIndex === 0) {
return 0;
}
};
}
},
getDurationInMilliSeconds(duration, durationIndex) {
if (duration > 0) {
if (durationIndex === 0) {
return duration * 1000;
} else if (durationIndex === 1) {
return duration * 60 * 1000;
} else if (durationIndex === 2) {
return duration * 60 * 60 * 1000;
}
}
},
listActivities() {
let groups = Object.keys(this.planData);
let activities = [];
Expand All @@ -356,18 +304,18 @@ export default {
},
isActivityInBounds(activity) {
const startInBounds =
activity.start >= this.openmct.time.bounds()?.start &&
activity.start <= this.openmct.time.bounds()?.end;
activity.start >= this.timeContext.bounds()?.start &&
activity.start <= this.timeContext.bounds()?.end;
const endInBounds =
activity.end >= this.openmct.time.bounds()?.start &&
activity.end <= this.openmct.time.bounds()?.end;
activity.end >= this.timeContext.bounds()?.start &&
activity.end <= this.timeContext.bounds()?.end;
const middleInBounds =
activity.start <= this.openmct.time.bounds()?.start &&
activity.end >= this.openmct.time.bounds()?.end;
activity.start <= this.timeContext.bounds()?.start &&
activity.end >= this.timeContext.bounds()?.end;

return startInBounds || endInBounds || middleInBounds;
},
filterActivities(activity, index) {
filterActivities(activity) {
if (this.isEditing) {
return true;
}
Expand All @@ -381,15 +329,12 @@ export default {
return false;
}
//current event or future start event or past end event
const isCurrent = this.timestamp >= activity.start && this.timestamp <= activity.end;
const isPast =
this.timestamp > activity.end &&
(this.viewBounds?.pastEnd === undefined ||
activity.end >= this.viewBounds?.pastEnd(this.timestamp));
const isFuture =
this.timestamp < activity.start &&
(this.viewBounds?.futureStart === undefined ||
activity.start <= this.viewBounds?.futureStart(this.timestamp));
const showCurrentEvents = this.domainObject.configuration.currentEventsIndex > 0;

const isCurrent =
showCurrentEvents && this.timestamp >= activity.start && this.timestamp <= activity.end;
const isPast = this.timestamp > activity.end;
const isFuture = this.timestamp < activity.start;

return isCurrent || isPast || isFuture;
},
Expand Down
28 changes: 3 additions & 25 deletions src/plugins/timelist/inspector/EventProperties.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,34 +32,15 @@
{{ activityOption }}
</option>
</select>
<input
v-if="index === 2"
v-model="duration"
class="c-input c-input--sm"
type="text"
@change="updateForm('duration')"
/>
<select v-if="index === 2" v-model="durationIndex" @change="updateForm('durationIndex')">
<option
v-for="(durationOption, durationKey) in durationOptions"
:key="durationKey"
:value="durationKey"
>
{{ durationOption }}
</option>
</select>
</div>
<div v-else class="c-inspect-properties__value">
{{ activitiesOptions[index] }}
<span v-if="index > 1">{{ duration }} {{ durationOptions[durationIndex] }}</span>
</div>
</li>
</template>

<script>
const ACTIVITIES_OPTIONS = ["Don't show", 'Show all', 'Show starts within', 'Show after end for'];

const DURATION_OPTIONS = ['seconds', 'minutes', 'hours'];
const ACTIVITIES_OPTIONS = ["Don't show", 'Show all'];

export default {
inject: ['openmct', 'domainObject'],
Expand All @@ -76,11 +57,8 @@ export default {
emits: ['updated'],
data() {
return {
index: this.domainObject.configuration[`${this.prefix}Index`],
durationIndex: this.domainObject.configuration[`${this.prefix}DurationIndex`],
duration: this.domainObject.configuration[`${this.prefix}Duration`],
index: this.domainObject.configuration[`${this.prefix}Index`] % 2, //this is modulo since we previously had more options and index could have been > 1
activitiesOptions: ACTIVITIES_OPTIONS,
durationOptions: DURATION_OPTIONS,
isEditing: this.openmct.editor.isEditing()
};
},
Expand Down Expand Up @@ -116,7 +94,7 @@ export default {
});
},
isValid() {
return this.index < 2 || (this.durationIndex >= 0 && this.duration > 0);
return this.index <= 1;
},
setEditState(isEditing) {
this.isEditing = isEditing;
Expand Down
10 changes: 1 addition & 9 deletions src/plugins/timelist/inspector/TimelistPropertiesView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<div class="c-timelist-properties">
<div class="c-inspect-properties">
<ul class="c-inspect-properties__section">
<div class="c-inspect-properties_header" title="'Timeframe options'">Timeframe</div>
<div class="c-inspect-properties_header" title="'Display options'">Display Options</div>
<li class="c-inspect-properties__row">
<div v-if="canEdit" class="c-inspect-properties__hint span-all">
These settings don't affect the view while editing, but will be applied after editing is
Expand Down Expand Up @@ -72,17 +72,9 @@ import EventProperties from './EventProperties.vue';
import Filtering from './FilteringComponent.vue';

const EVENT_TYPES = [
{
label: 'Future Events',
prefix: 'futureEvents'
},
{
label: 'Current Events',
prefix: 'currentEvents'
},
{
label: 'Past Events',
prefix: 'pastEvents'
}
];

Expand Down
54 changes: 39 additions & 15 deletions src/plugins/timelist/pluginSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe('the plugin', function () {
let twoHoursPast = now - 1000 * 60 * 60 * 2;
let oneHourPast = now - 1000 * 60 * 60;
let twoHoursFuture = now + 1000 * 60 * 60 * 2;
let threeHoursFuture = now + 1000 * 60 * 60 * 3;
let planObject = {
identifier: {
key: 'test-plan-object',
Expand All @@ -71,6 +72,14 @@ describe('the plugin', function () {
type: 'TEST-GROUP',
color: 'fuchsia',
textColor: 'black'
},
{
name: 'Sed ut perspiciatis two',
start: now,
end: threeHoursFuture,
type: 'TEST-GROUP',
color: 'fuchsia',
textColor: 'black'
}
]
})
Expand All @@ -85,13 +94,13 @@ describe('the plugin', function () {
openmct = createOpenMct({
timeSystemKey: 'utc',
bounds: {
start: twoHoursPast,
end: twoHoursFuture
start: twoHoursFuture,
end: threeHoursFuture
}
});
openmct.time.setMode(FIXED_MODE_KEY, {
start: twoHoursPast,
end: twoHoursFuture
start: twoHoursFuture,
end: threeHoursFuture
});
openmct.install(new TimelistPlugin());

Expand Down Expand Up @@ -215,7 +224,7 @@ describe('the plugin', function () {

it('displays the activities', () => {
const items = element.querySelectorAll(LIST_ITEM_CLASS);
expect(items.length).toEqual(2);
expect(items.length).toEqual(1);
});

it('displays the activity headers', () => {
Expand All @@ -230,14 +239,10 @@ describe('the plugin', function () {
const itemEls = element.querySelectorAll(LIST_ITEM_CLASS);
const itemValues = itemEls[0].querySelectorAll(LIST_ITEM_VALUE_CLASS);
expect(itemValues.length).toEqual(4);
expect(itemValues[3].innerHTML.trim()).toEqual(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua'
);
expect(itemValues[0].innerHTML.trim()).toEqual(
timeFormatter.format(twoHoursPast, TIME_FORMAT)
);
expect(itemValues[3].innerHTML.trim()).toEqual('Sed ut perspiciatis');
expect(itemValues[0].innerHTML.trim()).toEqual(timeFormatter.format(now, TIME_FORMAT));
expect(itemValues[1].innerHTML.trim()).toEqual(
timeFormatter.format(oneHourPast, TIME_FORMAT)
timeFormatter.format(twoHoursFuture, TIME_FORMAT)
);

done();
Expand Down Expand Up @@ -313,7 +318,7 @@ describe('the plugin', function () {
type: TIMELIST_TYPE,
id: 'test-object',
configuration: {
sortOrderIndex: 0,
sortOrderIndex: 2,
futureEventsIndex: 1,
futureEventsDurationIndex: 0,
futureEventsDuration: 0,
Expand Down Expand Up @@ -350,7 +355,26 @@ describe('the plugin', function () {

return nextTick(() => {
const items = element.querySelectorAll(LIST_ITEM_CLASS);
expect(items.length).toEqual(1);
expect(items.length).toEqual(2);
});
});

it('activities and sorts them correctly', () => {
mockComposition.emit('add', planObject);

return nextTick(() => {
const timeFormat = openmct.time.timeSystem().timeFormat;
const timeFormatter = openmct.telemetry.getValueFormatter({ format: timeFormat }).formatter;

const items = element.querySelectorAll(LIST_ITEM_CLASS);
expect(items.length).toEqual(2);

const itemValues = items[1].querySelectorAll(LIST_ITEM_VALUE_CLASS);
expect(itemValues[0].innerHTML.trim()).toEqual(timeFormatter.format(now, TIME_FORMAT));
expect(itemValues[1].innerHTML.trim()).toEqual(
timeFormatter.format(threeHoursFuture, TIME_FORMAT)
);
expect(itemValues[3].innerHTML.trim()).toEqual('Sed ut perspiciatis two');
});
});
});
Expand Down Expand Up @@ -405,7 +429,7 @@ describe('the plugin', function () {

return nextTick(() => {
const items = element.querySelectorAll(LIST_ITEM_CLASS);
expect(items.length).toEqual(1);
expect(items.length).toEqual(2);
});
});
});
Expand Down
Loading

0 comments on commit ae22920

Please sign in to comment.