diff --git a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml index 8dbc01479ecab0a4d92c15856375888552623432..9fabe2eb7f1ea7c4ae293044537cb507c31c439c 100644 --- a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml +++ b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml @@ -164,6 +164,7 @@ Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. <updatable>false</updatable> <nullable>false</nullable> <key>indexed</key> + <default-value>0</default-value> <description>an indexed column; 1 means true, 0 means false</description> </property> <property> diff --git a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1_1.xml b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1_1.xml index 74ae692d6a05b6f14149e2999d11dae029dccb2a..43efe31c1acf0935951ed40fa761c533a11694ae 100644 --- a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1_1.xml +++ b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1_1.xml @@ -35,15 +35,45 @@ Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. <add> <property> <name>arraysize</name> - <type>java.lang.Integer</type> + <type>java.lang.String</type> <updatable>false</updatable> <key>arraysize</key> </property> + <property> + <name>xtype</name> + <type>java.lang.String</type> + <updatable>true</updatable> + </property> <property> <name>column_index</name> <type>java.lang.Integer</type> <updatable>true</updatable> </property> + <property> + <name>indexed</name> + <type>java.lang.Boolean</type> + <updatable>false</updatable> + <nullable>false</nullable> + <default-value>false</default-value> + <key>indexed</key> + <description>an indexed column</description> + </property> + <property> + <name>principal</name> + <type>java.lang.Boolean</type> + <updatable>true</updatable> + <nullable>false</nullable> + <default-value>false</default-value> + <description>a principal column</description> + </property> + <property> + <name>std</name> + <type>java.lang.Boolean</type> + <updatable>true</updatable> + <nullable>false</nullable> + <default-value>false</default-value> + <description>a standard column</description> + </property> </add> </table> </tap_schema> diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConfigurationManager.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConfigurationManager.java index 953d0108dce928bbffb8258a220ab30fb55c9fac..75d560e27e30a09fda34805a6396695f51206845 100644 --- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConfigurationManager.java +++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConfigurationManager.java @@ -123,7 +123,7 @@ public class ConfigurationManager { if (user.getUsername() == null) { return false; } - + for (UserConfiguration u : usersConfig.getUsers()) { if (u.getUsername().equals(user.getUsername())) { return false; @@ -148,6 +148,20 @@ public class ConfigurationManager { return false; } + public synchronized boolean editUser(String username, String role, String password) { + + for (UserConfiguration u : usersConfig.getUsers()) { + if (u.getUsername().equals(username)) { + u.setRole(role); + u.setPassword(password); + updateUsersConfigurationFile(); + return true; + } + } + + return false; + } + /** * Add a new UCD to the list, but only if the word has not already been * entered. diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/CredentialsEditing.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/CredentialsEditing.java index 3201fa5a821a9862820ef46c64c721b79ae283ff..f2d9ad91c4f8c48c76e219c9eb55f1daf7075478 100644 --- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/CredentialsEditing.java +++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/CredentialsEditing.java @@ -65,6 +65,10 @@ public class CredentialsEditing implements Serializable { private boolean separateCredentials; private int currentEditingRow; + public void test() { + String x = ""; + } + @PostConstruct public void init() { sourceCredentials = new Credentials(); diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaEditingBean.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaEditingBean.java index 66fd74860ae5cfa7acd20a0ddb565f273f88af4b..c5f361260493cd419cf53bafc1733f13410eb8ad 100644 --- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaEditingBean.java +++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaEditingBean.java @@ -57,8 +57,6 @@ public class TapSchemaEditingBean implements Serializable { private static final long serialVersionUID = -6251004452688984277L; private static final Logger LOG = LoggerFactory.getLogger(TapSchemaEditingBean.class); - private static final String COLUMNS_COMPONENT_ID = "main:columns-list"; - @Inject SchemaSelectionBean schemaSelection; @@ -352,53 +350,23 @@ public class TapSchemaEditingBean implements Serializable { public void removeColumn(String name) { selectedTable.removeChild(name); - Integer selectedColumnIndex = null; if (selectedColumn != null) { - int index = 0; for (Column column : selectedTable.getAddedOrRemovedChildren()) { if (column.getName().equals(selectedColumn.getName())) { - selectedColumnIndex = index; break; } - index++; } } - - CustomPartialResponseWriter writer = CustomPartialResponseWriter.getCurrentInstance(); - - final String updateResult = selectedColumnIndex == null ? "{}" : "{\"selectedColumn\":" + selectedColumnIndex + "}"; - - writer.encodeComponent(COLUMNS_COMPONENT_ID); - writer.addCustomJSUpdate(COLUMNS_COMPONENT_ID, new JSUpdateHandler() { - - @Override - public String getUpdate() { - return updateResult; - } - }); } public void undoRemoveColumn() throws SQLException { this.undoRemove(selectedColumn); - int i = 0; for (Column column : selectedTable.getAddedOrRemovedChildren()) { if (column.getName().equals(selectedColumn.getName())) { break; } - i++; } - - final int columnIndex = i; - - CustomPartialResponseWriter writer = CustomPartialResponseWriter.getCurrentInstance(); - writer.addCustomJSUpdate(COLUMNS_COMPONENT_ID, new JSUpdateHandler() { - - @Override - public String getUpdate() { - return columnIndex + ""; - } - }); } public void reload() { diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UCDEditor.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UCDEditor.java index cc887973a7b6902124f277a73d96efcbf8b2acab..1e1555a06f53f35a8c314c761f78a4e3b072ffa7 100644 --- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UCDEditor.java +++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UCDEditor.java @@ -6,6 +6,7 @@ import it.inaf.ia2.tsm.webapp.xmlconfig.UCDConfiguration; import java.io.IOException; import java.io.Serializable; import java.util.List; +import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Named; import org.apache.deltaspike.core.api.scope.WindowScoped; @@ -29,7 +30,7 @@ public class UCDEditor implements Serializable { private boolean viewExisting; private UCDConfiguration newUCDConfiguration; private String invalidUCDMessage; - + public void openDialog() { viewExisting = true; newUCDConfiguration = new UCDConfiguration(user.getUsername()); diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UsersEditing.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UsersEditing.java index 04b8daa7b7880481c86aee6341cb101570b3a196..e2e90530b89ef726f894a12be17edb56d40c306c 100644 --- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UsersEditing.java +++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UsersEditing.java @@ -22,9 +22,13 @@ */ package it.inaf.ia2.tsm.webapp; +import it.inaf.ia2.tsm.webapp.env.CustomPartialResponseWriter; +import it.inaf.ia2.tsm.webapp.env.JSUpdateHandler; import it.inaf.ia2.tsm.webapp.xmlconfig.UserConfiguration; import java.io.Serializable; import java.util.List; +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; import javax.inject.Inject; import javax.inject.Named; import org.apache.deltaspike.core.api.scope.WindowScoped; @@ -42,7 +46,13 @@ public class UsersEditing implements Serializable { @Inject private ConfigurationManager config; - private UserConfiguration newUser; + private UserConfiguration userInEditing; + private UserConfiguration userToRemove; + + private boolean newUser; + private String password; + private String passwordConfirm; + private String role; public String open() { return "usersEditing.xhtml?faces-redirect=true"; @@ -52,29 +62,108 @@ public class UsersEditing implements Serializable { return config.getUsersConfiguration(); } - public void save() { - //config.updateUsersList(users); + public void editNewUser() { + newUser = true; + userInEditing = new UserConfiguration(); + role = "user"; } - public void createNewUser() { - newUser = new UserConfiguration(); + public void editExistingUser(UserConfiguration user) { + newUser = false; + userInEditing = user; + role = user.getRole(); } - public void addUser() { - if (newUser != null) { - config.addUser(newUser); - } + public UserConfiguration getUserInEditing() { + return userInEditing; } - public void removeUser(UserConfiguration user) { - config.deleteUser(user.getUsername()); + public boolean isNewUser() { + return newUser; } - public UserConfiguration getNewUser() { - return newUser; + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPasswordConfirm() { + return passwordConfirm; + } + + public void setPasswordConfirm(String passwordConfirm) { + this.passwordConfirm = passwordConfirm; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public UserConfiguration getUserToRemove() { + return userToRemove; } - public void setNewUser(UserConfiguration newUser) { - this.newUser = newUser; + public void setUserToRemove(UserConfiguration userToRemove) { + this.userToRemove = userToRemove; + } + + public void saveEdit() { + boolean canSave = true; + + if (userInEditing.getUsername() == null || userInEditing.getUsername().isEmpty()) { + FacesContext.getCurrentInstance().addMessage("main:username", new FacesMessage("Username is required")); + canSave = false; + } + + if (canSave && newUser) { + for (UserConfiguration user : config.getUsersConfiguration()) { + if (user.getUsername().equals(userInEditing.getUsername())) { + FacesContext.getCurrentInstance().addMessage("main:username", new FacesMessage("This username already exists.")); + canSave = false; + break; + } + } + } + + if (password == null || password.isEmpty()) { + FacesContext.getCurrentInstance().addMessage("main:password", new FacesMessage("Password is required")); + canSave = false; + } + + if (password != null && !password.equals(passwordConfirm)) { + FacesContext.getCurrentInstance().addMessage("main:confirm-password", new FacesMessage("Passwords don't match")); + canSave = false; + } + + final String jsUpdate = String.valueOf(canSave); + CustomPartialResponseWriter.getCurrentInstance().addCustomJSUpdate(new JSUpdateHandler() { + @Override + public String getUpdate() { + return jsUpdate; + } + }); + + if (canSave) { + if (newUser) { + userInEditing.setRole(role); + userInEditing.setPassword(password); + config.addUser(userInEditing); + } else { + config.editUser(userInEditing.getUsername(), role, password); + } + } + } + + public void confirmUserDeletion() { + if (userToRemove != null) { + config.deleteUser(userToRemove.getUsername()); + } } } diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/CustomPartialResponseWriter.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/CustomPartialResponseWriter.java index a5fe0cd446b424e25d8e910d447563df643151bb..431d503aa1a40213d8724a0c68a31a031649ca32 100644 --- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/CustomPartialResponseWriter.java +++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/CustomPartialResponseWriter.java @@ -24,11 +24,8 @@ package it.inaf.ia2.tsm.webapp.env; import java.io.IOException; import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; -import javax.faces.component.UIComponent; +import java.util.concurrent.ConcurrentHashMap; import javax.faces.context.FacesContext; import javax.faces.context.PartialResponseWriter; import javax.faces.context.ResponseWriter; @@ -39,19 +36,15 @@ import javax.faces.context.ResponseWriter; */ public class CustomPartialResponseWriter extends PartialResponseWriter { - private final Set<String> componentsToEncode; private final Map<String, JSUpdateHandler> customJSUpdates; public CustomPartialResponseWriter(ResponseWriter wrapped) { super(wrapped); - componentsToEncode = new HashSet<>(); - customJSUpdates = new HashMap<>(); + customJSUpdates = new ConcurrentHashMap<>(); } @Override public void endDocument() throws IOException { - FacesContext fctx = FacesContext.getCurrentInstance(); - if (!customJSUpdates.isEmpty()) { startExtension(Collections.singletonMap("id", "jsupdates")); for (Map.Entry<String, JSUpdateHandler> entry : customJSUpdates.entrySet()) { @@ -64,25 +57,9 @@ public class CustomPartialResponseWriter extends PartialResponseWriter { endExtension(); } - if (!componentsToEncode.isEmpty()) { - startExtension(Collections.singletonMap("id", "htmlupdates")); - for (String componentId : componentsToEncode) { - UIComponent component = fctx.getViewRoot().findComponent(componentId); - startElement("htmlupdate", null); - writeAttribute("src", componentId, null); - component.encodeAll(fctx); - endElement("htmlupdate"); - } - endExtension(); - } - super.endDocument(); } - public void encodeComponent(String componentId) { - componentsToEncode.add(componentId); - } - public void addCustomJSUpdate(String componentId, JSUpdateHandler updateHandler) { customJSUpdates.put(componentId, updateHandler); } diff --git a/TASMAN-webapp/src/main/webapp/resources/css/style.css b/TASMAN-webapp/src/main/webapp/resources/css/style.css index 88bc9d7d4095072f19affd35c648a6ac1dc2ea4b..ddb34d0908e2b14820044932b7fbd3a7f1996c17 100644 --- a/TASMAN-webapp/src/main/webapp/resources/css/style.css +++ b/TASMAN-webapp/src/main/webapp/resources/css/style.css @@ -206,4 +206,16 @@ footer { table input+label { margin-right: 10px; margin-left: 3px; +} + +#users-list-wrapper { + font-size: 17px; +} + +#users-list-wrapper li { + padding-top: 8px; +} + +#users-list-wrapper li a:hover { + text-decoration: none; } \ No newline at end of file diff --git a/TASMAN-webapp/src/main/webapp/resources/js/common.js b/TASMAN-webapp/src/main/webapp/resources/js/common.js index f6612216fd73d1039a4b95926f196f3a6dbe04de..c525d2d7752f7c12f3dcbd876f8707bbbc677008 100644 --- a/TASMAN-webapp/src/main/webapp/resources/js/common.js +++ b/TASMAN-webapp/src/main/webapp/resources/js/common.js @@ -27,6 +27,40 @@ $('#errorModal .errorName').text(""); $('#errorModal .errorMessage').text(errorMessage); $('#errorModal').modal('show'); + }, + doOnSuccess: function (callback) { + return function (event) { + if (event.status === 'success' + && $(event.responseXML).find('error').length === 0) { + callback(); + } + }; + }, + // Function factory to handle custom communications between the backing bean and JavaScript functions + eventHandlerFactory: function (handler, componentId) { + return function (event) { + + if (event.status === 'success' + && $(event.responseXML).find('error').length === 0) { + + var srcId = componentId ? componentId : event.source.getAttribute('id'); + var jsUpdate = null; + + var jsupdates = event.responseXML.getElementById('jsupdates'); + if (jsupdates) { + jsupdates = jsupdates.childNodes; + for (var i = 0; i < jsupdates.length; i++) { + var jsu = jsupdates[i]; + if (jsu.getAttribute('src') === srcId) { + jsUpdate = jsu.innerText || jsu.textContent; + break; + } + } + } + + handler(event.source, jsUpdate); + } + }; } }; @@ -40,6 +74,9 @@ if (jsf) { jsf.ajax.addOnError(function (error) { + // Close all previously opened modals. + $('.modal').modal('hide'); + $('#errorModal .errorName').text(error.errorName); $('#errorModal .errorMessage').text(error.errorMessage); if (error.errorName.indexOf('ViewExpiredException') !== -1) { diff --git a/TASMAN-webapp/src/main/webapp/resources/js/edit-tapschema.js b/TASMAN-webapp/src/main/webapp/resources/js/edit-tapschema.js index 38b2c0850daf4458415fb33db21d5fdeeea515c0..d90a385d09584a347ed692e1333b72021dc9f5fc 100644 --- a/TASMAN-webapp/src/main/webapp/resources/js/edit-tapschema.js +++ b/TASMAN-webapp/src/main/webapp/resources/js/edit-tapschema.js @@ -1,48 +1,12 @@ (function ($, TSM) { - // Function factory to handle custom communications between the backing bean and JavaScript functions - function eventHandlerFactory(handler, componentId) { - return function (event) { - if (event.status === 'success') { - var srcId = componentId ? componentId : event.source.getAttribute('id'); - var jsUpdate = null, htmlUpdate = null; - - var jsupdates = event.responseXML.getElementById('jsupdates'); - if (jsupdates) { - jsupdates = jsupdates.childNodes; - for (var i = 0; i < jsupdates.length; i++) { - var jsu = jsupdates[i]; - if (jsu.getAttribute('src') === srcId) { - jsUpdate = jsu.innerText || jsu.textContent; - break; - } - } - } - - var htmlupdates = event.responseXML.getElementById('htmlupdates'); - if (htmlupdates) { - htmlupdates = htmlupdates.childNodes; - for (var i = 0; i < htmlupdates.length; i++) { - var hu = htmlupdates[i]; - if (hu.getAttribute('src') === srcId) { - htmlUpdate = hu; - break; - } - } - } - - handler(event.source, jsUpdate, htmlUpdate); - } - }; - } - var COLUMNS_COMPONENT_ID = 'main:columns-list'; - TSM.displayUpdateOperations = eventHandlerFactory(function (srcElement, jsupdate) { + TSM.displayUpdateOperations = TSM.eventHandlerFactory(function (srcElement, jsupdate) { $('#updateOperationsModal').modal('show'); }); - TSM.saveUCDCalled = eventHandlerFactory(function (srcElement, jsupdate) { + TSM.saveUCDCalled = TSM.eventHandlerFactory(function (srcElement, jsupdate) { if (jsupdate !== null) { $('#searchUCDModal').modal('hide'); } @@ -50,7 +14,7 @@ $('.loading').addClass('hide'); }); - TSM.textInputChanged = eventHandlerFactory(function (srcElement, jsupdate) { + TSM.textInputChanged = TSM.eventHandlerFactory(function (srcElement, jsupdate) { $(srcElement).toggleClass('changed', jsupdate === 'true'); }); @@ -68,7 +32,7 @@ } }; - TSM.columnRemoved = eventHandlerFactory(function (srcElement, jsupdate, htmlupdate) { + TSM.columnRemoved = TSM.eventHandlerFactory(function (srcElement, jsupdate) { jsupdate = JSON.parse(jsupdate); var $ul = $(srcElement).closest('ul'); $(srcElement).closest('a').find('span').addClass('strikeout'); @@ -80,7 +44,7 @@ } }, COLUMNS_COMPONENT_ID); - TSM.columnRemovalUndo = eventHandlerFactory(function (srcElement, jsupdate) { + TSM.columnRemovalUndo = TSM.eventHandlerFactory(function (srcElement, jsupdate) { var $a = $('#main\\:columns-list\\:' + jsupdate + '\\:column-selector'); $a.find('input').prop('disabled', false); $a.find('.strikeout').removeClass('strikeout'); diff --git a/TASMAN-webapp/src/main/webapp/resources/js/ucd-editor.js b/TASMAN-webapp/src/main/webapp/resources/js/ucd-editor.js index 3ae2c38b7b63b120ea101452f9f06b22961faf42..5132a9904cedac87ffe07f9566fd470b05bf4ffa 100644 --- a/TASMAN-webapp/src/main/webapp/resources/js/ucd-editor.js +++ b/TASMAN-webapp/src/main/webapp/resources/js/ucd-editor.js @@ -2,12 +2,9 @@ window.UCDEditor = { - open: function (event) { - if (event.status === 'success') { - $('#ucd-editor').modal('show'); - } - } - + open: TSM.doOnSuccess(function () { + $('#ucd-editor').modal('show'); + }) }; })(jQuery); \ No newline at end of file diff --git a/TASMAN-webapp/src/main/webapp/resources/js/user-editor.js b/TASMAN-webapp/src/main/webapp/resources/js/user-editor.js new file mode 100644 index 0000000000000000000000000000000000000000..d3359be05fb068bca564c93b77f8c82d82d9deda --- /dev/null +++ b/TASMAN-webapp/src/main/webapp/resources/js/user-editor.js @@ -0,0 +1,22 @@ +(function ($, TSM) { + + window.UserEditor = { + + open: TSM.doOnSuccess(function () { + $('#user-editing-modal').modal('show'); + }), + checkEditResult: TSM.eventHandlerFactory(function(srcElement, jsUpdate) { + if(jsUpdate === "true") { + $('#user-editing-modal').modal('hide'); + } + }), + openConfirmDelete: TSM.doOnSuccess(function () { + $('#confirm-user-deletion-modal').modal('show'); + }), + closeConfirmDelete: TSM.doOnSuccess(function () { + $('#confirm-user-deletion-modal').modal('hide'); + }) + + }; + +})(jQuery, TSM); \ No newline at end of file diff --git a/TASMAN-webapp/src/main/webapp/resources/tsm_components/ucd_editor.xhtml b/TASMAN-webapp/src/main/webapp/resources/tsm_components/ucd_editor.xhtml index d148008d76bd8af9e110f40bdbfe82bb63db0461..9ed13bd898dd6a12f8bd1260a7314fbd42367d72 100644 --- a/TASMAN-webapp/src/main/webapp/resources/tsm_components/ucd_editor.xhtml +++ b/TASMAN-webapp/src/main/webapp/resources/tsm_components/ucd_editor.xhtml @@ -16,7 +16,7 @@ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title">Custom UCDs</h4> </div> - <h:panelGroup class="modal-body" layout="block" id="ucd-editor-body" rendered="#{ucdEditor.customUCDs ne null}"> + <h:panelGroup class="modal-body" layout="block" id="ucd-editor-body" rendered="#{ucdEditor.customUCDs ne null and ucdEditor.newUCDConfiguration ne null}"> <h:selectOneRadio value="#{ucdEditor.viewExisting}"> <f:selectItem itemValue="#{true}" itemLabel="View existing" /> <f:selectItem itemValue="#{false}" itemLabel="Add new" /> diff --git a/TASMAN-webapp/src/main/webapp/usersEditing.xhtml b/TASMAN-webapp/src/main/webapp/usersEditing.xhtml index 980db8d6274aec4287b2f354e2e6fe50f1d6daac..2b189dfd3f3cb3c8defb6f3b0c5b269fd0a5798d 100644 --- a/TASMAN-webapp/src/main/webapp/usersEditing.xhtml +++ b/TASMAN-webapp/src/main/webapp/usersEditing.xhtml @@ -8,6 +8,7 @@ <ui:define name="title">TASMAN - Users Management</ui:define> <ui:define name="scripts"> <h:outputScript library="js" name="ucd-editor.js"></h:outputScript> + <h:outputScript library="js" name="user-editor.js"></h:outputScript> </ui:define> <ui:define name="content"> <f:event listener="#{loggedInChecker.checkFromNonIndex()}" type="preRenderView" /> @@ -23,64 +24,121 @@ </div> </div> - <div class="form-horizontal"> - <ui:repeat value="#{usersEditing.users}" var="u" varStatus="loop"> - <div class="col-xs-8 col-xs-offset-2"> - <div class="panel panel-default"> - <div class="panel-body"> - <div class="row"> - <div class="col-xs-1"> - <h:commandLink action="#{usersEditing.removeUser(loop.index)}" class="text-danger btn-lg pull-right"> - <span class="glyphicon glyphicon-trash"></span> - <f:ajax execute="@form" render="@form" /> - </h:commandLink> - </div> - <div class="col-xs-11"> - <div class="form-group"> - <h:outputLabel class="control-label col-xs-3" for="username">Username</h:outputLabel> - <div class="col-xs-6"> - <h:inputText value="#{u.username}" class="form-control" id="username" /> - </div> - </div> - <div class="form-group"> - <h:outputLabel class="control-label col-xs-3" for="password">Password</h:outputLabel> - <div class="col-xs-6"> - <h:inputText value="#{u.password}" class="form-control" id="password" /> - </div> - </div> - <div class="form-group"> - <h:outputLabel class="control-label col-xs-3" for="role">Role</h:outputLabel> - <div class="col-xs-6"> - <h:inputText value="#{u.role}" class="form-control" id="role" /> - </div> - </div> - </div> - </div> - </div> - </div> + <h:panelGroup class="form-horizontal" layout="block" id="users-list"> + + <div class="row"> + <div class="col-xs-8 col-xs-offset-2" id="users-list-wrapper"> + <p>List of users:</p> + <ul> + <ui:repeat value="#{usersEditing.users}" var="u" varStatus="loop"> + <li> + <h:commandLink action="#{usersEditing.setUserToRemove(u)}" class="text-danger" title="Delete"> + <span class="glyphicon glyphicon-trash"></span> + <f:ajax execute="@form" render="@form" onevent="UserEditor.openConfirmDelete" /> + </h:commandLink> + <h:commandLink action="#{usersEditing.editExistingUser(u)}" title="Edit"> + <span class="glyphicon glyphicon-pencil"></span> + <f:ajax execute="@form" render="@form" onevent="UserEditor.open" /> + </h:commandLink> + <strong>#{u.username}</strong> (#{u.role}) + </li> + </ui:repeat> + </ul> </div> - </ui:repeat> + </div> <div class="row"> - <div class="col-xs-8 col-xs-offset-3"> - <h:commandLink action="#{usersEditing.addUser()}" class="btn btn-success"> + <div class="col-xs-8 col-xs-offset-2"> + <br/> + <h:commandLink action="#{usersEditing.editNewUser()}" class="btn btn-success"> <span class="glyphicon glyphicon-plus"></span> Add user - <f:ajax execute="@form" render="@form" /> + <f:ajax execute="@form" render="@form" onevent="UserEditor.open" /> </h:commandLink> </div> </div> - <div class="row"> - <div class="col-xs-6 col-xs-offset-3 text-center"> - <br/><br/> - <h:commandLink action="#{usersEditing.save()}" class="btn btn-primary"> - <span class="glyphicon glyphicon-floppy-disk"></span> - Save - </h:commandLink> + </h:panelGroup> + </div> + + <div class="modal fade" id="user-editing-modal" tabindex="-1" role="dialog" aria-labelledby="user-editing-modal-title"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> + <h4 class="modal-title" id="user-editing-modal-title">Edit user</h4> + </div> + <h:panelGroup class="modal-body" rendered="#{usersEditing.userInEditing ne null}" layout="block"> + <h:panelGroup class="form-horizontal" layout="block" id="user-editing-modal-body"> + <h:panelGroup class="form-group" layout="block" rendered="#{usersEditing.newUser}"> + <h:outputLabel class="col-xs-4 control-label" for="username">Username</h:outputLabel> + <div class="col-xs-8"> + <h:inputText id="username" value="#{usersEditing.userInEditing.username}" class="form-control" /> + <span class="text-danger"><h:message for="username" /></span> + </div> + </h:panelGroup> + <h:panelGroup class="form-group" layout="block" rendered="#{!usersEditing.newUser}"> + <label class="col-xs-4 control-label">Username</label> + <div class="col-xs-8"> + <p class="form-control-static">#{usersEditing.userInEditing.username}</p> + </div> + </h:panelGroup> + <div class="form-group"> + <h:outputLabel class="col-xs-4 control-label" for="password">Password</h:outputLabel> + <div class="col-xs-8"> + <h:inputSecret id="password" value="#{usersEditing.password}" class="form-control" /> + <span class="text-danger"><h:message for="password" /></span> + </div> + </div> + <div class="form-group"> + <h:outputLabel class="col-xs-4 control-label" for="confirm-password">Confirm password</h:outputLabel> + <div class="col-xs-8"> + <h:inputSecret id="confirm-password" value="#{usersEditing.passwordConfirm}" class="form-control" /> + <span class="text-danger"><h:message for="confirm-password" /></span> + </div> + </div> + <div class="form-group"> + <h:outputLabel class="col-xs-4 control-label" for="role">Role</h:outputLabel> + <div class="col-xs-8"> + <h:selectOneMenu id="role" class="form-control" value="#{usersEditing.role}"> + <f:selectItem itemLabel="Admin" itemValue="admin" /> + <f:selectItem itemLabel="Generic User" itemValue="user" /> + </h:selectOneMenu> + </div> + </div> + </h:panelGroup> + </h:panelGroup> + <div class="modal-footer"> + <h:commandButton class="btn btn-primary" value="Confirm" action="#{usersEditing.saveEdit()}"> + <f:ajax execute="@form" render=":main:user-editing-modal-body :main:users-list" onevent="UserEditor.checkEditResult" /> + </h:commandButton> + <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> + </div> + </div> + </div> + </div> + <div class="modal fade" id="confirm-user-deletion-modal" tabindex="-1" role="dialog" aria-labelledby="confirm-user-deletion-modal-title"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> + <h4 class="modal-title" id="confirm-user-deletion-modal-title">Confirm deletion</h4> + </div> + <h:panelGroup class="modal-body" rendered="#{usersEditing.userToRemove ne null}" layout="block"> + <div class="row"> + <div class="col-xs-12"> + Do you really want to delete the user <strong>#{usersEditing.userToRemove.username}</strong>? + </div> + </div> + </h:panelGroup> + <div class="modal-footer"> + <h:commandButton class="btn btn-danger" value="Confirm" action="#{usersEditing.confirmUserDeletion()}"> + <f:ajax execute="@form" render="@this :main:users-list" onevent="UserEditor.closeConfirmDelete" /> + </h:commandButton> + <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> </div> </div> </div> </div> - + <tsm_components:ucd_editor /> </h:form> </ui:define>