# filter in RegattaOverview now shows last event first

# filter in RegattaOverview now shows all active races and up to 2 additional (e.g. aborted)
# unexpected results when showing different course areas / fleets
This commit is contained in:
Lukas Niemeier committed 2013-05-03 00:04:39 +08:00
1 parent 6273a3a9dd
commit 8c8cb56435
7 files changed
+170 -62

No files matched your search

@@ -554,4 +554,6 @@ public interface StringMessages extends Messages {
String distanceToStarboardEndOfStartlineWhenPassingStart();
String distanceToStarboardEndOfStartlineWhenPassingStartTooltip();
String waypoints();
String disableRaceFilter();
String enableRaceFilter();
}
@@ -557,3 +557,5 @@ noWindFixesAvailable=No Wind-Fixes available.
distanceToStarboardEndOfStartlineWhenPassingStart=Dist. Stb-Side of Line when Starting
distanceToStarboardEndOfStartlineWhenPassingStartTooltip=Distance to starboard side of start line or to the single start mark when the competitor passed the start
waypoints=Waypoints
disableRaceFilter=Disable filter
enableRaceFilter=Enable filter
@@ -553,3 +553,5 @@ noWindFixesAvailable=Kein Wind-Fixes vorhanden.
distanceToStarboardEndOfStartlineWhenPassingStart=Dist. Stb.-Seite d. Linie beim Starten
distanceToStarboardEndOfStartlineWhenPassingStartTooltip=Abstand von der Steuerbord-Seite der Startlinie bzw. Abstand zur einzelnen Starttonne als der Teilnehmer den Start passiert hat
waypoints=Wegpunkte
disableRaceFilter=Deaktiviere Filter
enableRaceFilter=Aktiviere Filter
@@ -49,6 +49,7 @@ public class RegattaOverviewPanel extends SimplePanel implements RegattaOverview
private final Label eventNameLabel;
private final Label venueNameLabel;
private final Label timeLabel;
private final Button filterButton;
private final Button refreshNowButton;
private final Button startStopUpdatingButton;
@@ -103,6 +104,16 @@ public class RegattaOverviewPanel extends SimplePanel implements RegattaOverview
grid.getColumnFormatter().getElement(1).getStyle().setPaddingTop(2.0, Unit.EM);
grid.getColumnFormatter().getElement(1).getStyle().setPaddingLeft(20.0, Unit.PX);
this.filterButton = new Button(stringMessages.disableRaceFilter());
filterButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
boolean isFilterActive = regattaOverviewTableComposite.switchFilter();
filterButton.setText(isFilterActive ?
stringMessages.disableRaceFilter() : stringMessages.enableRaceFilter());
}
});
this.refreshNowButton = new Button(stringMessages.refreshNow());
refreshNowButton.addClickHandler(new ClickHandler() {
@@ -129,6 +140,8 @@ public class RegattaOverviewPanel extends SimplePanel implements RegattaOverview
}
});
this.refreshNowButton.getElement().getStyle().setMarginLeft(20.0, Unit.PX);
this.startStopUpdatingButton.getElement().getStyle().setMarginLeft(20.0, Unit.PX);
this.serverUpdateTimer = new Timer(PlayModes.Live, serverUpdateRate);
@@ -192,6 +205,7 @@ public class RegattaOverviewPanel extends SimplePanel implements RegattaOverview
refreshStartStopClockPanel.setStyleName(STYLE_REFRESH_STOP_TIME);
refreshStartStopClockPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
refreshStartStopClockPanel.add(filterButton);
refreshStartStopClockPanel.add(refreshNowButton);
refreshStartStopClockPanel.add(startStopUpdatingButton);
refreshStartStopClockPanel.add(timeLabel);
@@ -2,6 +2,7 @@ package com.sap.sailing.gwt.ui.regattaoverview;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
@@ -34,6 +35,9 @@ import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
public class RegattaOverviewTableComposite extends Composite {
private List<RegattaOverviewEntryDTO> allEntries;
private boolean isFilterActive;
private final SelectionModel<RegattaOverviewEntryDTO> raceSelectionModel;
private final CellTable<RegattaOverviewEntryDTO> regattaOverviewTable;
private ListDataProvider<RegattaOverviewEntryDTO> regattaOverviewDataProvider;
@@ -51,13 +55,16 @@ public class RegattaOverviewTableComposite extends Composite {
private static RegattaOverviewTableResources tableRes = GWT.create(RegattaOverviewTableResources.class);
public RegattaOverviewTableComposite(final SailingServiceAsync sailingService, ErrorReporter errorReporter,
final StringMessages stringMessages, final String eventIdAsString, final RegattaOverviewRaceSelectionProvider raceSelectionProvider) {
final StringMessages stringMessages, final String eventIdAsString,
final RegattaOverviewRaceSelectionProvider raceSelectionProvider) {
this.sailingService = sailingService;
this.stringMessages = stringMessages;
this.eventIdAsString = eventIdAsString;
this.raceSelectionProvider = raceSelectionProvider;
this.flagImageResolver = new FlagImageResolver();
this.isFilterActive = true;
mainPanel = new SimplePanel();
panel = new VerticalPanel();
mainPanel.setWidget(panel);
@@ -65,7 +72,7 @@ public class RegattaOverviewTableComposite extends Composite {
regattaOverviewDataProvider = new ListDataProvider<RegattaOverviewEntryDTO>();
regattaOverviewTable = createRegattaTable();
raceSelectionModel = new SingleSelectionModel<RegattaOverviewEntryDTO>();
raceSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@@ -73,15 +80,15 @@ public class RegattaOverviewTableComposite extends Composite {
public void onSelectionChange(SelectionChangeEvent event) {
showSelectedRaces();
}
});
regattaOverviewTable.setSelectionModel(raceSelectionModel);
panel.add(regattaOverviewTable);
initWidget(mainPanel);
loadAndUpdateEventLog();
}
@@ -101,44 +108,107 @@ public class RegattaOverviewTableComposite extends Composite {
loadAndUpdateEventLog();
}
protected void loadAndUpdateEventLog() {
sailingService.getRegattaOverviewEntriesForEvent(eventIdAsString, new MarkedAsyncCallback<List<RegattaOverviewEntryDTO>>() {
public boolean switchFilter() {
this.isFilterActive = !isFilterActive;
updateTable(allEntries);
return isFilterActive;
}
private void updateTable(List<RegattaOverviewEntryDTO> newEntries) {
allEntries = newEntries;
regattaOverviewDataProvider.getList().clear();
regattaOverviewDataProvider.getList().addAll(filterAndSort(allEntries));
// now sort again according to selected criterion
ColumnSortEvent.fire(regattaOverviewTable, regattaOverviewTable.getColumnSortList());
}
private Collection<? extends RegattaOverviewEntryDTO> filterAndSort(List<RegattaOverviewEntryDTO> raceList) {
List<RegattaOverviewEntryDTO> reversedUnfilterted = new ArrayList<RegattaOverviewEntryDTO>(raceList);
Collections.sort(reversedUnfilterted, new Comparator<RegattaOverviewEntryDTO>() {
@Override
protected void handleFailure(Throwable cause) {
}
@Override
protected void handleSuccess(List<RegattaOverviewEntryDTO> result) {
regattaOverviewDataProvider.getList().clear();
regattaOverviewDataProvider.getList().addAll(filter(result));
// now sort again according to selected criterion
ColumnSortEvent.fire(regattaOverviewTable, regattaOverviewTable.getColumnSortList());
}
private Collection<? extends RegattaOverviewEntryDTO> filter(List<RegattaOverviewEntryDTO> unfilteredRaceList) {
List<RegattaOverviewEntryDTO> filterResult = new ArrayList<RegattaOverviewEntryDTO>();
for (RegattaOverviewEntryDTO entry : unfilteredRaceList) {
if (entry.raceInfo.lastStatus != RaceLogRaceStatus.UNKNOWN
&& entry.raceInfo.lastStatus != RaceLogRaceStatus.UNSCHEDULED
&& entry.raceInfo.lastStatus != RaceLogRaceStatus.FINISHED) {
filterResult.add(entry);
}
public int compare(RegattaOverviewEntryDTO left, RegattaOverviewEntryDTO right) {
int result = left.courseAreaName.compareTo(right.courseAreaName);
if (result == 0) {
if (left.regattaName != null && right.regattaName != null) {
result = left.regattaName.compareTo(right.regattaName);
}
if (result == 0) {
result = left.raceInfo.fleet.compareTo(right.raceInfo.fleet);
if (result == 0) {
result = right.raceInfo.raceName.compareTo(left.raceInfo.raceName);
}
return filterResult;
}
}
return result;
}
});
// And now we are going to filter
if (!isFilterActive) {
return reversedUnfilterted;
}
List<RegattaOverviewEntryDTO> filtered = new ArrayList<RegattaOverviewEntryDTO>();
int maxAddtionalRacesCount = 2;
for (RegattaOverviewEntryDTO entry : reversedUnfilterted) {
RaceLogRaceStatus status = entry.raceInfo.lastStatus;
if (status != null && isRaceActive(status)) {
filtered.add(entry);
continue;
}
if (maxAddtionalRacesCount == 0) {
continue;
}
if (entry.raceInfo.hasEvents) {
maxAddtionalRacesCount--;
filtered.add(entry);
}
}
// Add the "next race" to the list of races
// TODO: Should be done for each course area, for each regatta, for each fleet...
if (filtered.size() > 0 && filtered.size() != reversedUnfilterted.size()) {
RegattaOverviewEntryDTO topMostEntry = filtered.get(0);
int topMostIndex = reversedUnfilterted.indexOf(topMostEntry);
if (topMostIndex >= 1) {
filtered.add(0, reversedUnfilterted.get(topMostIndex - 1));
}
}
return filtered;
}
private boolean isRaceActive(RaceLogRaceStatus status) {
return status.equals(RaceLogRaceStatus.SCHEDULED) || status.equals(RaceLogRaceStatus.STARTPHASE)
|| status.equals(RaceLogRaceStatus.RUNNING) || status.equals(RaceLogRaceStatus.FINISHING);
}
protected void loadAndUpdateEventLog() {
sailingService.getRegattaOverviewEntriesForEvent(eventIdAsString,
new MarkedAsyncCallback<List<RegattaOverviewEntryDTO>>() {
@Override
protected void handleFailure(Throwable cause) {
}
@Override
protected void handleSuccess(List<RegattaOverviewEntryDTO> result) {
updateTable(result);
}
});
}
private CellTable<RegattaOverviewEntryDTO> createRegattaTable() {
CellTable<RegattaOverviewEntryDTO> table = new CellTable<RegattaOverviewEntryDTO>(/* pageSize */10000, tableRes);
regattaOverviewDataProvider.addDataDisplay(table);
table.setWidth("100%");
ListHandler<RegattaOverviewEntryDTO> regattaOverviewListHandler = new ListHandler<RegattaOverviewEntryDTO>(
regattaOverviewDataProvider.getList());
TextColumn<RegattaOverviewEntryDTO> courseAreaColumn = new TextColumn<RegattaOverviewEntryDTO>() {
@Override
public String getValue(RegattaOverviewEntryDTO entryDTO) {
@@ -152,9 +222,9 @@ public class RegattaOverviewTableComposite extends Composite {
public int compare(RegattaOverviewEntryDTO left, RegattaOverviewEntryDTO right) {
return left.courseAreaName.compareTo(right.courseAreaName);
}
});
TextColumn<RegattaOverviewEntryDTO> regattaNameColumn = new TextColumn<RegattaOverviewEntryDTO>() {
@Override
public String getValue(RegattaOverviewEntryDTO entryDTO) {
@@ -168,9 +238,9 @@ public class RegattaOverviewTableComposite extends Composite {
public int compare(RegattaOverviewEntryDTO left, RegattaOverviewEntryDTO right) {
return left.regattaName.compareTo(right.regattaName);
}
});
TextColumn<RegattaOverviewEntryDTO> fleetNameColumn = new TextColumn<RegattaOverviewEntryDTO>() {
@Override
public String getValue(RegattaOverviewEntryDTO entryDTO) {
@@ -184,7 +254,7 @@ public class RegattaOverviewTableComposite extends Composite {
public int compare(RegattaOverviewEntryDTO left, RegattaOverviewEntryDTO right) {
return left.raceInfo.fleet.compareTo(right.raceInfo.fleet);
}
});
TextColumn<RegattaOverviewEntryDTO> raceNameColumn = new TextColumn<RegattaOverviewEntryDTO>() {
@@ -198,9 +268,9 @@ public class RegattaOverviewTableComposite extends Composite {
@Override
public int compare(RegattaOverviewEntryDTO left, RegattaOverviewEntryDTO right) {
return left.raceInfo.raceName.compareTo(right.raceInfo.raceName);
return right.raceInfo.raceName.compareTo(left.raceInfo.raceName);
}
});
TextColumn<RegattaOverviewEntryDTO> raceStartTimeColumn = new TextColumn<RegattaOverviewEntryDTO>() {
@@ -233,9 +303,9 @@ public class RegattaOverviewTableComposite extends Composite {
}
return result;
}
});
TextColumn<RegattaOverviewEntryDTO> raceStatusColumn = new TextColumn<RegattaOverviewEntryDTO>() {
@Override
public String getValue(RegattaOverviewEntryDTO entryDTO) {
@@ -249,54 +319,62 @@ public class RegattaOverviewTableComposite extends Composite {
public int compare(RegattaOverviewEntryDTO left, RegattaOverviewEntryDTO right) {
return left.raceInfo.lastStatus.compareTo(right.raceInfo.lastStatus);
}
});
Column<RegattaOverviewEntryDTO, ImageResource> lastUpperFlagColumn = new Column<RegattaOverviewEntryDTO, ImageResource>(new ImageResourceCell()) {
Column<RegattaOverviewEntryDTO, ImageResource> lastUpperFlagColumn = new Column<RegattaOverviewEntryDTO, ImageResource>(
new ImageResourceCell()) {
@Override
public ImageResource getValue(RegattaOverviewEntryDTO entryDTO) {
return flagImageResolver.resolveFlagToImage(entryDTO.raceInfo.lastUpperFlag);
}
};
Column<RegattaOverviewEntryDTO, ImageResource> lastLowerFlagColumn = new Column<RegattaOverviewEntryDTO, ImageResource>(new ImageResourceCell()) {
Column<RegattaOverviewEntryDTO, ImageResource> lastLowerFlagColumn = new Column<RegattaOverviewEntryDTO, ImageResource>(
new ImageResourceCell()) {
@Override
public ImageResource getValue(RegattaOverviewEntryDTO entryDTO) {
return flagImageResolver.resolveFlagToImage(entryDTO.raceInfo.lastLowerFlag);
}
};
Column<RegattaOverviewEntryDTO, ImageResource> lastFlagDirectionColumn = new Column<RegattaOverviewEntryDTO, ImageResource>(new ImageResourceCell()) {
Column<RegattaOverviewEntryDTO, ImageResource> lastFlagDirectionColumn = new Column<RegattaOverviewEntryDTO, ImageResource>(
new ImageResourceCell()) {
@Override
public ImageResource getValue(RegattaOverviewEntryDTO entryDTO) {
if(entryDTO.raceInfo.lastUpperFlag != null)
if (entryDTO.raceInfo.lastUpperFlag != null)
return flagImageResolver.resolveFlagDirectionToImage(entryDTO.raceInfo.displayed);
else
return null;
}
};
TextColumn<RegattaOverviewEntryDTO> raceAddditionalInformationColumn = new TextColumn<RegattaOverviewEntryDTO>() {
@Override
public String getValue(RegattaOverviewEntryDTO entryDTO) {
StringBuffer additionalInformation = new StringBuffer();
if(entryDTO.raceInfo.pathfinderId!=null){
additionalInformation.append("Pathfinder: "+entryDTO.raceInfo.pathfinderId);
if (entryDTO.raceInfo.hasEvents && !isRaceActive(entryDTO.raceInfo.lastStatus)) {
additionalInformation.append("Race has been aborted before. ");
}
if(entryDTO.raceInfo.pathfinderId!=null && entryDTO.raceInfo.gateLineOpeningTime!=null){
if (entryDTO.raceInfo.pathfinderId != null) {
additionalInformation.append("Pathfinder: " + entryDTO.raceInfo.pathfinderId);
}
if (entryDTO.raceInfo.pathfinderId != null && entryDTO.raceInfo.gateLineOpeningTime != null) {
additionalInformation.append(" / ");
}
if(entryDTO.raceInfo.gateLineOpeningTime!=null){
additionalInformation.append("GateLineOpeningTime: "+(entryDTO.raceInfo.gateLineOpeningTime/(60*1000))+" minutes");
if (entryDTO.raceInfo.gateLineOpeningTime != null) {
additionalInformation.append("GateLineOpeningTime: "
+ (entryDTO.raceInfo.gateLineOpeningTime / (60 * 1000)) + " minutes");
}
return additionalInformation.toString();
}
};
table.addColumn(courseAreaColumn, stringMessages.courseArea());
table.addColumn(regattaNameColumn, stringMessages.boatClass()); // For sailors the boat class also contains additional infos such as woman/man, e.g. Laser Radial Woman or Laser Radial Men
table.addColumn(regattaNameColumn, stringMessages.boatClass()); // For sailors the boat class also contains
// additional infos such as woman/man, e.g.
// Laser Radial Woman or Laser Radial Men
table.addColumn(fleetNameColumn, stringMessages.fleet());
table.addColumn(raceNameColumn, stringMessages.race());
table.addColumn(raceStartTimeColumn, stringMessages.startTime());
@@ -309,21 +387,23 @@ public class RegattaOverviewTableComposite extends Composite {
return table;
}
public List<RegattaOverviewEntryDTO> getAllRaces() {
return regattaOverviewDataProvider.getList();
return allEntries;
}
private void showSelectedRaces() {
List<RegattaOverviewEntryDTO> selectedRaces = getSelectedRaces();
RegattaOverviewTableComposite.this.raceSelectionProvider.setSelection(selectedRaces);
}
private String getStatusText(RaceInfoDTO raceInfo) {
String statusText = "";
if (raceInfo.lastStatus.equals(RaceLogRaceStatus.RUNNING) && raceInfo.lastUpperFlag.equals(Flags.XRAY) && raceInfo.displayed) {
if (raceInfo.lastStatus.equals(RaceLogRaceStatus.RUNNING) && raceInfo.lastUpperFlag.equals(Flags.XRAY)
&& raceInfo.displayed) {
statusText = "Race is running (had early starters)";
} else if (raceInfo.lastStatus.equals(RaceLogRaceStatus.RUNNING) && raceInfo.lastUpperFlag.equals(Flags.XRAY) && !raceInfo.displayed) {
} else if (raceInfo.lastStatus.equals(RaceLogRaceStatus.RUNNING) && raceInfo.lastUpperFlag.equals(Flags.XRAY)
&& !raceInfo.displayed) {
statusText = "Race is running";
} else if (raceInfo.lastStatus.equals(RaceLogRaceStatus.RUNNING)) {
statusText = "Race is running";
@@ -1145,8 +1145,15 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
RaceInfoDTO raceInfoDTO = new RaceInfoDTO();
RaceLog raceLog = raceColumn.getRaceLog(fleet);
if (raceLog != null) {
PassAwareRaceLog passAwareRaceLog = PassAwareRaceLogImpl.copy(raceLog);
try {
passAwareRaceLog.lockForRead();
raceInfoDTO.hasEvents = !Util.isEmpty(passAwareRaceLog.getRawFixes());
} finally {
passAwareRaceLog.unlockAfterRead();
}
StartTimeFinder startTimeFinder = new StartTimeFinder(passAwareRaceLog);
if(startTimeFinder.getStartTime()!=null){
raceInfoDTO.startTime = startTimeFinder.getStartTime().asDate();
@@ -10,6 +10,7 @@ import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
public class RaceInfoDTO implements IsSerializable {
public String raceName;
public String fleet;
public boolean hasEvents;
public Date startTime;
public RaceLogRaceStatus lastStatus;
public Flags lastUpperFlag;