Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoeland Jago Douma <rullzer@users.noreply.github.com>2016-08-30 11:02:06 +0300
committerGitHub <noreply@github.com>2016-08-30 11:02:06 +0300
commitd2a96a69a466f08be9ac1836937d621a1f3a8f71 (patch)
tree5085857991194b380107b3b68cb0d01770ababf6
parent690fc46eff20b5ed732766689e450c544e5c6b8e (diff)
parent434d68129dc79160344d039b64d76e1f6974bb5c (diff)
Merge pull request #1175 from nextcloud/backport-1128-stable9
[stable9] Users page lazy multiselect group dropdowns
-rw-r--r--core/js/multiselect.js52
-rw-r--r--settings/css/settings.css9
-rw-r--r--settings/js/users/groups.js4
-rw-r--r--settings/js/users/users.js174
-rw-r--r--settings/templates/users/main.php4
-rw-r--r--settings/templates/users/part.createuser.php11
-rw-r--r--settings/templates/users/part.userlist.php8
7 files changed, 143 insertions, 119 deletions
diff --git a/core/js/multiselect.js b/core/js/multiselect.js
index 6d5c54ac0f5..49a7934a468 100644
--- a/core/js/multiselect.js
+++ b/core/js/multiselect.js
@@ -32,7 +32,7 @@
'onuncheck':false,
'minWidth': 'default;'
};
- var slideDuration = 200;
+ var slideDuration = 0;
$(this).attr('data-msid', multiSelectId);
$.extend(settings,options);
$.each(this.children(),function(i,option) {
@@ -75,6 +75,26 @@
var self = this;
self.menuDirection = 'down';
+
+ function closeDropDown() {
+ if(!button.parent().data('preventHide')) {
+ // How can I save the effect in a var?
+ if(self.menuDirection === 'down') {
+ button.parent().children('ul').slideUp(slideDuration,function() {
+ button.parent().children('ul').remove();
+ button.removeClass('active down');
+ $(self).trigger($.Event('dropdownclosed', settings));
+ });
+ } else {
+ button.parent().children('ul').fadeOut(slideDuration,function() {
+ button.parent().children('ul').remove();
+ button.removeClass('active up');
+ $(self).trigger($.Event('dropdownclosed', settings));
+ });
+ }
+ }
+ }
+
button.click(function(event){
var button=$(this);
@@ -83,21 +103,20 @@
button.parent().children('ul').slideUp(slideDuration,function() {
button.parent().children('ul').remove();
button.removeClass('active down');
+ $(self).trigger($.Event('dropdownclosed', settings));
});
} else {
button.parent().children('ul').fadeOut(slideDuration,function() {
button.parent().children('ul').remove();
button.removeClass('active up');
+ $(self).trigger($.Event('dropdownclosed', settings));
});
}
return;
}
+ // tell other lists to shut themselves
var lists=$('ul.multiselectoptions');
- lists.slideUp(slideDuration,function(){
- lists.remove();
- $('div.multiselect').removeClass('active');
- button.addClass('active');
- });
+ lists.trigger($.Event('shut'));
button.addClass('active');
event.stopPropagation();
var options=$(this).parent().next().children();
@@ -309,29 +328,16 @@
list.detach().insertBefore($(this));
list.addClass('up');
button.addClass('up');
- list.fadeIn();
+ list.show();
self.menuDirection = 'up';
}
list.click(function(event) {
event.stopPropagation();
});
+ list.one('shut', closeDropDown);
});
- $(window).click(function() {
- if(!button.parent().data('preventHide')) {
- // How can I save the effect in a var?
- if(self.menuDirection === 'down') {
- button.parent().children('ul').slideUp(slideDuration,function() {
- button.parent().children('ul').remove();
- button.removeClass('active down');
- });
- } else {
- button.parent().children('ul').fadeOut(slideDuration,function() {
- button.parent().children('ul').remove();
- button.removeClass('active up');
- });
- }
- }
- });
+
+ $(window).click(closeDropDown);
return span;
};
diff --git a/settings/css/settings.css b/settings/css/settings.css
index db6cced6185..b29b65d28f1 100644
--- a/settings/css/settings.css
+++ b/settings/css/settings.css
@@ -194,6 +194,15 @@ span.usersLastLoginTooltip { white-space: nowrap; }
color: #000000;
}
+#newuser .groups {
+ display: inline;
+}
+
+#newuser .groupsListContainer.hidden,
+#userlist .groupsListContainer.hidden {
+ display: none;
+}
+
tr:hover>td.password>span, tr:hover>td.displayName>span { margin:0; cursor:pointer; }
tr:hover>td.remove>a, tr:hover>td.password>img,tr:hover>td.displayName>img, tr:hover>td.quota>img { visibility:visible; cursor:pointer; }
td.remove {
diff --git a/settings/js/users/groups.js b/settings/js/users/groups.js
index 27c41884504..78c0f42b77d 100644
--- a/settings/js/users/groups.js
+++ b/settings/js/users/groups.js
@@ -136,10 +136,6 @@ GroupList = {
var addedGroup = result.groupname;
UserList.availableGroups = $.unique($.merge(UserList.availableGroups, [addedGroup]));
GroupList.addGroup(result.groupname);
-
- $('.groupsselect, .subadminsselect')
- .append($('<option>', { value: result.groupname })
- .text(result.groupname));
}
GroupList.toggleAddGroup();
}).fail(function(result) {
diff --git a/settings/js/users/users.js b/settings/js/users/users.js
index fcfa5a83e6c..55c0d84db8c 100644
--- a/settings/js/users/users.js
+++ b/settings/js/users/users.js
@@ -57,9 +57,6 @@ var UserList = {
var $tr = $userListBody.find('tr:first-child').clone();
// this removes just the `display:none` of the template row
$tr.removeAttr('style');
- var subAdminsEl;
- var subAdminSelect;
- var groupsSelect;
/**
* Avatar or placeholder
@@ -86,32 +83,17 @@ var UserList = {
$tr.find('td.mailAddress > .action').tooltip({placement: 'top'});
$tr.find('td.password > .action').tooltip({placement: 'top'});
+
/**
* groups and subadmins
*/
- // make them look like the multiselect buttons
- // until they get time to really get initialized
- groupsSelect = $('<select multiple="multiple" class="groupsselect multiselect button" data-placehoder="Groups" title="' + t('settings', 'no group') + '"></select>')
- .data('username', user.name)
- .data('user-groups', user.groups);
- if ($tr.find('td.subadmins').length > 0) {
- subAdminSelect = $('<select multiple="multiple" class="subadminsselect multiselect button" data-placehoder="subadmins" title="' + t('settings', 'no group') + '">')
- .data('username', user.name)
- .data('user-groups', user.groups)
- .data('subadmin', user.subadmin);
- $tr.find('td.subadmins').empty();
- }
- $.each(this.availableGroups, function (i, group) {
- groupsSelect.append($('<option value="' + escapeHTML(group) + '">' + escapeHTML(group) + '</option>'));
- if (typeof subAdminSelect !== 'undefined' && group !== 'admin') {
- subAdminSelect.append($('<option value="' + escapeHTML(group) + '">' + escapeHTML(group) + '</option>'));
- }
- });
- $tr.find('td.groups').empty().append(groupsSelect);
- subAdminsEl = $tr.find('td.subadmins');
- if (subAdminsEl.length > 0) {
- subAdminsEl.append(subAdminSelect);
- }
+ var $tdGroups = $tr.find('td.groups');
+ this._updateGroupListLabel($tdGroups, user.groups);
+ $tdGroups.find('.action').tooltip({placement: 'top'});
+
+ var $tdSubadmins = $tr.find('td.subadmins');
+ this._updateGroupListLabel($tdSubadmins, user.subadmin);
+ $tdSubadmins.find('.action').tooltip({placement: 'top'});
/**
* remove action
@@ -195,10 +177,6 @@ var UserList = {
// defer init so the user first sees the list appear more quickly
window.setTimeout(function(){
$quotaSelect.singleSelect();
- UserList.applyGroupSelect(groupsSelect);
- if (subAdminSelect) {
- UserList.applySubadminSelect(subAdminSelect);
- }
}, 0);
return $tr;
},
@@ -319,7 +297,7 @@ var UserList = {
},
markRemove: function(uid) {
var $tr = UserList.getRow(uid);
- var groups = $tr.find('.groups .groupsselect').val();
+ var groups = $tr.find('.groups').data('groups');
for(var i in groups) {
var gid = groups[i];
var $li = GroupList.getGroupLI(gid);
@@ -334,7 +312,7 @@ var UserList = {
},
undoRemove: function(uid) {
var $tr = UserList.getRow(uid);
- var groups = $tr.find('.groups .groupsselect').val();
+ var groups = $tr.find('.groups').data('groups');
for(var i in groups) {
var gid = groups[i];
var $li = GroupList.getGroupLI(gid);
@@ -435,19 +413,9 @@ var UserList = {
});
},
- applyGroupSelect: function (element) {
- var checked = [];
+ applyGroupSelect: function (element, user, checked) {
var $element = $(element);
- var user = UserList.getUID($element);
- if ($element.data('user-groups')) {
- if (typeof $element.data('user-groups') === 'string') {
- checked = $element.data('user-groups').split(", ");
- }
- else {
- checked = $element.data('user-groups');
- }
- }
var checkHandler = null;
if(user) { // Only if in a user row, and not the #newusergroups select
checkHandler = function (group) {
@@ -487,13 +455,6 @@ var UserList = {
};
}
var addGroup = function (select, group) {
- $('select[multiple]').each(function (index, element) {
- $element = $(element);
- if ($element.find('option').filterAttr('value', group).length === 0 &&
- select.data('msid') !== $element.data('msid')) {
- $element.append('<option value="' + escapeHTML(group) + '">' + escapeHTML(group) + '</option>');
- }
- });
GroupList.addGroup(escapeHTML(group));
};
var label;
@@ -514,19 +475,8 @@ var UserList = {
});
},
- applySubadminSelect: function (element) {
- var checked = [];
+ applySubadminSelect: function (element, user, checked) {
var $element = $(element);
- var user = UserList.getUID($element);
-
- if ($element.data('subadmin')) {
- if (typeof $element.data('subadmin') === 'string') {
- checked = $element.data('subadmin').split(", ");
- }
- else {
- checked = $element.data('subadmin');
- }
- }
var checkHandler = function (group) {
if (group === 'admin') {
return false;
@@ -542,15 +492,7 @@ var UserList = {
);
};
- var addSubAdmin = function (group) {
- $('select[multiple]').each(function (index, element) {
- if ($(element).find('option').filterAttr('value', group).length === 0) {
- $(element).append('<option value="' + escapeHTML(group) + '">' + escapeHTML(group) + '</option>');
- }
- });
- };
$element.multiSelect({
- createCallback: addSubAdmin,
createText: null,
checked: checked,
oncheck: checkHandler,
@@ -599,6 +541,76 @@ var UserList = {
}
}
);
+ },
+
+ /**
+ * Creates a temporary jquery.multiselect selector on the given group field
+ */
+ _triggerGroupEdit: function($td, isSubadminSelect) {
+ var $groupsListContainer = $td.find('.groupsListContainer');
+ var placeholder = $groupsListContainer.attr('data-placeholder') || t('settings', 'no group');
+ var user = UserList.getUID($td);
+ var checked = $td.data('groups') || [];
+ var extraGroups = [].concat(checked);
+
+ $td.find('.multiselectoptions').remove();
+
+ // jquery.multiselect can only work with select+options in DOM ? We'll give jquery.multiselect what it wants...
+ var $groupsSelect;
+ if (isSubadminSelect) {
+ $groupsSelect = $('<select multiple="multiple" class="groupsselect multiselect button" title="' + placeholder + '"></select>');
+ } else {
+ $groupsSelect = $('<select multiple="multiple" class="subadminsselect multiselect button" title="' + placeholder + '"></select>')
+ }
+
+ function createItem(group) {
+ if (isSubadminSelect && group === 'admin') {
+ // can't become subadmin of "admin" group
+ return;
+ }
+ $groupsSelect.append($('<option value="' + escapeHTML(group) + '">' + escapeHTML(group) + '</option>'));
+ }
+
+ $.each(this.availableGroups, function (i, group) {
+ // some new groups might be selected but not in the available groups list yet
+ var extraIndex = extraGroups.indexOf(group);
+ if (extraIndex >= 0) {
+ // remove extra group as it was found
+ extraGroups.splice(extraIndex, 1);
+ }
+ createItem(group);
+ });
+ $.each(extraGroups, function (i, group) {
+ createItem(group);
+ });
+
+ $td.append($groupsSelect);
+
+ if (isSubadminSelect) {
+ UserList.applySubadminSelect($groupsSelect, user, checked);
+ } else {
+ UserList.applyGroupSelect($groupsSelect, user, checked);
+ }
+
+ $groupsListContainer.addClass('hidden');
+ $td.find('.multiselect:not(.groupsListContainer):first').click();
+ $groupsSelect.on('dropdownclosed', function(e) {
+ $groupsSelect.remove();
+ $td.find('.multiselect:not(.groupsListContainer)').parent().remove();
+ $td.find('.multiselectoptions').remove();
+ $groupsListContainer.removeClass('hidden');
+ UserList._updateGroupListLabel($td, e.checked);
+ });
+ },
+
+ /**
+ * Updates the groups list td with the given groups selection
+ */
+ _updateGroupListLabel: function($td, groups) {
+ var placeholder = $td.find('.groupsListContainer').attr('data-placeholder');
+ var $groupsEl = $td.find('.groupsList');
+ $groupsEl.text(groups.join(', ') || placeholder || t('settings', 'no group'));
+ $td.data('groups', groups);
}
};
@@ -623,13 +635,6 @@ $(document).ready(function () {
// TODO: move other init calls inside of initialize
UserList.initialize($('#userlist'));
- $('.groupsselect').each(function (index, element) {
- UserList.applyGroupSelect(element);
- });
- $('.subadminsselect').each(function (index, element) {
- UserList.applySubadminSelect(element);
- });
-
$userListBody.on('click', '.password', function (event) {
event.stopPropagation();
@@ -758,11 +763,24 @@ $(document).ready(function () {
});
});
+ $('#newuser .groupsListContainer').on('click', function (event) {
+ event.stopPropagation();
+ var $div = $(this).closest('.groups');
+ UserList._triggerGroupEdit($div);
+ });
+ $userListBody.on('click', '.groups .groupsListContainer, .subadmins .groupsListContainer', function (event) {
+ event.stopPropagation();
+ var $td = $(this).closest('td');
+ var isSubadminSelect = $td.hasClass('subadmins');
+ UserList._triggerGroupEdit($td, isSubadminSelect);
+ });
+
// init the quota field select box after it is shown the first time
$('#app-settings').one('show', function() {
$(this).find('#default_quota').singleSelect().on('change', UserList.onQuotaSelect);
});
+ UserList._updateGroupListLabel($('#newuser .groups'), []);
$('#newuser').submit(function (event) {
event.preventDefault();
var username = $('#newusername').val();
@@ -798,7 +816,7 @@ $(document).ready(function () {
}
promise.then(function() {
- var groups = $('#newusergroups').val() || [];
+ var groups = $('#newuser .groups').data('groups') || [];
$.post(
OC.generateUrl('/settings/users/users'),
{
diff --git a/settings/templates/users/main.php b/settings/templates/users/main.php
index f50f83b38b3..b363a4c4da8 100644
--- a/settings/templates/users/main.php
+++ b/settings/templates/users/main.php
@@ -19,10 +19,10 @@ style('settings', 'settings');
$userlistParams = array();
$allGroups=array();
-foreach($_["groups"] as $group) {
+foreach($_["adminGroup"] as $group) {
$allGroups[] = $group['name'];
}
-foreach($_["adminGroup"] as $group) {
+foreach($_["groups"] as $group) {
$allGroups[] = $group['name'];
}
$userlistParams['subadmingroups'] = $allGroups;
diff --git a/settings/templates/users/part.createuser.php b/settings/templates/users/part.createuser.php
index 0fc5a2bdeaa..6f23d06cfa3 100644
--- a/settings/templates/users/part.createuser.php
+++ b/settings/templates/users/part.createuser.php
@@ -10,16 +10,7 @@
<input id="newemail" type="text" style="display:none"
placeholder="<?php p($l->t('E-Mail'))?>"
autocomplete="off" autocapitalize="off" autocorrect="off" />
- <select
- class="groupsselect" id="newusergroups" data-placeholder="groups"
- title="<?php p($l->t('Groups'))?>" multiple="multiple">
- <?php foreach($_["adminGroup"] as $adminGroup): ?>
- <option value="<?php p($adminGroup['name']);?>"><?php p($adminGroup['name']); ?></option>
- <?php endforeach; ?>
- <?php foreach($_["groups"] as $group): ?>
- <option value="<?php p($group['name']);?>"><?php p($group['name']);?></option>
- <?php endforeach;?>
- </select>
+ <div class="groups"><div class="groupsListContainer multiselect button" data-placeholder="<?php p($l->t('Groups'))?>"><span class="title groupsList"></span><span class="icon-triangle-s"></span></div></div>
<input type="submit" class="button" value="<?php p($l->t('Create'))?>" />
</form>
<?php if((bool)$_['recoveryAdminEnabled']): ?>
diff --git a/settings/templates/users/part.userlist.php b/settings/templates/users/part.userlist.php
index 15b7cb4abd7..788fe3a4a8e 100644
--- a/settings/templates/users/part.userlist.php
+++ b/settings/templates/users/part.userlist.php
@@ -38,9 +38,13 @@
src="<?php p(image_path('core', 'actions/rename.svg'))?>"
alt="<?php p($l->t('change email address'))?>" title="<?php p($l->t('change email address'))?>"/>
</td>
- <td class="groups"></td>
+ <td class="groups"><div class="groupsListContainer multiselect button"
+ ><span class="title groupsList"></span><span class="icon-triangle-s"></span></div>
+ </td>
<?php if(is_array($_['subadmins']) || $_['subadmins']): ?>
- <td class="subadmins"></td>
+ <td class="subadmins"><div class="groupsListContainer multiselect button"
+ ><span class="title groupsList"></span><span class="icon-triangle-s"></span></div>
+ </td>
<?php endif;?>
<td class="quota">
<select class="quota-user" data-inputtitle="<?php p($l->t('Please enter storage quota (ex: "512 MB" or "12 GB")')) ?>">