Skip to content

Commit

Permalink
Merge pull request sakaiproject#1229 from bjones86/SAK-30023
Browse files Browse the repository at this point in the history
SAK-30023 create a view for Joinable Sets to see which users haven't joined a group yet
  • Loading branch information
bjones86 committed Nov 2, 2015
2 parents ade6e53 + c8a09c4 commit 18b53ac
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ group.joinable.additionalGroups=Generate Additional Groups
group.joinable.pendingGroups=Pending groups:
group.joinable.pendingGroups.disclaimer=These groups will be created when you save your changes.
group.joinable.edit.saveChanges=Save Changes
group.joinable.usersNotInSet=Users who have not yet joined a group in this set
group.members=Members
group.joinable.generate=Generate
group.joinable.delete=Delete Set
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1392,7 +1392,61 @@ public boolean existRoleGroup(String roleId)

return rv;
}


/**
* Find all users in the current site who are not a member of any of a set's
* given groups
* @param setGroups all existing groups for the set
* @return a list of all users who are not in any of the set's groups
*/
public List<User> getUsersNotInJoinableSet( List<Group> setGroups )
{
// Build a set of all user IDs in any of the set's groups
Set<String> usersInSet = new HashSet<>();
for( Group setGroup : setGroups )
{
usersInSet.addAll( setGroup.getUsers() );
}

// Find users of the site with specified role(s) who are not in any of the set's groups
List<User> usersNotInSet = new ArrayList<>();
for( String userID : site.getUsers() )
{
if( !usersInSet.contains( userID ) )
{
try
{
usersNotInSet.add( userDirectoryService.getUser( userID ) );
}
catch( UserNotDefinedException ex )
{
M_log.debug( this + ".getUsersNotInJoinableSet: can't find user for " + userID, ex );
}
}
}

// Return sorted list of users not in the set
Collections.sort( usersNotInSet, new UserComparator() );
return usersNotInSet;
}

/**
* Sorts users by last name, first name, display id
*
* @author <a href="mailto:[email protected]">Carl Hall</a>
*/
private static class UserComparator implements Comparator<User>
{
public int compare(User user1, User user2)
{
String displayName1 = user1.getLastName() + ", " + user1.getFirstName() + " ("
+ user1.getDisplayId() + ")";
String displayName2 = user2.getLastName() + ", " + user2.getFirstName() + " ("
+ user2.getDisplayId() + ")";
return displayName1.compareTo( displayName2 );
}
}

/**
** Comparator for sorting Group objects
**/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.site.api.Group;
import org.sakaiproject.site.tool.helper.managegroupsectionrole.impl.SiteManageGroupSectionRoleHandler;
import org.sakaiproject.user.api.User;

import uk.org.ponder.messageutil.MessageLocator;
import uk.org.ponder.messageutil.TargettedMessageList;
Expand Down Expand Up @@ -78,6 +79,7 @@ else if( edit && nameChange )
// Current groups
UIOutput.make(groupForm, "current-groups-title", messageLocator.getMessage("group.joinable.currentgroups"));
List<String> setGroupNames = new ArrayList<>();
List<Group> setGroups = new ArrayList<>();
for(Group group : handler.site.getGroups()){
String joinableSet = group.getProperties().getProperty(Group.GROUP_PROP_JOINABLE_SET);
if(joinableSet != null){
Expand All @@ -86,10 +88,13 @@ else if( edit && nameChange )
if( !handler.pendingGroupTitles.contains( group.getTitle() ) )
{
setGroupNames.add(group.getTitle());
setGroups.add( group );
}
}
}
}

// Sort the groups before adding them to the UI
Collections.sort(setGroupNames);
int i = 0;
for(String name : setGroupNames){
Expand All @@ -112,11 +117,8 @@ else if( edit && nameChange )
i++;
}
}
}

