TCR fixes 2 (#2286)

* prevent default on dragover in dropHint, to allow drop event to fire

* add notebook snapshot to preview

* fix for preview image overlay

* pin fast-sass-loader version to 1.4.6

* fix saveAs in plot image export

* fix elements search in inspector

* fix current Search error

* fix anonymous render error in layout

* navigate and edit on create

* remove domainObjects from composition when deleting frames and containers, and also fix a bug whereby a user can add domainObject via drag and drop(composition) but because of the lack of containers, it will not be added to the flexible layout

* fix index undefined error when reordering containers

* throw an error when user cancels instead of returning false

* fixes for toolbar not updating on selection change

* fix errors when objects without context are returned by the search aggregator

* prompt user before cancelling edit

* check transactions before prompting user

* add save and continue editing option to save menu

* prompt user if in edit mode and is navigating away
This commit is contained in:
Deep Tailor
2019-03-11 11:47:53 -07:00
committed by Andrew Henry
parent 1c8f23dea1
commit 402062110d
13 changed files with 196 additions and 76 deletions

View File

@ -1,6 +1,10 @@
<template>
<div class="c-elements-pool">
<Search class="c-elements-pool__search" @input="applySearch"></Search>
<Search class="c-elements-pool__search"
:value="currentSearch"
@input="applySearch"
@clear="applySearch">
</Search>
<div class="c-elements-pool__elements">
<ul class="tree c-tree c-elements-pool__tree" id="inspector-elements-tree"
v-if="elements.length > 0">
@ -69,7 +73,8 @@ export default {
return {
elements: [],
isEditing: this.openmct.editor.isEditing(),
parentObject: undefined
parentObject: undefined,
currentSearch: ''
}
},
mounted() {

View File

@ -15,7 +15,7 @@
{{ domainObject.name }}
</span>
</div>
<div class="l-browse-bar__context-actions c-disclosure-button" @click="showContextMenu"></div>
<div class="l-browse-bar__context-actions c-disclosure-button" @click.prevent.stop="showContextMenu"></div>
</div>
<div class="l-browse-bar__end">
@ -24,7 +24,7 @@
<button class="c-button--menu"
:class="currentView.cssClass"
title="Switch view type"
@click="toggleViewMenu">
@click.stop="toggleViewMenu">
<span class="c-button__label">
{{ currentView.name }}
</span>
@ -43,13 +43,32 @@
</div>
<!-- Action buttons -->
<div class="l-browse-bar__actions">
<button class="l-browse-bar__actions__edit c-button icon-notebook"
<button class="l-browse-bar__actions__notebook-entry c-button icon-notebook"
title="New Notebook entry"
@click="snapshot()">
</button>
<button class="l-browse-bar__actions__notebook-entry c-button c-button--major icon-pencil" title="Edit" v-if="isViewEditable & !isEditing" @click="edit()"></button>
<button class="l-browse-bar__actions c-button c-button--major icon-save" title="Save and Finish Editing" v-if="isEditing" @click="saveAndFinishEditing()"></button>
<button class="l-browse-bar__actions c-button icon-x" title="Cancel Editing" v-if="isEditing" @click="cancelEditing()"></button>
<button class="l-browse-bar__actions__edit c-button c-button--major icon-pencil" title="Edit" v-if="isViewEditable & !isEditing" @click="edit()"></button>
<div class="l-browse-bar__view-switcher c-ctrl-wrapper c-ctrl-wrapper--menus-left"
v-if="isEditing">
<button class="c-button--menu c-button--major icon-save" title="Save" @click.stop="toggleSaveMenu"></button>
<div class="c-menu" v-show="showSaveMenu">
<ul>
<li @click="saveAndFinishEditing"
class="icon-save"
title="Save and Finish Editing">
Save and Finish Editing
</li>
<li @click="saveAndContinueEditing"
class="icon-save"
title="Save and Continue Editing">
Save and Continue Editing
</li>
</ul>
</div>
</div>
<button class="l-browse-bar__actions c-button icon-x" title="Cancel Editing" v-if="isEditing" @click="promptUserandCancelEditing()"></button>
</div>
</div>
</div>
@ -62,10 +81,16 @@ const PLACEHOLDER_OBJECT = {};
export default {
inject: ['openmct'],
methods: {
toggleViewMenu(event) {
event.stopPropagation();
toggleViewMenu() {
this.showViewMenu = !this.showViewMenu;
},
toggleSaveMenu() {
this.showSaveMenu = !this.showSaveMenu;
},
closeViewAndSaveMenu() {
this.showViewMenu = false;
this.showSaveMenu = false;
},
updateName(event) {
// TODO: handle isssues with contenteditable text escaping.
if (event.target.innerText !== this.domainObject.name) {
@ -84,20 +109,48 @@ const PLACEHOLDER_OBJECT = {};
edit() {
this.openmct.editor.edit();
},
cancelEditing() {
this.openmct.editor.cancel();
promptUserandCancelEditing() {
let dialog = this.openmct.overlays.dialog({
iconClass: 'alert',
message: 'Are you sure you want to continue? All unsaved changes will be lost!',
buttons: [
{
label: 'Ok',
emphasis: true,
callback: () => {
this.openmct.editor.cancel();
dialog.dismiss();
}
},
{
label: 'Cancel',
callback: () => {
dialog.dismiss();
}
}
]
});
},
promptUserbeforeNavigatingAway(event) {
if(this.openmct.editor.isEditing()) {
event.preventDefault();
event.returnValue = '';
}
},
saveAndFinishEditing() {
this.openmct.editor.save().then(()=> {
return this.openmct.editor.save().then(()=> {
this.openmct.notifications.info('Save successful');
}).catch((error) => {
this.openmct.notifications.error('Error saving objects');
console.error(error);
});
},
saveAndContinueEditing() {
this.saveAndFinishEditing().then(() => {
this.openmct.editor.edit();
});
},
showContextMenu(event) {
event.preventDefault();
event.stopPropagation();
this.openmct.contextMenu._showContextMenuForObjectPath(this.openmct.router.path, event.clientX, event.clientY);
},
snapshot() {
@ -111,6 +164,7 @@ const PLACEHOLDER_OBJECT = {};
data: function () {
return {
showViewMenu: false,
showSaveMenu: false,
domainObject: PLACEHOLDER_OBJECT,
viewKey: undefined,
isEditing: this.openmct.editor.isEditing()
@ -161,15 +215,16 @@ const PLACEHOLDER_OBJECT = {};
mounted: function () {
this.notebookSnapshot = new NotebookSnapshot(this.openmct);
document.addEventListener('click', () => {
if (this.showViewMenu) {
this.showViewMenu = false;
}
});
document.addEventListener('click', this.closeViewAndSaveMenu);
window.addEventListener('beforeunload', this.promptUserbeforeNavigatingAway);
this.openmct.editor.on('isEditing', (isEditing) => {
this.isEditing = isEditing;
});
},
beforeDestroy: function () {
document.removeEventListener('click', this.closeViewAndSaveMenu);
window.removeEventListener('click', this.promptUserbeforeNavigatingAway);
}
}
</script>

View File

@ -299,26 +299,20 @@
this.openmct.editor.on('isEditing', (isEditing)=>{
this.isEditing = isEditing;
});
this.openmct.selection.on('change', this.toggleHasToolbar);
},
data: function () {
return {
fullScreen: false,
conductorComponent: {},
isEditing: false
conductorComponent: undefined,
isEditing: false,
hasToolbar: false
}
},
computed: {
toolbar() {
let selection = this.openmct.selection.get();
let structure = undefined;
if (!selection[0]) {
structure = [];
} else {
structure = this.openmct.toolbars.get(selection);
}
return this.isEditing && structure.length > 0;
return this.hasToolbar && this.isEditing;
}
},
methods: {
@ -333,6 +327,17 @@
},
openInNewTab(event) {
window.open(window.location.href);
},
toggleHasToolbar(selection) {
let structure = undefined;
if (!selection[0]) {
structure = [];
} else {
structure = this.openmct.toolbars.get(selection);
}
this.hasToolbar = structure.length > 0;
}
}
}

View File

@ -178,15 +178,21 @@
getFilteredChildren() {
this.searchService.query(this.searchValue).then(children => {
this.filteredTreeItems = children.hits.map(child => {
let objectPath = child.object.getCapability('context')
.getPath().slice(1).map(oldObject => oldObject.useCapability('adapter'))
.reverse(),
object = child.object.useCapability('adapter');
let context = child.object.getCapability('context'),
object = child.object.useCapability('adapter'),
objectPath = [];
if (context) {
objectPath = context.getPath().slice(1)
.map(oldObject => oldObject.useCapability('adapter'))
.reverse();
}
return {
id: this.openmct.objects.makeKeyString(object.identifier),
object,
objectPath
objectPath
}
});
});

View File

@ -20,19 +20,31 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<div class="l-preview-window">
<div class="l-preview-window__object-name l-browse-bar__object-name--w" :class="type.cssClass">
<span class="l-browse-bar__object-name">
{{ domainObject.name }}
</span>
<context-menu-drop-down :object-path="objectPath"></context-menu-drop-down>
<div class="l-preview-window">
<div class="l-browse-bar">
<div class="l-browse-bar__start">
<div class="l-browse-bar__object-name--w"
:class="type.cssClass">
<span class="l-browse-bar__object-name">
{{ domainObject.name }}
</span>
<context-menu-drop-down :object-path="objectPath"></context-menu-drop-down>
</div>
</div>
<div class="l-browse-bar__end">
<div class="l-browse-bar__actions">
<button class="l-browse-bar__actions__edit c-button icon-notebook"
title="New Notebook entry"
@click="snapshot">
</button>
</div>
</div>
</div>
<div class="l-preview-window__object-view">
<div ref="objectView"></div>
</div>
</div>
<div class="l-preview-window__object-view">
<div ref="objectView">
</div>
</div>
</div>
</template>
</template>
<style lang="scss">
@import '~styles/sass-base';
@ -63,6 +75,7 @@
<script>
import ContextMenuDropDown from '../../ui/components/contextMenuDropDown.vue';
import NotebookSnapshot from '../utils/notebook-snapshot';
export default {
components: {
@ -72,6 +85,12 @@
'openmct',
'objectPath'
],
methods: {
snapshot() {
let element = document.getElementsByClassName("l-preview-window__object-view")[0];
this.notebookSnapshot.capture(this.domainObject, element);
}
},
data() {
let domainObject = this.objectPath[0];
let type = this.openmct.types.get(domainObject.type);
@ -85,6 +104,7 @@
let viewProvider = this.openmct.objectViews.get(this.domainObject)[0];
this.view = viewProvider.view(this.domainObject);
this.view.show(this.$refs.objectView, false);
this.notebookSnapshot = new NotebookSnapshot(this.openmct);
},
destroy() {
this.view.destroy();