Roles management working good
[lgpl/argeo-commons.git] / security / runtime / org.argeo.security.ria / src / argeo-ria-lib / security / class / org / argeo / security / ria / RolesApplet.js
index 3d6ad869fb85b2a757148d6fa5994c6b43886e04..65b5427b30259fbe5dc1a968744151cbad0d73f1 100644 (file)
@@ -27,12 +27,87 @@ qx.Class.define("org.argeo.security.ria.RolesApplet",
         * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions} 
         */
        commands : {
-               init : {}
+               init : {
+                       "new_role" : {
+                               label           : "Create Role", 
+                               icon            : "org.argeo.security.ria/list-add.png",
+                               shortcut        : "Control+n",
+                               enabled         : true,
+                               menu            : "Roles",
+                               toolbar         : null,
+                               callback        : function(e){
+                                       // Prompt for new name
+                                       var modal = new org.argeo.ria.components.Modal();
+                                       modal.makePromptForm("Please enter a role name", function(roleName){
+                                               var service = org.argeo.security.ria.SecurityAPI.getCreateRoleService(roleName);
+                                               service.addListener("completed", function(response){
+                                                       this.loadRolesList();
+                                               }, this);
+                                               service.send();
+                                       }, this);
+                                       modal.attachAndShow();
+                               },
+                               command         : null
+                       },      
+                       "delete_role" : {
+                               label           : "Delete Role", 
+                               icon            : "org.argeo.security.ria/list-remove.png",
+                               shortcut        : "Control+s",
+                               enabled         : true,
+                               menu            : "Roles",
+                               toolbar         : null,
+                               callback        : function(e){
+                                       // Call service to delete
+                                       var roles = this.getViewSelection().getNodes();
+                                       for(var i=0;i<roles.length;i++){
+                                               var service = org.argeo.security.ria.SecurityAPI.getDeleteRoleService(roles[i]);
+                                               service.addListener("completed", function(response){
+                                                       this.loadRolesList();
+                                               }, this);
+                                               service.send();
+                                       }
+                               },
+                               selectionChange : function(viewName, data){
+                                       if(viewName != "roles") return;
+                                       this.setEnabled(!(data == null || !data.length));                                       
+                               },
+                               command         : null
+                       },                                              
+                       "edit_role" : {
+                               label           : "Edit Role", 
+                               icon            : "org.argeo.security.ria/document-properties.png",
+                               shortcut        : "Control+r",
+                               enabled         : true,
+                               menu            : "Roles",
+                               toolbar         : null,
+                               callback        : function(e){
+                                       // Call service to delete
+                                       this.setGuiMode("edit");
+                               },
+                               selectionChange : function(viewName, data){
+                                       if(viewName != "roles") return;
+                                       this.setEnabled(!(data == null || !data.length || data.length > 1));                                    
+                               },
+                               command         : null
+                       }                                               
+               }
        },
        viewSelection : {
                nullable:false, 
                check:"org.argeo.ria.components.ViewSelection"
        },
+       guiMode : {
+               apply : "_applyGuiMode"
+       },
+       rolesList : {
+               check : "Array",
+               event : "changeRolesList"
+       },      
+       chooserOriginalSelection : {},
+       chooserSelectionModified : {
+               init:false,
+               event : "chooserSelectionWasModified"
+       },
        instanceId : {init:""},
        instanceLabel : {init:""}
   },
@@ -45,7 +120,13 @@ qx.Class.define("org.argeo.security.ria.RolesApplet",
         */
        init : function(viewPane){
                this.setView(viewPane);
-               this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));                
+               this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
+               
+               this.toolBar = new qx.ui.toolbar.ToolBar();
+               this.toolBarPart = new qx.ui.toolbar.Part();
+               this.toolBar.add(this.toolBarPart);             
+               viewPane.add(this.toolBar);
+               
                this.tableModel = new qx.ui.table.model.Simple();
                this.tableModel.setColumns(["Role Name"]);
                this.table = new qx.ui.table.Table(this.tableModel, {
@@ -53,22 +134,248 @@ qx.Class.define("org.argeo.security.ria.RolesApplet",
                                        return new qx.ui.table.columnmodel.Resize(obj)
                                }
                        });
