mirror of
https://github.com/nasa/openmct.git
synced 2025-06-06 01:11:41 +00:00
[Edit] Add notifications to Save & SaveAs (#1258)
* [Edit] Added notifications to SaveAsAction * [Edit] Added notifications to SaveAction * [Edit] Update SaveAsActionSpec * [Edit] No error notif when user cancels SaveAs
This commit is contained in:
parent
90a7ca8ae5
commit
532f7a76f9
@ -211,7 +211,8 @@ define([
|
|||||||
"cssclass": "icon-save labeled",
|
"cssclass": "icon-save labeled",
|
||||||
"description": "Save changes made to these objects.",
|
"description": "Save changes made to these objects.",
|
||||||
"depends": [
|
"depends": [
|
||||||
"dialogService"
|
"dialogService",
|
||||||
|
"notificationService"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -222,7 +223,8 @@ define([
|
|||||||
"cssclass": "icon-save labeled",
|
"cssclass": "icon-save labeled",
|
||||||
"description": "Save changes made to these objects.",
|
"description": "Save changes made to these objects.",
|
||||||
"depends": [
|
"depends": [
|
||||||
"dialogService"
|
"dialogService",
|
||||||
|
"notificationService"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -236,7 +238,8 @@ define([
|
|||||||
"$injector",
|
"$injector",
|
||||||
"policyService",
|
"policyService",
|
||||||
"dialogService",
|
"dialogService",
|
||||||
"copyService"
|
"copyService",
|
||||||
|
"notificationService"
|
||||||
],
|
],
|
||||||
"priority": "mandatory"
|
"priority": "mandatory"
|
||||||
},
|
},
|
||||||
|
@ -33,10 +33,12 @@ define(
|
|||||||
*/
|
*/
|
||||||
function SaveAction(
|
function SaveAction(
|
||||||
dialogService,
|
dialogService,
|
||||||
|
notificationService,
|
||||||
context
|
context
|
||||||
) {
|
) {
|
||||||
this.domainObject = (context || {}).domainObject;
|
this.domainObject = (context || {}).domainObject;
|
||||||
this.dialogService = dialogService;
|
this.dialogService = dialogService;
|
||||||
|
this.notificationService = notificationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,7 +49,8 @@ define(
|
|||||||
* @memberof platform/commonUI/edit.SaveAction#
|
* @memberof platform/commonUI/edit.SaveAction#
|
||||||
*/
|
*/
|
||||||
SaveAction.prototype.perform = function () {
|
SaveAction.prototype.perform = function () {
|
||||||
var domainObject = this.domainObject,
|
var self = this,
|
||||||
|
domainObject = this.domainObject,
|
||||||
dialog = new SaveInProgressDialog(this.dialogService);
|
dialog = new SaveInProgressDialog(this.dialogService);
|
||||||
|
|
||||||
// Invoke any save behavior introduced by the editor capability;
|
// Invoke any save behavior introduced by the editor capability;
|
||||||
@ -58,15 +61,21 @@ define(
|
|||||||
return domainObject.getCapability("editor").save();
|
return domainObject.getCapability("editor").save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideBlockingDialog() {
|
function onSuccess() {
|
||||||
dialog.hide();
|
dialog.hide();
|
||||||
|
self.notificationService.info("Save Succeeded");
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFailure() {
|
||||||
|
dialog.hide();
|
||||||
|
self.notificationService.error("Save Failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.show();
|
dialog.show();
|
||||||
|
|
||||||
return doSave()
|
return doSave()
|
||||||
.then(hideBlockingDialog)
|
.then(onSuccess)
|
||||||
.catch(hideBlockingDialog);
|
.catch(onFailure);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,11 +33,13 @@ define(
|
|||||||
*/
|
*/
|
||||||
function SaveAndStopEditingAction(
|
function SaveAndStopEditingAction(
|
||||||
dialogService,
|
dialogService,
|
||||||
|
notificationService,
|
||||||
context
|
context
|
||||||
) {
|
) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.domainObject = (context || {}).domainObject;
|
this.domainObject = (context || {}).domainObject;
|
||||||
this.dialogService = dialogService;
|
this.dialogService = dialogService;
|
||||||
|
this.notificationService = notificationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,7 +51,7 @@ define(
|
|||||||
*/
|
*/
|
||||||
SaveAndStopEditingAction.prototype.perform = function () {
|
SaveAndStopEditingAction.prototype.perform = function () {
|
||||||
var domainObject = this.domainObject,
|
var domainObject = this.domainObject,
|
||||||
saveAction = new SaveAction(this.dialogService, this.context);
|
saveAction = new SaveAction(this.dialogService, this.notificationService, this.context);
|
||||||
|
|
||||||
function closeEditor() {
|
function closeEditor() {
|
||||||
return domainObject.getCapability("editor").finish();
|
return domainObject.getCapability("editor").finish();
|
||||||
|
@ -43,6 +43,7 @@ define([
|
|||||||
policyService,
|
policyService,
|
||||||
dialogService,
|
dialogService,
|
||||||
copyService,
|
copyService,
|
||||||
|
notificationService,
|
||||||
context
|
context
|
||||||
) {
|
) {
|
||||||
this.domainObject = (context || {}).domainObject;
|
this.domainObject = (context || {}).domainObject;
|
||||||
@ -52,6 +53,7 @@ define([
|
|||||||
this.policyService = policyService;
|
this.policyService = policyService;
|
||||||
this.dialogService = dialogService;
|
this.dialogService = dialogService;
|
||||||
this.copyService = copyService;
|
this.copyService = copyService;
|
||||||
|
this.notificationService = notificationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,8 +119,10 @@ define([
|
|||||||
|
|
||||||
return self.dialogService
|
return self.dialogService
|
||||||
.getUserInput(wizard.getFormStructure(true),
|
.getUserInput(wizard.getFormStructure(true),
|
||||||
wizard.getInitialFormValue()
|
wizard.getInitialFormValue())
|
||||||
).then(wizard.populateObjectFromInput.bind(wizard));
|
.then(wizard.populateObjectFromInput.bind(wizard), function (failureReason) {
|
||||||
|
return Promise.reject("user canceled");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showBlockingDialog(object) {
|
function showBlockingDialog(object) {
|
||||||
@ -176,8 +180,16 @@ define([
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onFailure() {
|
function onSuccess(object) {
|
||||||
|
self.notificationService.info("Save Succeeded");
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFailure(reason) {
|
||||||
hideBlockingDialog();
|
hideBlockingDialog();
|
||||||
|
if (reason !== "user canceled") {
|
||||||
|
self.notificationService.error("Save Failed");
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,6 +202,7 @@ define([
|
|||||||
.then(saveAfterClone)
|
.then(saveAfterClone)
|
||||||
.then(finishEditing)
|
.then(finishEditing)
|
||||||
.then(hideBlockingDialog)
|
.then(hideBlockingDialog)
|
||||||
|
.then(onSuccess)
|
||||||
.catch(onFailure);
|
.catch(onFailure);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
/*global describe,it,expect,beforeEach,jasmine,waitsFor,runs*/
|
||||||
|
|
||||||
define(
|
define(
|
||||||
["../../src/actions/SaveAction"],
|
["../../src/actions/SaveAction"],
|
||||||
@ -28,7 +29,8 @@ define(
|
|||||||
var mockDomainObject,
|
var mockDomainObject,
|
||||||
mockEditorCapability,
|
mockEditorCapability,
|
||||||
actionContext,
|
actionContext,
|
||||||
dialogService,
|
mockDialogService,
|
||||||
|
mockNotificationService,
|
||||||
mockActionCapability,
|
mockActionCapability,
|
||||||
capabilities = {},
|
capabilities = {},
|
||||||
action;
|
action;
|
||||||
@ -68,11 +70,17 @@ define(
|
|||||||
actionContext = {
|
actionContext = {
|
||||||
domainObject: mockDomainObject
|
domainObject: mockDomainObject
|
||||||
};
|
};
|
||||||
dialogService = jasmine.createSpyObj(
|
|
||||||
|
mockDialogService = jasmine.createSpyObj(
|
||||||
"dialogService",
|
"dialogService",
|
||||||
["showBlockingMessage"]
|
["showBlockingMessage"]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
mockNotificationService = jasmine.createSpyObj(
|
||||||
|
"notificationService",
|
||||||
|
["info", "error"]
|
||||||
|
);
|
||||||
|
|
||||||
mockDomainObject.hasCapability.andReturn(true);
|
mockDomainObject.hasCapability.andReturn(true);
|
||||||
mockDomainObject.getCapability.andCallFake(function (capability) {
|
mockDomainObject.getCapability.andCallFake(function (capability) {
|
||||||
return capabilities[capability];
|
return capabilities[capability];
|
||||||
@ -81,7 +89,7 @@ define(
|
|||||||
mockEditorCapability.save.andReturn(mockPromise(true));
|
mockEditorCapability.save.andReturn(mockPromise(true));
|
||||||
mockEditorCapability.isEditContextRoot.andReturn(true);
|
mockEditorCapability.isEditContextRoot.andReturn(true);
|
||||||
|
|
||||||
action = new SaveAction(dialogService, actionContext);
|
action = new SaveAction(mockDialogService, mockNotificationService, actionContext);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("only applies to domain object with an editor capability", function () {
|
it("only applies to domain object with an editor capability", function () {
|
||||||
@ -105,30 +113,54 @@ define(
|
|||||||
expect(mockEditorCapability.save).toHaveBeenCalled();
|
expect(mockEditorCapability.save).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("a blocking dialog", function () {
|
describe("in order to keep the user in the loop", function () {
|
||||||
var mockDialogHandle;
|
var mockDialogHandle;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
mockDialogHandle = jasmine.createSpyObj("dialogHandle", ["dismiss"]);
|
mockDialogHandle = jasmine.createSpyObj("dialogHandle", ["dismiss"]);
|
||||||
dialogService.showBlockingMessage.andReturn(mockDialogHandle);
|
mockDialogService.showBlockingMessage.andReturn(mockDialogHandle);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it("shows a dialog while saving", function () {
|
it("shows a dialog while saving", function () {
|
||||||
mockEditorCapability.save.andReturn(new Promise(function () {
|
mockEditorCapability.save.andReturn(new Promise(function () {
|
||||||
}));
|
}));
|
||||||
action.perform();
|
action.perform();
|
||||||
expect(dialogService.showBlockingMessage).toHaveBeenCalled();
|
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
|
||||||
expect(mockDialogHandle.dismiss).not.toHaveBeenCalled();
|
expect(mockDialogHandle.dismiss).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("hides a dialog when saving is complete", function () {
|
it("hides the dialog when saving is complete", function () {
|
||||||
action.perform();
|
action.perform();
|
||||||
expect(dialogService.showBlockingMessage).toHaveBeenCalled();
|
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
|
||||||
expect(mockDialogHandle.dismiss).toHaveBeenCalled();
|
expect(mockDialogHandle.dismiss).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
|
it("notifies if saving succeeded", function () {
|
||||||
|
var mockCallback = jasmine.createSpy("callback");
|
||||||
|
mockEditorCapability.save.andReturn(Promise.resolve("success"));
|
||||||
|
action.perform().then(mockCallback);
|
||||||
|
waitsFor(function () {
|
||||||
|
return mockCallback.calls.length > 0;
|
||||||
|
});
|
||||||
|
runs(function () {
|
||||||
|
expect(mockNotificationService.info).toHaveBeenCalled();
|
||||||
|
expect(mockNotificationService.error).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("notifies if saving failed", function () {
|
||||||
|
var mockCallback = jasmine.createSpy("callback");
|
||||||
|
mockEditorCapability.save.andReturn(Promise.reject("some failure reason"));
|
||||||
|
action.perform().then(mockCallback);
|
||||||
|
waitsFor(function () {
|
||||||
|
return mockCallback.calls.length > 0;
|
||||||
|
});
|
||||||
|
runs(function () {
|
||||||
|
expect(mockNotificationService.error).toHaveBeenCalled();
|
||||||
|
expect(mockNotificationService.info).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
/*global describe,it,expect,beforeEach,jasmine*/
|
||||||
|
|
||||||
define(
|
define(
|
||||||
["../../src/actions/SaveAndStopEditingAction"],
|
["../../src/actions/SaveAndStopEditingAction"],
|
||||||
@ -35,6 +36,7 @@ define(
|
|||||||
mockEditorCapability,
|
mockEditorCapability,
|
||||||
actionContext,
|
actionContext,
|
||||||
dialogService,
|
dialogService,
|
||||||
|
notificationService,
|
||||||
mockActionCapability,
|
mockActionCapability,
|
||||||
capabilities = {},
|
capabilities = {},
|
||||||
action;
|
action;
|
||||||
@ -79,6 +81,11 @@ define(
|
|||||||
["showBlockingMessage"]
|
["showBlockingMessage"]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
notificationService = jasmine.createSpyObj(
|
||||||
|
"notificationService",
|
||||||
|
["info", "error"]
|
||||||
|
);
|
||||||
|
|
||||||
mockDomainObject.hasCapability.andReturn(true);
|
mockDomainObject.hasCapability.andReturn(true);
|
||||||
mockDomainObject.getCapability.andCallFake(function (capability) {
|
mockDomainObject.getCapability.andCallFake(function (capability) {
|
||||||
return capabilities[capability];
|
return capabilities[capability];
|
||||||
@ -87,7 +94,7 @@ define(
|
|||||||
mockEditorCapability.save.andReturn(mockPromise(true));
|
mockEditorCapability.save.andReturn(mockPromise(true));
|
||||||
mockEditorCapability.isEditContextRoot.andReturn(true);
|
mockEditorCapability.isEditContextRoot.andReturn(true);
|
||||||
|
|
||||||
action = new SaveAndStopEditingAction(dialogService, actionContext);
|
action = new SaveAndStopEditingAction(dialogService, notificationService, actionContext);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ define(
|
|||||||
mockObjectService,
|
mockObjectService,
|
||||||
mockDialogService,
|
mockDialogService,
|
||||||
mockCopyService,
|
mockCopyService,
|
||||||
|
mockNotificationService,
|
||||||
mockParent,
|
mockParent,
|
||||||
actionContext,
|
actionContext,
|
||||||
capabilities = {},
|
capabilities = {},
|
||||||
@ -112,11 +113,25 @@ define(
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
mockNotificationService = jasmine.createSpyObj(
|
||||||
|
"notificationService",
|
||||||
|
[
|
||||||
|
"info",
|
||||||
|
"error"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
actionContext = {
|
actionContext = {
|
||||||
domainObject: mockDomainObject
|
domainObject: mockDomainObject
|
||||||
};
|
};
|
||||||
|
|
||||||
action = new SaveAsAction(undefined, undefined, mockDialogService, mockCopyService, actionContext);
|
action = new SaveAsAction(
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
mockDialogService,
|
||||||
|
mockCopyService,
|
||||||
|
mockNotificationService,
|
||||||
|
actionContext);
|
||||||
|
|
||||||
spyOn(action, "getObjectService");
|
spyOn(action, "getObjectService");
|
||||||
action.getObjectService.andReturn(mockObjectService);
|
action.getObjectService.andReturn(mockObjectService);
|
||||||
@ -186,7 +201,7 @@ define(
|
|||||||
expect(mockDialogService.getUserInput).toHaveBeenCalled();
|
expect(mockDialogService.getUserInput).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("a blocking dialog", function () {
|
describe("in order to keep the user in the loop", function () {
|
||||||
var mockDialogHandle;
|
var mockDialogHandle;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
@ -194,14 +209,14 @@ define(
|
|||||||
mockDialogService.showBlockingMessage.andReturn(mockDialogHandle);
|
mockDialogService.showBlockingMessage.andReturn(mockDialogHandle);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("indicates that a save is taking place", function () {
|
it("shows a blocking dialog indicating that saving is in progress", function () {
|
||||||
mockEditorCapability.save.andReturn(new Promise(function () {}));
|
mockEditorCapability.save.andReturn(new Promise(function () {}));
|
||||||
action.perform();
|
action.perform();
|
||||||
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
|
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
|
||||||
expect(mockDialogHandle.dismiss).not.toHaveBeenCalled();
|
expect(mockDialogHandle.dismiss).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("is hidden after saving", function () {
|
it("hides the blocking dialog after saving finishes", function () {
|
||||||
var mockCallback = jasmine.createSpy();
|
var mockCallback = jasmine.createSpy();
|
||||||
action.perform().then(mockCallback);
|
action.perform().then(mockCallback);
|
||||||
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
|
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
|
||||||
@ -212,6 +227,31 @@ define(
|
|||||||
expect(mockDialogHandle.dismiss).toHaveBeenCalled();
|
expect(mockDialogHandle.dismiss).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("notifies if saving succeeded", function () {
|
||||||
|
var mockCallback = jasmine.createSpy();
|
||||||
|
action.perform().then(mockCallback);
|
||||||
|
waitsFor(function () {
|
||||||
|
return mockCallback.calls.length > 0;
|
||||||
|
});
|
||||||
|
runs(function () {
|
||||||
|
expect(mockNotificationService.info).toHaveBeenCalled();
|
||||||
|
expect(mockNotificationService.error).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("notifies if saving failed", function () {
|
||||||
|
mockCopyService.perform.andReturn(Promise.reject("some failure reason"));
|
||||||
|
var mockCallback = jasmine.createSpy();
|
||||||
|
action.perform().then(mockCallback);
|
||||||
|
waitsFor(function () {
|
||||||
|
return mockCallback.calls.length > 0;
|
||||||
|
});
|
||||||
|
runs(function () {
|
||||||
|
expect(mockNotificationService.error).toHaveBeenCalled();
|
||||||
|
expect(mockNotificationService.info).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user