Changeset - d43cf470e625
[Not reviewed]
default
0 2 0
Mads Kiilerich - 8 years ago 2017-08-13 17:19:18
mads@kiilerich.com
autocomplete: use select2 when selecting users or groups to give permissions

This is a minimal change to MembersAutoComplete, inspired by Dominik Ruf.

The UX is slightly different than before, with select2 putting up an extra
input field, already before typing anything.

We use minimumInputLength 1 to get the same behaviour as before and avoid
displaying all users in a list.
2 files changed with 22 insertions and 25 deletions:
0 comments (0 inline, 0 general)
kallithea/public/js/base.js
Show inline comments
 
@@ -1144,52 +1144,50 @@ var SimpleUserAutoComplete = function ($
 
        },
 
        minimumInputLength: 1,
 
        query: function (query) {
 
            query.callback({results: autocompleteMatchUsers(query.term, users_list)});
 
        },
 
        formatSelection: autocompleteFormatter,
 
        formatResult: autocompleteFormatter,
 
        escapeMarkup: function(m) { return m; },
 
        id: function(item) { return item.nname; },
 
    });
 
}
 

	
 
var MembersAutoComplete = function ($inputElement, users_list, groups_list) {
 
var MembersAutoComplete = function ($inputElement, $typeElement, users_list, groups_list) {
 

	
 
    var matchAll = function (sQuery) {
 
        var u = autocompleteMatchUsers(sQuery, users_list);
 
        var g = autocompleteMatchGroups(sQuery, groups_list);
 
        return u.concat(g);
 
    };
 

	
 
    var membersAC = autocompleteCreate($inputElement, matchAll);
 

	
 
    // Handler for selection of an entry
 
    var itemSelectHandler = function (sType, aArgs) {
 
        var nextId = $inputElement.prop('id').split('perm_new_member_name_')[1];
 
        var myAC = aArgs[0]; // reference back to the AC instance
 
        var elLI = aArgs[1]; // reference to the selected LI element
 
        var oData = aArgs[2]; // object literal of selected item's result data
 
        //fill the autocomplete with value
 
        if (oData.nname != undefined) {
 
            //users
 
            myAC.getInputEl().value = oData.nname;
 
            $('#perm_new_member_type_'+nextId).val('user');
 
    $inputElement.select2(
 
    {
 
        placeholder: $inputElement.attr('placeholder'),
 
        minimumInputLength: 1,
 
        query: function (query) {
 
            query.callback({results: matchAll(query.term)});
 
        },
 
        formatSelection: autocompleteFormatter,
 
        formatResult: autocompleteFormatter,
 
        escapeMarkup: function(m) { return m; },
 
    }).on("select2-selecting", function(e) {
 
        // e.choice.id is automatically used as selection value - just set the type of the selection
 
        if (e.choice.nname != undefined) {
 
            $typeElement.val('user');
 
        } else {
 
            //groups
 
            myAC.getInputEl().value = oData.grname;
 
            $('#perm_new_member_type_'+nextId).val('users_group');
 
            $typeElement.val('users_group');
 
        }
 
    };
 
    membersAC.itemSelectEvent.subscribe(itemSelectHandler);
 
    });
 
}
 

	
 
var MentionsAutoComplete = function ($inputElement, users_list) {
 
    var matchUsers = function (sQuery) {
 
            var org_sQuery = sQuery;
 
            if(this.mentionQuery == null){
 
                return []
 
            }
 
            sQuery = this.mentionQuery;
 
            return autocompleteMatchUsers(sQuery, users_list);
 
    }
 

	
 
@@ -1331,35 +1329,33 @@ var PullRequestAutoComplete = function (
 
        $inputElement.select2("close");
 
        e.preventDefault();
 
    });
 
}
 

	
 

	
 
function addPermAction(perm_type, users_list, groups_list) {
 
    var template =
 
        '<td><input type="radio" value="{1}.none" name="perm_new_member_{0}" id="perm_new_member_{0}"></td>' +
 
        '<td><input type="radio" value="{1}.read" checked="checked" name="perm_new_member_{0}" id="perm_new_member_{0}"></td>' +
 
        '<td><input type="radio" value="{1}.write" name="perm_new_member_{0}" id="perm_new_member_{0}"></td>' +
 
        '<td><input type="radio" value="{1}.admin" name="perm_new_member_{0}" id="perm_new_member_{0}"></td>' +
 
        '<td class="ac">' +
 
            '<div class="perm_ac" id="perm_ac_{0}">' +
 
                '<input class="yui-ac-input" id="perm_new_member_name_{0}" name="perm_new_member_name_{0}" value="" type="text">' +
 
        '<td>' +
 
                '<input class="form-control" id="perm_new_member_name_{0}" name="perm_new_member_name_{0}" value="" type="text" placeholder="{2}">' +
 
                '<input id="perm_new_member_type_{0}" name="perm_new_member_type_{0}" value="" type="hidden">' +
 
            '</div>' +
 
        '</td>' +
 
        '<td></td>';
 
    var $last_node = $('.last_new_member').last(); // empty tr between last and add
 
    var next_id = $('.new_members').length;
 
    $last_node.before($('<tr class="new_members">').append(template.format(next_id, perm_type)));
 
    MembersAutoComplete($("#perm_new_member_name_"+next_id), users_list, groups_list);
 
    $last_node.before($('<tr class="new_members">').append(template.format(next_id, perm_type, _TM['Type name of user or member to grant permission'])));
 
    MembersAutoComplete($("#perm_new_member_name_"+next_id), $("#perm_new_member_type_"+next_id), users_list, groups_list);
 
}
 

	
 
function ajaxActionRevokePermission(url, obj_id, obj_type, field_id, extra_data) {
 
    var success = function (o) {
 
            $('#' + field_id).remove();
 
        };
 
    var failure = function (o) {
 
            alert(_TM['Failed to revoke permission'] + ": " + o.status);
 
        };
 
    var query_params = {};
 
    // put extra data into POST
 
    if (extra_data !== undefined && (typeof extra_data === 'object')){
kallithea/templates/base/root.html
Show inline comments
 
@@ -28,24 +28,25 @@
 
                'Group':${h.jshtml(_('Group'))},
 
                'members':${h.jshtml(_('members'))},
 
                'Loading ...':${h.jshtml(_('Loading ...'))},
 
                'loading ...':${h.jshtml(_('loading ...'))},
 
                'Search truncated': ${h.jshtml(_('Search truncated'))},
 
                'No matching files': ${h.jshtml(_('No matching files'))},
 
                'Open New Pull Request from {0}': ${h.jshtml(_('Open New Pull Request from {0}'))},
 
                'Open New Pull Request for {0} &rarr; {1}': ${h.js(_('Open New Pull Request for {0} &rarr; {1}'))},
 
                'Show Selected Changesets {0} &rarr; {1}': ${h.js(_('Show Selected Changesets {0} &rarr; {1}'))},
 
                'Selection Link': ${h.jshtml(_('Selection Link'))},
 
                'Collapse Diff': ${h.jshtml(_('Collapse Diff'))},
 
                'Expand Diff': ${h.jshtml(_('Expand Diff'))},
 
                'Type name of user or member to grant permission': ${h.jshtml(_('Type name of user or member to grant permission'))},
 
                'Failed to revoke permission': ${h.jshtml(_('Failed to revoke permission'))},
 
                'Confirm to revoke permission for {0}: {1} ?': ${h.jshtml(_('Confirm to revoke permission for {0}: {1} ?'))},
 
                'Enabled': ${h.jshtml(_('Enabled'))},
 
                'Disabled': ${h.jshtml(_('Disabled'))},
 
                'Select changeset': ${h.jshtml(_('Select changeset'))},
 
                'Specify changeset': ${h.jshtml(_('Specify changeset'))},
 
                'MSG_SORTASC': ${h.jshtml(_('Click to sort ascending'))},
 
                'MSG_SORTDESC': ${h.jshtml(_('Click to sort descending'))},
 
                'MSG_EMPTY': ${h.jshtml(_('No records found.'))},
 
                'MSG_ERROR': ${h.jshtml(_('Data error.'))},
 
                'MSG_LOADING': ${h.jshtml(_('Loading...'))}
 
            };
0 comments (0 inline, 0 general)