Что нового

В данном разделе приведена информация о новой функциональности и возможных несовместимых изменениях в фреймворке Jmix и Jmix Studio версии 2.4. Примите их во внимание при обновлении с предыдущей версии фреймворка.

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

Минимальная требуемая версия IntelliJ IDEA - 2024.1.

Раздел Апгрейд проекта содержит информацию о том, как обновить проект с помощью Studio. Процедура автоматической миграции вносит следующие изменения в ваш проект:

  • Обновляет версию Jmix BOM, которая, в свою очередь, определяет версии всех зависимостей.

  • Обновляет версию Jmix Gradle plugin.

  • Обновляет версию Gradle wrapper до 8.10.2 в gradle/wrapper/gradle-wrapper.properties.

  • Если проект включает дополнение REST API, добавляет свойство jmix.resource-server.authenticated-url-patterns, смотрите подробности ниже.

  • Заменяет вызовы методов dateTimeParameter(), dateParameter() и timeParameter() билдера диалогового окна ввода на вызовы localDateTimeParameter(), localDateParameter() и localTimeParameter(). См. подробности ниже.

  • Добавляет дополнение Grid Export Actions в проект, если он включает дополнение Data Tools. См. подробности ниже.

  • Устанавливает свойство приложения jmix.ui.component.default-trim-enabled в false. См. подробности ниже.

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

Если после обновления проекта и запуска приложения вы столкнетесь со следующей исключительной ситуацией:

com.vaadin.flow.server.ExecutionFailedException: Vite build exited with a non zero status

удалите следующие файлы и каталоги из корня проекта: node_modules, package.json, pnpm-lock.yaml, tsconfig.json, types.d.ts, vite.config.ts, vite.generated.ts

Кроме того, если у вас глобально установлен Node.js, обновите его до последней LTS версии доступной на сайте https://nodejs.org.

Обновленные зависимости

Следующие основные зависимости были обновлены:

Новая и улучшенная функциональность

Новые дополнения

Доступны следующие новые дополнения:

  • Дополнение Calendar предоставляет UI-компонент, который позволяет отображать привязанные к данным события в календаре с различным отображением (день, неделя, месяц и т. д.) и редактировать их с помощью перетаскивания и изменения размера.

  • Дополнение Pivot Table предоставляет UI-компонент, который позволяет преобразовать набор данных в сводную таблицу и манипулировать ею с помощью 2D интерфейса перетаскивания.

  • Дополнение Kanban представляет UI-компонент, который отображает Канбан-доску. Он показывает рабочий процесс на разных этапах проекта, используя карточки для задач и колонки для этапов.

  • Дополнение UI Constraints позволяет контролировать видимость и доступность UI-компонентов с использованием декларативных политик, определенных в ресурсных ролях.

  • Дополнение REST DataStore позволяет получать доступ к внешним сущностям из удаленного Jmix-приложения через стандартный интерфейс DataManager, так же как к локальным JPA-сущностям.

Привязка данных для HTML-компонентов

HTML-компоненты, такие как div, span, h1…​h5 и другие, теперь могут быть привязаны к сущностям модели данных декларативно в XML с использованием атрибутов dataContainer и property.

В большинстве случаев это избавляет от необходимости программно задавать значения в этих компонентах в контроллерах экрана.

Fragment Renderer

Рендереры для virtualList, dataGrid и других компонентов теперь могут быть определены с помощью фрагментов.

Новый XML-элемент fragmentRenderer должен указывать класс Java фрагмента, например:

<virtualList itemsContainer="usersDc">
    <fragmentRenderer class="com.company.onboarding.view.userfragment.UserFragment"/>
</virtualList>

Пример фрагмента, используемого в качестве рендерера:

<fragment xmlns="http://jmix.io/schema/flowui/fragment">
    <data>
        <instance id="userDc" class="com.company.onboarding.entity.User">
            <loader id="userDl"/>
        </instance>
    </data>
    <content>
            <formLayout id="form" dataContainer="userDc">
                <textField id="usernameField" property="username" readOnly="true"/>
                <textField id="firstNameField" property="firstName"/>
                <textField id="lastNameField" property="lastName"/>
                <textField id="emailField" property="email"/>
            </formLayout>
        </hbox>
    </content>
</fragment>

Класс рендерера фрагмента должен расширять базовый класс FragmentRenderer с параметрами типов, указывающими корневой компонент и отображаемую сущность, например:

@FragmentDescriptor("user-fragment.xml")
@RendererItemContainer("userDc")
public class UserFragment extends FragmentRenderer<FormLayout, User> {
}

Аннотация @RendererItemContainer используется для указания контейнера данных, принимающего отображаемую сущность.

