Создание пользовательского поля в Jira

Уровень опыта

Начинающий. Вы можете следовать этому руководству, даже если раньше не разрабатывали приложение.

Оценка времени

Для завершения этого урока вам потребуется около 30 минут.

Применимость

Jira 7.0.0 и более поздних версий.

Обзор учебника

В этом учебном пособии показано, как создать простое пользовательское поле, которое может хранить значение валюты. Чтобы создать это поле, вы создаете приложение Jira, состоящее из следующих компонентов:

  1. Java-классы, инкапсулирующие логику приложения.
  2. Ресурсы для отображения пользовательского интерфейса приложения (шаблоны Velocity ).
  3. Дескриптор приложения (файл XML), чтобы включить модуль плагина в приложении Atlassian.

Каждый компонент рассматривается ниже в этом уроке.

Об этих инструкциях

Вы можете использовать любую поддерживаемую комбинацию операционной системы и IDE для создания этого приложения. Эти инструкции были написаны с использованием IntelliJ IDEA 2017.3 на macOS Sierra. Если вы используете другую комбинацию, вы должны использовать эквивалентные операции для своей конкретной среды.

Этот учебник был последний раз проверен с помощью Jira 7.7.1 с использованием Atlassian Plugin SDK 6.3.10.

Прежде чем вы начнете

Чтобы завершить этот учебник, вам необходимо:

  1. Знать основы разработки Java: классы, интерфейсы, методы, способы использования компилятора и т. д.
  2. Иметь последнюю версию Atlassian Plugin SDK для вашей системы разработки. Если у вас нет SDK или вы не знакомы с ним, начните с информации о начале работы.

Источник приложения

Мы рекомендуем вам проработать этот учебник. Если вы хотите пропустить или проверить свою работу, когда закончите, вы можете найти исходный код приложения на Atlassian Bitbucket. Чтобы клонировать репозиторий, выполните следующую команду:


git clone https://bitbucket.org/atlassian_tutorial/jira-custom-field

Кроме того, вы можете загрузить исходный код в виде ZIP-архива.

Шаг 1. Создайте проект приложения

На этом этапе вы будете использовать две команды atlas- для создания кода-заглушки для вашего приложения. atlas-команды являются частью Atlasian Plugin SDK и автоматизируют большую часть разработки приложений для вас.

  1. Откройте терминал и перейдите в каталог, в котором вы хотите сохранить код приложения.
  2. Чтобы создать скелет приложения Jira, выполните следующую команду:

atlas-create-jira-plugin

  1. Чтобы определить ваше приложение, введите следующую информацию.

group-id

com.example.plugins.tutorial.jira

artifact-id

tutorial-jira-custom-field

version

1.0-SNAPSHOT

package

com.example.plugins.tutorial.jira.customfields

  1. Подтвердите свои записи при появлении запроса.
  2. Перейдите в каталог tutorial-jira-custom-field, созданный на предыдущем шаге.
  3. Удалите тестовые каталоги.

Настройка тестирования для вашего приложения не входит в этот учебник. Чтобы удалить сгенерированный тестовый скелет, выполните следующие команды:


rm -rf ./src/test/java
rm -rf ./src/test/resources/

  1. Удалите ненужные файлы классов Java.

