decorate image
decorate image
В связи с техническими работами сайт будет недоступен 21 декабря 2024 с 12:00 до 12:30 МСК
Все статьи

Выпущена версия Jmix 2.2

Данная статья описывает важные обновления, представленных в только что вышедшем релизе Jmix 2.2.

Полная информация об изменениях доступна на странице документации Что нового.

Дополнение Charts

Пожалуй, самая заметная новая функциональность Jmix 2.2 - долгожданное дополнение Charts. Оно интегрирует Apache ECharts, библиотеку диаграмм на JavaScript с открытым исходным кодом, в Jmix UI. Теперь вы можете использовать всю мощь диаграмм ECharts, настраивая их через XML или Java в вашем Jmix-приложении, и легко подключать диаграммы к данным на стороне сервера, так же как другие компоненты UI.

Например, для сущности VehicleCount, которая хранит количество различных транспортных средств по годам в атрибутах cars, motorcycles, bicycles и year, вы можете настроить диаграмму для визуализации данных следующим образом:

<data>  
    <collection id="vehiclesDc"  
                class="com.company.demo.entity.VehicleCount">  
        <fetchPlan extends="_local"/>  
        <loader id="vehiclesDl" readOnly="true">  
            <query>  
                <![CDATA[select e from VehicleCount e order by e.year]]>  
            </query>  
        </loader>  
    </collection>  
</data>
<layout>
	<charts:chart id="chart">  
	    <charts:dataSet>  
	        <charts:source dataContainer="vehiclesDc"  
	                       categoryField="year"  
	                       valueFields="cars motorcycles bicycles"/>  
	    </charts:dataSet>  
	    <charts:series>  
	        <charts:bar name="Cars"/>  
	        <charts:bar name="Motorcycles" stack="stack"/>  
	        <charts:bar name="Bicycles" stack="stack"/>  
	    </charts:series>  
	    <charts:xAxes>  
	        <charts:xAxis/>  
	    </charts:xAxes>  
	    <charts:yAxes>  
	        <charts:yAxis>  
	            <charts:axisLabel formatter="{value}"/>  
	        </charts:yAxis>  
	    </charts:yAxes>  
		<charts:title text="Vehicles" subtext="By Year"/>  
		<charts:legend/>
	</charts:chart>

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

Мы постарались сделать XML и Java API диаграмм максимально близкими к нативному JavaScript API библиотеки ECharts, что позволяет легко настраивать диаграмму в Jmix, обращаясь к исчерпывающей документации ECharts.

Дополнение Charts свободно доступно на Marketplace и может быть использовано в любом проекте, основанном на Jmix 2.2.

Улучшения в дополнении Maps

Дополнение Maps получило новые важные функции: возможность отображения MultiPoint, MultiLine и MultiPolygon, слой тепловых карт и кластеризацию.

MultiPolygon - это просто коллекция полигонов в одной геометрии. В приведенном ниже примере мы создаем MultiPolygon, состоящий из двух прямоугольников:

private void addMultiPolygon(VectorSource vectorSource) {  
    GeometryFactory factory = GeometryUtils.getGeometryFactory();  
    Polygon polygon1 = factory.createPolygon(  
            factory.createLinearRing(new Coordinate[]{  
                    new Coordinate(15.5, 38.9),  
                    new Coordinate(15.5, 44.9),  
                    new Coordinate(9.5, 44.9),  
                    new Coordinate(9.5, 38.9),  
                    new Coordinate(15.5, 38.9)}));  
    Polygon polygon2 = factory.createPolygon(  
            factory.createLinearRing(new Coordinate[]{  
                    new Coordinate(20.7, 40.9),  
                    new Coordinate(26.7, 40.9),  
                    new Coordinate(26.7, 34.9),  
                    new Coordinate(20.7, 34.9),  
                    new Coordinate(20.7, 40.9)}));  
    MultiPolygon multiPolygon = factory.createMultiPolygon(new Polygon[]{polygon1, polygon2});  
    vectorSource.addFeature(new MultiPolygonFeature(multiPolygon));  
}

Он будет показан на карте следующим образом:

Функция кластеризации позволяет отображать большое количество маркеров на карте, объединяя их. В следующем примере карта показывает самые известные города, основанные римлянами:

