release 2.0.2 merge to master (#5044)

* Fix version number

* temp remove e2e-ci until percy fix (#5032)

* [Imagery] Improve View Large Action Performance (#5024)

* added the ability to pass the element you would like to enlarge to the view large action
* Example of performance marks (#5027)
Co-authored-by: John Hill <john.c.hill@nasa.gov>
Co-authored-by: unlikelyzero <jchill2@gmail.com>
Co-authored-by: Andrew Henry <andrew.k.henry@nasa.gov>

* [Notebooks] Transactions for entry creation/editing (#4917)

* adding transactions to notebook entry editing

Co-authored-by: Nikhil <nikhil.k.mandlik@nasa.gov>
Co-authored-by: Andrew Henry <andrew.k.henry@nasa.gov>

* Revert "temp remove e2e-ci until percy fix (#5032)" (#5047)

This reverts commit 5b4ba7772affd0b73d64b031cfe4ded5c0e3a856.

Co-authored-by: John Hill <john.c.hill@nasa.gov>
Co-authored-by: Jamie V <jamie.j.vigliotta@nasa.gov>
Co-authored-by: Nikhil <nikhil.k.mandlik@nasa.gov>
Co-authored-by: Andrew Henry <andrew.k.henry@nasa.gov>
This commit is contained in:
Shefali Joshi 2022-04-08 11:35:34 -07:00 committed by GitHub
parent 3a11291a3b
commit 47099786cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 149 additions and 47 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "openmct", "name": "openmct",
"version": "2.0.2-SNAPSHOT", "version": "2.0.2",
"description": "The Open MCT core platform", "description": "The Open MCT core platform",
"devDependencies": { "devDependencies": {
"@babel/eslint-parser": "7.16.3", "@babel/eslint-parser": "7.16.3",

View File

@ -35,6 +35,8 @@
ref="searchResults" ref="searchResults"
:domain-object="domainObject" :domain-object="domainObject"
:results="searchResults" :results="searchResults"
@cancelEdit="cancelTransaction"
@editingEntry="startTransaction"
@changeSectionPage="changeSelectedSection" @changeSectionPage="changeSelectedSection"
@updateEntries="updateEntries" @updateEntries="updateEntries"
/> />
@ -140,6 +142,8 @@
:selected-page="selectedPage" :selected-page="selectedPage"
:selected-section="selectedSection" :selected-section="selectedSection"
:read-only="false" :read-only="false"
@cancelEdit="cancelTransaction"
@editingEntry="startTransaction"
@deleteEntry="deleteEntry" @deleteEntry="deleteEntry"
@updateEntry="updateEntry" @updateEntry="updateEntry"
/> />
@ -710,6 +714,8 @@ export default {
notebookEntries[this.selectedSection.id][this.selectedPage.id] = entries; notebookEntries[this.selectedSection.id][this.selectedPage.id] = entries;
mutateObject(this.openmct, this.domainObject, 'configuration.entries', notebookEntries); mutateObject(this.openmct, this.domainObject, 'configuration.entries', notebookEntries);
this.saveTransaction();
}, },
getPageIdFromUrl() { getPageIdFromUrl() {
return this.openmct.router.getParams().pageId; return this.openmct.router.getParams().pageId;
@ -746,6 +752,39 @@ export default {
this.selectPage(pageId); this.selectPage(pageId);
this.syncUrlWithPageAndSection(); this.syncUrlWithPageAndSection();
},
activeTransaction() {
return this.openmct.objects.getActiveTransaction();
},
startTransaction() {
if (!this.openmct.editor.isEditing()) {
this.openmct.objects.startTransaction();
}
},
saveTransaction() {
const transaction = this.activeTransaction();
if (!transaction || this.openmct.editor.isEditing()) {
return;
}
return transaction.commit()
.catch(error => {
throw error;
}).finally(() => {
this.openmct.objects.endTransaction();
});
},
cancelTransaction() {
if (!this.openmct.editor.isEditing()) {
const transaction = this.activeTransaction();
transaction.cancel()
.catch(error => {
throw error;
}).finally(() => {
this.openmct.objects.endTransaction();
});
}
} }
} }
}; };

View File

@ -55,6 +55,7 @@
class="c-ne__text c-ne__input" class="c-ne__text c-ne__input"
tabindex="0" tabindex="0"
contenteditable contenteditable
@focus="editingEntry()"
@blur="updateEntryValue($event)" @blur="updateEntryValue($event)"
@keydown.enter.exact.prevent @keydown.enter.exact.prevent
@keyup.enter.exact.prevent="forceBlur($event)" @keyup.enter.exact.prevent="forceBlur($event)"
@ -284,11 +285,16 @@ export default {
this.$emit('updateEntry', this.entry); this.$emit('updateEntry', this.entry);
}, },
editingEntry() {
this.$emit('editingEntry');
},
updateEntryValue($event) { updateEntryValue($event) {
const value = $event.target.innerText; const value = $event.target.innerText;
if (value !== this.entry.text && value.match(/\S/)) { if (value !== this.entry.text && value.match(/\S/)) {
this.entry.text = value; this.entry.text = value;
this.$emit('updateEntry', this.entry); this.$emit('updateEntry', this.entry);
} else {
this.$emit('cancelEdit');
} }
} }
} }

View File

@ -33,6 +33,8 @@
:read-only="true" :read-only="true"
:selected-page="result.page" :selected-page="result.page"
:selected-section="result.section" :selected-section="result.section"
@editingEntry="editingEntry"
@cancelEdit="cancelEdit"
@changeSectionPage="changeSectionPage" @changeSectionPage="changeSectionPage"
@updateEntries="updateEntries" @updateEntries="updateEntries"
/> />
@ -63,6 +65,12 @@ export default {
} }
}, },
methods: { methods: {
editingEntry() {
this.$emit('editingEntry');
},
cancelEdit() {
this.$emit('cancelEdit');
},
changeSectionPage(data) { changeSectionPage(data) {
this.$emit('changeSectionPage', data); this.$emit('changeSectionPage', data);
}, },

View File

@ -38,41 +38,41 @@ export default class ViewLargeAction {
} }
invoke(objectPath, view) { invoke(objectPath, view) {
const parentElement = view.parentElement; performance.mark('viewlarge.start');
let childElement = parentElement && parentElement.firstChild; const childElement = view?.parentElement?.firstChild;
if (!childElement) { if (!childElement) {
const message = "ViewLargeAction: missing element"; const message = "ViewLargeAction: missing element";
this.openmct.notifications.error(message); this.openmct.notifications.error(message);
throw new Error(message); throw new Error(message);
} }
this._expand(objectPath, childElement); this._expand(objectPath, view);
} }
appliesTo(objectPath, view = {}) { appliesTo(objectPath, view) {
const parentElement = view.parentElement; const childElement = view?.parentElement?.firstChild;
const element = parentElement && parentElement.firstChild;
const viewLargeAction = element && !element.classList.contains('js-main-container') return childElement && !childElement.classList.contains('js-main-container')
&& !this.openmct.router.isNavigatedObject(objectPath); && !this.openmct.router.isNavigatedObject(objectPath);
return viewLargeAction;
} }
_expand(objectPath, childElement) { _expand(objectPath, view) {
const parentElement = childElement.parentElement; const element = this._getPreview(objectPath, view);
this.overlay = this.openmct.overlays.overlay({ this.overlay = this.openmct.overlays.overlay({
element: this._getPreview(objectPath), element,
size: 'large', size: 'large',
autoHide: false, autoHide: false,
onDestroy() { onDestroy: () => {
parentElement.append(childElement); this.preview.$destroy();
this.preview = undefined;
delete this.preview;
} }
}); });
} }
_getPreview(objectPath) { _getPreview(objectPath, view) {
const preview = new Vue({ this.preview = new Vue({
components: { components: {
Preview Preview
}, },
@ -80,9 +80,14 @@ export default class ViewLargeAction {
openmct: this.openmct, openmct: this.openmct,
objectPath objectPath
}, },
template: '<Preview></Preview>' data() {
return {
view
};
},
template: '<Preview :existing-view="view"></Preview>'
}); });
return preview.$mount().$el; return this.preview.$mount().$el;
} }
} }