//unjoin (edit page)
if(edit){
//first set the option:
// Unjoin, first set the option:
for(Group group : handler.site.getGroups()){
String joinableSetName = group.getProperties().getProperty(Group.GROUP_PROP_JOINABLE_SET);
if(joinableSetName != null && joinableSetName.equals(handler.joinableSetName)){
Expand All @@ -131,57 +133,69 @@ else if( edit && nameChange )
allowUnjoinEdit.decorate( new UIStyleDecorator( "edit" ) );
UIBoundBoolean allowUnjoinCheckboxEdit = UIBoundBoolean.make(allowUnjoinEdit, "allowUnjoinEdit", "#{SiteManageGroupSectionRoleHandler.unjoinable}");
UILabelTargetDecorator.targetLabel(UIMessage.make(allowUnjoinEdit, "allowUnjoinEdit-label", "group.allow.unjoinable"), allowUnjoinCheckboxEdit);
}

//Additional Row
if(edit){
// Additional row
UIBranchContainer additionalRow = UIBranchContainer.make(groupForm,"additional-title-row:");
additionalRow.decorate( new UIStyleDecorator( "edit collapsed" ) );
UIOutput.make(additionalRow, "additional-title", messageLocator.getMessage("group.joinable.additionalGroups"));

// Allow unjoin
UIBranchContainer allowUnjoin = UIBranchContainer.make(groupForm,"allowunjoin-row:");
UIBoundBoolean allowUnjoinCheckbox = UIBoundBoolean.make(allowUnjoin, "allowUnjoin", "#{SiteManageGroupSectionRoleHandler.unjoinable}");
UILabelTargetDecorator.targetLabel(UIMessage.make(allowUnjoin, "allowUnjoin-label", "group.allow.unjoinable"), allowUnjoinCheckbox);

// Generate button
UIBranchContainer generateRow = UIBranchContainer.make(groupForm,"generate-row:");
generateRow.decorate( new UIStyleDecorator( "edit" ) );
UICommand.make(generateRow, "generate", messageLocator.getMessage("group.joinable.generate"), "#{SiteManageGroupSectionRoleHandler.processGenerateJoinableSet}");

// Delete set button
UICommand.make(groupForm, "delete", messageLocator.getMessage("group.joinable.delete"), "#{SiteManageGroupSectionRoleHandler.processDeleteJoinableSet}");

// Users not in the set
i = 0;
List<User> usersNotInSet = handler.getUsersNotInJoinableSet( setGroups );
if( !usersNotInSet.isEmpty() )
{
UIBranchContainer usersNotInSetRow = UIBranchContainer.make( groupForm,"usersNotInSet-title-row:" );
usersNotInSetRow.decorate( new UIStyleDecorator( "edit collapsed" ) );
UIOutput.make( usersNotInSetRow, "usersNotInSet-title", messageLocator.getMessage( "group.joinable.usersNotInSet" ) );
for( User user : usersNotInSet )
{
UIBranchContainer userRow = UIBranchContainer.make( groupForm, "user-row:", Integer.toString( i ) );
String userRowString = user.getLastName() + ", " + user.getFirstName() + " (" + user.getDisplayId() + ")";
UIOutput.make( userRow, "user", userRowString );
userRow.decorate( new UIStyleDecorator( "edit" ) );
i++;
}
}
}

//Num of Groups Row
UIBranchContainer groupsRow = UIBranchContainer.make(groupForm,"num-groups-row:");
UILabelTargetDecorator.targetLabel(UIMessage.make(groupsRow, "group-unit", "group.joinable.numOfGroups"), UIInput.make(groupsRow, "num-groups", "SiteManageGroupSectionRoleHandler.joinableSetNumOfGroups"));
if(edit){
groupsRow.decorate( new UIStyleDecorator( "edit" ) );
}

//Max members Row:
UIBranchContainer maxRow = UIBranchContainer.make(groupForm,"max-members-row:");
UILabelTargetDecorator.targetLabel(UIMessage.make(maxRow, "group-max-members", "group.joinable.maxMembers"), UIInput.make(maxRow, "num-max-members", "SiteManageGroupSectionRoleHandler.joinableSetNumOfMembers"));
if(edit){
maxRow.decorate( new UIStyleDecorator( "edit" ) );
}

//allow preview row:
UIBranchContainer allowPreviewRow = UIBranchContainer.make(groupForm,"allowpreview-row:");
UIBoundBoolean checkbox = UIBoundBoolean.make(allowPreviewRow, "allowPreviewMembership", "#{SiteManageGroupSectionRoleHandler.allowPreviewMembership}");
UILabelTargetDecorator.targetLabel(UIMessage.make(allowPreviewRow, "allowPreviewMembership-label", "group.joinable.allowPreview"), checkbox);
if(edit){
allowPreviewRow.decorate( new UIStyleDecorator( "edit" ) );
}

//allow view members row:
UIBranchContainer allowViewRow = UIBranchContainer.make(groupForm,"allowview-row:");
UIBoundBoolean viewMembersCheckbox = UIBoundBoolean.make(allowViewRow, "allowViewMembership", "#{SiteManageGroupSectionRoleHandler.allowViewMembership}");
UILabelTargetDecorator.targetLabel(UIMessage.make(allowViewRow, "allowViewMembership-label", "group.allow.view.membership2"), viewMembersCheckbox);
if(edit){
allowViewRow.decorate( new UIStyleDecorator( "edit" ) );
}

//allow unjoin
if(!edit){
UIBranchContainer allowUnjoin = UIBranchContainer.make(groupForm,"allowunjoin-row:");
UIBoundBoolean allowUnjoinCheckbox = UIBoundBoolean.make(allowUnjoin, "allowUnjoin", "#{SiteManageGroupSectionRoleHandler.unjoinable}");
UILabelTargetDecorator.targetLabel(UIMessage.make(allowUnjoin, "allowUnjoin-label", "group.allow.unjoinable"), allowUnjoinCheckbox);
}

// Generate button
if(edit){
UIBranchContainer generateRow = UIBranchContainer.make(groupForm,"generate-row:");
generateRow.decorate( new UIStyleDecorator( "edit" ) );
UICommand.make(generateRow, "generate", messageLocator.getMessage("group.joinable.generate"), "#{SiteManageGroupSectionRoleHandler.processGenerateJoinableSet}");
// Edit UI specific styles
if( edit )
{
groupsRow.decorate( new UIStyleDecorator( "edit" ) );
maxRow.decorate( new UIStyleDecorator( "edit" ) );
allowPreviewRow.decorate( new UIStyleDecorator( "edit" ) );
allowViewRow.decorate( new UIStyleDecorator( "edit" ) );
}

//Save/Cancel
Expand All @@ -191,17 +205,12 @@ else if( edit && nameChange )
UICommand cancel = UICommand.make(groupForm, "cancel", messageLocator.getMessage("cancel"), "#{SiteManageGroupSectionRoleHandler.processBack}");
cancel.parameters.add(new UIDeletionBinding("#{destroyScope.resultScope}"));

// Delete Set button:
if(edit){
UICommand.make(groupForm, "delete", messageLocator.getMessage("group.joinable.delete"), "#{SiteManageGroupSectionRoleHandler.processDeleteJoinableSet}");
}

//process any messages
tml = handler.messages;
if (tml.size() > 0) {
for (int i = 0; i < tml.size(); i ++ ) {
UIBranchContainer errorRow = UIBranchContainer.make(groupForm,"error-row:", Integer.toString(i));
String outString = "";
String outString;
if (tml.messageAt(i).args != null ) {
outString = messageLocator.getMessage(tml.messageAt(i).acquireMessageCode(),tml.messageAt(i).args[0]);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,40 +190,52 @@ div#groupsContainer, div#groupListLabel, div#pendingGroupsContainer, div#pending
display: table-cell;
}

div#pendingGroupListLabel {

div#userPanel div.edit.collapsed h4, div#userPanel div.edit.expanded h4 {
font-weight: normal;
}

div#genPanel div.edit.collapsed, div#genPanel div.edit.expanded {
div#genPanel div.edit.collapsed, div#genPanel div.edit.expanded,
div#userPanel div.edit.collapsed, div#userPanel div.edit.expanded {
display: block !important;
background-color: #FFF;
}

div#genPanel div.collapsed h4, div#genPanel div.expanded h4 {
div#genPanel div.collapsed h4, div#genPanel div.expanded h4,
div#userPanel div.collapsed h4, div#userPanel div.expanded h4{
display: inline-block;
color: #000;
cursor: pointer;
}

div#genPanel div.collapsed h4 {
div#genPanel div.collapsed h4, div#userPanel div.collapsed h4 {
background: url('/library/image/sakai/expand.gif') no-repeat left !important;
}

div#genPanel div.expanded h4 {
div#genPanel div.expanded h4, div#userPanel div.expanded h4 {
background: url('/library/image/sakai/collapse.gif') no-repeat left !important;
}

