In my extended User editor, I have a button click method that needs to remove a design-time role and add a different design-time role, but I can’t get the screen to reflect the new role. It adds a blank line to the User Roles collection table.
@Subscribe("approveRequestedRoleBtn")
public void onApproveRequestedRoleBtnClick(Button.ClickEvent event) {
//Remove all existing from collection
List<UserRole> currentUserRoles = new ArrayList<>();
currentUserRoles.addAll(getEditedEntity().getUserRoles());
getEditedEntity().getUserRoles().removeAll(currentUserRoles);
for (UserRole currentUserRole : currentUserRoles) {
rolesDs.removeItem(currentUserRole);
}
//Add requested role to collection
UserRole requestedUserRole = metadata.create(UserRole.class);
requestedUserRole.setUser(getEditedEntity());
requestedUserRole.setRoleName(((ExtUser) getEditedEntity()).getRequestedRole().getId());
// ??????????
rolesDs.addItem(requestedUserRole);
getEditedEntity().getUserRoles().add(requestedUserRole);
// UserRole is added to the table at this point, but the line is blank
rolesDs.refresh();
dsContext.refresh();
}
I asked about this in a different post, but I’m not sure the answer was directed at this specific problem because I added it as another question.
I can’t find how to get the table to reflect the changes. I’ve checked the documentation and searched the forum, but maybe I didn’t understand a solution for this issue.
When you are adding a new item to the rolesDs - it automatically adds the item to the underlying collection.
As a general, when you extend platform functionality, it is a good idea to study its code. In this case - code of the com.haulmont.cuba.gui.app.security.user.edit.UserEditor.
So, like I said above, these are design-time roles. Since there’s no Role in the database, I didn’t set this, and set the roleName attribute of the UserRole object instead. If this is incorrect, please let me know (though I don’t know how it could be, because the database shows nothing in the role_id column of the sec_user_role table for design-time roles).
Yes, I was just showing what I’ve tried in order to get the rolesTable to reflect the changes. I apologize for the confusion.
Also, yes, I was just showing what I’ve tried in order to get the rolesTable to reflect the changes. I should have removed this line before posting. I have removed the getEditedEntity().getUserRoles().add(requestedUserRole); line.
It doesn’t appear that the actionPerform method is doing anything to the rolesTable object other than setting the focus and setting multi-select to true. I see nothing in the actionPerform method to show how to interact with the context of the data. So again, that’s the question that I’ve been trying to pry an answer for; how can I get the rolesTables to reflect the changes of adding the role programmatically? This is all I need regarding this issue.
The current state of my method is as follows:
@Subscribe("approveRequestedRoleBtn")
public void onApproveRequestedRoleBtnClick(Button.ClickEvent event) {
rolesDs.suspendListeners();
//Remove all existing from collection
List<UserRole> currentUserRoles = new ArrayList<>();
currentUserRoles.addAll(getEditedEntity().getUserRoles());
for (UserRole currentUserRole : currentUserRoles) {
rolesDs.removeItem(currentUserRole);
}
//Add requested role to collection
UserRole requestedUserRole = metadata.create(UserRole.class);
requestedUserRole.setUser(userDs.getItem());
requestedUserRole.setRoleName(((ExtUser) getEditedEntity()).getRequestedRole().getId());
try {
rolesDs.addItem(requestedUserRole);
} finally {
rolesDs.resumeListeners();
}
}
The UserRole object is adding correctly (saving and reloading the editor screen reflects this), but it doesn’t show in the rolesTable prior to saving. It only shows a blank line:
It feels weird for me that I have to convince you…
If you invoke “Find Usages” action for the UserRole#setRoleName method
Then you will see the logic in the UserEditor#preCommit method that performs all necessary work:
Datasources provide data to data-aware components.
…
When a user changes a value in the component, the new value is set for the entity attribute in the datasource.
When the entity attribute is modified in the code, the new value is set and displayed in the visual component.
User input can be monitored both by datasource listeners and value listeners on the component – they are notified sequentially.
To read or write the value of an attribute in the application code, it is recommended to use the datasource, rather than the component. Below is an example of reading the attribute:
I really appreciate the help (if not the rude reply)! Thank you for helping me understand how roles are set, despite the difference between design-time and runtime role definitions. I will remember this for the future.