-               this.table.setStatusBarVisible(false);                  
+               this.table.setStatusBarVisible(false);
+               this.table.setShowCellFocusIndicator(false);
+               this.table.setColumnVisibilityButtonVisible(false);
+               this.table.highlightFocusedRow(false);                  
                viewPane.add(this.table, {height:"100%"});
+               this.table.getSelectionModel().addListener("changeSelection", function(){
+                       this._selectionToValues(this.table.getSelectionModel(), this.getViewSelection());
+               }, this);
                
-               var selectionModel = this.table.getSelectionModel(); 
-               selectionModel.addListener("changeSelection", function(){
-                       var ranges = selectionModel.getSelectedRanges();
+               this.rolesUsersStub = {"ROLE_ADMIN":["gandalf"],"ROLE_USER":["demo","frodo","gandalf"]};
+                                       
+               this.toggleButton = new qx.ui.form.ToggleButton("Filter", "org.argeo.security.ria/go-next.png");
+               this.toggleButton.set({
+                       show:"icon",
+                       margin:2,
+                       toolTip :new qx.ui.tooltip.ToolTip("Apply automatic filtering on Users list")                   
                });
+                               
+               // TOGGLE THE GUI MODES                 
+               this.toggleButton.addListener("changeChecked", function(event){
+                       this.setGuiMode(event.getData()?"filter":"clear");
+               }, this);
+               
+               this.saveButton = new qx.ui.form.Button("Save", "org.argeo.security.ria/document-save.png");
+               this.saveButton.set({
+                       show:"icon",
+                       margin:2,
+                       toolTip :new qx.ui.tooltip.ToolTip("Save changes"),
+                       visibility : "excluded"
+               });
+               
+               this.cancelButton = new qx.ui.form.Button("Cancel", "org.argeo.security.ria/window-close.png");
+               this.cancelButton.set({
+                       show:"icon",
+                       margin:2,
+                       toolTip :new qx.ui.tooltip.ToolTip("Cancel changes"),
+                       visibility : "excluded"                         
+               });
+               
+               this.saveButton.addListener("execute", function(){
+                       if(!this.usersAppletReference){
+                               this.setGuiMode(this.initialState);
+                               return;
+                       }
+                       var newSelection = this.usersAppletReference.getViewSelection().getNodes();
+                       var diff = this._selectionDiff(this.getChooserOriginalSelection(), newSelection);
+                       this.saveRoleModifications(diff.deltaPlus, diff.deltaMinus);
+                       this.setGuiMode(this.initialState);
+               }, this);
+               this.cancelButton.addListener("execute", function(){
+                       if(!this.getChooserSelectionModified()){
+                               this.setGuiMode(this.initialState);
+                               return;
+                       }
+                       var modal = new org.argeo.ria.components.Modal("Warning");
+                       modal.addConfirm("There are unsaved changes!\n Are you sure you want to close?");
+                       modal.addListener("ok", function(){
+                               this.setGuiMode(this.initialState);
+                       }, this);
+                       modal.attachAndShow();                  
+               }, this);
+               
+               this.table.addListener("cellDblclick", function(cellEvent){
+                       this.setGuiMode("edit");
+               }, this);
+               this.addListener("changeRolesList", function(event){
+                       var data = [];
+                       event.getData().forEach(function(el){data.push([el]);});
+                       this.tableModel.setData(data);                                                  
+               }, this);
+               
+               this.setGuiMode("clear");
+       },
+       
+       _applyGuiMode : function(guiMode, previousMode){
+               var selectionModel = this.table.getSelectionModel();
+               if(!this.usersAppletReference){
+                       var vManager = org.argeo.ria.components.ViewsManager.getInstance();
+                       this.usersAppletReference = vManager.getViewPaneById("users").getContent();
+               }
+               
+               this.saveButton.setVisibility((guiMode=="edit"?"visible":"excluded"));
+               this.cancelButton.setVisibility((guiMode=="edit"?"visible":"excluded"));
+               this.table.setEnabled((guiMode=="edit"?false:true));
+               this.toggleButton.setVisibility((guiMode=="edit"?"excluded":"visible"));                        
+               
+               if(guiMode == "filter"){
+                       if(this.usersAppletReference){
+                               this.usersAppletReference.setGuiMode(("filter"));
+                               var viewSel = this.usersAppletReference.getViewSelection();
+                               viewSel.removeListener("changeSelection", this.monitorChooserSelectionChanges, this);                   
+                       }
+                       selectionModel.addListener("changeSelection", this.selectionToFilter, this);
+                       selectionModel.setSelectionMode(qx.ui.table.selection.Model.MULTIPLE_INTERVAL_SELECTION_TOGGLE);
+                       this.selectionToFilter();                       
+               }else if(guiMode == "edit"){
+                       if(!this.usersAppletReference) return;
+                       this.initialState = previousMode;
+                       if(previousMode == "filter"){
+                               this.usersAppletReference.setGuiMode(("clear"));
+                               selectionModel.removeListener("changeSelection", this.selectionToFilter, this);
+                       }
+                       this.usersAppletReference.setGuiMode(("chooser"));
+                       this.selectionToChooser(); // Warning, to be called before calling listener!
+                       var viewSel = this.usersAppletReference.getViewSelection();
+                       viewSel.addListener("changeSelection", this.monitorChooserSelectionChanges, this);
+               }else if(guiMode == "clear"){
+                       if(this.usersAppletReference){
+                               this.usersAppletReference.setGuiMode(("clear"));
+                               var viewSel = this.usersAppletReference.getViewSelection();
+                               viewSel.removeListener("changeSelection", this.monitorChooserSelectionChanges, this);                   
+                       }
+                       this.table.setEnabled(true);
+                       selectionModel.removeListener("changeSelection", this.selectionToFilter, this);
+                       selectionModel.setSelectionMode(qx.ui.table.selection.Model.SINGLE_SELECTION);                          
+               }
+       },
+       
+       saveRoleModifications : function(deltaPlus, deltaMinus){
+               //console.log(deltaPlus);
+               //console.log(deltaMinus);
+               // LOAD CONCERNED USERS
+               var selectionModel = this.table.getSelectionModel();
+               if(!selectionModel.getSelectedCount()){
+                       return;
+               }
+               var roleValue = this._selectionToValues(selectionModel)[0];
+               
+               var users = deltaPlus.concat(deltaMinus);
+               for(var i=0;i<users.length;i++){
+                       var user = users[i];
+                       var userDetailService = org.argeo.security.ria.SecurityAPI.getUserDetailsService(users[i]);
+                       userDetailService.addListener("completed", function(response){
+                               var userRoles = response.getContent().roles;
+                               if(qx.lang.Array.contains(deltaPlus, user)){
+                                       userRoles.push(roleValue);
+                               }else if(qx.lang.Array.contains(deltaMinus, user)){
+                                       qx.lang.Array.remove(userRoles, roleValue);
+                               }
+                               var userSaveService = org.argeo.security.ria.SecurityAPI.getUpdateUserService(response.getContent());
+                               userSaveService.addListener("completed", function(e){
+                                       this.fireDataEvent("changeRolesList", this.getRolesList());
+                               }, this);
+                               userSaveService.send();
+                       }, this);
+                       userDetailService.send();
+               }
+       },
+       
+       monitorChooserSelectionChanges : function(event){
+               if(!this.usersAppletReference || this.getChooserSelectionModified()) return;
+               var initialSelection = this.getChooserOriginalSelection();
+               var crtSelection = event.getTarget().getNodes();
+               if(!qx.lang.Array.equals(initialSelection.sort(), crtSelection.sort())){
+                       this.setChooserSelectionModified(true);                         
+                       this.saveButton.setEnabled(true);
+               }
+       },
+       
+       selectionToFilter : function(){
+               if(!this.usersAppletReference) return;
+               var selectionModel = this.table.getSelectionModel();
+               if(!selectionModel.getSelectedCount()){
+                       this.usersAppletReference.resetHiddenRows();
+                       return;
+               }
+               this.usersAppletReference.applyFilter(this._selectionToValues(selectionModel), "roles", true);                  
+       },
+       
+       selectionToChooser : function(){
+               if(!this.usersAppletReference) return;
+               var selectionModel = this.table.getSelectionModel();
+               if(!selectionModel.getSelectedCount()){
+                       this.usersAppletReference.resetHiddenRows();
+                       return;
+               }
+               var uniqueValue = this._selectionToValues(selectionModel)[0];
+               //var initSelection = this.rolesUsersStub[uniqueValue];
+               this.usersAppletReference.applySelection(uniqueValue, "roles");
+               var initSelection = this.usersAppletReference.getViewSelection().getNodes(); 
+               this.setChooserOriginalSelection(initSelection);
+               this.setChooserSelectionModified(false);
+               this.saveButton.setEnabled(false);
+       },
+       
+       _selectionToValues : function(selectionModel, viewSelection){           
+               if(viewSelection){
+                       viewSelection.setBatchMode(true);
+                       viewSelection.clear();
+               }
+               if(!selectionModel.getSelectedCount()) return [];
+               var ranges = selectionModel.getSelectedRanges();
+               var values = [];
+               for(var i=0;i<ranges.length;i++){
+                       for(var j=ranges[i].minIndex;j<=ranges[i].maxIndex;j++){                                        
+                               values.push(this.tableModel.getData()[j][0]);
+                               if(viewSelection){
+                                       viewSelection.addNode(this.tableModel.getData()[j][0]);
+                               }
+                       }
+               }
+               if(viewSelection){
+                       viewSelection.setBatchMode(false);
+               }
+               return values;
+       },
+       
+       _selectionDiff : function(initialSelection, modifiedSelection){
+               var deltaMinus = qx.lang.Array.clone(initialSelection);
+               var deltaPlus = qx.lang.Array.clone(modifiedSelection);
+               qx.lang.Array.exclude(deltaPlus, initialSelection);
+               qx.lang.Array.exclude(deltaMinus, modifiedSelection);
+               return {deltaPlus : deltaPlus, deltaMinus : deltaMinus};
        },
        
        /**
         * Load a given row : the data passed must be a simple data array.
         * @param data {Element} The text xml description. 
         */
-       load : function(){              
-               var data = [["ROLE_ADMIN"],["ROLE_USER"]];
-               this.tableModel.setData(data);
+       load : function(){
+               
+               var commands = this.getCommands();
+               this.toolBarPart.add(commands["new_role"].command.getToolbarButton());
+               this.toolBarPart.add(commands["delete_role"].command.getToolbarButton());
+               this.toolBarPart.add(commands["edit_role"].command.getToolbarButton());                 
+               this.toolBar.addSpacer();
+               this.toolBar.add(this.toggleButton);
+               this.toolBar.add(this.saveButton);              
+               this.toolBar.add(this.cancelButton);                            
+               this.toolBar.setShow("icon");
+               
+               this.loadRolesList();
+               
+       },
+       
+       loadRolesList : function(){
+               this.setRolesList([]);
+               var service = org.argeo.security.ria.SecurityAPI.getListRolesService();
+               service.addListener("completed", function(response){
+                       this.setRolesList(response.getContent());
+               }, this);
+               service.send();                 
        },
                 
        addScroll : function(){