Compare commits

..

11 Commits

Author SHA1 Message Date
Deep Tailor
085f6d3352 Merge branch 'master' into fix-view-switcher 2021-03-03 15:37:57 -08:00
Jamie V
905e397d3f making sure ALL telemetry for a given indicator is fresh (#3734) 2021-03-03 15:37:49 -08:00
Deep Tailor
1891551430 Merge branch 'master' into fix-view-switcher 2021-03-03 15:36:26 -08:00
Joshi
75c4f0171f Force Vue to look for the reactive property and recompute views 2021-03-03 15:22:59 -08:00
Shefali Joshi
e70a636073 Accept plans from a file OR from JSON object (couchDB) (#3729)
Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2021-03-03 14:50:48 -08:00
Jamie V
03abb5e5de [Abort Search] Completely Abort Search (#3728)
* added new spacecraftPosition keys and changed old spacecraft keys to spacecraftOriention keys, updated how freshness is determined

* due to tests, added some checks for missing related telemetry before acting on it

* lint fixes

* pr comments, change simple if to Boolean

* checking if search aborted before aggregating search results, which calls getOriginalPath, which calls more gets

* removing erroneous abort signal check
2021-03-03 14:05:17 -08:00
Shefali Joshi
ac20c01233 Fix method name in Plan.vue (#3726) 2021-03-03 13:34:07 -08:00
Shefali Joshi
b8ded0a16e Hide vue plots from showing up in the view-switcher and in the preview window (#3725)
* Hide vue plots from showing up in the view-switcher and in the preview window.
2021-03-03 11:33:31 -08:00
Deep Tailor
b68f79f427 [Elements Pool][Flexible Layout] Improvements (#3694)
* fix flexible-layout bug

* abstract element item from elements pool

* improve dragging of elements pool

* better dragover handling in elements pool

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.com>
Co-authored-by: Shefali Joshi <simplyrender@gmail.com>
2021-03-03 09:50:48 -08:00
Jamie V
221d10d3e6 [Imagery Freshness] Update Telemetry for Imagery Freshness (#3723)
* added new spacecraftPosition keys and changed old spacecraft keys to spacecraftOriention keys, updated how freshness is determined

* due to tests, added some checks for missing related telemetry before acting on it

* lint fixes

* pr comments, change simple if to Boolean
2021-03-02 16:55:27 -08:00
Charles Hacskaylo
22d32eed1d Tweak plan view (#3724)
* Plan view final sanding for Build 4

- Removed unused selector;
- Changed class pointer for "no-activites" labels, refined text;

* Plan view final sanding for Build 4

- Removed unused selector;
- Changed class pointer for "no-activites" labels, refined text;
2021-03-02 15:36:23 -08:00
31 changed files with 292 additions and 132 deletions

View File

@@ -71,10 +71,10 @@ define(
openmct.editor.cancel();
}
function isFirstViewEditable(domainObject) {
let firstView = openmct.objectViews.get(domainObject)[0];
function isFirstViewEditable(domainObject, objectPath) {
let firstView = openmct.objectViews.get(domainObject, objectPath)[0];
return firstView && firstView.canEdit && firstView.canEdit(domainObject);
return firstView && firstView.canEdit && firstView.canEdit(domainObject, objectPath);
}
function navigateAndEdit(object) {
@@ -88,7 +88,7 @@ define(
window.location.href = url;
if (isFirstViewEditable(object.useCapability('adapter'))) {
if (isFirstViewEditable(object.useCapability('adapter'), objectPath)) {
openmct.editor.edit();
}
}

View File

@@ -32,7 +32,7 @@ define([], function () {
if (Object.prototype.hasOwnProperty.call(view, 'provider')) {
const domainObject = legacyObject.useCapability('adapter');
return view.provider.canView(domainObject);
return view.provider.canView(domainObject, this.openmct.router.path);
}
return true;

View File

@@ -98,7 +98,7 @@ describe("The LAD Table", () => {
});
it("should provide a table view only for lad table objects", () => {
let applicableViews = openmct.objectViews.get(mockObj.ladTable);
let applicableViews = openmct.objectViews.get(mockObj.ladTable, []);
let ladTableView = applicableViews.find(
(viewProvider) => viewProvider.key === ladTableKey
@@ -185,7 +185,7 @@ describe("The LAD Table", () => {
end: bounds.end
});
applicableViews = openmct.objectViews.get(mockObj.ladTable);
applicableViews = openmct.objectViews.get(mockObj.ladTable, []);
ladTableViewProvider = applicableViews.find((viewProvider) => viewProvider.key === ladTableKey);
ladTableView = ladTableViewProvider.view(mockObj.ladTable, [mockObj.ladTable]);
ladTableView.show(child, true);
@@ -296,7 +296,7 @@ describe("The LAD Table Set", () => {
});
it("should provide a lad table set view only for lad table set objects", () => {
let applicableViews = openmct.objectViews.get(mockObj.ladTableSet);
let applicableViews = openmct.objectViews.get(mockObj.ladTableSet, []);
let ladTableSetView = applicableViews.find(
(viewProvider) => viewProvider.key === ladTableSetKey
@@ -391,7 +391,7 @@ describe("The LAD Table Set", () => {
end: bounds.end
});
applicableViews = openmct.objectViews.get(mockObj.ladTableSet);
applicableViews = openmct.objectViews.get(mockObj.ladTableSet, []);
ladTableSetViewProvider = applicableViews.find((viewProvider) => viewProvider.key === ladTableSetKey);
ladTableSetView = ladTableSetViewProvider.view(mockObj.ladTableSet, [mockObj.ladTableSet]);
ladTableSetView.show(child, true);

View File

@@ -67,11 +67,11 @@ describe("AutoflowTabularPlugin", () => {
});
it("applies its view to the type from options", () => {
expect(provider.canView(testObject)).toBe(true);
expect(provider.canView(testObject, [])).toBe(true);
});
it("does not apply to other types", () => {
expect(provider.canView({ type: 'foo' })).toBe(false);
expect(provider.canView({ type: 'foo' }, [])).toBe(false);
});
describe("provides a view which", () => {

View File

@@ -136,7 +136,7 @@ describe('the plugin', function () {
}
};
const applicableViews = openmct.objectViews.get(testViewObject);
const applicableViews = openmct.objectViews.get(testViewObject, []);
let conditionSetView = applicableViews.find((viewProvider) => viewProvider.key === 'conditionSet.view');
expect(conditionSetView).toBeDefined();
});

View File

@@ -83,7 +83,7 @@ describe('the plugin', function () {
}
};
const applicableViews = openmct.objectViews.get(testViewObject);
const applicableViews = openmct.objectViews.get(testViewObject, []);
let displayLayoutViewProvider = applicableViews.find((viewProvider) => viewProvider.key === 'layout.view');
expect(displayLayoutViewProvider).toBeDefined();
});

View File

@@ -271,11 +271,6 @@ export default {
});
},
removeFromComposition(identifier) {
let keystring = this.openmct.objects.makeKeyString(identifier);
this.identifierMap[keystring] = undefined;
delete this.identifierMap[keystring];
this.composition.remove({identifier});
},
setSelectionToParent() {
@@ -355,6 +350,9 @@ export default {
removeChildObject(identifier) {
let removeIdentifier = this.openmct.objects.makeKeyString(identifier);
this.identifierMap[removeIdentifier] = undefined;
delete this.identifierMap[removeIdentifier];
this.containers.forEach(container => {
container.frames = container.frames.filter(frame => {
let frameIdentifier = this.openmct.objects.makeKeyString(frame.domainObjectIdentifier);

View File

@@ -271,11 +271,27 @@ export default {
if (this.relatedTelemetry.hasRelatedTelemetry) {
isFresh = true;
for (let key of this.spacecraftKeys) {
for (let key of this.spacecraftPositionKeys) {
if (this.relatedTelemetry[key] && latest[key] && focused[key]) {
if (!this.relatedTelemetry[key].comparisonFunction(latest[key], focused[key])) {
isFresh = false;
}
isFresh = isFresh && Boolean(this.relatedTelemetry[key].comparisonFunction(latest[key], focused[key]));
} else {
isFresh = false;
}
}
}
return isFresh;
},
isSpacecraftOrientationFresh() {
let isFresh = undefined;
let latest = this.latestRelatedTelemetry;
let focused = this.focusedImageRelatedTelemetry;
if (this.relatedTelemetry.hasRelatedTelemetry) {
isFresh = true;
for (let key of this.spacecraftOrientationKeys) {
if (this.relatedTelemetry[key] && latest[key] && focused[key]) {
isFresh = isFresh && Boolean(this.relatedTelemetry[key].comparisonFunction(latest[key], focused[key]));
} else {
isFresh = false;
}
@@ -293,12 +309,10 @@ export default {
isFresh = true;
// camera freshness relies on spacecraft position freshness
if (this.isSpacecraftPositionFresh) {
if (this.isSpacecraftPositionFresh && this.isSpacecraftOrientationFresh) {
for (let key of this.cameraKeys) {
if (this.relatedTelemetry[key] && latest[key] && focused[key]) {
if (!this.relatedTelemetry[key].comparisonFunction(latest[key], focused[key])) {
isFresh = false;
}
isFresh = isFresh && Boolean(this.relatedTelemetry[key].comparisonFunction(latest[key], focused[key]));
} else {
isFresh = false;
}
@@ -333,7 +347,8 @@ export default {
this.imageFormatter = this.openmct.telemetry.getValueFormatter(this.imageHints);
// related telemetry keys
this.spacecraftKeys = ['heading', 'roll', 'pitch'];
this.spacecraftPositionKeys = ['positionX', 'positionY', 'positionZ'];
this.spacecraftOrientationKeys = ['heading', 'roll', 'pitch'];
this.cameraKeys = ['cameraPan', 'cameraTilt'];
this.sunKeys = ['sunOrientation'];
@@ -380,7 +395,7 @@ export default {
// unsubscribe from related telemetry
if (this.relatedTelemetry.hasRelatedTelemetry) {
for (let key of this.relatedTelemetry.keys) {
if (this.relatedTelemetry[key].unsubscribe) {
if (this.relatedTelemetry[key] && this.relatedTelemetry[key].unsubscribe) {
this.relatedTelemetry[key].unsubscribe();
}
}
@@ -391,7 +406,7 @@ export default {
this.relatedTelemetry = new RelatedTelemetry(
this.openmct,
this.domainObject,
[...this.spacecraftKeys, ...this.cameraKeys, ...this.sunKeys]
[...this.spacecraftPositionKeys, ...this.spacecraftOrientationKeys, ...this.cameraKeys, ...this.sunKeys]
);
if (this.relatedTelemetry.hasRelatedTelemetry) {
@@ -466,7 +481,7 @@ export default {
}
},
trackLatestRelatedTelemetry() {
[...this.spacecraftKeys, ...this.cameraKeys, ...this.sunKeys].forEach(key => {
[...this.spacecraftPositionKeys, ...this.spacecraftOrientationKeys, ...this.cameraKeys, ...this.sunKeys].forEach(key => {
if (this.relatedTelemetry[key] && this.relatedTelemetry[key].subscribe) {
this.relatedTelemetry[key].subscribe((datum) => {
let valueKey = this.relatedTelemetry[key].realtime.valueKey;

View File

@@ -68,12 +68,14 @@ export default class RelatedTelemetry {
await Promise.all(
this.keys.map(async (key) => {
if (this[key].historical) {
await this._initializeHistorical(key);
}
if (this[key]) {
if (this[key].historical) {
await this._initializeHistorical(key);
}
if (this[key].realtime && this[key].realtime.telemetryObjectId) {
await this._intializeRealtime(key);
if (this[key].realtime && this[key].realtime.telemetryObjectId) {
await this._intializeRealtime(key);
}
}
})
);
@@ -153,7 +155,7 @@ export default class RelatedTelemetry {
destroy() {
this._openmct.time.off('timeSystem', this._timeSystemChange);
for (let key of this.keys) {
if (this[key].unsubscribe) {
if (this[key] && this[key].unsubscribe) {
this[key].unsubscribe();
}
}

View File

@@ -235,7 +235,7 @@ describe("The Imagery View Layout", () => {
});
it("should provide an imagery view only for imagery producing objects", () => {
let applicableViews = openmct.objectViews.get(imageryObject);
let applicableViews = openmct.objectViews.get(imageryObject, []);
let imageryView = applicableViews.find(
viewProvider => viewProvider.key === imageryKey
);
@@ -265,7 +265,7 @@ describe("The Imagery View Layout", () => {
end: bounds.end + 100
});
applicableViews = openmct.objectViews.get(imageryObject);
applicableViews = openmct.objectViews.get(imageryObject, []);
imageryViewProvider = applicableViews.find(viewProvider => viewProvider.key === imageryKey);
imageryView = imageryViewProvider.view(imageryObject);
imageryView.show(child);

View File

@@ -101,7 +101,7 @@ describe("Notebook plugin:", () => {
creatable: true
};
const applicableViews = openmct.objectViews.get(notebookViewObject);
const applicableViews = openmct.objectViews.get(notebookViewObject, []);
notebookViewProvider = applicableViews.find(viewProvider => viewProvider.key === notebookObject.key);
notebookView = notebookViewProvider.view(notebookViewObject);

View File

@@ -94,7 +94,7 @@ export default {
},
methods: {
observeForChanges(mutatedObject) {
this.validateJSON(mutatedObject.selectFile.body);
this.getPlanData(mutatedObject);
this.setScaleAndPlotActivities();
},
resize() {

View File

@@ -82,7 +82,7 @@ describe('the plugin', function () {
type: "plan"
};
const applicableViews = openmct.objectViews.get(testViewObject);
const applicableViews = openmct.objectViews.get(testViewObject, []);
let planView = applicableViews.find((viewProvider) => viewProvider.key === 'plan.view');
expect(planView).toBeDefined();
});
@@ -135,7 +135,7 @@ describe('the plugin', function () {
}
};
const applicableViews = openmct.objectViews.get(planDomainObject);
const applicableViews = openmct.objectViews.get(planDomainObject, []);
planView = applicableViews.find((viewProvider) => viewProvider.key === 'plan.view');
let view = planView.view(planDomainObject, mockObjectPath);
view.show(child, true);

View File

@@ -1,10 +1,14 @@
export function getValidatedPlan(domainObject) {
let jsonString = domainObject.selectFile.body;
let body = domainObject.selectFile.body;
let json = {};
try {
json = JSON.parse(jsonString);
} catch (e) {
return json;
if (typeof body === 'string') {
try {
json = JSON.parse(body);
} catch (e) {
return json;
}
} else {
json = body;
}
return json;

View File

@@ -32,12 +32,12 @@ export default function OverlayPlotViewProvider(openmct) {
key: 'plot-overlay',
name: 'Overlay Plot',
cssClass: 'icon-telemetry',
canView(domainObject) {
return domainObject.type === 'telemetry.plot.overlay';
canView(domainObject, objectPath) {
return isCompactView(objectPath) && domainObject.type === 'telemetry.plot.overlay';
},
canEdit(domainObject) {
return domainObject.type === 'telemetry.plot.overlay';
canEdit(domainObject, objectPath) {
return isCompactView(objectPath) && domainObject.type === 'telemetry.plot.overlay';
},
view: function (domainObject, objectPath) {

View File

@@ -47,8 +47,8 @@ export default function PlotViewProvider(openmct) {
key: 'plot-simple',
name: 'Plot',
cssClass: 'icon-telemetry',
canView(domainObject) {
return hasTelemetry(domainObject, openmct);
canView(domainObject, objectPath) {
return isCompactView(objectPath) && hasTelemetry(domainObject, openmct);
},
view: function (domainObject, objectPath) {

View File

@@ -33,8 +33,27 @@ describe("the plugin", function () {
let openmct;
let telemetryPromise;
let cleanupFirst;
let mockObjectPath;
beforeEach((done) => {
mockObjectPath = [
{
name: 'mock folder',
type: 'fake-folder',
identifier: {
key: 'mock-folder',
namespace: ''
}
},
{
name: 'mock parent folder',
type: 'time-strip',
identifier: {
key: 'mock-parent-folder',
namespace: ''
}
}
];
const testTelemetry = [
{
'utc': 1,
@@ -134,7 +153,7 @@ describe("the plugin", function () {
}
};
const applicableViews = openmct.objectViews.get(testTelemetryObject);
const applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
let plotView = applicableViews.find((viewProvider) => viewProvider.key === "plot-simple");
expect(plotView).toBeDefined();
});
@@ -150,7 +169,7 @@ describe("the plugin", function () {
}
};
const applicableViews = openmct.objectViews.get(testTelemetryObject);
const applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
let plotView = applicableViews.find((viewProvider) => viewProvider.key === "plot-overlay");
expect(plotView).toBeDefined();
});
@@ -166,7 +185,7 @@ describe("the plugin", function () {
}
};
const applicableViews = openmct.objectViews.get(testTelemetryObject);
const applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
let plotView = applicableViews.find((viewProvider) => viewProvider.key === "plot-stacked");
expect(plotView).toBeDefined();
});
@@ -218,7 +237,7 @@ describe("the plugin", function () {
}
};
applicableViews = openmct.objectViews.get(testTelemetryObject);
applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
plotViewProvider = applicableViews.find((viewProvider) => viewProvider.key === "plot-simple");
plotView = plotViewProvider.view(testTelemetryObject, [testTelemetryObject]);
plotView.show(child, true);

View File

@@ -32,12 +32,12 @@ export default function StackedPlotViewProvider(openmct) {
key: 'plot-stacked',
name: 'Stacked Plot',
cssClass: 'icon-telemetry',
canView(domainObject) {
return domainObject.type === 'telemetry.plot.stacked';
canView(domainObject, objectPath) {
return isCompactView(objectPath) && domainObject.type === 'telemetry.plot.stacked';
},
canEdit(domainObject) {
return domainObject.type === 'telemetry.plot.stacked';
canEdit(domainObject, objectPath) {
return isCompactView(objectPath) && domainObject.type === 'telemetry.plot.stacked';
},
view: function (domainObject, objectPath) {

View File

@@ -103,7 +103,7 @@ describe("the plugin", () => {
}
};
const applicableViews = openmct.objectViews.get(testTelemetryObject);
const applicableViews = openmct.objectViews.get(testTelemetryObject, []);
let tableView = applicableViews.find((viewProvider) => viewProvider.key === 'table');
expect(tableView).toBeDefined();
});
@@ -174,7 +174,7 @@ describe("the plugin", () => {
openmct.router.path = [testTelemetryObject];
applicableViews = openmct.objectViews.get(testTelemetryObject);
applicableViews = openmct.objectViews.get(testTelemetryObject, []);
tableViewProvider = applicableViews.find((viewProvider) => viewProvider.key === 'table');
tableView = tableViewProvider.view(testTelemetryObject, [testTelemetryObject]);
tableView.show(child, true);

View File

@@ -87,9 +87,9 @@ const unknownObjectType = {
}
};
function getViewKey(domainObject, openmct) {
function getViewKey(domainObject, objectPath, openmct) {
let viewKey = '';
const plotView = openmct.objectViews.get(domainObject).find((view) => {
const plotView = openmct.objectViews.get(domainObject, objectPath).find((view) => {
return view.key.startsWith('plot-') && view.key !== 'plot-single';
});
if (plotView) {
@@ -136,7 +136,7 @@ export default {
let type = this.openmct.types.get(domainObject.type) || unknownObjectType;
let keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
let objectPath = [domainObject].concat(this.objectPath.slice());
let viewKey = getViewKey(domainObject, this.openmct);
let viewKey = getViewKey(domainObject, objectPath, this.openmct);
let rowCount = 0;
if (domainObject.type === 'plan') {
rowCount = Object.keys(getValidatedPlan(domainObject)).length;

View File

@@ -29,8 +29,27 @@ describe('the plugin', function () {
let element;
let child;
let openmct;
let mockObjectPath;
beforeEach((done) => {
mockObjectPath = [
{
name: 'mock folder',
type: 'fake-folder',
identifier: {
key: 'mock-folder',
namespace: ''
}
},
{
name: 'mock parent folder',
type: 'time-strip',
identifier: {
key: 'mock-parent-folder',
namespace: ''
}
}
];
const appHolder = document.createElement('div');
appHolder.style.width = '640px';
appHolder.style.height = '480px';
@@ -87,7 +106,7 @@ describe('the plugin', function () {
type: "time-strip"
};
const applicableViews = openmct.objectViews.get(testViewObject);
const applicableViews = openmct.objectViews.get(testViewObject, mockObjectPath);
timelineView = applicableViews.find((viewProvider) => viewProvider.key === 'time-strip.view');
let view = timelineView.view(testViewObject, element);
view.show(child, true);

View File

@@ -320,7 +320,8 @@ export default {
let provider = this.openmct.objectViews.getByProviderKey(this.getViewKey());
if (!provider) {
provider = this.openmct.objectViews.get(this.domainObject)[0];
let objectPath = this.currentObjectPath || this.objectPath;
provider = this.openmct.objectViews.get(this.domainObject, objectPath)[0];
if (!provider) {
return;
}
@@ -329,10 +330,11 @@ export default {
return provider;
},
editIfEditable(event) {
let objectPath = this.currentObjectPath || this.objectPath;
let provider = this.getViewProvider();
if (provider
&& provider.canEdit
&& provider.canEdit(this.domainObject)
&& provider.canEdit(this.domainObject, objectPath)
&& this.isEditingAllowed()
&& !this.openmct.editor.isEditing()) {
this.openmct.editor.edit();

View File

@@ -0,0 +1,96 @@
<template>
<li
draggable="true"
@dragstart="emitDragStartEvent"
@dragenter="onDragenter"
@dragover="onDragover"
@dragleave="onDragleave"
@drop="emitDropEvent"
>
<div
class="c-tree__item c-elements-pool__item"
:class="{
'is-context-clicked': contextClickActive,
'hover': hover
}"
>
<span
class="c-elements-pool__grippy c-grippy c-grippy--vertical-drag"
></span>
<object-label
:domain-object="elementObject"
:object-path="[elementObject, parentObject]"
@context-click-active="setContextClickState"
/>
</div>
</li>
</template>
<script>
import ObjectLabel from '../components/ObjectLabel.vue';
export default {
components: {
ObjectLabel
},
props: {
index: {
type: Number,
required: true,
default: () => {
return 0;
}
},
elementObject: {
type: Object,
required: true,
default: () => {
return {};
}
},
parentObject: {
type: Object,
required: true,
default: () => {
return {};
}
},
allowDrop: {
type: Boolean
}
},
data() {
return {
contextClickActive: false,
hover: false
};
},
methods: {
onDragover(event) {
event.preventDefault();
},
emitDropEvent(event) {
this.$emit('drop-custom', this.index);
this.hover = false;
},
emitDragStartEvent(event) {
this.$emit('dragstart-custom', this.index);
},
onDragenter(event) {
if (this.allowDrop) {
this.hover = true;
this.dragElement = event.target.parentElement;
}
},
onDragleave(event) {
if (event.target.parentElement === this.dragElement) {
this.hover = false;
delete this.dragElement;
}
},
setContextClickState(state) {
this.contextClickActive = state;
}
}
};
</script>

View File

@@ -8,34 +8,22 @@
/>
<div
class="c-elements-pool__elements"
:class="{'is-dragging': isDragging}"
>
<ul
v-if="elements.length > 0"
id="inspector-elements-tree"
class="c-tree c-elements-pool__tree"
>
<li
<element-item
v-for="(element, index) in elements"
:key="element.identifier.key"
@drop="moveTo(index)"
@dragover="allowDrop"
>
<div
class="c-tree__item c-elements-pool__item"
draggable="true"
@dragstart="moveFrom(index)"
>
<span
v-if="elements.length > 1 && isEditing"
class="c-elements-pool__grippy c-grippy c-grippy--vertical-drag"
></span>
<object-label
:domain-object="element"
:object-path="[element, parentObject]"
/>
</div>
</li>
:index="index"
:element-object="element"
:parent-object="parentObject"
:allow-drop="allowDrop"
@dragstart-custom="moveFrom(index)"
@drop-custom="moveTo(index)"
/>
<li
class="js-last-place"
@drop="moveToIndex(elements.length)"
@@ -51,12 +39,12 @@
<script>
import _ from 'lodash';
import Search from '../components/search.vue';
import ObjectLabel from '../components/ObjectLabel.vue';
import ElementItem from './ElementItem.vue';
export default {
components: {
'Search': Search,
'ObjectLabel': ObjectLabel
'ElementItem': ElementItem
},
inject: ['openmct'],
data() {
@@ -65,8 +53,9 @@ export default {
isEditing: this.openmct.editor.isEditing(),
parentObject: undefined,
currentSearch: '',
isDragging: false,
selection: []
selection: [],
contextClickTracker: {},
allowDrop: false
};
},
mounted() {
@@ -148,20 +137,15 @@ export default {
&& element.name.toLowerCase().search(this.currentSearch) !== -1;
});
},
allowDrop(event) {
event.preventDefault();
},
moveTo(moveToIndex) {
this.composition.reorder(this.moveFromIndex, moveToIndex);
if (this.allowDrop) {
this.composition.reorder(this.moveFromIndex, moveToIndex);
this.allowDrop = false;
}
},
moveFrom(index) {
this.isDragging = true;
this.allowDrop = true;
this.moveFromIndex = index;
document.addEventListener('dragend', this.hideDragStyling);
},
hideDragStyling() {
this.isDragging = false;
document.removeEventListener('dragend', this.hideDragStyling);
}
}
};

View File

@@ -29,7 +29,7 @@
handle="before"
label="Elements"
>
<elements />
<elements-pool />
</pane>
</multipane>
<multipane
@@ -55,7 +55,7 @@
<script>
import multipane from '../layout/multipane.vue';
import pane from '../layout/pane.vue';
import Elements from './Elements.vue';
import ElementsPool from './ElementsPool.vue';
import Location from './Location.vue';
import Properties from './Properties.vue';
import ObjectName from './ObjectName.vue';
@@ -71,7 +71,7 @@ export default {
SavedStylesInspectorView,
multipane,
pane,
Elements,
ElementsPool,
Properties,
ObjectName,
Location,

View File

@@ -15,9 +15,6 @@
&__elements {
flex: 1 1 auto;
overflow: auto;
&.is-dragging {
li { opacity: 0.2; }
}
}
.c-grippy {
@@ -27,8 +24,16 @@
transform: translateY(-2px);
width: $d; height: $d;
}
&.is-context-clicked {
box-shadow: inset $colorItemTreeSelectedBg 0 0 0 1px;
}
.hover {
background-color: $colorItemTreeSelectedBg;
}
}
.js-last-place {
height: 10px;
}
}

View File

@@ -159,10 +159,14 @@ export default {
return this.views.filter(v => v.key === this.viewKey)[0] || {};
},
views() {
if (this.domainObject && (this.openmct.router.started !== true)) {
return [];
}
return this
.openmct
.objectViews
.get(this.domainObject)
.get(this.domainObject, this.openmct.router.path)
.map((p) => {
return {
key: p.key,
@@ -197,7 +201,7 @@ export default {
if (currentViewKey !== undefined) {
let currentViewProvider = this.openmct.objectViews.getByProviderKey(currentViewKey);
return currentViewProvider.canEdit && currentViewProvider.canEdit(this.domainObject);
return currentViewProvider.canEdit && currentViewProvider.canEdit(this.domainObject, this.openmct.router.path);
}
return false;

View File

@@ -698,7 +698,7 @@ export default {
const promises = this.openmct.objects.search(this.searchValue, abortSignal)
.map(promise => promise
.then(results => this.aggregateSearchResults(results)));
.then(results => this.aggregateSearchResults(results, abortSignal)));
Promise.all(promises).then(() => {
this.searchLoading = false;
@@ -710,24 +710,26 @@ export default {
}
});
},
async aggregateSearchResults(results) {
async aggregateSearchResults(results, abortSignal) {
for (const result of results) {
const objectPath = await this.openmct.objects.getOriginalPath(result.identifier);
if (!abortSignal.aborted) {
const objectPath = await this.openmct.objects.getOriginalPath(result.identifier);
// removing the item itself, as the path we pass to buildTreeItem is a parent path
objectPath.shift();
// removing the item itself, as the path we pass to buildTreeItem is a parent path
objectPath.shift();
// if root, remove, we're not using in object path for tree
let lastObject = objectPath.length ? objectPath[objectPath.length - 1] : false;
if (lastObject && lastObject.type === 'root') {
objectPath.pop();
// if root, remove, we're not using in object path for tree
let lastObject = objectPath.length ? objectPath[objectPath.length - 1] : false;
if (lastObject && lastObject.type === 'root') {
objectPath.pop();
}
// we reverse the objectPath in the tree, so have to do it here first,
// since this one is already in the correct direction
let resultObject = this.buildTreeItem(result, objectPath.reverse());
this.searchResultItems.push(resultObject);
}
// we reverse the objectPath in the tree, so have to do it here first,
// since this one is already in the correct direction
let resultObject = this.buildTreeItem(result, objectPath.reverse());
this.searchResultItems.push(resultObject);
}
},
searchTree(value) {

View File

@@ -58,7 +58,7 @@ export default {
};
},
mounted() {
this.views = this.openmct.objectViews.get(this.domainObject).map((view) => {
this.views = this.openmct.objectViews.get(this.domainObject, this.objectPath).map((view) => {
view.callBack = () => {
return this.setView(view);
};

View File

@@ -39,10 +39,16 @@ define(['EventEmitter'], function (EventEmitter) {
/**
* @private for platform-internal use
* @param {*} item the object to be viewed
* @param {array} objectPath - The current contextual object path of the view object
* eg current domainObject is located under MyItems which is under Root
* @returns {module:openmct.ViewProvider[]} any providers
* which can provide views of this object
*/
ViewRegistry.prototype.get = function (item) {
ViewRegistry.prototype.get = function (item, objectPath) {
if (objectPath === undefined) {
throw "objectPath must be provided to get applicable views for an object";
}
function byPriority(providerA, providerB) {
let priorityA = providerA.priority ? providerA.priority(item) : DEFAULT_VIEW_PRIORITY;
let priorityB = providerB.priority ? providerB.priority(item) : DEFAULT_VIEW_PRIORITY;
@@ -52,7 +58,7 @@ define(['EventEmitter'], function (EventEmitter) {
return this.getAllProviders()
.filter(function (provider) {
return provider.canView(item);
return provider.canView(item, objectPath);
}).sort(byPriority);
};
@@ -181,6 +187,8 @@ define(['EventEmitter'], function (EventEmitter) {
* @memberof module:openmct.ViewProvider#
* @param {module:openmct.DomainObject} domainObject the domain object
* to be viewed
* @param {array} objectPath - The current contextual object path of the view object
* eg current domainObject is located under MyItems which is under Root
* @returns {boolean} 'true' if the view applies to the provided object,
* otherwise 'false'.
*/
@@ -201,6 +209,8 @@ define(['EventEmitter'], function (EventEmitter) {
* @memberof module:openmct.ViewProvider#
* @param {module:openmct.DomainObject} domainObject the domain object
* to be edited
* @param {array} objectPath - The current contextual object path of the view object
* eg current domainObject is located under MyItems which is under Root
* @returns {boolean} 'true' if the view can be used to edit the provided object,
* otherwise 'false'.
*/

View File

@@ -100,13 +100,13 @@ define([
document.title = browseObject.name; //change document title to current object in main view
if (currentProvider && currentProvider.canView(browseObject)) {
if (currentProvider && currentProvider.canView(browseObject, openmct.router.path)) {
viewObject(browseObject, currentProvider);
return;
}
let defaultProvider = openmct.objectViews.get(browseObject)[0];
let defaultProvider = openmct.objectViews.get(browseObject, openmct.router.path)[0];
if (defaultProvider) {
openmct.router.updateParams({
view: defaultProvider.key