Для получения более подробной информации см. #3699.

Асинхронные задачи

Новый бин UiAsyncTasks позволяет выполнять операцию в отдельном потоке, используя контекст безопасности текущего пользователя, а затем обновлять UI результатом этой операции.

В отличие от Фоновые задачи, это легковесный механизм, основанный на CompletableFuture.

Обрезка пробелов в текстовых полях

Компоненты textField и textArea теперь имеют атрибут trimEnabled, который контролирует, обрезает ли компонент пробелы в начале и в конце введенной строки.

Свойство приложения jmix.ui.component.default-trim-enabled задает значение этого атрибута по умолчанию для всего приложения. В новых проектах это свойство равно true. Процедура миграции в Studio устанавливает это свойство в false для существующих проектов, чтобы минимизировать изменения в поведении.

Переключение вариантов тем

Новый класс ThemeUtils содержит методы для переключения вариантов тем во время выполнения. Это позволяет легко переключаться между светлой и темной темами в вашем приложении.

Пример можно найти в разделе Смена вариантов тем во время выполнения.

Немедленная валидация обязательных полей

Новое свойство приложения jmix.ui.component.immediate-required-validation-enabled позволяет отключить валидацию обязательных полей при открытии экрана.

Настройки экспорта таблиц

При использовании дополнения Grid Export Actions набор опций экспорта теперь может быть определен конкретным действием экспорта с использованием его метода setAvailableExportModes() и соответствующего свойства availableExportModes в XML. Набор опций по умолчанию определяется свойством приложения jmix.gridexport.default-export-modes.

Использование часового пояса браузера

Если часовой пояс не задан пользователю явно, он может быть получена из веб-браузера при входе. Эта опция контролируется методом isAutoTimeZone() интерфейса HasTimeZone, реализованного стандартной сущностью User, сгенерированной в проектах.

В существующих проектах поведение не изменится, поскольку этот метод по умолчанию возвращает false. В новых проектах User будет сгенерирован с isAutoTimeZone(), возвращающим true.

Расширенная настройка безопасности эндпойнтов

Добавлены дополнительные опции для настройки безопасности эндпойнтов при использовании дополнений Authorization Server или OpenID Connect:

  • Свойства jmix.resource-server.authenticated-url-patterns и jmix.resource-server.anonymous-url-patterns

  • AuthenticatedUrlPatternsProvider и AnonymousUrlPatternsProvider

  • AuthenticatedRequestMatcherProvider и AnonymousRequestMatcherProvider

Дополнительную информацию можно найти в разделе Аутентификация на основе токенов.

Старый AuthorizedUrlsProvider помечен как устаревший, но по-прежнему работает, как и свойства jmix.rest.authenticated-url-patterns и jmix.rest.anonymous-url-patterns. Рекомендуется перенести настройку на новые интерфейсы или свойства.

Улучшение поиска

Новая аннотация @ExtendedSearch может быть добавлена к интерфейсу определения индекса для предоставления функциональности поиска "Начинается с". Она инструктирует дополнение Search создать дополнительные "виртуальные" поля для каждого "реального" поля для хранения подготовленных префиксных терминов.

Компонент searchField теперь позволяет пользователям открыть окно Search settings, чтобы задать стратегию поиска, размер результатов и, при необходимости, набор сущностей для поиска только в этих сущностях. Если в проекте есть определения индекса с @ExtendedSearch, список стратегий включает "Начинается с".

Стратегии allTermsAnyField и allTermsSingleField помечены как устаревшие.

Улучшение REST API

Универсальный REST API теперь поддерживает CRUD-операции с DTO-сущностями в эндпойнтах /entities. Условия поиска, предоставленные в эндпойнт entities/:entityName/search, преобразуются в дерево Condition и передаются в DataManager. Это позволяет запрашивать DTO-сущности, которые в свою очередь загружаются из другого REST API через REST DataStore.

Условия поиска в формате JSON теперь могут включать объекты в значения свойств, например:

{
  "

conditions": [
    {
      "property": "field1",
      "operator": "=",
      "value": {
        "_entityName": "Customer",
        "id": "00000000-0000-0000-0000-000000000001",
        "firstName": "John",
        "lastName": "Doe"
      }
    }
  ]
}

Инспектор компонентов Studio

Инспектор компонентов Jmix UI теперь группирует свойства по категориям: General, Data Binding, Size, Position, Look & Feel, Other. Эта новая функция позволяет быстро найти нужное свойство, не просматривая длинный список.

Категории отображаются только в проектах, основанных на Jmix 2.4 и выше.

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

