Merge remote-tracking branch 'server/master'

This commit is contained in:
Axel Uhl committed 2014-09-15 12:18:41 +02:00
commit 8771249183
81 files changed
+1679 -586

No files matched your search

@@ -69,7 +69,7 @@ public class TracTrac {
for (TracTracRaceRecordDTO raceRecord : racesThatCanBeTracked.getB()) {
RaceRecord record = getTracTracAdapter().getSingleTracTracRaceRecord(new URL(raceRecord.jsonURL), raceRecord.id, /*loadClientParams*/true);
if (record.getRaceStatus().equals(TracTracConnectionConstants.REPLAY_STATUS)) {
if (record.getRaceStatus().equals(TracTracConnectionConstants.REPLAY_STATUS) || record.getRaceVisibility().equals(TracTracConnectionConstants.REPLAY_VISIBILITY)) {
RegattaIdentifier regattaForRaceRecord = null;
if (raceRecord.hasRememberedRegatta()) {
Regatta regatta = getService().getRememberedRegattaForRace(raceRecord.id);
@@ -85,9 +85,9 @@ public class TracTrac {
MongoRaceLogStoreFactory.INSTANCE.getMongoRaceLogStore(getService().getMongoObjectFactory(), getService().getDomainObjectFactory()),
RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, /*simulateWithStartTimeNow*/false,
/*tracTracUsername*/"", /*tracTracPassword*/"",
record.getRaceStatus());
record.getRaceStatus(), record.getRaceVisibility());
} else {
logger.info("Ignoring race " + record.getName() + " because it is in status " + record.getRaceStatus());
logger.info("Ignoring race " + record.getName() + " because it is in status " + record.getRaceStatus() + " and visibility " + record.getRaceVisibility());
}
}
}
@@ -107,7 +107,7 @@ public class TracTrac {
raceRecord.getTrackingStartTime().asDate(),
raceRecord
.getTrackingEndTime().asDate(), raceRecord.getRaceStartTime().asDate(),
raceRecord.getBoatClassNames(), raceRecord.getRaceStatus(), raceRecord.getJsonURL().toString(),
raceRecord.getBoatClassNames(), raceRecord.getRaceStatus(), raceRecord.getRaceVisibility(), raceRecord.getJsonURL().toString(),
hasRememberedRegatta(raceRecord.getID())));
}
return new com.sap.sse.common.Util.Pair<String, List<TracTracRaceRecordDTO>>(raceRecords.getA(), result);
@@ -7,6 +7,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sap.sailing.domain.common.ScoringSchemeType;
/**
* Captures the serializable properties of a leaderboard which in particular has the competitors, any optional display
* name mappings for the competitors, races and their net / total points as well as possible reasons for maximum points
@@ -62,10 +64,11 @@ public class LeaderboardDTO extends AbstractLeaderboardDTO implements Serializab
* from it by the {@link #clone()} operation.
* @param hasOverallDetails TODO
*/
public LeaderboardDTO(Date timePointOfLastCorrectionsValidity, String comment, boolean higherScoreIsBetter, UUIDGenerator uuidGenerator, boolean hasOverallDetails) {
public LeaderboardDTO(Date timePointOfLastCorrectionsValidity, String comment, ScoringSchemeType scoringScheme, boolean higherScoreIsBetter, UUIDGenerator uuidGenerator, boolean hasOverallDetails) {
initCollections();
id = uuidGenerator.generateRandomUUID();
this.timePointOfLastCorrectionsValidity = timePointOfLastCorrectionsValidity;
this.scoringScheme = scoringScheme;
this.comment = comment;
this.higherScoresIsBetter = higherScoreIsBetter;
this.hasOverallDetails = hasOverallDetails;
@@ -56,25 +56,25 @@ public class MultipleClassesInRegattaTest {
httpAndHost+"/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=cce678c8-97e6-11e0-9aed-406186cbf87c"),
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false,
EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, new DummyTrackedRegattaRegistry());
EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY, new DummyTrackedRegattaRegistry());
kiwotest2 = domainFactory
.createRaceTracker(
new URL(
httpAndHost+"/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=11290bd6-97e7-11e0-9aed-406186cbf87c"),
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, new DummyTrackedRegattaRegistry());
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY, new DummyTrackedRegattaRegistry());
kiwotest3 = domainFactory
.createRaceTracker(
new URL(
httpAndHost+"/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=39635b24-97e7-11e0-9aed-406186cbf87c"),
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, new DummyTrackedRegattaRegistry());
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY, new DummyTrackedRegattaRegistry());
weym470may112014_2 = domainFactory
.createRaceTracker(
new URL(
httpAndHost+"/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=04498426-7dfd-11e0-8236-406186cbf87c"),
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, new DummyTrackedRegattaRegistry());
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY, new DummyTrackedRegattaRegistry());
assertEquals("STG", kiwotest1.getRegatta().getBoatClass().getName());
assertEquals("505", kiwotest2.getRegatta().getBoatClass().getName());
@@ -62,7 +62,7 @@ public class UnicodeCharactersInCompetitorNamesTest {
+ TracTracConnectionConstants.PORT_STORED),
new URI("http://tracms.traclive.dk/update_course"),
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l,
/* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, "tracTest", "tracTest", "",
/* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, "tracTest", "tracTest", "", "",
new DummyTrackedRegattaRegistry());
Iterable<Competitor> competitors = fourtyninerYellow_2.getRacesHandle().getRace().getCompetitors();
@@ -134,7 +134,8 @@ public interface DomainFactory {
*/
TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking,
TimePoint endOfTracking, long delayToLiveInMillis, boolean simulateWithStartTimeNow, RaceLogStore raceLogStore,
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, TrackedRegattaRegistry trackedRegattaRegistry) throws MalformedURLException, FileNotFoundException,
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword,
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry) throws MalformedURLException, FileNotFoundException,
URISyntaxException, CreateModelException, SubscriberInitializationException;
/**
@@ -143,7 +144,7 @@ public interface DomainFactory {
*/
RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking,
TimePoint endOfTracking, long delayToLiveInMillis, boolean simulateWithStartTimeNow, RaceLogStore raceLogStore,
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, TrackedRegattaRegistry trackedRegattaRegistry) throws MalformedURLException, FileNotFoundException,
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry) throws MalformedURLException, FileNotFoundException,
URISyntaxException, CreateModelException, SubscriberInitializationException;
BoatClass getOrCreateBoatClass(String competitorClassName);
@@ -245,7 +246,7 @@ public interface DomainFactory {
RaceTrackingConnectivityParameters createTrackingConnectivityParameters(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis, boolean simulateWithStartTimeNow, RaceLogStore raceLogStore,
String tracTracUsername, String tracTracPassword, String raceStatus);
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility);
/**
* Removes all knowledge about <code>tractracRace</code> which includes removing it from the race cache, from the
* {@link com.sap.sailing.domain.base.Regatta} and, if a {@link TrackedRace} for the corresponding
@@ -38,17 +38,19 @@ public class RaceRecord {
private final URI storedURI;
private final List<String> boatClassNames;
private final String raceStatus;
private final String raceVisibility;
private final URL jsonUrl;
public RaceRecord(URL jsonURL, String regattaName, String name, String replayURL, String paramURLAsString,
String ID, String trackingstarttime, String trackingendtime, String racestarttime,
String commaSeparatedBoatClassNames, String status, boolean loadLiveAndStoredURI)
String commaSeparatedBoatClassNames, String status, String visibility, boolean loadLiveAndStoredURI)
throws URISyntaxException, IOException {
super();
this.regattaName = regattaName;
this.name = name;
this.replayURL = replayURL;
this.raceStatus = status;
this.raceVisibility = visibility;
this.ID = ID;
this.jsonUrl = jsonURL;
this.boatClassNames = new ArrayList<String>();
@@ -188,6 +190,10 @@ public class RaceRecord {
return raceStatus;
}
public String getRaceVisibility() {
return raceVisibility;
}
public URL getJsonURL() {
return jsonUrl;
}
@@ -48,7 +48,7 @@ public interface TracTracAdapter {
*/
RaceHandle addTracTracRace(TrackerManager trackerManager, URL paramURL, URI liveURI, URI storedURI,
URI courseDesignUpdateURI, RaceLogStore raceLogStore, long timeoutInMilliseconds,
String tracTracUsername, String tracTracPassword, String raceStatus) throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception;
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility) throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception;
/**
* Same as {@link #addTracTracRace(URL, URI, URI, WindStore, long)}, only that start and end of tracking are
@@ -68,7 +68,9 @@ public interface TracTracAdapter {
RaceHandle addTracTracRace(TrackerManager trackerManager, RegattaIdentifier regattaToAddTo, URL paramURL, URI liveURI,
URI storedURI, URI courseDesignUpdateURI, TimePoint trackingStartTime,
TimePoint trackingEndTime, RaceLogStore raceLogStore,
long timeoutForReceivingRaceDefinitionInMilliseconds, boolean simulateWithStartTimeNow, String tracTracUsername, String tracTracPassword, String raceStatus)
long timeoutForReceivingRaceDefinitionInMilliseconds, boolean simulateWithStartTimeNow,
String tracTracUsername, String tracTracPassword,
String raceStatus, String raceVisibility)
throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception;
/**
@@ -10,8 +10,26 @@ public interface TracTracConnectionConstants {
final int PORT_LIVE = 1520; //For official usage use 4400; for SAP-dedicated server use 1520
final int PORT_STORED = PORT_LIVE + 1; //For official usage use 4401;
/*
* ‘Status’ is the one that we used originally and is an enumerate with the values:
* - HIDDEN: the race is hidden
* - OFFLINE: the race is visible but it can not be loaded
* - ONLINE: the race is visible and online
* - REPLAY: the race is online and the mtb-file has been created (this value is no longer being used as we no longer display information about whether data are being retrieved from data base or file)
* ‘Visibility’ was introduced this year to improve some short comings of the ‘status’ attribute and is an enumerate with the values:
* - HIDDEN: the race is hidden (same meaning as above)
* - OFFLINE: the race is visible but it can not be loaded (same meaning as above)
* - ONLINE: the race can be loaded and it is in a live status (live or future)
* - REPLAY: the race can be loaded and it is over (a race in the past)
* In addition to these we would like to add a new value for the visibility attribute called "UPCOMING" that means that the race is online (can be loaded) and it is in the future.
*/
final String HIDDEN_STATUS = "HIDDEN";
final String ONLINE_STATUS = "ONLINE";
final Object REPLAY_STATUS = "REPLAY";
final String HIDDEN_VISIBILITY = "HIDDEN";
final String ONLINE_VISIBILITY = "ONLINE";
final Object REPLAY_VISIBILITY = "REPLAY";
}
@@ -635,20 +635,21 @@ public class DomainFactoryImpl implements DomainFactory {
@Override
public TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking,
TimePoint endOfTracking, long delayToLiveInMillis, boolean simulateWithStartTimeNow,
RaceLogStore raceLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus,
RaceLogStore raceLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
String tracTracPassword, String raceStatus, String raceVisibility,
TrackedRegattaRegistry trackedRegattaRegistry) throws MalformedURLException, FileNotFoundException,
URISyntaxException, CreateModelException, SubscriberInitializationException {
return new TracTracRaceTrackerImpl(this, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
simulateWithStartTimeNow, raceLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, trackedRegattaRegistry);
simulateWithStartTimeNow, raceLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry);
}
@Override
public RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
boolean simulateWithStartTimeNow, RaceLogStore raceLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, TrackedRegattaRegistry trackedRegattaRegistry)
boolean simulateWithStartTimeNow, RaceLogStore raceLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry)
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException, SubscriberInitializationException {
return new TracTracRaceTrackerImpl(regatta, this, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
simulateWithStartTimeNow, raceLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, trackedRegattaRegistry);
simulateWithStartTimeNow, raceLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry);
}
@Override
@@ -664,9 +665,10 @@ public class DomainFactoryImpl implements DomainFactory {
@Override
public RaceTrackingConnectivityParameters createTrackingConnectivityParameters(URL paramURL, URI liveURI,
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
boolean simulateWithStartTimeNow, RaceLogStore raceLogStore, String tracTracUsername, String tracTracPassword, String raceStatus) {
boolean simulateWithStartTimeNow, RaceLogStore raceLogStore, String tracTracUsername,
String tracTracPassword, String raceStatus, String raceVisibility) {
return new RaceTrackingConnectivityParametersImpl(paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking,
delayToLiveInMillis, simulateWithStartTimeNow, raceLogStore, this, tracTracUsername, tracTracPassword, raceStatus);
delayToLiveInMillis, simulateWithStartTimeNow, raceLogStore, this, tracTracUsername, tracTracPassword, raceStatus, raceVisibility);
}
@Override
@@ -42,7 +42,9 @@ public class JSONServiceImpl implements JSONService {
(String) jsonRaceEntry.get("tracking_endtime"),
(String) jsonRaceEntry.get("race_starttime"),
(String) jsonRaceEntry.get("classes"),
(String) jsonRaceEntry.get("status"), /*loadLiveAndStoreURI*/ loadLiveAndStoredURI);
(String) jsonRaceEntry.get("status"),
(String) jsonRaceEntry.get("visibility"),
/*loadLiveAndStoreURI*/ loadLiveAndStoredURI);
return raceRecord;
}
@@ -32,10 +32,12 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
private final String tracTracUsername;
private final String tracTracPassword;
private final String raceStatus;
private final String raceVisibility;
public RaceTrackingConnectivityParametersImpl(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking,
TimePoint endOfTracking, long delayToLiveInMillis, boolean simulateWithStartTimeNow,
RaceLogStore raceLogStore, DomainFactory domainFactory, String tracTracUsername, String tracTracPassword, String raceStatus) {
RaceLogStore raceLogStore, DomainFactory domainFactory, String tracTracUsername, String tracTracPassword,
String raceStatus, String raceVisibility) {
super();
this.paramURL = paramURL;
this.liveURI = liveURI;
@@ -50,13 +52,14 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
this.tracTracUsername = tracTracUsername;
this.tracTracPassword = tracTracPassword;
this.raceStatus = raceStatus;
this.raceVisibility = raceVisibility;
}
@Override
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore, GPSFixStore gpsFixStore) throws MalformedURLException,
FileNotFoundException, URISyntaxException, CreateModelException, SubscriberInitializationException {
RaceTracker tracker = domainFactory.createRaceTracker(paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking,
endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, raceLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, trackedRegattaRegistry);
endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, raceLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry);
return tracker;
}
@@ -64,7 +67,7 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore, GPSFixStore gpsFixStore)
throws Exception {
RaceTracker tracker = domainFactory.createRaceTracker(regatta, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking,
endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, raceLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, trackedRegattaRegistry);
endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, raceLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry);
return tracker;
}
@@ -48,14 +48,14 @@ public class TracTracAdapterImpl implements TracTracAdapter {
@Override
public RaceHandle addTracTracRace(TrackerManager trackerManager, URL paramURL, URI liveURI, URI storedURI,
URI courseDesignUpdateURI, RaceLogStore raceLogStore, long timeoutInMilliseconds,
String tracTracUsername, String tracTracPassword, String raceStatus) throws Exception {
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility) throws Exception {
return trackerManager.addRace(
/* regattaToAddTo */null,
getTracTracDomainFactory().createTrackingConnectivityParameters(paramURL, liveURI, storedURI,
courseDesignUpdateURI,
/* startOfTracking */null,
/* endOfTracking */null, delayToLiveInMillis, /* simulateWithStartTimeNow */false,
raceLogStore, tracTracUsername, tracTracPassword, raceStatus), timeoutInMilliseconds);
raceLogStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility), timeoutInMilliseconds);
}
@Override
@@ -63,12 +63,12 @@ public class TracTracAdapterImpl implements TracTracAdapter {
URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking,
TimePoint endOfTracking, RaceLogStore raceLogStore,
long timeoutInMilliseconds, boolean simulateWithStartTimeNow, String tracTracUsername,
String tracTracPassword, String raceStatus) throws Exception {
String tracTracPassword, String raceStatus, String raceVisibility) throws Exception {
return trackerManager.addRace(
regattaToAddTo,
getTracTracDomainFactory().createTrackingConnectivityParameters(paramURL, liveURI, storedURI,
courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
simulateWithStartTimeNow, raceLogStore, tracTracUsername, tracTracPassword, raceStatus),
simulateWithStartTimeNow, raceLogStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility),
timeoutInMilliseconds);
}
@@ -89,7 +89,7 @@ public class TracTracAdapterImpl implements TracTracAdapter {
for (RaceRecord rr : jsonService.getRaceRecords()) {
URL paramURL = rr.getParamURL();
regatta = addTracTracRace(trackerManager, paramURL, liveURI, storedURI, courseDesignUpdateURI, raceLogStore,
timeoutInMilliseconds, tracTracUsername, "", tracTracPassword).getRegatta();
timeoutInMilliseconds, tracTracUsername, "", "", tracTracPassword).getRegatta();
}
return regatta;
}
@@ -247,21 +247,21 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
*/
protected TracTracRaceTrackerImpl(DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
boolean simulateWithStartTimeNow, RaceLogStore raceLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, TrackedRegattaRegistry trackedRegattaRegistry)
boolean simulateWithStartTimeNow, RaceLogStore raceLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry)
throws URISyntaxException, MalformedURLException, FileNotFoundException, CreateModelException, SubscriberInitializationException {
this(ModelLocator.getEventFactory().createRace(new URI(paramURL.toString())), domainFactory,
paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking,
delayToLiveInMillis, simulateWithStartTimeNow, raceLogStore, windStore, gpsFixStore, tracTracUsername,
tracTracPassword, raceStatus, trackedRegattaRegistry);
tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry);
}
private TracTracRaceTrackerImpl(IRace tractracRace, DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis, boolean simulateWithStartTimeNow,
RaceLogStore raceLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, TrackedRegattaRegistry trackedRegattaRegistry)
RaceLogStore raceLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry)
throws URISyntaxException, MalformedURLException, FileNotFoundException, SubscriberInitializationException {
this(tractracRace, null, domainFactory, paramURL, liveURI, storedURI, courseDesignUpdateURI,
startOfTracking, endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, raceLogStore, windStore, gpsFixStore,
tracTracUsername, tracTracPassword, raceStatus, trackedRegattaRegistry);
tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry);
}
/**
@@ -272,12 +272,12 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
*/
protected TracTracRaceTrackerImpl(Regatta regatta, DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis, boolean simulateWithStartTimeNow,
RaceLogStore raceLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, TrackedRegattaRegistry trackedRegattaRegistry)
RaceLogStore raceLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry)
throws URISyntaxException, MalformedURLException, FileNotFoundException, CreateModelException, SubscriberInitializationException {
this(ModelLocator.getEventFactory().createRace(new URI(paramURL.toString())), regatta,
domainFactory, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking,
delayToLiveInMillis, simulateWithStartTimeNow, raceLogStore, windStore, gpsFixStore, tracTracUsername,
tracTracPassword, raceStatus, trackedRegattaRegistry);
tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry);
}
/**
@@ -294,7 +294,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
private TracTracRaceTrackerImpl(IRace tractracRace, final Regatta regatta, DomainFactory domainFactory,
URL paramURL, URI liveURI, URI storedURI, URI tracTracUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
long delayToLiveInMillis, boolean simulateWithStartTimeNow, RaceLogStore raceLogStore,
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, TrackedRegattaRegistry trackedRegattaRegistry)
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry)
throws URISyntaxException, MalformedURLException, FileNotFoundException, SubscriberInitializationException {
super();
this.trackedRegattaRegistry = trackedRegattaRegistry;
@@ -317,7 +317,8 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
}
// check if there is a directory configured where stored data files can be cached
// only cache files for races in REPLAY state
if (raceStatus != null && raceStatus.equals(TracTracConnectionConstants.REPLAY_STATUS)) {
if ( (raceStatus != null && raceStatus.equals(TracTracConnectionConstants.REPLAY_STATUS)) ||
(raceVisibility != null && raceVisibility.equals(TracTracConnectionConstants.REPLAY_VISIBILITY)) ) {
storedURI = checkForCachedStoredData(storedURI);
}
@@ -1236,7 +1236,8 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
final LeaderboardDTOCalculationReuseCache cache = new LeaderboardDTOCalculationReuseCache(timePoint);
final LeaderboardDTO result = new LeaderboardDTO(this.getScoreCorrection().getTimePointOfLastCorrectionsValidity() == null ? null
: this.getScoreCorrection().getTimePointOfLastCorrectionsValidity().asDate(),
this.getScoreCorrection() == null ? null : this.getScoreCorrection().getComment(), this
this.getScoreCorrection() == null ? null : this.getScoreCorrection().getComment(),
this.getScoringScheme() == null ? null : this.getScoringScheme().getType(), this
.getScoringScheme().isHigherBetter(), new UUIDGenerator(), addOverallDetails);
result.competitors = new ArrayList<CompetitorDTO>();
result.name = this.getName();
@@ -19,12 +19,17 @@ import com.sap.sse.common.Util;
* 10 points for the winner. Iff for one race column a {@link AdditionalScoringInformationEvent}
* is found then 8 points are applied for the winner.
*
* From Phil, Race Director, on 12.09.2014: "If there is a tie in the regatta score between two or more boats at any time, the tie
* shall be broken in favour of the boat that has won the most races. If a tie still remains, it shall be broken in
* favour of the boat that had the better place at the last race sailed."
*
* @author Simon Marcel Pamies
*/
public class HighPointFirstGets10Or8AndLastBreaksTie extends HighPointFirstGetsFixedScore {
private static final long serialVersionUID = 1L;
private final double SCORE_FOR_WINNER_IF_OVERWRITTEN = 8.0;
private static final int MIN_RACES_REQUIRED_TO_BE_SCORED = 3;
public HighPointFirstGets10Or8AndLastBreaksTie() {
super(10.0);
@@ -37,7 +42,52 @@ public class HighPointFirstGets10Or8AndLastBreaksTie extends HighPointFirstGetsF
@Override
public int compareByBetterScore(List<Util.Pair<RaceColumn, Double>> o1Scores, List<Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter) {
return 0;
assert o1Scores.size() == o2Scores.size();
int o1Wins = getWins(o1Scores);
int o2Wins = getWins(o2Scores);
int result = o2Wins - o1Wins;
if (result == 0 && o1Scores.size() >= 1 && o2Scores.size() >= 1) {
result = o1Scores.get(o1Scores.size()-1).getB().compareTo(o2Scores.get(o2Scores.size()-1).getB());
}
return result;
}
/**
* Counts a competitor's wins by comparing the scores to {@link #MAX_POINTS} which is the score attributed to a race
* won
*/
private int getWins(List<com.sap.sse.common.Util.Pair<RaceColumn, Double>> scores) {
int wins = 0;
for (com.sap.sse.common.Util.Pair<RaceColumn, Double> score : scores) {
if (Math.abs(score.getB() - getScoreForRaceWinner() * score.getA().getFactor()) < 0.0000001) {
wins++;
}
}
return wins;
}
/**
* Generally, in the Extreme Sailing Series the number of races scored doesn't matter. However, if a competitor
* scored fewer than five races, the competitor doesn't participate in the overall ranking and is therefore to be
* sorted worse than all competitors completing five or more races.
*/
@Override
public int compareByNumberOfRacesScored(int competitor1NumberOfRacesScored, int competitor2NumberOfRacesScored) {
int result;
if (competitor1NumberOfRacesScored >= MIN_RACES_REQUIRED_TO_BE_SCORED) {
if (competitor2NumberOfRacesScored >= MIN_RACES_REQUIRED_TO_BE_SCORED) {
result = 0;
} else {
result = -1; // competitor1 is better ("less") because it's the only one of the two scoring more than MIN_RACES_REQUIRED_TO_BE_SCORED
}
} else {
if (competitor2NumberOfRacesScored >= MIN_RACES_REQUIRED_TO_BE_SCORED) {
result = 1; // competitor2 is better ("less") because it's the only one of the two scoring more than MIN_RACES_REQUIRED_TO_BE_SCORED
} else {
result = 0;
}
}
return result;
}
@Override
@@ -8,6 +8,8 @@ import java.util.Map;
import java.util.NavigableSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.RaceColumn;
@@ -33,6 +35,7 @@ import com.sap.sse.common.Util;
*/
public class ScoreCorrectionImpl implements SettableScoreCorrection {
private static final long serialVersionUID = -7088305215528928135L;
private static final Logger logger = Logger.getLogger(ScoreCorrectionImpl.class.getName());
/**
* If no max point reason is provided for a competitor/race, {@link MaxPointsReason#NONE} should be the default.
@@ -439,6 +442,7 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
}
}, numberOfCompetitorsInLeaderboardFetcher);
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception while computing corrected non maxed score", e);
throw new RuntimeException(e);
}
} else {
@@ -55,7 +55,7 @@ public class TestColumnSwapping {
leaderboardCreationDate = new Date();
try {
// get Leaderboard with name and current date
leaderboardOriginalDTO = new LeaderboardDTO(null, null, /* higherScoreIsBetter */ false, new LeaderboardDTO.UUIDGenerator() {
leaderboardOriginalDTO = new LeaderboardDTO(null, null, ScoringSchemeType.LOW_POINT, /* higherScoreIsBetter */ false, new LeaderboardDTO.UUIDGenerator() {
@Override
public String generateRandomUUID() {
return UUID.randomUUID().toString();
@@ -119,7 +119,7 @@ public class TestColumnSwapping {
@Test
public void testLeaderBoardDTOMethods() {
lb = new LeaderboardDTO(null, null, /* higherScoreIsBetter */ false, new LeaderboardDTO.UUIDGenerator() {
lb = new LeaderboardDTO(null, null, ScoringSchemeType.LOW_POINT, /* higherScoreIsBetter */ false, new LeaderboardDTO.UUIDGenerator() {
@Override
public String generateRandomUUID() {
return UUID.randomUUID().toString();
+7
View File
@@ -28,6 +28,13 @@
<!-- -->
<script type="text/javascript" src="com.sap.sailing.gwt.Home/com.sap.sailing.gwt.Home.nocache.js"></script>
<script type="text/javascript" src="js/newhome/idangerous.swiper.js"></script>
<script type="text/javascript" src="js/jquery-1.5.2.min.js"></script>
<script type="text/javascript" src="highcharts/js/highcharts.js"></script>
<!-- Optionally, add a highcharts theme file -->
<script type="text/javascript" src="highcharts/js/themes/grid.js"></script>
</head>
<!-- -->
@@ -13,7 +13,7 @@ import com.sap.sailing.gwt.home.client.place.event.TabletAndDesktopEventWithoutR
import com.sap.sailing.gwt.home.client.place.events.EventsActivity;
import com.sap.sailing.gwt.home.client.place.events.EventsView;
import com.sap.sailing.gwt.home.client.place.events.TabletAndDesktopEventsView;
import com.sap.sailing.gwt.home.client.place.leaderboard.LeaderboardView;
import com.sap.sailing.gwt.home.client.place.leaderboard.AnalyticsView;
import com.sap.sailing.gwt.home.client.place.leaderboard.TabletAndDesktopLeaderboardView;
import com.sap.sailing.gwt.home.client.place.searchresult.SearchResultView;
import com.sap.sailing.gwt.home.client.place.searchresult.TabletAndDesktopSearchResultView;
@@ -79,7 +79,7 @@ public class SmartphoneApplicationClientFactory extends AbstractApplicationClien
}
@Override
public LeaderboardView createLeaderboardView(EventDTO event, String leaderboardName, Timer timerForClientServerOffset) {
public AnalyticsView createLeaderboardView(EventDTO event, String leaderboardName, Timer timerForClientServerOffset) {
return new TabletAndDesktopLeaderboardView(event, leaderboardName, timerForClientServerOffset, getPlaceNavigator());
}
@@ -13,7 +13,7 @@ import com.sap.sailing.gwt.home.client.place.event.TabletAndDesktopEventWithoutR
import com.sap.sailing.gwt.home.client.place.events.EventsActivity;
import com.sap.sailing.gwt.home.client.place.events.EventsView;
import com.sap.sailing.gwt.home.client.place.events.TabletAndDesktopEventsView;
import com.sap.sailing.gwt.home.client.place.leaderboard.LeaderboardView;
import com.sap.sailing.gwt.home.client.place.leaderboard.AnalyticsView;
import com.sap.sailing.gwt.home.client.place.leaderboard.TabletAndDesktopLeaderboardView;
import com.sap.sailing.gwt.home.client.place.searchresult.SearchResultView;
import com.sap.sailing.gwt.home.client.place.searchresult.TabletAndDesktopSearchResultView;
@@ -79,7 +79,7 @@ public class TabletAndDesktopApplicationClientFactory extends AbstractApplicatio
}
@Override
public LeaderboardView createLeaderboardView(EventDTO event, String leaderboardName, Timer timerForClientServerOffset) {
public AnalyticsView createLeaderboardView(EventDTO event, String leaderboardName, Timer timerForClientServerOffset) {
return new TabletAndDesktopLeaderboardView(event, leaderboardName, timerForClientServerOffset, getPlaceNavigator());
}
@@ -29,6 +29,11 @@ public interface TextMessages extends Messages {
String errorMessageNoSuchLeaderboard();
String raceNotScheduled();
String regattaDetails();
String regatta();
String competitorsAnalytics();
String chooseChart();
String series();
String regattaLeaderboards();
String countdownDays();
String countdownHours();
@@ -21,6 +21,11 @@ errorMessageLoadingData=An error occured while loading the data for this page.
errorMessageNoSuchLeaderboard=Could not find a leaderboard with this name.
raceNotScheduled=Not scheduled.
regattaDetails=Regatta details
regatta=Regatta
competitorsAnalytics=Competitors Analytics
chooseChart=Choose chart type
series=Series
regattaLeaderboards=Regatta leaderboards
countdownDays=Days
countdownHours=Hrs
@@ -21,6 +21,11 @@ errorMessageLoadingData=Beim Laden der Daten für diese Seite ist ein Fehler auf
errorMessageNoSuchLeaderboard=Es wurde keine Ergebnisliste mit diesem Namen gefunden.
raceNotScheduled=Keine Startzeit bekannt
regattaDetails=Regatta anzeigen
regatta=Regatta
competitorsAnalytics=Teilnehmeranalysen
chooseChart=Wähle einen Diagrammtyp aus
series=Serie
regattaLeaderboards=Regattaergebnisse
countdownDays=Tage
countdownHours=Std.
@@ -60,7 +60,7 @@ public class TabletAndDesktopEventView extends Composite implements EventView, E
this.event = event;
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> regattaStructure = getRegattaStructure(event, raceGroups);
eventHeader = new EventHeader(event, this);
eventHeader = new EventHeader(event, navigator, this);
eventRegattaList = new EventRegattaList(event, regattaStructure, timerForClientServerOffset, navigator, this);
eventRegattaRaces = new EventRegattaRaces(event, timerForClientServerOffset, navigator, this);
eventOverview = new EventOverview(event, this);
@@ -12,6 +12,7 @@ import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.gwt.home.client.app.PlaceNavigator;
import com.sap.sailing.gwt.home.client.i18n.TextMessages;
import com.sap.sailing.gwt.home.client.place.event.AbstractEventComposite;
@@ -63,15 +64,18 @@ public class EventHeader extends AbstractEventComposite {
@UiField ImageElement eventLogo2;
// @UiField ImageElement eventLogo3;
private final String defaultLogoUrl = "http://static.sapsailing.com/ubilabsimages/default/default_event_logo.jpg";
// private final List<Anchor> links1;
// private final List<Anchor> links2;
// private final List<Anchor> links3;
public EventHeader(EventDTO event, EventPageNavigator pageNavigator) {
private final String defaultLogoUrl = "http://static.sapsailing.com/ubilabsimages/default/default_event_logo.jpg";
private final PlaceNavigator placeNavigator;
public EventHeader(EventDTO event, PlaceNavigator placeNavigator, EventPageNavigator pageNavigator) {
super(event, pageNavigator);
this.placeNavigator = placeNavigator;
initResources();
// links1 = Arrays.asList(new Anchor[] { overviewLink, regattasLink, scheduleLink, mediaLink });
@@ -97,18 +101,7 @@ public class EventHeader extends AbstractEventComposite {
public EventHeader(EventDTO event) {
super(event, null);
initResources();
isFinishedDiv.getStyle().setDisplay(Display.NONE);
isLiveDiv.getStyle().setDisplay(Display.NONE);
setDataNavigationType("normal");
updateUI();
}
public EventHeader(EventDTO event, PlaceNavigator placeNavigator) {
super(event, null);
this.placeNavigator = null;
initResources();
isFinishedDiv.getStyle().setDisplay(Display.NONE);
@@ -235,8 +228,12 @@ public class EventHeader extends AbstractEventComposite {
@UiHandler("seriesLeaderboardAnchor")
void seriesLeaderboardClicked(ClickEvent clickevent) {
if(getEvent().isFakeSeries()) {
getPageNavigator().openOverallLeaderboardViewer(getEvent().getLeaderboardGroups().get(0));
EventDTO event = getEvent();
if(event.isFakeSeries()) {
LeaderboardGroupDTO leaderboardGroupDTO = getEvent().getLeaderboardGroups().get(0);
String overallLeaderboardName = leaderboardGroupDTO.getName() + " " + LeaderboardNameConstants.OVERALL;
placeNavigator.goToLeaderboard(event.id.toString(), overallLeaderboardName, event.getBaseURL(), event.isOnRemoteServer());
}
}
@@ -0,0 +1,82 @@
package com.sap.sailing.gwt.home.client.place.event.oldcompetitorcharts;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
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.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources;
import com.sap.sailing.gwt.ui.client.DetailTypeFormatter;
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardChart;
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardChartSettings;
public class OldCompetitorCharts extends Composite {
private static OldCompetitorChartsUiBinder uiBinder = GWT.create(OldCompetitorChartsUiBinder.class);
interface OldCompetitorChartsUiBinder extends UiBinder<Widget, OldCompetitorCharts> {
}
@UiField HTMLPanel oldCompetitorChartsPanel;
@UiField ListBox chartTypeSelectionListBox;
private final List<DetailType> availableDetailsTypes;
private MultiCompetitorLeaderboardChart multiCompetitorChart;
public OldCompetitorCharts() {
this.availableDetailsTypes = new ArrayList<DetailType>();
this.multiCompetitorChart = null;
EventRegattaLeaderboardResources.INSTANCE.css().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
}
public void setChart(MultiCompetitorLeaderboardChart multiCompetitorChart, List<DetailType> availableDetailsTypes, DetailType initialDetailType) {
this.multiCompetitorChart = multiCompetitorChart;
this.availableDetailsTypes.clear();
this.availableDetailsTypes.addAll(availableDetailsTypes);
fillChartTypeSelectionBox(initialDetailType);
oldCompetitorChartsPanel.add(multiCompetitorChart);
}
private void fillChartTypeSelectionBox(DetailType initialDetailType) {
chartTypeSelectionListBox.clear();
int i = 0;
for (DetailType detailType : availableDetailsTypes) {
chartTypeSelectionListBox.addItem(DetailTypeFormatter.format(detailType), detailType.name());
if (detailType == initialDetailType) {
chartTypeSelectionListBox.setSelectedIndex(i);
}
i++;
}
}
@UiHandler("chartTypeSelectionListBox")
void chartTypeSelectionChanged(ChangeEvent event) {
DetailType selectedChartDetailType = getSelectedChartDetailType();
multiCompetitorChart.updateSettings(new MultiCompetitorLeaderboardChartSettings(selectedChartDetailType));
}
public DetailType getSelectedChartDetailType() {
DetailType result = null;
int selectedIndex = chartTypeSelectionListBox.getSelectedIndex();
String selectedDetailType = chartTypeSelectionListBox.getValue(selectedIndex);
for (DetailType detailType : availableDetailsTypes) {
if (detailType.name().equals(selectedDetailType)) {
result = detailType;
break;
}
}
return result;
}
}
@@ -0,0 +1,25 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.place.event"
xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.leaderboard"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="i18n" type="com.sap.sailing.gwt.home.client.i18n.TextMessages"/>
<ui:with field="res" type="com.sap.sailing.gwt.home.client.HomeResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
<ui:with field="local_res2" type="com.sap.sailing.gwt.home.client.place.event.regattaanalytics.RegattaAnalyticsResources" />
<g:HTMLPanel>
<div class="{res.mainCss.grid}">
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
<h3><ui:text from="{i18n.competitorsAnalytics}" /></h3>
</div>
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_settings}">
<ui:text from="{i18n.chooseChart}" />
<g:ListBox ui:field="chartTypeSelectionListBox" />
</div>
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
<g:HTMLPanel ui:field="oldCompetitorChartsPanel">
</g:HTMLPanel>
</div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,5 @@
.oldLeaderboardPanel {
background-color:#f8f8f8;
padding: 0 10px 10px 10px;
width: 100%;
}
@@ -0,0 +1,108 @@
package com.sap.sailing.gwt.home.client.place.event.oldleaderboard;
import java.util.Date;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.ParagraphElement;
import com.google.gwt.dom.client.Style.Visibility;
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.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.gwt.home.client.i18n.TextMessages;
import com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources;
import com.sap.sailing.gwt.ui.client.DebugIdHelper;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialog;
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.ui.leaderboard.ScoringSchemeTypeFormatter;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.player.Timer.PlayModes;
import com.sap.sse.gwt.client.player.Timer.PlayStates;
public class OldLeaderboard extends Composite {
private static OldLeaderboardUiBinder uiBinder = GWT.create(OldLeaderboardUiBinder.class);
interface OldLeaderboardUiBinder extends UiBinder<Widget, OldLeaderboard> {
}
@UiField HTMLPanel oldLeaderboardPanel;
@UiField Anchor settingsAnchor;
@UiField Anchor autoRefreshAnchor;
@UiField ParagraphElement lastScoringUpdateTimeDiv;
@UiField ParagraphElement lastScoringUpdateTextDiv;
@UiField ParagraphElement lastScoringCommentDiv;
@UiField ParagraphElement scoringSchemeDiv;
private LeaderboardPanel leaderboardPanel;
private Timer autoRefreshTimer;
public OldLeaderboard() {
this.leaderboardPanel = null;
EventRegattaLeaderboardResources.INSTANCE.css().ensureInjected();
OldLeaderboardResources.INSTANCE.css().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
}
@UiHandler("autoRefreshAnchor")
void toogleAutoRefreshClicked(ClickEvent event) {
if(autoRefreshTimer != null) {
if (autoRefreshTimer.getPlayState() == PlayStates.Playing) {
autoRefreshTimer.pause();
autoRefreshAnchor.getElement().getStyle().setBackgroundColor("#f0ab00");
} else {
// playing the standalone leaderboard means putting it into live mode
autoRefreshTimer.setPlayMode(PlayModes.Live);
autoRefreshAnchor.getElement().getStyle().setBackgroundColor("red");
}
}
}
@UiHandler("settingsAnchor")
void settingsClicked(ClickEvent event) {
if(leaderboardPanel != null) {
final String componentName = leaderboardPanel.getLocalizedShortName();
final String debugIdPrefix = DebugIdHelper.createDebugId(componentName);
SettingsDialog<LeaderboardSettings> dialog = new SettingsDialog<LeaderboardSettings>(leaderboardPanel,
StringMessages.INSTANCE);
dialog.ensureDebugId(debugIdPrefix + "SettingsDialog");
dialog.show();
}
}
public void setLeaderboard(LeaderboardPanel leaderboardPanel, final Timer timer) {
this.autoRefreshTimer = timer;
this.leaderboardPanel = leaderboardPanel;
oldLeaderboardPanel.add(leaderboardPanel);
}
public void updatedLeaderboard(LeaderboardDTO leaderboard, boolean hasLiveRace) {
if(leaderboard != null) {
lastScoringCommentDiv.setInnerText(leaderboard.getComment() != null ? leaderboard.getComment() : "");
scoringSchemeDiv.setInnerText(leaderboard.scoringScheme != null ? ScoringSchemeTypeFormatter.format(leaderboard.scoringScheme, StringMessages.INSTANCE) : "");
if (leaderboard.getTimePointOfLastCorrectionsValidity() != null) {
Date lastCorrectionDate = leaderboard.getTimePointOfLastCorrectionsValidity();
String lastUpdate = DateAndTimeFormatterUtil.defaultDateFormatter.render(lastCorrectionDate) + ", "
+ DateAndTimeFormatterUtil.longTimeFormatter.render(lastCorrectionDate);
lastScoringUpdateTimeDiv.setInnerText(lastUpdate);
lastScoringUpdateTextDiv.setInnerText(TextMessages.INSTANCE.eventRegattaLeaderboardLastScoreUpdate());
} else {
lastScoringUpdateTimeDiv.setInnerText("");
lastScoringUpdateTextDiv.setInnerText("");
}
lastScoringUpdateTimeDiv.getStyle().setVisibility(!hasLiveRace ? Visibility.VISIBLE : Visibility.HIDDEN);
}
}
}
@@ -0,0 +1,37 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.place.event"
xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.leaderboard"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="i18n" type="com.sap.sailing.gwt.home.client.i18n.TextMessages"/>
<ui:with field="res" type="com.sap.sailing.gwt.home.client.HomeResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
<ui:with field="local_res2" type="com.sap.sailing.gwt.home.client.place.event.oldleaderboard.OldLeaderboardResources" />
<g:HTMLPanel>
<div class="{res.mainCss.grid}">
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
<p ui:field="lastScoringCommentDiv" class="{local_res.css.regattaleaderboard_meta_scoring_comment}"></p>
<p ui:field="scoringSchemeDiv" class="{local_res.css.regattaleaderboard_meta_scoring_type}"></p>
</div>
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_settings}">
<div class="{local_res.css.regattaleaderboard_meta_update}">
<p ui:field="lastScoringUpdateTextDiv" class="{local_res.css.regattaleaderboard_meta_update_text}"></p>
<p ui:field="lastScoringUpdateTimeDiv" class="{local_res.css.regattaleaderboard_meta_update_timestamp}"></p>
</div>
<g:Anchor ui:field="autoRefreshAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_reload}"></g:Anchor>
<g:Anchor ui:field="settingsAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_settings_button}"></g:Anchor>
</div>
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
<table class="{local_res.css.regattaleaderboard_table}">
<tr class="{local_res.css.regattaleaderboard_header}">
<td>
<g:HTMLPanel ui:field="oldLeaderboardPanel" styleName="{local_res2.css.oldLeaderboardPanel}">
</g:HTMLPanel>
</td>
</tr>
</table>
</div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,16 @@
package com.sap.sailing.gwt.home.client.place.event.oldleaderboard;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
public interface OldLeaderboardResources extends ClientBundle {
public static final OldLeaderboardResources INSTANCE = GWT.create(OldLeaderboardResources.class);
@Source("com/sap/sailing/gwt/home/client/place/event/oldleaderboard/OldLeaderboard.css")
LocalCss css();
public interface LocalCss extends CssResource {
String oldLeaderboardPanel();
}
}
@@ -0,0 +1,5 @@
.oldMultiLeaderboardPanel {
background-color:#f8f8f8;
padding: 0 10px 10px 10px;
width: 100%;
}
@@ -0,0 +1,108 @@
package com.sap.sailing.gwt.home.client.place.event.oldmultileaderboard;
import java.util.Date;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.ParagraphElement;
import com.google.gwt.dom.client.Style.Visibility;
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.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.gwt.home.client.i18n.TextMessages;
import com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources;
import com.sap.sailing.gwt.ui.client.DebugIdHelper;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialog;
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.ui.leaderboard.MultiLeaderboardPanel;
import com.sap.sailing.gwt.ui.leaderboard.ScoringSchemeTypeFormatter;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.player.Timer.PlayModes;
import com.sap.sse.gwt.client.player.Timer.PlayStates;
public class OldMultiLeaderboard extends Composite {
private static OldMultiLeaderboardUiBinder uiBinder = GWT.create(OldMultiLeaderboardUiBinder.class);
interface OldMultiLeaderboardUiBinder extends UiBinder<Widget, OldMultiLeaderboard> {
}
@UiField HTMLPanel oldMultiLeaderboardPanel;
@UiField Anchor settingsAnchor;
@UiField Anchor autoRefreshAnchor;
@UiField ParagraphElement lastScoringUpdateTimeDiv;
@UiField ParagraphElement lastScoringUpdateTextDiv;
@UiField ParagraphElement lastScoringCommentDiv;
@UiField ParagraphElement scoringSchemeDiv;
private MultiLeaderboardPanel multiLeaderboardPanel;
private Timer autoRefreshTimer;
public OldMultiLeaderboard() {
this.multiLeaderboardPanel = null;
EventRegattaLeaderboardResources.INSTANCE.css().ensureInjected();
OldMultiLeaderboardResources.INSTANCE.css().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
}
@UiHandler("autoRefreshAnchor")
void toogleAutoRefreshClicked(ClickEvent event) {
if(autoRefreshTimer != null) {
if (autoRefreshTimer.getPlayState() == PlayStates.Playing) {
autoRefreshTimer.pause();
autoRefreshAnchor.getElement().getStyle().setBackgroundColor("#f0ab00");
} else {
// playing the standalone leaderboard means putting it into live mode
autoRefreshTimer.setPlayMode(PlayModes.Live);
autoRefreshAnchor.getElement().getStyle().setBackgroundColor("red");
}
}
}
@UiHandler("settingsAnchor")
void settingsClicked(ClickEvent event) {
if(multiLeaderboardPanel != null) {
final String componentName = multiLeaderboardPanel.getLocalizedShortName();
final String debugIdPrefix = DebugIdHelper.createDebugId(componentName);
SettingsDialog<LeaderboardSettings> dialog = new SettingsDialog<LeaderboardSettings>(multiLeaderboardPanel,
StringMessages.INSTANCE);
dialog.ensureDebugId(debugIdPrefix + "SettingsDialog");
dialog.show();
}
}
public void setMultiLeaderboard(MultiLeaderboardPanel multiLeaderboardPanel, final Timer timer) {
this.autoRefreshTimer = timer;
this.multiLeaderboardPanel = multiLeaderboardPanel;
oldMultiLeaderboardPanel.add(multiLeaderboardPanel);
}
public void updatedMultiLeaderboard(LeaderboardDTO leaderboard, boolean hasLiveRace) {
if(leaderboard != null) {
lastScoringCommentDiv.setInnerText(leaderboard.getComment() != null ? leaderboard.getComment() : "");
scoringSchemeDiv.setInnerText(leaderboard.scoringScheme != null ? ScoringSchemeTypeFormatter.format(leaderboard.scoringScheme, StringMessages.INSTANCE) : "");
if (leaderboard.getTimePointOfLastCorrectionsValidity() != null) {
Date lastCorrectionDate = leaderboard.getTimePointOfLastCorrectionsValidity();
String lastUpdate = DateAndTimeFormatterUtil.defaultDateFormatter.render(lastCorrectionDate) + ", "
+ DateAndTimeFormatterUtil.longTimeFormatter.render(lastCorrectionDate);
lastScoringUpdateTimeDiv.setInnerText(lastUpdate);
lastScoringUpdateTextDiv.setInnerText(TextMessages.INSTANCE.eventRegattaLeaderboardLastScoreUpdate());
} else {
lastScoringUpdateTimeDiv.setInnerText("");
lastScoringUpdateTextDiv.setInnerText("");
}
lastScoringUpdateTimeDiv.getStyle().setVisibility(!hasLiveRace ? Visibility.VISIBLE : Visibility.HIDDEN);
}
}
}
@@ -0,0 +1,37 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.place.event"
xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.leaderboard"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="i18n" type="com.sap.sailing.gwt.home.client.i18n.TextMessages"/>
<ui:with field="res" type="com.sap.sailing.gwt.home.client.HomeResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
<ui:with field="local_res2" type="com.sap.sailing.gwt.home.client.place.event.oldmultileaderboard.OldMultiLeaderboardResources" />
<g:HTMLPanel>
<div class="{res.mainCss.grid}">
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
<p ui:field="lastScoringCommentDiv" class="{local_res.css.regattaleaderboard_meta_scoring_comment}"></p>
<p ui:field="scoringSchemeDiv" class="{local_res.css.regattaleaderboard_meta_scoring_type}"></p>
</div>
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_settings}">
<div class="{local_res.css.regattaleaderboard_meta_update}">
<p ui:field="lastScoringUpdateTextDiv" class="{local_res.css.regattaleaderboard_meta_update_text}"></p>
<p ui:field="lastScoringUpdateTimeDiv" class="{local_res.css.regattaleaderboard_meta_update_timestamp}"></p>
</div>
<g:Anchor ui:field="autoRefreshAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_reload}"></g:Anchor>
<g:Anchor ui:field="settingsAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_settings_button}"></g:Anchor>
</div>
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
<table class="{local_res.css.regattaleaderboard_table}">
<tr class="{local_res.css.regattaleaderboard_header}">
<td>
<g:HTMLPanel ui:field="oldMultiLeaderboardPanel" styleName="{local_res2.css.oldMultiLeaderboardPanel}">
</g:HTMLPanel>
</td>
</tr>
</table>
</div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,16 @@
package com.sap.sailing.gwt.home.client.place.event.oldmultileaderboard;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
public interface OldMultiLeaderboardResources extends ClientBundle {
public static final OldMultiLeaderboardResources INSTANCE = GWT.create(OldMultiLeaderboardResources.class);
@Source("com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.css")
LocalCss css();
public interface LocalCss extends CssResource {
String oldMultiLeaderboardPanel();
}
}
@@ -39,7 +39,6 @@ public class Regatta extends Composite {
private final EventDTO event;
private final Timer timerForClientServerOffset;
private final EventPageNavigator pageNavigator;
@SuppressWarnings("unused")
private final PlaceNavigator placeNavigator;
private StrippedLeaderboardDTO leaderboard;
private RaceGroupDTO raceGroup;
@@ -163,10 +162,7 @@ public class Regatta extends Composite {
public void onBrowserEvent(Event browserEvent) {
switch (DOM.eventGetType(browserEvent)) {
case Event.ONCLICK:
pageNavigator.openLeaderboardViewer(leaderboardGroup, leaderboard);
// the new leaderboard view integrated into the new design
//placeNavigator.goToLeaderboard(event.id.toString(), leaderboard.name, event.getBaseURL(), event.isOnRemoteServer());
placeNavigator.goToLeaderboard(event.id.toString(), leaderboard.name, event.getBaseURL(), event.isOnRemoteServer());
break;
}
}
@@ -0,0 +1,5 @@
.oldLeaderboardPanel {
background-color:#f8f8f8;
padding: 0 10px 10px 10px;
width: 100%;
}
@@ -0,0 +1,167 @@
package com.sap.sailing.gwt.home.client.place.event.regattaanalytics;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.SpanElement;
import com.google.gwt.dom.client.Style.Visibility;
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.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.dto.FleetDTO;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
import com.sap.sailing.gwt.home.client.HomeResources;
import com.sap.sailing.gwt.home.client.app.PlaceNavigator;
import com.sap.sailing.gwt.home.client.place.event.header.CompactEventHeader;
import com.sap.sailing.gwt.home.client.place.event.oldcompetitorcharts.OldCompetitorCharts;
import com.sap.sailing.gwt.home.client.place.event.oldleaderboard.OldLeaderboard;
import com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.useragent.UserAgentDetails;
public class RegattaAnalytics extends Composite implements LeaderboardUpdateListener {
private static RegattaAnalyticsUiBinder uiBinder = GWT.create(RegattaAnalyticsUiBinder.class);
interface RegattaAnalyticsUiBinder extends UiBinder<Widget, RegattaAnalytics> {
}
@UiField OldLeaderboard oldLeaderboardComposite;
@UiField OldCompetitorCharts oldCompetitorChartsComposite;
@UiField(provided=true) CompactEventHeader eventHeader;
@UiField SpanElement title;
@UiField DivElement liveRaceDiv;
@UiField HTMLPanel leaderboardTabPanel;
@UiField HTMLPanel competitorChartsTabPanel;
private HTMLPanel activeTabPanel;
private Anchor activeAnchor;
@UiField Anchor leaderboardAnchor;
@UiField Anchor competitorChartsAnchor;
private RegattaAnalyticsDataManager regattaAnalyticsManager;
private Timer autoRefreshTimer;
public RegattaAnalytics(EventDTO event, String leaderboardName, Timer timerForClientServerOffset, PlaceNavigator placeNavigator) {
eventHeader = new CompactEventHeader(event, leaderboardName, placeNavigator);
EventRegattaLeaderboardResources.INSTANCE.css().ensureInjected();
RegattaAnalyticsResources.INSTANCE.css().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
title.setInnerText(leaderboardName);
activeAnchor = leaderboardAnchor;
activeTabPanel = leaderboardTabPanel;
activeAnchor.addStyleName(HomeResources.INSTANCE.mainCss().navbar_buttonactive());
competitorChartsTabPanel.setVisible(false);
liveRaceDiv.getStyle().setVisibility(Visibility.HIDDEN);
}
public void createRegattaAnalyticsViewer(final SailingServiceAsync sailingService, final AsyncActionsExecutor asyncActionsExecutor,
final Timer timer, final LeaderboardSettings leaderboardSettings, final RaceIdentifier preselectedRace,
final String leaderboardGroupName, String leaderboardName, final ErrorReporter errorReporter,
final UserAgentDetails userAgent, boolean showRaceDetails,
boolean autoExpandLastRaceColumn, boolean showOverallLeaderboard) {
this.autoRefreshTimer = timer;
regattaAnalyticsManager = new RegattaAnalyticsDataManager(sailingService, asyncActionsExecutor, timer, errorReporter, userAgent);
regattaAnalyticsManager.createLeaderboardPanel(leaderboardSettings, preselectedRace, leaderboardGroupName,
leaderboardName, showRaceDetails, autoExpandLastRaceColumn);
List<DetailType> availableDetailsTypes = new ArrayList<DetailType>();
DetailType initialDetailType = DetailType.REGATTA_RANK;
availableDetailsTypes.add(DetailType.REGATTA_RANK);
availableDetailsTypes.add(DetailType.REGATTA_TOTAL_POINTS_SUM);
regattaAnalyticsManager.createMultiCompetitorChart(leaderboardName, initialDetailType);
oldLeaderboardComposite.setLeaderboard(regattaAnalyticsManager.getLeaderboardPanel(), autoRefreshTimer);
regattaAnalyticsManager.getLeaderboardPanel().addLeaderboardUpdateListener(this);
oldCompetitorChartsComposite.setChart(regattaAnalyticsManager.getMultiCompetitorChart(), availableDetailsTypes, initialDetailType);
regattaAnalyticsManager.hideCompetitorChart();
}
@Override
public void updatedLeaderboard(LeaderboardDTO leaderboard) {
if(activeTabPanel == leaderboardTabPanel) {
StringMessages stringMessages = StringMessages.INSTANCE;
if(leaderboard != null) {
List<Pair<RaceColumnDTO, FleetDTO>> liveRaces = leaderboard.getLiveRaces(autoRefreshTimer.getLiveTimePointInMillis());
boolean hasLiveRace = !liveRaces.isEmpty();
if (hasLiveRace) {
String liveRaceText = "";
if(liveRaces.size() == 1) {
Pair<RaceColumnDTO, FleetDTO> liveRace = liveRaces.get(0);
liveRaceText = stringMessages.raceIsLive("'" + liveRace.getA().getRaceColumnName() + "'");
} else {
String raceNames = "";
for (Pair<RaceColumnDTO, FleetDTO> liveRace : liveRaces) {
raceNames += "'" + liveRace.getA().getRaceColumnName() + "', ";
}
// remove last ", "
raceNames = raceNames.substring(0, raceNames.length() - 2);
liveRaceText = stringMessages.racesAreLive(raceNames);
}
liveRaceDiv.setInnerText(liveRaceText);
} else {
liveRaceDiv.setInnerText("");
}
liveRaceDiv.getStyle().setVisibility(hasLiveRace ? Visibility.VISIBLE : Visibility.HIDDEN);
oldLeaderboardComposite.updatedLeaderboard(leaderboard, hasLiveRace);
}
}
}
@Override
public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) {
}
@UiHandler("leaderboardAnchor")
void leaderboardTabClicked(ClickEvent event) {
setActiveTabPanel(leaderboardTabPanel, leaderboardAnchor);
regattaAnalyticsManager.hideCompetitorChart();
}
@UiHandler("competitorChartsAnchor")
void competitorChartsTabClicked(ClickEvent event) {
setActiveTabPanel(competitorChartsTabPanel, competitorChartsAnchor);
DetailType selectedChartDetailType = oldCompetitorChartsComposite.getSelectedChartDetailType();
regattaAnalyticsManager.showCompetitorChart(selectedChartDetailType);
}
private void setActiveTabPanel(HTMLPanel newActivePanel, Anchor newActiveAnchor) {
if(activeTabPanel != null) {
activeTabPanel.setVisible(false);
activeAnchor.removeStyleName(HomeResources.INSTANCE.mainCss().navbar_buttonactive());
}
activeTabPanel = newActivePanel;
activeAnchor = newActiveAnchor;
activeTabPanel.setVisible(true);
activeAnchor.addStyleName(HomeResources.INSTANCE.mainCss().navbar_buttonactive());
}
}
@@ -0,0 +1,34 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.place.event"
xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.leaderboard"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="i18n" type="com.sap.sailing.gwt.home.client.i18n.TextMessages"/>
<ui:with field="res" type="com.sap.sailing.gwt.home.client.HomeResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
<ui:with field="local_res2" type="com.sap.sailing.gwt.home.client.place.event.regattaanalytics.RegattaAnalyticsResources" />
<g:HTMLPanel>
<s:header.CompactEventHeader ui:field='eventHeader'/>
<div class="{res.mainCss.grid} {local_res.css.regattaleaderboard}">
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {local_res.css.regattaleaderboard_meta}">
<h3 class="{local_res.css.regattaleaderboard_meta_title}">
<span style="color:darkgrey;"><ui:text from='{i18n.regatta}'/></span>
<span ui:field="title"></span>
</h3>
<div ui:field="liveRaceDiv" class="{res.mainCss.label} {local_res.css.regattaleaderboard_meta_status} {local_res.css.regattaleaderboard_meta_statuslive}">
<ui:text from='{i18n.live}'/>
</div>
</div>
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {local_res.css.regattaleaderboard_meta_navigation}">
<g:Anchor ui:field="leaderboardAnchor" href="javascript:;" styleName="{res.mainCss.navbar_button}"><ui:text from="{i18n.leaderboard}" /></g:Anchor>
<g:Anchor ui:field="competitorChartsAnchor" href="javascript:;" styleName="{res.mainCss.navbar_button}"><ui:text from="{i18n.competitorsAnalytics}" /></g:Anchor>
</div>
</div>
<g:HTMLPanel ui:field="leaderboardTabPanel">
<s:oldleaderboard.OldLeaderboard ui:field='oldLeaderboardComposite'/>
</g:HTMLPanel>
<g:HTMLPanel ui:field="competitorChartsTabPanel">
<s:oldcompetitorcharts.OldCompetitorCharts ui:field='oldCompetitorChartsComposite'/>
</g:HTMLPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,106 @@
package com.sap.sailing.gwt.home.client.place.event.regattaanalytics;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
import com.sap.sailing.gwt.ui.client.DebugIdHelper;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardChart;
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardChartSettings;
import com.sap.sailing.gwt.ui.client.shared.components.Component;
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialog;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.useragent.UserAgentDetails;
/**
* A class managing analytical data on the regatta level (like leaderboard, regatta rank, etc.)
*
* @author Frank Mittag (c163874)
*/
public class RegattaAnalyticsDataManager {
private LeaderboardPanel leaderboardPanel;
private MultiCompetitorLeaderboardChart multiCompetitorChart;
private final CompetitorSelectionModel competitorSelectionProvider;
private final AsyncActionsExecutor asyncActionsExecutor;
private final ErrorReporter errorReporter;
private final UserAgentDetails userAgent;
private final SailingServiceAsync sailingService;
private final Timer timer;
public RegattaAnalyticsDataManager(final SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, Timer timer, ErrorReporter errorReporter, UserAgentDetails userAgent) {
this.competitorSelectionProvider = new CompetitorSelectionModel(/* hasMultiSelection */true);
this.sailingService = sailingService;
this.asyncActionsExecutor = asyncActionsExecutor;
this.timer = timer;
this.errorReporter = errorReporter;
this.userAgent = userAgent;
this.leaderboardPanel = null;
this.multiCompetitorChart = null;
}
public LeaderboardPanel createLeaderboardPanel(final LeaderboardSettings leaderboardSettings, final RaceIdentifier preselectedRace,
final String leaderboardGroupName, String leaderboardName, boolean showRaceDetails,
boolean autoExpandLastRaceColumn) {
if(leaderboardPanel == null) {
leaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor, leaderboardSettings, true, preselectedRace,
competitorSelectionProvider, timer, leaderboardGroupName, leaderboardName, errorReporter,
StringMessages.INSTANCE, userAgent, showRaceDetails, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, /* raceTimesInfoProvider */null, autoExpandLastRaceColumn, /* adjustTimerDelay */
true, false, false);
}
return leaderboardPanel;
}
public MultiCompetitorLeaderboardChart createMultiCompetitorChart(String leaderboardName, DetailType chartDetailType) {
if(multiCompetitorChart == null) {
multiCompetitorChart = new MultiCompetitorLeaderboardChart(sailingService, asyncActionsExecutor, leaderboardName, chartDetailType,
competitorSelectionProvider, timer, StringMessages.INSTANCE, errorReporter);
multiCompetitorChart.setVisible(false);
}
return multiCompetitorChart;
}
public LeaderboardPanel getLeaderboardPanel() {
return leaderboardPanel;
}
public MultiCompetitorLeaderboardChart getMultiCompetitorChart() {
return multiCompetitorChart;
}
public void showCompetitorChart(DetailType chartDetailType) {
MultiCompetitorLeaderboardChart multiCompetitorChart = getMultiCompetitorChart();
MultiCompetitorLeaderboardChartSettings settings = new MultiCompetitorLeaderboardChartSettings(chartDetailType);
multiCompetitorChart.updateSettings(settings);
multiCompetitorChart.setVisible(true);
timer.addTimeListener(multiCompetitorChart);
multiCompetitorChart.timeChanged(timer.getTime(), null);
}
public void hideCompetitorChart() {
MultiCompetitorLeaderboardChart multiCompetitorChart = getMultiCompetitorChart();
multiCompetitorChart.setVisible(false);
timer.removeTimeListener(multiCompetitorChart);
}
public void showLeaderboardSettingsDialog() {
showComponentSettingsDialog(leaderboardPanel, null);
}
public void showChartSettingsDialog() {
showComponentSettingsDialog(multiCompetitorChart, null);
}
protected <SettingsType> void showComponentSettingsDialog(final Component<SettingsType> component, String componentDisplayName) {
String componentName = componentDisplayName != null ? componentDisplayName : component.getLocalizedShortName();
String debugIdPrefix = DebugIdHelper.createDebugId(componentName);
SettingsDialog<SettingsType> dialog = new SettingsDialog<SettingsType>(component, StringMessages.INSTANCE);
dialog.ensureDebugId(debugIdPrefix + "SettingsDialog");
dialog.show();
}
}
@@ -0,0 +1,16 @@
package com.sap.sailing.gwt.home.client.place.event.regattaanalytics;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
public interface RegattaAnalyticsResources extends ClientBundle {
public static final RegattaAnalyticsResources INSTANCE = GWT.create(RegattaAnalyticsResources.class);
@Source("com/sap/sailing/gwt/home/client/place/event/regattaanalytics/RegattaAnalytics.css")
LocalCss css();
public interface LocalCss extends CssResource {
String oldLeaderboardPanel();
}
}
@@ -37,56 +37,83 @@
.leaderboardcompetitor_itemcenter {
text-align: center;
}
.eventregattaleaderboard_table {
padding: 0 1rem;
}
.eventregattaleaderboard {
.regattaleaderboard {
font-size: 15px;
font-size: 1rem;
width: 100%;
}
.eventregattaleaderboard_meta {
margin: 2.333333333333333em auto;
.regattaleaderboard_meta {
margin: 1.333333333333333em auto;
}
.eventregattaleaderboard_meta_title {
.regattaleaderboard_meta_title {
display: inline-block;
margin-bottom: 0;
}
.eventregattaleaderboard_meta_update {
font-weight: 600;
color: #999;
.regattaleaderboard_meta_status {
position: absolute;
top: 0.636363636363636em;
}
.eventregattaleaderboard_meta_button {
float: right;
.regattaleaderboard_meta_statuslive {
display: inline-block;
margin-left: 0.666666666666667em;
background: #e94a1b;
color: #f6f9fc;
}
.regattaleaderboard_meta_navigation {
padding-top: 1em;
padding-bottom: 1em;
border-bottom: 1px solid #ddd;
}
.regattaleaderboard_meta_scoring,
.regattaleaderboard_meta_update {
margin-top: 1em;
}
.eventregattaleaderboard_meta_reload {
float: right;
width: 39px;
height: 39px;
margin: 0 0 10px 0;
background-color: #f0ab00;
background-image: url("images/home/reload.png");
.regattaleaderboard_meta_scoring_comment,
.regattaleaderboard_meta_update_comment,
.regattaleaderboard_meta_scoring_type,
.regattaleaderboard_meta_update_type,
.regattaleaderboard_meta_scoring_timestamp,
.regattaleaderboard_meta_update_timestamp,
.regattaleaderboard_meta_scoring_text,
.regattaleaderboard_meta_update_text {
margin: 0;
}
.regattaleaderboard_meta_update {
display: inline-block;
text-align: right;
}
.regattaleaderboard_meta_reload,
.regattaleaderboard_meta_settings_button {
display: inline-block;
width: 2.666666666666667em;
height: 2.666666666666667em;
margin: 0 0 0 0.666666666666667em;
background-repeat: no-repeat;
background-position: center center;
}
.eventregattaleaderboard_meta_reload:hover {
background-color: #d89a00;
.regattaleaderboard_meta_reload {
background-color: #8ab54e;
background-image: url("images/home/reload.png");
}
.eventregattaleaderboard_meta_settings {
float: right;
width: 39px;
height: 39px;
margin: 0 0 10px 0;
.regattaleaderboard_meta_reload:hover {
background-color: #7ca445;
}
.regattaleaderboard_meta_settings {
display: inline-block;
text-align: right;
}
.regattaleaderboard_meta_settings_button {
width: 2.666666666666667em;
height: 2.666666666666667em;
margin: 0 0 0 0.666666666666667em;
background-color: #f0ab00;
background-image: url("images/home/settings.png");
background-repeat: no-repeat;
background-position: center center;
background-size: 50%;
}
.eventregattaleaderboard_meta_settings:hover {
background-color: #d89a00;
.regattaleaderboard_table {
margin-top: 0.666666666666667em;
}
.eventregattaleaderboard_header {
.regattaleaderboard_header {
background: #f2f2f2;
color: #008fcc;
text-transform: uppercase;
@@ -95,72 +122,72 @@
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
.eventregattaleaderboard_header_item {
.regattaleaderboard_header_item {
margin: 0;
padding: 2.333333333333333em 0 2.333333333333333em 1.666666666666667em;
font-weight: 600;
}
.eventregattaleaderboard_header_itemrank {
.regattaleaderboard_header_itemrank {
min-width: 12rem;
text-align: center;
}
.eventregattaleaderboard_header_itemcompetitor {
.regattaleaderboard_header_itemcompetitor {
min-width: 16rem;
}
.eventregattaleaderboard_header_itemname {
.regattaleaderboard_header_itemname {
min-width: 16rem;
}
.eventregattaleaderboard_header_itemdata {
.regattaleaderboard_header_itemdata {
min-width: 24rem;
}
.eventregattaleaderboard_header_itemdata_element,
.eventregattaleaderboard_header_itemdata_elementascending,
.eventregattaleaderboard_header_itemdata_elementdescending {
width: 50px;
.regattaleaderboard_header_itemdata_element,
.regattaleaderboard_header_itemdata_elementascending,
.regattaleaderboard_header_itemdata_elementdescending {
width: 3.333333333333333em;
text-align: right;
}
.eventregattaleaderboard_header_itempoints {
.regattaleaderboard_header_itempoints {
min-width: 12rem;
text-align: center;
}
.eventregattaleaderboard_header_item_name,
.eventregattaleaderboard_header_itemdata_element_name {
.regattaleaderboard_header_item_name,
.regattaleaderboard_header_itemdata_element_name {
display: inline-block;
}
.eventregattaleaderboard_header_itemdescending:before,
.eventregattaleaderboard_header_itemdata_elementdescending:before {
.regattaleaderboard_header_itemdescending:before,
.regattaleaderboard_header_itemdata_elementdescending:before {
content: '';
display: inline-block;
width: 12px;
height: 12px;
line-height: 20px;
margin-right: 5px;
width: 0.8em;
height: 0.8em;
line-height: 1.333333333333333em;
margin-right: 0.333333333333333em;
background-repeat: no-repeat;
background-position: center center;
background-image: url("images/home/arrow-down-yellow.png");
}
.eventregattaleaderboard_header_itemascending:before,
.eventregattaleaderboard_header_itemdata_elementascending:before {
.regattaleaderboard_header_itemascending:before,
.regattaleaderboard_header_itemdata_elementascending:before {
content: '';
display: inline-block;
width: 12px;
height: 12px;
line-height: 20px;
margin-right: 5px;
width: 0.8em;
height: 0.8em;
line-height: 1.333333333333333em;
margin-right: 0.333333333333333em;
background-repeat: no-repeat;
background-position: center center;
background-image: url("images/home/arrow-up-yellow.png");
}
.eventregattaleaderboard_header_table {
.regattaleaderboard_header_table {
width: 100%;
table-layout: fixed;
}
.eventregattaleaderboard_body {
.regattaleaderboard_body {
width: 100%;
max-width: 100%;
}
.eventregattaleaderboard_data_element {
width: 50px;
.regattaleaderboard_data_element {
width: 3.333333333333333em;
text-align: right;
}
.leaderboardcompetitor:last-child {
@@ -8,29 +8,40 @@
<g:HTMLPanel>
<!-- The leaderboard of races of a regatta-->
<div class="{res.mediaCss.grid} {local_res.css.eventregattaleaderboard_meta}">
<div class="{res.mediaCss.small6} {res.mediaCss.columns}">
<h3 class="{local_res.css.eventregattaleaderboard_meta_title}">{leaderboard.scoringComment}{#if navigation.isFinished}{/if navigation.isFinished}
</h3>
<div class="{local_res.css.eventregattaleaderboard_meta_update}"><ui:text from='{i18n.eventRegattaLeaderboardLastScoreUpdate}'/>: &nbsp; {leaderboard.lastScoringUpdate}</div>
<div class="{res.mediaCss.grid} {local_res.css.regattaleaderboard}">
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {local_res.css.regattaleaderboard_meta}">
<header>
<h3 class="{local_res.css.regattaleaderboard_meta_title}"></h3>{#if navigation.isLive}
<div class="{res.mainCss.label} {local_res.css.regattaleaderboard_meta_status} {local_res.css.regattaleaderboard_meta_statuslive}"><ui:text from='{i18n.live}'/></div>{/if navigation.isLive}
</header>
</div>
<div class="{res.mediaCss.small6} {res.mediaCss.columns}"><a href="#" class="{local_res.css.eventregattaleaderboard_meta_reload}"></a><a href="#" class="{res.mainCss.button} {local_res.css.eventregattaleaderboard_meta_button}"><ui:text from='{i18n.eventRegattaLeaderboardExtendLeaderboard}'/></a></div>
</div>
<div class="{res.mediaCss.grid} {local_res.css.eventregattaleaderboard_table}">
<table class="{local_res.css.eventregattaleaderboard}">
<tr class="{local_res.css.eventregattaleaderboard_header}">
<td class="{local_res.css.eventregattaleaderboard_header_item} {local_res.css.eventregattaleaderboard_header_itemrank} {local_res.css.eventregattaleaderboard_header_itemascending}"><a href="#" class="{local_res.css.eventregattaleaderboard_header_item_name}"><ui:text from='{i18n.eventRegattaLeaderboardRegattaRank}'/></a></td>
<td class="{local_res.css.eventregattaleaderboard_header_item} {local_res.css.eventregattaleaderboard_header_itemcompetitor} {local_res.css.eventregattaleaderboard_header_itemdescending}"><a href="#" class="{local_res.css.eventregattaleaderboard_header_item_name}"><ui:text from='{i18n.eventRegattaLeaderboardCompetitor}'/></a></td>
<td class="{local_res.css.eventregattaleaderboard_header_item} {local_res.css.eventregattaleaderboard_header_itemname}"><a href="#" class="{local_res.css.eventregattaleaderboard_header_item_name}"><ui:text from='{i18n.eventRegattaLeaderboardName}'/></a></td>
<td class="{local_res.css.eventregattaleaderboard_header_item} {local_res.css.eventregattaleaderboard_header_itemdata}">
<table class="{local_res.css.eventregattaleaderboard_header_table}">
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {local_res.css.regattaleaderboard_meta_navigation}"><a href="#" class="{res.mainCss.navbar_button} {res.mainCss.navbar_buttonactive}"><ui:text from='{i18n.leaderBoard}'/></a><a href="#" class="{res.mainCss.navbar_button}"><ui:text from='{i18n.eventRegattaLeaderboardRegattaRank}'/></a><a href="#" class="{res.mainCss.navbar_button}"><ui:text from='{i18n.eventRegattaLeaderboardTotalPoints}'/></a></div>
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
<p class="{local_res.css.regattaleaderboard_meta_scoring_comment}">{leaderboard.scoringComment}</p>
<p class="{local_res.css.regattaleaderboard_meta_scoring_type}"></p>
</div>
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_settings}">
<div class="{local_res.css.regattaleaderboard_meta_update}">
<p class="{local_res.css.regattaleaderboard_meta_update_text}"><ui:text from='{i18n.eventRegattaLeaderboardLastScoreUpdate}'/></p>
<p class="{local_res.css.regattaleaderboard_meta_update_timestamp}">{leaderboard.lastScoringUpdate}</p>
</div><a href="#" class="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_reload}"></a><a href="#" class="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_settings_button}"></a>
</div>
<div class="{res.mediaCss.small12} {res.mediaCss.column}">
<table class="{local_res.css.regattaleaderboard_table}">
<tr class="{local_res.css.regattaleaderboard_header}">
<td class="{local_res.css.regattaleaderboard_header_item} {local_res.css.regattaleaderboard_header_itemrank} {local_res.css.regattaleaderboard_header_itemascending}"><a href="#" class="{local_res.css.regattaleaderboard_header_item_name}"><ui:text from='{i18n.eventRegattaLeaderboardRegattaRank}'/></a></td>
<td class="{local_res.css.regattaleaderboard_header_item} {local_res.css.regattaleaderboard_header_itemcompetitor} {local_res.css.regattaleaderboard_header_itemdescending}"><a href="#" class="{local_res.css.regattaleaderboard_header_item_name}"><ui:text from='{i18n.eventRegattaLeaderboardCompetitor}'/></a></td>
<td class="{local_res.css.regattaleaderboard_header_item} {local_res.css.regattaleaderboard_header_itemname}"><a href="#" class="{local_res.css.regattaleaderboard_header_item_name}"><ui:text from='{i18n.eventRegattaLeaderboardName}'/></a></td>
<td class="{local_res.css.regattaleaderboard_header_item} {local_res.css.regattaleaderboard_header_itemdata}">
<table class="{local_res.css.regattaleaderboard_header_table}">
<tr>{#each columnName in leaderboard.columnNames}<s:eventRegattaLeaderboard.RegattaLeaderboardHeaderColumn ui:field='columnName'></s>{/each leaderboard.columnNames}
</tr>
</table>
</td>
<td class="{local_res.css.eventregattaleaderboard_header_item} {local_res.css.eventregattaleaderboard_header_itempoints}"><a href="#" class="{local_res.css.eventregattaleaderboard_header_item_name}"><ui:text from='{i18n.eventRegattaLeaderboardTotalPoints}'/></a></td>
<td class="{local_res.css.regattaleaderboard_header_item} {local_res.css.regattaleaderboard_header_itempoints}"><a href="#" class="{local_res.css.regattaleaderboard_header_item_name}"><ui:text from='{i18n.eventRegattaLeaderboardTotalPoints}'/></a></td>
</tr>{#each competitor in leaderboard.competitors}<s:eventRegattaLeaderboard.RegattaLeaderboardCompetitor ui:field='competitor'></s>{/each leaderboard.competitors}
</table>
</div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -16,31 +16,43 @@ public interface EventRegattaLeaderboardResources extends ClientBundle {
String leaderboardcompetitor_image();
String leaderboardcompetitor_nationality();
String leaderboardcompetitor_itemcenter();
String eventregattaleaderboard_table();
String eventregattaleaderboard();
String eventregattaleaderboard_meta();
String eventregattaleaderboard_meta_title();
String eventregattaleaderboard_meta_update();
String eventregattaleaderboard_meta_button();
String eventregattaleaderboard_meta_reload();
String eventregattaleaderboard_meta_settings();
String eventregattaleaderboard_header();
String eventregattaleaderboard_header_item();
String eventregattaleaderboard_header_itemrank();
String eventregattaleaderboard_header_itemcompetitor();
String eventregattaleaderboard_header_itemname();
String eventregattaleaderboard_header_itemdata();
String eventregattaleaderboard_header_itemdata_element();
String eventregattaleaderboard_header_itemdata_elementascending();
String eventregattaleaderboard_header_itemdata_elementdescending();
String eventregattaleaderboard_header_itempoints();
String eventregattaleaderboard_header_item_name();
String eventregattaleaderboard_header_itemdata_element_name();
String eventregattaleaderboard_header_itemdescending();
String eventregattaleaderboard_header_itemascending();
String eventregattaleaderboard_header_table();
String eventregattaleaderboard_body();
String eventregattaleaderboard_data_element();
String regattaleaderboard();
String regattaleaderboard_meta();
String regattaleaderboard_meta_title();
String regattaleaderboard_meta_status();
String regattaleaderboard_meta_statuslive();
String regattaleaderboard_meta_navigation();
String regattaleaderboard_meta_scoring();
String regattaleaderboard_meta_update();
String regattaleaderboard_meta_scoring_comment();
String regattaleaderboard_meta_update_comment();
String regattaleaderboard_meta_scoring_type();
String regattaleaderboard_meta_update_type();
String regattaleaderboard_meta_scoring_timestamp();
String regattaleaderboard_meta_update_timestamp();
String regattaleaderboard_meta_scoring_text();
String regattaleaderboard_meta_update_text();
String regattaleaderboard_meta_reload();
String regattaleaderboard_meta_settings_button();
String regattaleaderboard_meta_settings();
String regattaleaderboard_table();
String regattaleaderboard_header();
String regattaleaderboard_header_item();
String regattaleaderboard_header_itemrank();
String regattaleaderboard_header_itemcompetitor();
String regattaleaderboard_header_itemname();
String regattaleaderboard_header_itemdata();
String regattaleaderboard_header_itemdata_element();
String regattaleaderboard_header_itemdata_elementascending();
String regattaleaderboard_header_itemdata_elementdescending();
String regattaleaderboard_header_itempoints();
String regattaleaderboard_header_item_name();
String regattaleaderboard_header_itemdata_element_name();
String regattaleaderboard_header_itemdescending();
String regattaleaderboard_header_itemascending();
String regattaleaderboard_header_table();
String regattaleaderboard_body();
String regattaleaderboard_data_element();
String leaderboardcompetitor_item();
String leaderboardcompetitor_itemcentercenter();
String leaderboardcompetitor_item_table();
@@ -46,6 +46,7 @@ public class EventRegattaList extends AbstractEventComposite {
@UiField SpanElement allBoatClassesSelected;
private final Map<String, List<Regatta>> regattaElementsByLeaderboardGroup;
private final List<AnchorElement> leaderboardGroupFilterAnchors;
public EventRegattaList(EventDTO event, Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> regattaStructure,
Timer timerForClientServerOffset, PlaceNavigator placeNavigator, EventPageNavigator pageNavigator) {
@@ -55,7 +56,7 @@ public class EventRegattaList extends AbstractEventComposite {
initWidget(uiBinder.createAndBindUi(this));
regattaElementsByLeaderboardGroup = new HashMap<>();
leaderboardGroupFilterAnchors = new ArrayList<AnchorElement>();
boolean isSeries = event.isFakeSeries();
boolean hasMultipleLeaderboardGroups = event.getLeaderboardGroups().size() > 1;
@@ -73,6 +74,7 @@ public class EventRegattaList extends AbstractEventComposite {
String leaderboardGroupName = LongNamesUtil.shortenLeaderboardGroupName(event.getName(), leaderboardGroup.getName());
filterLeaderboardGroupAnchor.setInnerText(leaderboardGroupName);
regattaGroupsNavigationPanel.appendChild(filterLeaderboardGroupAnchor);
leaderboardGroupFilterAnchors.add(filterLeaderboardGroupAnchor);
registerFilterLeaderboardGroupEvent(filterLeaderboardGroupAnchor, leaderboardGroup);
}
@@ -99,7 +101,7 @@ public class EventRegattaList extends AbstractEventComposite {
}
}
private void registerFilterLeaderboardGroupEvent(AnchorElement filterLeaderboardGroupAnchor, final LeaderboardGroupDTO leaderboardGroup) {
private void registerFilterLeaderboardGroupEvent(final AnchorElement filterLeaderboardGroupAnchor, final LeaderboardGroupDTO leaderboardGroup) {
Event.sinkEvents(filterLeaderboardGroupAnchor, Event.ONCLICK);
Event.setEventListener(filterLeaderboardGroupAnchor, new EventListener() {
@Override
@@ -107,6 +109,11 @@ public class EventRegattaList extends AbstractEventComposite {
switch (DOM.eventGetType(event)) {
case Event.ONCLICK:
filterRegattaListByLeaderboardGroup(leaderboardGroup);
for(AnchorElement anchor: leaderboardGroupFilterAnchors) {
anchor.removeClassName(HomeResources.INSTANCE.mainCss().navbar_buttonactive());
}
filterLeaderboardGroupAnchor.addClassName(HomeResources.INSTANCE.mainCss().navbar_buttonactive());
break;
}
}
@@ -116,6 +123,7 @@ public class EventRegattaList extends AbstractEventComposite {
private void filterRegattaListByLeaderboardGroup(LeaderboardGroupDTO leaderboardGroup) {
if (leaderboardGroup != null) {
allBoatClassesSelected.getStyle().setDisplay(Display.NONE);
filterNoLeaderboardGroupsAnchor.removeClassName(HomeResources.INSTANCE.mainCss().navbar_buttonactive());
// hide all regattas of the not selected leaderboardgroup
for (LeaderboardGroupDTO lg : getEvent().getLeaderboardGroups()) {
boolean isVisible = leaderboardGroup.getName().equals(lg.getName());
@@ -127,6 +135,7 @@ public class EventRegattaList extends AbstractEventComposite {
} else {
// make all regattas visible
allBoatClassesSelected.getStyle().setDisplay(Display.INLINE_BLOCK);
filterNoLeaderboardGroupsAnchor.addClassName(HomeResources.INSTANCE.mainCss().navbar_buttonactive());
for (LeaderboardGroupDTO lg : getEvent().getLeaderboardGroups()) {
List<Regatta> regattaElements = regattaElementsByLeaderboardGroup.get(lg.getName());
for (Regatta regatta : regattaElements) {
@@ -0,0 +1,11 @@
.oldLeaderboardPanel {
background-color:#f8f8f8;
padding: 0 10px 10px 10px;
width: 100%;
}
.oldMultiLeaderboardPanel {
background-color:#f8f8f8;
padding: 0 10px 10px 10px;
width: 100%;
}
@@ -0,0 +1,196 @@
package com.sap.sailing.gwt.home.client.place.event.seriesanalytics;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.SpanElement;
import com.google.gwt.dom.client.Style.Visibility;
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.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.dto.FleetDTO;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
import com.sap.sailing.gwt.home.client.HomeResources;
import com.sap.sailing.gwt.home.client.app.PlaceNavigator;
import com.sap.sailing.gwt.home.client.place.event.header.CompactEventHeader;
import com.sap.sailing.gwt.home.client.place.event.oldcompetitorcharts.OldCompetitorCharts;
import com.sap.sailing.gwt.home.client.place.event.oldleaderboard.OldLeaderboard;
import com.sap.sailing.gwt.home.client.place.event.oldmultileaderboard.OldMultiLeaderboard;
import com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.useragent.UserAgentDetails;
public class EventSeriesAnalytics extends Composite implements LeaderboardUpdateListener {
private static EventSeriesAnalyticsUiBinder uiBinder = GWT.create(EventSeriesAnalyticsUiBinder.class);
interface EventSeriesAnalyticsUiBinder extends UiBinder<Widget, EventSeriesAnalytics> {
}
@UiField OldLeaderboard oldOverallLeaderboardComposite;
@UiField OldCompetitorCharts oldCompetitorChartsComposite;
@UiField OldMultiLeaderboard oldRegattaLeaderboardsComposite;
@UiField(provided=true) CompactEventHeader eventHeader;
@UiField SpanElement title;
@UiField DivElement liveRaceDiv;
@UiField HTMLPanel overallLeaderboardTabPanel;
@UiField HTMLPanel regattaLeaderboardsTabPanel;
@UiField HTMLPanel competitorChartsTabPanel;
private HTMLPanel activeTabPanel;
private Widget activeContentWidget;
private Anchor activeAnchor;
@UiField Anchor overallLeaderboardAnchor;
@UiField Anchor regattaLeaderboardsAnchor;
@UiField Anchor competitorChartsAnchor;
private EventSeriesAnalyticsDataManager eventSeriesAnalyticsManager;
private Timer autoRefreshTimer;
public EventSeriesAnalytics(EventDTO event, String leaderboardName, Timer timerForClientServerOffset, PlaceNavigator placeNavigator) {
eventHeader = new CompactEventHeader(event, leaderboardName, placeNavigator);
EventRegattaLeaderboardResources.INSTANCE.css().ensureInjected();
EventSeriesAnalyticsResources.INSTANCE.css().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
String seriesTitle = leaderboardName;
if(seriesTitle.endsWith(LeaderboardNameConstants.OVERALL)) {
seriesTitle = seriesTitle.substring(0, seriesTitle.length() - LeaderboardNameConstants.OVERALL.length());
seriesTitle = seriesTitle.trim();
}
title.setInnerText(seriesTitle);
activeAnchor = overallLeaderboardAnchor;
activeTabPanel = overallLeaderboardTabPanel;
activeContentWidget = null;
activeAnchor.addStyleName(HomeResources.INSTANCE.mainCss().navbar_buttonactive());
regattaLeaderboardsTabPanel.setVisible(false);
competitorChartsTabPanel.setVisible(false);
liveRaceDiv.getStyle().setVisibility(Visibility.HIDDEN);
}
public void createSeriesAnalyticsViewer(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
Timer timer, LeaderboardSettings leaderboardSettings, String preselectedLeaderboardName, RaceIdentifier preselectedRace,
String leaderboardGroupName, String metaLeaderboardName, ErrorReporter errorReporter,
UserAgentDetails userAgent, boolean showRaceDetails,
boolean autoExpandLastRaceColumn, boolean showSeriesLeaderboards) {
this.autoRefreshTimer = timer;
eventSeriesAnalyticsManager = new EventSeriesAnalyticsDataManager(sailingService, asyncActionsExecutor, timer, errorReporter, userAgent);
eventSeriesAnalyticsManager.createOverallLeaderboardPanel(leaderboardSettings, preselectedRace, leaderboardGroupName, metaLeaderboardName, showRaceDetails, autoExpandLastRaceColumn);
eventSeriesAnalyticsManager.createMultiLeaderboardPanel(leaderboardSettings, null /*preSelectedLeaderboardName */, preselectedRace, leaderboardGroupName, metaLeaderboardName, showRaceDetails, autoExpandLastRaceColumn);
DetailType initialDetailType = DetailType.OVERALL_RANK;
List<DetailType> availableDetailsTypes = new ArrayList<DetailType>();
availableDetailsTypes.add(DetailType.OVERALL_RANK);
availableDetailsTypes.add(DetailType.REGATTA_TOTAL_POINTS_SUM);
eventSeriesAnalyticsManager.createMultiCompetitorChart(metaLeaderboardName, DetailType.OVERALL_RANK);
oldOverallLeaderboardComposite.setLeaderboard(eventSeriesAnalyticsManager.getLeaderboardPanel(), timer);
oldRegattaLeaderboardsComposite.setMultiLeaderboard(eventSeriesAnalyticsManager.getMultiLeaderboardPanel(), timer);
oldCompetitorChartsComposite.setChart(eventSeriesAnalyticsManager.getMultiCompetitorChart(), availableDetailsTypes, initialDetailType);
eventSeriesAnalyticsManager.hideCompetitorChart();
eventSeriesAnalyticsManager.getLeaderboardPanel().addLeaderboardUpdateListener(this);
eventSeriesAnalyticsManager.getMultiLeaderboardPanel().addLeaderboardUpdateListener(this);
activeContentWidget = eventSeriesAnalyticsManager.getLeaderboardPanel();
}
@Override
public void updatedLeaderboard(LeaderboardDTO leaderboard) {
if(activeTabPanel == overallLeaderboardTabPanel) {
StringMessages stringMessages = StringMessages.INSTANCE;
if(leaderboard != null) {
List<Pair<RaceColumnDTO, FleetDTO>> liveRaces = leaderboard.getLiveRaces(autoRefreshTimer.getLiveTimePointInMillis());
boolean hasLiveRace = !liveRaces.isEmpty();
if (hasLiveRace) {
String liveRaceText = "";
if(liveRaces.size() == 1) {
Pair<RaceColumnDTO, FleetDTO> liveRace = liveRaces.get(0);
liveRaceText = stringMessages.raceIsLive("'" + liveRace.getA().getRaceColumnName() + "'");
} else {
String raceNames = "";
for (Pair<RaceColumnDTO, FleetDTO> liveRace : liveRaces) {
raceNames += "'" + liveRace.getA().getRaceColumnName() + "', ";
}
// remove last ", "
raceNames = raceNames.substring(0, raceNames.length() - 2);
liveRaceText = stringMessages.racesAreLive(raceNames);
}
liveRaceDiv.setInnerText(liveRaceText);
} else {
liveRaceDiv.setInnerText("");
}
liveRaceDiv.getStyle().setVisibility(hasLiveRace ? Visibility.VISIBLE : Visibility.HIDDEN);
oldOverallLeaderboardComposite.updatedLeaderboard(leaderboard, hasLiveRace);
}
} else if(activeTabPanel == regattaLeaderboardsTabPanel) {
oldRegattaLeaderboardsComposite.updatedMultiLeaderboard(leaderboard, false);
}
}
@Override
public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) {
}
@UiHandler("overallLeaderboardAnchor")
void overallLeaderboardTabClicked(ClickEvent event) {
setActiveTabPanel(overallLeaderboardTabPanel, eventSeriesAnalyticsManager.getLeaderboardPanel(), overallLeaderboardAnchor);
}
@UiHandler("regattaLeaderboardsAnchor")
void regattaLeaderboardsTabClicked(ClickEvent event) {
setActiveTabPanel(regattaLeaderboardsTabPanel, eventSeriesAnalyticsManager.getMultiLeaderboardPanel(), regattaLeaderboardsAnchor);
}
@UiHandler("competitorChartsAnchor")
void competitorChartsTabClicked(ClickEvent event) {
setActiveTabPanel(competitorChartsTabPanel, eventSeriesAnalyticsManager.getMultiCompetitorChart(), competitorChartsAnchor);
DetailType selectedChartDetailType = oldCompetitorChartsComposite.getSelectedChartDetailType();
eventSeriesAnalyticsManager.showCompetitorChart(selectedChartDetailType);
}
private void setActiveTabPanel(HTMLPanel newActivePanel, Widget newActiveContentWidget, Anchor newActiveAnchor) {
if(activeTabPanel != null) {
activeTabPanel.setVisible(false);
activeAnchor.removeStyleName(HomeResources.INSTANCE.mainCss().navbar_buttonactive());
}
if(activeContentWidget != null) {
activeContentWidget.setVisible(false);
}
activeTabPanel = newActivePanel;
activeContentWidget = newActiveContentWidget;
activeAnchor = newActiveAnchor;
activeTabPanel.setVisible(true);
activeContentWidget.setVisible(true);
activeAnchor.addStyleName(HomeResources.INSTANCE.mainCss().navbar_buttonactive());
}
}
@@ -0,0 +1,38 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.place.event"
xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.leaderboard"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="i18n" type="com.sap.sailing.gwt.home.client.i18n.TextMessages"/>
<ui:with field="res" type="com.sap.sailing.gwt.home.client.HomeResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
<ui:with field="local_res2" type="com.sap.sailing.gwt.home.client.place.event.seriesanalytics.EventSeriesAnalyticsResources" />
<g:HTMLPanel>
<s:header.CompactEventHeader ui:field='eventHeader'/>
<div class="{res.mainCss.grid} {local_res.css.regattaleaderboard}">
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {local_res.css.regattaleaderboard_meta}">
<h3 class="{local_res.css.regattaleaderboard_meta_title}">
<span style="color:darkgrey;"><ui:text from='{i18n.series}'/></span>
<span ui:field="title"></span>
</h3>
<div ui:field="liveRaceDiv" class="{res.mainCss.label} {local_res.css.regattaleaderboard_meta_status} {local_res.css.regattaleaderboard_meta_statuslive}">
<ui:text from='{i18n.live}'/>
</div>
</div>
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {local_res.css.regattaleaderboard_meta_navigation}">
<g:Anchor ui:field="overallLeaderboardAnchor" href="javascript:;" styleName="{res.mainCss.navbar_button}"><ui:text from="{i18n.overallLeaderboard}" /></g:Anchor>
<g:Anchor ui:field="regattaLeaderboardsAnchor" href="javascript:;" styleName="{res.mainCss.navbar_button}"><ui:text from="{i18n.regattaLeaderboards}" /></g:Anchor>
<g:Anchor ui:field="competitorChartsAnchor" href="javascript:;" styleName="{res.mainCss.navbar_button}"><ui:text from="{i18n.competitorsAnalytics}" /></g:Anchor>
</div>
</div>
<g:HTMLPanel ui:field="overallLeaderboardTabPanel">
<s:oldleaderboard.OldLeaderboard ui:field='oldOverallLeaderboardComposite'/>
</g:HTMLPanel>
<g:HTMLPanel ui:field="regattaLeaderboardsTabPanel">
<s:oldmultileaderboard.OldMultiLeaderboard ui:field='oldRegattaLeaderboardsComposite'/>
</g:HTMLPanel>
<g:HTMLPanel ui:field="competitorChartsTabPanel">
<s:oldcompetitorcharts.OldCompetitorCharts ui:field='oldCompetitorChartsComposite'/>
</g:HTMLPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,129 @@
package com.sap.sailing.gwt.home.client.place.event.seriesanalytics;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
import com.sap.sailing.gwt.ui.client.DebugIdHelper;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardChart;
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardChartSettings;
import com.sap.sailing.gwt.ui.client.shared.components.Component;
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialog;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.ui.leaderboard.MultiLeaderboardPanel;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.useragent.UserAgentDetails;
/**
* A viewer for an overall series leaderboard. Additionally the viewer can render a chart for the series leaderboard and
* a MultiLeaderboardPanel where the user can select to show one leaderboard of the series.
*
* @author Frank Mittag (c163874)
* @author Axel Uhl (d043530)
*/
public class EventSeriesAnalyticsDataManager {
private LeaderboardPanel overallLeaderboardPanel;
private MultiCompetitorLeaderboardChart multiCompetitorChart;
private MultiLeaderboardPanel multiLeaderboardPanel;
private final CompetitorSelectionModel competitorSelectionProvider;
private final AsyncActionsExecutor asyncActionsExecutor;
private final ErrorReporter errorReporter;
private final UserAgentDetails userAgent;
private final SailingServiceAsync sailingService;
private final Timer timer;
public EventSeriesAnalyticsDataManager(final SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, Timer timer, ErrorReporter errorReporter, UserAgentDetails userAgent) {
this.competitorSelectionProvider = new CompetitorSelectionModel(/* hasMultiSelection */true);
this.sailingService = sailingService;
this.asyncActionsExecutor = asyncActionsExecutor;
this.timer = timer;
this.errorReporter = errorReporter;
this.userAgent = userAgent;
this.overallLeaderboardPanel = null;
this.multiCompetitorChart = null;
}
public LeaderboardPanel createOverallLeaderboardPanel(final LeaderboardSettings leaderboardSettings, final RaceIdentifier preselectedRace,
final String leaderboardGroupName, String leaderboardName, boolean showRaceDetails,
boolean autoExpandLastRaceColumn) {
if(overallLeaderboardPanel == null) {
overallLeaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor, leaderboardSettings, true, preselectedRace,
competitorSelectionProvider, timer, leaderboardGroupName, leaderboardName, errorReporter,
StringMessages.INSTANCE, userAgent, showRaceDetails, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, /* raceTimesInfoProvider */null, autoExpandLastRaceColumn, /* adjustTimerDelay */
true, false, false);
}
return overallLeaderboardPanel;
}
public MultiCompetitorLeaderboardChart createMultiCompetitorChart(String leaderboardName, DetailType chartDetailType) {
if(multiCompetitorChart == null) {
multiCompetitorChart = new MultiCompetitorLeaderboardChart(sailingService, asyncActionsExecutor, leaderboardName, chartDetailType,
competitorSelectionProvider, timer, StringMessages.INSTANCE, errorReporter);
multiCompetitorChart.setVisible(false);
}
return multiCompetitorChart;
}
public MultiLeaderboardPanel createMultiLeaderboardPanel(LeaderboardSettings leaderboardSettings,
String preselectedLeaderboardName, RaceIdentifier preselectedRace, String leaderboardGroupName,
String metaLeaderboardName, boolean showRaceDetails, boolean autoExpandLastRaceColumn) {
if(multiLeaderboardPanel == null) {
multiLeaderboardPanel = new MultiLeaderboardPanel(sailingService, metaLeaderboardName, asyncActionsExecutor, timer, true /*isEmbedded*/,
preselectedLeaderboardName, preselectedRace, errorReporter, StringMessages.INSTANCE,
userAgent, showRaceDetails, autoExpandLastRaceColumn);
}
return multiLeaderboardPanel;
}
public MultiLeaderboardPanel getMultiLeaderboardPanel() {
return multiLeaderboardPanel;
}
public LeaderboardPanel getLeaderboardPanel() {
return overallLeaderboardPanel;
}
public MultiCompetitorLeaderboardChart getMultiCompetitorChart() {
return multiCompetitorChart;
}
public void showCompetitorChart(DetailType chartDetailType) {
MultiCompetitorLeaderboardChart multiCompetitorChart = getMultiCompetitorChart();
MultiCompetitorLeaderboardChartSettings settings = new MultiCompetitorLeaderboardChartSettings(chartDetailType);
multiCompetitorChart.updateSettings(settings);
multiCompetitorChart.setVisible(true);
timer.addTimeListener(multiCompetitorChart);
multiCompetitorChart.timeChanged(timer.getTime(), null);
}
public void hideCompetitorChart() {
MultiCompetitorLeaderboardChart multiCompetitorChart = getMultiCompetitorChart();
multiCompetitorChart.setVisible(false);
timer.removeTimeListener(multiCompetitorChart);
}
public void showOverallLeaderboardSettingsDialog() {
showComponentSettingsDialog(overallLeaderboardPanel, null);
}
public void showRegattaLeaderboardsSettingsDialog() {
showComponentSettingsDialog(multiLeaderboardPanel, null);
}
public void showChartSettingsDialog() {
showComponentSettingsDialog(multiCompetitorChart, null);
}
protected <SettingsType> void showComponentSettingsDialog(final Component<SettingsType> component, String componentDisplayName) {
String componentName = componentDisplayName != null ? componentDisplayName : component.getLocalizedShortName();
String debugIdPrefix = DebugIdHelper.createDebugId(componentName);
SettingsDialog<SettingsType> dialog = new SettingsDialog<SettingsType>(component, StringMessages.INSTANCE);
dialog.ensureDebugId(debugIdPrefix + "SettingsDialog");
dialog.show();
}
}
@@ -0,0 +1,17 @@
package com.sap.sailing.gwt.home.client.place.event.seriesanalytics;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
public interface EventSeriesAnalyticsResources extends ClientBundle {
public static final EventSeriesAnalyticsResources INSTANCE = GWT.create(EventSeriesAnalyticsResources.class);
@Source("com/sap/sailing/gwt/home/client/place/event/seriesanalytics/EventSeriesAnalytics.css")
LocalCss css();
public interface LocalCss extends CssResource {
String oldLeaderboardPanel();
String oldMultiLeaderboardPanel();
}
}
@@ -39,8 +39,8 @@ public class TabletAndDesktopEventsView extends AbstractEventsView {
recentEventsWidget.setVisible(true);
upcomingEventsWidget.setVisible(false);
recentEventsLink.getElement().removeClassName(homeRes.mainCss().buttoninactive());
upcomingEventsLink.getElement().addClassName(homeRes.mainCss().buttoninactive());
recentEventsLink.getElement().addClassName(homeRes.mainCss().navbar_buttonactive());
upcomingEventsLink.getElement().removeClassName(homeRes.mainCss().navbar_buttonactive());
}
@UiHandler("upcomingEventsLink")
@@ -48,8 +48,8 @@ public class TabletAndDesktopEventsView extends AbstractEventsView {
recentEventsWidget.setVisible(false);
upcomingEventsWidget.setVisible(true);
recentEventsLink.getElement().addClassName(homeRes.mainCss().buttoninactive());
upcomingEventsLink.getElement().removeClassName(homeRes.mainCss().buttoninactive());
upcomingEventsLink.getElement().addClassName(homeRes.mainCss().navbar_buttonactive());
recentEventsLink.getElement().removeClassName(homeRes.mainCss().navbar_buttonactive());
}
@Override
@@ -6,29 +6,20 @@
<ui:with field="i18n" type="com.sap.sailing.gwt.home.client.i18n.TextMessages"/>
<ui:with field="res" type="com.sap.sailing.gwt.home.client.HomeResources" />
<ui:style>
.eventsoverviewnavigation {
font-size: 16px;
.events-overview-navigation {
font-size: 1rem;
margin: 1.875em 0;
}
.eventsoverviewnavigation_button {
text-transform: uppercase;
margin-right: 0.625em;
}
</ui:style>
<g:HTMLPanel>
<div class="{style.eventsoverviewnavigation}">
<div class="{style.events-overview-navigation} {res.mainCss.navbar}">
<div class="{res.mainCss.grid}">
<div class="{res.mediaCss.small6} {res.mediaCss.columns}">
<g:Anchor href="javascript:;" ui:field="recentEventsLink" styleName="{res.mainCss.button} {style.eventsoverviewnavigation_button}" ><ui:text from='{i18n.eventOverviewRecentEvents}'/></g:Anchor>
<g:Anchor href="javascript:;" ui:field="upcomingEventsLink" styleName="{res.mainCss.button} {res.mainCss.buttoninactive} {style.eventsoverviewnavigation_button}" ><ui:text from='{i18n.eventOverviewUpcomingSchedule}'/></g:Anchor>
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
<g:Anchor href="javascript:;" ui:field="recentEventsLink" styleName="{res.mainCss.navbar_button} {res.mainCss.navbar_buttonactive}" ><ui:text from='{i18n.eventOverviewRecentEvents}'/></g:Anchor>
<g:Anchor href="javascript:;" ui:field="upcomingEventsLink" styleName="{res.mainCss.navbar_button}" ><ui:text from='{i18n.eventOverviewUpcomingSchedule}'/></g:Anchor>
</div>
</div>
</div>
<p:recent.EventsOverviewRecent ui:field='recentEventsWidget'/>
<p:upcoming.EventsOverviewUpcoming ui:field='upcomingEventsWidget'/>
</g:HTMLPanel>
</ui:UiBinder>
@@ -4,24 +4,23 @@ import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.useragent.UserAgentDetails;
public interface LeaderboardView {
public interface AnalyticsView {
Widget asWidget();
void createLeaderboardViewer(final SailingServiceAsync sailingService, final AsyncActionsExecutor asyncActionsExecutor,
void createRegattaAnalyticsViewer(final SailingServiceAsync sailingService, final AsyncActionsExecutor asyncActionsExecutor,
final Timer timer, final LeaderboardSettings leaderboardSettings, final RaceIdentifier preselectedRace,
final String leaderboardGroupName, String leaderboardName, final ErrorReporter errorReporter,
final StringMessages stringMessages, final UserAgentDetails userAgent, boolean showRaceDetails,
final UserAgentDetails userAgent, boolean showRaceDetails,
boolean autoExpandLastRaceColumn, boolean showOverallLeaderboard);
void createMetaLeaderboardViewer(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
void createSeriesAnalyticsViewer(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
Timer timer, LeaderboardSettings leaderboardSettings, String preselectedLeaderboardName, RaceIdentifier preselectedRace,
String leaderboardGroupName, String metaLeaderboardName, ErrorReporter errorReporter,
StringMessages stringMessages, UserAgentDetails userAgent, boolean showRaceDetails,
UserAgentDetails userAgent, boolean showRaceDetails,
boolean autoExpandLastRaceColumn, boolean showSeriesLeaderboards);
}
@@ -18,7 +18,6 @@ import com.sap.sailing.domain.common.RegattaNameAndRaceName;
import com.sap.sailing.gwt.home.client.i18n.TextMessages;
import com.sap.sailing.gwt.home.client.shared.placeholder.Placeholder;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings.RaceColumnSelectionStrategies;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettingsFactory;
@@ -65,7 +64,7 @@ public class LeaderboardActivity extends AbstractActivity implements ErrorReport
@Override
public void onSuccess(Util.Pair<String, LeaderboardType> leaderboardNameAndType) {
if (leaderboardNameAndType != null && leaderboardName.equals(leaderboardNameAndType.getA())) {
createLeaderboardViewer(panel, event, leaderboardNameAndType.getA(), leaderboardNameAndType.getB(), showRaceDetails);
createAnalyticsViewer(panel, event, leaderboardNameAndType.getA(), leaderboardNameAndType.getB(), showRaceDetails);
} else {
createErrorView(TextMessages.INSTANCE.errorMessageNoSuchLeaderboard(), null, panel);
}
@@ -88,7 +87,7 @@ public class LeaderboardActivity extends AbstractActivity implements ErrorReport
});
}
private void createLeaderboardViewer(AcceptsOneWidget panel, EventDTO event, String leaderboardName, LeaderboardType leaderboardType, boolean showRaceDetails) {
private void createAnalyticsViewer(AcceptsOneWidget panel, EventDTO event, String leaderboardName, LeaderboardType leaderboardType, boolean showRaceDetails) {
String leaderboardDisplayName = Window.Location.getParameter("displayName");
if (leaderboardDisplayName == null || leaderboardDisplayName.isEmpty()) {
leaderboardDisplayName = leaderboardName;
@@ -106,19 +105,19 @@ public class LeaderboardActivity extends AbstractActivity implements ErrorReport
boolean showOverallLeaderboard = GwtHttpRequestUtils.getBooleanParameter(LeaderboardUrlSettings.PARAM_SHOW_OVERALL_LEADERBOARD, false);
boolean showSeriesLeaderboards = GwtHttpRequestUtils.getBooleanParameter(LeaderboardUrlSettings.PARAM_SHOW_SERIES_LEADERBOARDS, false);
LeaderboardView leaderboardView = clientFactory.createLeaderboardView(event, leaderboardName, timerForClientServerOffset);
AnalyticsView analyticsView = clientFactory.createLeaderboardView(event, leaderboardName, timerForClientServerOffset);
if (leaderboardType.isMetaLeaderboard()) {
leaderboardView.createMetaLeaderboardViewer(clientFactory.getSailingService(), new AsyncActionsExecutor(),
timer, leaderboardSettings, null, preselectedRace, "leaderboardGroupName", leaderboardName, this, StringMessages.INSTANCE,
analyticsView.createSeriesAnalyticsViewer(clientFactory.getSailingService(), new AsyncActionsExecutor(),
timer, leaderboardSettings, null, preselectedRace, "leaderboardGroupName", leaderboardName, this,
userAgent, showRaceDetails, autoExpandLastRaceColumn, showSeriesLeaderboards);
} else {
leaderboardView.createLeaderboardViewer(clientFactory.getSailingService(), new AsyncActionsExecutor(),
timer, leaderboardSettings, preselectedRace, "leaderboardGroupName", leaderboardName, this, StringMessages.INSTANCE,
analyticsView.createRegattaAnalyticsViewer(clientFactory.getSailingService(), new AsyncActionsExecutor(),
timer, leaderboardSettings, preselectedRace, "leaderboardGroupName", leaderboardName, this,
userAgent, showRaceDetails, autoExpandLastRaceColumn, showOverallLeaderboard);
}
panel.setWidget(leaderboardView.asWidget());
panel.setWidget(analyticsView.asWidget());
}
/**
@@ -5,5 +5,5 @@ import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sse.gwt.client.player.Timer;
public interface LeaderboardClientFactory extends SailingClientFactory {
LeaderboardView createLeaderboardView(EventDTO event, String leaderboardName, Timer timerForClientServerOffset);
AnalyticsView createLeaderboardView(EventDTO event, String leaderboardName, Timer timerForClientServerOffset);
}
@@ -1,105 +1,57 @@
package com.sap.sailing.gwt.home.client.place.leaderboard;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.HeadingElement;
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.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.gwt.home.client.app.PlaceNavigator;
import com.sap.sailing.gwt.home.client.i18n.TextMessages;
import com.sap.sailing.gwt.home.client.place.event.header.CompactEventHeader;
import com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources;
import com.sap.sailing.gwt.home.client.shared.leaderboard.AbstractLeaderboardViewer;
import com.sap.sailing.gwt.home.client.shared.leaderboard.LeaderboardViewer;
import com.sap.sailing.gwt.home.client.shared.leaderboard.MetaLeaderboardViewer;
import com.sap.sailing.gwt.ui.client.DebugIdHelper;
import com.sap.sailing.gwt.home.client.place.event.regattaanalytics.RegattaAnalytics;
import com.sap.sailing.gwt.home.client.place.event.seriesanalytics.EventSeriesAnalytics;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialog;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.useragent.UserAgentDetails;
public class TabletAndDesktopLeaderboardView extends Composite implements LeaderboardView {
public class TabletAndDesktopLeaderboardView extends Composite implements AnalyticsView {
private static LeaderboardPageViewUiBinder uiBinder = GWT.create(LeaderboardPageViewUiBinder.class);
interface LeaderboardPageViewUiBinder extends UiBinder<Widget, TabletAndDesktopLeaderboardView> {
}
@UiField HTMLPanel leaderboardPanel;
@UiField(provided=true) CompactEventHeader eventHeader;
// temp fields --> will be moved to a leaderboard partial later on
@UiField HeadingElement title;
@UiField Anchor settingsAnchor;
@UiField Anchor reloadAnchor;
private AbstractLeaderboardViewer leaderboardViewer;
@UiField(provided=true) RegattaAnalytics regattaAnalytics;
@UiField(provided=true) EventSeriesAnalytics seriesAnalytics;
public TabletAndDesktopLeaderboardView(EventDTO event, String leaderboardName, Timer timerForClientServerOffset, PlaceNavigator placeNavigator) {
eventHeader = new CompactEventHeader(event, leaderboardName, placeNavigator);
regattaAnalytics = new RegattaAnalytics(event, leaderboardName, timerForClientServerOffset, placeNavigator);
seriesAnalytics = new EventSeriesAnalytics(event, leaderboardName, timerForClientServerOffset, placeNavigator);
EventRegattaLeaderboardResources.INSTANCE.css().ensureInjected();
regattaAnalytics.setVisible(false);
seriesAnalytics.setVisible(false);
initWidget(uiBinder.createAndBindUi(this));
reloadAnchor.setVisible(false);
title.setInnerText(TextMessages.INSTANCE.leaderboard() + ": " + leaderboardName);
}
public void createLeaderboardViewer(final SailingServiceAsync sailingService, final AsyncActionsExecutor asyncActionsExecutor,
public void createRegattaAnalyticsViewer(final SailingServiceAsync sailingService, final AsyncActionsExecutor asyncActionsExecutor,
final Timer timer, final LeaderboardSettings leaderboardSettings, final RaceIdentifier preselectedRace,
final String leaderboardGroupName, String leaderboardName, final ErrorReporter errorReporter,
final StringMessages stringMessages, final UserAgentDetails userAgent, boolean showRaceDetails,
final UserAgentDetails userAgent, boolean showRaceDetails,
boolean autoExpandLastRaceColumn, boolean showOverallLeaderboard) {
leaderboardViewer = new LeaderboardViewer(sailingService, new AsyncActionsExecutor(),
timer, leaderboardSettings, preselectedRace, leaderboardGroupName, leaderboardName, errorReporter, stringMessages,
userAgent, showRaceDetails, autoExpandLastRaceColumn, showOverallLeaderboard);
ScrollPanel contentScrollPanel = new ScrollPanel();
contentScrollPanel.setWidget(leaderboardViewer);
leaderboardPanel.add(contentScrollPanel);
regattaAnalytics.createRegattaAnalyticsViewer(sailingService, asyncActionsExecutor, timer, leaderboardSettings, preselectedRace,
leaderboardGroupName, leaderboardName, errorReporter, userAgent, showRaceDetails, autoExpandLastRaceColumn, showOverallLeaderboard);
regattaAnalytics.setVisible(true);
}
public void createMetaLeaderboardViewer(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
public void createSeriesAnalyticsViewer(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
Timer timer, LeaderboardSettings leaderboardSettings, String preselectedLeaderboardName, RaceIdentifier preselectedRace,
String leaderboardGroupName, String metaLeaderboardName, ErrorReporter errorReporter,
StringMessages stringMessages, UserAgentDetails userAgent, boolean showRaceDetails,
boolean autoExpandLastRaceColumn, boolean showSeriesLeaderboards) {
leaderboardViewer = new MetaLeaderboardViewer(sailingService, new AsyncActionsExecutor(),
timer, leaderboardSettings, null, preselectedRace, leaderboardGroupName, metaLeaderboardName, errorReporter, stringMessages,
userAgent, showRaceDetails, autoExpandLastRaceColumn, showSeriesLeaderboards);
ScrollPanel contentScrollPanel = new ScrollPanel();
contentScrollPanel.setWidget(leaderboardViewer);
leaderboardPanel.add(contentScrollPanel);
}
@UiHandler("reloadAnchor")
void reloadClicked(ClickEvent event) {
}
@UiHandler("settingsAnchor")
void settingsClicked(ClickEvent event) {
LeaderboardPanel leaderboardComponent = leaderboardViewer.getLeaderboardPanel();
final String componentName = leaderboardComponent.getLocalizedShortName();
final String debugIdPrefix = DebugIdHelper.createDebugId(componentName);
SettingsDialog<LeaderboardSettings> dialog = new SettingsDialog<LeaderboardSettings>(leaderboardComponent,
StringMessages.INSTANCE);
dialog.ensureDebugId(debugIdPrefix + "SettingsDialog");
dialog.show();
UserAgentDetails userAgent, boolean showRaceDetails, boolean autoExpandLastRaceColumn, boolean showSeriesLeaderboards) {
seriesAnalytics.createSeriesAnalyticsViewer(sailingService, asyncActionsExecutor, timer, leaderboardSettings, preselectedLeaderboardName,
preselectedRace, leaderboardGroupName, metaLeaderboardName, errorReporter, userAgent, showRaceDetails, autoExpandLastRaceColumn, showSeriesLeaderboards);
seriesAnalytics.setVisible(true);
}
}
@@ -1,36 +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:s="urn:import:com.sap.sailing.gwt.home.client.place.event"
xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.leaderboard"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="i18n" type="com.sap.sailing.gwt.home.client.i18n.TextMessages"/>
<ui:with field="res" type="com.sap.sailing.gwt.home.client.HomeResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
<ui:style>
.leaderboardPanel {
background-color:#f8f8f8;
padding: 0 10px 10px 10px;
}
</ui:style>
<g:HTMLPanel>
<s:header.CompactEventHeader ui:field='eventHeader'/>
<!-- The leaderboard of a regatta-->
<div class="{res.mainCss.grid} {local_res.css.eventregattaleaderboard_meta}">
<div class="{res.mediaCss.small9} {res.mediaCss.columns}">
<h3 ui:field="title" class="{local_res.css.eventregattaleaderboard_meta_title}">
</h3>
<!--
<div class="{local_res.css.eventregattaleaderboard_meta_update}"><ui:text from='{i18n.eventRegattaLeaderboardLastScoreUpdate}'/>: &nbsp; {leaderboard.lastScoringUpdate}</div>
-->
</div>
<div class="{res.mediaCss.small3} {res.mediaCss.columns}">
<g:Anchor ui:field="settingsAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.eventregattaleaderboard_meta_settings}"></g:Anchor>
<g:Anchor ui:field="reloadAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.eventregattaleaderboard_meta_reload}"></g:Anchor>
</div>
<div class="{res.mediaCss.large12} {res.mediaCss.columns}">
<g:HTMLPanel ui:field="leaderboardPanel" styleName="{style.leaderboardPanel}">
</g:HTMLPanel>
</div>
</div>
<s:regattaanalytics.RegattaAnalytics ui:field='regattaAnalytics'/>
<s:seriesanalytics.EventSeriesAnalytics ui:field='seriesAnalytics'/>
</g:HTMLPanel>
</ui:UiBinder>
@@ -1,66 +0,0 @@
package com.sap.sailing.gwt.home.client.shared.leaderboard;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.SimplePanel;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
import com.sap.sailing.gwt.ui.client.DebugIdHelper;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.components.Component;
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialog;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.Timer;
/**
* A base class for a leaderboard viewer.
*
* @author Frank Mittag (c163874)
*/
public abstract class AbstractLeaderboardViewer extends SimplePanel {
protected final StringMessages stringMessages;
private final LeaderboardPanel leaderboardPanel;
protected final CompetitorSelectionModel competitorSelectionProvider;
protected final AsyncActionsExecutor asyncActionsExecutor;
protected final Timer timer;
public AbstractLeaderboardViewer(CompetitorSelectionModel competitorSelectionProvider, AsyncActionsExecutor asyncActionsExecutor,
Timer timer, StringMessages stringMessages, LeaderboardPanel leaderboardPanel) {
this.competitorSelectionProvider = competitorSelectionProvider;
this.leaderboardPanel = leaderboardPanel;
this.asyncActionsExecutor = asyncActionsExecutor;
this.stringMessages = stringMessages;
this.timer = timer;
}
public LeaderboardPanel getLeaderboardPanel() {
return leaderboardPanel;
}
protected <SettingsType> void addComponentToNavigationMenu(final Component<SettingsType> component, boolean isCheckboxEnabled,
String componentDisplayName, final boolean hasSettingsWhenComponentIsInvisible) {
final String componentName = componentDisplayName != null ? componentDisplayName : component.getLocalizedShortName();
final String debugIdPrefix = DebugIdHelper.createDebugId(componentName);
final Button settingsButton = new Button("");
settingsButton.ensureDebugId(debugIdPrefix + "SettingsButton");
if (component.hasSettings()) {
settingsButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
SettingsDialog<SettingsType> dialog = new SettingsDialog<SettingsType>(component,
stringMessages);
dialog.ensureDebugId(debugIdPrefix + "SettingsDialog");
dialog.show();
}
});
}
settingsButton.setEnabled(component.hasSettings() && hasSettingsWhenComponentIsInvisible);
// settingsButton.addStyleName(STYLE_VIEWER_TOOLBAR_SETTINGS_BUTTON);
settingsButton.getElement().getStyle().setFloat(Style.Float.LEFT);
settingsButton.setTitle(stringMessages.settingsForComponent(componentName));
}
}
@@ -1,79 +0,0 @@
package com.sap.sailing.gwt.home.client.shared.leaderboard;
import java.util.List;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlowPanel;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.async.MarkedAsyncCallback;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.useragent.UserAgentDetails;
/**
* A viewer for a single leaderboard and a leaderboard chart.
* @author Frank Mittag (c163874)
*
*/
public class LeaderboardViewer extends AbstractLeaderboardViewer {
private LeaderboardPanel overallLeaderboardPanel;
public LeaderboardViewer(final SailingServiceAsync sailingService, final AsyncActionsExecutor asyncActionsExecutor,
final Timer timer, final LeaderboardSettings leaderboardSettings, final RaceIdentifier preselectedRace,
final String leaderboardGroupName, String leaderboardName, final ErrorReporter errorReporter,
final StringMessages stringMessages, final UserAgentDetails userAgent, boolean showRaceDetails,
boolean autoExpandLastRaceColumn, boolean showOverallLeaderboard) {
this(new CompetitorSelectionModel(/* hasMultiSelection */true), sailingService, asyncActionsExecutor, timer,
leaderboardSettings, preselectedRace, leaderboardGroupName, leaderboardName, errorReporter,
stringMessages, userAgent, showRaceDetails, autoExpandLastRaceColumn, showOverallLeaderboard);
}
private LeaderboardViewer(CompetitorSelectionModel competitorSelectionModel,
final SailingServiceAsync sailingService, final AsyncActionsExecutor asyncActionsExecutor,
final Timer timer, final LeaderboardSettings leaderboardSettings, final RaceIdentifier preselectedRace,
final String leaderboardGroupName, String leaderboardName, final ErrorReporter errorReporter,
final StringMessages stringMessages, final UserAgentDetails userAgent, boolean showRaceDetails,
boolean autoExpandLastRaceColumn, boolean showOverallLeaderboard) {
super(competitorSelectionModel, asyncActionsExecutor, timer, stringMessages, new LeaderboardPanel(
sailingService, asyncActionsExecutor, leaderboardSettings, preselectedRace,
competitorSelectionModel, timer, leaderboardGroupName, leaderboardName, errorReporter,
stringMessages, userAgent, showRaceDetails, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, /* raceTimesInfoProvider */null, autoExpandLastRaceColumn, /* adjustTimerDelay */
true, false, false));
final FlowPanel mainPanel = new FlowPanel();
setWidget(mainPanel);
mainPanel.add(getLeaderboardPanel());
overallLeaderboardPanel = null;
if(showOverallLeaderboard) {
sailingService.getOverallLeaderboardNamesContaining(leaderboardName, new MarkedAsyncCallback<List<String>>(
new AsyncCallback<List<String>>() {
@Override
public void onSuccess(List<String> result) {
if(result.size() == 1) {
String overallLeaderboardName = result.get(0);
overallLeaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor,
leaderboardSettings, preselectedRace, competitorSelectionProvider, timer,
leaderboardGroupName, overallLeaderboardName, errorReporter, stringMessages, userAgent,
false, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, /* raceTimesInfoProvider */null, false,
/* adjustTimerDelay */ true, /*autoApplyTopNFilter*/false, false);
mainPanel.add(overallLeaderboardPanel);
addComponentToNavigationMenu(overallLeaderboardPanel, true, stringMessages.seriesLeaderboard(),
/* hasSettingsWhenComponentIsInvisible*/ true);
}
}
@Override
public void onFailure(Throwable caught) {
// DO NOTHING
}
}));
}
}
}
@@ -1,59 +0,0 @@
package com.sap.sailing.gwt.home.client.shared.leaderboard;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
import com.sap.sailing.gwt.ui.leaderboard.MultiLeaderboardPanel;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.useragent.UserAgentDetails;
/**
* A viewer for an overall series leaderboard. Additionally the viewer can render a chart for the series leaderboard and
* a MultiLeaderboardPanel where the user can select to show one leaderboard of the series.
*
* @author Frank Mittag (c163874)
* @author Axel Uhl (d043530)
*/
public class MetaLeaderboardViewer extends AbstractLeaderboardViewer {
private final MultiLeaderboardPanel multiLeaderboardPanel;
public MetaLeaderboardViewer(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
Timer timer, LeaderboardSettings leaderboardSettings, String preselectedLeaderboardName, RaceIdentifier preselectedRace,
String leaderboardGroupName, String metaLeaderboardName, ErrorReporter errorReporter,
StringMessages stringMessages, UserAgentDetails userAgent, boolean showRaceDetails,
boolean autoExpandLastRaceColumn, boolean showSeriesLeaderboards) {
this(new CompetitorSelectionModel(/* hasMultiSelection */true), sailingService, asyncActionsExecutor, timer,
leaderboardSettings, preselectedLeaderboardName, preselectedRace, leaderboardGroupName, metaLeaderboardName,
errorReporter, stringMessages, userAgent, showRaceDetails, autoExpandLastRaceColumn, showSeriesLeaderboards);
}
private MetaLeaderboardViewer(CompetitorSelectionModel competitorSelectionModel, SailingServiceAsync sailingService,
AsyncActionsExecutor asyncActionsExecutor, Timer timer, LeaderboardSettings leaderboardSettings,
String preselectedLeaderboardName, RaceIdentifier preselectedRace, String leaderboardGroupName,
String metaLeaderboardName, ErrorReporter errorReporter, StringMessages stringMessages,
UserAgentDetails userAgent, boolean showRaceDetails, boolean autoExpandLastRaceColumn, boolean showSeriesLeaderboards) {
super(competitorSelectionModel, asyncActionsExecutor, timer, stringMessages, new LeaderboardPanel(sailingService, asyncActionsExecutor,
leaderboardSettings, preselectedRace, competitorSelectionModel, timer,
leaderboardGroupName, metaLeaderboardName, errorReporter, stringMessages, userAgent,
showRaceDetails, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, /* raceTimesInfoProvider */null, autoExpandLastRaceColumn,
/* adjustTimerDelay */ true, /*autoApplyTopNFilter*/false, false));
final FlowPanel mainPanel = new FlowPanel();
setWidget(mainPanel);
final Label overallStandingsLabel = new Label(stringMessages.overallStandings());
overallStandingsLabel.setStyleName("leaderboardHeading");
multiLeaderboardPanel = new MultiLeaderboardPanel(sailingService, metaLeaderboardName, asyncActionsExecutor, timer,
preselectedLeaderboardName, preselectedRace, errorReporter, stringMessages,
userAgent, showRaceDetails, autoExpandLastRaceColumn);
multiLeaderboardPanel.setVisible(showSeriesLeaderboards);
mainPanel.add(getLeaderboardPanel());
mainPanel.add(multiLeaderboardPanel);
}
}
@@ -345,6 +345,13 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
}
};
raceStatusColumn.setSortable(true);
TextColumn<TracTracRaceRecordDTO> raceVisibilityColumn = new TextColumn<TracTracRaceRecordDTO>() {
@Override
public String getValue(TracTracRaceRecordDTO object) {
return object.raceVisibility;
}
};
raceVisibilityColumn.setSortable(true);
SelectionCheckboxColumn<TracTracRaceRecordDTO> selectionCheckboxColumn = new SelectionCheckboxColumn<TracTracRaceRecordDTO>(tableResources.cellTableStyle().cellTableCheckboxSelected(),
tableResources.cellTableStyle().cellTableCheckboxDeselected(), tableResources.cellTableStyle().cellTableCheckboxColumnCell()) {
@@ -364,6 +371,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
racesTable.addColumn(boatClassColumn, stringMessages.boatClass());
racesTable.addColumn(raceStartTrackingColumn, stringMessages.startTime());
racesTable.addColumn(raceStatusColumn, stringMessages.raceStatusColumn());
racesTable.addColumn(raceVisibilityColumn, stringMessages.raceVisibilityColumn());
racesTable.addColumnSortHandler(getRaceTableColumnSortHandler(selectionCheckboxColumn, this.raceList.getList(),
raceNameColumn, boatClassColumn, raceStartTrackingColumn, raceStatusColumn));
racesTable.setSelectionModel(selectionCheckboxColumn.getSelectionModel(), selectionCheckboxColumn.getSelectionManager());
@@ -1084,4 +1084,5 @@ public interface StringMessages extends Messages {
String manageMedia();
String manageMediaTooltip();
String showAll();
String raceVisibilityColumn();
}
@@ -1065,3 +1065,4 @@ hideVideoPopup=Hide Video
manageMedia=Manage Media
manageMediaTooltip=Configure audio and video clips, synchronize times
showAll=Show all
raceVisibilityColumn=Visibility
@@ -1060,3 +1060,4 @@ hideVideoPopup=Video verstecken
manageMedia=Audio/Video verwalten
manageMediaTooltip=Audio- und Video-Clips verwalten, Zeiten synchronisieren
showAll=Alle zeigen
raceVisibilityColumn=Sichtbarkeit
@@ -1016,3 +1016,4 @@ hideVideoPopup=Hide Video
manageMedia=Manage Media
manageMediaTooltip=Configure audio and video clips, synchronize times
showAll=Show all
raceVisibilityColumn=Visibility
@@ -12,6 +12,11 @@ public class DateAndTimeFormatterUtil {
public static DateTimeFormatRenderer defaultTimeFormatter = new DateTimeFormatRenderer(
DateTimeFormat.getFormat(PredefinedFormat.TIME_LONG));
public static DateTimeFormatRenderer longDateFormatter = new DateTimeFormatRenderer(
DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.DATE_LONG));
public static DateTimeFormatRenderer longTimeFormatter = new DateTimeFormatRenderer(
DateTimeFormat.getFormat("HH:mm:ss zzz"));
private static DateTimeFormatRenderer secondsTimeFormatter = new DateTimeFormatRenderer(
DateTimeFormat.getFormat("m:ss"));
private static DateTimeFormatRenderer minutesAndSecondsTimeFormatter = new DateTimeFormatRenderer(
@@ -28,7 +28,6 @@ import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
@@ -95,6 +94,7 @@ import com.sap.sailing.gwt.ui.client.shared.controls.SelectionCheckboxColumn;
import com.sap.sailing.gwt.ui.client.shared.filter.CompetitorRaceRankFilter;
import com.sap.sailing.gwt.ui.client.shared.filter.FilterWithUI;
import com.sap.sailing.gwt.ui.client.shared.filter.LeaderboardFetcher;
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
import com.sap.sailing.gwt.ui.leaderboard.DetailTypeColumn.LegDetailField;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings.RaceColumnSelectionStrategies;
import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
@@ -241,7 +241,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
* This anchor's HTML holds the image tag for the play/pause button that needs to be updated when the {@link #timer}
* changes its playing state
*/
private final Anchor playPause;
private Anchor playPause;
private final CompetitorSelectionProvider competitorSelectionProvider;
private final HorizontalPanel filterControlPanel;
@@ -273,23 +273,18 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
private final VerticalPanel contentPanel;
private final HorizontalPanel refreshAndSettingsPanel;
private HorizontalPanel refreshAndSettingsPanel;
private Label scoreCorrectionLastUpdateTimeLabel;
private Label scoreCorrectionCommentLabel;
private Label liveRaceLabel;
private final FlowPanel informationPanel;
private final Label scoreCorrectionLastUpdateTimeLabel;
private final Label scoreCorrectionCommentLabel;
private final Label liveRaceLabel;
private final DateTimeFormat dateFormatter = DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.DATE_LONG);
private final DateTimeFormat timeFormatter = DateTimeFormat.getFormat("HH:mm:ss zzz");
private boolean isEmbedded = false;
private boolean isEmbedded;
private static LeaderboardResources resources = GWT.create(LeaderboardResources.class);
private static LeaderboardTableResources tableResources = GWT.create(LeaderboardTableResources.class);
private final ImageResource pauseIcon;
private final ImageResource playIcon;
private ImageResource pauseIcon;
private ImageResource playIcon;
private final BusyIndicator busyIndicator;
@@ -615,7 +610,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
public void render(Context context, LeaderboardRowDTO object, SafeHtmlBuilder sb) {
String competitorColor = LeaderboardPanel.this.competitorSelectionProvider.getColor(object.competitor).getAsHtml();
String competitorColorBarStyle;
if (LeaderboardPanel.this.isEmbedded) {
if (LeaderboardPanel.this.isEmbedded && preSelectedRace != null) {
competitorColorBarStyle = "style=\"border-bottom: 2px solid " + competitorColor + ";\"";
} else {
competitorColorBarStyle = "style=\"border: none;\"";
@@ -1582,16 +1577,16 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
LeaderboardSettings settings, CompetitorSelectionProvider competitorSelectionProvider,
String leaderboardName, ErrorReporter errorReporter, final StringMessages stringMessages,
final UserAgentDetails userAgent, boolean showRaceDetails) {
this(sailingService, asyncActionsExecutor, settings, /* preSelectedRace */null, competitorSelectionProvider,
this(sailingService, asyncActionsExecutor, settings, false, /* preSelectedRace */null, competitorSelectionProvider,
null, leaderboardName, errorReporter, stringMessages, userAgent, showRaceDetails);
}
public LeaderboardPanel(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
LeaderboardSettings settings, RaceIdentifier preSelectedRace,
LeaderboardSettings settings, boolean isEmbedded, RaceIdentifier preSelectedRace,
CompetitorSelectionProvider competitorSelectionProvider, String leaderboardGroupName,
String leaderboardName, ErrorReporter errorReporter, final StringMessages stringMessages,
final UserAgentDetails userAgent, boolean showRaceDetails) {
this(sailingService, asyncActionsExecutor, settings, preSelectedRace, competitorSelectionProvider, new Timer(
this(sailingService, asyncActionsExecutor, settings, isEmbedded, preSelectedRace, competitorSelectionProvider, new Timer(
// perform the first request as "live" but don't by default auto-play
PlayModes.Live, PlayStates.Paused, /* delayBetweenAutoAdvancesInMilliseconds */3000l), leaderboardGroupName,
leaderboardName, errorReporter, stringMessages, userAgent, showRaceDetails,
@@ -1600,7 +1595,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
}
public LeaderboardPanel(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
LeaderboardSettings settings, RaceIdentifier preSelectedRace,
LeaderboardSettings settings, boolean isEmbedded, RaceIdentifier preSelectedRace,
CompetitorSelectionProvider competitorSelectionProvider, Timer timer, String leaderboardGroupName,
String leaderboardName, ErrorReporter errorReporter, final StringMessages stringMessages,
final UserAgentDetails userAgent, boolean showRaceDetails, CompetitorFilterPanel competitorSearchTextBox,
@@ -1611,6 +1606,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
this.showRaceDetails = showRaceDetails;
this.sailingService = sailingService;
this.asyncActionsExecutor = asyncActionsExecutor;
this.isEmbedded = isEmbedded;
this.preSelectedRace = preSelectedRace;
this.competitorSelectionProvider = competitorSelectionProvider;
competitorSelectionProvider.addCompetitorSelectionChangeListener(this);
@@ -1708,16 +1704,41 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
loadCompleteLeaderboard(getLeaderboardDisplayDate());
}
if (this.preSelectedRace == null) {
isEmbedded = false;
} else {
isEmbedded = true;
}
contentPanel = new VerticalPanel();
contentPanel.setStyleName(STYLE_LEADERBOARD_CONTENT);
busyIndicator = new SimpleBusyIndicator(false, 0.8f);
busyIndicator.ensureDebugId("BusyIndicator");
// the information panel
informationPanel = new FlowPanel();
if (!isEmbedded) {
Widget toolbarPanel = createToolbarPanel();
contentPanel.add(toolbarPanel);
}
if (competitorSearchTextBox != null) {
contentPanel.add(competitorSearchTextBox);
contentPanel.add(busyIndicator);
competitorSearchTextBox.getSettingsButton().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
new SettingsDialog<LeaderboardSettings>(LeaderboardPanel.this, stringMessages).show();
}
});
this.competitorFilterPanel = competitorSearchTextBox;
}
SortedCellTable<LeaderboardRowDTO> leaderboardTable = getLeaderboardTable();
leaderboardTable.getElement().getStyle().setMarginTop(5, Unit.PX);
filterControlPanel = new HorizontalPanel();
filterControlPanel.setStyleName("LeaderboardPanel-FilterControl-Panel");
contentPanel.add(leaderboardTable);
if (showCompetitorFilterStatus) {
contentPanel.add(createFilterDeselectionControl());
}
setWidget(contentPanel);
raceNameForDefaultSorting = settings.getNameOfRaceToSort();
}
private Widget createToolbarPanel() {
FlowPanel informationPanel = new FlowPanel();
informationPanel.setStyleName(STYLE_LEADERBOARD_INFO);
scoreCorrectionLastUpdateTimeLabel = new Label("");
scoreCorrectionCommentLabel = new Label("");
@@ -1735,8 +1756,6 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
DockPanel toolbarPanel = new DockPanel();
toolbarPanel.ensureDebugId("ToolbarPanel");
toolbarPanel.setStyleName(STYLE_LEADERBOARD_TOOLBAR);
busyIndicator = new SimpleBusyIndicator(false, 0.8f);
busyIndicator.ensureDebugId("BusyIndicator");
if (!isEmbedded) {
toolbarPanel.add(informationPanel, DockPanel.WEST);
toolbarPanel.add(busyIndicator, DockPanel.WEST);
@@ -1771,30 +1790,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
refreshAndSettingsPanel.add(refreshPanel);
toolbarPanel.add(refreshAndSettingsPanel, DockPanel.EAST);
if (!isEmbedded) {
contentPanel.add(toolbarPanel);
}
if (competitorSearchTextBox != null) {
contentPanel.add(competitorSearchTextBox);
contentPanel.add(busyIndicator);
competitorSearchTextBox.getSettingsButton().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
new SettingsDialog<LeaderboardSettings>(LeaderboardPanel.this, stringMessages).show();
}
});
this.competitorFilterPanel = competitorSearchTextBox;
}
SortedCellTable<LeaderboardRowDTO> leaderboardTable = getLeaderboardTable();
leaderboardTable.getElement().getStyle().setMarginTop(5, Unit.PX);
filterControlPanel = new HorizontalPanel();
filterControlPanel.setStyleName("LeaderboardPanel-FilterControl-Panel");
contentPanel.add(leaderboardTable);
if (showCompetitorFilterStatus) {
contentPanel.add(createFilterDeselectionControl());
}
setWidget(contentPanel);
raceNameForDefaultSorting = settings.getNameOfRaceToSort();
return toolbarPanel;
}
private Widget createFilterDeselectionControl() {
@@ -2240,11 +2236,12 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
leaderboardTable.sortColumn(columnToSortFor, columnToSortFor.getPreferredSortingOrder().isAscending());
}
if(!isEmbedded) {
scoreCorrectionCommentLabel.setText(leaderboard.getComment() != null ? leaderboard.getComment() : "");
if (leaderboard.getTimePointOfLastCorrectionsValidity() != null) {
Date lastCorrectionDate = leaderboard.getTimePointOfLastCorrectionsValidity();
String lastUpdate = dateFormatter.format(lastCorrectionDate) + ", "
+ timeFormatter.format(lastCorrectionDate);
String lastUpdate = DateAndTimeFormatterUtil.longDateFormatter.render(lastCorrectionDate) + ", "
+ DateAndTimeFormatterUtil.longTimeFormatter.render(lastCorrectionDate);
scoreCorrectionLastUpdateTimeLabel.setText(stringMessages.lastScoreUpdate() + ": " + lastUpdate);
} else {
scoreCorrectionLastUpdateTimeLabel.setText("");
@@ -2259,11 +2256,11 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
liveRaceText = stringMessages.raceIsLive("'" + liveRace.getA().getRaceColumnName() + "'");
} else {
String raceNames = "";
for(com.sap.sse.common.Util.Pair<RaceColumnDTO, FleetDTO> liveRace: liveRaces) {
for (com.sap.sse.common.Util.Pair<RaceColumnDTO, FleetDTO> liveRace : liveRaces) {
raceNames += "'" + liveRace.getA().getRaceColumnName() + "', ";
}
// remove last ", "
raceNames = raceNames.substring(0, raceNames.length()-2);
raceNames = raceNames.substring(0, raceNames.length() - 2);
liveRaceText = stringMessages.racesAreLive(raceNames);
}
liveRaceLabel.setText(liveRaceText);
@@ -2272,6 +2269,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
}
scoreCorrectionLastUpdateTimeLabel.setVisible(!hasLiveRace);
liveRaceLabel.setVisible(hasLiveRace);
}
informLeaderboardUpdateListenersAboutLeaderboardUpdated(leaderboard);
getBusyIndicator().setBusy(false);
}
@@ -2899,9 +2897,11 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
@Override
public void playStateChanged(PlayStates playState, PlayModes playMode) {
currentlyHandlingPlayStateChange = true;
if(!isEmbedded) {
playPause.setHTML(getPlayPauseImgHtml(playState));
playPause.setTitle(playState == PlayStates.Playing ? stringMessages.pauseAutomaticRefresh() : stringMessages
.autoRefresh());
playPause.setTitle(playState == PlayStates.Playing ? stringMessages.pauseAutomaticRefresh() : stringMessages.autoRefresh());
}
if (!settingsUpdatedExplicitly && playMode != oldPlayMode) {
// if settings weren't explicitly modified, auto-switch to live mode settings and sort for
// any pre-selected race; we need to copy the previously selected race columns to the new RaceColumnSelection
@@ -3035,6 +3035,9 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
if (timer != null) {
timer.removeTimeListener(this);
}
if(leaderboardUpdateListener != null) {
leaderboardUpdateListener.clear();
}
}
protected Timer getTimer() {
@@ -45,7 +45,7 @@ public class LeaderboardViewer extends AbstractLeaderboardViewer {
boolean hideToolbar, boolean autoExpandLastRaceColumn, boolean showCharts, DetailType chartDetailType,
boolean showOverallLeaderboard) {
super(competitorSelectionModel, asyncActionsExecutor, timer, stringMessages, hideToolbar, new LeaderboardPanel(
sailingService, asyncActionsExecutor, leaderboardSettings, preselectedRace,
sailingService, asyncActionsExecutor, leaderboardSettings, preselectedRace != null, preselectedRace,
competitorSelectionModel, timer, leaderboardGroupName, leaderboardName, errorReporter,
stringMessages, userAgent, showRaceDetails, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, /* adjustTimerDelay */
/* raceTimesInfoProvider */null, autoExpandLastRaceColumn, true, /*autoApplyTopNFilter*/ false, false));
@@ -76,7 +76,7 @@ public class LeaderboardViewer extends AbstractLeaderboardViewer {
if(result.size() == 1) {
String overallLeaderboardName = result.get(0);
overallLeaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor,
leaderboardSettings, preselectedRace, competitorSelectionProvider, timer,
leaderboardSettings, preselectedRace != null, preselectedRace, competitorSelectionProvider, timer,
leaderboardGroupName, overallLeaderboardName, errorReporter, stringMessages, userAgent,
false, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, /* raceTimesInfoProvider */null,
false, /* adjustTimerDelay */ true, /*autoApplyTopNFilter*/ false, false);
@@ -45,7 +45,7 @@ public class MetaLeaderboardViewer extends AbstractLeaderboardViewer {
boolean showCharts, DetailType chartDetailType, boolean showSeriesLeaderboards) {
super(competitorSelectionModel, asyncActionsExecutor, timer, stringMessages, hideToolbar,
new LeaderboardPanel(sailingService, asyncActionsExecutor,
leaderboardSettings, preselectedRace, competitorSelectionModel, timer,
leaderboardSettings, preselectedRace != null, preselectedRace, competitorSelectionModel, timer,
leaderboardGroupName, metaLeaderboardName, errorReporter, stringMessages, userAgent,
showRaceDetails, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, /* raceTimesInfoProvider */null,
autoExpandLastRaceColumn, /* adjustTimerDelay */ true, /*autoApplyTopNFilter*/ false, false));
@@ -58,7 +58,7 @@ public class MetaLeaderboardViewer extends AbstractLeaderboardViewer {
multiCompetitorChart.setVisible(showCharts);
multiCompetitorChart.getElement().getStyle().setMarginTop(10, Unit.PX);
multiCompetitorChart.getElement().getStyle().setMarginBottom(10, Unit.PX);
multiLeaderboardPanel = new MultiLeaderboardPanel(sailingService, metaLeaderboardName, asyncActionsExecutor, timer,
multiLeaderboardPanel = new MultiLeaderboardPanel(sailingService, metaLeaderboardName, asyncActionsExecutor, timer, false /*isEmbedded*/,
preselectedLeaderboardName, preselectedRace, errorReporter, stringMessages,
userAgent, showRaceDetails, autoExpandLastRaceColumn);
multiLeaderboardPanel.setVisible(showSeriesLeaderboards);
@@ -19,6 +19,7 @@ import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.components.AbstractLazyComponent;
@@ -56,9 +57,12 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
private TabPanel leaderboardsTabPanel;
private Label leaderboardsLabel;
private final String metaLeaderboardName;
private final boolean isEmbedded;
public MultiLeaderboardPanel(SailingServiceAsync sailingService, String metaLeaderboardName, AsyncActionsExecutor asyncActionsExecutor, Timer timer,
String preselectedLeaderboardName, RaceIdentifier preselectedRace,
private List<LeaderboardUpdateListener> leaderboardUpdateListener;
public MultiLeaderboardPanel(SailingServiceAsync sailingService, String metaLeaderboardName, AsyncActionsExecutor asyncActionsExecutor,
Timer timer, boolean isEmbedded, String preselectedLeaderboardName, RaceIdentifier preselectedRace,
ErrorReporter errorReporter, StringMessages stringMessages,
UserAgentDetails userAgent, boolean showRaceDetails, boolean autoExpandLastRaceColumn) {
this.stringMessages = stringMessages;
@@ -69,12 +73,14 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
this.userAgent = userAgent;
this.showRaceDetails = showRaceDetails;
this.timer = timer;
this.isEmbedded = isEmbedded;
this.selectedLeaderboardName = preselectedLeaderboardName;
selectedLeaderboardFlowPanel = null;
selectedLeaderboardPanel = null;
leaderboardNamesAndDisplayNames = new ArrayList<Util.Pair<String, String>>();
leaderboardNamesAndSettings = new HashMap<String, LeaderboardSettings>();
leaderboardUpdateListener = new ArrayList<LeaderboardUpdateListener>();
}
private LeaderboardSettings getOrCreateLeaderboardSettings(String leaderboardName, LeaderboardSettings currentLeaderboardSettings) {
@@ -94,11 +100,13 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
public Widget createWidget() {
mainPanel = new VerticalPanel();
if(!isEmbedded) {
leaderboardsLabel = new Label(stringMessages.regattaLeaderboards());
leaderboardsLabel.setVisible(false);
leaderboardsLabel.getElement().getStyle().setFontWeight(FontWeight.BOLD);
leaderboardsLabel.getElement().getStyle().setMargin(5, Unit.PX);
mainPanel.add(leaderboardsLabel);
}
leaderboardsTabPanel = new TabPanel();
leaderboardsTabPanel.setVisible(false);
@@ -142,6 +150,10 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
selectedLeaderboardPanel.updateSettings(newSettings);
}
public void addLeaderboardUpdateListener(LeaderboardUpdateListener listener) {
this.leaderboardUpdateListener.add(listener);
}
public void setLeaderboardNames(List<Util.Pair<String, String>> newLeaderboardNamesAndDisplayNames) {
leaderboardNamesAndDisplayNames.clear();
leaderboardNamesAndDisplayNames.addAll(newLeaderboardNamesAndDisplayNames);
@@ -184,9 +196,11 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
}
leaderboardsTabPanel.setVisible(leaderboardCount > 0);
if(!isEmbedded) {
leaderboardsLabel.setVisible(leaderboardCount > 0);
}
}
}
private void updateSelectedLeaderboard(String newSelectedLeaderboardName, int newTabIndex) {
if(newSelectedLeaderboardName != null) {
@@ -199,12 +213,16 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
selectedLeaderboardFlowPanel = (FlowPanel) leaderboardsTabPanel.getWidget(newTabIndex);
LeaderboardSettings newLeaderboardSettings = getOrCreateLeaderboardSettings(newSelectedLeaderboardName, leaderboardNamesAndSettings.get(selectedLeaderboardName));
selectedLeaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor, newLeaderboardSettings,
selectedLeaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor, newLeaderboardSettings, isEmbedded,
/* preselectedRace*/ null, new CompetitorSelectionModel(true), timer,
null, newSelectedLeaderboardName, errorReporter, stringMessages, userAgent,
showRaceDetails, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, /* raceTimesInfoProvider */null,
false, /* adjustTimerDelay */ true, /*autoApplyTopNFilter*/ false, false);
selectedLeaderboardFlowPanel.add(selectedLeaderboardPanel);
for(LeaderboardUpdateListener listener: leaderboardUpdateListener) {
selectedLeaderboardPanel.addLeaderboardUpdateListener(listener);
}
} else {
if(selectedLeaderboardPanel != null && selectedLeaderboardFlowPanel != null) {
selectedLeaderboardPanel.removeAllListeners();
@@ -276,7 +276,7 @@ public class RaceBoardPanel extends SimplePanel implements RegattasDisplayer, Ra
/* nameOfRaceToSort */ selectedRaceIdentifier.getRaceName(),
/* nameOfRaceColumnToShow */ null, /* nameOfRaceToShow */ selectedRaceIdentifier.getRaceName(),
new ExplicitRaceColumnSelectionWithPreselectedRace(selectedRaceIdentifier), /* showRegattaRank */ false);
return new LeaderboardPanel(sailingService, asyncActionsExecutor, leaderBoardSettings, selectedRaceIdentifier,
return new LeaderboardPanel(sailingService, asyncActionsExecutor, leaderBoardSettings, selectedRaceIdentifier != null, selectedRaceIdentifier,
competitorSelectionModel, timer, leaderboardGroupName, leaderboardName, errorReporter, stringMessages,
userAgent, /* showRaceDetails */ true, competitorSearchTextBox,
/* showSelectionCheckbox */ true, raceTimesInfoProvider, /* autoExpandLastRaceColumn */ false,
@@ -250,7 +250,7 @@ public class RegattaOverviewPanel extends SimplePanel {
leaderboardsTabPanel.clear();
for (StrippedLeaderboardDTO leaderboard : result) {
LeaderboardPanel leaderboardPanel = new LeaderboardPanel(sailingService,
new AsyncActionsExecutor(), leaderboardSettings,
new AsyncActionsExecutor(), leaderboardSettings, false,
/*preSelectedRace*/null,
competitorSelectionProvider,
null, leaderboard.name,
@@ -196,7 +196,7 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
new AsyncCallback<List<RegattaOverviewEntryDTO>>() {
@Override
public void onFailure(Throwable cause) {
errorReporter.reportError(cause.getMessage());
// ignore errors as state can recover
}
@Override
@@ -1013,7 +1013,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
raceRecord.getTrackingStartTime().asDate(),
raceRecord
.getTrackingEndTime().asDate(), raceRecord.getRaceStartTime().asDate(),
raceRecord.getBoatClassNames(), raceRecord.getRaceStatus(), raceRecord.getJsonURL().toString(),
raceRecord.getBoatClassNames(), raceRecord.getRaceStatus(), raceRecord.getRaceVisibility(), raceRecord.getJsonURL().toString(),
hasRememberedRegatta(raceRecord.getID())));
}
return new com.sap.sse.common.Util.Pair<String, List<TracTracRaceRecordDTO>>(raceRecords.getA(), result);
@@ -1057,7 +1057,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
MongoRaceLogStoreFactory.INSTANCE.getMongoRaceLogStore(mongoObjectFactory, domainObjectFactory),
RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, simulateWithStartTimeNow,
tracTracUsername, tracTracPassword,
record.getRaceStatus());
record.getRaceStatus(), record.getRaceVisibility());
if (trackWind) {
new Thread("Wind tracking starter for race " + record.getEventName() + "/" + record.getName()) {
public void run() {
@@ -10,12 +10,13 @@ public class TracTracRaceRecordDTO extends AbstractRaceRecordDTO {
public Date trackingEndTime;
public Date raceStartTime;
public String raceStatus;
public String raceVisibility;
public Iterable<String> boatClassNames;
public TracTracRaceRecordDTO() {}
public TracTracRaceRecordDTO(String id, String regattaName, String name, Date trackingStartTime,
Date trackingEndTime, Date raceStartTime, Iterable<String> boatClassNames, String status, String jsonUrl, boolean hasRememberedRegatta) {
Date trackingEndTime, Date raceStartTime, Iterable<String> boatClassNames, String status, String visibility, String jsonUrl, boolean hasRememberedRegatta) {
super(name, hasRememberedRegatta);
this.regattaName = regattaName;
this.id = id;
@@ -24,6 +25,7 @@ public class TracTracRaceRecordDTO extends AbstractRaceRecordDTO {
this.raceStartTime = raceStartTime;
this.boatClassNames = boatClassNames;
this.raceStatus = status;
this.raceVisibility = visibility;
this.jsonURL = jsonUrl;
}
@@ -113,7 +113,7 @@ public class TVViewController implements RaceTimesInfoProviderListener {
private LeaderboardPanel createLeaderboardPanel(String leaderboardGroupName, String leaderboardName, boolean showRaceDetails) {
CompetitorSelectionModel selectionModel = new CompetitorSelectionModel(/* hasMultiSelection */ true);
LeaderboardPanel leaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor,
leaderboardSettings,
leaderboardSettings, false,
/* preSelectedRace */null, selectionModel, leaderboardTimer, leaderboardGroupName, leaderboardName,
errorReporter, stringMessages, userAgent, showRaceDetails, /* competitorSearchTextBox */ null, /* showRegattaRank */
/* showSelectionCheckbox */false, /* raceTimesInfoProvider */null, false, /* autoExpandLastRaceColumn */
@@ -135,12 +135,13 @@ figcaption {
outline: none;
text-decoration: none;
}
.navbar_buttonactive {
.navbar_buttonactive,
.navbar_buttonactive:focus {
color: #fff;
background-color: #999;
background-color: #f0ab00;
}
.navbar_buttonactive:hover {
background-color: #8a8a8a;
background-color: #d89a00;
}
.button {
font-size: 15px;
@@ -83,7 +83,7 @@ public class TrackRaceReplicationTest extends AbstractServerReplicationTest {
});
trackingParams = com.sap.sailing.domain.tractracadapter.DomainFactory.INSTANCE.createTrackingConnectivityParameters(paramURL,
liveURI, storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, /* delayToLiveInMillis */
0l, /* simulateWithStartTimeNow */false, EmptyRaceLogStore.INSTANCE, tracTracUsername, tracTracPassword, "");
0l, /* simulateWithStartTimeNow */false, EmptyRaceLogStore.INSTANCE, tracTracUsername, tracTracPassword, "", "");
}
private void startTracking() throws Exception, InterruptedException {
@@ -70,7 +70,7 @@ public class RaceTrackerTest {
tracTracAdapterFactory = new TracTracAdapterFactoryImpl();
raceHandle = tracTracAdapterFactory.getOrCreateTracTracAdapter(service.getBaseDomainFactory())
.addTracTracRace(service, paramUrl, liveUri, storedUri, courseDesignUpdateUri, EmptyRaceLogStore.INSTANCE,
/* timeoutInMilliseconds */60000, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS);
/* timeoutInMilliseconds */60000, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY);
logger.info("Calling raceHandle.getRaces()");
RaceDefinition race = raceHandle.getRace(); // wait for RaceDefinition to be completely wired in Regatta
logger.info("Obtained race: "+race);
@@ -127,7 +127,8 @@ public class RaceTrackerTest {
service.removeRegatta(raceHandle.getRegatta());
RaceHandle myRaceHandle = tracTracAdapterFactory.getOrCreateTracTracAdapter(service.getBaseDomainFactory())
.addTracTracRace(service, paramUrl, liveUri, storedUri, courseDesignUpdateUri, EmptyRaceLogStore.INSTANCE,
/* timeoutInMilliseconds */60000, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS);
/* timeoutInMilliseconds */60000, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS,
TracTracConnectionConstants.ONLINE_VISIBILITY);
TrackedRegatta newTrackedRegatta = myRaceHandle.getTrackedRegatta();
assertNotSame(oldTrackedRegatta, newTrackedRegatta);
TrackedRace newTrackedRace = getTrackedRace(newTrackedRegatta);
@@ -153,7 +154,8 @@ public class RaceTrackerTest {
TrackedRace oldTrackedRace = getTrackedRace(oldTrackedRegatta);
RaceHandle myRaceHandle = tracTracAdapterFactory.getOrCreateTracTracAdapter(service.getBaseDomainFactory())
.addTracTracRace(service, paramUrl, liveUri, storedUri, courseDesignUpdateUri, EmptyRaceLogStore.INSTANCE,
/* timeoutInMilliseconds */60000, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS);
/* timeoutInMilliseconds */60000, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS,
TracTracConnectionConstants.ONLINE_VISIBILITY);
TrackedRegatta newTrackedEvent = myRaceHandle.getTrackedRegatta();
TrackedRace newTrackedRace = getTrackedRace(newTrackedEvent);
// expecting a new tracked race to be created when starting over with tracking
@@ -82,7 +82,8 @@ public class SimulatorUtils {
String tractracPassword = "";
RaceHandle raceHandle = tracTracAdapterFactory.getOrCreateTracTracAdapter(service.getBaseDomainFactory())
.addTracTracRace(service, paramURL, liveURI, storedURI, null, raceLogStore,
timeoutInMilliseconds, tractracUsername, tractracPassword, TracTracConnectionConstants.ONLINE_STATUS);
timeoutInMilliseconds, tractracUsername, tractracPassword, TracTracConnectionConstants.ONLINE_STATUS,
TracTracConnectionConstants.ONLINE_VISIBILITY);
return raceHandle;
}
@@ -229,11 +229,21 @@ public class LeaderboardData extends ExportAction {
addNamedElementWithValue(raceElement, "end_of_tracking_time_as_millis", handleValue(race.getEndOfTracking()));
LineDetails start = race.getStartLine(race.getStartOfTracking());
if (start != null) {
if (start.getLength() != null) {
addNamedElementWithValue(raceElement, "start_line_length_in_meters", start.getLength().getMeters());
} else {
addNamedElementWithValue(raceElement, "start_line_length_in_meters", 0);
}
Distance advantage = start.getAdvantage();
addNamedElementWithValue(raceElement, "start_advantage_in_meters", advantage != null ? advantage.getMeters() : 0);
NauticalSide nauticalSideWhileApproaching = start.getAdvantageousSideWhileApproachingLine();
addNamedElementWithValue(raceElement, "advantageous_side_while_approaching_start_line", nauticalSideWhileApproaching != null ? nauticalSideWhileApproaching.name() : "UNKNOWN");
} else {
addNamedElementWithValue(raceElement, "start_line_length_in_meters", 0);
addNamedElementWithValue(raceElement, "start_advantage_in_meters", 0);
addNamedElementWithValue(raceElement, "advantageous_side_while_approaching_start_line", "UNKNOWN");
}
Distance raceCourseLength = race.getCourseLength();
if (raceCourseLength == null) {
@@ -421,8 +431,10 @@ public class LeaderboardData extends ExportAction {
}
Tack startTack = race.getTack(competitor, race.getStartOfRace());
addNamedElementWithValue(competitorRaceDataElement, "start_tack", startTack != null ? startTack.name() : "UNKNOWN");
addNamedElementWithValue(competitorRaceDataElement, "starboard_mark_name", race.getStartLine(race.getStartOfRace()).getStarboardMarkWhileApproachingLine().getName());
addNamedElementWithValue(competitorRaceDataElement, "distance_to_start_line_on_race_start_in_meters", race.getDistanceToStartLine(competitor, race.getStartOfRace()).getMeters());
LineDetails startLine = race.getStartLine(race.getStartOfRace());
addNamedElementWithValue(competitorRaceDataElement, "starboard_mark_name", startLine != null ? startLine.getStarboardMarkWhileApproachingLine().getName() : "UNKNOWN");
Distance distanceToStartLine = race.getDistanceToStartLine(competitor, race.getStartOfRace());
addNamedElementWithValue(competitorRaceDataElement, "distance_to_start_line_on_race_start_in_meters", distanceToStartLine != null ? distanceToStartLine.getMeters() : 0);
Speed estimatedSpeedAtStartSignal = race.getTrack(competitor).getEstimatedSpeed(race.getStartOfRace());
if (estimatedSpeedAtStartSignal == null) {
raceConfidenceAndErrorMessages = updateConfidence("Competitor " + competitor.getName() + " has no valid speed at start for this race!", 0.1, raceConfidenceAndErrorMessages);