mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-22 03:53:56 +00:00
Merge branch 'master' into bug4207
This commit is contained in:
commit
49e655d76f
279 files changed
+6149
-2862
No files matched your search
+53
-18
@@ -9,6 +9,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.logging.Level;
|
||||
@@ -89,28 +90,43 @@ public class MongoSensorFixStoreImpl implements MongoSensorFixStore {
|
||||
DBObject fixObject = (DBObject) object.get(FieldNames.GPSFIX.name());
|
||||
return this.<T> findService(type).transformBack(fixObject);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <FixT extends Timed> boolean loadOldestFix(Consumer<FixT> consumer, DeviceIdentifier device, TimeRange timeRangeToLoad) throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
return loadFixes(consumer, device, timeRangeToLoad.from(), timeRangeToLoad.to(), false, cursor -> cursor.sort(new BasicDBObject(FieldNames.TIME_AS_MILLIS.name(), /* ascending */ 1)).limit(1));
|
||||
return loadFixes(consumer, device, timeRangeToLoad.from(), timeRangeToLoad.to(), false, () -> false, (d) -> {
|
||||
}, cursor -> cursor.sort(new BasicDBObject(FieldNames.TIME_AS_MILLIS.name(), /* ascending */ 1)).limit(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <FixT extends Timed> boolean loadYoungestFix(Consumer<FixT> consumer, DeviceIdentifier device, TimeRange timeRangeToLoad) throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
return loadFixes(consumer, device, timeRangeToLoad.from(), timeRangeToLoad.to(), false, cursor -> cursor.sort(new BasicDBObject(FieldNames.TIME_AS_MILLIS.name(), /* descending */ -1)).limit(1));
|
||||
return loadFixes(consumer, device, timeRangeToLoad.from(), timeRangeToLoad.to(), false, () -> false, (d) -> {
|
||||
}, cursor -> cursor.sort(new BasicDBObject(FieldNames.TIME_AS_MILLIS.name(), /* descending */ -1)).limit(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <FixT extends Timed> void loadFixes(Consumer<FixT> consumer, DeviceIdentifier device, TimePoint from,
|
||||
TimePoint to, boolean inclusive) throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
loadFixes(consumer, device, from, to, inclusive, UnaryOperator.identity());
|
||||
loadFixes(consumer, device, from, to, inclusive, () -> false, (d) -> {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <FixT extends Timed> void loadFixes(Consumer<FixT> consumer, DeviceIdentifier device, TimePoint from,
|
||||
TimePoint to, boolean inclusive, BooleanSupplier isPreemptiveStopped, Consumer<Double> progressConsumer)
|
||||
throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
loadFixes(consumer, device, from, to, inclusive, isPreemptiveStopped, progressConsumer,
|
||||
UnaryOperator.identity());
|
||||
}
|
||||
|
||||
private <FixT extends Timed> boolean loadFixes(Consumer<FixT> consumer, DeviceIdentifier device, TimePoint from,
|
||||
TimePoint to, boolean inclusive, UnaryOperator<DBCursor> dbCursorCallback) throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
TimePoint to, boolean inclusive, BooleanSupplier isPreemptiveStopped, Consumer<Double> progressConsumer,
|
||||
UnaryOperator<DBCursor> dbCursorCallback)
|
||||
throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
progressConsumer.accept(0d);
|
||||
|
||||
final TimePoint loadFixesFrom = from == null ? TimePoint.BeginningOfTime : from;
|
||||
final TimePoint loadFixesTo = to == null ? TimePoint.EndOfTime : to;
|
||||
|
||||
|
||||
Object dbDeviceId = storeDeviceId(deviceServiceFinder, device);
|
||||
final QueryBuilder queryBuilder = QueryBuilder.start(FieldNames.DEVICE_ID.name()).is(dbDeviceId)
|
||||
.and(FieldNames.TIME_AS_MILLIS.name());
|
||||
@@ -118,12 +134,26 @@ public class MongoSensorFixStoreImpl implements MongoSensorFixStore {
|
||||
queryBuilder.greaterThanEquals(loadFixesFrom.asMillis()).and(FieldNames.TIME_AS_MILLIS.name())
|
||||
.lessThanEquals(loadFixesTo.asMillis());
|
||||
} else {
|
||||
queryBuilder.greaterThanEquals(loadFixesFrom.asMillis()).and(FieldNames.TIME_AS_MILLIS.name()).lessThan(loadFixesTo.asMillis());
|
||||
queryBuilder.greaterThanEquals(loadFixesFrom.asMillis()).and(FieldNames.TIME_AS_MILLIS.name())
|
||||
.lessThan(loadFixesTo.asMillis());
|
||||
}
|
||||
DBObject query = queryBuilder.get();
|
||||
DBCursor result = dbCursorCallback.apply(fixesCollection.find(query));
|
||||
boolean fixLoaded = false;
|
||||
double max = result.size();
|
||||
// update roughly every percent, but at not more often than every 100th entry
|
||||
int reportIncrement = (int) Math.max(max / 100, 100);
|
||||
int current = 0;
|
||||
for (DBObject fixObject : result) {
|
||||
current++;
|
||||
|
||||
if (current % reportIncrement == 0) {
|
||||
progressConsumer.accept(current / max);
|
||||
if (isPreemptiveStopped.getAsBoolean()) {
|
||||
logger.log(Level.WARNING, "Exiting because of preemtive stop requested " + fixObject);
|
||||
return fixLoaded;
|
||||
}
|
||||
}
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
FixT fix = (FixT) loadFix(fixObject);
|
||||
@@ -137,6 +167,8 @@ public class MongoSensorFixStoreImpl implements MongoSensorFixStore {
|
||||
"Unexpected fix type (" + type + ") encountered when trying to load track for " + device);
|
||||
}
|
||||
}
|
||||
|
||||
progressConsumer.accept(1d);
|
||||
return fixLoaded;
|
||||
}
|
||||
|
||||
@@ -150,7 +182,7 @@ public class MongoSensorFixStoreImpl implements MongoSensorFixStore {
|
||||
final Object dbDeviceId = storeDeviceId(deviceServiceFinder, device);
|
||||
final int nrOfTotalFixes = Util.size(fixes);
|
||||
final ArrayList<DBObject> dbFixes = new ArrayList<>(nrOfTotalFixes);
|
||||
|
||||
|
||||
TimePoint newFrom = null;
|
||||
TimePoint newTo = null;
|
||||
for (FixT fix : fixes) {
|
||||
@@ -173,14 +205,14 @@ public class MongoSensorFixStoreImpl implements MongoSensorFixStore {
|
||||
final BasicDBObject updateOperation = new BasicDBObject();
|
||||
final BasicDBObject newMetadata = new BasicDBObject();
|
||||
newMetadata.put(FieldNames.DEVICE_ID.name(), dbDeviceId);
|
||||
|
||||
|
||||
TimeRange oldTimeRange = getTimeRangeCoveredByFixes(device);
|
||||
if (oldTimeRange != null) {
|
||||
newFrom = oldTimeRange.from().before(newFrom) ? oldTimeRange.from() : newFrom;
|
||||
newTo = oldTimeRange.to().after(newTo) ? oldTimeRange.to() : newTo;
|
||||
}
|
||||
final TimeRange newTimeRange = new TimeRangeImpl(newFrom, newTo);
|
||||
|
||||
|
||||
storeTimeRange(newTimeRange, newMetadata, FieldNames.TIMERANGE);
|
||||
updateOperation.append("$set", newMetadata);
|
||||
updateOperation.append("$inc", new BasicDBObject(FieldNames.NUM_FIXES.name(), nrOfTotalFixes));
|
||||
@@ -221,7 +253,7 @@ public class MongoSensorFixStoreImpl implements MongoSensorFixStore {
|
||||
public void removeListener(FixReceivedListener<? extends Timed> listener) {
|
||||
LockUtil.executeWithWriteLock(listenersLock, () -> Util.removeFromAllValueSets(listeners, listener));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void removeListener(FixReceivedListener<? extends Timed> listener, DeviceIdentifier device) {
|
||||
LockUtil.executeWithWriteLock(listenersLock, () -> Util.removeFromValueSet(listeners, device, listener));
|
||||
@@ -264,12 +296,13 @@ public class MongoSensorFixStoreImpl implements MongoSensorFixStore {
|
||||
/**
|
||||
* Try to find a service implementing specified type of objects interface using the {@link #fixServiceFinder}.
|
||||
* <p>
|
||||
* To support an additional fix type, an implementation of {@link FixMongoHandler} is required, which specifies how to
|
||||
* transform a fix forth to and back from database. This implementation needs to be
|
||||
* registered during OSGi bundle activator startup, providing respective type mapping properties.
|
||||
* To support an additional fix type, an implementation of {@link FixMongoHandler} is required, which specifies how
|
||||
* to transform a fix forth to and back from database. This implementation needs to be registered during OSGi bundle
|
||||
* activator startup, providing respective type mapping properties.
|
||||
* </p>
|
||||
*
|
||||
* @param type type object to find service for
|
||||
* @param type
|
||||
* type object to find service for
|
||||
* @return the registered {@link FixMongoHandler} implementation
|
||||
*
|
||||
* @see TypeBasedServiceFinder#findService(String)
|
||||
@@ -282,11 +315,13 @@ public class MongoSensorFixStoreImpl implements MongoSensorFixStore {
|
||||
@Override
|
||||
public <FixT extends Timed> Map<DeviceIdentifier, FixT> getLastFix(Iterable<DeviceIdentifier> forDevices)
|
||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
Map<DeviceIdentifier, FixT> result = new HashMap<>();
|
||||
Map<DeviceIdentifier, FixT> result = new HashMap<>();
|
||||
for (final DeviceIdentifier deviceIdentifier : forDevices) {
|
||||
final DBObject deviceQuery = new BasicDBObject(FieldNames.DEVICE_ID.name()+"."+FieldNames.DEVICE_TYPE_SPECIFIC_ID.name(),
|
||||
final DBObject deviceQuery = new BasicDBObject(
|
||||
FieldNames.DEVICE_ID.name() + "." + FieldNames.DEVICE_TYPE_SPECIFIC_ID.name(),
|
||||
deviceIdentifier.getStringRepresentation());
|
||||
final DBObject orderBy = new BasicDBObject(FieldNames.GPSFIX.name()+"."+FieldNames.TIME_AS_MILLIS.name(), -1);
|
||||
final DBObject orderBy = new BasicDBObject(
|
||||
FieldNames.GPSFIX.name() + "." + FieldNames.TIME_AS_MILLIS.name(), -1);
|
||||
DBCursor lastFixForDeviceCursor = fixesCollection.find(deviceQuery).sort(orderBy).limit(1);
|
||||
if (lastFixForDeviceCursor.hasNext()) {
|
||||
final DBObject lastFixForDeviceDbObject = lastFixForDeviceCursor.next();
|
||||
|
||||
+79
-25
@@ -5,6 +5,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -30,10 +31,13 @@ import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||
import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneImeiServiceFinderFactory;
|
||||
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sse.common.Timed;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class SensorFixStoreTest {
|
||||
private static final long FIX_TIMESTAMP = 110;
|
||||
private static final long FIX_TIMESTAMP2 = 120;
|
||||
@@ -88,32 +92,82 @@ public class SensorFixStoreTest {
|
||||
newStore();
|
||||
assertEquals(1, store.getNumberOfFixes(device));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFixDataIsPreservedOnStore() throws Exception {
|
||||
DoubleVectorFix fix = addBravoFix(device, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
|
||||
|
||||
verifySingleFix(fix, 100, 200, device, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgressSingle() throws Exception {
|
||||
testProgress(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFew() throws Exception {
|
||||
testProgress(80);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLittle() throws Exception {
|
||||
testProgress(109);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgressMay() throws Exception {
|
||||
testProgress(2000);
|
||||
}
|
||||
|
||||
private void testProgress(int fixes) throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
for (int i = 0; i < fixes; i++) {
|
||||
addBravoFix(device, FIX_TIMESTAMP + 1, FIX_RIDE_HEIGHT);
|
||||
}
|
||||
|
||||
List<Double> progressData = new ArrayList<>();
|
||||
store.loadFixes((fix) -> {
|
||||
}, device, new MillisecondsTimePoint(FIX_TIMESTAMP - 1), new MillisecondsTimePoint(FIX_TIMESTAMP + fixes + 1),
|
||||
true, () -> false, new Consumer<Double>() {
|
||||
|
||||
@Override
|
||||
public void accept(Double progress) {
|
||||
progressData.add(progress);
|
||||
}
|
||||
});
|
||||
|
||||
// validate monotone rising
|
||||
// validate between 0 and 1 (inclusive)
|
||||
Double last = 0.0;
|
||||
for (Double progress : progressData) {
|
||||
Assert.assertTrue(progress <= 1);
|
||||
Assert.assertTrue(progress >= 0);
|
||||
Assert.assertTrue(progress >= last);
|
||||
last = progress;
|
||||
}
|
||||
//validate that 0-100 updates do exist
|
||||
Assert.assertFalse(progressData.isEmpty());
|
||||
Assert.assertTrue(progressData.size() <= 100);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFixWithinExclusiveBoundsIsLoaded() throws Exception {
|
||||
DoubleVectorFix fix = addBravoFix(device, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
verifySingleFix(fix, FIX_TIMESTAMP - 1, FIX_TIMESTAMP + 1, device, false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFixOnInclusiveLowerBoundIsLoaded() throws Exception {
|
||||
DoubleVectorFix fix = addBravoFix(device, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
verifySingleFix(fix, FIX_TIMESTAMP, FIX_TIMESTAMP + 1, device, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFixOnInclusiveUpperBoundIsLoaded() throws Exception {
|
||||
DoubleVectorFix fix = addBravoFix(device, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
verifySingleFix(fix, FIX_TIMESTAMP-1, FIX_TIMESTAMP, device, true);
|
||||
verifySingleFix(fix, FIX_TIMESTAMP - 1, FIX_TIMESTAMP, device, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFixesOnExclusiveEndBoundsArentLoaded() throws Exception {
|
||||
DoubleVectorFix fix = addBravoFix(device, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
@@ -136,16 +190,16 @@ public class SensorFixStoreTest {
|
||||
addBravoFix(device, FIX_TIMESTAMP + 5, FIX_RIDE_HEIGHT2);
|
||||
verifyOldestFix(oldestFix, FIX_TIMESTAMP, FIX_TIMESTAMP2, device);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSingleListenerIsNotified() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener = mockFixReceivedListener();
|
||||
store.addListener(listener, device);
|
||||
DoubleVectorFix doubleVectorFix = addBravoFix(device, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
|
||||
|
||||
Mockito.verify(listener, Mockito.times(1)).fixReceived(device, doubleVectorFix);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMultipleListenersForSameDeviceAreNotified() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener1 = mockFixReceivedListener();
|
||||
@@ -153,20 +207,20 @@ public class SensorFixStoreTest {
|
||||
store.addListener(listener1, device);
|
||||
store.addListener(listener2, device);
|
||||
DoubleVectorFix doubleVectorFix = addBravoFix(device, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
|
||||
|
||||
Mockito.verify(listener1, Mockito.times(1)).fixReceived(device, doubleVectorFix);
|
||||
Mockito.verify(listener2, Mockito.times(1)).fixReceived(device, doubleVectorFix);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testListenerForNonMatchingDeviceIsNotNotified() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener = mockFixReceivedListener();
|
||||
store.addListener(listener, device);
|
||||
addBravoFix(device2, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
|
||||
|
||||
Mockito.verifyZeroInteractions(listener);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testOnlyListenerForMatchingDeviceIsNotified() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener1 = mockFixReceivedListener();
|
||||
@@ -174,23 +228,23 @@ public class SensorFixStoreTest {
|
||||
store.addListener(listener1, device);
|
||||
store.addListener(listener2, device2);
|
||||
DoubleVectorFix doubleVectorFix = addBravoFix(device, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
|
||||
|
||||
Mockito.verify(listener1, Mockito.times(1)).fixReceived(device, doubleVectorFix);
|
||||
Mockito.verifyZeroInteractions(listener2);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testListenerForMatchingDeviceIsNotifiedMultipleTimes() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener = mockFixReceivedListener();
|
||||
store.addListener(listener, device);
|
||||
DoubleVectorFix doubleVectorFix1 = addBravoFix(device, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
DoubleVectorFix doubleVectorFix2 = addBravoFix(device, FIX_TIMESTAMP2, FIX_RIDE_HEIGHT2);
|
||||
|
||||
|
||||
Mockito.verify(listener, Mockito.times(1)).fixReceived(device, doubleVectorFix1);
|
||||
Mockito.verify(listener, Mockito.times(1)).fixReceived(device, doubleVectorFix2);
|
||||
Mockito.verifyNoMoreInteractions(listener);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAfterRemoveListenerIsNotNotified() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener = mockFixReceivedListener();
|
||||
@@ -199,7 +253,7 @@ public class SensorFixStoreTest {
|
||||
addBravoFix(device, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
Mockito.verifyZeroInteractions(listener);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAfterRemoveForDeviceListenerIsNotNotified() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener = mockFixReceivedListener();
|
||||
@@ -208,7 +262,7 @@ public class SensorFixStoreTest {
|
||||
addBravoFix(device, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
Mockito.verifyZeroInteractions(listener);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAfterRemoveForNonMatchingDeviceListenerIsNotified() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener = mockFixReceivedListener();
|
||||
@@ -217,7 +271,7 @@ public class SensorFixStoreTest {
|
||||
DoubleVectorFix doubleVectorFix = addBravoFix(device, FIX_TIMESTAMP, FIX_RIDE_HEIGHT);
|
||||
Mockito.verify(listener, Mockito.times(1)).fixReceived(device, doubleVectorFix);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testListenerForMultipleDevicesIsNotifiedMultipleTimes() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener = mockFixReceivedListener();
|
||||
@@ -229,7 +283,7 @@ public class SensorFixStoreTest {
|
||||
Mockito.verify(listener, Mockito.times(1)).fixReceived(device2, doubleVectorFix2);
|
||||
Mockito.verifyNoMoreInteractions(listener);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAfterRemoveListenerForMultipleDevicesIsNotNotified() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener = mockFixReceivedListener();
|
||||
@@ -240,7 +294,7 @@ public class SensorFixStoreTest {
|
||||
addBravoFix(device2, FIX_TIMESTAMP2, FIX_RIDE_HEIGHT2);
|
||||
Mockito.verifyZeroInteractions(listener);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAfterRemoveListenerForOneDevicesIsNotifiedForOtherDevice() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener = mockFixReceivedListener();
|
||||
@@ -252,7 +306,7 @@ public class SensorFixStoreTest {
|
||||
Mockito.verify(listener, Mockito.times(1)).fixReceived(device2, doubleVectorFix2);
|
||||
Mockito.verifyNoMoreInteractions(listener);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAfterRemoveListenerOtherListenerIsNotified() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener1 = mockFixReceivedListener();
|
||||
@@ -265,7 +319,7 @@ public class SensorFixStoreTest {
|
||||
Mockito.verifyNoMoreInteractions(listener2);
|
||||
Mockito.verifyZeroInteractions(listener1);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAfterRemoveForDeviceListenerOtherListenerIsNotified() throws Exception {
|
||||
FixReceivedListener<DoubleVectorFix> listener1 = mockFixReceivedListener();
|
||||
@@ -278,7 +332,7 @@ public class SensorFixStoreTest {
|
||||
Mockito.verifyNoMoreInteractions(listener2);
|
||||
Mockito.verifyZeroInteractions(listener1);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private FixReceivedListener<DoubleVectorFix> mockFixReceivedListener() {
|
||||
FixReceivedListener<DoubleVectorFix> listener = Mockito.mock(FixReceivedListener.class);
|
||||
|
||||
Regular → Executable
+92
-27
@@ -2,11 +2,14 @@ package com.sap.sailing.domain.racelogtracking.impl.fixtracker;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -273,10 +276,11 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
* special handling.
|
||||
*/
|
||||
private void loadFixesForNewlyCoveredTimeRanges(WithID item,
|
||||
Map<RegattaLogDeviceMappingEvent<WithID>, MultiTimeRange> newlyCoveredTimeRanges) {
|
||||
Map<RegattaLogDeviceMappingEvent<WithID>, MultiTimeRange> newlyCoveredTimeRanges,
|
||||
Consumer<Double> progressConsumer, BooleanSupplier stopCallback) {
|
||||
if (trackedRace.getStartOfTracking() != null) {
|
||||
TimeRange trackingTimeRange = getTrackingTimeRange();
|
||||
loadFixesInTrackingTimeRange(newlyCoveredTimeRanges, trackingTimeRange);
|
||||
loadFixesInTrackingTimeRange(newlyCoveredTimeRanges, trackingTimeRange, progressConsumer, stopCallback);
|
||||
if (item instanceof Mark) {
|
||||
Mark mark = (Mark) item;
|
||||
DynamicGPSFixTrack<Mark, GPSFix> track = trackedRace.getOrCreateTrack(mark);
|
||||
@@ -300,19 +304,42 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
*/
|
||||
private void loadFixesInTrackingTimeRange(
|
||||
Map<RegattaLogDeviceMappingEvent<WithID>, MultiTimeRange> newlyCoveredTimeRanges,
|
||||
TimeRange trackingTimeRange) {
|
||||
newlyCoveredTimeRanges.forEach((event, timeRange) -> {
|
||||
loadFixesForMultiTimeRange(timeRange.intersection(trackingTimeRange), event);
|
||||
});
|
||||
TimeRange trackingTimeRange, Consumer<Double> progressConsumer, BooleanSupplier stopCallback) {
|
||||
final MultiJobProgressUpdater progressUpdater = new MultiJobProgressUpdater(newlyCoveredTimeRanges.size());
|
||||
int currentJobNr = 0;
|
||||
for (Entry<RegattaLogDeviceMappingEvent<WithID>, MultiTimeRange> e : newlyCoveredTimeRanges.entrySet()) {
|
||||
final int jobNr = currentJobNr;
|
||||
MultiTimeRange timeRange = e.getValue();
|
||||
RegattaLogDeviceMappingEvent<WithID> event = e.getKey();
|
||||
loadFixesForMultiTimeRange(timeRange.intersection(trackingTimeRange), event, p -> {
|
||||
progressUpdater.updateProgress(jobNr, p);
|
||||
progressConsumer.accept(progressUpdater.getProgress());
|
||||
}, stopCallback);
|
||||
currentJobNr++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads fixes for the parts of the given {@link MultiTimeRange} using the given mapping event.
|
||||
*/
|
||||
private void loadFixesForMultiTimeRange(MultiTimeRange effectiveRangeToLoad,
|
||||
RegattaLogDeviceMappingEvent<WithID> event) {
|
||||
RegattaLogDeviceMappingEvent<WithID> event, Consumer<Double> progressConsumer, BooleanSupplier stopCallback) {
|
||||
if (!effectiveRangeToLoad.isEmpty()) {
|
||||
effectiveRangeToLoad.forEach(timeRange -> loadFixes(timeRange, event));
|
||||
int currentJobNr = 0;
|
||||
final int nrOfJobs = Util.size(effectiveRangeToLoad);
|
||||
final MultiJobProgressUpdater progressUpdater = new MultiJobProgressUpdater(nrOfJobs);
|
||||
|
||||
for (TimeRange timeRange : effectiveRangeToLoad) {
|
||||
final int jobNr = currentJobNr;
|
||||
loadFixes(timeRange, event, p -> {
|
||||
progressUpdater.updateProgress(jobNr, p);
|
||||
progressConsumer.accept(progressUpdater.getProgress());
|
||||
}, stopCallback);
|
||||
currentJobNr++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,7 +360,8 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
/**
|
||||
* Loads the fixes in the specified {@link TimeRange} using a visitor of the given mapping event.
|
||||
*/
|
||||
private void loadFixes(TimeRange timeRangeToLoad, RegattaLogDeviceMappingEvent<? extends WithID> mappingEvent) {
|
||||
private void loadFixes(TimeRange timeRangeToLoad, RegattaLogDeviceMappingEvent<? extends WithID> mappingEvent,
|
||||
final Consumer<Double> progressConsumer, final BooleanSupplier stopCallback) {
|
||||
if (timeRangeToLoad != null && !preemptiveStopRequested.get()) {
|
||||
mappingEvent.accept(new MappingEventVisitor() {
|
||||
@Override
|
||||
@@ -347,7 +375,8 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
// competitor retrieved from the mapping event does not have a track in trackedRace
|
||||
try {
|
||||
sensorFixStore.<DoubleVectorFix> loadFixes(fix -> mapper.addFix(track, fix), event.getDevice(),
|
||||
timeRangeToLoad.from(), timeRangeToLoad.to(), /* toIsInclusive */ false);
|
||||
timeRangeToLoad.from(), timeRangeToLoad.to(), /* toIsInclusive */ false,
|
||||
stopCallback, progressConsumer);
|
||||
} catch (NoCorrespondingServiceRegisteredException | TransformationException e) {
|
||||
logger.log(Level.WARNING, "Could not load track for competitor: " + event.getMappedTo()
|
||||
+ "; device: " + event.getDevice());
|
||||
@@ -364,7 +393,8 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
// competitor retrieved from the mapping event does not have a track in trackedRace
|
||||
try {
|
||||
sensorFixStore.<GPSFixMoving> loadFixes(fix -> track.add(fix, true), event.getDevice(),
|
||||
timeRangeToLoad.from(), timeRangeToLoad.to(), /* toIsInclusive */ false);
|
||||
timeRangeToLoad.from(), timeRangeToLoad.to(), /* toIsInclusive */ false,
|
||||
stopCallback, progressConsumer);
|
||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
||||
logger.log(Level.WARNING, "Could not load competitor track " + event.getMappedTo() + "; device "
|
||||
+ event.getDevice());
|
||||
@@ -377,7 +407,8 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
DynamicGPSFixTrack<Mark, GPSFix> track = trackedRace.getOrCreateTrack(event.getMappedTo());
|
||||
try {
|
||||
sensorFixStore.<GPSFix> loadFixes(fix -> track.add(fix, true), event.getDevice(),
|
||||
timeRangeToLoad.from(), timeRangeToLoad.to(), /* toIsInclusive */ false);
|
||||
timeRangeToLoad.from(), timeRangeToLoad.to(), /* toIsInclusive */ false,
|
||||
stopCallback, progressConsumer);
|
||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
||||
logger.log(Level.WARNING, "Could not load mark track " + event.getMappedTo());
|
||||
}
|
||||
@@ -524,8 +555,8 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
double progressSum = 0.0;
|
||||
boolean allFinished = true;
|
||||
for (AbstractLoadingJob loadingJob : loadingJobs) {
|
||||
allFinished &= loadingJob.finished;
|
||||
progressSum += loadingJob.progress;
|
||||
allFinished &= loadingJob.isFinished();
|
||||
progressSum += loadingJob.getProgress();
|
||||
}
|
||||
if (allFinished) {
|
||||
loadingJobs.clear();
|
||||
@@ -563,7 +594,7 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
public boolean isStopRequested() {
|
||||
return stopRequested.get();
|
||||
}
|
||||
|
||||
|
||||
private class FixLoaderDeviceMappings extends RegattaLogDeviceMappings<WithID> {
|
||||
public FixLoaderDeviceMappings(Iterable<RegattaLog> initialRegattaLogs, String raceNameForLock) {
|
||||
super(initialRegattaLogs, raceNameForLock);
|
||||
@@ -593,26 +624,60 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
* Subclasses are intended to be run using an executor.
|
||||
*/
|
||||
private abstract class AbstractLoadingJob implements Runnable {
|
||||
double progress = 0;
|
||||
boolean finished = false;
|
||||
volatile double currentProgress = 0d;
|
||||
volatile boolean isFinished = false;
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
progress = 0.5;
|
||||
|
||||
updateStatusAndProgressWithErrorHandling();
|
||||
|
||||
try {
|
||||
load();
|
||||
load(this::updateProgress, preemptiveStopRequested::get);
|
||||
} finally {
|
||||
progress = 1.0;
|
||||
finished = true;
|
||||
updateStatusAndProgressWithErrorHandling();
|
||||
isFinished = true;
|
||||
updateProgress(1d);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void load();
|
||||
private void updateProgress(double newProgress) {
|
||||
currentProgress = newProgress;
|
||||
updateStatusAndProgressWithErrorHandling();
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return isFinished;
|
||||
}
|
||||
|
||||
public double getProgress() {
|
||||
return currentProgress;
|
||||
}
|
||||
|
||||
protected abstract void load(Consumer<Double> progressConsumer, BooleanSupplier stopCallback);
|
||||
}
|
||||
|
||||
public class MultiJobProgressUpdater {
|
||||
volatile double[] currentProgress = new double[1];
|
||||
|
||||
public MultiJobProgressUpdater(int nrOfJobs) {
|
||||
super();
|
||||
currentProgress = new double[nrOfJobs];
|
||||
}
|
||||
|
||||
void updateProgress(int jobNr, double progress) {
|
||||
if (jobNr >= 0 && jobNr < currentProgress.length) {
|
||||
currentProgress[jobNr] = progress;
|
||||
}
|
||||
|
||||
}
|
||||
public double getProgress() {
|
||||
double progress = 0d;
|
||||
for (int i = 0; i < currentProgress.length; i++) {
|
||||
progress += currentProgress[i] / currentProgress.length;
|
||||
}
|
||||
return progress;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Loads fixes for an item's mappings in a defined tracking {@link TimeRange}. This is used when the tracking
|
||||
* {@link TimeRange} is extended. No better fixes for {@link Mark} are being loaded because if available, these must
|
||||
@@ -631,8 +696,8 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
loadFixesInTrackingTimeRange(newlyCoveredTimeRanges, trackingTimeRange);
|
||||
protected void load(Consumer<Double> progressConsumer, BooleanSupplier stopCallback) {
|
||||
loadFixesInTrackingTimeRange(newlyCoveredTimeRanges, trackingTimeRange, progressConsumer, stopCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -652,8 +717,8 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
loadFixesForNewlyCoveredTimeRanges(item, newlyCoveredTimeRanges);
|
||||
protected void load(Consumer<Double> progressConsumer, BooleanSupplier stopCallback) {
|
||||
loadFixesForNewlyCoveredTimeRanges(item, newlyCoveredTimeRanges, progressConsumer, stopCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-19
@@ -13,30 +13,12 @@ public class ConfirmedFinishPositioningListFinder extends RaceLogAnalyzer<Compet
|
||||
|
||||
@Override
|
||||
protected CompetitorResults performAnalysis() {
|
||||
return performAnalysis(/* eventToIgnore */ null);
|
||||
}
|
||||
|
||||
private CompetitorResults performAnalysis(RaceLogFinishPositioningConfirmedEvent eventToIgnore) {
|
||||
for (RaceLogEvent event : getPassEventsDescending()) {
|
||||
if (event != eventToIgnore && event instanceof RaceLogFinishPositioningConfirmedEvent) {
|
||||
if (event instanceof RaceLogFinishPositioningConfirmedEvent) {
|
||||
RaceLogFinishPositioningConfirmedEvent finishPositioningEvent = (RaceLogFinishPositioningConfirmedEvent) event;
|
||||
return finishPositioningEvent.getPositionedCompetitorsIDsNamesMaxPointsReasons();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #analyze()}, only that if {@code event} is found in the log then it is ignored for this
|
||||
* analysis. This way, the method returns a result as it would have been without {@code event} in the
|
||||
* {@link RaceLog}. This can be useful, e.g., to determine the result prior to the last update.
|
||||
*/
|
||||
public CompetitorResults analyzeIgnoring(RaceLogFinishPositioningConfirmedEvent event) {
|
||||
log.lockForRead();
|
||||
try {
|
||||
return performAnalysis(event);
|
||||
} finally {
|
||||
log.unlockAfterRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -32,8 +32,8 @@ public interface SettableScoreCorrection extends ScoreCorrection {
|
||||
void uncorrectScore(Competitor competitor, RaceColumn raceColumn);
|
||||
|
||||
/**
|
||||
* @return <code>null</code> if not set for the competitor, e.g., because no correction was made or an explicit
|
||||
* {@link MaxPointsReason} was provided for the competitor.
|
||||
* @return <code>null</code> if not set for the competitor, e.g., because no correction was made or only a
|
||||
* {@link MaxPointsReason} but no explicit score was provided for the competitor.
|
||||
*/
|
||||
Double getExplicitScoreCorrection(Competitor competitor, RaceColumn raceColumn);
|
||||
|
||||
|
||||
+52
-15
@@ -1,6 +1,8 @@
|
||||
package com.sap.sailing.domain.racelog.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceCompetitorMappingFinder;
|
||||
@@ -21,10 +23,10 @@ import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
* At the moment, the timerange covered by the fixes for a device, and the number of
|
||||
* fixes for a device are stored in a metadata collection. Should be changed, see bug 1982.
|
||||
* At the moment, the timerange covered by the fixes for a device, and the number of fixes for a device are stored in a
|
||||
* metadata collection. Should be changed, see bug 1982.
|
||||
*
|
||||
* @author Fredrik Teschke
|
||||
*
|
||||
*/
|
||||
public class GPSFixStoreImpl implements GPSFixStore {
|
||||
private final SensorFixStore sensorFixStore;
|
||||
@@ -34,31 +36,44 @@ public class GPSFixStoreImpl implements GPSFixStore {
|
||||
}
|
||||
|
||||
private <FixT extends GPSFix> void loadTrack(DynamicGPSFixTrack<?, FixT> track, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to, boolean toIsInclusive) throws NoCorrespondingServiceRegisteredException,
|
||||
TransformationException {
|
||||
sensorFixStore.<FixT>loadFixes(fix->track.add(fix, /* replace */ true), device, from, to, toIsInclusive);
|
||||
TimePoint from, TimePoint to, boolean toIsInclusive)
|
||||
throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
loadTrack(track, device, from, to, toIsInclusive, () -> {
|
||||
return false;
|
||||
}, (c) -> {
|
||||
});
|
||||
}
|
||||
|
||||
private <FixT extends GPSFix> void loadTrack(DynamicGPSFixTrack<?, FixT> track, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to, boolean toIsInclusive, BooleanSupplier isPreemptiveStopped,
|
||||
Consumer<Double> progress)
|
||||
throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
sensorFixStore.<FixT> loadFixes(fix -> track.add(fix, /* replace */ true), device, from, to, toIsInclusive,
|
||||
isPreemptiveStopped, progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track, RegattaLog log, Competitor competitor)
|
||||
throws NoCorrespondingServiceRegisteredException, TransformationException{
|
||||
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track, RegattaLog log,
|
||||
Competitor competitor) throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
List<DeviceMappingWithRegattaLogEvent<Competitor>> mappings = new RegattaLogDeviceCompetitorMappingFinder(log)
|
||||
.analyze().get(competitor);
|
||||
if (mappings != null) {
|
||||
for (DeviceMapping<Competitor> mapping : mappings) {
|
||||
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), false /*toIsInclusive*/);
|
||||
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(),
|
||||
false /* toIsInclusive */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark)
|
||||
throws NoCorrespondingServiceRegisteredException, TransformationException{
|
||||
throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
List<DeviceMappingWithRegattaLogEvent<Mark>> mappings = new RegattaLogDeviceMarkMappingFinder(log).analyze()
|
||||
.get(mark);
|
||||
if (mappings != null) {
|
||||
for (DeviceMapping<Mark> mapping : mappings) {
|
||||
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), false /*toIsInclusive*/);
|
||||
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(),
|
||||
false /* toIsInclusive */);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,17 +82,39 @@ public class GPSFixStoreImpl implements GPSFixStore {
|
||||
public void storeFix(DeviceIdentifier device, GPSFix fix) {
|
||||
sensorFixStore.storeFix(device, fix);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark,
|
||||
TimePoint start, TimePoint end) throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track,
|
||||
DeviceMapping<Competitor> mapping, TimePoint start, TimePoint end, BooleanSupplier isPreemptiveStopped,
|
||||
Consumer<Double> progressReporter)
|
||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
|
||||
// loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true
|
||||
// /*inclusive*/);
|
||||
final TimePoint from = Util.getLatestOfTimePoints(start, mapping.getTimeRange().from());
|
||||
final TimePoint to = Util.getEarliestOfTimePoints(end, mapping.getTimeRange().to());
|
||||
loadTrack(track, mapping.getDevice(), from, to, true /* inclusive */, isPreemptiveStopped, progressReporter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, DeviceMapping<Mark> mapping, TimePoint start,
|
||||
TimePoint end, BooleanSupplier isPreemptiveStopped, Consumer<Double> progressReport)
|
||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
final TimePoint from = Util.getLatestOfTimePoints(start, mapping.getTimeRange().from());
|
||||
final TimePoint to = Util.getEarliestOfTimePoints(end, mapping.getTimeRange().to());
|
||||
loadTrack(track, mapping.getDevice(), from, to, true /* inclusive */, isPreemptiveStopped, progressReport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark, TimePoint start,
|
||||
TimePoint end) throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
List<DeviceMappingWithRegattaLogEvent<Mark>> mappings = new RegattaLogDeviceMarkMappingFinder(log).analyze()
|
||||
.get(mark);
|
||||
if (mappings != null) {
|
||||
for (DeviceMapping<Mark> mapping : mappings) {
|
||||
final TimePoint from = Util.getLatestOfTimePoints(start, mapping.getTimeRange().from());
|
||||
final TimePoint to = Util.getEarliestOfTimePoints(end, mapping.getTimeRange().to());
|
||||
loadTrack(track, mapping.getDevice(), from, to, false /*toIsInclusive*/);
|
||||
loadTrack(track, mapping.getDevice(), from, to, false /* toIsInclusive */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+19
@@ -1,5 +1,8 @@
|
||||
package com.sap.sailing.domain.racelog.tracking;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
@@ -7,6 +10,7 @@ import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
@@ -32,4 +36,19 @@ public enum EmptyGPSFixStore implements GPSFixStore {
|
||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark,
|
||||
TimePoint start, TimePoint end) throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track,
|
||||
DeviceMapping<Competitor> mapping, TimePoint start, TimePoint end, BooleanSupplier isPreemptiveStopped,
|
||||
Consumer<Double> progressReporter)
|
||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, DeviceMapping<Mark> mapping, TimePoint start,
|
||||
TimePoint end, BooleanSupplier isPreemptiveStopped, Consumer<Double> progressReporter)
|
||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
|
||||
}
|
||||
}
|
||||
+8
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.racelog.tracking;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
@@ -41,6 +42,13 @@ public enum EmptySensorFixStore implements SensorFixStore {
|
||||
TransformationException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <FixT extends Timed> void loadFixes(Consumer<FixT> consumer, DeviceIdentifier deviceIdentifier,
|
||||
TimePoint start, TimePoint end, boolean inclusive, BooleanSupplier isPreemptiveStopped,
|
||||
Consumer<Double> progressReporter)
|
||||
throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <FixT extends Timed> void storeFix(DeviceIdentifier device, FixT fix) {
|
||||
}
|
||||
|
||||
+16
@@ -1,5 +1,8 @@
|
||||
package com.sap.sailing.domain.racelog.tracking;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||
@@ -9,6 +12,7 @@ import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
@@ -41,5 +45,17 @@ public interface GPSFixStore {
|
||||
void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark, TimePoint start,
|
||||
TimePoint end) throws TransformationException, NoCorrespondingServiceRegisteredException;
|
||||
|
||||
void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track, DeviceMapping<Competitor> mapping,
|
||||
TimePoint start, TimePoint end, BooleanSupplier isPreemptiveStopped, Consumer<Double> progressReporter)
|
||||
throws TransformationException, NoCorrespondingServiceRegisteredException;
|
||||
|
||||
/**
|
||||
* Load all fixes that correspond to the {@code mapping}.
|
||||
*/
|
||||
void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, DeviceMapping<Mark> mapping, TimePoint start,
|
||||
TimePoint end, BooleanSupplier isPreemptiveStopped, Consumer<Double> progressReport)
|
||||
throws TransformationException,
|
||||
NoCorrespondingServiceRegisteredException;
|
||||
|
||||
void storeFix(DeviceIdentifier device, GPSFix fix) throws TransformationException, NoCorrespondingServiceRegisteredException;
|
||||
}
|
||||
+17
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.racelog.tracking;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
@@ -37,6 +38,22 @@ public interface SensorFixStore {
|
||||
<FixT extends Timed> void loadFixes(Consumer<FixT> consumer, DeviceIdentifier deviceIdentifier, TimePoint start, TimePoint end,
|
||||
boolean toIsInclusive) throws NoCorrespondingServiceRegisteredException,
|
||||
TransformationException;
|
||||
|
||||
/**
|
||||
* Loads fixes for a device in a given time range.
|
||||
*
|
||||
* @param consumer will be called for each loaded fix. Must not be <code>null</code>.
|
||||
* @param deviceIdentifier the device to load the fixes for. Must not be <code>null</code>.
|
||||
* @param start the lower bound of the time range to load. If <code>null</code>, fixes are loaded from {@link TimePoint#BeginningOfTime}.
|
||||
* @param end the upper bound of the time range to load. If <code>null</code>, fixes are loaded to {@link TimePoint#EndOfTime}.
|
||||
* @param inclusive true if fixes exactly at the bounds of the time range should be loaded, false otherwise.
|
||||
* @param progressReporter not allowed to be null, can be used to get reports of the approximate loading progress
|
||||
*/
|
||||
<FixT extends Timed> void loadFixes(Consumer<FixT> consumer, DeviceIdentifier deviceIdentifier, TimePoint start,
|
||||
TimePoint end, boolean inclusive, BooleanSupplier isPreemptiveStopped,
|
||||
Consumer<Double> progressReporter)
|
||||
throws NoCorrespondingServiceRegisteredException,
|
||||
TransformationException;
|
||||
|
||||
/**
|
||||
* Saves a single fix for the given device and informs all registered listeners about the new fix.
|
||||
|
||||
+2
-2
@@ -58,12 +58,12 @@ public class AutoplayPerspectiveLifecycle extends AbstractPerspectiveLifecycle<A
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AutoplayPerspectiveOwnSettings extractOwnGlobalSettings(AutoplayPerspectiveOwnSettings settings) {
|
||||
protected AutoplayPerspectiveOwnSettings extractOwnUserSettings(AutoplayPerspectiveOwnSettings settings) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AutoplayPerspectiveOwnSettings extractOwnContextSettings(AutoplayPerspectiveOwnSettings settings) {
|
||||
protected AutoplayPerspectiveOwnSettings extractOwnDocumentSettings(AutoplayPerspectiveOwnSettings settings) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ import com.sap.sailing.gwt.common.client.FullscreenUtil;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.gwt.client.shared.components.AbstractCompositeComponent;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
public class SAPHeaderComponent extends AbstractCompositeComponent<SAPHeaderComponentSettings> {
|
||||
@@ -56,7 +56,7 @@ public class SAPHeaderComponent extends AbstractCompositeComponent<SAPHeaderComp
|
||||
}
|
||||
|
||||
@Override
|
||||
public SAPHeaderComponentSettingsDialogComponent getSettingsDialogComponent() {
|
||||
public SAPHeaderComponentSettingsDialogComponent getSettingsDialogComponent(SAPHeaderComponentSettings settings) {
|
||||
return componentLifecycle.getSettingsDialogComponent(settings);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -40,12 +40,12 @@ public class SAPHeaderComponentLifecycle implements ComponentLifecycle<SAPHeader
|
||||
}
|
||||
|
||||
@Override
|
||||
public SAPHeaderComponentSettings extractGlobalSettings(SAPHeaderComponentSettings settings) {
|
||||
public SAPHeaderComponentSettings extractUserSettings(SAPHeaderComponentSettings settings) {
|
||||
return createDefaultSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SAPHeaderComponentSettings extractContextSpecificSettings(SAPHeaderComponentSettings settings) {
|
||||
public SAPHeaderComponentSettings extractDocumentSettings(SAPHeaderComponentSettings settings) {
|
||||
return createDefaultSettings();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,9 +29,9 @@ import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
|
||||
import com.sap.sse.gwt.client.shared.perspective.AbstractPerspectiveComposite;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
|
||||
|
||||
/**
|
||||
* A perspective managing a header with a single leaderboard filling the rest of the screen.
|
||||
|
||||
+2
-2
@@ -64,13 +64,13 @@ public class LeaderboardWithHeaderPerspectiveLifecycle extends AbstractPerspecti
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LeaderboardWithHeaderPerspectiveSettings extractOwnGlobalSettings(
|
||||
protected LeaderboardWithHeaderPerspectiveSettings extractOwnUserSettings(
|
||||
LeaderboardWithHeaderPerspectiveSettings settings) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LeaderboardWithHeaderPerspectiveSettings extractOwnContextSettings(
|
||||
protected LeaderboardWithHeaderPerspectiveSettings extractOwnDocumentSettings(
|
||||
LeaderboardWithHeaderPerspectiveSettings settings) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
+4
-2
@@ -3,7 +3,6 @@ package com.sap.sailing.gwt.common.theme.component.celltable;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.resources.client.ClientBundle;
|
||||
import com.google.gwt.user.cellview.client.CellTable;
|
||||
import com.google.gwt.user.cellview.client.CellTable.Style;
|
||||
|
||||
/**
|
||||
* {@link ClientBundle} with avoids the standard {@link CellTable} styles.
|
||||
@@ -11,9 +10,12 @@ import com.google.gwt.user.cellview.client.CellTable.Style;
|
||||
public interface CleanCellTableResources extends CellTable.Resources {
|
||||
|
||||
public static final CleanCellTableResources INSTANCE = GWT.create(CleanCellTableResources.class);
|
||||
|
||||
public interface CleanCellTableStyle extends CellTable.Style {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Source("CleanCellTable.css")
|
||||
public Style cellTableStyle();
|
||||
public CleanCellTableStyle cellTableStyle();
|
||||
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
.cellTableWidget {
|
||||
font-size: 1rem;
|
||||
border: 1px solid #dedede;
|
||||
border-radius: .333333333333333em;
|
||||
border-spacing: 0;
|
||||
border-collapse: separate;
|
||||
overflow: hidden;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
.cellTableWidget>thead>tr {
|
||||
color: #666;
|
||||
background-color: #dfdfdf;
|
||||
border-bottom: 1px solid #dedede;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
border-radius: .333333333333333em 0 0 .333333333333333em;
|
||||
}
|
||||
|
||||
.cellTableWidget>thead>tr>th {
|
||||
padding: .666666666666667em .666666666666667em .666666666666667em 1.333333333333333em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
.cellTableCell {
|
||||
text-align: left;
|
||||
vertical-align: baseline;
|
||||
border-bottom: 1px solid #dfdfdf;
|
||||
white-space: nowrap;
|
||||
padding: 1.4em .666666666666667em .733333333333333em 1.333333333333333em;
|
||||
}
|
||||
|
||||
.buttonCell {
|
||||
text-align: right;
|
||||
vertical-align: middle;
|
||||
padding-left: 0;
|
||||
padding-right: .666666666666667em;
|
||||
padding-top: .666666666666667em;
|
||||
}
|
||||
|
||||
.buttonCell>div>button {
|
||||
font-size: 1rem;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
background: #008fcc;
|
||||
display: -webkit-inline-box;
|
||||
display: -webkit-inline-flex;
|
||||
display: -moz-inline-box;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
-webkit-box-flex: 0;
|
||||
-webkit-flex: 0;
|
||||
-moz-box-flex: 0;
|
||||
-ms-flex: 0;
|
||||
flex: 0;
|
||||
text-align: center;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
-moz-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
height: 2.666666666666667em;
|
||||
padding: 0 1em 0 1em;
|
||||
border-radius: .2em;
|
||||
position: relative;
|
||||
border: none;
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.sap.sailing.gwt.common.theme.component.celltable;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.resources.client.ClientBundle;
|
||||
import com.google.gwt.user.cellview.client.CellTable;
|
||||
|
||||
/**
|
||||
* {@link ClientBundle} with avoids the standard {@link CellTable} styles.
|
||||
*/
|
||||
public interface DesignedCellTableResources extends CellTable.Resources {
|
||||
|
||||
public static final DesignedCellTableResources INSTANCE = GWT.create(DesignedCellTableResources.class);
|
||||
|
||||
public interface DesignedCellTableStyle extends CellTable.Style {
|
||||
String buttonCell();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Source({"CleanCellTable.css", "DesignedCellTable.css"})
|
||||
public DesignedCellTableStyle cellTableStyle();
|
||||
|
||||
}
|
||||
+8
-6
@@ -30,10 +30,6 @@ public class SearchResultItem extends AbstractSearchResultItem {
|
||||
this.navigator = navigator;
|
||||
this.item = item;
|
||||
init(uiBinder.createAndBindUi(this), item);
|
||||
SearchResultEventInfoDTO event = item.getEvents().iterator().next();
|
||||
String eventId = String.valueOf(event.getId()), leaderboardName = item.getLeaderboardName(), baseUrl = item.getBaseUrl();
|
||||
PlaceNavigation<?> regattaNavigation = navigator.getRegattaNavigation(eventId, leaderboardName, baseUrl, item.isOnRemoteServer());
|
||||
regattaNavigation.configureAnchorElement(resultTitleUi);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,10 +37,16 @@ public class SearchResultItem extends AbstractSearchResultItem {
|
||||
return resultTitleUi;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureRegattaNavigation(String eventId, String leaderboardName, String baseUrl, boolean isOnRemoteServer) {
|
||||
navigator.getRegattaNavigation(eventId, leaderboardName, baseUrl, item.isOnRemoteServer()).configureAnchorElement(resultTitleUi);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addEventInfo(SearchResultEventInfoDTO event) {
|
||||
eventInfoContainerUi.appendChild(new SearchResultItemEventInfo(
|
||||
navigator, event, item.getBaseUrl(), item.isOnRemoteServer()).getElement());
|
||||
String eventId = String.valueOf(event.getId());
|
||||
PlaceNavigation<?> eventNavigation = navigator.getEventNavigation(eventId, item.getBaseUrl(), item.isOnRemoteServer());
|
||||
eventInfoContainerUi.appendChild(new SearchResultItemEventInfo(event, eventNavigation).getElement());
|
||||
}
|
||||
|
||||
}
|
||||
+7
-7
@@ -7,7 +7,6 @@ import com.google.gwt.dom.client.SpanElement;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.sap.sailing.gwt.home.communication.search.SearchResultEventInfoDTO;
|
||||
import com.sap.sailing.gwt.home.desktop.app.DesktopPlacesNavigator;
|
||||
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
|
||||
import com.sap.sailing.gwt.home.shared.partials.searchresult.AbstractSearchResultItemEventInfo;
|
||||
|
||||
@@ -22,12 +21,8 @@ public class SearchResultItemEventInfo extends AbstractSearchResultItemEventInfo
|
||||
@UiField SpanElement eventVenueUi;
|
||||
@UiField SpanElement eventDateUi;
|
||||
|
||||
SearchResultItemEventInfo(DesktopPlacesNavigator navigator, SearchResultEventInfoDTO event, String baseUrl,
|
||||
boolean isOnRemoteServer) {
|
||||
init(uiBinder.createAndBindUi(this), event);
|
||||
String eventId = String.valueOf(event.getId());
|
||||
PlaceNavigation<?> eventNavigation = navigator.getEventNavigation(eventId, baseUrl, isOnRemoteServer);
|
||||
eventNavigation.configureAnchorElement(eventNameUi);
|
||||
SearchResultItemEventInfo(SearchResultEventInfoDTO event, PlaceNavigation<?> navigation) {
|
||||
init(uiBinder.createAndBindUi(this), event, navigation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -44,4 +39,9 @@ public class SearchResultItemEventInfo extends AbstractSearchResultItemEventInfo
|
||||
protected Element getEventDateUi() {
|
||||
return eventDateUi;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AnchorElement getNavigationUi() {
|
||||
return eventNameUi;
|
||||
}
|
||||
}
|
||||
+9
-18
@@ -9,7 +9,6 @@ import com.google.gwt.place.shared.Place;
|
||||
import com.google.gwt.safehtml.shared.SafeUri;
|
||||
import com.google.gwt.safehtml.shared.UriUtils;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.gwt.common.client.controls.tabbar.TabView;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchSystem;
|
||||
@@ -149,28 +148,20 @@ public abstract class AbstractEventActivity<PLACE extends AbstractEventPlace> ex
|
||||
|
||||
@Override
|
||||
public String getRaceViewerURL(SimpleRaceMetadataDTO raceMetadata, String mode) {
|
||||
RaceIdentifier raceIdentifier = raceMetadata.getRegattaAndRaceIdentifier();
|
||||
RaceboardContextDefinition raceboardContext = new RaceboardContextDefinition(raceIdentifier.getRegattaName(),
|
||||
raceIdentifier.getRaceName(), raceMetadata.getLeaderboardName(), raceMetadata.getLeaderboardGroupName(),
|
||||
null, mode);
|
||||
RaceBoardPerspectiveOwnSettings perspectiveOwnSettings = RaceBoardPerspectiveOwnSettings
|
||||
.createDefaultWithCanReplayDuringLiveRaces(true);
|
||||
;
|
||||
HashMap<String, Settings> innerSettings = new HashMap<>();
|
||||
innerSettings.put(RaceMapLifecycle.ID, RaceMapSettings.getDefaultWithShowMapControls(true));
|
||||
PerspectiveCompositeSettings<RaceBoardPerspectiveOwnSettings> settings = new PerspectiveCompositeSettings<>(
|
||||
perspectiveOwnSettings, innerSettings);
|
||||
|
||||
return EntryPointWithSettingsLinkFactory.createRaceBoardLink(raceboardContext, settings);
|
||||
return getRaceViewerURL(raceMetadata.getLeaderboardName(), raceMetadata.getLeaderboardGroupName(),
|
||||
raceMetadata.getRegattaAndRaceIdentifier(), mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRaceViewerURL(String leaderboardName, String leaderboardGroupName, RegattaAndRaceIdentifier raceIdentifier) {
|
||||
return getRaceViewerURL(leaderboardName, leaderboardGroupName, raceIdentifier, null);
|
||||
}
|
||||
|
||||
private String getRaceViewerURL(String leaderboardName, String leaderboardGroupName, RegattaAndRaceIdentifier raceIdentifier, String mode) {
|
||||
RaceboardContextDefinition raceboardContext = new RaceboardContextDefinition(raceIdentifier.getRegattaName(),
|
||||
raceIdentifier.getRaceName(), leaderboardName, leaderboardGroupName, null, null);
|
||||
RaceBoardPerspectiveOwnSettings perspectiveOwnSettings = RaceBoardPerspectiveOwnSettings
|
||||
.createDefaultWithCanReplayDuringLiveRaces(true);
|
||||
;
|
||||
raceIdentifier.getRaceName(), leaderboardName, leaderboardGroupName, UUID.fromString(ctx.getEventId()), mode);
|
||||
RaceBoardPerspectiveOwnSettings perspectiveOwnSettings = new RaceBoardPerspectiveOwnSettings();
|
||||
|
||||
HashMap<String, Settings> innerSettings = new HashMap<>();
|
||||
innerSettings.put(RaceMapLifecycle.ID, RaceMapSettings.getDefaultWithShowMapControls(true));
|
||||
PerspectiveCompositeSettings<RaceBoardPerspectiveOwnSettings> settings = new PerspectiveCompositeSettings<>(
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialog;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
|
||||
/**
|
||||
* A class managing analytical data on the regatta level (like leaderboard, regatta rank, etc.)
|
||||
|
||||
+10
-14
@@ -7,20 +7,18 @@ import com.sap.sailing.gwt.home.desktop.places.Consumer;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardPanelLifecycle;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardUrlSettings;
|
||||
import com.sap.sailing.gwt.settings.client.utils.StorageDefinitionIdFactory;
|
||||
import com.sap.sailing.gwt.settings.client.utils.StoredSettingsLocationFactory;
|
||||
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sse.gwt.client.mutationobserver.ElementSizeMutationObserver;
|
||||
import com.sap.sse.gwt.client.mutationobserver.ElementSizeMutationObserver.DomMutationCallback;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.perspective.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.perspective.SettingsStorageManager;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.settings.PlaceBasedUserSettingsStorageManager;
|
||||
import com.sap.sse.security.ui.settings.StorageDefinitionId;
|
||||
import com.sap.sse.security.ui.settings.PlaceBasedComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
|
||||
|
||||
/**
|
||||
* An abstract regatta tabView with some shared functions between the leaderboard tab and competitors chart tab
|
||||
@@ -41,7 +39,7 @@ public abstract class SharedLeaderboardRegattaTabView<T extends AbstractEventReg
|
||||
|
||||
final ComponentContext<LeaderboardSettings> componentContext = createLeaderboardComponentContext(leaderboardName, userService,
|
||||
placeToken);
|
||||
componentContext.initInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
|
||||
componentContext.getInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
|
||||
@Override
|
||||
public void onSuccess(LeaderboardSettings leaderboardSettings) {
|
||||
final LeaderboardPanel leaderboardPanel = regattaAnalyticsManager.createLeaderboardPanel(null, componentContext, //
|
||||
@@ -82,13 +80,11 @@ public abstract class SharedLeaderboardRegattaTabView<T extends AbstractEventReg
|
||||
|
||||
protected ComponentContext<LeaderboardSettings> createLeaderboardComponentContext(String leaderboardName, UserService userService,
|
||||
String placeToken) {
|
||||
final LeaderboardPanelLifecycle lifeCycle = new LeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
|
||||
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForEventRegattaLeaderboard(leaderboardName);
|
||||
final SettingsStorageManager<LeaderboardSettings> settingsStorageManager = new PlaceBasedUserSettingsStorageManager<>(
|
||||
userService, storageDefinitionId, placeToken);
|
||||
final LeaderboardPanelLifecycle lifecycle = new LeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
|
||||
final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory.createStoredSettingsLocatorForEventRegattaLeaderboard(leaderboardName);
|
||||
|
||||
final ComponentContext<LeaderboardSettings> componentContext = new ComponentContextWithSettingsStorage<>(
|
||||
lifeCycle, settingsStorageManager);
|
||||
final ComponentContext<LeaderboardSettings> componentContext = new PlaceBasedComponentContextWithSettingsStorage<>(
|
||||
lifecycle, userService, storageDefinition, placeToken);
|
||||
return componentContext;
|
||||
}
|
||||
}
|
||||
+6
-8
@@ -33,7 +33,7 @@ import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings;
|
||||
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateProvider;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sse.gwt.client.shared.perspective.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.dispatch.shared.commands.CollectionResult;
|
||||
|
||||
/**
|
||||
@@ -88,8 +88,7 @@ public class RegattaLeaderboardTabView extends SharedLeaderboardRegattaTabView<R
|
||||
if (regattaId != null && !regattaId.isEmpty()) {
|
||||
String leaderboardName = regattaId;
|
||||
RegattaAnalyticsDataManager regattaAnalyticsManager = currentPresenter.getCtx().getRegattaAnalyticsManager();
|
||||
LeaderboardPanel leaderboardPanel = regattaAnalyticsManager.getLeaderboardPanel();
|
||||
|
||||
LeaderboardPanel leaderboardPanel = regattaAnalyticsManager.getLeaderboardPanel();
|
||||
final Consumer<LeaderboardPanel> leaderboardConsumer = new Consumer<LeaderboardPanel>() {
|
||||
@Override
|
||||
public void consume(LeaderboardPanel leaderboardPanel) {
|
||||
@@ -113,18 +112,18 @@ public class RegattaLeaderboardTabView extends SharedLeaderboardRegattaTabView<R
|
||||
}
|
||||
regattaAnalyticsManager.hideCompetitorChart();
|
||||
contentArea.setWidget(RegattaLeaderboardTabView.this);
|
||||
if (leaderboardPanel.getLeaderboard() != null) {
|
||||
if(leaderboardPanel.getLeaderboard() != null) {
|
||||
leaderboard.updatedLeaderboard(leaderboardPanel.getLeaderboard());
|
||||
}
|
||||
}
|
||||
};
|
||||
if (leaderboardPanel == null) {
|
||||
if(leaderboardPanel == null) {
|
||||
createSharedLeaderboardPanel(leaderboardName, regattaAnalyticsManager,
|
||||
currentPresenter.getUserService(), /* FIXME placeToken */ null, leaderboardConsumer);
|
||||
} else if ( /* FIXME placeToken not empty */ false) {
|
||||
} else if( /*FIXME placeToken not empty */ false) {
|
||||
createLeaderboardComponentContext(leaderboardName, currentPresenter.getUserService(),
|
||||
/* FIXME placeToken */ null)
|
||||
.initInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
|
||||
.getInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
|
||||
@Override
|
||||
public void onSuccess(LeaderboardSettings settings) {
|
||||
leaderboardPanel.updateSettings(settings);
|
||||
@@ -134,7 +133,6 @@ public class RegattaLeaderboardTabView extends SharedLeaderboardRegattaTabView<R
|
||||
} else {
|
||||
leaderboardConsumer.consume(leaderboardPanel);
|
||||
}
|
||||
|
||||
} else {
|
||||
contentArea.setWidget(new Label("No leaderboard specified, cannot proceed to leaderboardpage"));
|
||||
new com.google.gwt.user.client.Timer() {
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialog;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
|
||||
/**
|
||||
* A viewer for an overall series leaderboard. Additionally the viewer can render a chart for the series leaderboard and
|
||||
|
||||
+10
-14
@@ -7,18 +7,16 @@ import com.sap.sailing.gwt.home.desktop.places.Consumer;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardPanelLifecycle;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardUrlSettings;
|
||||
import com.sap.sailing.gwt.settings.client.utils.StorageDefinitionIdFactory;
|
||||
import com.sap.sailing.gwt.settings.client.utils.StoredSettingsLocationFactory;
|
||||
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.perspective.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.perspective.SettingsStorageManager;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.settings.PlaceBasedUserSettingsStorageManager;
|
||||
import com.sap.sse.security.ui.settings.StorageDefinitionId;
|
||||
import com.sap.sse.security.ui.settings.PlaceBasedComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
|
||||
|
||||
/**
|
||||
* An abstract series tabView with some shared functions between the overall leaderboard tab and competitors chart tab
|
||||
@@ -39,7 +37,7 @@ public abstract class SharedLeaderboardEventSeriesTabView<T extends AbstractSeri
|
||||
|
||||
final ComponentContext<LeaderboardSettings> componentContext = createLeaderboardComponentContext(leaderboardName, userService,
|
||||
placeToken);
|
||||
componentContext.initInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
|
||||
componentContext.getInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
|
||||
@Override
|
||||
public void onSuccess(LeaderboardSettings leaderboardSettings) {
|
||||
LeaderboardPanel leaderboardPanel = eventSeriesAnalyticsManager.createOverallLeaderboardPanel(null,
|
||||
@@ -64,13 +62,11 @@ public abstract class SharedLeaderboardEventSeriesTabView<T extends AbstractSeri
|
||||
|
||||
protected ComponentContext<LeaderboardSettings> createLeaderboardComponentContext(String leaderboardName, UserService userService,
|
||||
String placeToken) {
|
||||
final LeaderboardPanelLifecycle lifeCycle = new LeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
|
||||
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForSeriesOverallLeaderboard(leaderboardName);
|
||||
final SettingsStorageManager<LeaderboardSettings> settingsStorageManager = new PlaceBasedUserSettingsStorageManager<>(
|
||||
userService, storageDefinitionId, placeToken);
|
||||
final LeaderboardPanelLifecycle lifecycle = new LeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
|
||||
final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory.createStoredSettingsLocatorForSeriesOverallLeaderboard(leaderboardName);
|
||||
|
||||
final ComponentContext<LeaderboardSettings> componentContext = new ComponentContextWithSettingsStorage<>(
|
||||
lifeCycle, settingsStorageManager);
|
||||
final ComponentContext<LeaderboardSettings> componentContext = new PlaceBasedComponentContextWithSettingsStorage<>(
|
||||
lifecycle, userService, storageDefinition, placeToken);
|
||||
return componentContext;
|
||||
}
|
||||
}
|
||||
+9
-13
@@ -22,18 +22,16 @@ import com.sap.sailing.gwt.home.desktop.places.fakeseries.SeriesView;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardUrlSettings;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.MultiLeaderboardPanelLifecycle;
|
||||
import com.sap.sailing.gwt.settings.client.utils.StorageDefinitionIdFactory;
|
||||
import com.sap.sailing.gwt.settings.client.utils.StoredSettingsLocationFactory;
|
||||
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.MultiLeaderboardProxyPanel;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.perspective.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.perspective.SettingsStorageManager;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.settings.PlaceBasedUserSettingsStorageManager;
|
||||
import com.sap.sse.security.ui.settings.StorageDefinitionId;
|
||||
import com.sap.sse.security.ui.settings.PlaceBasedComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
|
||||
|
||||
public class EventSeriesLeaderboardsTabView extends Composite implements SeriesTabView<EventSeriesLeaderboardsPlace>,
|
||||
LeaderboardUpdateListener {
|
||||
@@ -77,7 +75,7 @@ public class EventSeriesLeaderboardsTabView extends Composite implements SeriesT
|
||||
final boolean autoExpandLastRaceColumn = GwtHttpRequestUtils.getBooleanParameter(LeaderboardUrlSettings.PARAM_AUTO_EXPAND_LAST_RACE_COLUMN, false);
|
||||
|
||||
final ComponentContext<LeaderboardSettings> componentContext = createLeaderboardComponentContext(leaderboardName, currentPresenter.getUserService(), /*FIXME placeToken */ null);
|
||||
componentContext.initInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
|
||||
componentContext.getInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
|
||||
@Override
|
||||
public void onSuccess(LeaderboardSettings settings) {
|
||||
MultiLeaderboardProxyPanel leaderboardPanel = regattaAnalyticsManager.createMultiLeaderboardPanel(null, componentContext,
|
||||
@@ -129,12 +127,10 @@ public class EventSeriesLeaderboardsTabView extends Composite implements SeriesT
|
||||
private ComponentContext<LeaderboardSettings> createLeaderboardComponentContext(String leaderboardName, UserService userService,
|
||||
String placeToken) {
|
||||
final MultiLeaderboardPanelLifecycle lifecycle = new MultiLeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
|
||||
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForSeriesRegattaLeaderboards(leaderboardName);
|
||||
final SettingsStorageManager<LeaderboardSettings> settingsStorageManager = new PlaceBasedUserSettingsStorageManager<>(
|
||||
userService, storageDefinitionId, placeToken);
|
||||
final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory.createStoredSettingsLocatorForSeriesRegattaLeaderboards(leaderboardName);
|
||||
|
||||
final ComponentContext<LeaderboardSettings> componentContext = new ComponentContextWithSettingsStorage<>(
|
||||
lifecycle, settingsStorageManager);
|
||||
final ComponentContext<LeaderboardSettings> componentContext = new PlaceBasedComponentContextWithSettingsStorage<>(
|
||||
lifecycle, userService, storageDefinition, placeToken);
|
||||
return componentContext;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import com.sap.sailing.gwt.home.desktop.places.fakeseries.SeriesView;
|
||||
import com.sap.sailing.gwt.home.desktop.places.fakeseries.SharedLeaderboardEventSeriesTabView;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sse.gwt.client.shared.perspective.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
|
||||
|
||||
/**
|
||||
* Created by pgtaboada on 25.11.14.
|
||||
@@ -78,7 +78,7 @@ public class EventSeriesOverallLeaderboardTabView extends SharedLeaderboardEvent
|
||||
if(leaderboardPanel == null) {
|
||||
createSharedLeaderboardPanel(leaderboardName, eventSeriesAnalyticsManager, currentPresenter.getUserService(), /*FIXME placeToken */ null, leaderboardConsumer);
|
||||
} else if( /*FIXME placeToken not empty */ false) {
|
||||
createLeaderboardComponentContext(leaderboardName, currentPresenter.getUserService(), /*FIXME placeToken */ null).initInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
|
||||
createLeaderboardComponentContext(leaderboardName, currentPresenter.getUserService(), /*FIXME placeToken */ null).getInitialSettings(new DefaultOnSettingsLoadedCallback<LeaderboardSettings>() {
|
||||
@Override
|
||||
public void onSuccess(LeaderboardSettings settings) {
|
||||
leaderboardPanel.updateSettings(settings);
|
||||
|
||||
+3
@@ -47,6 +47,9 @@
|
||||
<c:tabcontent title="{i18n.favoritesAndNotifications}">
|
||||
<s:preferencestab.UserProfilePreferencesTabView ui:field="preferencesTabUi" />
|
||||
</c:tabcontent>
|
||||
<c:tabcontent title="{i18n.settings}">
|
||||
<s:settingstab.UserProfileSettingsTabView ui:field="settingsTabUi" />
|
||||
</c:tabcontent>
|
||||
</c:TabPanel>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
+2
-1
@@ -4,6 +4,7 @@ import com.sap.sailing.gwt.home.shared.app.ClientFactoryWithDispatch;
|
||||
import com.sap.sailing.gwt.ui.client.SailingClientFactory;
|
||||
import com.sap.sailing.gwt.ui.client.refresh.ErrorAndBusyClientFactory;
|
||||
import com.sap.sse.security.ui.authentication.WithAuthenticationManager;
|
||||
import com.sap.sse.security.ui.authentication.WithUserService;
|
||||
|
||||
public interface UserProfileClientFactory extends ClientFactoryWithDispatch, SailingClientFactory, ErrorAndBusyClientFactory, WithAuthenticationManager {
|
||||
public interface UserProfileClientFactory extends ClientFactoryWithDispatch, SailingClientFactory, ErrorAndBusyClientFactory, WithAuthenticationManager, WithUserService {
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab;
|
||||
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.TextArea;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsEntry;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
|
||||
public class SettingsEntryDialog extends DataEntryDialog<UserSettingsEntry> {
|
||||
|
||||
private final FlowPanel fp;
|
||||
|
||||
public SettingsEntryDialog(UserSettingsEntry entry, Runnable deleteCallback) {
|
||||
super(StringMessages.INSTANCE.settings(), StringMessages.INSTANCE.settingsForId(entry.getKey()), StringMessages.INSTANCE.remove(), StringMessages.INSTANCE.cancel(), null, false, new DialogCallback<UserSettingsEntry>() {
|
||||
@Override
|
||||
public void ok(UserSettingsEntry editedObject) {
|
||||
deleteCallback.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
});
|
||||
|
||||
fp = new FlowPanel();
|
||||
|
||||
final String userProfileSettings = entry.getProfileData();
|
||||
boolean hasUserData = (userProfileSettings != null && !userProfileSettings.isEmpty());
|
||||
final String localSettings = entry.getLocalData();
|
||||
|
||||
TextArea textArea = createTextArea(hasUserData ? userProfileSettings : localSettings);
|
||||
textArea.setReadOnly(true);
|
||||
fp.add(textArea);
|
||||
}
|
||||
|
||||
public TextArea createTextArea(final String initialValue) {
|
||||
final TextArea textArea = super.createTextArea(initialValue);
|
||||
textArea.getElement().getStyle().setWidth(25, Unit.EM);
|
||||
textArea.getElement().getStyle().setHeight(15, Unit.EM);
|
||||
return textArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Widget getAdditionalWidget() {
|
||||
return fp;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UserSettingsEntry getResult() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab;
|
||||
|
||||
import com.sap.sailing.gwt.home.desktop.places.user.profile.UserProfileClientFactory;
|
||||
import com.sap.sailing.gwt.home.desktop.places.user.profile.UserProfileView;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsPresenter;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
|
||||
import com.sap.sse.security.ui.authentication.app.AuthenticationContext;
|
||||
|
||||
public class UserProfileSettingsPresenter implements UserProfileSettingsView.Presenter {
|
||||
|
||||
private final UserProfileSettingsView view;
|
||||
private final UserProfileView.Presenter userProfilePresenter;
|
||||
private final UserSettingsView.Presenter userSettingsPresenter;
|
||||
|
||||
public UserProfileSettingsPresenter(final UserProfileSettingsView view,
|
||||
final UserProfileView.Presenter userProfilePresenter) {
|
||||
this.view = view;
|
||||
this.userProfilePresenter = userProfilePresenter;
|
||||
this.userSettingsPresenter = new UserSettingsPresenter<UserProfileClientFactory>(
|
||||
userProfilePresenter.getClientFactory());
|
||||
view.setPresenter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserSettingsView.Presenter getUserSettingsPresenter() {
|
||||
return userSettingsPresenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthenticationContext(AuthenticationContext authenticationContext) {
|
||||
view.getDecorator().setAuthenticationContext(authenticationContext);
|
||||
if (authenticationContext.isLoggedIn()) {
|
||||
userSettingsPresenter.loadData();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doTriggerLoginForm() {
|
||||
userProfilePresenter.doTriggerLoginForm();
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab;
|
||||
|
||||
import com.google.gwt.user.client.ui.AcceptsOneWidget;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.sap.sailing.gwt.common.client.controls.tabbar.TabView;
|
||||
import com.sap.sailing.gwt.home.desktop.places.user.profile.UserProfileTabView;
|
||||
import com.sap.sailing.gwt.home.desktop.places.user.profile.UserProfileView;
|
||||
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserProfileSettingsPlace;
|
||||
import com.sap.sse.security.ui.authentication.app.AuthenticationContext;
|
||||
|
||||
public class UserProfileSettingsTabView extends Composite implements UserProfileTabView<UserProfileSettingsPlace> {
|
||||
|
||||
private UserProfileSettingsView.Presenter currentPresenter;
|
||||
private UserProfileSettingsView view;
|
||||
|
||||
@Override
|
||||
public Class<UserProfileSettingsPlace> getPlaceClassForActivation() {
|
||||
return UserProfileSettingsPlace.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TabView.State getState() {
|
||||
return ExperimentalFeatures.SHOW_MY_SETTINGS_IN_USER_PROFILE ? TabView.State.VISIBLE : TabView.State.INVISIBLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(UserProfileSettingsPlace myPlace, AcceptsOneWidget contentArea) {
|
||||
contentArea.setWidget(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthenticationContext(AuthenticationContext authenticationContext) {
|
||||
currentPresenter.setAuthenticationContext(authenticationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileSettingsPlace placeToFire() {
|
||||
return new UserProfileSettingsPlace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPresenter(UserProfileView.Presenter currentPresenter) {
|
||||
view = new UserProfileSettingsViewImpl();
|
||||
this.currentPresenter = new UserProfileSettingsPresenter(view, currentPresenter);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab;
|
||||
|
||||
import com.google.gwt.user.client.ui.IsWidget;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
|
||||
import com.sap.sse.security.ui.authentication.app.NeedsAuthenticationContext;
|
||||
import com.sap.sse.security.ui.authentication.decorator.NotLoggedInPresenter;
|
||||
|
||||
public interface UserProfileSettingsView extends IsWidget {
|
||||
|
||||
void setPresenter(Presenter presenter);
|
||||
|
||||
NeedsAuthenticationContext getDecorator();
|
||||
|
||||
public interface Presenter extends NotLoggedInPresenter, NeedsAuthenticationContext {
|
||||
UserSettingsView.Presenter getUserSettingsPresenter();
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.home.shared.usermanagement.decorator.AuthorizedContentDecoratorDesktop;
|
||||
import com.sap.sse.security.ui.authentication.app.NeedsAuthenticationContext;
|
||||
|
||||
public class UserProfileSettingsViewImpl extends Composite implements UserProfileSettingsView {
|
||||
|
||||
interface MyBinder extends UiBinder<Widget, UserProfileSettingsViewImpl> {
|
||||
}
|
||||
|
||||
private static MyBinder uiBinder = GWT.create(MyBinder.class);
|
||||
|
||||
@UiField(provided = true) AuthorizedContentDecoratorDesktop decoratorUi;
|
||||
@UiField(provided = true) UserSettings userSettingsUi;
|
||||
|
||||
@Override
|
||||
public void setPresenter(Presenter presenter) {
|
||||
decoratorUi = new AuthorizedContentDecoratorDesktop(presenter);
|
||||
userSettingsUi = new UserSettings(presenter.getUserSettingsPresenter());
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NeedsAuthenticationContext getDecorator() {
|
||||
return decoratorUi;
|
||||
}
|
||||
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'
|
||||
xmlns:um="urn:import:com.sap.sailing.gwt.home.shared.usermanagement.decorator"
|
||||
xmlns:us="urn:import:com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<um:AuthorizedContentDecoratorDesktop ui:field="decoratorUi">
|
||||
<um:content>
|
||||
<us:UserSettings ui:field="userSettingsUi"/>
|
||||
</um:content>
|
||||
</um:AuthorizedContentDecoratorDesktop>
|
||||
</ui:UiBinder>
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
package com.sap.sailing.gwt.home.desktop.places.user.profile.settingstab;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.cell.client.ButtonCell;
|
||||
import com.google.gwt.cell.client.FieldUpdater;
|
||||
import com.google.gwt.cell.client.TextCell;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.dom.client.Style.Display;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.user.cellview.client.Column;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.impl.InvertibleComparatorAdapter;
|
||||
import com.sap.sailing.gwt.common.theme.component.celltable.DesignedCellTableResources;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsEntry;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.SortedCellTable;
|
||||
import com.sap.sse.common.Util.Function;
|
||||
import com.sap.sse.common.util.NaturalComparator;
|
||||
|
||||
/**
|
||||
* Implementation of {@link UserSettingsView} where users can change their preferred selections and notifications.
|
||||
*/
|
||||
public class UserSettings extends Composite implements UserSettingsView {
|
||||
|
||||
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
|
||||
|
||||
interface MyUiBinder extends UiBinder<Widget, UserSettings> {
|
||||
}
|
||||
|
||||
@UiField
|
||||
DivElement notificationsTextUi;
|
||||
@UiField
|
||||
DivElement tableWrapper;
|
||||
@UiField(provided = true)
|
||||
final SortedCellTable<UserSettingsEntry> userSettingsTable = new SortedCellTable<>(0,
|
||||
DesignedCellTableResources.INSTANCE);
|
||||
private final Column<UserSettingsEntry, String> keyColumn = new Column<UserSettingsEntry, String>(new TextCell()) {
|
||||
@Override
|
||||
public String getValue(UserSettingsEntry entry) {
|
||||
return entry.getKeyWithoutContext();
|
||||
}
|
||||
};
|
||||
private final Column<UserSettingsEntry, String> documentSettingsIdColumn = new Column<UserSettingsEntry, String>(
|
||||
new TextCell()) {
|
||||
@Override
|
||||
public String getValue(UserSettingsEntry entry) {
|
||||
return entry.getDocumentSettingsId();
|
||||
}
|
||||
};
|
||||
private final Column<UserSettingsEntry, String> deleteColumn = new Column<UserSettingsEntry, String>(
|
||||
new ButtonCell()) {
|
||||
@Override
|
||||
public String getValue(UserSettingsEntry entry) {
|
||||
return StringMessages.INSTANCE.remove();
|
||||
}
|
||||
};
|
||||
private final Column<UserSettingsEntry, String> showColumn = new Column<UserSettingsEntry, String>(
|
||||
new ButtonCell()) {
|
||||
@Override
|
||||
public String getValue(UserSettingsEntry entry) {
|
||||
return StringMessages.INSTANCE.show();
|
||||
}
|
||||
};
|
||||
|
||||
public UserSettings(UserSettingsView.Presenter presenter) {
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
|
||||
deleteColumn.setFieldUpdater(new FieldUpdater<UserSettingsEntry, String>() {
|
||||
@Override
|
||||
public void update(int index, UserSettingsEntry object, String value) {
|
||||
presenter.remove(object);
|
||||
}
|
||||
});
|
||||
|
||||
showColumn.setFieldUpdater(new FieldUpdater<UserSettingsEntry, String>() {
|
||||
@Override
|
||||
public void update(int index, UserSettingsEntry object, String value) {
|
||||
new SettingsEntryDialog(object, () -> presenter.remove(object)).show();
|
||||
}
|
||||
});
|
||||
|
||||
userSettingsTable.addColumn(keyColumn, StringMessages.INSTANCE.settingsId(),
|
||||
new StringComparator(UserSettingsEntry::getKeyWithoutContext), true);
|
||||
userSettingsTable.addColumn(documentSettingsIdColumn, StringMessages.INSTANCE.documentSettingsId(),
|
||||
new StringComparator(UserSettingsEntry::getDocumentSettingsId), true);
|
||||
showColumn.setCellStyleNames(DesignedCellTableResources.INSTANCE.cellTableStyle().buttonCell());
|
||||
userSettingsTable.addColumn(showColumn, "", null, false);
|
||||
deleteColumn.setCellStyleNames(DesignedCellTableResources.INSTANCE.cellTableStyle().buttonCell());
|
||||
userSettingsTable.addColumn(deleteColumn, "", null, false);
|
||||
|
||||
presenter.setView(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntries(List<UserSettingsEntry> entries) {
|
||||
if (entries.isEmpty()) {
|
||||
notificationsTextUi.setInnerText(StringMessages.INSTANCE.noDataFound());
|
||||
tableWrapper.getStyle().setDisplay(Display.NONE);
|
||||
} else {
|
||||
notificationsTextUi.setInnerText(StringMessages.INSTANCE.userProfileSettingsTabDescription());
|
||||
tableWrapper.getStyle().clearDisplay();
|
||||
userSettingsTable.setPageSize(entries.size());
|
||||
userSettingsTable.setList(entries);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class StringComparator extends InvertibleComparatorAdapter<UserSettingsEntry> {
|
||||
private final NaturalComparator innerComnparator = new NaturalComparator();
|
||||
private final Function<UserSettingsEntry, String> valueExtractor;
|
||||
|
||||
public StringComparator(Function<UserSettingsEntry, String> valueExtractor) {
|
||||
this.valueExtractor = valueExtractor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(UserSettingsEntry o1, UserSettingsEntry o2) {
|
||||
final String s1 = valueExtractor.get(o1);
|
||||
final String s2 = valueExtractor.get(o2);
|
||||
return innerComnparator.compare(s1, s2);
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
|
||||
xmlns:um="urn:import:com.sap.sailing.gwt.home.shared.usermanagement.decorator"
|
||||
xmlns:ms="urn:import:com.sap.sailing.gwt.home.shared.partials.multiselection" xmlns:c="urn:import:com.google.gwt.user.cellview.client">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:style>
|
||||
.table {
|
||||
width: 100%;
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel addStyleNames="{res.mediaCss.grid} {res.mainCss.spacermarginbottommediumsmall}">
|
||||
<div ui:field="notificationsTextUi" class="{res.mediaCss.column} {res.mediaCss.medium12} {res.mainCss.spacermargintopsmall} {res.mainCss.spacermarginbottomsmall}">
|
||||
<ui:text from="{i18n.userNotificationsOnlyIfMailAddressIsVerified}" />
|
||||
</div>
|
||||
<div ui:field="tableWrapper" class="{res.mediaCss.column} {res.mediaCss.small12} {res.mainCss.spacermargintopmediumsmall}">
|
||||
<c:CellTable ui:field="userSettingsTable" addStyleNames="{style.table}" />
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
+8
@@ -17,6 +17,14 @@
|
||||
for the competitor is cleared, the rank is set to 0 and the penalty is
|
||||
set to "NONE" then the competitor will remain in the list, and this
|
||||
"empty" result will be sent to the server, clearing any previous score
|
||||
</li>
|
||||
<li>When entering and publishing partial results, updates will only be applied
|
||||
for those competitors for which a result has been entered. In particular,
|
||||
when operating with multiple devices on the same course area and in case
|
||||
the devices haven't synchronized their states yet this will make sure that
|
||||
partial results entered on one device will not unnecessarily remove changes
|
||||
applied on another device.
|
||||
</li>
|
||||
corrections that were sent to the server. This is the only way to
|
||||
"reset" an erroneous score correction entirely from the app, because
|
||||
swiping and thus removing the competitor from the list would leave the
|
||||
|
||||
+30
-12
@@ -4,8 +4,24 @@
|
||||
<div id="mainContent">
|
||||
<h4 class="articleHeadline">What's New - SAP Sailing Analytics</h4>
|
||||
<div class="innerContent">
|
||||
|
||||
<h5 class="articleSubheadline">May 2017</h5>
|
||||
<h5 class="articleSubheadline">June 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>Several improvements were implemented regarding user settings:
|
||||
<ul>
|
||||
<li>Document settings are saved as delta to the user defaults instead of the delta to the system defaults.
|
||||
In cases where a setting has the value 'A' as system default and 'B' as user default, it's now possible to set it back to 'A' for a document.
|
||||
Settings stored before this change will continue to work with the old overwriting semantic.</li>
|
||||
<li>Collection based settings are now stored as delta to the default set of values. This means that removals and additions are being recorded instead of all values of a setting.
|
||||
Having value 'A' as system default and adding 'B' for the user default and 'C' for one document will select values 'A', 'B' and 'C' for the document.</li>
|
||||
<li>Settings dialogs now have a 'reset to default' button. When pressing this button, user defaults as well as the current document settings are being reset to the system defaults.
|
||||
In addition, the settings dialog is updated to show the system defaults. Those defaults will only take effect for the current view when pressing ok.</li>
|
||||
<li>User settings can now also be saved for <code>/gwt/RaceBoard.html</code>. Be aware that different modes have distinct settings so that defaults defined for one mode do not have any effect on other modes.</li>
|
||||
<li>On the user profile page you can now find a list of all stored settings. You can show the technical settings data and remove specific setting entries.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">May 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>It's now possible to show nationality flags in addition to competitor images in leaderboards if both are available.
|
||||
If no competitor images are available, this won't have any effect.
|
||||
@@ -15,20 +31,22 @@
|
||||
|
||||
<h5 class="articleSubheadline">April 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>Several pages are now enabled to save user settings. In settings dialogs there is a "Make default"
|
||||
button in the lower-left corner which is displayed when saving of settings is enabled. A click on that
|
||||
button causes the system to use the new settings as default values for the same page for any other context opened, e.g. another event.
|
||||
A click on OK button causes the system to store current settings for the current context and restore the same settings
|
||||
when the user opens the page with the same context again unless there are specific parameters given by the URL. Settings saved this way are
|
||||
stored locally in the browser's local storage and in the user profile if you are logged in.
|
||||
Some settings are only valid in a specific context (e.g. the selected race columns to show are stored for a specific leaderboard only).
|
||||
This feature required changing several URL parameters, which means that previously saved bookmarks might work slightly different.
|
||||
Affected pages:
|
||||
<li>Several pages are now enabled to save user settings with the following specifics:
|
||||
<ul>
|
||||
<li>In settings dialogs there is a "Make default" button in the lower-left corner which is displayed when saving of settings is enabled. A click on that
|
||||
button causes the system to use the new settings as default values for the same page. This is independent of a race, event or leaderboard to be shown.</li>
|
||||
<li>A click on OK button causes the system to store the settings as document settings. Document settings are only used for the same event, leaderboard or race.
|
||||
When the page is opened for e.g. the same race, the settings used last time are loaded.</li>
|
||||
<li>Settings saved this way are stored locally in the browser's local storage and in the user profile if you are logged in.</li>
|
||||
<li>Settings can be overwritten by URL parameters.</li>
|
||||
</ul>
|
||||
The following pages are now enabled to provide user settings:
|
||||
<ul>
|
||||
<li><code>/gwt/Leaderboard.html</code></li>
|
||||
<li><code>/gwt/RegattaOverview.html</code></li>
|
||||
<li>Leaderboards embedded in <code>/gwt/Home.html</code></li>
|
||||
</ul>
|
||||
</ul>
|
||||
This feature required changing several URL parameters, which means that previously saved bookmarks might work slightly different.
|
||||
</li>
|
||||
<li>The maneuver loss calculation for penalty circles has been improved. Previously, the end of the
|
||||
penalty circle maneuver was considered to be at the last of the two adjacent tack/gybe maneuvers.
|
||||
|
||||
+2
-1
@@ -29,6 +29,7 @@ import com.sap.sse.gwt.client.mvp.ErrorView;
|
||||
import com.sap.sse.security.ui.authentication.AuthenticationManager;
|
||||
import com.sap.sse.security.ui.authentication.AuthenticationManagerImpl;
|
||||
import com.sap.sse.security.ui.authentication.WithAuthenticationManager;
|
||||
import com.sap.sse.security.ui.authentication.WithUserService;
|
||||
import com.sap.sse.security.ui.client.SecureClientFactoryImpl;
|
||||
import com.sap.sse.security.ui.client.i18n.StringMessages;
|
||||
|
||||
@@ -40,7 +41,7 @@ import com.sap.sse.security.ui.client.i18n.StringMessages;
|
||||
public class MobileApplicationClientFactory extends
|
||||
SecureClientFactoryImpl<ApplicationTopLevelView<ResettableNavigationPathDisplay>> implements
|
||||
ErrorAndBusyClientFactory, SearchResultClientFactory, ConfirmationClientFactory, PasswordResetClientFactory,
|
||||
WithAuthenticationManager {
|
||||
WithAuthenticationManager, WithUserService {
|
||||
private final MobilePlacesNavigator navigator;
|
||||
private final SailingDispatchSystem dispatch = new SailingDispatchSystemImpl();
|
||||
private final AuthenticationManager authenticationManager;
|
||||
|
||||
+27
-10
@@ -49,26 +49,42 @@
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
.searchresult_item {
|
||||
padding: 1.333333333333333em 1em;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
.searchresult_item_link,
|
||||
.searchresult_item_link:visited,
|
||||
.searchresult_item_link:after {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 1em;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
.searchresult_item_headline {
|
||||
font-size: 1.066666666666667em;
|
||||
font-weight: 700;
|
||||
margin-right: 2em;
|
||||
font-weight: bold;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
.searchresult_item_event {
|
||||
font-size: 0.866666666666667em;
|
||||
color: #0a0a0a;
|
||||
margin-right: 2em;
|
||||
}
|
||||
.searchresult_item_event_link {
|
||||
color: #0a0a0a;
|
||||
font-size: 1.066666666666667em;
|
||||
font-weight: bold;
|
||||
color: #bcbcbc;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
.searchresult_item_event_link,
|
||||
.searchresult_item_event_link:visited,
|
||||
.searchresult_item_event_link:active {
|
||||
font-size: 93.3333333333%;
|
||||
position: relative;
|
||||
display: block;
|
||||
color: #0a0a0a;
|
||||
padding: 0.5em 1em 0.5em 3em;
|
||||
border-top: 1px solid #ebebeb;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
.searchresult_item_event_info {
|
||||
font-size: 0.866666666666667em;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
.searchresult_item_event_separator:after {
|
||||
content: "|";
|
||||
@@ -76,13 +92,14 @@
|
||||
color: #ccc;
|
||||
}
|
||||
.searchresult_item_arrow {
|
||||
font-size: 1rem;
|
||||
background: url("images/home/arrow-down-grey.png");
|
||||
background-size: contain;
|
||||
display: block;
|
||||
width: 1.333333333333333em;
|
||||
height: 1.333333333333333em;
|
||||
top: 50%;
|
||||
right: 1em;
|
||||
right: 0.666666666666667em;
|
||||
position: absolute;
|
||||
-webkit-transform: translateY(-50%) rotate(-90deg);
|
||||
-moz-transform: translateY(-50%) rotate(-90deg);
|
||||
|
||||
+13
-9
@@ -16,21 +16,19 @@ public class SearchResultItem extends AbstractSearchResultItem {
|
||||
|
||||
private static SearchResultItemUiBinder uiBinder = GWT.create(SearchResultItemUiBinder.class);
|
||||
|
||||
interface SearchResultItemUiBinder extends UiBinder<AnchorElement, SearchResultItem> {
|
||||
interface SearchResultItemUiBinder extends UiBinder<DivElement, SearchResultItem> {
|
||||
}
|
||||
|
||||
@UiField DivElement resultTitleUi;
|
||||
@UiField DivElement eventInfoContainerUi;
|
||||
private final AnchorElement anchorUi;
|
||||
@UiField AnchorElement anchorUi;
|
||||
private final MobilePlacesNavigator navigator;
|
||||
private final SearchResultDTO item;
|
||||
|
||||
SearchResultItem(MobilePlacesNavigator navigator, SearchResultDTO item) {
|
||||
this.navigator = navigator;
|
||||
init(anchorUi = uiBinder.createAndBindUi(this), item);
|
||||
SearchResultEventInfoDTO event = item.getEvents().iterator().next();
|
||||
String eventId = String.valueOf(event.getId()), leaderboardName = item.getLeaderboardName(), baseUrl = item.getBaseUrl();
|
||||
PlaceNavigation<?> regattaNavigation = navigator.getRegattaNavigation(eventId, leaderboardName, baseUrl, item.isOnRemoteServer());
|
||||
regattaNavigation.configureAnchorElement(anchorUi);
|
||||
this.item = item;
|
||||
init(uiBinder.createAndBindUi(this), item);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,10 +36,16 @@ public class SearchResultItem extends AbstractSearchResultItem {
|
||||
return resultTitleUi;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureRegattaNavigation(String eventId, String leaderboardName, String baseUrl, boolean isOnRemoteServer) {
|
||||
navigator.getRegattaNavigation(eventId, leaderboardName, baseUrl, item.isOnRemoteServer()).configureAnchorElement(anchorUi);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addEventInfo(SearchResultEventInfoDTO event) {
|
||||
if (eventInfoContainerUi.hasChildNodes()) return; // TODO: Temporary add only one event on mobile
|
||||
eventInfoContainerUi.appendChild(new SearchResultItemEventInfo(navigator, event).getElement());
|
||||
String eventId = String.valueOf(event.getId());
|
||||
PlaceNavigation<?> eventNavigation = navigator.getEventNavigation(eventId, item.getBaseUrl(), item.isOnRemoteServer());
|
||||
eventInfoContainerUi.appendChild(new SearchResultItemEventInfo(event, eventNavigation).getElement());
|
||||
}
|
||||
|
||||
}
|
||||
+6
-4
@@ -4,9 +4,11 @@
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.mobile.partials.searchresult.SearchResultResources" />
|
||||
<a class="{local_res.css.searchresult_item} {res.mediaCss.small12} {res.mediaCss.columns}">
|
||||
<div class="{local_res.css.searchresult_item_headline}" ui:field="resultTitleUi"> </div>
|
||||
<div class="{local_res.css.searchresult_item} {res.mediaCss.small12} {res.mediaCss.columns}">
|
||||
<a class="{local_res.css.searchresult_item_link}" ui:field="anchorUi" >
|
||||
<div class="{local_res.css.searchresult_item_headline}" ui:field="resultTitleUi"> </div>
|
||||
<div class="{local_res.css.searchresult_item_arrow}"></div>
|
||||
</a>
|
||||
<div ui:field="eventInfoContainerUi"></div>
|
||||
<div class="{local_res.css.searchresult_item_arrow}"></div>
|
||||
</a>
|
||||
</div>
|
||||
</ui:UiBinder>
|
||||
+11
-4
@@ -1,28 +1,30 @@
|
||||
package com.sap.sailing.gwt.home.mobile.partials.searchresult;
|
||||
|
||||
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.SpanElement;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.sap.sailing.gwt.home.communication.search.SearchResultEventInfoDTO;
|
||||
import com.sap.sailing.gwt.home.mobile.app.MobilePlacesNavigator;
|
||||
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
|
||||
import com.sap.sailing.gwt.home.shared.partials.searchresult.AbstractSearchResultItemEventInfo;
|
||||
|
||||
public class SearchResultItemEventInfo extends AbstractSearchResultItemEventInfo {
|
||||
|
||||
private static SearchResultItemEventInfoUiBinder uiBinder = GWT.create(SearchResultItemEventInfoUiBinder.class);
|
||||
|
||||
interface SearchResultItemEventInfoUiBinder extends UiBinder<Element, SearchResultItemEventInfo> {
|
||||
interface SearchResultItemEventInfoUiBinder extends UiBinder<AnchorElement, SearchResultItemEventInfo> {
|
||||
}
|
||||
|
||||
@UiField DivElement eventNameUi;
|
||||
@UiField SpanElement eventVenueUi;
|
||||
@UiField SpanElement eventDateUi;
|
||||
private final AnchorElement anchorUi;
|
||||
|
||||
SearchResultItemEventInfo(MobilePlacesNavigator navigator, SearchResultEventInfoDTO event) {
|
||||
init(uiBinder.createAndBindUi(this), event);
|
||||
SearchResultItemEventInfo(SearchResultEventInfoDTO event, PlaceNavigation<?> navigation) {
|
||||
init(anchorUi = uiBinder.createAndBindUi(this), event, navigation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,5 +41,10 @@ public class SearchResultItemEventInfo extends AbstractSearchResultItemEventInfo
|
||||
protected Element getEventDateUi() {
|
||||
return eventDateUi;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AnchorElement getNavigationUi() {
|
||||
return anchorUi;
|
||||
}
|
||||
|
||||
}
|
||||
+5
-4
@@ -4,11 +4,12 @@
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.mobile.partials.searchresult.SearchResultResources" />
|
||||
<div class="{local_res.css.searchresult_item_event}">
|
||||
<div class="{local_res.css.searchresult_item_event_link}" ui:field="eventNameUi"></div>
|
||||
<div>
|
||||
<a class="{local_res.css.searchresult_item_event_link}">
|
||||
<div class="{local_res.css.searchresult_item_event}" ui:field="eventNameUi"></div>
|
||||
<div class="{local_res.css.searchresult_item_event_info}">
|
||||
<span class="{local_res.css.searchresult_item_event_separator}" ui:field="eventVenueUi"></span>
|
||||
<span ui:field="eventDateUi"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="{local_res.css.searchresult_item_arrow}"></div>
|
||||
</a>
|
||||
</ui:UiBinder>
|
||||
+2
@@ -20,8 +20,10 @@ public interface SearchResultResources extends ClientBundle {
|
||||
String searchresult_header_form_button();
|
||||
String searchresult_amount();
|
||||
String searchresult_item();
|
||||
String searchresult_item_link();
|
||||
String searchresult_item_headline();
|
||||
String searchresult_item_event();
|
||||
String searchresult_item_event_info();
|
||||
String searchresult_item_event_link();
|
||||
String searchresult_item_event_separator();
|
||||
String searchresult_item_arrow();
|
||||
|
||||
+9
-4
@@ -63,6 +63,9 @@
|
||||
font-size: 0.866666666666667em;
|
||||
color: #0a0a0a;
|
||||
}
|
||||
.sectionheader_item, .sectionheader_item_title, .sectionheader_item_subtitle {
|
||||
max-width: 100%;
|
||||
}
|
||||
.sectionheader_item_infotext {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
@@ -112,9 +115,8 @@ img.sectionheader_item_arrow.accordion.collapsed {
|
||||
background: url("images/mobile/filter.svg") 100% no-repeat transparent;
|
||||
background-size: 1.333333333333333em;
|
||||
}
|
||||
.sectionheader_item_adjust_title {
|
||||
margin-left: 4em;
|
||||
margin-right: 2.5em;
|
||||
.sectionheader_item_adjust_title_left {
|
||||
padding-left: 4em;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
-webkit-transform: translateY(-50%);
|
||||
@@ -122,6 +124,9 @@ img.sectionheader_item_arrow.accordion.collapsed {
|
||||
-ms-transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.sectionheader_item_adjust_title > h2 {
|
||||
.sectionheader_item_adjust_title_left > h2 {
|
||||
display: inline;
|
||||
}
|
||||
.sectionheader_item_adjust_title_right {
|
||||
padding-right: 2.5em;
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
|
||||
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:mp="urn:import:com.sap.sailing.gwt.home.mobile.partials">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.mobile.partials.sectionHeader.SectionHeaderResources" />
|
||||
<g:HTMLPanel>
|
||||
<div class="{res.mediaCss.grid}">
|
||||
<a href="#" title="TODO">
|
||||
<!-- IF isStandalone ADD class 'section-header--stand-alone' -->
|
||||
<div class="{local_res.css.sectionheader} {res.mediaCss.small12} {res.mediaCss.columns} {local_res.css.sectionheaderstandalone}">
|
||||
<!-- IF END -->
|
||||
<mp:sectionHeader.SectionHeaderContent />
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="{res.mediaCss.grid}">
|
||||
<!-- IF isStandalone ADD class 'section-header--stand-alone' -->
|
||||
<div class="{local_res.css.sectionheader} {res.mediaCss.small12} {res.mediaCss.columns} {local_res.css.sectionheaderstandalone}">
|
||||
<!-- IF END -->
|
||||
<mp:sectionHeader.SectionHeaderContent />
|
||||
</div>
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
+14
-7
@@ -10,8 +10,6 @@ import com.google.gwt.dom.client.Style.Display;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.user.client.DOM;
|
||||
import com.google.gwt.user.client.Event;
|
||||
import com.google.gwt.user.client.EventListener;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
@@ -75,7 +73,8 @@ public class SectionHeaderContent extends Composite {
|
||||
public void setImageUrl(String imageUrl) {
|
||||
imageUi.getStyle().clearDisplay();
|
||||
imageUi.getStyle().setBackgroundImage("url(" + imageUrl + ")");
|
||||
titleAndLabelContainerUi.addClassName(SectionHeaderResources.INSTANCE.css().sectionheader_item_adjust_title());
|
||||
titleAndLabelContainerUi
|
||||
.addClassName(SectionHeaderResources.INSTANCE.css().sectionheader_item_adjust_title_left());
|
||||
}
|
||||
|
||||
public void setInfoText(String infoText) {
|
||||
@@ -97,23 +96,31 @@ public class SectionHeaderContent extends Composite {
|
||||
});
|
||||
actionArrowUi.setSrc("images/mobile/arrow-down-grey.png");
|
||||
actionArrowUi.addClassName(SectionHeaderResources.INSTANCE.css().accordion());
|
||||
titleAndLabelContainerUi
|
||||
.addClassName(SectionHeaderResources.INSTANCE.css().sectionheader_item_adjust_title_right());
|
||||
actionArrowUi.getStyle().clearDisplay();
|
||||
headerRightUi.getStyle().clearDisplay();
|
||||
}
|
||||
|
||||
public void setClickAction(final PlaceNavigation<?> placeNavigation) {
|
||||
placeNavigation.configureAnchorElement(headerMainUi);
|
||||
this.adjustedActionStyles();
|
||||
titleAndLabelContainerUi
|
||||
.addClassName(SectionHeaderResources.INSTANCE.css().sectionheader_item_adjust_title_right());
|
||||
headerRightUi.getStyle().clearDisplay();
|
||||
actionArrowUi.getStyle().clearDisplay();
|
||||
}
|
||||
|
||||
public void setClickAction(final String url) {
|
||||
headerMainUi.setHref(url);
|
||||
DOM.setEventListener(headerMainUi, new EventListener() {
|
||||
@Override
|
||||
public void onBrowserEvent(Event event) {
|
||||
}
|
||||
DOM.setEventListener(headerMainUi, event -> {
|
||||
});
|
||||
this.adjustedActionStyles();
|
||||
}
|
||||
|
||||
private void adjustedActionStyles() {
|
||||
titleAndLabelContainerUi
|
||||
.addClassName(SectionHeaderResources.INSTANCE.css().sectionheader_item_adjust_title_right());
|
||||
headerRightUi.getStyle().clearDisplay();
|
||||
actionArrowUi.getStyle().clearDisplay();
|
||||
}
|
||||
|
||||
+2
-1
@@ -23,7 +23,8 @@ public interface SectionHeaderResources extends ClientBundle {
|
||||
String sectionheader_item_subtitle();
|
||||
String sectionheader_item_infotext();
|
||||
String sectionheader_item_arrow();
|
||||
String sectionheader_item_adjust_title();
|
||||
String sectionheader_item_adjust_title_left();
|
||||
String sectionheader_item_adjust_title_right();
|
||||
String sectionheader_item_select();
|
||||
String accordion();
|
||||
String collapsed();
|
||||
|
||||
+2
-3
@@ -261,13 +261,12 @@ public abstract class AbstractEventActivity<PLACE extends AbstractEventPlace> ex
|
||||
RaceboardContextDefinition raceboardContext = new RaceboardContextDefinition(raceIdentifier.getRegattaName(),
|
||||
raceIdentifier.getRaceName(), leaderboardName, leaderboardGroupName,
|
||||
UUID.fromString(getCtx().getEventId()), mode);
|
||||
RaceBoardPerspectiveOwnSettings perspectiveOwnSettings = RaceBoardPerspectiveOwnSettings
|
||||
.createDefaultWithCanReplayDuringLiveRaces(true);
|
||||
RaceBoardPerspectiveOwnSettings perspectiveOwnSettings = new RaceBoardPerspectiveOwnSettings();
|
||||
|
||||
HashMap<String, Settings> innerSettings = new HashMap<>();
|
||||
innerSettings.put(RaceMapLifecycle.ID, RaceMapSettings.getDefaultWithShowMapControls(true));
|
||||
PerspectiveCompositeSettings<RaceBoardPerspectiveOwnSettings> settings = new PerspectiveCompositeSettings<>(
|
||||
perspectiveOwnSettings, innerSettings);
|
||||
|
||||
return EntryPointWithSettingsLinkFactory.createRaceBoardLink(raceboardContext, settings);
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -28,4 +28,9 @@ public abstract class AbstractUserProfileActivity extends AbstractActivity imple
|
||||
return clientFactory.getNavigator().getUserPreferencesNavigation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlaceNavigation<? extends AbstractUserProfilePlace> getUserSettingsNavigation() {
|
||||
return clientFactory.getNavigator().getUserSettingsNavigation();
|
||||
}
|
||||
|
||||
}
|
||||
+4
@@ -9,6 +9,7 @@ import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.common.client.SharedResources;
|
||||
import com.sap.sailing.gwt.home.mobile.partials.quickfinder.Quickfinder;
|
||||
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
|
||||
import com.sap.sailing.gwt.home.shared.usermanagement.decorator.AuthorizedContentDecoratorMobile;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.security.ui.authentication.app.AuthenticationContext;
|
||||
@@ -42,6 +43,9 @@ public class AbstractUserProfileView extends Composite implements UserProfileVie
|
||||
this.layout.quickfinderUi.addPlaceholderItem(i18n.profileQuickfinder());
|
||||
this.layout.quickfinderUi.addItem(i18n.details(), presenter.getUserProfileNavigation());
|
||||
this.layout.quickfinderUi.addItem(i18n.favoritesAndNotifications(), presenter.getUserPreferencesNavigation());
|
||||
if(ExperimentalFeatures.SHOW_MY_SETTINGS_IN_USER_PROFILE) {
|
||||
this.layout.quickfinderUi.addItem(i18n.settings(), presenter.getUserSettingsNavigation());
|
||||
}
|
||||
}
|
||||
|
||||
protected final void setViewContent(IsWidget content) {
|
||||
|
||||
+4
@@ -4,8 +4,10 @@ import com.google.gwt.core.client.GWT;
|
||||
import com.sap.sailing.gwt.home.mobile.app.MobileApplicationClientFactory;
|
||||
import com.sap.sailing.gwt.home.mobile.places.user.profile.details.UserProfileDetailsActivity;
|
||||
import com.sap.sailing.gwt.home.mobile.places.user.profile.preferences.UserProfilePreferencesActivity;
|
||||
import com.sap.sailing.gwt.home.mobile.places.user.profile.settings.UserProfileSettingsActivity;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.AbstractUserProfilePlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.preferences.UserProfilePreferencesPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserProfileSettingsPlace;
|
||||
import com.sap.sse.gwt.client.mvp.AbstractActivityProxy;
|
||||
|
||||
public class UserProfileActivityProxy extends AbstractActivityProxy {
|
||||
@@ -26,6 +28,8 @@ public class UserProfileActivityProxy extends AbstractActivityProxy {
|
||||
if (currentPlace instanceof UserProfilePreferencesPlace) {
|
||||
UserProfilePreferencesPlace userProfilePrefsPlace = (UserProfilePreferencesPlace) currentPlace;
|
||||
super.onSuccess(new UserProfilePreferencesActivity(userProfilePrefsPlace, clientFactory));
|
||||
} else if(currentPlace instanceof UserProfileSettingsPlace) {
|
||||
super.onSuccess(new UserProfileSettingsActivity((UserProfileSettingsPlace) currentPlace, clientFactory));
|
||||
} else {
|
||||
super.onSuccess(new UserProfileDetailsActivity(currentPlace, clientFactory));
|
||||
}
|
||||
|
||||
+1
@@ -11,5 +11,6 @@ public interface UserProfileViewBase extends IsWidget, NeedsAuthenticationContex
|
||||
public interface Presenter extends NotLoggedInPresenter {
|
||||
PlaceNavigation<? extends AbstractUserProfilePlace> getUserProfileNavigation();
|
||||
PlaceNavigation<? extends AbstractUserProfilePlace> getUserPreferencesNavigation();
|
||||
PlaceNavigation<? extends AbstractUserProfilePlace> getUserSettingsNavigation();
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.sap.sailing.gwt.home.mobile.places.user.profile.settings;
|
||||
|
||||
import com.google.gwt.event.shared.EventBus;
|
||||
import com.google.gwt.user.client.ui.AcceptsOneWidget;
|
||||
import com.sap.sailing.gwt.home.mobile.app.MobileApplicationClientFactory;
|
||||
import com.sap.sailing.gwt.home.mobile.places.user.profile.AbstractUserProfileActivity;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserProfileSettingsPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsPresenter;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
|
||||
import com.sap.sse.security.ui.authentication.AuthenticationContextEvent;
|
||||
|
||||
public class UserProfileSettingsActivity extends AbstractUserProfileActivity implements UserProfileSettingsView.Presenter {
|
||||
|
||||
private final UserSettingsView.Presenter userSettingsPresenter;
|
||||
private final UserProfileSettingsView currentView;
|
||||
|
||||
public UserProfileSettingsActivity(UserProfileSettingsPlace place,
|
||||
MobileApplicationClientFactory clientFactory) {
|
||||
super(clientFactory);
|
||||
this.userSettingsPresenter = new UserSettingsPresenter<MobileApplicationClientFactory>(clientFactory);
|
||||
this.currentView = new UserProfileSettingsViewImpl(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(final AcceptsOneWidget panel, final EventBus eventBus) {
|
||||
panel.setWidget(currentView);
|
||||
currentView.setAuthenticationContext(clientFactory.getAuthenticationManager().getAuthenticationContext());
|
||||
eventBus.addHandler(AuthenticationContextEvent.TYPE, new AuthenticationContextEvent.Handler() {
|
||||
@Override
|
||||
public void onUserChangeEvent(AuthenticationContextEvent event) {
|
||||
currentView.setAuthenticationContext(event.getCtx());
|
||||
}
|
||||
});
|
||||
if (clientFactory.getAuthenticationManager().getAuthenticationContext().isLoggedIn()) {
|
||||
userSettingsPresenter.loadData();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserSettingsView.Presenter getUserSettingsPresenter() {
|
||||
return userSettingsPresenter;
|
||||
}
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.sap.sailing.gwt.home.mobile.places.user.profile.settings;
|
||||
|
||||
import com.sap.sailing.gwt.home.mobile.places.user.profile.UserProfileViewBase;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
|
||||
|
||||
public interface UserProfileSettingsView extends UserProfileViewBase {
|
||||
|
||||
public interface Presenter extends UserProfileViewBase.Presenter {
|
||||
UserSettingsView.Presenter getUserSettingsPresenter();
|
||||
}
|
||||
}
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.sap.sailing.gwt.home.mobile.places.user.profile.settings;
|
||||
|
||||
import com.sap.sailing.gwt.home.mobile.places.user.profile.AbstractUserProfileView;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
|
||||
|
||||
public class UserProfileSettingsViewImpl extends AbstractUserProfileView implements UserProfileSettingsView {
|
||||
|
||||
private final UserSettingsView userPreferencesView;
|
||||
|
||||
public UserProfileSettingsViewImpl(UserProfileSettingsView.Presenter presenter) {
|
||||
super(presenter);
|
||||
this.userPreferencesView = new UserSettings(presenter.getUserSettingsPresenter());
|
||||
this.setViewContent(userPreferencesView);
|
||||
}
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.sap.sailing.gwt.home.mobile.places.user.profile.settings;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsEntry;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsView;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
|
||||
/**
|
||||
* Implementation of {@link UserSettingsView} where users can change their preferred selections and notifications.
|
||||
*/
|
||||
public class UserSettings extends Composite implements UserSettingsView {
|
||||
|
||||
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
|
||||
|
||||
interface MyUiBinder extends UiBinder<Widget, UserSettings> {
|
||||
}
|
||||
|
||||
@UiField
|
||||
DivElement notificationsTextUi;
|
||||
@UiField
|
||||
FlowPanel settingsContainerUi;
|
||||
|
||||
private final Presenter presenter;
|
||||
|
||||
public UserSettings(UserSettingsView.Presenter presenter) {
|
||||
this.presenter = presenter;
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
presenter.setView(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntries(List<UserSettingsEntry> entries) {
|
||||
notificationsTextUi.setInnerText(entries.isEmpty() ? StringMessages.INSTANCE.noDataFound()
|
||||
: StringMessages.INSTANCE.userProfileSettingsTabDescription());
|
||||
settingsContainerUi.clear();
|
||||
entries.forEach(entry -> settingsContainerUi.add(new UserSettingsItem(entry, () -> presenter.remove(entry))));
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<g:HTMLPanel addStyleNames="{res.mediaCss.grid} {res.mainCss.spacermarginbottommediumsmall}">
|
||||
<div ui:field="notificationsTextUi" class="{res.mediaCss.column} {res.mediaCss.small12} {res.mainCss.spacermargintopsmall} {res.mainCss.spacermarginbottomsmall}">
|
||||
<ui:text from="{i18n.userNotificationsOnlyIfMailAddressIsVerified}" />
|
||||
</div>
|
||||
<g:FlowPanel ui:field="settingsContainerUi" addStyleNames="{res.mediaCss.column} {res.mediaCss.small12}" />
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.sap.sailing.gwt.home.mobile.places.user.profile.settings;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.uibinder.client.UiHandler;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.HTMLPanel;
|
||||
import com.sap.sailing.gwt.home.mobile.partials.section.MobileSection;
|
||||
import com.sap.sailing.gwt.home.mobile.partials.sectionHeader.SectionHeaderContent;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserSettingsEntry;
|
||||
|
||||
public class UserSettingsItem extends Composite {
|
||||
|
||||
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
|
||||
|
||||
interface MyUiBinder extends UiBinder<MobileSection, UserSettingsItem> {
|
||||
}
|
||||
|
||||
@UiField SectionHeaderContent sectionHeaderUi;
|
||||
@UiField HTMLPanel contentContainerUi;
|
||||
@UiField DivElement settingsDataUi;
|
||||
private final Runnable deleteCallback;
|
||||
|
||||
public UserSettingsItem(UserSettingsEntry userSettingsEntry, Runnable deleteCallback) {
|
||||
this.deleteCallback = deleteCallback;
|
||||
MobileSection mobileSection = uiBinder.createAndBindUi(this);
|
||||
mobileSection.setEdgeToEdgeContent(true);
|
||||
initWidget(mobileSection);
|
||||
|
||||
|
||||
sectionHeaderUi.setSectionTitle(userSettingsEntry.getKeyWithoutContext());
|
||||
sectionHeaderUi.setSubtitle(userSettingsEntry.getDocumentSettingsId());
|
||||
final String userProfileSettings = userSettingsEntry.getProfileData();
|
||||
boolean hasUserData = (userProfileSettings != null && !userProfileSettings.isEmpty());
|
||||
final String localSettings = userSettingsEntry.getLocalData();
|
||||
settingsDataUi.setInnerText(hasUserData ? userProfileSettings : localSettings);
|
||||
|
||||
sectionHeaderUi.initCollapsibility(contentContainerUi.getElement(), false);
|
||||
}
|
||||
|
||||
@UiHandler("deleteControlUi")
|
||||
void onRemoveControlClicked(ClickEvent event) {
|
||||
this.deleteCallback.run();
|
||||
}
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
|
||||
xmlns:ms="urn:import:com.sap.sailing.gwt.home.mobile.partials.section"
|
||||
xmlns:sh="urn:import:com.sap.sailing.gwt.home.mobile.partials.sectionHeader">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:style>
|
||||
.wordwrapping {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.content {
|
||||
padding: .333333333333333em;
|
||||
}
|
||||
.deleteControl {
|
||||
width: 100%;
|
||||
}
|
||||
</ui:style>
|
||||
<ms:MobileSection addStyleNames="{style.wordwrapping}">
|
||||
<ms:header>
|
||||
<sh:SectionHeaderContent ui:field="sectionHeaderUi"/>
|
||||
</ms:header>
|
||||
<ms:content>
|
||||
<g:HTMLPanel ui:field="contentContainerUi" addStyleNames="{style.content}">
|
||||
<div ui:field="settingsDataUi" class="{res.mainCss.spacermarginbottomsmall}"></div>
|
||||
<g:Button ui:field="deleteControlUi" text="{i18n.delete}"
|
||||
addStyleNames="{res.mainCss.button} {res.mainCss.buttonprimary} {style.deleteControl}" />
|
||||
</g:HTMLPanel>
|
||||
</ms:content>
|
||||
</ms:MobileSection>
|
||||
</ui:UiBinder>
|
||||
+4
@@ -13,4 +13,8 @@ public class ExperimentalFeatures {
|
||||
* Provide buttons for user management login via social services like facebook or google.
|
||||
*/
|
||||
public static final boolean SHOW_SOCIAL_LOGINS_FOR_USER_MANAGEMENT = false;
|
||||
/**
|
||||
* Provide a tab "settings" in the user profile page.
|
||||
*/
|
||||
public static final boolean SHOW_MY_SETTINGS_IN_USER_PROFILE = true;
|
||||
}
|
||||
+2
@@ -38,6 +38,7 @@ import com.sap.sailing.gwt.home.shared.places.user.passwordreset.PasswordResetPl
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.UserProfileDefaultPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.UserProfileDetailsPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.preferences.UserProfilePreferencesPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserProfileSettingsPlace;
|
||||
|
||||
@WithTokenizers({ AboutUsPlace.Tokenizer.class, ContactPlace.Tokenizer.class, EventPlace.Tokenizer.class,
|
||||
EventsPlace.Tokenizer.class, SolutionsPlace.Tokenizer.class, WhatsNewPlace.Tokenizer.class,
|
||||
@@ -72,6 +73,7 @@ import com.sap.sailing.gwt.home.shared.places.user.profile.preferences.UserProfi
|
||||
UserProfileDefaultPlace.Tokenizer.class,
|
||||
UserProfileDetailsPlace.Tokenizer.class,
|
||||
UserProfilePreferencesPlace.Tokenizer.class,
|
||||
UserProfileSettingsPlace.Tokenizer.class,
|
||||
AuthenticationPlace.Tokenizer.class,
|
||||
ConfirmationPlace.Tokenizer.class,
|
||||
PasswordResetPlace.Tokenizer.class,
|
||||
|
||||
+5
@@ -21,6 +21,7 @@ import com.sap.sailing.gwt.home.shared.places.user.passwordreset.PasswordResetPl
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.AbstractUserProfilePlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.UserProfileDefaultPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.preferences.UserProfilePreferencesPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.settings.UserProfileSettingsPlace;
|
||||
|
||||
public class HomePlacesNavigator extends AbstractPlaceNavigator {
|
||||
|
||||
@@ -103,4 +104,8 @@ public class HomePlacesNavigator extends AbstractPlaceNavigator {
|
||||
public PlaceNavigation<? extends AbstractUserProfilePlace> getUserPreferencesNavigation() {
|
||||
return createLocalPlaceNavigation(new UserProfilePreferencesPlace());
|
||||
}
|
||||
|
||||
public PlaceNavigation<? extends AbstractUserProfilePlace> getUserSettingsNavigation() {
|
||||
return createLocalPlaceNavigation(new UserProfileSettingsPlace());
|
||||
}
|
||||
}
|
||||
+5
@@ -10,11 +10,16 @@ public abstract class AbstractSearchResultItem extends Widget {
|
||||
protected final void init(Element element, SearchResultDTO item) {
|
||||
setElement(element);
|
||||
getResultTitleUi().setInnerText(item.getDisplayName());
|
||||
String eventId = String.valueOf(item.getEvents().iterator().next().getId());
|
||||
configureRegattaNavigation(eventId, item.getLeaderboardName(), item.getBaseUrl(), item.isOnRemoteServer());
|
||||
for (SearchResultEventInfoDTO event : item.getEvents()) {
|
||||
addEventInfo(event);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void configureRegattaNavigation(String eventId,
|
||||
String leaderboardName, String baseUrl, boolean isOnRemoteServer);
|
||||
|
||||
protected abstract Element getResultTitleUi();
|
||||
|
||||
protected abstract void addEventInfo(SearchResultEventInfoDTO event);
|
||||
|
||||
+6
-1
@@ -2,19 +2,22 @@ package com.sap.sailing.gwt.home.shared.partials.searchresult;
|
||||
|
||||
import static com.sap.sailing.gwt.home.shared.utils.EventDatesFormatterUtil.formatDateRangeWithYear;
|
||||
|
||||
import com.google.gwt.dom.client.AnchorElement;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.user.client.ui.UIObject;
|
||||
import com.sap.sailing.gwt.home.communication.search.SearchResultEventInfoDTO;
|
||||
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
|
||||
|
||||
public abstract class AbstractSearchResultItemEventInfo extends UIObject {
|
||||
|
||||
protected final void init(Element element, SearchResultEventInfoDTO event) {
|
||||
protected final void init(Element element, SearchResultEventInfoDTO event, PlaceNavigation<?> navigation) {
|
||||
setElement(element);
|
||||
getEventNameUi().setInnerText(event.getName());
|
||||
getEventVenueUi().setInnerText(event.getVenueName());
|
||||
if (event.getStartDate() != null && event.getEndDate() != null) {
|
||||
getEventDateUi().setInnerText(formatDateRangeWithYear(event.getStartDate(), event.getEndDate()));
|
||||
}
|
||||
navigation.configureAnchorElement(getNavigationUi());
|
||||
}
|
||||
|
||||
protected abstract Element getEventNameUi();
|
||||
@@ -22,5 +25,7 @@ public abstract class AbstractSearchResultItemEventInfo extends UIObject {
|
||||
protected abstract Element getEventVenueUi();
|
||||
|
||||
protected abstract Element getEventDateUi();
|
||||
|
||||
protected abstract AnchorElement getNavigationUi();
|
||||
|
||||
}
|
||||
+1
@@ -26,6 +26,7 @@ public class PlaceTokenPrefixes {
|
||||
public static final String UserProfileDefault = "/user/profile/";
|
||||
public static final String UserProfileDetails = "/user/profile/details/";
|
||||
public static final String UserProfilePreferences = "/user/profile/preferences/";
|
||||
public static final String UserProfileSettings = "/user/profile/settings/";
|
||||
public static final String UserConfirmation = "/user/confirmation/";
|
||||
public static final String UserPasswordReset = "/user/passwordreset/";
|
||||
public static final String UserAuthentication = "/user/auth/";
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.sap.sailing.gwt.home.shared.places.user.profile.settings;
|
||||
|
||||
import com.google.gwt.place.shared.Prefix;
|
||||
import com.sap.sailing.gwt.home.shared.app.HasMobileVersion;
|
||||
import com.sap.sailing.gwt.home.shared.places.PlaceTokenPrefixes;
|
||||
import com.sap.sailing.gwt.home.shared.places.user.profile.AbstractUserProfilePlace;
|
||||
|
||||
|
||||
public class UserProfileSettingsPlace extends AbstractUserProfilePlace implements HasMobileVersion {
|
||||
|
||||
@Prefix(PlaceTokenPrefixes.UserProfileSettings)
|
||||
public static class Tokenizer extends AbstractUserProfilePlace.Tokenizer<UserProfileSettingsPlace> {
|
||||
@Override
|
||||
protected UserProfileSettingsPlace getRealPlace() {
|
||||
return new UserProfileSettingsPlace();
|
||||
}
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.sap.sailing.gwt.home.shared.places.user.profile.settings;
|
||||
|
||||
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
|
||||
|
||||
public class UserSettingsEntry {
|
||||
|
||||
private final String key;
|
||||
private final String keyWithoutContext;
|
||||
private final String documentSettingsId;
|
||||
private final String profileData;
|
||||
private final String localData;
|
||||
|
||||
public UserSettingsEntry(String key, String profileData, String localData) {
|
||||
super();
|
||||
final int separatorIndex = key.indexOf(StoredSettingsLocation.DOCUMENT_SETTINGS_SUFFIX_SEPARATOR);
|
||||
if(separatorIndex > 0) {
|
||||
keyWithoutContext = key.substring(0, separatorIndex);
|
||||
documentSettingsId = key.substring(separatorIndex + 1);
|
||||
} else {
|
||||
keyWithoutContext = key;
|
||||
documentSettingsId = null;
|
||||
}
|
||||
this.key = key;
|
||||
this.profileData = profileData;
|
||||
this.localData = localData;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getProfileData() {
|
||||
return profileData;
|
||||
}
|
||||
|
||||
public String getLocalData() {
|
||||
return localData;
|
||||
}
|
||||
|
||||
public String getDocumentSettingsId() {
|
||||
return documentSettingsId;
|
||||
}
|
||||
|
||||
public String getKeyWithoutContext() {
|
||||
return keyWithoutContext;
|
||||
}
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
package com.sap.sailing.gwt.home.shared.places.user.profile.settings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.google.gwt.storage.client.Storage;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.gwt.home.shared.app.ClientFactoryWithDispatch;
|
||||
import com.sap.sailing.gwt.ui.client.refresh.ErrorAndBusyClientFactory;
|
||||
import com.sap.sailing.gwt.ui.shared.settings.SailingSettingsConstants;
|
||||
import com.sap.sse.security.ui.authentication.WithAuthenticationManager;
|
||||
import com.sap.sse.security.ui.authentication.WithUserService;
|
||||
|
||||
/**
|
||||
* @param <C>
|
||||
* the provided client factory type
|
||||
*/
|
||||
public class UserSettingsPresenter<C extends ClientFactoryWithDispatch & ErrorAndBusyClientFactory & WithAuthenticationManager & WithUserService>
|
||||
implements UserSettingsView.Presenter {
|
||||
|
||||
private final C clientFactory;
|
||||
private UserSettingsView view;
|
||||
|
||||
private final List<UserSettingsEntry> currentlyShownEntries = new ArrayList<>();
|
||||
|
||||
public UserSettingsPresenter(C clientFactory) {
|
||||
this.clientFactory = clientFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData() {
|
||||
if(clientFactory.getAuthenticationManager().getAuthenticationContext().isLoggedIn()) {
|
||||
clientFactory.getUserService().getAllPreferences(new AsyncCallback<Map<String,String>>() {
|
||||
@Override
|
||||
public void onSuccess(Map<String, String> result) {
|
||||
loadSettingsFromLocalStorage(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
clientFactory.createErrorView("Error while loading user settings!", caught);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
loadSettingsFromLocalStorage(Collections.emptyMap());
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSettingsFromLocalStorage(final Map<String, String> userSettings) {
|
||||
final Map<String, String> localSettings = loadSettingsFromLocalStorage();
|
||||
final Set<String> allKeys = new TreeSet<>((a, b) -> a.compareTo(b));
|
||||
allKeys.addAll(userSettings.keySet());
|
||||
allKeys.addAll(localSettings.keySet());
|
||||
currentlyShownEntries.clear();
|
||||
for(String key : allKeys) {
|
||||
currentlyShownEntries.add(new UserSettingsEntry(key, userSettings.get(key), localSettings.get(key)));
|
||||
}
|
||||
view.setEntries(currentlyShownEntries);
|
||||
}
|
||||
|
||||
private Map<String, String> loadSettingsFromLocalStorage() {
|
||||
final Map<String, String> localSettings;
|
||||
if(Storage.isLocalStorageSupported()) {
|
||||
localSettings = new HashMap<String, String>();
|
||||
Storage localStorage = Storage.getLocalStorageIfSupported();
|
||||
for(int i = 0; i< localStorage.getLength(); i++) {
|
||||
String key = localStorage.key(i);
|
||||
if(key.startsWith(SailingSettingsConstants.USER_SETTINGS_UI)) {
|
||||
String value = localStorage.getItem(key);
|
||||
localSettings.put(key, value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
localSettings = Collections.emptyMap();
|
||||
}
|
||||
return localSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(UserSettingsEntry entry) {
|
||||
String storageKey = entry.getKey();
|
||||
clientFactory.getUserService().unsetPreference(storageKey);
|
||||
if(Storage.isLocalStorageSupported()) {
|
||||
Storage localStorage = Storage.getLocalStorageIfSupported();
|
||||
localStorage.removeItem(storageKey);
|
||||
}
|
||||
currentlyShownEntries.remove(entry);
|
||||
view.setEntries(currentlyShownEntries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setView(UserSettingsView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.sap.sailing.gwt.home.shared.places.user.profile.settings;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.ui.IsWidget;
|
||||
import com.sap.sailing.gwt.home.shared.partials.multiselection.SuggestedMultiSelectionDataProvider;
|
||||
|
||||
/**
|
||||
* Interface for the user preferences UI. To support desktop as well as mobile version, an
|
||||
* {@link #setEdgeToEdge(boolean) edge-to-edge} flag can be provided, in order to meet the respective layout
|
||||
* requirements.
|
||||
*/
|
||||
public interface UserSettingsView extends IsWidget {
|
||||
|
||||
void setEntries(List<UserSettingsEntry> entries);
|
||||
|
||||
/**
|
||||
* Presenter interface for the user preferences UI, providing methods to load preferences and to access the required
|
||||
* {@link SuggestedMultiSelectionDataProvider}s.
|
||||
*/
|
||||
public interface Presenter {
|
||||
void loadData();
|
||||
|
||||
void remove(UserSettingsEntry entry);
|
||||
|
||||
void setView(UserSettingsView view);
|
||||
}
|
||||
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package com.sap.sailing.gwt.regattaoverview.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
|
||||
|
||||
public interface EventAndRaceGroupAvailabilityListener {
|
||||
void onEventUpdated(EventDTO event);
|
||||
void onRaceGroupsUpdated(List<RaceGroupDTO> raceGroups);
|
||||
}
|
||||
+3
-17
@@ -16,11 +16,9 @@ import com.google.gwt.user.client.ui.ScrollPanel;
|
||||
import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication;
|
||||
import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication;
|
||||
import com.sap.sailing.gwt.common.client.SharedResources;
|
||||
import com.sap.sailing.gwt.regattaoverview.client.RegattaRaceStatesComponent.EntryHandler;
|
||||
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaOverviewContextDefinition;
|
||||
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaRaceStatesSettings;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
|
||||
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
|
||||
public class RegattaOverviewEntryPoint extends AbstractSailingEntryPoint {
|
||||
@@ -56,30 +54,18 @@ public class RegattaOverviewEntryPoint extends AbstractSailingEntryPoint {
|
||||
siteHeader.addWidgetToRightSide(clockLabel);
|
||||
containerPanel.addNorth(siteHeader, 75);
|
||||
|
||||
RegattaOverviewContextDefinition regattaOverviewSettings = serializer
|
||||
RegattaOverviewContextDefinition regattaOverviewContextDefinition = serializer
|
||||
.deserializeFromCurrentLocation(new RegattaOverviewContextDefinition());
|
||||
|
||||
if (regattaOverviewSettings.getEvent() == null) {
|
||||
if (regattaOverviewContextDefinition.getEvent() == null) {
|
||||
Window.alert("Missing parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
createAndAddDetailPanel();
|
||||
createAndAddRegattaPanel(regattaOverviewSettings);
|
||||
createAndAddRegattaPanel(regattaOverviewContextDefinition);
|
||||
toggleDetailPanel(false);
|
||||
|
||||
regattaPanel.setEntryClickedHandler(new EntryHandler() {
|
||||
@Override
|
||||
public void onEntryClicked(RegattaOverviewEntryDTO entry) {
|
||||
detailPanel.show(entry);
|
||||
toggleDetailPanel(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntryUpdated(RegattaOverviewEntryDTO entry) {
|
||||
detailPanel.update(entry);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void toggleDetailPanel(boolean visibile) {
|
||||
|
||||
+82
-100
@@ -23,7 +23,7 @@ import com.sap.sailing.gwt.regattaoverview.client.RegattaRaceStatesComponent.Ent
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings;
|
||||
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaOverviewContextDefinition;
|
||||
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaRaceStatesSettings;
|
||||
import com.sap.sailing.gwt.settings.client.utils.StorageDefinitionIdFactory;
|
||||
import com.sap.sailing.gwt.settings.client.utils.StoredSettingsLocationFactory;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
@@ -40,13 +40,12 @@ import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayStates;
|
||||
import com.sap.sse.gwt.client.shared.components.LinkWithSettingsGenerator;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialog;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.perspective.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.perspective.SettingsStorageManager;
|
||||
import com.sap.sse.gwt.client.shared.perspective.IgnoreLocalSettings;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.settings.StorageDefinitionId;
|
||||
import com.sap.sse.security.ui.settings.UserSettingsStorageManager;
|
||||
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
|
||||
|
||||
public class RegattaOverviewPanel extends SimplePanel {
|
||||
|
||||
@@ -63,7 +62,6 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
private final RegattaOverviewContextDefinition regattaOverviewContextDefinition;
|
||||
private EventDTO eventDTO;
|
||||
private List<RaceGroupDTO> raceGroupDTOs;
|
||||
private List<EventAndRaceGroupAvailabilityListener> eventRaceGroupListeners;
|
||||
private boolean showLeaderboard = false;
|
||||
|
||||
private RegattaRaceStatesComponent regattaRaceStatesComponent;
|
||||
@@ -74,12 +72,20 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
private final Anchor startStopUpdatingButton;
|
||||
private CheckBox leaderboardCheckBox;
|
||||
private final FlowPanel repeatedInfoLabel = new FlowPanel();
|
||||
private VerticalPanel mainPanel;
|
||||
private UserService userService;
|
||||
private ComponentContext<RegattaRaceStatesSettings> componentContext;
|
||||
|
||||
private final RegattaOverviewResources.LocalCss style = RegattaOverviewResources.INSTANCE.css();
|
||||
private final SharedResources RES = SharedResources.INSTANCE;
|
||||
|
||||
private EntryHandler entryClickedHandler = null;
|
||||
|
||||
public void setEntryClickedHandler(EntryHandler handler) {
|
||||
regattaRaceStatesComponent.setEntryClickedHandler(handler);
|
||||
entryClickedHandler = handler;
|
||||
if(regattaRaceStatesComponent != null) {
|
||||
regattaRaceStatesComponent.setEntryClickedHandler(handler);
|
||||
}
|
||||
}
|
||||
|
||||
public RegattaOverviewPanel(
|
||||
@@ -97,12 +103,9 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
this.uiUpdateTimer = new Timer(PlayModes.Live, uiUpdateRateInMs);
|
||||
this.eventDTO = null;
|
||||
this.raceGroupDTOs = new ArrayList<RaceGroupDTO>();
|
||||
this.eventRaceGroupListeners = new ArrayList<EventAndRaceGroupAvailabilityListener>();
|
||||
this.userService = userService;
|
||||
|
||||
retrieveEvent();
|
||||
retrieveRegattaStructure();
|
||||
|
||||
VerticalPanel mainPanel = new VerticalPanel();
|
||||
mainPanel = new VerticalPanel();
|
||||
setWidget(mainPanel);
|
||||
mainPanel.setWidth("100%");
|
||||
mainPanel.addStyleName(style.contentWrapper());
|
||||
@@ -130,7 +133,7 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
// TODO should we always set ignoreLocalSettings=true when creating links?
|
||||
new SettingsDialog<RegattaRaceStatesSettings>(regattaRaceStatesComponent, stringMessages,
|
||||
new LinkWithSettingsGenerator<>(regattaOverviewContextDefinition,
|
||||
UserSettingsStorageManager.getIgnoreLocalSettings())).show();
|
||||
IgnoreLocalSettings.getIgnoreLocalSettingsFromCurrentUrl())).show();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -152,17 +155,67 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
|
||||
});
|
||||
|
||||
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForRegattaOverview(regattaOverviewContextDefinition);
|
||||
final RegattaRaceStatesComponentLifecycle lifecycle = new RegattaRaceStatesComponentLifecycle();
|
||||
final SettingsStorageManager<RegattaRaceStatesSettings> settingsStorageManager = UserSettingsStorageManager
|
||||
.createSettingsStorageManager(userService, storageDefinitionId);
|
||||
final ComponentContext<RegattaRaceStatesSettings> componentContext = new ComponentContextWithSettingsStorage<>(
|
||||
lifecycle, settingsStorageManager);
|
||||
//FIXME The chained calls from here are independent from each other and should be implemented with Dispatching Framework
|
||||
sailingService.getEventById(regattaOverviewContextDefinition.getEvent(), false, new MarkedAsyncCallback<EventDTO>(
|
||||
new AsyncCallback<EventDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable cause) {
|
||||
settingsButton.setEnabled(false);
|
||||
errorReporter.reportError("Error trying to load event with id " + regattaOverviewContextDefinition.getEvent() + " : "
|
||||
+ cause.getMessage());
|
||||
continueInitAfterEventRetrieved();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(EventDTO result) {
|
||||
setEvent(result);
|
||||
continueInitAfterEventRetrieved();
|
||||
}
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
private void continueInitAfterEventRetrieved() {
|
||||
sailingService.getRegattaStructureForEvent(regattaOverviewContextDefinition.getEvent(), new MarkedAsyncCallback<List<RaceGroupDTO>>(
|
||||
new AsyncCallback<List<RaceGroupDTO>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable cause) {
|
||||
errorReporter.reportError("Error trying to load regattas for event with id " + regattaOverviewContextDefinition.getEvent() + " : "
|
||||
+ cause.getMessage());
|
||||
continueInitAfterRaceGroupsRetrieved();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(List<RaceGroupDTO> result) {
|
||||
raceGroupDTOs.clear();
|
||||
raceGroupDTOs.addAll(result);
|
||||
continueInitAfterRaceGroupsRetrieved();
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
private void continueInitAfterRaceGroupsRetrieved() {
|
||||
final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory.createStoredSettingsLocatorForRegattaOverview(regattaOverviewContextDefinition);
|
||||
final RegattaRaceStatesComponentLifecycle lifecycle = new RegattaRaceStatesComponentLifecycle(eventDTO == null ? null : eventDTO.venue.getCourseAreas(), raceGroupDTOs);
|
||||
componentContext = new ComponentContextWithSettingsStorage<>(
|
||||
lifecycle, userService, storageDefinition);
|
||||
|
||||
componentContext.getInitialSettings(new DefaultOnSettingsLoadedCallback<RegattaRaceStatesSettings>() {
|
||||
@Override
|
||||
public void onSuccess(RegattaRaceStatesSettings defaultSettings) {
|
||||
continueInitAfterSettingsRetrieved(defaultSettings);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void continueInitAfterSettingsRetrieved(RegattaRaceStatesSettings defaultSettings) {
|
||||
regattaRaceStatesComponent = new RegattaRaceStatesComponent(null, componentContext, sailingService, errorReporter,
|
||||
stringMessages,
|
||||
regattaOverviewContextDefinition.getEvent(), lifecycle.createDefaultSettings(), uiUpdateTimer);
|
||||
this.eventRaceGroupListeners.add(regattaRaceStatesComponent);
|
||||
regattaOverviewContextDefinition.getEvent(), eventDTO, raceGroupDTOs, defaultSettings, uiUpdateTimer);
|
||||
|
||||
regattaRaceStatesComponent.setEntryClickedHandler(entryClickedHandler);
|
||||
|
||||
regattaRaceStatesComponent.setWidth("100%");
|
||||
|
||||
this.serverUpdateTimer.addTimeListener(new TimeListener() {
|
||||
@@ -223,13 +276,7 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
} else {
|
||||
leaderboardsTabPanel = null;
|
||||
}
|
||||
|
||||
componentContext.initInitialSettings(new DefaultOnSettingsLoadedCallback<RegattaRaceStatesSettings>() {
|
||||
@Override
|
||||
public void onSuccess(RegattaRaceStatesSettings defaultSettings) {
|
||||
regattaRaceStatesComponent.updateSettings(defaultSettings);
|
||||
}
|
||||
});
|
||||
checkToEnableSettingsButton();
|
||||
}
|
||||
|
||||
private CheckBox addLeaderboardEnablerButton() {
|
||||
@@ -297,80 +344,15 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void retrieveEvent() {
|
||||
sailingService.getEventById(regattaOverviewContextDefinition.getEvent(), false, new MarkedAsyncCallback<EventDTO>(
|
||||
new AsyncCallback<EventDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable cause) {
|
||||
settingsButton.setEnabled(false);
|
||||
errorReporter.reportError("Error trying to load event with id " + regattaOverviewContextDefinition.getEvent() + " : "
|
||||
+ cause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(EventDTO result) {
|
||||
if (result != null) {
|
||||
setEvent(result);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void setEvent(EventDTO event) {
|
||||
eventDTO = event;
|
||||
onEventUpdated();
|
||||
}
|
||||
|
||||
private void onEventUpdated() {
|
||||
fireEvent(new EventDTOLoadedEvent(eventDTO));
|
||||
|
||||
for (EventAndRaceGroupAvailabilityListener listener : this.eventRaceGroupListeners) {
|
||||
listener.onEventUpdated(eventDTO);
|
||||
}
|
||||
checkToEnableSettingsButton();
|
||||
}
|
||||
|
||||
private void retrieveRegattaStructure() {
|
||||
sailingService.getRegattaStructureForEvent(regattaOverviewContextDefinition.getEvent(), new MarkedAsyncCallback<List<RaceGroupDTO>>(
|
||||
new AsyncCallback<List<RaceGroupDTO>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable cause) {
|
||||
errorReporter.reportError("Error trying to load regattas for event with id " + regattaOverviewContextDefinition.getEvent() + " : "
|
||||
+ cause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(List<RaceGroupDTO> result) {
|
||||
if (result != null) {
|
||||
setRaceGroups(result);
|
||||
}
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
protected void setRaceGroups(List<RaceGroupDTO> result) {
|
||||
|
||||
raceGroupDTOs.clear();
|
||||
raceGroupDTOs.addAll(result);
|
||||
onRaceGroupsUpdated();
|
||||
}
|
||||
|
||||
private void onRaceGroupsUpdated() {
|
||||
for (EventAndRaceGroupAvailabilityListener listener : this.eventRaceGroupListeners) {
|
||||
listener.onRaceGroupsUpdated(raceGroupDTOs);
|
||||
}
|
||||
checkToEnableSettingsButton();
|
||||
}
|
||||
|
||||
private void checkToEnableSettingsButton() {
|
||||
if (eventDTO != null && raceGroupDTOs.size() > 0) {
|
||||
settingsButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void setEvent(EventDTO event) {
|
||||
eventDTO = event;
|
||||
fireEvent(new EventDTOLoadedEvent(eventDTO));
|
||||
}
|
||||
|
||||
}
|
||||
+12
-21
@@ -73,16 +73,15 @@ import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.shared.components.AbstractCompositeComponent;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
|
||||
/**
|
||||
* This component shows a table displaying the current state of races for a given event. Which races are shown depends
|
||||
* on the setting {@link RegattaRaceStatesSettings}. Each entry shows what flags are currently displayed, what start
|
||||
* time the race has and additional information, e.g. for Gate start.
|
||||
*/
|
||||
public class RegattaRaceStatesComponent extends AbstractCompositeComponent<RegattaRaceStatesSettings> implements
|
||||
EventAndRaceGroupAvailabilityListener {
|
||||
public class RegattaRaceStatesComponent extends AbstractCompositeComponent<RegattaRaceStatesSettings> {
|
||||
public interface EntryHandler {
|
||||
void onEntryClicked(RegattaOverviewEntryDTO entry);
|
||||
|
||||
@@ -136,22 +135,21 @@ public class RegattaRaceStatesComponent extends AbstractCompositeComponent<Regat
|
||||
* Whenever this component makes a service call and receives an update on the current server time, the
|
||||
* timer passed for this argument will be synchronized.
|
||||
*/
|
||||
public RegattaRaceStatesComponent(Component<?> parent, ComponentContext<?> context,
|
||||
public RegattaRaceStatesComponent(Component<?> parent, ComponentContext<?> componentContext,
|
||||
final SailingServiceAsync sailingService,
|
||||
ErrorReporter errorReporter,
|
||||
final StringMessages stringMessages, final UUID eventId, RegattaRaceStatesSettings settings,
|
||||
final StringMessages stringMessages, UUID eventId, EventDTO eventDTO, List<RaceGroupDTO> raceGroupDTOs, RegattaRaceStatesSettings settings,
|
||||
Timer timerToSynchronize) {
|
||||
super(parent, context);
|
||||
super(parent, componentContext);
|
||||
this.eventId = eventId;
|
||||
this.sailingService = sailingService;
|
||||
this.stringMessages = stringMessages;
|
||||
this.eventId = eventId;
|
||||
this.allEntries = new ArrayList<RegattaOverviewEntryDTO>();
|
||||
this.timerToSynchronize = timerToSynchronize;
|
||||
this.eventDTO = null;
|
||||
this.raceGroupDTOs = null;
|
||||
this.flagInterpreter = new RaceStateFlagsInterpreter(stringMessages);
|
||||
this.settings = new RegattaRaceStatesSettings();
|
||||
updateSettings(settings);
|
||||
mainPanel = new VerticalPanel();
|
||||
mainPanel.getElement().getStyle().setWidth(100, Unit.PCT);
|
||||
regattaOverviewDataProvider = new ListDataProvider<RegattaOverviewEntryDTO>();
|
||||
@@ -160,6 +158,9 @@ public class RegattaRaceStatesComponent extends AbstractCompositeComponent<Regat
|
||||
mainPanel.add(tableHolder);
|
||||
initWidget(mainPanel);
|
||||
getElement().getStyle().setWidth(100, Unit.PCT);
|
||||
this.eventDTO = eventDTO;
|
||||
setRaceGroups(raceGroupDTOs);
|
||||
updateSettings(settings);
|
||||
}
|
||||
|
||||
public void onUpdateServer() {
|
||||
@@ -346,7 +347,7 @@ public class RegattaRaceStatesComponent extends AbstractCompositeComponent<Regat
|
||||
}
|
||||
|
||||
protected void loadAndUpdateEventLog() {
|
||||
if (eventId == null || eventDTO == null || raceGroupDTOs == null) {
|
||||
if (eventDTO == null || raceGroupDTOs == null) {
|
||||
return;
|
||||
}
|
||||
final long clientTimeWhenRequestWasSent = System.currentTimeMillis();
|
||||
@@ -727,7 +728,7 @@ public class RegattaRaceStatesComponent extends AbstractCompositeComponent<Regat
|
||||
}
|
||||
|
||||
@Override
|
||||
public SettingsDialogComponent<RegattaRaceStatesSettings> getSettingsDialogComponent() {
|
||||
public SettingsDialogComponent<RegattaRaceStatesSettings> getSettingsDialogComponent(RegattaRaceStatesSettings settings) {
|
||||
return new RegattaRaceStatesSettingsDialogComponent(settings, stringMessages,
|
||||
Collections.unmodifiableList(eventDTO.venue.getCourseAreas()),
|
||||
Collections.unmodifiableList(raceGroupDTOs));
|
||||
@@ -775,15 +776,7 @@ public class RegattaRaceStatesComponent extends AbstractCompositeComponent<Regat
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEventUpdated(EventDTO event) {
|
||||
eventDTO = event;
|
||||
setDefaultCourseAreas();
|
||||
refreshTableWithNewSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceGroupsUpdated(List<RaceGroupDTO> raceGroups) {
|
||||
private void setRaceGroups(List<RaceGroupDTO> raceGroups) {
|
||||
raceGroupDTOs = raceGroups;
|
||||
GWT.log("onRaceGroupsUpdated");
|
||||
if (raceGroupDTOs != null) {
|
||||
@@ -817,8 +810,6 @@ public class RegattaRaceStatesComponent extends AbstractCompositeComponent<Regat
|
||||
// }
|
||||
// }
|
||||
// regattaOverviewTable.redraw();
|
||||
setDefaultRegattas();
|
||||
refreshTableWithNewSettings();
|
||||
}
|
||||
|
||||
private DialogBox createCourseViewDialogBox(RaceInfoDTO raceInfoDTO) {
|
||||
|
||||
+21
-3
@@ -1,13 +1,24 @@
|
||||
package com.sap.sailing.gwt.regattaoverview.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaRaceStatesSettings;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
|
||||
import com.sap.sse.gwt.client.shared.components.ComponentLifecycle;
|
||||
|
||||
public class RegattaRaceStatesComponentLifecycle implements ComponentLifecycle<RegattaRaceStatesSettings> {
|
||||
|
||||
public static final String ID = "rrs";
|
||||
private List<CourseAreaDTO> courseAreaDTOs;
|
||||
private List<RaceGroupDTO> raceGroupDTOs;
|
||||
|
||||
public RegattaRaceStatesComponentLifecycle(List<CourseAreaDTO> courseAreaDTOs, List<RaceGroupDTO> raceGroupDTOs) {
|
||||
this.courseAreaDTOs = courseAreaDTOs;
|
||||
this.raceGroupDTOs = raceGroupDTOs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegattaRaceStatesSettingsDialogComponent getSettingsDialogComponent(RegattaRaceStatesSettings settings) {
|
||||
// TODO implement if needed
|
||||
@@ -19,7 +30,14 @@ public class RegattaRaceStatesComponentLifecycle implements ComponentLifecycle<R
|
||||
|
||||
@Override
|
||||
public RegattaRaceStatesSettings createDefaultSettings() {
|
||||
return new RegattaRaceStatesSettings();
|
||||
RegattaRaceStatesSettings settings = new RegattaRaceStatesSettings();
|
||||
if(courseAreaDTOs != null) {
|
||||
settings.setDefaultCourseAreas(courseAreaDTOs);
|
||||
}
|
||||
if(raceGroupDTOs != null) {
|
||||
settings.setDefaultRegattas(raceGroupDTOs);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,13 +56,13 @@ public class RegattaRaceStatesComponentLifecycle implements ComponentLifecycle<R
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegattaRaceStatesSettings extractGlobalSettings(RegattaRaceStatesSettings settings) {
|
||||
public RegattaRaceStatesSettings extractUserSettings(RegattaRaceStatesSettings settings) {
|
||||
return settings.createInstanceWithSettings(null, null, settings.isShowOnlyRacesOfSameDay(),
|
||||
settings.isShowOnlyCurrentlyRunningRaces());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegattaRaceStatesSettings extractContextSpecificSettings(RegattaRaceStatesSettings settings) {
|
||||
public RegattaRaceStatesSettings extractDocumentSettings(RegattaRaceStatesSettings settings) {
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -25,12 +25,12 @@ public abstract class AbstractLeaderboardPerspectiveLifecycle extends AbstractPe
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LeaderboardPerspectiveOwnSettings extractOwnGlobalSettings(LeaderboardPerspectiveOwnSettings settings) {
|
||||
protected LeaderboardPerspectiveOwnSettings extractOwnUserSettings(LeaderboardPerspectiveOwnSettings settings) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LeaderboardPerspectiveOwnSettings extractOwnContextSettings(LeaderboardPerspectiveOwnSettings settings) {
|
||||
protected LeaderboardPerspectiveOwnSettings extractOwnDocumentSettings(LeaderboardPerspectiveOwnSettings settings) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
+6
-7
@@ -5,6 +5,7 @@ import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.common.dto.AbstractLeaderboardDTO;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.common.settings.generic.support.SettingsUtil;
|
||||
import com.sap.sse.gwt.client.shared.components.ComponentLifecycle;
|
||||
|
||||
public class LeaderboardPanelLifecycle
|
||||
@@ -27,7 +28,7 @@ public class LeaderboardPanelLifecycle
|
||||
@Override
|
||||
public LeaderboardSettings createDefaultSettings() {
|
||||
return LeaderboardSettingsFactory.getInstance()
|
||||
.createNewSettingsWithCustomDefaults(new LeaderboardSettings(namesOfRaceColumns));
|
||||
.createNewDefaultSettingsWithRaceColumns(namesOfRaceColumns);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,8 +47,8 @@ public class LeaderboardPanelLifecycle
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderboardSettings extractGlobalSettings(LeaderboardSettings currentLeaderboardSettings) {
|
||||
LeaderboardSettings defaultLeaderboardSettings = currentLeaderboardSettings.getDefaultSettings();
|
||||
public LeaderboardSettings extractUserSettings(LeaderboardSettings currentLeaderboardSettings) {
|
||||
LeaderboardSettings defaultLeaderboardSettings = createDefaultSettings();
|
||||
LeaderboardSettings globalLeaderboardSettings = new LeaderboardSettings(
|
||||
currentLeaderboardSettings.getManeuverDetailsToShow(), currentLeaderboardSettings.getLegDetailsToShow(),
|
||||
currentLeaderboardSettings.getRaceDetailsToShow(), currentLeaderboardSettings.getOverallDetailsToShow(),
|
||||
@@ -64,13 +65,11 @@ public class LeaderboardPanelLifecycle
|
||||
currentLeaderboardSettings.isShowCompetitorSailIdColumn(),
|
||||
currentLeaderboardSettings.isShowCompetitorFullNameColumn(),
|
||||
currentLeaderboardSettings.isShowCompetitorNationality());
|
||||
globalLeaderboardSettings = LeaderboardSettingsFactory.getInstance().keepDefaults(currentLeaderboardSettings,
|
||||
globalLeaderboardSettings);
|
||||
return globalLeaderboardSettings;
|
||||
return SettingsUtil.copyValues(globalLeaderboardSettings, defaultLeaderboardSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderboardSettings extractContextSpecificSettings(LeaderboardSettings leaderboardSettings) {
|
||||
public LeaderboardSettings extractDocumentSettings(LeaderboardSettings leaderboardSettings) {
|
||||
return leaderboardSettings;
|
||||
}
|
||||
|
||||
|
||||
-4
@@ -7,10 +7,6 @@ public class LeaderboardPerspectiveLifecycle extends AbstractLeaderboardPerspect
|
||||
|
||||
public static final String ID = "lbh";
|
||||
|
||||
public LeaderboardPerspectiveLifecycle(StringMessages stringMessages) {
|
||||
this(stringMessages, null);
|
||||
}
|
||||
|
||||
public LeaderboardPerspectiveLifecycle(StringMessages stringMessages, AbstractLeaderboardDTO leaderboard) {
|
||||
super(stringMessages, leaderboard, false);
|
||||
addLifeCycle(new OverallLeaderboardPanelLifecycle(null, stringMessages));
|
||||
|
||||
+54
-127
@@ -5,19 +5,18 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.gwt.settings.client.settingtypes.converter.DetailTypeStringToEnumConverter;
|
||||
import com.sap.sailing.gwt.settings.client.settingtypes.converter.RaceColumnSelectionStrategiesStringToEnumConverter;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.settings.generic.AbstractGenericSerializableSettings;
|
||||
import com.sap.sse.common.settings.generic.BooleanSetting;
|
||||
import com.sap.sse.common.settings.generic.EnumListSetting;
|
||||
import com.sap.sse.common.settings.generic.EnumSetSetting;
|
||||
import com.sap.sse.common.settings.generic.EnumSetting;
|
||||
import com.sap.sse.common.settings.generic.IntegerSetting;
|
||||
import com.sap.sse.common.settings.generic.LongSetting;
|
||||
import com.sap.sse.common.settings.generic.StringListSetting;
|
||||
import com.sap.sse.common.settings.generic.StringSetSetting;
|
||||
import com.sap.sse.common.settings.generic.StringSetting;
|
||||
import com.sap.sse.common.settings.util.SettingsDefaultValuesUtils;
|
||||
|
||||
/**
|
||||
* Settings for the {@link LeaderboardPanel} component. If you change here, please also visit
|
||||
@@ -34,23 +33,23 @@ public class LeaderboardSettings extends AbstractGenericSerializableSettings {
|
||||
* Only one of {@link #namesOfRaceColumnsToShow} and {@link #namesOfRacesToShow} must be non-<code>null</code>.
|
||||
* Only valid when the {@link #activeRaceColumnSelectionStrategy} is set to EXPLIZIT
|
||||
*/
|
||||
private StringListSetting namesOfRaceColumnsToShow;
|
||||
private StringSetSetting namesOfRaceColumnsToShow;
|
||||
|
||||
/**
|
||||
* Only one of {@link #namesOfRaceColumnsToShow} and {@link #namesOfRacesToShow} must be non-<code>null</code>.
|
||||
* Only valid when the {@link #activeRaceColumnSelectionStrategy} is set to EXPLIZIT
|
||||
*/
|
||||
private StringListSetting namesOfRacesToShow;
|
||||
private StringSetSetting namesOfRacesToShow;
|
||||
|
||||
/**
|
||||
* Only valid when the {@link #activeRaceColumnSelectionStrategy} is set to LAST_N
|
||||
*/
|
||||
private IntegerSetting numberOfLastRacesToShow;
|
||||
|
||||
private EnumListSetting<DetailType> maneuverDetailsToShow;
|
||||
private EnumListSetting<DetailType> legDetailsToShow;
|
||||
private EnumListSetting<DetailType> raceDetailsToShow;
|
||||
private EnumListSetting<DetailType> overallDetailsToShow;
|
||||
private EnumSetSetting<DetailType> maneuverDetailsToShow;
|
||||
private EnumSetSetting<DetailType> legDetailsToShow;
|
||||
private EnumSetSetting<DetailType> raceDetailsToShow;
|
||||
private EnumSetSetting<DetailType> overallDetailsToShow;
|
||||
private boolean autoExpandPreSelectedRace = false;
|
||||
private LongSetting delayBetweenAutoAdvancesInMilliseconds;
|
||||
private BooleanSetting updateUponPlayStateChange;
|
||||
@@ -87,27 +86,27 @@ public class LeaderboardSettings extends AbstractGenericSerializableSettings {
|
||||
@Override
|
||||
protected void addChildSettings() {
|
||||
isShowCompetitorNationality = new BooleanSetting("showCompetitorNationality", this, false);
|
||||
namesOfRaceColumnsToShow = new StringListSetting("namesOfRaceColumnsToShow", this);
|
||||
namesOfRacesToShow = new StringListSetting("namesOfRacesToShow", this, null);
|
||||
namesOfRaceColumnsToShow = new StringSetSetting("namesOfRaceColumnsToShow", this);
|
||||
namesOfRacesToShow = new StringSetSetting("namesOfRacesToShow", this, null);
|
||||
numberOfLastRacesToShow = new IntegerSetting("numberOfLastRacesToShow", this, null);
|
||||
List<DetailType> maneuverDetails = new ArrayList<DetailType>();
|
||||
maneuverDetails.add(DetailType.TACK);
|
||||
maneuverDetails.add(DetailType.JIBE);
|
||||
maneuverDetails.add(DetailType.PENALTY_CIRCLE);
|
||||
maneuverDetailsToShow = new EnumListSetting<>("maneuverDetailsToShow", this, maneuverDetails, new DetailTypeStringToEnumConverter());
|
||||
maneuverDetailsToShow = new EnumSetSetting<>("maneuverDetailsToShow", this, maneuverDetails, DetailType::valueOf);
|
||||
List<DetailType> legDetails = new ArrayList<DetailType>();
|
||||
legDetails.add(DetailType.DISTANCE_TRAVELED);
|
||||
legDetails.add(DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
legDetails.add(DetailType.RANK_GAIN);
|
||||
legDetailsToShow = new EnumListSetting<>("legDetailsToShow", this, legDetails, new DetailTypeStringToEnumConverter());
|
||||
legDetailsToShow = new EnumSetSetting<>("legDetailsToShow", this, legDetails, DetailType::valueOf);
|
||||
List<DetailType> raceDetails = new ArrayList<DetailType>();
|
||||
raceDetails.add(DetailType.DISPLAY_LEGS);
|
||||
raceDetailsToShow = new EnumListSetting<>("raceDetailsToShow", this, raceDetails, new DetailTypeStringToEnumConverter());
|
||||
raceDetailsToShow = new EnumSetSetting<>("raceDetailsToShow", this, raceDetails, DetailType::valueOf);
|
||||
List<DetailType> overallDetails = new ArrayList<>();
|
||||
overallDetails.add(DetailType.REGATTA_RANK);
|
||||
overallDetailsToShow = new EnumListSetting<>("overallDetailsToShow", this, overallDetails, new DetailTypeStringToEnumConverter());
|
||||
overallDetailsToShow = new EnumSetSetting<>("overallDetailsToShow", this, overallDetails, DetailType::valueOf);
|
||||
delayBetweenAutoAdvancesInMilliseconds = new LongSetting("delayBetweenAutoAdvancesInMilliseconds", this, LeaderboardEntryPoint.DEFAULT_REFRESH_INTERVAL_MILLIS);
|
||||
activeRaceColumnSelectionStrategy = new EnumSetting<>("activeRaceColumnSelectionStrategy", this, RaceColumnSelectionStrategies.EXPLICIT, new RaceColumnSelectionStrategiesStringToEnumConverter());
|
||||
activeRaceColumnSelectionStrategy = new EnumSetting<>("activeRaceColumnSelectionStrategy", this, RaceColumnSelectionStrategies.EXPLICIT, RaceColumnSelectionStrategies::valueOf);
|
||||
nameOfRaceToSort = new StringSetting("nameOfRaceToSort", this, null);
|
||||
updateUponPlayStateChange = new BooleanSetting("updateUponPlayStateChange", this, true);
|
||||
sortAscending = new BooleanSetting("sortAscending", this, true);
|
||||
@@ -124,35 +123,11 @@ public class LeaderboardSettings extends AbstractGenericSerializableSettings {
|
||||
this.namesOfRaceColumnsToShow.setValues(namesOfRaceColumnsToShow);
|
||||
}
|
||||
|
||||
public LeaderboardSettings(Iterable<String> namesOfRaceColumnsToShow, Long delayBetweenAutoAdvancesInMilliseconds) {
|
||||
this.namesOfRaceColumnsToShow.setValues(namesOfRaceColumnsToShow);
|
||||
this.delayBetweenAutoAdvancesInMilliseconds.setValue(delayBetweenAutoAdvancesInMilliseconds);
|
||||
}
|
||||
|
||||
public LeaderboardSettings(Long delayBetweenAutoAdvancesInMilliseconds, Integer numberOfLastRacesToShow,
|
||||
RaceColumnSelectionStrategies activeRaceColumnSelectionStrategy) {
|
||||
this.delayBetweenAutoAdvancesInMilliseconds.setValue(delayBetweenAutoAdvancesInMilliseconds);
|
||||
this.numberOfLastRacesToShow.setValue(numberOfLastRacesToShow);
|
||||
this.activeRaceColumnSelectionStrategy.setValue(activeRaceColumnSelectionStrategy);
|
||||
}
|
||||
|
||||
public LeaderboardSettings(List<String> namesOfRaceColumnsToShow, List<String> namesOfRacesToShow, List<DetailType> overallDetailsToShow,
|
||||
String nameOfRaceToSort, boolean autoExpandPreSelectedRace,
|
||||
boolean showCompetitorSailIdColumn, boolean showCompetitorFullNameColumn) {
|
||||
this.namesOfRaceColumnsToShow.setValues(namesOfRaceColumnsToShow);
|
||||
this.namesOfRacesToShow.setValues(namesOfRacesToShow);
|
||||
this.overallDetailsToShow.setValues(overallDetailsToShow);
|
||||
this.nameOfRaceToSort.setValue(nameOfRaceToSort);
|
||||
this.autoExpandPreSelectedRace = autoExpandPreSelectedRace;
|
||||
this.showCompetitorSailIdColumn.setValue(showCompetitorSailIdColumn);
|
||||
this.showCompetitorFullNameColumn.setValue(showCompetitorFullNameColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param raceColumnsToShow <code>null</code> means don't modify the list of races shown
|
||||
*/
|
||||
public LeaderboardSettings(List<DetailType> maneuverDetailsToShow, List<DetailType> legDetailsToShow,
|
||||
List<DetailType> raceDetailsToShow, List<DetailType> overallDetailsToShow,
|
||||
public LeaderboardSettings(Collection<DetailType> maneuverDetailsToShow, Collection<DetailType> legDetailsToShow,
|
||||
Collection<DetailType> raceDetailsToShow, Collection<DetailType> overallDetailsToShow,
|
||||
List<String> namesOfRaceColumnsToShow, List<String> namesOfRacesToShow, Integer numberOfLastRacesToShow,
|
||||
boolean autoExpandPreSelectedRace, Long delayBetweenAutoAdvancesInMilliseconds, String nameOfRaceToSort,
|
||||
boolean sortAscending, boolean updateUponPlayStateChange, RaceColumnSelectionStrategies activeRaceColumnSelectionStrategy,
|
||||
@@ -182,32 +157,33 @@ public class LeaderboardSettings extends AbstractGenericSerializableSettings {
|
||||
this.isShowCompetitorNationality.setValue(isCompetitorNationalityColumnVisible);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A live collection that reflects the current state of the settings of a leaderboard panel
|
||||
*/
|
||||
public List<DetailType> getManeuverDetailsToShow() {
|
||||
return Util.createList(maneuverDetailsToShow.getValues());
|
||||
public Collection<DetailType> getManeuverDetailsToShow() {
|
||||
return Util.createSet(maneuverDetailsToShow.getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* A live collection that reflects the current state of the settings of a leaderboard panel
|
||||
*/
|
||||
public List<DetailType> getLegDetailsToShow() {
|
||||
return Util.createList(legDetailsToShow.getValues());
|
||||
public Collection<DetailType> getLegDetailsToShow() {
|
||||
return Util.createSet(legDetailsToShow.getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* A live collection that reflects the current state of the settings of a leaderboard panel
|
||||
*/
|
||||
public List<DetailType> getRaceDetailsToShow() {
|
||||
return Util.createList(raceDetailsToShow.getValues());
|
||||
public Collection<DetailType> getRaceDetailsToShow() {
|
||||
return Util.createSet(raceDetailsToShow.getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* A live collection that reflects the current state of the settings of a leaderboard panel
|
||||
*/
|
||||
public List<DetailType> getOverallDetailsToShow() {
|
||||
return Util.createList(overallDetailsToShow.getValues());
|
||||
public Collection<DetailType> getOverallDetailsToShow() {
|
||||
return Util.createSet(overallDetailsToShow.getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,83 +264,34 @@ public class LeaderboardSettings extends AbstractGenericSerializableSettings {
|
||||
return isShowCompetitorNationality.getValue();
|
||||
}
|
||||
|
||||
void overrideDefaultValues(LeaderboardSettings newDefaults) {
|
||||
autoExpandPreSelectedRace = newDefaults.autoExpandPreSelectedRace;
|
||||
boolean namesOfRaceColumnsToShowWasDefault = Util.equals(namesOfRaceColumnsToShow.getValues(), namesOfRaceColumnsToShow.getDefaultValues());
|
||||
namesOfRaceColumnsToShow.setDefaultValues(newDefaults.namesOfRaceColumnsToShow.getValues());
|
||||
namesOfRacesToShow.setDefaultValues(newDefaults.namesOfRacesToShow.getValues());
|
||||
if(getNamesOfRaceColumnsToShow() != null && getNamesOfRacesToShow() != null) {
|
||||
if(namesOfRaceColumnsToShowWasDefault) {
|
||||
namesOfRaceColumnsToShow.setValues(null);
|
||||
} else {
|
||||
namesOfRacesToShow.setValues(null);
|
||||
}
|
||||
public LeaderboardSettings overrideDefaultsForNamesOfRaceColumns(List<String> namesOfRaceColumns) {
|
||||
LeaderboardSettings newSettings = new LeaderboardSettings();
|
||||
newSettings.legDetailsToShow.setValues(this.getLegDetailsToShow());
|
||||
newSettings.raceDetailsToShow.setValues(this.getRaceDetailsToShow());
|
||||
newSettings.overallDetailsToShow.setValues(this.getOverallDetailsToShow());
|
||||
newSettings.numberOfLastRacesToShow.setValue(this.getNumberOfLastRacesToShow());
|
||||
newSettings.activeRaceColumnSelectionStrategy.setValue(this.getActiveRaceColumnSelectionStrategy());
|
||||
newSettings.autoExpandPreSelectedRace = this.isAutoExpandPreSelectedRace();
|
||||
newSettings.delayBetweenAutoAdvancesInMilliseconds.setValue(this.getDelayBetweenAutoAdvancesInMilliseconds());
|
||||
newSettings.maneuverDetailsToShow.setValues(this.getManeuverDetailsToShow());
|
||||
newSettings.nameOfRaceToSort.setValue(this.getNameOfRaceToSort());
|
||||
newSettings.sortAscending.setValue(this.isSortAscending());
|
||||
newSettings.updateUponPlayStateChange.setValue(this.isUpdateUponPlayStateChange());
|
||||
newSettings.showAddedScores.setValue(this.isShowAddedScores());
|
||||
newSettings.showCompetitorSailIdColumn.setValue(this.isShowCompetitorSailIdColumn());
|
||||
newSettings.showCompetitorFullNameColumn.setValue(this.isShowCompetitorFullNameColumn());
|
||||
newSettings.showOverallColumnWithNumberOfRacesCompletedPerCompetitor.setValue(this.isShowOverallColumnWithNumberOfRacesCompletedPerCompetitor());
|
||||
newSettings.isShowCompetitorNationality.setValue(this.isShowCompetitorNationality());
|
||||
if(namesOfRaceColumns != null && !namesOfRaceColumns.isEmpty()) {
|
||||
newSettings.namesOfRacesToShow.setValues(null);
|
||||
}
|
||||
numberOfLastRacesToShow.setDefaultValue(newDefaults.numberOfLastRacesToShow.getValue());
|
||||
maneuverDetailsToShow.setDefaultValues(newDefaults.maneuverDetailsToShow.getValues());
|
||||
legDetailsToShow.setDefaultValues(newDefaults.legDetailsToShow.getValues());
|
||||
raceDetailsToShow.setDefaultValues(newDefaults.raceDetailsToShow.getValues());
|
||||
overallDetailsToShow.setDefaultValues(newDefaults.overallDetailsToShow.getValues());
|
||||
delayBetweenAutoAdvancesInMilliseconds.setDefaultValue(newDefaults.delayBetweenAutoAdvancesInMilliseconds.getValue());
|
||||
activeRaceColumnSelectionStrategy.setDefaultValue(newDefaults.activeRaceColumnSelectionStrategy.getValue());
|
||||
nameOfRaceToSort.setDefaultValue(newDefaults.nameOfRaceToSort.getValue());
|
||||
updateUponPlayStateChange.setDefaultValue(newDefaults.updateUponPlayStateChange.getValue());
|
||||
sortAscending.setDefaultValue(newDefaults.sortAscending.getValue());
|
||||
showAddedScores.setDefaultValue(newDefaults.showAddedScores.getValue());
|
||||
showCompetitorSailIdColumn.setDefaultValue(newDefaults.showCompetitorSailIdColumn.getValue());
|
||||
showCompetitorFullNameColumn.setDefaultValue(newDefaults.showCompetitorFullNameColumn.getValue());
|
||||
showOverallColumnWithNumberOfRacesCompletedPerCompetitor.setDefaultValue(newDefaults.showOverallColumnWithNumberOfRacesCompletedPerCompetitor.getValue());
|
||||
isShowCompetitorNationality.setDefaultValue(newDefaults.isShowCompetitorNationality.getValue());
|
||||
newSettings.namesOfRaceColumnsToShow.setValues(this.getNamesOfRaceColumnsToShow());
|
||||
SettingsDefaultValuesUtils.keepDefaults(this, newSettings);
|
||||
if(namesOfRaceColumns != null && !namesOfRaceColumns.isEmpty()) {
|
||||
newSettings.namesOfRacesToShow.setDefaultValues(null);
|
||||
}
|
||||
newSettings.namesOfRaceColumnsToShow.setDefaultValues(namesOfRaceColumns);
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
void setValues(LeaderboardSettings settingsWithCustomValues) {
|
||||
this.legDetailsToShow.setValues(settingsWithCustomValues.getLegDetailsToShow());
|
||||
this.raceDetailsToShow.setValues(settingsWithCustomValues.getRaceDetailsToShow());
|
||||
this.overallDetailsToShow.setValues(settingsWithCustomValues.getOverallDetailsToShow());
|
||||
this.namesOfRacesToShow.setValues(settingsWithCustomValues.getNamesOfRacesToShow());
|
||||
this.namesOfRaceColumnsToShow.setValues(settingsWithCustomValues.getNamesOfRaceColumnsToShow());
|
||||
this.numberOfLastRacesToShow.setValue(settingsWithCustomValues.getNumberOfLastRacesToShow());
|
||||
this.activeRaceColumnSelectionStrategy.setValue(settingsWithCustomValues.getActiveRaceColumnSelectionStrategy());
|
||||
this.autoExpandPreSelectedRace = settingsWithCustomValues.isAutoExpandPreSelectedRace();
|
||||
this.delayBetweenAutoAdvancesInMilliseconds.setValue(settingsWithCustomValues.getDelayBetweenAutoAdvancesInMilliseconds());
|
||||
this.maneuverDetailsToShow.setValues(settingsWithCustomValues.getManeuverDetailsToShow());
|
||||
this.nameOfRaceToSort.setValue(settingsWithCustomValues.getNameOfRaceToSort());
|
||||
this.sortAscending.setValue(settingsWithCustomValues.isSortAscending());
|
||||
this.updateUponPlayStateChange.setValue(settingsWithCustomValues.isUpdateUponPlayStateChange());
|
||||
this.showAddedScores.setValue(settingsWithCustomValues.isShowAddedScores());
|
||||
this.showCompetitorSailIdColumn.setValue(settingsWithCustomValues.isShowCompetitorSailIdColumn());
|
||||
this.showCompetitorFullNameColumn.setValue(settingsWithCustomValues.isShowCompetitorFullNameColumn());
|
||||
this.isShowCompetitorNationality.setValue(settingsWithCustomValues.isShowCompetitorNationality());
|
||||
this.showOverallColumnWithNumberOfRacesCompletedPerCompetitor.setValue(settingsWithCustomValues.isShowOverallColumnWithNumberOfRacesCompletedPerCompetitor());
|
||||
}
|
||||
|
||||
public LeaderboardSettings getDefaultSettings() {
|
||||
LeaderboardSettings leaderboardSettings = new LeaderboardSettings();
|
||||
leaderboardSettings.legDetailsToShow.setDefaultValues(legDetailsToShow.getDefaultValues());
|
||||
leaderboardSettings.raceDetailsToShow.setDefaultValues(raceDetailsToShow.getDefaultValues());
|
||||
leaderboardSettings.overallDetailsToShow.setDefaultValues(overallDetailsToShow.getDefaultValues());
|
||||
leaderboardSettings.namesOfRacesToShow.setDefaultValues(namesOfRacesToShow.getDefaultValues());
|
||||
leaderboardSettings.namesOfRaceColumnsToShow.setDefaultValues(namesOfRaceColumnsToShow.getDefaultValues());
|
||||
leaderboardSettings.numberOfLastRacesToShow.setDefaultValue(numberOfLastRacesToShow.getDefaultValue());
|
||||
leaderboardSettings.activeRaceColumnSelectionStrategy.setDefaultValue(activeRaceColumnSelectionStrategy.getDefaultValue());
|
||||
leaderboardSettings.autoExpandPreSelectedRace = autoExpandPreSelectedRace;
|
||||
leaderboardSettings.delayBetweenAutoAdvancesInMilliseconds.setDefaultValue(delayBetweenAutoAdvancesInMilliseconds.getDefaultValue());
|
||||
leaderboardSettings.maneuverDetailsToShow.setDefaultValues(maneuverDetailsToShow.getDefaultValues());
|
||||
leaderboardSettings.nameOfRaceToSort.setDefaultValue(nameOfRaceToSort.getDefaultValue());
|
||||
leaderboardSettings.sortAscending.setDefaultValue(sortAscending.getDefaultValue());
|
||||
leaderboardSettings.updateUponPlayStateChange.setDefaultValue(updateUponPlayStateChange.getDefaultValue());
|
||||
leaderboardSettings.showAddedScores.setDefaultValue(showAddedScores.getDefaultValue());
|
||||
leaderboardSettings.showCompetitorSailIdColumn.setDefaultValue(showCompetitorSailIdColumn.getDefaultValue());
|
||||
leaderboardSettings.showCompetitorFullNameColumn.setDefaultValue(showCompetitorFullNameColumn.getDefaultValue());
|
||||
leaderboardSettings.showOverallColumnWithNumberOfRacesCompletedPerCompetitor.setDefaultValue(showOverallColumnWithNumberOfRacesCompletedPerCompetitor.getDefaultValue());
|
||||
leaderboardSettings.isShowCompetitorNationality.setDefaultValue(isShowCompetitorNationality.getDefaultValue());
|
||||
return leaderboardSettings;
|
||||
}
|
||||
|
||||
public static LeaderboardSettings createDefaultSettings(Collection<String> defaultNamesOfRaceColumnsToShow) {
|
||||
LeaderboardSettings leaderboardSettings = new LeaderboardSettings();
|
||||
leaderboardSettings.namesOfRaceColumnsToShow.setDefaultValues(defaultNamesOfRaceColumnsToShow);
|
||||
|
||||
return leaderboardSettings;
|
||||
}
|
||||
}
|
||||
+9
-6
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.gwt.settings.client.leaderboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -29,6 +30,7 @@ import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LegColumn;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.ManeuverCountRaceColumn;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.settings.util.SettingsDefaultValuesUtils;
|
||||
import com.sap.sse.gwt.client.controls.IntegerBox;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog.Validator;
|
||||
@@ -89,7 +91,7 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
meneuverPanel.addStyleName("SettingsDialogComponent");
|
||||
FlowPanel meneuverContent = new FlowPanel();
|
||||
meneuverContent.addStyleName("dialogInnerContent");
|
||||
List<DetailType> currentMeneuverDetailSelection = initialSettings.getManeuverDetailsToShow();
|
||||
Collection<DetailType> currentMeneuverDetailSelection = initialSettings.getManeuverDetailsToShow();
|
||||
for (DetailType detailType : ManeuverCountRaceColumn.getAvailableManeuverDetailColumnTypes()) {
|
||||
CheckBox checkbox = createAndRegisterCheckbox(dialog, detailType,
|
||||
currentMeneuverDetailSelection.contains(detailType), maneuverDetailCheckboxes);
|
||||
@@ -131,7 +133,7 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
raceDetailDialog.add(dialog.createHeadline(stringMessages.raceDetailsToShow(), true));
|
||||
raceDetailDialog.addStyleName("SettingsDialogComponent");
|
||||
int detailCountInCurrentFlowPanel = 0;
|
||||
List<DetailType> currentRaceDetailSelection = initialSettings.getRaceDetailsToShow();
|
||||
Collection<DetailType> currentRaceDetailSelection = initialSettings.getRaceDetailsToShow();
|
||||
FlowPanel raceDetailDialogContent = null;
|
||||
for (DetailType type : LeaderboardPanel.getAvailableRaceDetailColumnTypes()) {
|
||||
if (detailCountInCurrentFlowPanel % 8 == 0) {
|
||||
@@ -161,7 +163,7 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
raceStartAnalysisDialog.add(dialog.createHeadline(stringMessages.raceStartAnalysis(), true));
|
||||
raceStartAnalysisDialog.addStyleName("SettingsDialogComponent");
|
||||
int detailCountInCurrentFlowPanel = 0;
|
||||
List<DetailType> currentRaceDetailSelection = initialSettings.getRaceDetailsToShow();
|
||||
Collection<DetailType> currentRaceDetailSelection = initialSettings.getRaceDetailsToShow();
|
||||
FlowPanel raceStartAnalysisDialogContent = null;
|
||||
for (DetailType type : LeaderboardPanel.getAvailableRaceStartAnalysisColumnTypes()) {
|
||||
if (detailCountInCurrentFlowPanel % 8 == 0) {
|
||||
@@ -184,7 +186,7 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
overallDetailDialog.addStyleName("SettingsDialogComponent overallDetailSettings");
|
||||
FlowPanel overallDetailDialogContent = new FlowPanel();
|
||||
overallDetailDialogContent.addStyleName("dialogInnerContent");
|
||||
List<DetailType> currentOverallDetailSelection = initialSettings.getOverallDetailsToShow();
|
||||
Collection<DetailType> currentOverallDetailSelection = initialSettings.getOverallDetailsToShow();
|
||||
for (DetailType type : LeaderboardPanel.getAvailableOverallDetailColumnTypes()) {
|
||||
CheckBox checkbox = createAndRegisterCheckbox(dialog, type, currentOverallDetailSelection.contains(type),
|
||||
overallDetailCheckboxes);
|
||||
@@ -220,7 +222,7 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
legDetailsToShow.add(dialog.createHeadline(stringMessages.legDetailsToShow(), true));
|
||||
legDetailsToShow.addStyleName("SettingsDialogComponent");
|
||||
FlowPanel legDetailsContent = null;
|
||||
List<DetailType> currentLegDetailSelection = initialSettings.getLegDetailsToShow();
|
||||
Collection<DetailType> currentLegDetailSelection = initialSettings.getLegDetailsToShow();
|
||||
int detailCountInCurrentFlowPanel = 0;
|
||||
for (DetailType type : LegColumn.getAvailableLegDetailColumnTypes()) {
|
||||
if (detailCountInCurrentFlowPanel % 8 == 0) {
|
||||
@@ -402,7 +404,8 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
/*showOverallColumnWithNumberOfRacesSailedPerCompetitor*/ showOverallColumnWithNumberOfRacesSailedPerCompetitorCheckBox.getValue().booleanValue(),
|
||||
showCompetitorSailIdColumnheckBox.getValue(), showCompetitorFullNameColumnCheckBox.getValue(),
|
||||
isCompetitorNationalityColumnVisible.getValue());
|
||||
return LeaderboardSettingsFactory.getInstance().keepDefaults(initialSettings, newSettings);
|
||||
SettingsDefaultValuesUtils.keepDefaults(initialSettings, newSettings);
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+51
-189
@@ -1,14 +1,14 @@
|
||||
package com.sap.sailing.gwt.settings.client.leaderboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings.RaceColumnSelectionStrategies;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.common.settings.generic.support.SettingsUtil;
|
||||
import com.sap.sse.common.settings.util.SettingsDefaultValuesUtils;
|
||||
|
||||
/**
|
||||
* A factory class creating leaderboard settings for different contexts (user role, live or replay mode, etc.
|
||||
@@ -16,201 +16,71 @@ import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
public class LeaderboardSettingsFactory {
|
||||
private static LeaderboardSettingsFactory instance;
|
||||
|
||||
public synchronized static LeaderboardSettingsFactory getInstance() {
|
||||
public static LeaderboardSettingsFactory getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new LeaderboardSettingsFactory();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nameOfRaceToSort
|
||||
* if <code>null</code>, don't sort any race column
|
||||
* @param nameOfRaceColumnToShow
|
||||
* if <code>null</code>, the settings returned will cause the list of race columns shown to remain
|
||||
* unchanged during {@link LeaderboardPanel#updateSettings(LeaderboardSettings)}; otherwise, the settings
|
||||
* will show the single race column identified by this argument
|
||||
* @param nameOfRaceToShow
|
||||
* alternatively to <code>nameOfRaceColumnToShow</code>, this argument may be used in case the race name
|
||||
* is known, but its column name is not. If <code>null</code>, and <code>nameOfRaceColumnToShow</code> is
|
||||
* also <code>null</code>, no change to the selected race columns will happen while updating the
|
||||
* leaderboard settings. It is an error to pass non-<code>null</code> values for both,
|
||||
* <code>nameOfRaceColumnToShow</code> <em>and</em> <code>nameOfRaceToShow</code>, and an
|
||||
* {@link IllegalArgumentException} will be thrown in this case.
|
||||
* @param raceColumnSelection
|
||||
* the settings will be constructed such that the new settings will have the same race columns selected
|
||||
* as those selected by this argument
|
||||
* @param showRegattaRank
|
||||
* if <code>null</code>, the overall detail settings that are responsible for deciding whether or not to
|
||||
* show the regatta rank are left unchanged; otherwise, a non-<code>null</code> overall details
|
||||
* collection will be put to the settings and the {@link DetailType#REGATTA_RANK} will be added to the
|
||||
* overall details if and only if this parameter is <code>true</code>
|
||||
* @param raceColumnSelectionType
|
||||
* @param raceColumnSelection
|
||||
*/
|
||||
public LeaderboardSettings createNewSettingsForPlayMode(PlayModes playMode, String nameOfRaceToSort, String nameOfRaceColumnToShow,
|
||||
String nameOfRaceToShow, boolean showRegattaRank, boolean showCompetitorSailIdColumn,
|
||||
boolean showCompetitorNameColumn, Integer raceColumnSelectionNumber,
|
||||
RaceColumnSelectionStrategies raceColumnSelectionType) {
|
||||
if (nameOfRaceColumnToShow != null && nameOfRaceToShow != null) {
|
||||
throw new IllegalArgumentException("Can identify only one race to show, either by race name or by its column name, but not both");
|
||||
}
|
||||
LeaderboardSettings settings = null;
|
||||
List<String> namesOfRaceColumnsToShow = nameOfRaceColumnToShow == null ? null : Collections.singletonList(nameOfRaceColumnToShow);
|
||||
List<String> namesOfRacesToShow = nameOfRaceToShow == null ? null : Collections.singletonList(nameOfRaceToShow);
|
||||
switch (playMode) {
|
||||
case Live:
|
||||
List<DetailType> maneuverDetails = new ArrayList<DetailType>();
|
||||
maneuverDetails.add(DetailType.TACK);
|
||||
maneuverDetails.add(DetailType.JIBE);
|
||||
maneuverDetails.add(DetailType.PENALTY_CIRCLE);
|
||||
List<DetailType> legDetails = new ArrayList<DetailType>();
|
||||
legDetails.add(DetailType.DISTANCE_TRAVELED);
|
||||
legDetails.add(DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
legDetails.add(DetailType.ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS);
|
||||
legDetails.add(DetailType.RANK_GAIN);
|
||||
List<DetailType> raceDetails = new ArrayList<DetailType>();
|
||||
raceDetails.add(DetailType.RACE_DISTANCE_TRAVELED);
|
||||
raceDetails.add(DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
raceDetails.add(DetailType.RACE_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD_IN_METERS);
|
||||
raceDetails.add(DetailType.NUMBER_OF_MANEUVERS);
|
||||
raceDetails.add(DetailType.DISPLAY_LEGS);
|
||||
final List<DetailType> overallDetails = createOverallDetailsForShowRegattaRank(showRegattaRank);
|
||||
settings = new LeaderboardSettings(maneuverDetails, legDetails, raceDetails, overallDetails,
|
||||
namesOfRaceColumnsToShow,
|
||||
namesOfRacesToShow, raceColumnSelectionNumber,
|
||||
/* set autoExpandPreSelectedRace to true if we look at a single race */ nameOfRaceColumnToShow != null || nameOfRaceToShow != null,
|
||||
/* refresh interval */ null, /* name of race to sort */ nameOfRaceToSort,
|
||||
/* ascending */ true, /* updateUponPlayStateChange */ true, raceColumnSelectionType,
|
||||
/*showAddedScores*/ false, /*showOverallRacesCompleted*/ false,
|
||||
showCompetitorSailIdColumn, showCompetitorNameColumn, false);
|
||||
break;
|
||||
case Replay:
|
||||
settings = createNewDefaultSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, nameOfRaceToSort, /* autoExpandFirstRace */
|
||||
nameOfRaceColumnToShow != null, showRegattaRank, showCompetitorSailIdColumn, showCompetitorNameColumn);
|
||||
break;
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param showRegattaRank
|
||||
* Puts overall details
|
||||
* collection to the settings and adds {@link DetailType#REGATTA_RANK} to the
|
||||
* overall details if and only if this parameter is <code>true</code>
|
||||
*/
|
||||
private List<DetailType> createOverallDetailsForShowRegattaRank(boolean showRegattaRank) {
|
||||
final List<DetailType> overallDetails = new ArrayList<>();
|
||||
if (showRegattaRank) {
|
||||
overallDetails.add(DetailType.REGATTA_RANK);
|
||||
}
|
||||
return overallDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param namesOfRaceColumnsToShow
|
||||
* if <code>null</code>, create settings which leave the list of races to show unchanged when applied
|
||||
* using {@link LeaderboardPanel#updateSettings(LeaderboardSettings)}; otherwise, the list of names of
|
||||
* the race columns (not their races!) that will be shown, so that, e.g., an empty list causes no race
|
||||
* columns to be shown
|
||||
* @param namesOfRacesToShow
|
||||
* alternatively, races to show can also be specified by their race names; if not <code>null</code>,
|
||||
* <code>namesOfRaceColumnsToShow</code> must be <code>null</code>
|
||||
* @param showRegattaRank
|
||||
* if <code>null</code>, the overall detail settings that are responsible for deciding whether or not to
|
||||
* show the regatta rank are left unchanged; otherwise, a non-<code>null</code> overall details
|
||||
* collection will be put to the settings and the {@link DetailType#REGATTA_RANK} will be added to the
|
||||
* overall details if and only if this parameter is <code>true</code>
|
||||
*/
|
||||
private LeaderboardSettings createNewDefaultSettings(List<String> namesOfRaceColumnsToShow,
|
||||
List<String> namesOfRacesToShow, String nameOfRaceToSort, boolean autoExpandPreSelectedRace, Boolean showRegattaRank,
|
||||
boolean showCompetitorSailIdColumn, boolean showCompetitorFullNameColumn) {
|
||||
final List<DetailType> overallDetails = createOverallDetailsForShowRegattaRank(showRegattaRank);
|
||||
return new LeaderboardSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, overallDetails,
|
||||
nameOfRaceToSort, autoExpandPreSelectedRace,
|
||||
showCompetitorSailIdColumn, showCompetitorFullNameColumn);
|
||||
}
|
||||
|
||||
public LeaderboardSettings createNewSettingsWithCustomDefaults(LeaderboardSettings customDefaultSettings, LeaderboardSettings settingsWithCustomValues) {
|
||||
LeaderboardSettings leaderboardSettings = new LeaderboardSettings();
|
||||
leaderboardSettings.overrideDefaultValues(customDefaultSettings);
|
||||
leaderboardSettings.setValues(settingsWithCustomValues);
|
||||
public LeaderboardSettings createNewDefaultSettingsWithRaceColumns(List<String> namesOfRaceColumns) {
|
||||
LeaderboardSettings leaderboardSettings = new LeaderboardSettings(namesOfRaceColumns);
|
||||
SettingsUtil.copyDefaultsFromValues(leaderboardSettings, leaderboardSettings);
|
||||
return leaderboardSettings;
|
||||
}
|
||||
|
||||
public LeaderboardSettings createNewSettingsWithCustomDefaults(LeaderboardSettings customDefaultSettings) {
|
||||
LeaderboardSettings leaderboardSettings = new LeaderboardSettings();
|
||||
leaderboardSettings.overrideDefaultValues(customDefaultSettings);
|
||||
return leaderboardSettings;
|
||||
|
||||
public LeaderboardSettings createNewSettingsWithCustomRaceDetails(List<DetailType> raceDetailsToShow) {
|
||||
LeaderboardSettings defaultSettings = new LeaderboardSettings();
|
||||
return new LeaderboardSettings(
|
||||
defaultSettings.getManeuverDetailsToShow(),
|
||||
defaultSettings.getLegDetailsToShow(),
|
||||
raceDetailsToShow, defaultSettings.getOverallDetailsToShow(),
|
||||
Util.cloneListOrNull(defaultSettings.getNamesOfRaceColumnsToShow()),
|
||||
Util.cloneListOrNull(defaultSettings.getNamesOfRacesToShow()),
|
||||
defaultSettings.getNumberOfLastRacesToShow(),
|
||||
defaultSettings.isAutoExpandPreSelectedRace(),
|
||||
defaultSettings.getDelayBetweenAutoAdvancesInMilliseconds(),
|
||||
defaultSettings.getNameOfRaceToSort(), defaultSettings.isSortAscending(),
|
||||
defaultSettings.isUpdateUponPlayStateChange(),
|
||||
defaultSettings.getActiveRaceColumnSelectionStrategy(),
|
||||
defaultSettings.isShowAddedScores(),
|
||||
defaultSettings.isShowOverallColumnWithNumberOfRacesCompletedPerCompetitor(),
|
||||
defaultSettings.isShowCompetitorSailIdColumn(),
|
||||
defaultSettings.isShowCompetitorFullNameColumn(),
|
||||
defaultSettings.isShowCompetitorNationality());
|
||||
}
|
||||
|
||||
public LeaderboardSettings overrideDefaultValuesWithNewDefaults(LeaderboardSettings settingsWithCustomValues, LeaderboardSettings customDefaultSettings) {
|
||||
LeaderboardSettings leaderboardSettings = new LeaderboardSettings();
|
||||
leaderboardSettings.setValues(settingsWithCustomValues);
|
||||
leaderboardSettings.overrideDefaultValues(customDefaultSettings);
|
||||
return leaderboardSettings;
|
||||
}
|
||||
|
||||
public LeaderboardSettings keepDefaults(LeaderboardSettings previousSettings, LeaderboardSettings newSettings) {
|
||||
LeaderboardSettings leaderboardSettings = previousSettings.getDefaultSettings();
|
||||
leaderboardSettings.setValues(newSettings);
|
||||
return leaderboardSettings;
|
||||
}
|
||||
|
||||
public LeaderboardSettings overrideDefaultValuesForRaceDetails(LeaderboardSettings existingSettings, List<DetailType> newRaceDetailsDefaultValues) {
|
||||
LeaderboardSettings newSettings = new LeaderboardSettings(
|
||||
Util.cloneListOrNull(existingSettings.getManeuverDetailsToShow()),
|
||||
Util.cloneListOrNull(existingSettings.getLegDetailsToShow()),
|
||||
newRaceDetailsDefaultValues, Util.cloneListOrNull(existingSettings.getOverallDetailsToShow()),
|
||||
Util.cloneListOrNull(existingSettings.getNamesOfRaceColumnsToShow()),
|
||||
Util.cloneListOrNull(existingSettings.getNamesOfRacesToShow()),
|
||||
existingSettings.getNumberOfLastRacesToShow(), /* auto-expand pre-selected race */ true,
|
||||
existingSettings.getDelayBetweenAutoAdvancesInMilliseconds(),
|
||||
existingSettings.getNameOfRaceToSort(), existingSettings.isSortAscending(),
|
||||
existingSettings.isUpdateUponPlayStateChange(),
|
||||
existingSettings.getActiveRaceColumnSelectionStrategy(),
|
||||
existingSettings.isShowAddedScores(),
|
||||
existingSettings.isShowOverallColumnWithNumberOfRacesCompletedPerCompetitor(),
|
||||
existingSettings.isShowCompetitorSailIdColumn(),
|
||||
existingSettings.isShowCompetitorFullNameColumn(),
|
||||
existingSettings.isShowCompetitorNationality());
|
||||
|
||||
final LeaderboardSettings existingDefaultSettings = existingSettings.getDefaultSettings();
|
||||
|
||||
LeaderboardSettings newDefaultSettings = new LeaderboardSettings(
|
||||
Util.cloneListOrNull(existingDefaultSettings.getManeuverDetailsToShow()),
|
||||
Util.cloneListOrNull(existingDefaultSettings.getLegDetailsToShow()),
|
||||
newRaceDetailsDefaultValues, Util.cloneListOrNull(existingDefaultSettings.getOverallDetailsToShow()),
|
||||
Util.cloneListOrNull(existingDefaultSettings.getNamesOfRaceColumnsToShow()),
|
||||
Util.cloneListOrNull(existingDefaultSettings.getNamesOfRacesToShow()),
|
||||
existingDefaultSettings.getNumberOfLastRacesToShow(), /* auto-expand pre-selected race */ true,
|
||||
existingDefaultSettings.getDelayBetweenAutoAdvancesInMilliseconds(),
|
||||
existingDefaultSettings.getNameOfRaceToSort(), existingDefaultSettings.isSortAscending(),
|
||||
existingDefaultSettings.isUpdateUponPlayStateChange(),
|
||||
existingDefaultSettings.getActiveRaceColumnSelectionStrategy(),
|
||||
existingDefaultSettings.isShowAddedScores(),
|
||||
existingDefaultSettings.isShowOverallColumnWithNumberOfRacesCompletedPerCompetitor(),
|
||||
existingDefaultSettings.isShowCompetitorSailIdColumn(),
|
||||
existingDefaultSettings.isShowCompetitorFullNameColumn(),
|
||||
existingSettings.isShowCompetitorNationality());
|
||||
|
||||
newDefaultSettings = LeaderboardSettingsFactory.getInstance().createNewSettingsWithCustomDefaults(newDefaultSettings);
|
||||
|
||||
newSettings = LeaderboardSettingsFactory.getInstance().keepDefaults(newDefaultSettings, newSettings);
|
||||
return newSettings;
|
||||
public LeaderboardSettings createSettingsWithCustomExpandPreselectedRaceState(LeaderboardSettings settings, boolean expandPreselectedRace) {
|
||||
return new LeaderboardSettings(
|
||||
settings.getManeuverDetailsToShow(),
|
||||
settings.getLegDetailsToShow(),
|
||||
settings.getRaceDetailsToShow(), settings.getOverallDetailsToShow(),
|
||||
Util.cloneListOrNull(settings.getNamesOfRaceColumnsToShow()),
|
||||
Util.cloneListOrNull(settings.getNamesOfRacesToShow()),
|
||||
settings.getNumberOfLastRacesToShow(), expandPreselectedRace,
|
||||
settings.getDelayBetweenAutoAdvancesInMilliseconds(),
|
||||
settings.getNameOfRaceToSort(), settings.isSortAscending(),
|
||||
settings.isUpdateUponPlayStateChange(),
|
||||
settings.getActiveRaceColumnSelectionStrategy(),
|
||||
settings.isShowAddedScores(),
|
||||
settings.isShowOverallColumnWithNumberOfRacesCompletedPerCompetitor(),
|
||||
settings.isShowCompetitorSailIdColumn(),
|
||||
settings.isShowCompetitorFullNameColumn(),
|
||||
settings.isShowCompetitorNationality());
|
||||
}
|
||||
|
||||
public LeaderboardSettings mergeLeaderboardSettings(LeaderboardSettings settingsWithRaceSelection, LeaderboardSettings settingsWithDetails) {
|
||||
LeaderboardSettings newSettings = mergeLeaderboardSettingsHelper(settingsWithRaceSelection, settingsWithDetails);
|
||||
LeaderboardSettings newDefaultSettings = mergeLeaderboardSettingsHelper(settingsWithRaceSelection.getDefaultSettings(), settingsWithDetails.getDefaultSettings());
|
||||
return keepDefaults(newDefaultSettings, newSettings);
|
||||
LeaderboardSettings newDefaultSettings = mergeLeaderboardSettingsHelper(SettingsDefaultValuesUtils.getDefaultSettings(new LeaderboardSettings(), settingsWithRaceSelection), SettingsDefaultValuesUtils.getDefaultSettings(new LeaderboardSettings(), settingsWithDetails));
|
||||
SettingsDefaultValuesUtils.keepDefaults(newDefaultSettings, newSettings);
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
private LeaderboardSettings mergeLeaderboardSettingsHelper(LeaderboardSettings settingsWithRaceSelection, LeaderboardSettings settingsWithDetails) {
|
||||
List<DetailType> maneuverDetails = copyDetailTypes(settingsWithDetails.getManeuverDetailsToShow());
|
||||
List<DetailType> legDetails = copyDetailTypes(settingsWithDetails.getLegDetailsToShow());
|
||||
List<DetailType> raceDetails = copyDetailTypes(settingsWithDetails.getRaceDetailsToShow());
|
||||
List<DetailType> overallDetailsToShow = copyDetailTypes(settingsWithDetails.getOverallDetailsToShow());
|
||||
Collection<DetailType> maneuverDetails = settingsWithDetails.getManeuverDetailsToShow();
|
||||
Collection<DetailType> legDetails = settingsWithDetails.getLegDetailsToShow();
|
||||
Collection<DetailType> raceDetails = settingsWithDetails.getRaceDetailsToShow();
|
||||
Collection<DetailType> overallDetailsToShow = settingsWithDetails.getOverallDetailsToShow();
|
||||
Long refreshIntervalInMs = settingsWithDetails.getDelayBetweenAutoAdvancesInMilliseconds();
|
||||
|
||||
RaceColumnSelectionStrategies strategy = settingsWithRaceSelection.getActiveRaceColumnSelectionStrategy();
|
||||
@@ -231,14 +101,6 @@ public class LeaderboardSettingsFactory {
|
||||
settingsWithRaceSelection.isShowCompetitorNationality());
|
||||
}
|
||||
|
||||
private List<DetailType> copyDetailTypes(List<DetailType> detailTypes) {
|
||||
List<DetailType> result = null;
|
||||
if(detailTypes != null) {
|
||||
result = new ArrayList<DetailType>(detailTypes);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<String> copyRaceNamesList(List<String> raceNames) {
|
||||
List<String> result = null;
|
||||
if(raceNames != null) {
|
||||
|
||||
+7
-4
@@ -7,13 +7,12 @@ public class MetaLeaderboardPerspectiveLifecycle extends AbstractLeaderboardPers
|
||||
|
||||
public static final String ID = "mlbh";
|
||||
|
||||
public MetaLeaderboardPerspectiveLifecycle(StringMessages stringMessages) {
|
||||
this(stringMessages, null);
|
||||
}
|
||||
private final MultiLeaderboardPanelLifecycle multiLeaderboardPanelLifecycle;
|
||||
|
||||
public MetaLeaderboardPerspectiveLifecycle(StringMessages stringMessages, AbstractLeaderboardDTO leaderboard) {
|
||||
super(stringMessages, leaderboard, true);
|
||||
addLifeCycle(new MultiLeaderboardPanelLifecycle(null, stringMessages));
|
||||
multiLeaderboardPanelLifecycle = new MultiLeaderboardPanelLifecycle(null, stringMessages);
|
||||
addLifeCycle(multiLeaderboardPanelLifecycle);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -25,4 +24,8 @@ public class MetaLeaderboardPerspectiveLifecycle extends AbstractLeaderboardPers
|
||||
public String getComponentId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public MultiLeaderboardPanelLifecycle getMultiLeaderboardPanelLifecycle() {
|
||||
return multiLeaderboardPanelLifecycle;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -44,13 +44,13 @@ public class MultiCompetitorLeaderboardChartLifecycle implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiCompetitorLeaderboardChartSettings extractGlobalSettings(
|
||||
public MultiCompetitorLeaderboardChartSettings extractUserSettings(
|
||||
MultiCompetitorLeaderboardChartSettings settings) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiCompetitorLeaderboardChartSettings extractContextSpecificSettings(
|
||||
public MultiCompetitorLeaderboardChartSettings extractDocumentSettings(
|
||||
MultiCompetitorLeaderboardChartSettings settings) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ public class MultiLeaderboardPanelLifecycle extends LeaderboardPanelLifecycle {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderboardSettings extractContextSpecificSettings(LeaderboardSettings leaderboardSettings) {
|
||||
public LeaderboardSettings extractDocumentSettings(LeaderboardSettings leaderboardSettings) {
|
||||
return createDefaultSettings();
|
||||
}
|
||||
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
package com.sap.sailing.gwt.settings.client.settingtypes.converter;
|
||||
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sse.common.settings.generic.StringToEnumConverter;
|
||||
|
||||
public class DetailTypeStringToEnumConverter implements StringToEnumConverter<DetailType> {
|
||||
|
||||
@Override
|
||||
public DetailType fromString(String stringValue) {
|
||||
return DetailType.valueOf(stringValue);
|
||||
}
|
||||
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
package com.sap.sailing.gwt.settings.client.settingtypes.converter;
|
||||
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapHelpLinesSettings.HelpLineTypes;
|
||||
import com.sap.sse.common.settings.generic.StringToEnumConverter;
|
||||
|
||||
public class HelpLineTypesStringToEnumConverter implements StringToEnumConverter<HelpLineTypes> {
|
||||
|
||||
@Override
|
||||
public HelpLineTypes fromString(String stringValue) {
|
||||
return HelpLineTypes.valueOf(stringValue);
|
||||
}
|
||||
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
package com.sap.sailing.gwt.settings.client.settingtypes.converter;
|
||||
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sse.common.settings.generic.StringToEnumConverter;
|
||||
|
||||
public class ManeuverTypeStringToEnumConverter implements StringToEnumConverter<ManeuverType> {
|
||||
|
||||
@Override
|
||||
public ManeuverType fromString(String stringValue) {
|
||||
return ManeuverType.valueOf(stringValue);
|
||||
}
|
||||
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
package com.sap.sailing.gwt.settings.client.settingtypes.converter;
|
||||
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings.RaceColumnSelectionStrategies;
|
||||
import com.sap.sse.common.settings.generic.StringToEnumConverter;
|
||||
|
||||
public class RaceColumnSelectionStrategiesStringToEnumConverter implements StringToEnumConverter<RaceColumnSelectionStrategies> {
|
||||
|
||||
@Override
|
||||
public RaceColumnSelectionStrategies fromString(String stringValue) {
|
||||
return RaceColumnSelectionStrategies.valueOf(stringValue);
|
||||
}
|
||||
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
package com.sap.sailing.gwt.settings.client.settingtypes.converter;
|
||||
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sse.common.settings.generic.StringToEnumConverter;
|
||||
|
||||
public class WindSourceTypeStringToEnumConverter implements StringToEnumConverter<WindSourceType> {
|
||||
|
||||
@Override
|
||||
public WindSourceType fromString(String stringValue) {
|
||||
return WindSourceType.valueOf(stringValue);
|
||||
}
|
||||
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
package com.sap.sailing.gwt.settings.client.settingtypes.converter;
|
||||
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapZoomSettings.ZoomTypes;
|
||||
import com.sap.sse.common.settings.generic.StringToEnumConverter;
|
||||
|
||||
public class ZoomTypesStringToEnumConverter implements StringToEnumConverter<ZoomTypes> {
|
||||
|
||||
@Override
|
||||
public ZoomTypes fromString(String stringValue) {
|
||||
return ZoomTypes.valueOf(stringValue);
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.sap.sailing.gwt.settings.client.utils;
|
||||
|
||||
import com.sap.sailing.gwt.ui.shared.settings.SailingSettingsConstants;
|
||||
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
|
||||
|
||||
public class SailingStoredSettingsLocation extends StoredSettingsLocation {
|
||||
|
||||
/**
|
||||
* @see com.sap.sse.security.ui.settings.StoredSettingsLocation#StoredSettingsLocation(String, String)
|
||||
*/
|
||||
public SailingStoredSettingsLocation(String userSettingsIdPart, String documentSettingsIdPart) {
|
||||
super(SailingSettingsConstants.USER_SETTINGS_UI, userSettingsIdPart, documentSettingsIdPart);
|
||||
}
|
||||
|
||||
}
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
package com.sap.sailing.gwt.settings.client.utils;
|
||||
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardContextDefinition;
|
||||
import com.sap.sailing.gwt.settings.client.raceboard.RaceboardContextDefinition;
|
||||
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaOverviewContextDefinition;
|
||||
import com.sap.sse.security.ui.settings.StorageDefinitionId;
|
||||
|
||||
public class StorageDefinitionIdFactory {
|
||||
|
||||
private StorageDefinitionIdFactory() {
|
||||
}
|
||||
|
||||
private static final String RACEBOARD = "Raceboard";
|
||||
private static final String LEADERBOARD = "Leaderboard";
|
||||
private static final String REGATTA_OVERVIEW = "RegattaOverview";
|
||||
private static final String EVENT_REGATTA_LEADERBOARD = "EventRegattaLeaderboard";
|
||||
private static final String SERIES_OVERALL_LEADERBOARD = "SeriesOverallLeaderboard";
|
||||
private static final String SERIES_REGATTA_LEADERBOARDS = "SeriesRegattaLeaderboards";
|
||||
|
||||
public static final StorageDefinitionId createStorageDefinitionIdForRaceBoard(
|
||||
RaceboardContextDefinition raceboardContextDefinition) {
|
||||
String globalDefinitionId = RACEBOARD;
|
||||
if (raceboardContextDefinition.getMode() != null) {
|
||||
globalDefinitionId += "." + raceboardContextDefinition.getMode().toString();
|
||||
}
|
||||
|
||||
String contextDefinitionId = StorageDefinitionId.buildContextDefinitionId(raceboardContextDefinition.getRegattaName(),
|
||||
raceboardContextDefinition.getRaceName(), raceboardContextDefinition.getLeaderboardName());
|
||||
|
||||
return new StorageDefinitionId(globalDefinitionId, contextDefinitionId);
|
||||
}
|
||||
|
||||
public static final StorageDefinitionId createStorageDefinitionIdForLeaderboard(
|
||||
LeaderboardContextDefinition leaderboardContextDefinition) {
|
||||
return new StorageDefinitionId(LEADERBOARD,
|
||||
StorageDefinitionId.buildContextDefinitionId(leaderboardContextDefinition.getLeaderboardName()));
|
||||
}
|
||||
|
||||
public static final StorageDefinitionId createStorageDefinitionIdForRegattaOverview(
|
||||
RegattaOverviewContextDefinition regattaOverviewContextDefinition) {
|
||||
return new StorageDefinitionId(REGATTA_OVERVIEW,
|
||||
StorageDefinitionId.buildContextDefinitionId(regattaOverviewContextDefinition.getEvent().toString()));
|
||||
}
|
||||
|
||||
public static final StorageDefinitionId createStorageDefinitionIdForEventRegattaLeaderboard(String leaderboardName) {
|
||||
return new StorageDefinitionId(EVENT_REGATTA_LEADERBOARD,
|
||||
StorageDefinitionId.buildContextDefinitionId(leaderboardName));
|
||||
}
|
||||
|
||||
public static final StorageDefinitionId createStorageDefinitionIdForSeriesOverallLeaderboard(String leaderboardName) {
|
||||
return new StorageDefinitionId(SERIES_OVERALL_LEADERBOARD,
|
||||
StorageDefinitionId.buildContextDefinitionId(leaderboardName));
|
||||
}
|
||||
|
||||
public static final StorageDefinitionId createStorageDefinitionIdForSeriesRegattaLeaderboards(String leaderboardName) {
|
||||
return new StorageDefinitionId(SERIES_REGATTA_LEADERBOARDS,
|
||||
StorageDefinitionId.buildContextDefinitionId(leaderboardName));
|
||||
}
|
||||
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package com.sap.sailing.gwt.settings.client.utils;
|
||||
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardContextDefinition;
|
||||
import com.sap.sailing.gwt.settings.client.raceboard.RaceboardContextDefinition;
|
||||
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaOverviewContextDefinition;
|
||||
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
|
||||
|
||||
/**
|
||||
* Factory for {@link StoredSettingsLocation}s which are used in Sailing Analytics.
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
*/
|
||||
public class StoredSettingsLocationFactory {
|
||||
|
||||
private StoredSettingsLocationFactory() {
|
||||
}
|
||||
|
||||
private static final String RACEBOARD = "Raceboard";
|
||||
private static final String LEADERBOARD = "Leaderboard";
|
||||
private static final String REGATTA_OVERVIEW = "RegattaOverview";
|
||||
private static final String EVENT_REGATTA_LEADERBOARD = "EventRegattaLeaderboard";
|
||||
private static final String SERIES_OVERALL_LEADERBOARD = "SeriesOverallLeaderboard";
|
||||
private static final String SERIES_REGATTA_LEADERBOARDS = "SeriesRegattaLeaderboards";
|
||||
|
||||
public static final StoredSettingsLocation createStoredSettingsLocatorForRaceBoard(
|
||||
RaceboardContextDefinition raceboardContextDefinition, String raceBoardModeName) {
|
||||
String userSettingsIdPart = RACEBOARD;
|
||||
if(raceBoardModeName != null) {
|
||||
userSettingsIdPart += "." + raceBoardModeName;
|
||||
}
|
||||
String documentSettingsIdPart = StoredSettingsLocation.buildDocumentSettingsIdPart(raceboardContextDefinition.getRegattaName(),
|
||||
raceboardContextDefinition.getRaceName(), raceboardContextDefinition.getLeaderboardName());
|
||||
|
||||
return new SailingStoredSettingsLocation(userSettingsIdPart, documentSettingsIdPart);
|
||||
}
|
||||
|
||||
public static final StoredSettingsLocation createStoredSettingsLocatorForLeaderboard(
|
||||
LeaderboardContextDefinition leaderboardContextDefinition) {
|
||||
return new SailingStoredSettingsLocation(LEADERBOARD,
|
||||
StoredSettingsLocation.buildDocumentSettingsIdPart(leaderboardContextDefinition.getLeaderboardName()));
|
||||
}
|
||||
|
||||
public static final StoredSettingsLocation createStoredSettingsLocatorForRegattaOverview(
|
||||
RegattaOverviewContextDefinition regattaOverviewContextDefinition) {
|
||||
return new SailingStoredSettingsLocation(REGATTA_OVERVIEW,
|
||||
StoredSettingsLocation.buildDocumentSettingsIdPart(regattaOverviewContextDefinition.getEvent().toString()));
|
||||
}
|
||||
|
||||
public static final StoredSettingsLocation createStoredSettingsLocatorForEventRegattaLeaderboard(String leaderboardName) {
|
||||
return new SailingStoredSettingsLocation(EVENT_REGATTA_LEADERBOARD,
|
||||
StoredSettingsLocation.buildDocumentSettingsIdPart(leaderboardName));
|
||||
}
|
||||
|
||||
public static final StoredSettingsLocation createStoredSettingsLocatorForSeriesOverallLeaderboard(String leaderboardName) {
|
||||
return new SailingStoredSettingsLocation(SERIES_OVERALL_LEADERBOARD,
|
||||
StoredSettingsLocation.buildDocumentSettingsIdPart(leaderboardName));
|
||||
}
|
||||
|
||||
public static final StoredSettingsLocation createStoredSettingsLocatorForSeriesRegattaLeaderboards(String leaderboardName) {
|
||||
return new SailingStoredSettingsLocation(SERIES_REGATTA_LEADERBOARDS,
|
||||
StoredSettingsLocation.buildDocumentSettingsIdPart(leaderboardName));
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -233,18 +233,18 @@ public abstract class AbstractLeaderboardConfigPanel extends FormPanel implement
|
||||
@Override
|
||||
public void onSelectionChange(SelectionChangeEvent event) {
|
||||
Set<RaceDTO> selectedRaces = refreshableTrackedRaceSelectionModel.getSelectedSet();
|
||||
RaceDTO selectedRace = selectedRaces.iterator().next();
|
||||
RaceColumnDTOAndFleetDTOWithNameBasedEquality selectedRaceColumnAndFleetName = getSelectedRaceColumnWithFleet();
|
||||
RaceColumnDTO selectedRaceColumn = selectedRaceColumnAndFleetName.getA();
|
||||
FleetDTO selectedRaceColumnFleet = selectedRaceColumnAndFleetName.getB();
|
||||
// if no leaderboard column is selected, ignore the race selection change
|
||||
if (selectedRaceColumnAndFleetName != null) {
|
||||
RaceColumnDTO selectedRaceColumn = selectedRaceColumnAndFleetName.getA();
|
||||
FleetDTO selectedRaceColumnFleet = selectedRaceColumnAndFleetName.getB();
|
||||
if (selectedRaces.isEmpty()) {
|
||||
if (hasLink(selectedRaceColumnAndFleetName)) {
|
||||
unlinkRaceColumnFromTrackedRace(selectedRaceColumn.getRaceColumnName(),
|
||||
selectedRaceColumnFleet);
|
||||
}
|
||||
} else {
|
||||
RaceDTO selectedRace = selectedRaces.iterator().next();
|
||||
if (hasLink(selectedRaceColumnAndFleetName)
|
||||
&& !isLinkedToRace(selectedRaceColumnAndFleetName, selectedRace)) {
|
||||
if (Window.confirm(stringMessages.trackedRaceAlreadyLinked())) {
|
||||
|
||||
+2
-2
@@ -56,7 +56,7 @@ import com.sap.sse.gwt.client.panels.CustomizableFilterablePanel;
|
||||
import com.sap.sse.gwt.client.shared.components.AbstractCompositeComponent;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
|
||||
import com.sap.sse.gwt.client.shared.perspective.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
|
||||
public abstract class AbstractTrackedRacesListComposite extends AbstractCompositeComponent<TrackedRacesSettings> implements
|
||||
RegattasDisplayer {
|
||||
@@ -435,7 +435,7 @@ public abstract class AbstractTrackedRacesListComposite extends AbstractComposit
|
||||
}
|
||||
|
||||
@Override
|
||||
public SettingsDialogComponent<TrackedRacesSettings> getSettingsDialogComponent() {
|
||||
public SettingsDialogComponent<TrackedRacesSettings> getSettingsDialogComponent(TrackedRacesSettings settings) {
|
||||
return new TrackedRacesSettingsDialogComponent<TrackedRacesSettings>(settings, stringMessages);
|
||||
}
|
||||
|
||||
|
||||
+7
-4
@@ -377,18 +377,21 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
|
||||
table.addColumn(eventActionColumn, stringMessages.actions());
|
||||
table.setSelectionModel(eventSelectionCheckboxColumn.getSelectionModel(), eventSelectionCheckboxColumn.getSelectionManager());
|
||||
|
||||
table.addColumnSortHandler(getEventTableColumnSortHandler(eventListDataProvider.getList(), eventNameColumn,
|
||||
venueNameColumn, startEndDateColumn, isPublicColumn, courseAreasColumn, leaderboardGroupsColumn));
|
||||
table.addColumnSortHandler(getEventTableColumnSortHandler(eventListDataProvider.getList(),
|
||||
eventSelectionCheckboxColumn, eventNameColumn, venueNameColumn, startEndDateColumn, isPublicColumn,
|
||||
courseAreasColumn, leaderboardGroupsColumn));
|
||||
table.getColumnSortList().push(startEndDateColumn);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
private ListHandler<EventDTO> getEventTableColumnSortHandler(List<EventDTO> eventRecords,
|
||||
Column<EventDTO, SafeHtml> eventNameColumn, TextColumn<EventDTO> venueNameColumn,
|
||||
TextColumn<EventDTO> startEndDateColumn, TextColumn<EventDTO> isPublicColumn, Column<EventDTO, SafeHtml> courseAreasColumn,
|
||||
SelectionCheckboxColumn<EventDTO> eventSelectionCheckboxColumn, Column<EventDTO, SafeHtml> eventNameColumn,
|
||||
TextColumn<EventDTO> venueNameColumn, TextColumn<EventDTO> startEndDateColumn,
|
||||
TextColumn<EventDTO> isPublicColumn, Column<EventDTO, SafeHtml> courseAreasColumn,
|
||||
Column<EventDTO, List<MultipleLinkCell.CellLink>> leaderboardGroupsColumn) {
|
||||
ListHandler<EventDTO> result = new ListHandler<EventDTO>(eventRecords);
|
||||
result.setComparator(eventSelectionCheckboxColumn, eventSelectionCheckboxColumn.getComparator());
|
||||
result.setComparator(eventNameColumn, new Comparator<EventDTO>() {
|
||||
@Override
|
||||
public int compare(EventDTO e1, EventDTO e2) {
|
||||
|
||||
+24
@@ -527,6 +527,14 @@ public class LeaderboardGroupConfigPanel extends AbstractRegattaPanel implements
|
||||
return group.description.length() <= 100 ? group.description : group.description.substring(0, 98) + "...";
|
||||
}
|
||||
};
|
||||
groupDescriptionColumn.setSortable(true);
|
||||
leaderboardGroupsListHandler.setComparator(groupDescriptionColumn, new Comparator<LeaderboardGroupDTO>() {
|
||||
@Override
|
||||
public int compare(LeaderboardGroupDTO group1, LeaderboardGroupDTO group2) {
|
||||
return new NaturalComparator(false).compare(group1.description, group2.description);
|
||||
}
|
||||
});
|
||||
|
||||
TextColumn<LeaderboardGroupDTO> groupDisplayNameColumn = new TextColumn<LeaderboardGroupDTO>() {
|
||||
@Override
|
||||
public String getValue(LeaderboardGroupDTO group) {
|
||||
@@ -534,6 +542,14 @@ public class LeaderboardGroupConfigPanel extends AbstractRegattaPanel implements
|
||||
group.getDisplayName().length() <= 100 ? group.getDisplayName() : group.getDisplayName().substring(0, 98) + "...";
|
||||
}
|
||||
};
|
||||
groupDisplayNameColumn.setSortable(true);
|
||||
leaderboardGroupsListHandler.setComparator(groupDisplayNameColumn, new Comparator<LeaderboardGroupDTO>() {
|
||||
@Override
|
||||
public int compare(LeaderboardGroupDTO group1, LeaderboardGroupDTO group2) {
|
||||
return new NaturalComparator(false).compare(group1.getDisplayName(), group2.getDisplayName());
|
||||
}
|
||||
});
|
||||
|
||||
TextColumn<LeaderboardGroupDTO> hasOverallLeaderboardColumn = new TextColumn<LeaderboardGroupDTO>() {
|
||||
@Override
|
||||
public String getValue(LeaderboardGroupDTO group) {
|
||||
@@ -544,6 +560,14 @@ public class LeaderboardGroupConfigPanel extends AbstractRegattaPanel implements
|
||||
return result;
|
||||
}
|
||||
};
|
||||
hasOverallLeaderboardColumn.setSortable(true);
|
||||
leaderboardGroupsListHandler.setComparator(hasOverallLeaderboardColumn, new Comparator<LeaderboardGroupDTO>() {
|
||||
@Override
|
||||
public int compare(LeaderboardGroupDTO group1, LeaderboardGroupDTO group2) {
|
||||
return new NaturalComparator(false).compare(hasOverallLeaderboardColumn.getValue(group1),
|
||||
hasOverallLeaderboardColumn.getValue(group2));
|
||||
}
|
||||
});
|
||||
|
||||
ImagesBarColumn<LeaderboardGroupDTO, LeaderboardGroupConfigImagesBarCell> groupActionsColumn = new ImagesBarColumn<LeaderboardGroupDTO, LeaderboardGroupConfigImagesBarCell>(
|
||||
new LeaderboardGroupConfigImagesBarCell(stringMessages));
|
||||
|
||||
Loaded 100 of 279 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user