]> git.argeo.org Git - lgpl/argeo-commons.git/blob - ria/UserEditorApplet.js
Prepare next development cycle
[lgpl/argeo-commons.git] / ria / UserEditorApplet.js
1 /**
2 * A simple Hello World applet for documentation purpose.
3 * The only associated command is the "Close" command.
4 */
5 /* *************************************************
6 #asset(resource/org.argeo.security.ria/*)
7 ****************************************************/
8 qx.Class.define("org.argeo.security.ria.UserEditorApplet",
9 {
10 extend : qx.ui.container.Composite,
11 implement : [org.argeo.ria.components.IView],
12
13 construct : function(){
14 this.base(arguments);
15 this.setLayout(new qx.ui.layout.VBox(5));
16 },
17
18 events : {
19 "savedUser" : "qx.event.type.Data"
20 },
21
22 properties :
23 {
24 /**
25 * The viewPane inside which this applet is added.
26 */
27 view : {
28 init : null
29 },
30 /**
31 * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
32 */
33 commands : {
34 init : {
35 "save_user" : {
36 label : "Save",
37 icon : "org.argeo.security.ria/document-save.png",
38 shortcut : "Control+s",
39 enabled : true,
40 menu : "Users",
41 toolbar : "user",
42 callback : function(e){
43 // CALL SERVICE AND GET UP TO DATE USER
44 this.saveUser();
45 },
46 selectionChange : function(viewName, data){
47 if(viewName != "editor") return;
48 var iApplet = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById("editor").getContent();
49 this.setEnabled(iApplet.getModified());
50 },
51 command : null
52 },
53 "add_nature" : {
54 label : "Add Nature ...",
55 icon : "org.argeo.security.ria/list-add.png",
56 shortcut : null,
57 enabled : true,
58 menu : "Natures",
59 toolbar : null,
60 callback : function(e){
61 },
62 submenuCallback : function(commandClass){
63 this._addNatureTab(commandClass, null, true);
64 },
65 submenu : [
66 {"label" : "Totot", "icon":"","commandId" : "toto"},
67 {"label" : "Totot", "icon":"","commandId" : "toto"}
68 ],
69 selectionChange : function(viewName, data){
70 if(viewName != "editor") return;
71 var iApplet = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById("editor").getContent();
72 if(iApplet && iApplet.getCurrentNatureTabs() && iApplet.getAvailableNatures()
73 && iApplet.getCurrentNatureTabs().length < qx.lang.Object.getLength(iApplet.getAvailableNatures())){
74 this.setEnabled(true);
75 }else{
76 this.setEnabled(false);
77 }
78 },
79 command : null
80 },
81 "remove_nature" : {
82 label : "Remove Nature",
83 icon : "org.argeo.security.ria/list-remove.png",
84 shortcut : null,
85 enabled : true,
86 menu : "Natures",
87 toolbar : null,
88 callback : function(e){
89 this.removeSelectedTab();
90 },
91 selectionChange : function(viewName, data){
92 if(viewName != "editor") return;
93 var iApplet = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById("editor").getContent();
94 if(iApplet && iApplet.getSelectedNatureTab() && iApplet.getSelectedNatureTab().getUserData("NATURE_CLASS")){
95 this.setEnabled(true);
96 }else{
97 this.setEnabled(false);
98 }
99 },
100 command : null
101 },
102 "close" : {
103 label : "Close",
104 icon : "org.argeo.security.ria/window-close.png",
105 shortcut : "Control+w",
106 enabled : true,
107 menu : "Users",
108 toolbar : "user",
109 callback : function(e){
110 // Call service to delete
111 var iApplet = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById("editor").getContent();
112 if(!iApplet.getModified() && !iApplet.getNaturesModified()){
113 this.getView().closeCurrent();
114 return;
115 }
116 var modal = new org.argeo.ria.components.Modal("Warning");
117 modal.addConfirm("There are unsaved changes!\n Are you sure you want to close?");
118 modal.addListener("ok", function(){
119 this.getView().closeCurrent();
120 }, this);
121 modal.attachAndShow();
122 },
123 command : null
124 }
125 }
126 },
127 viewSelection : {
128 nullable:false,
129 check:"org.argeo.ria.components.ViewSelection"
130 },
131 modified : {
132 init : false,
133 apply : "_applyDetailsModified"
134 },
135 naturesModified : {
136 init : false,
137 apply : "_applyNaturesModified"
138 },
139 rolesList : {
140
141 },
142 instanceId : {
143 init:"",
144 event : "changeInstanceId"
145 },
146 instanceLabel : {
147 init:"Editor",
148 event : "changeInstanceLabel"
149 },
150 loaded : {
151 init : false
152 },
153 currentNatureTabs : {
154 },
155 availableNatures : {
156 },
157 selectedNatureTab : {
158 nullable : true
159 },
160 currentUser : {
161
162 }
163 },
164
165 members :
166 {
167 /**
168 * Called at applet creation. Just registers viewPane.
169 * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.
170 */
171 init : function(viewPane, data){
172 if(!data.USER){
173 var now = new Date();
174 this.setInstanceId(now.getTime());
175 this.setInstanceLabel("New User");
176 }else{
177 this.setInstanceId(data.USER);
178 this.setInstanceLabel("User " + data.USER);
179 }
180 this.setView(viewPane);
181 this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
182
183 this.naturesManager = new org.argeo.security.ria.components.NaturesManager();
184 var detectedNatures = this.naturesManager.getDetectedNatures();
185 this.setAvailableNatures(detectedNatures);
186
187 // TOOLBAR
188 this.buttonGB = new qx.ui.container.Composite(new qx.ui.layout.HBox(5, "right"));
189 this.add(this.buttonGB);
190
191 this.setCurrentNatureTabs([]);
192 this.naturesTab = new qx.ui.tabview.TabView("top");
193 this.naturesTab.addListener("changeSelected", function(e){
194 this.setSelectedNatureTab(e.getData());
195 this.getViewSelection().triggerEvent();
196 }, this);
197
198 this.basicPage = new qx.ui.tabview.Page("Basic Information");
199 this.basicPage.setLayout(new qx.ui.layout.VBox(5));
200
201 // GROUPBOXES
202
203 this.basicGB = new qx.ui.groupbox.GroupBox("Base Informations");
204 var grid = new qx.ui.layout.Grid(5,5);
205 this.basicGB.setLayout(grid);
206 grid.setColumnFlex(0,1);
207 grid.setColumnAlign(0,"right", "middle");
208 grid.setColumnFlex(1,2);
209 this._initializeGroupBox(this.basicGB);
210
211 this.passGB = new qx.ui.groupbox.GroupBox("Set/Modify Password");
212 this.passGB.setLayout(new qx.ui.layout.VBox());
213 this._initializeGroupBox(this.passGB);
214
215 this.add(this.basicGB);
216 this.add(this.passGB);
217
218 // FIELDS
219 this.usernameField = new qx.ui.form.TextField();
220 this.basicGB.add(new qx.ui.basic.Label("Username"), {row:0,column:0});
221 this.basicGB.add(this.usernameField, {row:0,column:1});
222
223 this.rolesField = new org.argeo.ria.components.ui.MultipleComboBox();
224 this.rolesField.setChoiceValues(data.ROLES_LIST);
225 this.basicGB.add(new qx.ui.basic.Label("Roles"), {row:1,column:0});
226 this.basicGB.add(this.rolesField, {row:1,column:1});
227
228 this.passPane = new org.argeo.security.ria.components.PasswordCredentialImpl();
229 this.passGB.add(this.passPane.getContainer());
230
231 //this.naturesTab.add(this.basicPage);
232 this.natureButtonGB = new qx.ui.container.Composite(new qx.ui.layout.HBox(5, "right"));
233 this.natureButtonGB.setMarginTop(15);
234 this.add(this.natureButtonGB);
235
236
237 this.add(this.naturesTab, {flex:1});
238
239 this.naturesTab.setVisibility("excluded");
240 this.fakePane = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
241 this.fakePane.setVisibility("visible");
242 this.fakePane.setDecorator("tabview-pane");
243 this.fakePane.setMarginTop(30);
244 this.add(this.fakePane, {flex:1});
245
246 title = new qx.ui.basic.Atom("User Details", "org.argeo.security.ria/preferences-users.png");
247 title.setFont(qx.bom.Font.fromString("16px sans-serif bold"));
248 this.buttonGB.add(title);
249 this.buttonGB.add(new qx.ui.core.Spacer(), {flex:1});
250
251 var title2 = new qx.ui.basic.Atom("User Natures", "org.argeo.security.ria/identity.png");
252 title2.setFont(qx.bom.Font.fromString("16px sans-serif bold"));
253 this.natureButtonGB.add(title2);
254 this.natureButtonGB.add(new qx.ui.core.Spacer(), {flex:1});
255
256
257 },
258
259 saveUser : function(){
260 var user = this.getCurrentUser();
261 user.setName(this.usernameField.getValue());
262 var roles = this.rolesField.getValue();
263 if(roles && roles != ""){
264 user.setRoles(roles.split(","));
265 }else{
266 user.setRoles([]);
267 }
268
269 // GO TO AND RETURN FROM SERVER
270 if(user.isCreate()){
271 if(!this.passPane.validate()){
272 this.error("Warning, passwords differ!");
273 return;
274 }
275 user.setPassword(this.passPane.getData());
276 var create = true;
277 var userExists = false;
278 var req = org.argeo.security.ria.SecurityAPI.getUserExistsService(user.getName());
279 req.addListener("completed", function(response){
280 userExists = response.getContent().value;
281 }, this);
282 req.setAsynchronous(false);
283 req.send();
284 if(userExists){
285 this.error("User already exists, choose another name!");
286 return;
287 }
288 }else{
289 var pass = this.passPane.getData();
290 if(pass != null && !this.passPane.validate()){
291 this.error("Warning, passwords differ!");
292 return;
293 }
294 }
295 this.passPane.clear();
296 var saveCompletedCallback = qx.lang.Function.bind(function(){
297 if(create){
298 this.setInstanceLabel("User " + user.getName());
299 this.setInstanceId(user.getName());
300 }
301 this._setGuiInCreateMode(false);
302 this.partialRefreshUser(user, ["details","natures"]);
303 this.setModified(false);
304 this.getViewSelection().triggerEvent();
305 this.fireDataEvent("savedUser", user);
306 }, this);
307 var userService = user.getSaveService();
308 userService.addListener("completed", function(response){
309 if(response.getContent().status && response.getContent().status == "ERROR"){
310 return;
311 }
312 user.load(response.getContent(), "json");
313 if(pass!=null){
314 var passService = org.argeo.security.ria.SecurityAPI.getUpdateUserPassService(user.getName(), pass);
315 passService.addListener("completed", function(response){
316 if(response.getContent().status){
317 this.info(response.getContent().message);
318 }
319 saveCompletedCallback();
320 }, this);
321 passService.send();
322 }else{
323 saveCompletedCallback();
324 }
325 }, this);
326 userService.send();
327 },
328
329 _addNatureTab : function(natureClass, natureData, select){
330 var crtTabs = this.getCurrentNatureTabs();
331 if(qx.lang.Array.contains(crtTabs, natureClass.NATURE_TYPE)){
332 this.error("There can only be one instance of a given nature type!");
333 return null;
334 }
335 if(!this.naturesTab.isVisible()){
336 if(this.fakePane) this.fakePane.setVisibility("excluded");
337 this.naturesTab.setVisibility("visible");
338 }
339 var page = new qx.ui.tabview.Page("Nature : " + natureClass.NATURE_LABEL);
340 page.setLayout(new qx.ui.layout.Dock());
341 page.setUserData("NATURE_CLASS", natureClass);
342 var newClass = new natureClass();
343 page.add(newClass.getContainer(), {edge:"center"});
344
345 buttons = new qx.ui.container.Composite(new qx.ui.layout.HBox(5, "center"));
346 var editB = new qx.ui.form.Button("Edit this Nature", "org.argeo.security.ria/document-properties-22.png");
347 var saveB = new qx.ui.form.Button("Save", "org.argeo.security.ria/dialog-apply.png");
348 var cancelB = new qx.ui.form.Button("Cancel", "org.argeo.security.ria/dialog-cancel.png");
349 buttons.add(editB);
350 buttons.add(saveB);
351 buttons.add(cancelB);
352 page.add(buttons, {edge:"south"});
353 editB.addListener("execute", function(){
354 newClass.setEditMode(true);
355 editB.setVisibility("excluded");
356 saveB.setVisibility("visible");
357 cancelB.setVisibility("visible");
358 });
359 cancelB.addListener("execute", function(){
360 if(newClass.getIsNew()){
361 this._removeNatureTab(natureClass);
362 }
363 newClass.setEditMode(false);
364 editB.setVisibility("visible");
365 saveB.setVisibility("excluded");
366 cancelB.setVisibility("excluded");
367 }, this);
368 saveB.addListener("execute", function(){
369 // SAVE CURRENT NATURE
370 var data = newClass.getData();
371 if(newClass.getIsNew()){
372 this.getCurrentUser().addNature(data);
373 }else{
374 this.getCurrentUser().updateNature(data);
375 }
376 this.saveUser();
377 this.setNaturesModified(false);
378 newClass.setEditMode(false);
379 editB.setVisibility("visible");
380 saveB.setVisibility("excluded");
381 cancelB.setVisibility("excluded");
382 }, this);
383 if(natureData){
384 newClass.setData(natureData);
385 cancelB.execute();
386 }else{
387 newClass.setIsNew(true);
388 editB.execute();
389 }
390 this.naturesTab.add(page);
391 crtTabs.push(natureClass.NATURE_TYPE);
392 this.getViewSelection().triggerEvent();
393 newClass.addListener("modified", function(){
394 this.setNaturesModified(true);
395 }, this);
396 if(select){
397 this.naturesTab.setSelected(page);
398 }
399 return page;
400 },
401
402 _removeNatureTab : function(natureClass){
403 this.naturesTab.getChildren().forEach(function(el){
404 if(el.getUserData("NATURE_CLASS") == natureClass){
405 this.naturesTab.remove(el);
406 qx.lang.Array.remove(this.getCurrentNatureTabs(), natureClass.NATURE_TYPE);
407 this.getViewSelection().triggerEvent();
408 }
409 }, this);
410 if(this.naturesTab.getChildren().length == 0){
411 this.naturesTab.setVisibility("excluded");
412 this.fakePane.setVisibility("visible");
413 }
414 },
415
416 removeSelectedTab : function(){
417 var selected = this.naturesTab.getSelected();
418 var tabClass = selected.getUserData("NATURE_CLASS");
419 var user = this.getCurrentUser();
420 user.removeNature(tabClass.NATURE_TYPE);
421 this.saveUser();
422 this._removeNatureTab(tabClass);
423 },
424
425 removeAllTabs : function(){
426 while(this.naturesTab.getSelected()){
427 this._removeNatureTab(this.naturesTab.getSelected().getUserData("NATURE_CLASS"));
428 }
429 },
430
431 _setGuiInCreateMode : function(bool){
432 if(bool){
433 if(!this.natureButtonGB.isVisible()) return;
434 this.natureButtonGB.hide();
435 this.fakePane.setVisibility("excluded");
436 }else{
437 if(this.natureButtonGB.isVisible()) return;
438 this.natureButtonGB.show();
439 this.fakePane.setVisibility("visible");
440 }
441 },
442
443 _attachListeners : function(){
444 this.usernameField.addListener("changeValue", function(){
445 this.setModified(true);
446 }, this);
447 this.rolesField.addListener("changeValue", function(){
448 this.setModified(true);
449 }, this);
450 this.passPane.addListener("modified", function(){
451 this.setModified(true);
452 }, this);
453 },
454
455 _initializeGroupBox: function(groupBox){
456 groupBox.setPadding(0);
457 groupBox.getChildrenContainer().setPadding(8);
458 },
459
460 _applyDetailsModified : function(value){
461 if(value) this.getViewSelection().triggerEvent();
462 },
463
464 _applyNaturesModified : function(value){
465 if(value) this.getViewSelection().triggerEvent();
466 },
467
468 loadUserData : function(userName){
469 var userDataService = org.argeo.security.ria.SecurityAPI.getUserDetailsService(userName);
470 userDataService.addListener("completed", function(response){
471 var user = new org.argeo.security.ria.model.User();
472 user.load(response.getContent(), "json");
473 this.setCurrentUser(user);
474 this.usernameField.setValue(user.getName());
475 this.usernameField.setReadOnly(true);
476 this.rolesField.setValue(user.getRoles());
477 var userNatureTabs = this.naturesManager.detectNaturesInData(user.getNatures());
478 if(userNatureTabs.length){
479 userNatureTabs.forEach(function(el){
480 this._addNatureTab(el.NATURE_CLASS, el.NATURE_DATA);
481 }, this);
482 }
483 this._attachListeners();
484 }, this);
485 userDataService.send();
486 },
487
488 partialRefreshUser : function(user, target){
489 if(!qx.lang.Array.isArray(target)) target = [target];
490
491 if(qx.lang.Array.contains(target,"natures")){
492 if(this.getSelectedNatureTab()){
493 var selectedTab = this.getSelectedNatureTab().getUserData("NATURE_CLASS");
494 }
495 this.removeAllTabs();
496 var userNatureTabs = this.naturesManager.detectNaturesInData(user.getNatures());
497 if(userNatureTabs.length){
498 userNatureTabs.forEach(function(el){
499 this._addNatureTab(el.NATURE_CLASS, el.NATURE_DATA, (selectedTab && selectedTab == el.NATURE_CLASS));
500 }, this);
501 }
502 }
503 if(qx.lang.Array.contains(target,"details")){
504 this.setInstanceLabel("User "+user.getName());
505 this.usernameField.setValue(user.getName());
506 this.rolesField.setValue(user.getRoles());
507 this.usernameField.setReadOnly(true);
508 }
509 },
510
511 /**
512 * Load a given row : the data passed must be a simple data array.
513 * @param data {Element} The text xml description.
514 */
515 load : function(userName){
516 if(this.getLoaded()){
517 return;
518 }
519 // MUST BE DONE AFTER COMMANDS ARE INITIALIZED!
520 var commands = this.getCommands();
521 var saveButton = commands["save_user"].command.getFormButton();
522 var closeButton = commands["close"].command.getFormButton();
523 var removeButton = commands["remove_nature"].command.getFormButton();
524 var natureButton = commands["add_nature"].command.getFormButton();
525
526 var detectedNatures = this.getAvailableNatures();
527 var newMenu = [];
528 for(var key in detectedNatures){
529 newMenu.push({"label" : detectedNatures[key].NATURE_LABEL, "icon":"", "commandId" : detectedNatures[key]});
530 }
531 commands["add_nature"].command.setMenu(newMenu);
532
533 natureButton.setShow("icon");
534 removeButton.setShow("icon");
535 saveButton.setShow("icon");
536 closeButton.setShow("icon");
537
538 this.buttonGB.add(saveButton);
539 this.buttonGB.add(closeButton);
540 this.natureButtonGB.add(natureButton);
541 this.natureButtonGB.add(removeButton);
542
543 if(userName){
544 this.loadUserData(userName);
545 this._setGuiInCreateMode(false);
546 }else{
547 this.setCurrentUser(new org.argeo.security.ria.model.User());
548 this._setGuiInCreateMode(true);
549 this._attachListeners();
550 this.setModified(true);
551 }
552
553
554 this.setLoaded(true);
555
556 },
557
558 addScroll : function(){
559 return false;
560 },
561
562 close : function(){
563 return false;
564 }
565
566 }
567 });