Недавно мы выпустили новую версию Jmix 1.5. В этой статье я расскажу о ключевых обновлениях, представленных в этом функциональном релизе.
Как обычно, полную информацию об изменениях и инструкции по обновлению смотрите на странице документации "Что нового".
Изменения в Studio UI/UX
Начнем с обсуждения хорошо заметных изменений в новой версии Studio.
Мы провели несколько сессий UX-тестирования с разработчиками, незнакомыми с Jmix, и сделали вывод, что текущий дизайнер экранов UI чересчур сложен. Три окна инструментов и несколько панелей XML/предпросмотра пугают пользователей, видящих инструмент впервые. С другой стороны, мы выяснили, что люди легко обнаруживают действия, доступные из верхней панели текущего редактора, а также склонны искать возможные варианты действий в контекстных меню.
Поэтому мы решили отказаться от статической палитры компонентов и перенести ее содержимое во всплывающее окно, открывающееся из разных мест интерфейса: из верхней панели действий, из контекстного меню иерархии компонентов, и из меню Generate редактора исходного кода. Палитра во всплывающем окне поддерживает поиск и перетаскивание в иерархию и в код:
Иерархия компонентов и инспектор теперь соединены в одно окно инструментов Jmix UI, которое находится по умолчанию справа. Таким образом, дизайнер UI теперь имеет только одно окно инструментов, а палитра компонентов легко доступна из различных мест интерфейса.
Еще одним проблемным местом в интерфейсе Studio была палитра Code Snippets. Найти ее среди других окон инструментов для начинающего пользователя было почти невозможно, в то время как особенно полезна она именно новичкам. Теперь сниппеты доступны во всплывающем окне, которое открывается из верхней панели действий и из меню Generate при редактировании бинов Spring и контроллеров UI:
Улучшения Flow UI
Мы продолжаем активно работать над возможностями Flow UI, чтобы со временем сделать его основной технологий создания UI в Jmix.
В релизе 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 и регулярно обновляется. Патчи для релиза 1.5 будут выходить примерно раз в месяц.
Мы будем рады увидеть ваши отзывы на нашем форуме!
Спасибо всем, кто поделился своими идеями, предложениями и сообщениями об ошибках!