Skip to content

Commit 736cba7

Browse files
authored
Merge pull request #1056 from nasa/blocking-save-dialog
[Save] Show blocking dialog
2 parents 8bdf1e3 + 24e870a commit 736cba7

File tree

6 files changed

+107
-14
lines changed

6 files changed

+107
-14
lines changed

platform/commonUI/edit/bundle.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,9 @@ define([
206206
"implementation": SaveAction,
207207
"name": "Save",
208208
"description": "Save changes made to these objects.",
209-
"depends": [],
209+
"depends": [
210+
"dialogService"
211+
],
210212
"priority": "mandatory"
211213
},
212214
{

platform/commonUI/edit/src/actions/SaveAction.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
*****************************************************************************/
2222

2323
define(
24-
[],
25-
function () {
24+
['./SaveInProgressDialog'],
25+
function (SaveInProgressDialog) {
2626

2727
/**
2828
* The "Save" action; the action triggered by clicking Save from
@@ -33,9 +33,11 @@ define(
3333
* @memberof platform/commonUI/edit
3434
*/
3535
function SaveAction(
36+
dialogService,
3637
context
3738
) {
3839
this.domainObject = (context || {}).domainObject;
40+
this.dialogService = dialogService;
3941
}
4042

4143
/**
@@ -46,7 +48,8 @@ define(
4648
* @memberof platform/commonUI/edit.SaveAction#
4749
*/
4850
SaveAction.prototype.perform = function () {
49-
var domainObject = this.domainObject;
51+
var domainObject = this.domainObject,
52+
dialog = new SaveInProgressDialog(this.dialogService);
5053

5154
function resolveWith(object) {
5255
return function () {
@@ -72,8 +75,17 @@ define(
7275
return object;
7376
}
7477

75-
//return doSave().then(returnToBrowse);
76-
return doSave().then(returnToBrowse);
78+
function hideBlockingDialog(object) {
79+
dialog.hide();
80+
return object;
81+
}
82+
83+
dialog.show();
84+
85+
return doSave()
86+
.then(hideBlockingDialog)
87+
.then(returnToBrowse)
88+
.catch(hideBlockingDialog);
7789
};
7890

7991
/**

platform/commonUI/edit/src/actions/SaveAsAction.js

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,14 @@
2121
*****************************************************************************/
2222

2323

24-
define(
25-
['../creation/CreateWizard'],
26-
function (CreateWizard) {
24+
define([
25+
'../creation/CreateWizard',
26+
'./SaveInProgressDialog'
27+
],
28+
function (
29+
CreateWizard,
30+
SaveInProgressDialog
31+
) {
2732

2833
/**
2934
* The "Save" action; the action triggered by clicking Save from
@@ -105,7 +110,8 @@ define(
105110
SaveAsAction.prototype.save = function () {
106111
var self = this,
107112
domainObject = this.domainObject,
108-
copyService = this.copyService;
113+
copyService = this.copyService,
114+
dialog = new SaveInProgressDialog(this.dialogService);
109115

110116
function doWizardSave(parent) {
111117
var wizard = self.createWizard(parent);
@@ -116,6 +122,16 @@ define(
116122
).then(wizard.populateObjectFromInput.bind(wizard));
117123
}
118124

125+
function showBlockingDialog(object) {
126+
dialog.show();
127+
return object;
128+
}
129+
130+
function hideBlockingDialog(object) {
131+
dialog.hide();
132+
return object;
133+
}
134+
119135
function fetchObject(objectId) {
120136
return self.getObjectService().getObjects([objectId]).then(function (objects) {
121137
return objects[objectId];
@@ -140,14 +156,22 @@ define(
140156
.then(resolveWith(clonedObject));
141157
}
142158

159+
function onFailure() {
160+
hideBlockingDialog();
161+
return false;
162+
}
163+
143164
return getParent(domainObject)
144165
.then(doWizardSave)
166+
.then(showBlockingDialog)
145167
.then(getParent)
146168
.then(cloneIntoParent)
147169
.then(commitEditingAfterClone)
148-
.catch(resolveWith(false));
170+
.then(hideBlockingDialog)
171+
.catch(onFailure);
149172
};
150173

174+
151175
/**
152176
* Check if this action is applicable in a given context.
153177
* This will ensure that a domain object is present in the context,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
define([], function () {
2+
function SaveInProgressDialog(dialogService) {
3+
this.dialogService = dialogService;
4+
}
5+
6+
SaveInProgressDialog.prototype.show = function () {
7+
this.dialogService.showBlockingMessage({
8+
title: "Saving...",
9+
hint: "Do not navigate away from this page or close this browser tab while this message is displayed.",
10+
unknownProgress: true,
11+
severity: "info"
12+
});
13+
};
14+
15+
SaveInProgressDialog.prototype.hide = function () {
16+
this.dialogService.dismiss();
17+
};
18+
19+
return SaveInProgressDialog;
20+
});

platform/commonUI/edit/test/actions/SaveActionSpec.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ define(
2828
var mockDomainObject,
2929
mockEditorCapability,
3030
actionContext,
31+
dialogService,
3132
mockActionCapability,
3233
capabilities = {},
3334
action;
@@ -36,6 +37,9 @@ define(
3637
return {
3738
then: function (callback) {
3839
return mockPromise(callback(value));
40+
},
41+
catch: function (callback) {
42+
return mockPromise(callback(value));
3943
}
4044
};
4145
}
@@ -64,6 +68,10 @@ define(
6468
actionContext = {
6569
domainObject: mockDomainObject
6670
};
71+
dialogService = jasmine.createSpyObj(
72+
"dialogService",
73+
["showBlockingMessage", "dismiss"]
74+
);
6775

6876
mockDomainObject.hasCapability.andReturn(true);
6977
mockDomainObject.getCapability.andCallFake(function (capability) {
@@ -73,8 +81,7 @@ define(
7381
mockEditorCapability.save.andReturn(mockPromise(true));
7482
mockEditorCapability.isEditContextRoot.andReturn(true);
7583

76-
action = new SaveAction(actionContext);
77-
84+
action = new SaveAction(dialogService, actionContext);
7885
});
7986

8087
it("only applies to domain object with an editor capability", function () {
@@ -104,6 +111,19 @@ define(
104111
expect(mockActionCapability.perform).toHaveBeenCalledWith("navigate");
105112
});
106113

114+
it("shows a dialog while saving", function () {
115+
mockEditorCapability.save.andReturn(new Promise(function () {}));
116+
action.perform();
117+
expect(dialogService.showBlockingMessage).toHaveBeenCalled();
118+
expect(dialogService.dismiss).not.toHaveBeenCalled();
119+
});
120+
121+
it("hides a dialog when saving is complete", function () {
122+
action.perform();
123+
expect(dialogService.showBlockingMessage).toHaveBeenCalled();
124+
expect(dialogService.dismiss).toHaveBeenCalled();
125+
});
126+
107127
});
108128
}
109129
);

platform/commonUI/edit/test/actions/SaveAsActionSpec.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ define(
100100
mockDialogService = jasmine.createSpyObj(
101101
"dialogService",
102102
[
103-
"getUserInput"
103+
"getUserInput",
104+
"showBlockingMessage",
105+
"dismiss"
104106
]
105107
);
106108
mockDialogService.getUserInput.andReturn(mockPromise(undefined));
@@ -169,6 +171,19 @@ define(
169171
expect(mockDialogService.getUserInput).toHaveBeenCalled();
170172
});
171173

174+
it("shows a blocking dialog while waiting for save", function () {
175+
mockEditorCapability.save.andReturn(new Promise(function () {}));
176+
action.perform();
177+
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
178+
expect(mockDialogService.dismiss).not.toHaveBeenCalled();
179+
});
180+
181+
it("hides the blocking dialog after saving", function () {
182+
action.perform();
183+
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
184+
expect(mockDialogService.dismiss).toHaveBeenCalled();
185+
});
186+
172187
});
173188
}
174189
);

0 commit comments

Comments
 (0)