diff --git a/tcms/static/js/jsonrpc.js b/tcms/static/js/jsonrpc.js index 87e6e06d13..45f4c9d3d6 100644 --- a/tcms/static/js/jsonrpc.js +++ b/tcms/static/js/jsonrpc.js @@ -86,3 +86,45 @@ export function testPlanAutoComplete (selector, planCache) { } }) } + +export function userAutoComplete (selector, cache) { + $(`${selector}.typeahead`).typeahead({ + minLength: 1, + highlight: true + }, { + name: 'users-autocomplete', + limit: 100, + async: true, + display: function (user) { + let displayName = user.username + if (user.email) { + displayName += ` <${user.email}>` + } + cache[displayName] = user + return displayName + }, + source: function (query, processSync, processAsync) { + query = query.trim() + if (query === '') { + return + } + + let rpcQuery = { pk: query } + + if (isNaN(query)) { + if (query.length < 3) { + return + } + + rpcQuery = { username__icontains: query } + if (query.indexOf('@') > -1) { + rpcQuery = { email__icontains: query } + } + } + + jsonRPC('User.filter', rpcQuery, function (data) { + return processAsync(data) + }) + } + }) +} diff --git a/tcms/testruns/static/testruns/js/get.js b/tcms/testruns/static/testruns/js/get.js index aead2c3ec6..d9307c63be 100644 --- a/tcms/testruns/static/testruns/js/get.js +++ b/tcms/testruns/static/testruns/js/get.js @@ -1,5 +1,5 @@ import { fetchBugDetails } from '../../../../static/js/bugs' -import { jsonRPC } from '../../../../static/js/jsonrpc' +import { jsonRPC, userAutoComplete } from '../../../../static/js/jsonrpc' import { propertiesCard } from '../../../../static/js/properties' import { tagsCard } from '../../../../static/js/tags' import { @@ -16,11 +16,13 @@ import { initSimpleMDE } from '../../../../static/js/simplemde_security_override const allExecutionStatuses = {} const allExecutions = {} const expandedExecutionIds = [] +const userAutocompleteCache = {} const permissions = { removeTag: false, addComment: false, removeComment: false, - viewHistoricalTestExecution: false + viewHistoricalTestExecution: false, + viewUser: false } const autocompleteCache = {} @@ -42,6 +44,7 @@ export function pageTestrunsGetReadyHandler () { permissions.addComment = $('#test_run_pk').data('perm-add-comment') === 'True' permissions.removeComment = $('#test_run_pk').data('perm-remove-comment') === 'True' permissions.viewHistoricalTestExecution = $('#test_run_pk').data('perm-view-historical-testexecution') === 'True' + permissions.viewUser = $('#test_run_pk').data('perm-view-user') === 'True' const testRunId = $('#test_run_pk').data('pk') @@ -135,7 +138,7 @@ export function pageTestrunsGetReadyHandler () { $('.change-assignee-bulk').click(function () { $(this).parents('.dropdown').toggleClass('open') - changeAssigneeBulk() + openChangeAssigneeModal() return false }) @@ -189,6 +192,10 @@ export function pageTestrunsGetReadyHandler () { }) quickSearchAndAddTestCase(testRunId, addTestCaseToRun, autocompleteCache, { case_status__is_confirmed: true }) + if (permissions.viewUser) { + userAutoComplete('#id-change-assignee', userAutocompleteCache) + } + $('#btn-search-cases').click(function () { return advancedSearchAndAddTestCases( testRunId, 'TestRun.add_case', $(this).attr('href'), @@ -811,19 +818,35 @@ function reloadRowFor (execution, updateTestRun = false) { }) } -function changeAssigneeBulk () { +function openChangeAssigneeModal () { const selected = selectedCheckboxes() if ($.isEmptyObject(selected)) { return false } - const enterAssigneeText = $('#test_run_pk').data('trans-enter-assignee-name-or-email') - const assignee = prompt(enterAssigneeText) + const input = $('#id-change-assignee') + input.val('') + $('.change-assignee-form').off('submit') + $('.change-assignee-form').submit(() => { + const assigneeValue = input.val().trim() + const selectedUser = userAutocompleteCache[assigneeValue] + const assignee = selectedUser ? selectedUser.username : assigneeValue + + if (!assignee) { + return false + } - if (!assignee) { + changeAssigneeBulk(selected.executionIds, assignee) + $('#change-assignee-modal').modal('hide') return false - } - selected.executionIds.forEach(executionId => { + }) + + $('#change-assignee-modal').modal('show') + return true +} + +function changeAssigneeBulk (executionIds, assignee) { + executionIds.forEach(executionId => { jsonRPC('TestExecution.update', [executionId, { assignee }], execution => { reloadRowFor(execution) }) diff --git a/tcms/testruns/templates/testruns/get.html b/tcms/testruns/templates/testruns/get.html index b7f78e9985..c080d43369 100644 --- a/tcms/testruns/templates/testruns/get.html +++ b/tcms/testruns/templates/testruns/get.html @@ -19,6 +19,7 @@

{% trans "Add hyperlink" +{% if perms.testruns.change_testexecution %} + +{% endif %} +