mirror of
https://github.com/nasa/openmct.git
synced 2025-02-01 08:48:28 +00:00
Allows drag and dropping plans into timelist (#5300)
* Bump d3-selection from 1.3.2 to 3.0.0 Bumps [d3-selection](https://github.com/d3/d3-selection) from 1.3.2 to 3.0.0. - [Release notes](https://github.com/d3/d3-selection/releases) - [Commits](https://github.com/d3/d3-selection/compare/v1.3.2...v3.0.0) --- updated-dependencies: - dependency-name: d3-selection dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Don't require a plan file for timelist Allow dropping a plan to timelist * Rename methods and remove unused code * Fix typo * Boost test coverage to get over 52% * Adds tests for webPage plugin * Adds more tests for filtering * Adds more filtering tests * Removes one test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
05e3303828
commit
d13d7dc8f3
@ -22,7 +22,7 @@
|
||||
|
||||
export function getValidatedData(domainObject) {
|
||||
let sourceMap = domainObject.sourceMap;
|
||||
let body = domainObject.selectFile.body;
|
||||
let body = domainObject.selectFile?.body;
|
||||
let json = {};
|
||||
if (typeof body === 'string') {
|
||||
try {
|
||||
@ -30,7 +30,7 @@ export function getValidatedData(domainObject) {
|
||||
} catch (e) {
|
||||
return json;
|
||||
}
|
||||
} else {
|
||||
} else if (body !== undefined) {
|
||||
json = body;
|
||||
}
|
||||
|
||||
|
@ -27,17 +27,18 @@
|
||||
:show-ucontents="item.domainObject.type === 'plan'"
|
||||
:span-rows-count="item.rowCount"
|
||||
>
|
||||
<template slot="label">
|
||||
<template #label>
|
||||
{{ item.domainObject.name }}
|
||||
</template>
|
||||
<template #object>
|
||||
<object-view
|
||||
ref="objectView"
|
||||
slot="object"
|
||||
class="u-contents"
|
||||
:default-object="item.domainObject"
|
||||
:object-path="item.objectPath"
|
||||
@change-action-collection="setActionCollection"
|
||||
/>
|
||||
</template>
|
||||
</swim-lane>
|
||||
</template>
|
||||
|
||||
|
@ -29,10 +29,10 @@
|
||||
v-for="timeSystemItem in timeSystems"
|
||||
:key="timeSystemItem.timeSystem.key"
|
||||
>
|
||||
<template slot="label">
|
||||
<template #label>
|
||||
{{ timeSystemItem.timeSystem.name }}
|
||||
</template>
|
||||
<template slot="object">
|
||||
<template #object>
|
||||
<timeline-axis
|
||||
:bounds="timeSystemItem.bounds"
|
||||
:time-system="timeSystemItem.timeSystem"
|
||||
@ -50,7 +50,7 @@
|
||||
<timeline-object-view
|
||||
v-for="item in items"
|
||||
:key="item.keyString"
|
||||
class="c-timeline__content"
|
||||
class="c-timeline__content js-timeline__content"
|
||||
:item="item"
|
||||
/>
|
||||
</div>
|
||||
@ -93,15 +93,15 @@ export default {
|
||||
this.stopFollowingTimeContext();
|
||||
},
|
||||
mounted() {
|
||||
this.items = [];
|
||||
this.setTimeContext();
|
||||
|
||||
if (this.composition) {
|
||||
this.composition.on('add', this.addItem);
|
||||
this.composition.on('remove', this.removeItem);
|
||||
this.composition.on('reorder', this.reorder);
|
||||
this.composition.load();
|
||||
}
|
||||
|
||||
this.setTimeContext();
|
||||
this.getTimeSystems();
|
||||
},
|
||||
methods: {
|
||||
addItem(domainObject) {
|
||||
@ -165,6 +165,7 @@ export default {
|
||||
this.stopFollowingTimeContext();
|
||||
|
||||
this.timeContext = this.openmct.time.getContextForView(this.objectPath);
|
||||
this.getTimeSystems();
|
||||
this.updateViewBounds(this.timeContext.bounds());
|
||||
this.timeContext.on('bounds', this.updateViewBounds);
|
||||
},
|
||||
|
@ -20,9 +20,10 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import { createOpenMct, resetApplicationState } from "utils/testing";
|
||||
import { createOpenMct, resetApplicationState } from "@/utils/testing";
|
||||
import TimelinePlugin from "./plugin";
|
||||
import Vue from 'vue';
|
||||
import EventEmitter from "EventEmitter";
|
||||
|
||||
describe('the plugin', function () {
|
||||
let objectDef;
|
||||
@ -30,6 +31,37 @@ describe('the plugin', function () {
|
||||
let child;
|
||||
let openmct;
|
||||
let mockObjectPath;
|
||||
let mockCompositionForTimelist;
|
||||
let planObject = {
|
||||
identifier: {
|
||||
key: 'test-plan-object',
|
||||
namespace: ''
|
||||
},
|
||||
type: 'plan',
|
||||
id: "test-plan-object",
|
||||
selectFile: {
|
||||
body: JSON.stringify({
|
||||
"TEST-GROUP": [
|
||||
{
|
||||
"name": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua",
|
||||
"start": 1597170002854,
|
||||
"end": 1597171032854,
|
||||
"type": "TEST-GROUP",
|
||||
"color": "fuchsia",
|
||||
"textColor": "black"
|
||||
},
|
||||
{
|
||||
"name": "Sed ut perspiciatis",
|
||||
"start": 1597171132854,
|
||||
"end": 1597171232854,
|
||||
"type": "TEST-GROUP",
|
||||
"color": "fuchsia",
|
||||
"textColor": "black"
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
beforeEach((done) => {
|
||||
mockObjectPath = [
|
||||
@ -107,7 +139,23 @@ describe('the plugin', function () {
|
||||
key: "test-object",
|
||||
namespace: ''
|
||||
},
|
||||
type: "time-strip"
|
||||
type: "time-strip",
|
||||
configuration: {
|
||||
useIndependentTime: false,
|
||||
timeOptions: {
|
||||
mode: {
|
||||
key: 'fixed'
|
||||
},
|
||||
fixedOffsets: {
|
||||
start: 10,
|
||||
end: 11
|
||||
},
|
||||
clockOffsets: {
|
||||
start: -(30 * 60 * 1000),
|
||||
end: (30 * 60 * 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const applicableViews = openmct.objectViews.get(testViewObject, mockObjectPath);
|
||||
@ -133,6 +181,58 @@ describe('the plugin', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('the timeline composition', () => {
|
||||
let timelineDomainObject;
|
||||
let timelineView;
|
||||
|
||||
beforeEach(() => {
|
||||
timelineDomainObject = {
|
||||
identifier: {
|
||||
key: 'test-object',
|
||||
namespace: ''
|
||||
},
|
||||
type: 'time-strip',
|
||||
id: "test-object",
|
||||
configuration: {
|
||||
useIndependentTime: false
|
||||
},
|
||||
composition: [
|
||||
{
|
||||
identifier: {
|
||||
key: 'test-plan-object',
|
||||
namespace: ''
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
mockCompositionForTimelist = new EventEmitter();
|
||||
mockCompositionForTimelist.load = () => {
|
||||
mockCompositionForTimelist.emit('add', planObject);
|
||||
|
||||
return [planObject];
|
||||
};
|
||||
|
||||
spyOn(openmct.composition, 'get').withArgs(timelineDomainObject).and.returnValue(mockCompositionForTimelist);
|
||||
|
||||
openmct.router.path = [timelineDomainObject];
|
||||
|
||||
const applicableViews = openmct.objectViews.get(timelineDomainObject, [timelineDomainObject]);
|
||||
timelineView = applicableViews.find((viewProvider) => viewProvider.key === 'time-strip.view');
|
||||
let view = timelineView.view(timelineDomainObject, [timelineDomainObject]);
|
||||
view.show(child, true);
|
||||
|
||||
return Vue.nextTick();
|
||||
});
|
||||
|
||||
it('loads the plan from composition', () => {
|
||||
return Vue.nextTick(() => {
|
||||
const items = element.querySelectorAll('.js-timeline__content');
|
||||
expect(items.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('the independent time conductor', () => {
|
||||
let timelineView;
|
||||
let testViewObject = {
|
||||
@ -181,7 +281,7 @@ describe('the plugin', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('the independent time conductor', () => {
|
||||
describe('the independent time conductor - fixed', () => {
|
||||
let timelineView;
|
||||
let testViewObject2 = {
|
||||
id: "test-object2",
|
||||
|
@ -96,8 +96,10 @@ export default {
|
||||
components: {
|
||||
ListView
|
||||
},
|
||||
inject: ['openmct', 'domainObject', 'path'],
|
||||
inject: ['openmct', 'domainObject', 'path', 'composition'],
|
||||
data() {
|
||||
this.planObjects = [];
|
||||
|
||||
return {
|
||||
viewBounds: undefined,
|
||||
height: 0,
|
||||
@ -111,7 +113,7 @@ export default {
|
||||
this.timestamp = Date.now();
|
||||
this.getPlanDataAndSetConfig(this.domainObject);
|
||||
|
||||
this.unlisten = this.openmct.objects.observe(this.domainObject, 'selectFile', this.getPlanDataAndSetConfig);
|
||||
this.unlisten = this.openmct.objects.observe(this.domainObject, 'selectFile', this.planFileUpdated);
|
||||
this.unlistenConfig = this.openmct.objects.observe(this.domainObject, 'configuration', this.setViewFromConfig);
|
||||
this.removeStatusListener = this.openmct.status.observe(this.domainObject.identifier, this.setStatus);
|
||||
this.status = this.openmct.status.get(this.domainObject.identifier);
|
||||
@ -120,6 +122,12 @@ export default {
|
||||
|
||||
this.deferAutoScroll = _.debounce(this.deferAutoScroll, 500);
|
||||
this.$el.parentElement.addEventListener('scroll', this.deferAutoScroll, true);
|
||||
|
||||
if (this.composition) {
|
||||
this.composition.on('add', this.addToComposition);
|
||||
this.composition.on('remove', this.removeItem);
|
||||
this.composition.load();
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.unlisten) {
|
||||
@ -144,8 +152,19 @@ export default {
|
||||
if (this.clearAutoScrollDisabledTimer) {
|
||||
clearTimeout(this.clearAutoScrollDisabledTimer);
|
||||
}
|
||||
|
||||
if (this.composition) {
|
||||
this.composition.off('add', this.addToComposition);
|
||||
this.composition.off('remove', this.removeItem);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
planFileUpdated(selectFile) {
|
||||
this.getPlanData({
|
||||
selectFile,
|
||||
sourceMap: this.domainObject.sourceMap
|
||||
});
|
||||
},
|
||||
getPlanDataAndSetConfig(mutatedObject) {
|
||||
this.getPlanData(mutatedObject);
|
||||
this.setViewFromConfig(mutatedObject.configuration);
|
||||
@ -163,6 +182,58 @@ export default {
|
||||
this.listActivities();
|
||||
}
|
||||
},
|
||||
addItem(domainObject) {
|
||||
this.planObjects = [domainObject];
|
||||
this.resetPlanData();
|
||||
if (domainObject.type === 'plan') {
|
||||
this.getPlanDataAndSetConfig({
|
||||
...this.domainObject,
|
||||
selectFile: domainObject.selectFile
|
||||
});
|
||||
}
|
||||
},
|
||||
addToComposition(telemetryObject) {
|
||||
if (this.planObjects.length > 0) {
|
||||
this.confirmReplacePlan(telemetryObject);
|
||||
} else {
|
||||
this.addItem(telemetryObject);
|
||||
}
|
||||
},
|
||||
confirmReplacePlan(telemetryObject) {
|
||||
const dialog = this.openmct.overlays.dialog({
|
||||
iconClass: 'alert',
|
||||
message: 'This action will replace the current plan. Do you want to continue?',
|
||||
buttons: [
|
||||
{
|
||||
label: 'Ok',
|
||||
emphasis: true,
|
||||
callback: () => {
|
||||
const oldTelemetryObject = this.planObjects[0];
|
||||
this.removeFromComposition(oldTelemetryObject);
|
||||
this.addItem(telemetryObject);
|
||||
dialog.dismiss();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Cancel',
|
||||
callback: () => {
|
||||
this.removeFromComposition(telemetryObject);
|
||||
dialog.dismiss();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
},
|
||||
removeFromComposition(telemetryObject) {
|
||||
this.composition.remove(telemetryObject);
|
||||
},
|
||||
removeItem() {
|
||||
this.planObjects = [];
|
||||
this.resetPlanData();
|
||||
},
|
||||
resetPlanData() {
|
||||
this.planData = {};
|
||||
},
|
||||
getPlanData(domainObject) {
|
||||
this.planData = getValidatedData(domainObject);
|
||||
},
|
||||
@ -176,7 +247,7 @@ export default {
|
||||
const futureEventsDurationIndex = this.domainObject.configuration.futureEventsDurationIndex;
|
||||
|
||||
if (pastEventsIndex === 0 && futureEventsIndex === 0 && currentEventsIndex === 0) {
|
||||
//show all events
|
||||
//don't show all events
|
||||
this.showAll = false;
|
||||
this.viewBounds = undefined;
|
||||
this.hideAll = true;
|
||||
|
34
src/plugins/timelist/TimelistCompositionPolicy.js
Normal file
34
src/plugins/timelist/TimelistCompositionPolicy.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2022, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
import {TIMELIST_TYPE} from "@/plugins/timelist/constants";
|
||||
|
||||
export default function TimelistCompositionPolicy(openmct) {
|
||||
return {
|
||||
allow: function (parent, child) {
|
||||
if (parent.type === TIMELIST_TYPE && child.type !== 'plan') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
@ -52,7 +52,8 @@ export default function TimelistViewProvider(openmct) {
|
||||
provide: {
|
||||
openmct,
|
||||
domainObject,
|
||||
path: objectPath
|
||||
path: objectPath,
|
||||
composition: openmct.composition.get(domainObject)
|
||||
},
|
||||
template: '<timelist></timelist>'
|
||||
});
|
||||
|
@ -23,6 +23,7 @@
|
||||
import TimelistViewProvider from './TimelistViewProvider';
|
||||
import { TIMELIST_TYPE } from './constants';
|
||||
import TimeListInspectorViewProvider from "./inspector/TimeListInspectorViewProvider";
|
||||
import TimelistCompositionPolicy from "@/plugins/timelist/TimelistCompositionPolicy";
|
||||
|
||||
export default function () {
|
||||
return function install(openmct) {
|
||||
@ -37,7 +38,6 @@ export default function () {
|
||||
name: 'Upload Plan (JSON File)',
|
||||
key: 'selectFile',
|
||||
control: 'file-input',
|
||||
required: true,
|
||||
text: 'Select File...',
|
||||
type: 'application/json',
|
||||
property: [
|
||||
@ -59,10 +59,12 @@ export default function () {
|
||||
pastEventsDuration: 20,
|
||||
filter: ''
|
||||
};
|
||||
domainObject.composition = [];
|
||||
}
|
||||
});
|
||||
openmct.objectViews.addProvider(new TimelistViewProvider(openmct));
|
||||
openmct.inspectorViews.addProvider(new TimeListInspectorViewProvider(openmct));
|
||||
openmct.composition.addPolicy(new TimelistCompositionPolicy(openmct).allow);
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import TimelistPlugin from "./plugin";
|
||||
import { TIMELIST_TYPE } from "./constants";
|
||||
import Vue from 'vue';
|
||||
import moment from "moment";
|
||||
import EventEmitter from "EventEmitter";
|
||||
|
||||
const LIST_ITEM_CLASS = '.js-table__body .js-list-item';
|
||||
const LIST_ITEM_VALUE_CLASS = '.js-list-item__value';
|
||||
@ -37,6 +38,41 @@ describe('the plugin', function () {
|
||||
let openmct;
|
||||
let appHolder;
|
||||
let originalRouterPath;
|
||||
let mockComposition;
|
||||
let now = Date.now();
|
||||
let twoHoursPast = now - (1000 * 60 * 60 * 2);
|
||||
let oneHourPast = now - (1000 * 60 * 60);
|
||||
let twoHoursFuture = now + (1000 * 60 * 60 * 2);
|
||||
let planObject = {
|
||||
identifier: {
|
||||
key: 'test-plan-object',
|
||||
namespace: ''
|
||||
},
|
||||
type: 'plan',
|
||||
id: "test-plan-object",
|
||||
selectFile: {
|
||||
body: JSON.stringify({
|
||||
"TEST-GROUP": [
|
||||
{
|
||||
"name": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua",
|
||||
"start": twoHoursPast,
|
||||
"end": oneHourPast,
|
||||
"type": "TEST-GROUP",
|
||||
"color": "fuchsia",
|
||||
"textColor": "black"
|
||||
},
|
||||
{
|
||||
"name": "Sed ut perspiciatis",
|
||||
"start": now,
|
||||
"end": twoHoursFuture,
|
||||
"type": "TEST-GROUP",
|
||||
"color": "fuchsia",
|
||||
"textColor": "black"
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
beforeEach((done) => {
|
||||
appHolder = document.createElement('div');
|
||||
@ -58,6 +94,15 @@ describe('the plugin', function () {
|
||||
|
||||
originalRouterPath = openmct.router.path;
|
||||
|
||||
mockComposition = new EventEmitter();
|
||||
mockComposition.load = () => {
|
||||
mockComposition.emit('add', planObject);
|
||||
|
||||
return Promise.resolve([planObject]);
|
||||
};
|
||||
|
||||
spyOn(openmct.composition, 'get').and.returnValue(mockComposition);
|
||||
|
||||
openmct.on('start', done);
|
||||
openmct.start(appHolder);
|
||||
});
|
||||
@ -112,13 +157,13 @@ describe('the plugin', function () {
|
||||
sortOrderIndex: 0,
|
||||
futureEventsIndex: 1,
|
||||
futureEventsDurationIndex: 0,
|
||||
futureEventsDuration: 20,
|
||||
futureEventsDuration: 0,
|
||||
currentEventsIndex: 1,
|
||||
currentEventsDurationIndex: 0,
|
||||
currentEventsDuration: 20,
|
||||
currentEventsDuration: 0,
|
||||
pastEventsIndex: 1,
|
||||
pastEventsDurationIndex: 0,
|
||||
pastEventsDuration: 20,
|
||||
pastEventsDuration: 0,
|
||||
filter: ''
|
||||
},
|
||||
selectFile: {
|
||||
@ -126,16 +171,16 @@ describe('the plugin', function () {
|
||||
"TEST-GROUP": [
|
||||
{
|
||||
"name": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua",
|
||||
"start": 1597170002854,
|
||||
"end": 1597171032854,
|
||||
"start": twoHoursPast,
|
||||
"end": oneHourPast,
|
||||
"type": "TEST-GROUP",
|
||||
"color": "fuchsia",
|
||||
"textColor": "black"
|
||||
},
|
||||
{
|
||||
"name": "Sed ut perspiciatis",
|
||||
"start": 1597171132854,
|
||||
"end": 1597171232854,
|
||||
"start": now,
|
||||
"end": twoHoursFuture,
|
||||
"type": "TEST-GROUP",
|
||||
"color": "fuchsia",
|
||||
"textColor": "black"
|
||||
@ -171,11 +216,164 @@ describe('the plugin', function () {
|
||||
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(`${moment(1597170002854).format('YYYY-MM-DD HH:mm:ss:SSS')}Z`);
|
||||
expect(itemValues[1].innerHTML.trim()).toEqual(`${moment(1597171032854).format('YYYY-MM-DD HH:mm:ss:SSS')}Z`);
|
||||
expect(itemValues[0].innerHTML.trim()).toEqual(`${moment(twoHoursPast).format('YYYY-MM-DD HH:mm:ss:SSS')}Z`);
|
||||
expect(itemValues[1].innerHTML.trim()).toEqual(`${moment(oneHourPast).format('YYYY-MM-DD HH:mm:ss:SSS')}Z`);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('the timelist composition', () => {
|
||||
let timelistDomainObject;
|
||||
let timelistView;
|
||||
|
||||
beforeEach(() => {
|
||||
timelistDomainObject = {
|
||||
identifier: {
|
||||
key: 'test-object',
|
||||
namespace: ''
|
||||
},
|
||||
type: TIMELIST_TYPE,
|
||||
id: "test-object",
|
||||
configuration: {
|
||||
sortOrderIndex: 0,
|
||||
futureEventsIndex: 1,
|
||||
futureEventsDurationIndex: 0,
|
||||
futureEventsDuration: 0,
|
||||
currentEventsIndex: 1,
|
||||
currentEventsDurationIndex: 0,
|
||||
currentEventsDuration: 0,
|
||||
pastEventsIndex: 1,
|
||||
pastEventsDurationIndex: 0,
|
||||
pastEventsDuration: 0,
|
||||
filter: ''
|
||||
},
|
||||
composition: [{
|
||||
identifier: {
|
||||
key: 'test-plan-object',
|
||||
namespace: ''
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
openmct.router.path = [timelistDomainObject];
|
||||
|
||||
const applicableViews = openmct.objectViews.get(timelistDomainObject, [timelistDomainObject]);
|
||||
timelistView = applicableViews.find((viewProvider) => viewProvider.key === 'timelist.view');
|
||||
let view = timelistView.view(timelistDomainObject, [timelistDomainObject]);
|
||||
view.show(child, true);
|
||||
|
||||
return Vue.nextTick();
|
||||
});
|
||||
|
||||
it('loads the plan from composition', () => {
|
||||
return Vue.nextTick(() => {
|
||||
const items = element.querySelectorAll(LIST_ITEM_CLASS);
|
||||
expect(items.length).toEqual(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('filters', () => {
|
||||
let timelistDomainObject;
|
||||
let timelistView;
|
||||
|
||||
beforeEach(() => {
|
||||
timelistDomainObject = {
|
||||
identifier: {
|
||||
key: 'test-object',
|
||||
namespace: ''
|
||||
},
|
||||
type: TIMELIST_TYPE,
|
||||
id: "test-object",
|
||||
configuration: {
|
||||
sortOrderIndex: 0,
|
||||
futureEventsIndex: 1,
|
||||
futureEventsDurationIndex: 0,
|
||||
futureEventsDuration: 0,
|
||||
currentEventsIndex: 1,
|
||||
currentEventsDurationIndex: 0,
|
||||
currentEventsDuration: 0,
|
||||
pastEventsIndex: 1,
|
||||
pastEventsDurationIndex: 0,
|
||||
pastEventsDuration: 0,
|
||||
filter: 'perspiciatis'
|
||||
},
|
||||
composition: [{
|
||||
identifier: {
|
||||
key: 'test-plan-object',
|
||||
namespace: ''
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
openmct.router.path = [timelistDomainObject];
|
||||
|
||||
const applicableViews = openmct.objectViews.get(timelistDomainObject, [timelistDomainObject]);
|
||||
timelistView = applicableViews.find((viewProvider) => viewProvider.key === 'timelist.view');
|
||||
let view = timelistView.view(timelistDomainObject, [timelistDomainObject]);
|
||||
view.show(child, true);
|
||||
|
||||
return Vue.nextTick();
|
||||
});
|
||||
|
||||
it('activities', () => {
|
||||
return Vue.nextTick(() => {
|
||||
const items = element.querySelectorAll(LIST_ITEM_CLASS);
|
||||
expect(items.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('time filtering - past', () => {
|
||||
let timelistDomainObject;
|
||||
let timelistView;
|
||||
|
||||
beforeEach(() => {
|
||||
timelistDomainObject = {
|
||||
identifier: {
|
||||
key: 'test-object',
|
||||
namespace: ''
|
||||
},
|
||||
type: TIMELIST_TYPE,
|
||||
id: "test-object",
|
||||
configuration: {
|
||||
sortOrderIndex: 0,
|
||||
futureEventsIndex: 1,
|
||||
futureEventsDurationIndex: 0,
|
||||
futureEventsDuration: 0,
|
||||
currentEventsIndex: 1,
|
||||
currentEventsDurationIndex: 0,
|
||||
currentEventsDuration: 0,
|
||||
pastEventsIndex: 0,
|
||||
pastEventsDurationIndex: 0,
|
||||
pastEventsDuration: 0,
|
||||
filter: ''
|
||||
},
|
||||
composition: [{
|
||||
identifier: {
|
||||
key: 'test-plan-object',
|
||||
namespace: ''
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
openmct.router.path = [timelistDomainObject];
|
||||
|
||||
const applicableViews = openmct.objectViews.get(timelistDomainObject, [timelistDomainObject]);
|
||||
timelistView = applicableViews.find((viewProvider) => viewProvider.key === 'timelist.view');
|
||||
let view = timelistView.view(timelistDomainObject, [timelistDomainObject]);
|
||||
view.show(child, true);
|
||||
|
||||
return Vue.nextTick();
|
||||
});
|
||||
|
||||
it('hides past events', () => {
|
||||
return Vue.nextTick(() => {
|
||||
const items = element.querySelectorAll(LIST_ITEM_CLASS);
|
||||
expect(items.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
106
src/plugins/webPage/pluginSpec.js
Normal file
106
src/plugins/webPage/pluginSpec.js
Normal file
@ -0,0 +1,106 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2022, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import { createOpenMct, resetApplicationState } from "utils/testing";
|
||||
import WebPagePlugin from "./plugin";
|
||||
|
||||
function getView(openmct, domainObj, objectPath) {
|
||||
const applicableViews = openmct.objectViews.get(domainObj, objectPath);
|
||||
const webpageView = applicableViews.find((viewProvider) => viewProvider.key === 'webPage');
|
||||
|
||||
return webpageView.view(domainObj);
|
||||
}
|
||||
|
||||
function destroyView(view) {
|
||||
return view.destroy();
|
||||
}
|
||||
|
||||
describe("The web page plugin", function () {
|
||||
let mockDomainObject;
|
||||
let mockDomainObjectPath;
|
||||
let openmct;
|
||||
let element;
|
||||
let child;
|
||||
let view;
|
||||
|
||||
beforeEach((done) => {
|
||||
mockDomainObjectPath = [
|
||||
{
|
||||
name: 'mock webpage',
|
||||
type: 'webpage',
|
||||
identifier: {
|
||||
key: 'mock-webpage',
|
||||
namespace: ''
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
mockDomainObject = {
|
||||
displayFormat: "",
|
||||
name: "Unnamed WebPage",
|
||||
type: "webPage",
|
||||
location: "f69c21ac-24ef-450c-8e2f-3d527087d285",
|
||||
modified: 1627483839783,
|
||||
url: "123",
|
||||
displayText: "123",
|
||||
persisted: 1627483839783,
|
||||
id: "3d9c243d-dffb-446b-8474-d9931a99d679",
|
||||
identifier: {
|
||||
namespace: "",
|
||||
key: "3d9c243d-dffb-446b-8474-d9931a99d679"
|
||||
}
|
||||
};
|
||||
|
||||
openmct = createOpenMct();
|
||||
openmct.install(new WebPagePlugin());
|
||||
|
||||
element = document.createElement('div');
|
||||
element.style.width = '640px';
|
||||
element.style.height = '480px';
|
||||
child = document.createElement('div');
|
||||
child.style.width = '640px';
|
||||
child.style.height = '480px';
|
||||
element.appendChild(child);
|
||||
|
||||
openmct.on('start', done);
|
||||
openmct.startHeadless();
|
||||
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
destroyView(view);
|
||||
|
||||
return resetApplicationState(openmct);
|
||||
});
|
||||
|
||||
describe('the view', () => {
|
||||
beforeEach(() => {
|
||||
view = getView(openmct, mockDomainObject, mockDomainObjectPath);
|
||||
view.show(child, true);
|
||||
});
|
||||
|
||||
it('provides a view', () => {
|
||||
expect(view).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user