View File

@ -22,10 +22,10 @@
<template> <template>
<div class="l-preview-window js-preview-window"> <div class="l-preview-window js-preview-window">
<PreviewHeader <PreviewHeader
:current-view="currentView" :current-view="currentViewProvider"
:action-collection="actionCollection" :action-collection="actionCollection"
:domain-object="domainObject" :domain-object="domainObject"
:views="views" :views="viewProviders"
/> />
<div class="l-preview-window__object-view js-notebook-snapshot-item"> <div class="l-preview-window__object-view js-notebook-snapshot-item">
<div ref="objectView"></div> <div ref="objectView"></div>
@ -52,6 +52,12 @@ export default {
default() { default() {
return undefined; return undefined;
} }
},
existingView: {
type: Object,
default() {
return undefined;
}
} }
}, },
data() { data() {
@ -60,21 +66,25 @@ export default {
return { return {
domainObject: domainObject, domainObject: domainObject,
viewKey: undefined, viewKey: undefined,
views: [], viewProviders: [],
currentView: {}, currentViewProvider: {},
actionCollection: undefined actionCollection: undefined,
existingViewIndex: 0
}; };
}, },
mounted() { mounted() {
this.views = this.openmct.objectViews.get(this.domainObject, this.objectPath).map((view) => { this.viewProviders = this.openmct.objectViews.get(this.domainObject, this.objectPath);
view.onItemClicked = () => { this.viewProviders.forEach((provider, index) => {
return this.setView(view); provider.onItemClicked = () => {
}; if (this.existingView && provider.key === this.existingView.key) {
this.existingViewIndex = index;
}
return view; this.setView(provider);
};
}); });
this.setView(this.views[0]); this.setView(this.viewProviders[0]);
}, },
beforeDestroy() { beforeDestroy() {
if (this.stopListeningStyles) { if (this.stopListeningStyles) {
@ -91,41 +101,74 @@ export default {
} }
}, },
destroyed() { destroyed() {
this.view.destroy(); if (!this.existingView) {
this.view.destroy();
} else if (this.existingViewElement) {
// if the existing view element is populated, it's the currently viewed view
// in preview and we need to add it back to the parent.
this.addExistingViewBackToParent();
}
}, },
methods: { methods: {
clear() { clear() {
if (this.view) { if (this.view) {
this.view.destroy(); if (this.view !== this.existingView) {
this.$refs.objectView.innerHTML = ''; this.view.destroy();
} } else {
this.addExistingViewBackToParent();
}
delete this.view; this.$refs.objectView.innerHTML = '';
delete this.viewContainer; delete this.view;
delete this.viewContainer;
}
}, },
setView(view) { setView(viewProvider) {
if (this.viewKey === view.key) { if (this.viewKey === viewProvider.key) {
return; return;
} }
const isExistingView = viewProvider.key === this.existingView.key;
this.clear(); this.clear();
this.viewKey = view.key;
this.currentView = view; this.viewKey = viewProvider.key;
this.initializeViewContainer();
if (isExistingView) {
this.view = this.existingView;
this.existingViewElement = this.existingView.parentElement.firstChild;
this.currentViewProvider = this.viewProviders[this.existingViewIndex];
} else {
this.currentViewProvider = viewProvider;
this.view = this.currentViewProvider.view(this.domainObject, this.objectPath);
}
this.getActionsCollection(this.view);
if (isExistingView) {
this.viewContainer.appendChild(this.existingViewElement);
} else {
this.view.show(this.viewContainer, false, this.viewOptions);
}
this.initObjectStyles();
},
addExistingViewBackToParent() {
this.existingView.parentElement.appendChild(this.existingViewElement);
delete this.existingViewElement;
},
initializeViewContainer() {
this.viewContainer = document.createElement('div'); this.viewContainer = document.createElement('div');
this.viewContainer.classList.add('l-angular-ov-wrapper'); this.viewContainer.classList.add('l-angular-ov-wrapper');
this.$refs.objectView.append(this.viewContainer); this.$refs.objectView.append(this.viewContainer);
this.view = this.currentView.view(this.domainObject, this.objectPath);
this.getActionsCollection();
this.view.show(this.viewContainer, false, this.viewOptions);
this.initObjectStyles();
}, },
getActionsCollection() { getActionsCollection(view) {
if (this.actionCollection) { if (this.actionCollection) {
this.actionCollection.destroy(); this.actionCollection.destroy();
} }
this.actionCollection = this.openmct.actions.getActionsCollection(this.objectPath, this.view); this.actionCollection = this.openmct.actions.getActionsCollection(this.objectPath, view);
}, },
initObjectStyles() { initObjectStyles() {
if (!this.styleRuleManager) { if (!this.styleRuleManager) {

View File

@ -90,6 +90,7 @@ define(['EventEmitter'], function (EventEmitter) {
provider.view = (domainObject, objectPath) => { provider.view = (domainObject, objectPath) => {
const viewObject = wrappedView(domainObject, objectPath); const viewObject = wrappedView(domainObject, objectPath);
const wrappedShow = viewObject.show.bind(viewObject); const wrappedShow = viewObject.show.bind(viewObject);
viewObject.key = key; // provide access to provider key on view object
viewObject.show = (element, isEditing, viewOptions) => { viewObject.show = (element, isEditing, viewOptions) => {
viewObject.parentElement = element.parentElement; viewObject.parentElement = element.parentElement;
wrappedShow(element, isEditing, viewOptions); wrappedShow(element, isEditing, viewOptions);