Это достигается просто оборачиванием источника векторных данных в элемент cluster в XML экрана:

<maps:geoMap>  
    <maps:layers>  
        <maps:tile>  
            <maps:osmSource/>  
        </maps:tile>  
        <maps:vector id="cityLayer">  
            <maps:cluster distance="30">  
                <maps:dataVectorSource dataContainer="citiesDc" property="point"/>  
            </maps:cluster>  
        </maps:vector>  
    </maps:layers>  
    <maps:mapView centerY="41.9" centerX="12.48" zoom="4.5"/>  
</maps:geoMap>

Те же данные можно визуализировать в виде тепловой карты, где значения представлены цветом:

Тепловая карта настраивается специальным слоем heatmap с собственным источником данных, подключенным к тому же контейнеру данных:

<maps:geoMap>  
    <maps:layers>  
        <maps:tile>  
            <maps:osmSource/>  
        </maps:tile>  
        <maps:heatmap radius="15">  
            <maps:heatmapDataVectorSource dataContainer="citiesDc" property="point"/>  
        </maps:heatmap>  
    </maps:layers>  
    <maps:mapView centerY="41.9" centerX="12.48" zoom="4.5"/>  
</maps:geoMap>

Улучшения в BPM

Чтобы сократить цикл обратной связи при разработке процессов в Studio, мы реализовали горячее развертывание определений процессов в работающее приложение. Вы можете увидеть кнопку Hot Deploy Process в верхней панели дизайнера BPMN. Приложение выводит сообщение в журнал, когда процесс успешно развернут:

Мастер форм процесса в Studio теперь может генерировать форму для начального события. Такая форма будет содержать кнопку Start process, которая вызывает API процессного движка.

Этот мастер также содержит новый пункт Process form for entity instance в раскрывающемся списке Form template. Если вы выберете этот вариант, мастер позволит вам выбрать или создать переменную типа Entity. Результатом будет форма процесса, содержащая контейнер данных и поле для редактирования выбранной сущности.

Компонент RichTextEditor

Новый компонент richTextEditor, основанный на JavaScript-библиотеке Quill, позволяет редактировать текст с форматированием и сохранять его как HTML:

Компонент поддерживает работу с данными и может быть легко подключен к вашей модели данных:

<richTextEditor id="descriptionField" width="100%"  
                dataContainer="stepDc" property="description"/>

Улучшения в главном экране

Новый компонент menuFilterField позволяет пользователям фильтровать элементы главного меню.

Достаточно разместить поле фильтра на экране и подключить его к listMenu:

<menuFilterField menu="menu"
                 placeholder="Search..." classNames="ms-s me-s"/>
<nav id="navigation" classNames="jmix-main-view-navigation" ariaLabel="msg://navigation.ariaLabel">
    <listMenu id="menu"/>
</nav>

Фильтрация меню в действии:

Следующее улучшение, касающееся главного экрана, - возможность декларативно определять содержимое при отсутствии открытых дочерних экранов. Используйте для этого элемент initialLayout компонента appLayout:

<appLayout>
    <navigationBar .../>
    <drawerLayout .../>
    <initialLayout>
        <h2 text="Hello world!"/>
    </initialLayout>
</appLayout>

Тогда приложение будет выглядеть следующим образом:

И, вероятно, наиболее ожидаемое улучшение в этой области - это горизонтальное основное меню:

Оно реализовано с помощью компонента horizontalMenu, который получает структуру меню из того же дескриптора menu.xml. Таким образом, вы можете легко заменить стандартное вертикальное listMenu на верхнее горизонтальное меню в любой момент в вашем проекте. Самый простой способ сделать это - нажать New → View и выбрать шаблон Main view with top menu. Если вы выберете флажок Use as default main view на втором шаге мастера, Studio установит новый главный экран в свойство приложения jmix.ui.main-view-id и в атрибут layout аннотации @Route для всех существующих экранов, например:

@Route(value = "users", layout = MainViewTopMenu.class)

В результате новый главный экран с горизонтальным меню заработает сразу же после запуска приложения.

Улучшения в DataGrid

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

Мы также завершили работу над фильтром в заголовках столбцов: теперь его можно отразить в URL для создания глубокой ссылки и сохранения состояния экрана при переходе к представлению деталей и обратно. Используйте для этого новый элемент dataGridFilter фасета urlQueryParameters.

