
Представим ситуацию – вам надо сделать небольшой отчет на основе данных из другой системы. Звучит обыденно и вы сразу в голове представляете, что надо будет делать: узнать какие будут входные данные и в каком виде они к нам поступят, какая будет логика отчета (что на что надо умножить и т.д.) и в каком виде отчет должен быть представлен (график, диаграмма, таблица и т.д.), реализовать.
Но что, если я вам скажу, что это должна быть не какая-то новая система, а плагин для Jira. Все вышесказанное никуда не уходит, но добавляются нюансы. Вот о таких нюансах (и как не вылететь из-за них из всех разумных сроков) эта статья.
Начало положено
У нас в группе компаний НЛМК для отслеживания задач используется Jira. И естественно в процессе использования она была сильно адаптирована под наши рабочие процессы (много кастомных полей, несколько workflow под разные типы задач и т.д.). И вот назрела необходимость сделать небольшой отчет, который будет агрегировать информацию по задачам на разработку (в терминологии НЛМК – задание на изменение или просто ЗНИ) в разрезе этих кастомных полей. Как уже было написано выше, задача довольно таки тривиальная и многие сейчас скажут – “Да я подобные задачи делаю по 2 каждый день. Не вижу проблемы”. Мы тоже сначала не видели.
К отчету были приведены следующие требования:
-
возможность задать параметры отчета, которые будут выступать фильтрами для ЗНИ, которые должны попасть в отчет;
-
сам отчет будет представлен в виде таблицы;
-
должна быть возможность выгрузить отчет в виде excel-файла.
Если говорят, что надо делать, значит сделаем. После небольшого мозгового штурма были 2 основных варианта:
-
реализовать функционал в качестве плагина для JIRA;
-
сделать свою систему, которая будет использовать Jira в качестве master-системы.
Со вторым подходом все понятно: все свое кастомное (front, back, экспорт в excel), стучимся в Jira по REST и запрашиваем необходимую информацию. Займет, предположительно, больше времени, но на выходе получим расширяемую систему с претензиями на рост.
Начали копать про плагины для Jira. Сначала все выглядело не очень позитивно. Но потом выяснилось, что Atlassian SDK позволяет добавить в плагин модуль report. Читаем первые 2 абзаца документации (приведу тезисно):
-
модуль позволяет реализовать отчет на основе данных из Jira (неудивительно);
-
позволяет сделать как html-представление, так и в виде excel-файла;
-
позволяет задать пользователю параметры перед формирование отчета.
Выглядит словно под нас делали, но мы не стали спешить радоваться и решили сначала посмотреть, как это все предлагают реализовывать.
Начальные параметры указываются непосредственно
в atlassian-plugin.xml:
<properties> <property> <key>startDate</key> <name>report.startdate</name> <description>report.startdate.description</description> <type>date</type> </property> <property> <key>endDate</key> <name>report.issuecreation.enddate</name> <description>report.enddate.description</description> <type>date</type></property> </property> <property> <key>projectid</key> <name>report.issuecreation.projectid.name</name> <description>report.projectid.description</description> <type>multiselect</type> <values class="com.company.report.valuesgenerator.ProjectsGenerator"/> </property> </properties>
Из этого описания сама Jira сгенерирует страницу с параметрами. При нажатии кнопки будет вызван основной класс отчета, в который придут выбранные параметры, на основании которых будет реализована логика формирования отчета. Далее сгенерированный отчет объединяется с шаблоном и результат выводится на экран пользователю.
А что по экспорту в excel? В основном классе отчета можно переопределить метод isExcelViewSupported класса AbstractReport, чтобы он возвращал true и тогда в углу отчета появляется магическая кнопка для экспорта в excel-файл.
Что из этого всего вытекает:
-
не надо самим делать полностью front, лишь непосредственно страницу отчета;
-
не надо самим делать экспорт в excel;
-
отчет будет в существующей системе, которой уже пользуются пользователи.
На основе всего вышесказанного было принято решение реализовывать отчет в виде плагина для Jira.
Первый блин — не комом, но могло быть и лучше
На основе всего изученного выше начали работу. Делали все так сказать по фэн-шую с небольшими вкраплениями собственных идей. Но как оказалось не все так гладко в датском королевстве.
Начнем с экрана с начальными параметрами. Jira правда сгенерировала этот экран на основе указанного нами xml, но вот красота сего произведения оставляла желать лучшего. И если с полями для выбора дат все было вполне приемлемо, то вот с multiselect все оказалось хуже.

На выходе получался стандартный select с атрибутом multiple. С одной стороны, все работает – значения успешно прокидываются в select, пользователь может выбрать несколько значений, который потом успешно попадают в основной класс отчета. С другой стороны, пользоваться этим было откровенно неудобно, особенно если у параметра было много допустимых значений (больше 5).
Далее возникла проблема экспортом отчета в excel. Опять же, при нажатии кнопки экспорта, пользователю предлагалось загрузить на компьютер файл с форматом .xls, который можно было открыть и увидеть ту же информацию. Однако как оказалось это не настоящий excel, а просто html-файл с форматом .xls. Excel достаточно умный чтобы открыть такой файл, но вот дальнейшая работа с ним проблематична – если надо дополнительно что-то посчитать или не дай бог построить сводный отчет, то беда.
С этой проблемой нам удалось справиться. Jira позволяет в плагине добавить свой REST-endpoint, который будет казаться частью самой Jira, что мы и сделали. Отвечал этот endpoint за генерацию «настоящего» excel-файла по параметрам с первого экрана. Чтобы его вызвать была добавлена соответствующая кнопка на экран с самим отчетом.
Следующая проблема, с которой нам пришлось бороться это проблема прав. В Jira все отчеты, реализованные через модуль report попадают во вкладку «Отчеты» экрана проекта. Получается, что все пользователи могут этот отчет вызвать, что нас категорически не устраивало. После некоторых раздумий пришли к такому решению: проверять права на этапе генерирования отчета и в случае если у пользователя нет прав на данный отчет, после экрана с параметрами выдавать другую страницу с соответствующим сообщением.
В итоге было принято решение что текущая реализация подойдет в качестве первой версии отчета, но есть над чем работать.
Надо еще подумать
Начали думать, как нам быть и что делать. Посмотрим, что происходит под капотом.

