Merge branch 'master' into bug2059

This commit is contained in:
Steffen Schaefer committed 2017-07-03 10:56:22 +02:00
commit 0bef006d94
485 files changed
+7640 -3960

No files matched your search

@@ -528,7 +528,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
logger.info("Couldn't find regatta "+regattaName+" for corresponding regatta leaderboard. Not loading regatta leaderboard.");
} else {
result = new RegattaLeaderboardImpl(regatta, resultDiscardingRule);
result.setName(leaderboardName);
result.setName(leaderboardName); // this will temporarily set the display name; it will be adjusted later if a display name is found
}
return result;
}
@@ -1,7 +1,6 @@
package com.sap.sailing.domain.racelogtracking.impl;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
@@ -11,17 +10,10 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.StreamSupport;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import org.osgi.framework.ServiceReference;
import com.google.zxing.WriterException;
import com.sap.sailing.domain.abstractlog.impl.LastEventOfTypeFinder;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
@@ -73,7 +65,9 @@ import com.sap.sse.common.mail.MailException;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.i18n.ResourceBundleStringMessages;
import com.sap.sse.mail.MailService;
import com.sap.sse.qrcode.QRCodeGenerationUtil;
import com.sap.sse.mail.QRCodeMimeBodyPartSupplier;
import com.sap.sse.mail.SerializableDefaultMimeBodyPartSupplier;
import com.sap.sse.mail.SerializableMultipartSupplier;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.util.impl.NonGwtUrlHelper;
@@ -322,9 +316,6 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
final ResourceBundleStringMessages B = RaceLogTrackingI18n.STRING_MESSAGES;
String subject = String.format("%s %s", B.get(locale, "trackingInvitationFor"), invitee);
// taken from http://www.tutorialspoint.com/javamail_api/javamail_api_send_inlineimage_in_email.htm
BodyPart messageTextPart = new MimeBodyPart();
boolean hasIOSAppUrl = iOSAppUrl != null && !iOSAppUrl.isEmpty();
boolean hasAndroidAppUrl = androidAppUrl != null && !androidAppUrl.isEmpty();
boolean hasLogoUrl = logoUrl != null && !logoUrl.isEmpty();
@@ -373,26 +364,16 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
htmlText.append("</html>");
try {
messageTextPart.setContent(htmlText.toString(), "text/html");
BodyPart messageImagePart = new MimeBodyPart();
InputStream imageIs = QRCodeGenerationUtil.create(url, 250);
DataSource imageDs = new ByteArrayDataSource(imageIs, "image/png");
messageImagePart.setDataHandler(new DataHandler(imageDs));
messageImagePart.setHeader("Content-ID", "<image>");
messageImagePart.setHeader("Content-Disposition", "inline;filename=\"qr.png\"");
MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(messageTextPart);
multipart.addBodyPart(messageImagePart);
getMailService().sendMail(toAddress, subject, multipart);
} catch (MessagingException | MailException | WriterException | IOException e) {
final SerializableMultipartSupplier multipartSupplier = new SerializableMultipartSupplier("Invite",
new SerializableDefaultMimeBodyPartSupplier(htmlText.toString(), "text/html"),
new QRCodeMimeBodyPartSupplier(url));
getMailService().sendMail(toAddress, subject, multipartSupplier);
} catch (MessagingException | MailException | IOException e) {
logger.log(Level.SEVERE, "Error trying to send mail to " + invitee + " with e-mail address " + toAddress, e);
throw new MailException(e.getMessage());
}
}
@Override
public void inviteBuoyTenderViaEmail(Event event, Leaderboard leaderboard, String serverUrlWithoutTrailingSlash,
String emails, String iOSAppUrl, String androidAppUrl, Locale locale) throws MailException {
@@ -13,30 +13,12 @@ public class ConfirmedFinishPositioningListFinder extends RaceLogAnalyzer<Compet
@Override
protected CompetitorResults performAnalysis() {
return performAnalysis(/* eventToIgnore */ null);
}
private CompetitorResults performAnalysis(RaceLogFinishPositioningConfirmedEvent eventToIgnore) {
for (RaceLogEvent event : getPassEventsDescending()) {
if (event != eventToIgnore && event instanceof RaceLogFinishPositioningConfirmedEvent) {
if (event instanceof RaceLogFinishPositioningConfirmedEvent) {
RaceLogFinishPositioningConfirmedEvent finishPositioningEvent = (RaceLogFinishPositioningConfirmedEvent) event;
return finishPositioningEvent.getPositionedCompetitorsIDsNamesMaxPointsReasons();
}
}
return null;
}
/**
* Same as {@link #analyze()}, only that if {@code event} is found in the log then it is ignored for this
* analysis. This way, the method returns a result as it would have been without {@code event} in the
* {@link RaceLog}. This can be useful, e.g., to determine the result prior to the last update.
*/
public CompetitorResults analyzeIgnoring(RaceLogFinishPositioningConfirmedEvent event) {
log.lockForRead();
try {
return performAnalysis(event);
} finally {
log.unlockAfterRead();
}
}
}
@@ -5,7 +5,6 @@ import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import com.sap.sailing.domain.swisstimingadapter.RaceType;
@@ -53,14 +52,4 @@ public class DomainFactoryTest {
assertThat(raceType, is(notNullValue()));
assertThat(raceType.getRaceCode(), is(OlympicRaceCode.UNKNOWN));
}
@Ignore
@Test
public void testCompetitorLookup() throws Exception {
before();
// swissTimingDomainFactory.getOrCreateCompetitor(boatID, threeLetterIOCCode, name, boatClass);
}
}
@@ -41,7 +41,6 @@ public class SwissTimingRaceConfigurationTest {
}
}
@Ignore("According to Radek Masnica ('masnica.r@st-software.com') the OTA stuff may not be supported any longer by the SwissTiming Leipzip lab... 2017-05-19")
@Test
public void testRaceConfig_446483_no_detail_config() throws Exception {
URL configFileURL = new URL(MessageFormat.format(SwissTimingReplayServiceImpl.RACE_CONFIG_URL_TEMPLATE, "446483"));
@@ -59,7 +58,6 @@ public class SwissTimingRaceConfigurationTest {
}
@Ignore("According to Radek Masnica ('masnica.r@st-software.com') the OTA stuff may not be supported any longer by the SwissTiming Leipzip lab... 2017-05-19")
@Test
public void testRaceConfig_6260_with_detail_config() throws Exception {
URL configFileURL = new URL(MessageFormat.format(SwissTimingReplayServiceImpl.RACE_CONFIG_URL_TEMPLATE, "6260"));
@@ -74,12 +74,11 @@ public class SwissTimingReplayAdapterServiceTest {
assertEquals(321920, replayCountListener.rankingMarkCount);
}
@Ignore("According to Radek Masnica ('masnica.r@st-software.com') the OTA stuff may not be supported any longer by the SwissTiming Leipzip lab... 2017-05-19")
@Test
public void testRaceData_SAW005905_20120805_EqualsOnlineVersion() throws Exception {
byte[] localCopy = read(getClass().getResourceAsStream("/SAW005905.20120805.replay"));
byte[] onlineCopy = read((InputStream) new URL(
"http://live.ota.st-sportservice.com/Replay?id=446495&_start=0").getContent());
"http://ota2.sportresult.com/Replay?id=446495&_start=0").getContent());
assertArrayEquals(localCopy, onlineCopy);
}
@@ -114,13 +113,12 @@ public class SwissTimingReplayAdapterServiceTest {
assertEquals(9500, replayCountListener.rankingMarkCount);
}
@Ignore("According to Radek Masnica ('masnica.r@st-software.com') the OTA stuff may not be supported any longer by the SwissTiming Leipzip lab... 2017-05-19")
@Test
public void testRaceData_SAW005905_20120805_online() throws Exception {
SwissTimingReplayTestListener replayCountListener = new SwissTimingReplayTestListener();
// race ID is 450053, as extracted from http://live.ota.st-sportservice.com/service?cmd=unity_race_overview&id=91
byte[] onlineCopy = read((InputStream) new URL(
"http://live.ota.st-sportservice.com/Replay?id=446495&_start=0").getContent());
"http://ota2.sportresult.com/Replay?id=446495&_start=0").getContent());
new SwissTimingReplayParserImpl().readData(new ByteArrayInputStream(onlineCopy), replayCountListener);
assertEquals(0, replayCountListener.keyFrameIndexSum);
assertEquals(715, replayCountListener.keyFrameIndexPositionCount);
@@ -34,7 +34,7 @@ import com.sap.sse.util.ByteArrayOutputStreamWithVisibleBuffer;
public class SwissTimingReplayServiceImpl implements SwissTimingReplayService {
public static final String RACE_CONFIG_URL_TEMPLATE = "http://live.ota.st-sportservice.com/configuration?_race={0}&effective=1&additional=config";
public static final String RACE_CONFIG_URL_TEMPLATE = "http://ota2.sportresult.com/configuration?_race={0}&effective=1&additional=config";
private static final String SWISSTIMING_DATEFORMAT_PATTERN = "dd.MM.yyyy HH:mm";
private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("GMT");
@@ -2,6 +2,7 @@ package com.sap.sailing.domain.test;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
@@ -13,9 +14,13 @@ import com.sap.sailing.domain.base.impl.CourseAreaImpl;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
import com.sap.sailing.domain.leaderboard.FlexibleRaceColumn;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.impl.FlexibleLeaderboardImpl;
import com.sap.sailing.domain.leaderboard.impl.LeaderboardGroupImpl;
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.meta.LeaderboardGroupMetaLeaderboard;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
@@ -44,21 +49,64 @@ public class LeaderboardDTOCacheInvalidationTest {
public void testFlexibleLeaderboardDisplayNameChangeInvalidatesCache()
throws NoWindException, InterruptedException, ExecutionException {
final String name = "My Flexible Leaderboard";
final String newName = "New Name of Flexible Leaderboard";
final String oldDisplayName = "D1";
final String newDisplayName = "D2";
final TimePoint now = MillisecondsTimePoint.now();
FlexibleLeaderboard l = new FlexibleLeaderboardImpl(name,
new ThresholdBasedResultDiscardingRuleImpl(new int[0]), new LowPoint(),
new CourseAreaImpl("My Course Area", UUID.randomUUID()));
final LeaderboardGroup lg = new LeaderboardGroupImpl("LG", "LG", /* displayName */ null, /* displayGroupsInReverseOrder */ false, Arrays.asList(l));
final LeaderboardGroupMetaLeaderboard seriesLb = new LeaderboardGroupMetaLeaderboard(lg, new LowPoint(), new ThresholdBasedResultDiscardingRuleImpl(new int[0]));
LeaderboardDTO seriesLbDtoBeforeDisplayNameIsSet = seriesLb.getLeaderboardDTO(now, Collections.<String> emptySet(),
/* addOverallDetails */ false, /* trackedRegattaRegistry */ null, DomainFactory.INSTANCE,
/* fillTotalPointsUncorrected */ false);
assertEquals(name, seriesLbDtoBeforeDisplayNameIsSet.getRaceList().iterator().next().getName());
l.setName(newName);
LeaderboardDTO seriesLbDtoBeforeDisplayNameIsSetAndAfterNameWasChanged = seriesLb.getLeaderboardDTO(now, Collections.<String> emptySet(),
/* addOverallDetails */ false, /* trackedRegattaRegistry */ null, DomainFactory.INSTANCE,
/* fillTotalPointsUncorrected */ false);
assertEquals(newName, seriesLbDtoBeforeDisplayNameIsSetAndAfterNameWasChanged.getRaceList().iterator().next().getName());
l.setDisplayName(oldDisplayName);
final TimePoint now = MillisecondsTimePoint.now();
LeaderboardDTO dto = l.getLeaderboardDTO(now, Collections.<String> emptySet(),
/* addOverallDetails */ false, /* trackedRegattaRegistry */ null, DomainFactory.INSTANCE,
/* fillTotalPointsUncorrected */ false);
assertEquals(oldDisplayName, dto.getDisplayName());
LeaderboardDTO seriesLbDto = seriesLb.getLeaderboardDTO(now, Collections.<String> emptySet(),
/* addOverallDetails */ false, /* trackedRegattaRegistry */ null, DomainFactory.INSTANCE,
/* fillTotalPointsUncorrected */ false);
assertEquals(oldDisplayName, seriesLbDto.getRaceList().iterator().next().getName());
l.setDisplayName(newDisplayName);
LeaderboardDTO dtoNew = l.getLeaderboardDTO(now, Collections.<String> emptySet(),
/* addOverallDetails */ false, /* trackedRegattaRegistry */ null, DomainFactory.INSTANCE,
/* fillTotalPointsUncorrected */ false);
assertEquals(newDisplayName, dtoNew.getDisplayName());
LeaderboardDTO seriesLbDtoNew = seriesLb.getLeaderboardDTO(now, Collections.<String> emptySet(),
/* addOverallDetails */ false, /* trackedRegattaRegistry */ null, DomainFactory.INSTANCE,
/* fillTotalPointsUncorrected */ false);
assertEquals(newDisplayName, seriesLbDtoNew.getRaceList().iterator().next().getName());
}
@Test
public void testFlexibleLeaderboardRaceColumnNameChangeInvalidatesCache()
throws NoWindException, InterruptedException, ExecutionException {
final String name = "My Flexible Leaderboard";
FlexibleLeaderboard l = new FlexibleLeaderboardImpl(name,
new ThresholdBasedResultDiscardingRuleImpl(new int[0]), new LowPoint(),
new CourseAreaImpl("My Course Area", UUID.randomUUID()));
final String oldRaceColumnName = "Old";
FlexibleRaceColumn rc = l.addRaceColumn(oldRaceColumnName, /* medalRace */ false);
final TimePoint now = MillisecondsTimePoint.now();
LeaderboardDTO dto = l.getLeaderboardDTO(now, Collections.<String> emptySet(),
/* addOverallDetails */ false, /* trackedRegattaRegistry */ null, DomainFactory.INSTANCE,
/* fillTotalPointsUncorrected */ false);
assertEquals(oldRaceColumnName, dto.getRaceList().iterator().next().getName());
final String newRaceColumnName = "New";
rc.setName(newRaceColumnName);
LeaderboardDTO dtoNew = l.getLeaderboardDTO(now, Collections.<String> emptySet(),
/* addOverallDetails */ false, /* trackedRegattaRegistry */ null, DomainFactory.INSTANCE,
/* fillTotalPointsUncorrected */ false);
assertEquals(newRaceColumnName, dtoNew.getRaceList().iterator().next().getName());
}
}
@@ -65,7 +65,6 @@ import com.tractrac.subscription.lib.api.ISubscriberFactory;
import com.tractrac.subscription.lib.api.SubscriberInitializationException;
import com.tractrac.subscription.lib.api.SubscriptionLocator;
import com.tractrac.subscription.lib.api.competitor.ICompetitorsListener;
import com.tractrac.subscription.lib.api.control.IControlsListener;
import com.tractrac.subscription.lib.api.event.IConnectionStatusListener;
import com.tractrac.subscription.lib.api.event.ILiveDataEvent;
import com.tractrac.subscription.lib.api.event.IStoredDataEvent;
@@ -196,7 +195,6 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
private final IEventSubscriber eventSubscriber;
private final IRaceSubscriber raceSubscriber;
private final IRacesListener racesListener;
private final IControlsListener controlsListener;
private final ICompetitorsListener competitorsListener;
private final Set<Receiver> receivers;
private final DomainFactory domainFactory;
@@ -335,15 +333,6 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
// Initialize data controller using live and stored data sources
ISubscriberFactory subscriberFactory = SubscriptionLocator.getSusbcriberFactory();
eventSubscriber = subscriberFactory.createEventSubscriber(tractracEvent, liveURI, effectifeStoredURI);
controlsListener = new IControlsListener() {
@Override
public void updateControl(IControl control) {}
@Override
public void deleteControl(UUID controlId) {}
@Override
public void addControl(IControl control) {}
};
eventSubscriber.subscribeControls(controlsListener);
competitorsListener = new ICompetitorsListener() {
@Override
public void updateCompetitor(ICompetitor competitor) {
@@ -549,7 +538,6 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
stopped = true;
eventSubscriber.unsubscribeRaces(racesListener);
eventSubscriber.unsubscribeCompetitors(competitorsListener);
eventSubscriber.unsubscribeControls(controlsListener);
raceSubscriber.stop();
eventSubscriber.stop();
raceSubscriber.unsubscribeConnectionStatus(this);
@@ -33,6 +33,8 @@ public interface RaceColumnListener extends Serializable {
void raceColumnMoved(RaceColumn raceColumn, int newIndex);
void raceColumnNameChanged(RaceColumn raceColumn, String oldName, String newName);
void factorChanged(RaceColumn raceColumn, Double oldFactor, Double newFactor);
void competitorDisplayNameChanged(Competitor competitor, String oldDisplayName, String displayName);
@@ -79,6 +79,11 @@ public interface RaceColumnListenerWithDefaultAction extends RaceColumnListener
defaultAction();
}
@Override
default void raceColumnNameChanged(RaceColumn raceColumn, String oldName, String newName) {
defaultAction();
}
@Override
default void factorChanged(RaceColumn raceColumn, Double oldFactor, Double newFactor) {
defaultAction();
@@ -508,6 +508,11 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
raceColumnListeners.notifyListenersAboutRaceColumnMoved(raceColumn, newIndex);
}
@Override
public void raceColumnNameChanged(RaceColumn raceColumn, String oldName, String newName) {
raceColumnListeners.notifyListenersAboutRaceColumnNameChanged(raceColumn, oldName, newName);
}
@Override
public void factorChanged(RaceColumn raceColumn, Double oldFactor, Double newFactor) {
raceColumnListeners.notifyListenersAboutFactorChanged(raceColumn, oldFactor, newFactor);
@@ -361,6 +361,11 @@ public class SeriesImpl extends RenamableImpl implements Series, RaceColumnListe
raceColumnListeners.notifyListenersAboutRaceColumnMoved(raceColumn, newIndex);
}
@Override
public void raceColumnNameChanged(RaceColumn raceColumn, String oldName, String newName) {
raceColumnListeners.notifyListenersAboutRaceColumnNameChanged(raceColumn, oldName, newName);
}
@Override
public void factorChanged(RaceColumn raceColumn, Double oldFactor, Double newFactor) {
raceColumnListeners.notifyListenersAboutFactorChanged(raceColumn, oldFactor, newFactor);
@@ -48,7 +48,7 @@ public interface FlexibleLeaderboard extends LeaderboardThatHasRegattaLike, Rena
* tells if the column to add represents a medal race which has double score and cannot be discarded
* @return the race column in the leaderboard used to represent the tracked <code>race</code>
*/
RaceColumn addRaceColumn(String name, boolean medalRace);
FlexibleRaceColumn addRaceColumn(String name, boolean medalRace);
/**
* Adds a tracked race to this leaderboard. If a {@link RaceColumn} with name <code>columnName</code> already exists
@@ -62,7 +62,7 @@ public interface FlexibleLeaderboard extends LeaderboardThatHasRegattaLike, Rena
*
* @return the race column in the leaderboard used to represent the tracked <code>race</code>
*/
RaceColumn addRace(TrackedRace race, String columnName, boolean medalRace);
FlexibleRaceColumn addRace(TrackedRace race, String columnName, boolean medalRace);
void removeRaceColumn(String columnName);
@@ -1,10 +1,10 @@
package com.sap.sailing.domain.leaderboard;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.common.Renamable;
import com.sap.sailing.domain.regattalike.IsRegattaLike;
public interface FlexibleRaceColumn extends RaceColumn {
void setName(String newName);
public interface FlexibleRaceColumn extends RaceColumn, Renamable {
void setIsMedalRace(boolean isMedalRace);
void setRegattaLikeHelper(IsRegattaLike regattaLikeHelper);
}
@@ -32,8 +32,8 @@ public interface SettableScoreCorrection extends ScoreCorrection {
void uncorrectScore(Competitor competitor, RaceColumn raceColumn);
/**
* @return <code>null</code> if not set for the competitor, e.g., because no correction was made or an explicit
* {@link MaxPointsReason} was provided for the competitor.
* @return <code>null</code> if not set for the competitor, e.g., because no correction was made or only a
* {@link MaxPointsReason} but no explicit score was provided for the competitor.
*/
Double getExplicitScoreCorrection(Competitor competitor, RaceColumn raceColumn);
@@ -246,7 +246,11 @@ public abstract class AbstractLeaderboardWithCache implements Leaderboard {
}
protected void notifyLeaderboardChangeListeners(Consumer<LeaderboardChangeListener> notifier) {
for (final LeaderboardChangeListener listener : leaderboardChangeListeners) {
final Set<LeaderboardChangeListener> workingListeners;
synchronized (leaderboardChangeListeners) {
workingListeners = new HashSet<>(leaderboardChangeListeners);
}
for (final LeaderboardChangeListener listener : workingListeners) {
try {
notifier.accept(listener);
} catch (Exception e) {
@@ -258,12 +262,16 @@ public abstract class AbstractLeaderboardWithCache implements Leaderboard {
@Override
public void addLeaderboardChangeListener(LeaderboardChangeListener listener) {
leaderboardChangeListeners.add(listener);
synchronized (leaderboardChangeListeners) {
leaderboardChangeListeners.add(listener);
}
}
@Override
public void removeLeaderboardChangeListener(LeaderboardChangeListener listener) {
leaderboardChangeListeners.remove(listener);
synchronized (leaderboardChangeListeners) {
leaderboardChangeListeners.remove(listener);
}
}
@Override
@@ -258,6 +258,11 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
getRaceColumnListeners().notifyListenersAboutRaceColumnMoved(raceColumn, newIndex);
}
@Override
public void raceColumnNameChanged(RaceColumn raceColumn, String oldName, String newName) {
getRaceColumnListeners().notifyListenersAboutRaceColumnNameChanged(raceColumn, oldName, newName);
}
@Override
public void factorChanged(RaceColumn raceColumn, Double oldFactor, Double newFactor) {
getRaceColumnListeners().notifyListenersAboutFactorChanged(raceColumn, oldFactor, newFactor);
@@ -9,18 +9,16 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CompetitorFactory;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.RaceColumnListener;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.impl.RaceColumnListenerWithDefaultAction;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.leaderboard.DelayedLeaderboardCorrections;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.IsManagedByCache;
@@ -41,7 +39,7 @@ import com.sap.sse.common.IsManagedByCache;
* @author Axel Uhl (d043530)
*
*/
public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorrections, IsManagedByCache<SharedDomainFactory> {
public class DelayedLeaderboardCorrectionsImpl implements RaceColumnListenerWithDefaultAction, DelayedLeaderboardCorrections, IsManagedByCache<SharedDomainFactory> {
private static final long serialVersionUID = 8824782847677232275L;
// structures that key corrections by competitor ID
@@ -270,72 +268,17 @@ public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorr
assignLeftOvers(trackedRace);
}
@Override
public void trackedRaceUnlinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
}
@Override
public void isMedalRaceChanged(RaceColumn raceColumn, boolean newIsMedalRace) {
}
@Override
public void isFleetsCanRunInParallelChanged(RaceColumn raceColumn, boolean newIsFleetsCanRunInParallel) {
}
@Override
public void isStartsWithZeroScoreChanged(RaceColumn raceColumn, boolean newIsStartsWithZeroScore) {
}
@Override
public void hasSplitFleetContiguousScoringChanged(RaceColumn raceColumn, boolean hasSplitFleetContiguousScoring) {
}
@Override
public void isFirstColumnIsNonDiscardableCarryForwardChanged(RaceColumn raceColumn, boolean firstColumnIsNonDiscardableCarryForward) {
}
@Override
public boolean canAddRaceColumnToContainer(RaceColumn raceColumn) {
return true;
}
@Override
public void raceColumnAddedToContainer(RaceColumn raceColumn) {
}
@Override
public void raceColumnRemovedFromContainer(RaceColumn raceColumn) {
}
@Override
public void raceColumnMoved(RaceColumn raceColumn, int newIndex) {
}
@Override
public void factorChanged(RaceColumn raceColumn, Double oldFactor, Double newFactor) {
}
@Override
public void competitorDisplayNameChanged(Competitor competitor, String oldDisplayName, String displayName) {
}
@Override
public void resultDiscardingRuleChanged(ResultDiscardingRule oldDiscardingRule, ResultDiscardingRule newDiscardingRule) {
}
@Override
public void raceLogEventAdded(RaceColumn raceColumn, RaceLogIdentifier raceLogIdentifier, RaceLogEvent event) {
}
@Override
public boolean isTransient() {
return false;
}
@Override
public IsManagedByCache<SharedDomainFactory> resolve(SharedDomainFactory domainFactory) {
this.competitorFactory = domainFactory;
return this;
}
/**
* The default action for {@link RaceColumnListener} callbacks is to do nothing
*/
@Override
public void defaultAction() {
}
}
@@ -154,7 +154,7 @@ public class FlexibleLeaderboardImpl extends AbstractLeaderboardImpl implements
}
@Override
public RaceColumn addRace(TrackedRace race, String columnName, boolean medalRace) {
public FlexibleRaceColumn addRace(TrackedRace race, String columnName, boolean medalRace) {
FlexibleRaceColumn column = addRaceColumn(columnName, medalRace, /* logAlreadyExistingColumn */false);
column.setTrackedRace(defaultFleet, race); // triggers listeners because this object was registered above as
// race column listener on the column
@@ -139,6 +139,9 @@ public class LeaderboardGroupImpl extends LeaderboardGroupBaseImpl implements Le
@Override
public void addLeaderboard(Leaderboard leaderboard) {
if (leaderboard == overallLeaderboard) {
throw new IllegalArgumentException("Cannot insert the overall leaderboard into its own leaderboard group");
}
LockUtil.lockForWrite(leaderboardsLock);
try {
addLeaderboardAt(leaderboard, leaderboards.size());
@@ -8,6 +8,7 @@ import com.sap.sailing.domain.base.impl.AbstractRaceColumn;
import com.sap.sailing.domain.leaderboard.FlexibleRaceColumn;
import com.sap.sailing.domain.regattalike.IsRegattaLike;
import com.sap.sailing.domain.tracking.RaceExecutionOrderProvider;
import com.sap.sse.common.Util;
public class RaceColumnImpl extends AbstractRaceColumn implements FlexibleRaceColumn {
private static final long serialVersionUID = -7801617988982540470L;
@@ -26,7 +27,11 @@ public class RaceColumnImpl extends AbstractRaceColumn implements FlexibleRaceCo
@Override
public void setName(String newName) {
final String oldName = this.name;
this.name = newName;
if (!Util.equalsWithNull(oldName, newName)) {
getRaceColumnListeners().notifyListenersAboutRaceColumnNameChanged(this, oldName, newName);
}
}
@Override
@@ -7,6 +7,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.LeaderboardChangeListener;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.RaceColumnListener;
@@ -28,7 +29,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
* @author Axel Uhl
*
*/
public class MetaLeaderboardColumn extends SimpleAbstractRaceColumn implements RaceColumn, RaceColumnListener {
public class MetaLeaderboardColumn extends SimpleAbstractRaceColumn implements RaceColumn, RaceColumnListener, LeaderboardChangeListener {
private static final long serialVersionUID = 3092096133388262955L;
private final Leaderboard leaderboard;
private final Fleet metaFleet;
@@ -38,6 +39,7 @@ public class MetaLeaderboardColumn extends SimpleAbstractRaceColumn implements R
this.leaderboard = leaderboard;
this.metaFleet = metaFleet;
leaderboard.addRaceColumnListener(this);
leaderboard.addLeaderboardChangeListener(this);
}
@Override
@@ -161,6 +163,11 @@ public class MetaLeaderboardColumn extends SimpleAbstractRaceColumn implements R
getRaceColumnListeners().notifyListenersAboutRaceColumnMoved(raceColumn, newIndex);
}
@Override
public void raceColumnNameChanged(RaceColumn raceColumn, String oldName, String newName) {
getRaceColumnListeners().notifyListenersAboutRaceColumnNameChanged(raceColumn, oldName, newName);
}
@Override
public void factorChanged(RaceColumn raceColumn, Double oldFactor, Double newFactor) {
getRaceColumnListeners().notifyListenersAboutFactorChanged(raceColumn, oldFactor, newFactor);
@@ -284,4 +291,25 @@ public class MetaLeaderboardColumn extends SimpleAbstractRaceColumn implements R
@Override
public void disableCompetitorRegistrationOnRaceLog(Fleet fleetByName) {
}
/**
* When the leaderboard name changes, notify this to this object's {@link RaceColumnListener}s as a
* change of this race column's name, but only if no {@link Leaderboard#getDisplayName() display name}
* is set because that would take precedence over the regular name.
*/
@Override
public void nameChanged(String oldName, String newName) {
if (leaderboard.getDisplayName() == null) {
getRaceColumnListeners().notifyListenersAboutRaceColumnNameChanged(this, oldName, newName);
}
}
/**
* When the leaderboard display name changes, notify this to this object's {@link RaceColumnListener}s as a
* change of this race column's name
*/
@Override
public void displayNameChanged(String oldDisplayName, String newDisplayName) {
getRaceColumnListeners().notifyListenersAboutRaceColumnNameChanged(this, oldDisplayName, newDisplayName);
}
}
@@ -128,6 +128,12 @@ public class RaceColumnListeners implements Serializable {
}
}
public void notifyListenersAboutRaceColumnNameChanged(RaceColumn raceColumn, String oldName, String newName) {
for (RaceColumnListener listener : getRaceColumnListeners()) {
listener.raceColumnNameChanged(raceColumn, oldName, newName);
}
}
private Set<RaceColumnListener> getRaceColumnListeners() {
synchronized (raceColumnListeners) {
return new HashSet<RaceColumnListener>(raceColumnListeners);
@@ -58,12 +58,12 @@ public class AutoplayPerspectiveLifecycle extends AbstractPerspectiveLifecycle<A
}
@Override
protected AutoplayPerspectiveOwnSettings extractOwnGlobalSettings(AutoplayPerspectiveOwnSettings settings) {
protected AutoplayPerspectiveOwnSettings extractOwnUserSettings(AutoplayPerspectiveOwnSettings settings) {
return settings;
}
@Override
protected AutoplayPerspectiveOwnSettings extractOwnContextSettings(AutoplayPerspectiveOwnSettings settings) {
protected AutoplayPerspectiveOwnSettings extractOwnDocumentSettings(AutoplayPerspectiveOwnSettings settings) {
return settings;
}
@@ -9,7 +9,7 @@ import com.sap.sailing.gwt.common.client.FullscreenUtil;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.gwt.client.shared.components.AbstractCompositeComponent;
import com.sap.sse.gwt.client.shared.components.Component;
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
import com.sap.sse.security.ui.client.UserService;
public class SAPHeaderComponent extends AbstractCompositeComponent<SAPHeaderComponentSettings> {
@@ -56,7 +56,7 @@ public class SAPHeaderComponent extends AbstractCompositeComponent<SAPHeaderComp
}
@Override
public SAPHeaderComponentSettingsDialogComponent getSettingsDialogComponent() {
public SAPHeaderComponentSettingsDialogComponent getSettingsDialogComponent(SAPHeaderComponentSettings settings) {
return componentLifecycle.getSettingsDialogComponent(settings);
}
@@ -40,12 +40,12 @@ public class SAPHeaderComponentLifecycle implements ComponentLifecycle<SAPHeader
}
@Override
public SAPHeaderComponentSettings extractGlobalSettings(SAPHeaderComponentSettings settings) {
public SAPHeaderComponentSettings extractUserSettings(SAPHeaderComponentSettings settings) {
return createDefaultSettings();
}
@Override
public SAPHeaderComponentSettings extractContextSpecificSettings(SAPHeaderComponentSettings settings) {
public SAPHeaderComponentSettings extractDocumentSettings(SAPHeaderComponentSettings settings) {
return createDefaultSettings();
}
}
@@ -29,9 +29,9 @@ import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.shared.components.Component;
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
import com.sap.sse.gwt.client.shared.perspective.AbstractPerspectiveComposite;
import com.sap.sse.gwt.client.shared.perspective.ComponentContextWithSettingsStorage;
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
import com.sap.sse.security.ui.client.UserService;
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
/**
* A perspective managing a header with a single leaderboard filling the rest of the screen.
@@ -64,13 +64,13 @@ public class LeaderboardWithHeaderPerspectiveLifecycle extends AbstractPerspecti
}
@Override
protected LeaderboardWithHeaderPerspectiveSettings extractOwnGlobalSettings(
protected LeaderboardWithHeaderPerspectiveSettings extractOwnUserSettings(
LeaderboardWithHeaderPerspectiveSettings settings) {
return settings;
}
@Override
protected LeaderboardWithHeaderPerspectiveSettings extractOwnContextSettings(
protected LeaderboardWithHeaderPerspectiveSettings extractOwnDocumentSettings(
LeaderboardWithHeaderPerspectiveSettings settings) {
return settings;
}
@@ -3,7 +3,6 @@ package com.sap.sailing.gwt.common.theme.component.celltable;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.CellTable.Style;
/**
* {@link ClientBundle} with avoids the standard {@link CellTable} styles.
@@ -11,9 +10,12 @@ import com.google.gwt.user.cellview.client.CellTable.Style;
public interface CleanCellTableResources extends CellTable.Resources {
public static final CleanCellTableResources INSTANCE = GWT.create(CleanCellTableResources.class);
public interface CleanCellTableStyle extends CellTable.Style {
}
@Override
@Source("CleanCellTable.css")
public Style cellTableStyle();
public CleanCellTableStyle cellTableStyle();
}
@@ -0,0 +1,68 @@
.cellTableWidget {
font-size: 1rem;
border: 1px solid #dedede;
border-radius: .333333333333333em;
border-spacing: 0;
border-collapse: separate;
overflow: hidden;
background-color: #f2f2f2;
}
.cellTableWidget>thead>tr {
color: #666;
background-color: #dfdfdf;
border-bottom: 1px solid #dedede;
text-transform: uppercase;
font-weight: 600;
border-radius: .333333333333333em 0 0 .333333333333333em;
}
.cellTableWidget>thead>tr>th {
padding: .666666666666667em .666666666666667em .666666666666667em 1.333333333333333em;
text-align: left;
}
.cellTableCell {
text-align: left;
vertical-align: baseline;
border-bottom: 1px solid #dfdfdf;
white-space: nowrap;
padding: 1.4em .666666666666667em .733333333333333em 1.333333333333333em;
}
.buttonCell {
text-align: right;
vertical-align: middle;
padding-left: 0;
padding-right: .666666666666667em;
padding-top: .666666666666667em;
}
.buttonCell>div>button {
font-size: 1rem;
color: #fff;
font-weight: 700;
background: #008fcc;
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -moz-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-box-flex: 0;
-webkit-flex: 0;
-moz-box-flex: 0;
-ms-flex: 0;
flex: 0;
text-align: center;
-webkit-box-align: center;
-webkit-align-items: center;
-moz-box-align: center;
-ms-flex-align: center;
align-items: center;
height: 2.666666666666667em;
padding: 0 1em 0 1em;
border-radius: .2em;
position: relative;
border: none;
}
@@ -0,0 +1,22 @@
package com.sap.sailing.gwt.common.theme.component.celltable;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.user.cellview.client.CellTable;
/**
* {@link ClientBundle} with avoids the standard {@link CellTable} styles.
*/
public interface DesignedCellTableResources extends CellTable.Resources {
public static final DesignedCellTableResources INSTANCE = GWT.create(DesignedCellTableResources.class);
public interface DesignedCellTableStyle extends CellTable.Style {
String buttonCell();
}
@Override
@Source({"CleanCellTable.css", "DesignedCellTable.css"})
public DesignedCellTableStyle cellTableStyle();
}
@@ -9,7 +9,6 @@ import com.google.gwt.place.shared.Place;
import com.google.gwt.safehtml.shared.SafeUri;
import com.google.gwt.safehtml.shared.UriUtils;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.gwt.common.client.controls.tabbar.TabView;
import com.sap.sailing.gwt.home.communication.SailingDispatchSystem;
@@ -149,28 +148,20 @@ public abstract class AbstractEventActivity<PLACE extends AbstractEventPlace> ex
@Override
public String getRaceViewerURL(SimpleRaceMetadataDTO raceMetadata, String mode) {
RaceIdentifier raceIdentifier = raceMetadata.getRegattaAndRaceIdentifier();
RaceboardContextDefinition raceboardContext = new RaceboardContextDefinition(raceIdentifier.getRegattaName(),
raceIdentifier.getRaceName(), raceMetadata.getLeaderboardName(), raceMetadata.getLeaderboardGroupName(),
null, mode);
RaceBoardPerspectiveOwnSettings perspectiveOwnSettings = RaceBoardPerspectiveOwnSettings
.createDefaultWithCanReplayDuringLiveRaces(true);
;
HashMap<String, Settings> innerSettings = new HashMap<>();
innerSettings.put(RaceMapLifecycle.ID, RaceMapSettings.getDefaultWithShowMapControls(true));
PerspectiveCompositeSettings<RaceBoardPerspectiveOwnSettings> settings = new PerspectiveCompositeSettings<>(
perspectiveOwnSettings, innerSettings);
return EntryPointWithSettingsLinkFactory.createRaceBoardLink(raceboardContext, settings);
return getRaceViewerURL(raceMetadata.getLeaderboardName(), raceMetadata.getLeaderboardGroupName(),
raceMetadata.getRegattaAndRaceIdentifier(), mode);
}
@Override
public String getRaceViewerURL(String leaderboardName, String leaderboardGroupName, RegattaAndRaceIdentifier raceIdentifier) {
return getRaceViewerURL(leaderboardName, leaderboardGroupName, raceIdentifier, null);
}
private String getRaceViewerURL(String leaderboardName, String leaderboardGroupName, RegattaAndRaceIdentifier raceIdentifier, String mode) {
RaceboardContextDefinition raceboardContext = new RaceboardContextDefinition(raceIdentifier.getRegattaName(),
raceIdentifier.getRaceName(), leaderboardName, leaderboardGroupName, null, null);
RaceBoardPerspectiveOwnSettings perspectiveOwnSettings = RaceBoardPerspectiveOwnSettings
.createDefaultWithCanReplayDuringLiveRaces(true);
;
raceIdentifier.getRaceName(), leaderboardName, leaderboardGroupName, UUID.fromString(ctx.getEventId()), mode);
RaceBoardPerspectiveOwnSettings perspectiveOwnSettings = new RaceBoardPerspectiveOwnSettings();
HashMap<String, Settings> innerSettings = new HashMap<>();
innerSettings.put(RaceMapLifecycle.ID, RaceMapSettings.getDefaultWithShowMapControls(true));
PerspectiveCompositeSettings<RaceBoardPerspectiveOwnSettings> settings = new PerspectiveCompositeSettings<>(
@@ -16,7 +16,7 @@ import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.shared.components.Component;
import com.sap.sse.gwt.client.shared.components.SettingsDialog;
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
/**
* A class managing analytical data on the regatta level (like leaderboard, regatta rank, etc.)
@@ -7,20 +7,18 @@ import com.sap.sailing.gwt.home.desktop.places.Consumer;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardPanelLifecycle;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardUrlSettings;
import com.sap.sailing.gwt.settings.client.utils.StorageDefinitionIdFactory;
import com.sap.sailing.gwt.settings.client.utils.StoredSettingsLocationFactory;
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sse.gwt.client.mutationobserver.ElementSizeMutationObserver;
import com.sap.sse.gwt.client.mutationobserver.ElementSizeMutationObserver.DomMutationCallback;
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
import com.sap.sse.gwt.client.shared.perspective.ComponentContextWithSettingsStorage;
import com.sap.sse.gwt.client.shared.perspective.DefaultOnSettingsLoadedCallback;
import com.sap.sse.gwt.client.shared.perspective.SettingsStorageManager;
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
import com.sap.sse.security.ui.client.UserService;
import com.sap.sse.security.ui.settings.PlaceBasedUserSettingsStorageManager;
import com.sap.sse.security.ui.settings.StorageDefinitionId;
import com.sap.sse.security.ui.settings.PlaceBasedComponentContextWithSettingsStorage;
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
/**
* An abstract regatta tabView with some shared functions between the leaderboard tab and competitors chart tab
@@ -41,7 +39,7 @@ public abstract class SharedLeaderboardRegattaTabView<T extends AbstractEventReg
final ComponentContext<LeaderboardSettings> componentContext = createLeaderboardComponentContext(leaderboardName, userService,
placeToken);
componentContext.initInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
componentContext.getInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
@Override
public void onSuccess(LeaderboardSettings leaderboardSettings) {
final LeaderboardPanel leaderboardPanel = regattaAnalyticsManager.createLeaderboardPanel(null, componentContext, //
@@ -82,13 +80,11 @@ public abstract class SharedLeaderboardRegattaTabView<T extends AbstractEventReg
protected ComponentContext<LeaderboardSettings> createLeaderboardComponentContext(String leaderboardName, UserService userService,
String placeToken) {
final LeaderboardPanelLifecycle lifeCycle = new LeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForEventRegattaLeaderboard(leaderboardName);
final SettingsStorageManager<LeaderboardSettings> settingsStorageManager = new PlaceBasedUserSettingsStorageManager<>(
userService, storageDefinitionId, placeToken);
final LeaderboardPanelLifecycle lifecycle = new LeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory.createStoredSettingsLocatorForEventRegattaLeaderboard(leaderboardName);
final ComponentContext<LeaderboardSettings> componentContext = new ComponentContextWithSettingsStorage<>(
lifeCycle, settingsStorageManager);
final ComponentContext<LeaderboardSettings> componentContext = new PlaceBasedComponentContextWithSettingsStorage<>(
lifecycle, userService, storageDefinition, placeToken);
return componentContext;
}
}
@@ -33,7 +33,7 @@ import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateProvider;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sse.gwt.client.shared.perspective.DefaultOnSettingsLoadedCallback;
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
import com.sap.sse.gwt.dispatch.shared.commands.CollectionResult;
/**
@@ -88,8 +88,7 @@ public class RegattaLeaderboardTabView extends SharedLeaderboardRegattaTabView<R
if (regattaId != null && !regattaId.isEmpty()) {
String leaderboardName = regattaId;
RegattaAnalyticsDataManager regattaAnalyticsManager = currentPresenter.getCtx().getRegattaAnalyticsManager();
LeaderboardPanel leaderboardPanel = regattaAnalyticsManager.getLeaderboardPanel();
LeaderboardPanel leaderboardPanel = regattaAnalyticsManager.getLeaderboardPanel();
final Consumer<LeaderboardPanel> leaderboardConsumer = new Consumer<LeaderboardPanel>() {
@Override
public void consume(LeaderboardPanel leaderboardPanel) {
@@ -113,18 +112,18 @@ public class RegattaLeaderboardTabView extends SharedLeaderboardRegattaTabView<R
}
regattaAnalyticsManager.hideCompetitorChart();
contentArea.setWidget(RegattaLeaderboardTabView.this);
if (leaderboardPanel.getLeaderboard() != null) {
if(leaderboardPanel.getLeaderboard() != null) {
leaderboard.updatedLeaderboard(leaderboardPanel.getLeaderboard());
}
}
};
if (leaderboardPanel == null) {
if(leaderboardPanel == null) {
createSharedLeaderboardPanel(leaderboardName, regattaAnalyticsManager,
currentPresenter.getUserService(), /* FIXME placeToken */ null, leaderboardConsumer);
} else if ( /* FIXME placeToken not empty */ false) {
} else if( /*FIXME placeToken not empty */ false) {
createLeaderboardComponentContext(leaderboardName, currentPresenter.getUserService(),
/* FIXME placeToken */ null)
.initInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
.getInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
@Override
public void onSuccess(LeaderboardSettings settings) {
leaderboardPanel.updateSettings(settings);
@@ -134,7 +133,6 @@ public class RegattaLeaderboardTabView extends SharedLeaderboardRegattaTabView<R
} else {
leaderboardConsumer.consume(leaderboardPanel);
}
} else {
contentArea.setWidget(new Label("No leaderboard specified, cannot proceed to leaderboardpage"));
new com.google.gwt.user.client.Timer() {
@@ -25,7 +25,7 @@ import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.shared.components.Component;
import com.sap.sse.gwt.client.shared.components.SettingsDialog;
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
/**
* A viewer for an overall series leaderboard. Additionally the viewer can render a chart for the series leaderboard and
@@ -7,18 +7,16 @@ import com.sap.sailing.gwt.home.desktop.places.Consumer;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardPanelLifecycle;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardUrlSettings;
import com.sap.sailing.gwt.settings.client.utils.StorageDefinitionIdFactory;
import com.sap.sailing.gwt.settings.client.utils.StoredSettingsLocationFactory;
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
import com.sap.sse.gwt.client.shared.perspective.ComponentContextWithSettingsStorage;
import com.sap.sse.gwt.client.shared.perspective.DefaultOnSettingsLoadedCallback;
import com.sap.sse.gwt.client.shared.perspective.SettingsStorageManager;
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
import com.sap.sse.security.ui.client.UserService;
import com.sap.sse.security.ui.settings.PlaceBasedUserSettingsStorageManager;
import com.sap.sse.security.ui.settings.StorageDefinitionId;
import com.sap.sse.security.ui.settings.PlaceBasedComponentContextWithSettingsStorage;
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
/**
* An abstract series tabView with some shared functions between the overall leaderboard tab and competitors chart tab
@@ -39,7 +37,7 @@ public abstract class SharedLeaderboardEventSeriesTabView<T extends AbstractSeri
final ComponentContext<LeaderboardSettings> componentContext = createLeaderboardComponentContext(leaderboardName, userService,
placeToken);
componentContext.initInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
componentContext.getInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
@Override
public void onSuccess(LeaderboardSettings leaderboardSettings) {
LeaderboardPanel leaderboardPanel = eventSeriesAnalyticsManager.createOverallLeaderboardPanel(null,
@@ -64,13 +62,11 @@ public abstract class SharedLeaderboardEventSeriesTabView<T extends AbstractSeri
protected ComponentContext<LeaderboardSettings> createLeaderboardComponentContext(String leaderboardName, UserService userService,
String placeToken) {
final LeaderboardPanelLifecycle lifeCycle = new LeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForSeriesOverallLeaderboard(leaderboardName);
final SettingsStorageManager<LeaderboardSettings> settingsStorageManager = new PlaceBasedUserSettingsStorageManager<>(
userService, storageDefinitionId, placeToken);
final LeaderboardPanelLifecycle lifecycle = new LeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory.createStoredSettingsLocatorForSeriesOverallLeaderboard(leaderboardName);
final ComponentContext<LeaderboardSettings> componentContext = new ComponentContextWithSettingsStorage<>(
lifeCycle, settingsStorageManager);
final ComponentContext<LeaderboardSettings> componentContext = new PlaceBasedComponentContextWithSettingsStorage<>(
lifecycle, userService, storageDefinition, placeToken);
return componentContext;
}
}
@@ -22,18 +22,16 @@ import com.sap.sailing.gwt.home.desktop.places.fakeseries.SeriesView;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardUrlSettings;
import com.sap.sailing.gwt.settings.client.leaderboard.MultiLeaderboardPanelLifecycle;
import com.sap.sailing.gwt.settings.client.utils.StorageDefinitionIdFactory;
import com.sap.sailing.gwt.settings.client.utils.StoredSettingsLocationFactory;
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.MultiLeaderboardProxyPanel;
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
import com.sap.sse.gwt.client.shared.perspective.ComponentContextWithSettingsStorage;
import com.sap.sse.gwt.client.shared.perspective.DefaultOnSettingsLoadedCallback;
import com.sap.sse.gwt.client.shared.perspective.SettingsStorageManager;
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
import com.sap.sse.security.ui.client.UserService;
import com.sap.sse.security.ui.settings.PlaceBasedUserSettingsStorageManager;
import com.sap.sse.security.ui.settings.StorageDefinitionId;
import com.sap.sse.security.ui.settings.PlaceBasedComponentContextWithSettingsStorage;
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
public class EventSeriesLeaderboardsTabView extends Composite implements SeriesTabView<EventSeriesLeaderboardsPlace>,
LeaderboardUpdateListener {
@@ -77,7 +75,7 @@ public class EventSeriesLeaderboardsTabView extends Composite implements SeriesT
final boolean autoExpandLastRaceColumn = GwtHttpRequestUtils.getBooleanParameter(LeaderboardUrlSettings.PARAM_AUTO_EXPAND_LAST_RACE_COLUMN, false);
final ComponentContext<LeaderboardSettings> componentContext = createLeaderboardComponentContext(leaderboardName, currentPresenter.getUserService(), /*FIXME placeToken */ null);
componentContext.initInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
componentContext.getInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
@Override
public void onSuccess(LeaderboardSettings settings) {
MultiLeaderboardProxyPanel leaderboardPanel = regattaAnalyticsManager.createMultiLeaderboardPanel(null, componentContext,
@@ -129,12 +127,10 @@ public class EventSeriesLeaderboardsTabView extends Composite implements SeriesT
private ComponentContext<LeaderboardSettings> createLeaderboardComponentContext(String leaderboardName, UserService userService,
String placeToken) {
final MultiLeaderboardPanelLifecycle lifecycle = new MultiLeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForSeriesRegattaLeaderboards(leaderboardName);
final SettingsStorageManager<LeaderboardSettings> settingsStorageManager = new PlaceBasedUserSettingsStorageManager<>(
userService, storageDefinitionId, placeToken);
final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory.createStoredSettingsLocatorForSeriesRegattaLeaderboards(leaderboardName);
final ComponentContext<LeaderboardSettings> componentContext = new ComponentContextWithSettingsStorage<>(
lifecycle, settingsStorageManager);
final ComponentContext<LeaderboardSettings> componentContext = new PlaceBasedComponentContextWithSettingsStorage<>(
lifecycle, userService, storageDefinition, placeToken);
return componentContext;
}
@@ -18,7 +18,7 @@ import com.sap.sailing.gwt.home.desktop.places.fakeseries.SeriesView;
import com.sap.sailing.gwt.home.desktop.places.fakeseries.SharedLeaderboardEventSeriesTabView;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sse.gwt.client.shared.perspective.DefaultOnSettingsLoadedCallback;
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
/**
* Created by pgtaboada on 25.11.14.
@@ -78,7 +78,7 @@ public class EventSeriesOverallLeaderboardTabView extends SharedLeaderboardEvent
if(leaderboardPanel == null) {
createSharedLeaderboardPanel(leaderboardName, eventSeriesAnalyticsManager, currentPresenter.getUserService(), /*FIXME placeToken */ null, leaderboardConsumer);
} else if( /*FIXME placeToken not empty */ false) {
createLeaderboardComponentContext(leaderboardName, currentPresenter.getUserService(), /*FIXME placeToken */ null).initInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
createLeaderboardComponentContext(leaderboardName, currentPresenter.getUserService(), /*FIXME placeToken */ null).getInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
@Override
public void onSuccess(LeaderboardSettings settings) {
leaderboardPanel.updateSettings(settings);
@@ -47,6 +47,9 @@
<c:tabcontent title="{i18n.favoritesAndNotifications}">
<s:preferencestab.UserProfilePreferencesTabView ui:field="preferencesTabUi" />
</c:tabcontent>
<c:tabcontent title="{i18n.settings}">
<s:settingstab.UserProfileSettingsTabView ui:field="settingsTabUi" />
</c:tabcontent>
</c:TabPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -4,6 +4,7 @@ import com.sap.sailing.gwt.home.shared.app.ClientFactoryWithDispatch;
import com.sap.sailing.gwt.ui.client.SailingClientFactory;
import com.sap.sailing.gwt.ui.client.refresh.ErrorAndBusyClientFactory;
import com.sap.sse.security.ui.authentication.WithAuthenticationManager;
import com.sap.sse.security.ui.authentication.WithUserService;
public interface UserProfileClientFactory extends ClientFactoryWithDispatch, SailingClientFactory, ErrorAndBusyClientFactory, WithAuthenticationManager {
public interface UserProfileClientFactory extends ClientFactoryWithDispatch, SailingClientFactory, ErrorAndBusyClientFactory, WithAuthenticationManager, WithUserService {
}
@@ -0,0 +1,55 @@
package com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsEntry;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
public class SettingsEntryDialog extends DataEntryDialog<UserSettingsEntry> {
private final FlowPanel fp;
public SettingsEntryDialog(UserSettingsEntry entry, Runnable deleteCallback) {
super(StringMessages.INSTANCE.settings(), StringMessages.INSTANCE.settingsForId(entry.getKey()), StringMessages.INSTANCE.remove(), StringMessages.INSTANCE.cancel(), null, false, new DialogCallback<UserSettingsEntry>() {
@Override
public void ok(UserSettingsEntry editedObject) {
deleteCallback.run();
}
@Override
public void cancel() {
}
});
fp = new FlowPanel();
final String userProfileSettings = entry.getProfileData();
boolean hasUserData = (userProfileSettings != null && !userProfileSettings.isEmpty());
final String localSettings = entry.getLocalData();
TextArea textArea = createTextArea(hasUserData ? userProfileSettings : localSettings);
textArea.setReadOnly(true);
fp.add(textArea);
}
public TextArea createTextArea(final String initialValue) {
final TextArea textArea = super.createTextArea(initialValue);
textArea.getElement().getStyle().setWidth(25, Unit.EM);
textArea.getElement().getStyle().setHeight(15, Unit.EM);
return textArea;
}
@Override
protected Widget getAdditionalWidget() {
return fp;
}
@Override
protected UserSettingsEntry getResult() {
return null;
}
}
@@ -0,0 +1,41 @@
package com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab;
import com.sap.sailing.gwt.home.desktop.places.user.profile.UserProfileClientFactory;
import com.sap.sailing.gwt.home.desktop.places.user.profile.UserProfileView;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsPresenter;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
import com.sap.sse.security.ui.authentication.app.AuthenticationContext;
public class UserProfileSettingsPresenter implements UserProfileSettingsView.Presenter {
private final UserProfileSettingsView view;
private final UserProfileView.Presenter userProfilePresenter;
private final UserSettingsView.Presenter userSettingsPresenter;
public UserProfileSettingsPresenter(final UserProfileSettingsView view,
final UserProfileView.Presenter userProfilePresenter) {
this.view = view;
this.userProfilePresenter = userProfilePresenter;
this.userSettingsPresenter = new UserSettingsPresenter<UserProfileClientFactory>(
userProfilePresenter.getClientFactory());
view.setPresenter(this);
}
@Override
public UserSettingsView.Presenter getUserSettingsPresenter() {
return userSettingsPresenter;
}
@Override
public void setAuthenticationContext(AuthenticationContext authenticationContext) {
view.getDecorator().setAuthenticationContext(authenticationContext);
if (authenticationContext.isLoggedIn()) {
userSettingsPresenter.loadData();
}
}
@Override
public void doTriggerLoginForm() {
userProfilePresenter.doTriggerLoginForm();
}
}
@@ -0,0 +1,51 @@
package com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.Composite;
import com.sap.sailing.gwt.common.client.controls.tabbar.TabView;
import com.sap.sailing.gwt.home.desktop.places.user.profile.UserProfileTabView;
import com.sap.sailing.gwt.home.desktop.places.user.profile.UserProfileView;
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserProfileSettingsPlace;
import com.sap.sse.security.ui.authentication.app.AuthenticationContext;
public class UserProfileSettingsTabView extends Composite implements UserProfileTabView<UserProfileSettingsPlace> {
private UserProfileSettingsView.Presenter currentPresenter;
private UserProfileSettingsView view;
@Override
public Class<UserProfileSettingsPlace> getPlaceClassForActivation() {
return UserProfileSettingsPlace.class;
}
@Override
public TabView.State getState() {
return ExperimentalFeatures.SHOW_MY_SETTINGS_IN_USER_PROFILE ? TabView.State.VISIBLE : TabView.State.INVISIBLE;
}
@Override
public void start(UserProfileSettingsPlace myPlace, AcceptsOneWidget contentArea) {
contentArea.setWidget(view);
}
@Override
public void setAuthenticationContext(AuthenticationContext authenticationContext) {
currentPresenter.setAuthenticationContext(authenticationContext);
}
@Override
public void stop() {
}
@Override
public UserProfileSettingsPlace placeToFire() {
return new UserProfileSettingsPlace();
}
@Override
public void setPresenter(UserProfileView.Presenter currentPresenter) {
view = new UserProfileSettingsViewImpl();
this.currentPresenter = new UserProfileSettingsPresenter(view, currentPresenter);
}
}
@@ -0,0 +1,17 @@
package com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab;
import com.google.gwt.user.client.ui.IsWidget;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
import com.sap.sse.security.ui.authentication.app.NeedsAuthenticationContext;
import com.sap.sse.security.ui.authentication.decorator.NotLoggedInPresenter;
public interface UserProfileSettingsView extends IsWidget {
void setPresenter(Presenter presenter);
NeedsAuthenticationContext getDecorator();
public interface Presenter extends NotLoggedInPresenter, NeedsAuthenticationContext {
UserSettingsView.Presenter getUserSettingsPresenter();
}
}
@@ -0,0 +1,33 @@
package com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.shared.usermanagement.decorator.AuthorizedContentDecoratorDesktop;
import com.sap.sse.security.ui.authentication.app.NeedsAuthenticationContext;
public class UserProfileSettingsViewImpl extends Composite implements UserProfileSettingsView {
interface MyBinder extends UiBinder<Widget, UserProfileSettingsViewImpl> {
}
private static MyBinder uiBinder = GWT.create(MyBinder.class);
@UiField(provided = true) AuthorizedContentDecoratorDesktop decoratorUi;
@UiField(provided = true) UserSettings userSettingsUi;
@Override
public void setPresenter(Presenter presenter) {
decoratorUi = new AuthorizedContentDecoratorDesktop(presenter);
userSettingsUi = new UserSettings(presenter.getUserSettingsPresenter());
initWidget(uiBinder.createAndBindUi(this));
}
@Override
public NeedsAuthenticationContext getDecorator() {
return decoratorUi;
}
}
@@ -0,0 +1,11 @@
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:um="urn:import:com.sap.sailing.gwt.home.shared.usermanagement.decorator"
xmlns:us="urn:import:com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<um:AuthorizedContentDecoratorDesktop ui:field="decoratorUi">
<um:content>
<us:UserSettings ui:field="userSettingsUi"/>
</um:content>
</um:AuthorizedContentDecoratorDesktop>
</ui:UiBinder>
@@ -0,0 +1,127 @@
package com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab;
import java.util.List;
import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.impl.InvertibleComparatorAdapter;
import com.sap.sailing.gwt.common.theme.component.celltable.DesignedCellTableResources;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsEntry;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.SortedCellTable;
import com.sap.sse.common.Util.Function;
import com.sap.sse.common.util.NaturalComparator;
/**
* Implementation of {@link UserSettingsView} where users can change their preferred selections and notifications.
*/
public class UserSettings extends Composite implements UserSettingsView {
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
interface MyUiBinder extends UiBinder<Widget, UserSettings> {
}
@UiField
DivElement notificationsTextUi;
@UiField
DivElement tableWrapper;
@UiField(provided = true)
final SortedCellTable<UserSettingsEntry> userSettingsTable = new SortedCellTable<>(0,
DesignedCellTableResources.INSTANCE);
private final Column<UserSettingsEntry, String> keyColumn = new Column<UserSettingsEntry, String>(new TextCell()) {
@Override
public String getValue(UserSettingsEntry entry) {
return entry.getKeyWithoutContext();
}
};
private final Column<UserSettingsEntry, String> documentSettingsIdColumn = new Column<UserSettingsEntry, String>(
new TextCell()) {
@Override
public String getValue(UserSettingsEntry entry) {
return entry.getDocumentSettingsId();
}
};
private final Column<UserSettingsEntry, String> deleteColumn = new Column<UserSettingsEntry, String>(
new ButtonCell()) {
@Override
public String getValue(UserSettingsEntry entry) {
return StringMessages.INSTANCE.remove();
}
};
private final Column<UserSettingsEntry, String> showColumn = new Column<UserSettingsEntry, String>(
new ButtonCell()) {
@Override
public String getValue(UserSettingsEntry entry) {
return StringMessages.INSTANCE.show();
}
};
public UserSettings(UserSettingsView.Presenter presenter) {
initWidget(uiBinder.createAndBindUi(this));
deleteColumn.setFieldUpdater(new FieldUpdater<UserSettingsEntry, String>() {
@Override
public void update(int index, UserSettingsEntry object, String value) {
presenter.remove(object);
}
});
showColumn.setFieldUpdater(new FieldUpdater<UserSettingsEntry, String>() {
@Override
public void update(int index, UserSettingsEntry object, String value) {
new SettingsEntryDialog(object, () -> presenter.remove(object)).show();
}
});
userSettingsTable.addColumn(keyColumn, StringMessages.INSTANCE.settingsId(),
new StringComparator(UserSettingsEntry::getKeyWithoutContext), true);
userSettingsTable.addColumn(documentSettingsIdColumn, StringMessages.INSTANCE.documentSettingsId(),
new StringComparator(UserSettingsEntry::getDocumentSettingsId), true);
showColumn.setCellStyleNames(DesignedCellTableResources.INSTANCE.cellTableStyle().buttonCell());
userSettingsTable.addColumn(showColumn, "", null, false);
deleteColumn.setCellStyleNames(DesignedCellTableResources.INSTANCE.cellTableStyle().buttonCell());
userSettingsTable.addColumn(deleteColumn, "", null, false);
presenter.setView(this);
}
@Override
public void setEntries(List<UserSettingsEntry> entries) {
if (entries.isEmpty()) {
notificationsTextUi.setInnerText(StringMessages.INSTANCE.noDataFound());
tableWrapper.getStyle().setDisplay(Display.NONE);
} else {
notificationsTextUi.setInnerText(StringMessages.INSTANCE.userProfileSettingsTabDescription());
tableWrapper.getStyle().clearDisplay();
userSettingsTable.setPageSize(entries.size());
userSettingsTable.setList(entries);
}
}
private static final class StringComparator extends InvertibleComparatorAdapter<UserSettingsEntry> {
private final NaturalComparator innerComnparator = new NaturalComparator();
private final Function<UserSettingsEntry, String> valueExtractor;
public StringComparator(Function<UserSettingsEntry, String> valueExtractor) {
this.valueExtractor = valueExtractor;
}
@Override
public int compare(UserSettingsEntry o1, UserSettingsEntry o2) {
final String s1 = valueExtractor.get(o1);
final String s2 = valueExtractor.get(o2);
return innerComnparator.compare(s1, s2);
}
}
}
@@ -0,0 +1,20 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:um="urn:import:com.sap.sailing.gwt.home.shared.usermanagement.decorator"
xmlns:ms="urn:import:com.sap.sailing.gwt.home.shared.partials.multiselection" xmlns:c="urn:import:com.google.gwt.user.cellview.client">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:style>
.table {
width: 100%;
}
</ui:style>
<g:HTMLPanel addStyleNames="{res.mediaCss.grid} {res.mainCss.spacermarginbottommediumsmall}">
<div ui:field="notificationsTextUi" class="{res.mediaCss.column} {res.mediaCss.medium12} {res.mainCss.spacermargintopsmall} {res.mainCss.spacermarginbottomsmall}">
<ui:text from="{i18n.userNotificationsOnlyIfMailAddressIsVerified}" />
</div>
<div ui:field="tableWrapper" class="{res.mediaCss.column} {res.mediaCss.small12} {res.mainCss.spacermargintopmediumsmall}">
<c:CellTable ui:field="userSettingsTable" addStyleNames="{style.table}" />
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -10,6 +10,27 @@
particularly also during the start phase, making it possible to
enter penalties such as OCS, BFD or UFD when they occur.
</li>
<li>When adding a result for a competitor, this result can be "reset" in
two ways: either the entry is swiped from the result list (trash can).
This way, no update will be sent to the server for that competitor until
it is added again to the result list. If instead any explicit score
for the competitor is cleared, the rank is set to 0 and the penalty is
set to "NONE" then the competitor will remain in the list, and this
"empty" result will be sent to the server, clearing any previous score
</li>
<li>When entering and publishing partial results, updates will only be applied
for those competitors for which a result has been entered. In particular,
when operating with multiple devices on the same course area and in case
the devices haven't synchronized their states yet this will make sure that
partial results entered on one device will not unnecessarily remove changes
applied on another device.
</li>
corrections that were sent to the server. This is the only way to
"reset" an erroneous score correction entirely from the app, because
swiping and thus removing the competitor from the list would leave the
previous score correction unchanged on the server upon the next result
publication.
</li>
</ul>
<h5 class="articleSubheadline">April 2017</h5>
@@ -4,8 +4,24 @@
<div id="mainContent">
<h4 class="articleHeadline">What's New - SAP Sailing Analytics</h4>
<div class="innerContent">
<h5 class="articleSubheadline">May 2017</h5>
<h5 class="articleSubheadline">June 2017</h5>
<ul class="bulletList">
<li>Several improvements were implemented regarding user settings:
<ul>
<li>Document settings are saved as delta to the user defaults instead of the delta to the system defaults.
In cases where a setting has the value 'A' as system default and 'B' as user default, it's now possible to set it back to 'A' for a document.
Settings stored before this change will continue to work with the old overwriting semantic.</li>
<li>Collection based settings are now stored as delta to the default set of values. This means that removals and additions are being recorded instead of all values of a setting.
Having value 'A' as system default and adding 'B' for the user default and 'C' for one document will select values 'A', 'B' and 'C' for the document.</li>
<li>Settings dialogs now have a 'reset to default' button. When pressing this button, user defaults as well as the current document settings are being reset to the system defaults.
In addition, the settings dialog is updated to show the system defaults. Those defaults will only take effect for the current view when pressing ok.</li>
<li>User settings can now also be saved for <code>/gwt/RaceBoard.html</code>. Be aware that different modes have distinct settings so that defaults defined for one mode do not have any effect on other modes.</li>
<li>On the user profile page you can now find a list of all stored settings. You can show the technical settings data and remove specific setting entries.</li>
</ul>
</li>
</ul>
<h5 class="articleSubheadline">May 2017</h5>
<ul class="bulletList">
<li>It's now possible to show nationality flags in addition to competitor images in leaderboards if both are available.
If no competitor images are available, this won't have any effect.
@@ -15,20 +31,22 @@
<h5 class="articleSubheadline">April 2017</h5>
<ul class="bulletList">
<li>Several pages are now enabled to save user settings. In settings dialogs there is a "Make default"
button in the lower-left corner which is displayed when saving of settings is enabled. A click on that
button causes the system to use the new settings as default values for the same page for any other context opened, e.g. another event.
A click on OK button causes the system to store current settings for the current context and restore the same settings
when the user opens the page with the same context again unless there are specific parameters given by the URL. Settings saved this way are
stored locally in the browser's local storage and in the user profile if you are logged in.
Some settings are only valid in a specific context (e.g. the selected race columns to show are stored for a specific leaderboard only).
This feature required changing several URL parameters, which means that previously saved bookmarks might work slightly different.
Affected pages:
<li>Several pages are now enabled to save user settings with the following specifics:
<ul>
<li>In settings dialogs there is a "Make default" button in the lower-left corner which is displayed when saving of settings is enabled. A click on that
button causes the system to use the new settings as default values for the same page. This is independent of a race, event or leaderboard to be shown.</li>
<li>A click on OK button causes the system to store the settings as document settings. Document settings are only used for the same event, leaderboard or race.
When the page is opened for e.g. the same race, the settings used last time are loaded.</li>
<li>Settings saved this way are stored locally in the browser's local storage and in the user profile if you are logged in.</li>
<li>Settings can be overwritten by URL parameters.</li>
</ul>
The following pages are now enabled to provide user settings:
<ul>
<li><code>/gwt/Leaderboard.html</code></li>
<li><code>/gwt/RegattaOverview.html</code></li>
<li>Leaderboards embedded in <code>/gwt/Home.html</code></li>
</ul>
</ul>
This feature required changing several URL parameters, which means that previously saved bookmarks might work slightly different.
</li>
<li>The maneuver loss calculation for penalty circles has been improved. Previously, the end of the
penalty circle maneuver was considered to be at the last of the two adjacent tack/gybe maneuvers.
@@ -29,6 +29,7 @@ import com.sap.sse.gwt.client.mvp.ErrorView;
import com.sap.sse.security.ui.authentication.AuthenticationManager;
import com.sap.sse.security.ui.authentication.AuthenticationManagerImpl;
import com.sap.sse.security.ui.authentication.WithAuthenticationManager;
import com.sap.sse.security.ui.authentication.WithUserService;
import com.sap.sse.security.ui.client.SecureClientFactoryImpl;
import com.sap.sse.security.ui.client.i18n.StringMessages;
@@ -40,7 +41,7 @@ import com.sap.sse.security.ui.client.i18n.StringMessages;
public class MobileApplicationClientFactory extends
SecureClientFactoryImpl<ApplicationTopLevelView<ResettableNavigationPathDisplay>> implements
ErrorAndBusyClientFactory, SearchResultClientFactory, ConfirmationClientFactory, PasswordResetClientFactory,
WithAuthenticationManager {
WithAuthenticationManager, WithUserService {
private final MobilePlacesNavigator navigator;
private final SailingDispatchSystem dispatch = new SailingDispatchSystemImpl();
private final AuthenticationManager authenticationManager;
@@ -63,6 +63,9 @@
font-size: 0.866666666666667em;
color: #0a0a0a;
}
.sectionheader_item, .sectionheader_item_title, .sectionheader_item_subtitle {
max-width: 100%;
}
.sectionheader_item_infotext {
display: inline-block;
vertical-align: middle;
@@ -112,9 +115,8 @@ img.sectionheader_item_arrow.accordion.collapsed {
background: url("images/mobile/filter.svg") 100% no-repeat transparent;
background-size: 1.333333333333333em;
}
.sectionheader_item_adjust_title {
margin-left: 4em;
margin-right: 2.5em;
.sectionheader_item_adjust_title_left {
padding-left: 4em;
position: absolute;
top: 50%;
-webkit-transform: translateY(-50%);
@@ -122,6 +124,9 @@ img.sectionheader_item_arrow.accordion.collapsed {
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
.sectionheader_item_adjust_title > h2 {
.sectionheader_item_adjust_title_left > h2 {
display: inline;
}
.sectionheader_item_adjust_title_right {
padding-right: 2.5em;
}
@@ -1,25 +0,0 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:mp="urn:import:com.sap.sailing.gwt.home.mobile.partials">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.mobile.partials.sectionHeader.SectionHeaderResources" />
<g:HTMLPanel>
<div class="{res.mediaCss.grid}">
<a href="#" title="TODO">
<!-- IF isStandalone ADD class 'section-header--stand-alone' -->
<div class="{local_res.css.sectionheader} {res.mediaCss.small12} {res.mediaCss.columns} {local_res.css.sectionheaderstandalone}">
<!-- IF END -->
<mp:sectionHeader.SectionHeaderContent />
</div>
</a>
</div>
<div class="{res.mediaCss.grid}">
<!-- IF isStandalone ADD class 'section-header--stand-alone' -->
<div class="{local_res.css.sectionheader} {res.mediaCss.small12} {res.mediaCss.columns} {local_res.css.sectionheaderstandalone}">
<!-- IF END -->
<mp:sectionHeader.SectionHeaderContent />
</div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -10,8 +10,6 @@ import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.SimplePanel;
@@ -75,7 +73,8 @@ public class SectionHeaderContent extends Composite {
public void setImageUrl(String imageUrl) {
imageUi.getStyle().clearDisplay();
imageUi.getStyle().setBackgroundImage("url(" + imageUrl + ")");
titleAndLabelContainerUi.addClassName(SectionHeaderResources.INSTANCE.css().sectionheader_item_adjust_title());
titleAndLabelContainerUi
.addClassName(SectionHeaderResources.INSTANCE.css().sectionheader_item_adjust_title_left());
}
public void setInfoText(String infoText) {
@@ -97,23 +96,31 @@ public class SectionHeaderContent extends Composite {
});
actionArrowUi.setSrc("images/mobile/arrow-down-grey.png");
actionArrowUi.addClassName(SectionHeaderResources.INSTANCE.css().accordion());
titleAndLabelContainerUi
.addClassName(SectionHeaderResources.INSTANCE.css().sectionheader_item_adjust_title_right());
actionArrowUi.getStyle().clearDisplay();
headerRightUi.getStyle().clearDisplay();
}
public void setClickAction(final PlaceNavigation<?> placeNavigation) {
placeNavigation.configureAnchorElement(headerMainUi);
this.adjustedActionStyles();
titleAndLabelContainerUi
.addClassName(SectionHeaderResources.INSTANCE.css().sectionheader_item_adjust_title_right());
headerRightUi.getStyle().clearDisplay();
actionArrowUi.getStyle().clearDisplay();
}
public void setClickAction(final String url) {
headerMainUi.setHref(url);
DOM.setEventListener(headerMainUi, new EventListener() {
@Override
public void onBrowserEvent(Event event) {
}
DOM.setEventListener(headerMainUi, event -> {
});
this.adjustedActionStyles();
}
private void adjustedActionStyles() {
titleAndLabelContainerUi
.addClassName(SectionHeaderResources.INSTANCE.css().sectionheader_item_adjust_title_right());
headerRightUi.getStyle().clearDisplay();
actionArrowUi.getStyle().clearDisplay();
}
@@ -23,7 +23,8 @@ public interface SectionHeaderResources extends ClientBundle {
String sectionheader_item_subtitle();
String sectionheader_item_infotext();
String sectionheader_item_arrow();
String sectionheader_item_adjust_title();
String sectionheader_item_adjust_title_left();
String sectionheader_item_adjust_title_right();
String sectionheader_item_select();
String accordion();
String collapsed();
@@ -261,13 +261,12 @@ public abstract class AbstractEventActivity<PLACE extends AbstractEventPlace> ex
RaceboardContextDefinition raceboardContext = new RaceboardContextDefinition(raceIdentifier.getRegattaName(),
raceIdentifier.getRaceName(), leaderboardName, leaderboardGroupName,
UUID.fromString(getCtx().getEventId()), mode);
RaceBoardPerspectiveOwnSettings perspectiveOwnSettings = RaceBoardPerspectiveOwnSettings
.createDefaultWithCanReplayDuringLiveRaces(true);
RaceBoardPerspectiveOwnSettings perspectiveOwnSettings = new RaceBoardPerspectiveOwnSettings();
HashMap<String, Settings> innerSettings = new HashMap<>();
innerSettings.put(RaceMapLifecycle.ID, RaceMapSettings.getDefaultWithShowMapControls(true));
PerspectiveCompositeSettings<RaceBoardPerspectiveOwnSettings> settings = new PerspectiveCompositeSettings<>(
perspectiveOwnSettings, innerSettings);
return EntryPointWithSettingsLinkFactory.createRaceBoardLink(raceboardContext, settings);
}
@@ -28,4 +28,9 @@ public abstract class AbstractUserProfileActivity extends AbstractActivity imple
return clientFactory.getNavigator().getUserPreferencesNavigation();
}
@Override
public PlaceNavigation<? extends AbstractUserProfilePlace> getUserSettingsNavigation() {
return clientFactory.getNavigator().getUserSettingsNavigation();
}
}
@@ -9,6 +9,7 @@ import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.common.client.SharedResources;
import com.sap.sailing.gwt.home.mobile.partials.quickfinder.Quickfinder;
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
import com.sap.sailing.gwt.home.shared.usermanagement.decorator.AuthorizedContentDecoratorMobile;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.security.ui.authentication.app.AuthenticationContext;
@@ -42,6 +43,9 @@ public class AbstractUserProfileView extends Composite implements UserProfileVie
this.layout.quickfinderUi.addPlaceholderItem(i18n.profileQuickfinder());
this.layout.quickfinderUi.addItem(i18n.details(), presenter.getUserProfileNavigation());
this.layout.quickfinderUi.addItem(i18n.favoritesAndNotifications(), presenter.getUserPreferencesNavigation());
if(ExperimentalFeatures.SHOW_MY_SETTINGS_IN_USER_PROFILE) {
this.layout.quickfinderUi.addItem(i18n.settings(), presenter.getUserSettingsNavigation());
}
}
protected final void setViewContent(IsWidget content) {
@@ -4,8 +4,10 @@ import com.google.gwt.core.client.GWT;
import com.sap.sailing.gwt.home.mobile.app.MobileApplicationClientFactory;
import com.sap.sailing.gwt.home.mobile.places.user.profile.details.UserProfileDetailsActivity;
import com.sap.sailing.gwt.home.mobile.places.user.profile.preferences.UserProfilePreferencesActivity;
import com.sap.sailing.gwt.home.mobile.places.user.profile.settings.UserProfileSettingsActivity;
import com.sap.sailing.gwt.home.shared.places.user.profile.AbstractUserProfilePlace;
import com.sap.sailing.gwt.home.shared.places.user.profile.preferences.UserProfilePreferencesPlace;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserProfileSettingsPlace;
import com.sap.sse.gwt.client.mvp.AbstractActivityProxy;
public class UserProfileActivityProxy extends AbstractActivityProxy {
@@ -26,6 +28,8 @@ public class UserProfileActivityProxy extends AbstractActivityProxy {
if (currentPlace instanceof UserProfilePreferencesPlace) {
UserProfilePreferencesPlace userProfilePrefsPlace = (UserProfilePreferencesPlace) currentPlace;
super.onSuccess(new UserProfilePreferencesActivity(userProfilePrefsPlace, clientFactory));
} else if(currentPlace instanceof UserProfileSettingsPlace) {
super.onSuccess(new UserProfileSettingsActivity((UserProfileSettingsPlace) currentPlace, clientFactory));
} else {
super.onSuccess(new UserProfileDetailsActivity(currentPlace, clientFactory));
}
@@ -11,5 +11,6 @@ public interface UserProfileViewBase extends IsWidget, NeedsAuthenticationContex
public interface Presenter extends NotLoggedInPresenter {
PlaceNavigation<? extends AbstractUserProfilePlace> getUserProfileNavigation();
PlaceNavigation<? extends AbstractUserProfilePlace> getUserPreferencesNavigation();
PlaceNavigation<? extends AbstractUserProfilePlace> getUserSettingsNavigation();
}
}
@@ -0,0 +1,44 @@
package com.sap.sailing.gwt.home.mobile.places.user.profile.settings;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.sap.sailing.gwt.home.mobile.app.MobileApplicationClientFactory;
import com.sap.sailing.gwt.home.mobile.places.user.profile.AbstractUserProfileActivity;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserProfileSettingsPlace;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsPresenter;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
import com.sap.sse.security.ui.authentication.AuthenticationContextEvent;
public class UserProfileSettingsActivity extends AbstractUserProfileActivity implements UserProfileSettingsView.Presenter {
private final UserSettingsView.Presenter userSettingsPresenter;
private final UserProfileSettingsView currentView;
public UserProfileSettingsActivity(UserProfileSettingsPlace place,
MobileApplicationClientFactory clientFactory) {
super(clientFactory);
this.userSettingsPresenter = new UserSettingsPresenter<MobileApplicationClientFactory>(clientFactory);
this.currentView = new UserProfileSettingsViewImpl(this);
}
@Override
public void start(final AcceptsOneWidget panel, final EventBus eventBus) {
panel.setWidget(currentView);
currentView.setAuthenticationContext(clientFactory.getAuthenticationManager().getAuthenticationContext());
eventBus.addHandler(AuthenticationContextEvent.TYPE, new AuthenticationContextEvent.Handler() {
@Override
public void onUserChangeEvent(AuthenticationContextEvent event) {
currentView.setAuthenticationContext(event.getCtx());
}
});
if (clientFactory.getAuthenticationManager().getAuthenticationContext().isLoggedIn()) {
userSettingsPresenter.loadData();
}
}
@Override
public UserSettingsView.Presenter getUserSettingsPresenter() {
return userSettingsPresenter;
}
}
@@ -0,0 +1,12 @@
package com.sap.sailing.gwt.home.mobile.places.user.profile.settings;
import com.sap.sailing.gwt.home.mobile.places.user.profile.UserProfileViewBase;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
public interface UserProfileSettingsView extends UserProfileViewBase {
public interface Presenter extends UserProfileViewBase.Presenter {
UserSettingsView.Presenter getUserSettingsPresenter();
}
}
@@ -0,0 +1,16 @@
package com.sap.sailing.gwt.home.mobile.places.user.profile.settings;
import com.sap.sailing.gwt.home.mobile.places.user.profile.AbstractUserProfileView;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
public class UserProfileSettingsViewImpl extends AbstractUserProfileView implements UserProfileSettingsView {
private final UserSettingsView userPreferencesView;
public UserProfileSettingsViewImpl(UserProfileSettingsView.Presenter presenter) {
super(presenter);
this.userPreferencesView = new UserSettings(presenter.getUserSettingsPresenter());
this.setViewContent(userPreferencesView);
}
}
@@ -0,0 +1,46 @@
package com.sap.sailing.gwt.home.mobile.places.user.profile.settings;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsEntry;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
import com.sap.sailing.gwt.ui.client.StringMessages;
/**
* Implementation of {@link UserSettingsView} where users can change their preferred selections and notifications.
*/
public class UserSettings extends Composite implements UserSettingsView {
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
interface MyUiBinder extends UiBinder<Widget, UserSettings> {
}
@UiField
DivElement notificationsTextUi;
@UiField
FlowPanel settingsContainerUi;
private final Presenter presenter;
public UserSettings(UserSettingsView.Presenter presenter) {
this.presenter = presenter;
initWidget(uiBinder.createAndBindUi(this));
presenter.setView(this);
}
@Override
public void setEntries(List<UserSettingsEntry> entries) {
notificationsTextUi.setInnerText(entries.isEmpty() ? StringMessages.INSTANCE.noDataFound()
: StringMessages.INSTANCE.userProfileSettingsTabDescription());
settingsContainerUi.clear();
entries.forEach(entry -> settingsContainerUi.add(new UserSettingsItem(entry, () -> presenter.remove(entry))));
}
}
@@ -0,0 +1,11 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<g:HTMLPanel addStyleNames="{res.mediaCss.grid} {res.mainCss.spacermarginbottommediumsmall}">
<div ui:field="notificationsTextUi" class="{res.mediaCss.column} {res.mediaCss.small12} {res.mainCss.spacermargintopsmall} {res.mainCss.spacermarginbottomsmall}">
<ui:text from="{i18n.userNotificationsOnlyIfMailAddressIsVerified}" />
</div>
<g:FlowPanel ui:field="settingsContainerUi" addStyleNames="{res.mediaCss.column} {res.mediaCss.small12}" />
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,49 @@
package com.sap.sailing.gwt.home.mobile.places.user.profile.settings;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.sap.sailing.gwt.home.mobile.partials.section.MobileSection;
import com.sap.sailing.gwt.home.mobile.partials.sectionHeader.SectionHeaderContent;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsEntry;
public class UserSettingsItem extends Composite {
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
interface MyUiBinder extends UiBinder<MobileSection, UserSettingsItem> {
}
@UiField SectionHeaderContent sectionHeaderUi;
@UiField HTMLPanel contentContainerUi;
@UiField DivElement settingsDataUi;
private final Runnable deleteCallback;
public UserSettingsItem(UserSettingsEntry userSettingsEntry, Runnable deleteCallback) {
this.deleteCallback = deleteCallback;
MobileSection mobileSection = uiBinder.createAndBindUi(this);
mobileSection.setEdgeToEdgeContent(true);
initWidget(mobileSection);
sectionHeaderUi.setSectionTitle(userSettingsEntry.getKeyWithoutContext());
sectionHeaderUi.setSubtitle(userSettingsEntry.getDocumentSettingsId());
final String userProfileSettings = userSettingsEntry.getProfileData();
boolean hasUserData = (userProfileSettings != null && !userProfileSettings.isEmpty());
final String localSettings = userSettingsEntry.getLocalData();
settingsDataUi.setInnerText(hasUserData ? userProfileSettings : localSettings);
sectionHeaderUi.initCollapsibility(contentContainerUi.getElement(), false);
}
@UiHandler("deleteControlUi")
void onRemoveControlClicked(ClickEvent event) {
this.deleteCallback.run();
}
}
@@ -0,0 +1,30 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:ms="urn:import:com.sap.sailing.gwt.home.mobile.partials.section"
xmlns:sh="urn:import:com.sap.sailing.gwt.home.mobile.partials.sectionHeader">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:style>
.wordwrapping {
word-wrap: break-word;
}
.content {
padding: .333333333333333em;
}
.deleteControl {
width: 100%;
}
</ui:style>
<ms:MobileSection addStyleNames="{style.wordwrapping}">
<ms:header>
<sh:SectionHeaderContent ui:field="sectionHeaderUi"/>
</ms:header>
<ms:content>
<g:HTMLPanel ui:field="contentContainerUi" addStyleNames="{style.content}">
<div ui:field="settingsDataUi" class="{res.mainCss.spacermarginbottomsmall}"></div>
<g:Button ui:field="deleteControlUi" text="{i18n.delete}"
addStyleNames="{res.mainCss.button} {res.mainCss.buttonprimary} {style.deleteControl}" />
</g:HTMLPanel>
</ms:content>
</ms:MobileSection>
</ui:UiBinder>
@@ -13,4 +13,8 @@ public class ExperimentalFeatures {
* Provide buttons for user management login via social services like facebook or google.
*/
public static final boolean SHOW_SOCIAL_LOGINS_FOR_USER_MANAGEMENT = false;
/**
* Provide a tab "settings" in the user profile page.
*/
public static final boolean SHOW_MY_SETTINGS_IN_USER_PROFILE = true;
}
@@ -38,6 +38,7 @@ import com.sap.sailing.gwt.home.shared.places.user.passwordreset.PasswordResetPl
import com.sap.sailing.gwt.home.shared.places.user.profile.UserProfileDefaultPlace;
import com.sap.sailing.gwt.home.shared.places.user.profile.UserProfileDetailsPlace;
import com.sap.sailing.gwt.home.shared.places.user.profile.preferences.UserProfilePreferencesPlace;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserProfileSettingsPlace;
@WithTokenizers({ AboutUsPlace.Tokenizer.class, ContactPlace.Tokenizer.class, EventPlace.Tokenizer.class,
EventsPlace.Tokenizer.class, SolutionsPlace.Tokenizer.class, WhatsNewPlace.Tokenizer.class,
@@ -72,6 +73,7 @@ import com.sap.sailing.gwt.home.shared.places.user.profile.preferences.UserProfi
UserProfileDefaultPlace.Tokenizer.class,
UserProfileDetailsPlace.Tokenizer.class,
UserProfilePreferencesPlace.Tokenizer.class,
UserProfileSettingsPlace.Tokenizer.class,
AuthenticationPlace.Tokenizer.class,
ConfirmationPlace.Tokenizer.class,
PasswordResetPlace.Tokenizer.class,
@@ -21,6 +21,7 @@ import com.sap.sailing.gwt.home.shared.places.user.passwordreset.PasswordResetPl
import com.sap.sailing.gwt.home.shared.places.user.profile.AbstractUserProfilePlace;
import com.sap.sailing.gwt.home.shared.places.user.profile.UserProfileDefaultPlace;
import com.sap.sailing.gwt.home.shared.places.user.profile.preferences.UserProfilePreferencesPlace;
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserProfileSettingsPlace;
public class HomePlacesNavigator extends AbstractPlaceNavigator {
@@ -103,4 +104,8 @@ public class HomePlacesNavigator extends AbstractPlaceNavigator {
public PlaceNavigation<? extends AbstractUserProfilePlace> getUserPreferencesNavigation() {
return createLocalPlaceNavigation(new UserProfilePreferencesPlace());
}
public PlaceNavigation<? extends AbstractUserProfilePlace> getUserSettingsNavigation() {
return createLocalPlaceNavigation(new UserProfileSettingsPlace());
}
}
@@ -26,6 +26,7 @@ public class PlaceTokenPrefixes {
public static final String UserProfileDefault = "/user/profile/";
public static final String UserProfileDetails = "/user/profile/details/";
public static final String UserProfilePreferences = "/user/profile/preferences/";
public static final String UserProfileSettings = "/user/profile/settings/";
public static final String UserConfirmation = "/user/confirmation/";
public static final String UserPasswordReset = "/user/passwordreset/";
public static final String UserAuthentication = "/user/auth/";
@@ -0,0 +1,18 @@
package com.sap.sailing.gwt.home.shared.places.user.profile.settings;
import com.google.gwt.place.shared.Prefix;
import com.sap.sailing.gwt.home.shared.app.HasMobileVersion;
import com.sap.sailing.gwt.home.shared.places.PlaceTokenPrefixes;
import com.sap.sailing.gwt.home.shared.places.user.profile.AbstractUserProfilePlace;
public class UserProfileSettingsPlace extends AbstractUserProfilePlace implements HasMobileVersion {
@Prefix(PlaceTokenPrefixes.UserProfileSettings)
public static class Tokenizer extends AbstractUserProfilePlace.Tokenizer<UserProfileSettingsPlace> {
@Override
protected UserProfileSettingsPlace getRealPlace() {
return new UserProfileSettingsPlace();
}
}
}
@@ -0,0 +1,47 @@
package com.sap.sailing.gwt.home.shared.places.user.profile.settings;
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
public class UserSettingsEntry {
private final String key;
private final String keyWithoutContext;
private final String documentSettingsId;
private final String profileData;
private final String localData;
public UserSettingsEntry(String key, String profileData, String localData) {
super();
final int separatorIndex = key.indexOf(StoredSettingsLocation.DOCUMENT_SETTINGS_SUFFIX_SEPARATOR);
if(separatorIndex > 0) {
keyWithoutContext = key.substring(0, separatorIndex);
documentSettingsId = key.substring(separatorIndex + 1);
} else {
keyWithoutContext = key;
documentSettingsId = null;
}
this.key = key;
this.profileData = profileData;
this.localData = localData;
}
public String getKey() {
return key;
}
public String getProfileData() {
return profileData;
}
public String getLocalData() {
return localData;
}
public String getDocumentSettingsId() {
return documentSettingsId;
}
public String getKeyWithoutContext() {
return keyWithoutContext;
}
}
@@ -0,0 +1,101 @@
package com.sap.sailing.gwt.home.shared.places.user.profile.settings;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import com.google.gwt.storage.client.Storage;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.gwt.home.shared.app.ClientFactoryWithDispatch;
import com.sap.sailing.gwt.ui.client.refresh.ErrorAndBusyClientFactory;
import com.sap.sailing.gwt.ui.shared.settings.SailingSettingsConstants;
import com.sap.sse.security.ui.authentication.WithAuthenticationManager;
import com.sap.sse.security.ui.authentication.WithUserService;
/**
* @param <C>
* the provided client factory type
*/
public class UserSettingsPresenter<C extends ClientFactoryWithDispatch & ErrorAndBusyClientFactory & WithAuthenticationManager & WithUserService>
implements UserSettingsView.Presenter {
private final C clientFactory;
private UserSettingsView view;
private final List<UserSettingsEntry> currentlyShownEntries = new ArrayList<>();
public UserSettingsPresenter(C clientFactory) {
this.clientFactory = clientFactory;
}
@Override
public void loadData() {
if(clientFactory.getAuthenticationManager().getAuthenticationContext().isLoggedIn()) {
clientFactory.getUserService().getAllPreferences(new AsyncCallback<Map<String,String>>() {
@Override
public void onSuccess(Map<String, String> result) {
loadSettingsFromLocalStorage(result);
}
@Override
public void onFailure(Throwable caught) {
clientFactory.createErrorView("Error while loading user settings!", caught);
}
});
} else {
loadSettingsFromLocalStorage(Collections.emptyMap());
}
}
private void loadSettingsFromLocalStorage(final Map<String, String> userSettings) {
final Map<String, String> localSettings = loadSettingsFromLocalStorage();
final Set<String> allKeys = new TreeSet<>((a, b) -> a.compareTo(b));
allKeys.addAll(userSettings.keySet());
allKeys.addAll(localSettings.keySet());
currentlyShownEntries.clear();
for(String key : allKeys) {
currentlyShownEntries.add(new UserSettingsEntry(key, userSettings.get(key), localSettings.get(key)));
}
view.setEntries(currentlyShownEntries);
}
private Map<String, String> loadSettingsFromLocalStorage() {
final Map<String, String> localSettings;
if(Storage.isLocalStorageSupported()) {
localSettings = new HashMap<String, String>();
Storage localStorage = Storage.getLocalStorageIfSupported();
for(int i = 0; i< localStorage.getLength(); i++) {
String key = localStorage.key(i);
if(key.startsWith(SailingSettingsConstants.USER_SETTINGS_UI)) {
String value = localStorage.getItem(key);
localSettings.put(key, value);
}
}
} else {
localSettings = Collections.emptyMap();
}
return localSettings;
}
@Override
public void remove(UserSettingsEntry entry) {
String storageKey = entry.getKey();
clientFactory.getUserService().unsetPreference(storageKey);
if(Storage.isLocalStorageSupported()) {
Storage localStorage = Storage.getLocalStorageIfSupported();
localStorage.removeItem(storageKey);
}
currentlyShownEntries.remove(entry);
view.setEntries(currentlyShownEntries);
}
@Override
public void setView(UserSettingsView view) {
this.view = view;
}
}
@@ -0,0 +1,29 @@
package com.sap.sailing.gwt.home.shared.places.user.profile.settings;
import java.util.List;
import com.google.gwt.user.client.ui.IsWidget;
import com.sap.sailing.gwt.home.shared.partials.multiselection.SuggestedMultiSelectionDataProvider;
/**
* Interface for the user preferences UI. To support desktop as well as mobile version, an
* {@link #setEdgeToEdge(boolean) edge-to-edge} flag can be provided, in order to meet the respective layout
* requirements.
*/
public interface UserSettingsView extends IsWidget {
void setEntries(List<UserSettingsEntry> entries);
/**
* Presenter interface for the user preferences UI, providing methods to load preferences and to access the required
* {@link SuggestedMultiSelectionDataProvider}s.
*/
public interface Presenter {
void loadData();
void remove(UserSettingsEntry entry);
void setView(UserSettingsView view);
}
}
@@ -1,11 +0,0 @@
package com.sap.sailing.gwt.regattaoverview.client;
import java.util.List;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
public interface EventAndRaceGroupAvailabilityListener {
void onEventUpdated(EventDTO event);
void onRaceGroupsUpdated(List<RaceGroupDTO> raceGroups);
}
@@ -16,11 +16,9 @@ import com.google.gwt.user.client.ui.ScrollPanel;
import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication;
import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication;
import com.sap.sailing.gwt.common.client.SharedResources;
import com.sap.sailing.gwt.regattaoverview.client.RegattaRaceStatesComponent.EntryHandler;
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaOverviewContextDefinition;
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaRaceStatesSettings;
import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint;
import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
public class RegattaOverviewEntryPoint extends AbstractSailingEntryPoint {
@@ -56,30 +54,18 @@ public class RegattaOverviewEntryPoint extends AbstractSailingEntryPoint {
siteHeader.addWidgetToRightSide(clockLabel);
containerPanel.addNorth(siteHeader, 75);
RegattaOverviewContextDefinition regattaOverviewSettings = serializer
RegattaOverviewContextDefinition regattaOverviewContextDefinition = serializer
.deserializeFromCurrentLocation(new RegattaOverviewContextDefinition());
if (regattaOverviewSettings.getEvent() == null) {
if (regattaOverviewContextDefinition.getEvent() == null) {
Window.alert("Missing parameter");
return;
}
createAndAddDetailPanel();
createAndAddRegattaPanel(regattaOverviewSettings);
createAndAddRegattaPanel(regattaOverviewContextDefinition);
toggleDetailPanel(false);
regattaPanel.setEntryClickedHandler(new EntryHandler() {
@Override
public void onEntryClicked(RegattaOverviewEntryDTO entry) {
detailPanel.show(entry);
toggleDetailPanel(true);
}
@Override
public void onEntryUpdated(RegattaOverviewEntryDTO entry) {
detailPanel.update(entry);
}
});
}
private void toggleDetailPanel(boolean visibile) {
@@ -23,7 +23,7 @@ import com.sap.sailing.gwt.regattaoverview.client.RegattaRaceStatesComponent.Ent
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaOverviewContextDefinition;
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaRaceStatesSettings;
import com.sap.sailing.gwt.settings.client.utils.StorageDefinitionIdFactory;
import com.sap.sailing.gwt.settings.client.utils.StoredSettingsLocationFactory;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
@@ -40,13 +40,12 @@ import com.sap.sse.gwt.client.player.Timer.PlayModes;
import com.sap.sse.gwt.client.player.Timer.PlayStates;
import com.sap.sse.gwt.client.shared.components.LinkWithSettingsGenerator;
import com.sap.sse.gwt.client.shared.components.SettingsDialog;
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
import com.sap.sse.gwt.client.shared.perspective.ComponentContextWithSettingsStorage;
import com.sap.sse.gwt.client.shared.perspective.DefaultOnSettingsLoadedCallback;
import com.sap.sse.gwt.client.shared.perspective.SettingsStorageManager;
import com.sap.sse.gwt.client.shared.perspective.IgnoreLocalSettings;
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
import com.sap.sse.security.ui.client.UserService;
import com.sap.sse.security.ui.settings.StorageDefinitionId;
import com.sap.sse.security.ui.settings.UserSettingsStorageManager;
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
public class RegattaOverviewPanel extends SimplePanel {
@@ -63,7 +62,6 @@ public class RegattaOverviewPanel extends SimplePanel {
private final RegattaOverviewContextDefinition regattaOverviewContextDefinition;
private EventDTO eventDTO;
private List<RaceGroupDTO> raceGroupDTOs;
private List<EventAndRaceGroupAvailabilityListener> eventRaceGroupListeners;
private boolean showLeaderboard = false;
private RegattaRaceStatesComponent regattaRaceStatesComponent;
@@ -74,12 +72,20 @@ public class RegattaOverviewPanel extends SimplePanel {
private final Anchor startStopUpdatingButton;
private CheckBox leaderboardCheckBox;
private final FlowPanel repeatedInfoLabel = new FlowPanel();
private VerticalPanel mainPanel;
private UserService userService;
private ComponentContext<RegattaRaceStatesSettings> componentContext;
private final RegattaOverviewResources.LocalCss style = RegattaOverviewResources.INSTANCE.css();
private final SharedResources RES = SharedResources.INSTANCE;
private EntryHandler entryClickedHandler = null;
public void setEntryClickedHandler(EntryHandler handler) {
regattaRaceStatesComponent.setEntryClickedHandler(handler);
entryClickedHandler = handler;
if(regattaRaceStatesComponent != null) {
regattaRaceStatesComponent.setEntryClickedHandler(handler);
}
}
public RegattaOverviewPanel(
@@ -97,12 +103,9 @@ public class RegattaOverviewPanel extends SimplePanel {
this.uiUpdateTimer = new Timer(PlayModes.Live, uiUpdateRateInMs);
this.eventDTO = null;
this.raceGroupDTOs = new ArrayList<RaceGroupDTO>();
this.eventRaceGroupListeners = new ArrayList<EventAndRaceGroupAvailabilityListener>();
this.userService = userService;
retrieveEvent();
retrieveRegattaStructure();
VerticalPanel mainPanel = new VerticalPanel();
mainPanel = new VerticalPanel();
setWidget(mainPanel);
mainPanel.setWidth("100%");
mainPanel.addStyleName(style.contentWrapper());
@@ -130,7 +133,7 @@ public class RegattaOverviewPanel extends SimplePanel {
// TODO should we always set ignoreLocalSettings=true when creating links?
new SettingsDialog<RegattaRaceStatesSettings>(regattaRaceStatesComponent, stringMessages,
new LinkWithSettingsGenerator<>(regattaOverviewContextDefinition,
UserSettingsStorageManager.getIgnoreLocalSettings())).show();
IgnoreLocalSettings.getIgnoreLocalSettingsFromCurrentUrl())).show();
}
});
@@ -152,17 +155,67 @@ public class RegattaOverviewPanel extends SimplePanel {
});
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForRegattaOverview(regattaOverviewContextDefinition);
final RegattaRaceStatesComponentLifecycle lifecycle = new RegattaRaceStatesComponentLifecycle();
final SettingsStorageManager<RegattaRaceStatesSettings> settingsStorageManager = UserSettingsStorageManager
.createSettingsStorageManager(userService, storageDefinitionId);
final ComponentContext<RegattaRaceStatesSettings> componentContext = new ComponentContextWithSettingsStorage<>(
lifecycle, settingsStorageManager);
//FIXME The chained calls from here are independent from each other and should be implemented with Dispatching Framework
sailingService.getEventById(regattaOverviewContextDefinition.getEvent(), false, new MarkedAsyncCallback<EventDTO>(
new AsyncCallback<EventDTO>() {
@Override
public void onFailure(Throwable cause) {
settingsButton.setEnabled(false);
errorReporter.reportError("Error trying to load event with id " + regattaOverviewContextDefinition.getEvent() + " : "
+ cause.getMessage());
continueInitAfterEventRetrieved();
}
@Override
public void onSuccess(EventDTO result) {
setEvent(result);
continueInitAfterEventRetrieved();
}
}));
}
private void continueInitAfterEventRetrieved() {
sailingService.getRegattaStructureForEvent(regattaOverviewContextDefinition.getEvent(), new MarkedAsyncCallback<List<RaceGroupDTO>>(
new AsyncCallback<List<RaceGroupDTO>>() {
@Override
public void onFailure(Throwable cause) {
errorReporter.reportError("Error trying to load regattas for event with id " + regattaOverviewContextDefinition.getEvent() + " : "
+ cause.getMessage());
continueInitAfterRaceGroupsRetrieved();
}
@Override
public void onSuccess(List<RaceGroupDTO> result) {
raceGroupDTOs.clear();
raceGroupDTOs.addAll(result);
continueInitAfterRaceGroupsRetrieved();
}
}));
}
private void continueInitAfterRaceGroupsRetrieved() {
final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory.createStoredSettingsLocatorForRegattaOverview(regattaOverviewContextDefinition);
final RegattaRaceStatesComponentLifecycle lifecycle = new RegattaRaceStatesComponentLifecycle(eventDTO == null ? null : eventDTO.venue.getCourseAreas(), raceGroupDTOs);
componentContext = new ComponentContextWithSettingsStorage<>(
lifecycle, userService, storageDefinition);
componentContext.getInitialSettings(new DefaultOnSettingsLoadedCallback<RegattaRaceStatesSettings>() {
@Override
public void onSuccess(RegattaRaceStatesSettings defaultSettings) {
continueInitAfterSettingsRetrieved(defaultSettings);
}
});
}
private void continueInitAfterSettingsRetrieved(RegattaRaceStatesSettings defaultSettings) {
regattaRaceStatesComponent = new RegattaRaceStatesComponent(null, componentContext, sailingService, errorReporter,
stringMessages,
regattaOverviewContextDefinition.getEvent(), lifecycle.createDefaultSettings(), uiUpdateTimer);
this.eventRaceGroupListeners.add(regattaRaceStatesComponent);
regattaOverviewContextDefinition.getEvent(), eventDTO, raceGroupDTOs, defaultSettings, uiUpdateTimer);
regattaRaceStatesComponent.setEntryClickedHandler(entryClickedHandler);
regattaRaceStatesComponent.setWidth("100%");
this.serverUpdateTimer.addTimeListener(new TimeListener() {
@@ -223,13 +276,7 @@ public class RegattaOverviewPanel extends SimplePanel {
} else {
leaderboardsTabPanel = null;
}
componentContext.initInitialSettings(new DefaultOnSettingsLoadedCallback<RegattaRaceStatesSettings>() {
@Override
public void onSuccess(RegattaRaceStatesSettings defaultSettings) {
regattaRaceStatesComponent.updateSettings(defaultSettings);
}
});
checkToEnableSettingsButton();
}
private CheckBox addLeaderboardEnablerButton() {
@@ -297,80 +344,15 @@ public class RegattaOverviewPanel extends SimplePanel {
}
}
private void retrieveEvent() {
sailingService.getEventById(regattaOverviewContextDefinition.getEvent(), false, new MarkedAsyncCallback<EventDTO>(
new AsyncCallback<EventDTO>() {
@Override
public void onFailure(Throwable cause) {
settingsButton.setEnabled(false);
errorReporter.reportError("Error trying to load event with id " + regattaOverviewContextDefinition.getEvent() + " : "
+ cause.getMessage());
}
@Override
public void onSuccess(EventDTO result) {
if (result != null) {
setEvent(result);
}
}
}));
}
protected void setEvent(EventDTO event) {
eventDTO = event;
onEventUpdated();
}
private void onEventUpdated() {
fireEvent(new EventDTOLoadedEvent(eventDTO));
for (EventAndRaceGroupAvailabilityListener listener : this.eventRaceGroupListeners) {
listener.onEventUpdated(eventDTO);
}
checkToEnableSettingsButton();
}
private void retrieveRegattaStructure() {
sailingService.getRegattaStructureForEvent(regattaOverviewContextDefinition.getEvent(), new MarkedAsyncCallback<List<RaceGroupDTO>>(
new AsyncCallback<List<RaceGroupDTO>>() {
@Override
public void onFailure(Throwable cause) {
errorReporter.reportError("Error trying to load regattas for event with id " + regattaOverviewContextDefinition.getEvent() + " : "
+ cause.getMessage());
}
@Override
public void onSuccess(List<RaceGroupDTO> result) {
if (result != null) {
setRaceGroups(result);
}
}
}));
}
protected void setRaceGroups(List<RaceGroupDTO> result) {
raceGroupDTOs.clear();
raceGroupDTOs.addAll(result);
onRaceGroupsUpdated();
}
private void onRaceGroupsUpdated() {
for (EventAndRaceGroupAvailabilityListener listener : this.eventRaceGroupListeners) {
listener.onRaceGroupsUpdated(raceGroupDTOs);
}
checkToEnableSettingsButton();
}
private void checkToEnableSettingsButton() {
if (eventDTO != null && raceGroupDTOs.size() > 0) {
settingsButton.setEnabled(true);
}
}
private void setEvent(EventDTO event) {
eventDTO = event;
fireEvent(new EventDTOLoadedEvent(eventDTO));
}
}
@@ -73,16 +73,15 @@ import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.shared.components.AbstractCompositeComponent;
import com.sap.sse.gwt.client.shared.components.Component;
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
/**
* This component shows a table displaying the current state of races for a given event. Which races are shown depends
* on the setting {@link RegattaRaceStatesSettings}. Each entry shows what flags are currently displayed, what start
* time the race has and additional information, e.g. for Gate start.
*/
public class RegattaRaceStatesComponent extends AbstractCompositeComponent<RegattaRaceStatesSettings> implements
EventAndRaceGroupAvailabilityListener {
public class RegattaRaceStatesComponent extends AbstractCompositeComponent<RegattaRaceStatesSettings> {
public interface EntryHandler {
void onEntryClicked(RegattaOverviewEntryDTO entry);
@@ -136,22 +135,21 @@ public class RegattaRaceStatesComponent extends AbstractCompositeComponent<Regat
* Whenever this component makes a service call and receives an update on the current server time, the
* timer passed for this argument will be synchronized.
*/
public RegattaRaceStatesComponent(Component<?> parent, ComponentContext<?> context,
public RegattaRaceStatesComponent(Component<?> parent, ComponentContext<?> componentContext,
final SailingServiceAsync sailingService,
ErrorReporter errorReporter,
final StringMessages stringMessages, final UUID eventId, RegattaRaceStatesSettings settings,
final StringMessages stringMessages, UUID eventId, EventDTO eventDTO, List<RaceGroupDTO> raceGroupDTOs, RegattaRaceStatesSettings settings,
Timer timerToSynchronize) {
super(parent, context);
super(parent, componentContext);
this.eventId = eventId;
this.sailingService = sailingService;
this.stringMessages = stringMessages;
this.eventId = eventId;
this.allEntries = new ArrayList<RegattaOverviewEntryDTO>();
this.timerToSynchronize = timerToSynchronize;
this.eventDTO = null;
this.raceGroupDTOs = null;
this.flagInterpreter = new RaceStateFlagsInterpreter(stringMessages);
this.settings = new RegattaRaceStatesSettings();
updateSettings(settings);
mainPanel = new VerticalPanel();
mainPanel.getElement().getStyle().setWidth(100, Unit.PCT);
regattaOverviewDataProvider = new ListDataProvider<RegattaOverviewEntryDTO>();
@@ -160,6 +158,9 @@ public class RegattaRaceStatesComponent extends AbstractCompositeComponent<Regat
mainPanel.add(tableHolder);
initWidget(mainPanel);
getElement().getStyle().setWidth(100, Unit.PCT);
this.eventDTO = eventDTO;
setRaceGroups(raceGroupDTOs);
updateSettings(settings);
}
public void onUpdateServer() {
@@ -346,7 +347,7 @@ public class RegattaRaceStatesComponent extends AbstractCompositeComponent<Regat
}
protected void loadAndUpdateEventLog() {
if (eventId == null || eventDTO == null || raceGroupDTOs == null) {
if (eventDTO == null || raceGroupDTOs == null) {
return;
}
final long clientTimeWhenRequestWasSent = System.currentTimeMillis();
@@ -727,7 +728,7 @@ public class RegattaRaceStatesComponent extends AbstractCompositeComponent<Regat
}
@Override
public SettingsDialogComponent<RegattaRaceStatesSettings> getSettingsDialogComponent() {
public SettingsDialogComponent<RegattaRaceStatesSettings> getSettingsDialogComponent(RegattaRaceStatesSettings settings) {
return new RegattaRaceStatesSettingsDialogComponent(settings, stringMessages,
Collections.unmodifiableList(eventDTO.venue.getCourseAreas()),
Collections.unmodifiableList(raceGroupDTOs));
@@ -775,15 +776,7 @@ public class RegattaRaceStatesComponent extends AbstractCompositeComponent<Regat
return this;
}
@Override
public void onEventUpdated(EventDTO event) {
eventDTO = event;
setDefaultCourseAreas();
refreshTableWithNewSettings();
}
@Override
public void onRaceGroupsUpdated(List<RaceGroupDTO> raceGroups) {
private void setRaceGroups(List<RaceGroupDTO> raceGroups) {
raceGroupDTOs = raceGroups;
GWT.log("onRaceGroupsUpdated");
if (raceGroupDTOs != null) {
@@ -817,8 +810,6 @@ public class RegattaRaceStatesComponent extends AbstractCompositeComponent<Regat
// }
// }
// regattaOverviewTable.redraw();
setDefaultRegattas();
refreshTableWithNewSettings();
}
private DialogBox createCourseViewDialogBox(RaceInfoDTO raceInfoDTO) {
@@ -1,13 +1,24 @@
package com.sap.sailing.gwt.regattaoverview.client;
import java.util.List;
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaRaceStatesSettings;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
import com.sap.sse.gwt.client.shared.components.ComponentLifecycle;
public class RegattaRaceStatesComponentLifecycle implements ComponentLifecycle<RegattaRaceStatesSettings> {
public static final String ID = "rrs";
private List<CourseAreaDTO> courseAreaDTOs;
private List<RaceGroupDTO> raceGroupDTOs;
public RegattaRaceStatesComponentLifecycle(List<CourseAreaDTO> courseAreaDTOs, List<RaceGroupDTO> raceGroupDTOs) {
this.courseAreaDTOs = courseAreaDTOs;
this.raceGroupDTOs = raceGroupDTOs;
}
@Override
public RegattaRaceStatesSettingsDialogComponent getSettingsDialogComponent(RegattaRaceStatesSettings settings) {
// TODO implement if needed
@@ -19,7 +30,14 @@ public class RegattaRaceStatesComponentLifecycle implements ComponentLifecycle<R
@Override
public RegattaRaceStatesSettings createDefaultSettings() {
return new RegattaRaceStatesSettings();
RegattaRaceStatesSettings settings = new RegattaRaceStatesSettings();
if(courseAreaDTOs != null) {
settings.setDefaultCourseAreas(courseAreaDTOs);
}
if(raceGroupDTOs != null) {
settings.setDefaultRegattas(raceGroupDTOs);
}
return settings;
}
@Override
@@ -38,13 +56,13 @@ public class RegattaRaceStatesComponentLifecycle implements ComponentLifecycle<R
}
@Override
public RegattaRaceStatesSettings extractGlobalSettings(RegattaRaceStatesSettings settings) {
public RegattaRaceStatesSettings extractUserSettings(RegattaRaceStatesSettings settings) {
return settings.createInstanceWithSettings(null, null, settings.isShowOnlyRacesOfSameDay(),
settings.isShowOnlyCurrentlyRunningRaces());
}
@Override
public RegattaRaceStatesSettings extractContextSpecificSettings(RegattaRaceStatesSettings settings) {
public RegattaRaceStatesSettings extractDocumentSettings(RegattaRaceStatesSettings settings) {
return settings;
}
}
@@ -25,12 +25,12 @@ public abstract class AbstractLeaderboardPerspectiveLifecycle extends AbstractPe
}
@Override
protected LeaderboardPerspectiveOwnSettings extractOwnGlobalSettings(LeaderboardPerspectiveOwnSettings settings) {
protected LeaderboardPerspectiveOwnSettings extractOwnUserSettings(LeaderboardPerspectiveOwnSettings settings) {
return settings;
}
@Override
protected LeaderboardPerspectiveOwnSettings extractOwnContextSettings(LeaderboardPerspectiveOwnSettings settings) {
protected LeaderboardPerspectiveOwnSettings extractOwnDocumentSettings(LeaderboardPerspectiveOwnSettings settings) {
return settings;
}
@@ -5,6 +5,7 @@ import java.util.List;
import com.sap.sailing.domain.common.dto.AbstractLeaderboardDTO;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.common.settings.generic.support.SettingsUtil;
import com.sap.sse.gwt.client.shared.components.ComponentLifecycle;
public class LeaderboardPanelLifecycle
@@ -27,7 +28,7 @@ public class LeaderboardPanelLifecycle
@Override
public LeaderboardSettings createDefaultSettings() {
return LeaderboardSettingsFactory.getInstance()
.createNewSettingsWithCustomDefaults(new LeaderboardSettings(namesOfRaceColumns));
.createNewDefaultSettingsWithRaceColumns(namesOfRaceColumns);
}
@Override
@@ -46,8 +47,8 @@ public class LeaderboardPanelLifecycle
}
@Override
public LeaderboardSettings extractGlobalSettings(LeaderboardSettings currentLeaderboardSettings) {
LeaderboardSettings defaultLeaderboardSettings = currentLeaderboardSettings.getDefaultSettings();
public LeaderboardSettings extractUserSettings(LeaderboardSettings currentLeaderboardSettings) {
LeaderboardSettings defaultLeaderboardSettings = createDefaultSettings();
LeaderboardSettings globalLeaderboardSettings = new LeaderboardSettings(
currentLeaderboardSettings.getManeuverDetailsToShow(), currentLeaderboardSettings.getLegDetailsToShow(),
currentLeaderboardSettings.getRaceDetailsToShow(), currentLeaderboardSettings.getOverallDetailsToShow(),
@@ -64,13 +65,11 @@ public class LeaderboardPanelLifecycle
currentLeaderboardSettings.isShowCompetitorSailIdColumn(),
currentLeaderboardSettings.isShowCompetitorFullNameColumn(),
currentLeaderboardSettings.isShowCompetitorNationality());
globalLeaderboardSettings = LeaderboardSettingsFactory.getInstance().keepDefaults(currentLeaderboardSettings,
globalLeaderboardSettings);
return globalLeaderboardSettings;
return SettingsUtil.copyValues(globalLeaderboardSettings, defaultLeaderboardSettings);
}
@Override
public LeaderboardSettings extractContextSpecificSettings(LeaderboardSettings leaderboardSettings) {
public LeaderboardSettings extractDocumentSettings(LeaderboardSettings leaderboardSettings) {
return leaderboardSettings;
}
@@ -7,10 +7,6 @@ public class LeaderboardPerspectiveLifecycle extends AbstractLeaderboardPerspect
public static final String ID = "lbh";
public LeaderboardPerspectiveLifecycle(StringMessages stringMessages) {
this(stringMessages, null);
}
public LeaderboardPerspectiveLifecycle(StringMessages stringMessages, AbstractLeaderboardDTO leaderboard) {
super(stringMessages, leaderboard, false);
addLifeCycle(new OverallLeaderboardPanelLifecycle(null, stringMessages));
@@ -5,19 +5,18 @@ import java.util.Collection;
import java.util.List;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.gwt.settings.client.settingtypes.converter.DetailTypeStringToEnumConverter;
import com.sap.sailing.gwt.settings.client.settingtypes.converter.RaceColumnSelectionStrategiesStringToEnumConverter;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardEntryPoint;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sse.common.Util;
import com.sap.sse.common.settings.generic.AbstractGenericSerializableSettings;
import com.sap.sse.common.settings.generic.BooleanSetting;
import com.sap.sse.common.settings.generic.EnumListSetting;
import com.sap.sse.common.settings.generic.EnumSetSetting;
import com.sap.sse.common.settings.generic.EnumSetting;
import com.sap.sse.common.settings.generic.IntegerSetting;
import com.sap.sse.common.settings.generic.LongSetting;
import com.sap.sse.common.settings.generic.StringListSetting;
import com.sap.sse.common.settings.generic.StringSetSetting;
import com.sap.sse.common.settings.generic.StringSetting;
import com.sap.sse.common.settings.util.SettingsDefaultValuesUtils;
/**
* Settings for the {@link LeaderboardPanel} component. If you change here, please also visit
@@ -34,23 +33,23 @@ public class LeaderboardSettings extends AbstractGenericSerializableSettings {
* Only one of {@link #namesOfRaceColumnsToShow} and {@link #namesOfRacesToShow} must be non-<code>null</code>.
* Only valid when the {@link #activeRaceColumnSelectionStrategy} is set to EXPLIZIT
*/
private StringListSetting namesOfRaceColumnsToShow;
private StringSetSetting namesOfRaceColumnsToShow;
/**
* Only one of {@link #namesOfRaceColumnsToShow} and {@link #namesOfRacesToShow} must be non-<code>null</code>.
* Only valid when the {@link #activeRaceColumnSelectionStrategy} is set to EXPLIZIT
*/
private StringListSetting namesOfRacesToShow;
private StringSetSetting namesOfRacesToShow;
/**
* Only valid when the {@link #activeRaceColumnSelectionStrategy} is set to LAST_N
*/
private IntegerSetting numberOfLastRacesToShow;
private EnumListSetting<DetailType> maneuverDetailsToShow;
private EnumListSetting<DetailType> legDetailsToShow;
private EnumListSetting<DetailType> raceDetailsToShow;
private EnumListSetting<DetailType> overallDetailsToShow;
private EnumSetSetting<DetailType> maneuverDetailsToShow;
private EnumSetSetting<DetailType> legDetailsToShow;
private EnumSetSetting<DetailType> raceDetailsToShow;
private EnumSetSetting<DetailType> overallDetailsToShow;
private boolean autoExpandPreSelectedRace = false;
private LongSetting delayBetweenAutoAdvancesInMilliseconds;
private BooleanSetting updateUponPlayStateChange;
@@ -87,27 +86,27 @@ public class LeaderboardSettings extends AbstractGenericSerializableSettings {
@Override
protected void addChildSettings() {
isShowCompetitorNationality = new BooleanSetting("showCompetitorNationality", this, false);
namesOfRaceColumnsToShow = new StringListSetting("namesOfRaceColumnsToShow", this);
namesOfRacesToShow = new StringListSetting("namesOfRacesToShow", this, null);
namesOfRaceColumnsToShow = new StringSetSetting("namesOfRaceColumnsToShow", this);
namesOfRacesToShow = new StringSetSetting("namesOfRacesToShow", this, null);
numberOfLastRacesToShow = new IntegerSetting("numberOfLastRacesToShow", this, null);
List<DetailType> maneuverDetails = new ArrayList<DetailType>();
maneuverDetails.add(DetailType.TACK);
maneuverDetails.add(DetailType.JIBE);
maneuverDetails.add(DetailType.PENALTY_CIRCLE);
maneuverDetailsToShow = new EnumListSetting<>("maneuverDetailsToShow", this, maneuverDetails, new DetailTypeStringToEnumConverter());
maneuverDetailsToShow = new EnumSetSetting<>("maneuverDetailsToShow", this, maneuverDetails, DetailType::valueOf);
List<DetailType> legDetails = new ArrayList<DetailType>();
legDetails.add(DetailType.DISTANCE_TRAVELED);
legDetails.add(DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
legDetails.add(DetailType.RANK_GAIN);
legDetailsToShow = new EnumListSetting<>("legDetailsToShow", this, legDetails, new DetailTypeStringToEnumConverter());
legDetailsToShow = new EnumSetSetting<>("legDetailsToShow", this, legDetails, DetailType::valueOf);
List<DetailType> raceDetails = new ArrayList<DetailType>();
raceDetails.add(DetailType.DISPLAY_LEGS);
raceDetailsToShow = new EnumListSetting<>("raceDetailsToShow", this, raceDetails, new DetailTypeStringToEnumConverter());
raceDetailsToShow = new EnumSetSetting<>("raceDetailsToShow", this, raceDetails, DetailType::valueOf);
List<DetailType> overallDetails = new ArrayList<>();
overallDetails.add(DetailType.REGATTA_RANK);
overallDetailsToShow = new EnumListSetting<>("overallDetailsToShow", this, overallDetails, new DetailTypeStringToEnumConverter());
overallDetailsToShow = new EnumSetSetting<>("overallDetailsToShow", this, overallDetails, DetailType::valueOf);
delayBetweenAutoAdvancesInMilliseconds = new LongSetting("delayBetweenAutoAdvancesInMilliseconds", this, LeaderboardEntryPoint.DEFAULT_REFRESH_INTERVAL_MILLIS);
activeRaceColumnSelectionStrategy = new EnumSetting<>("activeRaceColumnSelectionStrategy", this, RaceColumnSelectionStrategies.EXPLICIT, new RaceColumnSelectionStrategiesStringToEnumConverter());
activeRaceColumnSelectionStrategy = new EnumSetting<>("activeRaceColumnSelectionStrategy", this, RaceColumnSelectionStrategies.EXPLICIT, RaceColumnSelectionStrategies::valueOf);
nameOfRaceToSort = new StringSetting("nameOfRaceToSort", this, null);
updateUponPlayStateChange = new BooleanSetting("updateUponPlayStateChange", this, true);
sortAscending = new BooleanSetting("sortAscending", this, true);
@@ -124,35 +123,11 @@ public class LeaderboardSettings extends AbstractGenericSerializableSettings {
this.namesOfRaceColumnsToShow.setValues(namesOfRaceColumnsToShow);
}
public LeaderboardSettings(Iterable<String> namesOfRaceColumnsToShow, Long delayBetweenAutoAdvancesInMilliseconds) {
this.namesOfRaceColumnsToShow.setValues(namesOfRaceColumnsToShow);
this.delayBetweenAutoAdvancesInMilliseconds.setValue(delayBetweenAutoAdvancesInMilliseconds);
}
public LeaderboardSettings(Long delayBetweenAutoAdvancesInMilliseconds, Integer numberOfLastRacesToShow,
RaceColumnSelectionStrategies activeRaceColumnSelectionStrategy) {
this.delayBetweenAutoAdvancesInMilliseconds.setValue(delayBetweenAutoAdvancesInMilliseconds);
this.numberOfLastRacesToShow.setValue(numberOfLastRacesToShow);
this.activeRaceColumnSelectionStrategy.setValue(activeRaceColumnSelectionStrategy);
}
public LeaderboardSettings(List<String> namesOfRaceColumnsToShow, List<String> namesOfRacesToShow, List<DetailType> overallDetailsToShow,
String nameOfRaceToSort, boolean autoExpandPreSelectedRace,
boolean showCompetitorSailIdColumn, boolean showCompetitorFullNameColumn) {
this.namesOfRaceColumnsToShow.setValues(namesOfRaceColumnsToShow);
this.namesOfRacesToShow.setValues(namesOfRacesToShow);
this.overallDetailsToShow.setValues(overallDetailsToShow);
this.nameOfRaceToSort.setValue(nameOfRaceToSort);
this.autoExpandPreSelectedRace = autoExpandPreSelectedRace;
this.showCompetitorSailIdColumn.setValue(showCompetitorSailIdColumn);
this.showCompetitorFullNameColumn.setValue(showCompetitorFullNameColumn);
}
/**
* @param raceColumnsToShow <code>null</code> means don't modify the list of races shown
*/
public LeaderboardSettings(List<DetailType> maneuverDetailsToShow, List<DetailType> legDetailsToShow,
List<DetailType> raceDetailsToShow, List<DetailType> overallDetailsToShow,
public LeaderboardSettings(Collection<DetailType> maneuverDetailsToShow, Collection<DetailType> legDetailsToShow,
Collection<DetailType> raceDetailsToShow, Collection<DetailType> overallDetailsToShow,
List<String> namesOfRaceColumnsToShow, List<String> namesOfRacesToShow, Integer numberOfLastRacesToShow,
boolean autoExpandPreSelectedRace, Long delayBetweenAutoAdvancesInMilliseconds, String nameOfRaceToSort,
boolean sortAscending, boolean updateUponPlayStateChange, RaceColumnSelectionStrategies activeRaceColumnSelectionStrategy,
@@ -182,32 +157,33 @@ public class LeaderboardSettings extends AbstractGenericSerializableSettings {
this.isShowCompetitorNationality.setValue(isCompetitorNationalityColumnVisible);
}
/**
* A live collection that reflects the current state of the settings of a leaderboard panel
*/
public List<DetailType> getManeuverDetailsToShow() {
return Util.createList(maneuverDetailsToShow.getValues());
public Collection<DetailType> getManeuverDetailsToShow() {
return Util.createSet(maneuverDetailsToShow.getValues());
}
/**
* A live collection that reflects the current state of the settings of a leaderboard panel
*/
public List<DetailType> getLegDetailsToShow() {
return Util.createList(legDetailsToShow.getValues());
public Collection<DetailType> getLegDetailsToShow() {
return Util.createSet(legDetailsToShow.getValues());
}
/**
* A live collection that reflects the current state of the settings of a leaderboard panel
*/
public List<DetailType> getRaceDetailsToShow() {
return Util.createList(raceDetailsToShow.getValues());
public Collection<DetailType> getRaceDetailsToShow() {
return Util.createSet(raceDetailsToShow.getValues());
}
/**
* A live collection that reflects the current state of the settings of a leaderboard panel
*/
public List<DetailType> getOverallDetailsToShow() {
return Util.createList(overallDetailsToShow.getValues());
public Collection<DetailType> getOverallDetailsToShow() {
return Util.createSet(overallDetailsToShow.getValues());
}
/**
@@ -288,83 +264,34 @@ public class LeaderboardSettings extends AbstractGenericSerializableSettings {
return isShowCompetitorNationality.getValue();
}
void overrideDefaultValues(LeaderboardSettings newDefaults) {
autoExpandPreSelectedRace = newDefaults.autoExpandPreSelectedRace;
boolean namesOfRaceColumnsToShowWasDefault = Util.equals(namesOfRaceColumnsToShow.getValues(), namesOfRaceColumnsToShow.getDefaultValues());
namesOfRaceColumnsToShow.setDefaultValues(newDefaults.namesOfRaceColumnsToShow.getValues());
namesOfRacesToShow.setDefaultValues(newDefaults.namesOfRacesToShow.getValues());
if(getNamesOfRaceColumnsToShow() != null && getNamesOfRacesToShow() != null) {
if(namesOfRaceColumnsToShowWasDefault) {
namesOfRaceColumnsToShow.setValues(null);
} else {
namesOfRacesToShow.setValues(null);
}
public LeaderboardSettings overrideDefaultsForNamesOfRaceColumns(List<String> namesOfRaceColumns) {
LeaderboardSettings newSettings = new LeaderboardSettings();
newSettings.legDetailsToShow.setValues(this.getLegDetailsToShow());
newSettings.raceDetailsToShow.setValues(this.getRaceDetailsToShow());
newSettings.overallDetailsToShow.setValues(this.getOverallDetailsToShow());
newSettings.numberOfLastRacesToShow.setValue(this.getNumberOfLastRacesToShow());
newSettings.activeRaceColumnSelectionStrategy.setValue(this.getActiveRaceColumnSelectionStrategy());
newSettings.autoExpandPreSelectedRace = this.isAutoExpandPreSelectedRace();
newSettings.delayBetweenAutoAdvancesInMilliseconds.setValue(this.getDelayBetweenAutoAdvancesInMilliseconds());
newSettings.maneuverDetailsToShow.setValues(this.getManeuverDetailsToShow());
newSettings.nameOfRaceToSort.setValue(this.getNameOfRaceToSort());
newSettings.sortAscending.setValue(this.isSortAscending());
newSettings.updateUponPlayStateChange.setValue(this.isUpdateUponPlayStateChange());
newSettings.showAddedScores.setValue(this.isShowAddedScores());
newSettings.showCompetitorSailIdColumn.setValue(this.isShowCompetitorSailIdColumn());
newSettings.showCompetitorFullNameColumn.setValue(this.isShowCompetitorFullNameColumn());
newSettings.showOverallColumnWithNumberOfRacesCompletedPerCompetitor.setValue(this.isShowOverallColumnWithNumberOfRacesCompletedPerCompetitor());
newSettings.isShowCompetitorNationality.setValue(this.isShowCompetitorNationality());
if(namesOfRaceColumns != null && !namesOfRaceColumns.isEmpty()) {
newSettings.namesOfRacesToShow.setValues(null);
}
numberOfLastRacesToShow.setDefaultValue(newDefaults.numberOfLastRacesToShow.getValue());
maneuverDetailsToShow.setDefaultValues(newDefaults.maneuverDetailsToShow.getValues());
legDetailsToShow.setDefaultValues(newDefaults.legDetailsToShow.getValues());
raceDetailsToShow.setDefaultValues(newDefaults.raceDetailsToShow.getValues());
overallDetailsToShow.setDefaultValues(newDefaults.overallDetailsToShow.getValues());
delayBetweenAutoAdvancesInMilliseconds.setDefaultValue(newDefaults.delayBetweenAutoAdvancesInMilliseconds.getValue());
activeRaceColumnSelectionStrategy.setDefaultValue(newDefaults.activeRaceColumnSelectionStrategy.getValue());
nameOfRaceToSort.setDefaultValue(newDefaults.nameOfRaceToSort.getValue());
updateUponPlayStateChange.setDefaultValue(newDefaults.updateUponPlayStateChange.getValue());
sortAscending.setDefaultValue(newDefaults.sortAscending.getValue());
showAddedScores.setDefaultValue(newDefaults.showAddedScores.getValue());
showCompetitorSailIdColumn.setDefaultValue(newDefaults.showCompetitorSailIdColumn.getValue());
showCompetitorFullNameColumn.setDefaultValue(newDefaults.showCompetitorFullNameColumn.getValue());
showOverallColumnWithNumberOfRacesCompletedPerCompetitor.setDefaultValue(newDefaults.showOverallColumnWithNumberOfRacesCompletedPerCompetitor.getValue());
isShowCompetitorNationality.setDefaultValue(newDefaults.isShowCompetitorNationality.getValue());
newSettings.namesOfRaceColumnsToShow.setValues(this.getNamesOfRaceColumnsToShow());
SettingsDefaultValuesUtils.keepDefaults(this, newSettings);
if(namesOfRaceColumns != null && !namesOfRaceColumns.isEmpty()) {
newSettings.namesOfRacesToShow.setDefaultValues(null);
}
newSettings.namesOfRaceColumnsToShow.setDefaultValues(namesOfRaceColumns);
return newSettings;
}
void setValues(LeaderboardSettings settingsWithCustomValues) {
this.legDetailsToShow.setValues(settingsWithCustomValues.getLegDetailsToShow());
this.raceDetailsToShow.setValues(settingsWithCustomValues.getRaceDetailsToShow());
this.overallDetailsToShow.setValues(settingsWithCustomValues.getOverallDetailsToShow());
this.namesOfRacesToShow.setValues(settingsWithCustomValues.getNamesOfRacesToShow());
this.namesOfRaceColumnsToShow.setValues(settingsWithCustomValues.getNamesOfRaceColumnsToShow());
this.numberOfLastRacesToShow.setValue(settingsWithCustomValues.getNumberOfLastRacesToShow());
this.activeRaceColumnSelectionStrategy.setValue(settingsWithCustomValues.getActiveRaceColumnSelectionStrategy());
this.autoExpandPreSelectedRace = settingsWithCustomValues.isAutoExpandPreSelectedRace();
this.delayBetweenAutoAdvancesInMilliseconds.setValue(settingsWithCustomValues.getDelayBetweenAutoAdvancesInMilliseconds());
this.maneuverDetailsToShow.setValues(settingsWithCustomValues.getManeuverDetailsToShow());
this.nameOfRaceToSort.setValue(settingsWithCustomValues.getNameOfRaceToSort());
this.sortAscending.setValue(settingsWithCustomValues.isSortAscending());
this.updateUponPlayStateChange.setValue(settingsWithCustomValues.isUpdateUponPlayStateChange());
this.showAddedScores.setValue(settingsWithCustomValues.isShowAddedScores());
this.showCompetitorSailIdColumn.setValue(settingsWithCustomValues.isShowCompetitorSailIdColumn());
this.showCompetitorFullNameColumn.setValue(settingsWithCustomValues.isShowCompetitorFullNameColumn());
this.isShowCompetitorNationality.setValue(settingsWithCustomValues.isShowCompetitorNationality());
this.showOverallColumnWithNumberOfRacesCompletedPerCompetitor.setValue(settingsWithCustomValues.isShowOverallColumnWithNumberOfRacesCompletedPerCompetitor());
}
public LeaderboardSettings getDefaultSettings() {
LeaderboardSettings leaderboardSettings = new LeaderboardSettings();
leaderboardSettings.legDetailsToShow.setDefaultValues(legDetailsToShow.getDefaultValues());
leaderboardSettings.raceDetailsToShow.setDefaultValues(raceDetailsToShow.getDefaultValues());
leaderboardSettings.overallDetailsToShow.setDefaultValues(overallDetailsToShow.getDefaultValues());
leaderboardSettings.namesOfRacesToShow.setDefaultValues(namesOfRacesToShow.getDefaultValues());
leaderboardSettings.namesOfRaceColumnsToShow.setDefaultValues(namesOfRaceColumnsToShow.getDefaultValues());
leaderboardSettings.numberOfLastRacesToShow.setDefaultValue(numberOfLastRacesToShow.getDefaultValue());
leaderboardSettings.activeRaceColumnSelectionStrategy.setDefaultValue(activeRaceColumnSelectionStrategy.getDefaultValue());
leaderboardSettings.autoExpandPreSelectedRace = autoExpandPreSelectedRace;
leaderboardSettings.delayBetweenAutoAdvancesInMilliseconds.setDefaultValue(delayBetweenAutoAdvancesInMilliseconds.getDefaultValue());
leaderboardSettings.maneuverDetailsToShow.setDefaultValues(maneuverDetailsToShow.getDefaultValues());
leaderboardSettings.nameOfRaceToSort.setDefaultValue(nameOfRaceToSort.getDefaultValue());
leaderboardSettings.sortAscending.setDefaultValue(sortAscending.getDefaultValue());
leaderboardSettings.updateUponPlayStateChange.setDefaultValue(updateUponPlayStateChange.getDefaultValue());
leaderboardSettings.showAddedScores.setDefaultValue(showAddedScores.getDefaultValue());
leaderboardSettings.showCompetitorSailIdColumn.setDefaultValue(showCompetitorSailIdColumn.getDefaultValue());
leaderboardSettings.showCompetitorFullNameColumn.setDefaultValue(showCompetitorFullNameColumn.getDefaultValue());
leaderboardSettings.showOverallColumnWithNumberOfRacesCompletedPerCompetitor.setDefaultValue(showOverallColumnWithNumberOfRacesCompletedPerCompetitor.getDefaultValue());
leaderboardSettings.isShowCompetitorNationality.setDefaultValue(isShowCompetitorNationality.getDefaultValue());
return leaderboardSettings;
}
public static LeaderboardSettings createDefaultSettings(Collection<String> defaultNamesOfRaceColumnsToShow) {
LeaderboardSettings leaderboardSettings = new LeaderboardSettings();
leaderboardSettings.namesOfRaceColumnsToShow.setDefaultValues(defaultNamesOfRaceColumnsToShow);
return leaderboardSettings;
}
}
@@ -1,6 +1,7 @@
package com.sap.sailing.gwt.settings.client.leaderboard;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -29,6 +30,7 @@ import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sailing.gwt.ui.leaderboard.LegColumn;
import com.sap.sailing.gwt.ui.leaderboard.ManeuverCountRaceColumn;
import com.sap.sse.common.Util;
import com.sap.sse.common.settings.util.SettingsDefaultValuesUtils;
import com.sap.sse.gwt.client.controls.IntegerBox;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.Validator;
@@ -89,7 +91,7 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
meneuverPanel.addStyleName("SettingsDialogComponent");
FlowPanel meneuverContent = new FlowPanel();
meneuverContent.addStyleName("dialogInnerContent");
List<DetailType> currentMeneuverDetailSelection = initialSettings.getManeuverDetailsToShow();
Collection<DetailType> currentMeneuverDetailSelection = initialSettings.getManeuverDetailsToShow();
for (DetailType detailType : ManeuverCountRaceColumn.getAvailableManeuverDetailColumnTypes()) {
CheckBox checkbox = createAndRegisterCheckbox(dialog, detailType,
currentMeneuverDetailSelection.contains(detailType), maneuverDetailCheckboxes);
@@ -131,7 +133,7 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
raceDetailDialog.add(dialog.createHeadline(stringMessages.raceDetailsToShow(), true));
raceDetailDialog.addStyleName("SettingsDialogComponent");
int detailCountInCurrentFlowPanel = 0;
List<DetailType> currentRaceDetailSelection = initialSettings.getRaceDetailsToShow();
Collection<DetailType> currentRaceDetailSelection = initialSettings.getRaceDetailsToShow();
FlowPanel raceDetailDialogContent = null;
for (DetailType type : LeaderboardPanel.getAvailableRaceDetailColumnTypes()) {
if (detailCountInCurrentFlowPanel % 8 == 0) {
@@ -161,7 +163,7 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
raceStartAnalysisDialog.add(dialog.createHeadline(stringMessages.raceStartAnalysis(), true));
raceStartAnalysisDialog.addStyleName("SettingsDialogComponent");
int detailCountInCurrentFlowPanel = 0;
List<DetailType> currentRaceDetailSelection = initialSettings.getRaceDetailsToShow();
Collection<DetailType> currentRaceDetailSelection = initialSettings.getRaceDetailsToShow();
FlowPanel raceStartAnalysisDialogContent = null;
for (DetailType type : LeaderboardPanel.getAvailableRaceStartAnalysisColumnTypes()) {
if (detailCountInCurrentFlowPanel % 8 == 0) {
@@ -184,7 +186,7 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
overallDetailDialog.addStyleName("SettingsDialogComponent overallDetailSettings");
FlowPanel overallDetailDialogContent = new FlowPanel();
overallDetailDialogContent.addStyleName("dialogInnerContent");
List<DetailType> currentOverallDetailSelection = initialSettings.getOverallDetailsToShow();
Collection<DetailType> currentOverallDetailSelection = initialSettings.getOverallDetailsToShow();
for (DetailType type : LeaderboardPanel.getAvailableOverallDetailColumnTypes()) {
CheckBox checkbox = createAndRegisterCheckbox(dialog, type, currentOverallDetailSelection.contains(type),
overallDetailCheckboxes);
@@ -220,7 +222,7 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
legDetailsToShow.add(dialog.createHeadline(stringMessages.legDetailsToShow(), true));
legDetailsToShow.addStyleName("SettingsDialogComponent");
FlowPanel legDetailsContent = null;
List<DetailType> currentLegDetailSelection = initialSettings.getLegDetailsToShow();
Collection<DetailType> currentLegDetailSelection = initialSettings.getLegDetailsToShow();
int detailCountInCurrentFlowPanel = 0;
for (DetailType type : LegColumn.getAvailableLegDetailColumnTypes()) {
if (detailCountInCurrentFlowPanel % 8 == 0) {
@@ -402,7 +404,8 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
/*showOverallColumnWithNumberOfRacesSailedPerCompetitor*/ showOverallColumnWithNumberOfRacesSailedPerCompetitorCheckBox.getValue().booleanValue(),
showCompetitorSailIdColumnheckBox.getValue(), showCompetitorFullNameColumnCheckBox.getValue(),
isCompetitorNationalityColumnVisible.getValue());
return LeaderboardSettingsFactory.getInstance().keepDefaults(initialSettings, newSettings);
SettingsDefaultValuesUtils.keepDefaults(initialSettings, newSettings);
return newSettings;
}
@Override
@@ -1,14 +1,14 @@
package com.sap.sailing.gwt.settings.client.leaderboard;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Collection;
import java.util.List;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings.RaceColumnSelectionStrategies;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sse.common.Util;
import com.sap.sse.gwt.client.player.Timer.PlayModes;
import com.sap.sse.common.settings.generic.support.SettingsUtil;
import com.sap.sse.common.settings.util.SettingsDefaultValuesUtils;
/**
* A factory class creating leaderboard settings for different contexts (user role, live or replay mode, etc.
@@ -16,201 +16,71 @@ import com.sap.sse.gwt.client.player.Timer.PlayModes;
public class LeaderboardSettingsFactory {
private static LeaderboardSettingsFactory instance;
public synchronized static LeaderboardSettingsFactory getInstance() {
public static LeaderboardSettingsFactory getInstance() {
if (instance == null) {
instance = new LeaderboardSettingsFactory();
}
return instance;
}
/**
* @param nameOfRaceToSort
* if <code>null</code>, don't sort any race column
* @param nameOfRaceColumnToShow
* if <code>null</code>, the settings returned will cause the list of race columns shown to remain
* unchanged during {@link LeaderboardPanel#updateSettings(LeaderboardSettings)}; otherwise, the settings
* will show the single race column identified by this argument
* @param nameOfRaceToShow
* alternatively to <code>nameOfRaceColumnToShow</code>, this argument may be used in case the race name
* is known, but its column name is not. If <code>null</code>, and <code>nameOfRaceColumnToShow</code> is
* also <code>null</code>, no change to the selected race columns will happen while updating the
* leaderboard settings. It is an error to pass non-<code>null</code> values for both,
* <code>nameOfRaceColumnToShow</code> <em>and</em> <code>nameOfRaceToShow</code>, and an
* {@link IllegalArgumentException} will be thrown in this case.
* @param raceColumnSelection
* the settings will be constructed such that the new settings will have the same race columns selected
* as those selected by this argument
* @param showRegattaRank
* if <code>null</code>, the overall detail settings that are responsible for deciding whether or not to
* show the regatta rank are left unchanged; otherwise, a non-<code>null</code> overall details
* collection will be put to the settings and the {@link DetailType#REGATTA_RANK} will be added to the
* overall details if and only if this parameter is <code>true</code>
* @param raceColumnSelectionType
* @param raceColumnSelection
*/
public LeaderboardSettings createNewSettingsForPlayMode(PlayModes playMode, String nameOfRaceToSort, String nameOfRaceColumnToShow,
String nameOfRaceToShow, boolean showRegattaRank, boolean showCompetitorSailIdColumn,
boolean showCompetitorNameColumn, Integer raceColumnSelectionNumber,
RaceColumnSelectionStrategies raceColumnSelectionType) {
if (nameOfRaceColumnToShow != null && nameOfRaceToShow != null) {
throw new IllegalArgumentException("Can identify only one race to show, either by race name or by its column name, but not both");
}
LeaderboardSettings settings = null;
List<String> namesOfRaceColumnsToShow = nameOfRaceColumnToShow == null ? null : Collections.singletonList(nameOfRaceColumnToShow);
List<String> namesOfRacesToShow = nameOfRaceToShow == null ? null : Collections.singletonList(nameOfRaceToShow);
switch (playMode) {
case Live:
List<DetailType> maneuverDetails = new ArrayList<DetailType>();
maneuverDetails.add(DetailType.TACK);
maneuverDetails.add(DetailType.JIBE);
maneuverDetails.add(DetailType.PENALTY_CIRCLE);
List<DetailType> legDetails = new ArrayList<DetailType>();
legDetails.add(DetailType.DISTANCE_TRAVELED);
legDetails.add(DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
legDetails.add(DetailType.ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS);
legDetails.add(DetailType.RANK_GAIN);
List<DetailType> raceDetails = new ArrayList<DetailType>();
raceDetails.add(DetailType.RACE_DISTANCE_TRAVELED);
raceDetails.add(DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
raceDetails.add(DetailType.RACE_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD_IN_METERS);
raceDetails.add(DetailType.NUMBER_OF_MANEUVERS);
raceDetails.add(DetailType.DISPLAY_LEGS);
final List<DetailType> overallDetails = createOverallDetailsForShowRegattaRank(showRegattaRank);
settings = new LeaderboardSettings(maneuverDetails, legDetails, raceDetails, overallDetails,
namesOfRaceColumnsToShow,
namesOfRacesToShow, raceColumnSelectionNumber,
/* set autoExpandPreSelectedRace to true if we look at a single race */ nameOfRaceColumnToShow != null || nameOfRaceToShow != null,
/* refresh interval */ null, /* name of race to sort */ nameOfRaceToSort,
/* ascending */ true, /* updateUponPlayStateChange */ true, raceColumnSelectionType,
/*showAddedScores*/ false, /*showOverallRacesCompleted*/ false,
showCompetitorSailIdColumn, showCompetitorNameColumn, false);
break;
case Replay:
settings = createNewDefaultSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, nameOfRaceToSort, /* autoExpandFirstRace */
nameOfRaceColumnToShow != null, showRegattaRank, showCompetitorSailIdColumn, showCompetitorNameColumn);
break;
}
return settings;
}
/**
* @param showRegattaRank
* Puts overall details
* collection to the settings and adds {@link DetailType#REGATTA_RANK} to the
* overall details if and only if this parameter is <code>true</code>
*/
private List<DetailType> createOverallDetailsForShowRegattaRank(boolean showRegattaRank) {
final List<DetailType> overallDetails = new ArrayList<>();
if (showRegattaRank) {
overallDetails.add(DetailType.REGATTA_RANK);
}
return overallDetails;
}
/**
* @param namesOfRaceColumnsToShow
* if <code>null</code>, create settings which leave the list of races to show unchanged when applied
* using {@link LeaderboardPanel#updateSettings(LeaderboardSettings)}; otherwise, the list of names of
* the race columns (not their races!) that will be shown, so that, e.g., an empty list causes no race
* columns to be shown
* @param namesOfRacesToShow
* alternatively, races to show can also be specified by their race names; if not <code>null</code>,
* <code>namesOfRaceColumnsToShow</code> must be <code>null</code>
* @param showRegattaRank
* if <code>null</code>, the overall detail settings that are responsible for deciding whether or not to
* show the regatta rank are left unchanged; otherwise, a non-<code>null</code> overall details
* collection will be put to the settings and the {@link DetailType#REGATTA_RANK} will be added to the
* overall details if and only if this parameter is <code>true</code>
*/
private LeaderboardSettings createNewDefaultSettings(List<String> namesOfRaceColumnsToShow,
List<String> namesOfRacesToShow, String nameOfRaceToSort, boolean autoExpandPreSelectedRace, Boolean showRegattaRank,
boolean showCompetitorSailIdColumn, boolean showCompetitorFullNameColumn) {
final List<DetailType> overallDetails = createOverallDetailsForShowRegattaRank(showRegattaRank);
return new LeaderboardSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, overallDetails,
nameOfRaceToSort, autoExpandPreSelectedRace,
showCompetitorSailIdColumn, showCompetitorFullNameColumn);
}
public LeaderboardSettings createNewSettingsWithCustomDefaults(LeaderboardSettings customDefaultSettings, LeaderboardSettings settingsWithCustomValues) {
LeaderboardSettings leaderboardSettings = new LeaderboardSettings();
leaderboardSettings.overrideDefaultValues(customDefaultSettings);
leaderboardSettings.setValues(settingsWithCustomValues);
public LeaderboardSettings createNewDefaultSettingsWithRaceColumns(List<String> namesOfRaceColumns) {
LeaderboardSettings leaderboardSettings = new LeaderboardSettings(namesOfRaceColumns);
SettingsUtil.copyDefaultsFromValues(leaderboardSettings, leaderboardSettings);
return leaderboardSettings;
}
public LeaderboardSettings createNewSettingsWithCustomDefaults(LeaderboardSettings customDefaultSettings) {
LeaderboardSettings leaderboardSettings = new LeaderboardSettings();
leaderboardSettings.overrideDefaultValues(customDefaultSettings);
return leaderboardSettings;
public LeaderboardSettings createNewSettingsWithCustomRaceDetails(List<DetailType> raceDetailsToShow) {
LeaderboardSettings defaultSettings = new LeaderboardSettings();
return new LeaderboardSettings(
defaultSettings.getManeuverDetailsToShow(),
defaultSettings.getLegDetailsToShow(),
raceDetailsToShow, defaultSettings.getOverallDetailsToShow(),
Util.cloneListOrNull(defaultSettings.getNamesOfRaceColumnsToShow()),
Util.cloneListOrNull(defaultSettings.getNamesOfRacesToShow()),
defaultSettings.getNumberOfLastRacesToShow(),
defaultSettings.isAutoExpandPreSelectedRace(),
defaultSettings.getDelayBetweenAutoAdvancesInMilliseconds(),
defaultSettings.getNameOfRaceToSort(), defaultSettings.isSortAscending(),
defaultSettings.isUpdateUponPlayStateChange(),
defaultSettings.getActiveRaceColumnSelectionStrategy(),
defaultSettings.isShowAddedScores(),
defaultSettings.isShowOverallColumnWithNumberOfRacesCompletedPerCompetitor(),
defaultSettings.isShowCompetitorSailIdColumn(),
defaultSettings.isShowCompetitorFullNameColumn(),
defaultSettings.isShowCompetitorNationality());
}
public LeaderboardSettings overrideDefaultValuesWithNewDefaults(LeaderboardSettings settingsWithCustomValues, LeaderboardSettings customDefaultSettings) {
LeaderboardSettings leaderboardSettings = new LeaderboardSettings();
leaderboardSettings.setValues(settingsWithCustomValues);
leaderboardSettings.overrideDefaultValues(customDefaultSettings);
return leaderboardSettings;
}
public LeaderboardSettings keepDefaults(LeaderboardSettings previousSettings, LeaderboardSettings newSettings) {
LeaderboardSettings leaderboardSettings = previousSettings.getDefaultSettings();
leaderboardSettings.setValues(newSettings);
return leaderboardSettings;
}
public LeaderboardSettings overrideDefaultValuesForRaceDetails(LeaderboardSettings existingSettings, List<DetailType> newRaceDetailsDefaultValues) {
LeaderboardSettings newSettings = new LeaderboardSettings(
Util.cloneListOrNull(existingSettings.getManeuverDetailsToShow()),
Util.cloneListOrNull(existingSettings.getLegDetailsToShow()),
newRaceDetailsDefaultValues, Util.cloneListOrNull(existingSettings.getOverallDetailsToShow()),
Util.cloneListOrNull(existingSettings.getNamesOfRaceColumnsToShow()),
Util.cloneListOrNull(existingSettings.getNamesOfRacesToShow()),
existingSettings.getNumberOfLastRacesToShow(), /* auto-expand pre-selected race */ true,
existingSettings.getDelayBetweenAutoAdvancesInMilliseconds(),
existingSettings.getNameOfRaceToSort(), existingSettings.isSortAscending(),
existingSettings.isUpdateUponPlayStateChange(),
existingSettings.getActiveRaceColumnSelectionStrategy(),
existingSettings.isShowAddedScores(),
existingSettings.isShowOverallColumnWithNumberOfRacesCompletedPerCompetitor(),
existingSettings.isShowCompetitorSailIdColumn(),
existingSettings.isShowCompetitorFullNameColumn(),
existingSettings.isShowCompetitorNationality());
final LeaderboardSettings existingDefaultSettings = existingSettings.getDefaultSettings();
LeaderboardSettings newDefaultSettings = new LeaderboardSettings(
Util.cloneListOrNull(existingDefaultSettings.getManeuverDetailsToShow()),
Util.cloneListOrNull(existingDefaultSettings.getLegDetailsToShow()),
newRaceDetailsDefaultValues, Util.cloneListOrNull(existingDefaultSettings.getOverallDetailsToShow()),
Util.cloneListOrNull(existingDefaultSettings.getNamesOfRaceColumnsToShow()),
Util.cloneListOrNull(existingDefaultSettings.getNamesOfRacesToShow()),
existingDefaultSettings.getNumberOfLastRacesToShow(), /* auto-expand pre-selected race */ true,
existingDefaultSettings.getDelayBetweenAutoAdvancesInMilliseconds(),
existingDefaultSettings.getNameOfRaceToSort(), existingDefaultSettings.isSortAscending(),
existingDefaultSettings.isUpdateUponPlayStateChange(),
existingDefaultSettings.getActiveRaceColumnSelectionStrategy(),
existingDefaultSettings.isShowAddedScores(),
existingDefaultSettings.isShowOverallColumnWithNumberOfRacesCompletedPerCompetitor(),
existingDefaultSettings.isShowCompetitorSailIdColumn(),
existingDefaultSettings.isShowCompetitorFullNameColumn(),
existingSettings.isShowCompetitorNationality());
newDefaultSettings = LeaderboardSettingsFactory.getInstance().createNewSettingsWithCustomDefaults(newDefaultSettings);
newSettings = LeaderboardSettingsFactory.getInstance().keepDefaults(newDefaultSettings, newSettings);
return newSettings;
public LeaderboardSettings createSettingsWithCustomExpandPreselectedRaceState(LeaderboardSettings settings, boolean expandPreselectedRace) {
return new LeaderboardSettings(
settings.getManeuverDetailsToShow(),
settings.getLegDetailsToShow(),
settings.getRaceDetailsToShow(), settings.getOverallDetailsToShow(),
Util.cloneListOrNull(settings.getNamesOfRaceColumnsToShow()),
Util.cloneListOrNull(settings.getNamesOfRacesToShow()),
settings.getNumberOfLastRacesToShow(), expandPreselectedRace,
settings.getDelayBetweenAutoAdvancesInMilliseconds(),
settings.getNameOfRaceToSort(), settings.isSortAscending(),
settings.isUpdateUponPlayStateChange(),
settings.getActiveRaceColumnSelectionStrategy(),
settings.isShowAddedScores(),
settings.isShowOverallColumnWithNumberOfRacesCompletedPerCompetitor(),
settings.isShowCompetitorSailIdColumn(),
settings.isShowCompetitorFullNameColumn(),
settings.isShowCompetitorNationality());
}
public LeaderboardSettings mergeLeaderboardSettings(LeaderboardSettings settingsWithRaceSelection, LeaderboardSettings settingsWithDetails) {
LeaderboardSettings newSettings = mergeLeaderboardSettingsHelper(settingsWithRaceSelection, settingsWithDetails);
LeaderboardSettings newDefaultSettings = mergeLeaderboardSettingsHelper(settingsWithRaceSelection.getDefaultSettings(), settingsWithDetails.getDefaultSettings());
return keepDefaults(newDefaultSettings, newSettings);
LeaderboardSettings newDefaultSettings = mergeLeaderboardSettingsHelper(SettingsDefaultValuesUtils.getDefaultSettings(new LeaderboardSettings(), settingsWithRaceSelection), SettingsDefaultValuesUtils.getDefaultSettings(new LeaderboardSettings(), settingsWithDetails));
SettingsDefaultValuesUtils.keepDefaults(newDefaultSettings, newSettings);
return newSettings;
}
private LeaderboardSettings mergeLeaderboardSettingsHelper(LeaderboardSettings settingsWithRaceSelection, LeaderboardSettings settingsWithDetails) {
List<DetailType> maneuverDetails = copyDetailTypes(settingsWithDetails.getManeuverDetailsToShow());
List<DetailType> legDetails = copyDetailTypes(settingsWithDetails.getLegDetailsToShow());
List<DetailType> raceDetails = copyDetailTypes(settingsWithDetails.getRaceDetailsToShow());
List<DetailType> overallDetailsToShow = copyDetailTypes(settingsWithDetails.getOverallDetailsToShow());
Collection<DetailType> maneuverDetails = settingsWithDetails.getManeuverDetailsToShow();
Collection<DetailType> legDetails = settingsWithDetails.getLegDetailsToShow();
Collection<DetailType> raceDetails = settingsWithDetails.getRaceDetailsToShow();
Collection<DetailType> overallDetailsToShow = settingsWithDetails.getOverallDetailsToShow();
Long refreshIntervalInMs = settingsWithDetails.getDelayBetweenAutoAdvancesInMilliseconds();
RaceColumnSelectionStrategies strategy = settingsWithRaceSelection.getActiveRaceColumnSelectionStrategy();
@@ -231,14 +101,6 @@ public class LeaderboardSettingsFactory {
settingsWithRaceSelection.isShowCompetitorNationality());
}
private List<DetailType> copyDetailTypes(List<DetailType> detailTypes) {
List<DetailType> result = null;
if(detailTypes != null) {
result = new ArrayList<DetailType>(detailTypes);
}
return result;
}
private List<String> copyRaceNamesList(List<String> raceNames) {
List<String> result = null;
if(raceNames != null) {
@@ -7,13 +7,12 @@ public class MetaLeaderboardPerspectiveLifecycle extends AbstractLeaderboardPers
public static final String ID = "mlbh";
public MetaLeaderboardPerspectiveLifecycle(StringMessages stringMessages) {
this(stringMessages, null);
}
private final MultiLeaderboardPanelLifecycle multiLeaderboardPanelLifecycle;
public MetaLeaderboardPerspectiveLifecycle(StringMessages stringMessages, AbstractLeaderboardDTO leaderboard) {
super(stringMessages, leaderboard, true);
addLifeCycle(new MultiLeaderboardPanelLifecycle(null, stringMessages));
multiLeaderboardPanelLifecycle = new MultiLeaderboardPanelLifecycle(null, stringMessages);
addLifeCycle(multiLeaderboardPanelLifecycle);
}
@Override
@@ -25,4 +24,8 @@ public class MetaLeaderboardPerspectiveLifecycle extends AbstractLeaderboardPers
public String getComponentId() {
return ID;
}
public MultiLeaderboardPanelLifecycle getMultiLeaderboardPanelLifecycle() {
return multiLeaderboardPanelLifecycle;
}
}
@@ -44,13 +44,13 @@ public class MultiCompetitorLeaderboardChartLifecycle implements
}
@Override
public MultiCompetitorLeaderboardChartSettings extractGlobalSettings(
public MultiCompetitorLeaderboardChartSettings extractUserSettings(
MultiCompetitorLeaderboardChartSettings settings) {
return settings;
}
@Override
public MultiCompetitorLeaderboardChartSettings extractContextSpecificSettings(
public MultiCompetitorLeaderboardChartSettings extractDocumentSettings(
MultiCompetitorLeaderboardChartSettings settings) {
return settings;
}
@@ -20,7 +20,7 @@ public class MultiLeaderboardPanelLifecycle extends LeaderboardPanelLifecycle {
}
@Override
public LeaderboardSettings extractContextSpecificSettings(LeaderboardSettings leaderboardSettings) {
public LeaderboardSettings extractDocumentSettings(LeaderboardSettings leaderboardSettings) {
return createDefaultSettings();
}
@@ -1,13 +0,0 @@
package com.sap.sailing.gwt.settings.client.settingtypes.converter;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sse.common.settings.generic.StringToEnumConverter;
public class DetailTypeStringToEnumConverter implements StringToEnumConverter<DetailType> {
@Override
public DetailType fromString(String stringValue) {
return DetailType.valueOf(stringValue);
}
}
@@ -1,13 +0,0 @@
package com.sap.sailing.gwt.settings.client.settingtypes.converter;
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapHelpLinesSettings.HelpLineTypes;
import com.sap.sse.common.settings.generic.StringToEnumConverter;
public class HelpLineTypesStringToEnumConverter implements StringToEnumConverter<HelpLineTypes> {
@Override
public HelpLineTypes fromString(String stringValue) {
return HelpLineTypes.valueOf(stringValue);
}
}
@@ -1,13 +0,0 @@
package com.sap.sailing.gwt.settings.client.settingtypes.converter;
import com.sap.sailing.domain.common.ManeuverType;
import com.sap.sse.common.settings.generic.StringToEnumConverter;
public class ManeuverTypeStringToEnumConverter implements StringToEnumConverter<ManeuverType> {
@Override
public ManeuverType fromString(String stringValue) {
return ManeuverType.valueOf(stringValue);
}
}
@@ -1,13 +0,0 @@
package com.sap.sailing.gwt.settings.client.settingtypes.converter;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings.RaceColumnSelectionStrategies;
import com.sap.sse.common.settings.generic.StringToEnumConverter;
public class RaceColumnSelectionStrategiesStringToEnumConverter implements StringToEnumConverter<RaceColumnSelectionStrategies> {
@Override
public RaceColumnSelectionStrategies fromString(String stringValue) {
return RaceColumnSelectionStrategies.valueOf(stringValue);
}
}
@@ -1,13 +0,0 @@
package com.sap.sailing.gwt.settings.client.settingtypes.converter;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sse.common.settings.generic.StringToEnumConverter;
public class WindSourceTypeStringToEnumConverter implements StringToEnumConverter<WindSourceType> {
@Override
public WindSourceType fromString(String stringValue) {
return WindSourceType.valueOf(stringValue);
}
}
@@ -1,13 +0,0 @@
package com.sap.sailing.gwt.settings.client.settingtypes.converter;
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapZoomSettings.ZoomTypes;
import com.sap.sse.common.settings.generic.StringToEnumConverter;
public class ZoomTypesStringToEnumConverter implements StringToEnumConverter<ZoomTypes> {
@Override
public ZoomTypes fromString(String stringValue) {
return ZoomTypes.valueOf(stringValue);
}
}
@@ -0,0 +1,15 @@
package com.sap.sailing.gwt.settings.client.utils;
import com.sap.sailing.gwt.ui.shared.settings.SailingSettingsConstants;
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
public class SailingStoredSettingsLocation extends StoredSettingsLocation {
/**
* @see com.sap.sse.security.ui.settings.StoredSettingsLocation#StoredSettingsLocation(String, String)
*/
public SailingStoredSettingsLocation(String userSettingsIdPart, String documentSettingsIdPart) {
super(SailingSettingsConstants.USER_SETTINGS_UI, userSettingsIdPart, documentSettingsIdPart);
}
}
@@ -1,60 +0,0 @@
package com.sap.sailing.gwt.settings.client.utils;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardContextDefinition;
import com.sap.sailing.gwt.settings.client.raceboard.RaceboardContextDefinition;
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaOverviewContextDefinition;
import com.sap.sse.security.ui.settings.StorageDefinitionId;
public class StorageDefinitionIdFactory {
private StorageDefinitionIdFactory() {
}
private static final String RACEBOARD = "Raceboard";
private static final String LEADERBOARD = "Leaderboard";
private static final String REGATTA_OVERVIEW = "RegattaOverview";
private static final String EVENT_REGATTA_LEADERBOARD = "EventRegattaLeaderboard";
private static final String SERIES_OVERALL_LEADERBOARD = "SeriesOverallLeaderboard";
private static final String SERIES_REGATTA_LEADERBOARDS = "SeriesRegattaLeaderboards";
public static final StorageDefinitionId createStorageDefinitionIdForRaceBoard(
RaceboardContextDefinition raceboardContextDefinition) {
String globalDefinitionId = RACEBOARD;
if (raceboardContextDefinition.getMode() != null) {
globalDefinitionId += "." + raceboardContextDefinition.getMode().toString();
}
String contextDefinitionId = StorageDefinitionId.buildContextDefinitionId(raceboardContextDefinition.getRegattaName(),
raceboardContextDefinition.getRaceName(), raceboardContextDefinition.getLeaderboardName());
return new StorageDefinitionId(globalDefinitionId, contextDefinitionId);
}
public static final StorageDefinitionId createStorageDefinitionIdForLeaderboard(
LeaderboardContextDefinition leaderboardContextDefinition) {
return new StorageDefinitionId(LEADERBOARD,
StorageDefinitionId.buildContextDefinitionId(leaderboardContextDefinition.getLeaderboardName()));
}
public static final StorageDefinitionId createStorageDefinitionIdForRegattaOverview(
RegattaOverviewContextDefinition regattaOverviewContextDefinition) {
return new StorageDefinitionId(REGATTA_OVERVIEW,
StorageDefinitionId.buildContextDefinitionId(regattaOverviewContextDefinition.getEvent().toString()));
}
public static final StorageDefinitionId createStorageDefinitionIdForEventRegattaLeaderboard(String leaderboardName) {
return new StorageDefinitionId(EVENT_REGATTA_LEADERBOARD,
StorageDefinitionId.buildContextDefinitionId(leaderboardName));
}
public static final StorageDefinitionId createStorageDefinitionIdForSeriesOverallLeaderboard(String leaderboardName) {
return new StorageDefinitionId(SERIES_OVERALL_LEADERBOARD,
StorageDefinitionId.buildContextDefinitionId(leaderboardName));
}
public static final StorageDefinitionId createStorageDefinitionIdForSeriesRegattaLeaderboards(String leaderboardName) {
return new StorageDefinitionId(SERIES_REGATTA_LEADERBOARDS,
StorageDefinitionId.buildContextDefinitionId(leaderboardName));
}
}
@@ -0,0 +1,65 @@
package com.sap.sailing.gwt.settings.client.utils;
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardContextDefinition;
import com.sap.sailing.gwt.settings.client.raceboard.RaceboardContextDefinition;
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaOverviewContextDefinition;
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
/**
* Factory for {@link StoredSettingsLocation}s which are used in Sailing Analytics.
*
* @author Vladislav Chumak
*
*/
public class StoredSettingsLocationFactory {
private StoredSettingsLocationFactory() {
}
private static final String RACEBOARD = "Raceboard";
private static final String LEADERBOARD = "Leaderboard";
private static final String REGATTA_OVERVIEW = "RegattaOverview";
private static final String EVENT_REGATTA_LEADERBOARD = "EventRegattaLeaderboard";
private static final String SERIES_OVERALL_LEADERBOARD = "SeriesOverallLeaderboard";
private static final String SERIES_REGATTA_LEADERBOARDS = "SeriesRegattaLeaderboards";
public static final StoredSettingsLocation createStoredSettingsLocatorForRaceBoard(
RaceboardContextDefinition raceboardContextDefinition, String raceBoardModeName) {
String userSettingsIdPart = RACEBOARD;
if(raceBoardModeName != null) {
userSettingsIdPart += "." + raceBoardModeName;
}
String documentSettingsIdPart = StoredSettingsLocation.buildDocumentSettingsIdPart(raceboardContextDefinition.getRegattaName(),
raceboardContextDefinition.getRaceName(), raceboardContextDefinition.getLeaderboardName());
return new SailingStoredSettingsLocation(userSettingsIdPart, documentSettingsIdPart);
}
public static final StoredSettingsLocation createStoredSettingsLocatorForLeaderboard(
LeaderboardContextDefinition leaderboardContextDefinition) {
return new SailingStoredSettingsLocation(LEADERBOARD,
StoredSettingsLocation.buildDocumentSettingsIdPart(leaderboardContextDefinition.getLeaderboardName()));
}
public static final StoredSettingsLocation createStoredSettingsLocatorForRegattaOverview(
RegattaOverviewContextDefinition regattaOverviewContextDefinition) {
return new SailingStoredSettingsLocation(REGATTA_OVERVIEW,
StoredSettingsLocation.buildDocumentSettingsIdPart(regattaOverviewContextDefinition.getEvent().toString()));
}
public static final StoredSettingsLocation createStoredSettingsLocatorForEventRegattaLeaderboard(String leaderboardName) {
return new SailingStoredSettingsLocation(EVENT_REGATTA_LEADERBOARD,
StoredSettingsLocation.buildDocumentSettingsIdPart(leaderboardName));
}
public static final StoredSettingsLocation createStoredSettingsLocatorForSeriesOverallLeaderboard(String leaderboardName) {
return new SailingStoredSettingsLocation(SERIES_OVERALL_LEADERBOARD,
StoredSettingsLocation.buildDocumentSettingsIdPart(leaderboardName));
}
public static final StoredSettingsLocation createStoredSettingsLocatorForSeriesRegattaLeaderboards(String leaderboardName) {
return new SailingStoredSettingsLocation(SERIES_REGATTA_LEADERBOARDS,
StoredSettingsLocation.buildDocumentSettingsIdPart(leaderboardName));
}
}
Loaded 100 of 485 files, more files were not shown because too many files have changed in this diff. Show more