Еще одна полезная функция - новый компонент gridColumnVisibility, который позволяет пользователям скрывать и отображать столбцы таблицы:

Свойства-коллекции в универсальном фильтре

Ранее, чтобы фильтровать сущность по ее атрибуту-коллекции, используя компонент genericFilter, нужно было определять условие JPQL с join и where-выражениями. Очевидно, что это было нечто сложно достижимое для конечного пользователя.

Теперь фильтрация по ссылкам "to-many" и их вложенным атрибутам так же проста, как и для ссылок "to-one": они отображаются в диалоге Add condition общего фильтра, и необходимые условия JPQL генерируются фреймворком автоматически.

В следующем примере список пользователей фильтруется по атрибуту completedDate связанной коллекции steps:

Сокращено время сборки

В то время как технология hot deploy дает возможность сократить цикл обратной связи при разработке UI, она не применяется к разработке бизнес-логики. Поэтому быстрый перезапуск приложения остается важным.

В версии Jmix 2.2, этап модификации байткода сущностей (enhancing), который занимает значительное время во время сборки, выполняется только в том случае, если с момента последней сборки модель данных была изменена. Следовательно, если вы работаете над бинами Spring, не модифицируя сущности, процесс сборки и перезапуска теперь выполняется значительно быстрее, особенно в проектах с большими моделями данных.

Новые сниппеты кода

Если в вашем проекте включены дополнения Reports, Email sending, BPM или Notifications, вы можете воспользоваться новыми сниппетами, связанными с API этих дополнений.

Например, если вам нужно запустить отчет при нажатии пользователем кнопки, вы можете сгенерировать метод-слушатель нажатия кнопки, а затем перетащить сниппет Run report using UiReportRunner в код слушателя. Studio предложит вам указать отчет, который вы хотите запустить, и сгенерирует соответствующий код:

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

Добавление компонентов с помощью мастеров

По мере расширения коллекции UI-компонентов, для новичков становится все сложнее находить подходящий компонент для конкретной задачи.

Поэтому мы решили предоставить дополнительный, еще более декларативный способ создания экранов. Вместо выбора компонента из палитры Add Component разработчик может запустить мастер, который предлагает серию вопросов. Затем мастер генерирует целый фрагмент, содержащий предварительно настроенные компоненты данных и визуальные компоненты.

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

В следующем ролике мастер Edit entity attributes создает formLayout с полями, подключенными к контейнеру данных:

Эта функция в настоящее время является экспериментальной, и мы планируем расширить её в будущем, добавив больше мастеров и сделав их более полезными в различных сценариях использования.

Генерация тестов

Когда вы откроете проект в новой Студии, вы увидите новый пункт Tests в окне инструментов Jmix. Двойной щелчок по этому элементу перенесет вас в окно инструментов Project в каталог src/test/java.

Действия New → Advanced → Integration Test и UI Integration Test позволяют быстро создавать заготовки для тестов бизнес-логики и интеграционных тестов UI.

Бесплатная Студия для небольших проектов

И последнее, но не менее важное: теперь премиальные RAD-функции Студии доступны бесплатно для небольших проектов, в которых число сущностей и ролей не превышает 10. Это означает, что вы получаете доступ ко всем визуальным инструментам Студии для изучения, экспериментов и создания личных проектов или коммерческих приложений, не нуждаясь в активной коммерческой или пробной подписке. Единственным ограничением является то, что эти проекты не должны содержать большую модель данных и безопасности.

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

Заключение

В следующем функциональном релизе в июне 2024 года мы планируем реализовать интеграцию с Apache Superset, ведущей платформой для визуализации данных с открытым исходным кодом.

На стороне Studio мы собираемся предоставить подход к агрегированию Liquibase changelogs и действия для быстрого преобразования аналогичных компонентов UI, таких как entityPicker и entityComboBox.

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

Наш подробный план для будущих версий доступен в виде проекта на GitHub. Патчи для текущей версии 2.2 будут выходить примерно раз в месяц.

Будем рады увидеть ваши отзывы на нашем форуме!

Спасибо всем, кто отправлял нам PR-ы, делился своими идеями, предложениями и сообщениями об ошибках!

Jmix - это open-source платформа быстрой разработки бизнес-приложений на Java