Jira из xml генерирует начальную страницу для выбора параметров отчета. Для каждого select в плагине должен присутствовать класс реализующий интерфейс ValuesGenerator. В качестве примера можно привести генератор для проектов:
public class ProjectsGenerator implements ValuesGenerator { @Override public Map getValues(Map map) { final ProjectManager projectManager = ComponentAccessor.getProjectManager(); return projectManager.getProjects().stream() .collect(Collectors.toMap(Project::getKey, Project::getName)); } }
После того как будут получены значения для всех select интерфейс выбора параметров будет предоставлен пользователю. Вот на этом моменте уже появляются 2 проблемы:
-
не можем вклиниться в процесс генерации этого экрана и сделать его более приятным глазу;
-
на данном этапе нет возможности провалидировать параметры, выбранные пользователем из-за чего валидация в основном классе отчета.
Проблема с правами возникает из-за того, что создатели Jira предполагают, что все отчеты, реализованные через модуль report должны быть доступны через соответствующую вкладку в проекте. В рамках нашей задачи такой подход нас не устраивает.
После тщательного изучения документации нашли что есть такой модуль как webwork. Суть его в том, что в рамках него можно объявлять несколько связок url-шаблон-класс с переходами от одной связки к другой. Кроме того, в этом же модуле можно сразу указать какие роли требуются для перехода по данному url. В atlassian-plugin.xml это выглядит следующим образом (пример взят из документации):
<webwork1 key="reference-actions" name="Reference WebWork Action" class="java.lang.Object" roles-required="use"> <actions> <action name="com.atlassian.jira.dev.reference.plugin.actions.PreparedReferenceAction" alias="PreparedReferenceAction" roles-required="sysadmin"> <view name="success">templates/actions/prepared-reference-action.vm</view> </action> <action name="com.atlassian.jira.dev.reference.plugin.actions.ReferenceAction" alias="ReferenceAction"> <view name="success">templates/actions/reference-action.vm</view> </action> </actions> </webwork1>
Работа плагина с учетом нового подхода будет выглядеть следующим образом:

Можно сделать так сказать двойную проверку прав, которая будет происходить средствами самой Jira:
-
на уровне видимости кнопки – реализуется с помощью condition для web-item;
-
на уровне action в модуле webwork (на случай если у пользователя осталась ссылка на отчет, а права у него забрали).
Теперь касательно интерфейса. Если мы не можем вклиниться в его генерацию мы просто реализуем свой. В таком случае будет возможность и навести красоту, и вынести валидацию параметров из основного класса отчета в класс для страницы с параметрами.
Соответственно в нашем случае описание модуля будет выглядеть следующим образом:
<webwork1 key="report" name="report-webwork" i18n-name-key="report.name" class="java.lang.Object" roles-required="report-role" > <description key="report.description">Report-webwork Plugin</description> <actions> <action name="com.report.webwork.ReportConfigurationAction" alias="ReportConfiguration"> <view name="report-configuration">/templates/configuration/report-configuration.vm</view> </action> <action name="com.report.webwork.WebReportAction" alias="WebReport"> <view name="view">/templates/view/html-view.vm</view> </action> </actions> </webwork1>
Данный подход был предложен заказчику, и он согласился что надо пробовать.
Второй блин
Решили идти итерациями:
-
перевод текущего функционала на webwork;
-
добавление дополнительных «хотелок» (подсветка строк в отчете, добавление новых столбцов и т.д.);
-
решение проблемы с правами.
Основным челенджом первой итерации было написать собственно страницы с параметрами отчета. Тут уж мы обратились за помощью к коллегам из отдела frontend-разработки – обрисовали им ситуацию и что хотим получить на выходе. После некоторого молчания коллеги нам выкатили UI, в котором элементы выглядят уже гораздо приятнее:

От нас оставалось только преобразовать это все в velocity-шаблон и привязать к определенному action в webwork. Конфигурация модуля выглядит следующим образом:
<webwork1 key="report" name="report-webwork" i18n-name-key="report.name" class="java.lang.Object" roles-required="report-role" > <description key="report.description">Report-webwork Plugin</description> <actions> <action name="com.report.webwork.ReportConfigurationAction" alias="ReportConfiguration"> <view name="report-configuration">/templates/configuration/report-configuration.vm</view> </action> <action name="com.report.webwork.WebReportAction" alias="WebReport"> <view name="view">/templates/view/html-view.vm</view> </action> </actions> </webwork1>
Классы, которые предоставляли выдающим спискам значения подверглись минимальной доработке, после чего у нас появился красивый экран с параметрами отчета.

Был добавлен web-item, который представлял собой ссылку на action с конфигурацией отчета. В результате в верхней панели появилась кнопка для вызова отчета.
REST-endpoint для экспорта в excel в итоге переехал без изменений.
На выходе получился отчет с приятным интерфейсом, той же функциональностью (за мелкими улучшениями) и реализованный более гибким способом.

ссылка на оригинал статьи https://habr.com/ru/company/nlmk/blog/681874/
Добавить комментарий