mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-05 18:42:55 +00:00
bug5927: Created a new list box premium element to move the colored-tails selection behind the paywall.
- added reset of view in case of user event status change
This commit is contained in:
1 parent
93c075edd2
commit
3ab4e414aa
5 files changed
+310
-18
No files matched your search
+2
-1
@@ -66,7 +66,8 @@ public class SecuredDomainType extends HasPermissionsImpl {
|
||||
EXPORT,
|
||||
SIMULATOR,
|
||||
VIEWSTREAMLETS,
|
||||
VIEWANALYSISCHARTS;
|
||||
VIEWANALYSISCHARTS,
|
||||
DETAILTYPES;
|
||||
|
||||
private static final Action[] ALL_ACTIONS = DefaultActions.plus(TrackedRaceActions.values());
|
||||
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.sap.sailing.gwt.common.client.premium;
|
||||
|
||||
import static com.sap.sailing.gwt.common.client.premium.SailingPremiumIconRessource.INSTANCE;
|
||||
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory;
|
||||
import com.sap.sse.security.shared.HasPermissions.Action;
|
||||
import com.sap.sse.security.shared.dto.SecuredDTO;
|
||||
import com.sap.sse.security.ui.client.premium.PaywallResolver;
|
||||
import com.sap.sse.security.ui.client.premium.PremiumListBox;
|
||||
|
||||
public class SailingPremiumListBox extends PremiumListBox {
|
||||
|
||||
public SailingPremiumListBox(final String label, final String emptyValue, final Action action, final PaywallResolver paywallResolver, SecuredDTO contextDTO) {
|
||||
super(label, emptyValue, action, paywallResolver, contextDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Image createPremiumIcon() {
|
||||
return new Image();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUserPermissionUpdate(final boolean isPermitted) {
|
||||
super.onUserPermissionUpdate(isPermitted);
|
||||
image.setUrl((isPermitted ? INSTANCE.premiumIconPermitted() : INSTANCE.premiumIcon()).getSafeUri());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSubscribeDialogConfirmation(final Iterable<String> unlockingPlans) {
|
||||
Window.open(EntryPointLinkFactory.createSubscriptionPageLink(unlockingPlans), "_blank", "");
|
||||
}
|
||||
|
||||
}
|
||||
+43
-17
@@ -68,7 +68,6 @@ import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.ListBox;
|
||||
import com.google.gwt.user.client.ui.PopupPanel;
|
||||
import com.google.gwt.user.client.ui.PopupPanel.AnimationType;
|
||||
import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
|
||||
@@ -91,8 +90,10 @@ import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableBearing;
|
||||
import com.sap.sailing.domain.common.scalablevalue.impl.ScalablePosition;
|
||||
import com.sap.sailing.domain.common.security.SecuredDomainType;
|
||||
import com.sap.sailing.domain.common.security.SecuredDomainType.TrackedRaceActions;
|
||||
import com.sap.sailing.domain.common.windfinder.SpotDTO;
|
||||
import com.sap.sailing.gwt.common.client.FullscreenUtil;
|
||||
import com.sap.sailing.gwt.common.client.premium.SailingPremiumListBox;
|
||||
import com.sap.sailing.gwt.common.client.sharing.FloatingSharingButtonsResources;
|
||||
import com.sap.sailing.gwt.ui.actions.GetBoatPositionsAction;
|
||||
import com.sap.sailing.gwt.ui.actions.GetBoatPositionsCallback;
|
||||
@@ -181,6 +182,8 @@ import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.gwt.shared.ClientConfiguration;
|
||||
import com.sap.sse.gwt.shared.DebugConstants;
|
||||
import com.sap.sse.security.shared.dto.UserDTO;
|
||||
import com.sap.sse.security.ui.client.UserStatusEventHandler;
|
||||
import com.sap.sse.security.ui.client.premium.PaywallResolver;
|
||||
|
||||
public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> implements TimeListener, CompetitorSelectionChangeListener,
|
||||
@@ -2866,23 +2869,27 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
return vPanel;
|
||||
}
|
||||
|
||||
private ListBox createDetailTypeDropdown(CompetitorDTO competitor) {
|
||||
final ListBox lb = new ListBox();
|
||||
final NodeList<OptionElement> options = DOMUtils.getOptions(lb);
|
||||
lb.addItem(stringMessages.none(), "none");
|
||||
if (sortedAvailableDetailTypes != null) {
|
||||
for (int i = 0; i < sortedAvailableDetailTypes.size(); i++) {
|
||||
final DetailType detail = sortedAvailableDetailTypes.get(i);
|
||||
lb.addItem(DetailTypeFormatter.format(detail), detail.name());
|
||||
final String tooltip = DetailTypeFormatter.getTooltip(detail);
|
||||
if (Util.hasLength(tooltip)) {
|
||||
options.getItem(options.getLength()-1).setTitle(tooltip);
|
||||
}
|
||||
if (detail == selectedDetailType) {
|
||||
lb.setSelectedIndex(i + 1);
|
||||
}
|
||||
private VerticalPanel createDetailTypeDropdown(CompetitorDTO competitor) {
|
||||
final VerticalPanel vPanel = new VerticalPanel();
|
||||
vPanel.add(createDetailTypePremiumList(competitor));
|
||||
// reset component if user changes (login/out)
|
||||
paywallResolver.registerUserStatusEventHandler(new UserStatusEventHandler() {
|
||||
@Override
|
||||
public void onUserStatusChange(UserDTO user, boolean preAuthenticated) {
|
||||
vPanel.clear();
|
||||
vPanel.add(createDetailTypePremiumList(competitor));
|
||||
}
|
||||
}
|
||||
});
|
||||
return vPanel;
|
||||
}
|
||||
|
||||
private SailingPremiumListBox createDetailTypePremiumList(CompetitorDTO competitor) {
|
||||
// reset metric overlay
|
||||
selectedDetailType = null;
|
||||
metricOverlay.setVisible(false);
|
||||
// create new premium list box
|
||||
SailingPremiumListBox lb = new SailingPremiumListBox(stringMessages.none(), "none", TrackedRaceActions.DETAILTYPES, paywallResolver, competitor);
|
||||
fillItemsFromAvailableDetailTypes(lb);
|
||||
lb.setVisibleItemCount(1);
|
||||
lb.addChangeHandler(new ChangeHandler() {
|
||||
@Override
|
||||
@@ -2914,6 +2921,25 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
return lb;
|
||||
}
|
||||
|
||||
private void fillItemsFromAvailableDetailTypes(SailingPremiumListBox lb) {
|
||||
final NodeList<OptionElement> options = DOMUtils.getOptions(lb.getListBox());
|
||||
if (lb.isEnabled() && sortedAvailableDetailTypes != null) {
|
||||
for (int i = 0; i < sortedAvailableDetailTypes.size(); i++) {
|
||||
final DetailType detail = sortedAvailableDetailTypes.get(i);
|
||||
lb.addItem(DetailTypeFormatter.format(detail), detail.name());
|
||||
final String tooltip = DetailTypeFormatter.getTooltip(detail);
|
||||
if (Util.hasLength(tooltip)) {
|
||||
options.getItem(options.getLength()-1).setTitle(tooltip);
|
||||
}
|
||||
if (detail == selectedDetailType) {
|
||||
lb.setSelectedIndex(i + 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lb.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link CompetitorSelectionProvider#getSelectedCompetitors()} if
|
||||
* {@link RaceMapSettings#isShowOnlySelectedCompetitors() only selected competitors are to be shown}, the
|
||||
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
package com.sap.sse.security.ui.client.premium;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.event.dom.client.ChangeHandler;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.HasAllKeyHandlers;
|
||||
import com.google.gwt.event.dom.client.KeyDownHandler;
|
||||
import com.google.gwt.event.dom.client.KeyPressHandler;
|
||||
import com.google.gwt.event.dom.client.KeyUpHandler;
|
||||
import com.google.gwt.event.shared.HandlerRegistration;
|
||||
import com.google.gwt.resources.client.CssResource;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.uibinder.client.UiHandler;
|
||||
import com.google.gwt.user.client.ui.FocusPanel;
|
||||
import com.google.gwt.user.client.ui.FocusWidget;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.google.gwt.user.client.ui.ListBox;
|
||||
import com.sap.sse.gwt.client.dialog.ConfirmationDialog;
|
||||
import com.sap.sse.security.shared.HasPermissions.Action;
|
||||
import com.sap.sse.security.shared.dto.SecuredDTO;
|
||||
import com.sap.sse.security.shared.dto.UserDTO;
|
||||
import com.sap.sse.security.ui.client.UserStatusEventHandler;
|
||||
import com.sap.sse.security.ui.client.i18n.StringMessages;
|
||||
|
||||
public abstract class PremiumListBox extends PremiumUiElement implements HasAllKeyHandlers {
|
||||
|
||||
private static PremiumCheckBoxUiBinder uiBinder = GWT.create(PremiumCheckBoxUiBinder.class);
|
||||
|
||||
interface PremiumCheckBoxUiBinder extends UiBinder<FocusPanel, PremiumListBox> {
|
||||
}
|
||||
|
||||
interface Style extends CssResource {
|
||||
@ClassName("premium-container")
|
||||
String premiumContainer();
|
||||
|
||||
@ClassName("premium-list-box")
|
||||
String premiumListBox();
|
||||
|
||||
@ClassName("premium-permitted")
|
||||
String premiumPermitted();
|
||||
|
||||
@ClassName("premium-icon")
|
||||
String premiumIcon();
|
||||
}
|
||||
|
||||
@UiField
|
||||
StringMessages i18n;
|
||||
@UiField
|
||||
Style style;
|
||||
@UiField
|
||||
FocusPanel container;
|
||||
@UiField(provided = true)
|
||||
protected final Image image;
|
||||
@UiField(provided = true)
|
||||
protected final ListBox listBox;
|
||||
private final ConfirmationDialog subscribeDialog;
|
||||
|
||||
/**
|
||||
* A Composite component, that includes a list box and an additional premium icon, indicating that the feature to be
|
||||
* enabled is a premium feature if the user does not have the permission. By definition there is always minimum one
|
||||
* (empty) item with index 0.
|
||||
*/
|
||||
protected PremiumListBox(final String emptyLabel, String emptyValue, final Action action,
|
||||
final PaywallResolver paywallResolver, final SecuredDTO contextDTO) {
|
||||
super(action, paywallResolver, contextDTO);
|
||||
this.listBox = new ListBox();
|
||||
this.listBox.addItem(emptyLabel, emptyValue);
|
||||
this.listBox.setSelectedIndex(0);
|
||||
this.image = createPremiumIcon();
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
this.subscribeDialog = ConfirmationDialog.create(i18n.subscriptionSuggestionTitle(),
|
||||
i18n.pleaseSubscribeToUse(), i18n.takeMeToSubscriptions(), i18n.cancel(), () -> paywallResolver
|
||||
.getUnlockingSubscriptionPlans(action, contextDTO, this::onSubscribeDialogConfirmation));
|
||||
updateUserPermission();
|
||||
paywallResolver.registerUserStatusEventHandler(new UserStatusEventHandler() {
|
||||
@Override
|
||||
public void onUserStatusChange(UserDTO user, boolean preAuthenticated) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
while (this.listBox.getItemCount() > 1) {
|
||||
this.listBox.removeItem(1);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void onSubscribeDialogConfirmation(Iterable<String> unlockingPlans);
|
||||
|
||||
@Override
|
||||
protected void onEnsureDebugId(final String baseID) {
|
||||
this.listBox.ensureDebugId(baseID);
|
||||
}
|
||||
|
||||
@UiHandler("container")
|
||||
void onContainerClicked(final ClickEvent event) {
|
||||
if (!hasPermission()) {
|
||||
this.updateUserPermission();
|
||||
subscribeDialog.center();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUserPermissionUpdate(final boolean isPermitted) {
|
||||
listBox.setSelectedIndex(getSelectedIndex());
|
||||
listBox.setEnabled(isEnabled() && isPermitted);
|
||||
container.setStyleName(style.premiumPermitted(), isPermitted);
|
||||
}
|
||||
|
||||
public void addItem(String item, String value) {
|
||||
if (hasPermission()) {
|
||||
this.listBox.addItem(item, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedIndex(final int index) {
|
||||
if (hasPermission()) {
|
||||
this.listBox.setSelectedIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
public int getSelectedIndex() {
|
||||
int selectedIndex = 0;
|
||||
if (hasPermission()) {
|
||||
selectedIndex = this.listBox.getSelectedIndex();
|
||||
}
|
||||
return selectedIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* If NO permission is granted select empty item (index 0) and return the default empty value.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getSelectedValue() {
|
||||
if (!hasPermission()) {
|
||||
this.listBox.setSelectedIndex(0);
|
||||
}
|
||||
return this.listBox.getSelectedValue();
|
||||
}
|
||||
|
||||
public void setVisibleItemCount(int visibleItems) {
|
||||
if (hasPermission()) {
|
||||
this.listBox.setVisibleItemCount(visibleItems);
|
||||
}
|
||||
}
|
||||
|
||||
public HandlerRegistration addChangeHandler(final ChangeHandler handler) {
|
||||
return listBox.addChangeHandler(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(final boolean enabled) {
|
||||
super.setEnabled(enabled);
|
||||
listBox.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerRegistration addKeyDownHandler(final KeyDownHandler handler) {
|
||||
return container.addKeyDownHandler(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerRegistration addKeyPressHandler(final KeyPressHandler handler) {
|
||||
return container.addKeyPressHandler(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerRegistration addKeyUpHandler(final KeyUpHandler handler) {
|
||||
return container.addKeyUpHandler(handler);
|
||||
}
|
||||
|
||||
public FocusWidget getFocusWidget() {
|
||||
return this.listBox;
|
||||
}
|
||||
|
||||
public ListBox getListBox() {
|
||||
return this.listBox;
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<!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.sse.security.ui.client.i18n.StringMessages" />
|
||||
<ui:style type="com.sap.sse.security.ui.client.premium.PremiumListBox.Style">
|
||||
.premium-listbox {
|
||||
display: inline-block;
|
||||
}
|
||||
.premium-container,
|
||||
.premium-container select:disabled.premium-list-box + label {
|
||||
cursor: pointer;
|
||||
}
|
||||
.premium-container .premium-list-box {
|
||||
padding-right: 0;
|
||||
}
|
||||
.premium-container select.premium-list-box {
|
||||
border-radius: 4px;
|
||||
background-color: rgba(255,255,255,0.75);
|
||||
border: 1px solid #efaa00;
|
||||
}
|
||||
.premium-container {
|
||||
padding-right: 10px;
|
||||
top: -3px;
|
||||
position: relative;
|
||||
}
|
||||
.premium-permitted .premium-container,
|
||||
.premium-permitted .premium-container select:disabled.premium-list-box + label {
|
||||
cursor: default;
|
||||
}
|
||||
.premium-container select:disabled.premium-list-box {
|
||||
pointer-events: none;
|
||||
}
|
||||
.premium-container .premium-icon {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
margin: 2px;
|
||||
vertical-align: top;
|
||||
}
|
||||
.premium-permitted .premium-container .premium-icon {
|
||||
display: none;
|
||||
}
|
||||
</ui:style>
|
||||
<g:FocusPanel ui:field="container" addStyleNames="{style.premium-listbox}">
|
||||
<g:FlowPanel addStyleNames="{style.premium-container}">
|
||||
<g:ListBox ui:field="listBox" addStyleNames="{style.premium-list-box}" />
|
||||
<g:Image ui:field="image" addStyleNames="{style.premium-icon}"/>
|
||||
</g:FlowPanel>
|
||||
</g:FocusPanel>
|
||||
</ui:UiBinder>
|
||||
Reference in new issue
Block a user