Недавно мы выпустили новую версию платформы Jmix 1.5. В статье расскажем о ключевых обновлениях, представленных в этом функциональном релизе.
Но сначала – небольшое вступление, кто мы такие и о какой платформе идет речь. Мы в Haulmont специализируемся на разработке и внедрении корпоративных информационных систем и заказных решений, а также собственных технологий и инструментов.
Одна из наших разработок, Jmix – это технологическая open-source платформа для быстрой разработки бизнес-приложений на Java. О ней и пойдет речь.
Изменения в Studio UI/UX
Начнем с обсуждения хорошо заметных изменений в новой версии Studio - нашего плагина для IntelliJ IDEA, предназначенного для быстрой разработки на Jmix.
Мы провели несколько сессий UX-тестирования с разработчиками, незнакомыми с Jmix, и сделали вывод, что текущий дизайнер экранов UI чересчур сложен. Три окна инструментов и несколько панелей XML/предпросмотра пугают пользователей, видящих инструмент впервые. С другой стороны, мы выяснили, что люди легко обнаруживают действия, доступные из верхней панели текущего редактора, а также склонны искать возможные варианты действий в контекстных меню.
Поэтому решили отказаться от статической палитры компонентов и перенести ее содержимое во всплывающее окно, открывающееся из разных мест интерфейса: из верхней панели действий, из контекстного меню иерархии компонентов, и из меню Generate редактора исходного кода. Палитра во всплывающем окне поддерживает поиск и перетаскивание в иерархию и в код:
Иерархия компонентов и инспектор теперь соединены в одно окно инструментов Jmix UI, которое находится по умолчанию справа. Таким образом, дизайнер UI теперь имеет только одно окно инструментов, а палитра компонентов легко доступна из различных мест интерфейса.
Еще одним проблемным местом в интерфейсе Studio была палитра Code Snippets. Найти ее среди других окон инструментов для начинающего пользователя было почти невозможно, в то время как особенно полезна она именно новичкам. Теперь сниппеты доступны во всплывающем окне, которое открывается из верхней панели действий и из меню Generate при редактировании бинов Spring и контроллеров UI:
Улучшения Flow UI
Мы продолжаем активно работать над возможностями Flow UI, чтобы со временем сделать его основной технологий создания UI в Jmix.
Flow UI позволяет создавать адаптивные mobile-friendly веб-приложения без каких-либо особых усилий, используя ту же модель Java-программирования на стороне сервера и XML-компоновку с поддержкой в визуальном дизайнере Studio.
В релизе 1.5 мы обновили ядро до Vaadin 23.3 и интегрировали несколько визуальных компонентов.
TabSheet
Компонент tabsheet абсолютно необходим, когда нужно разместить большое количество UI-компонентов на одном экране. А это вполне обычная ситуация для бэкофис-приложений типа ERP или CRM, в которых наиболее часто используется Jmix.
В предыдущем релизе Jmix включал только компонент Tabs, который не является контейнером и требует программного переключения между разными частями экрана. Благодаря Vaadin 23.3, у нас теперь есть полнофункциональный TabSheet с полностью декларативной компоновкой:
<tabSheet width="100%">
<tab id="mainTab" label="Main">
<formLayout id="form" dataContainer="userDc">...</formLayout>
</tab>
<tab id="additionalTab" label="Onboarding steps">
<vbox>
<hbox>...</hbox>
<dataGrid width="100%" dataContainer="stepsDc">...</dataGrid>
</vbox>
</tab>
</tabSheet>
MultiSelectComboBox
Компонент MultiSelectComboBox также появился в новой версии Vaadin. Он позволяет пользователю выбирать несколько значений из выпадающего списка и удобно отображает их в поле. Мы интегрировали данный компонент в Jmix и добавили привязку к данным, так что его можно легко использовать для отображения и модификации атрибутов-коллекций. В примере ниже компонент MultiSelectComboBox используется для управления many-to-many коллекцией тегов продукта:
<instance id="productDc"
class="com.company.demo.entity.Product">
<fetchPlan extends="_base">
<property name="tags" fetchPlan="_base"/>
</fetchPlan>
<loader/>
</instance>
<collection class="com.company.demo.entity.Tag" id="allTagsDc">
<fetchPlan extends="_base"/>
<loader id="allTagsDl">
<query>
<![CDATA[select e from Tag e]]>
</query>
</loader>
</collection>
<!-- ... -->
<formLayout id="form" dataContainer="productDc">
<textField id="nameField" property="name"/>
<multiSelectComboBox property="tags" itemsContainer="allTagsDc"/>
</formLayout>
Поля Upload
Компонент Upload из набора компонентов Vaadin послужил основой для двух компонентов Flow UI: FileStorageUploadField and FileUploadField. Первый предназначен для загрузки файлов в файловое хранилище, и возвращает объект FileRef, который сохраняется в атрибуте сущности. Второй возвращает байтовый массив, который сохраняется напрямую в атрибуте сущности.
Использовать оба компонента в XML очень просто - достаточно установить контейнер данных с экземпляром сущности и указать имя атрибута:
<fileStorageUploadField id="uploadField"
dataContainer="userDc" property="picture"/>
Image
Компонент Image также получил декларативную привязку к данным. Теперь он может использоваться с атрибутами типа FileRef или байтового массива:
<image id="image"
dataContainer="userDc" property="picture"
height="280px" width="200px" classNames="user-picture"/>
Для настройки положения изображения необходимо использовать стили CSS. Например, для масштабирования изображения с сохранением соотношения сторон можно объявить следующий класс и использовать его в атрибуте classNames компонента:
.user-picture {
object-fit: contain;
}
Tooltip
Tooltip может отображать дополнительную информацию о UI-компоненте во всплывающей подсказке. Она появляется при наведении указателя мыши и при получении компонентом фокуса ввода.
Для компонентов, поддерживающих Tooltip, дизайнер UI в Studio отображает кнопку Add в панели инспектора:
В XML tooltip задается во вложенном элементе:
<textField id="nameField" property="name">
<tooltip text="Product name" position="BOTTOM_START"/>
</textField>
Универсальный фильтр
В классическом UI одним из наиболее популярных компонентов является Filter - он позволяет пользователям отбирать данные по различным критериям, включая свойства сущностей, ссылки, запросы JPQL и условные операторы. Можно сказать что это "щвейцарский нож" для структурированного поиска - разработчику нужно только добавить его на экран, а пользователи могут настраивать и применять его когда им это необходимо.
В Jmix 1.5 мы добавили в Flow UI компонент GenericFilter с базовой функциональностью: пользователи могут создавать любое количество условий по атрибутам графа сущностей. И как все остальное в Flow UI, компонент хорошо адаптируется под различную ширину экрана:
Параметры адаптации фильтра можно настраивать во вложенном элементе responsiveSteps
:
<genericFilter id="filter" dataLoader="usersDl"
summaryText="My filter">
<responsiveSteps>
<responsiveStep minWidth="0" columns="1"/>
<responsiveStep minWidth="800px" columns="2"/>
<responsiveStep minWidth="1200px" columns="3"/>
</responsiveSteps>
</genericFilter>
Очевидно, что фильтр должен сохранять свое состояние при навигации между экранами и при обновлении веб-страницы, иначе пользователи будут терять условия фильтрации, например после редактирования записи в экране деталей. Фасет queryParameters
автоматически отображает параметры фильтра на текущий URL, что обеспечивает корректное состояние фильтра при навигации и предоставляет глубокие ссылки, включающие условия фильтрации. Для конфигурирования фасета достаточно указать в нем компонент фильтра по его id:
<facets>
<queryParameters>
<genericFilter component="filter"/>
</queryParameters>
</facets>
Разработка компонента GenericFilter продолжается, и мы планируем включить все возможности классического фильтра в Flow UI в июньском релизе 2023 г.
Дополнения с Flow UI
В релизе 1.5 мы реализовали модули Flow UI для следующих популярных open-source дополнений:
Multitenancy
Quartz
Application Settings
Grid Export Actions
Они доступны в маркетплейсе дополнений Studio при работе над проектом с Flow UI.
Меню Flow UI
Вы могли заметить, что главное меню в проекте с Flow UI организовано по-другому по сравнению с классическим UI: каждое дополнение имеет свой собственный корневой узел с предопределенным порядком, и общего меню "Administration" нет. Такая структура по умолчанию вполне подходит для экспериментов и прототипирования, однако для реального приложения нужна собственная структура меню. То есть необходимо переключиться из режима "composite" в "single" и определить нужную структуру.
Раньше многие разработчики как можно дольше избегали использования режима "single", так как он приводил к проблеме при включении новых дополнений в проект: меню дополнений автоматически не появлялось в меню приложения и было непонятно как его добавить.
Теперь проблема с режимом "single" решена в дизайнере меню Flow UI. При переключении в режим "single" дизайнер показывает дополнительную панель слева. Она содержит все пункты меню, предоставляемые дополнениями для использования в приложении. При подключении нового дополнения достаточно открыть дизайнер меню и перетащить появившиеся пункты в желаемое место меню приложения.
Экспорт в Excel
Одна из часто используемых возможностей Jmix - экспорт в Excel данных, отображаемых в таблице UI. Эта функциональность была специально предназначена для экспорта того, что в данный момент видно пользователю, то есть текущей страницы данных, отобранных по фильтру. Однако часто пользователям требуется экспортировать все отфильтрованные записи, а не только текущую страницу.
В релизе 1.5 мы доработали действие excelExport
, предоставляемое дополнением Grid Export Actions: если пользователь выбирает опцию "All rows" в диалоге экспорта, то выгружаются все записи. Загрузка данных из БД производится партиями для оптимальной производительности и использования памяти сервера.
Новое поведение реализовано и в классическом и в Flow UI.
UI пессимистичных блокировок
Фреймворк теперь предоставляет стандартный экран UI для управления пессимистичными блокировками. Его можно найти в меню Administration классического UI и в меню System Flow UI.
Администратор системы может просматривать список текущих блокировок и при необходимости вручную снимать блокировку.
Корневой Liquibase changelog
Важная особенность Jmix - помощь разработчикам в создании и запуске файлов changelog для версионирования баз данных. Studio генерирует файлы changelog по разнице между моделью данных и схемой БД и выполняет их при старте приложения. Когда новая версия приложения стартует в тестовом или продуктовом окружении, она запускает Liquibase для применения изменений на подключенных базах данных.
Однако иногда этого простого процесса недостаточно, и разработчикам нужно запускать Liquibase вне Studio и приложения, например на сервере CI с использованием Liquibase CLI или плагина Gradle.
Раньше это было крайне проблематично, так как корневой changelog проекта не содержал ссылок на файлы changelog из дополнений. Jmix брал информацию об используемых дополнениях из конфигурации проекта и создавал корректный changelog динамически в памяти перед запуском Liquibase.
Начиная с Jmix 1.5, корневой changelog проекта всегда полноценен и может выполняться с помощью Liquibase CLI или плагина Gradle. Studio автоматически обновляет необходимые включения при добавлении или удалении дополнений в проекте. Кроме того, Studio проверяет, что включения в корневом changelog соответствуют дополнениям, используемым в проекте. Если обнаруживается расхождение, Studio отображает диалог с уведомлением и предложением добавить или удалить включения.
Корневой файл changelog может быть открыт из окна инструментов Jmix двойным щелчком на узле хранилища данных:
Что дальше?
В июне 2023 года мы планируем выпустить новую версию со свежими мажорными версиями Spring Framework, Spring Boot, EclipseLink и Vaadin. Для этого нам необходимо будет использовать Java 17 для разработки и запуска приложений, это как минимум.
Кроме того, мы планируем реализовать модули Flow UI для наиболее популярных дополнений: Reports и BPM.
Наши планы на следующие релизы подробно описаны в виде проекта GitHub, который регулярно обновляется. Кроме того, примерно раз в месяц мы выпускаем патчи для текущего релиза.
Будем очень благодарны обратной связи на нашем форуме. Спасибо всем, кто поделился своими идеями, предложениями и сообщениями об ошибках! Вы помогаете нам делать Jmix лучше и полезнее.