пятница, 21 февраля 2025 г.

Задача: Создать ссылку, аналогичную Assignee to me для поля Reviewer (которое у нас имеется). Т.к. я не смог найти корректные зацепки за блок People - я пришел к альтернативному решению. Размещение кнопки справа, вверху, над блоком People. При нажатии - текущий пользователь будет назначен ревьювером.

image
Итоговый вариант

Из инструментов будет один ScriptRunner.

Код для Condition фрагмента я предварительно размещаю в отдельном файле (делаю для удобства хранения кода в гите). Вы же можете размещать скрипт inline.

package Projects.FSDK.UiFragments

import com.atlassian.jira.component.ComponentAccessor

def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def issueKey = issue.key 
def issue = ComponentAccessor.getIssueManager().getIssueObject(issueKey)

def projectKey = issue.getProjectObject().getKey()
if (projectKey != "FSDK") {
    return false
}

def customFieldManager = ComponentAccessor.getCustomFieldManager()
def reviewerField = customFieldManager.getCustomFieldObjectsByName("Reviewer")

if (reviewerField) {
    def reviewer = issue.getCustomFieldValue(reviewerField)
    return reviewer != currentUser
}

return true

Условие достаточно простое. Я ограничиваю отображение кнопки (фрагмента) в рамках тестового проекта FSDK. И дополнительное условие: если ревьювер уже имеется - кнопку тоже скрываю.

Теперь создаем сам фрагмент.

Нас интересует Custom web item.

Секция размещения: jira.issue.tools

Key: set-reviewer-button

Текст: I'm a Reviewer

Weight: 1

Condition: выбираем наш заготовленный код

Поле Do what: Do noting - you will use javascript to bind an action

Link (сейчас обясню): https://jira.instans.ru/rest/scriptrunner/latest/custom/setMeReviewer?issueKey=${issue.key}

Наш действие кнопки необходимо как то обрабатывать. Поэтому мы осуществим вызов нашего REST Endpoint, который создадим ниже. А пока - это это лишь ссылка заготовка, для окончательной реализации.

Сам фрагмент готов. Сохранив его - мы уже можем увидеть кнопку, в нужном проекте.

Т.к. ссылка пока ведет в никуда - приступим к созданию REST Endpoint.

REST Endpoint

Как я уже писал выше - нажатие на кнопку необходимо обрабатывать. Можно было бы усложнить и взаимодействовать с Ajax, чтобы нажатие было "бесшовным". Но я решил не усложнять и просто написать обработчик нажатия.

Итак, код для REST Endpoint я так же размещаю в отдельном файле:

package Projects.FSDK.RESTEndpoints


import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.UpdateIssueRequest

@BaseScript CustomEndpointDelegate delegate

setMeReviewer(groups: ['administrators','allUsers']) { MultivaluedMap queryParams ->

    def issueKey = queryParams.getFirst("issueKey") as String
    def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
    
    def issue = ComponentAccessor.getIssueManager().getIssueObject(issueKey)

    def customFieldManager = ComponentAccessor.getCustomFieldManager()
    def reviewerField = customFieldManager.getCustomFieldObjectsByName("Reviewer").first()

    if (reviewerField) {
        issue.setCustomFieldValue(reviewerField, currentUser)

        def updateRequest = UpdateIssueRequest.builder()
            .eventDispatchOption(EventDispatchOption.ISSUE_UPDATED) 
            .sendMail(true) 
            .build()

        ComponentAccessor.getIssueManager().updateIssue(currentUser, issue, updateRequest)

        def redirectUrl = "https://jira.instans.ru/browse/${issueKey}"
        return Response.status(302).location(URI.create(redirectUrl)).build()
    } else {
        return Response.status(400).type(MediaType.APPLICATION_JSON).entity([status: 'error', message: 'Reviewer field not found']).build()
    }
}

А потом просто создаю REST Endpoint и указываю этот файл, в качестве исполнительного.

Ключевые комментарии по файлу:

  • setMeReviewer(groups: ['administrators','allUsers']) - где setMeReviewer - это то самое окончание для нашей ссылки, которое мы указывали в веб-фрагменте. а группы - это перечисление локальных групп, которым доступно выполнение этого REST.

  • Мы могли бы просто выполнять необходимое нам действие, но в варианте по умолчанию - мы получим ответ JSON об успешном исполнении. Я же предпочел, чтобы пользователь видел ту же страницу issue. Поэтому прибегнул к редиректу по коду 302.

  • В ссылке веб-фрагмента, в конце ссылки - я передаю аргумент, в виде ключа issue.

Собственно всё. Эти простые действия позволяют нам получить функциональную кнопку, в нужном месте ;)

Комментариев нет:

Отправить комментарий