Merge remote-tracking branch 'origin' into bug2438

This commit is contained in:
Jan Broß committed 2014-11-28 13:55:23 +01:00
commit 6e71dab973
14 files changed
+1553 -893

No files matched your search

@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.ui.adminconsole;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.EventDTO;
@@ -10,9 +11,9 @@ import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
public class EventCreateDialog extends EventDialog {
public EventCreateDialog(Collection<EventDTO> existingEvents, StringMessages stringConstants, DialogCallback<EventDTO> callback) {
public EventCreateDialog(Collection<EventDTO> existingEvents, List<LeaderboardGroupDTO> availableLeaderboardGroups, StringMessages stringConstants, DialogCallback<EventDTO> callback) {
super(new EventParameterValidator(stringConstants, existingEvents), stringConstants,
/* leaderboardGroups */ Collections.<LeaderboardGroupDTO>emptyList(), callback);
availableLeaderboardGroups, /* leaderboardGroups */ Collections.<LeaderboardGroupDTO>emptyList(), callback);
nameEntryField = createTextBox(null);
nameEntryField.setVisibleLength(50);
descriptionEntryField = createTextArea(null);
@@ -0,0 +1,190 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sse.common.Util;
import com.sap.sse.gwt.client.ErrorReporter;
public class EventDetailsComposite extends Composite {
private EventDTO event;
private final StringMessages stringMessages;
private final Label eventId;
private final Label eventName;
private final Label venueName;
private final Label description;
private final Label startDate;
private final Label endDate;
private final Label isPublic;
private final Anchor officialWebsiteURL;
private final Anchor logoImageURL;
private final SimpleStringListComposite courseAreaNamesList;
private final SimpleStringListComposite imageURLList;
private final SimpleStringListComposite videoURLList;
private final SimpleStringListComposite sponsorImageURLList;
private final SimpleStringListComposite leaderboardGroupList;
private final CaptionPanel mainPanel;
public EventDetailsComposite(final SailingServiceAsync sailingService, final ErrorReporter errorReporter, final StringMessages stringMessages) {
super();
this.stringMessages = stringMessages;
event = null;
mainPanel = new CaptionPanel(stringMessages.regatta());
VerticalPanel vPanel = new VerticalPanel();
mainPanel.add(vPanel);
int rows = 14;
Grid grid = new Grid(rows, 2);
vPanel.add(grid);
int currentRow = 0;
eventId = createLabelAndValueWidget(grid, currentRow++, stringMessages.id(), "IdLabel");
eventName = createLabelAndValueWidget(grid, currentRow++, stringMessages.eventName(), "NameLabel");
description = createLabelAndValueWidget(grid, currentRow++, stringMessages.description(), "DescriptionLabel");
venueName = createLabelAndValueWidget(grid, currentRow++, stringMessages.venue(), "VenueLabel");
startDate = createLabelAndValueWidget(grid, currentRow++, stringMessages.startDate(), "StartDateLabel");
endDate = createLabelAndValueWidget(grid, currentRow++, stringMessages.endDate(), "EndDateLabel");
isPublic = createLabelAndValueWidget(grid, currentRow++, stringMessages.isPublic(), "IsPublicLabel");
officialWebsiteURL = createAnchorAndValueWidget(grid, currentRow++, stringMessages.eventOfficialWebsiteURL(), "OfficialWebsiteURLLabel");
logoImageURL = createAnchorAndValueWidget(grid, currentRow++, stringMessages.eventLogoImageURL(), "LogoImageURLLabel");
courseAreaNamesList = createLableAndValueListWidget(grid, currentRow++, stringMessages.courseAreas(), "CourseAreaValueList");
imageURLList = createLableAndValueListWidget(grid, currentRow++, stringMessages.imageURLs(), "ImageURLValueList");
videoURLList = createLableAndValueListWidget(grid, currentRow++, stringMessages.videoURLs(), "VideoURLValueList");
sponsorImageURLList = createLableAndValueListWidget(grid, currentRow++, stringMessages.sponsorImageURLs(), "SponsorImageURLValueList");
leaderboardGroupList = createLableAndValueListWidget(grid, currentRow++, stringMessages.leaderboardGroups(), "LeaderboardGroupValueList");
for(int i=0; i < rows; i++) {
grid.getCellFormatter().setVerticalAlignment(i, 0, HasVerticalAlignment.ALIGN_TOP);
grid.getCellFormatter().setVerticalAlignment(i, 1, HasVerticalAlignment.ALIGN_TOP);
}
initWidget(mainPanel);
}
private Label createLabelAndValueWidget(Grid grid, int row, String label, String debugId) {
Label valueLabel = new Label();
valueLabel.ensureDebugId(debugId);
grid.setWidget(row , 0, new Label(label + ":"));
grid.setWidget(row , 1, valueLabel);
return valueLabel;
}
private Anchor createAnchorAndValueWidget(Grid grid, int row, String label, String debugId) {
Anchor valueAnchor = new Anchor();
valueAnchor.setTarget("_blank");
valueAnchor.ensureDebugId(debugId);
grid.setWidget(row , 0, new Label(label + ":"));
grid.setWidget(row , 1, valueAnchor);
return valueAnchor;
}
private SimpleStringListComposite createLableAndValueListWidget(Grid grid, int row, String label, String debugId) {
SimpleStringListComposite valueList = new SimpleStringListComposite();
valueList.ensureDebugId(debugId);
grid.setWidget(row , 0, new Label(label + ":"));
grid.setWidget(row , 1, valueList);
return valueList;
}
public EventDTO getEvent() {
return event;
}
public void setEvent(EventDTO event) {
this.event = event;
updateEventDetails();
}
private void updateEventDetails() {
if (event != null) {
mainPanel.setCaptionText(stringMessages.event() + " " + event.getName());
eventName.setText(event.getName());
eventId.setText(event.id.toString());
venueName.setText(event.venue.getName());
description.setText(event.getDescription());
startDate.setText(event.startDate != null ? event.startDate.toString() : "");
endDate.setText(event.endDate != null ? event.endDate.toString() : "");
isPublic.setText(String.valueOf(event.isPublic));
officialWebsiteURL.setText(event.getOfficialWebsiteURL());
officialWebsiteURL.setHref(event.getOfficialWebsiteURL());
logoImageURL.setText(event.getLogoImageURL());
logoImageURL.setHref(event.getLogoImageURL());
List<String> courseAreaNames = new ArrayList<>();
if (event.venue.getCourseAreas() != null && event.venue.getCourseAreas().size() > 0) {
for (CourseAreaDTO courseArea : event.venue.getCourseAreas()) {
courseAreaNames.add(courseArea.getName());
}
}
courseAreaNamesList.setValues(courseAreaNames);
List<String> imageURLStringsAsList = new ArrayList<>();
Util.addAll(event.getImageURLs(), imageURLStringsAsList);
imageURLList.setValues(imageURLStringsAsList);
List<String> videoURLStringsAsList = new ArrayList<>();
Util.addAll(event.getVideoURLs(), videoURLStringsAsList);
videoURLList.setValues(videoURLStringsAsList);
List<String> sponsorImageURLStringsAsList = new ArrayList<>();
Util.addAll(event.getSponsorImageURLs(), sponsorImageURLStringsAsList);
sponsorImageURLList.setValues(sponsorImageURLStringsAsList);
List<String> leaderboardGroupNamesAsList = new ArrayList<>();
for(LeaderboardGroupDTO leaderboardGroupDTO: event.getLeaderboardGroups()) {
leaderboardGroupNamesAsList.add(leaderboardGroupDTO.getName());
}
leaderboardGroupList.setValues(leaderboardGroupNamesAsList);
}
}
private class SimpleStringListComposite extends Composite {
private final FlowPanel panel;
public SimpleStringListComposite() {
super();
panel = new FlowPanel();
this.initWidget(panel);
}
public void setValues(List<String> values) {
panel.clear();
for(String value: values) {
panel.add(new ListItemWidget(value));
}
}
}
public class ListItemWidget extends SimplePanel {
public ListItemWidget() {
super((Element) Document.get().createLIElement().cast());
getElement().getStyle().setProperty("listStylePosition", "inside");
}
public ListItemWidget(String s) {
this();
getElement().setInnerText(s);
}
public ListItemWidget(Widget w) {
this();
this.add(w);
}
}
}
@@ -9,11 +9,14 @@ import java.util.List;
import java.util.UUID;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TabLayoutPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
@@ -25,6 +28,7 @@ import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.VenueDTO;
import com.sap.sse.gwt.client.controls.listedit.StringConstantsListEditorComposite;
import com.sap.sse.gwt.client.controls.listedit.StringListInlineEditorComposite;
public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO> {
@@ -43,13 +47,9 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
protected StringListInlineEditorComposite imageURLList;
protected StringListInlineEditorComposite videoURLList;
protected StringListInlineEditorComposite sponsorImageURLList;
protected StringConstantsListEditorComposite leaderboardGroupList;
protected List<LeaderboardGroupDTO> availableLeaderboardGroups;
/**
* Allows subclasses to "park" a set of associated leaderboard groups for re-attachment to the new {@link EventDTO} produced
* by {@link #getResult()}.
*/
private final Iterable<LeaderboardGroupDTO> leaderboardGroups;
protected static class EventParameterValidator implements Validator<EventDTO> {
private StringMessages stringMessages;
@@ -113,21 +113,23 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
}
/**
* @param leaderboardGroups even though not editable in this dialog, this parameter gives an editing subclass a chance to "park" the leaderboard group
* @param leaderboardGroupsOfEvent even though not editable in this dialog, this parameter gives an editing subclass a chance to "park" the leaderboard group
* assignments for re-association with the new {@link EventDTO} created by the {@link #getResult} method.
*/
public EventDialog(EventParameterValidator validator, StringMessages stringMessages, Iterable<LeaderboardGroupDTO> leaderboardGroups,
DialogCallback<EventDTO> callback) {
public EventDialog(EventParameterValidator validator, StringMessages stringMessages, List<LeaderboardGroupDTO> availableLeaderboardGroups,
Iterable<LeaderboardGroupDTO> leaderboardGroupsOfEvent, DialogCallback<EventDTO> callback) {
super(stringMessages.event(), null, stringMessages.ok(), stringMessages.cancel(), validator,
callback);
this.leaderboardGroups = leaderboardGroups;
this.stringMessages = stringMessages;
this.availableLeaderboardGroups = availableLeaderboardGroups;
getDialogBox().setWidth("750px");
final ValueChangeHandler<Iterable<String>> valueChangeHandler = new ValueChangeHandler<Iterable<String>>() {
@Override
public void onValueChange(ValueChangeEvent<Iterable<String>> event) {
validate();
}
};
courseAreaNameList = new StringListInlineEditorComposite(Collections.<String> emptyList(),
new StringListInlineEditorComposite.ExpandedUi(stringMessages, resources.removeIcon(), /* suggestValues */
SuggestedCourseAreaNames.suggestedCourseAreaNames, stringMessages.enterCourseAreaName(), 50));
@@ -147,13 +149,24 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
new StringListInlineEditorComposite.ExpandedUi(stringMessages, resources.removeIcon(),
/* suggestValues */ imageSuggestionURLs, stringMessages.enterSponsorImageURL(), 80));
sponsorImageURLList.addValueChangeHandler(valueChangeHandler);
List<String> leaderboardGroupNames = new ArrayList<>();
for(LeaderboardGroupDTO leaderboardGroupDTO: availableLeaderboardGroups) {
leaderboardGroupNames.add(leaderboardGroupDTO.getName());
}
leaderboardGroupList = new StringConstantsListEditorComposite(Collections.<String> emptyList(),
new StringConstantsListEditorComposite.ExpandedUi(stringMessages, resources.removeIcon(),
leaderboardGroupNames, "Select a leaderboard group..."));
leaderboardGroupList.addValueChangeHandler(valueChangeHandler);
}
@Override
protected EventDTO getResult() {
EventDTO result = new EventDTO();
for (LeaderboardGroupDTO lg : leaderboardGroups) {
result.addLeaderboardGroup(lg);
List<String> leaderboardGroupNames = leaderboardGroupList.getValue();
for(LeaderboardGroupDTO lg: availableLeaderboardGroups) {
if(leaderboardGroupNames.contains(lg.getName())) {
result.addLeaderboardGroup(lg);
}
}
result.setName(nameEntryField.getText());
result.setDescription(descriptionEntryField.getText());
@@ -186,6 +199,7 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
@Override
protected Widget getAdditionalWidget() {
final VerticalPanel panel = new VerticalPanel();
panel.setWidth("100%");
Widget additionalWidget = super.getAdditionalWidget();
if (additionalWidget != null) {
panel.add(additionalWidget);
@@ -211,14 +225,14 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
formGrid.setWidget(7, 0, new Label(stringMessages.eventLogoImageURL() + ":"));
formGrid.setWidget(7, 1, logoImageURLEntryField);
panel.add(createHeadlineLabel(stringMessages.courseAreas()));
panel.add(courseAreaNameList);
panel.add(createHeadlineLabel(stringMessages.imageURLs()));
panel.add(imageURLList);
panel.add(createHeadlineLabel(stringMessages.videoURLs()));
panel.add(videoURLList);
panel.add(createHeadlineLabel(stringMessages.sponsorImageURLs()));
panel.add(sponsorImageURLList);
TabLayoutPanel tabPanel = new TabLayoutPanel(30, Unit.PX);
tabPanel.setHeight("250px");
panel.add(tabPanel);
tabPanel.add(new ScrollPanel(leaderboardGroupList), stringMessages.leaderboardGroups());
tabPanel.add(new ScrollPanel(courseAreaNameList), stringMessages.courseAreas());
tabPanel.add(new ScrollPanel(imageURLList), stringMessages.imageURLs());
tabPanel.add(new ScrollPanel(videoURLList), stringMessages.videoURLs());
tabPanel.add(new ScrollPanel(sponsorImageURLList), stringMessages.sponsorImageURLs());
return panel;
}
@@ -7,11 +7,12 @@ import java.util.List;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sse.common.Util;
public class EventEditDialog extends EventDialog {
public EventEditDialog(EventDTO event, Collection<EventDTO> otherExistingEvents, StringMessages stringMessages, DialogCallback<EventDTO> callback) {
super(new EventParameterValidator(stringMessages, otherExistingEvents), stringMessages, event.getLeaderboardGroups(), callback);
public EventEditDialog(EventDTO event, Collection<EventDTO> otherExistingEvents, List<LeaderboardGroupDTO> availableLeaderboardGroups, StringMessages stringMessages, DialogCallback<EventDTO> callback) {
super(new EventParameterValidator(stringMessages, otherExistingEvents), stringMessages, availableLeaderboardGroups, event.getLeaderboardGroups(), callback);
nameEntryField = createTextBox(event.getName());
nameEntryField.setVisibleLength(50);
descriptionEntryField = createTextArea(event.getDescription());
@@ -48,5 +49,10 @@ public class EventEditDialog extends EventDialog {
List<String> sponsorImageURLStringsAsList = new ArrayList<>();
Util.addAll(event.getSponsorImageURLs(), sponsorImageURLStringsAsList);
sponsorImageURLList.setValue(sponsorImageURLStringsAsList);
List<String> leaderboardGroupNames = new ArrayList<>();
for(LeaderboardGroupDTO leaderboardGroupDTO: event.getLeaderboardGroups()) {
leaderboardGroupNames.add(leaderboardGroupDTO.getName());
}
leaderboardGroupList.setValue(leaderboardGroupNames);
}
}
@@ -0,0 +1,650 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.SafeHtmlCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.sap.sailing.domain.common.impl.NaturalComparator;
import com.sap.sailing.gwt.ui.client.EventSelectionProvider;
import com.sap.sailing.gwt.ui.client.EventsRefresher;
import com.sap.sailing.gwt.ui.client.LeaderboardGroupsDisplayer;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.controls.SelectionCheckboxColumn;
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.URLEncoder;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
/**
/**
* A composite showing the list of all sailing events
* @author Frank Mittag (C5163974)
*/
public class EventListComposite extends Composite implements EventsRefresher, LeaderboardGroupsDisplayer {
private final SailingServiceAsync sailingService;
private final EventSelectionProvider eventSelectionProvider;
private final ErrorReporter errorReporter;
private final StringMessages stringMessages;
private CellTable<EventDTO> eventTable;
private MultiSelectionModel<EventDTO> eventSelectionModel;
private ListDataProvider<EventDTO> eventListDataProvider;
private List<EventDTO> allEvents;
private LabeledAbstractFilterablePanel<EventDTO> filterTextbox;
private Button removeEventsButton;
private final Label noEventsLabel;
private final SimplePanel mainPanel;
private final VerticalPanel panel;
private Iterable<LeaderboardGroupDTO> availableLeaderboardGroups;
public static class AnchorCell extends AbstractCell<SafeHtml> {
@Override
public void render(com.google.gwt.cell.client.Cell.Context context, SafeHtml safeHtml, SafeHtmlBuilder sb) {
sb.append(safeHtml);
}
}
interface AnchorTemplates extends SafeHtmlTemplates {
@SafeHtmlTemplates.Template("<a href=\"{0}\">{1}</a>")
SafeHtml cell(String url, String displayName);
}
private static AnchorTemplates ANCHORTEMPLATE = GWT.create(AnchorTemplates.class);
private final AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class);
public EventListComposite(final SailingServiceAsync sailingService, final EventSelectionProvider eventSelectionProvider,
final ErrorReporter errorReporter, final StringMessages stringMessages) {
this.sailingService = sailingService;
this.eventSelectionProvider = eventSelectionProvider;
this.stringMessages = stringMessages;
this.errorReporter = errorReporter;
availableLeaderboardGroups = Collections.emptyList();
allEvents = new ArrayList<EventDTO>();
mainPanel = new SimplePanel();
panel = new VerticalPanel();
mainPanel.setWidget(panel);
HorizontalPanel eventControlsPanel = new HorizontalPanel();
eventControlsPanel.setSpacing(5);
panel.add(eventControlsPanel);
Button refreshButton = new Button(stringMessages.refresh());
refreshButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
fillEvents();
}
});
eventControlsPanel.add(refreshButton);
Button createEventBtn = new Button(stringMessages.actionAddEvent());
createEventBtn.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
openCreateEventDialog();
}
});
eventControlsPanel.add(createEventBtn);
removeEventsButton = new Button(stringMessages.remove());
removeEventsButton.setEnabled(false);
removeEventsButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (Window.confirm(stringMessages.doYouReallyWantToRemoveEvents())) {
removeEvents(eventSelectionModel.getSelectedSet());
}
}
});
eventControlsPanel.add(removeEventsButton);
eventListDataProvider = new ListDataProvider<EventDTO>();
eventTable = createEventTable();
eventTable.ensureDebugId("EventsCellTable");
eventTable.setVisible(false);
@SuppressWarnings("unchecked")
MultiSelectionModel<EventDTO> multiSelectionModel = (MultiSelectionModel<EventDTO>) eventTable.getSelectionModel();
eventSelectionModel = multiSelectionModel;
eventSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
final boolean somethingSelected = !eventSelectionModel.getSelectedSet().isEmpty();
removeEventsButton.setEnabled(somethingSelected);
List<EventDTO> selectedEvents = getSelectedEvents();
List<UUID> selectedEventUUIDs = new ArrayList<UUID>();
for (EventDTO selectedEvent : selectedEvents) {
selectedEventUUIDs.add(selectedEvent.id);
}
EventListComposite.this.eventSelectionProvider.setSelection(selectedEventUUIDs);
}
});
panel.add(eventTable);
filterTextbox = new LabeledAbstractFilterablePanel<EventDTO>(new Label(stringMessages.filterEventsByName()), allEvents,
eventTable, eventListDataProvider) {
@Override
public Iterable<String> getSearchableStrings(EventDTO t) {
List<String> result = new ArrayList<String>();
result.add(t.getName());
result.add(t.venue.getName());
for (CourseAreaDTO c : t.venue.getCourseAreas()) {
result.add(c.getName());
}
for (LeaderboardGroupDTO lg : t.getLeaderboardGroups()) {
result.add(lg.getName());
}
return result;
}
};
eventControlsPanel.add(filterTextbox);
noEventsLabel = new Label("No events defined yet.");
noEventsLabel.ensureDebugId("NoRegattasLabel");
noEventsLabel.setWordWrap(false);
panel.add(noEventsLabel);
fillEvents();
initWidget(mainPanel);
}
private CellTable<EventDTO> createEventTable() {
CellTable<EventDTO> table = new CellTable<EventDTO>(/* pageSize */10000, tableRes);
eventListDataProvider.addDataDisplay(table);
table.setWidth("100%");
SelectionCheckboxColumn<EventDTO> eventSelectionCheckboxColumn = new SelectionCheckboxColumn<EventDTO>(tableRes.cellTableStyle().cellTableCheckboxSelected(),
tableRes.cellTableStyle().cellTableCheckboxDeselected(), tableRes.cellTableStyle().cellTableCheckboxColumnCell()) {
@Override
protected ListDataProvider<EventDTO> getListDataProvider() {
return eventListDataProvider;
}
@Override
public Boolean getValue(EventDTO row) {
return eventTable.getSelectionModel().isSelected(row);
}
};
AnchorCell anchorCell = new AnchorCell();
Column<EventDTO, SafeHtml> eventNameColumn = new Column<EventDTO, SafeHtml>(anchorCell) {
@Override
public SafeHtml getValue(EventDTO event) {
String debugParam = Window.Location.getParameter("gwt.codesvr");
String link = URLEncoder.encode("/gwt/RegattaOverview.html?event=" + event.id
+ (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""));
return ANCHORTEMPLATE.cell(link, event.getName());
}
};
TextColumn<EventDTO> venueNameColumn = new TextColumn<EventDTO>() {
@Override
public String getValue(EventDTO event) {
return event.venue != null ? event.venue.getName() : "";
}
};
TextColumn<EventDTO> startEndDateColumn = new TextColumn<EventDTO>() {
@Override
public String getValue(EventDTO event) {
return DateAndTimeFormatterUtil.formatDateRange(event.startDate, event.endDate);
}
};
TextColumn<EventDTO> isPublicColumn = new TextColumn<EventDTO>() {
@Override
public String getValue(EventDTO event) {
return event.isPublic ? stringMessages.yes() : stringMessages.no();
}
};
SafeHtmlCell courseAreasCell = new SafeHtmlCell();
Column<EventDTO, SafeHtml> courseAreasColumn = new Column<EventDTO, SafeHtml>(courseAreasCell) {
@Override
public SafeHtml getValue(EventDTO event) {
SafeHtmlBuilder builder = new SafeHtmlBuilder();
int courseAreasCount = event.venue.getCourseAreas().size();
int i = 1;
for (CourseAreaDTO courseArea : event.venue.getCourseAreas()) {
builder.appendEscaped(courseArea.getName());
if (i < courseAreasCount) {
builder.appendHtmlConstant(",&nbsp;");
// not more than 4 course areas per line
if(i % 4 == 0) {
builder.appendHtmlConstant("<br>");
}
}
i++;
}
return builder.toSafeHtml();
}
};
SafeHtmlCell leaderboardGroupsCell = new SafeHtmlCell();
Column<EventDTO, SafeHtml> leaderboardGroupsColumn = new Column<EventDTO, SafeHtml>(leaderboardGroupsCell) {
@Override
public SafeHtml getValue(EventDTO event) {
SafeHtmlBuilder builder = new SafeHtmlBuilder();
boolean first = true;
for (LeaderboardGroupDTO lg : event.getLeaderboardGroups()) {
if (first) {
first = false;
} else {
builder.appendHtmlConstant("<br>");
}
builder.appendEscaped(lg.getName());
}
return builder.toSafeHtml();
}
};
TextColumn<EventDTO> imageURLsColumn = new TextColumn<EventDTO>() {
@Override
public String getValue(EventDTO event) {
String result = "";
int imageCount = Util.size(event.getImageURLs());
if(imageCount > 0) {
result = imageCount + " image(s)";
}
return result;
}
};
TextColumn<EventDTO> videoURLsColumn = new TextColumn<EventDTO>() {
@Override
public String getValue(EventDTO event) {
String result = "";
int videoCount = Util.size(event.getVideoURLs());
if(videoCount > 0) {
result = videoCount + " video(s)";
}
return result;
}
};
TextColumn<EventDTO> sponsorImageURLsColumn = new TextColumn<EventDTO>() {
@Override
public String getValue(EventDTO event) {
String result = "";
int sponsorImageCount = Util.size(event.getSponsorImageURLs());
if(sponsorImageCount > 0) {
result = sponsorImageCount + " sponsor image(s)";
}
return result;
}
};
SafeHtmlCell associatedRegattasCell = new SafeHtmlCell();
Column<EventDTO, SafeHtml> associatedRegattasColumn = new Column<EventDTO, SafeHtml>(associatedRegattasCell) {
@Override
public SafeHtml getValue(EventDTO event) {
SafeHtmlBuilder builder = new SafeHtmlBuilder();
int regattaCount = event.regattas.size();
int i = 1;
for (RegattaDTO regatta : event.regattas) {
builder.appendEscaped(regatta.getName());
if (i < regattaCount) {
builder.appendHtmlConstant("<br>");
}
i++;
}
return builder.toSafeHtml();
}
};
ImagesBarColumn<EventDTO, EventConfigImagesBarCell> eventActionColumn = new ImagesBarColumn<EventDTO, EventConfigImagesBarCell>(
new EventConfigImagesBarCell(stringMessages));
eventActionColumn.setFieldUpdater(new FieldUpdater<EventDTO, String>() {
@Override
public void update(int index, EventDTO event, String value) {
if (EventConfigImagesBarCell.ACTION_REMOVE.equals(value)) {
if (Window.confirm(stringMessages.doYouReallyWantToRemoveEvent(event.getName()))) {
removeEvent(event);
}
} else if (EventConfigImagesBarCell.ACTION_EDIT.equals(value)) {
openEditEventDialog(event);
}
}
});
eventNameColumn.setSortable(true);
venueNameColumn.setSortable(true);
isPublicColumn.setSortable(true);
startEndDateColumn.setSortable(true);
courseAreasColumn.setSortable(true);
imageURLsColumn.setSortable(true);
videoURLsColumn.setSortable(true);
sponsorImageURLsColumn.setSortable(true);
leaderboardGroupsColumn.setSortable(true);
table.addColumn(eventSelectionCheckboxColumn, eventSelectionCheckboxColumn.getHeader());
table.addColumn(eventNameColumn, stringMessages.event());
table.addColumn(venueNameColumn, stringMessages.venue());
table.addColumn(startEndDateColumn, stringMessages.from() + "/" + stringMessages.to());
table.addColumn(isPublicColumn, stringMessages.isPublic());
table.addColumn(courseAreasColumn, stringMessages.courseAreas());
table.addColumn(leaderboardGroupsColumn, stringMessages.leaderboardGroups());
table.addColumn(imageURLsColumn, stringMessages.imageURLs());
table.addColumn(videoURLsColumn, stringMessages.videoURLs());
table.addColumn(sponsorImageURLsColumn, stringMessages.sponsorImageURLs());
table.addColumn(associatedRegattasColumn, stringMessages.regattas());
table.addColumn(eventActionColumn, stringMessages.actions());
table.setSelectionModel(eventSelectionCheckboxColumn.getSelectionModel(), eventSelectionCheckboxColumn.getSelectionManager());
table.addColumnSortHandler(getEventTableColumnSortHandler(eventListDataProvider.getList(), eventNameColumn,
venueNameColumn, startEndDateColumn, isPublicColumn));
table.getColumnSortList().push(startEndDateColumn);
return table;
}
private ListHandler<EventDTO> getEventTableColumnSortHandler(List<EventDTO> eventRecords,
Column<EventDTO, SafeHtml> eventNameColumn, TextColumn<EventDTO> venueNameColumn,
TextColumn<EventDTO> startEndDateColumn, TextColumn<EventDTO> isPublicColumn) {
ListHandler<EventDTO> result = new ListHandler<EventDTO>(eventRecords);
result.setComparator(eventNameColumn, new Comparator<EventDTO>() {
@Override
public int compare(EventDTO e1, EventDTO e2) {
return new NaturalComparator().compare(e1.getName(), e2.getName());
}
});
result.setComparator(venueNameColumn, new Comparator<EventDTO>() {
@Override
public int compare(EventDTO e1, EventDTO e2) {
return new NaturalComparator().compare(e1.venue.getName(), e2.venue.getName());
}
});
result.setComparator(startEndDateColumn, new Comparator<EventDTO>() {
@Override
public int compare(EventDTO e1, EventDTO e2) {
int result;
if(e1.startDate != null && e2.startDate != null) {
result = e2.startDate.compareTo(e1.startDate);
} else if(e1.startDate == null && e2.startDate != null) {
result = 1;
} else if(e1.startDate != null && e2.startDate == null) {
result = -1;
} else {
result = 0;
}
return result;
}
});
result.setComparator(isPublicColumn, new Comparator<EventDTO>() {
@Override
public int compare(EventDTO e1, EventDTO e2) {
return e1.isPublic == e2.isPublic ? 0 : e1.isPublic ? 1 : -1;
}
});
return result;
}
private void removeEvents(Collection<EventDTO> events) {
if (!events.isEmpty()) {
Collection<UUID> eventIds = new HashSet<UUID>();
for (EventDTO event : events) {
eventIds.add(event.id);
}
sailingService.removeEvents(eventIds, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to remove the events:" + caught.getMessage());
}
@Override
public void onSuccess(Void result) {
fillEvents();
}
});
}
}
private void removeEvent(final EventDTO event) {
sailingService.removeEvent(event.id, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to remove event " + event.getName() + ": " + caught.getMessage());
}
@Override
public void onSuccess(Void result) {
fillEvents();
}
});
}
private void openCreateEventDialog() {
List<EventDTO> existingEvents = new ArrayList<EventDTO>(eventListDataProvider.getList());
List<LeaderboardGroupDTO> existingLeaderboardGroups = new ArrayList<LeaderboardGroupDTO>();
Util.addAll(availableLeaderboardGroups, existingLeaderboardGroups);
EventCreateDialog dialog = new EventCreateDialog(Collections.unmodifiableCollection(existingEvents), existingLeaderboardGroups,
stringMessages, new DialogCallback<EventDTO>() {
@Override
public void cancel() {
}
@Override
public void ok(EventDTO newEvent) {
createNewEvent(newEvent);
}
});
dialog.show();
}
private void openEditEventDialog(final EventDTO selectedEvent) {
List<EventDTO> existingEvents = new ArrayList<EventDTO>(eventListDataProvider.getList());
existingEvents.remove(selectedEvent);
List<LeaderboardGroupDTO> existingLeaderboardGroups = new ArrayList<LeaderboardGroupDTO>();
Util.addAll(availableLeaderboardGroups, existingLeaderboardGroups);
EventEditDialog dialog = new EventEditDialog(selectedEvent, Collections.unmodifiableCollection(existingEvents),
existingLeaderboardGroups, stringMessages,
new DialogCallback<EventDTO>() {
@Override
public void cancel() {
}
@Override
public void ok(EventDTO updatedEvent) {
updateEvent(selectedEvent, updatedEvent);
}
});
dialog.show();
}
private void updateEvent(final EventDTO oldEvent, final EventDTO updatedEvent) {
Pair<List<CourseAreaDTO>, List<CourseAreaDTO>> courseAreasToAddAndRemove = getCourseAreasToAdd(oldEvent, updatedEvent);
List<CourseAreaDTO> courseAreasToAdd = courseAreasToAddAndRemove.getA();
List<CourseAreaDTO> courseAreasToRemove = courseAreasToAddAndRemove.getB();
List<UUID> updatedEventLeaderboardGroupIds = new ArrayList<>();
for (LeaderboardGroupDTO leaderboardGroup : updatedEvent.getLeaderboardGroups()) {
updatedEventLeaderboardGroupIds.add(leaderboardGroup.getId());
}
sailingService.updateEvent(oldEvent.id, oldEvent.getName(), updatedEvent.getDescription(),
updatedEvent.startDate, updatedEvent.endDate, updatedEvent.venue,
updatedEvent.isPublic, updatedEventLeaderboardGroupIds,
updatedEvent.getOfficialWebsiteURL(), updatedEvent.getLogoImageURL(),
updatedEvent.getImageURLs(), updatedEvent.getVideoURLs(), updatedEvent.getSponsorImageURLs(),
new AsyncCallback<EventDTO>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to update sailing event" + oldEvent.getName() + ": " + t.getMessage());
}
@Override
public void onSuccess(EventDTO result) {
fillEvents();
if (!oldEvent.getName().equals(updatedEvent.getName())) {
sailingService.renameEvent(oldEvent.id, updatedEvent.getName(), new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
fillEvents();
}
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to rename sailing event " + oldEvent.getName() + ": " + t.getMessage());
}
});
}
}
});
for (CourseAreaDTO courseArea : courseAreasToAdd) {
sailingService.createCourseArea(oldEvent.id, courseArea.getName(), new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to add course area to sailing event " + oldEvent.getName()
+ ": " + t.getMessage());
}
@Override
public void onSuccess(Void result) {
fillEvents();
}
});
}
for (CourseAreaDTO courseArea : courseAreasToRemove) {
sailingService.removeCourseArea(oldEvent.id, courseArea.id, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to remove course area from sailing event " + oldEvent.getName()
+ ": " + t.getMessage());
}
@Override
public void onSuccess(Void result) {
fillEvents();
}
});
}
}
private Pair<List<CourseAreaDTO>, List<CourseAreaDTO>> getCourseAreasToAdd(final EventDTO oldEvent, final EventDTO updatedEvent) {
List<CourseAreaDTO> courseAreasToAdd = new ArrayList<CourseAreaDTO>(updatedEvent.venue.getCourseAreas());
courseAreasToAdd.removeAll(oldEvent.venue.getCourseAreas());
List<CourseAreaDTO> courseAreasToRemove = new ArrayList<CourseAreaDTO>(oldEvent.venue.getCourseAreas());
courseAreasToRemove.removeAll(updatedEvent.venue.getCourseAreas());
return new Pair<List<CourseAreaDTO>, List<CourseAreaDTO>>(courseAreasToAdd, courseAreasToRemove);
}
private void createNewEvent(final EventDTO newEvent) {
List<String> courseAreaNames = new ArrayList<String>();
for (CourseAreaDTO courseAreaDTO : newEvent.venue.getCourseAreas()) {
courseAreaNames.add(courseAreaDTO.getName());
}
sailingService.createEvent(newEvent.getName(), newEvent.getDescription(), newEvent.startDate, newEvent.endDate,
newEvent.venue.getName(), newEvent.isPublic, courseAreaNames, newEvent.getImageURLs(),
newEvent.getVideoURLs(), newEvent.getSponsorImageURLs(), newEvent.getLogoImageURL(),
newEvent.getOfficialWebsiteURL(), new AsyncCallback<EventDTO>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to create new event " + newEvent.getName() + ": " + t.getMessage());
}
@Override
public void onSuccess(EventDTO newEvent) {
fillEvents();
}
});
}
@Override
public void fillLeaderboardGroups(Iterable<LeaderboardGroupDTO> leaderboardGroups) {
availableLeaderboardGroups = leaderboardGroups;
}
@Override
public void fillEvents() {
sailingService.getEvents(new AsyncCallback<List<EventDTO>>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Remote Procedure Call getEvents() - Failure: " + caught.getMessage());
}
@Override
public void onSuccess(List<EventDTO> events) {
if (events.isEmpty()) {
eventTable.setVisible(false);
noEventsLabel.setVisible(true);
} else {
eventTable.setVisible(true);
noEventsLabel.setVisible(false);
}
Set<UUID> selectedEventUUIDs = new HashSet<>();
for (EventDTO selectedEvent : eventSelectionModel.getSelectedSet()) {
selectedEventUUIDs.add(selectedEvent.id);
}
eventSelectionModel.clear();
allEvents.clear();
allEvents.addAll(events);
filterTextbox.updateAll(allEvents);
for (EventDTO e : allEvents) {
if (selectedEventUUIDs.contains(e.id)) {
eventSelectionModel.setSelected(e, true);
}
}
}
});
}
public List<EventDTO> getAllEvents() {
return allEvents;
}
private List<EventDTO> getSelectedEvents() {
List<EventDTO> result = new ArrayList<EventDTO>();
if (eventListDataProvider != null) {
for (EventDTO Event : eventListDataProvider.getList()) {
if (eventSelectionModel.isSelected(Event)) {
result.add(Event);
}
}
}
return result;
}
}
@@ -1,878 +1,83 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.SafeHtmlCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.sap.sailing.domain.common.impl.NaturalComparator;
import com.sap.sailing.gwt.ui.client.EventSelectionChangeListener;
import com.sap.sailing.gwt.ui.client.EventSelectionModel;
import com.sap.sailing.gwt.ui.client.EventSelectionProvider;
import com.sap.sailing.gwt.ui.client.EventsRefresher;
import com.sap.sailing.gwt.ui.client.LeaderboardGroupsDisplayer;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.URLEncoder;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
/**
* Allows administrators to manage data of a sailing event. This is a temporary panel because the managed event is not
* connected with any regatta and it used only to manage of basic attributes of the an event.
* Allows administrators to manage a sailing event.
*
* @author Frank Mittag (C5163974)
* @author Axel Uhl (d043530)
*/
public class EventManagementPanel extends SimplePanel implements EventsRefresher, LeaderboardGroupsDisplayer {
private final SailingServiceAsync sailingService;
private final ErrorReporter errorReporter;
private final StringMessages stringMessages;
private CellTable<EventDTO> eventTable;
private MultiSelectionModel<EventDTO> eventSelectionModel;
private ListDataProvider<EventDTO> eventProvider;
private List<EventDTO> allEvents;
private LabeledAbstractFilterablePanel<EventDTO> filterTextbox;
private Button removeEventsButton;
private TextColumn<EventDTO> startEndDateColumn;
private CellTable<LeaderboardGroupDTO> selectedEventLeaderboardGroupsTable;
private MultiSelectionModel<LeaderboardGroupDTO> selectedEventLeaderboardGroupsSelectionModel;
private ListDataProvider<LeaderboardGroupDTO> selectedEventLeaderboardGroupsProvider;
public class EventManagementPanel extends SimplePanel implements EventsRefresher, LeaderboardGroupsDisplayer, EventSelectionChangeListener {
private EventListComposite eventListComposite;
private EventDetailsComposite eventDetailsComposite;
private final CaptionPanel eventsPanel;
private EventSelectionProvider eventSelectionProvider;
private LabeledAbstractFilterablePanel<LeaderboardGroupDTO> availableLeaderboardGroupsFilterablePanel;
private CellTable<LeaderboardGroupDTO> availableLeaderboardGroupsTable;
private MultiSelectionModel<LeaderboardGroupDTO> availableLeaderboardGroupsSelectionModel;
private ListDataProvider<LeaderboardGroupDTO> availableLeaderboardGroupsProvider;
public static class AnchorCell extends AbstractCell<SafeHtml> {
@Override
public void render(com.google.gwt.cell.client.Cell.Context context, SafeHtml safeHtml, SafeHtmlBuilder sb) {
sb.append(safeHtml);
}
}
interface AnchorTemplates extends SafeHtmlTemplates {
@SafeHtmlTemplates.Template("<a href=\"{0}\">{1}</a>")
SafeHtml cell(String url, String displayName);
}
private static AnchorTemplates ANCHORTEMPLATE = GWT.create(AnchorTemplates.class);
private final AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class);
private final HorizontalPanel splitPanel;
private Button addToEventButton;
private Button removeFromEventButton;
private Iterable<LeaderboardGroupDTO> availableLeaderboardGroups;
public EventManagementPanel(final SailingServiceAsync sailingService, final ErrorReporter errorReporter,
final StringMessages stringMessages) {
availableLeaderboardGroups = Collections.emptySet();
this.sailingService = sailingService;
this.stringMessages = stringMessages;
this.errorReporter = errorReporter;
VerticalPanel mainPanel = new VerticalPanel();
this.setWidget(mainPanel);
setWidget(mainPanel);
mainPanel.setWidth("100%");
HorizontalPanel eventsPanel = new HorizontalPanel();
eventsPanel.setSpacing(5);
eventsPanel = new CaptionPanel(stringMessages.events());
mainPanel.add(eventsPanel);
VerticalPanel eventsContentPanel = new VerticalPanel();
eventsPanel.setContentWidget(eventsContentPanel);
Button refreshButton = new Button(stringMessages.refresh());
refreshButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
fillEvents();
}
});
eventsPanel.add(refreshButton);
eventSelectionProvider = new EventSelectionModel(true);
eventSelectionProvider.addEventSelectionChangeListener(this);
Button createEventBtn = new Button(stringMessages.actionAddEvent());
createEventBtn.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
openCreateEventDialog();
}
});
eventsPanel.add(createEventBtn);
removeEventsButton = new Button(stringMessages.remove());
removeEventsButton.setEnabled(false);
removeEventsButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (Window.confirm(stringMessages.doYouReallyWantToRemoveEvents())) {
removeEvents(eventSelectionModel.getSelectedSet());
}
}
});
eventsPanel.add(removeEventsButton);
// sailing events table
AnchorCell anchorCell = new AnchorCell();
final Column<EventDTO, SafeHtml> eventNameColumn = new Column<EventDTO, SafeHtml>(anchorCell) {
@Override
public SafeHtml getValue(EventDTO event) {
String debugParam = Window.Location.getParameter("gwt.codesvr");
String link = URLEncoder.encode("/gwt/RegattaOverview.html?event=" + event.id
+ (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""));
return ANCHORTEMPLATE.cell(link, event.getName());
}
};
TextColumn<EventDTO> venueNameColumn = new TextColumn<EventDTO>() {
@Override
public String getValue(EventDTO event) {
return event.venue != null ? event.venue.getName() : "";
}
};
startEndDateColumn = new TextColumn<EventDTO>() {
@Override
public String getValue(EventDTO event) {
return DateAndTimeFormatterUtil.formatDateRange(event.startDate, event.endDate);
}
};
final TextColumn<EventDTO> isPublicColumn = new TextColumn<EventDTO>() {
@Override
public String getValue(EventDTO event) {
return event.isPublic ? stringMessages.yes() : stringMessages.no();
}
};
final SafeHtmlCell courseAreasCell = new SafeHtmlCell();
final Column<EventDTO, SafeHtml> courseAreasColumn = new Column<EventDTO, SafeHtml>(courseAreasCell) {
@Override
public SafeHtml getValue(EventDTO event) {
SafeHtmlBuilder builder = new SafeHtmlBuilder();
int courseAreasCount = event.venue.getCourseAreas().size();
int i = 1;
for (CourseAreaDTO courseArea : event.venue.getCourseAreas()) {
builder.appendEscaped(courseArea.getName());
if (i < courseAreasCount) {
builder.appendHtmlConstant(",&nbsp;");
// not more than 4 course areas per line
if(i % 4 == 0) {
builder.appendHtmlConstant("<br>");
}
}
i++;
}
return builder.toSafeHtml();
}
};
eventListComposite = new EventListComposite(sailingService, eventSelectionProvider, errorReporter, stringMessages);
eventListComposite.ensureDebugId("EventListComposite");
eventsContentPanel.add(eventListComposite);
final SafeHtmlCell leaderboardGroupsCell = new SafeHtmlCell();
final Column<EventDTO, SafeHtml> leaderboardGroupsColumn = new Column<EventDTO, SafeHtml>(leaderboardGroupsCell) {
@Override
public SafeHtml getValue(EventDTO event) {
SafeHtmlBuilder builder = new SafeHtmlBuilder();
boolean first = true;
for (LeaderboardGroupDTO lg : event.getLeaderboardGroups()) {
if (first) {
first = false;
} else {
builder.appendHtmlConstant("<br>");
}
builder.appendEscaped(lg.getName());
}
return builder.toSafeHtml();
}
};
final TextColumn<EventDTO> imageURLsColumn = new TextColumn<EventDTO>() {
@Override
public String getValue(EventDTO event) {
String result = "";
int imageCount = Util.size(event.getImageURLs());
if(imageCount > 0) {
result = imageCount + " image(s)";
}
return result;
}
};
final TextColumn<EventDTO> videoURLsColumn = new TextColumn<EventDTO>() {
@Override
public String getValue(EventDTO event) {
String result = "";
int videoCount = Util.size(event.getVideoURLs());
if(videoCount > 0) {
result = videoCount + " video(s)";
}
return result;
}
};
final TextColumn<EventDTO> sponsorImageURLsColumn = new TextColumn<EventDTO>() {
@Override
public String getValue(EventDTO event) {
String result = "";
int sponsorImageCount = Util.size(event.getSponsorImageURLs());
if(sponsorImageCount > 0) {
result = sponsorImageCount + " sponsor image(s)";
}
return result;
}
};
final SafeHtmlCell associatedRegattasCell = new SafeHtmlCell();
final Column<EventDTO, SafeHtml> associatedRegattasColumn = new Column<EventDTO, SafeHtml>(associatedRegattasCell) {
@Override
public SafeHtml getValue(EventDTO event) {
SafeHtmlBuilder builder = new SafeHtmlBuilder();
int regattaCount = event.regattas.size();
int i = 1;
for (RegattaDTO regatta : event.regattas) {
builder.appendEscaped(regatta.getName());
if (i < regattaCount) {
builder.appendHtmlConstant("<br>");
}
i++;
}
return builder.toSafeHtml();
}
};
final ImagesBarColumn<EventDTO, EventConfigImagesBarCell> eventActionColumn = new ImagesBarColumn<EventDTO, EventConfigImagesBarCell>(
new EventConfigImagesBarCell(stringMessages));
eventActionColumn.setFieldUpdater(new FieldUpdater<EventDTO, String>() {
@Override
public void update(int index, EventDTO event, String value) {
if (EventConfigImagesBarCell.ACTION_REMOVE.equals(value)) {
if (Window.confirm(stringMessages.doYouReallyWantToRemoveEvent(event.getName()))) {
removeEvent(event);
}
} else if (EventConfigImagesBarCell.ACTION_EDIT.equals(value)) {
openEditEventDialog(event);
}
}
});
eventNameColumn.setSortable(true);
venueNameColumn.setSortable(true);
isPublicColumn.setSortable(true);
startEndDateColumn.setSortable(true);
courseAreasColumn.setSortable(true);
imageURLsColumn.setSortable(true);
videoURLsColumn.setSortable(true);
sponsorImageURLsColumn.setSortable(true);
leaderboardGroupsColumn.setSortable(true);
eventTable = new CellTable<EventDTO>(10000, tableRes);
eventTable.addColumn(eventNameColumn, stringMessages.event());
eventTable.addColumn(venueNameColumn, stringMessages.venue());
eventTable.addColumn(startEndDateColumn, stringMessages.from() + "/" + stringMessages.to());
eventTable.addColumn(isPublicColumn, stringMessages.isPublic());
eventTable.addColumn(courseAreasColumn, stringMessages.courseAreas());
eventTable.addColumn(leaderboardGroupsColumn, stringMessages.leaderboardGroups());
eventTable.addColumn(imageURLsColumn, stringMessages.imageURLs());
eventTable.addColumn(videoURLsColumn, stringMessages.videoURLs());
eventTable.addColumn(sponsorImageURLsColumn, stringMessages.sponsorImageURLs());
eventTable.addColumn(associatedRegattasColumn, stringMessages.regattas());
eventTable.addColumn(eventActionColumn, stringMessages.actions());
eventSelectionModel = new MultiSelectionModel<EventDTO>();
eventSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
final boolean somethingSelected = !eventSelectionModel.getSelectedSet().isEmpty();
removeEventsButton.setEnabled(somethingSelected);
updateLeaderboardGroupAssignmentPanel(eventSelectionModel.getSelectedSet());
}
});
eventTable.setSelectionModel(eventSelectionModel);
eventProvider = new ListDataProvider<EventDTO>();
eventProvider.addDataDisplay(eventTable);
mainPanel.add(eventTable);
allEvents = new ArrayList<EventDTO>();
eventTable.addColumnSortHandler(getEventTableColumnSortHandler(eventProvider.getList(), eventNameColumn,
venueNameColumn, startEndDateColumn, isPublicColumn));
eventTable.getColumnSortList().push(startEndDateColumn);
filterTextbox = new LabeledAbstractFilterablePanel<EventDTO>(new Label(stringMessages.filterEventsByName()), allEvents,
eventTable, eventProvider) {
@Override
public Iterable<String> getSearchableStrings(EventDTO t) {
List<String> result = new ArrayList<String>();
result.add(t.getName());
result.add(t.venue.getName());
for (CourseAreaDTO c : t.venue.getCourseAreas()) {
result.add(c.getName());
}
for (LeaderboardGroupDTO lg : t.getLeaderboardGroups()) {
result.add(lg.getName());
}
return result;
}
};
eventsPanel.add(filterTextbox);
fillEvents();
// prepare the caption panels and buttons for leaderboard group assignment but leave invisible for now
splitPanel = new HorizontalPanel();
splitPanel.ensureDebugId("EventLeaderboardGroupsAssignmentDetailsPanel");
splitPanel.setSpacing(5);
splitPanel.setWidth("100%");
splitPanel.setVisible(false);
mainPanel.add(splitPanel);
splitPanel.setVerticalAlignment(HorizontalPanel.ALIGN_TOP);
final Widget switchingButtonsPanel = createSwitchLeaderboardGroupsGUI(); // initialize this before the two tables because their event
// handlers require the buttons to be assigned
splitPanel.add(createLeaderboardGroupOfEventsPanel());
splitPanel.add(switchingButtonsPanel);
splitPanel.add(createAvailableLeaderboardGroupsPanel());
}
private Widget createLeaderboardGroupOfEventsPanel() {
selectedEventLeaderboardGroupsTable = new CellTable<LeaderboardGroupDTO>(10000000, tableRes);
CaptionPanel result = new CaptionPanel(stringMessages.leaderboardGroupsOfSelectedEvent());
result.add(selectedEventLeaderboardGroupsTable);
selectedEventLeaderboardGroupsSelectionModel = new MultiSelectionModel<>();
selectedEventLeaderboardGroupsSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
removeFromEventButton.setEnabled(!selectedEventLeaderboardGroupsSelectionModel.getSelectedSet().isEmpty());
}
});
selectedEventLeaderboardGroupsTable.setSelectionModel(selectedEventLeaderboardGroupsSelectionModel);
selectedEventLeaderboardGroupsProvider = new ListDataProvider<>();
selectedEventLeaderboardGroupsProvider.addDataDisplay(selectedEventLeaderboardGroupsTable);
TextColumn<LeaderboardGroupDTO> leaderboardGroupNameColumn = new TextColumn<LeaderboardGroupDTO>() {
@Override
public String getValue(LeaderboardGroupDTO event) {
return event.getName();
}
};
TextColumn<LeaderboardGroupDTO> leaderboardGroupDescriptionColumn = new TextColumn<LeaderboardGroupDTO>() {
@Override
public String getValue(LeaderboardGroupDTO event) {
String result = event.description;
if(event.description != null && event.description.length() > 40) {
result = event.description.substring(0, 40) + "...";
}
return result;
}
};
final SafeHtmlCell leaderboardsCell = new SafeHtmlCell();
Column<LeaderboardGroupDTO, SafeHtml> associatedLeaderboardsColumn = new Column<LeaderboardGroupDTO, SafeHtml>(leaderboardsCell) {
@Override
public SafeHtml getValue(LeaderboardGroupDTO leaderboardGroup) {
SafeHtmlBuilder builder = new SafeHtmlBuilder();
boolean first = true;
for (StrippedLeaderboardDTO leaderboard : leaderboardGroup.getLeaderboards()) {
if (first) {
first = false;
} else {
builder.appendHtmlConstant("<br>");
}
builder.appendEscaped(leaderboard.name);
}
return builder.toSafeHtml();
}
};
leaderboardGroupNameColumn.setSortable(true);
leaderboardGroupDescriptionColumn.setSortable(true);
selectedEventLeaderboardGroupsTable.addColumn(leaderboardGroupNameColumn, stringMessages.name());
selectedEventLeaderboardGroupsTable.addColumn(leaderboardGroupDescriptionColumn, stringMessages.description());
selectedEventLeaderboardGroupsTable.addColumn(associatedLeaderboardsColumn, stringMessages.leaderboards());
ListHandler<LeaderboardGroupDTO> sortHandler = new ListHandler<LeaderboardGroupDTO>(selectedEventLeaderboardGroupsProvider.getList());
sortHandler.setComparator(leaderboardGroupNameColumn, new Comparator<LeaderboardGroupDTO>() {
@Override
public int compare(LeaderboardGroupDTO e1, LeaderboardGroupDTO e2) {
return new NaturalComparator().compare(e1.getName(), e2.getName());
}
});
sortHandler.setComparator(leaderboardGroupDescriptionColumn, new Comparator<LeaderboardGroupDTO>() {
@Override
public int compare(LeaderboardGroupDTO e1, LeaderboardGroupDTO e2) {
return new NaturalComparator().compare(e1.description, e2.description);
}
});
selectedEventLeaderboardGroupsTable.addColumnSortHandler(sortHandler);
return result;
}
private Widget createAvailableLeaderboardGroupsPanel() {
availableLeaderboardGroupsTable = new CellTable<LeaderboardGroupDTO>(10000000, tableRes);
CaptionPanel result = new CaptionPanel(stringMessages.availableLeaderboardGroups());
availableLeaderboardGroupsSelectionModel = new MultiSelectionModel<>();
availableLeaderboardGroupsSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
addToEventButton.setEnabled(!availableLeaderboardGroupsSelectionModel.getSelectedSet().isEmpty());
}
});
availableLeaderboardGroupsTable.setSelectionModel(availableLeaderboardGroupsSelectionModel);
availableLeaderboardGroupsProvider = new ListDataProvider<>();
availableLeaderboardGroupsProvider.addDataDisplay(availableLeaderboardGroupsTable);
availableLeaderboardGroupsFilterablePanel = new LabeledAbstractFilterablePanel<LeaderboardGroupDTO>(new Label(
stringMessages.filterLeaderboardGroupsByName()), Collections.<LeaderboardGroupDTO> emptyList(),
availableLeaderboardGroupsTable, availableLeaderboardGroupsProvider) {
@Override
public Iterable<String> getSearchableStrings(LeaderboardGroupDTO t) {
List<String> result = new ArrayList<>();
result.add(t.getName());
result.add(t.description);
return result;
}
};
VerticalPanel vp = new VerticalPanel();
vp.add(availableLeaderboardGroupsFilterablePanel);
vp.add(availableLeaderboardGroupsTable);
result.add(vp);
TextColumn<LeaderboardGroupDTO> leaderboardGroupNameColumn = new TextColumn<LeaderboardGroupDTO>() {
@Override
public String getValue(LeaderboardGroupDTO event) {
return event.getName();
}
};
TextColumn<LeaderboardGroupDTO> leaderboardGroupDescriptionColumn = new TextColumn<LeaderboardGroupDTO>() {
@Override
public String getValue(LeaderboardGroupDTO event) {
String result = event.description;
if(event.description != null && event.description.length() > 40) {
result = event.description.substring(0, 40) + "...";
}
return result;
}
};
final SafeHtmlCell leaderboardsCell = new SafeHtmlCell();
Column<LeaderboardGroupDTO, SafeHtml> associatedLeaderboardsColumn = new Column<LeaderboardGroupDTO, SafeHtml>(leaderboardsCell) {
@Override
public SafeHtml getValue(LeaderboardGroupDTO leaderboardGroup) {
SafeHtmlBuilder builder = new SafeHtmlBuilder();
boolean first = true;
for (StrippedLeaderboardDTO leaderboard : leaderboardGroup.getLeaderboards()) {
if (first) {
first = false;
} else {
builder.appendHtmlConstant("<br>");
}
builder.appendEscaped(leaderboard.name);
}
return builder.toSafeHtml();
}
};
leaderboardGroupNameColumn.setSortable(true);
leaderboardGroupDescriptionColumn.setSortable(true);
availableLeaderboardGroupsTable.addColumn(leaderboardGroupNameColumn, stringMessages.name());
availableLeaderboardGroupsTable.addColumn(leaderboardGroupDescriptionColumn, stringMessages.description());
availableLeaderboardGroupsTable.addColumn(associatedLeaderboardsColumn, stringMessages.leaderboards());
ListHandler<LeaderboardGroupDTO> sortHandler = new ListHandler<LeaderboardGroupDTO>(availableLeaderboardGroupsProvider.getList());
sortHandler.setComparator(leaderboardGroupNameColumn, new Comparator<LeaderboardGroupDTO>() {
@Override
public int compare(LeaderboardGroupDTO e1, LeaderboardGroupDTO e2) {
return new NaturalComparator().compare(e1.getName(), e2.getName());
}
});
sortHandler.setComparator(leaderboardGroupDescriptionColumn, new Comparator<LeaderboardGroupDTO>() {
@Override
public int compare(LeaderboardGroupDTO e1, LeaderboardGroupDTO e2) {
return new NaturalComparator().compare(e1.description, e2.description);
}
});
availableLeaderboardGroupsTable.addColumnSortHandler(sortHandler);
return result;
}
private void updateLeaderboardGroupAssignmentPanel(Set<EventDTO> set) {
if (set.isEmpty() || set.size() > 1) {
splitPanel.setVisible(false);
} else {
splitPanel.setVisible(true);
selectedEventLeaderboardGroupsProvider.getList().clear();
final Iterable<LeaderboardGroupDTO> leaderboardGroupsOfSelectedEvent = set.iterator().next().getLeaderboardGroups();
Util.addAll(leaderboardGroupsOfSelectedEvent, selectedEventLeaderboardGroupsProvider.getList());
// deselect all items that are no longer in the list; this shall adjust the switch button enablement
for (LeaderboardGroupDTO lg : selectedEventLeaderboardGroupsSelectionModel.getSelectedSet()) {
if (!selectedEventLeaderboardGroupsProvider.getList().contains(lg)) {
selectedEventLeaderboardGroupsSelectionModel.setSelected(lg, false);
}
}
selectedEventLeaderboardGroupsProvider.refresh();
List<LeaderboardGroupDTO> allButEventsLeaderboardGroups = new ArrayList<>();
Util.addAll(availableLeaderboardGroups, allButEventsLeaderboardGroups);
Util.removeAll(leaderboardGroupsOfSelectedEvent, allButEventsLeaderboardGroups);
availableLeaderboardGroupsFilterablePanel.updateAll(allButEventsLeaderboardGroups);
// deselect all items that are no longer in the list; this shall adjust the switch button enablement
for (LeaderboardGroupDTO lg : availableLeaderboardGroupsSelectionModel.getSelectedSet()) {
if (!allButEventsLeaderboardGroups.contains(lg)) {
availableLeaderboardGroupsSelectionModel.setSelected(lg, false);
}
}
addToEventButton.setEnabled(!availableLeaderboardGroupsSelectionModel.getSelectedSet().isEmpty());
removeFromEventButton.setEnabled(!selectedEventLeaderboardGroupsSelectionModel.getSelectedSet().isEmpty());
}
}
private Widget createSwitchLeaderboardGroupsGUI() {
VerticalPanel switchLeaderboardGroupsPanel = new VerticalPanel();
switchLeaderboardGroupsPanel.setSpacing(5);
switchLeaderboardGroupsPanel.setWidth("5%");
addToEventButton = new Button("<-");
addToEventButton.ensureDebugId("AddLeaderboardGroupsButton");
addToEventButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
addSelectedLeaderboardGroupsToEvent();
}
});
addToEventButton.setEnabled(false);
switchLeaderboardGroupsPanel.add(addToEventButton);
removeFromEventButton = new Button("->");
removeFromEventButton.ensureDebugId("RemoveLeaderboardGroupsButton");
removeFromEventButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
removeSelectedLeaderboardGroupsFromEvent();
}
});
removeFromEventButton.setEnabled(false);
switchLeaderboardGroupsPanel.add(removeFromEventButton);
return switchLeaderboardGroupsPanel;
}
private void addSelectedLeaderboardGroupsToEvent() {
Set<LeaderboardGroupDTO> leaderboardGroupsToAdd = availableLeaderboardGroupsSelectionModel.getSelectedSet();
EventDTO selectedEvent = eventSelectionModel.getSelectedSet().iterator().next();
List<UUID> eventLeaderboardGroupUUIDs = new ArrayList<>();
for (LeaderboardGroupDTO lg : selectedEvent.getLeaderboardGroups()) {
eventLeaderboardGroupUUIDs.add(lg.getId());
}
for (LeaderboardGroupDTO lg : leaderboardGroupsToAdd) {
eventLeaderboardGroupUUIDs.add(lg.getId());
}
updateEventLeaderboardGroups(selectedEvent, eventLeaderboardGroupUUIDs);
}
private void updateEventLeaderboardGroups(final EventDTO event, List<UUID> eventLeaderboardGroupUUIDs) {
sailingService.updateEvent(event.id, event.getName(), event.getDescription(), event.startDate, event.endDate, event.venue,
event.isPublic, eventLeaderboardGroupUUIDs, event.getOfficialWebsiteURL(), event.getLogoImageURL(),
event.getImageURLs(), event.getVideoURLs(), event.getSponsorImageURLs(),
new AsyncCallback<EventDTO>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to update event's leaderboard list: "+caught.getMessage());
}
@Override
public void onSuccess(EventDTO updatedEvent) {
final boolean eventWasSelected = eventSelectionModel.getSelectedSet().contains(event);
if (eventWasSelected) {
eventSelectionModel.setSelected(event, false);
}
// replace event in events table and re-calculate everything else from there
int i=0;
for (EventDTO e : allEvents) {
if (e.id.equals(updatedEvent.id)) {
allEvents.set(i, updatedEvent);
filterTextbox.updateAll(allEvents);
if (eventWasSelected) {
eventSelectionModel.setSelected(updatedEvent, true);
}
updateLeaderboardGroupAssignmentPanel(eventSelectionModel.getSelectedSet());
break;
}
i++;
}
}
});
}
private void removeSelectedLeaderboardGroupsFromEvent() {
Set<LeaderboardGroupDTO> leaderboardGroupsToRemove = selectedEventLeaderboardGroupsSelectionModel.getSelectedSet();
EventDTO selectedEvent = eventSelectionModel.getSelectedSet().iterator().next();
List<UUID> eventLeaderboardGroupUUIDs = new ArrayList<>();
for (LeaderboardGroupDTO lg : selectedEvent.getLeaderboardGroups()) {
eventLeaderboardGroupUUIDs.add(lg.getId());
}
for (LeaderboardGroupDTO lg : leaderboardGroupsToRemove) {
eventLeaderboardGroupUUIDs.remove(lg.getId());
}
updateEventLeaderboardGroups(selectedEvent, eventLeaderboardGroupUUIDs);
}
private ListHandler<EventDTO> getEventTableColumnSortHandler(List<EventDTO> eventRecords,
Column<EventDTO, SafeHtml> eventNameColumn, TextColumn<EventDTO> venueNameColumn,
TextColumn<EventDTO> startEndDateColumn, TextColumn<EventDTO> isPublicColumn) {
ListHandler<EventDTO> result = new ListHandler<EventDTO>(eventRecords);
result.setComparator(eventNameColumn, new Comparator<EventDTO>() {
@Override
public int compare(EventDTO e1, EventDTO e2) {
return new NaturalComparator().compare(e1.getName(), e2.getName());
}
});
result.setComparator(venueNameColumn, new Comparator<EventDTO>() {
@Override
public int compare(EventDTO e1, EventDTO e2) {
return new NaturalComparator().compare(e1.venue.getName(), e2.venue.getName());
}
});
result.setComparator(startEndDateColumn, new Comparator<EventDTO>() {
@Override
public int compare(EventDTO e1, EventDTO e2) {
int result;
if(e1.startDate != null && e2.startDate != null) {
result = e2.startDate.compareTo(e1.startDate);
} else if(e1.startDate == null && e2.startDate != null) {
result = 1;
} else if(e1.startDate != null && e2.startDate == null) {
result = -1;
} else {
result = 0;
}
return result;
}
});
result.setComparator(isPublicColumn, new Comparator<EventDTO>() {
@Override
public int compare(EventDTO e1, EventDTO e2) {
return e1.isPublic == e2.isPublic ? 0 : e1.isPublic ? 1 : -1;
}
});
return result;
}
private void removeEvents(Collection<EventDTO> events) {
if (!events.isEmpty()) {
Collection<UUID> eventIds = new HashSet<UUID>();
for (EventDTO event : events) {
eventIds.add(event.id);
}
sailingService.removeEvents(eventIds, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to remove the events:" + caught.getMessage());
}
@Override
public void onSuccess(Void result) {
fillEvents();
}
});
}
}
private void removeEvent(final EventDTO event) {
sailingService.removeEvent(event.id, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to remove event " + event.getName() + ": " + caught.getMessage());
}
@Override
public void onSuccess(Void result) {
fillEvents();
}
});
}
private void openCreateEventDialog() {
List<EventDTO> existingEvents = new ArrayList<EventDTO>(eventProvider.getList());
EventCreateDialog dialog = new EventCreateDialog(Collections.unmodifiableCollection(existingEvents), stringMessages,
new DialogCallback<EventDTO>() {
@Override
public void cancel() {
}
@Override
public void ok(EventDTO newEvent) {
createNewEvent(newEvent);
}
});
dialog.show();
}
private void openEditEventDialog(final EventDTO selectedEvent) {
List<EventDTO> existingEvents = new ArrayList<EventDTO>(eventProvider.getList());
existingEvents.remove(selectedEvent);
EventEditDialog dialog = new EventEditDialog(selectedEvent, Collections.unmodifiableCollection(existingEvents), stringMessages,
new DialogCallback<EventDTO>() {
@Override
public void cancel() {
}
@Override
public void ok(EventDTO updatedEvent) {
updateEvent(selectedEvent, updatedEvent);
}
});
dialog.show();
}
private void updateEvent(final EventDTO oldEvent, final EventDTO updatedEvent) {
Pair<List<CourseAreaDTO>, List<CourseAreaDTO>> courseAreasToAddAndRemove = getCourseAreasToAdd(oldEvent, updatedEvent);
List<CourseAreaDTO> courseAreasToAdd = courseAreasToAddAndRemove.getA();
List<CourseAreaDTO> courseAreasToRemove = courseAreasToAddAndRemove.getB();
List<UUID> updatedEventLeaderboardGroupIds = new ArrayList<>();
for (LeaderboardGroupDTO leaderboardGroup : updatedEvent.getLeaderboardGroups()) {
updatedEventLeaderboardGroupIds.add(leaderboardGroup.getId());
}
sailingService.updateEvent(oldEvent.id, oldEvent.getName(), updatedEvent.getDescription(),
updatedEvent.startDate, updatedEvent.endDate, updatedEvent.venue,
updatedEvent.isPublic, updatedEventLeaderboardGroupIds,
updatedEvent.getOfficialWebsiteURL(), updatedEvent.getLogoImageURL(),
updatedEvent.getImageURLs(), updatedEvent.getVideoURLs(), updatedEvent.getSponsorImageURLs(),
new AsyncCallback<EventDTO>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to update sailing event" + oldEvent.getName() + ": " + t.getMessage());
}
@Override
public void onSuccess(EventDTO result) {
fillEvents();
if (!oldEvent.getName().equals(updatedEvent.getName())) {
sailingService.renameEvent(oldEvent.id, updatedEvent.getName(), new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
fillEvents();
}
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to rename sailing event " + oldEvent.getName() + ": " + t.getMessage());
}
});
}
}
});
for (CourseAreaDTO courseArea : courseAreasToAdd) {
sailingService.createCourseArea(oldEvent.id, courseArea.getName(), new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to add course area to sailing event " + oldEvent.getName()
+ ": " + t.getMessage());
}
@Override
public void onSuccess(Void result) {
fillEvents();
}
});
}
for (CourseAreaDTO courseArea : courseAreasToRemove) {
sailingService.removeCourseArea(oldEvent.id, courseArea.id, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to remove course area from sailing event " + oldEvent.getName()
+ ": " + t.getMessage());
}
@Override
public void onSuccess(Void result) {
fillEvents();
}
});
}
}
private Pair<List<CourseAreaDTO>, List<CourseAreaDTO>> getCourseAreasToAdd(final EventDTO oldEvent, final EventDTO updatedEvent) {
List<CourseAreaDTO> courseAreasToAdd = new ArrayList<CourseAreaDTO>(updatedEvent.venue.getCourseAreas());
courseAreasToAdd.removeAll(oldEvent.venue.getCourseAreas());
List<CourseAreaDTO> courseAreasToRemove = new ArrayList<CourseAreaDTO>(oldEvent.venue.getCourseAreas());
courseAreasToRemove.removeAll(updatedEvent.venue.getCourseAreas());
return new Pair<List<CourseAreaDTO>, List<CourseAreaDTO>>(courseAreasToAdd, courseAreasToRemove);
}
private void createNewEvent(final EventDTO newEvent) {
List<String> courseAreaNames = new ArrayList<String>();
for (CourseAreaDTO courseAreaDTO : newEvent.venue.getCourseAreas()) {
courseAreaNames.add(courseAreaDTO.getName());
}
sailingService.createEvent(newEvent.getName(), newEvent.getDescription(), newEvent.startDate, newEvent.endDate,
newEvent.venue.getName(), newEvent.isPublic, courseAreaNames, newEvent.getImageURLs(),
newEvent.getVideoURLs(), newEvent.getSponsorImageURLs(), newEvent.getLogoImageURL(),
newEvent.getOfficialWebsiteURL(), new AsyncCallback<EventDTO>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to create new event " + newEvent.getName() + ": " + t.getMessage());
}
@Override
public void onSuccess(EventDTO newEvent) {
fillEvents();
}
});
eventDetailsComposite = new EventDetailsComposite(sailingService, errorReporter, stringMessages);
eventDetailsComposite.ensureDebugId("EventDetailsComposite");
eventDetailsComposite.setVisible(false);
mainPanel.add(eventDetailsComposite);
}
@Override
public void fillEvents() {
sailingService.getEvents(new AsyncCallback<List<EventDTO>>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Remote Procedure Call getEvents() - Failure: " + caught.getMessage());
}
@Override
public void onSuccess(List<EventDTO> result) {
Set<UUID> selectedEventUUIDs = new HashSet<>();
for (EventDTO selectedEvent : eventSelectionModel.getSelectedSet()) {
selectedEventUUIDs.add(selectedEvent.id);
}
eventSelectionModel.clear();
allEvents.clear();
allEvents.addAll(result);
filterTextbox.updateAll(allEvents);
for (EventDTO e : allEvents) {
if (selectedEventUUIDs.contains(e.id)) {
eventSelectionModel.setSelected(e, true);
}
}
updateLeaderboardGroupAssignmentPanel(eventSelectionModel.getSelectedSet());
}
});
eventListComposite.fillEvents();
}
@Override
public void fillLeaderboardGroups(Iterable<LeaderboardGroupDTO> leaderboardGroups) {
availableLeaderboardGroups = leaderboardGroups;
updateLeaderboardGroupAssignmentPanel(eventSelectionModel.getSelectedSet());
eventListComposite.fillLeaderboardGroups(leaderboardGroups);
}
@Override
public void onEventSelectionChange(List<UUID> selectedEvents) {
final UUID selectedEventUUID;
if (selectedEvents.size() == 1 && eventListComposite.getAllEvents() != null) {
selectedEventUUID = selectedEvents.get(0);
for (EventDTO eventDTO : eventListComposite.getAllEvents()) {
if (eventDTO.id.equals(selectedEventUUID)) {
eventDetailsComposite.setEvent(eventDTO);
eventDetailsComposite.setVisible(true);
break;
}
}
} else {
eventDetailsComposite.setEvent(null);
eventDetailsComposite.setVisible(false);
}
}
}
@@ -0,0 +1,289 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import com.google.gwt.cell.client.SafeHtmlCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.sap.sailing.domain.common.impl.NaturalComparator;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sse.common.Util;
import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
public class LeaderboardGroupSelectorComposite extends Composite implements HasValueChangeHandlers<Iterable<LeaderboardGroupDTO>> {
private final StringMessages stringMessages;
private CellTable<LeaderboardGroupDTO> selectedEventLeaderboardGroupsTable;
private MultiSelectionModel<LeaderboardGroupDTO> selectedEventLeaderboardGroupsSelectionModel;
private ListDataProvider<LeaderboardGroupDTO> selectedEventLeaderboardGroupsProvider;
private LabeledAbstractFilterablePanel<LeaderboardGroupDTO> availableLeaderboardGroupsFilterablePanel;
private CellTable<LeaderboardGroupDTO> availableLeaderboardGroupsTable;
private MultiSelectionModel<LeaderboardGroupDTO> availableLeaderboardGroupsSelectionModel;
private ListDataProvider<LeaderboardGroupDTO> availableLeaderboardGroupsProvider;
private List<LeaderboardGroupDTO> availableLeaderboardGroups;
private List<LeaderboardGroupDTO> leaderboardGroups;
private Button addToEventButton;
private Button removeFromEventButton;
private final HorizontalPanel splitPanel;
private final AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class);
public LeaderboardGroupSelectorComposite(List<LeaderboardGroupDTO> leaderboardGroups, List<LeaderboardGroupDTO> availableLeaderboardGroups, final StringMessages stringMessages) {
super();
this.leaderboardGroups = leaderboardGroups;
this.availableLeaderboardGroups = availableLeaderboardGroups;
this.stringMessages = stringMessages;
splitPanel = new HorizontalPanel();
splitPanel.ensureDebugId("EventLeaderboardGroupsAssignmentDetailsPanel");
splitPanel.setSpacing(5);
splitPanel.setWidth("100%");
splitPanel.setVerticalAlignment(HorizontalPanel.ALIGN_TOP);
final Widget switchingButtonsPanel = createSwitchLeaderboardGroupsGUI();
splitPanel.add(createLeaderboardGroupOfEventsPanel());
splitPanel.add(switchingButtonsPanel);
splitPanel.add(createAvailableLeaderboardGroupsPanel());
initWidget(splitPanel);
}
private Widget createLeaderboardGroupOfEventsPanel() {
selectedEventLeaderboardGroupsTable = new CellTable<LeaderboardGroupDTO>(10000000, tableRes);
CaptionPanel result = new CaptionPanel(stringMessages.leaderboardGroupsOfSelectedEvent());
result.add(selectedEventLeaderboardGroupsTable);
selectedEventLeaderboardGroupsSelectionModel = new MultiSelectionModel<>();
selectedEventLeaderboardGroupsSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
removeFromEventButton.setEnabled(!selectedEventLeaderboardGroupsSelectionModel.getSelectedSet().isEmpty());
}
});
selectedEventLeaderboardGroupsTable.setSelectionModel(selectedEventLeaderboardGroupsSelectionModel);
selectedEventLeaderboardGroupsProvider = new ListDataProvider<>();
selectedEventLeaderboardGroupsProvider.addDataDisplay(selectedEventLeaderboardGroupsTable);
TextColumn<LeaderboardGroupDTO> leaderboardGroupNameColumn = new TextColumn<LeaderboardGroupDTO>() {
@Override
public String getValue(LeaderboardGroupDTO event) {
return event.getName();
}
};
final SafeHtmlCell leaderboardsCell = new SafeHtmlCell();
Column<LeaderboardGroupDTO, SafeHtml> associatedLeaderboardsColumn = new Column<LeaderboardGroupDTO, SafeHtml>(leaderboardsCell) {
@Override
public SafeHtml getValue(LeaderboardGroupDTO leaderboardGroup) {
SafeHtmlBuilder builder = new SafeHtmlBuilder();
boolean first = true;
for (StrippedLeaderboardDTO leaderboard : leaderboardGroup.getLeaderboards()) {
if (first) {
first = false;
} else {
builder.appendHtmlConstant("<br>");
}
builder.appendEscaped(leaderboard.name);
}
return builder.toSafeHtml();
}
};
leaderboardGroupNameColumn.setSortable(true);
selectedEventLeaderboardGroupsTable.addColumn(leaderboardGroupNameColumn, stringMessages.name());
selectedEventLeaderboardGroupsTable.addColumn(associatedLeaderboardsColumn, stringMessages.leaderboards());
ListHandler<LeaderboardGroupDTO> sortHandler = new ListHandler<LeaderboardGroupDTO>(selectedEventLeaderboardGroupsProvider.getList());
sortHandler.setComparator(leaderboardGroupNameColumn, new Comparator<LeaderboardGroupDTO>() {
@Override
public int compare(LeaderboardGroupDTO e1, LeaderboardGroupDTO e2) {
return new NaturalComparator().compare(e1.getName(), e2.getName());
}
});
selectedEventLeaderboardGroupsTable.addColumnSortHandler(sortHandler);
return result;
}
private Widget createAvailableLeaderboardGroupsPanel() {
availableLeaderboardGroupsTable = new CellTable<LeaderboardGroupDTO>(10000000, tableRes);
CaptionPanel result = new CaptionPanel(stringMessages.availableLeaderboardGroups());
availableLeaderboardGroupsSelectionModel = new MultiSelectionModel<>();
availableLeaderboardGroupsSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
addToEventButton.setEnabled(!availableLeaderboardGroupsSelectionModel.getSelectedSet().isEmpty());
}
});
availableLeaderboardGroupsTable.setSelectionModel(availableLeaderboardGroupsSelectionModel);
availableLeaderboardGroupsProvider = new ListDataProvider<>();
availableLeaderboardGroupsProvider.setList(availableLeaderboardGroups);
availableLeaderboardGroupsProvider.addDataDisplay(availableLeaderboardGroupsTable);
availableLeaderboardGroupsFilterablePanel = new LabeledAbstractFilterablePanel<LeaderboardGroupDTO>(new Label(
stringMessages.filterLeaderboardGroupsByName()), Collections.<LeaderboardGroupDTO> emptyList(),
availableLeaderboardGroupsTable, availableLeaderboardGroupsProvider) {
@Override
public Iterable<String> getSearchableStrings(LeaderboardGroupDTO t) {
List<String> result = new ArrayList<>();
result.add(t.getName());
return result;
}
};
VerticalPanel vp = new VerticalPanel();
vp.add(availableLeaderboardGroupsFilterablePanel);
vp.add(availableLeaderboardGroupsTable);
result.add(vp);
TextColumn<LeaderboardGroupDTO> leaderboardGroupNameColumn = new TextColumn<LeaderboardGroupDTO>() {
@Override
public String getValue(LeaderboardGroupDTO event) {
return event.getName();
}
};
final SafeHtmlCell leaderboardsCell = new SafeHtmlCell();
Column<LeaderboardGroupDTO, SafeHtml> associatedLeaderboardsColumn = new Column<LeaderboardGroupDTO, SafeHtml>(leaderboardsCell) {
@Override
public SafeHtml getValue(LeaderboardGroupDTO leaderboardGroup) {
SafeHtmlBuilder builder = new SafeHtmlBuilder();
boolean first = true;
for (StrippedLeaderboardDTO leaderboard : leaderboardGroup.getLeaderboards()) {
if (first) {
first = false;
} else {
builder.appendHtmlConstant("<br>");
}
builder.appendEscaped(leaderboard.name);
}
return builder.toSafeHtml();
}
};
leaderboardGroupNameColumn.setSortable(true);
availableLeaderboardGroupsTable.addColumn(leaderboardGroupNameColumn, stringMessages.name());
availableLeaderboardGroupsTable.addColumn(associatedLeaderboardsColumn, stringMessages.leaderboards());
ListHandler<LeaderboardGroupDTO> sortHandler = new ListHandler<LeaderboardGroupDTO>(availableLeaderboardGroupsProvider.getList());
sortHandler.setComparator(leaderboardGroupNameColumn, new Comparator<LeaderboardGroupDTO>() {
@Override
public int compare(LeaderboardGroupDTO e1, LeaderboardGroupDTO e2) {
return new NaturalComparator().compare(e1.getName(), e2.getName());
}
});
availableLeaderboardGroupsTable.addColumnSortHandler(sortHandler);
return result;
}
private void updateLeaderboardGroupAssignmentPanel() {
selectedEventLeaderboardGroupsProvider.getList().clear();
Util.addAll(leaderboardGroups, selectedEventLeaderboardGroupsProvider.getList());
// deselect all items that are no longer in the list; this shall adjust the switch button enablement
for (LeaderboardGroupDTO lg : selectedEventLeaderboardGroupsSelectionModel.getSelectedSet()) {
if (!selectedEventLeaderboardGroupsProvider.getList().contains(lg)) {
selectedEventLeaderboardGroupsSelectionModel.setSelected(lg, false);
}
}
selectedEventLeaderboardGroupsProvider.refresh();
List<LeaderboardGroupDTO> allButEventsLeaderboardGroups = new ArrayList<>();
Util.addAll(availableLeaderboardGroups, allButEventsLeaderboardGroups);
Util.removeAll(leaderboardGroups, allButEventsLeaderboardGroups);
availableLeaderboardGroupsFilterablePanel.updateAll(allButEventsLeaderboardGroups);
// deselect all items that are no longer in the list; this shall adjust the switch button enablement
for (LeaderboardGroupDTO lg : availableLeaderboardGroupsSelectionModel.getSelectedSet()) {
if (!allButEventsLeaderboardGroups.contains(lg)) {
availableLeaderboardGroupsSelectionModel.setSelected(lg, false);
}
}
addToEventButton.setEnabled(!availableLeaderboardGroupsSelectionModel.getSelectedSet().isEmpty());
removeFromEventButton.setEnabled(!selectedEventLeaderboardGroupsSelectionModel.getSelectedSet().isEmpty());
}
private Widget createSwitchLeaderboardGroupsGUI() {
VerticalPanel switchLeaderboardGroupsPanel = new VerticalPanel();
switchLeaderboardGroupsPanel.setSpacing(5);
switchLeaderboardGroupsPanel.setWidth("5%");
addToEventButton = new Button("<-");
addToEventButton.ensureDebugId("AddLeaderboardGroupsButton");
addToEventButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
addSelectedLeaderboardGroupsToEvent();
}
});
addToEventButton.setEnabled(false);
switchLeaderboardGroupsPanel.add(addToEventButton);
removeFromEventButton = new Button("->");
removeFromEventButton.ensureDebugId("RemoveLeaderboardGroupsButton");
removeFromEventButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
removeSelectedLeaderboardGroupsFromEvent();
}
});
removeFromEventButton.setEnabled(false);
switchLeaderboardGroupsPanel.add(removeFromEventButton);
return switchLeaderboardGroupsPanel;
}
private void addSelectedLeaderboardGroupsToEvent() {
Set<LeaderboardGroupDTO> leaderboardGroupsToAdd = availableLeaderboardGroupsSelectionModel.getSelectedSet();
List<UUID> eventLeaderboardGroupUUIDs = new ArrayList<>();
for (LeaderboardGroupDTO lg : leaderboardGroups) {
eventLeaderboardGroupUUIDs.add(lg.getId());
}
for (LeaderboardGroupDTO lg : leaderboardGroupsToAdd) {
eventLeaderboardGroupUUIDs.add(lg.getId());
}
}
private void removeSelectedLeaderboardGroupsFromEvent() {
Set<LeaderboardGroupDTO> leaderboardGroupsToRemove = selectedEventLeaderboardGroupsSelectionModel.getSelectedSet();
List<UUID> eventLeaderboardGroupUUIDs = new ArrayList<>();
for (LeaderboardGroupDTO lg : leaderboardGroups) {
eventLeaderboardGroupUUIDs.add(lg.getId());
}
for (LeaderboardGroupDTO lg : leaderboardGroupsToRemove) {
eventLeaderboardGroupUUIDs.remove(lg.getId());
}
}
@Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Iterable<LeaderboardGroupDTO>> handler) {
return addHandler(handler, ValueChangeEvent.getType());
}
public Set<LeaderboardGroupDTO> getSelectedLeaderboardGroups() {
return selectedEventLeaderboardGroupsSelectionModel.getSelectedSet();
}
public void setLeaderboardGroups(List<LeaderboardGroupDTO> leaderboardGroups) {
selectedEventLeaderboardGroupsProvider.setList(leaderboardGroups);
}
}
@@ -46,6 +46,7 @@ public class RegattaDetailsComposite extends Composite {
private final StringMessages stringMessages;
private final RegattaRefresher regattaRefresher;
private final Label regattaId;
private final Label regattaName;
private final Label boatClassName;
private final Label scoringSystem;
@@ -69,38 +70,19 @@ public class RegattaDetailsComposite extends Composite {
mainPanel = new CaptionPanel(stringMessages.regatta());
VerticalPanel vPanel = new VerticalPanel();
mainPanel.add(vPanel);
Grid grid = new Grid(6, 2);
int rows = 7;
Grid grid = new Grid(rows, 2);
vPanel.add(grid);
regattaName = new Label();
regattaName.ensureDebugId("NameLabel");
grid.setWidget(0 , 0, new Label(stringMessages.regattaName() + ":"));
grid.setWidget(0 , 1, regattaName);
boatClassName = new Label();
boatClassName.ensureDebugId("BoatClassLabel");
grid.setWidget(1 , 0, new Label(stringMessages.boatClass() + ":"));
grid.setWidget(1 , 1, boatClassName);
defaultCourseArea = new Label();
defaultCourseArea.ensureDebugId("CourseAreaLabel");
grid.setWidget(2 , 0, new Label(stringMessages.courseArea() + ":"));
grid.setWidget(2 , 1, defaultCourseArea);
useStartTimeInference = new Label();
useStartTimeInference.ensureDebugId("UseStartTimeInferenceLabel");
grid.setWidget(3 , 0, new Label(stringMessages.useStartTimeInference() + ":"));
grid.setWidget(3 , 1, useStartTimeInference);
configuration = new Label();
configuration.ensureDebugId("RacingProcedureLabel");
grid.setWidget(4, 0, new Label(stringMessages.racingProcedureConfiguration() + ":"));
grid.setWidget(4, 1, configuration);
scoringSystem = new Label();
scoringSystem.ensureDebugId("ScoringSystemLabel");
grid.setWidget(5 , 0, new Label(stringMessages.scoringSystem() + ":"));
grid.setWidget(5 , 1, scoringSystem);
int currentRow = 0;
regattaId = createLabelAndValueWidget(grid, currentRow++, stringMessages.id(), "RegattaIdLabel");
regattaName = createLabelAndValueWidget(grid, currentRow++, stringMessages.regattaName(), "NameLabel");
boatClassName = createLabelAndValueWidget(grid, currentRow++, stringMessages.boatClass(), "BoatClassLabel");
defaultCourseArea = createLabelAndValueWidget(grid, currentRow++, stringMessages.courseArea(), "CourseAreaLabel");
useStartTimeInference = createLabelAndValueWidget(grid, currentRow++, stringMessages.useStartTimeInference(), "UseStartTimeInferenceLabel");
configuration = createLabelAndValueWidget(grid, currentRow++, stringMessages.racingProcedureConfiguration(), "RacingProcedureLabel");
scoringSystem = createLabelAndValueWidget(grid, currentRow++, stringMessages.scoringSystem(), "ScoringSystemLabel");
seriesTable = createRegattaSeriesTable();
seriesTable.ensureDebugId("SeriesCellTable");
@@ -117,6 +99,14 @@ public class RegattaDetailsComposite extends Composite {
initWidget(mainPanel);
}
private Label createLabelAndValueWidget(Grid grid, int row, String label, String debugId) {
Label valueLabel = new Label();
valueLabel.ensureDebugId(debugId);
grid.setWidget(row , 0, new Label(label + ":"));
grid.setWidget(row , 1, valueLabel);
return valueLabel;
}
private CellTable<SeriesDTO> createRegattaSeriesTable() {
CellTable<SeriesDTO> table = new CellTable<SeriesDTO>(/* pageSize */10000, tableRes);
table.setWidth("100%");
@@ -375,6 +365,7 @@ public class RegattaDetailsComposite extends Composite {
private void updateRegattaDetails() {
if (regatta != null) {
mainPanel.setCaptionText(stringMessages.regatta() + " " + regatta.getName());
regattaId.setText(regatta.getName());
regattaName.setText(regatta.getName());
boatClassName.setText(regatta.boatClass != null ? regatta.boatClass.getName() : "");
defaultCourseArea.setText(regatta.defaultCourseAreaUuid == null ? "" : regatta.defaultCourseAreaName);
@@ -40,6 +40,11 @@ import com.sap.sse.gwt.client.async.MarkedAsyncCallback;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
/**
* A composite showing the list of all regattas
* @author Frank
*
*/
public class RegattaListComposite extends Composite implements RegattasDisplayer {
private final MultiSelectionModel<RegattaDTO> regattaSelectionModel;
@@ -76,6 +81,8 @@ public class RegattaListComposite extends Composite implements RegattasDisplayer
this.regattaRefresher = regattaRefresher;
this.errorReporter = errorReporter;
this.stringMessages = stringMessages;
allRegattas = new ArrayList<RegattaDTO>();
mainPanel = new SimplePanel();
panel = new VerticalPanel();
mainPanel.setWidget(panel);
@@ -103,7 +110,7 @@ public class RegattaListComposite extends Composite implements RegattasDisplayer
return string;
}
};
filterablePanelRegattas.getTextBox().ensureDebugId("ReggatasFilterTextBox");
filterablePanelRegattas.getTextBox().ensureDebugId("RegattasFilterTextBox");
panel.add(filterablePanelRegattas);
@SuppressWarnings("unchecked")
@@ -0,0 +1,22 @@
package com.sap.sailing.gwt.ui.client;
import java.util.List;
import java.util.UUID;
/**
* Allows UI components to observe a saling event selector, such as a drop-down box showing a list of sailing events
*
* @author Axel Uhl (d043530)
*
*/
public interface EventSelectionChangeListener {
/**
* The first element is the first one selected
*
* @param selectedEvents a non-<code>null</code> list which is empty if nothing is selected
*/
void onEventSelectionChange(List<UUID> selectedEvents);
}
@@ -0,0 +1,90 @@
package com.sap.sailing.gwt.ui.client;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class EventSelectionModel implements EventSelectionProvider {
private final List<UUID> selection;
private final List<UUID> allEvents;
private final Set<EventSelectionChangeListener> listeners;
private final boolean hasMultiSelection;
public EventSelectionModel(boolean hasMultiSelection) {
this.hasMultiSelection = hasMultiSelection;
this.selection = new ArrayList<UUID>();
this.allEvents = new ArrayList<UUID>();
listeners = new HashSet<EventSelectionChangeListener>();
}
@Override
public List<UUID> getSelectedEvents() {
return Collections.unmodifiableList(selection);
}
@Override
public void addEventSelectionChangeListener(EventSelectionChangeListener listener) {
listeners.add(listener);
}
@Override
public void removeEventSelectionChangeListener(EventSelectionChangeListener listener) {
listeners.remove(listener);
}
@Override
public void setSelection(List<UUID> newSelection, EventSelectionChangeListener... listenersNotToNotify) {
boolean notify = !selection.equals(newSelection);
selection.clear();
selection.addAll(newSelection);
if (notify) {
notifyListeners(listenersNotToNotify);
}
}
private void notifyListeners(EventSelectionChangeListener[] listenersNotToNotify) {
List<UUID> selectedEvents = getSelectedEvents();
for (EventSelectionChangeListener listener : listeners) {
if (listenersNotToNotify == null || !Arrays.asList(listenersNotToNotify).contains(listener)) {
listener.onEventSelectionChange(selectedEvents);
}
}
}
/**
* Sets the universe of all (sailing) events from which this selection model may select. An equal list will subsequently be
* returned by {@link #getallEvents()}. Events from the {@link #getSelectedEvents() selection} not in
* <code>newEvents</code> are removed from the selection. If this happens, the selection listeners are notified.
*/
@Override
public void setAllEvents(List<UUID> newEvents, EventSelectionChangeListener... listenersNotToNotify) {
allEvents.clear();
for (UUID r : newEvents) {
allEvents.add(r);
}
for (Iterator<UUID> i=selection.iterator(); i.hasNext(); ) {
UUID selectedRegatta = i.next();
if (!allEvents.contains(selectedRegatta)) {
i.remove();
}
}
// when setting all events, the actual EventDTOs will usually have changed their identity and maybe also their state;
// so notifying the selection listeners is necessary anyhow
notifyListeners(listenersNotToNotify);
}
@Override
public List<UUID> getAllEvents() {
return Collections.unmodifiableList(allEvents);
}
@Override
public boolean hasMultiSelection() {
return hasMultiSelection;
}
}
@@ -0,0 +1,26 @@
package com.sap.sailing.gwt.ui.client;
import java.util.List;
import java.util.UUID;
public interface EventSelectionProvider {
/**
* @return a non-<code>null</code> list which may be empty
*/
List<UUID> getSelectedEvents();
void addEventSelectionChangeListener(EventSelectionChangeListener listener);
void removeEventSelectionChangeListener(EventSelectionChangeListener listener);
void setSelection(List<UUID> newSelection, EventSelectionChangeListener... listenersNotToNotify);
boolean hasMultiSelection();
/**
* @return a non-<code>null</code> list which may be empty
*/
List<UUID> getAllEvents();
void setAllEvents(List<UUID> events, EventSelectionChangeListener... listenersNotToNotify);
}
@@ -0,0 +1,165 @@
package com.sap.sse.gwt.client.controls.listedit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sse.common.Util;
import com.sap.sse.gwt.client.StringMessages;
public class StringConstantsListEditorComposite extends ListEditorComposite<String> {
public StringConstantsListEditorComposite(Iterable<String> initialValues, StringMessages stringMessages,
String popupDialogTitle, ImageResource removeImage, Iterable<String> availableConstantValuesToAdd) {
this(initialValues, stringMessages, popupDialogTitle, removeImage, availableConstantValuesToAdd, /* placeholderTextForAddTextbox */ null);
}
public StringConstantsListEditorComposite(Iterable<String> initialValues, StringMessages stringMessages,
String popupDialogTitle, ImageResource removeImage, Iterable<String> availableConstantValuesToAdd, String placeholderTextForAddTextbox) {
super(initialValues, new CollapsedUi(stringMessages, popupDialogTitle,
new ExpandedUi(stringMessages, removeImage, availableConstantValuesToAdd, placeholderTextForAddTextbox)));
}
public StringConstantsListEditorComposite(Iterable<String> initialValues, StringMessages stringMessages,
ImageResource removeImage, Iterable<String> availableConstantValuesToAdd) {
super(initialValues, new ExpandedUi(stringMessages, removeImage, availableConstantValuesToAdd));
}
public StringConstantsListEditorComposite(Iterable<String> initialValues, StringMessages stringMessages,
ImageResource removeImage, Iterable<String> availableConstantValuesToAdd, String placeholderTextForAddTextbox) {
super(initialValues, new ExpandedUi(stringMessages, removeImage, availableConstantValuesToAdd, placeholderTextForAddTextbox));
}
public StringConstantsListEditorComposite(Iterable<String> initialValues, ListEditorUiStrategy<String> activeUi) {
super(initialValues, activeUi);
}
public static class CollapsedUi extends CollapsedListEditorUi<String> {
public CollapsedUi(StringMessages stringMessages, String dialogTitle, ExpandedListEditorUi<String> expandedUi) {
super(stringMessages, dialogTitle, expandedUi);
}
@Override
protected String getCollapsedValueText(List<String> value) {
StringBuilder valuesText = new StringBuilder();
for (int i = 0; i < value.size(); i++) {
if (i > 0) {
valuesText.append(',');
}
valuesText.append(value.get(i));
}
String condensedValue = valuesText.toString();
return condensedValue;
}
@Override
protected ListEditorComposite<String> createExpandedUi(Iterable<String> initialValues, ExpandedListEditorUi<String> ui) {
return new StringConstantsListEditorComposite(initialValues, ui);
}
}
public static class ExpandedUi extends ExpandedListEditorUi<String> {
protected final String placeholderTextForAddListbox;
protected final List<String> availableConstantValuesToAdd;
private ListBox selectionBox;
public ExpandedUi(StringMessages stringMessages, ImageResource removeImage, Iterable<String> availableConstantValuesToAdd) {
this(stringMessages, removeImage, availableConstantValuesToAdd, /* placeholderTextForAddTextbox */ null);
}
public ExpandedUi(StringMessages stringMessages, ImageResource removeImage, Iterable<String> constantValuesToAdd, String placeholderTextForAddListbox) {
super(stringMessages, removeImage, /*canRemoveItems*/true);
this.availableConstantValuesToAdd = new ArrayList<String>();
Util.addAll(constantValuesToAdd, availableConstantValuesToAdd);
Collections.sort(availableConstantValuesToAdd);
this.placeholderTextForAddListbox = placeholderTextForAddListbox;
this.selectionBox = null;
}
@Override
public void setContext(final ListEditorComposite<String> context) {
super.setContext(context);
context.addValueChangeHandler(new ValueChangeHandler<Iterable<String>>() {
@Override
public void onValueChange(ValueChangeEvent<Iterable<String>> event) {
if(selectionBox != null) {
// add a removed value item back to the list of available items
List<String> diffList = new ArrayList<>();
Util.addAll(availableConstantValuesToAdd, diffList);
diffList.removeAll(context.getValue());
Collections.sort(diffList);
updateSelectionListBox(selectionBox, diffList);
}
}
});
}
private void updateSelectionListBox(ListBox listBox, Iterable<String> values) {
listBox.clear();
if(placeholderTextForAddListbox != null) {
listBox.addItem(placeholderTextForAddListbox);
} else {
listBox.addItem("Please select");
}
for (String value : values) {
listBox.addItem(value);
}
}
protected ListBox createListBox() {
ListBox result = new ListBox(false);
updateSelectionListBox(result, availableConstantValuesToAdd);
return result;
}
@Override
protected Widget createAddWidget() {
selectionBox = createListBox();
selectionBox.ensureDebugId("SelectionListBox");
final Button addButton = new Button(getStringMessages().add());
addButton.ensureDebugId("AddButton");
addButton.setEnabled(false);
addButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
int selIndex = selectionBox.getSelectedIndex();
String seletedItemText = selectionBox.getItemText(selIndex);
addValue(seletedItemText);
selectionBox.setSelectedIndex(0);
addButton.setEnabled(false);
}
});
selectionBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
int selIndex = selectionBox.getSelectedIndex();
addButton.setEnabled(selIndex > 0);
}
});
HorizontalPanel panel = new HorizontalPanel();
panel.add(selectionBox);
panel.add(addButton);
return panel;
}
@Override
protected Widget createValueWidget(int rowIndex, String newValue) {
return new Label(newValue);
}
}
}
@@ -473,6 +473,10 @@ public abstract class DataEntryDialog<T> {
dateEntryDialog.center();
}
protected DialogBox getDialogBox() {
return dateEntryDialog;
}
public void ensureDebugId(String debugId) {
dateEntryDialog.ensureDebugId(debugId);
}