Bug 4104: Use DataEntryDialog to validate user input for tag & tag button creation/updating.

This commit is contained in:
Henri Kohlberg committed 2018-10-18 14:59:43 +02:00
1 parent 0f6b577eb0
commit a6c8167dbc
8 files changed
+487 -458

No files matched your search

@@ -48,7 +48,7 @@ public class SideBySideComponentViewer implements UserStatusEventHandler {
private static final int DEFAULT_SOUTH_SPLIT_PANEL_HEIGHT = 200;
private final int MIN_LEADERBOARD_WIDTH = Math.min(432, Window.getClientWidth() - 40); // fallback value "432" works well for 505 and ESS
private final int MIN_TAGGING_WIDTH = Math.min(350, Window.getClientWidth() - 40);
private final int MIN_TAGGING_WIDTH = Math.min(440, Window.getClientWidth() - 40);
/**
* Absolute Panel that informs its children about a resize
@@ -14,7 +14,6 @@ public class TagButton extends Button {
private String tag, imageURL, comment;
private boolean visibleForPublic;
private int imageWidth, imageHeight;
/**
* Creates tag button with given attributes.
@@ -30,8 +29,7 @@ public class TagButton extends Button {
* @param visibleForPublic
* should be <code>true</code> if everybody should see the generated tag, otherwise <code>false</code>
*/
protected TagButton(String buttonName, String tag, String imageURL, int imageWidth, int imageHeight, String comment,
boolean visibleForPublic) {
protected TagButton(String buttonName, String tag, String imageURL, String comment, boolean visibleForPublic) {
super(buttonName);
setStyleName(style.tagDialogButton());
@@ -39,8 +37,6 @@ public class TagButton extends Button {
this.imageURL = imageURL;
this.comment = comment;
this.visibleForPublic = visibleForPublic;
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
addStyleName("gwt-Button");
}
@@ -71,24 +67,6 @@ public class TagButton extends Button {
return comment;
}
/**
* Returns image width of corresponding tag.
*
* @return image width of tag
*/
protected int getImageWidth() {
return imageWidth;
}
/**
* Returns image height of corresponding tag.
*
* @return image height of tag
*/
protected int getImageHeight() {
return imageHeight;
}
/**
* Returns visibility of corresponding tag.
*
@@ -109,15 +87,13 @@ public class TagButton extends Button {
}
/**
* Sets URL, width and height of optional image for corresponding tag.
* Sets URL of optional image for corresponding tag.
*
* @param imageURL
* image URL, may be <code>null</code>
*/
protected void setImage(String imageURL, int imageWidth, int imageHeight) {
protected void setImageURL(String imageURL) {
this.imageURL = imageURL;
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
}
/**
@@ -11,7 +11,6 @@ import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.safehtml.shared.SafeUri;
import com.google.gwt.user.cellview.client.AbstractHasData.RedrawEvent.Handler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.TextColumn;
@@ -20,6 +19,7 @@ import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.sap.sailing.domain.common.dto.TagDTO;
import com.sap.sailing.gwt.ui.adminconsole.ImagesBarColumn;
import com.sap.sailing.gwt.ui.adminconsole.LeaderboardConfigImagesBarCell;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
@@ -29,6 +29,7 @@ import com.sap.sailing.gwt.ui.raceboard.tagging.TaggingPanelResources.TagPanelSt
import com.sap.sse.gwt.client.IconResources;
import com.sap.sse.gwt.client.Notification;
import com.sap.sse.gwt.client.Notification.NotificationType;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
import com.sap.sse.security.ui.client.UserService;
/**
@@ -84,13 +85,24 @@ public class TagButtonDialog extends DialogBox {
private final TaggingPanelResources resources = TaggingPanelResources.INSTANCE;
private final TagPanelStyle style = resources.style();
private final TaggingPanel taggingPanel;
private final StringMessages stringMessages;
private final TagInputPanel inputPanel;
private final TagPreviewPanel tagPreviewPanel;
private final CellTable<TagButton> tagButtonTable;
private final TagFooterPanel footerPanel;
private Button closeButton, saveButton, cancelButton, addTagButtonButton;
private TagButton selectedTagButton;
/**
* <b>May not be edited directly</b>!<br/>
* When {@link #updateTagMode} is set to <code>true</code>, UI is displaying version for updating a tag button
* (button names and click listener). When this boolean is set to <code>false</code>, UI is displaying version for
* creation of tag buttons. Use method {@link #setButtonMode(boolean)} to change this value and the corresponding
* UI.
*/
private boolean updateTagMode = false;
/**
* Centered dialog which allows users to edit their personal {@link TagButton tag-buttons}.
*
@@ -103,39 +115,52 @@ public class TagButtonDialog extends DialogBox {
* @param stringMessages
* string messages of {@link TaggingPanel}
*/
public TagButtonDialog(TaggingPanel taggingPanel, TagFooterPanel footerPanel, SailingServiceAsync sailingService, StringMessages stringMessages,
UserService userService) {
public TagButtonDialog(TaggingPanel taggingPanel, TagFooterPanel footerPanel, SailingServiceAsync sailingService,
StringMessages stringMessages, UserService userService) {
this.taggingPanel = taggingPanel;
this.stringMessages = stringMessages;
this.footerPanel = footerPanel;
setGlassEnabled(true);
setText(stringMessages.tagEditCustomTagButtons());
addStyleName(style.tagButtonDialog());
TagInputPanel inputPanel = new TagInputPanel(taggingPanel, sailingService, stringMessages);
TagPreviewPanel tagPreviewPanel = new TagPreviewPanel(taggingPanel, inputPanel, stringMessages, userService);
CellTable<TagButton> tagButtonsTable = createTable(footerPanel, inputPanel, tagPreviewPanel);
tagButtonsTable.addRedrawHandler(new Handler() {
inputPanel = new TagInputPanel(taggingPanel, sailingService, stringMessages, new DialogCallback<TagDTO>() {
@Override
public void onRedraw() {
// center dialog when content of tagButtonsTable changes (table needs to be redrawn)
center();
public void ok(TagDTO editedObject) {
if (updateTagMode) {
onSaveTagButtonChangesPressed();
} else {
onAddTagButtonPressed();
}
}
@Override
public void cancel() {
if (updateTagMode) {
onCancelTagButtonChangesPressed();
} else {
onCloseButtonPressed();
}
}
});
Panel controlButtonPanel = createButtonPanel(tagButtonsTable, inputPanel, tagPreviewPanel, footerPanel);
tagPreviewPanel = new TagPreviewPanel(taggingPanel, inputPanel, stringMessages, userService);
tagButtonTable = createTable(footerPanel, inputPanel, tagPreviewPanel);
tagButtonTable.addRedrawHandler(() -> {
// center dialog when content of tagButtonTable changes (table needs to be redrawn)
center();
});
Panel controlButtonPanel = createButtonPanel(tagButtonTable, inputPanel, tagPreviewPanel, footerPanel);
setButtonMode(false);
// wrap tag buttons table to control max-height of table
Panel tagButtonsTableWrapper = new SimplePanel();
tagButtonsTableWrapper.setStyleName(style.tagButtonTableWrapper());
tagButtonsTableWrapper.add(tagButtonsTable);
tagButtonsTableWrapper.add(tagButtonTable);
Panel mainPanel = new FlowPanel();
mainPanel.setStyleName(style.tagButtonDialogPanel());
mainPanel.add(tagButtonsTableWrapper);
mainPanel.add(inputPanel.getStatusLabel());
mainPanel.add(inputPanel);
mainPanel.add(controlButtonPanel);
mainPanel.add(tagPreviewPanel);
setWidget(mainPanel);
center();
}
@@ -195,38 +220,28 @@ public class TagButtonDialog extends DialogBox {
});
} else if (LeaderboardConfigImagesBarCell.ACTION_EDIT.equals(value)) {
selectedTagButton = button;
inputPanel.setTag(button.getTag());
inputPanel.setImageURL(button.getImageURL());
inputPanel.setComment(button.getComment());
inputPanel.setVisibleForPublic(button.isVisibleForPublic());
inputPanel.validateAndUpdate();
tagPreviewPanel.renderPreview(inputPanel);
saveButton.setVisible(true);
cancelButton.setVisible(true);
closeButton.setVisible(false);
addTagButtonButton.setVisible(false);
setButtonMode(true);
tagButtonTable.setVisible(false);
center();
}
}
});
tagButtonTable.addColumn(tagColumn, stringMessages.tagLabelTag());
tagButtonTable.addColumn(imageURLColumn, stringMessages.tagLabelImage());
tagButtonTable.addColumn(commentColumn, stringMessages.tagLabelComment());
tagButtonTable.addColumn(actionsColumn, stringMessages.tagLabelAction());
// set these width values manually as they are not accessable via CSS classes
tagButtonTable.setColumnWidth(tagColumn, "25%");
tagButtonTable.setColumnWidth(imageURLColumn, "20%");
tagButtonTable.setColumnWidth(commentColumn, "40%");
tagButtonTable.setColumnWidth(actionsColumn, "15%");
setRowData(tagButtonTable, taggingPanel.getTagButtons());
return tagButtonTable;
}
@@ -248,166 +263,17 @@ public class TagButtonDialog extends DialogBox {
*/
private Panel createButtonPanel(CellTable<TagButton> tagButtonTable, TagInputPanel inputPanel,
TagPreviewPanel tagPreviewPanel, TagFooterPanel footerPanel) {
addSaveButton(footerPanel, tagButtonTable, inputPanel, tagPreviewPanel);
addCancelButton(inputPanel, tagPreviewPanel, tagButtonTable);
addCloseButton(footerPanel, tagPreviewPanel);
addTagButtonButton(footerPanel, tagButtonTable, inputPanel, tagPreviewPanel);
Panel controlButtonPanel = new FlowPanel();
controlButtonPanel.setStyleName(style.buttonsPanel());
controlButtonPanel.add(addTagButtonButton);
controlButtonPanel.add(closeButton);
controlButtonPanel.add(saveButton);
controlButtonPanel.add(cancelButton);
return controlButtonPanel;
}
/**
* Creates a button allowing users to save their changes on a {@link TagButton}.
*
* @param footerPanel
* footer panel of {@link TaggingPanel}
* @param tagButtonTable
* {@link com.google.gwt.user.cellview.client.CellTable CellTable} containing {@link TagButton
* tag-buttons}
* @param inputPanel
* input fields of {@link TagButtonDialog} which allow to create new and modify existing {@link TagButton
* tag-buttons}
* @param tagPreviewPanel
* renders {@link TagPreviewPanel} preview of current input fields
*/
private void addSaveButton(TagFooterPanel footerPanel, CellTable<TagButton> tagButtonTable,
TagInputPanel inputPanel, TagPreviewPanel tagPreviewPanel) {
saveButton = new Button(stringMessages.save());
saveButton.setVisible(false);
saveButton.setStyleName(style.tagDialogButton());
saveButton.addStyleName("gwt-Button");
saveButton.addClickHandler(event -> {
if (!inputPanel.getTag().isEmpty()) {
selectedTagButton.setText(inputPanel.getTag());
selectedTagButton.setTag(inputPanel.getTag());
selectedTagButton.setComment(inputPanel.getComment());
selectedTagButton.setImage(inputPanel.getImageURL(), inputPanel.getImageWidth(), inputPanel.getImageHeight());
selectedTagButton.setVisibleForPublic(inputPanel.isVisibleForPublic());
footerPanel.storeAllTagButtons();
inputPanel.clearAllValues();
tagPreviewPanel.renderPreview(inputPanel);
tagButtonTable.redraw();
saveButton.setVisible(false);
cancelButton.setVisible(false);
closeButton.setVisible(true);
addTagButtonButton.setVisible(true);
selectedTagButton = null;
setRowData(tagButtonTable, taggingPanel.getTagButtons());
} else {
Notification.notify(stringMessages.tagNotSpecified(), NotificationType.WARNING);
}
center();
});
}
/**
* Creates a button allowing users to discard their changes on a {@link TagButton}.
*
* @param tagButtonTable
* {@link com.google.gwt.user.cellview.client.CellTable CellTable} containing {@link TagButton
* tag-buttons}
* @param inputPanel
* input fields of {@link TagButtonDialog} which allow to create new and modify existing {@link TagButton
* tag-buttons}
* @param tagPreviewPanel
* renders {@link TagPreviewPanel} preview of current input fields
*/
private void addCancelButton(TagInputPanel inputPanel, TagPreviewPanel tagPreviewPanel,
CellTable<TagButton> tagButtonTable) {
cancelButton = new Button(stringMessages.cancel());
cancelButton.setVisible(false);
Button okButton = inputPanel.getOkButton();
okButton.setStyleName(style.tagDialogButton());
okButton.addStyleName("gwt-Button");
Button cancelButton = inputPanel.getCancelButton();
cancelButton.setStyleName(style.tagDialogButton());
cancelButton.addStyleName("gwt-Button");
cancelButton.addClickHandler(event -> {
// ask user for confirmation to discard changes if values of input fields changed
if (!inputPanel.compareFieldsToTagButton(selectedTagButton)) {
new ConfirmationDialog(stringMessages, stringMessages.tagDiscardChangesHeading(),
stringMessages.tagDiscardChanges(), confirmed -> {
if (confirmed) {
inputPanel.clearAllValues();
tagPreviewPanel.renderPreview(inputPanel);
tagButtonTable.setVisible(true);
saveButton.setVisible(false);
cancelButton.setVisible(false);
closeButton.setVisible(true);
addTagButtonButton.setVisible(true);
center();
}
});
} else {
inputPanel.clearAllValues();
tagPreviewPanel.renderPreview(inputPanel);
tagButtonTable.setVisible(true);
saveButton.setVisible(false);
cancelButton.setVisible(false);
closeButton.setVisible(true);
addTagButtonButton.setVisible(true);
center();
}
});
}
/**
* Creates a button allowing users to close the {@link TagButtonDialog}.
*
* @param tagButtonTable
* {@link com.google.gwt.user.cellview.client.CellTable CellTable} containing {@link TagButton
* tag-buttons}
* @param inputPanel
* input fields of {@link TagButtonDialog} which allow to create new and modify existing {@link TagButton
* tag-buttons}
* @param tagPreviewPanel
* renders {@link TagPreviewPanel} preview of current input fields
*/
private void addCloseButton(TagFooterPanel footerPanel, TagPreviewPanel tagPreviewPanel) {
closeButton = new Button(stringMessages.close());
closeButton.setStyleName(style.tagDialogButton());
closeButton.addStyleName("gwt-Button");
closeButton.addClickHandler(event -> hide());
}
/**
* Creates a button allowing users to add a new {@link TagButton}.
*
* @param footerPanel
* footer panel of {@link TaggingPanel}
* @param tagButtonTable
* {@link com.google.gwt.user.cellview.client.CellTable CellTable} containing {@link TagButton
* tag-buttons}
* @param inputPanel
* input fields of {@link TagButtonDialog} which allow to create new and modify existing {@link TagButton
* tag-buttons}
* @param tagPreviewPanel
* renders {@link TagPreviewPanel} preview of current input fields
*/
private void addTagButtonButton(TagFooterPanel footerPanel, CellTable<TagButton> tagButtonTable,
TagInputPanel inputPanel, TagPreviewPanel tagPreviewPanel) {
addTagButtonButton = new Button(stringMessages.tagAddCustomTagButton());
addTagButtonButton.setStyleName(style.tagDialogButton());
addTagButtonButton.addStyleName("gwt-Button");
addTagButtonButton.addClickHandler(event -> {
if (!inputPanel.getTag().isEmpty()) {
TagButton tagButton = new TagButton(inputPanel.getTag(), inputPanel.getTag(), inputPanel.getImageURL(), inputPanel.getImageWidth(), inputPanel.getImageHeight(),
inputPanel.getComment(), inputPanel.isVisibleForPublic());
inputPanel.clearAllValues();
tagPreviewPanel.renderPreview(inputPanel);
taggingPanel.addTagButton(tagButton);
footerPanel.storeAllTagButtons();
footerPanel.recalculateHeight();
setRowData(tagButtonTable, taggingPanel.getTagButtons());
} else {
Notification.notify(stringMessages.tagNotSpecified(), NotificationType.WARNING);
}
center();
});
Panel controlButtonPanel = new FlowPanel();
controlButtonPanel.setStyleName(style.buttonsPanel());
controlButtonPanel.add(okButton);
controlButtonPanel.add(cancelButton);
return controlButtonPanel;
}
/**
@@ -425,4 +291,94 @@ public class TagButtonDialog extends DialogBox {
tagButtonTable.setRowData(buttons);
tagButtonTable.setVisible(!buttons.isEmpty());
}
/**
* Button click handler for 'save' button (can only be pressed when user is currently editing a tag button).
*/
private void onSaveTagButtonChangesPressed() {
selectedTagButton.setText(inputPanel.getTag());
selectedTagButton.setTag(inputPanel.getTag());
selectedTagButton.setComment(inputPanel.getComment());
selectedTagButton.setImageURL(inputPanel.getImageURL());
selectedTagButton.setVisibleForPublic(inputPanel.isVisibleForPublic());
footerPanel.storeAllTagButtons();
inputPanel.clearAllValues();
tagPreviewPanel.renderPreview(inputPanel);
tagButtonTable.redraw();
setButtonMode(false);
selectedTagButton = null;
setRowData(tagButtonTable, taggingPanel.getTagButtons());
center();
}
/**
* Button click handler for 'cancel' button (can only be pressed when user is currently editing a tag button).
*/
private void onCancelTagButtonChangesPressed() {
// ask user for confirmation to discard changes if values of input fields changed
if (!inputPanel.compareFieldsToTagButton(selectedTagButton)) {
new ConfirmationDialog(stringMessages, stringMessages.tagDiscardChangesHeading(),
stringMessages.tagDiscardChanges(), confirmed -> {
if (confirmed) {
inputPanel.clearAllValues();
tagPreviewPanel.renderPreview(inputPanel);
tagButtonTable.setVisible(true);
setButtonMode(false);
center();
}
});
} else {
inputPanel.clearAllValues();
tagPreviewPanel.renderPreview(inputPanel);
tagButtonTable.setVisible(true);
setButtonMode(false);
center();
}
}
/**
* Button click handler for 'add tag button' button (can only be pressed when user is currently creating a new tag
* button).
*/
private void onAddTagButtonPressed() {
if (inputPanel.getTag().isEmpty()) {
Notification.notify(stringMessages.tagNotSpecified(), NotificationType.WARNING);
} else {
TagButton tagButton = new TagButton(inputPanel.getTag(), inputPanel.getTag(), inputPanel.getImageURL(),
inputPanel.getComment(), inputPanel.isVisibleForPublic());
inputPanel.clearAllValues();
tagPreviewPanel.renderPreview(inputPanel);
taggingPanel.addTagButton(tagButton);
footerPanel.storeAllTagButtons();
footerPanel.recalculateHeight();
setRowData(tagButtonTable, taggingPanel.getTagButtons());
}
center();
}
/**
* Button click handler for 'close' button (can only be pressed when user is currently creating a new tag button).
*/
private void onCloseButtonPressed() {
hide();
}
/**
* Sets text of buttons regarding to current mode.
*
* @param updateTag
* should be <code>true</code> when user updates a tag button, otherwise <code>false</code> (default,
* create new tag button)
*/
private void setButtonMode(boolean updateTag) {
if (updateTag) {
inputPanel.getOkButton().setText(stringMessages.save());
inputPanel.getCancelButton().setText(stringMessages.cancel());
updateTagMode = true;
} else {
inputPanel.getOkButton().setText(stringMessages.tagAddCustomTagButton());
inputPanel.getCancelButton().setText(stringMessages.close());
updateTagMode = false;
}
}
}
@@ -5,7 +5,6 @@ import java.util.List;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
@@ -19,8 +18,6 @@ public class TagButtonJsonDeSerializer {
private static final String FIELD_TAG = "tag";
private static final String FIELD_COMMENT = "comment";
private static final String FIELD_IMAGE_URL = "imageURL";
private static final String FIELD_IMAGE_WIDTH = "imageWidth";
private static final String FIELD_IMAGE_HEIGHT = "imageHeight";
private static final String FIELD_VISIBLE_FOR_PUBLIC = "public";
public JSONArray serialize(List<TagButton> tagButtons) {
@@ -36,8 +33,6 @@ public class TagButtonJsonDeSerializer {
}
if (button.getImageURL() != null) {
tagButtonObject.put(FIELD_IMAGE_URL, new JSONString(button.getImageURL()));
tagButtonObject.put(FIELD_IMAGE_WIDTH, new JSONNumber(button.getImageWidth()));
tagButtonObject.put(FIELD_IMAGE_HEIGHT, new JSONNumber(button.getImageHeight()));
}
tagButtonObject.put(FIELD_VISIBLE_FOR_PUBLIC, JSONBoolean.getInstance(button.isVisibleForPublic()));
result.set(i++, tagButtonObject);
@@ -56,13 +51,9 @@ public class TagButtonJsonDeSerializer {
JSONString tagButtonTag = (JSONString) tagButtonValue.get(FIELD_TAG);
JSONString tagButtonComment = (JSONString) tagButtonValue.get(FIELD_COMMENT);
JSONString tagButtonImageURL = (JSONString) tagButtonValue.get(FIELD_IMAGE_URL);
JSONNumber tagButtonImageWidth = (JSONNumber) tagButtonValue.get(FIELD_IMAGE_WIDTH);
JSONNumber tagButtonImageHeight = (JSONNumber) tagButtonValue.get(FIELD_IMAGE_HEIGHT);
JSONBoolean tagButtonVisibleForPublic = (JSONBoolean) tagButtonValue.get(FIELD_VISIBLE_FOR_PUBLIC);
result.add(new TagButton(tagButtonName.stringValue(), tagButtonTag.stringValue(),
tagButtonImageURL == null ? null : tagButtonImageURL.stringValue(),
tagButtonImageWidth == null ? -1 : (int) tagButtonImageWidth.doubleValue(),
tagButtonImageHeight == null ? -1 : (int) tagButtonImageHeight.doubleValue(),
tagButtonComment == null ? null : tagButtonComment.stringValue(),
tagButtonVisibleForPublic.booleanValue()));
}
@@ -1,8 +1,9 @@
package com.sap.sailing.gwt.ui.raceboard.tagging;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextArea;
@@ -11,112 +12,235 @@ import com.sap.sailing.domain.common.dto.TagDTO;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.raceboard.tagging.TaggingPanelResources.TagPanelStyle;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.gwt.adminconsole.URLFieldWithFileUpload;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
/**
* Panel containing input fields for tag/tag button creation and modification.
*/
// TODO: use DataEntryDialog
public class TagInputPanel extends FlowPanel {
private final TagPanelStyle style = TaggingPanelResources.INSTANCE.style();
private static final String DEFAULT_TAG = "";
private static final String DEFAULT_COMMENT = "";
private static final String DEFAULT_IMAGE_URL = "";
private static final boolean DEFAULT_VISIBLE_FOR_PUBLIC = false;
private final TaggingPanel taggingPanel;
private final Grid grid;
private final TextBox tagTextBox;
private final URLFieldWithFileUpload imageUrlUploaderPanel;
private final TextArea commentTextArea;
private final FlowPanel checkboxWrapper;
private final CheckBox visibleForPublicCheckBox;
private final Label noPermissionForPublicTagsLabel;
/**
* Extends {@link DataEntryDialog} to provide input validation for tags. The dialog itself is never shown to the
* user therfor methods {@link #show()} and {@link #center()} are overriden to have no effect. Instead input fields
* can be used in other UIs as validator still has access to these fields.
*/
private class TagEntryFields extends DataEntryDialog<TagDTO> {
private final StringMessages stringMessages;
private final TaggingPanel taggingPanel;
private final TextBox tagTextBox;
private final TextArea commentTextArea;
private final CheckBox visibleForPublicCheckBox;
private final URLFieldWithFileUpload imageUploadPanel;
private int imageWidth = -1;
private int imageHeight = -1;
public TagEntryFields(StringMessages stringMessages, TaggingPanel taggingPanel,
DialogCallback<TagDTO> callback) {
// set empty values for parameters which are not shown to the user. okayButtonText will be set by the using
// components.
super(/* title */ "", /* message */ "", /* okayButtonText */ "", stringMessages.cancel(), null,
/* animationEnabled */ true, callback);
this.setValidator(this::validate);
this.stringMessages = stringMessages;
this.taggingPanel = taggingPanel;
tagTextBox = createTextBox(DEFAULT_TAG);
commentTextArea = createTextArea(DEFAULT_COMMENT);
visibleForPublicCheckBox = createCheckbox(stringMessages.tagVisibleForPublicCheckBox());
visibleForPublicCheckBox.setValue(DEFAULT_VISIBLE_FOR_PUBLIC);
imageUploadPanel = new URLFieldWithFileUpload(stringMessages);
validateAndUpdate();
}
/**
* Validates given <code>tagToValidate</code> and returns error message in case input is not valid.
*
* @param tagToValidate
* tag to be checked
* @return <code>error message</code> in case input is not valid, otherwise <code>null</code>
*/
private String validate(TagDTO tagToValidate) {
if (tagToValidate == null) {
return stringMessages.unknown();
} else if (tagToValidate.getTag() == null || tagToValidate.getTag().isEmpty()) {
return stringMessages.tagNotSpecified();
} else if (taggingPanel.tagAlreadyExists(tagToValidate.getTag(), tagToValidate.getComment(),
tagToValidate.getImageURL(), tagToValidate.getResizedImageURL(), tagToValidate.isVisibleForPublic(),
tagToValidate.getRaceTimepoint())) {
return stringMessages.tagAlreadyExists();
}
return null;
}
public TextBox getTagTextBox() {
return tagTextBox;
}
public TextArea getCommentTextArea() {
return commentTextArea;
}
public CheckBox getVisibleForPublicCheckBox() {
return visibleForPublicCheckBox;
}
public URLFieldWithFileUpload getImageUploadPanel() {
return imageUploadPanel;
}
public Button getOkButton() {
return super.getOkButton();
}
public Button getCancelButton() {
return super.getCancelButton();
}
public Label getStatusLabel() {
return super.getStatusLabel();
}
public boolean validateAndUpdate() {
return super.validateAndUpdate();
}
/**
* Returns {@link TagDTO} created by input fields which does only contain values entered explicitly by user.
*/
@Override
protected TagDTO getResult() {
return new TagDTO(getTagTextBox().getValue(), getCommentTextArea().getValue(),
getImageUploadPanel().getURL(), null, getVisibleForPublicCheckBox().getValue(), null, null, null);
}
@Override
protected FocusWidget getInitialFocusWidget() {
return null;
}
@Override
public void show() {
}
@Override
public void center() {
}
}
private final TagPanelStyle style = TaggingPanelResources.INSTANCE.style();
private final TaggingPanel taggingPanel;
private final TagEntryFields tagEntryFields;
private final Grid grid;
private final FlowPanel checkboxWrapper;
private final Label noPermissionForPublicTagsLabel;
/**
* Creates view allowing users to input values for tags and {@link TagButton tag-buttons}.
*/
protected TagInputPanel(TaggingPanel taggingPanel, SailingServiceAsync sailingService,
StringMessages stringMessages) {
setStyleName(style.tagInputPanel());
StringMessages stringMessages, DialogCallback<TagDTO> callback) {
this.taggingPanel = taggingPanel;
tagEntryFields = new TagEntryFields(stringMessages, taggingPanel, callback);
setStyleName(style.tagInputPanel());
grid = new Grid(4, 2);
// tag
Label tagLabel = new Label(stringMessages.tagLabelTag() + ":");
tagTextBox = new TextBox();
tagTextBox.setStyleName(style.tagInputPanelTag());
tagTextBox.setTitle(stringMessages.tagLabelTag());
tagTextBox.getElement().setPropertyString("placeholder", stringMessages.tagLabelTag());
tagEntryFields.getTagTextBox().setTitle(stringMessages.tagLabelTag());
tagEntryFields.getTagTextBox().setStyleName(style.tagInputPanelTag());
tagEntryFields.getTagTextBox().getElement().setPropertyString("placeholder", stringMessages.tagLabelTag());
grid.setWidget(0, 0, tagLabel);
grid.setWidget(0, 1, tagTextBox);
grid.setWidget(0, 1, tagEntryFields.getTagTextBox());
// image upload
Label imageLabel = new Label(stringMessages.tagLabelImage() + ":");
imageUrlUploaderPanel = new URLFieldWithFileUpload(stringMessages);
imageUrlUploaderPanel.addValueChangeHandler(event -> {
if (imageUrlUploaderPanel.getURL() == null || imageUrlUploaderPanel.getURL().isEmpty()) {
imageWidth = -1;
imageHeight = -1;
} else {
sailingService.resolveImageDimensions(imageUrlUploaderPanel.getURL(),
new AsyncCallback<Util.Pair<Integer, Integer>>() {
@Override
public void onSuccess(Pair<Integer, Integer> imageSize) {
if (imageSize != null) {
imageWidth = imageSize.getA();
imageHeight = imageSize.getB();
}
}
@Override
public void onFailure(Throwable caught) {
imageUrlUploaderPanel.setURL("");
}
});
}
});
grid.setWidget(1, 0, imageLabel);
grid.setWidget(1, 1, imageUrlUploaderPanel);
grid.setWidget(1, 1, tagEntryFields.getImageUploadPanel());
// comment
Label commentLabel = new Label(stringMessages.tagLabelComment() + ":");
commentTextArea = new TextArea();
commentTextArea.setStyleName(style.tagInputPanelComment());
commentTextArea.setVisibleLines(4);
commentTextArea.setTitle(stringMessages.tagLabelComment());
commentTextArea.getElement().setPropertyString("placeholder", stringMessages.tagLabelComment());
tagEntryFields.getCommentTextArea().setTitle(stringMessages.tagLabelComment());
tagEntryFields.getCommentTextArea().setStyleName(style.tagInputPanelComment());
tagEntryFields.getCommentTextArea().setVisibleLines(4);
tagEntryFields.getCommentTextArea().getElement().setPropertyString("placeholder",
stringMessages.tagLabelComment());
grid.setWidget(2, 0, commentLabel);
grid.setWidget(2, 1, commentTextArea);
grid.setWidget(2, 1, tagEntryFields.getCommentTextArea());
// visibility
Label visibilityLabel = new Label(stringMessages.tagLabelVisibility() + ":");
visibleForPublicCheckBox = new CheckBox(stringMessages.tagVisibleForPublicCheckBox());
visibleForPublicCheckBox.setValue(DEFAULT_VISIBLE_FOR_PUBLIC);
noPermissionForPublicTagsLabel = new Label(stringMessages.tagPublicModificationPermissionMissing());
checkboxWrapper = new FlowPanel();
checkboxWrapper.add(visibleForPublicCheckBox);
checkboxWrapper.add(tagEntryFields.getVisibleForPublicCheckBox());
checkboxWrapper.add(noPermissionForPublicTagsLabel);
grid.setWidget(3, 0, visibilityLabel);
grid.setWidget(3, 1, checkboxWrapper);
add(grid);
clearAllValues();
}
protected Button getOkButton() {
return tagEntryFields.getOkButton();
}
protected Button getCancelButton() {
return tagEntryFields.getCancelButton();
}
protected Label getStatusLabel() {
return tagEntryFields.getStatusLabel();
}
protected void validateAndUpdate() {
tagEntryFields.validateAndUpdate();
}
protected TextBox getTagTextBox() {
return tagEntryFields.getTagTextBox();
}
protected TextArea getCommentTextArea() {
return tagEntryFields.getCommentTextArea();
}
protected URLFieldWithFileUpload getImageURLTextBox() {
return tagEntryFields.getImageUploadPanel();
}
protected CheckBox getVisibleForPublicCheckBox() {
return tagEntryFields.getVisibleForPublicCheckBox();
}
protected String getTag() {
return getTagTextBox().getValue();
}
protected String getComment() {
return getCommentTextArea().getValue();
}
protected boolean isVisibleForPublic() {
return getVisibleForPublicCheckBox().getValue();
}
public String getImageURL() {
return imageUrlUploaderPanel.getURL();
return tagEntryFields.getImageUploadPanel().getURL();
}
public int getImageWidth() {
return imageWidth;
protected void setTag(String tag) {
getTagTextBox().setValue(tag);
}
public int getImageHeight() {
return imageHeight;
protected void setComment(String comment) {
getCommentTextArea().setValue(comment);
}
protected void setImageURL(String imageURL) {
getImageURLTextBox().setValue(imageURL);
}
protected void setVisibleForPublic(boolean visibleForPublic) {
getVisibleForPublicCheckBox().setValue(visibleForPublic);
}
/**
@@ -169,18 +293,6 @@ public class TagInputPanel extends FlowPanel {
&& isVisibleForPublic() == DEFAULT_VISIBLE_FOR_PUBLIC;
}
protected String getTag() {
return tagTextBox.getValue();
}
protected String getComment() {
return commentTextArea.getValue();
}
protected boolean isVisibleForPublic() {
return visibleForPublicCheckBox.getValue();
}
/**
* Sets all input fields to values of given {@link TagDTO tag}.
*
@@ -195,44 +307,16 @@ public class TagInputPanel extends FlowPanel {
setCurrentStatus();
}
protected void setTag(String tag) {
tagTextBox.setValue(tag);
}
protected void setComment(String comment) {
commentTextArea.setValue(comment);
}
protected void setImageURL(String imageURL) {
imageUrlUploaderPanel.setValue(imageURL);
}
protected void setVisibleForPublic(boolean visibleForPublic) {
visibleForPublicCheckBox.setValue(visibleForPublic);
}
protected TextBox getTagTextBox() {
return tagTextBox;
}
protected URLFieldWithFileUpload getImageURLTextBox() {
return imageUrlUploaderPanel;
}
protected TextArea getCommentTextArea() {
return commentTextArea;
}
protected CheckBox getVisibleForPublicCheckBox() {
return visibleForPublicCheckBox;
}
/**
* Sets visibility of checkbox for visibility of tag. Users without permission for public tag creation will see
* information label instead.
*/
protected void setCurrentStatus() {
if (taggingPanel.hasPermissionToModifyPublicTags()) {
visibleForPublicCheckBox.setVisible(true);
getVisibleForPublicCheckBox().setVisible(true);
noPermissionForPublicTagsLabel.setVisible(false);
} else {
visibleForPublicCheckBox.setVisible(false);
getVisibleForPublicCheckBox().setVisible(false);
noPermissionForPublicTagsLabel.setVisible(true);
}
}
@@ -4,10 +4,12 @@ import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.sap.sailing.domain.common.dto.TagDTO;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.raceboard.tagging.TaggingPanel.State;
import com.sap.sailing.gwt.ui.raceboard.tagging.TaggingPanelResources.TagPanelStyle;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
import com.sap.sse.security.ui.client.UserService;
/**
@@ -22,8 +24,9 @@ public class TagModificationPanel extends FlowPanel {
private final StringMessages stringMessages;
private final Label heading;
private final Panel editButtonsPanel, createButtonsPanel;
private final Panel buttonsPanel;
private final TagInputPanel inputPanel;
private final Button editCustomTagButtons;
/**
* Creates panel used to create tags and {@link TagButton tag-buttons}.
@@ -37,24 +40,41 @@ public class TagModificationPanel extends FlowPanel {
SailingServiceAsync sailingService, StringMessages stringMessages, UserService userService) {
this.taggingPanel = taggingPanel;
this.stringMessages = stringMessages;
setStyleName(style.tagModificationPanel());
inputPanel = new TagInputPanel(taggingPanel, sailingService, stringMessages, new DialogCallback<TagDTO>() {
@Override
public void ok(TagDTO editedObject) {
if (taggingPanel.getCurrentState().equals(State.EDIT_TAG)) {
taggingPanel.updateTag(taggingPanel.getSelectedTag(), inputPanel.getTag(), inputPanel.getComment(),
inputPanel.getImageURL(), inputPanel.isVisibleForPublic());
resetState();
} else {
if (taggingPanel.isLoggedInAndRaceLogAvailable()) {
taggingPanel.saveTag(inputPanel.getTag(), inputPanel.getComment(), inputPanel.getImageURL(),
inputPanel.isVisibleForPublic());
// TODO: Add callback to saveTag() to clear fields only if tag got really added
inputPanel.clearAllValues();
}
}
}
inputPanel = new TagInputPanel(taggingPanel, sailingService, stringMessages);
Button createTagFromInputFields = new Button(stringMessages.tagAddTag());
createTagFromInputFields.setStyleName(style.tagDialogButton());
createTagFromInputFields.addStyleName("gwt-Button");
createTagFromInputFields.addClickHandler(event -> {
if (taggingPanel.isLoggedInAndRaceLogAvailable()) {
taggingPanel.saveTag(inputPanel.getTag(), inputPanel.getComment(), inputPanel.getImageURL(),
inputPanel.getImageWidth(), inputPanel.getImageHeight(), inputPanel.isVisibleForPublic());
// TODO: Add callback to saveTag() to clear fields only if tag got really added
inputPanel.clearAllValues();
@Override
public void cancel() {
if ((taggingPanel.getCurrentState().equals(State.CREATE_TAG) && !inputPanel.isInputEmpty())
|| (taggingPanel.getCurrentState().equals(State.EDIT_TAG)
&& !inputPanel.compareFieldsToTag(taggingPanel.getSelectedTag()))) {
new ConfirmationDialog(stringMessages, stringMessages.tagDiscardChangesHeading(),
stringMessages.tagDiscardChanges(), result -> {
if (result) {
resetState();
}
});
} else {
resetState();
}
}
});
Button editCustomTagButtons = new Button(stringMessages.tagEditCustomTagButtons());
editCustomTagButtons = new Button(stringMessages.tagEditCustomTagButtons());
editCustomTagButtons.setStyleName(style.tagDialogButton());
editCustomTagButtons.addStyleName("gwt-Button");
editCustomTagButtons.addClickHandler(event -> {
@@ -62,47 +82,18 @@ public class TagModificationPanel extends FlowPanel {
new TagButtonDialog(taggingPanel, tagFooterPanel, sailingService, stringMessages, userService);
}
});
createButtonsPanel = new FlowPanel();
createButtonsPanel.setStyleName(style.buttonsPanel());
createButtonsPanel.add(editCustomTagButtons);
createButtonsPanel.add(createTagFromInputFields);
createButtonsPanel.setVisible(true);
Button saveTagChanges = new Button(stringMessages.save());
saveTagChanges.setStyleName(style.tagDialogButton());
saveTagChanges.addStyleName("gwt-Button");
saveTagChanges.addClickHandler(event -> {
taggingPanel.updateTag(taggingPanel.getSelectedTag(), inputPanel.getTag(), inputPanel.getComment(),
inputPanel.getImageURL(), inputPanel.getImageWidth(), inputPanel.getImageHeight(),
inputPanel.isVisibleForPublic());
resetState();
});
Button cancelTagChanges = new Button(stringMessages.cancel());
cancelTagChanges.setStyleName(style.tagDialogButton());
cancelTagChanges.addStyleName("gwt-Button");
cancelTagChanges.addClickHandler(event -> {
if ((taggingPanel.getCurrentState().equals(State.CREATE_TAG) && !inputPanel.isInputEmpty())
|| (taggingPanel.getCurrentState().equals(State.EDIT_TAG)
&& !inputPanel.compareFieldsToTag(taggingPanel.getSelectedTag()))) {
new ConfirmationDialog(stringMessages, stringMessages.tagDiscardChangesHeading(),
stringMessages.tagDiscardChanges(), result -> {
if (result) {
resetState();
}
});
} else {
resetState();
}
});
editButtonsPanel = new FlowPanel();
editButtonsPanel.setStyleName(style.buttonsPanel());
editButtonsPanel.add(saveTagChanges);
editButtonsPanel.add(cancelTagChanges);
editButtonsPanel.setVisible(false);
inputPanel.getOkButton().setText(stringMessages.tagAddTag());
inputPanel.getOkButton().setStyleName(style.tagDialogButton());
inputPanel.getOkButton().addStyleName("gwt-Button");
inputPanel.getCancelButton().setText(stringMessages.cancel());
inputPanel.getCancelButton().setStyleName(style.tagDialogButton());
inputPanel.getCancelButton().addStyleName("gwt-Button");
buttonsPanel = new FlowPanel();
buttonsPanel.setStyleName(style.buttonsPanel());
buttonsPanel.add(editCustomTagButtons);
buttonsPanel.add(inputPanel.getOkButton());
buttonsPanel.add(inputPanel.getCancelButton());
buttonsPanel.setVisible(true);
Panel headerPanel = new FlowPanel();
headerPanel.setStyleName(style.tagModificationPanelHeader());
heading = new Label(stringMessages.tagAddTags());
@@ -126,11 +117,10 @@ public class TagModificationPanel extends FlowPanel {
}
});
headerPanel.add(closeFooterButton);
add(headerPanel);
add(inputPanel.getStatusLabel());
add(inputPanel);
add(createButtonsPanel);
add(editButtonsPanel);
add(buttonsPanel);
}
/**
@@ -142,13 +132,16 @@ public class TagModificationPanel extends FlowPanel {
protected void setCurrentStatus(State state) {
if (state.equals(State.EDIT_TAG)) {
heading.setText(stringMessages.tagEditTag());
createButtonsPanel.setVisible(false);
editButtonsPanel.setVisible(true);
editCustomTagButtons.setVisible(false);
inputPanel.getOkButton().setText(stringMessages.save());
inputPanel.getCancelButton().setVisible(true);
inputPanel.setTag(taggingPanel.getSelectedTag());
inputPanel.validateAndUpdate();
} else {
heading.setText(stringMessages.tagAddTags());
createButtonsPanel.setVisible(true);
editButtonsPanel.setVisible(false);
editCustomTagButtons.setVisible(true);
inputPanel.getOkButton().setText(stringMessages.tagAddTag());
inputPanel.getCancelButton().setVisible(false);
}
inputPanel.setCurrentStatus();
}
@@ -32,6 +32,7 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.raceboard.tagging.TaggingPanelResources.TagPanelStyle;
import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.gwt.client.Notification;
@@ -247,65 +248,78 @@ public class TaggingPanel extends ComponentWithoutSettings
*
* @see #saveTag(String, Sting, String, boolean, TimePoint, boolean)
*/
protected void saveTag(String tag, String comment, String imageURL, int imageWidth, int imageHeight,
boolean visibleForPublic) {
getResizedImageURLForImageURL(imageURL, imageHeight, imageWidth, new AsyncCallback<String>() {
protected void saveTag(String tag, String comment, String imageURL, boolean visibleForPublic) {
getResizedImageURLForImageURL(imageURL, new AsyncCallback<String>() {
@Override
public void onFailure(Throwable caught) {
GWT.log(caught.getMessage());
}
@Override
public void onSuccess(String resultingResizedImageURL) {
saveTag(tag, comment, imageURL, resultingResizedImageURL, visibleForPublic, null);
public void onSuccess(String resizedImageURL) {
saveTag(tag, comment, imageURL, resizedImageURL, visibleForPublic, null);
}
});
}
/**
* Calling this method you get a resized image URL for your original image URL
* Returns image URL of resized image for given image URL.
*
* @param imageURL
* URL of image which needs to be resized
* @param imageWidth
* width of image needing to be resized
* @param imageHeight
* height of image needing to be resized
* @param callback
* An asynchronous callback containing the result, a resized image URL
* An asynchronous callback containing the resized image URL, <code>empty string</code> in case of empty
* given image URL
*/
protected void getResizedImageURLForImageURL(String imageURL, int imageWidth, int imageHeight,
AsyncCallback<String> callback) {
protected void getResizedImageURLForImageURL(String imageURL, AsyncCallback<String> callback) {
if (imageURL == null || imageURL.isEmpty()) {
callback.onSuccess(null);
callback.onSuccess("");
} else {
if (imageWidth < MediaTagConstants.TAGGING_IMAGE.getMinWidth()
|| imageHeight < MediaTagConstants.TAGGING_IMAGE.getMinHeight()) {
callback.onSuccess(null);// image to small
} else {
if (imageWidth > MediaTagConstants.TAGGING_IMAGE.getMaxWidth()
|| imageHeight > MediaTagConstants.TAGGING_IMAGE.getMaxHeight()) {
ArrayList<MediaTagConstants> tags = new ArrayList<MediaTagConstants>();
tags.add(MediaTagConstants.TAGGING_IMAGE);
sailingService.resizeImage(new ImageResizingTaskDTO(imageURL, new Date(), tags),
new AsyncCallback<Set<ImageDTO>>() {
@Override
public void onFailure(Throwable caught) {
callback.onSuccess(null);
}
@Override
public void onSuccess(Set<ImageDTO> result) {
String resizedImageURL = null;
if (result.size() != 0) {
resizedImageURL = result.iterator().next().getSourceRef();
}
callback.onSuccess(resizedImageURL);
}
});
} else {
callback.onSuccess(imageURL);
sailingService.resolveImageDimensions(imageURL, new AsyncCallback<Pair<Integer, Integer>>() {
@Override
public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
}
@Override
public void onSuccess(Pair<Integer, Integer> result) {
if (result == null || result.getA() == null || result.getB() == null) {
callback.onFailure(new IllegalArgumentException("Size of image could not be determined!"));
} else {
int imageWidth = result.getA();
int imageHeight = result.getB();
if (imageWidth < MediaTagConstants.TAGGING_IMAGE.getMinWidth()
|| imageHeight < MediaTagConstants.TAGGING_IMAGE.getMinHeight()) {
callback.onFailure(new IllegalArgumentException("Image is to small for resizing!"));
} else {
if (imageWidth > MediaTagConstants.TAGGING_IMAGE.getMaxWidth()
|| imageHeight > MediaTagConstants.TAGGING_IMAGE.getMaxHeight()) {
ArrayList<MediaTagConstants> tags = new ArrayList<MediaTagConstants>();
tags.add(MediaTagConstants.TAGGING_IMAGE);
sailingService.resizeImage(new ImageResizingTaskDTO(imageURL, new Date(), tags),
new AsyncCallback<Set<ImageDTO>>() {
@Override
public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
@Override
public void onSuccess(Set<ImageDTO> result) {
String resizedImageURL = null;
if (result.size() != 0) {
resizedImageURL = result.iterator().next().getSourceRef();
}
callback.onSuccess(resizedImageURL);
}
});
} else {
callback.onSuccess(imageURL);
}
}
}
}
});
}
}
@@ -320,16 +334,7 @@ public class TaggingPanel extends ComponentWithoutSettings
*/
protected void saveTag(String tag, String comment, String imageURL, String resizedImageURL,
boolean visibleForPublic, TimePoint raceTimePoint) {
boolean tagIsNewTag = true;
// check if tag already exists
for (TagDTO tagDTO : tagListProvider.getAllTags()) {
if (tagDTO.equals(tag, comment, imageURL, resizedImageURL, visibleForPublic,
userService.getCurrentUser().getName(), new MillisecondsTimePoint(getTimerTime()))) {
tagIsNewTag = false;
break;
}
}
if (!tagIsNewTag) {
if (tagAlreadyExists(tag, comment, imageURL, resizedImageURL, visibleForPublic, raceTimePoint)) {
// tag does already exist
Notification.notify(stringMessages.tagNotSavedReason(" " + stringMessages.tagAlreadyExists()),
NotificationType.WARNING);
@@ -420,19 +425,20 @@ public class TaggingPanel extends ComponentWithoutSettings
*
* @see TagDTO
*/
protected void updateTag(TagDTO tagToUpdate, String tag, String comment, String imageURL, int imageWidth,
int imageHeight, boolean visibleForPublic) {
// A new resized image gets created every time a tag is updated(if tag shall contain an image)
getResizedImageURLForImageURL(imageURL, imageHeight, imageWidth, new AsyncCallback<String>() {
protected void updateTag(TagDTO tagToUpdate, String tag, String comment, String imageURL,
boolean visibleForPublic) {
// A new resized image gets created every time a tag is updated (if tag shall contain an image)
getResizedImageURLForImageURL(imageURL, new AsyncCallback<String>() {
@Override
public void onFailure(Throwable caught) {
Notification.notify(stringMessages.tagNotSavedReason(caught.getMessage()), NotificationType.ERROR);
GWT.log(caught.getMessage());
}
@Override
public void onSuccess(String resultingResizedImageURL) {
public void onSuccess(String resizedImageURL) {
sailingService.updateTag(leaderboardName, raceColumn.getName(), fleet.getName(), tagToUpdate, tag,
comment, imageURL, resultingResizedImageURL, visibleForPublic,
new AsyncCallback<SuccessInfo>() {
comment, imageURL, resizedImageURL, visibleForPublic, new AsyncCallback<SuccessInfo>() {
@Override
public void onFailure(Throwable caught) {
Notification.notify(stringMessages.tagNotSavedReason(caught.getMessage()),
@@ -463,6 +469,22 @@ public class TaggingPanel extends ComponentWithoutSettings
});
}
/**
* Returns whether given tag already exists.
*
* @return <code>true</code> if tag already exists (only checked client side), otherwise <code>false</code>
*/
protected boolean tagAlreadyExists(String tag, String comment, String imageURL, String resizedImageURL,
boolean visibleForPublic, TimePoint raceTimePoint) {
for (TagDTO tagDTO : tagListProvider.getAllTags()) {
if (tagDTO.equals(tag, comment, imageURL, resizedImageURL, visibleForPublic,
userService.getCurrentUser().getName(), new MillisecondsTimePoint(getTimerTime()))) {
return true;
}
}
return false;
}
/**
* Removes all private tags from {@link TagListProvider}, loads all private tags from {@link SailingServiceAsync
* SailingService}, adds them to the {@link TagListProvider} and updates the UI via {@link #updateContent()}.
@@ -518,8 +540,8 @@ public class TaggingPanel extends ComponentWithoutSettings
*/
protected void addTagButton(TagButton tagButton) {
tagButton.addClickHandler(event -> {
saveTag(tagButton.getTag(), tagButton.getComment(), tagButton.getImageURL(), tagButton.getImageWidth(),
tagButton.getImageHeight(), tagButton.isVisibleForPublic());
saveTag(tagButton.getTag(), tagButton.getComment(), tagButton.getImageURL(),
tagButton.isVisibleForPublic());
});
tagButtons.add(tagButton);
}
@@ -70,6 +70,14 @@
display: inline-block;
}
@external errorLabel;
.errorLabel {
padding-top: 5px;
}
.tagModificationPanel .errorLabel {
font-size: 14px;
}
/**************************** Tag-Cells ****************************/
.tagCell {
@@ -185,7 +193,6 @@
.tagDialogButton {
max-width: 100%;
padding: 4px 4px;
cursor: pointer;
}