mirror of
https://github.com/nasa/openmct.git
synced 2025-01-01 19:06:40 +00:00
Merge branch 'master' into testing-guidelines
This commit is contained in:
commit
18ab034147
@ -4,7 +4,7 @@
|
|||||||
"description": "The Open MCT core platform",
|
"description": "The Open MCT core platform",
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"angular": "1.7.9",
|
"angular": ">=1.8.0",
|
||||||
"angular-route": "1.4.14",
|
"angular-route": "1.4.14",
|
||||||
"babel-eslint": "8.2.6",
|
"babel-eslint": "8.2.6",
|
||||||
"comma-separated-values": "^3.6.4",
|
"comma-separated-values": "^3.6.4",
|
||||||
|
39
src/plugins/LADTable/LADTableCompositionPolicy.js
Normal file
39
src/plugins/LADTable/LADTableCompositionPolicy.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2020, 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
export default class LADTableCompositionPolicy {
|
||||||
|
|
||||||
|
constructor(openmct) {
|
||||||
|
this.openmct = openmct;
|
||||||
|
return this.allow.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
allow(parent, child) {
|
||||||
|
if(parent.type === 'LadTable') {
|
||||||
|
return this.openmct.telemetry.isTelemetryObject(child);
|
||||||
|
} else if(parent.type === 'LadTableSet') {
|
||||||
|
return child.type === 'LadTable';
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -19,15 +19,10 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
import LadTableSet from './components/LadTableSet.vue';
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
define([
|
export default function LADTableSetViewProvider(openmct) {
|
||||||
'./components/LadTableSet.vue',
|
|
||||||
'vue'
|
|
||||||
], function (
|
|
||||||
LadTableSet,
|
|
||||||
Vue
|
|
||||||
) {
|
|
||||||
function LADTableSetViewProvider(openmct) {
|
|
||||||
return {
|
return {
|
||||||
key: 'LadTableSet',
|
key: 'LadTableSet',
|
||||||
name: 'LAD Table Set',
|
name: 'LAD Table Set',
|
||||||
@ -46,7 +41,7 @@ define([
|
|||||||
component = new Vue({
|
component = new Vue({
|
||||||
el: element,
|
el: element,
|
||||||
components: {
|
components: {
|
||||||
LadTableSet: LadTableSet.default
|
LadTableSet: LadTableSet
|
||||||
},
|
},
|
||||||
provide: {
|
provide: {
|
||||||
openmct,
|
openmct,
|
||||||
@ -67,5 +62,3 @@ define([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return LADTableSetViewProvider;
|
|
||||||
});
|
|
||||||
|
@ -19,15 +19,10 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
import LadTable from './components/LADTable.vue';
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
define([
|
export default function LADTableViewProvider(openmct) {
|
||||||
'./components/LADTable.vue',
|
|
||||||
'vue'
|
|
||||||
], function (
|
|
||||||
LadTableComponent,
|
|
||||||
Vue
|
|
||||||
) {
|
|
||||||
function LADTableViewProvider(openmct) {
|
|
||||||
return {
|
return {
|
||||||
key: 'LadTable',
|
key: 'LadTable',
|
||||||
name: 'LAD Table',
|
name: 'LAD Table',
|
||||||
@ -46,7 +41,7 @@ define([
|
|||||||
component = new Vue({
|
component = new Vue({
|
||||||
el: element,
|
el: element,
|
||||||
components: {
|
components: {
|
||||||
LadTableComponent: LadTableComponent.default
|
LadTableComponent: LadTable
|
||||||
},
|
},
|
||||||
provide: {
|
provide: {
|
||||||
openmct,
|
openmct,
|
||||||
@ -67,5 +62,3 @@ define([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return LADTableViewProvider;
|
|
||||||
});
|
|
||||||
|
@ -22,10 +22,16 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<tr @contextmenu.prevent="showContextMenu">
|
<tr
|
||||||
<td>{{ name }}</td>
|
class="js-lad-table__body__row"
|
||||||
<td>{{ formattedTimestamp }}</td>
|
@contextmenu.prevent="showContextMenu"
|
||||||
<td :class="valueClass">{{ value }}</td>
|
>
|
||||||
|
<td class="js-first-data">{{ name }}</td>
|
||||||
|
<td class="js-second-data">{{ formattedTimestamp }}</td>
|
||||||
|
<td
|
||||||
|
class="js-third-data"
|
||||||
|
:class="valueClass"
|
||||||
|
>{{ value }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -88,4 +88,3 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
>
|
>
|
||||||
<tr
|
<tr
|
||||||
:key="primary.key"
|
:key="primary.key"
|
||||||
class="c-table__group-header"
|
class="c-table__group-header js-lad-table-set__table-headers"
|
||||||
>
|
>
|
||||||
<td colspan="10">
|
<td colspan="10">
|
||||||
{{ primary.domainObject.name }}
|
{{ primary.domainObject.name }}
|
||||||
|
@ -19,16 +19,13 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
import LADTableViewProvider from './LADTableViewProvider';
|
||||||
|
import LADTableSetViewProvider from './LADTableSetViewProvider';
|
||||||
|
import LADTableCompositionPolicy from './LADTableCompositionPolicy';
|
||||||
|
|
||||||
define([
|
export default function plugin() {
|
||||||
'./LADTableViewProvider',
|
|
||||||
'./LADTableSetViewProvider'
|
|
||||||
], function (
|
|
||||||
LADTableViewProvider,
|
|
||||||
LADTableSetViewProvider
|
|
||||||
) {
|
|
||||||
return function plugin() {
|
|
||||||
return function install(openmct) {
|
return function install(openmct) {
|
||||||
|
|
||||||
openmct.objectViews.addProvider(new LADTableViewProvider(openmct));
|
openmct.objectViews.addProvider(new LADTableViewProvider(openmct));
|
||||||
openmct.objectViews.addProvider(new LADTableSetViewProvider(openmct));
|
openmct.objectViews.addProvider(new LADTableSetViewProvider(openmct));
|
||||||
|
|
||||||
@ -51,6 +48,7 @@ define([
|
|||||||
domainObject.composition = [];
|
domainObject.composition = [];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
openmct.composition.addPolicy(new LADTableCompositionPolicy(openmct));
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
});
|
|
||||||
|
365
src/plugins/LADTable/pluginSpec.js
Normal file
365
src/plugins/LADTable/pluginSpec.js
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2018, 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 LadPlugin from './plugin.js';
|
||||||
|
import Vue from 'vue';
|
||||||
|
import {
|
||||||
|
createOpenMct,
|
||||||
|
getMockObjects,
|
||||||
|
getMockTelemetry,
|
||||||
|
getLatestTelemetry,
|
||||||
|
resetApplicationState
|
||||||
|
} from 'utils/testing';
|
||||||
|
|
||||||
|
const TABLE_BODY_ROWS = '.js-lad-table__body__row';
|
||||||
|
const TABLE_BODY_FIRST_ROW = TABLE_BODY_ROWS + ':first-child';
|
||||||
|
const TABLE_BODY_FIRST_ROW_FIRST_DATA = TABLE_BODY_FIRST_ROW + ' .js-first-data';
|
||||||
|
const TABLE_BODY_FIRST_ROW_SECOND_DATA = TABLE_BODY_FIRST_ROW + ' .js-second-data';
|
||||||
|
const TABLE_BODY_FIRST_ROW_THIRD_DATA = TABLE_BODY_FIRST_ROW + ' .js-third-data';
|
||||||
|
const LAD_SET_TABLE_HEADERS = '.js-lad-table-set__table-headers';
|
||||||
|
|
||||||
|
function utcTimeFormat(value) {
|
||||||
|
return new Date(value).toISOString().replace('T', ' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("The LAD Table", () => {
|
||||||
|
const ladTableKey = 'LadTable';
|
||||||
|
|
||||||
|
let openmct,
|
||||||
|
ladPlugin,
|
||||||
|
parent,
|
||||||
|
child,
|
||||||
|
telemetryCount = 3,
|
||||||
|
timeFormat = 'utc',
|
||||||
|
mockTelemetry = getMockTelemetry({ count: telemetryCount, format: timeFormat }),
|
||||||
|
mockObj = getMockObjects({
|
||||||
|
objectKeyStrings: ['ladTable', 'telemetry'],
|
||||||
|
format: timeFormat
|
||||||
|
}),
|
||||||
|
bounds = {
|
||||||
|
start: 0,
|
||||||
|
end: 4
|
||||||
|
};
|
||||||
|
|
||||||
|
// add telemetry object as composition in lad table
|
||||||
|
mockObj.ladTable.composition.push(mockObj.telemetry.identifier);
|
||||||
|
|
||||||
|
// this setups up the app
|
||||||
|
beforeEach((done) => {
|
||||||
|
const appHolder = document.createElement('div');
|
||||||
|
appHolder.style.width = '640px';
|
||||||
|
appHolder.style.height = '480px';
|
||||||
|
|
||||||
|
openmct = createOpenMct();
|
||||||
|
|
||||||
|
parent = document.createElement('div');
|
||||||
|
child = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
|
||||||
|
spyOn(openmct.telemetry, 'request').and.returnValue(Promise.resolve([]));
|
||||||
|
|
||||||
|
ladPlugin = new LadPlugin();
|
||||||
|
openmct.install(ladPlugin);
|
||||||
|
|
||||||
|
spyOn(openmct.objects, 'get').and.returnValue(Promise.resolve({}));
|
||||||
|
|
||||||
|
openmct.time.bounds({ start: bounds.start, end: bounds.end });
|
||||||
|
|
||||||
|
openmct.on('start', done);
|
||||||
|
openmct.startHeadless(appHolder);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
resetApplicationState(openmct);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should provide a table view only for lad table objects", () => {
|
||||||
|
let applicableViews = openmct.objectViews.get(mockObj.ladTable),
|
||||||
|
ladTableView = applicableViews.find(
|
||||||
|
(viewProvider) => viewProvider.key === ladTableKey
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(applicableViews.length).toEqual(1);
|
||||||
|
expect(ladTableView).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('composition', () => {
|
||||||
|
let ladTableCompositionCollection;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
ladTableCompositionCollection = openmct.composition.get(mockObj.ladTable);
|
||||||
|
ladTableCompositionCollection.load();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should accept telemetry producing objects", () => {
|
||||||
|
expect(() => {
|
||||||
|
ladTableCompositionCollection.add(mockObj.telemetry);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should reject non-telemtry producing objects", () => {
|
||||||
|
expect(()=> {
|
||||||
|
ladTableCompositionCollection.add(mockObj.ladTable);
|
||||||
|
}).toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("table view", () => {
|
||||||
|
let applicableViews,
|
||||||
|
ladTableViewProvider,
|
||||||
|
ladTableView,
|
||||||
|
anotherTelemetryObj = getMockObjects({
|
||||||
|
objectKeyStrings: ['telemetry'],
|
||||||
|
overwrite: {
|
||||||
|
telemetry: {
|
||||||
|
name: "New Telemetry Object",
|
||||||
|
identifier: { namespace: "", key: "another-telemetry-object" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).telemetry;
|
||||||
|
|
||||||
|
// add another telemetry object as composition in lad table to test multi rows
|
||||||
|
mockObj.ladTable.composition.push(anotherTelemetryObj.identifier);
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
let telemetryRequestResolve,
|
||||||
|
telemetryObjectResolve,
|
||||||
|
anotherTelemetryObjectResolve;
|
||||||
|
let telemetryRequestPromise = new Promise((resolve) => {
|
||||||
|
telemetryRequestResolve = resolve;
|
||||||
|
}),
|
||||||
|
telemetryObjectPromise = new Promise((resolve) => {
|
||||||
|
telemetryObjectResolve = resolve;
|
||||||
|
}),
|
||||||
|
anotherTelemetryObjectPromise = new Promise((resolve) => {
|
||||||
|
anotherTelemetryObjectResolve = resolve;
|
||||||
|
})
|
||||||
|
openmct.telemetry.request.and.callFake(() => {
|
||||||
|
telemetryRequestResolve(mockTelemetry);
|
||||||
|
return telemetryRequestPromise;
|
||||||
|
});
|
||||||
|
openmct.objects.get.and.callFake((obj) => {
|
||||||
|
if(obj.key === 'telemetry-object') {
|
||||||
|
telemetryObjectResolve(mockObj.telemetry);
|
||||||
|
return telemetryObjectPromise;
|
||||||
|
} else {
|
||||||
|
anotherTelemetryObjectResolve(anotherTelemetryObj);
|
||||||
|
return anotherTelemetryObjectPromise;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
openmct.time.bounds({ start: bounds.start, end: bounds.end });
|
||||||
|
|
||||||
|
applicableViews = openmct.objectViews.get(mockObj.ladTable);
|
||||||
|
ladTableViewProvider = applicableViews.find((viewProvider) => viewProvider.key === ladTableKey);
|
||||||
|
ladTableView = ladTableViewProvider.view(mockObj.ladTable, [mockObj.ladTable]);
|
||||||
|
ladTableView.show(child, true);
|
||||||
|
|
||||||
|
await Promise.all([telemetryRequestPromise, telemetryObjectPromise, anotherTelemetryObjectPromise]);
|
||||||
|
await Vue.nextTick();
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show one row per object in the composition", () => {
|
||||||
|
const rowCount = parent.querySelectorAll(TABLE_BODY_ROWS).length;
|
||||||
|
expect(rowCount).toBe(mockObj.ladTable.composition.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show the most recent datum from the telemetry producing object", async () => {
|
||||||
|
const latestDatum = getLatestTelemetry(mockTelemetry, { timeFormat });
|
||||||
|
const expectedDate = utcTimeFormat(latestDatum[timeFormat]);
|
||||||
|
await Vue.nextTick();
|
||||||
|
const latestDate = parent.querySelector(TABLE_BODY_FIRST_ROW_SECOND_DATA).innerText;
|
||||||
|
expect(latestDate).toBe(expectedDate);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show the name provided for the the telemetry producing object", () => {
|
||||||
|
const rowName = parent.querySelector(TABLE_BODY_FIRST_ROW_FIRST_DATA).innerText,
|
||||||
|
expectedName = mockObj.telemetry.name;
|
||||||
|
expect(rowName).toBe(expectedName);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show the correct values for the datum based on domain and range hints", async () => {
|
||||||
|
const range = mockObj.telemetry.telemetry.values.find((val) => {
|
||||||
|
return val.hints && val.hints.range !== undefined;
|
||||||
|
}).key;
|
||||||
|
const domain = mockObj.telemetry.telemetry.values.find((val) => {
|
||||||
|
return val.hints && val.hints.domain !== undefined;
|
||||||
|
}).key;
|
||||||
|
const mostRecentTelemetry = getLatestTelemetry(mockTelemetry, { timeFormat });
|
||||||
|
const rangeValue = mostRecentTelemetry[range];
|
||||||
|
const domainValue = utcTimeFormat(mostRecentTelemetry[domain]);
|
||||||
|
await Vue.nextTick();
|
||||||
|
const actualDomainValue = parent.querySelector(TABLE_BODY_FIRST_ROW_SECOND_DATA).innerText;
|
||||||
|
const actualRangeValue = parent.querySelector(TABLE_BODY_FIRST_ROW_THIRD_DATA).innerText;
|
||||||
|
expect(actualRangeValue).toBe(rangeValue);
|
||||||
|
expect(actualDomainValue).toBe(domainValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("The LAD Table Set", () => {
|
||||||
|
const ladTableSetKey = 'LadTableSet';
|
||||||
|
|
||||||
|
let openmct,
|
||||||
|
ladPlugin,
|
||||||
|
parent,
|
||||||
|
child,
|
||||||
|
telemetryCount = 3,
|
||||||
|
timeFormat = 'utc',
|
||||||
|
mockTelemetry = getMockTelemetry({ count: telemetryCount, format: timeFormat }),
|
||||||
|
mockObj = getMockObjects({
|
||||||
|
objectKeyStrings: ['ladTable', 'ladTableSet', 'telemetry']
|
||||||
|
}),
|
||||||
|
bounds = {
|
||||||
|
start: 0,
|
||||||
|
end: 4
|
||||||
|
};
|
||||||
|
// add mock telemetry to lad table and lad table to lad table set (composition)
|
||||||
|
mockObj.ladTable.composition.push(mockObj.telemetry.identifier);
|
||||||
|
mockObj.ladTableSet.composition.push(mockObj.ladTable.identifier);
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
const appHolder = document.createElement('div');
|
||||||
|
appHolder.style.width = '640px';
|
||||||
|
appHolder.style.height = '480px';
|
||||||
|
|
||||||
|
openmct = createOpenMct();
|
||||||
|
|
||||||
|
parent = document.createElement('div');
|
||||||
|
child = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
|
|
||||||
|
spyOn(openmct.telemetry, 'request').and.returnValue(Promise.resolve([]));
|
||||||
|
|
||||||
|
ladPlugin = new LadPlugin();
|
||||||
|
openmct.install(ladPlugin);
|
||||||
|
|
||||||
|
spyOn(openmct.objects, 'get').and.returnValue(Promise.resolve({}));
|
||||||
|
|
||||||
|
openmct.time.bounds({ start: bounds.start, end: bounds.end });
|
||||||
|
|
||||||
|
openmct.on('start', done);
|
||||||
|
openmct.start(appHolder);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
resetApplicationState(openmct);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should provide a lad table set view only for lad table set objects", () => {
|
||||||
|
let applicableViews = openmct.objectViews.get(mockObj.ladTableSet),
|
||||||
|
ladTableSetView = applicableViews.find(
|
||||||
|
(viewProvider) => viewProvider.key === ladTableSetKey
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(applicableViews.length).toEqual(1);
|
||||||
|
expect(ladTableSetView).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('composition', () => {
|
||||||
|
let ladTableSetCompositionCollection;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
ladTableSetCompositionCollection = openmct.composition.get(mockObj.ladTableSet);
|
||||||
|
ladTableSetCompositionCollection.load();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should accept lad table objects", () => {
|
||||||
|
expect(() => {
|
||||||
|
ladTableSetCompositionCollection.add(mockObj.ladTable);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should reject non lad table objects", () => {
|
||||||
|
expect(()=> {
|
||||||
|
ladTableSetCompositionCollection.add(mockObj.telemetry);
|
||||||
|
}).toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("table view", () => {
|
||||||
|
let applicableViews,
|
||||||
|
ladTableSetViewProvider,
|
||||||
|
ladTableSetView,
|
||||||
|
otherObj = getMockObjects({
|
||||||
|
objectKeyStrings: ['ladTable'],
|
||||||
|
overwrite: {
|
||||||
|
ladTable: {
|
||||||
|
name: "New LAD Table Object",
|
||||||
|
identifier: { namespace: "", key: "another-lad-object" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// add another lad table (with telemetry object) object to the lad table set for multi row test
|
||||||
|
otherObj.ladTable.composition.push(mockObj.telemetry.identifier);
|
||||||
|
mockObj.ladTableSet.composition.push(otherObj.ladTable.identifier);
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
let telemetryRequestResolve,
|
||||||
|
ladObjectResolve,
|
||||||
|
anotherLadObjectResolve;
|
||||||
|
let telemetryRequestPromise = new Promise((resolve) => {
|
||||||
|
telemetryRequestResolve = resolve;
|
||||||
|
}),
|
||||||
|
ladObjectPromise = new Promise((resolve) => {
|
||||||
|
ladObjectResolve = resolve;
|
||||||
|
}),
|
||||||
|
anotherLadObjectPromise = new Promise((resolve) => {
|
||||||
|
anotherLadObjectResolve = resolve;
|
||||||
|
})
|
||||||
|
openmct.telemetry.request.and.callFake(() => {
|
||||||
|
telemetryRequestResolve(mockTelemetry);
|
||||||
|
return telemetryRequestPromise;
|
||||||
|
});
|
||||||
|
openmct.objects.get.and.callFake((obj) => {
|
||||||
|
if(obj.key === 'lad-object') {
|
||||||
|
ladObjectResolve(mockObj.ladObject);
|
||||||
|
return ladObjectPromise;
|
||||||
|
} else if(obj.key === 'another-lad-object') {
|
||||||
|
anotherLadObjectResolve(otherObj.ladObject);
|
||||||
|
return anotherLadObjectPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve({});
|
||||||
|
});
|
||||||
|
|
||||||
|
openmct.time.bounds({ start: bounds.start, end: bounds.end });
|
||||||
|
|
||||||
|
applicableViews = openmct.objectViews.get(mockObj.ladTableSet);
|
||||||
|
ladTableSetViewProvider = applicableViews.find((viewProvider) => viewProvider.key === ladTableSetKey);
|
||||||
|
ladTableSetView = ladTableSetViewProvider.view(mockObj.ladTableSet, [mockObj.ladTableSet]);
|
||||||
|
ladTableSetView.show(child, true);
|
||||||
|
|
||||||
|
await Promise.all([telemetryRequestPromise, ladObjectPromise, anotherLadObjectPromise]);
|
||||||
|
await Vue.nextTick();
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show one row per lad table object in the composition", () => {
|
||||||
|
const rowCount = parent.querySelectorAll(LAD_SET_TABLE_HEADERS).length;
|
||||||
|
expect(rowCount).toBe(mockObj.ladTableSet.composition.length);
|
||||||
|
pending();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -29,11 +29,15 @@ define([
|
|||||||
function isTelemetryObject(selectionPath) {
|
function isTelemetryObject(selectionPath) {
|
||||||
let selectedObject = selectionPath[0].context.item;
|
let selectedObject = selectionPath[0].context.item;
|
||||||
let parentObject = selectionPath[1].context.item;
|
let parentObject = selectionPath[1].context.item;
|
||||||
|
let selectedLayoutItem = selectionPath[0].context.layoutItem;
|
||||||
|
|
||||||
return parentObject &&
|
return parentObject &&
|
||||||
parentObject.type === 'layout' &&
|
parentObject.type === 'layout' &&
|
||||||
selectedObject &&
|
selectedObject &&
|
||||||
|
selectedLayoutItem &&
|
||||||
|
selectedLayoutItem.type === 'telemetry-view' &&
|
||||||
openmct.telemetry.isTelemetryObject(selectedObject) &&
|
openmct.telemetry.isTelemetryObject(selectedObject) &&
|
||||||
!options.showAsView.includes(selectedObject.type)
|
!options.showAsView.includes(selectedObject.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
* Open MCT, Copyright (c) 2014-2020, United States Government
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
* Administration. All rights reserved.
|
* Administration. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -72,6 +72,52 @@ define(['lodash'], function (_) {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
viewTypes = {
|
||||||
|
'telemetry-view': {
|
||||||
|
value: 'telemetry-view',
|
||||||
|
name: 'Alphanumeric',
|
||||||
|
class: 'icon-alphanumeric'
|
||||||
|
},
|
||||||
|
'telemetry.plot.overlay': {
|
||||||
|
value: 'telemetry.plot.overlay',
|
||||||
|
name: 'Overlay Plot',
|
||||||
|
class: "icon-plot-overlay"
|
||||||
|
},
|
||||||
|
'telemetry.plot.stacked': {
|
||||||
|
value: "telemetry.plot.stacked",
|
||||||
|
name: "Stacked Plot",
|
||||||
|
class: "icon-plot-stacked"
|
||||||
|
},
|
||||||
|
'table': {
|
||||||
|
value: 'table',
|
||||||
|
name: 'Table',
|
||||||
|
class: 'icon-tabular-realtime'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
applicableViews = {
|
||||||
|
'telemetry-view': [
|
||||||
|
viewTypes['telemetry.plot.overlay'],
|
||||||
|
viewTypes.table
|
||||||
|
],
|
||||||
|
'telemetry.plot.overlay': [
|
||||||
|
viewTypes['telemetry.plot.stacked'],
|
||||||
|
viewTypes.table,
|
||||||
|
viewTypes['telemetry-view']
|
||||||
|
],
|
||||||
|
'table': [
|
||||||
|
viewTypes['telemetry.plot.overlay'],
|
||||||
|
viewTypes['telemetry.plot.stacked'],
|
||||||
|
viewTypes['telemetry-view']
|
||||||
|
],
|
||||||
|
'telemetry-view-multi': [
|
||||||
|
viewTypes['telemetry.plot.overlay'],
|
||||||
|
viewTypes['telemetry.plot.stacked'],
|
||||||
|
viewTypes.table
|
||||||
|
],
|
||||||
|
'telemetry.plot.overlay-multi': [
|
||||||
|
viewTypes['telemetry.plot.stacked']
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
function getUserInput(form) {
|
function getUserInput(form) {
|
||||||
@ -415,6 +461,100 @@ define(['lodash'], function (_) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDuplicateButton(selectedParent, selectionPath, selection) {
|
||||||
|
return {
|
||||||
|
control: "button",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
icon: "icon-duplicate",
|
||||||
|
title: "Duplicate the selected object",
|
||||||
|
method: function () {
|
||||||
|
let duplicateItem = selectionPath[1].context.duplicateItem;
|
||||||
|
|
||||||
|
duplicateItem(selection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPropertyFromPath(object, path) {
|
||||||
|
let splitPath = path.split('.'),
|
||||||
|
property = Object.assign({}, object);
|
||||||
|
|
||||||
|
while (splitPath.length && property) {
|
||||||
|
property = property[splitPath.shift()];
|
||||||
|
}
|
||||||
|
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
function areAllViews(type, path, selection) {
|
||||||
|
let allTelemetry = true;
|
||||||
|
|
||||||
|
selection.forEach(selectedItem => {
|
||||||
|
let selectedItemContext = selectedItem[0].context;
|
||||||
|
|
||||||
|
if (getPropertyFromPath(selectedItemContext, path) !== type) {
|
||||||
|
allTelemetry = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return allTelemetry;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getViewSwitcherMenu(selectedParent, selectionPath, selection) {
|
||||||
|
if (selection.length === 1) {
|
||||||
|
let displayLayoutContext = selectionPath[1].context,
|
||||||
|
selectedItemContext = selectionPath[0].context,
|
||||||
|
selectedItemType = selectedItemContext.item.type;
|
||||||
|
|
||||||
|
if (selectedItemContext.layoutItem.type === 'telemetry-view') {
|
||||||
|
selectedItemType = 'telemetry-view';
|
||||||
|
}
|
||||||
|
|
||||||
|
let viewOptions = applicableViews[selectedItemType];
|
||||||
|
|
||||||
|
if (viewOptions) {
|
||||||
|
return {
|
||||||
|
control: "menu",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
icon: "icon-object",
|
||||||
|
title: "Switch the way this telemetry is displayed",
|
||||||
|
options: viewOptions,
|
||||||
|
method: function (option) {
|
||||||
|
displayLayoutContext.switchViewType(selectedItemContext, option.value, selection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else if (selection.length > 1) {
|
||||||
|
if (areAllViews('telemetry-view', 'layoutItem.type', selection)) {
|
||||||
|
let displayLayoutContext = selectionPath[1].context;
|
||||||
|
|
||||||
|
return {
|
||||||
|
control: "menu",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
icon: "icon-object",
|
||||||
|
title: "Merge into a telemetry table or plot",
|
||||||
|
options: applicableViews['telemetry-view-multi'],
|
||||||
|
method: function (option) {
|
||||||
|
displayLayoutContext.mergeMultipleTelemetryViews(selection, option.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else if (areAllViews('telemetry.plot.overlay', 'item.type', selection)) {
|
||||||
|
let displayLayoutContext = selectionPath[1].context;
|
||||||
|
|
||||||
|
return {
|
||||||
|
control: "menu",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
icon: "icon-object",
|
||||||
|
title: "Merge into a stacked plot",
|
||||||
|
options: applicableViews['telemetry.plot.overlay-multi'],
|
||||||
|
method: function (option) {
|
||||||
|
displayLayoutContext.mergeMultipleOverlayPlots(selection, option.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getSeparator() {
|
function getSeparator() {
|
||||||
return {
|
return {
|
||||||
control: "separator"
|
control: "separator"
|
||||||
@ -435,12 +575,14 @@ define(['lodash'], function (_) {
|
|||||||
'add-menu': [],
|
'add-menu': [],
|
||||||
'text': [],
|
'text': [],
|
||||||
'url': [],
|
'url': [],
|
||||||
|
'viewSwitcher': [],
|
||||||
'toggle-frame': [],
|
'toggle-frame': [],
|
||||||
'display-mode': [],
|
'display-mode': [],
|
||||||
'telemetry-value': [],
|
'telemetry-value': [],
|
||||||
'style': [],
|
'style': [],
|
||||||
'text-style': [],
|
'text-style': [],
|
||||||
'position': [],
|
'position': [],
|
||||||
|
'duplicate': [],
|
||||||
'remove': []
|
'remove': []
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -471,6 +613,9 @@ define(['lodash'], function (_) {
|
|||||||
if (toolbar.remove.length === 0) {
|
if (toolbar.remove.length === 0) {
|
||||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
|
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
|
||||||
}
|
}
|
||||||
|
if (toolbar.viewSwitcher.length === 0) {
|
||||||
|
toolbar.viewSwitcher = [getViewSwitcherMenu(selectedParent, selectionPath, selectedObjects)];
|
||||||
|
}
|
||||||
} else if (layoutItem.type === 'telemetry-view') {
|
} else if (layoutItem.type === 'telemetry-view') {
|
||||||
if (toolbar['display-mode'].length === 0) {
|
if (toolbar['display-mode'].length === 0) {
|
||||||
toolbar['display-mode'] = [getDisplayModeMenu(selectedParent, selectedObjects)];
|
toolbar['display-mode'] = [getDisplayModeMenu(selectedParent, selectedObjects)];
|
||||||
@ -495,6 +640,9 @@ define(['lodash'], function (_) {
|
|||||||
if (toolbar.remove.length === 0) {
|
if (toolbar.remove.length === 0) {
|
||||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
|
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
|
||||||
}
|
}
|
||||||
|
if (toolbar.viewSwitcher.length === 0) {
|
||||||
|
toolbar.viewSwitcher = [getViewSwitcherMenu(selectedParent, selectionPath, selectedObjects)];
|
||||||
|
}
|
||||||
} else if (layoutItem.type === 'text-view') {
|
} else if (layoutItem.type === 'text-view') {
|
||||||
if (toolbar['text-style'].length === 0) {
|
if (toolbar['text-style'].length === 0) {
|
||||||
toolbar['text-style'] = [
|
toolbar['text-style'] = [
|
||||||
@ -556,6 +704,9 @@ define(['lodash'], function (_) {
|
|||||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
|
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(toolbar.duplicate.length === 0) {
|
||||||
|
toolbar.duplicate = [getDuplicateButton(selectedParent, selectionPath, selectedObjects)];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let toolbarArray = Object.values(toolbar);
|
let toolbarArray = Object.values(toolbar);
|
||||||
|
@ -91,6 +91,13 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.context.index = newIndex;
|
this.context.index = newIndex;
|
||||||
|
},
|
||||||
|
item(newItem) {
|
||||||
|
if (!this.context) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context.layoutItem = newItem;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
:is="item.type"
|
:is="item.type"
|
||||||
v-for="(item, index) in layoutItems"
|
v-for="(item, index) in layoutItems"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
:ref="`layout-item-${item.id}`"
|
||||||
:item="item"
|
:item="item"
|
||||||
:grid-size="gridSize"
|
:grid-size="gridSize"
|
||||||
:init-select="initSelectIndex === index"
|
:init-select="initSelectIndex === index"
|
||||||
@ -92,6 +93,7 @@ const ORDERS = {
|
|||||||
bottom: Number.NEGATIVE_INFINITY
|
bottom: Number.NEGATIVE_INFINITY
|
||||||
};
|
};
|
||||||
const DRAG_OBJECT_TRANSFER_PREFIX = 'openmct/domain-object/';
|
const DRAG_OBJECT_TRANSFER_PREFIX = 'openmct/domain-object/';
|
||||||
|
const DUPLICATE_OFFSET = 3;
|
||||||
|
|
||||||
let components = ITEM_TYPE_VIEW_MAP;
|
let components = ITEM_TYPE_VIEW_MAP;
|
||||||
components['edit-marquee'] = EditMarquee;
|
components['edit-marquee'] = EditMarquee;
|
||||||
@ -301,9 +303,9 @@ export default {
|
|||||||
if (this.isTelemetry(domainObject)) {
|
if (this.isTelemetry(domainObject)) {
|
||||||
this.addItem('telemetry-view', domainObject, droppedObjectPosition);
|
this.addItem('telemetry-view', domainObject, droppedObjectPosition);
|
||||||
} else {
|
} else {
|
||||||
let identifier = this.openmct.objects.makeKeyString(domainObject.identifier);
|
let keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||||
|
|
||||||
if (!this.objectViewMap[identifier]) {
|
if (!this.objectViewMap[keyString]) {
|
||||||
this.addItem('subobject-view', domainObject, droppedObjectPosition);
|
this.addItem('subobject-view', domainObject, droppedObjectPosition);
|
||||||
} else {
|
} else {
|
||||||
let prompt = this.openmct.overlays.dialog({
|
let prompt = this.openmct.overlays.dialog({
|
||||||
@ -365,7 +367,8 @@ export default {
|
|||||||
let count = this.telemetryViewMap[keyString] || 0;
|
let count = this.telemetryViewMap[keyString] || 0;
|
||||||
this.telemetryViewMap[keyString] = ++count;
|
this.telemetryViewMap[keyString] = ++count;
|
||||||
} else if (item.type === "subobject-view") {
|
} else if (item.type === "subobject-view") {
|
||||||
this.objectViewMap[keyString] = true;
|
let count = this.objectViewMap[keyString] || 0;
|
||||||
|
this.objectViewMap[keyString] = ++count;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeItem(selectedItems) {
|
removeItem(selectedItems) {
|
||||||
@ -384,17 +387,25 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let keyString = this.openmct.objects.makeKeyString(item.identifier);
|
let keyString = this.openmct.objects.makeKeyString(item.identifier),
|
||||||
|
telemetryViewCount = this.telemetryViewMap[keyString],
|
||||||
|
objectViewCount = this.objectViewMap[keyString];
|
||||||
|
|
||||||
if (item.type === 'telemetry-view') {
|
if (item.type === 'telemetry-view') {
|
||||||
let count = --this.telemetryViewMap[keyString];
|
telemetryViewCount = --this.telemetryViewMap[keyString];
|
||||||
|
|
||||||
if (count === 0) {
|
if (telemetryViewCount === 0) {
|
||||||
delete this.telemetryViewMap[keyString];
|
delete this.telemetryViewMap[keyString];
|
||||||
this.removeFromComposition(keyString);
|
|
||||||
}
|
}
|
||||||
} else if (item.type === 'subobject-view') {
|
} else if (item.type === 'subobject-view') {
|
||||||
|
objectViewCount = --this.objectViewMap[keyString];
|
||||||
|
|
||||||
|
if (objectViewCount === 0) {
|
||||||
delete this.objectViewMap[keyString];
|
delete this.objectViewMap[keyString];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!telemetryViewCount && !objectViewCount) {
|
||||||
this.removeFromComposition(keyString);
|
this.removeFromComposition(keyString);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -411,12 +422,12 @@ export default {
|
|||||||
this.layoutItems.forEach(this.trackItem);
|
this.layoutItems.forEach(this.trackItem);
|
||||||
},
|
},
|
||||||
addChild(child) {
|
addChild(child) {
|
||||||
let identifier = this.openmct.objects.makeKeyString(child.identifier);
|
let keyString = this.openmct.objects.makeKeyString(child.identifier);
|
||||||
if (this.isTelemetry(child)) {
|
if (this.isTelemetry(child)) {
|
||||||
if (!this.telemetryViewMap[identifier]) {
|
if (!this.telemetryViewMap[keyString] && !this.objectViewMap[keyString]) {
|
||||||
this.addItem('telemetry-view', child);
|
this.addItem('telemetry-view', child);
|
||||||
}
|
}
|
||||||
} else if (!this.objectViewMap[identifier]) {
|
} else if (!this.objectViewMap[keyString]) {
|
||||||
this.addItem('subobject-view', child);
|
this.addItem('subobject-view', child);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -515,6 +526,180 @@ export default {
|
|||||||
let index = this.layoutItems.findIndex(item);
|
let index = this.layoutItems.findIndex(item);
|
||||||
item.format = format;
|
item.format = format;
|
||||||
this.mutate(`configuration.items[${index}]`, item);
|
this.mutate(`configuration.items[${index}]`, item);
|
||||||
|
},
|
||||||
|
createNewDomainObject(domainObject, composition, viewType, nameExtension, model) {
|
||||||
|
let identifier = {
|
||||||
|
key: uuid(),
|
||||||
|
namespace: domainObject.identifier.namespace
|
||||||
|
},
|
||||||
|
type = this.openmct.types.get(viewType),
|
||||||
|
parentKeyString = this.openmct.objects.makeKeyString(this.internalDomainObject.identifier),
|
||||||
|
objectName = nameExtension ? `${domainObject.name}-${nameExtension}` : domainObject.name,
|
||||||
|
object = {};
|
||||||
|
|
||||||
|
if (model) {
|
||||||
|
object = _.cloneDeep(model);
|
||||||
|
} else {
|
||||||
|
object.type = viewType;
|
||||||
|
type.definition.initialize(object);
|
||||||
|
object.composition.push(...composition);
|
||||||
|
}
|
||||||
|
|
||||||
|
object.name = objectName;
|
||||||
|
object.identifier = identifier;
|
||||||
|
object.location = parentKeyString;
|
||||||
|
|
||||||
|
this.openmct.objects.mutate(object, 'persisted', Date.now());
|
||||||
|
|
||||||
|
return object;
|
||||||
|
},
|
||||||
|
convertToTelemetryView(identifier, position) {
|
||||||
|
this.openmct.objects.get(identifier).then((domainObject) => {
|
||||||
|
this.composition.add(domainObject);
|
||||||
|
this.addItem('telemetry-view', domainObject, position);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
dispatchMultipleSelection(selectItemsArray) {
|
||||||
|
let event = new MouseEvent('click', {
|
||||||
|
bubbles: true,
|
||||||
|
shiftKey: true,
|
||||||
|
cancelable: true,
|
||||||
|
view: window
|
||||||
|
})
|
||||||
|
|
||||||
|
selectItemsArray.forEach((id) => {
|
||||||
|
let refId = `layout-item-${id}`,
|
||||||
|
component = this.$refs[refId] && this.$refs[refId][0];
|
||||||
|
|
||||||
|
if (component) {
|
||||||
|
component.immediatelySelect = event;
|
||||||
|
component.$el.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
duplicateItem(selectedItems) {
|
||||||
|
let objectStyles = this.internalDomainObject.configuration.objectStyles || {},
|
||||||
|
selectItemsArray = [],
|
||||||
|
newDomainObjectsArray = [];
|
||||||
|
|
||||||
|
selectedItems.forEach(selectedItem => {
|
||||||
|
let layoutItem = selectedItem[0].context.layoutItem,
|
||||||
|
domainObject = selectedItem[0].context.item,
|
||||||
|
layoutItemStyle = objectStyles[layoutItem.id],
|
||||||
|
copy = _.cloneDeep(layoutItem);
|
||||||
|
|
||||||
|
copy.id = uuid();
|
||||||
|
selectItemsArray.push(copy.id);
|
||||||
|
|
||||||
|
let offsetKeys = ['x', 'y'];
|
||||||
|
|
||||||
|
if (copy.type === 'line-view') {
|
||||||
|
offsetKeys = offsetKeys.concat(['x2', 'y2']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copy.type === 'subobject-view') {
|
||||||
|
let newDomainObject = this.createNewDomainObject(domainObject, domainObject.composition, domainObject.type, 'duplicate', domainObject);
|
||||||
|
|
||||||
|
newDomainObjectsArray.push(newDomainObject);
|
||||||
|
copy.identifier = newDomainObject.identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
offsetKeys.forEach(key => {
|
||||||
|
copy[key] += DUPLICATE_OFFSET
|
||||||
|
});
|
||||||
|
|
||||||
|
if (layoutItemStyle) {
|
||||||
|
objectStyles[copy.id] = layoutItemStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.trackItem(copy);
|
||||||
|
this.layoutItems.push(copy);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.openmct.objects.mutate(this.internalDomainObject, "configuration.items", this.layoutItems);
|
||||||
|
this.openmct.objects.mutate(this.internalDomainObject, "configuration.objectStyles", objectStyles);
|
||||||
|
this.$el.click(); //clear selection;
|
||||||
|
|
||||||
|
newDomainObjectsArray.forEach(domainObject => {
|
||||||
|
this.composition.add(domainObject);
|
||||||
|
});
|
||||||
|
this.dispatchMultipleSelection(selectItemsArray);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
mergeMultipleTelemetryViews(selection, viewType) {
|
||||||
|
let identifiers = selection.map(selectedItem => {
|
||||||
|
return selectedItem[0].context.layoutItem.identifier;
|
||||||
|
}),
|
||||||
|
firstDomainObject = selection[0][0].context.item,
|
||||||
|
firstLayoutItem = selection[0][0].context.layoutItem,
|
||||||
|
position = [firstLayoutItem.x, firstLayoutItem.y],
|
||||||
|
mockDomainObject = {
|
||||||
|
name: 'Merged Telemetry Views',
|
||||||
|
identifier: firstDomainObject.identifier
|
||||||
|
},
|
||||||
|
newDomainObject = this.createNewDomainObject(mockDomainObject, identifiers, viewType);
|
||||||
|
|
||||||
|
this.composition.add(newDomainObject);
|
||||||
|
this.addItem('subobject-view', newDomainObject, position);
|
||||||
|
this.removeItem(selection);
|
||||||
|
this.initSelectIndex = this.layoutItems.length - 1;
|
||||||
|
},
|
||||||
|
mergeMultipleOverlayPlots(selection, viewType) {
|
||||||
|
let overlayPlots = selection.map(selectedItem => selectedItem[0].context.item),
|
||||||
|
overlayPlotIdentifiers = overlayPlots.map(overlayPlot => overlayPlot.identifier),
|
||||||
|
firstOverlayPlot = overlayPlots[0],
|
||||||
|
firstLayoutItem = selection[0][0].context.layoutItem,
|
||||||
|
position = [firstLayoutItem.x, firstLayoutItem.y],
|
||||||
|
mockDomainObject = {
|
||||||
|
name: 'Merged Overlay Plots',
|
||||||
|
identifier: firstOverlayPlot.identifier
|
||||||
|
},
|
||||||
|
newDomainObject = this.createNewDomainObject(mockDomainObject, overlayPlotIdentifiers, viewType),
|
||||||
|
newDomainObjectKeyString = this.openmct.objects.makeKeyString(newDomainObject.identifier),
|
||||||
|
internalDomainObjectKeyString = this.openmct.objects.makeKeyString(this.internalDomainObject.identifier);
|
||||||
|
|
||||||
|
this.composition.add(newDomainObject);
|
||||||
|
this.addItem('subobject-view', newDomainObject, position);
|
||||||
|
|
||||||
|
overlayPlots.forEach(overlayPlot => {
|
||||||
|
if (overlayPlot.location === internalDomainObjectKeyString) {
|
||||||
|
this.openmct.objects.mutate(overlayPlot, 'location', newDomainObjectKeyString);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.removeItem(selection);
|
||||||
|
this.initSelectIndex = this.layoutItems.length - 1;
|
||||||
|
},
|
||||||
|
switchViewType(context, viewType, selection) {
|
||||||
|
let domainObject = context.item,
|
||||||
|
layoutItem = context.layoutItem,
|
||||||
|
position = [layoutItem.x, layoutItem.y],
|
||||||
|
newDomainObject,
|
||||||
|
layoutType = 'subobject-view';
|
||||||
|
|
||||||
|
if (layoutItem.type === 'telemetry-view') {
|
||||||
|
newDomainObject = this.createNewDomainObject(domainObject, [domainObject.identifier], viewType);
|
||||||
|
} else {
|
||||||
|
if (viewType !== 'telemetry-view') {
|
||||||
|
newDomainObject = this.createNewDomainObject(domainObject, domainObject.composition, viewType);
|
||||||
|
} else {
|
||||||
|
domainObject.composition.forEach((identifier , index) => {
|
||||||
|
let positionX = position[0] + (index * DUPLICATE_OFFSET),
|
||||||
|
positionY = position[1] + (index * DUPLICATE_OFFSET);
|
||||||
|
|
||||||
|
this.convertToTelemetryView(identifier, [positionX, positionY]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newDomainObject) {
|
||||||
|
this.composition.add(newDomainObject);
|
||||||
|
this.addItem(layoutType, newDomainObject, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.removeItem(selection);
|
||||||
|
this.initSelectIndex = this.layoutItems.length - 1; //restore selection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,13 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.context.index = newIndex;
|
this.context.index = newIndex;
|
||||||
|
},
|
||||||
|
item(newItem) {
|
||||||
|
if (!this.context) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context.layoutItem = newItem;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -194,6 +194,13 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.context.index = newIndex;
|
this.context.index = newIndex;
|
||||||
|
},
|
||||||
|
item(newItem) {
|
||||||
|
if (!this.context) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context.layoutItem = newItem;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -61,7 +61,7 @@ function hasFrameByDefault(type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
makeDefinition(openmct, gridSize, domainObject, position) {
|
makeDefinition(openmct, gridSize, domainObject, position, viewKey) {
|
||||||
let defaultDimensions = getDefaultDimensions(gridSize);
|
let defaultDimensions = getDefaultDimensions(gridSize);
|
||||||
position = position || DEFAULT_POSITION;
|
position = position || DEFAULT_POSITION;
|
||||||
|
|
||||||
@ -71,7 +71,8 @@ export default {
|
|||||||
x: position[0],
|
x: position[0],
|
||||||
y: position[1],
|
y: position[1],
|
||||||
identifier: domainObject.identifier,
|
identifier: domainObject.identifier,
|
||||||
hasFrame: hasFrameByDefault(domainObject.type)
|
hasFrame: hasFrameByDefault(domainObject.type),
|
||||||
|
viewKey
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: ['openmct', 'objectPath'],
|
inject: ['openmct', 'objectPath'],
|
||||||
@ -109,6 +110,13 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.context.index = newIndex;
|
this.context.index = newIndex;
|
||||||
|
},
|
||||||
|
item(newItem) {
|
||||||
|
if (!this.context) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context.layoutItem = newItem;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -131,7 +139,8 @@ export default {
|
|||||||
childContext.index = this.index;
|
childContext.index = this.index;
|
||||||
this.context = childContext;
|
this.context = childContext;
|
||||||
this.removeSelectable = this.openmct.selection.selectable(
|
this.removeSelectable = this.openmct.selection.selectable(
|
||||||
this.$el, this.context, this.initSelect);
|
this.$el, this.context, this.immediatelySelect || this.initSelect);
|
||||||
|
delete this.immediatelySelect;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,6 +168,10 @@ export default {
|
|||||||
this.context.index = newIndex;
|
this.context.index = newIndex;
|
||||||
},
|
},
|
||||||
item(newItem) {
|
item(newItem) {
|
||||||
|
if (!this.context) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.context.layoutItem = newItem;
|
this.context.layoutItem = newItem;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -242,7 +246,8 @@ export default {
|
|||||||
updateTelemetryFormat: this.updateTelemetryFormat
|
updateTelemetryFormat: this.updateTelemetryFormat
|
||||||
};
|
};
|
||||||
this.removeSelectable = this.openmct.selection.selectable(
|
this.removeSelectable = this.openmct.selection.selectable(
|
||||||
this.$el, this.context, this.initSelect);
|
this.$el, this.context, this.immediatelySelect || this.initSelect);
|
||||||
|
delete this.immediatelySelect;
|
||||||
},
|
},
|
||||||
updateTelemetryFormat(format) {
|
updateTelemetryFormat(format) {
|
||||||
this.$emit('formatChanged', this.item, format);
|
this.$emit('formatChanged', this.item, format);
|
||||||
|
@ -91,6 +91,13 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.context.index = newIndex;
|
this.context.index = newIndex;
|
||||||
|
},
|
||||||
|
item(newItem) {
|
||||||
|
if (!this.context) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context.layoutItem = newItem;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -66,8 +66,12 @@ export default function DisplayLayoutPlugin(options) {
|
|||||||
supportsMultiSelect: true,
|
supportsMultiSelect: true,
|
||||||
addElement: component && component.$refs.displayLayout.addElement,
|
addElement: component && component.$refs.displayLayout.addElement,
|
||||||
removeItem: component && component.$refs.displayLayout.removeItem,
|
removeItem: component && component.$refs.displayLayout.removeItem,
|
||||||
orderItem: component && component.$refs.displayLayout.orderItem
|
orderItem: component && component.$refs.displayLayout.orderItem,
|
||||||
}
|
duplicateItem: component && component.$refs.displayLayout.duplicateItem,
|
||||||
|
switchViewType: component && component.$refs.displayLayout.switchViewType,
|
||||||
|
mergeMultipleTelemetryViews: component && component.$refs.displayLayout.mergeMultipleTelemetryViews,
|
||||||
|
mergeMultipleOverlayPlots: component && component.$refs.displayLayout.mergeMultipleOverlayPlots
|
||||||
|
};
|
||||||
},
|
},
|
||||||
destroy() {
|
destroy() {
|
||||||
component.$destroy();
|
component.$destroy();
|
||||||
|
@ -28,8 +28,10 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
ConfigStore.prototype.deleteStore = function (id) {
|
ConfigStore.prototype.deleteStore = function (id) {
|
||||||
|
if (this.store[id]) {
|
||||||
this.store[id].destroy();
|
this.store[id].destroy();
|
||||||
delete this.store[id];
|
delete this.store[id];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ConfigStore.prototype.add = function (id, config) {
|
ConfigStore.prototype.add = function (id, config) {
|
||||||
|
@ -185,7 +185,7 @@ define([
|
|||||||
plugins.FolderView = FolderView;
|
plugins.FolderView = FolderView;
|
||||||
plugins.Tabs = Tabs;
|
plugins.Tabs = Tabs;
|
||||||
plugins.FlexibleLayout = FlexibleLayout;
|
plugins.FlexibleLayout = FlexibleLayout;
|
||||||
plugins.LADTable = LADTable;
|
plugins.LADTable = LADTable.default;
|
||||||
plugins.Filters = Filters;
|
plugins.Filters = Filters;
|
||||||
plugins.ObjectMigration = ObjectMigration.default;
|
plugins.ObjectMigration = ObjectMigration.default;
|
||||||
plugins.GoToOriginalAction = GoToOriginalAction.default;
|
plugins.GoToOriginalAction = GoToOriginalAction.default;
|
||||||
|
@ -238,10 +238,13 @@ define(
|
|||||||
context.item = newItem;
|
context.item = newItem;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (select) {
|
if (select) {
|
||||||
|
if (typeof select === 'object') {
|
||||||
|
element.dispatchEvent(select);
|
||||||
|
} else if (typeof select === 'boolean') {
|
||||||
element.click();
|
element.click();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return function () {
|
return function () {
|
||||||
element.removeEventListener('click', capture, true);
|
element.removeEventListener('click', capture, true);
|
||||||
|
@ -239,6 +239,7 @@ $glyph-icon-spectra-telemetry: '\eb25';
|
|||||||
$glyph-icon-command: '\eb26';
|
$glyph-icon-command: '\eb26';
|
||||||
$glyph-icon-conditional: '\eb27';
|
$glyph-icon-conditional: '\eb27';
|
||||||
$glyph-icon-condition-widget: '\eb28';
|
$glyph-icon-condition-widget: '\eb28';
|
||||||
|
$glyph-icon-alphanumeric: '\eb29';
|
||||||
|
|
||||||
/************************** GLYPHS AS DATA URI */
|
/************************** GLYPHS AS DATA URI */
|
||||||
// Only objects have been converted, for use in Create menu and folder views
|
// Only objects have been converted, for use in Create menu and folder views
|
||||||
|
@ -175,6 +175,7 @@
|
|||||||
.icon-command { @include glyphBefore($glyph-icon-command); }
|
.icon-command { @include glyphBefore($glyph-icon-command); }
|
||||||
.icon-conditional { @include glyphBefore($glyph-icon-conditional); }
|
.icon-conditional { @include glyphBefore($glyph-icon-conditional); }
|
||||||
.icon-condition-widget { @include glyphBefore($glyph-icon-condition-widget); }
|
.icon-condition-widget { @include glyphBefore($glyph-icon-condition-widget); }
|
||||||
|
.icon-alphanumeric { @include glyphBefore($glyph-icon-alphanumeric); }
|
||||||
|
|
||||||
/************************** 12 PX CLASSES */
|
/************************** 12 PX CLASSES */
|
||||||
// TODO: sync with 16px redo as of 10/25/18
|
// TODO: sync with 16px redo as of 10/25/18
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -143,4 +143,5 @@
|
|||||||
<glyph unicode="" glyph-name="icon-pushbutton" d="M370.2 372.6c9.326-8.53 19.666-16.261 30.729-22.914l0.871-0.486c-11.077 19.209-17.664 42.221-17.8 66.76v0.040c0 39.6 17.8 77.6 50.2 107.4 37 34 87.4 52.6 141.8 52.6 40.2 0 78.2-10.2 110.2-29.2-8.918 15.653-19.693 29.040-32.268 40.482l-0.132 0.118c-37 34-87.4 52.6-141.8 52.6s-104.8-18.6-141.8-52.6c-32.4-29.8-50.2-67.8-50.2-107.4s17.8-77.6 50.2-107.4zM885.4 562.4c-40.6 154.6-192.4 269.6-373.4 269.6s-332.8-115-373.4-269.6c-86-80-138.6-187.8-138.6-306.4 0-247.4 229.2-448 512-448s512 200.6 512 448c0 118.6-52.6 226.4-138.6 306.4zM512 704c141.2 0 256-100.4 256-224s-114.8-224-256-224-256 100.4-256 224 114.8 224 256 224zM512 0c-175.4 0-318.4 127.8-320 285.4 68.8-94.8 186.4-157.4 320-157.4s251.2 62.6 320 157.4c-1.6-157.6-144.6-285.4-320-285.4z" />
|
<glyph unicode="" glyph-name="icon-pushbutton" d="M370.2 372.6c9.326-8.53 19.666-16.261 30.729-22.914l0.871-0.486c-11.077 19.209-17.664 42.221-17.8 66.76v0.040c0 39.6 17.8 77.6 50.2 107.4 37 34 87.4 52.6 141.8 52.6 40.2 0 78.2-10.2 110.2-29.2-8.918 15.653-19.693 29.040-32.268 40.482l-0.132 0.118c-37 34-87.4 52.6-141.8 52.6s-104.8-18.6-141.8-52.6c-32.4-29.8-50.2-67.8-50.2-107.4s17.8-77.6 50.2-107.4zM885.4 562.4c-40.6 154.6-192.4 269.6-373.4 269.6s-332.8-115-373.4-269.6c-86-80-138.6-187.8-138.6-306.4 0-247.4 229.2-448 512-448s512 200.6 512 448c0 118.6-52.6 226.4-138.6 306.4zM512 704c141.2 0 256-100.4 256-224s-114.8-224-256-224-256 100.4-256 224 114.8 224 256 224zM512 0c-175.4 0-318.4 127.8-320 285.4 68.8-94.8 186.4-157.4 320-157.4s251.2 62.6 320 157.4c-1.6-157.6-144.6-285.4-320-285.4z" />
|
||||||
<glyph unicode="" glyph-name="icon-conditional" d="M512 832c-282.76 0-512-229.24-512-512s229.24-512 512-512 512 229.24 512 512-229.24 512-512 512zM512 64l-384 256 384 256 384-256z" />
|
<glyph unicode="" glyph-name="icon-conditional" d="M512 832c-282.76 0-512-229.24-512-512s229.24-512 512-512 512 229.24 512 512-229.24 512-512 512zM512 64l-384 256 384 256 384-256z" />
|
||||||
<glyph unicode="" glyph-name="icon-condition-widget" d="M832 832h-640c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h640c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM512 64l-384 256 384 256 384-256z" />
|
<glyph unicode="" glyph-name="icon-condition-widget" d="M832 832h-640c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h640c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM512 64l-384 256 384 256 384-256z" />
|
||||||
|
<glyph unicode="" glyph-name="icon-alphanumeric" d="M535.6 301.4c-8.4-1.6-17.2-3-26.2-4s-18.2-2.4-27.2-4c-10.196-1.861-18.808-4.010-27.21-6.633l1.61 0.433c-8.609-2.674-16.105-6.348-22.89-10.987l0.29 0.187c-6.693-4.517-12.283-10.107-16.663-16.585l-0.137-0.215c-4.6-6.8-7.4-15.6-8.8-26s-0.4-18.4 2.4-25.2c2.746-6.688 7.224-12.195 12.881-16.122l0.119-0.078c5.967-4.053 13.057-6.94 20.704-8.161l0.296-0.039c7.592-1.527 16.319-2.4 25.25-2.4 0.123 0 0.246 0 0.369 0h-0.019c22.2 0 39.6 3.6 52.6 11s23.2 16.2 30.2 26.4c6.273 8.873 11.271 19.191 14.426 30.285l0.174 0.715c1.853 6.809 3.601 15.41 4.855 24.169l0.145 1.231 5.2 41.6c-5.4-4.217-11.723-7.564-18.583-9.689l-0.417-0.111c-6.489-2.241-14.362-4.255-22.444-5.662l-0.956-0.138zM1024 448v192h-152l24 192h-192l-24-192h-256l24 192h-192l-24-192h-232v-192h208l-32-256h-176v-192h152l-24-192h192l24 192h256l-24-192h192l24 192h232v192h-208l32 256zM702.8 420.2l-26.4-211.8c-2.231-15.809-3.537-34.122-3.6-52.727v-0.073c0-16.8 2.2-29.4 6.4-37.8h-113.4c-1.342 5.556-2.338 12.122-2.781 18.84l-0.019 0.36c-0.261 3.524-0.409 7.634-0.409 11.778 0 2.962 0.076 5.907 0.226 8.832l-0.017-0.41c-18.663-17.401-41.395-30.694-66.597-38.289l-1.203-0.311c-22.627-6.956-48.639-10.974-75.586-11h-0.014c-0.764-0.011-1.666-0.018-2.569-0.018-18.098 0-35.598 2.563-52.156 7.345l1.325-0.328c-15.991 4.512-29.851 12.090-41.545 22.122l0.145-0.122c-11.233 9.982-19.792 22.733-24.624 37.192l-0.176 0.608c-5.2 15.2-6.4 33.4-3.8 54.4s9.4 42.2 19.4 57.2c9.524 14.399 21.535 26.346 35.532 35.512l0.468 0.288c13.387 8.662 28.922 15.533 45.512 19.765l1.088 0.235c13.436 3.792 30.801 7.554 48.47 10.41l2.93 0.39c17 2.6 33.8 4.6 50.4 6.2 16.628 1.527 31.69 4.070 46.349 7.643l-2.149-0.443c13 3 23.6 7.6 31.6 13.6s12.6 15 13.6 26.4 0.8 21.8-2.4 28.8c-2.849 6.902-7.542 12.56-13.468 16.517l-0.132 0.083c-6.217 4.011-13.604 6.78-21.543 7.774l-0.257 0.026c-7.897 1.277-17 2.007-26.274 2.007-0.537 0-1.073-0.002-1.609-0.007l0.082 0.001c-22 0-40-4.6-53.8-14.2s-23-25.2-28-47.2h-111.8c4.8 26.2 14.2 48 27.8 65.4 13.475 16.978 29.89 30.968 48.574 41.377l0.826 0.423c18.192 10.038 39.297 17.806 61.619 22.175l1.381 0.225c20.488 4.162 44.053 6.563 68.171 6.6h0.029c21.8-0.005 43.239-1.532 64.222-4.479l-2.422 0.279c20.641-2.809 39.324-8.783 56.401-17.461l-1.001 0.461c15.909-8.108 28.858-20.031 37.967-34.601l0.233-0.399c9-15 12.2-34.8 9-59.6z" />
|
||||||
</font></defs></svg>
|
</font></defs></svg>
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 54 KiB |
Binary file not shown.
Binary file not shown.
@ -21,7 +21,8 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
import MCT from 'MCT';
|
import MCT from 'MCT';
|
||||||
let nativeFunctions = [];
|
let nativeFunctions = [],
|
||||||
|
mockObjects = setMockObjects();
|
||||||
|
|
||||||
export function createOpenMct() {
|
export function createOpenMct() {
|
||||||
const openmct = new MCT();
|
const openmct = new MCT();
|
||||||
@ -68,3 +69,205 @@ export function resetApplicationState(openmct) {
|
|||||||
function clearBuiltinSpy(funcDefinition) {
|
function clearBuiltinSpy(funcDefinition) {
|
||||||
funcDefinition.object[funcDefinition.functionName] = funcDefinition.nativeFunction;
|
funcDefinition.object[funcDefinition.functionName] = funcDefinition.nativeFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getLatestTelemetry(telemetry = [], opts = {}) {
|
||||||
|
let latest = [],
|
||||||
|
timeFormat = opts.timeFormat || 'utc';
|
||||||
|
|
||||||
|
if(telemetry.length) {
|
||||||
|
latest = telemetry.reduce((prev, cur) => {
|
||||||
|
return prev[timeFormat] > cur[timeFormat] ? prev : cur;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return latest;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXAMPLE:
|
||||||
|
// getMockObjects({
|
||||||
|
// name: 'Jamie Telemetry',
|
||||||
|
// keys: ['test','other','yeah','sup'],
|
||||||
|
// format: 'local',
|
||||||
|
// telemetryConfig: {
|
||||||
|
// hints: {
|
||||||
|
// test: {
|
||||||
|
// domain: 1
|
||||||
|
// },
|
||||||
|
// other: {
|
||||||
|
// range: 2
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
export function getMockObjects(opts = {}) {
|
||||||
|
opts.type = opts.type || 'default';
|
||||||
|
if(opts.objectKeyStrings && !Array.isArray(opts.objectKeyStrings)) {
|
||||||
|
throw `"getMockObjects" optional parameter "objectKeyStrings" must be an array of string object keys`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let requestedMocks = {};
|
||||||
|
|
||||||
|
if (!opts.objectKeyStrings) {
|
||||||
|
requestedMocks = copyObj(mockObjects[opts.type]);
|
||||||
|
} else {
|
||||||
|
opts.objectKeyStrings.forEach(objKey => {
|
||||||
|
if(mockObjects[opts.type] && mockObjects[opts.type][objKey]) {
|
||||||
|
requestedMocks[objKey] = copyObj(mockObjects[opts.type][objKey]);
|
||||||
|
} else {
|
||||||
|
throw `No mock object for object key "${objKey}" of type "${opts.type}"`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// build out custom telemetry mappings if necessary
|
||||||
|
if(requestedMocks.telemetry && opts.telemetryConfig) {
|
||||||
|
let keys = opts.telemetryConfig.keys,
|
||||||
|
format = opts.telemetryConfig.format || 'utc',
|
||||||
|
hints = opts.telemetryConfig.hints,
|
||||||
|
values;
|
||||||
|
|
||||||
|
// if utc, keep default
|
||||||
|
if(format === 'utc') {
|
||||||
|
// save for later if new keys
|
||||||
|
if(keys) {
|
||||||
|
format = requestedMocks.telemetry
|
||||||
|
.telemetry.values.find((vals) => vals.key === 'utc');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
format = {
|
||||||
|
key: format,
|
||||||
|
name: "Time",
|
||||||
|
format: format === 'local' ? 'local-format' : format,
|
||||||
|
hints: {
|
||||||
|
domain: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(keys) {
|
||||||
|
values = keys.map((key) => ({ key, name: key + ' attribute' }));
|
||||||
|
values.push(format); // add time format back in
|
||||||
|
} else {
|
||||||
|
values = requestedMocks.telemetry.telemetry.values;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hints) {
|
||||||
|
for(let val of values) {
|
||||||
|
if(hints[val.key]) {
|
||||||
|
val.hints = hints[val.key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requestedMocks.telemetry.telemetry.values = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
// overwrite any field keys
|
||||||
|
if(opts.overwrite) {
|
||||||
|
for(let mock in requestedMocks) {
|
||||||
|
if(opts.overwrite[mock]) {
|
||||||
|
for(let key in opts.overwrite[mock]) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(opts.overwrite[mock], key)) {
|
||||||
|
requestedMocks[mock][key] = opts.overwrite[mock][key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestedMocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXAMPLE:
|
||||||
|
// getMockTelemetry({
|
||||||
|
// name: 'My Telemetry',
|
||||||
|
// keys: ['test','other','yeah','sup'],
|
||||||
|
// count: 8,
|
||||||
|
// format: 'local'
|
||||||
|
// })
|
||||||
|
export function getMockTelemetry(opts = {}) {
|
||||||
|
let count = opts.count || 2,
|
||||||
|
format = opts.format || 'utc',
|
||||||
|
name = opts.name || 'Mock Telemetry Datum',
|
||||||
|
keyCount = 2,
|
||||||
|
keys = false,
|
||||||
|
telemetry = [];
|
||||||
|
|
||||||
|
if(opts.keys && Array.isArray(opts.keys)) {
|
||||||
|
keyCount = opts.keys.length;
|
||||||
|
keys = opts.keys;
|
||||||
|
} else if(opts.keyCount) {
|
||||||
|
keyCount = opts.keyCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(let i = 1; i < count + 1; i++) {
|
||||||
|
let datum = {
|
||||||
|
[format]: i,
|
||||||
|
name
|
||||||
|
}
|
||||||
|
|
||||||
|
for(let k = 1; k < keyCount + 1; k++) {
|
||||||
|
let key = keys ? keys[k - 1] : 'some-key-' + k,
|
||||||
|
value = keys ? keys[k - 1] + ' value ' + i : 'some value ' + i + '-' + k;
|
||||||
|
datum[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
telemetry.push(datum);
|
||||||
|
}
|
||||||
|
|
||||||
|
return telemetry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy objects a bit more easily
|
||||||
|
function copyObj(obj) {
|
||||||
|
return JSON.parse(JSON.stringify(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
// add any other necessary types to this mockObjects object
|
||||||
|
function setMockObjects() {
|
||||||
|
return {
|
||||||
|
default: {
|
||||||
|
ladTable: {
|
||||||
|
identifier: { namespace: "", key: "lad-object"},
|
||||||
|
type: 'LadTable',
|
||||||
|
composition: []
|
||||||
|
},
|
||||||
|
ladTableSet: {
|
||||||
|
identifier: { namespace: "", key: "lad-set-object"},
|
||||||
|
type: 'LadTableSet',
|
||||||
|
composition: []
|
||||||
|
},
|
||||||
|
telemetry: {
|
||||||
|
identifier: { namespace: "", key: "telemetry-object"},
|
||||||
|
type: "test-telemetry-object",
|
||||||
|
name: "Test Telemetry Object",
|
||||||
|
telemetry: {
|
||||||
|
values: [{
|
||||||
|
key: "name",
|
||||||
|
name: "Name",
|
||||||
|
format: "string"
|
||||||
|
},{
|
||||||
|
key: "utc",
|
||||||
|
name: "Time",
|
||||||
|
format: "utc",
|
||||||
|
hints: {
|
||||||
|
domain: 1
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
name: "Some attribute 1",
|
||||||
|
key: "some-key-1",
|
||||||
|
hints: {
|
||||||
|
range: 1
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
name: "Some attribute 2",
|
||||||
|
key: "some-key-2"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
otherType: {
|
||||||
|
example: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user