From fc011f6a8a08064f48fd5f4280f1d4d3647ab7f1 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 14 Dec 2016 13:50:06 +0200 Subject: [PATCH] Provide configuration for events order in month and week views --- .../com/vaadin/v7/client/ui/VCalendar.java | 227 ++++++++++++++---- .../client/ui/calendar/CalendarConnector.java | 29 +++ .../client/ui/calendar/schedule/DateCell.java | 3 +- .../main/java/com/vaadin/v7/ui/Calendar.java | 31 +++ .../v7/shared/ui/calendar/CalendarState.java | 26 ++ .../calendar/CalendarEventsSort.java | 223 +++++++++++++++++ .../calendar/CalendarEventsSortTest.java | 183 ++++++++++++++ 7 files changed, 672 insertions(+), 50 deletions(-) create mode 100644 uitest/src/main/java/com/vaadin/v7/tests/components/calendar/CalendarEventsSort.java create mode 100644 uitest/src/test/java/com/vaadin/v7/tests/components/calendar/CalendarEventsSortTest.java diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VCalendar.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VCalendar.java index 9130a3faec..57bde573c6 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VCalendar.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/VCalendar.java @@ -41,6 +41,7 @@ import com.vaadin.v7.client.ui.calendar.schedule.SimpleWeekToolbar; import com.vaadin.v7.client.ui.calendar.schedule.WeekGrid; import com.vaadin.v7.client.ui.calendar.schedule.WeeklyLongEvents; import com.vaadin.v7.client.ui.calendar.schedule.dd.CalendarDropHandler; +import com.vaadin.v7.shared.ui.calendar.CalendarState.EventSortOrder; import com.vaadin.v7.shared.ui.calendar.DateConstants; /** @@ -98,6 +99,11 @@ public class VCalendar extends Composite implements VHasDropHandler { private int firstHour; private int lastHour; + private EventSortOrder eventSortOrder = EventSortOrder.DURATION_DESC; + + private static EventDurationComparator DEFAULT_COMPARATOR = new EventDurationComparator( + false); + private CalendarDropHandler dropHandler; /** @@ -241,6 +247,106 @@ public class VCalendar extends Composite implements VHasDropHandler { void contextMenu(ContextMenuEvent event, Widget widget); } + private static abstract class AbstractEventComparator + implements Comparator { + + @Override + public int compare(CalendarEvent e1, CalendarEvent e2) { + if (e1.isAllDay() != e2.isAllDay()) { + if (e2.isAllDay()) { + return 1; + } + return -1; + } + int result = doCompare(e1, e2); + if (result == 0) { + return indexCompare(e1, e2); + } + return result; + } + + protected int indexCompare(CalendarEvent e1, CalendarEvent e2) { + return ((Integer) e2.getIndex()).compareTo(e1.getIndex()); + } + + protected abstract int doCompare(CalendarEvent o1, CalendarEvent o2); + } + + private static class EventDurationComparator + extends AbstractEventComparator { + + EventDurationComparator(boolean ascending) { + isAscending = ascending; + } + + @Override + public int doCompare(CalendarEvent e1, CalendarEvent e2) { + int result = durationCompare(e1, e2, isAscending); + if (result == 0) { + return StartDateComparator.startDateCompare(e1, e2, + isAscending); + } + return result; + } + + static int durationCompare(CalendarEvent e1, CalendarEvent e2, + boolean ascending) { + int result = doDurationCompare(e1, e2); + return ascending ? -result : result; + } + + private static int doDurationCompare(CalendarEvent e1, + CalendarEvent e2) { + Long d1 = e1.getRangeInMilliseconds(); + Long d2 = e2.getRangeInMilliseconds(); + if (!d1.equals(0L) && !d2.equals(0L)) { + return d2.compareTo(d1); + } + + if (d2.equals(0L) && d1.equals(0L)) { + return 0; + } else if (d2.equals(0L) && d1 >= DateConstants.DAYINMILLIS) { + return -1; + } else if (d2.equals(0L) && d1 < DateConstants.DAYINMILLIS) { + return 1; + } else if (d1.equals(0L) && d2 >= DateConstants.DAYINMILLIS) { + return 1; + } else if (d1.equals(0L) && d2 < DateConstants.DAYINMILLIS) { + return -1; + } + return d2.compareTo(d1); + } + + private boolean isAscending; + + } + + private static class StartDateComparator extends AbstractEventComparator { + + StartDateComparator(boolean ascending) { + isAscending = ascending; + } + + @Override + public int doCompare(CalendarEvent e1, CalendarEvent e2) { + int result = startDateCompare(e1, e2, isAscending); + if (result == 0) { + // show a longer event after a shorter event + return EventDurationComparator.durationCompare(e1, e2, + isAscending); + } + return result; + } + + static int startDateCompare(CalendarEvent e1, CalendarEvent e2, + boolean ascending) { + int result = e1.getStartTime().compareTo(e2.getStartTime()); + return ascending ? -result : result; + } + + private boolean isAscending; + } + /** * Default constructor */ @@ -262,15 +368,15 @@ public class VCalendar extends Composite implements VHasDropHandler { e.onselectstart = function() { return false; } - + e.ondragstart = function() { return false; } }-*/; private void updateEventsToWeekGrid(CalendarEvent[] events) { - List allDayLong = new ArrayList(); - List belowDayLong = new ArrayList(); + List allDayLong = new ArrayList<>(); + List belowDayLong = new ArrayList<>(); for (CalendarEvent e : events) { if (e.isAllDay()) { @@ -302,7 +408,7 @@ public class VCalendar extends Composite implements VHasDropHandler { */ public void updateEventsToMonthGrid(Collection events, boolean drawImmediately) { - for (CalendarEvent e : sortEventsByDuration(events)) { + for (CalendarEvent e : sortEvents(events)) { // FIXME Why is drawImmediately not used ????? addEventToMonthGrid(e, false); } @@ -315,8 +421,8 @@ public class VCalendar extends Composite implements VHasDropHandler { boolean eventAdded = false; boolean inProgress = false; // Event adding has started boolean eventMoving = false; - List dayCells = new ArrayList(); - List timeCells = new ArrayList(); + List dayCells = new ArrayList<>(); + List timeCells = new ArrayList<>(); for (int row = 0; row < monthGrid.getRowCount(); row++) { if (eventAdded) { break; @@ -462,13 +568,45 @@ public class VCalendar extends Composite implements VHasDropHandler { addEventToMonthGrid(changedEvent, true); } + /** + * Sort the events by current sort order + * + * @param events + * The events to sort + * @return An array where the events has been sorted + */ + public CalendarEvent[] sortEvents(Collection events) { + if (EventSortOrder.DURATION_DESC.equals(eventSortOrder)) { + return sortEventsByDuration(events); + } else if (!EventSortOrder.UNSORTED.equals(eventSortOrder)) { + CalendarEvent[] sorted = events + .toArray(new CalendarEvent[events.size()]); + switch (eventSortOrder) { + case DURATION_ASC: + Arrays.sort(sorted, new EventDurationComparator(true)); + break; + case START_DATE_ASC: + Arrays.sort(sorted, new StartDateComparator(true)); + break; + case START_DATE_DESC: + Arrays.sort(sorted, new StartDateComparator(false)); + break; + } + return sorted; + } + return events.toArray(new CalendarEvent[events.size()]); + } + /** * Sort the event by how long they are - * + * * @param events * The events to sort * @return An array where the events has been sorted + * @deprecated use {@link #sortEvents(Collection)} method which shorts + * events by current sort order. */ + @Deprecated public CalendarEvent[] sortEventsByDuration( Collection events) { CalendarEvent[] sorted = events @@ -828,49 +966,18 @@ public class VCalendar extends Composite implements VHasDropHandler { } /** - * Returns a comparator which can compare calendar events. - * + * Returns the default comparator which can compare calendar events by + * duration. + * + * @deprecated this returns just one default comparator, but there are + * number of comparators that are used to sort events depending + * on order. + * * @return */ + @Deprecated public static Comparator getEventComparator() { - return new Comparator() { - - @Override - public int compare(CalendarEvent o1, CalendarEvent o2) { - if (o1.isAllDay() != o2.isAllDay()) { - if (o2.isAllDay()) { - return 1; - } - return -1; - } - - Long d1 = o1.getRangeInMilliseconds(); - Long d2 = o2.getRangeInMilliseconds(); - int r = 0; - if (!d1.equals(0L) && !d2.equals(0L)) { - r = d2.compareTo(d1); - return (r == 0) - ? ((Integer) o2.getIndex()).compareTo(o1.getIndex()) - : r; - } - - if (d2.equals(0L) && d1.equals(0L)) { - return ((Integer) o2.getIndex()).compareTo(o1.getIndex()); - } else if (d2.equals(0L) && d1 >= DateConstants.DAYINMILLIS) { - return -1; - } else if (d2.equals(0L) && d1 < DateConstants.DAYINMILLIS) { - return 1; - } else if (d1.equals(0L) && d2 >= DateConstants.DAYINMILLIS) { - return 1; - } else if (d1.equals(0L) && d2 < DateConstants.DAYINMILLIS) { - return -1; - } - r = d2.compareTo(d1); - return (r == 0) - ? ((Integer) o2.getIndex()).compareTo(o1.getIndex()) - : r; - } - }; + return DEFAULT_COMPARATOR; } /** @@ -1086,7 +1193,7 @@ public class VCalendar extends Composite implements VHasDropHandler { weekGrid = new WeekGrid(this, is24HFormat()); } updateWeekGrid(daysInMonth, days, today, realDayNames); - updateEventsToWeekGrid(sortEventsByDuration(events)); + updateEventsToWeekGrid(sortEvents(events)); outer.add(dayToolbar, DockPanel.NORTH); outer.add(weeklyLongEvents, DockPanel.NORTH); outer.add(weekGrid, DockPanel.SOUTH); @@ -1501,4 +1608,28 @@ public class VCalendar extends Composite implements VHasDropHandler { public boolean isEventCaptionAsHtml() { return eventCaptionAsHtml; } + + /** + * Set sort strategy for events. + * + * @param order + * sort order + */ + public void setSortOrder(EventSortOrder order) { + if (order == null) { + eventSortOrder = EventSortOrder.DURATION_DESC; + } else { + eventSortOrder = order; + } + } + + /** + * Return currently active sort order. + * + * @return current sort order + */ + public EventSortOrder getSortOrder() { + return eventSortOrder; + } + } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/calendar/CalendarConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/calendar/CalendarConnector.java index 0e50bd639d..456c9f392b 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/calendar/CalendarConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/calendar/CalendarConnector.java @@ -44,6 +44,7 @@ import com.vaadin.client.ui.ActionOwner; import com.vaadin.client.ui.SimpleManagedLayout; import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.Connect.LoadStyle; +import com.vaadin.shared.util.SharedUtil; import com.vaadin.v7.client.ui.AbstractLegacyComponentConnector; import com.vaadin.v7.client.ui.VCalendar; import com.vaadin.v7.client.ui.VCalendar.BackwardListener; @@ -71,6 +72,7 @@ import com.vaadin.v7.shared.ui.calendar.CalendarClientRpc; import com.vaadin.v7.shared.ui.calendar.CalendarEventId; import com.vaadin.v7.shared.ui.calendar.CalendarServerRpc; import com.vaadin.v7.shared.ui.calendar.CalendarState; +import com.vaadin.v7.shared.ui.calendar.CalendarState.EventSortOrder; import com.vaadin.v7.shared.ui.calendar.DateConstants; import com.vaadin.v7.ui.Calendar; @@ -352,6 +354,12 @@ public class CalendarConnector extends AbstractLegacyComponentConnector widget.setEventCaptionAsHtml(state.eventCaptionAsHtml); + EventSortOrder oldOrder = getWidget().getSortOrder(); + if (!SharedUtil.equals(oldOrder, getState().eventSortOrder)) { + getWidget().setSortOrder(getState().eventSortOrder); + } + updateEventsInView(); + List days = state.days; List events = state.events; @@ -449,6 +457,27 @@ public class CalendarConnector extends AbstractLegacyComponentConnector return true; } + private void updateEventsInView() { + CalendarState state = getState(); + List days = state.days; + List events = state.events; + + CalendarDropHandler dropHandler = getWidget().getDropHandler(); + if (showingMonthView()) { + updateMonthView(days, events); + if (dropHandler != null + && !(dropHandler instanceof CalendarMonthDropHandler)) { + getWidget().setDropHandler(new CalendarMonthDropHandler(this)); + } + } else { + updateWeekView(days, events); + if (dropHandler != null + && !(dropHandler instanceof CalendarWeekDropHandler)) { + getWidget().setDropHandler(new CalendarWeekDropHandler(this)); + } + } + } + private void updateMonthView(List days, List events) { CalendarState state = getState(); diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/calendar/schedule/DateCell.java b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/calendar/schedule/DateCell.java index 31f443cd77..d914de8ff5 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/ui/calendar/schedule/DateCell.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/ui/calendar/schedule/DateCell.java @@ -546,8 +546,7 @@ public class DateCell extends FocusableComplexPanel implements MouseDownHandler, events.add(dayEvent.getCalendarEvent()); index = 0; - for (CalendarEvent e : weekgrid.getCalendar() - .sortEventsByDuration(events)) { + for (CalendarEvent e : weekgrid.getCalendar().sortEvents(events)) { if (e.equals(dayEvent.getCalendarEvent())) { break; } diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/Calendar.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/Calendar.java index a33cce6eef..d347028895 100644 --- a/compatibility-server/src/main/java/com/vaadin/v7/ui/Calendar.java +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/Calendar.java @@ -57,6 +57,7 @@ import com.vaadin.v7.data.util.BeanItemContainer; import com.vaadin.v7.shared.ui.calendar.CalendarEventId; import com.vaadin.v7.shared.ui.calendar.CalendarServerRpc; import com.vaadin.v7.shared.ui.calendar.CalendarState; +import com.vaadin.v7.shared.ui.calendar.CalendarState.EventSortOrder; import com.vaadin.v7.shared.ui.calendar.DateConstants; import com.vaadin.v7.ui.components.calendar.CalendarComponentEvent; import com.vaadin.v7.ui.components.calendar.CalendarComponentEvents; @@ -999,6 +1000,36 @@ public class Calendar extends AbstractLegacyComponent } } + /** + * Sets sort order for events. By default sort order is + * {@link EventSortOrder#DURATION_DESC}. + * + * @param order + * sort strategy for events + */ + public void setEventSortOrder(EventSortOrder order) { + if (order == null) { + getState().eventSortOrder = EventSortOrder.DURATION_DESC; + } else { + getState().eventSortOrder = EventSortOrder.values()[order + .ordinal()]; + } + } + + /** + * Returns sort order for events. + * + * @return currently active sort strategy + */ + public EventSortOrder getEventSortOrder() { + EventSortOrder order = getState(false).eventSortOrder; + if (order == null) { + return EventSortOrder.DURATION_DESC; + } else { + return order; + } + } + private DateFormat getWeeklyCaptionFormatter() { if (weeklyCaptionFormat != null) { return new SimpleDateFormat(weeklyCaptionFormat, getLocale()); diff --git a/compatibility-shared/src/main/java/com/vaadin/v7/shared/ui/calendar/CalendarState.java b/compatibility-shared/src/main/java/com/vaadin/v7/shared/ui/calendar/CalendarState.java index dd15c09b7f..646c7eed44 100644 --- a/compatibility-shared/src/main/java/com/vaadin/v7/shared/ui/calendar/CalendarState.java +++ b/compatibility-shared/src/main/java/com/vaadin/v7/shared/ui/calendar/CalendarState.java @@ -40,6 +40,32 @@ public class CalendarState extends AbstractLegacyComponentState { public List actions; public boolean eventCaptionAsHtml; + public EventSortOrder eventSortOrder = EventSortOrder.DURATION_DESC; + + /** + * Defines sort strategy for events in calendar month view and week view. In + * month view events will be sorted from top to bottom using the order in + * day cell. In week view events inside same day will be sorted from left to + * right using the order if their intervals are overlapping. + *

+ *

    + *
  • {@code UNSORTED} means no sort. Events will be in the order provided + * by com.vaadin.ui.components.calendar.event.CalendarEventProvider. + *
  • {@code START_DATE_DESC} means descending sort by events start date + * (earlier event are shown first). + *
  • {@code DURATION_DESC} means descending sort by duration (longer event + * are shown first). + *
  • {@code START_DATE_ASC} means ascending sort by events start date + * (later event are shown first). + *
  • {@code DURATION_ASC} means ascending sort by duration (shorter event + * are shown first). + * + *
+ */ + public enum EventSortOrder { + UNSORTED, START_DATE_DESC, START_DATE_ASC, DURATION_DESC, DURATION_ASC; + } + public static class Day implements java.io.Serializable { public String date; public String localizedDateFormat; diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/calendar/CalendarEventsSort.java b/uitest/src/main/java/com/vaadin/v7/tests/components/calendar/CalendarEventsSort.java new file mode 100644 index 0000000000..4236aad2c9 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/calendar/CalendarEventsSort.java @@ -0,0 +1,223 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.v7.tests.components.calendar; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.v7.shared.ui.calendar.CalendarState.EventSortOrder; +import com.vaadin.v7.ui.Calendar; +import com.vaadin.v7.ui.components.calendar.event.BasicEvent; +import com.vaadin.v7.ui.components.calendar.event.CalendarEvent; +import com.vaadin.v7.ui.components.calendar.event.CalendarEventProvider; + +/** + * + * Test UI for event sorting in calendar month and week views. + * + * @author Vaadin Ltd + */ +public class CalendarEventsSort extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + getContent().setSizeFull(); + final Calendar calendar = new Calendar("Test calendar"); + + toMonthView(calendar); + calendar.setEventSortOrder(EventSortOrder.UNSORTED); + + calendar.setEventProvider(createEventProvider()); + addComponent(calendar); + + createSortByDateButton(calendar); + createSortByDurationButton(calendar); + createSortByProviderButton(calendar); + createViewSwitchButton(calendar); + } + + private void createViewSwitchButton(final Calendar calendar) { + Button toWeek = new Button("Switch to week view", new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + Button button = event.getButton(); + Boolean month = (Boolean) button.getData(); + button.setData(!month); + if (month) { + button.setCaption("Switch to month view"); + toWeekView(calendar); + } else { + button.setCaption("Switch to week view"); + toMonthView(calendar); + } + } + + }); + toWeek.addStyleName("view"); + toWeek.setData(true); + addComponent(toWeek); + } + + private Button createSortByProviderButton(final Calendar calendar) { + Button byProvider = new Button("Sort by provider", new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + calendar.setEventSortOrder(EventSortOrder.UNSORTED); + } + }); + byProvider.addStyleName("by-provider"); + addComponent(byProvider); + return byProvider; + } + + private void createSortByDurationButton(final Calendar calendar) { + Button byDuration = new Button("Sort by duration DESC", + new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + Button button = event.getButton(); + EventSortOrder order = (EventSortOrder) button + .getData(); + if (EventSortOrder.DURATION_DESC.equals(order)) { + order = EventSortOrder.DURATION_ASC; + button.setCaption("Sort by duration DESC"); + addSortOrder(true, button); + } else { + order = EventSortOrder.DURATION_DESC; + button.setCaption("Sort by duration ASC"); + addSortOrder(false, button); + } + button.setData(order); + calendar.setEventSortOrder(order); + } + }); + byDuration.addStyleName("by-duration"); + byDuration.setData(EventSortOrder.DURATION_ASC); + addComponent(byDuration); + } + + private void createSortByDateButton(final Calendar calendar) { + Button byStartDate = new Button("Sort by start date DESC", + new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + Button button = event.getButton(); + EventSortOrder order = (EventSortOrder) button + .getData(); + if (EventSortOrder.START_DATE_DESC.equals(order)) { + order = EventSortOrder.START_DATE_ASC; + button.setCaption("Sort by start date DESC"); + addSortOrder(true, button); + } else { + order = EventSortOrder.START_DATE_DESC; + button.setCaption("Sort by start date ASC"); + addSortOrder(false, button); + } + button.setData(order); + calendar.setEventSortOrder(order); + } + }); + byStartDate.setData(EventSortOrder.START_DATE_ASC); + byStartDate.addStyleName("by-start-date"); + addComponent(byStartDate); + } + + private CalendarEventProvider createEventProvider() { + CalendarEventProvider provider = new CalendarEventProvider() { + + @Override + public List getEvents(Date startDate, Date endDate) { + java.util.Calendar cal = java.util.Calendar.getInstance(); + cal.set(java.util.Calendar.HOUR_OF_DAY, 5); + cal.set(java.util.Calendar.MINUTE, 0); + cal.set(java.util.Calendar.SECOND, 0); + cal.set(java.util.Calendar.MILLISECOND, 0); + + Date start = cal.getTime(); + cal.add(java.util.Calendar.HOUR_OF_DAY, 2); + Date end = cal.getTime(); + + CalendarEvent event1 = new BasicEvent("first", "descr1", start, + end); + + cal.set(java.util.Calendar.HOUR_OF_DAY, 2); + start = cal.getTime(); + cal.add(java.util.Calendar.HOUR_OF_DAY, 4); + end = cal.getTime(); + + CalendarEvent event2 = new BasicEvent("second", "descr2", start, + end); + + cal.set(java.util.Calendar.HOUR_OF_DAY, 1); + start = cal.getTime(); + cal.add(java.util.Calendar.HOUR_OF_DAY, 2); + end = cal.getTime(); + + CalendarEvent event3 = new BasicEvent("third", "descr2", start, + end); + + return Arrays.asList(event1, event2, event3); + } + + }; + return provider; + } + + private void addSortOrder(boolean ascending, Button button) { + if (ascending) { + button.addStyleName("asc"); + button.removeStyleName("desc"); + } else { + button.removeStyleName("asc"); + button.addStyleName("desc"); + } + } + + private void toMonthView(final Calendar calendar) { + final java.util.Calendar cal = java.util.Calendar.getInstance(); + + cal.add(java.util.Calendar.DAY_OF_YEAR, -2); + calendar.setStartDate(cal.getTime()); + cal.add(java.util.Calendar.DAY_OF_YEAR, 14); + calendar.setEndDate(cal.getTime()); + } + + private void toWeekView(final Calendar calendar) { + java.util.Calendar cal = java.util.Calendar.getInstance(); + cal.add(java.util.Calendar.DAY_OF_YEAR, 2); + calendar.setEndDate(cal.getTime()); + } + + @Override + public String getDescription() { + return "Make event sorting strategy customizable."; + } + + @Override + protected Integer getTicketNumber() { + return 14849; + } +} \ No newline at end of file diff --git a/uitest/src/test/java/com/vaadin/v7/tests/components/calendar/CalendarEventsSortTest.java b/uitest/src/test/java/com/vaadin/v7/tests/components/calendar/CalendarEventsSortTest.java new file mode 100644 index 0000000000..27cf549a4f --- /dev/null +++ b/uitest/src/test/java/com/vaadin/v7/tests/components/calendar/CalendarEventsSortTest.java @@ -0,0 +1,183 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.v7.tests.components.calendar; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Check how event sorting works in calendar month and week views. + * + * @author Vaadin Ltd + */ +public class CalendarEventsSortTest extends MultiBrowserTest { + + @Test + public void testByDuration() { + openTestURL(); + + checkSortByDuration(true); + } + + @Test + public void testByStartDate() { + openTestURL(); + + checkSortByStartDate(true); + } + + @Test + public void testByProvider() { + openTestURL(); + + List events = findElements( + By.className("v-calendar-event-month")); + checkProviderOrder(events); + } + + @Test + public void testWeekByDuration() { + openTestURL(); + + findElement(By.className("view")).click(); + + checkSortByDuration(false); + } + + @Test + public void testWeekByStartDate() { + openTestURL(); + + findElement(By.className("view")).click(); + + checkSortByStartDate(false); + } + + @Test + public void testWeekByProvider() { + openTestURL(); + + findElement(By.className("view")).click(); + + List events = findElements( + By.className("v-calendar-event-caption")); + checkProviderOrder(events); + } + + private void checkSortByStartDate(boolean month) { + sort("by-start-date", false); + + String style = month ? "v-calendar-event-month" + : "v-calendar-event-caption"; + List events = findElements(By.className(style)); + checkStartDateOrderDesc(events); + + sort("by-start-date", true); + + events = findElements(By.className(style)); + checkStartDateOrderAsc(events); + } + + private void sort(String style, boolean ascending) { + findElement(By.className(style)).click(); + + if (!isElementPresent( + By.cssSelector('.' + style + (ascending ? ".asc" : ".desc")))) { + findElement(By.className(style)).click(); + } + } + + private void checkSortByDuration(boolean month) { + sort("by-duration", false); + + String style = month ? "v-calendar-event-month" + : "v-calendar-event-caption"; + + List events = findElements(By.className(style)); + checkDurationOrderDesc(events); + + sort("by-duration", true); + events = findElements(By.className(style)); + checkDurationOrderAsc(events); + } + + private void checkDurationOrderDesc(List events) { + Assert.assertTrue( + "'Second' event should be the first when sorted by duration", + events.get(0).getText().endsWith("second")); + Assert.assertTrue( + "'Third' event should be the second when sorted by duration", + events.get(1).getText().endsWith("third")); + Assert.assertTrue( + "'First' event should be the third when sorted by duration", + events.get(2).getText().endsWith("first")); + } + + private void checkDurationOrderAsc(List events) { + Assert.assertTrue( + "'First' event should be the first when sorted by duration", + events.get(0).getText().endsWith("first")); + Assert.assertTrue( + "'Third' event should be the second when sorted by duration", + events.get(1).getText().endsWith("third")); + Assert.assertTrue( + "'Second' event should be the third when sorted by duration", + events.get(2).getText().endsWith("second")); + } + + private void checkStartDateOrderDesc(List events) { + Assert.assertTrue( + "'Third' event should be the first when sorted by start date", + events.get(0).getText().endsWith("third")); + Assert.assertTrue( + "'Second' event should be the second when sorted by start date", + events.get(1).getText().endsWith("second")); + Assert.assertTrue( + "'First' event should be the third when sorted by start date", + events.get(2).getText().endsWith("first")); + } + + private void checkStartDateOrderAsc(List events) { + Assert.assertTrue( + "'First' event should be the first when sorted by start date", + events.get(0).getText().endsWith("first")); + Assert.assertTrue( + "'Second' event should be the second when sorted by start date", + events.get(1).getText().endsWith("second")); + Assert.assertTrue( + "'Third' event should be the third when sorted by start date", + events.get(2).getText().endsWith("third")); + } + + private void checkProviderOrder(List events) { + Assert.assertTrue( + "'First' event should be the first when sorted by provider", + events.get(0).getText().endsWith("first")); + Assert.assertTrue( + "'Second' event should be the second when sorted by provider", + events.get(1).getText().endsWith("second")); + Assert.assertTrue( + "'Third' event should be the third when sorted by provider", + events.get(2).getText().endsWith("third")); + } + +} -- 2.39.5