Compare commits

..

1 Commits

Author SHA1 Message Date
Henry Hsu
ccec5e8788 add mmgis plugin 2021-07-15 14:43:33 -07:00
15 changed files with 173 additions and 242 deletions

View File

@@ -185,6 +185,7 @@
}
]
}));
openmct.install(openmct.plugins.Mmgis({url: 'http://localhost:8888'}));
openmct.install(openmct.plugins.SummaryWidget());
openmct.install(openmct.plugins.Notebook());
openmct.install(openmct.plugins.LADTable());

View File

@@ -1,8 +1,10 @@
{
"name": "openmct",
"version": "1.7.6-SNAPSHOT",
"version": "1.7.4",
"description": "The Open MCT core platform",
"dependencies": {},
"dependencies": {
"openmct-mmgis": "git+https://trunk.arc.nasa.gov/bitbucket/scm/vipergds/openmct-mmgis.git#api-mmgis-inspector"
},
"devDependencies": {
"angular": ">=1.8.0",
"angular-route": "1.4.14",
@@ -37,18 +39,17 @@
"html2canvas": "^1.0.0-rc.7",
"imports-loader": "^0.8.0",
"istanbul-instrumenter-loader": "^3.0.1",
"jasmine-core": "^3.7.1",
"jasmine-core": "^3.1.0",
"jsdoc": "^3.3.2",
"karma": "6.3.4",
"karma": "5.1.1",
"karma-chrome-launcher": "3.1.0",
"karma-firefox-launcher": "2.1.0",
"karma-cli": "2.0.0",
"karma-coverage": "2.0.3",
"karma-coverage-istanbul-reporter": "3.0.3",
"karma-junit-reporter": "2.0.1",
"karma-firefox-launcher": "1.3.0",
"karma-html-reporter": "0.2.7",
"karma-jasmine": "4.0.1",
"karma-sourcemap-loader": "0.3.8",
"karma-jasmine": "3.3.1",
"karma-sourcemap-loader": "0.3.7",
"karma-webpack": "4.0.2",
"location-bar": "^3.0.1",
"lodash": "^4.17.12",
@@ -90,7 +91,6 @@
"test": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --single-run",
"test:debug": "cross-env NODE_ENV=debug karma start --no-single-run",
"test:coverage": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" COVERAGE=true karma start --single-run",
"test:coverage:firefox": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --single-run --browsers=FirefoxHeadless",
"test:watch": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --no-single-run",
"verify": "concurrently 'npm:test' 'npm:lint'",
"jsdoc": "jsdoc -c jsdoc.json -R API.md -r -d dist/docs/api",
@@ -102,9 +102,6 @@
"type": "git",
"url": "https://github.com/nasa/openmct.git"
},
"engines": {
"node": ">=10.10.2 <16.0.0"
},
"author": "",
"license": "Apache-2.0",
"private": true

View File

@@ -0,0 +1,70 @@
This bundle provides the Timeline domain object type, as well
as other associated domain object types and relevant views.
# Implementation notes
## Model Properties
The properties below record properties relevant to using and
understanding timelines based on their JSON representation.
Additional common properties, such as `modified`
or `persisted` timestamps, may also be present.
### Timeline Model
A timeline's model looks like:
```
{
"type": "timeline",
"start": {
"timestamp": <number> (milliseconds since epoch),
"epoch": <string> (currently, always "SET")
},
"capacity": <number> (optional; battery capacity in watt-hours)
"composition": <string[]> (array of identifiers for contained objects)
}
```
The identifiers in a timeline's `composition` field should refer to
other Timeline objects, or to Activity objects.
### Activity Model
An activity's model looks like:
```
{
"type": "activity",
"start": {
"timestamp": <number> (milliseconds since epoch),
"epoch": <string> (currently, always "SET")
},
"duration": {
"timestamp": <number> (duration of this activity, in milliseconds)
"epoch": "SET" (this is ignored)
},
"relationships": {
"modes": <string[]> (array of applicable Activity Mode ids)
},
"link": <string> (optional; URL linking to associated external resource)
"composition": <string[]> (array of identifiers for contained objects)
}
```
The identifiers in a timeline's `composition` field should only refer to
other Activity objects.
### Activity Mode Model
An activity mode's model looks like:
```
{
"type": "mode",
"resources": {
"comms": <number> (communications utilization, in Kbps)
"power": <number> (power utilization, in watts)
}
}
```

View File

@@ -0,0 +1,52 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, 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.
*****************************************************************************/
define([
"./res/templates/deprecated-timeline-message.html"
], function (
deprecatedTimelineMessage
) {
return {
name: 'platform/features/timeline',
definition: {
extensions: {
types: [
{
key: "timeline",
name: "Timeline",
description: "Timeline, Activity and Activity Mode objects have been deprecated and will no longer be supported. (07/18/2018)",
priority: 502
}
],
views: [
{
key: "timeline",
name: "Timeline",
type: "timeline",
description: "Timeline, Activity and Activity Mode objects have been deprecated and will no longer be supported. (07/18/2018)",
template: deprecatedTimelineMessage
}
]
}
}
};
});

View File

@@ -0,0 +1,10 @@
<div>
Timeline, Activity and Activity Mode objects have been deprecated and will no longer be supported.
</div>
<div>
Please open an issue in the
<a href="https://github.com/nasa/openmct/issues" target="_blank">
Open MCT Issue tracker
</a>
if you have any questions about the timeline plugin.
</div>

View File

@@ -173,11 +173,10 @@ define([
const limitEvaluator = oldObject.getCapability("limit");
return {
limits: () => {
return limitEvaluator.limits.then !== undefined
? limitEvaluator.limits()
: Promise.resolve(limitEvaluator.limits());
limits: function () {
return limitEvaluator.limits();
}
};
};

View File

@@ -39,6 +39,7 @@ const DEFAULTS = [
'platform/telemetry',
'platform/features/clock',
'platform/features/hyperlink',
'platform/features/timeline',
'platform/forms',
'platform/identity',
'platform/persistence/aggregator',
@@ -83,6 +84,7 @@ define([
'../platform/features/my-items/bundle',
'../platform/features/hyperlink/bundle',
'../platform/features/static-markup/bundle',
'../platform/features/timeline/bundle',
'../platform/forms/bundle',
'../platform/framework/bundle',
'../platform/framework/src/load/Bundle',

View File

@@ -24,23 +24,19 @@ import Plot from './Plot.vue';
import Vue from 'vue';
export default function PlotViewProvider(openmct) {
function hasNumericTelemetry(domainObject) {
function hasTelemetry(domainObject) {
if (!Object.prototype.hasOwnProperty.call(domainObject, 'telemetry')) {
return false;
}
let metadata = openmct.telemetry.getMetadata(domainObject);
return metadata.values().length > 0 && hasDomainAndNumericRange(metadata);
return metadata.values().length > 0 && hasDomainAndRange(metadata);
}
function hasDomainAndNumericRange(metadata) {
const rangeValues = metadata.valuesForHints(['range']);
const domains = metadata.valuesForHints(['domain']);
return domains.length > 0
&& rangeValues.length > 0
&& !rangeValues.every(value => value.format === 'string');
function hasDomainAndRange(metadata) {
return (metadata.valuesForHints(['range']).length > 0
&& metadata.valuesForHints(['domain']).length > 0);
}
function isCompactView(objectPath) {
@@ -48,11 +44,11 @@ export default function PlotViewProvider(openmct) {
}
return {
key: 'plot-single',
key: 'plot-simple',
name: 'Plot',
cssClass: 'icon-telemetry',
canView(domainObject, objectPath) {
return hasNumericTelemetry(domainObject);
return hasTelemetry(domainObject, openmct);
},
view: function (domainObject, objectPath) {

View File

@@ -201,57 +201,15 @@ describe("the plugin", function () {
hints: {
range: 1
}
},
{
key: "yet-another-key",
format: "string",
hints: {
range: 2
}
}]
}
};
const applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
const plotView = applicableViews.find((viewProvider) => viewProvider.key === "plot-single");
let plotView = applicableViews.find((viewProvider) => viewProvider.key === "plot-simple");
expect(plotView).toBeDefined();
});
it("does not provide a plot view if the telemetry is entirely non numeric", () => {
const testTelemetryObject = {
id: "test-object",
type: "test-object",
telemetry: {
values: [{
key: "some-key",
hints: {
domain: 1
}
},
{
key: "other-key",
format: "string",
hints: {
range: 1
}
},
{
key: "yet-another-key",
format: "string",
hints: {
range: 1
}
}]
}
};
const applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
const plotView = applicableViews.find((viewProvider) => viewProvider.key === "plot-single");
expect(plotView).toBeUndefined();
});
it("provides an overlay plot view for objects with telemetry", () => {
const testTelemetryObject = {
id: "test-object",
@@ -365,7 +323,7 @@ describe("the plugin", function () {
};
applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
plotViewProvider = applicableViews.find((viewProvider) => viewProvider.key === "plot-single");
plotViewProvider = applicableViews.find((viewProvider) => viewProvider.key === "plot-simple");
plotView = plotViewProvider.view(testTelemetryObject, [testTelemetryObject]);
plotView.show(child, true);
@@ -613,7 +571,7 @@ describe("the plugin", function () {
expect(legend.length).toBe(6);
});
xit("Renders X-axis ticks for the telemetry object", () => {
it("Renders X-axis ticks for the telemetry object", () => {
let xAxisElement = element.querySelectorAll(".gl-plot-axis-area.gl-plot-x .gl-plot-tick-wrapper");
expect(xAxisElement.length).toBe(1);

View File

@@ -65,7 +65,8 @@ define([
'./interceptors/plugin',
'./performanceIndicator/plugin',
'./CouchDBSearchFolder/plugin',
'./timeline/plugin'
'./timeline/plugin',
'/node_modules/openmct-mmgis/dist/openmct-mmgis'
], function (
_,
UTCTimeSystem,
@@ -111,7 +112,8 @@ define([
ObjectInterceptors,
PerformanceIndicator,
CouchDBSearchFolder,
Timeline
Timeline,
Mmgis
) {
const bundleMap = {
LocalStorage: 'platform/persistence/local',
@@ -212,6 +214,7 @@ define([
plugins.PerformanceIndicator = PerformanceIndicator.default;
plugins.CouchDBSearchFolder = CouchDBSearchFolder.default;
plugins.Timeline = Timeline.default;
plugins.Mmgis = Mmgis.default;
return plugins;
});

View File

@@ -85,7 +85,7 @@
<button
ref="startOffset"
class="c-button c-conductor__delta-button"
@click.prevent="showTimePopupStart"
@click="showTimePopupStart"
>
{{ offsets.start }}
</button>
@@ -133,7 +133,7 @@
<button
ref="endOffset"
class="c-button c-conductor__delta-button"
@click.prevent="showTimePopupEnd"
@click="showTimePopupEnd"
>
{{ offsets.end }}
</button>

View File

@@ -46,7 +46,6 @@
<multipane
class="l-shell__main"
:class="[resizingClass]"
type="horizontal"
>
<pane
@@ -54,8 +53,6 @@
handle="after"
label="Browse"
collapsable
@start-resizing="onStartResizing"
@end-resizing="onEndResizing"
>
<button
slot="controls"
@@ -105,8 +102,6 @@
handle="before"
label="Inspect"
collapsable
@start-resizing="onStartResizing"
@end-resizing="onEndResizing"
>
<Inspector
ref="inspector"
@@ -162,16 +157,12 @@ export default {
actionCollection: undefined,
triggerSync: false,
triggerReset: false,
headExpanded,
isResizing: false
headExpanded
};
},
computed: {
toolbar() {
return this.hasToolbar && this.isEditing;
},
resizingClass() {
return this.isResizing ? 'l-shell__resizing' : '';
}
},
mounted() {
@@ -249,12 +240,6 @@ export default {
},
handleTreeReset() {
this.triggerReset = !this.triggerReset;
},
onStartResizing() {
this.isResizing = true;
},
onEndResizing() {
this.isResizing = false;
}
}
};

View File

@@ -293,12 +293,6 @@
justify-content: space-between;
padding: $p;
}
&__resizing {
iframe {
pointer-events: none;
}
}
}
.is-editing {

View File

@@ -41,13 +41,8 @@
<script>
const COLLAPSE_THRESHOLD_PX = 40;
const HIDE_TREE_PARAM = 'hideTree';
const HIDE_INSPECTOR_PARAM = 'hideInspector';
const PANE_INSPECTOR = 'Inspect';
const PANE_TREE = 'Browse';
export default {
inject: ['openmct'],
props: {
handle: {
type: String,
@@ -75,59 +70,20 @@ export default {
this.type = this.$parent.type;
this.styleProp = (this.type === 'horizontal') ? 'width' : 'height';
},
async mounted() {
await this.$nextTick();
// Hide tree and/or inspector pane if specified in URL
this.handleHideUrl();
this.openmct.router.on('change:params', this.handleHideUrl);
},
beforeDestroy() {
this.openmct.router.off('change:params', this.handleHideUrl);
},
methods: {
toggleCollapse: function (e) {
let target = this.label === PANE_TREE ? HIDE_TREE_PARAM : HIDE_INSPECTOR_PARAM;
toggleCollapse: function () {
this.collapsed = !this.collapsed;
if (this.collapsed) {
this.handleCollapse();
this.addHideParam(target);
// Pane is expanded and is being collapsed
this.currentSize = (this.dragCollapse === true) ? this.initial : this.$el.style[this.styleProp];
this.$el.style[this.styleProp] = '';
} else {
this.handleExpand();
this.removeHideParam(target);
// Pane is collapsed and is being expanded
this.$el.style[this.styleProp] = this.currentSize;
delete this.currentSize;
delete this.dragCollapse;
}
},
handleHideUrl: function () {
if (!this.collapsable) {
return;
}
let hideTreeParam = this.openmct.router.getSearchParam(HIDE_TREE_PARAM);
let hideInspectorParam = this.openmct.router.getSearchParam(HIDE_INSPECTOR_PARAM);
let hideTree = hideTreeParam === 'true' && this.label === PANE_TREE;
let hideInspector = hideInspectorParam === 'true' && this.label === PANE_INSPECTOR;
if (hideTree || hideInspector) {
this.collapsed = true;
this.handleCollapse();
} else {
this.collapsed = false;
this.handleExpand();
}
},
addHideParam: function (target) {
this.openmct.router.setSearchParam(target, 'true');
},
removeHideParam: function (target) {
this.openmct.router.deleteSearchParam(target);
},
handleCollapse: function () {
this.currentSize = (this.dragCollapse === true) ? this.initial : this.$el.style[this.styleProp];
this.$el.style[this.styleProp] = '';
},
handleExpand: function () {
this.$el.style[this.styleProp] = this.currentSize;
delete this.currentSize;
delete this.dragCollapse;
},
trackSize: function () {
if (!this.dragCollapse === true) {
if (this.type === 'vertical') {
@@ -170,14 +126,12 @@ export default {
document.body.addEventListener('mousemove', this.updatePosition);
document.body.addEventListener('mouseup', this.end);
this.resizing = true;
this.$emit('start-resizing');
this.trackSize();
},
end: function (event) {
document.body.removeEventListener('mousemove', this.updatePosition);
document.body.removeEventListener('mouseup', this.end);
this.resizing = false;
this.$emit('end-resizing');
this.trackSize();
}
}

View File

@@ -1,90 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, 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';
describe("the pane", () => {
let openmct;
let appHolder;
let element;
let child;
let resolveFunction;
beforeEach((done) => {
openmct = createOpenMct();
appHolder = document.createElement('div');
appHolder.style.width = '640px';
appHolder.style.height = '480px';
openmct = createOpenMct();
openmct.install(openmct.plugins.MyItems());
openmct.install(openmct.plugins.LocalTimeSystem());
openmct.install(openmct.plugins.UTCTimeSystem());
element = document.createElement('div');
child = document.createElement('div');
element.appendChild(child);
openmct.on('start', done);
openmct.start(appHolder);
document.body.append(appHolder);
});
afterEach(() => {
return resetApplicationState(openmct);
});
it('toggling tree will toggle tree hide params', (done) => {
document.querySelector('.l-shell__pane-tree .l-pane__collapse-button').click();
expect(openmct.router.getSearchParam('hideTree')).toBe('true');
done();
});
it('tree pane collapses when adding hide tree param in URL', () => {
openmct.router.setSearchParam('hideTree', 'true');
expect(document.querySelector('.l-shell__pane-tree.l-pane--collapsed')).toBeDefined();
});
it('inspector pane collapses when adding hide inspector param in URL', () => {
openmct.router.setSearchParam('hideInspector', 'true');
expect(document.querySelector('.l-shell__pane-inspector.l-pane--collapsed')).toBeDefined();
});
it('toggle inspector pane will toggle inspector hide param', (done) => {
// There's a short delay on addubg the param.
resolveFunction = () => {
setTimeout(() => {
expect(openmct.router.getSearchParam('hideInspector')).toBe('true');
done();
}, 500);
};
openmct.router.on('change:params', resolveFunction);
document.querySelector('.l-shell__pane-inspector .l-pane__collapse-button').click();
});
});