div#genPanel div.edit {
div#genPanel div.edit, div#userPanel div.edit {
display: none;
background-color: #EEE;
}

div#genPanel div.edit p, div#genPanel div.edit h4 {
div#genPanel div.edit p, div#genPanel div.edit h4, div#userPanel div.edit h4 {
margin: 0;
border: 0;
padding: 1em 1em;
}

div#userPanel {
display: inline-block;
vertical-align: top;
margin-left: 1em;
}

div#userPanel div.edit div {
padding: 0 1em 0 1em;
}

div#genPanel div.edit input#allowpreview-row\:\:allowPreviewMembership,
div#genPanel div.edit input#allowview-row\:\:allowViewMembership,
div#genPanel div.edit input#generate-row\:\:generate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,21 +350,54 @@ function checkEnableRemove()
}
}

function toggleGenPanel( clickedElement )
function togglePanel( clickedElement, isUserPanel )
{
var div = clickedElement.parentNode;
if( div.className === "edit collapsed" )
{
div.className = "edit expanded";
$( div ).siblings().show();
resizeFrame( "grow" );
if( isUserPanel )
{
$( "#userRowsContainer" ).show();
$( "#userRowsContainer" ).children().show();
}
else
{
$( div ).siblings().show();
}
}
else
{
div.className = "edit collapsed";
$( div ).siblings().hide();
resizeFrame( "shrink" );
if( isUserPanel )
{
$( "#userRowsContainer" ).hide();
$( "#userRowsContainer" ).children().hide();
}
else
{
$( div ).siblings().hide();
}
}
}

