Merge branch 'bug3146' into ubilabs--rcapp--master

This commit is contained in:
wagnst committed 2015-07-20 12:58:39 +02:00
commit 317b5cf017
122 files changed
+4645 -1181

No files matched your search

+76 -76
View File
@@ -1,76 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
<listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/>
<listEntry value="com.sap.sailing.gwt.ui.DataMining"/>
<listEntry value="com.sap.sailing.gwt.ui.LeaderboardEditing"/>
<listEntry value="com.sap.sailing.gwt.ui.Spectator"/>
<listEntry value="com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
<listEntry value="com.sap.sailing.gwt.ui.PolarSheets"/>
<listEntry value="com.sap.sailing.gwt.ui.Leaderboard"/>
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
<listEntry value="com.sap.sailing.gwt.ui.YoutubePopup"/>
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
<listEntry value="com.sap.sailing.gwt.home.Home"/>
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
</listAttribute>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.sap.sailing.gwt.ui"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.theme/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.googlecode.java-diff-utils/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.json.simple/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.expeditionconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.udpconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.mongodb/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.operationaltransformation/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.replication/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.moxieapps.gwt.highcharts/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.geocoding/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.google.gwt.osgi/lib/gwt-user.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sailing.gwt.ui&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.adminconsole/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
</launchConfiguration>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
<listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/>
<listEntry value="com.sap.sailing.gwt.ui.DataMining"/>
<listEntry value="com.sap.sailing.gwt.ui.LeaderboardEditing"/>
<listEntry value="com.sap.sailing.gwt.ui.Spectator"/>
<listEntry value="com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
<listEntry value="com.sap.sailing.gwt.ui.PolarSheets"/>
<listEntry value="com.sap.sailing.gwt.ui.Leaderboard"/>
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
<listEntry value="com.sap.sailing.gwt.ui.YoutubePopup"/>
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
<listEntry value="com.sap.sailing.gwt.home.Home"/>
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
</listAttribute>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.sap.sailing.gwt.ui"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.theme/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.googlecode.java-diff-utils/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.json.simple/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.expeditionconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.udpconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.mongodb/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.operationaltransformation/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.replication/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.moxieapps.gwt.highcharts/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.geocoding/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.google.gwt.osgi/lib/gwt-user.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sailing.gwt.ui&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.adminconsole/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
</launchConfiguration>
Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

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

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

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