diff --git a/platform/commonUI/edit/src/actions/SaveAsAction.js b/platform/commonUI/edit/src/actions/SaveAsAction.js index a2091821eb..0388838657 100644 --- a/platform/commonUI/edit/src/actions/SaveAsAction.js +++ b/platform/commonUI/edit/src/actions/SaveAsAction.js @@ -92,16 +92,7 @@ function ( * @memberof platform/commonUI/edit.SaveAction# */ SaveAsAction.prototype.perform = function () { - // Discard the current root view (which will be the editing - // UI, which will have been pushed atop the Browse UI.) - function returnToBrowse(object) { - if (object) { - object.getCapability("action").perform("navigate"); - } - return object; - } - - return this.save().then(returnToBrowse); + return this.save(); }; /** @@ -192,7 +183,7 @@ function ( if (reason !== "user canceled") { self.notificationService.error("Save Failed"); } - return false; + throw reason; } return getParent(domainObject) diff --git a/platform/commonUI/edit/src/creation/CreateAction.js b/platform/commonUI/edit/src/creation/CreateAction.js index 1caa91cf75..d7de430021 100644 --- a/platform/commonUI/edit/src/creation/CreateAction.js +++ b/platform/commonUI/edit/src/creation/CreateAction.js @@ -67,20 +67,29 @@ define( openmct = this.openmct, newObject; - function onSave() { - // openmct.editor.save(); - } - function onCancel() { openmct.editor.cancel(); } + function navigateAndEdit(object) { + let objectPath = object.getCapability('context').getPath(), + url = '#/browse/' + objectPath + .map(function (o) { + return o && openmct.objects.makeKeyString(o.getId()) + }) + .join('/'); + + window.location.href = url; + + openmct.editor.edit(); + } + newModel.type = this.type.getKey(); newModel.location = this.parent.getId(); newObject = this.parent.useCapability('instantiation', newModel); openmct.editor.edit(); - newObject.getCapability("action").perform("save-as").then(onSave, onCancel); + newObject.getCapability("action").perform("save-as").then(navigateAndEdit, onCancel); // TODO: support editing object without saving object first. // Which means we have to toggle createwizard afterwards. For now, // We will disable this. diff --git a/platform/forms/src/controllers/SnapshotPreviewController.js b/platform/forms/src/controllers/SnapshotPreviewController.js index 7bc5b66d95..a716618247 100644 --- a/platform/forms/src/controllers/SnapshotPreviewController.js +++ b/platform/forms/src/controllers/SnapshotPreviewController.js @@ -29,12 +29,13 @@ define( function SnapshotPreviewController($scope, openmct) { $scope.previewImage = function (imageUrl) { - let image = document.createElement('img'); - image.src = imageUrl; + let imageDiv = document.createElement('div'); + imageDiv.classList = 'image-main s-image-main'; + imageDiv.style.backgroundImage = `url(${imageUrl})`; let previewImageOverlay = openmct.overlays.overlay( { - element: image, + element: imageDiv, size: 'large', buttons: [ { diff --git a/src/api/composition/DefaultCompositionProvider.js b/src/api/composition/DefaultCompositionProvider.js index fdb8dbb913..aa58e2cc20 100644 --- a/src/api/composition/DefaultCompositionProvider.js +++ b/src/api/composition/DefaultCompositionProvider.js @@ -178,8 +178,12 @@ define([ * @method remove */ DefaultCompositionProvider.prototype.remove = function (domainObject, childId) { - // TODO: this needs to be synchronized via mutation. - throw new Error('Default Provider does not implement removal.'); + let composition = domainObject.composition.filter(function (child) { + return !(childId.namespace === child.namespace && + childId.key === child.key); + }); + + this.publicAPI.objects.mutate(domainObject, 'composition', composition); }; /** diff --git a/src/plugins/flexibleLayout/components/flexibleLayout.vue b/src/plugins/flexibleLayout/components/flexibleLayout.vue index e300933820..5a03bff497 100644 --- a/src/plugins/flexibleLayout/components/flexibleLayout.vue +++ b/src/plugins/flexibleLayout/components/flexibleLayout.vue @@ -506,9 +506,27 @@ export default { this.persist(); }, deleteContainer(containerId) { - let container = this.containers.filter(c => c.id === containerId)[0]; - let containerIndex = this.containers.indexOf(container); + let container = this.containers.filter(c => c.id === containerId)[0], + containerIndex = this.containers.indexOf(container); + + /* + remove associated domainObjects from composition + */ + container.frames.forEach(f => { + this.composition.remove({identifier: f.domainObjectIdentifier}); + }); + this.containers.splice(containerIndex, 1); + + /* + add a container when there are no containers in the FL, + to prevent user from not being able to add a frame via + drag and drop. + */ + if (this.containers.length === 0) { + this.containers.push(new Container(100)); + } + sizeToFill(this.containers); this.persist(); }, @@ -548,6 +566,12 @@ export default { .frames .filter((f => f.id === frameId))[0]; let frameIndex = container.frames.indexOf(frame); + + /* + remove associated domainObject from composition + */ + this.composition.remove({identifier: frame.domainObjectIdentifier}); + container.frames.splice(frameIndex, 1); sizeToFill(container.frames); this.persist(containerIndex); @@ -620,7 +644,7 @@ export default { } else { this.containers.splice(toIndex, 0, container); } - this.persist(index); + this.persist(); }, removeChildObject(identifier) { let removeIdentifier = this.openmct.objects.makeKeyString(identifier); diff --git a/src/plugins/flexibleLayout/flexibleLayoutViewProvider.js b/src/plugins/flexibleLayout/flexibleLayoutViewProvider.js index fd48ffdedc..88f1111090 100644 --- a/src/plugins/flexibleLayout/flexibleLayoutViewProvider.js +++ b/src/plugins/flexibleLayout/flexibleLayoutViewProvider.js @@ -57,7 +57,7 @@ define([ layoutObject: domainObject }, el: element, - template: '' + template: '' }); }, getSelectionContext: function () { diff --git a/src/plugins/flexibleLayout/toolbarProvider.js b/src/plugins/flexibleLayout/toolbarProvider.js index b2a265509c..a3a98a6a12 100644 --- a/src/plugins/flexibleLayout/toolbarProvider.js +++ b/src/plugins/flexibleLayout/toolbarProvider.js @@ -204,7 +204,7 @@ function ToolbarProvider(openmct) { addContainer, toggleFrame ? separator: undefined, toggleFrame, - deleteFrame || deleteContainer ? separator: undefined, + deleteFrame || deleteContainer ? separator : undefined, deleteFrame, deleteContainer ]; diff --git a/src/plugins/plot/src/services/ExportImageService.js b/src/plugins/plot/src/services/ExportImageService.js index a6e416e922..e3319b03ec 100644 --- a/src/plugins/plot/src/services/ExportImageService.js +++ b/src/plugins/plot/src/services/ExportImageService.js @@ -30,7 +30,7 @@ define( ], function ( html2canvas, - saveAs + { saveAs } ) { /** diff --git a/src/ui/inspector/Elements.vue b/src/ui/inspector/Elements.vue index 494670b7fe..78ed569c2f 100644 --- a/src/ui/inspector/Elements.vue +++ b/src/ui/inspector/Elements.vue @@ -1,6 +1,10 @@ - + + @@ -69,7 +73,8 @@ export default { return { elements: [], isEditing: this.openmct.editor.isEditing(), - parentObject: undefined + parentObject: undefined, + currentSearch: '' } }, mounted() { diff --git a/src/ui/layout/BrowseBar.vue b/src/ui/layout/BrowseBar.vue index 3e75f64332..4811d4ceb3 100644 --- a/src/ui/layout/BrowseBar.vue +++ b/src/ui/layout/BrowseBar.vue @@ -15,7 +15,7 @@ {{ domainObject.name }} - + @@ -24,7 +24,7 @@ + @click.stop="toggleViewMenu"> {{ currentView.name }} @@ -43,13 +43,32 @@ - - - - + + + + + + + + Save and Finish Editing + + + Save and Continue Editing + + + + + + @@ -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); } } diff --git a/src/ui/layout/Layout.vue b/src/ui/layout/Layout.vue index bf96d212fd..1c35dffbac 100644 --- a/src/ui/layout/Layout.vue +++ b/src/ui/layout/Layout.vue @@ -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; } } } diff --git a/src/ui/layout/mct-tree.vue b/src/ui/layout/mct-tree.vue index a9946fea06..6649bc630c 100644 --- a/src/ui/layout/mct-tree.vue +++ b/src/ui/layout/mct-tree.vue @@ -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 } }); }); diff --git a/src/ui/preview/Preview.vue b/src/ui/preview/Preview.vue index 86751c2e11..3af677eb4d 100644 --- a/src/ui/preview/Preview.vue +++ b/src/ui/preview/Preview.vue @@ -20,19 +20,31 @@ * at runtime from the About dialog for additional information. *****************************************************************************/ - - - - {{ domainObject.name }} - - + + + + + + {{ domainObject.name }} + + + + + + + + + + + + + + - - - - - - +