diff options
author | Jörn Friedrich Dreyer <jfd@butonic.de> | 2014-08-21 16:48:45 +0400 |
---|---|---|
committer | Jörn Friedrich Dreyer <jfd@butonic.de> | 2014-10-13 19:18:35 +0400 |
commit | 5af5bd54981b8bc1e51730c623d9a6eb31fe8176 (patch) | |
tree | c7e722cb9895f1b201790c8fee00eb115bc6975e | |
parent | 564d28b57c0e56545db819f2f129cb9d6b879094 (diff) |
replace chosen with select2 to provide ajaxified user and group selection for files_external, fixes #7499
-rw-r--r-- | apps/files_external/ajax/applicable.php | 26 | ||||
-rw-r--r-- | apps/files_external/appinfo/routes.php | 29 | ||||
-rw-r--r-- | apps/files_external/css/settings.css | 25 | ||||
-rw-r--r-- | apps/files_external/js/settings.js | 147 | ||||
-rw-r--r-- | apps/files_external/settings.php | 6 | ||||
-rw-r--r-- | apps/files_external/templates/settings.php | 24 |
6 files changed, 222 insertions, 35 deletions
diff --git a/apps/files_external/ajax/applicable.php b/apps/files_external/ajax/applicable.php new file mode 100644 index 00000000000..1f0147758e7 --- /dev/null +++ b/apps/files_external/ajax/applicable.php @@ -0,0 +1,26 @@ +<?php + +OCP\JSON::checkAppEnabled('files_external'); +OCP\JSON::callCheck(); + +OCP\JSON::checkAdminUser(); + +$pattern = ''; +$limit = null; +$offset = null; +if (isset($_GET['pattern'])) { + $pattern = $_GET['pattern']; +} +if (isset($_GET['limit'])) { + $limit = $_GET['limit']; +} +if (isset($_GET['offset'])) { + $offset = $_GET['offset']; +} + +$groups = \OC_Group::getGroups($pattern, $limit, $offset); +$users = \OCP\User::getDisplayNames($pattern, $limit, $offset); + +$results = array('groups' => $groups, 'users' => $users); + +\OCP\JSON::success($results); diff --git a/apps/files_external/appinfo/routes.php b/apps/files_external/appinfo/routes.php new file mode 100644 index 00000000000..bf2f96734f4 --- /dev/null +++ b/apps/files_external/appinfo/routes.php @@ -0,0 +1,29 @@ +<?php +/** + * ownCloud - External Storage Routes + * + * @author Vincent Petry + * @copyright 2014 Vincent Petry <pvince81@owncloud.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +$this->create('files_external_list_applicable', '/applicable')->actionInclude('files_external/ajax/applicable.php'); + +OC_API::register('get', + '/apps/files_external/api/v1/mounts', + array('\OCA\Files\External\Api', 'getUserMounts'), + 'files_external'); + diff --git a/apps/files_external/css/settings.css b/apps/files_external/css/settings.css index 92f9f9e7a74..dd8da615e4a 100644 --- a/apps/files_external/css/settings.css +++ b/apps/files_external/css/settings.css @@ -27,3 +27,28 @@ tr:hover>td.remove>img { visibility:visible; cursor:pointer; } position: relative; top: 3px; } + + +#externalStorage td.status .success { + border-radius: 50%; +} + +#userMountingBackends { + padding-left: 25px; +} + +#body-settings .select2-results .select2-result-label { + height: 32px; + padding: 3px; +} +.select2-results .select2-result-label .avatardiv { + display:inline-block; +} +.select2-results .select2-result-label .avatardiv + span { + margin-left: 10px; +} +.select2-results .select2-result-label .avatardiv[data-type="group"] + span { + vertical-align: top; + top: 6px; + position: relative; +} diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 895f97bd2c3..4748e1d236d 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -41,9 +41,11 @@ OC.MountConfig={ } }); if ($('#externalStorage').data('admin') === true) { - var multiselect = $(tr).find('.chzn-select').val(); + var multiselect = $(tr).find('.applicableUsers').select2('val'); if (multiselect == null) { return false; + } else if (multiselect instanceof Array && multiselect.length === 0) { + multiselect.push('all'); } } if (addMountPoint) { @@ -161,7 +163,138 @@ OC.MountConfig={ }; $(document).ready(function() { - $('.chzn-select').chosen(); + //initialize hidden input field with list of users and groups + $('#externalStorage').find('tr:not(#addMountPoint)').each(function(i,tr) { + var applicable = $(tr).find('.applicable'); + if (applicable.length > 0) { + var groups = applicable.data('applicable-groups'); + var groupsId = []; + $.each(groups, function () { + groupsId.push(this+"(group)"); + }); + var users = applicable.data('applicable-users'); + if (users.indexOf('all') > -1) { + $(tr).find('.applicableUsers').val(''); + } else { + $(tr).find('.applicableUsers').val(groupsId.concat(users).join(',')); + } + } + }); + + var userListLimit = 30; + function addSelect2 ($elements) { + if ($elements.length > 0) { + $elements.select2({ + placeholder: t('files_external', 'All users. Type to select user or group.'), + allowClear: true, + multiple: true, + //minimumInputLength: 1, + ajax: { + url: OC.generateUrl('apps/files_external/applicable'), + dataType: 'json', + quietMillis: 100, + data: function (term, page) { // page is the one-based page number tracked by Select2 + return { + pattern: term, //search term + limit: userListLimit, // page size + offset: userListLimit*(page-1), // page number starts with 0 + }; + }, + results: function (data, page) { + if (data.status === "success") { + + var results = []; + var userCount = 0; // users is an object + + // add groups + $.each(data.groups, function(i, group) { + results.push({name:group+'(group)', displayname:group, type:'group' }); + }); + // add users + $.each(data.users, function(id, user) { + userCount++; + results.push({name:id, displayname:user, type:'user' }); + }); + + + var more = (userCount >= userListLimit) || (data.groups.length >= userListLimit); + return {results: results, more: more}; + } else { + //FIXME add error handling + } + } + }, + initSelection: function(element, callback) { + + var promises = []; + + var results = []; + + $(element.val().split(",")).each(function (i,userId) { + var def = new $.Deferred(); + promises.push(def.promise()); + + var pos = userId.indexOf('(group)'); + if (pos !== -1) { + //add as group + results.push({name:userId, displayname:userId.substr(0, pos), type:'group'}); + def.resolve(); + } else { + $.ajax(OC.generateUrl('apps/files_external/applicable'), { + data: { + pattern: userId + }, + dataType: "json" + }).done(function(data) { + if (data.status === "success") { + if (data.users[userId]) { + results.push({name:userId, displayname:data.users[userId], type:'user'}); + } + def.resolve(); + } else { + //FIXME add error handling + } + }); + } + }); + $.when.apply(undefined, promises).then(function(){ + callback(results); + }); + }, + id: function(element) { + return element.name; + }, + formatResult: function (element) { + var $result = $('<span><div class="avatardiv"/><span>'+escapeHTML(element.displayname)+'</span></span>'); + var $div = $result.find('.avatardiv') + .attr('data-type', element.type) + .attr('data-name', element.name) + .attr('data-displayname', element.displayname); + if (element.type === 'group') { + var url = OC.imagePath('core','places/contacts-dark'); // TODO better group icon + $div.html('<img width="32" height="32" src="'+url+'">'); + } + return $result.get(0).outerHTML; + }, + formatSelection: function (element) { + if (element.type === 'group') { + return '<span title="'+escapeHTML(element.name)+'" class="group">'+escapeHTML(element.displayname+' '+t('files_external', '(group)'))+'</span>'; + } else { + return '<span title="'+escapeHTML(element.name)+'" class="user">'+escapeHTML(element.displayname)+'</span>'; + } + }, + escapeMarkup: function (m) { return m; } // we escape the markup in formatResult and formatSelection + }).on("select2-loaded", function() { + $.each($(".avatardiv"), function(i, div) { + $div = $(div); + if ($div.data('type') === 'user') { + $div.avatar($div.data('name'),32); + } + }) + }); + } + } + addSelect2($('tr:not(#addMountPoint) .applicableUsers')); $('#externalStorage').on('change', '#selectBackend', function() { var tr = $(this).parent().parent(); @@ -199,15 +332,11 @@ $(document).ready(function() { return false; } }); - // Reset chosen - var chosen = $(tr).find('.applicable select'); - chosen.parent().find('div').remove(); - chosen.removeAttr('id').removeClass('chzn-done').css({display:'inline-block'}); - chosen.chosen(); $(tr).find('td').last().attr('class', 'remove'); $(tr).find('td').last().removeAttr('style'); $(tr).removeAttr('id'); $(this).remove(); + addSelect2($('tr:not(#addMountPoint) .applicableUsers')); }); function suggestMountPoint(defaultMountPoint) { @@ -260,8 +389,8 @@ $(document).ready(function() { OC.MountConfig.saveStorage($(this).parent().parent().parent()); }); - $('#externalStorage').on('change', '.applicable .chzn-select', function() { - OC.MountConfig.saveStorage($(this).parent().parent()); + $('#externalStorage').on('change', '.applicable', function() { + OC.MountConfig.saveStorage($(this).parent()); }); $('#sslCertificate').on('click', 'td.remove>img', function() { diff --git a/apps/files_external/settings.php b/apps/files_external/settings.php index 31183409e39..4d46f1da616 100644 --- a/apps/files_external/settings.php +++ b/apps/files_external/settings.php @@ -23,15 +23,13 @@ OC_Util::checkAdminUser(); OCP\Util::addScript('files_external', 'settings'); -OCP\Util::addscript('3rdparty', 'chosen/chosen.jquery.min'); OCP\Util::addStyle('files_external', 'settings'); -OCP\Util::addStyle('3rdparty', 'chosen/chosen'); +OCP\Util::addScript('files_external', '../3rdparty/select2/select2'); +OCP\Util::addStyle('files_external', '../3rdparty/select2/select2'); $tmpl = new OCP\Template('files_external', 'settings'); $tmpl->assign('isAdminPage', true); $tmpl->assign('mounts', OC_Mount_Config::getSystemMountPoints()); $tmpl->assign('backends', OC_Mount_Config::getBackends()); -$tmpl->assign('groups', OC_Group::getGroups()); -$tmpl->assign('users', OCP\User::getUsers()); $tmpl->assign('userDisplayNames', OC_User::getDisplayNames()); $tmpl->assign('dependencies', OC_Mount_Config::checkDependencies()); $tmpl->assign('allowUserMounting', OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes')); diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php index 34778ebaa53..7b4b33d3e13 100644 --- a/apps/files_external/templates/settings.php +++ b/apps/files_external/templates/settings.php @@ -17,7 +17,7 @@ <tbody width="100%"> <?php $_['mounts'] = array_merge($_['mounts'], array('' => array())); ?> <?php foreach ($_['mounts'] as $mount): ?> - <tr <?php print_unescaped(($mount['mountpoint'] !== '') ? 'class="'.OC_Util::sanitizeHTML($mount['class']).'"' : 'id="addMountPoint"'); ?>> + <tr <?php print_unescaped((isset($mount['mountpoint'])) ? 'class="'.OC_Util::sanitizeHTML($mount['class']).'"' : 'id="addMountPoint"'); ?>> <td class="status"> <?php if (isset($mount['status'])): ?> <span class="<?php p(($mount['status']) ? 'success' : 'error'); ?>"></span> @@ -85,27 +85,7 @@ print_unescaped(json_encode($mount['applicable']['groups'])); ?>' data-applicable-users='<?php if (isset($mount['applicable']['users'])) print_unescaped(json_encode($mount['applicable']['users'])); ?>'> - <select class="chzn-select" - multiple style="width:20em;" - data-placeholder="<?php p($l->t('None set')); ?>"> - <option value="all" <?php if (isset($mount['applicable']['users']) && in_array('all', $mount['applicable']['users'])) print_unescaped('selected="selected"');?> ><?php p($l->t('All Users')); ?></option> - <optgroup label="<?php p($l->t('Groups')); ?>"> - <?php foreach ($_['groups'] as $group): ?> - <option value="<?php p($group); ?>(group)" - <?php if (isset($mount['applicable']['groups']) && in_array($group, $mount['applicable']['groups'])): ?> - selected="selected" - <?php endif; ?>><?php p($group); ?></option> - <?php endforeach; ?> - </optgroup> - <optgroup label="<?php p($l->t('Users')); ?>"> - <?php foreach ($_['users'] as $user): ?> - <option value="<?php p($user); ?>" - <?php if (isset($mount['applicable']['users']) && in_array($user, $mount['applicable']['users'])): ?> - selected="selected" - <?php endif; ?>><?php p($_['userDisplayNames'][$user]); ?></option> - <?php endforeach; ?> - </optgroup> - </select> + <input type="hidden" class="applicableUsers" style="width:20em;" value=""/> </td> <?php endif; ?> <td <?php if ($mount['mountpoint'] != ''): ?>class="remove" |