rm -rf ./src/main/java/com/example/plugins/tutorial/confluence/*

  1. Импортируйте проект в свою избранную среду IDE.

Шаг 2. Просмотрите и настройте сгенерированный код заглушки

Это хорошая идея, чтобы ознакомиться с кодом приложения заглушки. В этом разделе мы проверим значение версии и настроим созданный класс заглушки. Откройте проект приложения в среде IDE и выполните следующие шаги.

Добавить метаданные приложения к POM

На этом этапе вы добавляете некоторые метаданные о своем приложении и вашей компании или организации.

 

  1. Перейдите в корневую папку вашего приложения и откройте файл pom.xml.
  2. Добавьте название организации или организации и URL вашего веб-сайта в элемент organization:

<organization>
    <name>Example Company</name>
    <url>http://www.example.com/</url>
</organization>

  1. Обновите элемент description :

<description> Предоставляет пользовательское поле для хранения денежных сумм. </ description>

  1. Сохраните файл.

Просмотрите созданный дескриптор приложения

Ваш код заглушки содержит файл дескриптора приложения atlassian-plugin.xml. Это XML-файл, который идентифицирует приложение для хост-приложения (Jira) и определяет требуемые функциональные возможности приложения.

 

В своей среде IDE перейдите к src / main / resources и откройте файл дескриптора.

Вы должны увидеть что-то вроде этого:


<atlassian-plugin key="${atlassian.plugin.key}" name="${project.name}" plugins-version="2">
    <plugin-info>
        <description>${project.description}</description>
        <version>${project.version}</version>
        <vendor name="${project.organization.name}" url="${project.organization.url}" />
        <param name="plugin-icon">images/pluginIcon.png</param>
        <param name="plugin-logo">images/pluginLogo.png</param>
    </plugin-info>
    <resource type="i18n" name="i18n" location="tutorial-jira-custom-field"/>
    <web-resource key="tutorial-jira-custom-field-resources" name="tutorial-jira-custom-field Web Resources">
        <dependency>com.atlassian.auiplugin:ajs</dependency>
        <resource type="download" name="tutorial-jira-custom-field.css" location="/css/tutorial-jira-custom-field.css"/>
        <resource type="download" name="tutorial-jira-custom-field.js" location="/js/tutorial-jira-custom-field.js"/>
        <resource type="download" name="images/" location="/images"/>
        <context>tutorial-jira-custom-field</context>
    </web-resource>

На следующем шаге вы будете использовать генератор модуля плагинов (другую atlas- команду) для создания кода-заглушки для модулей, необходимых приложению.

Шаг 3. Добавьте модули плагина в дескриптор приложения

Для этого урока вам понадобится модуль плагина Custom Field. Вы добавите это, используя команду atlas-create-jira-plugin-module.

  1. В своем терминале перейдите в корневую папку, где находится pom.xml.
  2. Выполните следующую команду:

atlas-create-jira-plugin-module

  1. Выберите опцию Custom Field.
  2. При появлении запроса введите параметры модуля.

Enter New Classname

Введите новое имя класса

MoneyCustomField (это класс CustomFieldType).

Package Name

Имя пакета

com.example.plugins.tutorial.jira.customfields

  1. Выберите «N» для «Показать расширенную настройку».
  2. Выберите «N» для «Добавить другой модуль плагина».

SDK добавляет объявление модуля в дескриптор приложения и создает исходные файлы для модуля, включая файлы классов и шаблоны презентаций.

Шаг 4. Написание кода приложения 

Вы уже создали заглушки для своих модулей плагина. Теперь вы напишите код для приложения. Наше приложение добавит пользовательское текстовое поле в задачу Jira, в котором хранится денежная стоимость. Для этого вам необходимо реализовать интерфейс CustomFieldType и создать шаблоны Velocity для просмотра и редактирования поля.

  1. Перейдите в / src / main / java / com / example / plugins / tutorial / jira / customfields и откройте класс MoneyCustomField.
  2. Этот класс был создан командой atlas-create-jira-plugin-module, которую вы запускали ранее.

Добавьте следующие инструкции импорта к тем, которые SDK добавил для вас:


import com.atlassian.jira.issue.customfields.impl.AbstractSingleFieldType;
import java.math.BigDecimal;
import com.atlassian.jira.issue.customfields.persistence.PersistenceFieldType;

  1. Пользовательские поля могут хранить отдельные значения или несколько значений. В нашем случае мы хотим сохранить одно значение. Измените объявление класса, чтобы расширить AbstractSingleFieldType. Кроме того, добавьте аннотацию @Scanned, поэтому Atlassian Spring Scanner «заметит» наш класс.

@Scanned
public class MoneyCustomField extends AbstractSingleFieldType<BigDecimal>

Этот класс обеспечивает большую часть  внедрения поля для вас. Также обратите внимание, что мы будем использовать BigDecimal как наш «транспортный объект» (для работы с валютой на Java). Транспортный объект - это простой старый Java-объект (POJO). Тип объекта представляет собой пользовательское поле.

 

  1. Создайте конструктор, который передает аргументы суперклассам и аннотирует их с помощью @Jira Import. Atlassian Spring Scanner импортирует их из главного приложения.

public MoneyCustomField(
        @JiraImport CustomFieldValuePersister customFieldValuePersister,
        @JiraImport GenericConfigManager genericConfigManager) {
    super(customFieldValuePersister, genericConfigManager);
}

Мы не будем переопределять что-либо в getVelocityParameters (). В нашем поле будет использоваться реализация по умолчанию из суперкласса AbstractCustomFieldType.

 

Мы также реализуем несколько абстрактных методов из AbstractSingleFieldType.

 

  1. Добавьте метод getStringFromSingularObject () в ваш класс:

@Override
public String getStringFromSingularObject(final BigDecimal singularObject) {
    if (singularObject == null)
        return null;
    else
        return singularObject.toString();
}

Этот метод превращает значение в нашем объекте Transport (BigDecimal, в нашем случае) в текст.

  1. Добавьте метод getSingularObjectFromString ():

@Override
public BigDecimal getSingularObjectFromString(final String string) throws FieldValidationException {
    if (string == null)
        return null;
    try {
        BigDecimal decimal = new BigDecimal(string);
    if (decimal.scale() > 2) {
       throw new FieldValidationException(
               "Maximum of 2 decimal places are allowed.");
    }
        return decimal.setScale(2);
    } catch (NumberFormatException ex) {
        throw new FieldValidationException("Not a valid number.");
    }
}

Метод берет входные данные от пользователя, проверяет их и затем помещает в транспортный объект. Мы хотим подтвердить, что пользователь вводит действительное число и что не более двух знаков после запятой.

 

  1. Чтобы рассказать Jira в каком столбце базы данных должны храниться данные, добавьте метод getDatabaseType (). Вы можете выбрать текст, длинный текст, число или дату. Мы могли бы использовать числовые данные, но мы будем использовать текст, чтобы он был простым.

@Override
protected PersistenceFieldType getDatabaseType() {
   return PersistenceFieldType.TYPE_LIMITED_TEXT;
}

  1. Добавьте метод getObjectFromDbValue ():

@Override
protected BigDecimal getObjectFromDbValue(final Object databaseValue)
        throws FieldValidationException { 
                                         return getSingularObjectFromString((String) databaseValue); 
} 

Это берет значение из базы данных и преобразует его в транспортный объект. Параметр value объявляется как Object, но будет String, Double или Date в зависимости от типа базы данных, указанного выше. Поскольку мы выбрали FieldType TEXT, мы получим строку и можем повторно использовать getSingularObjectFromString ().

 

  1. Добавьте метод getDbValueFromObject (). Он принимает значение как наш транспортный объект и преобразует его в объект, подходящий для хранения в базе данных. В нашем случае мы хотим преобразовать в String.

@Override
protected Object getDbValueFromObject(final BigDecimal customFieldObject) {
    return getStringFromSingularObject(customFieldObject);
}

Это для класса MoneyCustomField. Ваш класс должен выглядеть так (удален неиспользуемый код):


package com.example.plugins.tutorial.jira.customfields;
 
import com.atlassian.jira.issue.customfields.impl.AbstractSingleFieldType;
import com.atlassian.jira.issue.customfields.persistence.PersistenceFieldType;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.JiraImport;
import com.atlassian.jira.issue.customfields.manager.GenericConfigManager;
import com.atlassian.jira.issue.customfields.persistence.CustomFieldValuePersister;
import com.atlassian.jira.issue.customfields.impl.FieldValidationException;
import java.math.BigDecimal;
 
@Scanned
public class MoneyCustomField extends AbstractSingleFieldType<BigDecimal> {
 
    public MoneyCustomField(
            @JiraImport CustomFieldValuePersister customFieldValuePersister,
 
        super(customFieldValuePersister, genericConfigManager);
    }
 
    @Override
    public String getStringFromSingularObject(final BigDecimal singularObject) {
        if (singularObject == null)
            return null;
            return singularObject.toString();
    }
 
    @Override
    public BigDecimal getSingularObjectFromString(final String string) throws FieldValidationException {
        if (string == null)
            return null;
        try {
            BigDecimal decimal = new BigDecimal(string);
            if (decimal.scale() > 2) {
                throw new FieldValidationException(  "Maximum of 2 decimal places are allowed.");            
 }              return decimal.setScale(2);         
} catch (NumberFormatException ex) 
{             throw new FieldValidationException("Not a valid number.");         
}     }       
@Override     protected PersistenceFieldType getDatabaseType() {     }       
@Override     protected BigDecimal getObjectFromDbValue(final Object databaseValue)
            throws FieldValidationException {  
            return getSingularObjectFromString((String) databaseValue);    
}       
@Override     protected Object getDbValueFromObject(final BigDecimal customFieldObject) 
{         
return getStringFromSingularObject(customFieldObject);     
} 
} 

По умолчанию в приложениях Atlassian используется протокол Simple Logging Facade для Java (SLF4J) для ведения журнала. В примере мы не показываем, как использовать ведение журнала. В общем, вы можете добавлять сообщения журнала в свой код, где это необходимо, для устранения неполадок и отладки. Затем установите желаемый уровень ведения журнала в консоли администрирования Jira.

Учебное пособие для приложения, использующего ведение журнала, см. В разделе «Учебное пособие - написание прослушивателей событий Jira с библиотекой событий atlassian». Также ознакомьтесь с правилами ведения журнала Confluence. В то время как для Confluence эта страница охватывает некоторые общие концепции, связанные с протоколированием.

Шаг 6. Создайте и протестируйте приложение

Мы еще не закончили, но давайте попробуем то, что мы создали до сих пор.

 

Запустите Jira с вашим приложением и создайте проект

  1. Убедитесь, что вы сохранили все свои изменения кода до этой точки.
  2. Откройте терминал и перейдите в корневую папку приложения, где находится файл pom.xml.
  3. Выполните следующую команду:

atlas-run

Эта команда создает код приложения, запускает экземпляр Jira и устанавливает в нем ваше приложение. Это может занять несколько секунд. Когда процесс завершится, вы увидите много строк состояния на вашем экране с чем-то вроде следующего:


[INFO] jira started successfully in 71s at http://localhost:2990/jira
[INFO] Type CTRL-D to shutdown gracefully
[INFO] Type CTRL-C to exit

  1. Откройте localhost:2990/jira в вашем браузере.
  2. Войдите в систему с помощью admin / admin.

Поскольку это новый экземпляр, Jira предлагает вам выбрать тип проекта.

  1. Создайте новый проект Jira
  2. Введите название проекта и ключ.
  3. Нажмите «Отправить».

Jira отображает обзорную страницу для вашего нового проекта.

Добавьте свое пользовательское поле в конфигурацию проекта

  1. На странице обзора вашего нового проекта нажмите значок cog> Проблемы> Пользовательские поля.
  2. Нажмите «Добавить пользовательское поле», а затем «Дополнительно».
  3. Выберите свое приложение, а затем нажмите «Money Custom Field»> «Далее».
  4. При появлении запроса введите следующие данные.

ЗОНА:

Name

Expense Растрата

Description

Accepts a money amount Принимает денежную сумму

  1. Чтобы связать вкладку «Поле» со всеми экранами, выберите все флажки и нажмите «Далее».

РИСУНОК

  1. Нажмите «Обновить»

 

Проверьте новое поле

Теперь мы можем увидеть наше новое поле в действии, создав задачу.

  1. В панели меню нажмите «Создать задачу».
  2. Выберите новый созданный проект.
  3. В форме «Создать задачу» прокрутите страницу до конца и обратите внимание на текст-заполнитель edit.vm.

Приложение сработало, что хорошо, но пока оно не используется, что не так хорошо. Нам нужно настроить наш код шаблона, чтобы пользователь мог вводить данные в поле.

  1. Нажмите «Отмена», но продолжайте держать Jira запущенной и откройте окно браузера. Мы вернемся к нему через минуту.

Шаг 7. Отредактируйте шаблоны Velocity

Приложения могут выставлять интерфейс в Jira через шаблоны Velocity. SDK дал нам два шаблона: один для просмотра значения поля и другой для его редактирования.

Есть два дополнительных шаблона, которые вы можете создать: column-view, который позволяет настраивать рендеринг значений полей в навигаторе задач(Jira использует рендеринг view.vm в противном случае) и xml, который отображает ваше поле в XML и RSS-результат для задачи.

Дополнительную информацию см. в разделе «Учебное пособие - создание пользовательского типа поля».

Настройте шаблоны по умолчанию следующим образом:

  1. В новом окне терминала перейдите в src / main / resources / templates / customfields / money-custom-field.
  2. Откройте файл view.vm и замените его содержимое следующим текстом:

#if ($value)
    $$value
#end

Предложение #if просто проверяет нулевые значения в переменной value. Если его значение равно null, в рендеринге шаблона ничего не отображается. В противном случае $value во второй строке заменяется значением нашего транспортного объекта в визуализированном шаблоне.

Дополнительным символом «$» является буквальный знак доллара. Вы можете изменить это на другой символ валюты, если хотите (например, €$value).

 

  1. Откройте файл edit.vm и замените его содержимое следующим текстом:

#customControlHeader ($action $customField.id $customField.name $fieldLayoutItem.required $displayParameters $auiparams)
<input class="text" id="$customField.id" name="$customField.id" type="text" value="$textutils.htmlEncode($!value)" />
#customControlFooter ($action $customField.id $fieldLayoutItem.fieldDescription $displayParameters $auiparams)

Это тот же код, который содержится в шаблоне edit-basictext.vm в коде ядра Jira. Это означает, что это поле будет выглядеть так же, как и многие другие текстовые поля в Jira, которые используют шаблон ввода «основной текст».

#customControlHeader и #customControlFooter - это макросы Velocity, определенные в файле macroros.vm, встроенном в Jira. Эти макросы проверяют определенные условия и добавляют стандартный текст пользовательского интерфейса вокруг поля, включая метки, описание и сообщения об ошибках проверки.

Интересный бит - это элемент  input. Это элемент формы HTML, который предоставляет текстовое поле для ввода значения для нашего пользовательского поля.

Шаг 8. Повторите перезагрузку и снова попробуйте приложение.

  1. Чтобы перестроить приложение, выполните следующую команду, которая запускает QuickReload:

atlas-package

  1. Создайте задачу, как и раньше.

На этот раз наше поле «Расход» появится в нижней части формы.

  1. Введите значение в поле «Расход».
  2. Нажмите «Создать».

Поэкспериментируйте еще с этим полем. Вы можете попробовать ввести недопустимые значения. Попробуйте ввести что-то вроде «2» или «2.5» и посмотрите, как он будет отображаться после сохранения. Вы также можете оставить поле пустым. Измените некоторые задачи, которые вы создали. Обратите внимание, что если вы не вводите значение в поле, это поле будет скрыто при дальнейшем изменении задачи.

Поздравляю, вот и все!

Имейте удовольствие!

Следующие шаги

Вы можете продолжать экспериментировать с разными типами полей.

Кроме того, попробуйте расширить приложение, добавив  поисковик пользовательского поля. Вы можете использовать Atlassian Plugin SDK для генерации исходного кода для своего поисковика пользовательского поля, используя atlas-create-jira-plugin-module  и выбирать опцию Custom Field Searcher(поисковик пользовательского поля) в качестве создаваемого модуля. Оттуда вы можете выбрать класс поисковика пользовательского поля для расширения, например, поисковик текста или поисковик точного текста.

Дополнительные сведения о поисковиках пользовательского поля см. в разделе поисковик пользовательского поля.

Кроме того, проверьте эти ресурсы на пользовательских полях:

  • модуль плагина пользовательского поля.
  • Учебное пособие. Создание пользовательского типа поля.

По материалам Atlassian JIRA  Server Developer Creating a custom field in Jira