Compare commits

...

14 Commits

Author SHA1 Message Date
cc62f1d298 fixed filter field issue, and prevent elements pool from updating when selection has not changed 2019-04-10 13:53:26 -07:00
3219a64d09 Add root object to object path for legacy context menu actions (#2369) 2019-04-10 11:42:49 -07:00
570aa2c02a Resolve object paths properly for search results (#2370) 2019-04-10 10:17:50 -07:00
c577d2e231 Only switch into edit mode if view is editable (#2367) 2019-04-10 10:13:54 -07:00
6bf4b3aba8 Fixes some issues relating to removal of objects (#2366)
* Leave edit mode on navigation after removal

* Only leave edit mode if removing navigated item, or parent of

* Do not emit mutation from filters with out of date object model
2019-04-09 10:45:56 -07:00
b659f205f7 Reset selection on cancel (#2363) 2019-04-09 10:23:53 -07:00
40d54df567 Summary widget unsubscribe (#2364)
* Delete subscription handle to prevent double unsubscribe error

* Do not attempt to render undefined telemetry datum
2019-04-08 22:02:40 -07:00
b7fa5c7ba8 Avoid using the same separator object when adding separators to toolbar (#2362) 2019-04-06 17:04:52 -07:00
3b0605d17b Properties section for single select non-domain object (#2361)
* Display a message when a single non-domain object is selected.

* Reviewer's requested change
2019-04-06 14:55:46 -07:00
d93e7bfd1a Merge pull request #2360 from nasa/flex-layout-selection
Toolbar issues in Flexible layout
2019-04-06 13:57:21 -07:00
104cd0ed29 Merge branch 'topic-core-refactor' into flex-layout-selection 2019-04-05 20:09:36 -07:00
7fb3d86d06 Update toolbar to get value and mutate object if toolbar item doesn't have applicableSelectedItems. Also, modify flexibale layout to select parent by clicking the element instead of using selection's private methods. 2019-04-05 20:03:31 -07:00
dbb42e9bb6 Do not use Object.create() with Vueified objects (#2359) 2019-04-05 18:20:30 -07:00
d1baa1f98b Merge pull request #2357 from nasa/misc-ui-8
Misc UI 8
2019-04-05 17:31:07 -07:00
22 changed files with 170 additions and 82 deletions

View File

@ -49,7 +49,7 @@ define(
name: "Properties",
rows: this.properties.map(function (property, index) {
// Property definition is same as form row definition
var row = Object.create(property.getDefinition());
var row = JSON.parse(JSON.stringify(property.getDefinition()));
row.key = index;
return row;
}).filter(function (row) {

View File

@ -66,7 +66,7 @@ define(
name: "Properties",
rows: this.properties.map(function (property, index) {
// Property definition is same as form row definition
var row = Object.create(property.getDefinition());
var row = JSON.parse(JSON.stringify(property.getDefinition()));
// Use index as the key into the formValue;
// this correlates to the indexing provided by

View File

@ -33,20 +33,25 @@ export default class LegacyContextMenuAction {
}
invoke(objectPath) {
let context = {
category: 'contextual',
domainObject: this.openmct.legacyObject(objectPath)
}
let legacyAction = new this.LegacyAction(context);
this.openmct.objects.getRoot().then((root) => {
let pathWithRoot = objectPath.slice();
pathWithRoot.push(root);
if (!legacyAction.getMetadata) {
let metadata = Object.create(this.LegacyAction.definition);
metadata.context = context;
legacyAction.getMetadata = function () {
return metadata;
}.bind(legacyAction);
}
legacyAction.perform();
let context = {
category: 'contextual',
domainObject: this.openmct.legacyObject(pathWithRoot)
}
let legacyAction = new this.LegacyAction(context);
if (!legacyAction.getMetadata) {
let metadata = Object.create(this.LegacyAction.definition);
metadata.context = context;
legacyAction.getMetadata = function () {
return metadata;
}.bind(legacyAction);
}
legacyAction.perform();
});
}
appliesTo(objectPath) {

View File

@ -28,11 +28,6 @@ export default class Editor extends EventEmitter {
super();
this.editing = false;
this.openmct = openmct;
document.addEventListener('drop', (event) => {
if (!this.isEditing()) {
this.edit();
}
}, {capture: true});
}
/**

View File

@ -42,7 +42,10 @@
<!-- Checkbox list, NOT editing -->
<template v-if="filter.possibleValues && !isEditing">
<span>{{persistedFilters[filter.comparator].join(', ')}}</span>
<span
v-if="persistedFilters[filter.comparator]">
{{persistedFilters[filter.comparator].join(', ')}}
</span>
</template>
</div>
</li>

View File

@ -69,16 +69,17 @@ export default {
}
} else {
if (!this.updatedFilters[key]) {
this.updatedFilters[key] = {};
this.$set(this.updatedFilters, key, {});
}
this.updatedFilters[key][comparator] = [value ? valueName : undefined];
this.$set(this.updatedFilters[key], comparator, [value ? valueName : undefined]);
}
this.$emit('updateFilters', this.keyString, this.updatedFilters);
},
updateTextFilter(key, comparator, value) {
if (!this.updatedFilters[key]) {
this.updatedFilters[key] = {};
this.$set(this.updatedFilters, key, {});
this.$set(this.updatedFilters[key], comparator, '');
}
this.updatedFilters[key][comparator] = value;
this.$emit('updateFilters', this.keyString, this.updatedFilters);

View File

@ -23,17 +23,18 @@ export default {
FilterObject
},
inject: [
'openmct',
'providedObject'
'openmct'
],
data() {
let providedObject = this.openmct.selection.get()[0][0].context.item;
let persistedFilters = {};
if (this.providedObject.configuration && this.providedObject.configuration.filters) {
persistedFilters = this.providedObject.configuration.filters;
if (providedObject.configuration && providedObject.configuration.filters) {
persistedFilters = providedObject.configuration.filters;
}
return {
providedObject,
persistedFilters,
children: {}
}
@ -73,13 +74,14 @@ export default {
this.composition.on('add', this.addChildren);
this.composition.on('remove', this.removeChildren);
this.composition.load();
this.unobserve = this.openmct.objects.observe(this.providedObject, 'configuration.filters', this.updatePersistedFilters);
this.unobserveAllMutation = this.openmct.objects.observe(this.providedObject, '*', (mutatedObject) => this.providedObject = mutatedObject);
},
beforeDestroy() {
this.composition.off('add', this.addChildren);
this.composition.off('remove', this.removeChildren);
this.unobserve();
this.unobserveAllMutation();
}
}
</script>

View File

@ -42,14 +42,11 @@ define([
},
view: function (selection) {
let component;
let providedObject = selection[0][0].context.item;
return {
show: function (element) {
component = new Vue({
provide: {
openmct,
providedObject
openmct
},
components: {
FiltersView: FiltersView.default

View File

@ -571,8 +571,7 @@ export default {
});
},
setSelectionToParent() {
let currentSelection = this.openmct.selection.selected;
this.openmct.selection.select(currentSelection.slice(1));
this.$el.click();
},
allowContainerDrop(event, index) {
if (!event.dataTransfer.types.includes('containerid')) {

View File

@ -79,12 +79,14 @@ export default {
},
setSelection() {
this.$nextTick(function () {
let childContext = this.$refs.objectFrame.getSelectionContext();
childContext.item = this.domainObject;
childContext.type = 'frame';
childContext.frameId = this.frame.id;
this.unsubscribeSelection = this.openmct.selection.selectable(
this.$refs.frame, childContext, false);
if (this.$refs && this.$refs.objectFrame) {
let childContext = this.$refs.objectFrame.getSelectionContext();
childContext.item = this.domainObject;
childContext.type = 'frame';
childContext.frameId = this.frame.id;
this.unsubscribeSelection = this.openmct.selection.selectable(
this.$refs.frame, childContext, false);
}
});
},
initDrag(event) {

View File

@ -42,14 +42,7 @@ function ToolbarProvider(openmct) {
toggleContainer,
deleteContainer,
addContainer,
toggleFrame,
separator;
separator = {
control: "separator",
domainObject: primary.context.item,
key: "separator"
};
toggleFrame;
toggleContainer = {
control: 'toggle-button',
@ -70,6 +63,12 @@ function ToolbarProvider(openmct) {
]
};
function getSeparator() {
return {
control: "separator"
};
}
if (primary.context.type === 'frame') {
let frameId = primary.context.frameId;
let layoutObject = tertiary.context.item;
@ -203,9 +202,9 @@ function ToolbarProvider(openmct) {
let toolbar = [
toggleContainer,
addContainer,
toggleFrame ? separator: undefined,
toggleFrame ? getSeparator() : undefined,
toggleFrame,
deleteFrame || deleteContainer ? separator : undefined,
deleteFrame || deleteContainer ? getSeparator() : undefined,
deleteFrame,
deleteContainer
];

View File

@ -85,6 +85,10 @@ export default class RemoveAction {
);
this.openmct.objects.mutate(parent, 'composition', composition);
if (this.inNavigationPath(child) && this.openmct.editor.isEditing()) {
this.openmct.editor.save();
}
}
appliesTo(objectPath) {

View File

@ -237,6 +237,7 @@ define ([
});
delete this.compositionObjs[objectId];
this.subscriptions[objectId](); //unsubscribe from telemetry source
delete this.subscriptions[objectId];
this.eventEmitter.emit('remove', identifier);
if (_.isEmpty(this.compositionObjs)) {

View File

@ -43,7 +43,7 @@ define([
return evaluator.requestLatest(options)
.then(function (latestDatum) {
this.pool.release(evaluator);
return [latestDatum];
return latestDatum ? [latestDatum] : [];
}.bind(this));
};

View File

@ -52,7 +52,10 @@ define([
strategy: 'latest',
size: 1
}).then(function (results) {
if (this.destroyed || this.hasUpdated || this.renderTracker !== renderTracker) {
if (this.destroyed ||
this.hasUpdated ||
this.renderTracker !== renderTracker ||
results.length === 0) {
return;
}
this.updateState(results[results.length - 1]);

View File

@ -137,6 +137,10 @@ define([
let requestOptions = this.buildOptionsFromConfiguration(telemetryObject);
return this.openmct.telemetry.request(telemetryObject, requestOptions)
.then(telemetryData => {
//Check that telemetry object has not been removed since telemetry was requested.
if (!this.telemetryObjects.includes(telemetryObject)) {
return;
}
let keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier);
let columnMap = this.getColumnMapForObject(keyString);
let limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject);
@ -194,6 +198,10 @@ define([
let limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject);
this.subscriptions[keyString] = this.openmct.telemetry.subscribe(telemetryObject, (datum) => {
//Check that telemetry object has not been removed since telemetry was requested.
if (!this.telemetryObjects.includes(telemetryObject)) {
return;
}
this.boundedRows.add(new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
}, subscribeOptions);
}

View File

@ -34,7 +34,10 @@ export default {
this.currentObject = this.object;
this.updateView();
this.$el.addEventListener('dragover', this.onDragOver);
this.$el.addEventListener('drop', this.onDrop);
this.$el.addEventListener('drop', this.addObjectToParent);
this.$el.addEventListener('drop', this.editIfEditable, {
capture: true
});
},
methods: {
clear() {
@ -70,22 +73,18 @@ export default {
this.viewContainer = document.createElement('div');
this.viewContainer.classList.add('c-object-view','u-contents');
this.$el.append(this.viewContainer);
let provider = this.openmct.objectViews.getByProviderKey(this.viewKey);
let provider = this.getViewProvider();
if (!provider) {
provider = this.openmct.objectViews.get(this.currentObject)[0];
if (!provider) {
return;
}
return;
}
if (provider.edit && this.showEditView) {
if (this.openmct.editor.isEditing()) {
this.currentView = provider.edit(this.currentObject);
} else {
this.currentView = provider.view(this.currentObject, false);
}
this.openmct.editor.on('isEditing', this.toggleEditView);
this.releaseEditModeHandler = () => this.openmct.editor.off('isEditing', this.toggleEditView);
} else {
@ -133,7 +132,7 @@ export default {
event.preventDefault();
}
},
onDrop(event) {
addObjectToParent(event) {
if (this.hasComposableDomainObject(event)) {
let composableDomainObject = this.getComposableDomainObject(event);
this.currentObject.composition.push(composableDomainObject.identifier);
@ -142,6 +141,25 @@ export default {
event.stopPropagation();
}
},
getViewProvider() {
let provider = this.openmct.objectViews.getByProviderKey(this.viewKey);
if (!provider) {
provider = this.openmct.objectViews.get(this.currentObject)[0];
if (!provider) {
return;
}
}
return provider;
},
editIfEditable(event) {
let provider = this.getViewProvider();
if (provider &&
provider.canEdit(this.currentObject) &&
!this.openmct.editor.isEditing()) {
this.openmct.editor.edit();
}
},
hasComposableDomainObject(event) {
return event.dataTransfer.types.includes('openmct/composable-domain-object')
},

View File

@ -67,6 +67,7 @@
}
</style>
<script>
import _ from 'lodash';
import Search from '../components/search.vue';
import ObjectLabel from '../components/ObjectLabel.vue';
@ -82,7 +83,8 @@ export default {
isEditing: this.openmct.editor.isEditing(),
parentObject: undefined,
currentSearch: '',
isDragging: false
isDragging: false,
selection: []
}
},
mounted() {
@ -99,6 +101,10 @@ export default {
this.showSelection(this.openmct.selection.get());
},
showSelection(selection) {
if (_.isEqual(this.selection, selection)) {
return;
}
this.selection = selection;
this.elements = [];
this.elementsCache = {};
this.listeners = [];

View File

@ -1,7 +1,7 @@
<template>
<div class="c-properties c-properties--properties">
<div class="c-properties__header">Properties</div>
<ul class="c-properties__section" v-if="!multiSelect">
<ul class="c-properties__section" v-if="!multiSelect && !singleSelectNonObject">
<li class="c-properties__row">
<div class="c-properties__label">Title</div>
<div class="c-properties__value">{{ item.name }}</div>
@ -26,6 +26,7 @@
</li>
</ul>
<div class="c-properties__row--span-all" v-if="multiSelect">No properties to display for multiple items</div>
<div class="c-properties__row--span-all" v-if="singleSelectNonObject">No properties to display for this item</div>
</div>
</template>
@ -81,6 +82,9 @@ export default {
}, this.item)
};
});
},
singleSelectNonObject() {
return !this.item.identifier && !this.multiSelect;
}
},
mounted() {

View File

@ -121,7 +121,7 @@ const PLACEHOLDER_OBJECT = {};
callback: () => {
this.openmct.editor.cancel().then(() => {
//refresh object view
this.openmct.layout.$refs.browseObject.show(this.domainObject, this.viewKey, false);
this.openmct.layout.$refs.browseObject.show(this.domainObject, this.viewKey, true);
});
dialog.dismiss();
}

View File

@ -223,18 +223,23 @@
let context = child.object.getCapability('context'),
object = child.object.useCapability('adapter'),
objectPath = [];
objectPath = [],
navigateToParent;
if (context) {
objectPath = context.getPath().slice(1)
.map(oldObject => oldObject.useCapability('adapter'))
.reverse();
.reverse();
navigateToParent = '/browse/' + objectPath.slice(1)
.map((parent) => this.openmct.objects.makeKeyString(parent.identifier))
.join('/');
}
return {
id: this.openmct.objects.makeKeyString(object.identifier),
object,
objectPath
objectPath,
navigateToParent
}
});
});

View File

@ -115,7 +115,7 @@
let value = undefined;
let applicableSelectedItems = toolbarItem.applicableSelectedItems;
if (!applicableSelectedItems) {
if (!applicableSelectedItems && !toolbarItem.property) {
return value;
}
@ -123,9 +123,14 @@
value = this.getFormValue(domainObject, toolbarItem);
} else {
let values = [];
applicableSelectedItems.forEach(selectionPath => {
values.push(_.get(domainObject, this.getItemProperty(toolbarItem, selectionPath)));
});
if (applicableSelectedItems) {
applicableSelectedItems.forEach(selectionPath => {
values.push(this.getPropertyValue(domainObject, toolbarItem, selectionPath));
});
} else {
values.push(this.getPropertyValue(domainObject, toolbarItem));
}
// If all values are the same, use it, otherwise mark the item as non-specific.
if (values.every(value => value === values[0])) {
@ -138,14 +143,29 @@
return value;
},
getPropertyValue(domainObject, toolbarItem, selectionPath, formKey) {
let property = this.getItemProperty(toolbarItem, selectionPath);
if (formKey) {
property = property + "." + formKey;
}
return _.get(domainObject, property);
},
getFormValue(domainObject, toolbarItem) {
let value = {};
let values = {};
toolbarItem.formKeys.map(key => {
values[key] = [];
toolbarItem.applicableSelectedItems.forEach(selectionPath => {
values[key].push(_.get(domainObject, this.getItemProperty(toolbarItem, selectionPath) + "." + key));
});
if (toolbarItem.applicableSelectedItems) {
toolbarItem.applicableSelectedItems.forEach(selectionPath => {
values[key].push(this.getPropertyValue(domainObject, toolbarItem, selectionPath, key));
});
} else {
values[key].push(this.getPropertyValue(domainObject, toolbarItem, undefined, key));
}
});
for (const key in values) {
@ -192,19 +212,35 @@
this.structure.map(s => {
if (s.formKeys) {
s.formKeys.forEach(key => {
item.applicableSelectedItems.forEach(selectionPath => {
this.openmct.objects.mutate(item.domainObject,
this.getItemProperty(item, selectionPath) + "." + key, value[key]);
});
if (item.applicableSelectedItems) {
item.applicableSelectedItems.forEach(selectionPath => {
this.mutateObject(item, value[key], selectionPath, key);
});
} else {
this.mutateObject(item, value[key], undefined, key);
}
});
}
});
} else {
item.applicableSelectedItems.forEach(selectionPath => {
this.openmct.objects.mutate(item.domainObject, this.getItemProperty(item, selectionPath), value);
});
if (item.applicableSelectedItems) {
item.applicableSelectedItems.forEach(selectionPath => {
this.mutateObject(item, value, selectionPath);
});
} else {
this.mutateObject(item, value);
}
}
},
mutateObject(item, value, selectionPath, formKey) {
let property = this.getItemProperty(item, selectionPath);
if (formKey) {
property = property + "." + formKey;
}
this.openmct.objects.mutate(item.domainObject, property, value);
},
triggerMethod(item, event) {
if (item.method) {
item.method({...event});