Поддержка OpenAPI в Studio

Jmix Studio теперь предоставляет расширенную поддержку интеграции приложений на основе OpenAPI. Эти новые функции включают настройку генератора OpenAPI-клиентов в вашем проекте и автоматическую генерацию DTO-сущностей, мапперов и промежуточных сервисов, что упрощает интеграцию внешних REST API в приложения Jmix.

Практический пример и пошаговая инструкция по использованию этих функций находятся в руководстве Integrating Applications Using OpenAPI.

Шаблон композитного проекта для моно-репозитория

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

composite-project/
    subproject1/
        src/
        build.gradle
        settings.gradle
    subproject2/
        src/
        build.gradle
        settings.gradle
    build.gradle
    settings.gradle
    README.md

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

Интерфейс AcceptsTenant объявлен устаревшим

При использовании дополнения Multitenancy сущность User больше не обязана реализовывать интерфейс io.jmix.multitenancy.core.AcceptsTenant. Аннотации @TenantId на поле tenant теперь достаточно.

Интерфейс AcceptsTenant объявлен устаревшим и будет удален в будущем мажорном релизе.

Опасные изменения

Проблема со сборкой при использовании EnableJmixDataRepositories

Когда аннотация @EnableJmixDataRepositories используется в главном классе приложения, расширяющем AppShellConfigurator, сборка может завершаться с ошибкой, сопровождающейся следующим сообщением:

> Task :vaadinPrepareFrontend FAILED
Could not read com.vaadin.flow.theme.Theme annotation from class com.company.onboarding.OnboardingApplication.
java.lang.TypeNotPresentException: Type [unknown] not present

Проблема вызвана vaadin/flow#19616 и будет исправлена в будущих обновлениях.

Чтобы обойти эту проблему, перенесите аннотацию @EnableJmixDataRepositories в отдельный класс с аннотацией @Configuration в том же пакете, например:

package com.company.onboarding;

import io.jmix.core.repository.EnableJmixDataRepositories;
import org.springframework.context.annotation.Configuration;

@EnableJmixDataRepositories
@Configuration
public class OnboardingConfiguration {
}

Настройка безопасности эндпойнтов универсального REST

В связи с улучшением конфигурации безопасности эндпойнтов (см. выше), для настройки защиты эндпойнтов универсального REST API необходимо задать следующее свойство приложения:

jmix.resource-server.authenticated-url-patterns = /rest/**

Процедура миграции в Studio автоматически добавляет это свойство в application.properties.

Ошибка "Unauthorized" эндпойнтов универсального REST

Ранее универсальный REST API возвращал код HTTP 500, если запрос к защищенному эндпойнту выполнялся без заголовка Authorization. Теперь правильно возвращается HTTP 401.

Стили ListMenu

Стили компонента listMenu были изменены, чтобы исправить проблему с обрамлением при фокусировке:

  • Изменены отступы и поля для самого ListMenu.

  • Увеличен margin-inline-start для списка подменю.

  • Изменены отступы для MenuBarItem.

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

См. #3589 для получения дополнительной информации.

Параметры даты в диалоге ввода

Методы dateTimeParameter(), dateParameter() и timeParameter() конструктора диалога ввода были исправлены: теперь они создают параметры типа java.util.Date, java.sql.Date и java.sql.Time соответственно. Ранее они неверно создавали параметры LocalDateTime, LocalDate и LocalTime.

См. #3499 для получения дополнительной информации.

Процедура миграции в Studio автоматически заменяет вызовы этих методов на вызовы localDateTimeParameter(), localDateParameter() и localTimeParameter(), чтобы сохранить совместимость с возвращаемыми значениями.

Зависимость на дополнение Grid Export Actions

Ранее дополнение Data Tools содержало транзитивную зависимость от дополнения Grid Export Actions. Эта зависимость была удалена, поэтому теперь действия экспорта могут использоваться только в том случае, если дополнение Grid Export Actions включено явно.

Процедура миграции в Studio автоматически добавляет дополнение Grid Export Actions в проект, если он включает дополнение Data Tools.

Генерация файлов changelog для MariaDB

Spring Boot 3.3 привносит зависимость от Liquibase 4.27, в котором изменился тип столбца для атрибутов UUID с char(36) на uuid. Это изменение несовместимо с текущей поддержкой баз данных MySQL/MariaDB в Jmix и вызывает некорректное преобразование значений UUID.

Если вы используете MariaDB, понизьте версию Liquibase в вашем проекте, добавив следующую зависимость в build.gradle:

implementation 'org.liquibase:liquibase-core:4.25.0!!'

См. #3888 для получения дополнительной информации.

Список изменений