function adjustDivHeights()
{
var userRowsHeader = document.getElementById( "usersNotInSet-title-row::" );
var userPanelExpanded = userRowsHeader.classList.contains( "expanded" );
var groupFieldsHeight = document.getElementById( "groupFields" ).offsetHeight;
var userRowsHeaderHeight = userRowsHeader.offsetHeight;
var actualHeight = groupFieldsHeight - userRowsHeaderHeight;
var userRowsContainer = document.getElementById( "userRowsContainer" );
var style = "height: " + actualHeight + "px" + (userPanelExpanded ? "; overflow-y: scroll;" : ";" );
userRowsContainer.setAttribute( "style", style );
userRowsContainer.style.height = actualHeight + "px";
if( userPanelExpanded )
{
userRowsContainer.style.overflowY = "scroll";
}

resizeFrame( "grow" );
}

function adjustCount(caller, countName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ <h3 rsf:id="prompt"></h3>
</div>
<div id="genPanel">
<div rsf:id="additional-title-row:">
<h4 rsf:id="additional-title" onclick="toggleGenPanel( this );"></h4>
<h4 rsf:id="additional-title" onclick="togglePanel( this, false ); adjustDivHeights();"></h4>
</div>
<div rsf:id="num-groups-row:">
<p class="shorttext">
Expand Down Expand Up @@ -106,6 +106,17 @@ <h4 rsf:id="additional-title" onclick="toggleGenPanel( this );"></h4>
</div>
<input type="hidden" rsf:id="groupTitle-group-orig"/>
</div>
<div id="userPanel">
<div rsf:id="usersNotInSet-title-row:" id="userPanelHeader">
<h4 rsf:id="usersNotInSet-title" onclick="togglePanel( this, true ); adjustDivHeights();"></h4>
</div>
<div id="userRowsContainer">
<div rsf:id="user-row:">
<div rsf:id="user">
</div>
</div>
</div>
</div>
</form>
</div>
</body>
Expand Down

0 comments on commit 18b53ac

Please sign in to comment.