Merge branch 'master' into bug3023

This commit is contained in:
Frederik Petersen committed 2015-07-20 17:42:51 +02:00
commit dfbffe65d5
161 files changed
+4920 -1307

No files matched your search

@@ -16,11 +16,9 @@ public enum RaceLogRaceStatus {
}
public static boolean isActive(RaceLogRaceStatus status) {
if (status == null) {
return false;
}
return status != null &&
(status.equals(PRESCHEDULED) || status.equals(SCHEDULED) || status.equals(STARTPHASE) || status.equals(RUNNING) || status.equals(FINISHING));
return status.equals(SCHEDULED) || status.equals(STARTPHASE) || status.equals(RUNNING) || status.equals(FINISHING);
}
public int getOrderNumber() {
@@ -4,6 +4,7 @@ import java.io.Serializable;
import java.util.List;
import java.util.UUID;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationMatcher;
import com.sap.sailing.domain.common.MarkType;
import com.sap.sailing.domain.common.PassingInstruction;
@@ -108,4 +109,6 @@ public interface SharedDomainFactory extends CompetitorFactory {
ControlPointWithTwoMarks getOrCreateControlPointWithTwoMarks(Serializable id, String name, Mark left, Mark right);
ControlPointWithTwoMarks getOrCreateControlPointWithTwoMarks(String id, String name, Mark left, Mark right);
RaceLogResolver getRaceLogResolver();
}
@@ -16,6 +16,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CompetitorStore;
@@ -106,14 +107,18 @@ public class SharedDomainFactoryImpl implements SharedDomainFactory {
private final Set<String> mayStartWithNoUpwindLeg;
private final RaceLogResolver raceLogResolver;
/**
* Uses a transient competitor store
* @param raceLogResolver TODO
*/
public SharedDomainFactoryImpl() {
this(new TransientCompetitorStoreImpl());
public SharedDomainFactoryImpl(RaceLogResolver raceLogResolver) {
this(new TransientCompetitorStoreImpl(), raceLogResolver);
}
public SharedDomainFactoryImpl(CompetitorStore competitorStore) {
public SharedDomainFactoryImpl(CompetitorStore competitorStore, RaceLogResolver raceLogResolver) {
this.raceLogResolver = raceLogResolver;
waypointCacheReferenceQueue = new ReferenceQueue<Waypoint>();
nationalityCache = new HashMap<String, Nationality>();
markCache = new HashMap<Serializable, Mark>();
@@ -386,4 +391,8 @@ public class SharedDomainFactoryImpl implements SharedDomainFactory {
return markCache.get(markIdCache.get(toStringRepresentationOfID));
}
@Override
public RaceLogResolver getRaceLogResolver() {
return raceLogResolver;
}
}
@@ -17,7 +17,7 @@ public class DomainFactoryTest {
@Before
public void before() {
com.sap.sailing.domain.base.DomainFactory baseDomainFactory = new com.sap.sailing.domain.base.impl.DomainFactoryImpl();
com.sap.sailing.domain.base.DomainFactory baseDomainFactory = new com.sap.sailing.domain.base.impl.DomainFactoryImpl((srlid)->null);
swissTimingDomainFactory = new com.sap.sailing.domain.swisstimingadapter.impl.DomainFactoryImpl(
baseDomainFactory);
}
@@ -63,7 +63,7 @@ public class CompetitorListenerTest extends AbstractSerializationTest {
@Before
public void setUp() {
baseDomainFactory = new DomainFactoryImpl();
baseDomainFactory = new DomainFactoryImpl((srlid)->null);
competitor = TrackBasedTest.createCompetitor("Hasso");
nationalityChanged = false;
whatChangedNationality = null;
@@ -251,7 +251,7 @@ public class CompetitorListenerTest extends AbstractSerializationTest {
@Test
public void testCompetitorSerializationLosesAllExternalListeners() throws ClassNotFoundException, IOException {
DomainFactory baseDomainFactory = new DomainFactoryImpl();
DomainFactory baseDomainFactory = new DomainFactoryImpl((srlid)->null);
DynamicCompetitor clonedCompetitor = cloneBySerialization(competitor, baseDomainFactory);
clonedCompetitor.setName("Dr. Hasso Plattner");
clonedCompetitor.getBoat().setSailId("POR 40");
@@ -80,7 +80,7 @@ public class CourseUpdateTest extends AbstractTracTracLiveTest {
@Before
public void setUp() throws MalformedURLException, IOException, InterruptedException, URISyntaxException, SubscriberInitializationException, ParseException, CreateModelException {
super.setUp();
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl());
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl((srlid)->null));
domainRegatta = domainFactory.getOrCreateDefaultRegatta(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
getTracTracRace(), /* trackedRegattaRegistry */ null);
trackedRegatta = new DynamicTrackedRegattaImpl(domainRegatta);
@@ -118,7 +118,7 @@ public class LeaderboardCourseChangeTest {
ThresholdBasedResultDiscardingRule rule = new ThresholdBasedResultDiscardingRuleImpl(ruleRaw);
Leaderboard leaderboard = new RegattaLeaderboardImpl(mockedRegatta, rule);
DomainFactory baseDomainFactory = new DomainFactoryImpl();
DomainFactory baseDomainFactory = new DomainFactoryImpl((srlid)->null);
LeaderboardDTO leaderboardDTO = leaderboard.getLeaderboardDTO(timePoint, raceColumnNames, false,
trackedRegattaRegistry, baseDomainFactory, /* fillNetPointsUncorrected */ false);
@@ -39,7 +39,7 @@ public class MultipleClassesInRegattaTest {
@Before
public void setUp() {
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl());
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl((srlid)->null));
}
@Test
@@ -59,7 +59,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
*/
@Test
public void testHashCodeOfSerializedPairIsConsistent() throws ClassNotFoundException, IOException {
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
final Throwable s1 = new Throwable();
final Throwable s2 = new Throwable();
com.sap.sse.common.Util.Pair<Throwable, Throwable> p =
@@ -91,7 +91,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
*/
@Test
public void testSerializingIntArray() throws ClassNotFoundException, IOException {
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
int[] intArray = new int[] { 5, 8 };
int[] clone = cloneBySerialization(intArray, receiverDomainFactory);
assertTrue(Arrays.equals(intArray, clone));
@@ -99,7 +99,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test
public void testSerializingEventWithLeaderboardGroups() throws ClassNotFoundException, IOException {
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
Event e = new EventImpl("Event Name", MillisecondsTimePoint.now(), MillisecondsTimePoint.now().plus(
Duration.ONE_DAY.times(10)), "At Home", /* is public */true, UUID.randomUUID());
LeaderboardGroup lg1 = new LeaderboardGroupImpl("LG1", "LG1 Description", /* displayName */ null, /* displayGroupsInReverseOrder */ false, Collections.<Leaderboard> emptyList());
@@ -117,7 +117,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
*/
@Test
public void testSerializingResultDiscardingRuleImpl() throws ClassNotFoundException, IOException {
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
ThresholdBasedResultDiscardingRuleImpl rdri = new ThresholdBasedResultDiscardingRuleImpl(new int[] { 5, 8 });
ThresholdBasedResultDiscardingRuleImpl clone = cloneBySerialization(rdri, receiverDomainFactory);
assertTrue(Arrays.equals(rdri.getDiscardIndexResultsStartingWithHowManyRaces(),
@@ -136,7 +136,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
final double FACTOR = 2.0;
overallLeaderboard.getRaceColumnByName("Test Leaderboard").setFactor(FACTOR);
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
LeaderboardGroup clone = cloneBySerialization(leaderboardGroup, receiverDomainFactory);
assertEquals(FACTOR, overallLeaderboard.getRaceColumnByName("Test Leaderboard").getFactor(), 0.00000001);
assertEquals(FACTOR, clone.getOverallLeaderboard().getRaceColumnByName("Test Leaderboard").getFactor(), 0.00000001);
@@ -144,8 +144,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test
public void testIdentityStabilityOfMarkSerialization() throws ClassNotFoundException, IOException {
DomainFactory senderDomainFactory = new DomainFactoryImpl();
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
DomainFactory senderDomainFactory = new DomainFactoryImpl((srlid)->null);
DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
Mark sendersMark1 = senderDomainFactory.getOrCreateMark("TestBuoy1");
Mark receiversMark1 = cloneBySerialization(sendersMark1, receiverDomainFactory);
Mark receiversSecondCopyOfMark1 = cloneBySerialization(sendersMark1, receiverDomainFactory);
@@ -154,8 +154,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test
public void testIdentityStabilityOfWaypointSerialization() throws ClassNotFoundException, IOException {
DomainFactory senderDomainFactory = new DomainFactoryImpl();
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
DomainFactory senderDomainFactory = new DomainFactoryImpl((srlid)->null);
DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
Mark sendersMark1 = senderDomainFactory.getOrCreateMark("TestBuoy1");
Waypoint sendersWaypoint1 = senderDomainFactory.createWaypoint(sendersMark1, /*passingInstruction*/null);
Waypoint receiversWaypoint1 = cloneBySerialization(sendersWaypoint1, receiverDomainFactory);
@@ -165,8 +165,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test
public void testIdentityStabilityOfBoatClassSerialization() throws ClassNotFoundException, IOException {
DomainFactory senderDomainFactory = new DomainFactoryImpl();
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
DomainFactory senderDomainFactory = new DomainFactoryImpl((srlid)->null);
DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
BoatClass sendersBoatClass1 = senderDomainFactory.getOrCreateBoatClass("49er", /* typicallyStartsUpwind */ true);
BoatClass receiversBoatClass1 = cloneBySerialization(sendersBoatClass1, receiverDomainFactory);
BoatClass receiversSecondCopyOfBoatClass1 = cloneBySerialization(sendersBoatClass1, receiverDomainFactory);
@@ -175,8 +175,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test
public void testIdentityStabilityOfNationalitySerialization() throws ClassNotFoundException, IOException {
DomainFactory senderDomainFactory = new DomainFactoryImpl();
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
DomainFactory senderDomainFactory = new DomainFactoryImpl((srlid)->null);
DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
Nationality sendersNationality1 = senderDomainFactory.getOrCreateNationality("GER");
Nationality receiversNationality1 = cloneBySerialization(sendersNationality1, receiverDomainFactory);
Nationality receiversSecondCopyOfNationality1 = cloneBySerialization(sendersNationality1, receiverDomainFactory);
@@ -185,8 +185,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test
public void testIdentityStabilityOfCompetitorSerialization() throws ClassNotFoundException, IOException {
DomainFactory senderDomainFactory = new DomainFactoryImpl();
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
DomainFactory senderDomainFactory = new DomainFactoryImpl((srlid)->null);
DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
String competitorName = "Tina Maximiliane Lutz";
Competitor sendersCompetitor1 = new CompetitorImpl(123, competitorName, Color.RED, null, null, new TeamImpl("STG", Collections.singleton(
new PersonImpl(competitorName, senderDomainFactory.getOrCreateNationality("GER"),
@@ -201,8 +201,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test
public void ensureSameObjectWrittenTwiceComesOutIdentical() throws ClassNotFoundException, IOException {
final DomainFactoryImpl senderDomainFactory = new DomainFactoryImpl();
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
final DomainFactoryImpl senderDomainFactory = new DomainFactoryImpl((srlid)->null);
DomainFactory receiverDomainFactory = new DomainFactoryImpl((srlid)->null);
Nationality n = senderDomainFactory.getOrCreateNationality("GER");
Object[] copies = cloneManyBySerialization(receiverDomainFactory, n, n);
assertEquals(2, copies.length);
@@ -86,7 +86,7 @@ public abstract class OnlineTracTracBasedTest extends AbstractTracTracLiveTest {
@Before
public void setUp() throws MalformedURLException, IOException, InterruptedException, URISyntaxException, ParseException, SubscriberInitializationException, CreateModelException {
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl());
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl((srlid)->null));
// keep superclass implementation from automatically setting up for a Weymouth event and force subclasses
// to select a race
}
@@ -219,7 +219,7 @@ public abstract class OnlineTracTracBasedTest extends AbstractTracTracLiveTest {
throws FileNotFoundException, MalformedURLException, URISyntaxException, SubscriberInitializationException, CreateModelException {
super.setUp(paramUrl, liveUri, storedUri);
if (domainFactory == null) {
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl());
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl((srlid)->null));
}
domainEvent = domainFactory.getOrCreateDefaultRegatta(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
getTracTracRace(), /* trackedRegattaRegistry */ null);
@@ -38,7 +38,7 @@ public class UnicodeCharactersInCompetitorNamesTest {
@Before
public void setUp() {
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl());
domainFactory = new DomainFactoryImpl(new com.sap.sailing.domain.base.impl.DomainFactoryImpl((srlid)->null));
}
public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException, CreateModelException, SubscriberInitializationException {
@@ -23,6 +23,7 @@ import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RegattaListener;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithConfidence;
import com.sap.sailing.domain.base.Waypoint;
@@ -75,6 +76,7 @@ import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sailing.domain.tracking.impl.WindTrackImpl;
import com.sap.sse.common.Duration;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -985,4 +987,9 @@ public class MockedTrackedRace implements DynamicTrackedRace {
public RankingMetric getRankingMetric() {
return null;
}
@Override
public IsManagedByCache<SharedDomainFactory> resolve(SharedDomainFactory domainFactory) {
return this;
}
}
@@ -14,6 +14,7 @@ import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithConfidence;
import com.sap.sailing.domain.base.Waypoint;
@@ -57,6 +58,7 @@ import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sse.common.Duration;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -646,4 +648,9 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
@Override
public void detachRaceExecutionOrderProvider(RaceExecutionOrderProvider raceExecutionOrderProvider) {
}
@Override
public IsManagedByCache<SharedDomainFactory> resolve(SharedDomainFactory domainFactory) {
return this;
}
}
@@ -31,7 +31,7 @@ public interface DomainFactory extends SharedDomainFactory {
* the <code>RacingEventService.getBaseDomainFactory()</code> instead which should be the single instance used
* by all other services linked to the <code>RacingEventService</code>.
*/
static DomainFactory INSTANCE = new DomainFactoryImpl();
static DomainFactory INSTANCE = new DomainFactoryImpl((srlid)->null);
MarkPassing createMarkPassing(TimePoint timePoint, Waypoint waypoint, Competitor competitor);
@@ -8,6 +8,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CompetitorStore;
import com.sap.sailing.domain.base.DomainFactory;
@@ -67,12 +68,12 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain
/**
* Uses a transient competitor store
*/
public DomainFactoryImpl() {
super(new TransientCompetitorStoreImpl());
public DomainFactoryImpl(RaceLogResolver raceLogResolver) {
super(new TransientCompetitorStoreImpl(), raceLogResolver);
}
public DomainFactoryImpl(CompetitorStore competitorStore) {
super(competitorStore);
public DomainFactoryImpl(CompetitorStore competitorStore, RaceLogResolver raceLogResolver) {
super(competitorStore, raceLogResolver);
}
@Override
@@ -1670,8 +1670,9 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
result.estimatedTimeToNextWaypointInSeconds = estimatedTimeToNextMarkInSeconds==null?null:estimatedTimeToNextMarkInSeconds.asSeconds();
result.timeInMilliseconds = time.asMillis();
result.finished = trackedLeg.hasFinishedLeg(timePoint);
final TimePoint legFinishTime = trackedLeg.getFinishTime();
result.correctedTotalTime = trackedLeg.hasStartedLeg(timePoint) ? trackedLeg.getTrackedLeg().getTrackedRace().getRankingMetric().getCorrectedTime(trackedLeg.getCompetitor(),
trackedLeg.hasFinishedLeg(timePoint) ? trackedLeg.getFinishTime() : timePoint, cache) : null;
trackedLeg.hasFinishedLeg(timePoint) ? legFinishTime : timePoint, cache) : null;
// fetch the leg gap in own corrected time from the ranking metric
final Duration gapToLeaderInOwnTime = trackedLeg.getTrackedLeg().getTrackedRace().getRankingMetric().
getLegGapToLegLeaderInOwnTime(trackedLeg, timePoint, rankingInfo, cache);
@@ -1721,8 +1722,8 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
case TACK:
case JIBE:
case PENALTY_CIRCLE:
if (!maneuver.getTimePoint().before(startOfLeg) && (!trackedLeg.hasFinishedLeg(timePoint) ||
maneuver.getTimePoint().before(trackedLeg.getFinishTime()))) {
if (!maneuver.getTimePoint().before(startOfLeg) && (legFinishTime == null || legFinishTime.after(timePoint) ||
maneuver.getTimePoint().before(legFinishTime))) {
if (maneuver.getManeuverLoss() != null) {
result.numberOfManeuvers.put(maneuver.getType(),
result.numberOfManeuvers.get(maneuver.getType()) + 1);
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.leaderboard.impl;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import com.sap.sailing.domain.base.Competitor;
@@ -43,7 +44,7 @@ public class PerSeriesResultDiscardingRuleImpl implements ResultDiscardingRule {
}
private Iterable<RaceColumn> getColumnsToConsiderInSeries(Series series, Iterable<RaceColumn> allRaceColumnsToConsider) {
Set<RaceColumn> result = new HashSet<>();
Set<RaceColumn> result = new LinkedHashSet<>();
for (RaceColumn seriesColumn : series.getRaceColumns()) {
if (Util.contains(allRaceColumnsToConsider, seriesColumn)) {
result.add(seriesColumn);
@@ -593,7 +593,9 @@ public abstract class AbstractRankingMetric implements RankingMetric {
* For each leg the total windward distance sailed is limited to the leg's windward distance at its
* {@link TrackedLeg#getReferenceTimePoint() reference time point}. This ensures that significantly "overstaying" the lay lines
* doesn't let a competitor rank better than one who already passed the mark but traveled little windward distance in
* the next leg.
* the next leg.<p>
*
* If mark positions along the way are not known, the windward distance of those legs will be counted as 0.
*
* @param timePoint needed to determine <code>competitor</code>'s position at that time point; note that the
* time point for wind approximation is taken to be a reference time point selected based on the mark passings
@@ -620,7 +622,7 @@ public abstract class AbstractRankingMetric implements RankingMetric {
if (estimatedPosition != null) {
final Distance windwardDistanceFromLegStart = trackedLeg.getWindwardDistanceFromLegStart(estimatedPosition, cache);
final Distance legWindwardDistance = trackedLeg.getWindwardDistance(cache);
if (legWindwardDistance.compareTo(windwardDistanceFromLegStart) < 0) {
if (legWindwardDistance != null && legWindwardDistance.compareTo(windwardDistanceFromLegStart) < 0) {
d = d.add(legWindwardDistance);
} else {
// if the competitor is currently at the mark rounding, the windward distance within the leg may
@@ -632,7 +634,10 @@ public abstract class AbstractRankingMetric implements RankingMetric {
}
break;
} else {
d = d.add(trackedLeg.getWindwardDistance(cache));
final Distance legWindwardDistance = trackedLeg.getWindwardDistance(cache);
if (legWindwardDistance != null) {
d = d.add(legWindwardDistance);
}
}
}
}
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithConfidence;
import com.sap.sailing.domain.base.Waypoint;
@@ -46,6 +47,7 @@ import com.sap.sailing.domain.ranking.RankingMetric;
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
import com.sap.sse.common.Duration;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -64,7 +66,7 @@ import com.sap.sse.common.Util;
* @author Axel Uhl (d043530)
*
*/
public interface TrackedRace extends Serializable {
public interface TrackedRace extends Serializable, IsManagedByCache<SharedDomainFactory> {
final long MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS = 30000;
final long DEFAULT_LIVE_DELAY_IN_MILLISECONDS = 5000;
@@ -454,27 +454,30 @@ public class TrackedLegImpl implements TrackedLeg {
Distance getWindwardDistance(final Position pos1, final Position pos2, TimePoint at, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
Distance result;
try {
final LegType legType = cache.getLegType(this, at);
if (legType != LegType.REACHING) { // upwind or downwind
final Position effectivePosition = getEffectiveWindPosition(
() -> pos1.translateGreatCircle(pos1.getBearingGreatCircle(pos2), pos1.getDistance(pos2).scale(0.5)),
at, windPositionMode);
Wind wind = getTrackedRace().getWind(effectivePosition, at);
if (wind == null) {
result = pos2.alongTrackDistance(pos1, cache.getLegBearing(this, at));
if (pos1 == null || pos2 == null) {
result = null;
} else {
try {
final LegType legType = cache.getLegType(this, at);
if (legType != LegType.REACHING) { // upwind or downwind
final Position effectivePosition = getEffectiveWindPosition(() -> pos1.translateGreatCircle(
pos1.getBearingGreatCircle(pos2), pos1.getDistance(pos2).scale(0.5)), at, windPositionMode);
Wind wind = getTrackedRace().getWind(effectivePosition, at);
if (wind == null) {
result = pos2.alongTrackDistance(pos1, cache.getLegBearing(this, at));
} else {
Position projectionToLineThroughPos2 = pos1.projectToLineThrough(pos2, wind.getBearing());
result = pos2.alongTrackDistance(projectionToLineThroughPos2,
legType == LegType.UPWIND ? wind.getFrom() : wind.getBearing());
}
} else {
Position projectionToLineThroughPos2 = pos1.projectToLineThrough(pos2, wind.getBearing());
result = pos2.alongTrackDistance(projectionToLineThroughPos2,
legType == LegType.UPWIND ? wind.getFrom() : wind.getBearing());
// reaching leg, return distance projected onto leg's bearing
result = pos2.alongTrackDistance(pos1, cache.getLegBearing(this, at));
}
} else {
// reaching leg, return distance projected onto leg's bearing
} catch (NoWindException e) {
// no wind information; use along-track distance as fallback
result = pos2.alongTrackDistance(pos1, cache.getLegBearing(this, at));
}
} catch (NoWindException e) {
// no wind information; use along-track distance as fallback
result = pos2.alongTrackDistance(pos1, cache.getLegBearing(this, at));
}
return result;
}
@@ -54,6 +54,7 @@ import com.sap.sailing.domain.base.CourseListener;
import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithBearingWithConfidence;
import com.sap.sailing.domain.base.SpeedWithConfidence;
@@ -134,6 +135,7 @@ import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sse.common.Duration;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Timed;
@@ -1022,14 +1024,16 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
&& timePoint.compareTo(markPassings.last().getTimePoint()) > 0) {
// competitor has finished race at or before the requested time point; use time point of crossing the finish line
end = markPassings.last().getTimePoint();
} else if ((trackedLegOfCompetitor=getTrackedLeg(competitor, timePoint)) == null ||
(!trackedLegOfCompetitor.hasFinishedLeg(getEndOfTracking())
&& ((getEndOfTracking() != null && timePoint.after(getEndOfTracking()))
|| getStatus().getStatus() == TrackedRaceStatusEnum.FINISHED))) {
// If the race is no longer tracking and hence no more data can be expected, and the competitor
// hasn't finished a leg after the requested time point, no valid distance traveled can be determined
// for the competitor in this race the the time point requested
end = null;
} else {
final TimePoint endOfTracking = getEndOfTracking();
if ((trackedLegOfCompetitor=getTrackedLeg(competitor, timePoint)) == null ||
(endOfTracking != null && !trackedLegOfCompetitor.hasFinishedLeg(endOfTracking)
&& (timePoint.after(endOfTracking) || getStatus().getStatus() == TrackedRaceStatusEnum.FINISHED))) {
// If the race is no longer tracking and hence no more data can be expected, and the competitor
// hasn't finished a leg after the requested time point, no valid distance traveled can be determined
// for the competitor in this race the the time point requested
end = null;
}
}
if (end == null) {
result = null;
@@ -3692,4 +3696,14 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
public void setRaceLogResolver(RaceLogResolver raceLogResolver) {
this.raceLogResolver = raceLogResolver;
}
/**
* When given the opportunity to resolve after de-serialization, grabs the {@link RaceLogResolver} from the
* {@link SharedDomainFactory} because the field is transient and needs filling after de-serialization.
*/
@Override
public IsManagedByCache<SharedDomainFactory> resolve(SharedDomainFactory domainFactory) {
this.raceLogResolver = domainFactory.getRaceLogResolver();
return this;
}
}
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithConfidence;
import com.sap.sailing.domain.base.Waypoint;
@@ -63,6 +64,7 @@ import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sailing.domain.tracking.impl.WindTrackImpl;
import com.sap.sse.common.Duration;
import com.sap.sse.common.IsManagedByCache;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -783,4 +785,9 @@ public class MockedTrackedRace implements DynamicTrackedRace {
@Override
public void attachRaceExecutionProvider(RaceExecutionOrderProvider raceExecutionOrderProvider) {
}
@Override
public IsManagedByCache<SharedDomainFactory> resolve(SharedDomainFactory domainFactory) {
return this;
}
}
@@ -3,6 +3,7 @@
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
<listEntry value="com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart"/>
<listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/>
@@ -71,7 +72,7 @@
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -workDir &quot;${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9997 -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/EmbeddedMapAndWindChart com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Desktop com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -workDir &quot;${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/EmbeddedMapAndWindChart com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Desktop com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms1024m -Xmx3072m"/>
</launchConfiguration>
+76 -76
View File
@@ -1,76 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
<listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/>
<listEntry value="com.sap.sailing.gwt.ui.DataMining"/>
<listEntry value="com.sap.sailing.gwt.ui.LeaderboardEditing"/>
<listEntry value="com.sap.sailing.gwt.ui.Spectator"/>
<listEntry value="com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
<listEntry value="com.sap.sailing.gwt.ui.PolarSheets"/>
<listEntry value="com.sap.sailing.gwt.ui.Leaderboard"/>
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
<listEntry value="com.sap.sailing.gwt.ui.YoutubePopup"/>
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
<listEntry value="com.sap.sailing.gwt.home.Home"/>
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
</listAttribute>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.sap.sailing.gwt.ui"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.theme/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.googlecode.java-diff-utils/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.json.simple/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.expeditionconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.udpconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.mongodb/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.operationaltransformation/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.replication/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.moxieapps.gwt.highcharts/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.geocoding/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.google.gwt.osgi/lib/gwt-user.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sailing.gwt.ui&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.adminconsole/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
</launchConfiguration>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
<listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/>
<listEntry value="com.sap.sailing.gwt.ui.DataMining"/>
<listEntry value="com.sap.sailing.gwt.ui.LeaderboardEditing"/>
<listEntry value="com.sap.sailing.gwt.ui.Spectator"/>
<listEntry value="com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
<listEntry value="com.sap.sailing.gwt.ui.PolarSheets"/>
<listEntry value="com.sap.sailing.gwt.ui.Leaderboard"/>
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
<listEntry value="com.sap.sailing.gwt.ui.YoutubePopup"/>
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
<listEntry value="com.sap.sailing.gwt.home.Home"/>
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
</listAttribute>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.sap.sailing.gwt.ui"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.theme/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.googlecode.java-diff-utils/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.json.simple/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.expeditionconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.udpconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.mongodb/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.operationaltransformation/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.replication/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.moxieapps.gwt.highcharts/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.geocoding/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.google.gwt.osgi/lib/gwt-user.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sailing.gwt.ui&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.adminconsole/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
</launchConfiguration>
Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17.6 17.6"><circle fill="#8AB54E" cx="8.8" cy="8.8" r="8.8"/><path fill="#FFF" d="M12.9 6.1c-.4-.4-1-.4-1.4 0L7.9 9.6 6.5 8.2c-.4-.4-1-.4-1.4 0-.4.4-.4 1 0 1.4l2.1 2.1c.4.4 1 .4 1.4 0l4.2-4.2c.5-.4.5-1 .1-1.4z"/></svg>

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

@@ -36,6 +36,8 @@ import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO;
import com.sap.sailing.gwt.ui.shared.eventview.HasRegattaMetadata;
import com.sap.sailing.gwt.ui.shared.eventview.HasRegattaMetadata.RegattaState;
import com.sap.sailing.gwt.ui.shared.general.EventState;
import com.sap.sailing.gwt.ui.shared.media.MediaDTO;
import com.sap.sse.gwt.client.mvp.ErrorView;
import com.sap.sse.gwt.client.player.Timer;
@@ -306,6 +308,29 @@ public abstract class AbstractEventActivity<PLACE extends AbstractEventPlace> ex
}
return ctx.getEventDTO().isHasMedia();
}
@Override
public String getRegattaOverviewLink() {
String url = "RegattaOverview.html?ignoreLocalSettings=true&onlyrunningraces=false&event=" + getCtx().getEventId();
url += "&onlyracesofsameday=" + getCtx().getEventDTO().isRunning();
if(showRegattaMetadata()) {
url += "&regatta=" + getCtx().getRegattaId();
}
return url;
}
@Override
public boolean isEventOrRegattaLive() {
if(showRegattaMetadata()) {
if(ctx.getRegatta().getState() == RegattaState.RUNNING) {
return true;
}
if(ctx.getRegatta().getState() != RegattaState.UNKNOWN) {
return false;
}
}
return ctx.getEventDTO().getState() == EventState.RUNNING;
}
protected abstract EventView<PLACE, ?> getView();
@@ -49,7 +49,10 @@ public interface EventView<PLACE extends AbstractEventPlace, PRES extends EventV
PlaceNavigation<SeriesDefaultPlace> getCurrentEventSeriesNavigation();
boolean showRegattaMetadata();
boolean isEventOrRegattaLive();
HasRegattaMetadata getRegattaMetadata();
String getRegattaOverviewLink();
String getRaceViewerURL(StrippedLeaderboardDTO leaderboard, RaceDTO race);
@@ -1,10 +1,13 @@
package com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -12,18 +15,30 @@ import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.sap.sailing.gwt.common.client.SharedResources;
import com.sap.sailing.gwt.common.client.SharedResources.MainCss;
import com.sap.sailing.gwt.common.client.controls.tabbar.TabView;
import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView;
import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView.Presenter;
import com.sap.sailing.gwt.home.client.place.event.multiregatta.MultiregattaTabView;
import com.sap.sailing.gwt.home.client.place.event.overview.EventOverviewStage;
import com.sap.sailing.gwt.home.client.place.event.partials.eventregatta.EventRegattaList;
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.DropdownFilter;
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.DropdownFilter.DropdownFilterList;
import com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaList;
import com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaListStepsLegend;
import com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLive;
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshManager;
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshableWidget;
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.SortedSetResult;
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetLiveRacesForEventAction;
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetRegattaListViewAction;
import com.sap.sailing.gwt.ui.shared.dispatch.regatta.RegattaWithProgressDTO;
import com.sap.sse.common.Util.Triple;
/**
@@ -31,11 +46,22 @@ import com.sap.sse.common.Util.Triple;
*/
public class MultiregattaOverviewTabView extends Composite implements MultiregattaTabView<MultiregattaOverviewPlace> {
private Presenter currentPresenter;
public MultiregattaOverviewTabView() {
private static final MainCss MAIN_CSS = SharedResources.INSTANCE.mainCss();
interface MyBinder extends UiBinder<HTMLPanel, MultiregattaOverviewTabView> {
}
private static MyBinder ourUiBinder = GWT.create(MyBinder.class);
@UiField SimplePanel content;
@UiField(provided = true) EventOverviewStage stage;
@UiField(provided = true) RacesListLive racesListLive;
@UiField DivElement newContentContainerUi;
@UiField(provided = true) DropdownFilter<String> boatCategoryFilterUi;
@UiField MultiRegattaListStepsLegend regattaProgressLegendUi;
@UiField(provided = true) MultiRegattaList regattaListUi;
@UiField AnchorElement regattaOverviewLinkUi;
private Presenter currentPresenter;
@Override
public Class<MultiregattaOverviewPlace> getPlaceClassForActivation() {
@@ -54,78 +80,95 @@ public class MultiregattaOverviewTabView extends Composite implements Multiregat
@Override
public void start(MultiregattaOverviewPlace myPlace, AcceptsOneWidget contentArea) {
racesListLive = new RacesListLive(currentPresenter, true);
stage = new EventOverviewStage(currentPresenter);
racesListLive = new RacesListLive(currentPresenter, true);
MultiregattaOverviewRegattasTabViewRegattaFilterList regattaFilterList = new MultiregattaOverviewRegattasTabViewRegattaFilterList();
boatCategoryFilterUi = new DropdownFilter<String>(StringMessages.INSTANCE.allBoatClasses(), regattaFilterList);
regattaListUi = new MultiRegattaList(currentPresenter);
initWidget(ourUiBinder.createAndBindUi(this));
regattaOverviewLinkUi.setHref(currentPresenter.getRegattaOverviewLink());
regattaOverviewLinkUi.addClassName(currentPresenter.isEventOrRegattaLive() ? MAIN_CSS.buttonred() : MAIN_CSS.buttonprimary());
RefreshManager refreshManager = new RefreshManager(this, currentPresenter.getDispatch());
stage.setupRefresh(refreshManager);
refreshManager.add(racesListLive, new GetLiveRacesForEventAction(currentPresenter.getCtx().getEventDTO().getId()));
refreshManager.add(racesListLive.getRefreshable(), new GetLiveRacesForEventAction(currentPresenter.getCtx().getEventDTO().getId()));
if (ExperimentalFeatures.SHOW_NEW_REGATTA_LIST) {
refreshManager.add(regattaFilterList, new GetRegattaListViewAction(currentPresenter.getCtx().getEventDTO().getId()));
content.removeFromParent();
} else {
boatCategoryFilterUi.removeFromParent();
regattaProgressLegendUi.removeFromParent();
regattaListUi.removeFromParent();
newContentContainerUi.removeFromParent();
// TODO: understand, and than move this into appropiate place (probably context)
currentPresenter.ensureRegattaStructure(new AsyncCallback<List<RaceGroupDTO>>() {
@Override
public void onSuccess(List<RaceGroupDTO> raceGroups) {
if (raceGroups.size() > 0) {
initView();
} else {
// createEventWithoutRegattasView(event, panel);
}
}
@Override
public void onFailure(Throwable caught) {
// createErrorView(
// "Error while loading the regatta structure with service getRegattaStructureOfEvent()",
// caught, panel);
}
});
}
contentArea.setWidget(this);
}
// TODO: understand, and than move this into appropiate place (probably context)
currentPresenter.ensureRegattaStructure(new AsyncCallback<List<RaceGroupDTO>>() {
@Override
public void onSuccess(List<RaceGroupDTO> raceGroups) {
if (raceGroups.size() > 0) {
initView();
} else {
// createEventWithoutRegattasView(event, panel);
}
}
protected void initView() {
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> regattaStructure = getRegattaStructure();
EventRegattaList eventRegattaList = new EventRegattaList(regattaStructure, currentPresenter);
content.setWidget(eventRegattaList);
}
@Override
public void onFailure(Throwable caught) {
// createErrorView(
// "Error while loading the regatta structure with service getRegattaStructureOfEvent()",
// caught, panel);
}
});
}
protected void initView() {
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> regattaStructure = getRegattaStructure();
EventRegattaList eventRegattaList = new EventRegattaList(regattaStructure, currentPresenter);
content.setWidget(eventRegattaList);
}
private Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> getRegattaStructure() {
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> result = new HashMap<>();
Map<String, RaceGroupDTO> raceGroupsMap = new HashMap<>();
for (RaceGroupDTO raceGroup: currentPresenter.getCtx().getRaceGroups()) {
raceGroupsMap.put(raceGroup.getName(), raceGroup);
}
for (LeaderboardGroupDTO leaderboardGroup : currentPresenter.getCtx().getLeaderboardGroups()) {
for(StrippedLeaderboardDTO leaderboard: leaderboardGroup.getLeaderboards()) {
String leaderboardName = leaderboard.name;
result.put(leaderboardName, new Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>(raceGroupsMap.get(leaderboardName),
leaderboard, leaderboardGroup));
}
}
return result;
}
private Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> getRegattaStructure() {
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> result = new HashMap<>();
Map<String, RaceGroupDTO> raceGroupsMap = new HashMap<>();
for (RaceGroupDTO raceGroup : currentPresenter.getCtx().getRaceGroups()) {
raceGroupsMap.put(raceGroup.getName(), raceGroup);
}
for (LeaderboardGroupDTO leaderboardGroup : currentPresenter.getCtx().getLeaderboardGroups()) {
for (StrippedLeaderboardDTO leaderboard : leaderboardGroup.getLeaderboards()) {
String leaderboardName = leaderboard.name;
result.put(leaderboardName, new Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>(
raceGroupsMap.get(leaderboardName), leaderboard, leaderboardGroup));
}
}
return result;
}
@Override
public void stop() {
}
interface MyBinder extends UiBinder<HTMLPanel, MultiregattaOverviewTabView> {
}
private static MyBinder ourUiBinder = GWT.create(MyBinder.class);
@UiField SimplePanel content;
@UiField(provided = true) RacesListLive racesListLive;
@UiField(provided = true) EventOverviewStage stage;
@Override
public MultiregattaOverviewPlace placeToFire() {
return new MultiregattaOverviewPlace(currentPresenter.getCtx());
}
private class MultiregattaOverviewRegattasTabViewRegattaFilterList implements
DropdownFilterList<String>, RefreshableWidget<SortedSetResult<RegattaWithProgressDTO>> {
@Override
public void setData(SortedSetResult<RegattaWithProgressDTO> data, long nextUpdate, int updateNo) {
regattaListUi.setData(data, nextUpdate, updateNo);
boatCategoryFilterUi.updateFilterValues();
}
@Override
public Collection<String> getSelectableValues() {
return regattaListUi.getSelectableBoatCategories();
}
@Override
public void onSelectFilter(String value) {
regattaListUi.setVisibleBoatCategory(value);
}
}
}
@@ -1,15 +1,35 @@
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:r="urn:import:com.sap.sailing.gwt.home.client.place.event.partials.raceListLive"
xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.event.partials"
xmlns:o="urn:import:com.sap.sailing.gwt.home.client.place.event.overview">
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:style>
.legend_and_filter {
text-align: right;
}
.legend_and_filter > div, .legend_and_filter > a {
display: inline-block;
vertical-align: middle;
margin-left: 1.5em;
}
</ui:style>
<g:HTMLPanel>
<o:EventOverviewStage ui:field="stage" />
<div class="{res.mediaCss.grid}">
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
<r:RacesListLive ui:field="racesListLive" addStyleNames="{res.mainCss.spacermargin} {res.mainCss.spacermargintopmediumbig}" />
<div class="{res.mediaCss.grid}" ui:field="newContentContainerUi">
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {res.mainCss.spacermarginbottommedium}">
<p:raceListLive.RacesListLive ui:field="racesListLive" addStyleNames="{res.mainCss.spacermargin} {res.mainCss.spacermargintopmedium}" />
<div class="{res.mainCss.spacermargintopmedium} {style.legend_and_filter}">
<p:multiRegattaList.MultiRegattaListStepsLegend ui:field="regattaProgressLegendUi" />
<p:listNavigation.DropdownFilter ui:field="boatCategoryFilterUi" />
<a class="{res.mainCss.button} {res.mainCss.buttonstrong} {res.mainCss.buttonarrowrightwhite}"
target="_blank" ui:field="regattaOverviewLinkUi">
<ui:text from="{i18n.racesOverview}" />
</a>
</div>
<p:multiRegattaList.MultiRegattaList ui:field="regattaListUi" />
</div>
</div>
<g:SimplePanel ui:field="content" />
</g:HTMLPanel>
</ui:UiBinder>
</ui:UiBinder>
@@ -1,10 +1,13 @@
package com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -12,17 +15,29 @@ import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.sap.sailing.gwt.common.client.SharedResources;
import com.sap.sailing.gwt.common.client.SharedResources.MainCss;
import com.sap.sailing.gwt.common.client.controls.tabbar.TabView;
import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView;
import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView.Presenter;
import com.sap.sailing.gwt.home.client.place.event.multiregatta.MultiregattaTabView;
import com.sap.sailing.gwt.home.client.place.event.partials.eventregatta.EventRegattaList;
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.DropdownFilter;
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.DropdownFilter.DropdownFilterList;
import com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaList;
import com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaListStepsLegend;
import com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLive;
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshManager;
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshableWidget;
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.SortedSetResult;
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetLiveRacesForEventAction;
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetRegattaListViewAction;
import com.sap.sailing.gwt.ui.shared.dispatch.regatta.RegattaWithProgressDTO;
import com.sap.sse.common.Util.Triple;
/**
@@ -30,14 +45,22 @@ import com.sap.sse.common.Util.Triple;
*/
public class MultiregattaRegattasTabView extends Composite implements MultiregattaTabView<MultiregattaRegattasPlace> {
@UiField SimplePanel content;
@UiField(provided = true) RacesListLive racesListLive;
private Presenter currentPresenter;
public MultiregattaRegattasTabView() {
private static final MainCss MAIN_CSS = SharedResources.INSTANCE.mainCss();
interface MyBinder extends UiBinder<HTMLPanel, MultiregattaRegattasTabView> {
}
private static MyBinder ourUiBinder = GWT.create(MyBinder.class);
@UiField SimplePanel content;
@UiField DivElement newContentContainerUi;
@UiField(provided = true) RacesListLive racesListLiveUi;
@UiField(provided = true) DropdownFilter<String> boatCategoryFilterUi;
@UiField MultiRegattaListStepsLegend regattaProgressLegendUi;
@UiField(provided = true) MultiRegattaList regattaListUi;
@UiField AnchorElement regattaOverviewLinkUi;
private Presenter currentPresenter;
@Override
public Class<MultiregattaRegattasPlace> getPlaceClassForActivation() {
return MultiregattaRegattasPlace.class;
@@ -55,32 +78,47 @@ public class MultiregattaRegattasTabView extends Composite implements Multiregat
@Override
public void start(final MultiregattaRegattasPlace myPlace, final AcceptsOneWidget contentArea) {
racesListLive = new RacesListLive(currentPresenter, true);
initWidget(ourUiBinder.createAndBindUi(this));
RefreshManager refreshManager = new RefreshManager(this, currentPresenter.getDispatch());
refreshManager.add(racesListLive, new GetLiveRacesForEventAction(currentPresenter.getCtx().getEventDTO().getId()));
contentArea.setWidget(this);
racesListLiveUi = new RacesListLive(currentPresenter, true);
MultiregattaRegattasTabViewRegattaFilterList regattaFilterList = new MultiregattaRegattasTabViewRegattaFilterList();
boatCategoryFilterUi = new DropdownFilter<String>(StringMessages.INSTANCE.allBoatClasses(), regattaFilterList);
regattaListUi = new MultiRegattaList(currentPresenter);
// TODO: understand, and than move this into appropiate place (probably context)
currentPresenter.ensureRegattaStructure(new AsyncCallback<List<RaceGroupDTO>>() {
@Override
public void onSuccess(List<RaceGroupDTO> raceGroups) {
if (raceGroups.size() > 0) {
initView();
} else {
// createEventWithoutRegattasView(event, panel);
}
initWidget(ourUiBinder.createAndBindUi(this));
regattaOverviewLinkUi.setHref(currentPresenter.getRegattaOverviewLink());
regattaOverviewLinkUi.addClassName(currentPresenter.isEventOrRegattaLive() ? MAIN_CSS.buttonred() : MAIN_CSS.buttonprimary());
RefreshManager refreshManager = new RefreshManager(this, currentPresenter.getDispatch());
refreshManager.add(racesListLiveUi.getRefreshable(), new GetLiveRacesForEventAction(currentPresenter.getCtx().getEventDTO().getId()));
if (ExperimentalFeatures.SHOW_NEW_REGATTA_LIST) {
refreshManager.add(regattaFilterList, new GetRegattaListViewAction(currentPresenter.getCtx().getEventDTO().getId()));
content.removeFromParent();
} else {
boatCategoryFilterUi.removeFromParent();
regattaProgressLegendUi.removeFromParent();
regattaListUi.removeFromParent();
newContentContainerUi.removeFromParent();
// TODO: understand, and than move this into appropiate place (probably context)
currentPresenter.ensureRegattaStructure(new AsyncCallback<List<RaceGroupDTO>>() {
@Override
public void onSuccess(List<RaceGroupDTO> raceGroups) {
if (raceGroups.size() > 0) {
initView();
} else {
// createEventWithoutRegattasView(event, panel);
}
}
@Override
public void onFailure(Throwable caught) {
// createErrorView(
// "Error while loading the regatta structure with service getRegattaStructureOfEvent()",
// caught, panel);
}
});
@Override
public void onFailure(Throwable caught) {
// createErrorView(
// "Error while loading the regatta structure with service getRegattaStructureOfEvent()",
// caught, panel);
}
});
}
contentArea.setWidget(this);
}
protected void initView() {
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> regattaStructure = getRegattaStructure();
EventRegattaList eventRegattaList = new EventRegattaList(regattaStructure, currentPresenter);
@@ -106,17 +144,32 @@ public class MultiregattaRegattasTabView extends Composite implements Multiregat
@Override
public void stop() {
}
interface MyBinder extends UiBinder<HTMLPanel, MultiregattaRegattasTabView> {
}
private static MyBinder ourUiBinder = GWT.create(MyBinder.class);
@Override
public MultiregattaRegattasPlace placeToFire() {
return new MultiregattaRegattasPlace(currentPresenter.getCtx());
}
private class MultiregattaRegattasTabViewRegattaFilterList implements
DropdownFilterList<String>, RefreshableWidget<SortedSetResult<RegattaWithProgressDTO>> {
@Override
public void setData(SortedSetResult<RegattaWithProgressDTO> data, long nextUpdate, int updateNo) {
regattaListUi.setData(data, nextUpdate, updateNo);
boatCategoryFilterUi.updateFilterValues();
}
@Override
public Collection<String> getSelectableValues() {
return regattaListUi.getSelectableBoatCategories();
}
@Override
public void onSelectFilter(String value) {
regattaListUi.setVisibleBoatCategory(value);
}
}
}
@@ -1,19 +1,32 @@
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:r="urn:import:com.sap.sailing.gwt.home.client.place.event.partials.raceListLive">
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:style>
.space-top {
margin-top: 2em;
margin-bottom: 2em;
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.event.partials">
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:style>
.legend_and_filter {
text-align: right;
}
</ui:style>
<g:HTMLPanel>
<div class="{res.mediaCss.grid}">
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
<r:RacesListLive ui:field="racesListLive" addStyleNames="{style.space-top}" />
</div>
</div>
<g:SimplePanel ui:field="content" addStyleNames="{style.space-top}" />
</g:HTMLPanel>
</ui:UiBinder>
.legend_and_filter > div, .legend_and_filter > a {
display: inline-block;
vertical-align: middle;
margin-left: 1.5em;
}
</ui:style>
<g:HTMLPanel>
<div class="{res.mediaCss.grid}" ui:field="newContentContainerUi">
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {res.mainCss.spacermarginbottommedium}">
<p:raceListLive.RacesListLive ui:field="racesListLiveUi" addStyleNames="{res.mainCss.spacermargintopmedium}" />
<div class="{res.mainCss.spacermargintopmedium} {style.legend_and_filter}">
<p:multiRegattaList.MultiRegattaListStepsLegend ui:field="regattaProgressLegendUi" />
<p:listNavigation.DropdownFilter ui:field="boatCategoryFilterUi" />
<a class="{res.mainCss.button} {res.mainCss.buttonstrong} {res.mainCss.buttonarrowrightwhite}"
target="_blank" ui:field="regattaOverviewLinkUi">
<ui:text from="{i18n.racesOverview}" />
</a>
</div>
<p:multiRegattaList.MultiRegattaList ui:field="regattaListUi" />
</div>
</div>
<g:SimplePanel ui:field="content" />
</g:HTMLPanel>
</ui:UiBinder>
@@ -2,5 +2,5 @@
/* background-color:#f8f8f8; */
padding: 0 10px 10px 10px;
width: 100%;
font-weight: bold;
}
@@ -56,7 +56,6 @@ public class EventHeader extends Composite {
@UiField AnchorElement eventLink;
@UiField DivElement competitors;
@UiField DivElement races;
@UiField DivElement trackedRaces;
@UiField DivElement eventCategory;
@UiField DivElement courseAreaUi;
@@ -123,11 +122,6 @@ public class EventHeader extends Composite {
} else {
hide(races);
}
if(regattaMetadata.getTrackedRacesCount() > 0) {
trackedRaces.setInnerText(i18n.trackedRacesCount(regattaMetadata.getTrackedRacesCount()));
} else {
hide(trackedRaces);
}
if(regattaMetadata.getDefaultCourseAreaName() != null) {
courseAreaUi.setInnerText(i18n.courseAreaName(regattaMetadata.getDefaultCourseAreaName()));
} else {
@@ -159,7 +153,7 @@ public class EventHeader extends Composite {
hide(eventLink);
}
hide(competitors, races, trackedRaces, courseAreaUi, eventCategory);
hide(competitors, races, courseAreaUi, eventCategory);
}
initTitleAndSelection(nameToShow);
@@ -52,7 +52,6 @@
<!-- IF event.eventType === 'multi-regatta-event' -->
<div ui:field="competitors" class="{local_res.css.eventheader_intro_details_item}" />
<div ui:field="races" class="{local_res.css.eventheader_intro_details_item}" />
<div ui:field="trackedRaces" class="{local_res.css.eventheader_intro_details_item}" />
<div ui:field="courseAreaUi" class="{local_res.css.eventheader_intro_details_item}" />
<div ui:field="eventCategory" class="{local_res.css.eventheader_intro_details_item}" />
<!-- IFEND event.eventType === 'multi-regatta-event' -->
@@ -0,0 +1,112 @@
package com.sap.sailing.gwt.home.client.place.event.partials.listNavigation;
import java.util.Collection;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.common.client.LinkUtil;
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.RegattaNavigationResources.LocalCss;
import com.sap.sailing.gwt.home.client.shared.DropdownHandler;
public class DropdownFilter<T> extends Composite {
private static final LocalCss CSS = RegattaNavigationResources.INSTANCE.css();
private static ListDropdownFilterUiBinder uiBinder = GWT.create(ListDropdownFilterUiBinder.class);
interface ListDropdownFilterUiBinder extends UiBinder<Widget, DropdownFilter<?>> {
}
@UiField DivElement dropdownContainerUi;
@UiField DivElement currentValueUi;
@UiField FlowPanel filterItemContainerUi;
private final DropdownFilterList<T> filterList;
private final DropdownHandler dropdownHandler;
private final String nullValueLabel;
private T selectedFilterValue = null;
public DropdownFilter(String nullValueLabel, DropdownFilterList<T> filterList) {
this.nullValueLabel = nullValueLabel;
this.filterList = filterList;
CSS.ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
this.dropdownHandler = new ListFilterDropdownHandler();
}
public void updateFilterValues() {
filterItemContainerUi.clear();
DropdownFilterItem filterItemToSelect = addFilterValue(null, nullValueLabel);
for (T value : filterList.getSelectableValues()) {
DropdownFilterItem newFilterItem = addFilterValue(value, String.valueOf(value));
filterItemToSelect = value.equals(selectedFilterValue) ? newFilterItem : filterItemToSelect;
}
filterItemToSelect.select();
setVisible(filterList.getSelectableValues().size() > 1);
}
private DropdownFilterItem addFilterValue(T value, String label) {
DropdownFilterItem filterItem = new DropdownFilterItem(value, label);
filterItemContainerUi.add(filterItem);
return filterItem;
}
public interface DropdownFilterList<T> {
Collection<T> getSelectableValues();
void onSelectFilter(T value);
}
private class ListFilterDropdownHandler extends DropdownHandler {
private ListFilterDropdownHandler() {
super(dropdownContainerUi, filterItemContainerUi.getElement());
}
@Override
protected void dropdownStateChanged(boolean dropdownShown) {
if (dropdownShown) dropdownContainerUi.addClassName(CSS.jsdropdownactive());
else dropdownContainerUi.removeClassName(CSS.jsdropdownactive());
}
}
private class DropdownFilterItem extends Widget {
private final T value;
private final String label;
private DropdownFilterItem(T value, String label) {
this.value = value;
this.label = label;
this.setElement(DOM.createDiv().<DivElement>cast());
this.getElement().setInnerText(label);
this.addStyleName(CSS.regattanavigation_filter_dropdown_link());
this.initClickHandler();
}
private void initClickHandler() {
this.addDomHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if(LinkUtil.handleLinkClick((Event) event.getNativeEvent())) {
event.preventDefault();
DropdownFilterItem.this.select();
DropdownFilter.this.dropdownHandler.setVisible(false);
}
}
}, ClickEvent.getType());
}
private void select() {
DropdownFilter.this.selectedFilterValue = value;
DropdownFilter.this.currentValueUi.setInnerText(label);
for (int i=0; i < filterItemContainerUi.getWidgetCount(); i++) {
filterItemContainerUi.getWidget(i).removeStyleName(CSS.regattanavigation_filter_dropdown_linkactive());
}
this.addStyleName(CSS.regattanavigation_filter_dropdown_linkactive());
DropdownFilter.this.filterList.onSelectFilter(value);
}
}
}
@@ -0,0 +1,18 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="i18n_ubi" type="com.sap.sailing.gwt.common.client.i18n.TextMessages"/>
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.RegattaNavigationResources" />
<g:HTMLPanel>
<div class="{local_res.css.regattanavigation_filter} {local_res.css.jsdropdown}" ui:field="dropdownContainerUi">
<div class="{local_res.css.jsdropdown_head}">
<div class="{local_res.css.regattanavigation_filter_text}">
<ui:text from="{i18n.filterBy}" />:
</div>
<div class="{local_res.css.regattanavigation_filter_current}" ui:field="currentValueUi"></div>
</div>
<g:FlowPanel addStyleNames="{local_res.css.regattanavigation_filter_dropdown} {local_res.css.jsdropdown_content}" ui:field="filterItemContainerUi" />
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,85 @@
package com.sap.sailing.gwt.home.client.place.event.partials.listNavigation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.ListNavigationPanel.ListNavigationAction;
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.RegattaNavigationResources.LocalCss;
public class ListNavigationPanel<T extends ListNavigationAction> extends Composite {
private static final LocalCss CSS = RegattaNavigationResources.INSTANCE.css();
private static ListNavigationPanelUiBinder uiBinder = GWT.create(ListNavigationPanelUiBinder.class);
interface ListNavigationPanelUiBinder extends UiBinder<Widget, ListNavigationPanel<?>> {
}
@UiField FlowPanel actionContainerUi;
@UiField SimplePanel additionalWidgetContainerUi;
private SelectionCallback<T> selectionCallback;
public ListNavigationPanel(SelectionCallback<T> selectionCallback) {
this.selectionCallback = selectionCallback;
CSS.ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
}
public void addAction(final T action, boolean select) {
ActionWidget actionWidget = new ActionWidget(action);
actionContainerUi.add(actionWidget);
if (select) {
actionWidget.select();
}
}
public void setAdditionalWidget(Widget additionalWidget) {
this.additionalWidgetContainerUi.setWidget(additionalWidget);
}
public interface SelectionCallback<T> {
void onSelectAction(T action);
}
public interface ListNavigationAction {
String getDisplayName();
boolean isShowAdditionalWidget();
}
private class ActionWidget extends Label {
private final T action;
private final Display displayStyle;
private ActionWidget(T action) {
super(action.getDisplayName());
this.action = action;
this.displayStyle = action.isShowAdditionalWidget() ? Display.BLOCK : Display.NONE;
this.addStyleName(CSS.regattanavigation_button());
this.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
ActionWidget.this.select();
}
});
}
private void select() {
additionalWidgetContainerUi.getElement().getStyle().setDisplay(displayStyle);
for (int i=0; i < actionContainerUi.getWidgetCount(); i++) {
actionContainerUi.getWidget(i).removeStyleName(CSS.regattanavigation_buttonactive());
}
this.addStyleName(CSS.regattanavigation_buttonactive());
selectionCallback.onSelectAction(action);
}
}
}
@@ -0,0 +1,15 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="i18n_ubi" type="com.sap.sailing.gwt.common.client.i18n.TextMessages"/>
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.RegattaNavigationResources" />
<g:FlowPanel addStyleNames="{res.mediaCss.grid} {local_res.css.regattanavigation}" >
<g:FlowPanel addStyleNames="{res.mediaCss.small12} {res.mediaCss.large7} {res.mediaCss.columns}" ui:field="actionContainerUi">
<g:Label addStyleNames="{local_res.css.regattanavigation_text}">
<ui:text from='{i18n.display}' />:
</g:Label>
</g:FlowPanel>
<g:SimplePanel addStyleNames="{res.mediaCss.small12} {res.mediaCss.large5} {res.mediaCss.columns}" ui:field="additionalWidgetContainerUi"/>
</g:FlowPanel>
</ui:UiBinder>
@@ -0,0 +1,19 @@
package com.sap.sailing.gwt.home.client.place.event.partials.listNavigation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.user.client.ui.Widget;
public class RaceStateLegend extends Widget {
private static RaceStateLegendUiBinder uiBinder = GWT.create(RaceStateLegendUiBinder.class);
interface RaceStateLegendUiBinder extends UiBinder<Element, RaceStateLegend> {
}
public RaceStateLegend() {
setElement(uiBinder.createAndBindUi(this));
}
}
@@ -0,0 +1,21 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="i18n_ubi" type="com.sap.sailing.gwt.common.client.i18n.TextMessages"/>
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.RegattaNavigationResources" />
<div class="{local_res.css.regattanavigation_legend}">
<div class="{local_res.css.regattanavigation_legend_item} {local_res.css.regattanavigation_legend_itemtracked}">
<ui:text from='{i18n.tracked}' />
</div>
<div class="{local_res.css.regattanavigation_legend_item} {local_res.css.regattanavigation_legend_itemuntracked}">
<ui:text from='{i18n.untracked}' />
</div>
<div class="{local_res.css.regattanavigation_legend_item} {local_res.css.regattanavigation_legend_itemlive}">
<ui:text from='{i18n.playModeLive}' />
</div>
<div class="{local_res.css.regattanavigation_legend_item} {local_res.css.regattanavigation_legend_itemplanned}">
<ui:text from='{i18n.raceIsPlanned}' />
</div>
</div>
</ui:UiBinder>
@@ -0,0 +1,148 @@
/**
* A toggle buttons and legend for regatta races views
*/
.jsdropdown {
position: relative;
}
.jsdropdown_head {
padding-right: 2em;
}
.jsdropdown_head,
.jsdropdown_content {
text-indent: 0;
}
.regattanavigation {
font-size: 1rem;
margin-top: 1em;
margin-bottom: 1em;
}
.regattanavigation_text {
font-size: 0.866666666666667rem;
line-height: 2.307692307692307em;
margin-right: 0.769230769230769em;
display: inline-block;
color: #999;
}
.regattanavigation_button {
display: inline-block;
font-weight: 600;
padding: 0.333333333333333em 0.666666666666667em;
line-height: 1.333333333333333em;
margin-right: 0.666666666666667em;
color: #666;
background-color: #f2f2f2;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
transition: all 0.2s;
cursor: pointer;
}
.regattanavigation_button:hover {
text-decoration: none;
color: #fff;
background-color: #efaa00;
}
.regattanavigation_buttonactive {
color: #fff;
background-color: #efaa00;
}
.regattanavigation_filter {
font-size: 0.866666666666667rem;
text-align: right;
margin-top: 0;
background: transparent url("images/home/arrow-down-filled-black.png") no-repeat;
background-position: 96%;
background-size: 0.923076923076923em 0.538461538461538em;
border: 1px solid transparent;
border-radius: 0.333333333333333em 0.333333333333333em 0 0;
position: relative;
float: right;
cursor: pointer;
padding-left: 0.5em;
}
.regattanavigation_filter:hover,
.regattanavigation_filter.jsdropdownactive {
border-color: #dedede;
background-color: #f2f2f2;
}
.regattanavigation_filter.jsdropdownactive {
background-image: url("images/home/arrow-down-filled-yellow.png");
}
.regattanavigation_filter.jsdropdownactive .regattanavigation_filter_dropdown {
display: block;
}
.regattanavigation_filter_text,
.regattanavigation_filter_current {
display: inline-block;
line-height: 2.307692307692307em;
}
.regattanavigation_filter_text {
color: #999;
}
.regattanavigation_filter_dropdown {
display: none;
position: absolute;
right: -1px;
background: #fff;
border: 1px solid #dedede;
line-height: 2.307692307692307em;
z-index: 10;
width: 110%;
}
.regattanavigation_filter_dropdown_link {
display: block;
color: #999;
text-align: left;
padding: 0 2.307692307692307em 0 0.769230769230769em;
}
.regattanavigation_filter_dropdown_link:hover {
text-decoration: underline;
}
.regattanavigation_filter_dropdown_linkactive {
background: url("images/home/dropdown__check@2x.png") no-repeat;
background-position: 95%;
background-size: 1.2em 0.933333333333333em;
}
.regattanavigation_legend {
font-size: 1rem;
width: 100%;
margin-top: 1.333333333333333em;
}
@media (min-width: 61em) {
.regattanavigation_legend {
text-align: right;
margin-top: 0;
}
.regattanavigation_legend_item {
margin-right: 0;
margin-left: 0.666666666666667em;
}
}
.regattanavigation_legend_item {
display: inline-block;
padding: 0.4em 0.666666666666667em;
margin: 0.333333333333333em 0.666666666666667em 0.333333333333333em 0;
font-size: 0.666em;
font-weight: 700;
line-height: 0.666666666666667em;
border: 1px solid #008fcc;
}
.regattanavigation_legend_itemtracked {
color: #fff;
border-color: #008fcc;
background-color: #008fcc;
}
.regattanavigation_legend_itemuntracked {
color: #fff;
border-color: #ccc;
background-color: #666;
}
.regattanavigation_legend_itemlive {
color: #fff;
border-color: #e94a1b;
background-color: #e94a1b;
}
.regattanavigation_legend_itemplanned {
color: #ccc;
border-color: #ccc;
background-color: #fff;
}
@@ -0,0 +1,35 @@
package com.sap.sailing.gwt.home.client.place.event.partials.listNavigation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
public interface RegattaNavigationResources extends ClientBundle {
public static final RegattaNavigationResources INSTANCE = GWT.create(RegattaNavigationResources.class);
@Source("RegattaNavigation.gss")
LocalCss css();
public interface LocalCss extends CssResource {
String jsdropdown();
String jsdropdown_head();
String jsdropdown_content();
String regattanavigation();
String regattanavigation_text();
String regattanavigation_button();
String regattanavigation_buttonactive();
String regattanavigation_filter();
String jsdropdownactive();
String regattanavigation_filter_dropdown();
String regattanavigation_filter_text();
String regattanavigation_filter_current();
String regattanavigation_filter_dropdown_link();
String regattanavigation_filter_dropdown_linkactive();
String regattanavigation_legend();
String regattanavigation_legend_item();
String regattanavigation_legend_itemtracked();
String regattanavigation_legend_itemuntracked();
String regattanavigation_legend_itemlive();
String regattanavigation_legend_itemplanned();
}
}
@@ -0,0 +1,255 @@
/**
* A list of regattas to an event
*/
.race {
color: #333;
font-size: 1rem;
overflow: hidden;
}
.race:last-of-type .race_item {
border: none;
}
.race_fleetcorner {
width: 1em;
vertical-align: top;
border-bottom: 1px solid #ebebeb;
}
.race_fleetcorner_icon {
width: 1em;
margin-right: -2.333333333333333em;
position: relative;
top: 1px;
left: 1px;
border-style: solid;
border-color: transparent;
border-width: 1em 1em 0 0;
}
.race_item {
text-align: left;
vertical-align: baseline;
border-bottom: 1px solid #ebebeb;
white-space: nowrap;
padding: 1.4em 0.666666666666667em 0.733333333333333em 1.333333333333333em;
}
.race_item .button {
white-space: nowrap;
}
.race_item:first-of-type {
padding-left: 2em;
}
.race_itemrank:after {
content: '.';
}
.race_itemshort {
width: 5em;
}
.race_itemlong {
width: 32.5%;
}
.race_itemwind {
white-space: nowrap;
}
.race_itemwindflag {
padding: 1.066666666666667em 0.666666666666667em 0.4em 1.333333333333333em;
}
img.race_item_windflag {
max-width: 2.4em;
max-height: 2.4em;
vertical-align: middle;
}
.race_itemname {
font-weight: 600;
}
.race_itemwinner {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: middle;
min-width: 13.333333333333334em;
max-width: 16.666666666666668em;
}
.race_item_flag {
max-width: 1.6em;
max-height: 1.6em;
vertical-align: middle;
}
.race_item_position {
margin-right: 0.333333333333333em;
}
.race_item_winner {
margin-left: 5px;
vertical-align: middle;
}
.race_itemwinner {
padding: 0.733333333333333em 1.333333333333333em;
}
.race_itemcenter {
text-align: center;
}
.race_itemright {
text-align: right;
vertical-align: middle;
padding-left: 0;
padding-right: 0.666666666666667em;
padding-top: 0.666666666666667em;
}
.race_itemright_button {
padding: 0.666666666666667em;
}
.race_itemstatus {
position: relative;
}
.race_itemstatus:first-letter {
text-transform: capitalize;
}
.race_itemstatus_container {
min-width: 5.333333333333333em;
display: inline-block;
}
.race_itemstatus_container_text {
clip: auto;
}
.race_itemstatus_container_progressbar {
height: 0.2em;
position: relative;
top: 0.2em;
width: 100%;
background-color: #dedede;
}
.race_itemstatus_container_progressbar_progress {
height: 100%;
background-color: #efaa00;
}
.racewinners .race_item {
padding: 1.2em 0.666666666666667em 1.2em 1.333333333333333em;
}
.racewinners .race_item:nth-last-child(1) {
display: none;
}
@media (min-width: 61em) {
.racewinners .race_item:nth-last-child(1) {
display: inline-block;
}
}
.racewinners .race_itemname {
vertical-align: middle;
}
.race_fleetcornerblue:before {
border-top-color: #00f;
}
.race_fleetcornerred:before {
border-top-color: #f00;
}
.race_fleetcornersilver:before {
border-top-color: #c0c0c0;
}
.race_fleetcornergold:before {
border-top-color: #ffd700;
}
.race_fleetcorneryellow:before {
border-top-color: #ff0;
}
.regattalistitem {
font-size: 1rem;
float: left;
width: 100%;
margin-top: 2em;
border: 1px solid #ddd;
border-radius: 0.333333333333333em;
overflow: hidden;
}
.regattalistitem > div:last-child {
border-bottom: none;
}
.regattalistitem_table {
width: 100%;
border-spacing: 0;
border-collapse: separate;
border-bottom: 1px solid #ddd;
}
.regattalistitem_table:last-of-type {
border-bottom: none;
}
.regattalistitem_tableborderTop {
border-top: 1px solid #ebebeb;
}
.regattalistitem_steps {
border-bottom: 1px solid #ddd;
overflow: hidden;
}
.regattalistitem_steps_step {
float: left;
position: relative;
height: 4em;
text-transform: uppercase;
padding: 0 0.666666666666667em;
}
.regattalistitem_steps_stepinactive {
color: #ddd;
}
.regattalistitem_steps_step_infowrapper {
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
white-space: nowrap;
}
.regattalistitem_steps_step_name {
font-weight: 600;
display: inline-block;
margin-right: 0.333333333333333em;
font-size: 0;
}
.regattalistitem_steps_step_name::first-letter {
font-size: 0.866666666666667rem;
margin-right: 0.333333333333333rem;
}
@media (min-width: 49.0625em) {
.regattalistitem_steps_step_name::first-letter {
margin-right: 0;
}
}
@media (min-width: 49.0625em) {
.regattalistitem_steps_step_name {
font-size: 0.866666666666667em;
}
}
.regattalistitem_steps_step_check {
display: inline-block;
vertical-align: middle;
width: 1.066666666666667em;
height: 1.066666666666667em;
background-image: url("images/home/icon-green-check.svg");
background-repeat: no-repeat;
background-size: contain;
margin-right: 0.333333333333333em;
}
.regattalistitem_steps_step_progress {
display: inline-block;
font-size: 0.866666666666667em;
text-transform: none;
}
.regattalistitem_steps_step_fleets {
width: 100%;
height: 17px;
outline: 1px solid #dedede;
margin-top: 0.266666666666667em;
padding: 1px;
}
.regattalistitem_steps_step_fleets_fleet {
font-size: inherit;
}
.regattalistitem_steps_step_fleets_fleet_progress {
height: 100%;
}
.regattalistitem_steps_button {
height: 100%;
padding: 0.666666666666667em;
text-align: right;
margin-top: 3px;
}
.regattalistitem_steps_button .button {
margin-left: 0.8em;
}
@@ -0,0 +1,62 @@
package com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList;
import java.util.Collection;
import java.util.Collections;
import java.util.TreeSet;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView.Presenter;
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshableWidget;
import com.sap.sailing.gwt.ui.shared.dispatch.SortedSetResult;
import com.sap.sailing.gwt.ui.shared.dispatch.regatta.RegattaWithProgressDTO;
public class MultiRegattaList extends Composite implements RefreshableWidget<SortedSetResult<RegattaWithProgressDTO>> {
private static MultiRegattaListUiBinder uiBinder = GWT.create(MultiRegattaListUiBinder.class);
interface MultiRegattaListUiBinder extends UiBinder<Widget, MultiRegattaList> {
}
@UiField FlowPanel regattasContainerUi;
private final Presenter currentPresenter;
private final Collection<String> selectableBoatCategories = new TreeSet<>();
public MultiRegattaList(Presenter presenter) {
this.currentPresenter = presenter;
initWidget(uiBinder.createAndBindUi(this));
}
@Override
public void setData(SortedSetResult<RegattaWithProgressDTO> data, long nextUpdate, int updateNo) {
this.setListData(data == null ? Collections.<RegattaWithProgressDTO>emptySet() : data.getValues());
}
public void setListData(Collection<RegattaWithProgressDTO> data) {
regattasContainerUi.clear();
selectableBoatCategories.clear();
for (RegattaWithProgressDTO regattaWithProgress : data) {
regattasContainerUi.add(new MultiRegattaListItem(regattaWithProgress, currentPresenter));
String boatCategory = regattaWithProgress.getBoatCategory();
if(boatCategory != null) {
selectableBoatCategories.add(boatCategory);
}
}
}
public Collection<String> getSelectableBoatCategories() {
return selectableBoatCategories;
}
public void setVisibleBoatCategory(String visibleBoatCategory) {
for (int i=0; i < regattasContainerUi.getWidgetCount(); i++) {
MultiRegattaListItem item = (MultiRegattaListItem) regattasContainerUi.getWidget(i);
item.setVisibilityDependingOnBoatCategory(visibleBoatCategory);
}
}
}
@@ -0,0 +1,9 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.event.partials">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaListResources" />
<g:FlowPanel ui:field="regattasContainerUi">
</g:FlowPanel>
</ui:UiBinder>
@@ -0,0 +1,42 @@
package com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView.Presenter;
import com.sap.sailing.gwt.home.client.place.event.partials.regattaHeader.RegattaHeader;
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
import com.sap.sailing.gwt.ui.shared.dispatch.regatta.RegattaWithProgressDTO;
public class MultiRegattaListItem extends Composite {
private static MultiRegattaListItemUiBinder uiBinder = GWT.create(MultiRegattaListItemUiBinder.class);
interface MultiRegattaListItemUiBinder extends UiBinder<Widget, MultiRegattaListItem> {
}
@UiField(provided = true) RegattaHeader regattaHeaderUi;
@UiField(provided = true) MultiRegattaListSteps regattaStepsUi;
private final RegattaWithProgressDTO regattaWithProgress;
public MultiRegattaListItem(RegattaWithProgressDTO regattaWithProgress) {
this.regattaWithProgress = regattaWithProgress;
regattaHeaderUi = new RegattaHeader(regattaWithProgress);
regattaStepsUi = new MultiRegattaListSteps(regattaWithProgress.getProgress());
initWidget(uiBinder.createAndBindUi(this));
}
public MultiRegattaListItem(RegattaWithProgressDTO regattaWithProgress, Presenter presenter) {
this(regattaWithProgress);
regattaHeaderUi.setRegattaNavigation(presenter.getRegattaNavigation(regattaWithProgress.getId()));
PlaceNavigation<?> leaderboardNavigation = presenter.getRegattaLeaderboardNavigation(regattaWithProgress.getId());
regattaStepsUi.setLeaderboardNavigation(regattaWithProgress.getState(), leaderboardNavigation);
}
void setVisibilityDependingOnBoatCategory(String visibleBoatCategory) {
setVisible(visibleBoatCategory == null || visibleBoatCategory.equals(regattaWithProgress.getBoatCategory()));
}
}
@@ -0,0 +1,18 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.event.partials">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaListResources" />
<g:HTMLPanel>
<div class="{local_res.css.regattalistitem}">
<p:regattaHeader.RegattaHeader ui:field="regattaHeaderUi" />
<p:multiRegattaList.MultiRegattaListSteps ui:field="regattaStepsUi" />
<!--
<ubi:multiRegattaList.MultiRegattaListRace ui:fields='races'> </ubi>
<ubi:multiRegattaList.MultiRegattaListResult ui:fields='boatclass'> </ubi>
<ubi:multiRegattaList.MultiRegattaListFinalresult ui:fields='boatclass'> </ubi>
-->
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,59 @@
package com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
public interface MultiRegattaListResources extends ClientBundle {
public static final MultiRegattaListResources INSTANCE = GWT.create(MultiRegattaListResources.class);
@Source("MultiRegattaList.gss")
LocalCss css();
public interface LocalCss extends CssResource {
String race();
String race_item();
String race_fleetcorner();
String race_fleetcorner_icon();
String button();
String race_itemrank();
String race_itemshort();
String race_itemlong();
String race_itemwind();
String race_itemwindflag();
String race_item_windflag();
String race_itemname();
String race_itemwinner();
String race_item_flag();
String race_item_position();
String race_item_winner();
String race_itemcenter();
String race_itemright();
String race_itemright_button();
String race_itemstatus();
String race_itemstatus_container();
String race_itemstatus_container_text();
String race_itemstatus_container_progressbar();
String race_itemstatus_container_progressbar_progress();
String racewinners();
String race_fleetcornerblue();
String race_fleetcornerred();
String race_fleetcornersilver();
String race_fleetcornergold();
String race_fleetcorneryellow();
String regattalistitem();
String regattalistitem_table();
String regattalistitem_tableborderTop();
String regattalistitem_steps();
String regattalistitem_steps_step();
String regattalistitem_steps_stepinactive();
String regattalistitem_steps_step_infowrapper();
String regattalistitem_steps_step_name();
String regattalistitem_steps_step_check();
String regattalistitem_steps_step_progress();
String regattalistitem_steps_step_fleets();
String regattalistitem_steps_step_fleets_fleet();
String regattalistitem_steps_step_fleets_fleet_progress();
String regattalistitem_steps_button();
}
}
@@ -0,0 +1,100 @@
package com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.common.client.SharedResources;
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
import com.sap.sailing.gwt.ui.shared.dispatch.regatta.RegattaProgressDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.regatta.RegattaProgressSeriesDTO;
import com.sap.sailing.gwt.ui.shared.eventview.HasRegattaMetadata.RegattaState;
public class MultiRegattaListSteps extends Composite {
private static MultiRegattaListStepsUiBinder uiBinder = GWT.create(MultiRegattaListStepsUiBinder.class);
interface MultiRegattaListStepsUiBinder extends UiBinder<Widget, MultiRegattaListSteps> {
}
@UiField DivElement progressContainerUi;
@UiField DivElement stepsContainerUi;
@UiField DivElement leaderboardButtonContainerUi;
@UiField AnchorElement leaderboardButtonUi;
private HandlerRegistration windowResizeHandlerRegistration;
private final List<MultiRegattaListStepsBody> allMultiregattaSteps = new ArrayList<MultiRegattaListStepsBody>();
public MultiRegattaListSteps(RegattaProgressDTO regattaProgress) {
MultiRegattaListResources.INSTANCE.css().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
double sumParts = 0;
for(RegattaProgressSeriesDTO seriesProgress : regattaProgress.getSeries()) {
double parts = Math.pow(seriesProgress.getTotalRaceCount(), 0.4);
sumParts += parts;
}
for(RegattaProgressSeriesDTO seriesProgress : regattaProgress.getSeries()) {
double parts = Math.pow(seriesProgress.getTotalRaceCount(), 0.4);
double percentage = 100.0 * parts / sumParts;
MultiRegattaListStepsBody stepsBody = new MultiRegattaListStepsBody(seriesProgress);
allMultiregattaSteps.add(stepsBody);
stepsBody.getElement().getStyle().setWidth(percentage, Unit.PCT);
stepsContainerUi.appendChild(stepsBody.getElement());
}
}
@Override
protected void onLoad() {
windowResizeHandlerRegistration = Window.addResizeHandler(new ResizeHandler() {
@Override
public void onResize(ResizeEvent event) {
for (MultiRegattaListStepsBody widget : allMultiregattaSteps) {
widget.onResize();
}
}
});
}
@Override
protected void onUnload() {
windowResizeHandlerRegistration.removeHandler();
}
void setLeaderboardNavigation(RegattaState regattaState, PlaceNavigation<?> placeNavigation) {
placeNavigation.configureAnchorElement(leaderboardButtonUi);
leaderboardButtonUi.getStyle().clearDisplay();
leaderboardButtonUi.addClassName(getLeaderboardButtonStyle(regattaState));
stepsContainerUi.getStyle().setDisplay(Display.NONE);
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
stepsContainerUi.getStyle().clearDisplay();
stepsContainerUi.getStyle().setMarginRight(leaderboardButtonUi.getOffsetWidth() + 20, Unit.PX);
}
});
}
private String getLeaderboardButtonStyle(RegattaState regattaState) {
switch (regattaState) {
case UPCOMING: return SharedResources.INSTANCE.mainCss().buttoninactive();
case RUNNING: return SharedResources.INSTANCE.mainCss().buttonred();
default: return SharedResources.INSTANCE.mainCss().buttonprimary();
}
}
}
@@ -0,0 +1,18 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.event.partials">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaListResources" />
<g:HTMLPanel>
<div class="{local_res.css.regattalistitem_steps}" ui:field="progressContainerUi">
<div ui:field="stepsContainerUi" />
<div class="{local_res.css.regattalistitem_steps_button}" ui:field="leaderboardButtonContainerUi">
<a class="{res.mainCss.button} {res.mainCss.buttonstrong} {res.mainCss.buttonarrowrightwhite}"
style="display:none;" ui:field="leaderboardButtonUi">
<ui:text from='{i18n.leaderboard}' />
</a>
</div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,89 @@
package com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList;
import static com.sap.sailing.domain.common.LeaderboardNameConstants.DEFAULT_SERIES_NAME;
import java.util.Map;
import java.util.Map.Entry;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.UIObject;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.dispatch.regatta.RegattaProgressFleetDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.regatta.RegattaProgressSeriesDTO;
import com.sap.sailing.gwt.ui.shared.race.FleetMetadataDTO;
public class MultiRegattaListStepsBody extends UIObject implements RequiresResize {
private static final StringMessages I18N = StringMessages.INSTANCE;
private static MultiRegattaListStepsBodyUiBinder uiBinder = GWT.create(MultiRegattaListStepsBodyUiBinder.class);
interface MultiRegattaListStepsBodyUiBinder extends UiBinder<Element, MultiRegattaListStepsBody> {
}
@UiField DivElement nameUi;
@UiField DivElement checkUi;
@UiField DivElement progressUi;
@UiField DivElement fleetsContainerUi;
private final String seriesName;
public MultiRegattaListStepsBody(RegattaProgressSeriesDTO seriesProgress) {
setElement(uiBinder.createAndBindUi(this));
nameUi.getStyle().setVisibility(Visibility.HIDDEN);
seriesName = DEFAULT_SERIES_NAME.equals(seriesProgress.getName()) ? I18N.races() : seriesProgress.getName();
nameUi.setInnerText(seriesName);
if (seriesProgress.isCompleted()) {
progressUi.setInnerText(String.valueOf(seriesProgress.getTotalRaceCount()));
} else {
checkUi.getStyle().setDisplay(Display.NONE);
progressUi.setInnerText(I18N.currentOfTotal(
seriesProgress.getProgressRaceCount(), seriesProgress.getTotalRaceCount()));
}
addFleetProgresses(seriesProgress.getFleetState(), seriesProgress.getTotalRaceCount());
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
renderNames();
}
});
}
private void addFleetProgresses(Map<FleetMetadataDTO, RegattaProgressFleetDTO> fleetStates, int totalRaceCount) {
double height = fleetStates.isEmpty() ? 100.0 : 100.0 / fleetStates.size();
for (Entry<FleetMetadataDTO, RegattaProgressFleetDTO> fleetState : fleetStates.entrySet()) {
double finishedWidth = (fleetState.getValue().getFinishedRaceCount() * 100.0) / totalRaceCount;
double liveWidth = (fleetState.getValue().getFinishedAndLiveRaceCount() * 100.0) / totalRaceCount;
String fleetColor = fleetState.getKey().getFleetColor();
MultiRegattaListStepsBodyFleet fleet = new MultiRegattaListStepsBodyFleet(finishedWidth, liveWidth, height, fleetColor);
fleetsContainerUi.appendChild(fleet.getElement());
}
}
private void renderNames() {
if (getElement().getOffsetWidth() < nameUi.getOffsetWidth() + checkUi.getOffsetWidth()
+ progressUi.getOffsetWidth()) {
String[] tokens = seriesName.split(" ");
StringBuilder initials = new StringBuilder();
for (int i = 0; i < tokens.length; i++) {
initials.append(tokens[i].charAt(0));
}
nameUi.setInnerText(initials.toString());
}
nameUi.setTitle(seriesName);
nameUi.getStyle().setVisibility(Visibility.VISIBLE);
}
@Override
public void onResize() {
renderNames();
}
}
@@ -0,0 +1,15 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.event.partials">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaListResources" />
<div class="{local_res.css.regattalistitem_steps_step}">
<div class="{local_res.css.regattalistitem_steps_step_infowrapper}">
<div class="{local_res.css.regattalistitem_steps_step_name}" ui:field="nameUi"></div>
<div class="{local_res.css.regattalistitem_steps_step_check}" ui:field="checkUi"></div>
<div class="{local_res.css.regattalistitem_steps_step_progress}" ui:field="progressUi"></div>
<div class="{local_res.css.regattalistitem_steps_step_fleets}" ui:field="fleetsContainerUi"></div>
</div>
</div>
</ui:UiBinder>
@@ -0,0 +1,30 @@
package com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.UIObject;
public class MultiRegattaListStepsBodyFleet extends UIObject {
private static MultiRegattaListStepsBodyFleetUiBinder uiBinder = GWT.create(MultiRegattaListStepsBodyFleetUiBinder.class);
interface MultiRegattaListStepsBodyFleetUiBinder extends UiBinder<Element, MultiRegattaListStepsBodyFleet> {
}
@UiField DivElement fleetProgressBarUi;
@UiField DivElement fleetProgressBarLiveUi;
public MultiRegattaListStepsBodyFleet(double finishedWidth, double liveWidth, double height, String color) {
setElement(uiBinder.createAndBindUi(this));
getElement().getStyle().setHeight(height, Unit.PCT);
fleetProgressBarUi.getStyle().setWidth(finishedWidth, Unit.PCT);
fleetProgressBarUi.getStyle().setBackgroundColor(color);
fleetProgressBarLiveUi.getStyle().setWidth(liveWidth, Unit.PCT);
fleetProgressBarLiveUi.getStyle().setBackgroundColor("#ff4040");
}
}
@@ -0,0 +1,11 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.event.partials">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaListResources" />
<div class="{local_res.css.regattalistitem_steps_step_fleets_fleet}" style="position:relative;">
<div class="{local_res.css.regattalistitem_steps_step_fleets_fleet_progress}" style="position:absolute; top:0;" ui:field="fleetProgressBarLiveUi"></div>
<div class="{local_res.css.regattalistitem_steps_step_fleets_fleet_progress}" style="position:absolute; top:0;" ui:field="fleetProgressBarUi"></div>
</div>
</ui:UiBinder>
@@ -0,0 +1,19 @@
package com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.user.client.ui.Widget;
public class MultiRegattaListStepsLegend extends Widget {
private static MultiRegattaListStepsLegendUiBinder uiBinder = GWT.create(MultiRegattaListStepsLegendUiBinder.class);
interface MultiRegattaListStepsLegendUiBinder extends UiBinder<Element, MultiRegattaListStepsLegend> {
}
public MultiRegattaListStepsLegend() {
setElement(uiBinder.createAndBindUi(this));
}
}
@@ -0,0 +1,45 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:style>
.multiregatta_steps_legend {
font-size: 1rem;
text-align: right;
}
.multiregatta_steps_legend_item {
display: inline-block;
padding: 0.4em 0.666666666666667em;
margin: 0.333333333333333em 0 0.333333333333333em 0.666666666666667em;
font-size: 0.666em;
font-weight: 700;
line-height: 0.666666666666667em;
border: 1px solid #008fcc;
}
.multiregatta_steps_legend_item_finished {
color: #fff;
border-color: #ccc;
background-color: #f0ab00;
}
.multiregatta_steps_legend_item_live {
color: #fff;
border-color: #e94a1b;
background-color: #e94a1b;
}
.multiregatta_steps_legend_item_planned {
color: #ccc;
border-color: #ccc;
background-color: #fff;
}
</ui:style>
<div class="{style.multiregatta_steps_legend}">
<div class="{style.multiregatta_steps_legend_item} {style.multiregatta_steps_legend_item_finished}">
<ui:text from='{i18n.raceIsFinished}' />
</div>
<div class="{style.multiregatta_steps_legend_item} {style.multiregatta_steps_legend_item_live}">
<ui:text from='{i18n.playModeLive}' />
</div>
<div class="{style.multiregatta_steps_legend_item} {style.multiregatta_steps_legend_item_planned}">
<ui:text from='{i18n.raceIsPlanned}' />
</div>
</div>
</ui:UiBinder>
@@ -0,0 +1,174 @@
/**
* Competitions View Component for regatta races
*/
.phase {
font-size: 1rem;
margin-bottom: 2em;
}
.phase_head {
padding: 1.333333333333333em 1.333333333333333em 2.666666666666667em 2em;
background-color: #f2f2f2;
border: 1px solid #dedede;
border-radius: 0.333333333333333em 0.333333333333333em 0 0;
font-weight: 600;
color: #666;
}
.phase_head_title {
text-transform: uppercase;
float: left;
}
.phase_head_info {
font-size: 0.866666666666667em;
text-align: right;
float: right;
}
.phase_head_info_item {
display: inline-block;
padding-left: 0.769230769230769em;
margin-left: 0.769230769230769em;
border-left: 1px solid #dedede;
}
.phase_head_info_item:first-child {
border: none;
padding-left: 0;
margin-left: 0;
}
.regattalistitem .phase {
margin: 0;
}
.regattalistitem .phase_head {
background-color: transparent;
border: none;
border-radius: 0;
border-bottom: 1px solid #dedede;
}
.fleet {
font-size: 1rem;
border: 1px solid #dedede;
border-top: none;
position: relative;
}
.fleet:last-child {
border-radius: 0 0 0.333333333333333em 0.333333333333333em;
}
.fleet_corner {
position: absolute;
content: '';
display: block;
top: 1px;
left: 1px;
border-style: solid;
border-width: 1em 1em 0 0;
border-color: transparent;
}
.fleet_details {
color: #333;
position: absolute;
top: 1.333333333333333em;
left: 2em;
width: 20%;
}
@media (min-width: 61em) {
.fleet_details {
width: 13%;
}
}
.fleet_details_name {
font-weight: 600;
}
.fleet_details_competitors {
font-size: 0.866666666666667em;
color: #666;
}
.fleet_races {
padding: 0 1.333333333333333em 1% 25%;
}
@media (min-width: 61em) {
.fleet_races {
padding-left: 17%;
}
}
.fleet_races_race {
display: inline-block;
width: 19%;
margin: 1% 0 0 1%;
height: 4em;
line-height: 3.333333333333333em;
background-color: #008fcc;
border-radius: 0.2em;
-webkit-transition: background 0.2s;
-moz-transition: background 0.2s;
transition: background 0.2s;
text-decoration: none;
text-align: center;
color: #fff;
padding: 0.333333333333333em 0.333333333333333em;
}
@media (min-width: 45em) {
.fleet_races_race {
width: 15.66%;
line-height: inherit;
}
}
@media (min-width: 61em) {
.fleet_races_race {
width: 9%;
}
}
.fleet_races_race:hover {
background-color: #0081b8;
text-decoration: none;
}
.fleet_races_race_name,
.fleet_races_race_date {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.fleet_races_race_name {
font-size: 1.466666666666667em;
font-weight: 700;
}
.fleet_races_race_name:after {
content: '';
display: inline-block;
width: 0.466666666666667em;
height: 0.466666666666667em;
background: url("../images/home/skip-forward.png") no-repeat center center;
margin: 0 0 0.133333333333333em 0.133333333333333em;
}
.fleet_races_race_date {
width: 100%;
font-size: 0.666666666666667em;
font-weight: 600;
}
.fleet_races_raceuntracked {
background-color: #999;
}
.fleet_races_raceuntracked:hover {
background-color: #8a8a8a;
}
.fleet_races_racelive {
background-color: #e94a1b;
}
.fleet_races_racelive:hover {
background-color: #d54115;
}
.fleet_races_raceplanned {
color: #999;
background-color: #fff;
border: 1px solid #999;
}
.fleet_races_raceplanned:hover {
background-color: #e6e6e6;
}
.fleet_races_raceplanned .fleet_races_race_name:after {
display: none;
}
.regattalistitem .fleet {
border: none;
border-bottom: 1px solid #dedede;
}
.regattalistitem .fleet:last-of-type {
border-radius: 0;
}
@@ -0,0 +1,38 @@
package com.sap.sailing.gwt.home.client.place.event.partials.raceCompetition;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.ui.shared.dispatch.event.RaceListFleetDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.event.RaceListRaceDTO;
public class RegattaCompetitionFleet extends Widget {
private static RegattaCompetitionFleetUiBinder uiBinder = GWT.create(RegattaCompetitionFleetUiBinder.class);
interface RegattaCompetitionFleetUiBinder extends UiBinder<Element, RegattaCompetitionFleet> {
}
@UiField DivElement fleetCornerUi;
@UiField DivElement fleetNameUi;
@UiField DivElement competitorCountUi;
@UiField DivElement racesContainerUi;
public RegattaCompetitionFleet(RaceListFleetDTO fleet) {
setElement(uiBinder.createAndBindUi(this));
this.competitorCountUi.setInnerText(fleet.getCompetitorCount() + " Comp. TODO");
if (fleet.getFleet() != null) {
fleetNameUi.setInnerText(fleet.getFleet().getFleetName());
fleetCornerUi.getStyle().setProperty("borderTopColor", fleet.getFleet().getFleetColor());
}
}
public void addRace(RaceListRaceDTO race, String raceViewerURL) {
RegattaCompetitionFleetRace competitionRace = new RegattaCompetitionFleetRace(race, raceViewerURL);
racesContainerUi.appendChild(competitionRace.getElement());
}
}
@@ -0,0 +1,14 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:p='urn:import:com.sap.sailing.gwt.home.client.place.event.partials'>
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.raceCompetition.RegattaCompetitionResources" />
<div class="{local_res.css.fleet}">
<div class="{local_res.css.fleet_corner}" ui:field="fleetCornerUi"></div>
<div class="{local_res.css.fleet_details}">
<div class="{local_res.css.fleet_details_name}" ui:field="fleetNameUi"></div>
<div class="{local_res.css.fleet_details_competitors}" ui:field="competitorCountUi"></div>
</div>
<div class="{local_res.css.fleet_races}" ui:field="racesContainerUi"></div>
</div>
</ui:UiBinder>
@@ -0,0 +1,48 @@
package com.sap.sailing.gwt.home.client.place.event.partials.raceCompetition;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.UIObject;
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
import com.sap.sailing.gwt.ui.shared.dispatch.event.RaceListRaceDTO;
import com.sap.sailing.gwt.ui.shared.race.RaceMetadataDTO.RaceTrackingState;
import com.sap.sailing.gwt.ui.shared.race.RaceMetadataDTO.RaceViewState;
public class RegattaCompetitionFleetRace extends UIObject {
private static RegattaCompetitionFleetRaceUiBinder uiBinder = GWT.create(RegattaCompetitionFleetRaceUiBinder.class);
interface RegattaCompetitionFleetRaceUiBinder extends UiBinder<AnchorElement, RegattaCompetitionFleetRace> {
}
@UiField RegattaCompetitionResources local_res;
@UiField DivElement raceNameUi;
@UiField DivElement raceDateUi;
private final AnchorElement anchor;
public RegattaCompetitionFleetRace(RaceListRaceDTO race, String raceViewerUrl) {
anchor = uiBinder.createAndBindUi(this);
anchor.setHref(raceViewerUrl);
local_res.css().ensureInjected();
setupRaceState(race.getTrackingState(), race.getViewState());
this.raceNameUi.setInnerText(race.getRaceName());
if (race.getStart() != null) {
this.raceDateUi.setInnerText(DateAndTimeFormatterUtil.defaultDateFormatter.render(race.getStart()));
}
setElement(anchor);
}
private void setupRaceState(RaceTrackingState trackingState, RaceViewState viewState) {
if (viewState == RaceViewState.RUNNING) {
anchor.addClassName(local_res.css().fleet_races_racelive());
} else if (viewState == RaceViewState.PLANNED || viewState == RaceViewState.SCHEDULED) {
anchor.addClassName(local_res.css().fleet_races_raceplanned());
}
if (trackingState != RaceTrackingState.TRACKED_VALID_DATA) {
anchor.addClassName(local_res.css().fleet_races_raceuntracked());
}
}
}
@@ -0,0 +1,10 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:p='urn:import:com.sap.sailing.gwt.home.client.place.event.partials'>
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.raceCompetition.RegattaCompetitionResources" />
<a class="{local_res.css.fleet_races_race}" target="_blank">
<div class="{local_res.css.fleet_races_race_name}" ui:field="raceNameUi"></div>
<div class="{local_res.css.fleet_races_race_date} {res.mediaCss.hideonsmall}" ui:field="raceDateUi"></div>
</a>
</ui:UiBinder>
@@ -0,0 +1,33 @@
package com.sap.sailing.gwt.home.client.place.event.partials.raceCompetition;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
public interface RegattaCompetitionResources extends ClientBundle {
public static final RegattaCompetitionResources INSTANCE = GWT.create(RegattaCompetitionResources.class);
@Source("RegattaCompetition.gss")
LocalCss css();
public interface LocalCss extends CssResource {
String phase();
String phase_head();
String phase_head_title();
String phase_head_info();
String phase_head_info_item();
String regattalistitem();
String fleet();
String fleet_corner();
String fleet_details();
String fleet_details_name();
String fleet_details_competitors();
String fleet_races();
String fleet_races_race();
String fleet_races_race_name();
String fleet_races_race_date();
String fleet_races_raceuntracked();
String fleet_races_racelive();
String fleet_races_raceplanned();
}
}
@@ -0,0 +1,47 @@
package com.sap.sailing.gwt.home.client.place.event.partials.raceCompetition;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.sap.sailing.gwt.home.client.place.event.regatta.EventRegattaView.Presenter;
import com.sap.sailing.gwt.ui.shared.dispatch.event.RaceListFleetDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.event.RaceListRaceDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.event.RaceListSeriesDTO;
import com.sap.sailing.gwt.ui.shared.race.RaceMetadataDTO.RaceTrackingState;
public class RegattaCompetitionSeries extends Composite {
private static RegattaCompetitionSeriesUiBinder uiBinder = GWT.create(RegattaCompetitionSeriesUiBinder.class);
interface RegattaCompetitionSeriesUiBinder extends UiBinder<HTMLPanel, RegattaCompetitionSeries> {
}
@UiField DivElement seriesNameUi;
@UiField DivElement competitorCountUi;
@UiField DivElement raceCountUi;
private final HTMLPanel containerUi;
public RegattaCompetitionSeries(Presenter presenter, RaceListSeriesDTO series) {
initWidget(containerUi = uiBinder.createAndBindUi(this));
this.seriesNameUi.setInnerText(series.getSeriesName());
this.competitorCountUi.setInnerText(series.getCompetitorCount() + " Comp. TODO");
this.raceCountUi.setInnerText(series.getRaceCount() + " Races TODO");
for (RaceListFleetDTO fleet : series.getFleets()) {
addFleet(presenter, fleet);
}
}
public void addFleet(Presenter presenter, RaceListFleetDTO fleet) {
RegattaCompetitionFleet competitionFleet = new RegattaCompetitionFleet(fleet);
for (RaceListRaceDTO race : fleet.getRaces()) {
boolean tracked = race.getTrackingState() == RaceTrackingState.TRACKED_VALID_DATA;
String raceViewerUrl = tracked ? presenter.getRaceViewerURL(race.getRegattaName(), race.getTrackedRaceName()) : null;
competitionFleet.addRace(race, raceViewerUrl);
}
containerUi.add(competitionFleet);
}
}
@@ -0,0 +1,15 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:p='urn:import:com.sap.sailing.gwt.home.client.place.event.partials'>
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.raceCompetition.RegattaCompetitionResources" />
<g:HTMLPanel addStyleNames="{local_res.css.phase}">
<div class="{local_res.css.phase_head}">
<div class="{local_res.css.phase_head_title}" ui:field="seriesNameUi"></div>
<div class="{local_res.css.phase_head_info}">
<div class="{local_res.css.phase_head_info_item}" ui:field="competitorCountUi"></div>
<div class="{local_res.css.phase_head_info_item}" ui:field="raceCountUi"></div>
</div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -66,7 +66,7 @@
}
.race_itemwinner {
overflow: hidden;
white-space: nowrap;
white-space: normal;
text-overflow: ellipsis;
vertical-align: middle;
min-width: 13.333333333333334em;
@@ -1,40 +1,77 @@
package com.sap.sailing.gwt.home.client.place.event.partials.raceListLive;
import com.google.gwt.core.client.GWT;
import java.util.Collection;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.client.place.event.EventView;
import com.sap.sailing.gwt.home.client.place.event.partials.racelist.RaceList;
import com.sap.sailing.gwt.home.client.place.event.partials.racelist.AbstractRaceList;
import com.sap.sailing.gwt.home.client.place.event.partials.racelist.RaceListColumnFactory;
import com.sap.sailing.gwt.home.client.place.event.partials.racelist.RaceListContainer;
import com.sap.sailing.gwt.home.client.place.event.partials.racelist.RaceListDataUtil;
import com.sap.sailing.gwt.home.client.place.event.partials.racelist.SortableRaceListColumn;
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshableWidget;
import com.sap.sailing.gwt.ui.shared.dispatch.event.LiveRacesDTO;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.dispatch.CollectionResult;
import com.sap.sailing.gwt.ui.shared.dispatch.event.LiveRaceDTO;
public class RacesListLive extends Composite implements RefreshableWidget<LiveRacesDTO> {
public class RacesListLive extends Composite {
private static RacesListLiveUiBinder uiBinder = GWT.create(RacesListLiveUiBinder.class);
private final RaceListLiveRaces raceList;
private final RaceListContainer<LiveRaceDTO> raceListContainer;
interface RacesListLiveUiBinder extends UiBinder<Widget, RacesListLive> {
}
@UiField(provided = true) RaceList raceList;
public RacesListLive(EventView.Presenter presenter, boolean showRegattaDetails) {
RacesListLiveResources.INSTANCE.css().ensureInjected();
raceList = new RaceList(presenter, showRegattaDetails);
initWidget(uiBinder.createAndBindUi(this));
raceList = new RaceListLiveRaces(presenter, showRegattaDetails);
raceListContainer = new RaceListContainer<LiveRaceDTO>(StringMessages.INSTANCE.liveNow(), raceList);
initWidget(raceListContainer);
getElement().getStyle().setDisplay(Display.NONE);
}
@Override
public void setData(LiveRacesDTO data, long nextUpdate, int updateNo) {
if(data == null || data.getRaces().isEmpty()) {
getElement().getStyle().setDisplay(Display.NONE);
} else {
getElement().getStyle().clearDisplay();
this.raceList.setListData(data);
public RefreshableWidget<CollectionResult<LiveRaceDTO>> getRefreshable() {
return raceListContainer;
}
private class RaceListLiveRaces extends AbstractRaceList<LiveRaceDTO> {
private final SortableRaceListColumn<LiveRaceDTO, ?> regattaNameColumn = RaceListColumnFactory.getRegattaNameColumn();
private final SortableRaceListColumn<LiveRaceDTO, ?> flagsColumn = RaceListColumnFactory.getFlagsColumn();
private final SortableRaceListColumn<LiveRaceDTO, ?> windSpeedColumn = RaceListColumnFactory.getWindSpeedColumn();
private final SortableRaceListColumn<LiveRaceDTO, ?> courseAreaColumn = RaceListColumnFactory.getCourseAreaColumn();
private final SortableRaceListColumn<LiveRaceDTO, ?> courseColumn = RaceListColumnFactory.getCourseColumn();
private final SortableRaceListColumn<LiveRaceDTO, ?> raceViewStateColumn = RaceListColumnFactory.getRaceViewStateColumn();
public RaceListLiveRaces(EventView.Presenter presenter, boolean showRegattaDetails) {
super(presenter);
this.regattaNameColumn.setShowDetails(showRegattaDetails);
}
@Override
protected void setTableData(Collection<LiveRaceDTO> data) {
boolean hasFleets = RaceListDataUtil.hasFleets(data);
this.fleetCornerColumn.setShowDetails(hasFleets);
this.fleetNameColumn.setShowDetails(hasFleets);
this.startTimeColumn.setShowTimeOnly(!RaceListDataUtil.hasDifferentStartDates(data));
this.courseAreaColumn.setShowDetails(RaceListDataUtil.hasCourseAreas(data));
this.courseColumn.setShowDetails(RaceListDataUtil.hasCourses(data));
boolean hasWind = RaceListDataUtil.hasWind(data);
this.windSpeedColumn.setShowDetails(hasWind);
this.windDirectionColumn.setShowDetails(hasWind);
super.setTableData(data);
}
@Override
protected void initTableColumns() {
add(fleetCornerColumn);
add(regattaNameColumn);
add(raceNameColumn);
add(fleetNameColumn);
add(startTimeColumn);
add(flagsColumn);
add(windSpeedColumn);
add(windDirectionColumn);
add(courseAreaColumn);
add(courseColumn);
add(raceViewStateColumn);
add(raceViewerButtonColumn);
}
}
}
@@ -1,14 +0,0 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"
xmlns:r="urn:import:com.sap.sailing.gwt.home.client.place.event.partials.racelist">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLiveResources" />
<g:HTMLPanel addStyleNames="{local_res.css.raceslistlive}">
<h3>
<ui:text from='{i18n.liveNow}' />
</h3>
<r:RaceList ui:field="raceList"/>
</g:HTMLPanel>
</ui:UiBinder>
@@ -1,243 +1,64 @@
package com.sap.sailing.gwt.home.client.place.event.partials.racelist;
import java.util.Collection;
import java.util.Date;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.DateCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.TextTransform;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.safecss.shared.SafeStyles;
import com.google.gwt.safecss.shared.SafeStylesBuilder;
import com.google.gwt.safecss.shared.SafeStylesUtils;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortList;
import com.google.gwt.user.cellview.client.ColumnSortList.ColumnSortInfo;
import com.google.gwt.user.cellview.client.Header;
import com.google.gwt.user.cellview.client.RowStyles;
import com.google.gwt.user.cellview.client.TextHeader;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.SimplePanel;
import com.sap.sailing.domain.common.InvertibleComparator;
import com.sap.sailing.domain.common.SortingOrder;
import com.sap.sailing.domain.common.impl.NaturalComparator;
import com.sap.sailing.gwt.common.client.SharedResources;
import com.sap.sailing.gwt.common.client.SharedResources.MainCss;
import com.sap.sailing.gwt.common.client.SharedResources.MediaCss;
import com.sap.sailing.gwt.common.client.i18n.TextMessages;
import com.sap.sailing.gwt.home.client.place.event.EventView;
import com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLiveResources;
import com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLiveResources.LocalCss;
import com.sap.sailing.gwt.regattaoverview.client.FlagsMeaningExplanator;
import com.sap.sailing.gwt.regattaoverview.client.SailingFlagsBuilder;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.controls.SortableColumn;
import com.sap.sailing.gwt.home.client.place.event.partials.racelist.RaceListColumnFactory.SortableRaceListStartTimeColumn;
import com.sap.sailing.gwt.ui.leaderboard.SortedCellTable;
import com.sap.sailing.gwt.ui.shared.dispatch.event.LiveRaceDTO;
import com.sap.sailing.gwt.ui.shared.race.FlagStateDTO;
import com.sap.sailing.gwt.ui.shared.race.FleetMetadataDTO;
import com.sap.sailing.gwt.ui.shared.race.RaceMetadataDTO;
import com.sap.sailing.gwt.ui.shared.race.RaceMetadataDTO.RaceTrackingState;
import com.sap.sailing.gwt.ui.shared.race.RaceMetadataDTO.RaceViewState;
import com.sap.sailing.gwt.ui.shared.race.RaceProgressDTO;
import com.sap.sailing.gwt.ui.shared.race.SimpleWindDTO;
import com.sap.sailing.gwt.ui.shared.util.NullSafeComparableComparator;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sailing.gwt.ui.shared.race.wind.AbstractWindDTO;
import com.sap.sse.gwt.theme.client.component.celltable.CleanCellTableResources;
import com.sap.sse.gwt.theme.client.component.celltable.StyledHeaderOrFooterBuilder;
public abstract class AbstractRaceList<T extends RaceMetadataDTO> extends Composite {
public abstract class AbstractRaceList<T extends RaceMetadataDTO<? extends AbstractWindDTO>> extends Composite {
private static final LocalCss CSS = RacesListLiveResources.INSTANCE.css();
private static final MediaCss MEDIA_CSS = SharedResources.INSTANCE.mediaCss();
private static final StringMessages I18N = StringMessages.INSTANCE;
private static final CellTemplates TEMPLATE = GWT.create(CellTemplates.class);
interface CellTemplates extends SafeHtmlTemplates {
@Template("<div style=\"{1}\" class=\"{0}\"></div>")
SafeHtml fleetCorner(String styleNames, SafeStyles color);
@Template("<div>{3}</div><div class=\"{0}\"><div style=\"{2}\" class=\"{1}\"></div></div>")
SafeHtml viewStateRunning(String styleNamesBar, String styleNamesProgress, SafeStyles width, String text);
@Template("<img style=\"{0}\" src=\"images/home/windkompass_nord.svg\"/>")
SafeHtml windDirection(SafeStyles rotation);
@Template("<div style=\"{0}\">{1}</div>")
SafeHtml raceNotTracked(SafeStyles styles, String text);
@Template("<a href=\"{2}\" class=\"{0}\" target=\"_blank\">{1}</a>")
SafeHtml raceViewerLinkButton(String styleNames, String text, String link);
}
private final SimplePanel cellTableContainer = new SimplePanel();
private final EventView.Presenter presenter;
protected final SortableRaceListColumn<?> fleetCornerColumn = new RaceListColumn<FleetMetadataDTO>("",
new FleetCornerCell()) {
@Override
public String getColumnStyle() {
return CSS.race_fleetcorner();
}
@Override
public FleetMetadataDTO getValue(T object) {
return object.getFleet();
}
};
protected final SortableRaceListColumn<?> raceNameColumn = new SortableRaceListColumn<String>(I18N.race(),
new TextCell(), new InvertibleComparatorWrapper<T, String>(new NaturalComparator(false)) {
@Override
protected String getComparisonValue(T object) {
return object.getRaceName();
}
}) {
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), CSS.race_itemname());
}
@Override
public String getValue(T object) {
return object.getRaceName();
}
};
protected final SortableRaceListColumn<?> fleetNameColumn = new SortableRaceListColumn<String>(I18N.fleet(),
new TextCell(), new InvertibleComparatorWrapper<T, String>(new NaturalComparator(false)) {
@Override
protected String getComparisonValue(T object) {
return object.getFleet() != null ? object.getFleet().getFleetName() : null;
}
}) {
@Override
public String getHeaderStyle() {
return getStyleNamesString(CSS.raceslist_head_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getValue(T object) {
return object.getFleet() != null ? object.getFleet().getFleetName() : null;
}
};
protected final SortableRaceListColumn<?> startTimeColumn = new SortableRaceListColumn<Date>(I18N.start(),
new DateCell(DateTimeFormat.getFormat(PredefinedFormat.HOUR24_MINUTE)),
new InvertibleComparatorWrapper<T, Date>(new NullSafeComparableComparator<Date>()) {
@Override
protected Date getComparisonValue(T object) {
return object.getStart();
}
}) {
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return CSS.race_item();
}
@Override
public Date getValue(T object) {
return object.getStart();
}
};
protected final SortableRaceListColumn<?> courseAreaColumn = new SortableRaceListColumn<String>(I18N.courseArea(),
new TextCell(), new InvertibleComparatorWrapper<T, String>(new NaturalComparator(false)) {
@Override
protected String getComparisonValue(T object) {
return object.getCourseArea();
}
}) {
@Override
public String getHeaderStyle() {
return getStyleNamesString(CSS.raceslist_head_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getValue(T object) {
return object.getCourseArea();
}
};
protected final SortableRaceListColumn<?> courseColumn = new SortableRaceListColumn<String>(I18N.course(),
new TextCell(), new InvertibleComparatorWrapper<T, String>(new NaturalComparator(false)) {
@Override
protected String getComparisonValue(T object) {
return object.getCourse();
}
}) {
@Override
public String getHeaderStyle() {
return getStyleNamesString(CSS.raceslist_head_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getValue(T object) {
return object.getCourse();
}
};
protected final SortableRaceListColumn<?> raceViewerButtonColumn = new RaceListColumn<T>("",
new RaceViewerButtonCell()) {
@Override
public String getHeaderStyle() {
return getStyleNamesString(CSS.raceslist_head_item(), CSS.raceslist_head_itembutton());
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), CSS.race_itemright());
}
@Override
public T getValue(T object) {
return object;
}
};
protected final SortableRaceListColumn<T, ?> fleetCornerColumn = RaceListColumnFactory.getFleetCornerColumn();
protected final SortableRaceListColumn<T, ?> raceNameColumn = RaceListColumnFactory.getRaceNameColumn();
protected final SortableRaceListColumn<T, ?> fleetNameColumn = RaceListColumnFactory.getFleetNameColumn();
protected final SortableRaceListStartTimeColumn<T> startTimeColumn = RaceListColumnFactory.getStartTimeColumn();
protected final SortableRaceListColumn<T, ?> windDirectionColumn = RaceListColumnFactory.getWindDirectionColumn();
protected final SortableRaceListColumn<T, ?> raceViewerButtonColumn;
private SortedCellTable<T> cellTable;
protected AbstractRaceList(EventView.Presenter presenter) {
CSS.ensureInjected();
this.presenter = presenter;
this.raceViewerButtonColumn = RaceListColumnFactory.getRaceViewerButtonColumn(presenter);
this.initWidget(cellTableContainer);
}
@SuppressWarnings("unchecked")
protected void setTableData(Collection<T> data) {
Column<T, ?> sortColumn = (this.cellTable == null ? null : this.cellTable.getCurrentlySortedColumn());
ColumnSortList sortList = this.cellTable == null ? null : this.cellTable.getColumnSortList();
this.cellTable = new SortedCellTable<T>(data.size(), CleanCellTableResources.INSTANCE);
this.cellTableContainer.setWidget(this.cellTable);
this.initTableStyle();
this.initTableColumns();
this.cellTable.setList(data);
if (sortColumn != null && this.cellTable.getColumnIndex(sortColumn) >= 0) {
this.cellTable.sortColumn(sortColumn);
if (sortList != null && sortList.size() > 0) {
for (int i = sortList.size() - 1; i >= 0; i--) {
ColumnSortInfo sortInfo = sortList.get(i);
Column<T, ?> column = (Column<T, ?>) sortInfo.getColumn();
if(this.cellTable.getColumnIndex(column) >= 0) {
this.cellTable.sortColumn(column, sortInfo.isAscending());
}
}
} else {
this.cellTable.sortColumn(startTimeColumn);
}
}
@@ -254,124 +75,22 @@ public abstract class AbstractRaceList<T extends RaceMetadataDTO> extends Compos
protected abstract void initTableColumns();
protected void add(SortableRaceListColumn<?> column) {
if (column.getColumnStyle() != null) {
column.setCellStyleNames(column.getColumnStyle());
}
Header<?> header = column.getHeader();
if (header != null && column.getHeaderStyle() != null) {
header.setHeaderStyleNames(column.getHeaderStyle());
}
boolean ascending = column.getPreferredSortingOrder().isAscending();
this.cellTable.addColumn(column, header, column.getComparator(), ascending);
}
protected abstract class SortableRaceListColumn<C> extends SortableColumn<T, C> {
private final String headerText;
private final InvertibleComparator<T> comparator;
protected SortableRaceListColumn(String headerText, Cell<C> cell, InvertibleComparator<T> comparator) {
super(cell, SortingOrder.ASCENDING);
this.headerText = headerText;
this.comparator = comparator;
}
@Override
public final InvertibleComparator<T> getComparator() {
return comparator;
}
@Override
public final Header<?> getHeader() {
return new TextHeader(headerText);
}
protected final String getStyleNamesString(String... styleNames) {
return Util.join(" ", styleNames);
}
}
protected abstract class RaceListColumn<C> extends SortableRaceListColumn<C> {
protected RaceListColumn(String headerText, Cell<C> cell) {
super(headerText, cell, null);
}
}
private class FleetCornerCell extends AbstractCell<FleetMetadataDTO> {
@Override
public void render(Context context, FleetMetadataDTO value, SafeHtmlBuilder sb) {
if (value != null) {
sb.append(TEMPLATE.fleetCorner(CSS.race_fleetcorner_icon(),
SafeStylesUtils.fromTrustedNameAndValue("border-top-color", value.getFleetColor())));
protected void add(SortableRaceListColumn<T, ?> column) {
if (column.isShowDetails()) {
if (column.getColumnStyle() != null) {
column.setCellStyleNames(column.getColumnStyle());
}
}
}
protected class FlagsCell extends AbstractCell<FlagStateDTO> {
@Override
public void render(Context context, FlagStateDTO value, SafeHtmlBuilder sb) {
if (value != null) {
sb.append(SailingFlagsBuilder.render(value, 0.55, FlagsMeaningExplanator.getFlagsMeaning(I18N,
value.getLastUpperFlag(), value.getLastLowerFlag(), value.isLastFlagsAreDisplayed())));
Header<?> header = column.getHeader();
if (header != null && column.getHeaderStyle() != null) {
header.setHeaderStyleNames(column.getHeaderStyle());
}
}
}
protected class WindDirectionCell extends AbstractCell<SimpleWindDTO> {
@Override
public void render(Context context, SimpleWindDTO value, SafeHtmlBuilder sb) {
if (value != null) {
SafeStylesBuilder safeStyles = new SafeStylesBuilder();
safeStyles.trustedNameAndValue("-webkit-transform", "rotate(" + value.getTrueWindFromDeg() + "deg)");
safeStyles.trustedNameAndValue("transform", "rotate(" + value.getTrueWindFromDeg() + "deg)");
safeStyles.width(2.75, Unit.EM).height(2.75, Unit.EM);
sb.append(TEMPLATE.windDirection(safeStyles.toSafeStyles()));
boolean ascending = column.getPreferredSortingOrder().isAscending();
InvertibleComparator<T> comperator = column.getComparator();
if (comperator != null) {
comperator.setAscending(ascending);
}
this.cellTable.addColumn(column, header, comperator, ascending);
}
}
protected class RaceViewStateCell extends AbstractCell<LiveRaceDTO> {
@Override
public void render(Context context, LiveRaceDTO value, SafeHtmlBuilder sb) {
RaceViewState state = value.getViewState();
RaceProgressDTO progress = value.getProgress();
if (state == RaceViewState.SCHEDULED) {
double min = MillisecondsTimePoint.now().until(new MillisecondsTimePoint(value.getStart())).asMinutes();
sb.appendEscaped(I18N.startingInMinutes((int) min));
} else if (state == RaceViewState.RUNNING && progress != null) {
SafeStyles width = SafeStylesUtils.forWidth(progress.getPercentageProgress(), Unit.PCT);
String text = I18N.currentOfTotalLegs(progress.getCurrentLeg(), progress.getTotalLegs());
sb.append(TEMPLATE.viewStateRunning(CSS.race_itemstatus_progressbar(),
CSS.race_itemstatus_progressbar_progress(), width, text));
} else {
sb.appendEscaped(state.getLabel());
}
}
}
private class RaceViewerButtonCell extends AbstractCell<T> {
private final TextMessages I18N_UBI = TextMessages.INSTANCE;
private final MainCss css = SharedResources.INSTANCE.mainCss();
private final String watchNowStyle = getButtonStyleNames(css.buttonred());
private final String analyseRaceStyle = getButtonStyleNames(css.buttonprimary());
@Override
public void render(Context context, T data, SafeHtmlBuilder sb) {
if (data.getTrackingState() != RaceTrackingState.TRACKED_VALID_DATA) {
SafeStylesBuilder styles = new SafeStylesBuilder().textTransform(TextTransform.UPPERCASE);
styles.trustedColor("#666").trustedNameAndValue("font-size", "0.933333333333333rem").toSafeStyles();
styles.trustedNameAndValue("padding", "0.714285714285714em 1.071428571428571em");
sb.append(TEMPLATE.raceNotTracked(styles.toSafeStyles(), I18N_UBI.eventRegattaRaceNotTracked()));
} else {
String styleNames = data.getViewState() == RaceViewState.FINISHED ? analyseRaceStyle : watchNowStyle;
String text = data.getViewState() == RaceViewState.FINISHED ? I18N.analyseRace() : I18N_UBI.watchNow();
String raceViewerURL = presenter.getRaceViewerURL(data.getRegattaName(), data.getTrackedRaceName());
sb.append(TEMPLATE.raceViewerLinkButton(styleNames, text, raceViewerURL));
}
}
private final String getButtonStyleNames(String buttonColor) {
return Util.join(" ", css.button(), css.buttonstrong(), buttonColor, css.buttonarrowrightwhite());
}
}
}
@@ -1,179 +0,0 @@
package com.sap.sailing.gwt.home.client.place.event.partials.racelist;
import com.google.gwt.cell.client.TextCell;
import com.sap.sailing.domain.common.impl.NaturalComparator;
import com.sap.sailing.gwt.common.client.SharedResources;
import com.sap.sailing.gwt.common.client.SharedResources.MediaCss;
import com.sap.sailing.gwt.home.client.place.event.EventView;
import com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLiveResources;
import com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLiveResources.LocalCss;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.dispatch.event.LiveRaceDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.event.LiveRacesDTO;
import com.sap.sailing.gwt.ui.shared.race.FlagStateDTO;
import com.sap.sailing.gwt.ui.shared.race.RaceMetadataDTO.RaceViewState;
import com.sap.sailing.gwt.ui.shared.race.SimpleWindDTO;
import com.sap.sailing.gwt.ui.shared.util.NullSafeComparableComparator;
public class RaceList extends AbstractRaceList<LiveRaceDTO> {
private static final LocalCss CSS = RacesListLiveResources.INSTANCE.css();
private static final MediaCss MEDIA_CSS = SharedResources.INSTANCE.mediaCss();
private static final StringMessages I18N = StringMessages.INSTANCE;
private final boolean showRegattaDetails;
private boolean showFleetDetails;
private boolean showCourseAreaDetails;
private boolean showCourseDetails;
private boolean showWindDetails;
private final SortableRaceListColumn<?> regattaNameColumn = new SortableRaceListColumn<String>(I18N.regatta(),
new TextCell(), new InvertibleComparatorWrapper<LiveRaceDTO, String>(new NaturalComparator(false)) {
@Override
protected String getComparisonValue(LiveRaceDTO object) {
return object.getRegattaDisplayName();
}
}) {
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), CSS.race_itemname());
}
@Override
public String getValue(LiveRaceDTO object) {
return object.getRegattaDisplayName();
}
};
private final SortableRaceListColumn<?> flagsColumn = new RaceListColumn<FlagStateDTO>(I18N.flags(),
new FlagsCell()) {
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), CSS.racesListIcon());
}
@Override
public FlagStateDTO getValue(LiveRaceDTO object) {
return object.getFlagState();
}
};
private final SortableRaceListColumn<?> windSpeedColumn = new SortableRaceListColumn<String>(I18N.wind(),
new TextCell(), new InvertibleComparatorWrapper<LiveRaceDTO, Double>(
new NullSafeComparableComparator<Double>()) {
@Override
protected Double getComparisonValue(LiveRaceDTO object) {
return object.getWind() != null ? object.getWind().getTrueWindSpeedInKnots() : null;
}
}) {
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return CSS.race_item();
}
@Override
public String getValue(LiveRaceDTO object) {
return object.getWind() != null ? I18N.knotsValue(object.getWind().getTrueWindSpeedInKnots()) : null;
}
};
private final SortableRaceListColumn<?> windDirectionColumn = new SortableRaceListColumn<SimpleWindDTO>(
I18N.from(), new WindDirectionCell(), new InvertibleComparatorWrapper<LiveRaceDTO, Double>(
new NullSafeComparableComparator<Double>()) {
@Override
protected Double getComparisonValue(LiveRaceDTO object) {
return object.getWind() != null ? object.getWind().getTrueWindFromDeg() : null;
}
}) {
@Override
public String getHeaderStyle() {
return getStyleNamesString(CSS.raceslist_head_item(), MEDIA_CSS.hideonsmall());
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), CSS.racesListIcon(), MEDIA_CSS.hideonsmall());
}
@Override
public SimpleWindDTO getValue(LiveRaceDTO object) {
return object.getWind();
}
};
private final SortableRaceListColumn<?> raceViewStateColumn = new SortableRaceListColumn<LiveRaceDTO>(
I18N.status(), new RaceViewStateCell(), new InvertibleComparatorWrapper<LiveRaceDTO, RaceViewState>(
new NullSafeComparableComparator<RaceViewState>()) {
@Override
protected RaceViewState getComparisonValue(LiveRaceDTO object) {
return object.getViewState();
}
}) {
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return CSS.race_item();
}
@Override
public LiveRaceDTO getValue(LiveRaceDTO object) {
return object;
}
};
public RaceList(EventView.Presenter presenter, boolean showRegattaDetails) {
super(presenter);
this.showRegattaDetails = showRegattaDetails;
}
public void setListData(LiveRacesDTO data) {
this.showFleetDetails = data.hasFleets();
this.showCourseAreaDetails = data.hasCourseAreas();
this.showCourseDetails = data.hasCourses();
this.showWindDetails = data.hasWind();
setTableData(data.getRaces());
}
@Override
protected void initTableColumns() {
if (showFleetDetails) {
add(fleetCornerColumn);
}
if (showRegattaDetails) {
add(regattaNameColumn);
}
add(raceNameColumn);
if (showFleetDetails) {
add(fleetNameColumn);
}
add(startTimeColumn);
add(flagsColumn);
if(showWindDetails) {
add(windSpeedColumn);
add(windDirectionColumn);
}
if (showCourseAreaDetails) {
add(courseAreaColumn);
}
if(showCourseDetails) {
add(courseColumn);
}
add(raceViewStateColumn);
add(raceViewerButtonColumn);
}
}
@@ -0,0 +1,627 @@
package com.sap.sailing.gwt.home.client.place.event.partials.racelist;
import java.util.Date;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.TextTransform;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.safecss.shared.SafeStyles;
import com.google.gwt.safecss.shared.SafeStylesBuilder;
import com.google.gwt.safecss.shared.SafeStylesUtils;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeUri;
import com.google.gwt.safehtml.shared.UriUtils;
import com.google.gwt.user.cellview.client.SafeHtmlHeader;
import com.sap.sailing.domain.common.InvertibleComparator;
import com.sap.sailing.domain.common.SortingOrder;
import com.sap.sailing.domain.common.impl.NaturalComparator;
import com.sap.sailing.gwt.common.client.SharedResources;
import com.sap.sailing.gwt.common.client.SharedResources.MainCss;
import com.sap.sailing.gwt.common.client.SharedResources.MediaCss;
import com.sap.sailing.gwt.common.client.i18n.TextMessages;
import com.sap.sailing.gwt.home.client.place.event.EventView;
import com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLiveResources;
import com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLiveResources.LocalCss;
import com.sap.sailing.gwt.regattaoverview.client.FlagsMeaningExplanator;
import com.sap.sailing.gwt.regattaoverview.client.SailingFlagsBuilder;
import com.sap.sailing.gwt.ui.client.FlagImageResolver;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
import com.sap.sailing.gwt.ui.shared.dispatch.event.LiveRaceDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.event.RaceListRaceDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.event.SimpleCompetitorDTO;
import com.sap.sailing.gwt.ui.shared.race.FlagStateDTO;
import com.sap.sailing.gwt.ui.shared.race.FleetMetadataDTO;
import com.sap.sailing.gwt.ui.shared.race.RaceMetadataDTO;
import com.sap.sailing.gwt.ui.shared.race.RaceMetadataDTO.RaceTrackingState;
import com.sap.sailing.gwt.ui.shared.race.RaceMetadataDTO.RaceViewState;
import com.sap.sailing.gwt.ui.shared.race.RaceProgressDTO;
import com.sap.sailing.gwt.ui.shared.race.wind.AbstractWindDTO;
import com.sap.sailing.gwt.ui.shared.race.wind.WindStatisticsDTO;
import com.sap.sailing.gwt.ui.shared.util.NullSafeComparableComparator;
import com.sap.sailing.gwt.ui.shared.util.NullSafeComparatorWrapper;
import com.sap.sse.common.Duration;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class RaceListColumnFactory {
private static final LocalCss CSS = RacesListLiveResources.INSTANCE.css();
private static final MainCss MAIN_CSS = SharedResources.INSTANCE.mainCss();
private static final MediaCss MEDIA_CSS = SharedResources.INSTANCE.mediaCss();
private static final StringMessages I18N = StringMessages.INSTANCE;
private static final TextMessages I18N_UBI = TextMessages.INSTANCE;
private static final CellTemplates TEMPLATE = GWT.create(CellTemplates.class);
interface CellTemplates extends SafeHtmlTemplates {
@Template("<div style=\"{1}\" class=\"{0}\"></div>")
SafeHtml fleetCorner(String styleNames, SafeStyles color);
@Template("<div>{3}</div><div class=\"{0}\"><div style=\"{2}\" class=\"{1}\"></div></div>")
SafeHtml viewStateRunning(String styleNamesBar, String styleNamesProgress, SafeStyles width, String text);
@Template("<img style=\"{0}\" src=\"images/home/windkompass_nord.svg\"/>")
SafeHtml windDirection(SafeStyles rotation);
@Template("<div style=\"{0}\">{1}</div>")
SafeHtml raceNotTracked(SafeStyles styles, String text);
@Template("<a href=\"{2}\" class=\"{0}\" target=\"_blank\">{1}</a>")
SafeHtml raceViewerLinkButton(String styleNames, String text, String link);
@Template("<img src=\"{2}\" class=\"{0}\" /><span class=\"{1}\">{3}</span>")
SafeHtml winner(String styleNamesFlag, String styleNamesText, SafeUri flagImageURL, String name);
@Template("<img src=\"{1}\" class=\"{0}\" />")
SafeHtml imageHeader(String styleNames, SafeUri imageURL);
}
public static <T extends RaceMetadataDTO<?>> SortableRaceListColumn<T, FleetMetadataDTO> getFleetCornerColumn() {
Cell<FleetMetadataDTO> cell = new AbstractCell<FleetMetadataDTO>() {
@Override
public void render(Context context, FleetMetadataDTO value, SafeHtmlBuilder sb) {
if (value != null) {
SafeStyles style = SafeStylesUtils.fromTrustedNameAndValue("border-top-color", value.getFleetColor());
sb.append(TEMPLATE.fleetCorner(CSS.race_fleetcorner_icon(), style));
}
}
};
InvertibleComparator<T> comparator = null;
return new SortableRaceListColumn<T, FleetMetadataDTO>("", cell, comparator) {
@Override
public String getColumnStyle() {
return CSS.race_fleetcorner();
}
@Override
public FleetMetadataDTO getValue(T object) {
return object.getFleet();
}
};
}
public static <T extends RaceMetadataDTO<?>> SortableRaceListColumn<T, String> getRegattaNameColumn() {
Cell<String> cell = new TextCell();
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, String>(new NaturalComparator(false)) {
@Override
protected String getComparisonValue(T object) {
return object.getRegattaDisplayName();
}
};
return new SortableRaceListColumn<T, String>(I18N.regatta(), cell, comparator) {
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), CSS.race_itemname());
}
@Override
public String getValue(T object) {
return object.getRegattaDisplayName();
}
};
}
public static <T extends RaceMetadataDTO<?>> SortableRaceListColumn<T, String> getRaceNameColumn() {
Cell<String> cell = new TextCell();
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, String>(new NaturalComparator(false)) {
@Override
protected String getComparisonValue(T object) {
return object.getRaceName();
}
};
return new SortableRaceListColumn<T, String>(I18N.race(), cell, comparator) {
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), CSS.race_itemname());
}
@Override
public String getValue(T object) {
return object.getRaceName();
}
};
}
public static <T extends RaceMetadataDTO<?>> SortableRaceListColumn<T, String> getFleetNameColumn() {
Cell<String> cell = new TextCell();
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, String>(new NaturalComparator(false)) {
@Override
protected String getComparisonValue(T object) {
return object.getFleet() != null ? object.getFleet().getFleetName() : null;
}
};
return new SortableRaceListColumn<T, String>(I18N.fleet(), cell, comparator) {
@Override
public String getHeaderStyle() {
return getStyleNamesString(CSS.raceslist_head_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getValue(T object) {
return object.getFleet() != null ? object.getFleet().getFleetName() : null;
}
};
}
public static <T extends RaceMetadataDTO<?>> SortableRaceListStartTimeColumn<T> getStartTimeColumn() {
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, Date>(new NullSafeComparableComparator<Date>(true)) {
@Override
protected Date getComparisonValue(T object) {
return object.getStart();
}
};
return new SortableRaceListStartTimeColumn<T>(comparator);
}
public static <T extends RaceListRaceDTO> SortableRaceListColumn<T, String> getDurationColumn() {
Cell<String> cell = new TextCell();
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, Duration>(new NullSafeComparableComparator<Duration>(false)) {
@Override
protected Duration getComparisonValue(T object) {
return object.getDuration();
}
};
return new SortableRaceListColumn<T, String>(I18N.durationPlain(), cell, comparator) {
@Override
public String getHeaderStyle() {
return getStyleNamesString(CSS.raceslist_head_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getValue(T object) {
return object.getDuration() != null ? DateAndTimeFormatterUtil.formatElapsedTime(object.getDuration().asMillis()) : null;
}
};
}
public static <T extends LiveRaceDTO> SortableRaceListColumn<T, FlagStateDTO> getFlagsColumn() {
Cell<FlagStateDTO> cell = new AbstractCell<FlagStateDTO>() {
@Override
public void render(Context context, FlagStateDTO value, SafeHtmlBuilder sb) {
if (value != null) {
sb.append(SailingFlagsBuilder.render(value, 0.55, FlagsMeaningExplanator.getFlagsMeaning(I18N,
value.getLastUpperFlag(), value.getLastLowerFlag(), value.isLastFlagsAreDisplayed())));
}
}
};
InvertibleComparator<T> comparator = null;
return new SortableRaceListColumn<T, FlagStateDTO>(I18N.flags(), cell, comparator) {
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), CSS.racesListIcon());
}
@Override
public FlagStateDTO getValue(T object) {
return object.getFlagState();
}
};
}
public static <T extends LiveRaceDTO> SortableRaceListColumn<T, String> getWindSpeedColumn() {
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, Double>( new NullSafeComparableComparator<Double>()) {
@Override
protected Double getComparisonValue(T object) {
return object.getWind() != null ? object.getWind().getTrueWindSpeedInKnots() : null;
}
};
return new WindSpeedOrRangeColumn<T>(comparator) {
@Override
public String getValue(T object) {
return object.getWind() != null ? I18N.knotsValue(object.getWind().getTrueWindSpeedInKnots()) : null;
}
};
}
public static <T extends RaceListRaceDTO> SortableRaceListColumn<T, String> getWindRangeColumn() {
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, Double>(new NullSafeComparableComparator<Double>()) {
@Override
protected Double getComparisonValue(T object) {
WindStatisticsDTO wind = object.getWind();
return wind != null ? (wind.getTrueUpperboundWindInKnots() + wind .getTrueLowerboundWindInKnots()) : null;
}
};
return new WindSpeedOrRangeColumn<T>(comparator) {
@Override
public String getValue(T object) {
WindStatisticsDTO wind = object.getWind();
if (wind == null) {
return "";
} else if (wind.getRoundedDifference() <= 0d) {
return I18N.knotsValue(wind.getTrueLowerboundWindInKnots());
}
return I18N.knotsRange(wind.getTrueLowerboundWindInKnots(), wind.getTrueUpperboundWindInKnots());
}
};
}
public static <T extends RaceMetadataDTO<?>> SortableRaceListColumn<T, AbstractWindDTO> getWindDirectionColumn() {
Cell<AbstractWindDTO> cell = new AbstractCell<AbstractWindDTO>() {
@Override
public void render(Context context, AbstractWindDTO value, SafeHtmlBuilder sb) {
if (value != null) {
SafeStylesBuilder safeStyles = new SafeStylesBuilder();
safeStyles.trustedNameAndValue("-webkit-transform", "rotate(" + value.getTrueWindFromDeg() + "deg)");
safeStyles.trustedNameAndValue("transform", "rotate(" + value.getTrueWindFromDeg() + "deg)");
safeStyles.width(2.75, Unit.EM).height(2.75, Unit.EM);
sb.append(TEMPLATE.windDirection(safeStyles.toSafeStyles()));
}
}
};
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, Double>( new NullSafeComparableComparator<Double>()) {
@Override
protected Double getComparisonValue(T object) {
return object.getWind() != null ? object.getWind().getTrueWindFromDeg() : null;
}
};
return new SortableRaceListColumn<T, AbstractWindDTO>(I18N.from(), cell, comparator) {
@Override
public String getHeaderStyle() {
return getStyleNamesString(CSS.raceslist_head_item(), MEDIA_CSS.hideonsmall());
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), CSS.racesListIcon(), MEDIA_CSS.hideonsmall());
}
@Override
public AbstractWindDTO getValue(T object) {
return object.getWind();
}
};
}
public static <T extends RaceMetadataDTO<?>> SortableRaceListColumn<T, String> getCourseAreaColumn() {
Cell<String> cell = new TextCell();
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, String>(new NaturalComparator(false)) {
@Override
protected String getComparisonValue(T object) {
return object.getCourseArea();
}
};
return new SortableRaceListColumn<T, String>(I18N.courseArea(), cell, comparator) {
@Override
public String getHeaderStyle() {
return getStyleNamesString(CSS.raceslist_head_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getValue(T object) {
return object.getCourseArea();
}
};
}
public static <T extends RaceMetadataDTO<?>> SortableRaceListColumn<T, String> getCourseColumn() {
Cell<String> cell = new TextCell();
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, String>(new NaturalComparator(false)) {
@Override
protected String getComparisonValue(T object) {
return object.getCourse();
}
};
return new SortableRaceListColumn<T, String>(I18N.course(), cell, comparator) {
@Override
public String getHeaderStyle() {
return getStyleNamesString(CSS.raceslist_head_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), MEDIA_CSS.showonlarge());
}
@Override
public String getValue(T object) {
return object.getCourse();
}
};
}
public static <T extends RaceListRaceDTO> SortableRaceListColumn<T, Number> getWindSourcesCountColumn() {
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, Integer>(new NullSafeComparableComparator<Integer>(false)) {
@Override
protected Integer getComparisonValue(T object) {
return object.getWindSourcesCount();
}
};
return new DataCountColumn<T>(DataCountColumn.ICON_WIND, comparator) {
@Override
public Number getValue(T object) {
return object.getWindSourcesCount();
}
};
}
public static <T extends RaceListRaceDTO> SortableRaceListColumn<T, Number> getVideoCountColumn() {
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, Integer>(new NullSafeComparableComparator<Integer>(false)) {
@Override
protected Integer getComparisonValue(T object) {
return object.getVideoCount();
}
};
return new DataCountColumn<T>(DataCountColumn.ICON_VIDEO, comparator) {
@Override
public Number getValue(T object) {
return object.getVideoCount();
}
};
}
public static <T extends RaceListRaceDTO> SortableRaceListColumn<T, Number> getAudioCountColumn() {
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, Integer>(new NullSafeComparableComparator<Integer>(false)) {
@Override
protected Integer getComparisonValue(T object) {
return object.getAudioCount();
}
};
return new DataCountColumn<T>(DataCountColumn.ICON_AUDIO, comparator) {
@Override
public Number getValue(T object) {
return object.getAudioCount();
}
};
}
public static <T extends LiveRaceDTO> SortableRaceListColumn<T, T> getRaceViewStateColumn() {
Cell<T> cell = new AbstractCell<T>() {
@Override
public void render(Context context, T value, SafeHtmlBuilder sb) {
RaceViewState state = value.getViewState();
RaceProgressDTO progress = value.getProgress();
if (state == RaceViewState.SCHEDULED) {
double min = MillisecondsTimePoint.now().until(new MillisecondsTimePoint(value.getStart())).asMinutes();
sb.appendEscaped(I18N.startingInMinutes((int) min));
} else if (state == RaceViewState.RUNNING && progress != null) {
SafeStyles width = SafeStylesUtils.forWidth(progress.getPercentageProgress(), Unit.PCT);
String text = I18N.currentOfTotalLegs(progress.getCurrentLeg(), progress.getTotalLegs());
sb.append(TEMPLATE.viewStateRunning(CSS.race_itemstatus_progressbar(),
CSS.race_itemstatus_progressbar_progress(), width, text));
} else {
sb.appendEscaped(state.getLabel());
}
}
};
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, RaceViewState>(new NullSafeComparableComparator<RaceViewState>()) {
@Override
protected RaceViewState getComparisonValue(T object) {
return object.getViewState();
}
};
return new SortableRaceListColumn<T, T>(I18N.status(), cell, comparator) {
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return CSS.race_item();
}
@Override
public T getValue(T object) {
return object;
}
};
}
public static <T extends RaceListRaceDTO> SortableRaceListColumn<T, SimpleCompetitorDTO> getWinnerColumn() {
Cell<SimpleCompetitorDTO> cell = new AbstractCell<SimpleCompetitorDTO>() {
@Override
public void render(Context context, SimpleCompetitorDTO value, SafeHtmlBuilder sb) {
if (value != null) {
SafeUri flagImageUri = FlagImageResolver.getFlagImageUri(value.getFlagImageURL(), value.getTwoLetterIsoCountryCode());
sb.append(TEMPLATE.winner(CSS.race_item_flag(), CSS.race_item_winner(), flagImageUri, value.getName()));
}
}
};
InvertibleComparator<T> comparator = new InvertibleComparatorWrapper<T, String>(
new NullSafeComparatorWrapper<String>(new NaturalComparator(false), false)) {
@Override
protected String getComparisonValue(T object) {
return object.getWinner() != null ? object.getWinner().getName() : null;
}
};
return new SortableRaceListColumn<T, SimpleCompetitorDTO>(I18N.winner(), cell, comparator) {
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), CSS.race_itemwinner());
}
@Override
public SimpleCompetitorDTO getValue(T object) {
return object.getWinner();
}
};
}
public static <T extends RaceMetadataDTO<?>> SortableRaceListColumn<T, T> getRaceViewerButtonColumn(final EventView.Presenter presenter) {
Cell<T> cell = new AbstractCell<T>() {
private final String watchNowStyle = getButtonStyleNames(MAIN_CSS.buttonred());
private final String analyseRaceStyle = getButtonStyleNames(MAIN_CSS.buttonprimary());
@Override
public void render(Context context, T data, SafeHtmlBuilder sb) {
if (data.getTrackingState() != RaceTrackingState.TRACKED_VALID_DATA) {
SafeStylesBuilder styles = new SafeStylesBuilder().textTransform(TextTransform.UPPERCASE);
styles.trustedColor("#666").trustedNameAndValue("font-size", "0.933333333333333rem").toSafeStyles();
styles.trustedNameAndValue("padding", "0.714285714285714em 1.071428571428571em");
sb.append(TEMPLATE.raceNotTracked(styles.toSafeStyles(), I18N_UBI.eventRegattaRaceNotTracked()));
} else {
String styleNames = data.getViewState() == RaceViewState.FINISHED ? analyseRaceStyle : watchNowStyle;
String text = data.getViewState() == RaceViewState.FINISHED ? I18N.analyseRace() : I18N_UBI.watchNow();
String raceViewerURL = presenter.getRaceViewerURL(data.getRegattaName(), data.getTrackedRaceName());
sb.append(TEMPLATE.raceViewerLinkButton(styleNames, text, raceViewerURL));
}
}
private final String getButtonStyleNames(String buttonColor) {
return Util.join(" ", MAIN_CSS.button(), MAIN_CSS.buttonstrong(), buttonColor, MAIN_CSS.buttonarrowrightwhite());
}
};
InvertibleComparator<T> comparator = null;
return new SortableRaceListColumn<T, T>("", cell, comparator) {
@Override
public String getHeaderStyle() {
return getStyleNamesString(CSS.raceslist_head_item(), CSS.raceslist_head_itembutton());
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), CSS.race_itemright());
}
@Override
public T getValue(T object) {
return object;
}
};
}
public static class SortableRaceListStartTimeColumn<T extends RaceMetadataDTO<?>> extends SortableRaceListColumn<T, Date> {
protected SortableRaceListStartTimeColumn(InvertibleComparator<T> comparator) {
super(I18N.start(), new StartTimeCell(), comparator, SortingOrder.DESCENDING);
}
public void setShowTimeOnly(boolean showTimeOnly) {
((StartTimeCell) getCell()).showTimeOnly = showTimeOnly;
}
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return CSS.race_item();
}
@Override
public Date getValue(T object) {
return object.getStart();
}
private static class StartTimeCell extends AbstractCell<Date> {
private static final DateTimeFormat DATE_FORMAT = DateTimeFormat.getFormat(PredefinedFormat.MONTH_NUM_DAY);
private static final DateTimeFormat TIME_FORMAT = DateTimeFormat.getFormat(PredefinedFormat.HOUR24_MINUTE);
private boolean showTimeOnly = true;
@Override
public void render(Context context, Date value, SafeHtmlBuilder sb) {
if (value != null) {
sb.appendEscaped((showTimeOnly ? "" : DATE_FORMAT.format(value) + " ") + TIME_FORMAT.format(value));
}
}
}
}
private static abstract class WindSpeedOrRangeColumn<T extends RaceMetadataDTO<?>> extends SortableRaceListColumn<T, String> {
protected WindSpeedOrRangeColumn(InvertibleComparator<T> comparator) {
super(I18N.wind(), new TextCell(), comparator);
}
@Override
public String getHeaderStyle() {
return CSS.raceslist_head_item();
}
@Override
public String getColumnStyle() {
return CSS.race_item();
}
}
private static abstract class DataCountColumn<T extends RaceListRaceDTO> extends SortableRaceListColumn<T, Number> {
private static final SafeUri ICON_WIND = UriUtils.fromTrustedString("images/home/icon-wind.png");
private static final SafeUri ICON_VIDEO = UriUtils.fromTrustedString("images/home/icon-video.png");
private static final SafeUri ICON_AUDIO = UriUtils.fromTrustedString("images/home/icon-audio.png");
private DataCountColumn(final SafeUri imageUri, InvertibleComparator<T> comparator) {
super(new SafeHtmlHeader(TEMPLATE.imageHeader(CSS.raceslist_head_itemflag(), imageUri)), new AbstractCell<Number>() {
@Override
public void render(Context context, Number value, SafeHtmlBuilder sb) {
if (value != null && value.longValue() > 0) {
sb.append(value.longValue());
} else {
sb.appendHtmlConstant("&mdash;");
}
}
}, comparator, SortingOrder.DESCENDING);
}
@Override
public String getHeaderStyle() {
return getStyleNamesString(CSS.raceslist_head_item(), CSS.raceslist_head_itemcenter(), MEDIA_CSS.showonlarge());
}
@Override
public String getColumnStyle() {
return getStyleNamesString(CSS.race_item(), CSS.race_itemcenter(), MEDIA_CSS.showonlarge());
}
}
}
@@ -0,0 +1,71 @@
package com.sap.sailing.gwt.home.client.place.event.partials.racelist;
import java.util.Collection;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.HeadingElement;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLiveResources;
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshableWidget;
import com.sap.sailing.gwt.ui.shared.dispatch.CollectionResult;
import com.sap.sailing.gwt.ui.shared.race.RaceMetadataDTO;
public class RaceListContainer<T extends RaceMetadataDTO<?>> extends Composite implements RefreshableWidget<CollectionResult<T>> {
private static RaceListContainerUiBinder uiBinder = GWT.create(RaceListContainerUiBinder.class);
interface RaceListContainerUiBinder extends UiBinder<Widget, RaceListContainer<?>> {
}
@UiField HeadingElement titleUi;
@UiField DivElement infoUi;
@UiField DivElement noContentPlaceholderUi;
@UiField(provided = true) AbstractRaceList<T> raceListUi;
private String noContentPlaceholderText;
public RaceListContainer(String title, AbstractRaceList<T> raceList) {
this(title, null, raceList);
}
public RaceListContainer(String title, String noContentPlaceholderText, AbstractRaceList<T> raceList) {
this.noContentPlaceholderText = noContentPlaceholderText;
RacesListLiveResources.INSTANCE.css().ensureInjected();
this.raceListUi = raceList;
initWidget(uiBinder.createAndBindUi(this));
this.titleUi.setInnerText(title);
raceListUi.setVisible(false);
}
@Override
public void setData(CollectionResult<T> data, long nextUpdate, int updateNo) {
setRaceListData(data == null ? null : data.getValues());
}
public void setRaceListData(Collection<T> data) {
if(data == null || data.isEmpty()) {
if(noContentPlaceholderText == null) {
getElement().getStyle().setDisplay(Display.NONE);
} else {
noContentPlaceholderUi.setInnerText(noContentPlaceholderText);
noContentPlaceholderUi.getStyle().clearDisplay();
raceListUi.setVisible(false);
}
} else {
noContentPlaceholderUi.getStyle().setDisplay(Display.NONE);
getElement().getStyle().clearDisplay();
raceListUi.setVisible(true);
this.raceListUi.setTableData(data);
}
}
public void setInfoText(String infoText) {
this.infoUi.setInnerText(infoText);
this.infoUi.getStyle().clearDisplay();
}
}
@@ -0,0 +1,14 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"
xmlns:r="urn:import:com.sap.sailing.gwt.home.client.place.event.partials.racelist">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLiveResources" />
<g:HTMLPanel addStyleNames="{local_res.css.raceslistlive}">
<h3 ui:field="titleUi"></h3>
<div style="display: none;" ui:field="infoUi"></div>
<div style="display: none; font-weight: bold; font-style: italic;" ui:field="noContentPlaceholderUi"></div>
<r:AbstractRaceList ui:field="raceListUi"/>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,147 @@
package com.sap.sailing.gwt.home.client.place.event.partials.racelist;
import java.util.Collection;
import java.util.Date;
import com.sap.sailing.gwt.ui.shared.dispatch.event.RaceListRaceDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.event.SimpleCompetitorDTO;
import com.sap.sailing.gwt.ui.shared.race.FleetMetadataDTO;
import com.sap.sailing.gwt.ui.shared.race.RaceMetadataDTO;
import com.sap.sailing.gwt.ui.shared.race.wind.AbstractWindDTO;
import com.sap.sse.common.Duration;
public class RaceListDataUtil {
private interface ValueProvider<T, V> {
V getValue(T object);
}
private static <T extends RaceMetadataDTO<?>> boolean hasValues(Collection<T> races, ValueProvider<T, ?> valueProvider) {
for (T race : races) {
if (valueProvider.getValue(race) != null) {
return true;
}
}
return false;
}
private static <T extends RaceMetadataDTO<?>> boolean hasNumberValues(Collection<T> races, ValueProvider<T, Number> valueProvider) {
for (T race : races) {
Number value = valueProvider.getValue(race);
if (value != null && value.longValue() > 0) {
return true;
}
}
return false;
}
private static <T extends RaceMetadataDTO<?>> boolean hasDifferentValues(Collection<T> races, ValueProvider<T, ?> valueProvider) {
Object compareValue = null;
for (T race : races) {
Object currentValue = valueProvider.getValue(race);
if (currentValue == null) {
continue;
} else if (compareValue == null) {
compareValue = currentValue;
} else if (!compareValue.equals(currentValue)) {
return true;
}
}
return false;
}
public static <T extends RaceMetadataDTO<?>> boolean hasFleets(Collection<T> data) {
return hasValues(data, new ValueProvider<T, FleetMetadataDTO>() {
@Override
public FleetMetadataDTO getValue(T object) {
return object.getFleet();
}
});
}
public static <T extends RaceListRaceDTO> boolean hasDurations(Collection<T> data) {
return hasValues(data, new ValueProvider<T, Duration>() {
@Override
public Duration getValue(T object) {
return object.getDuration();
}
});
}
public static <T extends RaceMetadataDTO<?>> boolean hasWind(Collection<T> data) {
return hasValues(data, new ValueProvider<T, AbstractWindDTO>() {
@Override
public AbstractWindDTO getValue(T object) {
return object.getWind();
}
});
}
public static <T extends RaceListRaceDTO> boolean hasWindSources(Collection<T> data) {
return hasNumberValues(data, new ValueProvider<T, Number>() {
@Override
public Number getValue(T object) {
return object.getWindSourcesCount();
}
});
}
public static <T extends RaceListRaceDTO> boolean hasVideos(Collection<T> data) {
return hasNumberValues(data, new ValueProvider<T, Number>() {
@Override
public Number getValue(T object) {
return object.getVideoCount();
}
});
}
public static <T extends RaceListRaceDTO> boolean hasAudios(Collection<T> data) {
return hasNumberValues(data, new ValueProvider<T, Number>() {
@Override
public Number getValue(T object) {
return object.getAudioCount();
}
});
}
public static <T extends RaceMetadataDTO<?>> boolean hasCourses(Collection<T> data) {
return hasValues(data, new ValueProvider<T, String>() {
@Override
public String getValue(T object) {
return object.getCourse();
}
});
}
public static <T extends RaceMetadataDTO<?>> boolean hasCourseAreas(Collection<T> data) {
return hasValues(data, new ValueProvider<T, String>() {
@Override
public String getValue(T object) {
return object.getCourseArea();
}
});
}
public static <T extends RaceListRaceDTO> boolean hasWinner(Collection<T> data) {
return hasValues(data, new ValueProvider<T, SimpleCompetitorDTO>() {
@Override
public SimpleCompetitorDTO getValue(T object) {
return object.getWinner();
}
});
}
private static final long DAY_IN_MILLIS = 1000 * 60 * 60 * 24;
public static <T extends RaceMetadataDTO<?>> boolean hasDifferentStartDates(Collection<T> data) {
return hasDifferentValues(data, new ValueProvider<T, Long>() {
@Override
public Long getValue(T object) {
Date start = object.getStart();
if(start == null) {
return null;
}
return start.getTime() / DAY_IN_MILLIS;
}
});
}
}
@@ -0,0 +1,57 @@
package com.sap.sailing.gwt.home.client.place.event.partials.racelist;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.user.cellview.client.Header;
import com.google.gwt.user.cellview.client.TextHeader;
import com.sap.sailing.domain.common.InvertibleComparator;
import com.sap.sailing.domain.common.SortingOrder;
import com.sap.sailing.gwt.ui.client.shared.controls.SortableColumn;
import com.sap.sse.common.Util;
public abstract class SortableRaceListColumn<T, C> extends SortableColumn<T, C> {
private final Header<?> header;
private final InvertibleComparator<T> comparator;
private boolean showDetails = true;
protected SortableRaceListColumn(String headerText, Cell<C> cell, InvertibleComparator<T> comparator) {
this(new TextHeader(headerText), cell, comparator);
}
protected SortableRaceListColumn(String headerText, Cell<C> cell, InvertibleComparator<T> comparator, SortingOrder preferredSortingOrder) {
this(new TextHeader(headerText), cell, comparator, preferredSortingOrder);
}
protected SortableRaceListColumn(Header<?> header, Cell<C> cell, InvertibleComparator<T> comparator) {
this(header, cell, comparator, SortingOrder.ASCENDING);
}
protected SortableRaceListColumn(Header<?> header, Cell<C> cell, InvertibleComparator<T> comparator, SortingOrder preferredSortingOrder) {
super(cell, preferredSortingOrder);
this.header = header;
this.comparator = comparator;
}
@Override
public final InvertibleComparator<T> getComparator() {
return comparator;
}
@Override
public final Header<?> getHeader() {
return header;
}
public void setShowDetails(boolean showDetails) {
this.showDetails = showDetails;
}
public boolean isShowDetails() {
return showDetails;
}
protected final String getStyleNamesString(String... styleNames) {
return Util.join(" ", styleNames);
}
}
@@ -0,0 +1,125 @@
/**
* The header of a regatta of an event
*/
.regattaheader {
width: 100%;
float: left;
font-size: 1rem;
padding: 0.666666666666667em;
padding-right: 1em;
overflow: hidden;
color: #0a0a0a;
background-color: #f2f2f2;
border-bottom: 1px solid #ddd;
}
.regattaheaderpadding {
padding-right: 5em;
}
.regattaheader_logo {
float: left;
width: 3.333333333333333em;
height: 3.333333333333333em;
text-align: center;
line-height: 3.333333333333333em;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
.regattaheader_logo img {
display: inline-block;
text-align: center;
vertical-align: middle;
}
.regattaheader_content {
float: left;
width: 60%;
overflow: hidden;
border-left: 1px solid #ccc;
margin-left: 0.666666666666667em;
padding-left: 1em;
}
.regattaheader_content_title {
font-size: 1.466666666666667em;
font-weight: 700;
height: 1.363636363636364em;
line-height: 1.363636363636364em;
}
.regattaheader_content_details {
height: 1.333333333333333em;
}
.regattaheader_content_details_item {
float: left;
font-size: 13px;
font-weight: 600;
color: #666;
padding: 0 0.666666666666667em;
border-right: 1px solid #ccc;
}
.regattaheader_content_details_item:first-of-type {
padding-left: 0;
}
.regattaheader_content_details_item:last-of-type {
border: none;
padding-right: 0;
}
.regattaheader_toggle {
float: right;
width: 4em;
cursor: pointer;
margin: 0.666666666666667em 0 0.666666666666667em -4em;
line-height: 3.333333333333333em;
text-align: center;
padding: 0 0.666666666666667em;
border-left: 1px solid #ccc;
}
.regattaheader_toggle_icon {
padding: 1em 0;
width: 1.333333333333333em;
height: 1.333333333333333em;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}
.standings_listhidden .regattaheader_toggle_icon {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
.regattaheader_arrow {
position: absolute;
top: 0;
right: 0;
bottom: 0;
text-align: right;
padding: 0.666666666666667em;
padding-right: 4.666666666666667em;
background-image: url("images/home/arrow-down-grey.png");
background-size: 1.333333333333333em 1.333333333333333em;
background-position: center;
background-repeat: no-repeat;
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.regattaheader_update {
width: 20%;
float: right;
padding: 0.533333333333333em 0;
text-align: right;
font-weight: 600;
color: #666;
}
.regattaheader_update_title {
text-transform: uppercase;
}
img.regattaheader_update_title_icon {
height: 1.2em;
margin-right: 0.333333333333333em;
vertical-align: bottom;
}
.regattaheader_update_timestamp {
font-size: 12px;
}
@@ -0,0 +1,33 @@
package com.sap.sailing.gwt.home.client.place.event.partials.regattaHeader;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
import com.sap.sailing.gwt.ui.shared.eventview.RegattaMetadataDTO;
public class RegattaHeader extends Composite {
private static RegattaHeaderUiBinder uiBinder = GWT.create(RegattaHeaderUiBinder.class);
interface RegattaHeaderUiBinder extends UiBinder<Widget, RegattaHeader> {
}
@UiField AnchorElement headerBodyUi;
@UiField AnchorElement headerArrowUi;
public RegattaHeader(RegattaMetadataDTO regattaMetadata) {
initWidget(uiBinder.createAndBindUi(this));
headerBodyUi.appendChild(new RegattaHeaderBody(regattaMetadata).getElement());
}
public void setRegattaNavigation(PlaceNavigation<?> placeNavigation) {
headerArrowUi.getStyle().clearDisplay();
placeNavigation.configureAnchorElement(headerBodyUi);
placeNavigation.configureAnchorElement(headerArrowUi);
}
}
@@ -0,0 +1,23 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.event.partials">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.regattaHeader.RegattaHeaderResources" />
<g:HTMLPanel>
<div>
<div class="{res.mediaCss.grid}">
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
<a class="{local_res.css.regattaheader} {local_res.css.regattaheaderpadding}" ui:field="headerBodyUi"></a>
<!-- <a class="{local_res.css.regattaheader_toggle}"> -->
<!-- <img src="images/home/arrow-down-grey.png" class="{local_res.css.regattaheader_toggle_icon}"></img> -->
<!-- </a> -->
<a class="{local_res.css.regattaheader_arrow}" style="display:none;" ui:field="headerArrowUi"></a>
<!-- <div class="{local_res.css.regattaheader} {local_res.css.regattaheaderpadding}"></div> -->
<!-- <div class="{local_res.css.regattaheader_toggle}"></div> -->
<!-- <div class="{local_res.css.regattaheader_arrow}"></div> -->
</div>
</div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,61 @@
package com.sap.sailing.gwt.home.client.place.event.partials.regattaHeader;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.SpanElement;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.UIObject;
import com.sap.sailing.gwt.common.client.BoatClassImageResolver;
import com.sap.sailing.gwt.home.client.shared.LabelTypeUtil;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.eventview.RegattaMetadataDTO;
public class RegattaHeaderBody extends UIObject {
private static final StringMessages I18N = StringMessages.INSTANCE;
private static RegattaHeaderBodyUiBinder uiBinder = GWT.create(RegattaHeaderBodyUiBinder.class);
interface RegattaHeaderBodyUiBinder extends UiBinder<Element, RegattaHeaderBody> {
}
@UiField protected DivElement logoUi;
@UiField protected SpanElement nameUi;
@UiField protected DivElement labelUi;
@UiField protected DivElement detailsItemContainerUi;
public RegattaHeaderBody(RegattaMetadataDTO regattaMetadata) {
RegattaHeaderResources.INSTANCE.css().ensureInjected();
setElement(uiBinder.createAndBindUi(this));
ImageResource logo = BoatClassImageResolver.getBoatClassIconResource(regattaMetadata.getBoatClass());
logoUi.getStyle().setBackgroundImage("url('" + logo.getSafeUri().asString() + "')");
nameUi.setInnerText(regattaMetadata.getDisplayName());
LabelTypeUtil.renderLabelTypeOrHide(labelUi, regattaMetadata.getState().getStateMarker());
addDetailsItem(regattaMetadata.getCompetitorsCount(), I18N.competitorsCount(regattaMetadata.getCompetitorsCount()));
addDetailsItem(regattaMetadata.getRaceCount(), I18N.racesCount(regattaMetadata.getRaceCount()));
String defaultCourseAreaName = regattaMetadata.getDefaultCourseAreaName();
if(defaultCourseAreaName != null) {
addDetailsItem(I18N.courseAreaName(defaultCourseAreaName));
}
addDetailsItem(regattaMetadata.getBoatCategory());
}
private void addDetailsItem(int count, String text) {
if (count > 0) {
addDetailsItem(text);
}
}
private void addDetailsItem(String text) {
if(text != null) {
DivElement detailsItem = DOM.createDiv().cast();
detailsItem.addClassName(RegattaHeaderResources.INSTANCE.css().regattaheader_content_details_item());
detailsItem.setInnerText(text);
detailsItemContainerUi.appendChild(detailsItem);
}
}
}
@@ -0,0 +1,24 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.event.partials">
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.partials.regattaHeader.RegattaHeaderResources" />
<div>
<div class="{local_res.css.regattaheader_logo}" ui:field="logoUi"></div>
<div class="{local_res.css.regattaheader_content}">
<div class="{local_res.css.regattaheader_content_title}">
<span ui:field="nameUi"></span>
<div class="{res.mainCss.label}" ui:field="labelUi"></div>
</div>
<div class="{local_res.css.regattaheader_content_details}" ui:field="detailsItemContainerUi">
<!-- <div class="{local_res.css.regattaheader_content_details_item}"></div> -->
</div>
</div>
<!-- IF content.isLive <div class="{local_res.css.regattaheader_update}">
<div class="{local_res.css.regattaheader_update_title}"> <img src="images/home/reload-green.png"
class="{local_res.css.regattaheader_update_title_icon}"></img> <ui:text from='{i18n.lastUpdate}'
/> </div> <div class="{local_res.css.regattaheader_update_timestamp}"></div>
</div> IFEND content.isLive -->
</div>
</ui:UiBinder>
@@ -0,0 +1,30 @@
package com.sap.sailing.gwt.home.client.place.event.partials.regattaHeader;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
public interface RegattaHeaderResources extends ClientBundle {
public static final RegattaHeaderResources INSTANCE = GWT.create(RegattaHeaderResources.class);
@Source("RegattaHeader.gss")
LocalCss css();
public interface LocalCss extends CssResource {
String regattaheader();
String regattaheaderpadding();
String regattaheader_logo();
String regattaheader_content();
String regattaheader_content_title();
String regattaheader_content_details();
String regattaheader_content_details_item();
String regattaheader_toggle();
String regattaheader_toggle_icon();
String standings_listhidden();
String regattaheader_arrow();
String regattaheader_update();
String regattaheader_update_title();
String regattaheader_update_title_icon();
String regattaheader_update_timestamp();
}
}
@@ -48,7 +48,7 @@ public class RegattaOverviewTabView extends Composite implements RegattaTabView<
RefreshManager refreshManager = new RefreshManager(this, currentPresenter.getDispatch());
stage.setupRefresh(refreshManager);
refreshManager.add(racesListLive, new GetLiveRacesForRegattaAction(currentPresenter.getCtx().getEventDTO()
refreshManager.add(racesListLive.getRefreshable(), new GetLiveRacesForRegattaAction(currentPresenter.getCtx().getEventDTO()
.getId(), currentPresenter.getCtx().getRegattaId()));
contentArea.setWidget(this);
@@ -1,29 +1,85 @@
package com.sap.sailing.gwt.home.client.place.event.regatta.tabs;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.common.client.SharedResources;
import com.sap.sailing.gwt.common.client.controls.tabbar.TabView;
import com.sap.sailing.gwt.home.client.place.event.EventView;
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.ListNavigationPanel;
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.ListNavigationPanel.ListNavigationAction;
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.ListNavigationPanel.SelectionCallback;
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.RaceStateLegend;
import com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaListItem;
import com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaListStepsLegend;
import com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLive;
import com.sap.sailing.gwt.home.client.place.event.partials.racelist.AbstractRaceList;
import com.sap.sailing.gwt.home.client.place.event.partials.racelist.RaceListColumnFactory;
import com.sap.sailing.gwt.home.client.place.event.partials.racelist.RaceListContainer;
import com.sap.sailing.gwt.home.client.place.event.partials.racelist.RaceListDataUtil;
import com.sap.sailing.gwt.home.client.place.event.partials.racelist.SortableRaceListColumn;
import com.sap.sailing.gwt.home.client.place.event.partials.regattaraces.EventRegattaRaces;
import com.sap.sailing.gwt.home.client.place.event.regatta.EventRegattaView.Presenter;
import com.sap.sailing.gwt.home.client.place.event.regatta.RegattaTabView;
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshManager;
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshableWidget;
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetFinishedRacesAction;
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetLiveRacesForRegattaAction;
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetRegattaWithProgressAction;
import com.sap.sailing.gwt.ui.shared.dispatch.event.RaceListRaceDTO;
import com.sap.sailing.gwt.ui.shared.dispatch.regatta.RegattaWithProgressDTO;
import com.sap.sse.common.Util.Triple;
/**
* Created by pgtaboada on 25.11.14.
*/
public class RegattaRacesTabView extends Composite implements RegattaTabView<RegattaRacesPlace> {
private static final StringMessages I18N = StringMessages.INSTANCE;
private enum Navigation implements ListNavigationAction {
SORT_LIST_FORMAT("Sortable list Format TODO", false),
COMPETITION_FORMAT("Competition Format TODO", true);
private final String displayName;
private final boolean showAdditionalWidget;
private Navigation(String displayName, boolean showAdditionalWidget) {
this.displayName = displayName;
this.showAdditionalWidget = showAdditionalWidget;
}
@Override
public String getDisplayName() {
return displayName;
}
@Override
public boolean isShowAdditionalWidget() {
return showAdditionalWidget;
}
}
interface MyBinder extends UiBinder<HTMLPanel, RegattaRacesTabView> {
}
@@ -32,17 +88,19 @@ public class RegattaRacesTabView extends Composite implements RegattaTabView<Reg
private Presenter currentPresenter;
@UiField(provided = true)
protected EventRegattaRaces regattaRaces;
public RegattaRacesTabView() {
}
@UiField MultiRegattaListStepsLegend regattaProgressLegendUi;
@UiField SimplePanel regattaInfoContainerUi;
@UiField(provided = true) ListNavigationPanel<Navigation> listNavigationPanelUi;
@UiField DivElement listFormatContainerUi;
@UiField FlowPanel compFormatContainerUi;
@UiField SimplePanel oldContentContainer;
@UiField(provided = true) RacesListLive liveRacesListUi;
@UiField(provided = true) RaceListContainer<RaceListRaceDTO> raceListContainerUi;
@UiField AnchorElement regattaOverviewUi;
@Override
public void setPresenter(Presenter currentPresenter) {
this.currentPresenter = currentPresenter;
}
@Override
@@ -52,52 +110,69 @@ public class RegattaRacesTabView extends Composite implements RegattaTabView<Reg
@Override
public void start(RegattaRacesPlace myPlace, final AcceptsOneWidget contentArea) {
// TODO: understand, and than move this into appropiate place (probably context)
final String selectedRegattaId = myPlace.getCtx().getRegattaId();
listNavigationPanelUi = new ListNavigationPanel<Navigation>(new RegattaRacesTabViewNavigationSelectionCallback());
listNavigationPanelUi.setAdditionalWidget(new RaceStateLegend());
liveRacesListUi = new RacesListLive(currentPresenter, false);
raceListContainerUi = new RaceListContainer<>(I18N.finishedRaces(), I18N.noFinishedRaces(), new RaceListFinishedRaces(currentPresenter));
initWidget(ourUiBinder.createAndBindUi(RegattaRacesTabView.this));
currentPresenter.ensureRegattaStructure(new AsyncCallback<List<RaceGroupDTO>>() {
@Override
public void onSuccess(List<RaceGroupDTO> raceGroups) {
if (raceGroups.size() > 0) {
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> regattaStructure = getRegattaStructure();
Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO> selectedRegatta = regattaStructure
.get(selectedRegattaId);
regattaRaces = new EventRegattaRaces(currentPresenter);
regattaRaces.setRaces(selectedRegatta.getC(), false, selectedRegatta.getB(),
selectedRegatta.getA());
// if (eventDTO.isRunning()) {
// // create update time for race states only for running events
// serverUpdateTimer.addTimeListener(new TimeListener() {
// @Override
// public void timeChanged(Date newTime, Date oldTime) {
// loadAndUpdateEventRaceStatesLog();
// }
// });
// }
initWidget(ourUiBinder.createAndBindUi(RegattaRacesTabView.this));
contentArea.setWidget(RegattaRacesTabView.this);
} else {
// createEventWithoutRegattasView(event, panel);
}
regattaOverviewUi.setHref(currentPresenter.getRegattaOverviewLink());
if(currentPresenter.isEventOrRegattaLive()) {
regattaOverviewUi.addClassName(SharedResources.INSTANCE.mainCss().buttonred());
} else {
regattaOverviewUi.addClassName(SharedResources.INSTANCE.mainCss().buttonprimary());
}
RefreshManager refreshManager = new RefreshManager(this, currentPresenter.getDispatch());
if (ExperimentalFeatures.SHOW_NEW_RACES_LIST) {
listNavigationPanelUi.removeFromParent(); // TODO temporary removed
// listNavigationPanelUi.addAction(Navigation.SORT_LIST_FORMAT, true);
// listNavigationPanelUi.addAction(Navigation.COMPETITION_FORMAT, false);
refreshManager.add(liveRacesListUi.getRefreshable(), new GetLiveRacesForRegattaAction(myPlace.getCtx().getEventDTO().getId(), myPlace.getRegattaId()));
refreshManager.add(new RefreshableWidget<RegattaWithProgressDTO>() {
@Override
public void setData(RegattaWithProgressDTO data, long nextUpdate, int updateNo) {
regattaInfoContainerUi.setWidget(new MultiRegattaListItem(data));
}
}, new GetRegattaWithProgressAction(myPlace.getCtx().getEventDTO().getId(), myPlace.getRegattaId()));
refreshManager.add(raceListContainerUi, new GetFinishedRacesAction(myPlace.getCtx().getEventDTO().getId(), myPlace.getRegattaId()));
oldContentContainer.removeFromParent();
} else {
regattaProgressLegendUi.removeFromParent();
regattaInfoContainerUi.removeFromParent();
listFormatContainerUi.removeFromParent();
compFormatContainerUi.removeFromParent();
// TODO: understand, and than move this into appropiate place (probably context)
final String selectedRegattaId = myPlace.getCtx().getRegattaId();
currentPresenter.ensureRegattaStructure(new AsyncCallback<List<RaceGroupDTO>>() {
@Override
public void onSuccess(List<RaceGroupDTO> raceGroups) {
if (raceGroups.size() > 0) {
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> rs = getRegattaStructure();
Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO> selectedRegatta = rs .get(selectedRegattaId);
EventRegattaRaces regattaRaces = new EventRegattaRaces(currentPresenter);
oldContentContainer.setWidget(regattaRaces);
regattaRaces.setRaces(selectedRegatta.getC(), false, selectedRegatta.getB(), selectedRegatta.getA());
} else {
// createEventWithoutRegattasView(event, panel);
}
}
@Override
public void onFailure(Throwable caught) {
// createErrorView(
// "Error while loading the regatta structure with service getRegattaStructureOfEvent()",
// caught, panel);
}
});
@Override
public void onFailure(Throwable caught) {
// createErrorView(
// "Error while loading the regatta structure with service getRegattaStructureOfEvent()",
// caught, panel);
}
});
}
contentArea.setWidget(RegattaRacesTabView.this);
}
@Override
public void stop() {
}
@Override
@@ -109,7 +184,7 @@ public class RegattaRacesTabView extends Composite implements RegattaTabView<Reg
public Class<RegattaRacesPlace> getPlaceClassForActivation() {
return RegattaRacesPlace.class;
}
private Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> getRegattaStructure() {
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> result = new HashMap<>();
Map<String, RaceGroupDTO> raceGroupsMap = new HashMap<>();
@@ -127,4 +202,66 @@ public class RegattaRacesTabView extends Composite implements RegattaTabView<Reg
return result;
}
}
private class RegattaRacesTabViewNavigationSelectionCallback implements SelectionCallback<Navigation> {
@Override
public void onSelectAction(Navigation action) {
showWidget(listFormatContainerUi, action == Navigation.SORT_LIST_FORMAT);
showWidget(compFormatContainerUi, action == Navigation.COMPETITION_FORMAT);
}
private void showWidget(Widget widget, boolean show) {
showWidget(widget.getElement(), show);
}
private void showWidget(Element widget, boolean show) {
widget.getStyle().setDisplay(show ? Display.BLOCK : Display.NONE);
}
}
private class RaceListFinishedRaces extends AbstractRaceList<RaceListRaceDTO> {
private final SortableRaceListColumn<RaceListRaceDTO, ?> durationColumn = RaceListColumnFactory.getDurationColumn();
private final SortableRaceListColumn<RaceListRaceDTO, ?> windSpeedColumn = RaceListColumnFactory.getWindRangeColumn();
private final SortableRaceListColumn<RaceListRaceDTO, ?> windSourcesCountColumn = RaceListColumnFactory.getWindSourcesCountColumn();
private final SortableRaceListColumn<RaceListRaceDTO, ?> videoCountColumn = RaceListColumnFactory.getVideoCountColumn();
private final SortableRaceListColumn<RaceListRaceDTO, ?> audioCountColumn = RaceListColumnFactory.getAudioCountColumn();
private final SortableRaceListColumn<RaceListRaceDTO, ?> winnerColumn = RaceListColumnFactory.getWinnerColumn();
public RaceListFinishedRaces(EventView.Presenter presenter) {
super(presenter);
}
@Override
protected void setTableData(Collection<RaceListRaceDTO> data) {
boolean hasFleets = RaceListDataUtil.hasFleets(data);
this.fleetCornerColumn.setShowDetails(hasFleets);
this.fleetNameColumn.setShowDetails(hasFleets);
this.startTimeColumn.setShowTimeOnly(!RaceListDataUtil.hasDifferentStartDates(data));
this.durationColumn.setShowDetails(RaceListDataUtil.hasDurations(data));
boolean hasWind = RaceListDataUtil.hasWind(data);
this.windSpeedColumn.setShowDetails(hasWind);
this.windDirectionColumn.setShowDetails(hasWind);
this.windSourcesCountColumn.setShowDetails(RaceListDataUtil.hasWindSources(data));
this.videoCountColumn.setShowDetails(RaceListDataUtil.hasVideos(data));
this.audioCountColumn.setShowDetails(RaceListDataUtil.hasAudios(data));
this.winnerColumn.setShowDetails(RaceListDataUtil.hasWinner(data));
super.setTableData(data);
}
@Override
protected void initTableColumns() {
add(fleetCornerColumn);
add(raceNameColumn);
add(fleetNameColumn);
add(startTimeColumn);
add(durationColumn);
add(windSpeedColumn);
add(windDirectionColumn);
add(windSourcesCountColumn);
add(videoCountColumn);
add(audioCountColumn);
add(winnerColumn);
add(raceViewerButtonColumn);
}
}
}
@@ -1,8 +1,44 @@
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:p='urn:import:com.sap.sailing.gwt.home.client.place.event.partials'
>
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:p='urn:import:com.sap.sailing.gwt.home.client.place.event.partials'>
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:style>
.listContainer > div {
margin-bottom: 2em;
}
.legend {
margin-top: 2em;
margin-bottom: -1.5em;
}
.buttonContainer {
position: relative;
margin: 0 !important;
}
.regattaOverviewButton {
position: absolute;
right: 0;
top: -0.25em;
}
</ui:style>
<g:HTMLPanel ui:field="contentPanel">
<p:regattaraces.EventRegattaRaces ui:field="regattaRaces"/>
<div class="{res.mediaCss.grid}">
<p:multiRegattaList.MultiRegattaListStepsLegend addStyleNames="{res.mediaCss.small12} {res.mediaCss.columns} {style.legend}" ui:field="regattaProgressLegendUi" />
<g:SimplePanel addStyleNames="{res.mediaCss.small12} {res.mediaCss.columns} {res.mainCss.spacermarginbottommedium}" ui:field="regattaInfoContainerUi"/>
</div>
<p:listNavigation.ListNavigationPanel ui:field="listNavigationPanelUi"/>
<div class="{res.mediaCss.grid}">
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {style.listContainer}" ui:field="listFormatContainerUi">
<p:raceListLive.RacesListLive ui:field="liveRacesListUi" />
<div class="{style.buttonContainer}">
<a class="{res.mainCss.button} {res.mainCss.buttonstrong} {res.mainCss.buttonarrowrightwhite} {style.regattaOverviewButton}"
target="_blank" ui:field="regattaOverviewUi">
<ui:text from="{i18n.racesOverview}" />
</a>
</div>
<p:racelist.RaceListContainer ui:field="raceListContainerUi" />
</div>
<g:FlowPanel addStyleNames="{res.mediaCss.small12} {res.mediaCss.columns}" ui:field="compFormatContainerUi" />
</div>
<g:SimplePanel ui:field="oldContentContainer"/>
</g:HTMLPanel>
</ui:UiBinder>
@@ -114,13 +114,13 @@ public class RefreshManager {
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public <D extends DTO, A extends Action<ResultWithTTL<D>>> void add(RefreshableWidget<D> widget,
public <D extends DTO, A extends Action<ResultWithTTL<D>>> void add(RefreshableWidget<? super D> widget,
ActionProvider<A> provider) {
refreshables.add(new RefreshHolder(widget, provider));
reschedule();
}
public <D extends DTO, A extends Action<ResultWithTTL<D>>> void add(RefreshableWidget<D> widget, A action) {
public <D extends DTO, A extends Action<ResultWithTTL<D>>> void add(RefreshableWidget<? super D> widget, A action) {
add(widget, new DefaultActionProvider<>(action));
}
@@ -0,0 +1,18 @@
package com.sap.sailing.gwt.home.shared;
/**
* This class contains convenience boolean flags to enable/ disable features in experimental phase.
*/
public class ExperimentalFeatures {
/**
* Show new races list
*/
public static final boolean SHOW_NEW_RACES_LIST = true;
/**
* Show new regatta list
*/
public static final boolean SHOW_NEW_REGATTA_LIST = true;
}
@@ -28,6 +28,7 @@ public class RegattaOverviewEntryPoint extends AbstractSailingEntryPoint {
private final static String PARAM_ONLY_RACES_OF_SAME_DAY = "onlyracesofsameday";
private final static String PARAM_REGATTA = "regatta";
private final static String PARAM_COURSE_AREA = "coursearea";
private final static String PARAM_IGNORE_LOCAL_SETTINGS = "ignoreLocalSettings";
private DockLayoutPanel containerPanel;
private RaceDetailPanel detailPanel;
@@ -96,7 +97,8 @@ public class RegattaOverviewEntryPoint extends AbstractSailingEntryPoint {
private void createAndAddRegattaPanel(UUID eventId) {
RegattaRaceStatesSettings settings = createRegattaRaceStatesSettingsFromURL();
regattaPanel = new RegattaOverviewPanel(sailingService, this, getStringMessages(), eventId, settings, userAgent);
boolean ignoreLocalSettings = getIgnoreLocalSettingsFromURL();
regattaPanel = new RegattaOverviewPanel(sailingService, this, getStringMessages(), eventId, settings, userAgent, ignoreLocalSettings);
regattaPanel.addHandler(new EventDTOLoadedEvent.Handler() {
@Override
@@ -120,6 +122,10 @@ public class RegattaOverviewEntryPoint extends AbstractSailingEntryPoint {
containerPanel.add(scrollPanel);
}
private boolean getIgnoreLocalSettingsFromURL() {
return Boolean.parseBoolean(Window.Location.getParameter(PARAM_IGNORE_LOCAL_SETTINGS));
}
private void createAndAddDetailPanel() {
detailPanel = new RaceDetailPanel(getStringMessages(), new ClickHandler() {
@Override
@@ -81,7 +81,8 @@ public class RegattaOverviewPanel extends SimplePanel {
final StringMessages stringMessages,
UUID eventId,
RegattaRaceStatesSettings settings,
UserAgentDetails userAgent) {
UserAgentDetails userAgent,
boolean ignoreLocalSettings) {
this.sailingService = sailingService;
this.stringMessages = stringMessages;
@@ -102,7 +103,7 @@ public class RegattaOverviewPanel extends SimplePanel {
mainPanel.setWidth("100%");
mainPanel.addStyleName(style.contentWrapper());
regattaRaceStatesComponent = new RegattaRaceStatesComponent(sailingService, errorReporter, stringMessages, eventId, settings, uiUpdateTimer);
regattaRaceStatesComponent = new RegattaRaceStatesComponent(sailingService, errorReporter, stringMessages, eventId, settings, uiUpdateTimer, ignoreLocalSettings);
this.eventRaceGroupListeners.add(regattaRaceStatesComponent);
regattaRaceStatesComponent.setWidth("100%");
@@ -125,6 +125,7 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
private CellTable<RegattaOverviewEntryDTO> table;
boolean hasAnyRaceGroupASeries = false;
boolean hasAnyRaceGroupAFleet = false;
private final boolean ignoreLocalSettings;
public void setEntryClickedHandler(EntryHandler handler) {
this.entryClickedHandler = handler;
@@ -137,7 +138,7 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
*/
public RegattaRaceStatesComponent(final SailingServiceAsync sailingService, ErrorReporter errorReporter,
final StringMessages stringMessages, final UUID eventId, RegattaRaceStatesSettings settings,
Timer timerToSynchronize) {
Timer timerToSynchronize, boolean ignoreLocalSettings) {
this.sailingService = sailingService;
this.stringMessages = stringMessages;
this.eventId = eventId;
@@ -148,6 +149,7 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
this.localStorageRegattaOverviewEventKey = LOCAL_STORAGE_REGATTA_OVERVIEW_KEY + eventId.toString();
this.flagInterpreter = new RaceStateFlagsInterpreter(stringMessages);
this.settings = new RegattaRaceStatesSettings();
this.ignoreLocalSettings = ignoreLocalSettings;
loadAndSetSettings(settings);
mainPanel = new VerticalPanel();
mainPanel.getElement().getStyle().setWidth(100, Unit.PCT);
@@ -160,9 +162,11 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
}
private void loadAndSetSettings(RegattaRaceStatesSettings settings) {
RegattaRaceStatesSettings loadedSettings = loadRegattaRaceStatesSettings();
if (loadedSettings != null) {
settings = loadedSettings;
if(!ignoreLocalSettings) {
RegattaRaceStatesSettings loadedSettings = loadRegattaRaceStatesSettings();
if (loadedSettings != null) {
settings = loadedSettings;
}
}
updateSettings(settings);
}
@@ -38,8 +38,10 @@ import com.sap.sailing.gwt.ui.shared.media.SailingVideoDTO;
import com.sap.sailing.gwt.ui.shared.start.EventStageDTO;
import com.sap.sailing.gwt.ui.shared.start.StageEventType;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MediaDescriptor;
import com.sap.sse.common.media.MediaTagConstants;
@@ -188,6 +190,10 @@ public final class HomeServiceUtil {
return count;
}
public static int calculateRaceColumnCount(Leaderboard sl) {
return Util.size(sl.getRaceColumns());
}
public static int calculateTrackedRaceCount(Leaderboard sl) {
int count=0;
for (RaceColumn column : sl.getRaceColumns()) {
@@ -201,6 +207,20 @@ public final class HomeServiceUtil {
return count;
}
public static int calculateTrackedRaceColumnCount(Leaderboard sl) {
int count=0;
for (RaceColumn column : sl.getRaceColumns()) {
for (Fleet fleet : column.getFleets()) {
TrackedRace trackedRace = column.getTrackedRace(fleet);
if(trackedRace != null && trackedRace.hasGPSData() && trackedRace.hasWindData()) {
count++;
break;
}
}
}
return count;
}
public static String getBoatClassName(Leaderboard leaderboard) {
BoatClass boatClass = getBoatClass(leaderboard);
return boatClass == null ? null : boatClass.getName();
@@ -445,8 +465,7 @@ public final class HomeServiceUtil {
regattaDTO.setBoatCategory(leaderboardGroup.getDisplayName() != null ? leaderboardGroup.getDisplayName() : leaderboardGroup.getName());
}
regattaDTO.setCompetitorsCount(calculateCompetitorsCount(leaderboard));
regattaDTO.setRaceCount(calculateRaceCount(leaderboard));
regattaDTO.setTrackedRacesCount(calculateTrackedRaceCount(leaderboard));
regattaDTO.setRaceCount(calculateRaceColumnCount(leaderboard));
regattaDTO.setBoatClass(getBoatClassName(leaderboard));
if(leaderboard instanceof RegattaLeaderboard) {
Regatta regatta = ((RegattaLeaderboard) leaderboard).getRegatta();
@@ -466,6 +485,10 @@ public final class HomeServiceUtil {
return !liveRaces.isEmpty();
}
public static TimePoint getLiveTimePoint() {
return new MillisecondsTimePoint(getLiveTimePointInMillis());
}
private static long getLiveTimePointInMillis() {
// TODO better solution
long livePlayDelayInMillis = 15_000;
@@ -499,6 +499,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String scoringSchemeHighPointFirstGetsTen();
String knotsUnit();
String knotsValue(double value);
String knotsRange(double lowerValue, double upperValue);
String averageJibeLossInMetersTooltip();
String averageManeuverLossInMetersTooltip();
String averageTackLossInMetersTooltip();
@@ -1337,10 +1338,17 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String now();
String minutesAgo(String minutes);
String hoursAgo(String hours);
String winner();
String durationPlain();
String finishedRaces();
String selectCompetitor();
String allBoatClasses();
String points();
String numberOfRacesShort();
String courseGeometry();
String degreesToWind(String diff);
String miniLeeaderboardLegendText();
String currentOfTotal(int current, int total);
String noFinishedRaces();
String racesOverview();
}
@@ -521,6 +521,7 @@ raceIsLive=Race {0} is live
racesAreLive=Races {0} are live
knotsUnit=kts
knotsValue={0,number,#0.0} kts
knotsRange={0,number,#0.0} - {1,number,#0.0} kts
scoringSchemeHighPointFirstGetsOne=High Point, winner gets 1 point
scoringSchemeHighPointFirstGetsTen=High Point, winner gets 10 points
knotsUnit=kts
@@ -1306,9 +1307,16 @@ openLeaderboard=Open Leaderboard
now=Now
minutesAgo={0} min ago
hoursAgo={0} h ago
winner=Winner
durationPlain=Duration
finishedRaces=Finished Races
selectCompetitor=Please select one competitor
allBoatClasses=All Boat Classes
points=Points
numberOfRacesShort=# Races
courseGeometry=Course Geometry
degreesToWind={0}° to wind
miniLeeaderboardLegendText=Shows the points along with the number of races per competitor
miniLeeaderboardLegendText=Shows the points along with the number of races per competitor
currentOfTotal={0,number}/{1,number}
noFinishedRaces=There are no finished races yet
racesOverview=Races overview
@@ -524,6 +524,7 @@ scoringSchemeHighPointFirstGetsOne=High Point System, Gewinner erhält 1 Punkt
scoringSchemeHighPointFirstGetsTen=High Point System, Gewinner erhält 10 Punkte
knotsUnit=kn
knotsValue={0,number,#0.0} kn
knotsRange={0,number,#0.0} - {1,number,#0.0} kn
generatePolarSheet=Polardiagramm erstellen
polars=Polardiagramme
polarSheetChart=Polardiagramm
@@ -1296,9 +1297,16 @@ openLeaderboard=Rangliste öffnen
now=Jetzt
minutesAgo=vor {0} min
hoursAgo=vor {0} h
winner=Sieger
durationPlain=Dauer
finishedRaces=Beendete Wettfahrten
selectCompetitor=Bitte einen Teilnehmer auswählen
allBoatClasses=Alle Bootsklassen
points=Punkte
numberOfRacesShort=# Rennen
courseGeometry=Kursgeometrie
degreesToWind={0}° zum Wind
miniLeeaderboardLegendText=Es werden die Punkte und die Anzahl Rennen je Team angezeigt
miniLeeaderboardLegendText=Es werden die Punkte und die Anzahl Rennen je Team angezeigt
currentOfTotal={0,number}/{1,number}
noFinishedRaces=Es wurden noch keine Wettfahrten beendet.
racesOverview=Wettfahrtübersicht
@@ -510,6 +510,7 @@ raceIsLive=Гонка {0} в прямом эфире
racesAreLive=Гонки {0} в прямом эфире
knotsUnit=Узлы
knotsValue={0,number,#0.0} Узлы
knotsRange={0,number,#0.0} - {1,number,#0.0} Узлы
scoringSchemeHighPointFirstGetsOne=Самый лучший результат, победитель получает 1 очко
scoringSchemeHighPointFirstGetsTen=Самый лучший результат, победитель получает 10 очков
generatePolarSheet=Создать полярную электронную таблицу
@@ -1243,9 +1244,16 @@ openLeaderboard=Open Leaderboard
now=в настоящее время
minutesAgo={0} минут назад
hoursAgo={0} h часов назад
winner=победитель
durationPlain=Продолжительность
finishedRaces=Finished Races
selectCompetitor=Please select one competitor
allBoatClasses=All Boat Classes
points=Points
numberOfRacesShort=# Races
courseGeometry=Course Geometry
degreesToWind={0}° to wind
miniLeeaderboardLegendText=Shows points along with the number of races per competitor
miniLeeaderboardLegendText=Shows points along with the number of races per competitor
currentOfTotal={0,number}/{1,number}
noFinishedRaces=There are no finished races yet
racesOverview=Races overview
@@ -978,6 +978,7 @@ competitor=参赛队
tracked=跟踪
knotsUnit=kts
knotsValue={0,number,#0.0} kts
knotsRange={0,number,#0.0} - {1,number,#0.0} kts
errorTryingToObtainRaceLogMarkPassingData=Error trying to obtain race log mark passing data: {0}
imageURLs=Image URLs
speedOverGroundAtRaceStartTooltip=起航时的实际速度
@@ -1274,6 +1275,9 @@ raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds=Calc.Time
raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip=Calculated time at estimated arrival at the competitor that is currently farthest ahead in the race;\nestimation based on average VMG in current leg and equal (calculated) performance to fastest boat in all subsequent legs
sailorInfo=水手信息
sailorInfoLongText=Find here Notice Board,\nProtests, Sailor weather:
winner=Winner
durationPlain=Duration
finishedRaces=Finished Races
resultsQuickfinder=Results Quickfinder
statistics=Statistics
impressions=Impressions
@@ -1293,8 +1297,12 @@ noNews=There are no news available.
pointsValue={0,number,#0.00}
openLeaderboard=Open Leaderboard
selectCompetitor=Please select one competitor
allBoatClasses=All Boat Classes
points=Points
numberOfRacesShort=# Races
courseGeometry=Course Geometry
degreesToWind={0}° to wind
miniLeeaderboardLegendText=Shows points along with the number of races per competitor
miniLeeaderboardLegendText=Shows points along with the number of races per competitor
currentOfTotal={0,number}/{1,number}
noFinishedRaces=There are no finished races yet
racesOverview=Races overview
@@ -0,0 +1,7 @@
package com.sap.sailing.gwt.ui.shared.dispatch;
import java.util.Collection;
public interface CollectionResult<T extends DTO> extends DTO, Result {
Collection<T> getValues();
}
Loaded 100 of 161 files, more files were not shown because too many files have changed in this diff. Show more