Skip to content
Snippets Groups Projects
Commit 0006ba44 authored by uhensler's avatar uhensler
Browse files

OO-4630: Filter future and selected appointments

parent c77f674e
No related branches found
No related tags found
No related merge requests found
...@@ -63,11 +63,41 @@ public class DateUtils { ...@@ -63,11 +63,41 @@ public class DateUtils {
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime(); return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
} }
public static boolean isSameDate(Date date1, Date date2) {
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
return isSameDate(cal1, cal2);
}
protected static boolean isSameDate(Calendar cal1, Calendar cal2) {
return isSameDay(cal1, cal2) && isSameTime(cal1, cal2);
}
public static boolean isSameDay(Date date1, Date date2) {
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
return isSameDay(cal1, cal2);
}
public static boolean isSameDay(Calendar cal1, Calendar cal2) {
return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
}
public static boolean isSameTime(Date date1, Date date2) { public static boolean isSameTime(Date date1, Date date2) {
Calendar cal1 = Calendar.getInstance(); Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1); cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance(); Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2); cal2.setTime(date2);
return isSameTime(cal1, cal2);
}
public static boolean isSameTime(Calendar cal1, Calendar cal2) {
return (cal1.get(Calendar.SECOND) == cal2.get(Calendar.SECOND) && return (cal1.get(Calendar.SECOND) == cal2.get(Calendar.SECOND) &&
cal1.get(Calendar.MINUTE) == cal2.get(Calendar.MINUTE) && cal1.get(Calendar.MINUTE) == cal2.get(Calendar.MINUTE) &&
cal1.get(Calendar.HOUR) == cal2.get(Calendar.HOUR)); cal1.get(Calendar.HOUR) == cal2.get(Calendar.HOUR));
......
...@@ -19,15 +19,20 @@ ...@@ -19,15 +19,20 @@
*/ */
package org.olat.course.nodes.appointments.ui; package org.olat.course.nodes.appointments.ui;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.stream.Collectors;
import org.olat.core.commons.persistence.SortKey; import org.olat.core.commons.persistence.SortKey;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FilterableFlexiTableModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiSortableColumnDef; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiSortableColumnDef;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate; import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate;
import org.olat.core.util.DateUtils;
/** /**
* *
...@@ -36,9 +41,14 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFl ...@@ -36,9 +41,14 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFl
* *
*/ */
public class AppointmentDataModel extends DefaultFlexiTableDataModel<AppointmentRow> public class AppointmentDataModel extends DefaultFlexiTableDataModel<AppointmentRow>
implements SortableFlexiTableDataModel<AppointmentRow> { implements SortableFlexiTableDataModel<AppointmentRow>, FilterableFlexiTableModel {
public static final String FILTER_ALL = "all";
public static final String FILTER_PARTICIPATED = "participated";
public static final String FILTER_FUTURE = "future";
private final Locale locale; private final Locale locale;
private List<AppointmentRow> backups;
public AppointmentDataModel(FlexiTableColumnModel columnsModel, Locale locale) { public AppointmentDataModel(FlexiTableColumnModel columnsModel, Locale locale) {
super(columnsModel); super(columnsModel);
...@@ -50,6 +60,42 @@ implements SortableFlexiTableDataModel<AppointmentRow> { ...@@ -50,6 +60,42 @@ implements SortableFlexiTableDataModel<AppointmentRow> {
List<AppointmentRow> rows = new SortableFlexiTableModelDelegate<>(orderBy, this, locale).sort(); List<AppointmentRow> rows = new SortableFlexiTableModelDelegate<>(orderBy, this, locale).sort();
super.setObjects(rows); super.setObjects(rows);
} }
@Override
public void setObjects(List<AppointmentRow> objects) {
super.setObjects(objects);
backups = objects;
}
@Override
public void filter(String searchString, List<FlexiTableFilter> filters) {
if (filters == null || filters.isEmpty() || FILTER_ALL.equals(filters.get(0).getFilter())) {
super.setObjects(backups);
} else {
List<String> filterKeys = filters.stream().map(FlexiTableFilter::getFilter).collect(Collectors.toList());
Date now = new Date();
List<AppointmentRow> filteredRows = backups.stream()
.filter(r -> apply(filterKeys, r, now))
.collect(Collectors.toList());
super.setObjects(filteredRows);
}
}
private boolean apply(List<String> filterKeys, AppointmentRow row, Date date) {
if (filterKeys.contains(FILTER_PARTICIPATED) && row.getParticipation() != null) {
return true;
}
if (filterKeys.contains(FILTER_FUTURE)) {
Date end = row.getAppointment().getEnd();
end = DateUtils.isSameDate(end, row.getAppointment().getStart())
? DateUtils.setTime(end, 23, 59, 59)
: end;
if (date.before(end)) {
return true;
}
}
return false;
}
@Override @Override
public Object getValueAt(int row, int col) { public Object getValueAt(int row, int col) {
......
...@@ -24,7 +24,6 @@ import java.util.Date; ...@@ -24,7 +24,6 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import org.apache.commons.lang.time.DateUtils;
import org.olat.core.gui.UserRequest; import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component; import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.date.DateComponentFactory; import org.olat.core.gui.components.date.DateComponentFactory;
...@@ -32,6 +31,7 @@ import org.olat.core.gui.components.date.DateElement; ...@@ -32,6 +31,7 @@ import org.olat.core.gui.components.date.DateElement;
import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
import org.olat.core.gui.components.form.flexible.elements.FormLink; import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.form.flexible.impl.FormEvent;
...@@ -49,6 +49,7 @@ import org.olat.core.gui.control.WindowControl; ...@@ -49,6 +49,7 @@ import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxController;
import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
import org.olat.core.util.DateUtils;
import org.olat.core.util.StringHelper; import org.olat.core.util.StringHelper;
import org.olat.course.nodes.appointments.Appointment; import org.olat.course.nodes.appointments.Appointment;
import org.olat.course.nodes.appointments.Appointment.Status; import org.olat.course.nodes.appointments.Appointment.Status;
...@@ -115,6 +116,10 @@ public abstract class AppointmentListController extends FormBasicController impl ...@@ -115,6 +116,10 @@ public abstract class AppointmentListController extends FormBasicController impl
protected abstract String getTableCssClass(); protected abstract String getTableCssClass();
protected abstract List<String> getFilters();
protected abstract List<String> getDefaultFilters();
protected abstract String getPersistedPreferencesId(); protected abstract String getPersistedPreferencesId();
protected abstract List<AppointmentRow> loadModel(); protected abstract List<AppointmentRow> loadModel();
...@@ -210,6 +215,39 @@ public abstract class AppointmentListController extends FormBasicController impl ...@@ -210,6 +215,39 @@ public abstract class AppointmentListController extends FormBasicController impl
VelocityContainer rowVC = createVelocityContainer("appointment_row"); VelocityContainer rowVC = createVelocityContainer("appointment_row");
rowVC.setDomReplacementWrapperRequired(false); rowVC.setDomReplacementWrapperRequired(false);
tableEl.setRowRenderer(rowVC, this); tableEl.setRowRenderer(rowVC, this);
initFilters();
}
protected void initFilters() {
List<String> filters = getFilters();
if (filters != null && !filters.isEmpty()) {
List<FlexiTableFilter> tableFilters = new ArrayList<>(3);
List<String> defaultFilters = getDefaultFilters();
List<FlexiTableFilter> selectedFilters = new ArrayList<>(defaultFilters.size());
if (filters.contains(AppointmentDataModel.FILTER_PARTICIPATED)) {
FlexiTableFilter filter = new FlexiTableFilter(translate("filter.participated"), AppointmentDataModel.FILTER_PARTICIPATED, false);
tableFilters.add(filter);
if (defaultFilters.contains(AppointmentDataModel.FILTER_PARTICIPATED)) {
selectedFilters.add(filter);
}
}
if (filters.contains(AppointmentDataModel.FILTER_FUTURE)) {
FlexiTableFilter filter = new FlexiTableFilter(translate("filter.future"), AppointmentDataModel.FILTER_FUTURE, false);
tableFilters.add(filter);
if (defaultFilters.contains(AppointmentDataModel.FILTER_FUTURE)) {
selectedFilters.add(filter);
}
}
tableFilters.add(FlexiTableFilter.SPACER);
FlexiTableFilter filter = new FlexiTableFilter(translate("filter.all"), AppointmentDataModel.FILTER_ALL, true);
tableFilters.add(filter);
if (defaultFilters.contains(AppointmentDataModel.FILTER_ALL)) {
selectedFilters.add(filter);
}
tableEl.setFilters("Filters", tableFilters, true);
tableEl.setSelectedFilters(selectedFilters);
}
} }
private void updateModel() { private void updateModel() {
...@@ -229,7 +267,7 @@ public abstract class AppointmentListController extends FormBasicController impl ...@@ -229,7 +267,7 @@ public abstract class AppointmentListController extends FormBasicController impl
String time = null; String time = null;
boolean sameDay = DateUtils.isSameDay(begin, end); boolean sameDay = DateUtils.isSameDay(begin, end);
boolean sameTime = org.olat.core.util.DateUtils.isSameTime(begin, end); boolean sameTime = DateUtils.isSameTime(begin, end);
String startDate = StringHelper.formatLocaleDateFull(begin.getTime(), locale); String startDate = StringHelper.formatLocaleDateFull(begin.getTime(), locale);
String startTime = StringHelper.formatLocaleTime(begin.getTime(), locale); String startTime = StringHelper.formatLocaleTime(begin.getTime(), locale);
String endDate = StringHelper.formatLocaleDateFull(end.getTime(), locale); String endDate = StringHelper.formatLocaleDateFull(end.getTime(), locale);
......
...@@ -22,6 +22,7 @@ package org.olat.course.nodes.appointments.ui; ...@@ -22,6 +22,7 @@ package org.olat.course.nodes.appointments.ui;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -63,6 +64,16 @@ public class AppointmentListEditController extends AppointmentListController { ...@@ -63,6 +64,16 @@ public class AppointmentListEditController extends AppointmentListController {
return "o_edit"; return "o_edit";
} }
@Override
protected List<String> getFilters() {
return Collections.singletonList(AppointmentDataModel.FILTER_FUTURE);
}
@Override
protected List<String> getDefaultFilters() {
return Collections.singletonList(AppointmentDataModel.FILTER_ALL);
}
@Override @Override
protected String getPersistedPreferencesId() { protected String getPersistedPreferencesId() {
return "ap-appointment-edit"; return "ap-appointment-edit";
......
...@@ -22,6 +22,7 @@ package org.olat.course.nodes.appointments.ui; ...@@ -22,6 +22,7 @@ package org.olat.course.nodes.appointments.ui;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
...@@ -65,6 +66,16 @@ public class AppointmentListSelectionController extends AppointmentListControlle ...@@ -65,6 +66,16 @@ public class AppointmentListSelectionController extends AppointmentListControlle
return "o_selection"; return "o_selection";
} }
@Override
protected List<String> getFilters() {
return Arrays.asList(AppointmentDataModel.FILTER_PARTICIPATED, AppointmentDataModel.FILTER_FUTURE);
}
@Override
protected List<String> getDefaultFilters() {
return Arrays.asList(AppointmentDataModel.FILTER_PARTICIPATED, AppointmentDataModel.FILTER_FUTURE);
}
@Override @Override
protected String getPersistedPreferencesId() { protected String getPersistedPreferencesId() {
return "ap-appointment-selection"; return "ap-appointment-selection";
......
...@@ -66,6 +66,9 @@ error.select.appointment=Sie m\u00fcssen einen Termin ausw\u00e4hlen. ...@@ -66,6 +66,9 @@ error.select.appointment=Sie m\u00fcssen einen Termin ausw\u00e4hlen.
error.select.participant=Sie m\u00fcssen einen Teilnehmer ausw\u00e4hlen. error.select.participant=Sie m\u00fcssen einen Teilnehmer ausw\u00e4hlen.
error.start.after.end=Das Ende darf nicht vor dem Start liegen. error.start.after.end=Das Ende darf nicht vor dem Start liegen.
error.too.much.participations=Es gibt bereits {0} Teilnahmen. error.too.much.participations=Es gibt bereits {0} Teilnahmen.
filter.all=Alle anzeigen
filter.future=Zuk\u00fcnftig
filter.participated=Ausgew\u00e4hlt
full.day=Ganzer Tag full.day=Ganzer Tag
general=Konfiguration general=Konfiguration
mail.appointments.deleted.body=Liebe/r {0} <br><br>Folgende Termine wurden abgesagt.<br><br>{1} mail.appointments.deleted.body=Liebe/r {0} <br><br>Folgende Termine wurden abgesagt.<br><br>{1}
......
...@@ -65,6 +65,9 @@ error.select.appointment=You have to select an appointment. ...@@ -65,6 +65,9 @@ error.select.appointment=You have to select an appointment.
error.select.participant=You have to select a participant. error.select.participant=You have to select a participant.
error.start.after.end=The end date must not be before the start date. error.start.after.end=The end date must not be before the start date.
error.too.much.participations=There are already {0} participations. error.too.much.participations=There are already {0} participations.
filter.all=Show all
filter.future=Future
filter.participated=Selected
full.day=Full day full.day=Full day
general=Configuration general=Configuration
mail.appointments.deleted.body=Dear {0} <br><br>The following appointments were deleted.<br><br>{1} mail.appointments.deleted.body=Dear {0} <br><br>The following appointments were deleted.<br><br>{1}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment