1. Привязка календаря к данным
В этом разделе вы создадите:
-
Сущность JPA
Meeting. -
Компонент
FullCalendarс поставщиком данных.
Событие встречи
Сущность Meeting будет представлять событие в компоненте FullCalendar. Для корректного отображения требуются определенные свойства:
-
name- название события. -
startDate- дата и время начала события. Компонент не будет отображать события безstartDate. -
endDate- дата окончания события. ЕслиendDateне указано, компонент применит продолжительность по умолчанию на основе свойстваallDay. В этом руководстве свойствоallDayне используется; следовательно, события рассматриваются как события, не охватывающие весь день.
Создание сущности Meeting
Подробные инструкции по созданию сущностей JPA смотрите в разделе Простой CRUD самоучителя.
Сущность Meeting имеет следующие атрибуты:
-
nameтипаStringtype. Установите флажок Mandatory. -
startDateтипаLocalDateTime. Установите флажок Mandatory. -
endDateтипаLocalDateTime. -
user- тип атрибутаAssociation, сущностьUserв качестве типа Java и кардинальность many-to-one (многие-к-одному). Установите флажок Mandatory.
Сущность Meeting не требует стандартных экранов списка и деталей, поскольку она будет генерироваться программно и отображаться в компоненте FullCalendar.
Генерация Meeting
После того как пользователь завершит все этапы онбординга, приложение сгенерирует событие встречи для обсуждения выполненных задач. Это событие будет отображаться в экране Мой календарь пользователя.
Наилучший момент для проверки того, завершил ли пользователь все этапы, - это событие PreSaveEvent контекста данных (DataContext). Слушатель этого события проверяет наличие незавершенных этапов адаптации. Если незавершенных этапов нет, создается новое событие встречи.
@Subscribe(target = Target.DATA_CONTEXT)
public void onPreSave(final DataContext.PreSaveEvent event) {
List<UserStep> userSteps = userStepsDc.getItems().stream()
.filter(us -> us.getCompletedDate() == null)
.toList();
if (userSteps.isEmpty()) {
generateOnboardingResultsMeeting();
}
}
Далее мы реализуем метод generateOnboardingResultsMeeting(). Этот метод создает экземпляр события Meeting, запланированного на следующий рабочий день.
protected void generateOnboardingResultsMeeting() {
Meeting meeting = dataContext.create(Meeting.class); (1)
meeting.setName("Results meeting");
meeting.setUser((User) currentAuthentication.getUser());
int inDays = LocalDate.now().getDayOfWeek() == DayOfWeek.FRIDAY ? 3 : 1; (2)
LocalDateTime start = LocalDateTime.of( (3)
LocalDate.now().plusDays(inDays),
LocalTime.of(9, 30));
meeting.setStartDate(start);
meeting.setEndDate(start.plusMinutes(30));
}
| 1 | Создает и добавляет новый экземпляр Meeting в DataContext, автоматически сохраняя сущность. |
| 2 | Вычисляет следующий рабочий день; если сегодня пятница, встреча планируется на понедельник. |
| 3 | Устанавливает дату и время начала встречи на 9:30 утра следующего рабочего дня. |
Добавление компонентов в MyCalendar
Сначала создайте новый пустой экран с именем MyCalendar.
Studio сгенерирует и отобразит пустой экран в дизайнере.
Загрузка данных
Перед добавлением компонента FullCalendar создайте контейнер коллекций для сущности Meeting.
В панели действий нажмите кнопку Add Component, перейдите в раздел Data components и дважды щелкните Collection container. В появившемся диалоговом окне выберите Meeting в поле Entity и нажмите OK.
<collection id="meetingsDc" class="com.company.onboarding.entity.Meeting">
<loader id="meetingsDl" readOnly="true">
<query>
<![CDATA[select e from Meeting e]]>
</query>
</loader>
<fetchPlan extends="_base"/>
</collection>
Текущая конфигурация загрузчика данных извлекает все события от всех пользователей. Однако пользователи должны видеть только свои собственные события. Для реализации этой фильтрации необходимо изменить запрос JPQL - либо с помощью редактора, либо вручную - добавив условие, которое ограничивает результаты текущим пользователем, который вошел в систему:
<query>
<![CDATA[select e from Meeting e where e.user = :user]]>
</query>
Мы получаем данные о текущем авторизованном пользователе из бина CurrentAuthentication и передаем эту информацию загрузчику данных в обработчике события BeforeShowEvent:
-
Подпишитесь на событие
BeforeShowEvent. -
Инжектируйте загрузчик
meetingsDl. -
Инжектируйте бин
CurrentAuthentication.
Теперь мы можем установить параметр для загрузчика, чтобы он извлекал события для текущего пользователя:
@ViewComponent
private CollectionLoader<Meeting> meetingsDl;
@Autowired
private CurrentAuthentication currentAuthentication;
@Subscribe
public void onBeforeShow(final BeforeShowEvent event) {
final User user = (User) currentAuthentication.getUser();
meetingsDl.setParameter("user", user);
meetingsDl.load();
}
Добавление компонента FullCalendar
В панели действий нажмите Add Component, найдите элемент FullCalendar и дважды щелкните по нему.
После этого будет создан новый элемент calendar. Настройте атрибуты id, height и width, как показано ниже.
<calendar:calendar id="calendar"
height="100%"
width="100%"/>
Добавление поставщика данных
Поставщик данных является источником событий, отображаемых в FullCalendar. Существуют различные типы поставщиков данных, но мы будем использовать поставщик данных на основе контейнера данных.
Чтобы добавить ContainerDataProvider в компонент FullCalendar:
-
Выберите компонент
calendarв панели структуры Jmix UI или в XML-дескрипторе экрана. -
Нажмите кнопку Add на панели инспектора.
-
В выпадающем меню выберите Data Providers → ContainerDataProvider.
В появившемся диалоговом окне выберите meetingsDc.
Элемент containerDataProvider позволяет настроить сопоставление свойств сущности. Сущность Meeting содержит следующие свойства:
-
name -
startDate -
endDate
Поэтому следует указать следующие атрибуты:
<calendar:dataProviders>
<calendar:containerDataProvider dataContainer="meetingsDc"
title="name"
startDateTime="startDate"
endDateTime="endDate"/>
</calendar:dataProviders>
Давайте посмотрим: полное описание нашего календаря выглядит следующим образом:
<calendar:calendar id="calendar"
height="100%"
width="100%">
<calendar:dataProviders>
<calendar:containerDataProvider dataContainer="meetingsDc"
title="name"
startDateTime="startDate"
endDateTime="endDate"/>
</calendar:dataProviders>
</calendar:calendar>
Запустите приложение и войдите в систему как пользователь admin. У пользователя admin нет шагов онбординга, поэтому необходимо их сгенерировать:
-
Перейдите в экран
User.list, выбрав Users в меню приложения. -
Выберите пользователя
adminв DataGrid и нажмите кнопку Edit. Затем заполните поле Joining Date, сгенерируйте шаги онбординга и сохраните изменения. -
Перейдите в экран
MyCalendar, выбрав My Calendar в меню приложения.